[
  {
    "path": ".editorconfig",
    "content": "# top-most EditorConfig file\nroot = true\n\n# Unix-style newlines with a newline ending every file\n[*]\nend_of_line = lf\nindent_style = space\n# Scripts without suffixes in the project root tend to indent by two spaces\nindent_size = 2\n\n# Most of the project files indent by four spaces\n[*/**]\nindent_size = 4\n\n# Test files indent by two spaces\n[test/**]\nindent_size = 2\n\n# The config parser file indents by both two and four spaces,\n# so we choose to indent by two spaces as a common denominator.\n[*.yy]\nindent_size = 2\n\n[{Makefile,Makefile.am}]\nindent_style = tab\n\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/bug-report-for-version-2-x.md",
    "content": "---\nname: Bug report for version 2.x\nabout: Create a report to help us improve\ntitle: ''\nlabels: '2.x'\nassignees: ''\n\n---\n\n**Describe the bug**\n\nA clear and concise description of what the bug is.\n\n**Logs and dumps**\n\nOutput of:\n 1. DebugLogs (level 9)\n 2. AuditLogs\n 3. Error logs\n 4. If there is a crash, the core dump file.\n\n_Notice:_ Be carefully to not leak any confidential information.\n\n**To Reproduce**\n\nSteps to reproduce the behavior:\n\nA **curl** command line that mimics the original request and reproduces the problem. Or a ModSecurity v3 test case.\n\n[e.g: curl \"modsec-full/ca/..\\\\..\\\\..\\\\..\\\\..\\\\..\\\\/\\\\etc/\\\\passwd\" or [issue-394.json](https://github.com/SpiderLabs/ModSecurity/blob/v3/master/test/test-cases/regression/issue-394.json)]\n\n\n**Expected behavior**\n\nA clear and concise description of what you expected to happen.\n\n**Server (please complete the following information):**\n - ModSecurity version (and connector): [e.g. ModSecurity v3.0.1 with nginx-connector v1.0.0]\n - WebServer: [e.g. nginx-1.15.5]\n - OS (and distro): [e.g. Linux, archlinux]\n\n\n**Rule Set (please complete the following information):**\n - Running any public or commercial rule set? [e.g. SpiderLabs commercial rules]\n - What is the version number? [e.g. 2018-08-11]\n\n**Additional context**\n\nAdd any other context about the problem here.\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/bug-report-for-version-3-x.md",
    "content": "---\nname: Bug report for version 3.x\nabout: Create a report to help us improve. If you don't know a specific detail or\n  piece of information leave it blank, if necessary we will help you to figure out.\ntitle: ''\nlabels: '3.x'\nassignees: ''\n\n---\n\n**Describe the bug**\n\nA clear and concise description of what the bug is.\n\n**Logs and dumps**\n\nOutput of:\n 1. DebugLogs (level 9)\n 2. AuditLogs\n 3. Error logs\n 4. If there is a crash, the core dump file.\n\n_Notice:_ Be careful to not leak any confidential information.\n\n**To Reproduce**\n\nSteps to reproduce the behavior:\n\nA **curl** command line that mimics the original request and reproduces the problem. Or a ModSecurity v3 test case.\n\n[e.g: curl \"modsec-full/ca/..\\\\..\\\\..\\\\..\\\\..\\\\..\\\\/\\\\etc/\\\\passwd\" or [issue-394.json](https://github.com/SpiderLabs/ModSecurity/blob/v3/master/test/test-cases/regression/issue-394.json)]\n\n\n**Expected behavior**\n\nA clear and concise description of what you expected to happen.\n\n**Server (please complete the following information):**\n - ModSecurity version (and connector): [e.g. ModSecurity v3.0.8 with nginx-connector v1.0.3]\n - WebServer: [e.g. nginx-1.18.0]\n - OS (and distro): [e.g. Linux, archlinux]\n\n\n**Rule Set (please complete the following information):**\n - Running any public or commercial rule set? [e.g. SpiderLabs commercial rules]\n - What is the version number? [e.g. 2018-08-11]\n\n**Additional context**\n\nAdd any other context about the problem here.\n"
  },
  {
    "path": ".github/PULL_REQUEST_TEMPLATE.md",
    "content": "<!-- Thank you for contributing to OWASP ModSecurity, your effort is greatly appreciated -->\n<!-- Please help us by adding the information below in this PR so it aids reviewers -->\n\n## what\n\n<!--\n- Describe high-level what changed as a result of these commits (i.e. in plain-english, what do these changes mean?)\n- Use bullet points to be concise and to the point.\n-->\n\n## why\n\n<!--\n- Provide the justifications for the changes (e.g. business case).\n- Describe why these changes were made (e.g. why do these commits fix the problem?)\n- Use bullet points to be concise and to the point.\n-->\n\n## references\n\n<!--\n- Link to any supporting github issues or helpful documentation to add some context (e.g. stackoverflow).\n- Use `closes #123`, if this PR closes a GitHub issue `#123`\n-->\n"
  },
  {
    "path": ".github/workflows/ci.yml",
    "content": "name: Quality Assurance\n\non:\n  push:\n  pull_request:\n\njobs:\n  build-linux:\n    name: Linux (${{ matrix.platform.label }}, ${{ matrix.compiler.label }}, ${{ matrix.configure.label }})\n    runs-on: ${{ matrix.os }}\n    strategy:\n      matrix:\n        os: [ubuntu-22.04]\n        platform:\n          - {label: \"x64\", arch: \"amd64\", configure: \"\"}\n          - {label: \"x32\", arch: \"i386\", configure: \"PKG_CONFIG_PATH=/usr/lib/i386-linux-gnu/pkgconfig CFLAGS=-m32 CXXFLAGS=-m32 LDFLAGS=-m32\"}\n        compiler:\n          - {label: \"gcc\", cc: \"gcc\", cxx: \"g++\"}\n          - {label: \"clang\", cc: \"clang\", cxx: \"clang++\"}\n        configure:\n          - {label: \"with parser generation\", opt: \"--enable-parser-generation\" }\n          - {label: \"wo curl\",    opt: \"--without-curl\" }\n          - {label: \"wo lua\",     opt: \"--without-lua\" }\n          - {label: \"wo maxmind\", opt: \"--without-maxmind\" }\n          - {label: \"wo libxml\",  opt: \"--without-libxml\" }\n          - {label: \"wo geoip\",   opt: \"--without-geoip\" }\n          - {label: \"wo ssdeep\",  opt: \"--without-ssdeep\" }\n          - {label: \"with lmdb\",  opt: \"--with-lmdb\" }\n          - {label: \"with pcre\", opt: \"--with-pcre\" }\n        exclude:\n          - platform: {label: \"x32\"}\n            configure: {label: \"wo geoip\"}\n          - platform: {label: \"x32\"}\n            configure: {label: \"wo ssdeep\"}\n    steps:\n      - name: Setup Dependencies (common)\n        run: |\n          sudo dpkg --add-architecture ${{ matrix.platform.arch }}\n          sudo apt-get update -y -qq\n          sudo apt-get install -y libyajl-dev:${{ matrix.platform.arch }} \\\n                                  libcurl4-openssl-dev:${{ matrix.platform.arch }} \\\n                                  liblmdb-dev:${{ matrix.platform.arch }} \\\n                                  liblua5.2-dev:${{ matrix.platform.arch }} \\\n                                  libmaxminddb-dev:${{ matrix.platform.arch }} \\\n                                  libpcre2-dev:${{ matrix.platform.arch }} \\\n                                  pcre2-utils:${{ matrix.platform.arch }} \\\n                                  bison flex\n      - name: Setup Dependencies (x32)\n        if: ${{ matrix.platform.label == 'x32' }}\n        run: |\n          sudo apt-get install g++-multilib\n          sudo apt-get install -y libxml2-dev:${{ matrix.platform.arch }} \\\n                                  libpcre3-dev:${{ matrix.platform.arch }}\n      - name: Setup Dependencies (x64)\n        if: ${{ matrix.platform.label == 'x64' }}\n        run: |\n          sudo apt-get install -y libgeoip-dev:${{ matrix.platform.arch }} \\\n                                  libfuzzy-dev:${{ matrix.platform.arch }}\n      - uses: actions/checkout@v4\n        with:\n          submodules: true\n          fetch-depth: 0\n      - name: build.sh\n        run: ./build.sh\n      - name: configure\n        env:\n          CC: ${{ matrix.compiler.cc }}\n          CXX: ${{ matrix.compiler.cxx }}\n        run: ./configure ${{ matrix.platform.configure }} ${{ matrix.configure.opt }} --enable-assertions=yes\n      - uses: ammaraskar/gcc-problem-matcher@master\n      - name: make\n        run: make -j `nproc`\n      - name: check\n        run: make check\n\n  build-macos:\n    name: macOS (${{ matrix.configure.label }})\n    runs-on: ${{ matrix.os }}\n    strategy:\n      matrix:\n        os: [macos-14]\n        configure:\n          - {label: \"with parser generation\", opt: \"--enable-parser-generation\" }\n          - {label: \"wo curl\",    opt: \"--without-curl\" }\n          - {label: \"wo lua\",     opt: \"--without-lua\" }\n          - {label: \"wo maxmind\", opt: \"--without-maxmind\" }\n          - {label: \"wo libxml\",  opt: \"--without-libxml\" }\n          - {label: \"wo geoip\",   opt: \"--without-geoip\" }\n          - {label: \"wo ssdeep\",  opt: \"--without-ssdeep\" }\n          - {label: \"with lmdb\",  opt: \"--with-lmdb\" }\n          - {label: \"with pcre\", opt: \"--with-pcre\" }\n    steps:\n      - name: Setup Dependencies\n        # curl, pcre2 not installed because they're already\n        # included in the image\n        run: |\n          brew install autoconf \\\n                       automake \\\n                       libtool \\\n                       yajl \\\n                       lmdb \\\n                       lua \\\n                       libmaxminddb \\\n                       libxml2 \\\n                       ssdeep \\\n                       pcre \\\n                       bison \\\n                       flex\n      - uses: actions/checkout@v4\n        with:\n          submodules: true\n          fetch-depth: 0\n      - name: Build GeoIP\n        run: |\n          git clone --depth 1 --no-checkout https://github.com/maxmind/geoip-api-c.git\n          cd geoip-api-c\n          git fetch --tags\n          # Check out the last release, v1.6.12\n          git checkout 4b526e7331ca1d692b74a0509ddcc725622ed31a\n          autoreconf --install\n          ./configure --disable-dependency-tracking --disable-silent-rules --prefix=/opt/homebrew\n          make install\n      - name: build.sh\n        run: ./build.sh\n      - name: configure\n        run: ./configure ${{ matrix.configure.opt }} --enable-assertions=yes\n      - uses: ammaraskar/gcc-problem-matcher@master\n      - name: make\n        run: make -j `sysctl -n hw.logicalcpu`\n      - name: check\n        run: make check\n\n  build-windows:\n    name: Windows (${{ matrix.platform.label }}, ${{ matrix.configure.label }})\n    runs-on: ${{ matrix.os }}\n    strategy:\n      matrix:\n        os: [windows-2022]\n        platform:\n          - {label: \"x64\", arch: \"x86_64\"}\n        configuration: [Release]\n        configure:\n          - {label: \"full\",       opt: \"\" }\n          - {label: \"wo curl\",    opt: \"-DWITH_CURL=OFF\" }\n          - {label: \"wo lua\",     opt: \"-DWITH_LUA=OFF\" }\n          - {label: \"wo maxmind\", opt: \"-DWITH_MAXMIND=OFF\" }\n          - {label: \"wo libxml\",  opt: \"-DWITH_LIBXML2=OFF\" }\n          - {label: \"with lmdb\",  opt: \"-DWITH_LMDB=ON\" }\n    steps:\n      - uses: actions/checkout@v4\n        with:\n          submodules: true\n          fetch-depth: 0\n      - name: Install Conan\n        run: |\n          pip3 install conan --upgrade\n          conan profile detect\n      - uses: ammaraskar/msvc-problem-matcher@master\n      - name: Build ${{ matrix.configuration }} ${{ matrix.platform.arch }} ${{ matrix.configure.label }}\n        shell: cmd\n        run: vcbuild.bat ${{ matrix.configuration }} ${{ matrix.platform.arch }} NO_ASAN \"${{ matrix.configure.opt }}\"\n      - name: Set up test environment\n        working-directory: build\\win32\\build\\${{ matrix.configuration }}\n        env:\n          BASE_DIR: ..\\..\\..\\..\n        shell: cmd\n        run: |\n          copy unit_tests.exe %BASE_DIR%\\test\n          copy regression_tests.exe %BASE_DIR%\\test\n          copy libModSecurity.dll %BASE_DIR%\\test\n          copy %BASE_DIR%\\unicode.mapping %BASE_DIR%\\test\n          md \\tmp\n          md \\bin\n          copy \"C:\\Program Files\\Git\\usr\\bin\\echo.exe\" \\bin\n          copy \"C:\\Program Files\\Git\\usr\\bin\\echo.exe\" \\bin\\echo\n      - name: Disable tests that don't work on Windows\n        working-directory: test\\test-cases\\regression\n        shell: cmd\n        run: |\n          jq \"map(if .title == \\\"Test match variable (1/n)\\\" then .enabled = 0 else . end)\" issue-2423-msg-in-chain.json > tmp.json && move /Y tmp.json issue-2423-msg-in-chain.json\n          jq \"map(if .title == \\\"Test match variable (2/n)\\\" then .enabled = 0 else . end)\" issue-2423-msg-in-chain.json > tmp.json && move /Y tmp.json issue-2423-msg-in-chain.json\n          jq \"map(if .title == \\\"Test match variable (3/n)\\\" then .enabled = 0 else . end)\" issue-2423-msg-in-chain.json > tmp.json && move /Y tmp.json issue-2423-msg-in-chain.json\n          jq \"map(if .title == \\\"Variable offset - FILES_NAMES\\\" then .enabled = 0 else . end)\" offset-variable.json > tmp.json && move /Y tmp.json offset-variable.json\n      - name: Run tests\n        working-directory: build\\win32\\build\n        run: |\n          ctest -C ${{ matrix.configuration }} --output-on-failure\n\n  cppcheck:\n    runs-on: [macos-14]\n    steps:\n      - name: Setup Dependencies\n        run: |\n          brew install autoconf \\\n                       automake \\\n                       libtool \\\n                       cppcheck\n      - uses: actions/checkout@v4\n        with:\n          submodules: true\n          fetch-depth: 0\n      - name: configure\n        run: |\n          ./build.sh\n          ./configure\n      - name: cppcheck\n        run: make check-static\n"
  },
  {
    "path": ".github/workflows/ci_new.yml",
    "content": "name: Quality Assurance new\n\non:\n  push:\n  pull_request:\n\njobs:\n  build-linux:\n    name: Linux (${{ matrix.platform.label }}, ${{ matrix.compiler.label }}, ${{ matrix.configure.label }})\n\n    # Ubuntu 24.04 does not provide native 32-bit (i386) installation images.\n    # Only amd64 (x86_64) is officially supported. 32-bit has been removed from this matrix.\n    runs-on: ubuntu-24.04\n\n    strategy:\n      fail-fast: false\n      matrix:\n        platform:\n          - { label: \"x64\", arch: \"amd64\", configure: \"\" }\n\n        compiler:\n          - { label: \"gcc\",   cc: \"gcc\",   cxx: \"g++\" }\n          - { label: \"clang\", cc: \"clang\", cxx: \"clang++\" }\n\n        configure:\n          - { label: \"with parser generation\", opt: \"--enable-parser-generation\" }\n          - { label: \"without curl\",    opt: \"--without-curl\" }\n          - { label: \"without lua\",     opt: \"--without-lua\" }\n          - { label: \"without maxmind\", opt: \"--without-maxmind\" }\n          - { label: \"without libxml\",  opt: \"--without-libxml\" }\n          - { label: \"without geoip\",   opt: \"--without-geoip\" }\n          - { label: \"without ssdeep\",  opt: \"--without-ssdeep\" }\n          - { label: \"with lmdb\",       opt: \"--with-lmdb\" }\n          - { label: \"with pcre2 (default)\", opt: \"\" }\n          - { label: \"with pcre\",        opt: \"--with-pcre\" }\n\n    steps:\n      - uses: actions/checkout@v6\n        with:\n          fetch-depth: 0\n          submodules: recursive\n\n      - name: Install dependencies\n        run: |\n          sudo apt-get update -y -qq\n          sudo apt-get install -y \\\n            libyajl-dev \\\n            libcurl4-openssl-dev \\\n            liblmdb-dev \\\n            liblua5.2-dev \\\n            libmaxminddb-dev \\\n            libpcre2-dev \\\n            libxml2-dev \\\n            libfuzzy-dev \\\n            pcre2-utils \\\n            libpcre3-dev \\\n            bison \\\n            flex \\\n            pkg-config\n\n\n      - name: Run build preparation script\n        run: ./build.sh\n\n      - name: Configure\n        env:\n          CC: ${{ matrix.compiler.cc }}\n          CXX: ${{ matrix.compiler.cxx }}\n        run: ./configure ${{ matrix.platform.configure }} ${{ matrix.configure.opt }} --enable-assertions=yes\n\n      - uses: ammaraskar/gcc-problem-matcher@master\n\n      - name: Compile\n        run: make -j \"$(nproc)\"\n\n      - name: Run tests\n        run: make check\n\n  build-macos:\n    name: macOS (${{ matrix.configure.label }})\n    runs-on: macos-15\n\n    strategy:\n      fail-fast: false\n      matrix:\n        configure:\n          - { label: \"with parser generation\", opt: \"--enable-parser-generation\" }\n          - { label: \"without curl\",    opt: \"--without-curl\" }\n          - { label: \"without lua\",     opt: \"--without-lua\" }\n          - { label: \"without maxmind\", opt: \"--without-maxmind\" }\n          - { label: \"without libxml\",  opt: \"--without-libxml\" }\n          - { label: \"without geoip\",   opt: \"--without-geoip\" }\n          - { label: \"without ssdeep\",  opt: \"--without-ssdeep\" }\n          - { label: \"with lmdb\",       opt: \"--with-lmdb\" }\n          - { label: \"with pcre2 (default)\", opt: \"\" }\n          - { label: \"with pcre\",       opt: \"--with-pcre\" }\n\n    steps:\n      - uses: actions/checkout@v6\n        with:\n          fetch-depth: 0\n          submodules: recursive\n          \n      - name: Install dependencies\n        # curl and pcre2 are typically already available in the macOS runner image\n        run: |\n          brew install autoconf \\\n                       automake \\\n                       libtool \\\n                       yajl \\\n                       lmdb \\\n                       lua \\\n                       libmaxminddb \\\n                       libxml2 \\\n                       ssdeep \\\n                       pcre \\\n                       bison \\\n                       flex\n\n      - name: Run build preparation script\n        run: ./build.sh\n\n      - name: Configure\n        run: ./configure ${{ matrix.configure.opt }} --enable-assertions=yes\n\n      - uses: ammaraskar/gcc-problem-matcher@master\n\n      - name: Compile\n        run: make -j \"$(sysctl -n hw.logicalcpu)\"\n\n      - name: Run tests\n        run: make check\n\n  build-windows:\n    name: Windows (${{ matrix.platform.label }}, ${{ matrix.configure.label }})\n    runs-on: windows-2025\n\n    strategy:\n      fail-fast: false\n      matrix:\n        platform:\n          - { label: \"x64\", arch: \"x86_64\" }\n        configuration: [Release]\n        configure:\n          - { label: \"full\",             opt: \"\" }\n          - { label: \"without curl\",     opt: \"-DWITH_CURL=OFF\" }\n          - { label: \"without lua\",      opt: \"-DWITH_LUA=OFF\" }\n          - { label: \"without maxmind\",  opt: \"-DWITH_MAXMIND=OFF\" }\n          - { label: \"without libxml\",   opt: \"-DWITH_LIBXML2=OFF\" }\n          - { label: \"with lmdb\",        opt: \"-DWITH_LMDB=ON\" }\n\n    steps:\n      - uses: actions/checkout@v6\n        with:\n          fetch-depth: 0\n          submodules: recursive\n\n      - name: Install Conan package manager\n        run: |\n          pip3 install conan --upgrade\n          conan profile detect\n\n      - uses: ammaraskar/msvc-problem-matcher@master\n\n      - name: Build project\n        shell: cmd\n        run: vcbuild.bat ${{ matrix.configuration }} ${{ matrix.platform.arch }} NO_ASAN \"${{ matrix.configure.opt }}\"\n\n      - name: Prepare test environment\n        working-directory: build\\win32\\build\\${{ matrix.configuration }}\n        env:\n          BASE_DIR: ..\\..\\..\\..\n        shell: cmd\n        run: |\n          copy unit_tests.exe %BASE_DIR%\\test\n          copy regression_tests.exe %BASE_DIR%\\test\n          copy libModSecurity.dll %BASE_DIR%\\test\n          copy %BASE_DIR%\\unicode.mapping %BASE_DIR%\\test\n          md \\tmp\n          md \\bin\n          copy \"C:\\Program Files\\Git\\usr\\bin\\echo.exe\" \\bin\n          copy \"C:\\Program Files\\Git\\usr\\bin\\echo.exe\" \\bin\\echo\n\n      - name: Disable unsupported tests on Windows\n        working-directory: test\\test-cases\\regression\n        shell: cmd\n        run: |\n          jq \"map(if .title == \\\"Test match variable (1/n)\\\" then .enabled = 0 else . end)\" issue-2423-msg-in-chain.json > tmp.json && move /Y tmp.json issue-2423-msg-in-chain.json\n          jq \"map(if .title == \\\"Test match variable (2/n)\\\" then .enabled = 0 else . end)\" issue-2423-msg-in-chain.json > tmp.json && move /Y tmp.json issue-2423-msg-in-chain.json\n          jq \"map(if .title == \\\"Test match variable (3/n)\\\" then .enabled = 0 else . end)\" issue-2423-msg-in-chain.json > tmp.json && move /Y tmp.json issue-2423-msg-in-chain.json\n          jq \"map(if .title == \\\"Variable offset - FILES_NAMES\\\" then .enabled = 0 else . end)\" offset-variable.json > tmp.json && move /Y tmp.json offset-variable.json\n\n      - name: Run tests\n        working-directory: build\\win32\\build\n        run: ctest -C ${{ matrix.configuration }} --output-on-failure\n\n  cppcheck:\n    name: Static analysis (cppcheck)\n    runs-on: macos-15\n\n    steps:\n      - uses: actions/checkout@v6\n        with:\n          fetch-depth: 0\n          submodules: recursive\n\n      - name: Install cppcheck\n        run: |\n          brew install autoconf automake libtool cppcheck libmaxminddb yajl lua lmdb ssdeep\n\n      - name: Configure project\n        run: |\n          ./build.sh\n          ./configure\n\n      - name: Run cppcheck\n        run: make check-static\n\n  cppcheck-linux:\n    name: Static analysis (cppcheck, Linux, debian:sid)\n    runs-on: ubuntu-latest\n    container: debian:sid\n\n    steps:\n      - name: Install basic tools\n        run: |\n          apt-get update\n          apt-get install -y git\n\n      - name: Mark repo as safe for git\n        run: git config --global --add safe.directory $GITHUB_WORKSPACE\n        \n      - uses: actions/checkout@v6\n        with:\n          fetch-depth: 0\n          submodules: recursive\n\n\n      - name: Install dependencies (v2 style)\n        run: |\n          apt-get update\n          apt-get install -y \\\n            autoconf \\\n            automake \\\n            build-essential \\\n            libtool \\\n            pkg-config \\\n            cppcheck \\\n            libyajl-dev \\\n            libcurl4-openssl-dev \\\n            liblmdb-dev \\\n            liblua5.2-dev \\\n            libmaxminddb-dev \\\n            libpcre2-dev \\\n            libxml2-dev \\\n            libfuzzy-dev \\\n            pcre2-utils \\\n            bison \\\n            flex\n\n      - name: Run build preparation script\n        run: ./build.sh\n\n      - name: Configure project\n        run: ./configure\n\n      - name: Run cppcheck\n        run: make check-static\n"
  },
  {
    "path": ".gitignore",
    "content": "*.o\n*.lo\n*.la\n**/Makefile\n**/Makefile.in\naclocal.m4\nar-lib\nautom4te.cache/\nbuild/libtool.m4\nbuild/ltoptions.m4\nbuild/ltsugar.m4\nbuild/ltversion.m4\nbuild/lt~obsolete.m4\nbuild/win32/build\nbuild/win32/CMakeUserPresets.json\ncompile\nconfig.guess\nconfig.log\nconfig.status\nconfig.sub\nconfig.h.in~\nconfigure\nconfigure~\ndepcomp\nmodsecurity.pc\n.deps\n.libs\n.dirstamp\nsrc/config.h\nsrc/config.h.in\nsrc/location.hh\nsrc/position.hh\nsrc/stack.hh\nsrc/stamp-h1\nsrc/headers.mk\n/test/rules_optimization\n/test/regression_tests\n/test/unit_tests\n/test-driver\n/test/massif.out.*\n/test/benchmark/benchmark\n/test/benchmark/owasp-v3/\n/test/test-cases/regression/*.trs\n/test/test-cases/regression/*.log\n/test-suite.log\nylwrap\nmissing\ninstall-sh\nlibtool\nltmain.sh\nexamples/simple_example_using_c/test\n/tools/rules-check/modsec-rules-check\nexamples/multiprocess_c/multi\nexamples/multithread/multithread\nexamples/reading_logs_via_rule_message/simple_request\nexamples/reading_logs_with_offset/read\nexamples/using_bodies_in_chunks/simple_request\n"
  },
  {
    "path": ".gitmodules",
    "content": "[submodule \"test/test-cases/secrules-language-tests\"]\n\tpath = test/test-cases/secrules-language-tests\n\turl = https://github.com/owasp-modsecurity/secrules-language-tests\n[submodule \"others/libinjection\"]\n\tpath = others/libinjection\n\turl = https://github.com/libinjection/libinjection.git\n[submodule \"bindings/python\"]\n\tpath = bindings/python\n\turl = https://github.com/owasp-modsecurity/ModSecurity-Python-bindings.git\n[submodule \"others/mbedtls\"]\n\tpath = others/mbedtls\n\turl = https://github.com/Mbed-TLS/mbedtls.git\n"
  },
  {
    "path": "AUTHORS",
    "content": "zimmerle = Felipe Zimmerle <felipe@zimmerle.org>\nrbarnett = Ryan C. Barnett <rcbarnett@gmail.com>\ncsanders-git = Chaim Sanders <chaim@chaimsanders.com>\nvictorhora = Victor Hora <victorminuto@gmail.com>\n"
  },
  {
    "path": "CHANGES",
    "content": "v3.0.14 - 2025-Feb-25\n---------------------\n\n  - [fix: fixed htmlEntityDecode methods]\n    [PR from private repo - @theseion,@airween; fixed CVE-2025-27110]\n  - fix: Added missing header to avoid build error with gcc-15\n    [PR #3342 - @airween]\n  - Fix for issue #3334: build not finding YAJL\n    [PR #3335 - @RooHTaylor]\n  - fix: add value checking to @validateByteRange\n    [PR #3322 - @airween]\n  - fix: build library on OSX without GeoIP brew package\n    [PR #3319 - @theseion,@airween]\n  - Update README.md\n    [PR #3314 - @ElevationsRPG]\n  - Fix: Add false positive cppcheck-suppress for compatibility with upda…\n    [PR #3307 - @gberkes]\n  - fix: align TIME_MON variable's behavior\n    [PR #3306 - @M4tteoP,@theseion,@airween]\n  - Fix m_requestHostName variable behavior\n    [PR #3298 - @airween]\n  - Add regression rules for test\n    [PR #3291 - @hnakamur]\n  - Fix modsecurity-regression-test-secremoterules.txt URL in example\n    [PR #3287 - @hnakamur]\n  - Use latest version of cppcheck (2.15.0) to analyze codebase\n    [PR #3283 - @eduar-hte]\n  - Replace usage of range-checked 'at' method when vector/string has already been size checked\n    [PR #3280 - @eduar-hte]\n  - chore: add 'log' action to rule 200005\n    [PR #3266 - @airween]\n  - docs: add a logo picture for github dark theme\n    [PR #3264 - @xuruidong]\n  - Leverage std::make_unique & std::make_shared to create objects in the heap\n    [PR #3254 - @eduar-hte]\n  - Simplified handling of RuleMessage by removing usage of std::shared_ptr\n    [PR #3253 - @eduar-hte]\n  - Simplified constructors, copy constructors & assignment operators\n    [PR #3248 - @eduar-hte]\n\nv3.0.13 - 2024-Sep-03\n---------------------\n\n  - Adjust reference to modsecurity::utils::string::VALID_HEX\n    [PR #3243 - @eduar-hte]\n  - Lua::run: Move logging of str parameter to higher log level.\n    [PR #3240 - @frozenice]\n  - Remove unnecessary heap allocated copies in Transformation actions\n    [PR #3231 - @eduar-hte]\n  - Removed multiple heap-allocated copies in Pm::init & parse_pm_content\n    [PR #3233 - @eduar-hte]\n  - Unit tests results should not be displayed in 'automake output' mode\n    [PR #3232 - @eduar-hte]\n  - Replace usage of std::ctime, which is not safe in\n    multithread contexts\n    [PR #3228 - @eduar-hte]\n  - Removed unnecessary lock to call acmp_process_quick in Pm::evaluate\n    [PR #3227 - @eduar-hte]\n  - feat: Check if the MP header contains invalid character\n    [PR #3225 - @airween]\n  - Prevent concurrent access to data in InMemoryPerProcess'\n    resolveXXX methods\n    [PR #3216 - @eduar-hte]\n  - Remove several string copies and unnecessary heap allocations\n    [PR #3222 - @eduar-hte]\n  - Creating a std::string with a null pointer\n    is undefined behaviour\n    [PR #3220 - @eduar-hte]\n  - Simplifiy configuration to build using std C++17\n    [PR #3219 - @eduar-hte]\n  - Remove unnecessary dynamic casts\n    [PR #3218 - @eduar-hte]\n  - fix: Sonarcloud reported memleak fixes\n    [PR #3114 - @airween]\n  - V3/sonarcloud replace this declaration by a structured\n    binding declaration\n    [PR #3217 - @gberkes]\n  - Do not assume ModSecurityIntervention argument to\n    transaction::intervention has been initialized/cleaned\n    [PR #3212 - @eduar-hte]\n  - Refactor: used the init-statement to declare \"pos\" inside the\n    if statement\n    [PR #3214 - @gberkes]\n  - Refactor: moved 3 #include directives to the top of the file.\n    [PR #3213 - @gberkes]\n  - Fix SecRemoteRules regression test not to depend on a\n    specific error message\n    [PR #3211 - @eduar-hte]\n  - Fixed shared files deadlock in a multi-threaded Windows application\n    [PR #3210 - @eduar-hte]\n  - Add cleanup methods to complete C based ABI\n    [PR #3209 - @eduar-hte]\n  - Build on macOS with Apple silicon (arm64)\n    [PR #3208 - @eduar-hte]\n  - remove 'this throw' call in transaction\n    [PR #3207 - @gberkes]\n  - New API function: set hostname for log\n    [PR #3203 - @airween]\n  - Fixing typo in Dockerfile\n    [PR #3189 - @bitbehz]\n  - Simplify checkout of submodules in GitHub workflows (with support for git describe)\n    [PR #3185 - @eduar-hte]\n  - Update README.md: use submodule and use benchmark tool\n    [PR #3182 - @airween]\n  - Improve performance of VariableOrigin instances\n    [PR #3164 - @eduar-hte]\n  - Update libinjection & Mbed TLS\n    [PR #3161 - @eduar-hte]\n  - chore: add PR template (v3)\n    [PR #3160 - @fzipi]\n  - Update to seclang-scanner changes introduced by Windows support\n    [PR #3146 - @eduar-hte]\n  - GitHub build & quality assurance workflow updates\n    [PR #3144 - @eduar-hte]\n  - Add link to Rust bindings in README\n    [PR #3141 - @rkrishn7]\n  - Remove cppcheck suppressions with line numbers in test/cppcheck_suppressions.txt\n    [PR #3134 - @eduar-hte]\n  - Add support to build libModSecurity v3 on Windows\n    [PR #3132 - @eduar-hte]\n  - fix: update submodule url\n    [PR #3128 - @fzipi]\n  - fix(rbl): typo in rbl check selector\n    [PR #3127 - @fzipi]\n  - fix: Changed 'equal_range()' + loop by 'find()' in resolveFirst() methods\n    [PR #3117 - @airween]\n  - Deleted redundant code in 'ModSecurity::serverLog(...)'.\n    [PR #3116 - @gberkes]\n  - doc: Update CHANGES\n    [PR #3101 - @airween]\n  - Reduce the scope of variables in a for loop\n    [PR #3098 - @devzero2000]\n  - Clean up 'return' never will be executed.\n    [PR #3096 - @gberkes]\n  - fix: Replace obsolete macros\n    [PR #3095 - @airween]\n  - fix: Change 'SecEngineStatus' to Off by default\n    [PR #3092 - @airween]\n  - chore: update bug-report-for-version-3-x.md\n    [PR #3086 - @fzipi]\n  - test: Logical, syntax and cosmetic fixes on test cases\n    [PR #3080 - @MirkoDziadzka, @airween]\n  - Bump the C++ version from C++11 to C++17\n    [PR #3079 - @MirkoDziadzka]\n  - fix: makes uri decode platform independent\n    [PR #3016 - @M4tteoP]\n\nv3.0.12 - 2024-Jan-30\n---------------------\n\n  - Change REQUEST_FILENAME and REQUEST_BASENAME behavior\n    [Issue #3048 - @martinhsv, @theMiddleBlue, @theseion, @M4tteoP, @airween]\n  - Set the minimum security protocol version for SecRemoteRules\n    [Issue security/code-scanning/2 - @airween]\n\nv3.0.11 - 2023-Dec-06\n---------------------\n\n  - Add WRDE_NOCMD to wordexp call\n    [Issue #3024 - @sahruldotid, @martinhsv]\n  - Fix: validateDTD compile fails if when libxml2 not installed\n    [Issue #3014 - @zangobot, @martinhsv]\n  - Fix memory leak of validateDTD's dtd object\n    [Issue #3008 - @martinhsv, @zimmerle]\n  - Fix memory leaks in ValidateSchema\n    [Issue #3005 - @martinhsv, @zimmerle]\n  - Add support for expirevar action\n    [Issue #1803, #3001 - @martinhsv]\n  - Fix: lmdb regex match on non-null terminated string\n    [Issue #2985 - @martinhsv]\n  - Fix memory leaks in lmdb code (new'd strings)\n    [Issue #2983 - @martinhsv]\n  - Configure: add additional name to pcre2 pkg-config list\n    [Issue #2939 - @agebhar1, @fzipi, @martinhsv]\n\nv3.0.10 - 2023-Jul-25\n---------------------\n\n  - Fix: worst-case time in implementation of four transformations\n    [Issue #2934 - @martinhsv]\n  - Add TX synonym for MSC_PCRE_LIMITS_EXCEEDED\n    [Issue #2901 - @airween]\n  - Make MULTIPART_PART_HEADERS accessible to lua\n    [Issue #2916 - @martinhsv]\n  - Fix: Lua scripts cannot read whole collection at once\n    [Issue #2900 - @udi-aharon, @airween, @martinhsv]\n  - Fix: quoted Include config with wildcard\n    [Issue #2905 - @wiseelf, @airween, @martinhsv]\n  - Support isolated PCRE match limits\n    [Issue #2736 - @brandonpayton, @martinhsv]\n  - Fix: meta actions not applied if multiMatch in first rule of chain\n    [Issue #2867, #2868 - @mlevogiannis, @martinhsv]\n  - Fix: audit log may omit tags when multiMatch\n    [Issue #2866 - @mlevogiannis]\n  - Exclude CRLF from MULTIPART_PART_HEADER value\n    [Issue #2870 - @airween, @martinhsv]\n  - Configure: use AS_ECHO_N instead echo -n\n    [Issue #2894 - @liudongmiao, @martinhsv]\n  - Adjust position of memset from 2890\n    [Issue #2891 - @mirkodziadzka-avi, @martinhsv]\n  - Add test: empty lines in ipMatchFromFile test\n    [Issue #2846 - @tomsommer]\n\n\nv3.0.9 - 2023-Apr-12\n--------------------\n\n  - Fix: possible segfault on reload if duplicate ip+CIDR in ip match list\n    [Issue #2877, #2890 - @tomsommer, @martinhsv]\n  - Add some member variable inits in Transaction class (possible segfault)\n    [Issue #2886 - @GNU-Plus-Windows-User, @airween, @mdounin, @martinhsv]\n  - Resolve memory leak on reload (bison-generated variable)\n    [Issue #2876 - @martinhsv]\n  - Support equals sign in XPath expressions\n    [Issue #2328 - @dennus, @martinhsv]\n  - Encode two special chars in error.log output\n    [Issue #2854 - @airween, @martinhsv]\n  - Add JIT support for PCRE2\n    [Issue #2791 - @wfjsw, @airween, @FireBurn, @martinhsv]\n  - Support comments in ipMatchFromFile file via '#' token\n    [Issue #2554 - @tomsommer, @martinhsv]\n  - Use name package name libmaxminddb with pkg-config\n    [Issue #2595, #2596 - @frankvanbever, @ffontaine, @arnout]\n  - Fix: FILES_TMP_CONTENT collection key should use part name\n    [Issue #2831 - @airween]\n  - Use AS_HELP_STRING instead of obsolete AC_HELP_STRING macro\n    [Issue #2806 - @hughmcmaster]\n  - During configure, do not check for pcre if pcre2 specified\n    [Issue #2750 - @dvershinin, @martinhsv]\n  - Use pkg-config to find libxml2 first\n    [Issue #2714 - @hughmcmaster]\n  - Fix two rule-reload memory leak issues\n    [Issue #2801 - @Abce, @martinhsv]\n  - Correct whitespace handling for Include directive\n    [Issue #2800 - @877509395, @martinhsv]\n\n\nv3.0.8 - 2022-Sep-07\n--------------------\n\n  - Adjust parser activation rules in modsecurity.conf-recommended\n    [Issue #2796 - @terjanq, @martinhsv]\n  - Multipart parsing fixes and new MULTIPART_PART_HEADERS collection\n    [Issue #2795 - @terjanq, @martinhsv]\n  - Prevent LMDB related segfault\n    [Issue #2755, #2761 - @dvershinin]\n  - Fix msc_transaction_cleanup function comment typo\n    [Issue #2788 - @lookat23]\n  - Fix: MULTIPART_INVALID_PART connected to wrong internal variable\n    [Issue #2785 - @martinhsv]\n  - Restore Unique_id to include random portion after timestamp\n    [Issue #2752, #2758 - @datkps11, @martinhsv]\n\nv3.0.7 - 2022-May-30\n--------------------\n\n  - Move PCRE2 match block from member variable\n    [@martinhsv]\n  - Add SecArgumentsLimit, 200007 to modsecurity.conf-recommended\n    [Issue #2738 - @jleproust, @martinhsv]\n  - Fix memory leak when concurrent log includes REMOTE_USER\n    [Issue #2727 - @liudongmiao]\n  - Fix LMDB initialization issues\n    [Issue #2688 - @ziollek, @martinhsv]\n  - Fix initcol error message wording\n    [Issue #2732 - @877509395, @martinhsv]\n  - Tolerate other parameters after boundary in multipart C-T\n    [Issue #1900 - @martinhsv]\n  - Add DebugLog message for bad pattern in rx operator\n    [Issue #2723 - @martinhsv]\n  - Support PCRE2\n    [Issue #2668 - @martinhsv]\n  - Support SecRequestBodyNoFilesLimit\n    [Issue #2670 - @airween, @martinhsv]\n  - Fix misuses of LMDB API\n    [Issue #2601, #2602 - @hyc]\n  - Fix duplication typo in code comment\n    [Issue #2677 - @gleydsonsoares]\n  - Add ctl:auditEngine action support\n    [Issue #2606 - @alekravch, @martinhsv]\n  - Fix multiMatch msg, etc, population in audit log\n    [Issue #2573 - @Sachin-M-Desai, @martinhsv]\n  - Fix some name handling for ARGS_*NAMES: regex SecRuleUpdateTargetById, etc.\n    [Issue #2627, #2648 - @lontchianicet, @victorserbu2709, @martinhsv]\n  - Adjust confusing variable name in setRequestBody method\n    [Issue #2635 - @Mesar-Ali, @martinhsv]\n  - Multipart names/filenames may include single quote if double-quote enclosed\n    [Issue #2352 - @martinhsv]\n  - Add SecRequestBodyJsonDepthLimit to modsecurity.conf-recommended\n    [Issue #2647 - @theMiddleBlue, @airween, @877509395 ,@martinhsv]\n\n\nv3.0.6 - 2021-Nov-19\n--------------------\n\n  - Support configurable limit on depth of JSON parsing\n    [@theMiddleBlue, @martinhsv]\n\nv3.0.5 - 2021-Jul-07\n--------------------\n\n  - Handle URI received with uri-fragment\n    [@martinhsv]\n  - Having ARGS_NAMES, variables proxied\n    [@zimmerle, @martinhsv, @KaNikita]\n  - Use explicit path for cross-compile environments.\n    [Issue #2485 - @dtoubelis]\n  - Fix: FILES variable does not use multipart part name for key\n    [Issue #2377 - @martinhsv]\n  - Replaces put with setenv in SetEnv action\n    [Issue #2469 - @martinhsv, @WGH-, @zimmerle]\n  - Regression: Mark the test as failed in case of segfault.\n    [@zimmerle]\n  - Regex key selection should not be case-sensitive\n    [Issue #2296, #2107, #2297 - @michaelgranzow-avi, @victorhora,\n                                 @airween, @martinhsv, @zimmerle]\n  - Fix: Only delete Multipart tmp files after rules have run\n    [Issue #2427 - @martinhsv]\n  - Fixed MatchedVar on chained rules\n    [Issue #2423, #2435, #2436 - @michaelgranzow-avi]\n  - Add support for new operator rxGlobal\n    [@martinhsv]\n  - Fix maxminddb link on FreeBSD\n    [Issue #2131 - @granalberto, @zimmerle]\n  - Fix IP address logging in Section A\n    [Issue #2300 - @inaratech, @zavazingo, @martinhsv]\n  - Adds support to lua 5.4\n    [@zimmerle]\n  - GeoIP: switch to GEOIP_MEMORY_CACHE from GEOIP_INDEX_CACHE\n    [Issues #2378, #2186 - @defanator]\n  - rx: exit after full match (remove /g emulation); ensure capture\n    groups occuring after unused groups still populate TX vars\n    [Issue #2336 - @martinhsv]\n  - Correct CHANGES file entry for #2234\n  - Add support to test framework for audit log content verification\n    and add regression tests for issues #2000, #2196\n  - Support configurable limit on number of arguments processed\n    [Issue #2234 - @jleproust, @martinhsv]\n  - Multipart Content-Dispostion should allow field: filename*=\n    [@martinhsv]\n  - Fix rule-update-target for non-regex\n    [Issue 2251 - @martinhsv]\n  - Fix configure script when packaging for Buildroot\n    [Issue 2235 - @frankvanbever]\n  - modsecurity.pc.in: add Libs.private\n    [Issue #1918, #2253 - @ffontaine, @Dridi, @victorhora]  \n\nv3.0.4 - 2020-Jan-13\n--------------------\n\n - Fix: audit log data omitted when nolog,auditlog\n   [@martinhsv]\n - Fix: ModSecurity 3.x inspectFile operator does not pass\n   FILES_TMPNAMES parameter to lua engine\n   [Issue #2204, #2205 - @kadirerdogan]\n - XML: Remove error messages from stderr\n   [Issue #2010 - @JaiHarpalani, @zimmerle]\n - Filter comment or blank line for pmFromFile operator\n   [Issue #1645 - @LeeShan87, @victorhora, @tdoubley]\n - Additional adjustment to Cookie header parsing\n   [@martinhsv]\n - Restore chained rule part H logging to be more like 2.9 behaviour\n   [Issue #2196 - @martinhsv]\n - Small fixes in log messages to help debugging the file upload\n   [Issue #2130 - @airween]\n - Fix Cookie header parsing issues\n   [Issue #2201 - @airween, @martinhsv]\n - Fix rules with nolog are logging to part H\n   [Issue #2196 - @martinhsv]\n - Fix argument key-value pair parsing cases\n   [Issue #1904 - @martinhsv]\n - Fix: audit log part for response body for JSON format to be E\n   [Issue #2066 - @martinhsv, @zimmerle]\n - Make sure m_rulesMessages is filled after successfull match\n   [Issue #2000, #2048 - @victorhora, @defanator]\n - Fix @pm lookup for possible matches on offset zero.\n   [@zimmerle, @afoxdavidi, @martinhsv, @marshal09]\n - Regex lookup on the key name instead of COLLECTION:key\n   [@rdiperri-yottaa, @danbiagini-work, @mmelo-yottaa, @zimmerle]\n - Missing throw in Operator::instantiate\n   [Issue #2106 - @marduone]\n - Making block action execution dependent of the SecEngine status\n   [Issue #2113, #2111 - @theMiddleBlue, @airween]\n - Making block action execution dependent of the SecEngine status\n   [Issue #1960 - @theMiddleBlue, @zimmerle, @airween, @victorhora]\n - Having body limits to respect the rule engine state\n   [@zimmerle]\n - Fix SecRuleUpdateTargetById does not match regular expressions\n   [Issue #1872 - @zimmerle, @anush-cr, @victorhora, @j0k2r]  \n - Adds missing check for runtime ctl:ruleRemoveByTag\n   [Issue #2102, #2099 - @airween]\n - Adds a new operator verifySVNR that checks for Austrian social\n   security numbers.\n   [Issue #2063 - @Rufus125]\n - Fix variables output in debug logs\n   [Issue #2057 - @jleproust]\n - Correct typo validade in log output\n   [Issue #2059 - @nerrehmit]\n - fix/minor: Error encoding hexa decimal.\n   [Issue #2068 - @tech-ozon-io]\n - Limit more log variables to 200 characters.\n   [Issue #2073 - @jleproust]\n - parser: fix parsed file names\n   [@zimmerle]\n - Allow empty anchored variable\n   [Issue #2024 - @airween]\n - Fixed FILES_NAMES collection after the end of multipart parsing\n   [Issue #2016 - @airween]\n - Fixed validateByteRange parsing method\n   [Issue #2017 - @airween]\n - Removes a memory leak on the JSON parser\n   [@zimmerle]\n - Enables LMDB on the regression tests.\n   [Issue #2011, #2008 - @WGH-, @mdunc]\n - Fix: Extra whitespace in some configuration directives causing error\n   [Issue #2006 - @porjo, @zimmerle]\n - Refactoring on Regex and SMatch classes.\n   [@WGH-]\n - Fixed buffer overflow in Utils::Md5::hexdigest()\n   [Issue #2002 - @defanator]\n - Implemented merge() method for ConfigInt, ConfigDouble, ConfigString\n   [Issue #1990 - @defanator]\n - Adds initially support to the drop action.\n   [@zimmerle]\n - Complete merging of particular rule properties\n   [Issue #1978 - @defanator]\n - Replaces AC_CHECK_FILE with 'test -f'\n   [Issue #1984 - @chuckwolber]\n - Fix inet addr handling on 64 bit big endian systems\n   [Issue #1980 - @airween]\n - Fix tests on FreeBSD\n   [Issue #1973 - @defanator]\n - Changes ENV test case to read the default MODSECURTIY env var\n   [Issue #1969 - @zimmerle, @airween, @inittab]\n - Regression: Sets MODSECURITY env var during the tests execution\n   [Issue #1969 - @zimmerle, @airween, @inittab]\n - Fix setenv action to strdup key=variable\n   [@zimmerle]\n - Allow 0 length JSON requests.\n   [Issue #1822 - @allanbomsft, @zimmerle, @victorhora, @marcstern]\n - Fix \"make dist\" target to include default configuration\n   [Issue #1966 - @defanator]\n - Replaced log locking using mutex with fcntl lock\n   [Issue #1949, #1927 - @Cloaked9000]\n - Correct the usage of modsecurity::Phases::NUMBER_OF_PHASES\n   [Issue #1959 - @weliu]\n - Adds support to multiple ranges in ctl:ruleRemoveById\n   [Issue #1956 - @theseion, @victorhora, @zimmerle]\n - Rule variable interpolation broken\n   [Issue #1961 - @soonum, @zimmerle] \n - Make the boundary check less strict as per RFC2046\n   [Issue #1943 - @victorhora, @allanbomsft]\n - Fix buffer size for utf8toUnicode transformation\n   [Issue #1208 - @katef, @victorhora]\n\n\nv3.0.3 - 2018-Nov-05\n--------------------\n\n - Fix double macros bug\n   [Issue #1943 - @supplient, @zimmerle]\n - Override the default status code if not suitable to redirect action\n   [Issue #1850 - @zimmerle, @victorhora]\n - parser: Fix the support for CRLF configuration files\n   [Issue #1945 - @zimmerle, @defanator, @kjakub]\n - Organizes the server logs\n   [0xb7c36 and 0x5ac20 - @zimmerle, @steven-j-wojcik]\n - m_lineNumber in Rule not mapping with the correct line number in file\n   [Issue #1844 - @zimmerle, @victorhora, @xizeng]\n - Using shared_ptr instead of unique_ptr on rules exceptions\n   [Issue #1697 - @zimmerle, @brianp9906, @victorhora, @LeSwiss, @defanator]\n - Changes debuglogs schema to avoid unecessary str allocation\n   [0xb2840 - @zimmerle]\n - Fix the SecUnicodeMapFile and SecUnicodeCodePage\n   [0x3094d - @zimmerle, @victorhora]\n - Changes the timing to save the rule message\n   [0xca270 - @zimmerle]\n - Fix crash in msc_rules_add_file() when using disruptive action in chain\n   [Issue #1849 - @victorhora, @zimmerle, @rperper]\n - Fix memory leak in AuditLog::init()\n   [Issue #1897 - @weliu]\n - Fix RulesProperties::appendRules()\n   [Issue #1901 - @steven-j-wojcik]\n - Fix RULE lookup in chained rules\n   [0x3077c - @zimmerle]\n - @ipMatch \"Could not add entry\" on slash/32 notation in 2.9.0\n   [Issue #849 - @zimmerle, @dune73]\n - Using values after transformation at MATCHED_VARS\n   [0x14316 - @zimmerle]\n - Adds support to UpdateActionById.\n   [Issue #1800 - @zimmerle, @victorhora, @NisariAIT]\n - Add correct C function prototypes for msc_init and msc_create_rule_set\n   [Issue #1922 - @steven-j-wojcik]\n - Allow LuaJIT 2.1 to be used\n   [Issue #1909 - @victorhora, @mdunc]\n - Match m_id JSON log with RuleMessage and v2 format\n   [Issue #1185 - @victorhora]\n - Adds support to setenv action.\n   [Issue #1044 - @zimmerle]\n - Adds new transaction constructor that accepts the transaction id\n   as parameter.\n   [Issue #1627 - @defanator, @zimmerle]\n - Adds request IDs and URIs to the debug log\n   [Issue #1627 - @defanator, @zimmerle]\n - Treating variables exception on load-time instead of run time.\n   [0x028e0 and 0x275a1 - @zimmerle]\n - Fix: function m.setvar in Lua scripts and add testcases\n   [Issue #1859 - @nowaits, @victorhora]\n - Fix SecResponseBodyAccess and ctl:requestBodyAccess directives\n   [Issue #1531 - @victorhora, @defanator]\n - Fix OpenBSD build\n   [Issue #1841 - @victorhora, @zimmerle, @juanfra684]\n - Fix parser to support GeoLookup with MaxMind\n   [Issue #1884, #1895 - @victorhora, @everping]\n - parser: Fix simple quote setvar in the end of the line\n   [Issue #1831 - @zimmerle, @csanders-git]\n - Fix pc file\n   [Issue #1847 - @gquintard]\n - modsec_rules_check: uses the gnu `.la' instead of `.a' file\n   [Issue #1853 - @ste7677, @victorhora, @zimmerle]\n - good practices: Initialize variables before use it\n   [Issue #1889 - Marc Stern]\n - Fix utf-8 character encoding conversion\n   [Issue #1794 - @tinselcity, @zimmerle]\n - Adds support for ctl:requestBodyProcessor=URLENCODED\n   [Issue #1797 - @victorhora]\n - Add LUA compatibility for CentOS and try to use LuaJIT first if available\n   [Issue #1622 - @victorhora, @dmitryzykov]\n - Allow LuaJIT to be used\n   [Issue #1809 - @victorhora, @p0pr0ck5]\n - Implement support for Lua 5.1\n   [Issue #1809 - @p0pr0ck5, @victorhora]\n - Variable names must match fully, not partially. Match should be case\n   insensitive.\n   [Issue #1818, #1820, #1810, #1808 - @michaelgranzow-avi, @victorhora,\n                                       @theMiddleBlue, @airween, @zimmerle,\n                                       @LeeShan87]\n - Improves the performance while loading the rules\n   [Issue #1735 - @zimmerle, @p0pr0ck5, @victorhora]\n - Allow empty strings to be evaluated by regex::searchAll\n   [Issue #1799, #1785 - @victorhora, @XuanHuyDuong, @zimmerle]\n - Adds basic pkg-config info\n   [Issue #1790 - @gquintard, @zimmerle]\n - Fixed LMDB collection errors\n   [Issue #1787 - @airween, @zimmerle]\n - Fixed false positive MULTIPART_UNMATCHED_BOUNDARY errors\n   [Issue #1747, #1924 - @airween, @victorhora, @defanator, @zimmerle]\n - Fix ip tree lookup on netmask content\n   [Issue #1793 - @tinselcity, @zimmerle]\n - Changes the behavior of the default sec actions\n   [Issue #1629 - @mirkodziadzka-avi, @zimmerle, @victorhora]\n - Refactoring on {global,ip,resources,session,tx,user} collections\n   [Issue #1754, #1778 - @LeeShan87, @zimmerle, @victorhora, @wwd5613,\n                         @sobigboy]\n - Fix race condition in UniqueId::uniqueId()\n   [Issue #1786 - @weliu]\n - Fix memory leak in error message for msc_rules_merge C APIs\n   [Issue #1765 - @weliu]\n - Return false in SharedFiles::open() when an error happens\n   [Issue #1783 - @weliu]\n - Use rvalue reference in ModSecurity::serverLog\n   [Issue #1769 - @weliu]\n - Build System: Fix when multiple lines for curl version.\n   [Issue #1771 - @Artistan]\n - Checks if response body inspection is enabled before process it\n   [Issue #1643 - @zoltan-fedor, @dennus, @defanator, @zimmerle]\n - Code Cleanup.\n   [Issue #1757, #1755, #1756, #1761 - @p0pr0ck5]\n - Fix setvar parsing of quoted data\n   [Issue #1733, #1759, #1775 - @victorhora, @JaiHarpalani, @defanator]\n - Fix LDFLAGS for unit tests.\n   [Issue #1758 - @smlx]\n - Adds time stamp back to the audit logs\n   [Issue #1762 - @Pjack, @zimmerle]\n - Disables skip counter if debug log is disabled\n   [@zimmerle]\n - Cosmetics: Represents amount of skipped rules without decimal\n   [Issue #1737 - @p0pr0ck5]\n - Add missing escapeSeqDecode, urlEncode and trimLeft/Right tfns to parser\n   [Issue #1752 - @victorhora]\n - Fix STATUS var parsing and accept STATUS_LINE var for v2 backward comp.\n   [Issue #1738 - @victorhora]\n - Fix memory leak in modsecurity::utils::expandEnv()\n   [Issue #1750 - @defanator]\n - Initialize m_dtd member in ValidateDTD class as NULL\n   [Issue #1751 - @airween]\n - Fix broken @detectxss operator regression test case\n   [Issue #1739 - @p0pr0ck5]\n - Fix utils::string::ssplit() to handle delimiter in the end of string\n   [Issue #1743, #1744 - @defanator]\n - Fix variable FILES_TMPNAMES \n   [Issue #1646, #1610 - @victorhora, @zimmerle, @defanator]\n - Fix memory leak in Collections\n   [Issue #1729, #1730 - @defanator]\n\n\nv3.0.2 - 2018-Apr-03\n--------------------\n\n - Fix lib version information while generating the .so file\n   [@gl1f1v21, @zimmerle]\n\nv3.0.1 - 2018-Apr-02\n--------------------\n\n - Adds support for ctl:ruleRemoveByTag\n   [@zimmerle, @weliu]\n - Fix SecUploadDir configuration merge\n   [Issue #1720 - @zimmerle, @gjvanetten]\n - Include all prerequisites for \"make check\" into dist archive\n   [Issue #1716 - @defanator]\n - Fix: Reverse logic of checking output in @inspectFile\n   [Issue #1715 - @defanator]\n - Adds support to libMaxMind\n   [Issue #1307 - @zimmerle, @defanator]\n - Adds capture action to detectXSS\n   [Issue #1698 - @victorhora]\n - Temporarily accept invalid MULTIPART_SEMICOLON_MISSING operator\n   [Issue #1701 - @victorhora]\n - Adds capture action to detectSQLi\n   [Issue #1698 - @zimmerle]\n - Adds capture action to rbl\n   [Issue #1698 - @zimmerle]\n - Adds capture action to verifyCC\n   [Issue #1698 - @michaelgranzow-avi, @zimmerle]\n - Adds capture action to verifySSN\n   [Issue #1698 - @zimmerle]\n - Adds capture action to verifyCPF\n   [Issue #1698 - @zimmerle]\n - Prettier error messages for unsupported configurations (UX)\n   [@victorhora]\n - Add missing verify*** transformation statements to parser\n   [Issue #1006 and #1007 - @victorhora]\n - Fix a set of compilation warnings\n   [Issue #1650 - @zimmerle, @JayCase]\n - Check for disruptive action on SecDefaultAction.\n   [Issue #1614 - @zimmerle, @michaelgranzow-avi]\n - Fix block-block infinite loop.\n   [Issue #1614 - @zimmerle, @michaelgranzow-avi]\n - Correction remove_by_tag and remove_by_msg logic.\n   [Issue #1636 - @Minasu]\n - Fix LMDB compile error\n   [Issue #1691 - @airween]\n - Fix msc_who_am_i() to return pointer to a valid C string\n   [Issue #1640 - @defanator]\n - Added some cosmetics to autoconf related code\n   [Issue #1652 - @airween]\n - Fix \"make dist\" target to include necessary headers for Lua\n   [Issue #1678 - @defanator]\n - Fix \"include /foo/*.conf\" for single matched object in directory\n   [Issue #1677 - @defanator, @zimmerle]\n - Add missing Base64 transformation statements to parser\n   [Issue #1632 - @victorhora, @zimmerle]\n - Fixed resource load on ip match from file\n   [#1674 - @zimmerle, @StefaanSeys]\n - Fixed examples compilation while using disable-shared\n   [#1670 - @zimmerle, @ivanbaldo]\n - Fixed compilation issue while xml is disabled\n   [0x243028 - @zimmerle]\n - Having LDADD and LDFLAGS organized on Makefile.am\n   [0xd0e85e - @zimmerle]\n - Checking std::deque size before use it\n   [0x217cbf - @zimmerle, Yaron Dayagi]\n - perf improvement: Added the concept of RunTimeString and removed\n   all run time parser.\n   [0x3eae51 0x0320e0 0xb5688f 0xfe47a9 0xfa9842 0x1affc3 0x079de4\n    0xc7c04f 0x5262ea 0x01974a 0xd5ee1e - @zimmerle]\n - perf improvement: Checks debuglog level before format debug msg\n   [0x42ee9 - @zimmerle]\n - perf. improvement/rx: Only compute dynamic regex in case of macro\n   [0x91ff3 - @zimmerle]\n - Fix uri on the benchmark utility\n   [0x63bec - @zimmerle]\n - disable Lua on systems with liblua5.1\n   [Issue #1639 - @victorhora, @defanator]\n\nv3.0.0 - 2017-Dec-13\n--------------------\n\n - Improvements on LUA build scripts and support for LUA 5.2.\n   [Issue #1617 and #1622 - @victorhora, @zimmerle]\n - Fix compilation error with disable_debug_log flag\n   [0xfd84e - Izik Abramov]\n - Improvements on the benchmark tool.\n   [Issue #1615 - @zimmerle]\n - Fix lua headers on the build scripts\n   [Issue #1621 - @Minasu]\n - Refactoring on the JSON parser.\n   [Issue #1576, #1577 - Tobias Gutknecht, @zimmerle, @victorhora, @marcstern]\n - Adds support to WEBAPPID variable.\n   [Issue #1027 - @zimmerle, @victorhora]\n - Adds support for SecWebAppId.\n   [Issue #1442 - @zimmerle, @victorhora] \n - Adds support for SecRuleRemoveByTag.\n   [Issue #1476 - @zimmerle, @victorhora]\n - Adds support for update target by message.\n   [Issue #1474 - @zimmerle, @victorhora]\n - Adds support to SecRuleScript directive.\n   [Issue #994 - @zimmerle]\n - Adds support for the exec action.\n   [Issue #1050 - @zimmerle]\n - Adds support for transformations inside Lua engine\n   [Issue #994 - @zimmerle]\n - Adds initial support for Lua engine.\n   [Issue #994 - @zimmerle]\n - Adds support for @inspectFile operator.\n   [Issue #999 - @zimmerle, @victorhora]\n - Adds support for RESOURCE variable collection.\n   [Issue #1014 - @zimmerle, @victorhora]\n - Adds support for @fuzzyHash operator.\n   [Issue #997 - @zimmerle]\n - Fix build on non x86 arch build\n   [Issue #1598 - @athmane]\n - Fix memory issue while changing rule target dynamic\n   [Issue #1590 - @zimmerle, @slabber]\n - Fix log while displaying the name of a dict selection by regex.\n   [@zimmerle]\n - Setting http response code on the auditlog.\n   [Issue #1592 - @zimmerle]\n - Refactoring on RuleMessage class, now accepting http code as parameter.\n   [@zimmerle]\n - Having disruptive msgs as disruptive [instead of warnings] on audit log\n   [Issue #1592 - @zimmerle, @nobodysz]\n - Parser: Pipes are no longer welcomed inside regex dict element selection.\n   [Issue #1591 - @zimmerle, @slabber]\n - Avoids unicode initialization on every rules object\n   [Issue #1563 - @zimmerle, @Tiki-God, @sethinsd, @Cloaked9000, @AnoopAlias,\n                  @intelbg]\n - Makes clear to the user whenever the audit log is empty due to missing\n   JSON support.\n   [Issue #1585 - @zimmerle]\n - Makes auditlog more verbose on debug logs\n   [Issue: #1559 - @zimmerle]\n - Enable support for AuditLogFormat\n   Issue: #1583, #1493 and #1453 - @victorhora]\n - Adds macro expansion for @rx operator\n   [Issue: #1528, #1536 - @asterite3, @zimmerle]\n - Consideres under quoted variable while loading the rules.\n   [Felipe Zimmerle/@zimmerle, Victor Hora/@victorhora]\n - Store the connection and url parameters in std::string\n   [Issue: #1571 - @majordaw]\n - Eliminate some reorder and sign warnings\n   [Issue: #1572 - Dávid Major/@majordaw]\n - Makes parallel logging to work when SELinux is enabled.\n   [Issue: #1562 - David Buckle/@met3or]\n - Adds possibility to run the pm operator inside a mutex to avoid concurrent\n   access while working on a thread environment. This option is a compilation\n   flag.\n   [Felipe Zimmerle/@zimmerle]\n\n\nv3.0.0-rc1 - 2017-Aug-28\n------------------------\n\n Very first public version.\n\n"
  },
  {
    "path": "LICENSE",
    "content": "                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n"
  },
  {
    "path": "Makefile.am",
    "content": "\nif TEST_UTILITIES\nexport MAYBE_TEST = test\nendif\n\nif EXAMPLES\nexport MAYBE_EXAMPLES = examples\nendif\n\n\nSUBDIRS = \\\n\tothers \\\n\tsrc \\\n\tdoc \\\n\ttools \\\n\t$(MAYBE_EXAMPLES) \\\n\t$(MAYBE_TEST)\n\n\n\n# make clean\nCLEANFILES = \n\nACLOCAL_AMFLAGS = -I build\n\n# make maintainer-clean\nMAINTAINERCLEANFILES = \\\n\taclocal.m4 \\\n\tar-lib \\\n\tbuild/libtool.m4 \\\n\tbuild/lt~obsolete.m4 \\\n\tbuild/ltoptions.m4 \\\n\tbuild/ltsugar.m4 \\\n\tbuild/ltversion.m4 \\\n\tcoding-style.txt \\\n\tcompile \\\n\tconfig.guess \\\n\tconfig.sub \\\n\tconfigure \\\n\tcppcheck.txt \\\n\tdepcomp \\\n\tinstall-sh \\\n\tltmain.sh \\\n\tMakefile.in \\\n\tmissing \\\n\ttest/modsec-shared-collections \\\n\ttest/modsec-shared-collections-lock \\\n\ttest-suite-drd.log \\\n\ttest-suite-helgrind.log \\\n\ttest-suite-memcheck.log \\\n\tylwrap\n\nparser:\n\tcat src/parser/seclang-parser.hh | sed \"s/return \\*new (yyas_<T> ()) T (t)/return *new (yyas_<T> ()) T (std::move((T\\&)t))/g\"  > src/parser/seclang-parser.hh.fix && mv src/parser/seclang-parser.hh.fix src/parser/seclang-parser.hh\n\n\n\ncppcheck:\n\t@cppcheck -U YYSTYPE -U MBEDTLS_MD5_ALT -U MBEDTLS_SHA1_ALT \\\n\t\t-D MS_CPPCHECK_DISABLED_FOR_PARSER -U YY_USER_INIT \\\n\t\t--suppressions-list=./test/cppcheck_suppressions.txt \\\n\t\t--inline-suppr \\\n\t\t--enable=warning,style,performance,portability,unusedFunction,missingInclude \\\n\t\t--inconclusive \\\n\t\t--template=\"warning: {file},{line},{severity},{id},{message}\" \\\n\t\t-I headers -I . -I $(top_srcdir)/others -I $(top_srcdir)/src -I $(top_srcdir)/others/mbedtls/include \\\n\t\t--error-exitcode=1 \\\n\t\t-i \"src/parser/seclang-parser.cc\" -i \"src/parser/seclang-scanner.cc\" \\\n\t\t-i others \\\n\t\t--std=c++17 \\\n\t\t--force --verbose .\n\n\ncheck-static: cppcheck\n\ncheck-style: check-coding-style\n\ncheck-coding-style:\n\t@cpplint.py \\\n\t\t$$(find . -name \"*.h\" -o -name \"*.cc\" | xargs) 2>&1 \\\n \t\t| egrep -v $$(echo -n \"catchall\" ; \\\n\t  \t\tfor i in $$(cat test/coding_style_suppressions.txt); do echo -n \"|\"$$i; done) \\\n\t\t| sed 's/^\\./warning: ./g' > coding-style.txt\n\t-cat coding-style.txt\n\n\n@VALGRIND_CHECK_RULES@\nVALGRIND_SUPPRESSIONS_FILES = valgrind_suppressions.txt\n\nLOG_DRIVER = env $(SHELL) $(top_srcdir)/test/custom-test-driver\nAM_TESTS_ENVIRONMENT=AUTOMAKE_TESTS=true; export AUTOMAKE_TESTS;\nLOG_COMPILER=test/test-suite.sh\n\nTESTS=\ninclude test/test-suite.in\n\npkgconfigdir = $(libdir)/pkgconfig\npkgconfig_DATA = modsecurity.pc\nEXTRA_DIST = modsecurity.pc.in \\\n             modsecurity.conf-recommended \\\n             unicode.mapping\n\n"
  },
  {
    "path": "README.md",
    "content": "\n<picture>\n  <source media=\"(prefers-color-scheme: dark)\" srcset=\"./others/modsec_white_bg.png\">\n  <source media=\"(prefers-color-scheme: light)\" srcset=\"./others/modsec.png\">\n  <img src=\"./others/modsec.png\" width=\"50%\">\n</picture>\n\n![Quality Assurance](https://github.com/owasp-modsecurity/ModSecurity/workflows/Quality%20Assurance/badge.svg)\n[![Build Status](https://sonarcloud.io/api/project_badges/measure?project=owasp-modsecurity_ModSecurity&metric=alert_status)](https://sonarcloud.io/dashboard?id=owasp-modsecurity_ModSecurity)\n[![](https://sonarcloud.io/api/project_badges/measure?project=owasp-modsecurity_ModSecurity&metric=sqale_rating\n)](https://sonarcloud.io/dashboard?id=owasp-modsecurity_ModSecurity)\n[![](https://sonarcloud.io/api/project_badges/measure?project=owasp-modsecurity_ModSecurity&metric=reliability_rating\n)](https://sonarcloud.io/dashboard?id=owasp-modsecurity_ModSecurity)\n[![](https://sonarcloud.io/api/project_badges/measure?project=owasp-modsecurity_ModSecurity&metric=security_rating\n)](https://sonarcloud.io/dashboard?id=owasp-modsecurity_ModSecurity)\n[![](https://sonarcloud.io/api/project_badges/measure?project=owasp-modsecurity_ModSecurity&metric=vulnerabilities\n)](https://sonarcloud.io/dashboard?id=owasp-modsecurity_ModSecurity)\n\n\n\nLibmodsecurity is one component of the ModSecurity v3 project. The library\ncodebase serves as an interface to ModSecurity Connectors taking in web traffic\nand applying traditional ModSecurity processing. In general, it provides the\ncapability to load/interpret rules written in the ModSecurity SecRules format\nand apply them to HTTP content provided by your application via Connectors.\n\nIf you are looking for ModSecurity for Apache (aka ModSecurity v2.x), it is still under maintenance and available:\n[here](https://github.com/owasp-modsecurity/ModSecurity/tree/v2/master).\n\n### What is the difference between this project and the old ModSecurity (v2.x.x)?\n\n* All Apache dependencies have been removed\n* Higher performance\n* New features\n* New architecture\n\nLibmodsecurity is a complete rewrite of the ModSecurity platform. When it was first devised the ModSecurity project started as just an Apache module. Over time the project has been extended, due to popular demand, to support other platforms including (but not limited to) Nginx and IIS. In order to provide for the growing demand for additional platform support, it has became necessary to remove the Apache dependencies underlying this project, making it more platform independent.\n\nAs a result of this goal we have rearchitected Libmodsecurity such that it is no longer dependent on the Apache web server (both at compilation and during runtime). One side effect of this is that across all platforms users can expect increased performance. Additionally, we have taken this opportunity to lay the groundwork for some new features that users have been long seeking. For example we are looking to natively support auditlogs in the JSON format, along with a host of other functionality in future versions.\n\n\n### It is no longer just a module.\n\nThe 'ModSecurity' branch no longer contains the traditional module logic (for Nginx, Apache, and IIS) that has traditionally been packaged all together. Instead, this branch only contains the library portion (libmodsecurity) for this project. This library is consumed by what we have termed 'Connectors' these connectors will interface with your webserver and provide the library with a common format that it understands. Each of these connectors is maintained as a separate GitHub project. For instance, the Nginx connector is supplied by the ModSecurity-nginx project (https://github.com/owasp-modsecurity/ModSecurity-nginx).\n\nKeeping these connectors separated allows each project to have different release cycles, issues and development trees. Additionally, it means that when you install ModSecurity v3 you only get exactly what you need, no extras you won't be using.\n\n# Compilation\n\nBefore starting the compilation process, make sure that you have all the\ndependencies in place. Read the subsection “Dependencies”  for further\ninformation.\n\nAfter the compilation make sure that there are no issues on your\nbuild/platform. We strongly recommend the utilization of the unit tests and\nregression tests. These test utilities are located under the subfolder ‘tests’.\n\nAs a dynamic library, don’t forget that libmodsecurity must be installed to a location (folder) where you OS will be looking for dynamic libraries.\n\n\n\n### Unix (Linux, MacOS, FreeBSD, …)\n\nOn unix the project uses autotools to help the compilation process. Please note that if you are working with `git`, don't forget to initialize and update the submodules. Here's a quick how-to:\n```shell\n$ git clone --recursive https://github.com/owasp-modsecurity/ModSecurity ModSecurity\n$ cd ModSecurity\n```\n\nYou can then start the build process:\n\n```shell\n$ ./build.sh\n$ ./configure\n$ make\n$ sudo make install\n```\n\nDetails on distribution specific builds can be found in our Wiki:\n[Compilation Recipes](https://github.com/owasp-modsecurity/ModSecurity/wiki/Compilation-recipes)\n\n### Windows\n\nWindows build information can be found [here](build/win32/README.md).\n\n## Dependencies\n\nThis library is written in C++ using the C++17 standards. It also uses Flex\nand Yacc to produce the “Sec Rules Language” parser. Other, mandatory dependencies include YAJL, as ModSecurity uses JSON for producing logs and its testing framework, libpcre (not yet mandatory) for processing regular expressions in SecRules, and libXML2 (not yet mandatory) which is used for parsing XML requests.\n\nAll others dependencies are related to operators specified within SecRules or configuration directives and may not be required for compilation. A short list of such dependencies is as follows:\n\n* libinjection is needed for the operator @detectXSS and @detectSQL\n* curl is needed for the directive SecRemoteRules.\n\nIf those libraries are missing ModSecurity will be compiled without the support for the operator @detectXSS and the configuration directive SecRemoteRules.\n\n# Library documentation\n\nThe library documentation is written within the code in Doxygen format. To generate this documentation, please use the doxygen utility with the provided configuration file, “doxygen.cfg”, located with the \"doc/\" subfolder. This will generate HTML formatted documentation including usage examples.\n\n# Library utilization\n\nThe library provides a C++ and C interface. Some resources are currently only\navailable via the C++ interface, for instance, the capability to create custom logging\nmechanism (see the regression test to check for how those logging mechanism works).\nThe objective is to have both APIs (C, C++) providing the same functionality,\nif you find an aspect of the API that is missing via a particular interface, please open an issue.\n\nInside the subfolder examples, there are simple examples on how to use the API.\nBelow some are illustrated:\n\n###  Simple example using C++\n\n```c++\nusing ModSecurity::ModSecurity;\nusing ModSecurity::Rules;\nusing ModSecurity::Transaction;\n\nModSecurity *modsec;\nModSecurity::Rules *rules;\n\nmodsec = new ModSecurity();\n\nrules = new Rules();\n\nrules->loadFromUri(rules_file);\n\nTransaction *modsecTransaction = new Transaction(modsec, rules);\n\nmodsecTransaction->processConnection(\"127.0.0.1\");\nif (modsecTransaction->intervention()) {\n   std::cout << \"There is an intervention\" << std::endl;\n}\n```\n\n### Simple example using C\n\n```c\n#include \"modsecurity/modsecurity.h\"\n#include \"modsecurity/transaction.h\"\n\n\nchar main_rule_uri[] = \"basic_rules.conf\";\n\nint main (int argc, char **argv)\n{\n    ModSecurity *modsec = NULL;\n    Transaction *transaction = NULL;\n    Rules *rules = NULL;\n\n    modsec = msc_init();\n\n    rules = msc_create_rules_set();\n    msc_rules_add_file(rules, main_rule_uri);\n\n    transaction = msc_new_transaction(modsec, rules);\n\n    msc_process_connection(transaction, \"127.0.0.1\");\n    msc_process_uri(transaction, \"http://www.modsecurity.org/test?key1=value1&key2=value2&key3=value3&test=args&test=test\");\n    msc_process_request_headers(transaction);\n    msc_process_request_body(transaction);\n    msc_process_response_headers(transaction);\n    msc_process_response_body(transaction);\n\n    return 0;\n}\n\n```\n\n# Contributing\n\nYou are more than welcome to contribute to this project and look forward to growing the community around this new version of ModSecurity. Areas of interest include: New\nfunctionalities, fixes, bug report, support for beginning users, or anything that you\nare willing to help with.\n\n## Providing patches\n\nWe prefer to have your patch within the GitHub infrastructure to facilitate our\nreview work, and our Q.A. integration. GitHub provides excellent\ndocumentation on how to perform “Pull Requests”, more information available\nhere: https://help.github.com/articles/using-pull-requests/\n\nPlease respect the coding style. Pull requests can include various commits, so\nprovide one fix or one piece of functionality per commit. Please do not change anything outside\nthe scope of your target work (e.g. coding style in a function that you have\npassed by). For further information about the coding style used in this\nproject, please check: https://www.chromium.org/blink/coding-style\n\nProvides explanative commit messages. Your first line should  give the highlights of your\npatch, 3rd and on give a more detailed explanation/technical details about your\npatch. Patch explanation is valuable during the review process.\n\n### Don’t know where to start?\n\nWithin our code there are various items marked as TODO or FIXME that may need\nyour attention. Check the list of items by performing a grep:\n\n```\n$ cd /path/to/modsecurity-nginx\n$ egrep -Rin \"TODO|FIXME\" -R *\n```\n\nA TODO list is also available as part of the Doxygen documentation.\n\n### Testing your patch\n\nAlong with the manual testing, we strongly recommend you to use the our\nregression tests and unit tests. If you have implemented an operator, don’t\nforget to create unit tests for it. If you implement anything else, it is encouraged that you develop complimentary regression tests for it.\n\nThe regression test and unit test utilities are native and do not demand any\nexternal tool or script, although you need to fetch the test cases from other\nrepositories, as they are shared with other versions of ModSecurity, those\nothers repositories git submodules. To fetch the submodules repository and run\nthe utilities, follow the commands listed below:\n\n```shell\n$ cd /path/to/your/ModSecurity\n$ git submodule update --init --recursive\n$ make check\n ```\n\n### Debugging\n\n\nBefore start the debugging process, make sure of where your bug is. The problem\ncould be on your connector or in libmodsecurity. In order to identify where the\nbug is, it is recommended that you develop a regression test that mimics the\nscenario where the bug is happening. If the bug is reproducible with the\nregression-test utility, then it will be far simpler to debug and ensure that it never occurs again. On Linux it is\nrecommended that anyone undertaking debugging utilize gdb and/or valgrind as needed.\n\nDuring the configuration/compilation time, you may want to disable the compiler\noptimization making your “back traces” populated with readable data. Use the\nCFLAGS to disable the compilation optimization parameters:\n\n```shell\n$ export CFLAGS=\"-g -O0\"\n$ ./build.sh\n$ ./configure --enable-assertions=yes\n$ make\n$ sudo make install\n```\n\"Assertions allow us to document assumptions and to spot violations early in the\ndevelopment process. What is more, assertions allow us to spot violations with a\nminimum of effort.\" https://dl.acm.org/doi/pdf/10.1145/240964.240969\n\nIt is recommended to use assertions where applicable, and to enable them with\n'--enable-assertions=yes' during the testing and debugging workflow.\n\n### Benchmarking\n\nThe source tree includes a Benchmark tool that can help measure library performance. The tool is located in the `test/benchmark/` directory. The build process also creates the binary here, so you will have the tool after the compilation is finished.\n\nTo run, just type:\n\n```shell\ncd test/benchmark\n$ ./benchmark\nDoing 1000000 transactions...\n\n```\n\nYou can also pass a lower value:\n\n```shell\n$ ./benchmark 1000\nDoing 1000 transactions...\n```\n\nTo measure the time:\n```shell\n$ time ./benchmark 1000\nDoing 1000 transactions...\n\nreal\t0m0.351s\nuser\t0m0.337s\nsys\t0m0.022s\n```\n\nThis is very fast because the benchmark uses the minimal `modsecurity.conf.default` configuration, which doesn't include too many rules:\n\n```shell\n$ cat basic_rules.conf\n\nInclude \"../../modsecurity.conf-recommended\"\n\n```\n\nTo measure with real rules, run one of the download scripts in the same directory:\n\n```shell\n$ ./download-owasp-v3-rules.sh\nCloning into 'owasp-v3'...\nremote: Enumerating objects: 33007, done.\nremote: Counting objects: 100% (2581/2581), done.\nremote: Compressing objects: 100% (907/907), done.\nremote: Total 33007 (delta 2151), reused 2004 (delta 1638), pack-reused 30426\nReceiving objects: 100% (33007/33007), 9.02 MiB | 16.21 MiB/s, done.\nResolving deltas: 100% (25927/25927), done.\nSwitched to a new branch 'tag3.0.2'\n/path/to/ModSecurity/test/benchmark\nDone.\n\n$ cat basic_rules.conf\n\nInclude \"../../modsecurity.conf-recommended\"\n\nInclude \"owasp-v3/crs-setup.conf.example\"\nInclude \"owasp-v3/rules/*.conf\"\n```\n\nNow the command will give much higher value.\n\n#### How the benchmark works\n\nThe tool is a straightforward wrapper application that utilizes the library. It creates a ModSecurity instance and a RuleSet instance, then runs a loop based on the specified number. Within this loop, it creates a Transaction object to emulate real HTTP transactions.\n\nEach transaction is an HTTP/1.1 GET request with some GET parameters. Common headers are added, followed by the response headers and an XML body. Between phases, the tool checks whether an intervention has occurred. All transactions are created with the same data.\n\nNote that the tool does not call the last phase (logging).\n\nPlease remember to reset `basic_rules.conf` if you want to try with a different ruleset.\n\n## Reporting Issues\n\nIf you are facing a configuration issue or something is not working as you\nexpected to be, please use the ModSecurity user’s mailing list. Issues on GitHub\nare also welcomed, but we prefer to have user ask questions on the mailing list first so that you can reach an entire community. Also don’t forget to look for existing issues before open a new one.\n\nIf you are going to open a new issue on GitHub, don’t forget to tell us the\nversion of your libmodsecurity and the version of a specific connector if there\nis one.\n\n\n### Security issue\n\nPlease do not make public any security issue. Contact us at:\nmodsecurity@owasp.org reporting the issue. Once the problem is fixed your\ncredit will be given.\n\n## Feature request\n\nWe are open to discussing any new feature request with the community via the mailing lists. You can alternativly,\nfeel free to open GitHub issues requesting new features. Before opening a\nnew issue, please check if there is one already opened on the same topic.\n\n## Bindings\n\nThe libModSecurity design allows the integration with bindings. There is an effort to avoid breaking API [binary] compatibility to make an easy integration with possible bindings. Currently, there are a few notable projects maintained by the community:\n   * Python - https://github.com/actions-security/pymodsecurity\n   * Rust - https://github.com/rkrishn7/rust-modsecurity\n   * Varnish - https://github.com/xdecock/vmod-modsecurity\n\n## Packaging\n\nHaving our packages in distros on time is a desire that we have, so let us know\nif there is anything we can do to facilitate your work as a packager.\n\n## Sponsor Note\n\nDevelopment of ModSecurity is sponsored by Trustwave. Sponsorship will end July 1, 2024. Additional information can be found here https://www.trustwave.com/en-us/resources/security-resources/software-updates/end-of-sale-and-trustwave-support-for-modsecurity-web-application-firewall/\n"
  },
  {
    "path": "SECURITY.md",
    "content": "# Security Policy\n\n## Supported Versions\n\nThe latest versions of both v2.9.x and v3.0.x are supported.\n\n## Reporting a Vulnerability\n\nFor information on how to report a security issue, please see https://github.com/owasp-modsecurity/ModSecurity#security-issue\n"
  },
  {
    "path": "build/.empty",
    "content": ""
  },
  {
    "path": "build/ax_cxx_compile_stdcxx.m4",
    "content": "# ===========================================================================\n#  https://www.gnu.org/software/autoconf-archive/ax_cxx_compile_stdcxx.html\n# ===========================================================================\n#\n# SYNOPSIS\n#\n#   AX_CXX_COMPILE_STDCXX(VERSION, [ext|noext], [mandatory|optional])\n#\n# DESCRIPTION\n#\n#   Check for baseline language coverage in the compiler for the specified\n#   version of the C++ standard.  If necessary, add switches to CXX and\n#   CXXCPP to enable support.  VERSION may be '11', '14', '17', or '20' for\n#   the respective C++ standard version.\n#\n#   The second argument, if specified, indicates whether you insist on an\n#   extended mode (e.g. -std=gnu++11) or a strict conformance mode (e.g.\n#   -std=c++11).  If neither is specified, you get whatever works, with\n#   preference for no added switch, and then for an extended mode.\n#\n#   The third argument, if specified 'mandatory' or if left unspecified,\n#   indicates that baseline support for the specified C++ standard is\n#   required and that the macro should error out if no mode with that\n#   support is found.  If specified 'optional', then configuration proceeds\n#   regardless, after defining HAVE_CXX${VERSION} if and only if a\n#   supporting mode is found.\n#\n# LICENSE\n#\n#   Copyright (c) 2008 Benjamin Kosnik <bkoz@redhat.com>\n#   Copyright (c) 2012 Zack Weinberg <zackw@panix.com>\n#   Copyright (c) 2013 Roy Stogner <roystgnr@ices.utexas.edu>\n#   Copyright (c) 2014, 2015 Google Inc.; contributed by Alexey Sokolov <sokolov@google.com>\n#   Copyright (c) 2015 Paul Norman <penorman@mac.com>\n#   Copyright (c) 2015 Moritz Klammler <moritz@klammler.eu>\n#   Copyright (c) 2016, 2018 Krzesimir Nowak <qdlacz@gmail.com>\n#   Copyright (c) 2019 Enji Cooper <yaneurabeya@gmail.com>\n#   Copyright (c) 2020 Jason Merrill <jason@redhat.com>\n#   Copyright (c) 2021 Jörn Heusipp <osmanx@problemloesungsmaschine.de>\n#\n#   Copying and distribution of this file, with or without modification, are\n#   permitted in any medium without royalty provided the copyright notice\n#   and this notice are preserved.  This file is offered as-is, without any\n#   warranty.\n\n#serial 18\n\ndnl  This macro is based on the code from the AX_CXX_COMPILE_STDCXX_11 macro\ndnl  (serial version number 13).\n\nAC_DEFUN([AX_CXX_COMPILE_STDCXX], [dnl\n  m4_if([$1], [11], [ax_cxx_compile_alternatives=\"11 0x\"],\n        [$1], [14], [ax_cxx_compile_alternatives=\"14 1y\"],\n        [$1], [17], [ax_cxx_compile_alternatives=\"17 1z\"],\n        [$1], [20], [ax_cxx_compile_alternatives=\"20\"],\n        [m4_fatal([invalid first argument `$1' to AX_CXX_COMPILE_STDCXX])])dnl\n  m4_if([$2], [], [],\n        [$2], [ext], [],\n        [$2], [noext], [],\n        [m4_fatal([invalid second argument `$2' to AX_CXX_COMPILE_STDCXX])])dnl\n  m4_if([$3], [], [ax_cxx_compile_cxx$1_required=true],\n        [$3], [mandatory], [ax_cxx_compile_cxx$1_required=true],\n        [$3], [optional], [ax_cxx_compile_cxx$1_required=false],\n        [m4_fatal([invalid third argument `$3' to AX_CXX_COMPILE_STDCXX])])\n  AC_LANG_PUSH([C++])dnl\n  ac_success=no\n\n  m4_if([$2], [], [dnl\n    AC_CACHE_CHECK(whether $CXX supports C++$1 features by default,\n\t\t   ax_cv_cxx_compile_cxx$1,\n      [AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])],\n        [ax_cv_cxx_compile_cxx$1=yes],\n        [ax_cv_cxx_compile_cxx$1=no])])\n    if test x$ax_cv_cxx_compile_cxx$1 = xyes; then\n      ac_success=yes\n    fi])\n\n  m4_if([$2], [noext], [], [dnl\n  if test x$ac_success = xno; then\n    for alternative in ${ax_cxx_compile_alternatives}; do\n      switch=\"-std=gnu++${alternative}\"\n      cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx$1_$switch])\n      AC_CACHE_CHECK(whether $CXX supports C++$1 features with $switch,\n                     $cachevar,\n        [ac_save_CXX=\"$CXX\"\n         CXX=\"$CXX $switch\"\n         AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])],\n          [eval $cachevar=yes],\n          [eval $cachevar=no])\n         CXX=\"$ac_save_CXX\"])\n      if eval test x\\$$cachevar = xyes; then\n        CXX=\"$CXX $switch\"\n        if test -n \"$CXXCPP\" ; then\n          CXXCPP=\"$CXXCPP $switch\"\n        fi\n        ac_success=yes\n        break\n      fi\n    done\n  fi])\n\n  m4_if([$2], [ext], [], [dnl\n  if test x$ac_success = xno; then\n    dnl HP's aCC needs +std=c++11 according to:\n    dnl http://h21007.www2.hp.com/portal/download/files/unprot/aCxx/PDF_Release_Notes/769149-001.pdf\n    dnl Cray's crayCC needs \"-h std=c++11\"\n    dnl MSVC needs -std:c++NN for C++17 and later (default is C++14)\n    for alternative in ${ax_cxx_compile_alternatives}; do\n      for switch in -std=c++${alternative} +std=c++${alternative} \"-h std=c++${alternative}\" MSVC; do\n        if test x\"$switch\" = xMSVC; then\n          dnl AS_TR_SH maps both `:` and `=` to `_` so -std:c++17 would collide\n          dnl with -std=c++17.  We suffix the cache variable name with _MSVC to\n          dnl avoid this.\n          switch=-std:c++${alternative}\n          cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx$1_${switch}_MSVC])\n        else\n          cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx$1_$switch])\n        fi\n        AC_CACHE_CHECK(whether $CXX supports C++$1 features with $switch,\n                       $cachevar,\n          [ac_save_CXX=\"$CXX\"\n           CXX=\"$CXX $switch\"\n           AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])],\n            [eval $cachevar=yes],\n            [eval $cachevar=no])\n           CXX=\"$ac_save_CXX\"])\n        if eval test x\\$$cachevar = xyes; then\n          CXX=\"$CXX $switch\"\n          if test -n \"$CXXCPP\" ; then\n            CXXCPP=\"$CXXCPP $switch\"\n          fi\n          ac_success=yes\n          break\n        fi\n      done\n      if test x$ac_success = xyes; then\n        break\n      fi\n    done\n  fi])\n  AC_LANG_POP([C++])\n  if test x$ax_cxx_compile_cxx$1_required = xtrue; then\n    if test x$ac_success = xno; then\n      AC_MSG_ERROR([*** A compiler with support for C++$1 language features is required.])\n    fi\n  fi\n  if test x$ac_success = xno; then\n    HAVE_CXX$1=0\n    AC_MSG_NOTICE([No compiler with C++$1 support was found])\n  else\n    HAVE_CXX$1=1\n    AC_DEFINE(HAVE_CXX$1,1,\n              [define if the compiler supports basic C++$1 syntax])\n  fi\n  AC_SUBST(HAVE_CXX$1)\n])\n\n\ndnl  Test body for checking C++11 support\n\nm4_define([_AX_CXX_COMPILE_STDCXX_testbody_11],\n  _AX_CXX_COMPILE_STDCXX_testbody_new_in_11\n)\n\ndnl  Test body for checking C++14 support\n\nm4_define([_AX_CXX_COMPILE_STDCXX_testbody_14],\n  _AX_CXX_COMPILE_STDCXX_testbody_new_in_11\n  _AX_CXX_COMPILE_STDCXX_testbody_new_in_14\n)\n\ndnl  Test body for checking C++17 support\n\nm4_define([_AX_CXX_COMPILE_STDCXX_testbody_17],\n  _AX_CXX_COMPILE_STDCXX_testbody_new_in_11\n  _AX_CXX_COMPILE_STDCXX_testbody_new_in_14\n  _AX_CXX_COMPILE_STDCXX_testbody_new_in_17\n)\n\ndnl  Test body for checking C++20 support\n\nm4_define([_AX_CXX_COMPILE_STDCXX_testbody_20],\n  _AX_CXX_COMPILE_STDCXX_testbody_new_in_11\n  _AX_CXX_COMPILE_STDCXX_testbody_new_in_14\n  _AX_CXX_COMPILE_STDCXX_testbody_new_in_17\n  _AX_CXX_COMPILE_STDCXX_testbody_new_in_20\n)\n\n\ndnl  Tests for new features in C++11\n\nm4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_11], [[\n\n// If the compiler admits that it is not ready for C++11, why torture it?\n// Hopefully, this will speed up the test.\n\n#ifndef __cplusplus\n\n#error \"This is not a C++ compiler\"\n\n// MSVC always sets __cplusplus to 199711L in older versions; newer versions\n// only set it correctly if /Zc:__cplusplus is specified as well as a\n// /std:c++NN switch:\n// https://devblogs.microsoft.com/cppblog/msvc-now-correctly-reports-__cplusplus/\n#elif __cplusplus < 201103L && !defined _MSC_VER\n\n#error \"This is not a C++11 compiler\"\n\n#else\n\nnamespace cxx11\n{\n\n  namespace test_static_assert\n  {\n\n    template <typename T>\n    struct check\n    {\n      static_assert(sizeof(int) <= sizeof(T), \"not big enough\");\n    };\n\n  }\n\n  namespace test_final_override\n  {\n\n    struct Base\n    {\n      virtual ~Base() {}\n      virtual void f() {}\n    };\n\n    struct Derived : public Base\n    {\n      virtual ~Derived() override {}\n      virtual void f() override {}\n    };\n\n  }\n\n  namespace test_double_right_angle_brackets\n  {\n\n    template < typename T >\n    struct check {};\n\n    typedef check<void> single_type;\n    typedef check<check<void>> double_type;\n    typedef check<check<check<void>>> triple_type;\n    typedef check<check<check<check<void>>>> quadruple_type;\n\n  }\n\n  namespace test_decltype\n  {\n\n    int\n    f()\n    {\n      int a = 1;\n      decltype(a) b = 2;\n      return a + b;\n    }\n\n  }\n\n  namespace test_type_deduction\n  {\n\n    template < typename T1, typename T2 >\n    struct is_same\n    {\n      static const bool value = false;\n    };\n\n    template < typename T >\n    struct is_same<T, T>\n    {\n      static const bool value = true;\n    };\n\n    template < typename T1, typename T2 >\n    auto\n    add(T1 a1, T2 a2) -> decltype(a1 + a2)\n    {\n      return a1 + a2;\n    }\n\n    int\n    test(const int c, volatile int v)\n    {\n      static_assert(is_same<int, decltype(0)>::value == true, \"\");\n      static_assert(is_same<int, decltype(c)>::value == false, \"\");\n      static_assert(is_same<int, decltype(v)>::value == false, \"\");\n      auto ac = c;\n      auto av = v;\n      auto sumi = ac + av + 'x';\n      auto sumf = ac + av + 1.0;\n      static_assert(is_same<int, decltype(ac)>::value == true, \"\");\n      static_assert(is_same<int, decltype(av)>::value == true, \"\");\n      static_assert(is_same<int, decltype(sumi)>::value == true, \"\");\n      static_assert(is_same<int, decltype(sumf)>::value == false, \"\");\n      static_assert(is_same<int, decltype(add(c, v))>::value == true, \"\");\n      return (sumf > 0.0) ? sumi : add(c, v);\n    }\n\n  }\n\n  namespace test_noexcept\n  {\n\n    int f() { return 0; }\n    int g() noexcept { return 0; }\n\n    static_assert(noexcept(f()) == false, \"\");\n    static_assert(noexcept(g()) == true, \"\");\n\n  }\n\n  namespace test_constexpr\n  {\n\n    template < typename CharT >\n    unsigned long constexpr\n    strlen_c_r(const CharT *const s, const unsigned long acc) noexcept\n    {\n      return *s ? strlen_c_r(s + 1, acc + 1) : acc;\n    }\n\n    template < typename CharT >\n    unsigned long constexpr\n    strlen_c(const CharT *const s) noexcept\n    {\n      return strlen_c_r(s, 0UL);\n    }\n\n    static_assert(strlen_c(\"\") == 0UL, \"\");\n    static_assert(strlen_c(\"1\") == 1UL, \"\");\n    static_assert(strlen_c(\"example\") == 7UL, \"\");\n    static_assert(strlen_c(\"another\\0example\") == 7UL, \"\");\n\n  }\n\n  namespace test_rvalue_references\n  {\n\n    template < int N >\n    struct answer\n    {\n      static constexpr int value = N;\n    };\n\n    answer<1> f(int&)       { return answer<1>(); }\n    answer<2> f(const int&) { return answer<2>(); }\n    answer<3> f(int&&)      { return answer<3>(); }\n\n    void\n    test()\n    {\n      int i = 0;\n      const int c = 0;\n      static_assert(decltype(f(i))::value == 1, \"\");\n      static_assert(decltype(f(c))::value == 2, \"\");\n      static_assert(decltype(f(0))::value == 3, \"\");\n    }\n\n  }\n\n  namespace test_uniform_initialization\n  {\n\n    struct test\n    {\n      static const int zero {};\n      static const int one {1};\n    };\n\n    static_assert(test::zero == 0, \"\");\n    static_assert(test::one == 1, \"\");\n\n  }\n\n  namespace test_lambdas\n  {\n\n    void\n    test1()\n    {\n      auto lambda1 = [](){};\n      auto lambda2 = lambda1;\n      lambda1();\n      lambda2();\n    }\n\n    int\n    test2()\n    {\n      auto a = [](int i, int j){ return i + j; }(1, 2);\n      auto b = []() -> int { return '0'; }();\n      auto c = [=](){ return a + b; }();\n      auto d = [&](){ return c; }();\n      auto e = [a, &b](int x) mutable {\n        const auto identity = [](int y){ return y; };\n        for (auto i = 0; i < a; ++i)\n          a += b--;\n        return x + identity(a + b);\n      }(0);\n      return a + b + c + d + e;\n    }\n\n    int\n    test3()\n    {\n      const auto nullary = [](){ return 0; };\n      const auto unary = [](int x){ return x; };\n      using nullary_t = decltype(nullary);\n      using unary_t = decltype(unary);\n      const auto higher1st = [](nullary_t f){ return f(); };\n      const auto higher2nd = [unary](nullary_t f1){\n        return [unary, f1](unary_t f2){ return f2(unary(f1())); };\n      };\n      return higher1st(nullary) + higher2nd(nullary)(unary);\n    }\n\n  }\n\n  namespace test_variadic_templates\n  {\n\n    template <int...>\n    struct sum;\n\n    template <int N0, int... N1toN>\n    struct sum<N0, N1toN...>\n    {\n      static constexpr auto value = N0 + sum<N1toN...>::value;\n    };\n\n    template <>\n    struct sum<>\n    {\n      static constexpr auto value = 0;\n    };\n\n    static_assert(sum<>::value == 0, \"\");\n    static_assert(sum<1>::value == 1, \"\");\n    static_assert(sum<23>::value == 23, \"\");\n    static_assert(sum<1, 2>::value == 3, \"\");\n    static_assert(sum<5, 5, 11>::value == 21, \"\");\n    static_assert(sum<2, 3, 5, 7, 11, 13>::value == 41, \"\");\n\n  }\n\n  // http://stackoverflow.com/questions/13728184/template-aliases-and-sfinae\n  // Clang 3.1 fails with headers of libstd++ 4.8.3 when using std::function\n  // because of this.\n  namespace test_template_alias_sfinae\n  {\n\n    struct foo {};\n\n    template<typename T>\n    using member = typename T::member_type;\n\n    template<typename T>\n    void func(...) {}\n\n    template<typename T>\n    void func(member<T>*) {}\n\n    void test();\n\n    void test() { func<foo>(0); }\n\n  }\n\n}  // namespace cxx11\n\n#endif  // __cplusplus >= 201103L\n\n]])\n\n\ndnl  Tests for new features in C++14\n\nm4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_14], [[\n\n// If the compiler admits that it is not ready for C++14, why torture it?\n// Hopefully, this will speed up the test.\n\n#ifndef __cplusplus\n\n#error \"This is not a C++ compiler\"\n\n#elif __cplusplus < 201402L && !defined _MSC_VER\n\n#error \"This is not a C++14 compiler\"\n\n#else\n\nnamespace cxx14\n{\n\n  namespace test_polymorphic_lambdas\n  {\n\n    int\n    test()\n    {\n      const auto lambda = [](auto&&... args){\n        const auto istiny = [](auto x){\n          return (sizeof(x) == 1UL) ? 1 : 0;\n        };\n        const int aretiny[] = { istiny(args)... };\n        return aretiny[0];\n      };\n      return lambda(1, 1L, 1.0f, '1');\n    }\n\n  }\n\n  namespace test_binary_literals\n  {\n\n    constexpr auto ivii = 0b0000000000101010;\n    static_assert(ivii == 42, \"wrong value\");\n\n  }\n\n  namespace test_generalized_constexpr\n  {\n\n    template < typename CharT >\n    constexpr unsigned long\n    strlen_c(const CharT *const s) noexcept\n    {\n      auto length = 0UL;\n      for (auto p = s; *p; ++p)\n        ++length;\n      return length;\n    }\n\n    static_assert(strlen_c(\"\") == 0UL, \"\");\n    static_assert(strlen_c(\"x\") == 1UL, \"\");\n    static_assert(strlen_c(\"test\") == 4UL, \"\");\n    static_assert(strlen_c(\"another\\0test\") == 7UL, \"\");\n\n  }\n\n  namespace test_lambda_init_capture\n  {\n\n    int\n    test()\n    {\n      auto x = 0;\n      const auto lambda1 = [a = x](int b){ return a + b; };\n      const auto lambda2 = [a = lambda1(x)](){ return a; };\n      return lambda2();\n    }\n\n  }\n\n  namespace test_digit_separators\n  {\n\n    constexpr auto ten_million = 100'000'000;\n    static_assert(ten_million == 100000000, \"\");\n\n  }\n\n  namespace test_return_type_deduction\n  {\n\n    auto f(int& x) { return x; }\n    decltype(auto) g(int& x) { return x; }\n\n    template < typename T1, typename T2 >\n    struct is_same\n    {\n      static constexpr auto value = false;\n    };\n\n    template < typename T >\n    struct is_same<T, T>\n    {\n      static constexpr auto value = true;\n    };\n\n    int\n    test()\n    {\n      auto x = 0;\n      static_assert(is_same<int, decltype(f(x))>::value, \"\");\n      static_assert(is_same<int&, decltype(g(x))>::value, \"\");\n      return x;\n    }\n\n  }\n\n}  // namespace cxx14\n\n#endif  // __cplusplus >= 201402L\n\n]])\n\n\ndnl  Tests for new features in C++17\n\nm4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_17], [[\n\n// If the compiler admits that it is not ready for C++17, why torture it?\n// Hopefully, this will speed up the test.\n\n#ifndef __cplusplus\n\n#error \"This is not a C++ compiler\"\n\n#elif __cplusplus < 201703L && !defined _MSC_VER\n\n#error \"This is not a C++17 compiler\"\n\n#else\n\n#include <initializer_list>\n#include <utility>\n#include <type_traits>\n\nnamespace cxx17\n{\n\n  namespace test_constexpr_lambdas\n  {\n\n    constexpr int foo = [](){return 42;}();\n\n  }\n\n  namespace test::nested_namespace::definitions\n  {\n\n  }\n\n  namespace test_fold_expression\n  {\n\n    template<typename... Args>\n    int multiply(Args... args)\n    {\n      return (args * ... * 1);\n    }\n\n    template<typename... Args>\n    bool all(Args... args)\n    {\n      return (args && ...);\n    }\n\n  }\n\n  namespace test_extended_static_assert\n  {\n\n    static_assert (true);\n\n  }\n\n  namespace test_auto_brace_init_list\n  {\n\n    auto foo = {5};\n    auto bar {5};\n\n    static_assert(std::is_same<std::initializer_list<int>, decltype(foo)>::value);\n    static_assert(std::is_same<int, decltype(bar)>::value);\n  }\n\n  namespace test_typename_in_template_template_parameter\n  {\n\n    template<template<typename> typename X> struct D;\n\n  }\n\n  namespace test_fallthrough_nodiscard_maybe_unused_attributes\n  {\n\n    int f1()\n    {\n      return 42;\n    }\n\n    [[nodiscard]] int f2()\n    {\n      [[maybe_unused]] auto unused = f1();\n\n      switch (f1())\n      {\n      case 17:\n        f1();\n        [[fallthrough]];\n      case 42:\n        f1();\n      }\n      return f1();\n    }\n\n  }\n\n  namespace test_extended_aggregate_initialization\n  {\n\n    struct base1\n    {\n      int b1, b2 = 42;\n    };\n\n    struct base2\n    {\n      base2() {\n        b3 = 42;\n      }\n      int b3;\n    };\n\n    struct derived : base1, base2\n    {\n        int d;\n    };\n\n    derived d1 {{1, 2}, {}, 4};  // full initialization\n    derived d2 {{}, {}, 4};      // value-initialized bases\n\n  }\n\n  namespace test_general_range_based_for_loop\n  {\n\n    struct iter\n    {\n      int i;\n\n      int& operator* ()\n      {\n        return i;\n      }\n\n      const int& operator* () const\n      {\n        return i;\n      }\n\n      iter& operator++()\n      {\n        ++i;\n        return *this;\n      }\n    };\n\n    struct sentinel\n    {\n      int i;\n    };\n\n    bool operator== (const iter& i, const sentinel& s)\n    {\n      return i.i == s.i;\n    }\n\n    bool operator!= (const iter& i, const sentinel& s)\n    {\n      return !(i == s);\n    }\n\n    struct range\n    {\n      iter begin() const\n      {\n        return {0};\n      }\n\n      sentinel end() const\n      {\n        return {5};\n      }\n    };\n\n    void f()\n    {\n      range r {};\n\n      for (auto i : r)\n      {\n        [[maybe_unused]] auto v = i;\n      }\n    }\n\n  }\n\n  namespace test_lambda_capture_asterisk_this_by_value\n  {\n\n    struct t\n    {\n      int i;\n      int foo()\n      {\n        return [*this]()\n        {\n          return i;\n        }();\n      }\n    };\n\n  }\n\n  namespace test_enum_class_construction\n  {\n\n    enum class byte : unsigned char\n    {};\n\n    byte foo {42};\n\n  }\n\n  namespace test_constexpr_if\n  {\n\n    template <bool cond>\n    int f ()\n    {\n      if constexpr(cond)\n      {\n        return 13;\n      }\n      else\n      {\n        return 42;\n      }\n    }\n\n  }\n\n  namespace test_selection_statement_with_initializer\n  {\n\n    int f()\n    {\n      return 13;\n    }\n\n    int f2()\n    {\n      if (auto i = f(); i > 0)\n      {\n        return 3;\n      }\n\n      switch (auto i = f(); i + 4)\n      {\n      case 17:\n        return 2;\n\n      default:\n        return 1;\n      }\n    }\n\n  }\n\n  namespace test_template_argument_deduction_for_class_templates\n  {\n\n    template <typename T1, typename T2>\n    struct pair\n    {\n      pair (T1 p1, T2 p2)\n        : m1 {p1},\n          m2 {p2}\n      {}\n\n      T1 m1;\n      T2 m2;\n    };\n\n    void f()\n    {\n      [[maybe_unused]] auto p = pair{13, 42u};\n    }\n\n  }\n\n  namespace test_non_type_auto_template_parameters\n  {\n\n    template <auto n>\n    struct B\n    {};\n\n    B<5> b1;\n    B<'a'> b2;\n\n  }\n\n  namespace test_structured_bindings\n  {\n\n    int arr[2] = { 1, 2 };\n    std::pair<int, int> pr = { 1, 2 };\n\n    auto f1() -> int(&)[2]\n    {\n      return arr;\n    }\n\n    auto f2() -> std::pair<int, int>&\n    {\n      return pr;\n    }\n\n    struct S\n    {\n      int x1 : 2;\n      volatile double y1;\n    };\n\n    S f3()\n    {\n      return {};\n    }\n\n    auto [ x1, y1 ] = f1();\n    auto& [ xr1, yr1 ] = f1();\n    auto [ x2, y2 ] = f2();\n    auto& [ xr2, yr2 ] = f2();\n    const auto [ x3, y3 ] = f3();\n\n  }\n\n  namespace test_exception_spec_type_system\n  {\n\n    struct Good {};\n    struct Bad {};\n\n    void g1() noexcept;\n    void g2();\n\n    template<typename T>\n    Bad\n    f(T*, T*);\n\n    template<typename T1, typename T2>\n    Good\n    f(T1*, T2*);\n\n    static_assert (std::is_same_v<Good, decltype(f(g1, g2))>);\n\n  }\n\n  namespace test_inline_variables\n  {\n\n    template<class T> void f(T)\n    {}\n\n    template<class T> inline T g(T)\n    {\n      return T{};\n    }\n\n    template<> inline void f<>(int)\n    {}\n\n    template<> int g<>(int)\n    {\n      return 5;\n    }\n\n  }\n\n}  // namespace cxx17\n\n#endif  // __cplusplus < 201703L && !defined _MSC_VER\n\n]])\n\n\ndnl  Tests for new features in C++20\n\nm4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_20], [[\n\n#ifndef __cplusplus\n\n#error \"This is not a C++ compiler\"\n\n#elif __cplusplus < 202002L && !defined _MSC_VER\n\n#error \"This is not a C++20 compiler\"\n\n#else\n\n#include <version>\n\nnamespace cxx20\n{\n\n// As C++20 supports feature test macros in the standard, there is no\n// immediate need to actually test for feature availability on the\n// Autoconf side.\n\n}  // namespace cxx20\n\n#endif  // __cplusplus < 202002L && !defined _MSC_VER\n\n]])\n"
  },
  {
    "path": "build/ax_prog_doxygen.m4",
    "content": "# ===========================================================================\n#      http://www.gnu.org/software/autoconf-archive/ax_prog_doxygen.html\n# ===========================================================================\n#\n# SYNOPSIS\n#\n#   DX_INIT_DOXYGEN(PROJECT-NAME, DOXYFILE-PATH, [OUTPUT-DIR])\n#   DX_DOXYGEN_FEATURE(ON|OFF)\n#   DX_DOT_FEATURE(ON|OFF)\n#   DX_HTML_FEATURE(ON|OFF)\n#   DX_CHM_FEATURE(ON|OFF)\n#   DX_CHI_FEATURE(ON|OFF)\n#   DX_MAN_FEATURE(ON|OFF)\n#   DX_RTF_FEATURE(ON|OFF)\n#   DX_XML_FEATURE(ON|OFF)\n#   DX_PDF_FEATURE(ON|OFF)\n#   DX_PS_FEATURE(ON|OFF)\n#\n# DESCRIPTION\n#\n#   The DX_*_FEATURE macros control the default setting for the given\n#   Doxygen feature. Supported features are 'DOXYGEN' itself, 'DOT' for\n#   generating graphics, 'HTML' for plain HTML, 'CHM' for compressed HTML\n#   help (for MS users), 'CHI' for generating a seperate .chi file by the\n#   .chm file, and 'MAN', 'RTF', 'XML', 'PDF' and 'PS' for the appropriate\n#   output formats. The environment variable DOXYGEN_PAPER_SIZE may be\n#   specified to override the default 'a4wide' paper size.\n#\n#   By default, HTML, PDF and PS documentation is generated as this seems to\n#   be the most popular and portable combination. MAN pages created by\n#   Doxygen are usually problematic, though by picking an appropriate subset\n#   and doing some massaging they might be better than nothing. CHM and RTF\n#   are specific for MS (note that you can't generate both HTML and CHM at\n#   the same time). The XML is rather useless unless you apply specialized\n#   post-processing to it.\n#\n#   The macros mainly control the default state of the feature. The use can\n#   override the default by specifying --enable or --disable. The macros\n#   ensure that contradictory flags are not given (e.g.,\n#   --enable-doxygen-html and --enable-doxygen-chm,\n#   --enable-doxygen-anything with --disable-doxygen, etc.) Finally, each\n#   feature will be automatically disabled (with a warning) if the required\n#   programs are missing.\n#\n#   Once all the feature defaults have been specified, call DX_INIT_DOXYGEN\n#   with the following parameters: a one-word name for the project for use\n#   as a filename base etc., an optional configuration file name (the\n#   default is 'Doxyfile', the same as Doxygen's default), and an optional\n#   output directory name (the default is 'doxygen-doc').\n#\n#   Automake Support\n#\n#   The following is a template aminclude.am file for use with Automake.\n#   Make targets and variables values are controlled by the various\n#   DX_COND_* conditionals set by autoconf.\n#\n#   The provided targets are:\n#\n#     doxygen-doc: Generate all doxygen documentation.\n#\n#     doxygen-run: Run doxygen, which will generate some of the\n#                  documentation (HTML, CHM, CHI, MAN, RTF, XML)\n#                  but will not do the post processing required\n#                  for the rest of it (PS, PDF, and some MAN).\n#\n#     doxygen-man: Rename some doxygen generated man pages.\n#\n#     doxygen-ps:  Generate doxygen PostScript documentation.\n#\n#     doxygen-pdf: Generate doxygen PDF documentation.\n#\n#   Note that by default these are not integrated into the automake targets.\n#   If doxygen is used to generate man pages, you can achieve this\n#   integration by setting man3_MANS to the list of man pages generated and\n#   then adding the dependency:\n#\n#     $(man3_MANS): doxygen-doc\n#\n#   This will cause make to run doxygen and generate all the documentation.\n#\n#   The following variable is intended for use in Makefile.am:\n#\n#     DX_CLEANFILES = everything to clean.\n#\n#   Then add this variable to MOSTLYCLEANFILES.\n#\n#     ----- begin aminclude.am -------------------------------------\n#\n#     ## --------------------------------- ##\n#     ## Format-independent Doxygen rules. ##\n#     ## --------------------------------- ##\n#\n#     if DX_COND_doc\n#\n#     ## ------------------------------- ##\n#     ## Rules specific for HTML output. ##\n#     ## ------------------------------- ##\n#\n#     if DX_COND_html\n#\n#     DX_CLEAN_HTML = @DX_DOCDIR@/html\n#\n#     endif DX_COND_html\n#\n#     ## ------------------------------ ##\n#     ## Rules specific for CHM output. ##\n#     ## ------------------------------ ##\n#\n#     if DX_COND_chm\n#\n#     DX_CLEAN_CHM = @DX_DOCDIR@/chm\n#\n#     if DX_COND_chi\n#\n#     DX_CLEAN_CHI = @DX_DOCDIR@/@PACKAGE@.chi\n#\n#     endif DX_COND_chi\n#\n#     endif DX_COND_chm\n#\n#     ## ------------------------------ ##\n#     ## Rules specific for MAN output. ##\n#     ## ------------------------------ ##\n#\n#     if DX_COND_man\n#\n#     DX_CLEAN_MAN = @DX_DOCDIR@/man\n#\n#     endif DX_COND_man\n#\n#     ## ------------------------------ ##\n#     ## Rules specific for RTF output. ##\n#     ## ------------------------------ ##\n#\n#     if DX_COND_rtf\n#\n#     DX_CLEAN_RTF = @DX_DOCDIR@/rtf\n#\n#     endif DX_COND_rtf\n#\n#     ## ------------------------------ ##\n#     ## Rules specific for XML output. ##\n#     ## ------------------------------ ##\n#\n#     if DX_COND_xml\n#\n#     DX_CLEAN_XML = @DX_DOCDIR@/xml\n#\n#     endif DX_COND_xml\n#\n#     ## ----------------------------- ##\n#     ## Rules specific for PS output. ##\n#     ## ----------------------------- ##\n#\n#     if DX_COND_ps\n#\n#     DX_CLEAN_PS = @DX_DOCDIR@/@PACKAGE@.ps\n#\n#     DX_PS_GOAL = doxygen-ps\n#\n#     doxygen-ps: @DX_DOCDIR@/@PACKAGE@.ps\n#\n#     @DX_DOCDIR@/@PACKAGE@.ps: @DX_DOCDIR@/@PACKAGE@.tag\n#         cd @DX_DOCDIR@/latex; \\\n#         rm -f *.aux *.toc *.idx *.ind *.ilg *.log *.out; \\\n#         $(DX_LATEX) refman.tex; \\\n#         $(MAKEINDEX_PATH) refman.idx; \\\n#         $(DX_LATEX) refman.tex; \\\n#         countdown=5; \\\n#         while $(DX_EGREP) 'Rerun (LaTeX|to get cross-references right)' \\\n#                           refman.log > /dev/null 2>&1 \\\n#            && test $$countdown -gt 0; do \\\n#             $(DX_LATEX) refman.tex; \\\n#             countdown=`expr $$countdown - 1`; \\\n#         done; \\\n#         $(DX_DVIPS) -o ../@PACKAGE@.ps refman.dvi\n#\n#     endif DX_COND_ps\n#\n#     ## ------------------------------ ##\n#     ## Rules specific for PDF output. ##\n#     ## ------------------------------ ##\n#\n#     if DX_COND_pdf\n#\n#     DX_CLEAN_PDF = @DX_DOCDIR@/@PACKAGE@.pdf\n#\n#     DX_PDF_GOAL = doxygen-pdf\n#\n#     doxygen-pdf: @DX_DOCDIR@/@PACKAGE@.pdf\n#\n#     @DX_DOCDIR@/@PACKAGE@.pdf: @DX_DOCDIR@/@PACKAGE@.tag\n#         cd @DX_DOCDIR@/latex; \\\n#         rm -f *.aux *.toc *.idx *.ind *.ilg *.log *.out; \\\n#         $(DX_PDFLATEX) refman.tex; \\\n#         $(DX_MAKEINDEX) refman.idx; \\\n#         $(DX_PDFLATEX) refman.tex; \\\n#         countdown=5; \\\n#         while $(DX_EGREP) 'Rerun (LaTeX|to get cross-references right)' \\\n#                           refman.log > /dev/null 2>&1 \\\n#            && test $$countdown -gt 0; do \\\n#             $(DX_PDFLATEX) refman.tex; \\\n#             countdown=`expr $$countdown - 1`; \\\n#         done; \\\n#         mv refman.pdf ../@PACKAGE@.pdf\n#\n#     endif DX_COND_pdf\n#\n#     ## ------------------------------------------------- ##\n#     ## Rules specific for LaTeX (shared for PS and PDF). ##\n#     ## ------------------------------------------------- ##\n#\n#     if DX_COND_latex\n#\n#     DX_CLEAN_LATEX = @DX_DOCDIR@/latex\n#\n#     endif DX_COND_latex\n#\n#     .PHONY: doxygen-run doxygen-doc $(DX_PS_GOAL) $(DX_PDF_GOAL)\n#\n#     .INTERMEDIATE: doxygen-run $(DX_PS_GOAL) $(DX_PDF_GOAL)\n#\n#     doxygen-run: @DX_DOCDIR@/@PACKAGE@.tag\n#\n#     doxygen-doc: doxygen-run $(DX_PS_GOAL) $(DX_PDF_GOAL)\n#\n#     @DX_DOCDIR@/@PACKAGE@.tag: $(DX_CONFIG) $(pkginclude_HEADERS)\n#         rm -rf @DX_DOCDIR@\n#         $(DX_ENV) $(DX_DOXYGEN) $(srcdir)/$(DX_CONFIG)\n#         echo Timestamp >$@\n#\n#     DX_CLEANFILES = \\\n#         @DX_DOCDIR@/@PACKAGE@.tag \\\n#         -r \\\n#         $(DX_CLEAN_HTML) \\\n#         $(DX_CLEAN_CHM) \\\n#         $(DX_CLEAN_CHI) \\\n#         $(DX_CLEAN_MAN) \\\n#         $(DX_CLEAN_RTF) \\\n#         $(DX_CLEAN_XML) \\\n#         $(DX_CLEAN_PS) \\\n#         $(DX_CLEAN_PDF) \\\n#         $(DX_CLEAN_LATEX)\n#\n#     endif DX_COND_doc\n#\n#     ----- end aminclude.am ---------------------------------------\n#\n# LICENSE\n#\n#   Copyright (c) 2009 Oren Ben-Kiki <oren@ben-kiki.org>\n#\n#   Copying and distribution of this file, with or without modification, are\n#   permitted in any medium without royalty provided the copyright notice\n#   and this notice are preserved. This file is offered as-is, without any\n#   warranty.\n\n#serial 13\n\n## ----------##\n## Defaults. ##\n## ----------##\n\nDX_ENV=\"\"\nAC_DEFUN([DX_FEATURE_doc],  ON)\nAC_DEFUN([DX_FEATURE_dot],  OFF)\nAC_DEFUN([DX_FEATURE_man],  OFF)\nAC_DEFUN([DX_FEATURE_html], ON)\nAC_DEFUN([DX_FEATURE_chm],  OFF)\nAC_DEFUN([DX_FEATURE_chi],  OFF)\nAC_DEFUN([DX_FEATURE_rtf],  OFF)\nAC_DEFUN([DX_FEATURE_xml],  OFF)\nAC_DEFUN([DX_FEATURE_pdf],  ON)\nAC_DEFUN([DX_FEATURE_ps],   ON)\n\n## --------------- ##\n## Private macros. ##\n## --------------- ##\n\n# DX_ENV_APPEND(VARIABLE, VALUE)\n# ------------------------------\n# Append VARIABLE=\"VALUE\" to DX_ENV for invoking doxygen.\nAC_DEFUN([DX_ENV_APPEND], [AC_SUBST([DX_ENV], [\"$DX_ENV $1='$2'\"])])\n\n# DX_DIRNAME_EXPR\n# ---------------\n# Expand into a shell expression prints the directory part of a path.\nAC_DEFUN([DX_DIRNAME_EXPR],\n         [[expr \".$1\" : '\\(\\.\\)[^/]*$' \\| \"x$1\" : 'x\\(.*\\)/[^/]*$']])\n\n# DX_IF_FEATURE(FEATURE, IF-ON, IF-OFF)\n# -------------------------------------\n# Expands according to the M4 (static) status of the feature.\nAC_DEFUN([DX_IF_FEATURE], [ifelse(DX_FEATURE_$1, ON, [$2], [$3])])\n\n# DX_REQUIRE_PROG(VARIABLE, PROGRAM)\n# ----------------------------------\n# Require the specified program to be found for the DX_CURRENT_FEATURE to work.\nAC_DEFUN([DX_REQUIRE_PROG], [\nAC_PATH_TOOL([$1], [$2])\nif test \"$DX_FLAG_[]DX_CURRENT_FEATURE$$1\" = 1; then\n    AC_MSG_WARN([$2 not found - will not DX_CURRENT_DESCRIPTION])\n    AC_SUBST(DX_FLAG_[]DX_CURRENT_FEATURE, 0)\nfi\n])\n\n# DX_TEST_FEATURE(FEATURE)\n# ------------------------\n# Expand to a shell expression testing whether the feature is active.\nAC_DEFUN([DX_TEST_FEATURE], [test \"$DX_FLAG_$1\" = 1])\n\n# DX_CHECK_DEPEND(REQUIRED_FEATURE, REQUIRED_STATE)\n# -------------------------------------------------\n# Verify that a required features has the right state before trying to turn on\n# the DX_CURRENT_FEATURE.\nAC_DEFUN([DX_CHECK_DEPEND], [\ntest \"$DX_FLAG_$1\" = \"$2\" \\\n|| AC_MSG_ERROR([doxygen-DX_CURRENT_FEATURE ifelse([$2], 1,\n                            requires, contradicts) doxygen-DX_CURRENT_FEATURE])\n])\n\n# DX_CLEAR_DEPEND(FEATURE, REQUIRED_FEATURE, REQUIRED_STATE)\n# ----------------------------------------------------------\n# Turn off the DX_CURRENT_FEATURE if the required feature is off.\nAC_DEFUN([DX_CLEAR_DEPEND], [\ntest \"$DX_FLAG_$1\" = \"$2\" || AC_SUBST(DX_FLAG_[]DX_CURRENT_FEATURE, 0)\n])\n\n# DX_FEATURE_ARG(FEATURE, DESCRIPTION,\n#                CHECK_DEPEND, CLEAR_DEPEND,\n#                REQUIRE, DO-IF-ON, DO-IF-OFF)\n# --------------------------------------------\n# Parse the command-line option controlling a feature. CHECK_DEPEND is called\n# if the user explicitly turns the feature on (and invokes DX_CHECK_DEPEND),\n# otherwise CLEAR_DEPEND is called to turn off the default state if a required\n# feature is disabled (using DX_CLEAR_DEPEND). REQUIRE performs additional\n# requirement tests (DX_REQUIRE_PROG). Finally, an automake flag is set and\n# DO-IF-ON or DO-IF-OFF are called according to the final state of the feature.\nAC_DEFUN([DX_ARG_ABLE], [\n    AC_DEFUN([DX_CURRENT_FEATURE], [$1])\n    AC_DEFUN([DX_CURRENT_DESCRIPTION], [$2])\n    AC_ARG_ENABLE(doxygen-$1,\n                  [AS_HELP_STRING(DX_IF_FEATURE([$1], [--disable-doxygen-$1],\n                                                      [--enable-doxygen-$1]),\n                                  DX_IF_FEATURE([$1], [don't $2], [$2]))],\n                  [\ncase \"$enableval\" in\n#(\ny|Y|yes|Yes|YES)\n    AC_SUBST([DX_FLAG_$1], 1)\n    $3\n;; #(\nn|N|no|No|NO)\n    AC_SUBST([DX_FLAG_$1], 0)\n;; #(\n*)\n    AC_MSG_ERROR([invalid value '$enableval' given to doxygen-$1])\n;;\nesac\n], [\nAC_SUBST([DX_FLAG_$1], [DX_IF_FEATURE([$1], 1, 0)])\n$4\n])\nif DX_TEST_FEATURE([$1]); then\n    $5\n    :\nfi\nAM_CONDITIONAL(DX_COND_$1, DX_TEST_FEATURE([$1]))\nif DX_TEST_FEATURE([$1]); then\n    $6\n    :\nelse\n    $7\n    :\nfi\n])\n\n## -------------- ##\n## Public macros. ##\n## -------------- ##\n\n# DX_XXX_FEATURE(DEFAULT_STATE)\n# -----------------------------\nAC_DEFUN([DX_DOXYGEN_FEATURE], [AC_DEFUN([DX_FEATURE_doc],  [$1])])\nAC_DEFUN([DX_DOT_FEATURE],     [AC_DEFUN([DX_FEATURE_dot], [$1])])\nAC_DEFUN([DX_MAN_FEATURE],     [AC_DEFUN([DX_FEATURE_man],  [$1])])\nAC_DEFUN([DX_HTML_FEATURE],    [AC_DEFUN([DX_FEATURE_html], [$1])])\nAC_DEFUN([DX_CHM_FEATURE],     [AC_DEFUN([DX_FEATURE_chm],  [$1])])\nAC_DEFUN([DX_CHI_FEATURE],     [AC_DEFUN([DX_FEATURE_chi],  [$1])])\nAC_DEFUN([DX_RTF_FEATURE],     [AC_DEFUN([DX_FEATURE_rtf],  [$1])])\nAC_DEFUN([DX_XML_FEATURE],     [AC_DEFUN([DX_FEATURE_xml],  [$1])])\nAC_DEFUN([DX_XML_FEATURE],     [AC_DEFUN([DX_FEATURE_xml],  [$1])])\nAC_DEFUN([DX_PDF_FEATURE],     [AC_DEFUN([DX_FEATURE_pdf],  [$1])])\nAC_DEFUN([DX_PS_FEATURE],      [AC_DEFUN([DX_FEATURE_ps],   [$1])])\n\n# DX_INIT_DOXYGEN(PROJECT, [CONFIG-FILE], [OUTPUT-DOC-DIR])\n# ---------------------------------------------------------\n# PROJECT also serves as the base name for the documentation files.\n# The default CONFIG-FILE is \"Doxyfile\" and OUTPUT-DOC-DIR is \"doxygen-doc\".\nAC_DEFUN([DX_INIT_DOXYGEN], [\n\n# Files:\nAC_SUBST([DX_PROJECT], [$1])\nAC_SUBST([DX_CONFIG], [ifelse([$2], [], Doxyfile, [$2])])\nAC_SUBST([DX_DOCDIR], [ifelse([$3], [], doxygen-doc, [$3])])\n\n# Environment variables used inside doxygen.cfg:\nDX_ENV_APPEND(SRCDIR, $srcdir)\nDX_ENV_APPEND(PROJECT, $DX_PROJECT)\nDX_ENV_APPEND(DOCDIR, $DX_DOCDIR)\nDX_ENV_APPEND(VERSION, $PACKAGE_VERSION)\n\n# Doxygen itself:\nDX_ARG_ABLE(doc, [generate any doxygen documentation],\n            [],\n            [],\n            [DX_REQUIRE_PROG([DX_DOXYGEN], doxygen)\n             DX_REQUIRE_PROG([DX_PERL], perl)],\n            [DX_ENV_APPEND(PERL_PATH, $DX_PERL)])\n\n# Dot for graphics:\nDX_ARG_ABLE(dot, [generate graphics for doxygen documentation],\n            [DX_CHECK_DEPEND(doc, 1)],\n            [DX_CLEAR_DEPEND(doc, 1)],\n            [DX_REQUIRE_PROG([DX_DOT], dot)],\n            [DX_ENV_APPEND(HAVE_DOT, YES)\n             DX_ENV_APPEND(DOT_PATH, [`DX_DIRNAME_EXPR($DX_DOT)`])],\n            [DX_ENV_APPEND(HAVE_DOT, NO)])\n\n# Man pages generation:\nDX_ARG_ABLE(man, [generate doxygen manual pages],\n            [DX_CHECK_DEPEND(doc, 1)],\n            [DX_CLEAR_DEPEND(doc, 1)],\n            [],\n            [DX_ENV_APPEND(GENERATE_MAN, YES)],\n            [DX_ENV_APPEND(GENERATE_MAN, NO)])\n\n# RTF file generation:\nDX_ARG_ABLE(rtf, [generate doxygen RTF documentation],\n            [DX_CHECK_DEPEND(doc, 1)],\n            [DX_CLEAR_DEPEND(doc, 1)],\n            [],\n            [DX_ENV_APPEND(GENERATE_RTF, YES)],\n            [DX_ENV_APPEND(GENERATE_RTF, NO)])\n\n# XML file generation:\nDX_ARG_ABLE(xml, [generate doxygen XML documentation],\n            [DX_CHECK_DEPEND(doc, 1)],\n            [DX_CLEAR_DEPEND(doc, 1)],\n            [],\n            [DX_ENV_APPEND(GENERATE_XML, YES)],\n            [DX_ENV_APPEND(GENERATE_XML, NO)])\n\n# (Compressed) HTML help generation:\nDX_ARG_ABLE(chm, [generate doxygen compressed HTML help documentation],\n            [DX_CHECK_DEPEND(doc, 1)],\n            [DX_CLEAR_DEPEND(doc, 1)],\n            [DX_REQUIRE_PROG([DX_HHC], hhc)],\n            [DX_ENV_APPEND(HHC_PATH, $DX_HHC)\n             DX_ENV_APPEND(GENERATE_HTML, YES)\n             DX_ENV_APPEND(GENERATE_HTMLHELP, YES)],\n            [DX_ENV_APPEND(GENERATE_HTMLHELP, NO)])\n\n# Seperate CHI file generation.\nDX_ARG_ABLE(chi, [generate doxygen seperate compressed HTML help index file],\n            [DX_CHECK_DEPEND(chm, 1)],\n            [DX_CLEAR_DEPEND(chm, 1)],\n            [],\n            [DX_ENV_APPEND(GENERATE_CHI, YES)],\n            [DX_ENV_APPEND(GENERATE_CHI, NO)])\n\n# Plain HTML pages generation:\nDX_ARG_ABLE(html, [generate doxygen plain HTML documentation],\n            [DX_CHECK_DEPEND(doc, 1) DX_CHECK_DEPEND(chm, 0)],\n            [DX_CLEAR_DEPEND(doc, 1) DX_CLEAR_DEPEND(chm, 0)],\n            [],\n            [DX_ENV_APPEND(GENERATE_HTML, YES)],\n            [DX_TEST_FEATURE(chm) || DX_ENV_APPEND(GENERATE_HTML, NO)])\n\n# PostScript file generation:\nDX_ARG_ABLE(ps, [generate doxygen PostScript documentation],\n            [DX_CHECK_DEPEND(doc, 1)],\n            [DX_CLEAR_DEPEND(doc, 1)],\n            [DX_REQUIRE_PROG([DX_LATEX], latex)\n             DX_REQUIRE_PROG([DX_MAKEINDEX], makeindex)\n             DX_REQUIRE_PROG([DX_DVIPS], dvips)\n             DX_REQUIRE_PROG([DX_EGREP], egrep)])\n\n# PDF file generation:\nDX_ARG_ABLE(pdf, [generate doxygen PDF documentation],\n            [DX_CHECK_DEPEND(doc, 1)],\n            [DX_CLEAR_DEPEND(doc, 1)],\n            [DX_REQUIRE_PROG([DX_PDFLATEX], pdflatex)\n             DX_REQUIRE_PROG([DX_MAKEINDEX], makeindex)\n             DX_REQUIRE_PROG([DX_EGREP], egrep)])\n\n# LaTeX generation for PS and/or PDF:\nAM_CONDITIONAL(DX_COND_latex, DX_TEST_FEATURE(ps) || DX_TEST_FEATURE(pdf))\nif DX_TEST_FEATURE(ps) || DX_TEST_FEATURE(pdf); then\n    DX_ENV_APPEND(GENERATE_LATEX, YES)\nelse\n    DX_ENV_APPEND(GENERATE_LATEX, NO)\nfi\n\n# Paper size for PS and/or PDF:\nAC_ARG_VAR(DOXYGEN_PAPER_SIZE,\n           [a4wide (default), a4, letter, legal or executive])\ncase \"$DOXYGEN_PAPER_SIZE\" in\n#(\n\"\")\n    AC_SUBST(DOXYGEN_PAPER_SIZE, \"\")\n;; #(\na4wide|a4|letter|legal|executive)\n    DX_ENV_APPEND(PAPER_SIZE, $DOXYGEN_PAPER_SIZE)\n;; #(\n*)\n    AC_MSG_ERROR([unknown DOXYGEN_PAPER_SIZE='$DOXYGEN_PAPER_SIZE'])\n;;\nesac\n\n#For debugging:\n#echo DX_FLAG_doc=$DX_FLAG_doc\n#echo DX_FLAG_dot=$DX_FLAG_dot\n#echo DX_FLAG_man=$DX_FLAG_man\n#echo DX_FLAG_html=$DX_FLAG_html\n#echo DX_FLAG_chm=$DX_FLAG_chm\n#echo DX_FLAG_chi=$DX_FLAG_chi\n#echo DX_FLAG_rtf=$DX_FLAG_rtf\n#echo DX_FLAG_xml=$DX_FLAG_xml\n#echo DX_FLAG_pdf=$DX_FLAG_pdf\n#echo DX_FLAG_ps=$DX_FLAG_ps\n#echo DX_ENV=$DX_ENV\n])\n"
  },
  {
    "path": "build/ax_valgrind_check.m4",
    "content": "# ===========================================================================\n#     http://www.gnu.org/software/autoconf-archive/ax_valgrind_check.html\n# ===========================================================================\n#\n# SYNOPSIS\n#\n#   AX_VALGRIND_DFLT(memcheck|helgrind|drd|sgcheck, on|off)\n#   AX_VALGRIND_CHECK()\n#\n# DESCRIPTION\n#\n#   AX_VALGRIND_CHECK checks whether Valgrind is present and, if so, allows\n#   running `make check` under a variety of Valgrind tools to check for\n#   memory and threading errors.\n#\n#   Defines VALGRIND_CHECK_RULES which should be substituted in your\n#   Makefile; and $enable_valgrind which can be used in subsequent configure\n#   output. VALGRIND_ENABLED is defined and substituted, and corresponds to\n#   the value of the --enable-valgrind option, which defaults to being\n#   enabled if Valgrind is installed and disabled otherwise. Individual\n#   Valgrind tools can be disabled via --disable-valgrind-<tool>, the\n#   default is configurable via the AX_VALGRIND_DFLT command or is to use\n#   all commands not disabled via AX_VALGRIND_DFLT. All AX_VALGRIND_DFLT\n#   calls must be made before the call to AX_VALGRIND_CHECK.\n#\n#   If unit tests are written using a shell script and automake's\n#   LOG_COMPILER system, the $(VALGRIND) variable can be used within the\n#   shell scripts to enable Valgrind, as described here:\n#\n#     https://www.gnu.org/software/gnulib/manual/html_node/Running-self_002dtests-under-valgrind.html\n#\n#   Usage example:\n#\n#   configure.ac:\n#\n#     AX_VALGRIND_DFLT([sgcheck], [off])\n#     AX_VALGRIND_CHECK\n#\n#   Makefile.am:\n#\n#     @VALGRIND_CHECK_RULES@\n#     VALGRIND_SUPPRESSIONS_FILES = my-project.supp\n#     EXTRA_DIST = my-project.supp\n#\n#   This results in a \"check-valgrind\" rule being added to any Makefile.am\n#   which includes \"@VALGRIND_CHECK_RULES@\" (assuming the module has been\n#   configured with --enable-valgrind). Running `make check-valgrind` in\n#   that directory will run the module's test suite (`make check`) once for\n#   each of the available Valgrind tools (out of memcheck, helgrind and drd)\n#   while the sgcheck will be skipped unless enabled again on the\n#   commandline with --enable-valgrind-sgcheck. The results for each check\n#   will be output to test-suite-$toolname.log. The target will succeed if\n#   there are zero errors and fail otherwise.\n#\n#   Alternatively, a \"check-valgrind-$TOOL\" rule will be added, for $TOOL in\n#   memcheck, helgrind, drd and sgcheck. These are useful because often only\n#   some of those tools can be ran cleanly on a codebase.\n#\n#   The macro supports running with and without libtool.\n#\n# LICENSE\n#\n#   Copyright (c) 2014, 2015, 2016 Philip Withnall <philip.withnall@collabora.co.uk>\n#\n#   Copying and distribution of this file, with or without modification, are\n#   permitted in any medium without royalty provided the copyright notice\n#   and this notice are preserved.  This file is offered as-is, without any\n#   warranty.\n\n#serial 13\n\ndnl Configured tools\nm4_define([valgrind_tool_list], [[memcheck], [helgrind], [drd], [sgcheck]])\nm4_set_add_all([valgrind_exp_tool_set], [sgcheck])\nm4_foreach([vgtool], [valgrind_tool_list],\n           [m4_define([en_dflt_valgrind_]vgtool, [on])])\n\nAC_DEFUN([AX_VALGRIND_DFLT],[\n\tm4_define([en_dflt_valgrind_$1], [$2])\n])dnl\n\nAC_DEFUN([AX_VALGRIND_CHECK],[\n\tdnl Check for --enable-valgrind\n\tAC_ARG_ENABLE([valgrind],\n\t              [AS_HELP_STRING([--enable-valgrind], [Whether to enable Valgrind on the unit tests])],\n\t              [enable_valgrind=$enableval],[enable_valgrind=])\n\n\tAS_IF([test \"$enable_valgrind\" != \"no\"],[\n\t\t# Check for Valgrind.\n\t\tAC_CHECK_PROG([VALGRIND],[valgrind],[valgrind])\n\t\tAS_IF([test \"$VALGRIND\" = \"\"],[\n\t\t\tAS_IF([test \"$enable_valgrind\" = \"yes\"],[\n\t\t\t\tAC_MSG_ERROR([Could not find valgrind; either install it or reconfigure with --disable-valgrind])\n\t\t\t],[\n\t\t\t\tenable_valgrind=no\n\t\t\t])\n\t\t],[\n\t\t\tenable_valgrind=yes\n\t\t])\n\t])\n\n\tAM_CONDITIONAL([VALGRIND_ENABLED],[test \"$enable_valgrind\" = \"yes\"])\n\tAC_SUBST([VALGRIND_ENABLED],[$enable_valgrind])\n\n\t# Check for Valgrind tools we care about.\n\t[valgrind_enabled_tools=]\n\tm4_foreach([vgtool],[valgrind_tool_list],[\n\t\tAC_ARG_ENABLE([valgrind-]vgtool,\n\t\t    m4_if(m4_defn([en_dflt_valgrind_]vgtool),[off],dnl\n[AS_HELP_STRING([--enable-valgrind-]vgtool, [Whether to use ]vgtool[ during the Valgrind tests])],dnl\n[AS_HELP_STRING([--disable-valgrind-]vgtool, [Whether to skip ]vgtool[ during the Valgrind tests])]),\n\t\t              [enable_valgrind_]vgtool[=$enableval],\n\t\t              [enable_valgrind_]vgtool[=])\n\t\tAS_IF([test \"$enable_valgrind\" = \"no\"],[\n\t\t\tenable_valgrind_]vgtool[=no],\n\t\t      [test \"$enable_valgrind_]vgtool[\" ]dnl\nm4_if(m4_defn([en_dflt_valgrind_]vgtool), [off], [= \"yes\"], [!= \"no\"]),[\n\t\t\tAC_CACHE_CHECK([for Valgrind tool ]vgtool,\n\t\t\t               [ax_cv_valgrind_tool_]vgtool,[\n\t\t\t\tax_cv_valgrind_tool_]vgtool[=no\n\t\t\t\tm4_set_contains([valgrind_exp_tool_set],vgtool,\n\t\t\t\t    [m4_define([vgtoolx],[exp-]vgtool)],\n\t\t\t\t    [m4_define([vgtoolx],vgtool)])\n\t\t\t\tAS_IF([`$VALGRIND --tool=]vgtoolx[ --help >/dev/null 2>&1`],[\n\t\t\t\t\tax_cv_valgrind_tool_]vgtool[=yes\n\t\t\t\t])\n\t\t\t])\n\t\t\tAS_IF([test \"$ax_cv_valgrind_tool_]vgtool[\" = \"no\"],[\n\t\t\t\tAS_IF([test \"$enable_valgrind_]vgtool[\" = \"yes\"],[\n\t\t\t\t\tAC_MSG_ERROR([Valgrind does not support ]vgtool[; reconfigure with --disable-valgrind-]vgtool)\n\t\t\t\t],[\n\t\t\t\t\tenable_valgrind_]vgtool[=no\n\t\t\t\t])\n\t\t\t],[\n\t\t\t\tenable_valgrind_]vgtool[=yes\n\t\t\t])\n\t\t])\n\t\tAS_IF([test \"$enable_valgrind_]vgtool[\" = \"yes\"],[\n\t\t\tvalgrind_enabled_tools=\"$valgrind_enabled_tools ]m4_bpatsubst(vgtool,[^exp-])[\"\n\t\t])\n\t\tAC_SUBST([ENABLE_VALGRIND_]vgtool,[$enable_valgrind_]vgtool)\n\t])\n\tAC_SUBST([valgrind_tools],[\"]m4_join([ ], valgrind_tool_list)[\"])\n\tAC_SUBST([valgrind_enabled_tools],[$valgrind_enabled_tools])\n\n[VALGRIND_CHECK_RULES='\n# Valgrind check\n#\n# Optional:\n#  - VALGRIND_SUPPRESSIONS_FILES: Space-separated list of Valgrind suppressions\n#    files to load. (Default: empty)\n#  - VALGRIND_FLAGS: General flags to pass to all Valgrind tools.\n#    (Default: --num-callers=30)\n#  - VALGRIND_$toolname_FLAGS: Flags to pass to Valgrind $toolname (one of:\n#    memcheck, helgrind, drd, sgcheck). (Default: various)\n\n# Optional variables\nVALGRIND_SUPPRESSIONS ?= $(addprefix --suppressions=,$(VALGRIND_SUPPRESSIONS_FILES))\nVALGRIND_FLAGS ?= --num-callers=30\nVALGRIND_memcheck_FLAGS ?= --leak-check=full --show-reachable=no\nVALGRIND_helgrind_FLAGS ?= --history-level=approx\nVALGRIND_drd_FLAGS ?=\nVALGRIND_sgcheck_FLAGS ?=\n\n# Internal use\nvalgrind_log_files = $(addprefix test-suite-,$(addsuffix .log,$(valgrind_tools)))\n\nvalgrind_memcheck_flags = --tool=memcheck $(VALGRIND_memcheck_FLAGS)\nvalgrind_helgrind_flags = --tool=helgrind $(VALGRIND_helgrind_FLAGS)\nvalgrind_drd_flags = --tool=drd $(VALGRIND_drd_FLAGS)\nvalgrind_sgcheck_flags = --tool=exp-sgcheck $(VALGRIND_sgcheck_FLAGS)\n\nvalgrind_quiet = $(valgrind_quiet_$(V))\nvalgrind_quiet_ = $(valgrind_quiet_$(AM_DEFAULT_VERBOSITY))\nvalgrind_quiet_0 = --quiet\nvalgrind_v_use   = $(valgrind_v_use_$(V))\nvalgrind_v_use_  = $(valgrind_v_use_$(AM_DEFAULT_VERBOSITY))\nvalgrind_v_use_0 = @echo \"  USE   \" $(patsubst check-valgrind-%,%,$''@):;\n\n# Support running with and without libtool.\nifneq ($(LIBTOOL),)\nvalgrind_lt = $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=execute\nelse\nvalgrind_lt =\nendif\n\n# Use recursive makes in order to ignore errors during check\ncheck-valgrind:\nifeq ($(VALGRIND_ENABLED),yes)\n\t-$(A''M_V_at)$(foreach tool,$(valgrind_enabled_tools), \\\n\t\t$(MAKE) $(AM_MAKEFLAGS) -k check-valgrind-$(tool); \\\n\t)\nelse\n\t@echo \"Need to reconfigure with --enable-valgrind\"\nendif\n\n# Valgrind running\nVALGRIND_TESTS_ENVIRONMENT = \\\n\t$(TESTS_ENVIRONMENT) \\\n\tenv VALGRIND=$(VALGRIND) \\\n\tG_SLICE=always-malloc,debug-blocks \\\n\tG_DEBUG=fatal-warnings,fatal-criticals,gc-friendly\n\nVALGRIND_LOG_COMPILER = test/test-suite.sh $(VALGRIND_SUPPRESSIONS) $(VALGRIND_FLAGS)\n#\t$(valgrind_lt) \\\n#\t$(VALGRIND) $(VALGRIND_SUPPRESSIONS) --error-exitcode=1 $(VALGRIND_FLAGS)\n\ndefine valgrind_tool_rule =\ncheck-valgrind-$(1):\nifeq ($$(VALGRIND_ENABLED)-$$(ENABLE_VALGRIND_$(1)),yes-yes)\n\t$$(valgrind_v_use)$$(MAKE) check-TESTS \\\n\t\tTESTS_ENVIRONMENT=\"$$(VALGRIND_TESTS_ENVIRONMENT)\" \\\n\t\tLOG_COMPILER=\"$$(VALGRIND_LOG_COMPILER)\" \\\n\t\tLOG_FLAGS=\"$$(valgrind_$(1)_flags)\" \\\n\t\tTEST_SUITE_LOG=test-suite-$(1).log\nelse ifeq ($$(VALGRIND_ENABLED),yes)\n\t@echo \"Need to reconfigure with --enable-valgrind-$(1)\"\nelse\n\t@echo \"Need to reconfigure with --enable-valgrind\"\nendif\nendef\n\n$(foreach tool,$(valgrind_tools),$(eval $(call valgrind_tool_rule,$(tool))))\n\nA''M_DISTCHECK_CONFIGURE_FLAGS ?=\nA''M_DISTCHECK_CONFIGURE_FLAGS += --disable-valgrind\n\nMOSTLYCLEANFILES ?=\nMOSTLYCLEANFILES += $(valgrind_log_files)\n\n.PHONY: check-valgrind $(add-prefix check-valgrind-,$(valgrind_tools))\n']\n\n\tAC_SUBST([VALGRIND_CHECK_RULES])\n\tm4_ifdef([_AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE([VALGRIND_CHECK_RULES])])\n])\n"
  },
  {
    "path": "build/curl.m4",
    "content": "dnl Check for CURL Libraries\ndnl Sets:\ndnl  CURL_CFLAGS\ndnl  CURL_LDADD\ndnl  CURL_LDFLAGS\ndnl  CURL_VERSION\ndnl  CURL_DISPLAY\ndnl  CURL_FOUND\n\nAC_DEFUN([CHECK_CURL], [\nMSC_CHECK_LIB([CURL], [libcurl], [curl/curl.h], [curl], [-DWITH_CURL], [7.15.1])\n\n# Post-processing: TLSv1.2 version check\nif test \"x${CURL_FOUND}\" = \"x1\" && test -n \"${CURL_VERSION}\"; then\n    AC_MSG_CHECKING([if libcurl supports TLSv1.2])\n    _msc_curl_tlsv2_ver=`echo 7.34.0 | awk -F. '{print (\\$ 1 * 1000000) + (\\$ 2 * 1000) + \\$ 3}'`\n    _msc_curl_ver=`echo ${CURL_VERSION} | awk -F. '{print (\\$ 1 * 1000000) + (\\$ 2 * 1000) + \\$ 3}'`\n    if test \"${_msc_curl_tlsv2_ver}\" -le \"${_msc_curl_ver}\" 2>/dev/null; then\n        AC_MSG_RESULT([yes])\n        CURL_CFLAGS=\"${CURL_CFLAGS} -DWITH_CURL_SSLVERSION_TLSv1_2\"\n    else\n        AC_MSG_RESULT([no])\n    fi\n\n    # Check/warn if GnuTLS is used\n    AC_MSG_CHECKING([if libcurl is linked with gnutls])\n    _msc_curl_uses_gnutls=`echo ${CURL_LDADD} | grep gnutls | wc -l`\n    if test \"$_msc_curl_uses_gnutls\" -ne 0; then\n        AC_MSG_RESULT([yes])\n        AC_MSG_NOTICE([NOTE: curl linked with gnutls may be buggy, openssl recommended])\n    else\n        AC_MSG_RESULT([no])\n    fi\nfi\n\n]) # AC_DEFUN [CHECK_CURL]\n"
  },
  {
    "path": "build/libgeoip.m4",
    "content": "dnl Check for GeoIP Libraries\ndnl Sets:\ndnl  GEOIP_CFLAGS\ndnl  GEOIP_LDADD\ndnl  GEOIP_LDFLAGS\ndnl  GEOIP_VERSION\ndnl  GEOIP_DISPLAY\ndnl  GEOIP_FOUND\n\nAC_DEFUN([PROG_GEOIP], [\nMSC_CHECK_LIB([GEOIP], [geoip2 geoip GeoIP], [GeoIPCity.h], [GeoIP], [-DWITH_GEOIP])\n]) # AC_DEFUN [PROG_GEOIP]\n"
  },
  {
    "path": "build/libmaxmind.m4",
    "content": "dnl Check for MaxMind Libraries\ndnl Sets:\ndnl  MAXMIND_CFLAGS\ndnl  MAXMIND_LDADD\ndnl  MAXMIND_LDFLAGS\ndnl  MAXMIND_VERSION\ndnl  MAXMIND_DISPLAY\ndnl  MAXMIND_FOUND\n\nAC_DEFUN([PROG_MAXMIND], [\nMSC_CHECK_LIB([MAXMIND], [libmaxminddb], [maxminddb.h], [maxminddb], [-DWITH_MAXMIND])\n]) # AC_DEFUN [PROG_MAXMIND]\n"
  },
  {
    "path": "build/libxml.m4",
    "content": "dnl Check for LIBXML2 Libraries\ndnl Sets:\ndnl  LIBXML2_CFLAGS\ndnl  LIBXML2_LDADD\ndnl  LIBXML2_LDFLAGS\ndnl  LIBXML2_VERSION\ndnl  LIBXML2_DISPLAY\ndnl  LIBXML2_FOUND\n\nAC_DEFUN([CHECK_LIBXML2], [\nMSC_CHECK_LIB([LIBXML2], [libxml-2.0], [libxml/parser.h], [xml2], [-DWITH_LIBXML2], [2.6.29], [libxml])\n]) # AC_DEFUN [CHECK_LIBXML2]\n"
  },
  {
    "path": "build/lmdb.m4",
    "content": "dnl Check for LMDB Libraries\ndnl LMDB is disabled by default; only enabled when --with-lmdb is given.\ndnl Sets:\ndnl  LMDB_CFLAGS\ndnl  LMDB_LDADD\ndnl  LMDB_LDFLAGS\ndnl  LMDB_VERSION\ndnl  LMDB_DISPLAY\ndnl  LMDB_FOUND\n\nAC_DEFUN([PROG_LMDB], [\n\n# LMDB is opt-in: auto-detect finds it but we only activate when\n# --with-lmdb or --with-lmdb=PATH is given explicitly.\nMSC_CHECK_LIB([LMDB], [lmdb], [lmdb.h], [lmdb], [-DWITH_LMDB])\n\n# If LMDB was found by auto-detection (no explicit --with-lmdb) treat it\n# as disabled since LMDB is opt-in.\n_msc_lmdb_with_val=\"$with_lmdb\"\nif test \"x${_msc_lmdb_with_val}\" = \"x\" && test \"x${LMDB_FOUND}\" = \"x1\"; then\n    LMDB_FOUND=2\n    LMDB_CFLAGS=\"\"\n    LMDB_LDADD=\"\"\n    LMDB_LDFLAGS=\"\"\n    LMDB_DISPLAY=\"\"\n    AC_MSG_NOTICE([LMDB is disabled by default. Use --with-lmdb to enable.])\nfi\n\n]) # AC_DEFUN [PROG_LMDB]\n"
  },
  {
    "path": "build/lua.m4",
    "content": "dnl Check for LUA Libraries\ndnl Sets:\ndnl  LUA_CFLAGS\ndnl  LUA_LDADD\ndnl  LUA_LDFLAGS\ndnl  LUA_DISPLAY\ndnl  LUA_FOUND\n\nAC_DEFUN([CHECK_LUA], [\nMSC_CHECK_LIB([LUA], [lua54 lua5.4 lua-5.4 lua53 lua5.3 lua-5.3 lua52 lua5.2 lua-5.2 lua51 lua5.1 lua-5.1 luajit lua], [lua.h], [lua5.4 lua5.3 lua5.2 lua5.1 luajit-5.1 lua], [-DWITH_LUA])\n\n# Post-processing: detect Lua version and add version-specific defines\nif test \"x${LUA_FOUND}\" = \"x1\"; then\n\n    # Use version already detected by MSC_CHECK_LIB (from pkg-config) if available\n    if test -n \"${LUA_VERSION}\" && test \"x${LUA_VERSION}\" != \"xunknown\"; then\n        case ${LUA_VERSION} in\n            5.1*) LUA_CFLAGS=\"-DWITH_LUA_5_1 ${LUA_CFLAGS}\" ;;\n            5.2*) LUA_CFLAGS=\"-DWITH_LUA_5_2 ${LUA_CFLAGS}\" ;;\n            5.3*) LUA_CFLAGS=\"-DWITH_LUA_5_3 ${LUA_CFLAGS}\" ;;\n            5.4*) LUA_CFLAGS=\"-DWITH_LUA_5_4 ${LUA_CFLAGS}\" ;;\n            2.0*) LUA_CFLAGS=\"-DWITH_LUA_5_1 ${LUA_CFLAGS}\" ;;\n            2.1*) LUA_CFLAGS=\"-DWITH_LUA_5_1 -DWITH_LUA_JIT_2_1 ${LUA_CFLAGS}\" ;;\n        esac\n        AC_MSG_NOTICE([LUA version: ${LUA_VERSION}])\n    fi\n\n    # If no version detected yet, try compile tests\n    if test -z \"${LUA_VERSION}\" || test \"x${LUA_VERSION}\" = \"xunknown\"; then\n        LUA_VERSION=\"\"\n        _msc_save_CFLAGS=$CFLAGS\n        CFLAGS=\"${LUA_CFLAGS} ${CFLAGS}\"\n\n        AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include <lua.h> ]],\n            [[ #if (LUA_VERSION_NUM == 504)\n               return 0;\n               #else\n               #error not 5.4\n               #endif ]])],\n            [ _msc_lua_ver=504 ], [ _msc_lua_ver=\"\" ])\n\n        if test -z \"$_msc_lua_ver\"; then\n            AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include <lua.h> ]],\n                [[ #if (LUA_VERSION_NUM == 503)\n                   return 0;\n                   #else\n                   #error not 5.3\n                   #endif ]])],\n                [ _msc_lua_ver=503 ], [ _msc_lua_ver=\"\" ])\n        fi\n\n        if test -z \"$_msc_lua_ver\"; then\n            AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include <lua.h> ]],\n                [[ #if (LUA_VERSION_NUM == 502)\n                   return 0;\n                   #else\n                   #error not 5.2\n                   #endif ]])],\n                [ _msc_lua_ver=502 ], [ _msc_lua_ver=\"\" ])\n        fi\n\n        if test -z \"$_msc_lua_ver\"; then\n            AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include <lua.h> ]],\n                [[ #if (LUA_VERSION_NUM == 501)\n                   return 0;\n                   #else\n                   #error not 5.1\n                   #endif ]])],\n                [ _msc_lua_ver=501 ], [ _msc_lua_ver=\"\" ])\n        fi\n\n        CFLAGS=$_msc_save_CFLAGS\n\n        case $_msc_lua_ver in\n            501) LUA_CFLAGS=\"-DWITH_LUA_5_1 ${LUA_CFLAGS}\" ;;\n            502) LUA_CFLAGS=\"-DWITH_LUA_5_2 ${LUA_CFLAGS}\" ;;\n            503) LUA_CFLAGS=\"-DWITH_LUA_5_3 ${LUA_CFLAGS}\" ;;\n            504) LUA_CFLAGS=\"-DWITH_LUA_5_4 ${LUA_CFLAGS}\" ;;\n        esac\n        if test -n \"$_msc_lua_ver\"; then\n            AC_MSG_NOTICE([LUA version from compile test: $_msc_lua_ver])\n        fi\n    fi\n\n    LUA_DISPLAY=\"${LUA_LDADD} ${LUA_LDFLAGS}, ${LUA_CFLAGS}\"\nfi\n\n]) # AC_DEFUN [CHECK_LUA]\n"
  },
  {
    "path": "build/msc_find_lib.m4",
    "content": "dnl MSC_CHECK_LIB: Generic library detection macro\ndnl\ndnl MSC_CHECK_LIB(NAME, PKG_NAMES, HEADER, LIB_NAMES, EXTRA_CFLAGS,\ndnl               [MIN_VERSION], [WITH_NAME])\ndnl\ndnl Detects a library via pkg-config first, then falls back to manual\ndnl file-system scanning. Preserves the --with-LIB=PATH|yes|no interface.\ndnl\ndnl Sets and AC_SUBSTs:\ndnl   ${NAME}_CFLAGS, ${NAME}_LDADD, ${NAME}_LDFLAGS,\ndnl   ${NAME}_VERSION, ${NAME}_DISPLAY, ${NAME}_FOUND (0/1/2)\ndnl\ndnl NAME         - Variable prefix (e.g., YAJL, CURL, LIBXML2)\ndnl PKG_NAMES    - Space-separated pkg-config names to try\ndnl HEADER       - Header file to look for (e.g., yajl/yajl_parse.h)\ndnl LIB_NAMES    - Space-separated library names for -l flags\ndnl EXTRA_CFLAGS - Additional CFLAGS when found (e.g., -DWITH_YAJL)\ndnl MIN_VERSION  - Optional minimum version for pkg-config check\ndnl WITH_NAME    - Optional --with-X name if different from lowercased NAME\n\nAC_DEFUN([MSC_CHECK_LIB], [\nm4_pushdef([_MSC_NAME], [$1])dnl\nm4_pushdef([_MSC_PKG_NAMES], [$2])dnl\nm4_pushdef([_MSC_HEADER], [$3])dnl\nm4_pushdef([_MSC_LIB_NAMES], [$4])dnl\nm4_pushdef([_MSC_EXTRA_CFLAGS], [$5])dnl\nm4_pushdef([_MSC_MIN_VERSION], [$6])dnl\nm4_pushdef([_MSC_WITH_NAME], [m4_default([$7], m4_tolower([$1]))])dnl\nm4_pushdef([_MSC_POSSIBLE_PATHS], [/usr/local /usr /opt /opt/local /usr/lib /usr/local/lib /usr/lib64])dnl\nm4_pushdef([_MSC_POSSIBLE_EXTENSIONS], [so la sl dll dylib])dnl\n\n# Initialize variables\n$1_VERSION=\"\"\n$1_CFLAGS=\"\"\n$1_LDADD=\"\"\n$1_LDFLAGS=\"\"\n$1_DISPLAY=\"\"\n$1_FOUND=0\n_msc_[]m4_tolower($1)[]_mandatory=\"\"\n_msc_[]m4_tolower($1)[]_disabled=\"\"\n\nAC_ARG_WITH(\n    _MSC_WITH_NAME,\n    [AS_HELP_STRING([--with-]_MSC_WITH_NAME[=PATH],\n        [Path to ]_MSC_NAME[ prefix. Use 'no' to disable.])])\n\n# Get the value of the --with flag\n_msc_with_val=\"$with_[]m4_translit(_MSC_WITH_NAME, [-], [_])\"\n\nif test \"x${_msc_with_val}\" = \"xno\"; then\n    AC_MSG_NOTICE([$1 support disabled via --without-]_MSC_WITH_NAME)\n    _msc_[]m4_tolower($1)[]_disabled=yes\nelif test \"x${_msc_with_val}\" = \"xyes\"; then\n    _msc_[]m4_tolower($1)[]_mandatory=yes\n    AC_MSG_NOTICE([$1 support marked as mandatory])\n    # Try pkg-config\n    _MSC_TRY_PKG_CONFIG([$1], [_MSC_PKG_NAMES], [_MSC_MIN_VERSION])\n    if test -z \"${$1_VERSION}\"; then\n        _MSC_TRY_MANUAL([$1], [_MSC_HEADER], [_MSC_LIB_NAMES])\n    fi\nelif test \"x${_msc_with_val}\" = \"x\"; then\n    # Auto-detect\n    AC_MSG_NOTICE([Auto-detecting $1...])\n    _MSC_TRY_PKG_CONFIG([$1], [_MSC_PKG_NAMES], [_MSC_MIN_VERSION])\n    if test -z \"${$1_VERSION}\"; then\n        _MSC_TRY_MANUAL([$1], [_MSC_HEADER], [_MSC_LIB_NAMES])\n    fi\nelse\n    # Specific path provided\n    _msc_[]m4_tolower($1)[]_mandatory=yes\n    _MSC_TRY_PKG_CONFIG_AT([$1], [_MSC_PKG_NAMES], [_MSC_MIN_VERSION], [${_msc_with_val}])\n    if test -z \"${$1_VERSION}\"; then\n        _MSC_CHECK_AT([$1], [_MSC_HEADER], [_MSC_LIB_NAMES], [${_msc_with_val}])\n    fi\nfi\n\n# Evaluate results\nif test -n \"${$1_LDADD}\" || test -n \"${$1_VERSION}\"; then\n    $1_FOUND=1\n    AC_MSG_NOTICE([using $1 v${$1_VERSION}])\n    $1_CFLAGS=\"_MSC_EXTRA_CFLAGS ${$1_CFLAGS}\"\n    if test -z \"${$1_DISPLAY}\"; then\n        $1_DISPLAY=\"${$1_LDADD}, ${$1_CFLAGS}\"\n    fi\n    AC_SUBST($1_VERSION)\n    AC_SUBST($1_LDADD)\n    AC_SUBST($1_LDFLAGS)\n    AC_SUBST($1_CFLAGS)\n    AC_SUBST($1_DISPLAY)\nelif test -n \"${_msc_[]m4_tolower($1)[]_disabled}\"; then\n    $1_FOUND=2\nelif test -n \"${_msc_[]m4_tolower($1)[]_mandatory}\"; then\n    AC_MSG_ERROR([$1 was explicitly requested but not found])\nelse\n    AC_MSG_NOTICE([$1 library not found])\n    $1_FOUND=0\nfi\n\nAC_SUBST($1_FOUND)\n\nm4_popdef([_MSC_POSSIBLE_EXTENSIONS])dnl\nm4_popdef([_MSC_POSSIBLE_PATHS])dnl\nm4_popdef([_MSC_WITH_NAME])dnl\nm4_popdef([_MSC_MIN_VERSION])dnl\nm4_popdef([_MSC_EXTRA_CFLAGS])dnl\nm4_popdef([_MSC_LIB_NAMES])dnl\nm4_popdef([_MSC_HEADER])dnl\nm4_popdef([_MSC_PKG_NAMES])dnl\nm4_popdef([_MSC_NAME])dnl\n]) # MSC_CHECK_LIB\n\n\ndnl _MSC_TRY_PKG_CONFIG(NAME, PKG_NAMES, MIN_VERSION)\ndnl Try to find the library via pkg-config\nAC_DEFUN([_MSC_TRY_PKG_CONFIG], [\nif test -n \"${PKG_CONFIG}\"; then\n    _msc_pkg_name=\"\"\n    for _msc_p in $2; do\n        if test -n \"$3\"; then\n            if ${PKG_CONFIG} --exists \"${_msc_p} >= $3\" 2>/dev/null; then\n                _msc_pkg_name=\"${_msc_p}\"\n                break\n            fi\n        else\n            if ${PKG_CONFIG} --exists \"${_msc_p}\" 2>/dev/null; then\n                _msc_pkg_name=\"${_msc_p}\"\n                break\n            fi\n        fi\n    done\n    if test -n \"${_msc_pkg_name}\"; then\n        $1_VERSION=\"`${PKG_CONFIG} ${_msc_pkg_name} --modversion`\"\n        $1_CFLAGS=\"`${PKG_CONFIG} ${_msc_pkg_name} --cflags`\"\n        $1_LDADD=\"`${PKG_CONFIG} ${_msc_pkg_name} --libs-only-l`\"\n        $1_LDFLAGS=\"`${PKG_CONFIG} ${_msc_pkg_name} --libs-only-L --libs-only-other`\"\n        $1_DISPLAY=\"${$1_LDADD}, ${$1_CFLAGS}\"\n        AC_MSG_NOTICE([$1 found via pkg-config: ${_msc_pkg_name} v${$1_VERSION}])\n    fi\nfi\n]) # _MSC_TRY_PKG_CONFIG\n\n\ndnl _MSC_TRY_PKG_CONFIG_AT(NAME, PKG_NAMES, MIN_VERSION, PATH)\ndnl Try pkg-config with PKG_CONFIG_PATH set to a specific location\nAC_DEFUN([_MSC_TRY_PKG_CONFIG_AT], [\nif test -n \"${PKG_CONFIG}\"; then\n    _msc_save_pkg_config_path=\"${PKG_CONFIG_PATH}\"\n    PKG_CONFIG_PATH=\"$4/lib/pkgconfig:$4/lib64/pkgconfig:$4/share/pkgconfig:${PKG_CONFIG_PATH}\"\n    export PKG_CONFIG_PATH\n    _MSC_TRY_PKG_CONFIG([$1], [$2], [$3])\n    PKG_CONFIG_PATH=\"${_msc_save_pkg_config_path}\"\n    export PKG_CONFIG_PATH\nfi\n]) # _MSC_TRY_PKG_CONFIG_AT\n\n\ndnl _MSC_TRY_MANUAL(NAME, HEADER, LIB_NAMES)\ndnl Try to find the library by scanning common paths\nAC_DEFUN([_MSC_TRY_MANUAL], [\nfor _msc_search_path in /usr/local /usr /opt /opt/local /usr/lib /usr/local/lib /usr/lib64; do\n    _MSC_CHECK_AT([$1], [$2], [$3], [${_msc_search_path}])\n    if test -n \"${$1_VERSION}\"; then\n        break\n    fi\n    # Also check if LDADD was set (version may not always be detected manually)\n    if test -n \"${$1_LDADD}\"; then\n        break\n    fi\ndone\n]) # _MSC_TRY_MANUAL\n\n\ndnl _MSC_CHECK_AT(NAME, HEADER, LIB_NAMES, PATH)\ndnl Check for a library at a specific path\nAC_DEFUN([_MSC_CHECK_AT], [\n_msc_check_lib_path=\"\"\n_msc_check_lib_name=\"\"\n_msc_check_lib_file=\"\"\n_msc_check_inc_path=\"\"\n\n# Search for library files\nfor _msc_ext in so la sl dll dylib; do\n    for _msc_ln in $3; do\n        for _msc_try_path in \\\n            \"$4/lib${_msc_ln}.${_msc_ext}\" \\\n            \"$4/lib/lib${_msc_ln}.${_msc_ext}\" \\\n            \"$4/lib64/lib${_msc_ln}.${_msc_ext}\" \\\n            \"$4/lib/x86_64-linux-gnu/lib${_msc_ln}.${_msc_ext}\" \\\n            \"$4/lib/i386-linux-gnu/lib${_msc_ln}.${_msc_ext}\"; do\n            if test -e \"${_msc_try_path}\"; then\n                _msc_check_lib_path=\"`dirname ${_msc_try_path}`\"\n                _msc_check_lib_name=\"${_msc_ln}\"\n                _msc_check_lib_file=\"${_msc_try_path}\"\n                break 3\n            fi\n        done\n    done\ndone\n\n# Search for header file\n_msc_header_base=\"`basename $2`\"\n_msc_header_dir=\"`dirname $2`\"\nif test \"${_msc_header_dir}\" = \".\"; then\n    # Simple header name (e.g., \"lmdb.h\")\n    if test -e \"$4/include/$2\"; then\n        _msc_check_inc_path=\"$4/include\"\n    elif test -e \"$4/$2\"; then\n        _msc_check_inc_path=\"$4\"\n    fi\nelse\n    # Header with subdirectory (e.g., \"yajl/yajl_parse.h\")\n    if test -e \"$4/include/$2\"; then\n        _msc_check_inc_path=\"$4/include\"\n    elif test -e \"$4/$2\"; then\n        _msc_check_inc_path=\"$4\"\n    fi\nfi\n\nif test -n \"${_msc_check_lib_path}\" && test -n \"${_msc_check_inc_path}\"; then\n    AC_MSG_NOTICE([$1 headers found at: ${_msc_check_inc_path}])\n    AC_MSG_NOTICE([$1 library found at: ${_msc_check_lib_file}])\n    $1_CFLAGS=\"-I${_msc_check_inc_path}\"\n    $1_LDADD=\"-l${_msc_check_lib_name}\"\n    $1_LDFLAGS=\"-L${_msc_check_lib_path}\"\n    $1_DISPLAY=\"${_msc_check_lib_file}, ${_msc_check_inc_path}\"\n    # Version is unknown from manual detection\n    if test -z \"${$1_VERSION}\"; then\n        $1_VERSION=\"unknown\"\n    fi\nfi\n]) # _MSC_CHECK_AT\n\n\ndnl MSC_STATUS_LIB(DISPLAY_NAME, VAR_PREFIX)\ndnl Print a status line for the configure summary\nAC_DEFUN([MSC_STATUS_LIB], [\nif test \"x${$2_FOUND}\" = \"x0\"; then\n    echo \"   + $1 ....not found\"\nfi\nif test \"x${$2_FOUND}\" = \"x1\"; then\n    AS_ECHO_N([\"   + $1 ....found \"])\n    if ! test \"x${$2_VERSION}\" = \"x\"; then\n        echo \"v${$2_VERSION}\"\n    else\n        echo \"\"\n    fi\n    echo \"      ${$2_DISPLAY}\"\nfi\nif test \"x${$2_FOUND}\" = \"x2\"; then\n    echo \"   + $1 ....disabled\"\nfi\n]) # MSC_STATUS_LIB\n\n\ndnl MSC_ARG_ENABLE_BOOL(NAME, HELP_TEXT, DEFAULT, VARIABLE)\ndnl Wrapper for boolean AC_ARG_ENABLE options\nAC_DEFUN([MSC_ARG_ENABLE_BOOL], [\nAC_ARG_ENABLE($1,\n    [AS_HELP_STRING([--enable-$1],[$2])],\n    [case \"${enableval}\" in\n        yes) $4=true ;;\n        no)  $4=false ;;\n        *) AC_MSG_ERROR([bad value ${enableval} for --enable-$1]) ;;\n    esac],\n    [$4=$3])\n]) # MSC_ARG_ENABLE_BOOL\n"
  },
  {
    "path": "build/pcre.m4",
    "content": "dnl Check for PCRE Libraries\ndnl Sets:\ndnl  PCRE_CFLAGS\ndnl  PCRE_LDADD\ndnl  PCRE_LDFLAGS\ndnl  PCRE_VERSION\ndnl  PCRE_FOUND\n\nPCRE_CONFIG=\"\"\nPCRE_VERSION=\"\"\nPCRE_CPPFLAGS=\"\"\nPCRE_CFLAGS=\"\"\nPCRE_LDFLAGS=\"\"\nPCRE_LDADD=\"\"\nPCRE_LD_PATH=\"\"\n\nAC_DEFUN([CHECK_PCRE], [\nMSC_CHECK_LIB([PCRE], [libpcre], [pcre.h], [pcre], [-DWITH_PCRE])\n\n# Post-processing: JIT detection\nif test \"x${PCRE_FOUND}\" = \"x1\" && test -n \"${PCRE_VERSION}\"; then\n    AC_MSG_CHECKING([for PCRE JIT])\n    _msc_save_CFLAGS=$CFLAGS\n    _msc_save_LDFLAGS=$LDFLAGS\n    _msc_save_LIBS=$LIBS\n    CFLAGS=\"${PCRE_CFLAGS} ${CFLAGS}\"\n    LDFLAGS=\"${PCRE_LDADD} ${LDFLAGS}\"\n    LIBS=\"${PCRE_LDADD} ${LIBS}\"\n    AC_LINK_IFELSE(\n        [AC_LANG_PROGRAM([[ #include <pcre.h> ]],\n           [[ pcre_jit_exec(NULL, NULL, NULL, 0, 0, 0, NULL, 0, NULL); ]])],\n        [ _msc_pcre_jit_available=yes ],\n        [:]\n    )\n    if test \"x$_msc_pcre_jit_available\" = \"xyes\"; then\n        AC_MSG_RESULT([yes])\n        PCRE_CFLAGS=\"${PCRE_CFLAGS} -DPCRE_HAVE_JIT\"\n    else\n        AC_MSG_RESULT([no])\n    fi\n    CFLAGS=$_msc_save_CFLAGS\n    LDFLAGS=$_msc_save_LDFLAGS\n    LIBS=$_msc_save_LIBS\nfi\n\nAC_SUBST(PCRE_CONFIG)\nAC_SUBST(PCRE_CPPFLAGS)\nAC_SUBST(PCRE_LD_PATH)\n\n]) # AC_DEFUN [CHECK_PCRE]\n"
  },
  {
    "path": "build/pcre2.m4",
    "content": "dnl Check for PCRE2 Libraries\ndnl PCRE2 is enabled by default (mandatory unless --with-pcre is used).\ndnl Sets:\ndnl  PCRE2_CFLAGS\ndnl  PCRE2_LDADD\ndnl  PCRE2_LDFLAGS\ndnl  PCRE2_VERSION\ndnl  PCRE2_DISPLAY\ndnl  PCRE2_FOUND\n\nAC_DEFUN([PROG_PCRE2], [\nMSC_CHECK_LIB([PCRE2], [libpcre2-8 pcre2-8 pcre2], [pcre2.h], [pcre2-8], [])\n]) # AC_DEFUN [PROG_PCRE2]\n"
  },
  {
    "path": "build/release.sh",
    "content": "#!/bin/bash\n\ngit clean -xfdi\ngit submodule foreach --recursive git clean -xfdi\n\nVERSION=`git describe --tags`\nDIR_NAME=\"modsecurity-$VERSION\"\nTAR_NAME=\"modsecurity-$VERSION.tar.gz\"\n\nMY_DIR=${PWD##*/}\n./build.sh\n\ncd ..\ntar --transform \"s/^$MY_DIR/$DIR_NAME/\" -cvzf $TAR_NAME --exclude .git $MY_DIR\n\nsha256sum $TAR_NAME > $TAR_NAME.sha256\ngpg --detach-sign -a $TAR_NAME\n\ncd -\necho $TAR_NAME \": done.\"\n\n"
  },
  {
    "path": "build/ssdeep.m4",
    "content": "dnl Check for SSDEEP Libraries\ndnl Sets:\ndnl  SSDEEP_CFLAGS\ndnl  SSDEEP_LDADD\ndnl  SSDEEP_LDFLAGS\ndnl  SSDEEP_DISPLAY\ndnl  SSDEEP_FOUND\n\nAC_DEFUN([CHECK_SSDEEP], [\nMSC_CHECK_LIB([SSDEEP], [fuzzy], [fuzzy.h], [fuzzy], [-DWITH_SSDEEP])\n]) # AC_DEFUN [CHECK_SSDEEP]\n"
  },
  {
    "path": "build/win32/CMakeLists.txt",
    "content": "cmake_minimum_required(VERSION 3.24)\n\nset(BASE_DIR ${CMAKE_CURRENT_LIST_DIR}/../..)\n\noption(WITH_LMDB    \"Include LMDB support\"    OFF)\noption(WITH_LUA     \"Include LUA support\"     ON)\noption(WITH_LIBXML2 \"Include LibXML2 support\" ON)\noption(WITH_MAXMIND \"Include MaxMind support\" ON)\noption(WITH_CURL    \"Include CURL support\"    ON)\n\noption(USE_ASAN     \"Build with Address Sanitizer\" OFF)\n\n# common compiler settings\n\n# NOTE: MBEDTLS_CONFIG_FILE is not only required to compile the mbedtls subset in others, but also\n# when their headers are included while compiling libModSecurity\nadd_compile_definitions(WIN32 _CRT_SECURE_NO_WARNINGS MBEDTLS_CONFIG_FILE=\"mbedtls/mbedtls_config.h\")\n\n# set standards conformance preprocessor & compiler to align with cross-compiled codebase\n# NOTE: otherwise visual c++'s default compiler/preprocessor behaviour generates C4067 warnings\n# (unexpected tokens following preprocessor directive - expected a newline)\nadd_compile_options(/Zc:preprocessor /permissive-)\n\nif(USE_ASAN)\n  add_compile_options(/fsanitize=address)\n  add_link_options(/INFERASANLIBS /INCREMENTAL:no)\nendif()\n\n# libinjection\n\nproject(libinjection C)\n\nset(LIBINJECTION_DIR ${BASE_DIR}/others/libinjection)\n\nadd_library(libinjection STATIC ${LIBINJECTION_DIR}/src/libinjection_sqli.c ${LIBINJECTION_DIR}/src/libinjection_xss.c ${LIBINJECTION_DIR}/src/libinjection_html5.c)\n\n# get libinjection version with git describe\nexecute_process(\n    COMMAND git describe\n    WORKING_DIRECTORY ${LIBINJECTION_DIR}\n    OUTPUT_VARIABLE LIBINJECTION_VERSION\n    OUTPUT_STRIP_TRAILING_WHITESPACE\n)\n\nmessage(\"-- Detecting libinjection version - ${LIBINJECTION_VERSION}\")\n\ntarget_compile_definitions(libinjection PRIVATE LIBINJECTION_VERSION=\"${LIBINJECTION_VERSION}\")\n\n# mbedtls (mbedcrypto)\n\nproject(mbedcrypto C)\n\nset(MBEDTLS_DIR ${BASE_DIR}/others/mbedtls)\n\nadd_library(mbedcrypto STATIC ${MBEDTLS_DIR}/library/base64.c ${MBEDTLS_DIR}/library/sha1.c ${MBEDTLS_DIR}/library/md5.c ${MBEDTLS_DIR}/library/platform_util.c ${MBEDTLS_DIR}/library/constant_time.c)\n\ntarget_include_directories(mbedcrypto PRIVATE ${MBEDTLS_DIR}/include)\n\n# get mbedtls version with git describe\nexecute_process(\n    COMMAND git describe\n    WORKING_DIRECTORY ${MBEDTLS_DIR}\n    OUTPUT_VARIABLE MBEDTLS_VERSION\n    OUTPUT_STRIP_TRAILING_WHITESPACE\n)\n\nmessage(\"-- Detecting Mbed TLS version - ${MBEDTLS_VERSION}\")\n\n#\n# libModSecurity\n#\n\nproject(libModSecurity\n    VERSION\n        3.0.12\n    LANGUAGES\n        CXX\n)\n\nset(CMAKE_CXX_STANDARD 17)\nset(CMAKE_CXX_STANDARD_REQUIRED On)\nset(CMAKE_CXX_EXTENSIONS Off)\n\nset(PACKAGE_BUGREPORT \"security@modsecurity.org\")\nset(PACKAGE_NAME \"modsecurity\")\nset(PACKAGE_VERSION \"${PROJECT_VERSION}\")\nset(PACKAGE_STRING \"${PACKAGE_NAME} ${PACKAGE_VERSION}\")\nset(PACKAGE_TARNAME \"${PACKAGE_NAME}\")\n\nset(HAVE_YAJL     1)    # should always be one, mandatory dependency\nset(HAVE_GEOIP    0)    # should always be zero, no conan package available\nset(HAVE_SSDEEP   0)    # should always be zero, no conan package available\n\nmacro(enable_feature flag option)\n  if(${option})\n    set(${flag} 1)  # ON\n  else()\n    set(${flag} 0)  # OFF\n  endif()\nendmacro()\n\nenable_feature(HAVE_LMDB ${WITH_LMDB})\nenable_feature(HAVE_LUA ${WITH_LUA})\nenable_feature(HAVE_LIBXML2 ${WITH_LIBXML2})\nenable_feature(HAVE_MAXMIND ${WITH_MAXMIND})\nenable_feature(HAVE_CURL ${WITH_CURL})\n\ninclude(${CMAKE_CURRENT_LIST_DIR}/ConfigureChecks.cmake)\n\nconfigure_file(config.h.cmake ${BASE_DIR}/src/config.h)\n\nfind_package(PCRE2 REQUIRED)\nfind_package(Poco REQUIRED)\nfind_package(dirent REQUIRED)\t\t# used only by tests (check dirent::dirent refernces)\n\nmacro(include_package package flag)\n  if(${flag})\n    find_package(${package} REQUIRED)\n  endif()\nendmacro()\n\ninclude_package(yajl HAVE_YAJL)\ninclude_package(libxml2 HAVE_LIBXML2)\ninclude_package(lua HAVE_LUA)\ninclude_package(CURL HAVE_CURL)\ninclude_package(lmdb HAVE_LMDB)\ninclude_package(maxminddb HAVE_MAXMIND)\n\n# library\n#\n\n# NOTE: required to generate libModSecurity's import library (libModSecurity.lib), used by tests to link with shared library\nset(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)\n\nfile(GLOB_RECURSE libModSecuritySources ${BASE_DIR}/src/*.cc)\n\nadd_library(libModSecurity SHARED ${libModSecuritySources})\n\ntarget_compile_definitions(libModSecurity PRIVATE WITH_PCRE2)\ntarget_include_directories(libModSecurity PRIVATE ${BASE_DIR} ${BASE_DIR}/headers ${BASE_DIR}/others ${MBEDTLS_DIR}/include)\ntarget_link_libraries(libModSecurity PRIVATE pcre2::pcre2 libinjection mbedcrypto Poco::Poco Iphlpapi.lib)\n\nmacro(add_package_dependency project compile_definition link_library flag)\n  if(${flag})\n    target_compile_definitions(${project} PRIVATE ${compile_definition})\n    target_link_libraries(${project} PRIVATE ${link_library})\n  endif()\nendmacro()\n\nadd_package_dependency(libModSecurity WITH_YAJL yajl::yajl HAVE_YAJL)\nadd_package_dependency(libModSecurity WITH_LIBXML2 LibXml2::LibXml2 HAVE_LIBXML2)\nadd_package_dependency(libModSecurity WITH_LUA lua::lua HAVE_LUA)\nif(HAVE_LUA)\n  target_compile_definitions(libModSecurity PRIVATE WITH_LUA_5_4)\nendif()\nadd_package_dependency(libModSecurity MSC_WITH_CURL CURL::libcurl HAVE_CURL)\nadd_package_dependency(libModSecurity WITH_LMDB lmdb::lmdb HAVE_LMDB)\nadd_package_dependency(libModSecurity WITH_MAXMIND maxminddb::maxminddb HAVE_MAXMIND)\n\n# tests\n#\n\nproject(libModSecurityTests)\n\nfunction(setTestTargetProperties executable)\n  target_compile_definitions(${executable} PRIVATE WITH_PCRE2)\n  target_include_directories(${executable} PRIVATE ${BASE_DIR} ${BASE_DIR}/headers)\n  target_link_libraries(${executable} PRIVATE libModSecurity pcre2::pcre2 dirent::dirent)\n  add_package_dependency(${executable} WITH_YAJL yajl::yajl HAVE_YAJL)\nendfunction()\n\n# unit tests\nfile(GLOB unitTestSources ${BASE_DIR}/test/unit/*.cc)\nadd_executable(unit_tests ${unitTestSources} ${BASE_DIR}/test/common/custom_debug_log.cc)\nsetTestTargetProperties(unit_tests)\ntarget_compile_options(unit_tests PRIVATE /wd4805)\n\n# regression tests\nfile(GLOB regressionTestsSources ${BASE_DIR}/test/regression/*.cc)\nadd_executable(regression_tests ${regressionTestsSources} ${BASE_DIR}/test/common/custom_debug_log.cc)\nsetTestTargetProperties(regression_tests)\n\nmacro(add_regression_test_capability compile_definition flag)\n  if(${flag})\n    target_compile_definitions(regression_tests PRIVATE ${compile_definition})\n  endif()\nendmacro()\n\nadd_regression_test_capability(WITH_LUA HAVE_LUA)\nadd_regression_test_capability(WITH_CURL HAVE_CURL)\nadd_regression_test_capability(WITH_LMDB HAVE_LMDB)\nadd_regression_test_capability(WITH_MAXMIND HAVE_MAXMIND)\n\nenable_testing()\n\nfile(READ ${BASE_DIR}/test/test-suite.in TEST_FILES_RAW)\nstring(REPLACE \"\\n\" \";\" TEST_FILES ${TEST_FILES_RAW})\n\nforeach(TEST_FILE ${TEST_FILES})\n  # ignore comment lines\n  string(FIND ${TEST_FILE} \"#\" is_comment)\n  if(NOT is_comment EQUAL 0)\n    string(FIND ${TEST_FILE} \"TESTS+=\" is_valid_prefix)\n    if(NOT is_valid_prefix EQUAL 0)\n      message(FATAL_ERROR \"Invalid prefix in line: ${TEST_FILE}\")\n    endif()\n\n    # remove 'TESTS+=' prefix and 'test/' too because tests are launched\n    # from that directory\n    string(SUBSTRING ${TEST_FILE} 12 -1 TEST_FILE)\n\n    # test name\n    get_filename_component(TEST_NAME ${TEST_FILE} NAME_WE)\n\n    # determine test runner based on test path prefix\n    string(FIND ${TEST_FILE} \"test-cases/regression/\" is_regression_test)\n    if(is_regression_test EQUAL 0)\n        set(TEST_RUNNER \"regression_tests\")\n    else()\n        set(TEST_RUNNER \"unit_tests\")\n    endif()\n\n    add_test(NAME ${TEST_NAME} COMMAND ${TEST_RUNNER} ${TEST_FILE} WORKING_DIRECTORY ${BASE_DIR}/test)\n  endif()\nendforeach()\n\n# benchmark\nadd_executable(benchmark ${BASE_DIR}/test/benchmark/benchmark.cc)\nsetTestTargetProperties(benchmark)\n\n# rules_optimization\nadd_executable(rules_optimization ${BASE_DIR}/test/optimization/optimization.cc)\nsetTestTargetProperties(rules_optimization)\n\n\n# examples\n#\n\nproject(libModSecurityExamples)\n\nfunction(setExampleTargetProperties executable)\n  target_include_directories(${executable} PRIVATE ${BASE_DIR} ${BASE_DIR}/headers)\n  target_link_libraries(${executable} PRIVATE libModSecurity)\nendfunction()\n\n# simple_example_using_c\nadd_executable(simple_example_using_c ${BASE_DIR}/examples/simple_example_using_c/test.c)\nsetExampleTargetProperties(simple_example_using_c)\n\n# using_bodies_in_chunks\nadd_executable(using_bodies_in_chunks ${BASE_DIR}/examples/using_bodies_in_chunks/simple_request.cc)\nsetExampleTargetProperties(using_bodies_in_chunks)\n\n# reading_logs_via_rule_message\nadd_executable(reading_logs_via_rule_message ${BASE_DIR}/examples/reading_logs_via_rule_message/simple_request.cc)\nsetExampleTargetProperties(reading_logs_via_rule_message)\n\n# reading_logs_with_offset\nadd_executable(reading_logs_with_offset ${BASE_DIR}/examples/reading_logs_with_offset/read.cc)\nsetExampleTargetProperties(reading_logs_with_offset)\n\n# multithread\nadd_executable(multithread ${BASE_DIR}/examples/multithread/multithread.cc)\nsetExampleTargetProperties(multithread)\n\n# tools\n#\n\n# rules_check\nadd_executable(rules_check ${BASE_DIR}/tools/rules-check/rules-check.cc)\ntarget_include_directories(rules_check PRIVATE ${BASE_DIR} ${BASE_DIR}/headers)\ntarget_link_libraries(rules_check PRIVATE libModSecurity)\n"
  },
  {
    "path": "build/win32/ConfigureChecks.cmake",
    "content": "include(CheckIncludeFile)\ninclude(CheckIncludeFiles)\n\ncheck_include_file(\"dlfcn.h\" HAVE_DLFCN_H)\ncheck_include_file(\"inttypes.h\" HAVE_INTTYPES_H)\ncheck_include_file(\"stdint.h\" HAVE_STDINT_H)\ncheck_include_file(\"stdio.h\" HAVE_STDIO_H)\ncheck_include_file(\"stdlib.h\" HAVE_STDLIB_H)\ncheck_include_file(\"string\" HAVE_STRING)\ncheck_include_file(\"strings.h\" HAVE_STRINGS_H)\ncheck_include_file(\"string.h\" HAVE_STRING_H)\ncheck_include_file(\"sys/stat.h\" HAVE_SYS_STAT_H)\ncheck_include_file(\"sys/types.h\" HAVE_SYS_TYPES_H)\ncheck_include_file(\"sys/utsname.h\" HAVE_SYS_UTSNAME_H)\ncheck_include_file(\"unistd.h\" HAVE_UNISTD_H)\n\n#/* Define to 1 if you have the ANSI C header files. */\ncheck_include_files(\"stdlib.h;stdarg.h;string.h;float.h\" STDC_HEADERS)\n"
  },
  {
    "path": "build/win32/README.md",
    "content": "# libModSecurity Windows build information <!-- omit from toc -->\n\nThe Windows build of libModSecurity uses Build Tools for Visual Studio 2022 (for Visual C++ & CMake) and Conan package manager.\n\n## Contents <!-- omit from toc -->\n\n- [Prerequisites](#prerequisites)\n- [Build](#build)\n  - [Optional features](#optional-features)\n  - [Address Sanitizer](#address-sanitizer)\n  - [Docker container](#docker-container)\n\n## Prerequisites\n\n * [Build Tools for Visual Studio 2022](https://aka.ms/vs/17/release/vs_buildtools.exe)\n    * Install *Desktop development with C++* workload, which includes:\n        * MSVC C++ compiler\n        * Windows SDK\n        * CMake\n        * Address Sanitizer\n * [Conan package manager 2.10.2](https://github.com/conan-io/conan/releases/download/2.10.2/conan-2.10.2-windows-x86_64-installer.exe)\n    * Install and then setup the default Conan profile to use the MSVC C++ compiler:\n      1. Open a command-prompt and set the MSVC C++ compiler environment by executing: `C:\\BuildTools\\VC\\Auxiliary\\Build\\vcvars64.bat`\n      2. Execute: `conan profile detect --force`\n * [Git for Windows 2.44.0](https://github.com/git-for-windows/git/releases/download/v2.44.0.windows.1/Git-2.44.0-64-bit.exe)\n    * To clone the libModSecurity repository.\n    * NOTE: Make sure to initialize and update submodules (to get `libinjection` and regression tests)\n      * `git submodule init`\n      * `git submodule update`\n\n## Build\n\nInstall the prerequisites listed in the previous section, checkout libModSecurity and from the directory where it's located execute:\n\n```\nvcbuild.bat [build_configuration] [arch] [USE_ASAN]\n```\n\nwhere `[build_configuration]` can be: `Release` (default), `RelWithDebInfo`, `MinSizeRel` or `Debug`, and `[arch]` can be: `x86_64` (default) or `x86`.\n\nBuilt files will be located in the directory: `build\\win32\\build\\[build_configuration]` and include:\n\n * `libModSecurity.dll`\n * Executable files for test projects\n    * `unit_tests.exe`\n    * `regression_tests.exe`\n    * `benchmark.exe` \n    * `rules_optimization.exe`\n * Executable files for examples\n    * `simple_example_using_c.exe`\n    * `using_bodies_in_chunks.exe`\n    * `reading_logs_via_rule_message.exe`\n    * `reading_logs_with_offset.exe`\n    * `multithread.exe`\n * Executable files for tools\n    * `rules_check.exe`\n\nNOTE: When building a different configuration, it's recommended to reset:\n\n * the build directory: `build\\win32\\build`\n * previously built conan packages executing the command:\n    * `conan remove * -c`\n\n### Optional features\n\nBy default the following all the following features are enabled by including the associated third-party library through a Conan package:\n\n * libxml2 2.12.6 for XML processing support\n * libcurl 8.6.0 to support http requests from rules\n * libmaxminddb 1.9.1 to support reading MaxMind DB files.\n * LUA 5.4.6 to enable rules to run scripts in this language for extensibility\n * lmdb 0.9.31 in-memory database\n\nEach of these can be turned off by updating the associated `HAVE_xxx` variable (setting it to zero) in the beginning of the libModSecurity section of `CMakeLists.txt`.\n\n### Address Sanitizer\n\n[AddressSanitizer](https://github.com/google/sanitizers/wiki/AddressSanitizer) (aka ASan) is a memory error detector for C/C++.\n\nTo generate a build with *Address Sanitizer*, add the `USE_ASAN` optional third argument to `vcbuild.bat`. For example:\n   * `vcbuild.bat Debug x86_64 USE_ASAN`\n\nNOTE: `USE_ASAN` does not work with `Release` & `MinSizeRel` configurations because they do not include debug info (it is only compatible with `Debug` & `RelWithDebInfo` builds).\n\n * References\n   * [AddressSanitizer | Microsoft Learn](https://learn.microsoft.com/en-us/cpp/sanitizers/asan?view=msvc-170)\n   * [AddressSanitizer for Windows: x64 and Debug Build Support - C++ Team Blog (microsoft.com)](https://devblogs.microsoft.com/cppblog/asan-for-windows-x64-and-debug-build-support/)\n   * [AddressSanitizer language, build, and debugging reference | Microsoft Learn](https://learn.microsoft.com/en-us/cpp/sanitizers/asan-building?view=msvc-170)\n\n### Docker container\n\nA `Dockerfile` configuration file is provided in the `docker` subdir that creates a Windows container image which installs the [prerequisites](#prerequisites) and builds libModSecurity and other binaries.\n\nNOTE: Windows containers are supported in Docker Desktop for Windows, using the *Switch to Windows containers...* option on the context menu of the system tray icon.\n\nTo build the docker image, execute the following command (from the `build\\win32\\docker` directory):\n\n * `docker build -t libmodsecurity:latest -m 4GB .`\n   * Build type, architecture and build with Address Sanitizer can be configured through build arguments (`BUILD_TYPE`, `ARCH` & `USE_ASAN` respectively). For example, to generate a debug build, add the following argument:\n     * `--build-arg BUILD_TYPE=Debug`\n\nOnce the image is generated, the library and associated binaries (tests & examples) are located in the `C:\\src\\ModSecurity\\build\\win32\\build\\[build_type]` directory.\n\nTo extract the library (`libModSecurity.dll`) from the image, you can execute the following commands:\n\n * `docker container create --name [container_name] libmodsecurity`\n * `docker cp [container_name]:C:\\src\\ModSecurity\\build\\win32\\build\\[build_type]\\libModSecurity.dll .`\n   * NOTE: If you leave out the `libModSecurity.dll` filename out, you can copy all the built binaries (including examples & tests).\n\nAdditionally, the image can be used interactively for additional development work by executing:\n\n * `docker run -it libmodsecurity`\n"
  },
  {
    "path": "build/win32/conanfile.txt",
    "content": "[requires]\nyajl/2.1.0\npcre2/10.42\nlibxml2/2.12.6\nlua/5.4.6\nlibcurl/8.6.0\nlmdb/0.9.31\nlibmaxminddb/1.9.1\ndirent/1.24\npoco/1.13.3\n\n[generators]\nCMakeDeps\nCMakeToolchain\n"
  },
  {
    "path": "build/win32/config.h.cmake",
    "content": "/* config.h.cmake.  Based upon generated config.h.in.  */\n\n#ifndef MODSECURITY_CONFIG_H\n#define MODSECURITY_CONFIG_H 1\n\n/* Define to 1 if you have the <dlfcn.h> header file. */\n#cmakedefine HAVE_DLFCN_H\n\n/* Define to 1 if you have the <inttypes.h> header file. */\n#cmakedefine HAVE_INTTYPES_H\n\n/* Define to 1 if you have the <iostream> header file. */\n#cmakedefine HAVE_IOSTREAM\n\n/* Define to 1 if you have the <stdint.h> header file. */\n#cmakedefine HAVE_STDINT_H\n\n/* Define to 1 if you have the <stdio.h> header file. */\n#cmakedefine HAVE_STDIO_H\n\n/* Define to 1 if you have the <stdlib.h> header file. */\n#cmakedefine HAVE_STDLIB_H\n\n/* Define to 1 if you have the <string> header file. */\n#cmakedefine HAVE_STRING\n\n/* Define to 1 if you have the <strings.h> header file. */\n#cmakedefine HAVE_STRINGS_H\n\n/* Define to 1 if you have the <string.h> header file. */\n#cmakedefine HAVE_STRING_H\n\n/* Define to 1 if you have the <sys/stat.h> header file. */\n#cmakedefine HAVE_SYS_STAT_H\n\n/* Define to 1 if you have the <sys/types.h> header file. */\n#cmakedefine HAVE_SYS_TYPES_H\n\n/* Define to 1 if you have the <sys/utsname.h> header file. */\n#cmakedefine HAVE_SYS_UTSNAME_H\n\n/* Define to 1 if you have the <unistd.h> header file. */\n#cmakedefine HAVE_UNISTD_H\n\n/* Define if GeoIP is available */\n#cmakedefine HAVE_GEOIP\n\n/* Define if LMDB is available */\n#cmakedefine HAVE_LMDB\n\n/* Define if LUA is available */\n#cmakedefine HAVE_LUA\n\n/* Define if MaxMind is available */\n#cmakedefine HAVE_MAXMIND\n\n/* Define if SSDEEP is available */\n#cmakedefine HAVE_SSDEEP\n\n/* Define if YAJL is available */\n#cmakedefine HAVE_YAJL\n\n/* Define if libcurl is available */\n#cmakedefine HAVE_CURL\n\n/* Name of package */\n#define PACKAGE \"@PACKAGE_NAME@\"\n\n/* Define to the address where bug reports for this package should be sent. */\n#cmakedefine PACKAGE_BUGREPORT \"@PACKAGE_BUGREPORT@\"\n\n/* Define to the full name of this package. */\n#cmakedefine PACKAGE_NAME \"@PACKAGE_NAME@\"\n\n/* Define to the full name and version of this package. */\n#cmakedefine PACKAGE_STRING \"@PACKAGE_STRING@\"\n\n/* Define to the one symbol short name of this package. */\n#cmakedefine PACKAGE_TARNAME \"@PACKAGE_TARNAME@\"\n\n/* Define to the home page for this package. */\n#define PACKAGE_URL \"\"\n\n/* Define to the version of this package. */\n#cmakedefine PACKAGE_VERSION \"@PACKAGE_VERSION@\"\n\n/* Define to 1 if you have the ANSI C header files. */\n#ifndef STDC_HEADERS\n#cmakedefine STDC_HEADERS\n#endif\n\n#endif // ndef MODSECURITY_CONFIG_H"
  },
  {
    "path": "build/win32/docker/Dockerfile",
    "content": "# escape=`\n\nARG FROM_IMAGE=mcr.microsoft.com/windows/servercore:ltsc2022\nFROM ${FROM_IMAGE}\n\n# reset the shell.\nSHELL [\"cmd\", \"/S\", \"/C\"]\n\n# set up environment to collect install errors.\nCOPY InstallBuildTools.cmd C:\\TEMP\\\nADD https://aka.ms/vscollect.exe C:\\TEMP\\collect.exe\n\n# download channel for fixed install.\nARG CHANNEL_URL=https://aka.ms/vs/17/release/channel\nADD ${CHANNEL_URL} C:\\TEMP\\VisualStudio.chman\n\n# download and install Build Tools for Visual Studio 2022 for native desktop workload.\nADD https://aka.ms/vs/17/release/vs_buildtools.exe C:\\TEMP\\vs_buildtools.exe\nRUN C:\\TEMP\\InstallBuildTools.cmd C:\\TEMP\\vs_buildtools.exe --quiet --wait --norestart --nocache `\n    --channelUri C:\\TEMP\\VisualStudio.chman `\n    --installChannelUri C:\\TEMP\\VisualStudio.chman `\n    --add Microsoft.VisualStudio.Workload.VCTools  `\n    --includeRecommended `\n    --installPath C:\\BuildTools\n\n# download & install GIT\nARG GIT_VERSION=2.44.0\nARG GIT_BINARY=Git-${GIT_VERSION}-64-bit.exe\nARG GIT_URL=https://github.com/git-for-windows/git/releases/download/v${GIT_VERSION}.windows.1/${GIT_BINARY}\n\nCOPY git.inf C:\\TEMP\\\nARG INSTALLER=C:\\TEMP\\${GIT_BINARY}\nADD ${GIT_URL} ${INSTALLER}\nRUN %INSTALLER% /SP- /VERYSILENT /SUPPRESSMSGBOXES /NOCANCEL `\n    /NORESTART /CLOSEAPPLICATIONS /RESTARTAPPLICATIONS /LOADINF=git.inf\n\n# download & setup conan\nARG CONAN_VERSION=2.10.2\nARG CONAN_BINARY=conan-${CONAN_VERSION}-windows-x86_64-installer.exe\nARG CONAN_URL=https://github.com/conan-io/conan/releases/download/${CONAN_VERSION}/${CONAN_BINARY}\n\nARG INSTALLER=C:\\TEMP\\${CONAN_BINARY}\nADD ${CONAN_URL} ${INSTALLER}\nRUN %INSTALLER% /SP- /VERYSILENT /SUPPRESSMSGBOXES\n\n# setup conan profile\nRUN C:\\BuildTools\\VC\\Auxiliary\\Build\\vcvars64.bat && conan profile detect --force\n\n# download libModSecurity\n#\n\n# create src dir\nARG SRC_DIR=C:\\src\n\nWORKDIR C:\\\nRUN cmd.exe /C md %SRC_DIR%\n\n# libModSecurity\nWORKDIR ${SRC_DIR}\n\nARG MOD_SECURITY_TAG=v3/master\nRUN git clone -c advice.detachedHead=false --depth 1 --branch %MOD_SECURITY_TAG% https://github.com/owasp-modsecurity/ModSecurity.git\n\nARG MOD_SECURITY_DIR=${SRC_DIR}\\ModSecurity\nWORKDIR ${MOD_SECURITY_DIR}\n\n# fetch submodules (bindings/python, others/libinjection, test/test-cases/secrules-language-tests)\nRUN git submodule init\nRUN git submodule update\n\n# build libraries\n#\n\nARG BUILD_TYPE=Release\nARG ARCH=x86_64\nARG USE_ASAN=\n\nRUN C:\\BuildTools\\VC\\Auxiliary\\Build\\vcvars64.bat && vcbuild.bat %BUILD_TYPE% %ARCH% %USE_ASAN%\n\n# test suite\n#\n\n# setup test environment\nRUN cmd.exe /C md \\tmp\nRUN cmd.exe /C md \\bin\nRUN cmd.exe /C copy \"C:\\Program Files\\GIT\\usr\\bin\" \\bin > NUL\nRUN cmd.exe /C copy \"C:\\Program Files\\GIT\\usr\\bin\\echo.exe\" \\bin\\echo > NUL\n\n# disable tests that don't work on windows\nARG JQ_VERSION=1.7.1\nARG JQ_BINARY=jq-windows-amd64.exe\nARG JQ_URL=https://github.com/jqlang/jq/releases/download/jq-${JQ_VERSION}/${JQ_BINARY}\n\nARG JQ_BIN=C:\\TEMP\\jq.exe\nADD ${JQ_URL} ${JQ_BIN}\n\nWORKDIR ${MOD_SECURITY_DIR}\\test\\test-cases\\regression\n\nRUN %JQ_BIN% \"map(if .title == \\\"Test match variable (1/n)\\\" then .enabled = 0 else . end)\" issue-2423-msg-in-chain.json > tmp.json && move /Y tmp.json issue-2423-msg-in-chain.json\nRUN %JQ_BIN% \"map(if .title == \\\"Test match variable (2/n)\\\" then .enabled = 0 else . end)\" issue-2423-msg-in-chain.json > tmp.json && move /Y tmp.json issue-2423-msg-in-chain.json\nRUN %JQ_BIN% \"map(if .title == \\\"Test match variable (3/n)\\\" then .enabled = 0 else . end)\" issue-2423-msg-in-chain.json > tmp.json && move /Y tmp.json issue-2423-msg-in-chain.json\nRUN %JQ_BIN% \"map(if .title == \\\"Variable offset - FILES_NAMES\\\" then .enabled = 0 else . end)\" offset-variable.json > tmp.json && move /Y tmp.json offset-variable.json\n\n# run tests\nWORKDIR ${MOD_SECURITY_DIR}\\build\\win32\\build\n\nRUN C:\\BuildTools\\VC\\Auxiliary\\Build\\vcvars64.bat && ctest -C %BUILD_TYPE% --output-on-failure\n\n# setup container's entrypoint\n#\n\nWORKDIR C:\\\n\n# Use developer command prompt and start PowerShell if no other command specified.\nENTRYPOINT [\"C:\\\\BuildTools\\\\VC\\\\Auxiliary\\\\Build\\\\vcvars64.bat\", \"&&\", \"powershell.exe\", \"-NoLogo\", \"-ExecutionPolicy\", \"Bypass\"]\n"
  },
  {
    "path": "build/win32/docker/InstallBuildTools.cmd",
    "content": "@rem Copyright (C) Microsoft Corporation. All rights reserved.\n@rem Licensed under the MIT license. See LICENSE.txt in the project root for license information.\n\n@if not defined _echo echo off\nsetlocal enabledelayedexpansion\n\ncall %*\nif \"%ERRORLEVEL%\"==\"3010\" (\n    exit /b 0\n) else (\n    if not \"%ERRORLEVEL%\"==\"0\" (\n        set ERR=%ERRORLEVEL%\n        call C:\\TEMP\\collect.exe -zip:C:\\vslogs.zip\n\n        exit /b !ERR!\n    )\n)\n"
  },
  {
    "path": "build/win32/docker/git.inf",
    "content": "[Setup]\nLang=default\nDir=C:\\Program Files\\Git\nGroup=Git\nNoIcons=0\nSetupType=default\nComponents=ext,ext\\shellhere,ext\\guihere,gitlfs,assoc,autoupdate\nTasks=\nEditorOption=VIM\nCustomEditorPath=\nPathOption=Cmd\nSSHOption=OpenSSH\nTortoiseOption=false\nCURLOption=WinSSL\nCRLFOption=LFOnly\nBashTerminalOption=ConHost\nPerformanceTweaksFSCache=Enabled\nUseCredentialManager=Enabled\nEnableSymlinks=Disabled\nEnableBuiltinInteractiveAdd=Disabled"
  },
  {
    "path": "build/yajl.m4",
    "content": "dnl Check for YAJL Libraries\ndnl Sets:\ndnl  YAJL_CFLAGS\ndnl  YAJL_LDADD\ndnl  YAJL_LDFLAGS\ndnl  YAJL_VERSION\ndnl  YAJL_DISPLAY\ndnl  YAJL_FOUND\n\nAC_DEFUN([PROG_YAJL], [\nMSC_CHECK_LIB([YAJL], [yajl2 yajl], [yajl/yajl_parse.h], [yajl], [-DWITH_YAJL])\n\n# FIX: if the include directory in CFLAGS ends with \"include/yajl\",\n# remove the suffix \"/yajl\". The library header files are included\n# using the prefix (e.g., #include <yajl/yajl_tree.h>), and\n# this is even the case for the library itself (e.g.,\n# yajl_tree.h includes yajl/yajl_common.h).\n_msc_yajl_new_cflags=\"\"\nfor _msc_yajl_flag in $YAJL_CFLAGS; do\n    case \"$_msc_yajl_flag\" in\n        -I*/include/yajl)\n            _msc_yajl_new_flag=\"${_msc_yajl_flag%/yajl}\"\n            _msc_yajl_new_cflags=\"$_msc_yajl_new_cflags $_msc_yajl_new_flag\"\n            ;;\n        *)\n            _msc_yajl_new_cflags=\"$_msc_yajl_new_cflags $_msc_yajl_flag\"\n            ;;\n    esac\ndone\nYAJL_CFLAGS=\"$_msc_yajl_new_cflags\"\nYAJL_DISPLAY=\"${YAJL_LDADD}, ${YAJL_CFLAGS}\"\n\n]) # AC_DEFUN [PROG_YAJL]\n"
  },
  {
    "path": "build.sh",
    "content": "#!/bin/sh\n\nrm -rf autom4te.cache\nrm -f aclocal.m4\n\ncd src\nrm -f headers.mk\necho \"noinst_HEADERS = \\\\\" > headers.mk\nls -1 \\\n    actions/*.h \\\n    actions/ctl/*.h \\\n    actions/data/*.h \\\n    actions/disruptive/*.h \\\n    actions/transformations/*.h \\\n    debug_log/*.h \\\n    audit_log/writer/*.h \\\n    collection/backend/*.h \\\n    operators/*.h \\\n    parser/*.h \\\n    request_body_processor/*.h \\\n    utils/*.h \\\n    variables/*.h \\\n    engine/*.h \\\n    *.h | tr \"\\012\" \" \" >> headers.mk\ncd ../\n\ncase `uname` in Darwin*) glibtoolize --force --copy ;;\n  *) libtoolize --force --copy ;; esac\nautoreconf --install\nautoheader\nautomake --add-missing --foreign --copy --force-missing\nautoconf --force\nrm -rf autom4te.cache\n\n\n"
  },
  {
    "path": "configure.ac",
    "content": "# ModSecurity configure.ac\n\nAC_PREREQ([2.69])\n\n# Get the hash of the last commit, to be used if it is not an\n# official release.\nAC_DEFUN([MSC_GIT_HASH], m4_esyscmd_s(git log -1 --format=\"%h\" --abbrev-commit))\nAC_DEFUN([MSC_MAJOR], m4_esyscmd_s(cat headers/modsecurity/modsecurity.h | grep \"define MODSECURITY_MAJOR \" | awk {'print $3'} | sed 's/\\\"//g'))\nAC_DEFUN([MSC_MINOR], m4_esyscmd_s(cat headers/modsecurity/modsecurity.h | grep \"define MODSECURITY_MINOR \" | awk {'print $3'} | sed 's/\\\"//g'))\nAC_DEFUN([MSC_PATCHLEVEL], m4_esyscmd_s(cat headers/modsecurity/modsecurity.h | grep \"define MODSECURITY_PATCHLEVEL \" | awk {'print $3'} | sed 's/\\\"//g'))\nAC_DEFUN([MSC_TAG], m4_esyscmd_s(cat headers/modsecurity/modsecurity.h | grep \"define MODSECURITY_FTAG \" | awk {'print $3'} | sed 's/\\\"//g'))\n\n\n# Version definition to be further used by AC_INIT and \n# .so file naming.\nm4_define([msc_version_major], [MSC_MAJOR])\nm4_define([msc_version_minor], [MSC_MINOR])\nm4_define([msc_version_patchlevel], [MSC_PATCHLEVEL])\n\nm4_define([msc_version_c_plus_a], [m4_eval(msc_version_major + msc_version_minor)])\n\n\nm4_define([msc_version],\n    [msc_version_major.msc_version_minor])\n\nm4_define([msc_version_with_patchlevel],\n    [msc_version_major.msc_version_minor.msc_version_patchlevel])\n\nm4_define([msc_version_git],\n    [m4_esyscmd_s(git describe)])\n\nm4_define([msc_version_info],\n    [msc_version_c_plus_a:msc_version_patchlevel:msc_version_minor])\n\n\n# Project Information\nAC_INIT([modsecurity], [3.0], [security@modsecurity.org])\n\n\n# General definitions\nAC_CONFIG_MACRO_DIR([build])\nAC_PREFIX_DEFAULT([/usr/local/modsecurity])\n\n\n# General automake options.\nAM_INIT_AUTOMAKE([-Wall foreign subdir-objects])\n\n\n# Check for dependencies (C++, AR, Lex, Yacc and Make)\nAC_PROG_CXX\nAM_PROG_AR\nAC_PROG_AWK\nAC_PROG_CC\nAC_PROG_CPP\nAC_PROG_INSTALL\nAC_PROG_LN_S\nAC_PROG_MAKE_SET\nAC_PROG_MKDIR_P\nPKG_PROG_PKG_CONFIG\n\n\n# Set C++ standard version and check if compiler supports it.\nAX_CXX_COMPILE_STDCXX(17, noext, mandatory)\n\n# Check for libinjection\nif ! test -f \"${srcdir}/others/libinjection/src/libinjection_html5.c\"; then\nAC_MSG_ERROR([\\\n\n\n  libInjection was not found within ModSecurity source directory.\n\n  libInjection code is available as part of ModSecurity source code in a format\n  of a git-submodule. git-submodule allow us to specify the correct version of\n  libInjection and still uses the libInjection repository to download it.\n\n  You can download libInjection using git:\n\n     $ git submodule update --init --recursive\n\n   ])\nfi\n# Libinjection version\nAC_DEFUN([LIBINJECTION_VERSION], m4_esyscmd_s(cd \"others/libinjection\" && git describe && cd ../..))\nAC_SUBST([LIBINJECTION_VERSION])\n\n# Check for Mbed TLS\nif ! test -f \"${srcdir}/others/mbedtls/library/base64.c\"; then\nAC_MSG_ERROR([\\\n\n\n  Mbed TLS was not found within ModSecurity source directory.\n\n  Mbed TLS code is available as part of ModSecurity source code in a format\n  of a git-submodule. git-submodule allow us to specify the correct version of\n  Mbed TLS and still uses the Mbed TLS repository to download it.\n\n  You can download Mbed TLS using git:\n\n     $ git submodule update --init --recursive\n\n   ])\nfi\n# Mbed TLS version\nAC_DEFUN([MBEDTLS_VERSION], m4_esyscmd_s(cd \"others/mbedtls\" && git describe && cd ../..))\n\n# SecLang test version\nAC_DEFUN([SECLANG_TEST_VERSION], m4_esyscmd_s(cd \"test/test-cases/secrules-language-tests\" && git log -1 --format=\"%h\" --abbrev-commit && cd ../../..))\n\n\n# Check for yajl\nPROG_YAJL\n\nAM_CONDITIONAL([YAJL_VERSION], [test \"$YAJL_VERSION\" != \"\"])\n\n# Check for LibGeoIP\nPROG_GEOIP\n\n# Check for MaxMind\nPROG_MAXMIND\n\n# Check for LMDB\nPROG_LMDB\n\n# Check for SSDEEP\nCHECK_SSDEEP\n\n# Check for LUA\nCHECK_LUA\n\n\n#\n# Check for curl\n#\nCHECK_CURL\n\nif ! test -z \"${CURL_VERSION}\"; then\n  AC_DEFINE([MSC_WITH_CURL], [1], [Define if libcurl is available])\nfi\n\n\n#\n# Check for LibXML\n#\nCHECK_LIBXML2\n\n\n#\n# Check for libpcre only if explicitly requested\n#\nif test \"x${with_pcre}\" != \"x\" && test \"x${with_pcre}\" != \"xno\"; then\n  CHECK_PCRE\nelse\n  #\n  # Check for pcre2\n  #\n  PROG_PCRE2\nfi\n\n\n# Checks for header files.\nAC_CHECK_HEADERS([string])\nAC_CHECK_HEADERS([iostream])\nAC_CHECK_HEADERS([sys/utsname.h])\nAC_CHECK_HEADERS([arpa/inet.h fcntl.h inttypes.h libintl.h malloc.h netdb.h netinet/in.h stdint.h sys/ioctl.h sys/param.h sys/socket.h sys/time.h unistd.h])\n\n\n\n# Checks for typedefs, structures, and compiler characteristics.\nAC_CHECK_HEADER_STDBOOL\nAC_C_INLINE\nAC_TYPE_INT16_T\nAC_TYPE_INT32_T\nAC_TYPE_INT64_T\nAC_TYPE_INT8_T\nAC_TYPE_OFF_T\nAC_TYPE_PID_T\nAC_TYPE_SIZE_T\nAC_TYPE_SSIZE_T\nAC_TYPE_UINT16_T\nAC_TYPE_UINT32_T\nAC_TYPE_UINT64_T\nAC_TYPE_UINT8_T\nAC_CHECK_TYPES([ptrdiff_t])\nAC_CHECK_TYPES([time_t])\n\n# Checks for library functions.\nAC_FUNC_ERROR_AT_LINE\nAC_FUNC_FORK\nAC_FUNC_MALLOC\nAC_FUNC_REALLOC\nAC_CHECK_FUNCS([alarm clock_gettime gethostname gettimeofday inet_ntoa localtime_r memmove memset mkdir select setenv socket strcasecmp strchr strdup strerror strncasecmp strspn strstr strtol strtoul strtoull uname])\n\n# Initialize libtool\nLT_INIT\n\n# Identify platform\nAC_CANONICAL_HOST\n\ncase $host in\n  *-*-aix*)\n    echo \"Checking platform... Identified as AIX\"\n    AC_DEFINE([AIX], [1], [Define if the operating system is AIX])\n    PLATFORM=\"AIX\"\n    ;;\n  *-*-hpux*)\n    echo \"Checking platform... Identified as HPUX\"\n    AC_DEFINE([HPUX], [1], [Define if the operating system is HPUX])\n    PLATFORM=\"HPUX\"\n    ;;\n  *-*-darwin*)\n    echo \"Checking platform... Identified as Macintosh OS X\"\n    AC_DEFINE([MACOSX], [1], [Define if the operating system is Macintosh OSX])\n    PLATFORM=\"MacOSX\"\n    ;;\n  *-*-linux* | *-*uclinux*)\n    echo \"Checking platform... Identified as Linux\"\n    AC_DEFINE([LINUX], [1], [Define if the operating system is LINUX])\n    PLATFORM=\"Linux\"\n    ;;\n  *-*-solaris*)\n    echo \"Checking platform... Identified as Solaris\"\n    AC_DEFINE([SOLARIS], [1], [Define if the operating system is SOLARIS])\n    PLATFORM=\"Solaris\"\n    ;;\n  *-*-freebsd*)\n    echo \"Checking platform... Identified as FreeBSD\"\n    AC_DEFINE([FREEBSD], [1], [Define if the operating system is FREEBSD])\n    PLATFORM=\"FreeBSD\"\n    ;;\n  *-*-netbsd*)\n    echo \"Checking platform... Identified as NetBSD\"\n    AC_DEFINE([NETBSD], [1], [Define if the operating system is NETBSD])\n    PLATFORM=\"NetBSD\"\n    ;;\n  *-*-openbsd*)\n    echo \"Checking platform... Identified as OpenBSD\"\n    AC_DEFINE([OPENBSD], [1], [Define if the operating system is OPENBSD])\n    PLATFORM=\"OpenBSD\"\n    ;;\n  *-*-kfreebsd*)\n    echo \"Checking platform... Identified as kFreeBSD, treating as linux\"\n    AC_DEFINE([FREEBSD], [1], [Define if the operating system is FREEBSD])\n    PLATFORM=\"kFreeBSD\"\n    ;;\n  *-*-dragonfly*)\n    echo \"Checking platform... Identified as DragonFlyBSD, treating as linux\"\n    AC_DEFINE([DRAGONFLY], [1], [Define if the operating system is DRAGONFLY])\n    PLATFORM=\"DragonFly\"\n    ;;\n  *-*-gnu*.*)\n    echo \"Checking platform... Identified as HURD, treating as linux\"\n    AC_DEFINE([LINUX], [1], [Define if the operating system is LINUX])\n    PLATFORM=\"HURD\"\n    ;;\n       *)\n    echo \"Unknown CANONICAL_HOST $host\"\n    exit 1\n    ;;\nesac\n\n# Variables to be used inside the Makefile.am files.\nMSC_BASE_DIR=`pwd`\nAC_SUBST([MSC_BASE_DIR])\n\nMSC_VERSION_INFO=msc_version_info\nAC_SUBST([MSC_VERSION_INFO])\n\nMSC_VERSION_WITH_PATCHLEVEL=msc_version_with_patchlevel\nAC_SUBST([MSC_VERSION_WITH_PATCHLEVEL])\n\nMSC_VERSION=msc_version\nAC_SUBST([MSC_VERSION])\n\nMSC_GIT_VERSION=msc_version_git\nAC_SUBST([MSC_GIT_VERSION])\n\nMSC_ARG_ENABLE_BOOL([assertions], [Turn on assertions feature: undefine NDEBUG], [false], [assertions])\nMSC_ARG_ENABLE_BOOL([debug-logs], [Turn off the SecDebugLog feature], [true], [debugLogs])\nif test \"$debugLogs\" != \"true\"; then\n    MODSEC_NO_LOGS=\"-DNO_LOGS=1\"\n    AC_SUBST(MODSEC_NO_LOGS)\nfi\n\nMSC_ARG_ENABLE_BOOL([afl-fuzz], [Turn on the afl fuzzer compilation utilities], [false], [aflFuzzer])\nMSC_ARG_ENABLE_BOOL([examples], [Turn on the examples compilation (default option)], [true], [buildExamples])\nMSC_ARG_ENABLE_BOOL([parser-generation], [Enables parser generation during the build], [false], [buildParser])\nMSC_ARG_ENABLE_BOOL([mutex-on-pm], [Treat pm operations as critical section], [false], [mutexPm])\n\n\nif test $buildParser = true; then\n    AC_PROG_YACC\n    AC_PROG_LEX(noyywrap)\n    AC_PATH_PROG([FLEX], [flex])\n    test \"x$FLEX\" = \"x\" && AC_MSG_ERROR([flex is needed to build ModSecurity])\n\n    AC_PATH_PROG([BISON], [bison])\n    test \"x$BISON\" = \"x\" && AC_MSG_ERROR([bison is needed to build ModSecurity])\n\n    AC_PATH_PROG([YACC_INST], $YACC)\n    if test ! -f \"$srcdir/gram.c\"; then\n        if test -z \"$YACC_INST\"; then\n            AC_MSG_ERROR([yacc not found - unable to compile ModSecurity])\n        fi\n    fi\nfi\n\n\n# Decide if we want to build the tests or not.\nbuildTestUtilities=false\nif test \"x$YAJL_FOUND\" = \"x1\"; then\n    # Regression tests will not be able to run without the logging support.\n    # But we still have the unit tests.\n    # if test \"$debugLogs\" = \"true\"; then\n        buildTestUtilities=true\n    # fi\nfi\n\n\nAM_CONDITIONAL([TEST_UTILITIES], [test $buildTestUtilities = true])\nif test $buildTestUtilities = true; then\n    if test $debugLogs = true; then\n        if test -f ./test/test-list.sh; then\n            TEST_CASES=`./test/test-list.sh`\n        fi\n    fi\nfi\n\nAM_CONDITIONAL([EXAMPLES], [test $buildExamples = true])\nAM_CONDITIONAL([BUILD_PARSER], [test $buildParser = true])\nAM_CONDITIONAL([USE_MUTEX_ON_PM], [test $mutexPm = true])\n\n\n# General link options\nif test \"$PLATFORM\" != \"MacOSX\" -a \"$PLATFORM\" != \"OpenBSD\"; then\n    GLOBAL_LDADD=\"-lrt  \"\nfi\n\nif test \"$aflFuzzer\" == \"true\"; then\n    FUZZ_CPPCFLAGS=\"-fsanitize=address -fsanitize-coverage=4 \"\n    GLOBAL_LDADD=\"$GLOBAL_LDADD -fsanitize=address \"\n    GLOBAL_CPPFLAGS=\"$GLOBAL_CPPFLAGS $FUZZ_CPPCFLAGS\"\n    $buildExamples = false\nfi\n\ncase $assertions in\n    false) ASSERTIONS_CPPCFLAGS=\"-DNDEBUG\" ;;\n    true) ASSERTIONS_CPPCFLAGS=\"-UNDEBUG\" ;;\n    *) AC_MSG_ERROR(bad value ${assertions} for assertions) ;;\nesac\nGLOBAL_CPPFLAGS=\"$GLOBAL_CPPFLAGS $ASSERTIONS_CPPCFLAGS\"\n\nAC_SUBST(GLOBAL_LDADD)\nAC_SUBST(GLOBAL_CPPFLAGS)\n\nAM_CONDITIONAL([AFL_FUZZER], [test $aflFuzzer = true])\n\nGLOBAL_CFLAGS=\"\"\nAC_SUBST(GLOBAL_CFLAGS)\n\n# Files to be generated via autotools.\nAC_CONFIG_FILES([\\\n    modsecurity.pc \\\n    Makefile \\\n    doc/Makefile \\\n    src/Makefile \\\n    others/Makefile \\\n    tools/Makefile \\\n    tools/rules-check/Makefile\n    ])\n\nAM_COND_IF([TEST_UTILITIES],\n       [AC_CONFIG_FILES([test/Makefile test/benchmark/Makefile])])\n\nAM_COND_IF([EXAMPLES],\n       [AC_CONFIG_FILES([ \\\n            examples/Makefile \\\n            examples/simple_example_using_c/Makefile \\\n            examples/multiprocess_c/Makefile \\\n            examples/multithread/Makefile \\\n            examples/reading_logs_with_offset/Makefile \\\n            examples/reading_logs_via_rule_message/Makefile \\\n            examples/using_bodies_in_chunks/Makefile \\\n            ])])\n\nAM_COND_IF([AFL_FUZZER],\n       [AC_CONFIG_FILES([test/fuzzer/Makefile])])\n\nAM_COND_IF([BUILD_PARSER],\n       [AC_CONFIG_FILES([src/parser/Makefile])])\n\n\nAC_CONFIG_HEADERS([src/config.h])\n\n\n# Doxygen support\nDX_HTML_FEATURE(ON)\nDX_CHM_FEATURE(OFF)\nDX_CHI_FEATURE(OFF)\nDX_MAN_FEATURE(OFF)\nDX_RTF_FEATURE(OFF)\nDX_XML_FEATURE(OFF)\nDX_PDF_FEATURE(OFF)\nDX_PS_FEATURE(OFF)\n\nDX_INIT_DOXYGEN([ModSecurity],[doc/doxygen.cfg])\n\n# make check-valgrind\nAX_VALGRIND_DFLT([sgcheck], [off])\nAX_VALGRIND_CHECK\n\n# Generate the files.\nAC_OUTPUT\n\n\n# Print a fancy summary\necho \" \"\necho \" \"\necho \"ModSecurity - ${MSC_GIT_VERSION} for $PLATFORM\"\necho \" \"\necho \" Mandatory dependencies\"\nAS_ECHO_N(\"   + libInjection                                  ....\")\necho LIBINJECTION_VERSION\nAS_ECHO_N(\"   + Mbed TLS                                      ....\")\necho MBEDTLS_VERSION\nAS_ECHO_N(\"   + SecLang tests                                 ....\")\necho SECLANG_TEST_VERSION\n\necho \" \"\necho \" Optional dependencies\"\n\n\n\n## GeoIP - MaxMind (combined display)\nif test \"x$GEOIP_FOUND\" = \"x0\" && test \"x$MAXMIND_FOUND\" = \"x0\"; then\n    echo \"   + GeoIP/MaxMind                                 ....not found\"\nfi\nif test \"x$GEOIP_FOUND\" = \"x1\" || test \"x$MAXMIND_FOUND\" = \"x1\"; then\n    AS_ECHO_N([\"   + GeoIP/MaxMind                                 ....found \"])\n    echo \"\"\n    if test \"x$MAXMIND_FOUND\" = \"x1\"; then\n        echo \"      * (MaxMind) v${MAXMIND_VERSION}\"\n        echo \"         ${MAXMIND_DISPLAY}\"\n    fi\n    if test \"x$GEOIP_FOUND\" = \"x1\"; then\n        echo \"      * (GeoIP) v${GEOIP_VERSION}\"\n        echo \"         ${GEOIP_DISPLAY}\"\n    fi\nfi\nif test \"x$GEOIP_FOUND\" = \"x2\" && test \"x$MAXMIND_FOUND\" = \"x2\"; then\n    echo \"   + GeoIP/MaxMind                                 ....disabled\"\nfi\n\nMSC_STATUS_LIB([LibCURL                                      ], [CURL])\nMSC_STATUS_LIB([YAJL                                         ], [YAJL])\nMSC_STATUS_LIB([LMDB                                         ], [LMDB])\nMSC_STATUS_LIB([LibXML2                                      ], [LIBXML2])\nMSC_STATUS_LIB([SSDEEP                                       ], [SSDEEP])\nMSC_STATUS_LIB([LUA                                          ], [LUA])\n\n## PCRE (only shown when explicitly requested)\nif test \"x${with_pcre}\" != \"x\" && test \"x${with_pcre}\" != \"xno\"; then\n    if test -n \"${PCRE_VERSION}\"; then\n        echo \"   + PCRE                                          ....found \"\n        echo \"     using pcre v${PCRE_VERSION}\"\n        echo \"      ${PCRE_LDADD}, ${PCRE_CFLAGS}\"\n    else\n        AC_MSG_NOTICE([*** pcre library not found.])\n    fi\nfi\n\nMSC_STATUS_LIB([PCRE2                                         ], [PCRE2])\n\necho \" \"\necho \" Other Options\"\nif test $buildTestUtilities = true; then\n    if test $debugLogs = true; then\n        echo \"   + Test Utilities                                ....enabled\"\n    else\n        echo \"   + Test Utilities                                ....partially\"\n    fi\nelse\n    echo \"   + Test Utilities                                ....disabled\"\nfi\nif test $assertions = true; then\n    echo \"   + Assertions                                    ....enabled\"\nelse\n    echo \"   + Assertions                                    ....disabled\"\nfi\nif test $debugLogs = true; then\n    echo \"   + SecDebugLog                                   ....enabled\"\nelse\n    echo \"   + SecDebugLog                                   ....disabled\"\nfi\n\nif test \"$aflFuzzer\" = \"true\"; then\n    echo \"   + afl fuzzer                                    ....enabled\"\n    echo \"    ($FUZZ_CPPCFLAGS)\"\nelse\n    echo \"   + afl fuzzer                                    ....disabled\"\nfi\n\nif test \"$buildExamples\" = \"true\"; then\n    echo \"   + library examples                              ....enabled\"\nelse\n    echo \"   + library examples                              ....disabled\"\nfi\n\nif test \"$buildParser\" = \"true\"; then\n    echo \"   + Building parser                               ....enabled\"\nelse\n    echo \"   + Building parser                               ....disabled\"\nfi\n\nif test \"$mutexPm\" = \"true\"; then\n    echo \"   + Treating pm operations as critical section    ....enabled\"\nelse\n    echo \"   + Treating pm operations as critical section    ....disabled\"\nfi\n\n\necho \" \"\n\n\nif test \"$aflFuzzer\" = \"true\"; then\n    echo \"WARNING: afl fuzzer was enabled. Make sure you are using the\"\n    echo \" 'afl-clang-fast' as the compiler, otherwise the compilation\"\n    echo \"  will fail.\"\n    echo \" \"\n    echo \" You can set the compiler using:\"\n    echo \" \"\n    echo \"  $ export CXX=afl-clang-fast++ \"\n    echo \"  $ export CC=afl-clang-fast \"\n    echo \" \"\nfi\n\n"
  },
  {
    "path": "doc/.empty",
    "content": ""
  },
  {
    "path": "doc/Makefile.am",
    "content": "\nACLOCAL_AMFLAGS = -I build\n\n# Doxygen support\n# include $(top_srcdir)/build/ax_prog_doxygen.m4\n\n# distribution of the Doxygen configuration file\nEXTRA_DIST = \\\n\tdoxygen.cfg\n\n\nMAINTAINERCLEANFILES = \\\n\tMakefile.in \\\n\tdoxygen_sqlite3.db \\\n\thtml \\\n\tlatex\n\n"
  },
  {
    "path": "doc/doxygen.cfg",
    "content": "# Doxyfile 1.8.8\n\n# This file describes the settings to be used by the documentation system\n# doxygen (www.doxygen.org) for a project.\n#\n# All text after a double hash (##) is considered a comment and is placed in\n# front of the TAG it is preceding.\n#\n# All text after a single hash (#) is considered a comment and will be ignored.\n# The format is:\n# TAG = value [value, ...]\n# For lists, items can also be appended using:\n# TAG += value [value, ...]\n# Values that contain spaces should be placed between quotes (\\\" \\\").\n\n#---------------------------------------------------------------------------\n# Project related configuration options\n#---------------------------------------------------------------------------\n\n# This tag specifies the encoding used for all characters in the config file\n# that follow. The default is UTF-8 which is also the encoding used for all text\n# before the first occurrence of this tag. Doxygen uses libiconv (or the iconv\n# built into libc) for the transcoding. See http://www.gnu.org/software/libiconv\n# for the list of possible encodings.\n# The default value is: UTF-8.\n\nDOXYFILE_ENCODING      = UTF-8\n\n# The PROJECT_NAME tag is a single word (or a sequence of words surrounded by\n# double-quotes, unless you are using Doxywizard) that should identify the\n# project for which the documentation is generated. This name is used in the\n# title of most generated pages and in a few other places.\n# The default value is: My Project.\n\nPROJECT_NAME           = ModSecurity\n\n# The PROJECT_NUMBER tag can be used to enter a project or revision number. This\n# could be handy for archiving the generated documentation or if some version\n# control system is used.\n\nPROJECT_NUMBER         = 3.0.0\n\n# Using the PROJECT_BRIEF tag one can provide an optional one line description\n# for a project that appears at the top of each page and should give viewer a\n# quick idea about the purpose of the project. Keep the description short.\n\nPROJECT_BRIEF          = \"ModSecurity is an open source, cross platform web application firewall (WAF) engine for Apache, IIS and Nginx that is developed by Trustwave's SpiderLabs. It has a robust event-based programming language which provides protection from a range of attacks against web applications and allows for HTTP traffic monitoring, logging and real-time analys…\"\n\n# With the PROJECT_LOGO tag one can specify an logo or icon that is included in\n# the documentation. The maximum height of the logo should not exceed 55 pixels\n# and the maximum width should not exceed 200 pixels. Doxygen will copy the logo\n# to the output directory.\n\nPROJECT_LOGO           = ../doc/ms-doxygen-logo.png\n\n# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path\n# into which the generated documentation will be written. If a relative path is\n# entered, it will be relative to the location where doxygen was started. If\n# left blank the current directory will be used.\n\nOUTPUT_DIRECTORY       = ../doc\n\n# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create 4096 sub-\n# directories (in 2 levels) under the output directory of each output format and\n# will distribute the generated files over these directories. Enabling this\n# option can be useful when feeding doxygen a huge amount of source files, where\n# putting all generated files in the same directory would otherwise causes\n# performance problems for the file system.\n# The default value is: NO.\n\nCREATE_SUBDIRS         = NO\n\n# If the ALLOW_UNICODE_NAMES tag is set to YES, doxygen will allow non-ASCII\n# characters to appear in the names of generated files. If set to NO, non-ASCII\n# characters will be escaped, for example _xE3_x81_x84 will be used for Unicode\n# U+3044.\n# The default value is: NO.\n\nALLOW_UNICODE_NAMES    = NO\n\n# The OUTPUT_LANGUAGE tag is used to specify the language in which all\n# documentation generated by doxygen is written. Doxygen will use this\n# information to generate all constant output in the proper language.\n# Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Catalan, Chinese,\n# Chinese-Traditional, Croatian, Czech, Danish, Dutch, English (United States),\n# Esperanto, Farsi (Persian), Finnish, French, German, Greek, Hungarian,\n# Indonesian, Italian, Japanese, Japanese-en (Japanese with English messages),\n# Korean, Korean-en (Korean with English messages), Latvian, Lithuanian,\n# Macedonian, Norwegian, Persian (Farsi), Polish, Portuguese, Romanian, Russian,\n# Serbian, Serbian-Cyrillic, Slovak, Slovene, Spanish, Swedish, Turkish,\n# Ukrainian and Vietnamese.\n# The default value is: English.\n\nOUTPUT_LANGUAGE        = English\n\n# If the BRIEF_MEMBER_DESC tag is set to YES doxygen will include brief member\n# descriptions after the members that are listed in the file and class\n# documentation (similar to Javadoc). Set to NO to disable this.\n# The default value is: YES.\n\nBRIEF_MEMBER_DESC      = YES\n\n# If the REPEAT_BRIEF tag is set to YES doxygen will prepend the brief\n# description of a member or function before the detailed description\n#\n# Note: If both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the\n# brief descriptions will be completely suppressed.\n# The default value is: YES.\n\nREPEAT_BRIEF           = YES\n\n# This tag implements a quasi-intelligent brief description abbreviator that is\n# used to form the text in various listings. Each string in this list, if found\n# as the leading text of the brief description, will be stripped from the text\n# and the result, after processing the whole list, is used as the annotated\n# text. Otherwise, the brief description is used as-is. If left blank, the\n# following values are used ($name is automatically replaced with the name of\n# the entity):The $name class, The $name widget, The $name file, is, provides,\n# specifies, contains, represents, a, an and the.\n\nABBREVIATE_BRIEF       = \"The $name class\" \\\n                         \"The $name widget\" \\\n                         \"The $name file\" \\\n                         is \\\n                         provides \\\n                         specifies \\\n                         contains \\\n                         represents \\\n                         a \\\n                         an \\\n                         the\n\n# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then\n# doxygen will generate a detailed section even if there is only a brief\n# description.\n# The default value is: NO.\n\nALWAYS_DETAILED_SEC    = NO\n\n# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all\n# inherited members of a class in the documentation of that class as if those\n# members were ordinary class members. Constructors, destructors and assignment\n# operators of the base classes will not be shown.\n# The default value is: NO.\n\nINLINE_INHERITED_MEMB  = NO\n\n# If the FULL_PATH_NAMES tag is set to YES doxygen will prepend the full path\n# before files name in the file list and in the header files. If set to NO the\n# shortest path that makes the file name unique will be used\n# The default value is: YES.\n\nFULL_PATH_NAMES        = NO\n\n# The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path.\n# Stripping is only done if one of the specified strings matches the left-hand\n# part of the path. The tag can be used to show relative paths in the file list.\n# If left blank the directory from which doxygen is run is used as the path to\n# strip.\n#\n# Note that you can specify absolute paths here, but also relative paths, which\n# will be relative from the directory where doxygen is started.\n# This tag requires that the tag FULL_PATH_NAMES is set to YES.\n\nSTRIP_FROM_PATH        = \n\n# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the\n# path mentioned in the documentation of a class, which tells the reader which\n# header file to include in order to use a class. If left blank only the name of\n# the header file containing the class definition is used. Otherwise one should\n# specify the list of include paths that are normally passed to the compiler\n# using the -I flag.\n\nSTRIP_FROM_INC_PATH    = \n\n# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but\n# less readable) file names. This can be useful is your file systems doesn't\n# support long names like on DOS, Mac, or CD-ROM.\n# The default value is: NO.\n\nSHORT_NAMES            = NO\n\n# If the JAVADOC_AUTOBRIEF tag is set to YES then doxygen will interpret the\n# first line (until the first dot) of a Javadoc-style comment as the brief\n# description. If set to NO, the Javadoc-style will behave just like regular Qt-\n# style comments (thus requiring an explicit @brief command for a brief\n# description.)\n# The default value is: NO.\n\nJAVADOC_AUTOBRIEF      = NO\n\n# If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first\n# line (until the first dot) of a Qt-style comment as the brief description. If\n# set to NO, the Qt-style will behave just like regular Qt-style comments (thus\n# requiring an explicit \\brief command for a brief description.)\n# The default value is: NO.\n\nQT_AUTOBRIEF           = NO\n\n# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make doxygen treat a\n# multi-line C++ special comment block (i.e. a block of //! or /// comments) as\n# a brief description. This used to be the default behavior. The new default is\n# to treat a multi-line C++ comment block as a detailed description. Set this\n# tag to YES if you prefer the old behavior instead.\n#\n# Note that setting this tag to YES also means that rational rose comments are\n# not recognized any more.\n# The default value is: NO.\n\nMULTILINE_CPP_IS_BRIEF = NO\n\n# If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the\n# documentation from any documented member that it re-implements.\n# The default value is: YES.\n\nINHERIT_DOCS           = YES\n\n# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce a\n# new page for each member. If set to NO, the documentation of a member will be\n# part of the file/class/namespace that contains it.\n# The default value is: NO.\n\nSEPARATE_MEMBER_PAGES  = NO\n\n# The TAB_SIZE tag can be used to set the number of spaces in a tab. Doxygen\n# uses this value to replace tabs by spaces in code fragments.\n# Minimum value: 1, maximum value: 16, default value: 4.\n\nTAB_SIZE               = 4\n\n# This tag can be used to specify a number of aliases that act as commands in\n# the documentation. An alias has the form:\n# name=value\n# For example adding\n# \"sideeffect=@par Side Effects:\\n\"\n# will allow you to put the command \\sideeffect (or @sideeffect) in the\n# documentation, which will result in a user-defined paragraph with heading\n# \"Side Effects:\". You can put \\n's in the value part of an alias to insert\n# newlines.\n\nALIASES                = \n\n# This tag can be used to specify a number of word-keyword mappings (TCL only).\n# A mapping has the form \"name=value\". For example adding \"class=itcl::class\"\n# will allow you to use the command class in the itcl::class meaning.\n\nTCL_SUBST              = \n\n# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources\n# only. Doxygen will then generate output that is more tailored for C. For\n# instance, some of the names that are used will be different. The list of all\n# members will be omitted, etc.\n# The default value is: NO.\n\nOPTIMIZE_OUTPUT_FOR_C  = NO\n\n# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java or\n# Python sources only. Doxygen will then generate output that is more tailored\n# for that language. For instance, namespaces will be presented as packages,\n# qualified scopes will look different, etc.\n# The default value is: NO.\n\nOPTIMIZE_OUTPUT_JAVA   = NO\n\n# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran\n# sources. Doxygen will then generate output that is tailored for Fortran.\n# The default value is: NO.\n\nOPTIMIZE_FOR_FORTRAN   = NO\n\n# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL\n# sources. Doxygen will then generate output that is tailored for VHDL.\n# The default value is: NO.\n\nOPTIMIZE_OUTPUT_VHDL   = NO\n\n# Doxygen selects the parser to use depending on the extension of the files it\n# parses. With this tag you can assign which parser to use for a given\n# extension. Doxygen has a built-in mapping, but you can override or extend it\n# using this tag. The format is ext=language, where ext is a file extension, and\n# language is one of the parsers supported by doxygen: IDL, Java, Javascript,\n# C#, C, C++, D, PHP, Objective-C, Python, Fortran (fixed format Fortran:\n# FortranFixed, free formatted Fortran: FortranFree, unknown formatted Fortran:\n# Fortran. In the later case the parser tries to guess whether the code is fixed\n# or free formatted code, this is the default for Fortran type files), VHDL. For\n# instance to make doxygen treat .inc files as Fortran files (default is PHP),\n# and .f files as C (default is Fortran), use: inc=Fortran f=C.\n#\n# Note For files without extension you can use no_extension as a placeholder.\n#\n# Note that for custom extensions you also need to set FILE_PATTERNS otherwise\n# the files are not read by doxygen.\n\nEXTENSION_MAPPING      = \n\n# If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments\n# according to the Markdown format, which allows for more readable\n# documentation. See http://daringfireball.net/projects/markdown/ for details.\n# The output of markdown processing is further processed by doxygen, so you can\n# mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in\n# case of backward compatibilities issues.\n# The default value is: YES.\n\nMARKDOWN_SUPPORT       = YES\n\n# When enabled doxygen tries to link words that correspond to documented\n# classes, or namespaces to their corresponding documentation. Such a link can\n# be prevented in individual cases by by putting a % sign in front of the word\n# or globally by setting AUTOLINK_SUPPORT to NO.\n# The default value is: YES.\n\nAUTOLINK_SUPPORT       = YES\n\n# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want\n# to include (a tag file for) the STL sources as input, then you should set this\n# tag to YES in order to let doxygen match functions declarations and\n# definitions whose arguments contain STL classes (e.g. func(std::string);\n# versus func(std::string) {}). This also make the inheritance and collaboration\n# diagrams that involve STL classes more complete and accurate.\n# The default value is: NO.\n\nBUILTIN_STL_SUPPORT    = NO\n\n# If you use Microsoft's C++/CLI language, you should set this option to YES to\n# enable parsing support.\n# The default value is: NO.\n\nCPP_CLI_SUPPORT        = NO\n\n# Set the SIP_SUPPORT tag to YES if your project consists of sip (see:\n# http://www.riverbankcomputing.co.uk/software/sip/intro) sources only. Doxygen\n# will parse them like normal C++ but will assume all classes use public instead\n# of private inheritance when no explicit protection keyword is present.\n# The default value is: NO.\n\nSIP_SUPPORT            = NO\n\n# For Microsoft's IDL there are propget and propput attributes to indicate\n# getter and setter methods for a property. Setting this option to YES will make\n# doxygen to replace the get and set methods by a property in the documentation.\n# This will only work if the methods are indeed getting or setting a simple\n# type. If this is not the case, or you want to show the methods anyway, you\n# should set this option to NO.\n# The default value is: YES.\n\nIDL_PROPERTY_SUPPORT   = YES\n\n# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC\n# tag is set to YES, then doxygen will reuse the documentation of the first\n# member in the group (if any) for the other members of the group. By default\n# all members of a group must be documented explicitly.\n# The default value is: NO.\n\nDISTRIBUTE_GROUP_DOC   = NO\n\n# Set the SUBGROUPING tag to YES to allow class member groups of the same type\n# (for instance a group of public functions) to be put as a subgroup of that\n# type (e.g. under the Public Functions section). Set it to NO to prevent\n# subgrouping. Alternatively, this can be done per class using the\n# \\nosubgrouping command.\n# The default value is: YES.\n\nSUBGROUPING            = YES\n\n# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and unions\n# are shown inside the group in which they are included (e.g. using \\ingroup)\n# instead of on a separate page (for HTML and Man pages) or section (for LaTeX\n# and RTF).\n#\n# Note that this feature does not work in combination with\n# SEPARATE_MEMBER_PAGES.\n# The default value is: NO.\n\nINLINE_GROUPED_CLASSES = NO\n\n# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and unions\n# with only public data fields or simple typedef fields will be shown inline in\n# the documentation of the scope in which they are defined (i.e. file,\n# namespace, or group documentation), provided this scope is documented. If set\n# to NO, structs, classes, and unions are shown on a separate page (for HTML and\n# Man pages) or section (for LaTeX and RTF).\n# The default value is: NO.\n\nINLINE_SIMPLE_STRUCTS  = NO\n\n# When TYPEDEF_HIDES_STRUCT tag is enabled, a typedef of a struct, union, or\n# enum is documented as struct, union, or enum with the name of the typedef. So\n# typedef struct TypeS {} TypeT, will appear in the documentation as a struct\n# with name TypeT. When disabled the typedef will appear as a member of a file,\n# namespace, or class. And the struct will be named TypeS. This can typically be\n# useful for C code in case the coding convention dictates that all compound\n# types are typedef'ed and only the typedef is referenced, never the tag name.\n# The default value is: NO.\n\nTYPEDEF_HIDES_STRUCT   = NO\n\n# The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This\n# cache is used to resolve symbols given their name and scope. Since this can be\n# an expensive process and often the same symbol appears multiple times in the\n# code, doxygen keeps a cache of pre-resolved symbols. If the cache is too small\n# doxygen will become slower. If the cache is too large, memory is wasted. The\n# cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range\n# is 0..9, the default is 0, corresponding to a cache size of 2^16=65536\n# symbols. At the end of a run doxygen will report the cache usage and suggest\n# the optimal cache size from a speed point of view.\n# Minimum value: 0, maximum value: 9, default value: 0.\n\nLOOKUP_CACHE_SIZE      = 0\n\n#---------------------------------------------------------------------------\n# Build related configuration options\n#---------------------------------------------------------------------------\n\n# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in\n# documentation are documented, even if no documentation was available. Private\n# class members and static file members will be hidden unless the\n# EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES.\n# Note: This will also disable the warnings about undocumented members that are\n# normally produced when WARNINGS is set to YES.\n# The default value is: NO.\n\nEXTRACT_ALL            = YES\n\n# If the EXTRACT_PRIVATE tag is set to YES all private members of a class will\n# be included in the documentation.\n# The default value is: NO.\n\nEXTRACT_PRIVATE        = NO\n\n# If the EXTRACT_PACKAGE tag is set to YES all members with package or internal\n# scope will be included in the documentation.\n# The default value is: NO.\n\nEXTRACT_PACKAGE        = NO\n\n# If the EXTRACT_STATIC tag is set to YES all static members of a file will be\n# included in the documentation.\n# The default value is: NO.\n\nEXTRACT_STATIC         = NO\n\n# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) defined\n# locally in source files will be included in the documentation. If set to NO\n# only classes defined in header files are included. Does not have any effect\n# for Java sources.\n# The default value is: YES.\n\nEXTRACT_LOCAL_CLASSES  = YES\n\n# This flag is only useful for Objective-C code. When set to YES local methods,\n# which are defined in the implementation section but not in the interface are\n# included in the documentation. If set to NO only methods in the interface are\n# included.\n# The default value is: NO.\n\nEXTRACT_LOCAL_METHODS  = NO\n\n# If this flag is set to YES, the members of anonymous namespaces will be\n# extracted and appear in the documentation as a namespace called\n# 'anonymous_namespace{file}', where file will be replaced with the base name of\n# the file that contains the anonymous namespace. By default anonymous namespace\n# are hidden.\n# The default value is: NO.\n\nEXTRACT_ANON_NSPACES   = NO\n\n# If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all\n# undocumented members inside documented classes or files. If set to NO these\n# members will be included in the various overviews, but no documentation\n# section is generated. This option has no effect if EXTRACT_ALL is enabled.\n# The default value is: NO.\n\nHIDE_UNDOC_MEMBERS     = NO\n\n# If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all\n# undocumented classes that are normally visible in the class hierarchy. If set\n# to NO these classes will be included in the various overviews. This option has\n# no effect if EXTRACT_ALL is enabled.\n# The default value is: NO.\n\nHIDE_UNDOC_CLASSES     = NO\n\n# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend\n# (class|struct|union) declarations. If set to NO these declarations will be\n# included in the documentation.\n# The default value is: NO.\n\nHIDE_FRIEND_COMPOUNDS  = NO\n\n# If the HIDE_IN_BODY_DOCS tag is set to YES, doxygen will hide any\n# documentation blocks found inside the body of a function. If set to NO these\n# blocks will be appended to the function's detailed documentation block.\n# The default value is: NO.\n\nHIDE_IN_BODY_DOCS      = NO\n\n# The INTERNAL_DOCS tag determines if documentation that is typed after a\n# \\internal command is included. If the tag is set to NO then the documentation\n# will be excluded. Set it to YES to include the internal documentation.\n# The default value is: NO.\n\nINTERNAL_DOCS          = NO\n\n# If the CASE_SENSE_NAMES tag is set to NO then doxygen will only generate file\n# names in lower-case letters. If set to YES upper-case letters are also\n# allowed. This is useful if you have classes or files whose names only differ\n# in case and if your file system supports case sensitive file names. Windows\n# and Mac users are advised to set this option to NO.\n# The default value is: system dependent.\n\nCASE_SENSE_NAMES       = NO\n\n# If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with\n# their full class and namespace scopes in the documentation. If set to YES the\n# scope will be hidden.\n# The default value is: NO.\n\nHIDE_SCOPE_NAMES       = NO\n\n# If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of\n# the files that are included by a file in the documentation of that file.\n# The default value is: YES.\n\nSHOW_INCLUDE_FILES     = YES\n\n# If the SHOW_GROUPED_MEMB_INC tag is set to YES then Doxygen will add for each\n# grouped member an include statement to the documentation, telling the reader\n# which file to include in order to use the member.\n# The default value is: NO.\n\nSHOW_GROUPED_MEMB_INC  = NO\n\n# If the FORCE_LOCAL_INCLUDES tag is set to YES then doxygen will list include\n# files with double quotes in the documentation rather than with sharp brackets.\n# The default value is: NO.\n\nFORCE_LOCAL_INCLUDES   = NO\n\n# If the INLINE_INFO tag is set to YES then a tag [inline] is inserted in the\n# documentation for inline members.\n# The default value is: YES.\n\nINLINE_INFO            = YES\n\n# If the SORT_MEMBER_DOCS tag is set to YES then doxygen will sort the\n# (detailed) documentation of file and class members alphabetically by member\n# name. If set to NO the members will appear in declaration order.\n# The default value is: YES.\n\nSORT_MEMBER_DOCS       = YES\n\n# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief\n# descriptions of file, namespace and class members alphabetically by member\n# name. If set to NO the members will appear in declaration order. Note that\n# this will also influence the order of the classes in the class list.\n# The default value is: NO.\n\nSORT_BRIEF_DOCS        = NO\n\n# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the\n# (brief and detailed) documentation of class members so that constructors and\n# destructors are listed first. If set to NO the constructors will appear in the\n# respective orders defined by SORT_BRIEF_DOCS and SORT_MEMBER_DOCS.\n# Note: If SORT_BRIEF_DOCS is set to NO this option is ignored for sorting brief\n# member documentation.\n# Note: If SORT_MEMBER_DOCS is set to NO this option is ignored for sorting\n# detailed member documentation.\n# The default value is: NO.\n\nSORT_MEMBERS_CTORS_1ST = NO\n\n# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the hierarchy\n# of group names into alphabetical order. If set to NO the group names will\n# appear in their defined order.\n# The default value is: NO.\n\nSORT_GROUP_NAMES       = NO\n\n# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be sorted by\n# fully-qualified names, including namespaces. If set to NO, the class list will\n# be sorted only by class name, not including the namespace part.\n# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.\n# Note: This option applies only to the class list, not to the alphabetical\n# list.\n# The default value is: NO.\n\nSORT_BY_SCOPE_NAME     = NO\n\n# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to do proper\n# type resolution of all parameters of a function it will reject a match between\n# the prototype and the implementation of a member function even if there is\n# only one candidate or it is obvious which candidate to choose by doing a\n# simple string match. By disabling STRICT_PROTO_MATCHING doxygen will still\n# accept a match between prototype and implementation in such cases.\n# The default value is: NO.\n\nSTRICT_PROTO_MATCHING  = NO\n\n# The GENERATE_TODOLIST tag can be used to enable ( YES) or disable ( NO) the\n# todo list. This list is created by putting \\todo commands in the\n# documentation.\n# The default value is: YES.\n\nGENERATE_TODOLIST      = YES\n\n# The GENERATE_TESTLIST tag can be used to enable ( YES) or disable ( NO) the\n# test list. This list is created by putting \\test commands in the\n# documentation.\n# The default value is: YES.\n\nGENERATE_TESTLIST      = YES\n\n# The GENERATE_BUGLIST tag can be used to enable ( YES) or disable ( NO) the bug\n# list. This list is created by putting \\bug commands in the documentation.\n# The default value is: YES.\n\nGENERATE_BUGLIST       = YES\n\n# The GENERATE_DEPRECATEDLIST tag can be used to enable ( YES) or disable ( NO)\n# the deprecated list. This list is created by putting \\deprecated commands in\n# the documentation.\n# The default value is: YES.\n\nGENERATE_DEPRECATEDLIST= YES\n\n# The ENABLED_SECTIONS tag can be used to enable conditional documentation\n# sections, marked by \\if <section_label> ... \\endif and \\cond <section_label>\n# ... \\endcond blocks.\n\nENABLED_SECTIONS       = \n\n# The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the\n# initial value of a variable or macro / define can have for it to appear in the\n# documentation. If the initializer consists of more lines than specified here\n# it will be hidden. Use a value of 0 to hide initializers completely. The\n# appearance of the value of individual variables and macros / defines can be\n# controlled using \\showinitializer or \\hideinitializer command in the\n# documentation regardless of this setting.\n# Minimum value: 0, maximum value: 10000, default value: 30.\n\nMAX_INITIALIZER_LINES  = 30\n\n# Set the SHOW_USED_FILES tag to NO to disable the list of files generated at\n# the bottom of the documentation of classes and structs. If set to YES the list\n# will mention the files that were used to generate the documentation.\n# The default value is: YES.\n\nSHOW_USED_FILES        = YES\n\n# Set the SHOW_FILES tag to NO to disable the generation of the Files page. This\n# will remove the Files entry from the Quick Index and from the Folder Tree View\n# (if specified).\n# The default value is: YES.\n\nSHOW_FILES             = YES\n\n# Set the SHOW_NAMESPACES tag to NO to disable the generation of the Namespaces\n# page. This will remove the Namespaces entry from the Quick Index and from the\n# Folder Tree View (if specified).\n# The default value is: YES.\n\nSHOW_NAMESPACES        = YES\n\n# The FILE_VERSION_FILTER tag can be used to specify a program or script that\n# doxygen should invoke to get the current version for each file (typically from\n# the version control system). Doxygen will invoke the program by executing (via\n# popen()) the command command input-file, where command is the value of the\n# FILE_VERSION_FILTER tag, and input-file is the name of an input file provided\n# by doxygen. Whatever the program writes to standard output is used as the file\n# version. For an example see the documentation.\n\nFILE_VERSION_FILTER    = \n\n# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed\n# by doxygen. The layout file controls the global structure of the generated\n# output files in an output format independent way. To create the layout file\n# that represents doxygen's defaults, run doxygen with the -l option. You can\n# optionally specify a file name after the option, if omitted DoxygenLayout.xml\n# will be used as the name of the layout file.\n#\n# Note that if you run doxygen from a directory containing a file called\n# DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE\n# tag is left empty.\n\nLAYOUT_FILE            = \n\n# The CITE_BIB_FILES tag can be used to specify one or more bib files containing\n# the reference definitions. This must be a list of .bib files. The .bib\n# extension is automatically appended if omitted. This requires the bibtex tool\n# to be installed. See also http://en.wikipedia.org/wiki/BibTeX for more info.\n# For LaTeX the style of the bibliography can be controlled using\n# LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the\n# search path. See also \\cite for info how to create references.\n\nCITE_BIB_FILES         = \n\n#---------------------------------------------------------------------------\n# Configuration options related to warning and progress messages\n#---------------------------------------------------------------------------\n\n# The QUIET tag can be used to turn on/off the messages that are generated to\n# standard output by doxygen. If QUIET is set to YES this implies that the\n# messages are off.\n# The default value is: NO.\n\nQUIET                  = NO\n\n# The WARNINGS tag can be used to turn on/off the warning messages that are\n# generated to standard error ( stderr) by doxygen. If WARNINGS is set to YES\n# this implies that the warnings are on.\n#\n# Tip: Turn warnings on while writing the documentation.\n# The default value is: YES.\n\nWARNINGS               = YES\n\n# If the WARN_IF_UNDOCUMENTED tag is set to YES, then doxygen will generate\n# warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag\n# will automatically be disabled.\n# The default value is: YES.\n\nWARN_IF_UNDOCUMENTED   = YES\n\n# If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for\n# potential errors in the documentation, such as not documenting some parameters\n# in a documented function, or documenting parameters that don't exist or using\n# markup commands wrongly.\n# The default value is: YES.\n\nWARN_IF_DOC_ERROR      = YES\n\n# This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that\n# are documented, but have no documentation for their parameters or return\n# value. If set to NO doxygen will only warn about wrong or incomplete parameter\n# documentation, but not about the absence of documentation.\n# The default value is: NO.\n\nWARN_NO_PARAMDOC       = NO\n\n# The WARN_FORMAT tag determines the format of the warning messages that doxygen\n# can produce. The string should contain the $file, $line, and $text tags, which\n# will be replaced by the file and line number from which the warning originated\n# and the warning text. Optionally the format may contain $version, which will\n# be replaced by the version of the file (if it could be obtained via\n# FILE_VERSION_FILTER)\n# The default value is: $file:$line: $text.\n\nWARN_FORMAT            = \"$file:$line: $text\"\n\n# The WARN_LOGFILE tag can be used to specify a file to which warning and error\n# messages should be written. If left blank the output is written to standard\n# error (stderr).\n\nWARN_LOGFILE           = \n\n#---------------------------------------------------------------------------\n# Configuration options related to the input files\n#---------------------------------------------------------------------------\n\n# The INPUT tag is used to specify the files and/or directories that contain\n# documented source files. You may enter file names like myfile.cpp or\n# directories like /usr/src/myproject. Separate the files or directories with\n# spaces.\n# Note: If this tag is empty the current directory is searched.\n\nINPUT                  = ../headers/modsecurity/modsecurity.h ../src ../headers\n\n# This tag can be used to specify the character encoding of the source files\n# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses\n# libiconv (or the iconv built into libc) for the transcoding. See the libiconv\n# documentation (see: http://www.gnu.org/software/libiconv) for the list of\n# possible encodings.\n# The default value is: UTF-8.\n\nINPUT_ENCODING         = UTF-8\n\n# If the value of the INPUT tag contains directories, you can use the\n# FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and\n# *.h) to filter out the source-files in the directories. If left blank the\n# following patterns are tested:*.c, *.cc, *.cxx, *.cpp, *.c++, *.java, *.ii,\n# *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h, *.hh, *.hxx, *.hpp,\n# *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc, *.m, *.markdown,\n# *.md, *.mm, *.dox, *.py, *.f90, *.f, *.for, *.tcl, *.vhd, *.vhdl, *.ucf,\n# *.qsf, *.as and *.js.\n\nFILE_PATTERNS          = *.c \\\n                         *.cc \\\n                         *.cxx \\\n                         *.cpp \\\n                         *.c++ \\\n                         *.java \\\n                         *.ii \\\n                         *.ixx \\\n                         *.ipp \\\n                         *.i++ \\\n                         *.inl \\\n                         *.idl \\\n                         *.ddl \\\n                         *.odl \\\n                         *.h \\\n                         *.hh \\\n                         *.hxx \\\n                         *.hpp \\\n                         *.h++ \\\n                         *.cs \\\n                         *.d \\\n                         *.php \\\n                         *.php4 \\\n                         *.php5 \\\n                         *.phtml \\\n                         *.inc \\\n                         *.m \\\n                         *.markdown \\\n                         *.md \\\n                         *.mm \\\n                         *.dox \\\n                         *.py \\\n                         *.f90 \\\n                         *.f \\\n                         *.for \\\n                         *.tcl \\\n                         *.vhd \\\n                         *.vhdl \\\n                         *.ucf \\\n                         *.qsf \\\n                         *.as \\\n                         *.js\n\n# The RECURSIVE tag can be used to specify whether or not subdirectories should\n# be searched for input files as well.\n# The default value is: NO.\n\nRECURSIVE              = YES\n\n# The EXCLUDE tag can be used to specify files and/or directories that should be\n# excluded from the INPUT source files. This way you can easily exclude a\n# subdirectory from a directory tree whose root is specified with the INPUT tag.\n#\n# Note that relative paths are relative to the directory from which doxygen is\n# run.\n\nEXCLUDE                = \n\n# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or\n# directories that are symbolic links (a Unix file system feature) are excluded\n# from the input.\n# The default value is: NO.\n\nEXCLUDE_SYMLINKS       = NO\n\n# If the value of the INPUT tag contains directories, you can use the\n# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude\n# certain files from those directories.\n#\n# Note that the wildcards are matched against the file with absolute path, so to\n# exclude all test directories for example use the pattern */test/*\n\nEXCLUDE_PATTERNS       = \n\n# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names\n# (namespaces, classes, functions, etc.) that should be excluded from the\n# output. The symbol name can be a fully qualified name, a word, or if the\n# wildcard * is used, a substring. Examples: ANamespace, AClass,\n# AClass::ANamespace, ANamespace::*Test\n#\n# Note that the wildcards are matched against the file with absolute path, so to\n# exclude all test directories use the pattern */test/*\n\nEXCLUDE_SYMBOLS        = \n\n# The EXAMPLE_PATH tag can be used to specify one or more files or directories\n# that contain example code fragments that are included (see the \\include\n# command).\n\nEXAMPLE_PATH           = \n\n# If the value of the EXAMPLE_PATH tag contains directories, you can use the\n# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and\n# *.h) to filter out the source-files in the directories. If left blank all\n# files are included.\n\nEXAMPLE_PATTERNS       = *\n\n# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be\n# searched for input files to be used with the \\include or \\dontinclude commands\n# irrespective of the value of the RECURSIVE tag.\n# The default value is: NO.\n\nEXAMPLE_RECURSIVE      = NO\n\n# The IMAGE_PATH tag can be used to specify one or more files or directories\n# that contain images that are to be included in the documentation (see the\n# \\image command).\n\nIMAGE_PATH             = \n\n# The INPUT_FILTER tag can be used to specify a program that doxygen should\n# invoke to filter for each input file. Doxygen will invoke the filter program\n# by executing (via popen()) the command:\n#\n# <filter> <input-file>\n#\n# where <filter> is the value of the INPUT_FILTER tag, and <input-file> is the\n# name of an input file. Doxygen will then use the output that the filter\n# program writes to standard output. If FILTER_PATTERNS is specified, this tag\n# will be ignored.\n#\n# Note that the filter must not add or remove lines; it is applied before the\n# code is scanned, but not when the output code is generated. If lines are added\n# or removed, the anchors will not be placed correctly.\n\nINPUT_FILTER           = \n\n# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern\n# basis. Doxygen will compare the file name with each pattern and apply the\n# filter if there is a match. The filters are a list of the form: pattern=filter\n# (like *.cpp=my_cpp_filter). See INPUT_FILTER for further information on how\n# filters are used. If the FILTER_PATTERNS tag is empty or if none of the\n# patterns match the file name, INPUT_FILTER is applied.\n\nFILTER_PATTERNS        = \n\n# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using\n# INPUT_FILTER ) will also be used to filter the input files that are used for\n# producing the source files to browse (i.e. when SOURCE_BROWSER is set to YES).\n# The default value is: NO.\n\nFILTER_SOURCE_FILES    = NO\n\n# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file\n# pattern. A pattern will override the setting for FILTER_PATTERN (if any) and\n# it is also possible to disable source filtering for a specific pattern using\n# *.ext= (so without naming a filter).\n# This tag requires that the tag FILTER_SOURCE_FILES is set to YES.\n\nFILTER_SOURCE_PATTERNS = \n\n# If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that\n# is part of the input, its contents will be placed on the main page\n# (index.html). This can be useful if you have a project on for instance GitHub\n# and want to reuse the introduction page also for the doxygen output.\n\nUSE_MDFILE_AS_MAINPAGE = \n\n#---------------------------------------------------------------------------\n# Configuration options related to source browsing\n#---------------------------------------------------------------------------\n\n# If the SOURCE_BROWSER tag is set to YES then a list of source files will be\n# generated. Documented entities will be cross-referenced with these sources.\n#\n# Note: To get rid of all source code in the generated output, make sure that\n# also VERBATIM_HEADERS is set to NO.\n# The default value is: NO.\n\nSOURCE_BROWSER         = YES\n\n# Setting the INLINE_SOURCES tag to YES will include the body of functions,\n# classes and enums directly into the documentation.\n# The default value is: NO.\n\nINLINE_SOURCES         = NO\n\n# Setting the STRIP_CODE_COMMENTS tag to YES will instruct doxygen to hide any\n# special comment blocks from generated source code fragments. Normal C, C++ and\n# Fortran comments will always remain visible.\n# The default value is: YES.\n\nSTRIP_CODE_COMMENTS    = YES\n\n# If the REFERENCED_BY_RELATION tag is set to YES then for each documented\n# function all documented functions referencing it will be listed.\n# The default value is: NO.\n\nREFERENCED_BY_RELATION = NO\n\n# If the REFERENCES_RELATION tag is set to YES then for each documented function\n# all documented entities called/used by that function will be listed.\n# The default value is: NO.\n\nREFERENCES_RELATION    = NO\n\n# If the REFERENCES_LINK_SOURCE tag is set to YES and SOURCE_BROWSER tag is set\n# to YES, then the hyperlinks from functions in REFERENCES_RELATION and\n# REFERENCED_BY_RELATION lists will link to the source code. Otherwise they will\n# link to the documentation.\n# The default value is: YES.\n\nREFERENCES_LINK_SOURCE = YES\n\n# If SOURCE_TOOLTIPS is enabled (the default) then hovering a hyperlink in the\n# source code will show a tooltip with additional information such as prototype,\n# brief description and links to the definition and documentation. Since this\n# will make the HTML file larger and loading of large files a bit slower, you\n# can opt to disable this feature.\n# The default value is: YES.\n# This tag requires that the tag SOURCE_BROWSER is set to YES.\n\nSOURCE_TOOLTIPS        = YES\n\n# If the USE_HTAGS tag is set to YES then the references to source code will\n# point to the HTML generated by the htags(1) tool instead of doxygen built-in\n# source browser. The htags tool is part of GNU's global source tagging system\n# (see http://www.gnu.org/software/global/global.html). You will need version\n# 4.8.6 or higher.\n#\n# To use it do the following:\n# - Install the latest version of global\n# - Enable SOURCE_BROWSER and USE_HTAGS in the config file\n# - Make sure the INPUT points to the root of the source tree\n# - Run doxygen as normal\n#\n# Doxygen will invoke htags (and that will in turn invoke gtags), so these\n# tools must be available from the command line (i.e. in the search path).\n#\n# The result: instead of the source browser generated by doxygen, the links to\n# source code will now point to the output of htags.\n# The default value is: NO.\n# This tag requires that the tag SOURCE_BROWSER is set to YES.\n\nUSE_HTAGS              = NO\n\n# If the VERBATIM_HEADERS tag is set the YES then doxygen will generate a\n# verbatim copy of the header file for each class for which an include is\n# specified. Set to NO to disable this.\n# See also: Section \\class.\n# The default value is: YES.\n\nVERBATIM_HEADERS       = YES\n\n# If the CLANG_ASSISTED_PARSING tag is set to YES, then doxygen will use the\n# clang parser (see: http://clang.llvm.org/) for more accurate parsing at the\n# cost of reduced performance. This can be particularly helpful with template\n# rich C++ code for which doxygen's built-in parser lacks the necessary type\n# information.\n# Note: The availability of this option depends on whether or not doxygen was\n# compiled with the --with-libclang option.\n# The default value is: NO.\n\nCLANG_ASSISTED_PARSING = NO\n\n# If clang assisted parsing is enabled you can provide the compiler with command\n# line options that you would normally use when invoking the compiler. Note that\n# the include paths will already be set by doxygen for the files and directories\n# specified with INPUT and INCLUDE_PATH.\n# This tag requires that the tag CLANG_ASSISTED_PARSING is set to YES.\n\nCLANG_OPTIONS          = \n\n#---------------------------------------------------------------------------\n# Configuration options related to the alphabetical class index\n#---------------------------------------------------------------------------\n\n# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index of all\n# compounds will be generated. Enable this if the project contains a lot of\n# classes, structs, unions or interfaces.\n# The default value is: YES.\n\nALPHABETICAL_INDEX     = YES\n\n# The COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns in\n# which the alphabetical index list will be split.\n# Minimum value: 1, maximum value: 20, default value: 5.\n# This tag requires that the tag ALPHABETICAL_INDEX is set to YES.\n\nCOLS_IN_ALPHA_INDEX    = 5\n\n# In case all classes in a project start with a common prefix, all classes will\n# be put under the same header in the alphabetical index. The IGNORE_PREFIX tag\n# can be used to specify a prefix (or a list of prefixes) that should be ignored\n# while generating the index headers.\n# This tag requires that the tag ALPHABETICAL_INDEX is set to YES.\n\nIGNORE_PREFIX          = \n\n#---------------------------------------------------------------------------\n# Configuration options related to the HTML output\n#---------------------------------------------------------------------------\n\n# If the GENERATE_HTML tag is set to YES doxygen will generate HTML output\n# The default value is: YES.\n\nGENERATE_HTML          = YES\n\n# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. If a\n# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of\n# it.\n# The default directory is: html.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nHTML_OUTPUT            = html\n\n# The HTML_FILE_EXTENSION tag can be used to specify the file extension for each\n# generated HTML page (for example: .htm, .php, .asp).\n# The default value is: .html.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nHTML_FILE_EXTENSION    = .html\n\n# The HTML_HEADER tag can be used to specify a user-defined HTML header file for\n# each generated HTML page. If the tag is left blank doxygen will generate a\n# standard header.\n#\n# To get valid HTML the header file that includes any scripts and style sheets\n# that doxygen needs, which is dependent on the configuration options used (e.g.\n# the setting GENERATE_TREEVIEW). It is highly recommended to start with a\n# default header using\n# doxygen -w html new_header.html new_footer.html new_stylesheet.css\n# YourConfigFile\n# and then modify the file new_header.html. See also section \"Doxygen usage\"\n# for information on how to generate the default header that doxygen normally\n# uses.\n# Note: The header is subject to change so you typically have to regenerate the\n# default header when upgrading to a newer version of doxygen. For a description\n# of the possible markers and block names see the documentation.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nHTML_HEADER            = \n\n# The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each\n# generated HTML page. If the tag is left blank doxygen will generate a standard\n# footer. See HTML_HEADER for more information on how to generate a default\n# footer and what special commands can be used inside the footer. See also\n# section \"Doxygen usage\" for information on how to generate the default footer\n# that doxygen normally uses.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nHTML_FOOTER            = \n\n# The HTML_STYLESHEET tag can be used to specify a user-defined cascading style\n# sheet that is used by each HTML page. It can be used to fine-tune the look of\n# the HTML output. If left blank doxygen will generate a default style sheet.\n# See also section \"Doxygen usage\" for information on how to generate the style\n# sheet that doxygen normally uses.\n# Note: It is recommended to use HTML_EXTRA_STYLESHEET instead of this tag, as\n# it is more robust and this tag (HTML_STYLESHEET) will in the future become\n# obsolete.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nHTML_STYLESHEET        = \n\n# The HTML_EXTRA_STYLESHEET tag can be used to specify additional user-defined\n# cascading style sheets that are included after the standard style sheets\n# created by doxygen. Using this option one can overrule certain style aspects.\n# This is preferred over using HTML_STYLESHEET since it does not replace the\n# standard style sheet and is therefor more robust against future updates.\n# Doxygen will copy the style sheet files to the output directory.\n# Note: The order of the extra stylesheet files is of importance (e.g. the last\n# stylesheet in the list overrules the setting of the previous ones in the\n# list). For an example see the documentation.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nHTML_EXTRA_STYLESHEET  = \n\n# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or\n# other source files which should be copied to the HTML output directory. Note\n# that these files will be copied to the base HTML output directory. Use the\n# $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these\n# files. In the HTML_STYLESHEET file, use the file name only. Also note that the\n# files will be copied as-is; there are no commands or markers available.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nHTML_EXTRA_FILES       = \n\n# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen\n# will adjust the colors in the stylesheet and background images according to\n# this color. Hue is specified as an angle on a colorwheel, see\n# http://en.wikipedia.org/wiki/Hue for more information. For instance the value\n# 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300\n# purple, and 360 is red again.\n# Minimum value: 0, maximum value: 359, default value: 220.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nHTML_COLORSTYLE_HUE    = 220\n\n# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors\n# in the HTML output. For a value of 0 the output will use grayscales only. A\n# value of 255 will produce the most vivid colors.\n# Minimum value: 0, maximum value: 255, default value: 100.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nHTML_COLORSTYLE_SAT    = 100\n\n# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to the\n# luminance component of the colors in the HTML output. Values below 100\n# gradually make the output lighter, whereas values above 100 make the output\n# darker. The value divided by 100 is the actual gamma applied, so 80 represents\n# a gamma of 0.8, The value 220 represents a gamma of 2.2, and 100 does not\n# change the gamma.\n# Minimum value: 40, maximum value: 240, default value: 80.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nHTML_COLORSTYLE_GAMMA  = 80\n\n# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML\n# page will contain the date and time when the page was generated. Setting this\n# to NO can help when comparing the output of multiple runs.\n# The default value is: YES.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nHTML_TIMESTAMP         = YES\n\n# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML\n# documentation will contain sections that can be hidden and shown after the\n# page has loaded.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nHTML_DYNAMIC_SECTIONS  = NO\n\n# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries\n# shown in the various tree structured indices initially; the user can expand\n# and collapse entries dynamically later on. Doxygen will expand the tree to\n# such a level that at most the specified number of entries are visible (unless\n# a fully collapsed tree already exceeds this amount). So setting the number of\n# entries 1 will produce a full collapsed tree by default. 0 is a special value\n# representing an infinite number of entries and will result in a full expanded\n# tree by default.\n# Minimum value: 0, maximum value: 9999, default value: 100.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nHTML_INDEX_NUM_ENTRIES = 100\n\n# If the GENERATE_DOCSET tag is set to YES, additional index files will be\n# generated that can be used as input for Apple's Xcode 3 integrated development\n# environment (see: http://developer.apple.com/tools/xcode/), introduced with\n# OSX 10.5 (Leopard). To create a documentation set, doxygen will generate a\n# Makefile in the HTML output directory. Running make will produce the docset in\n# that directory and running make install will install the docset in\n# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at\n# startup. See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html\n# for more information.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nGENERATE_DOCSET        = NO\n\n# This tag determines the name of the docset feed. A documentation feed provides\n# an umbrella under which multiple documentation sets from a single provider\n# (such as a company or product suite) can be grouped.\n# The default value is: Doxygen generated docs.\n# This tag requires that the tag GENERATE_DOCSET is set to YES.\n\nDOCSET_FEEDNAME        = \"Doxygen generated docs\"\n\n# This tag specifies a string that should uniquely identify the documentation\n# set bundle. This should be a reverse domain-name style string, e.g.\n# com.mycompany.MyDocSet. Doxygen will append .docset to the name.\n# The default value is: org.doxygen.Project.\n# This tag requires that the tag GENERATE_DOCSET is set to YES.\n\nDOCSET_BUNDLE_ID       = org.doxygen.Project\n\n# The DOCSET_PUBLISHER_ID tag specifies a string that should uniquely identify\n# the documentation publisher. This should be a reverse domain-name style\n# string, e.g. com.mycompany.MyDocSet.documentation.\n# The default value is: org.doxygen.Publisher.\n# This tag requires that the tag GENERATE_DOCSET is set to YES.\n\nDOCSET_PUBLISHER_ID    = org.doxygen.Publisher\n\n# The DOCSET_PUBLISHER_NAME tag identifies the documentation publisher.\n# The default value is: Publisher.\n# This tag requires that the tag GENERATE_DOCSET is set to YES.\n\nDOCSET_PUBLISHER_NAME  = Publisher\n\n# If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three\n# additional HTML index files: index.hhp, index.hhc, and index.hhk. The\n# index.hhp is a project file that can be read by Microsoft's HTML Help Workshop\n# (see: http://www.microsoft.com/en-us/download/details.aspx?id=21138) on\n# Windows.\n#\n# The HTML Help Workshop contains a compiler that can convert all HTML output\n# generated by doxygen into a single compiled HTML file (.chm). Compiled HTML\n# files are now used as the Windows 98 help format, and will replace the old\n# Windows help format (.hlp) on all Windows platforms in the future. Compressed\n# HTML files also contain an index, a table of contents, and you can search for\n# words in the documentation. The HTML workshop also contains a viewer for\n# compressed HTML files.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nGENERATE_HTMLHELP      = NO\n\n# The CHM_FILE tag can be used to specify the file name of the resulting .chm\n# file. You can add a path in front of the file if the result should not be\n# written to the html output directory.\n# This tag requires that the tag GENERATE_HTMLHELP is set to YES.\n\nCHM_FILE               = \n\n# The HHC_LOCATION tag can be used to specify the location (absolute path\n# including file name) of the HTML help compiler ( hhc.exe). If non-empty\n# doxygen will try to run the HTML help compiler on the generated index.hhp.\n# The file has to be specified with full path.\n# This tag requires that the tag GENERATE_HTMLHELP is set to YES.\n\nHHC_LOCATION           = \n\n# The GENERATE_CHI flag controls if a separate .chi index file is generated (\n# YES) or that it should be included in the master .chm file ( NO).\n# The default value is: NO.\n# This tag requires that the tag GENERATE_HTMLHELP is set to YES.\n\nGENERATE_CHI           = NO\n\n# The CHM_INDEX_ENCODING is used to encode HtmlHelp index ( hhk), content ( hhc)\n# and project file content.\n# This tag requires that the tag GENERATE_HTMLHELP is set to YES.\n\nCHM_INDEX_ENCODING     = \n\n# The BINARY_TOC flag controls whether a binary table of contents is generated (\n# YES) or a normal table of contents ( NO) in the .chm file. Furthermore it\n# enables the Previous and Next buttons.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_HTMLHELP is set to YES.\n\nBINARY_TOC             = NO\n\n# The TOC_EXPAND flag can be set to YES to add extra items for group members to\n# the table of contents of the HTML help documentation and to the tree view.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_HTMLHELP is set to YES.\n\nTOC_EXPAND             = NO\n\n# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and\n# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that\n# can be used as input for Qt's qhelpgenerator to generate a Qt Compressed Help\n# (.qch) of the generated HTML documentation.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nGENERATE_QHP           = NO\n\n# If the QHG_LOCATION tag is specified, the QCH_FILE tag can be used to specify\n# the file name of the resulting .qch file. The path specified is relative to\n# the HTML output folder.\n# This tag requires that the tag GENERATE_QHP is set to YES.\n\nQCH_FILE               = \n\n# The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help\n# Project output. For more information please see Qt Help Project / Namespace\n# (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#namespace).\n# The default value is: org.doxygen.Project.\n# This tag requires that the tag GENERATE_QHP is set to YES.\n\nQHP_NAMESPACE          = org.doxygen.Project\n\n# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt\n# Help Project output. For more information please see Qt Help Project / Virtual\n# Folders (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#virtual-\n# folders).\n# The default value is: doc.\n# This tag requires that the tag GENERATE_QHP is set to YES.\n\nQHP_VIRTUAL_FOLDER     = doc\n\n# If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom\n# filter to add. For more information please see Qt Help Project / Custom\n# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom-\n# filters).\n# This tag requires that the tag GENERATE_QHP is set to YES.\n\nQHP_CUST_FILTER_NAME   = \n\n# The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the\n# custom filter to add. For more information please see Qt Help Project / Custom\n# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom-\n# filters).\n# This tag requires that the tag GENERATE_QHP is set to YES.\n\nQHP_CUST_FILTER_ATTRS  = \n\n# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this\n# project's filter section matches. Qt Help Project / Filter Attributes (see:\n# http://qt-project.org/doc/qt-4.8/qthelpproject.html#filter-attributes).\n# This tag requires that the tag GENERATE_QHP is set to YES.\n\nQHP_SECT_FILTER_ATTRS  = \n\n# The QHG_LOCATION tag can be used to specify the location of Qt's\n# qhelpgenerator. If non-empty doxygen will try to run qhelpgenerator on the\n# generated .qhp file.\n# This tag requires that the tag GENERATE_QHP is set to YES.\n\nQHG_LOCATION           = \n\n# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be\n# generated, together with the HTML files, they form an Eclipse help plugin. To\n# install this plugin and make it available under the help contents menu in\n# Eclipse, the contents of the directory containing the HTML and XML files needs\n# to be copied into the plugins directory of eclipse. The name of the directory\n# within the plugins directory should be the same as the ECLIPSE_DOC_ID value.\n# After copying Eclipse needs to be restarted before the help appears.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nGENERATE_ECLIPSEHELP   = NO\n\n# A unique identifier for the Eclipse help plugin. When installing the plugin\n# the directory name containing the HTML and XML files should also have this\n# name. Each documentation set should have its own identifier.\n# The default value is: org.doxygen.Project.\n# This tag requires that the tag GENERATE_ECLIPSEHELP is set to YES.\n\nECLIPSE_DOC_ID         = org.doxygen.Project\n\n# If you want full control over the layout of the generated HTML pages it might\n# be necessary to disable the index and replace it with your own. The\n# DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) at top\n# of each HTML page. A value of NO enables the index and the value YES disables\n# it. Since the tabs in the index contain the same information as the navigation\n# tree, you can set this option to YES if you also set GENERATE_TREEVIEW to YES.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nDISABLE_INDEX          = NO\n\n# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index\n# structure should be generated to display hierarchical information. If the tag\n# value is set to YES, a side panel will be generated containing a tree-like\n# index structure (just like the one that is generated for HTML Help). For this\n# to work a browser that supports JavaScript, DHTML, CSS and frames is required\n# (i.e. any modern browser). Windows users are probably better off using the\n# HTML help feature. Via custom stylesheets (see HTML_EXTRA_STYLESHEET) one can\n# further fine-tune the look of the index. As an example, the default style\n# sheet generated by doxygen has an example that shows how to put an image at\n# the root of the tree instead of the PROJECT_NAME. Since the tree basically has\n# the same information as the tab index, you could consider setting\n# DISABLE_INDEX to YES when enabling this option.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nGENERATE_TREEVIEW      = YES\n\n# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that\n# doxygen will group on one line in the generated HTML documentation.\n#\n# Note that a value of 0 will completely suppress the enum values from appearing\n# in the overview section.\n# Minimum value: 0, maximum value: 20, default value: 4.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nENUM_VALUES_PER_LINE   = 4\n\n# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be used\n# to set the initial width (in pixels) of the frame in which the tree is shown.\n# Minimum value: 0, maximum value: 1500, default value: 250.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nTREEVIEW_WIDTH         = 250\n\n# When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open links to\n# external symbols imported via tag files in a separate window.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nEXT_LINKS_IN_WINDOW    = NO\n\n# Use this tag to change the font size of LaTeX formulas included as images in\n# the HTML documentation. When you change the font size after a successful\n# doxygen run you need to manually remove any form_*.png images from the HTML\n# output directory to force them to be regenerated.\n# Minimum value: 8, maximum value: 50, default value: 10.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nFORMULA_FONTSIZE       = 10\n\n# Use the FORMULA_TRANPARENT tag to determine whether or not the images\n# generated for formulas are transparent PNGs. Transparent PNGs are not\n# supported properly for IE 6.0, but are supported on all modern browsers.\n#\n# Note that when changing this option you need to delete any form_*.png files in\n# the HTML output directory before the changes have effect.\n# The default value is: YES.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nFORMULA_TRANSPARENT    = YES\n\n# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see\n# http://www.mathjax.org) which uses client side Javascript for the rendering\n# instead of using prerendered bitmaps. Use this if you do not have LaTeX\n# installed or if you want to formulas look prettier in the HTML output. When\n# enabled you may also need to install MathJax separately and configure the path\n# to it using the MATHJAX_RELPATH option.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nUSE_MATHJAX            = NO\n\n# When MathJax is enabled you can set the default output format to be used for\n# the MathJax output. See the MathJax site (see:\n# http://docs.mathjax.org/en/latest/output.html) for more details.\n# Possible values are: HTML-CSS (which is slower, but has the best\n# compatibility), NativeMML (i.e. MathML) and SVG.\n# The default value is: HTML-CSS.\n# This tag requires that the tag USE_MATHJAX is set to YES.\n\nMATHJAX_FORMAT         = HTML-CSS\n\n# When MathJax is enabled you need to specify the location relative to the HTML\n# output directory using the MATHJAX_RELPATH option. The destination directory\n# should contain the MathJax.js script. For instance, if the mathjax directory\n# is located at the same level as the HTML output directory, then\n# MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax\n# Content Delivery Network so you can quickly see the result without installing\n# MathJax. However, it is strongly recommended to install a local copy of\n# MathJax from http://www.mathjax.org before deployment.\n# The default value is: http://cdn.mathjax.org/mathjax/latest.\n# This tag requires that the tag USE_MATHJAX is set to YES.\n\nMATHJAX_RELPATH        = http://cdn.mathjax.org/mathjax/latest\n\n# The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax\n# extension names that should be enabled during MathJax rendering. For example\n# MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols\n# This tag requires that the tag USE_MATHJAX is set to YES.\n\nMATHJAX_EXTENSIONS     = \n\n# The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces\n# of code that will be used on startup of the MathJax code. See the MathJax site\n# (see: http://docs.mathjax.org/en/latest/output.html) for more details. For an\n# example see the documentation.\n# This tag requires that the tag USE_MATHJAX is set to YES.\n\nMATHJAX_CODEFILE       = \n\n# When the SEARCHENGINE tag is enabled doxygen will generate a search box for\n# the HTML output. The underlying search engine uses javascript and DHTML and\n# should work on any modern browser. Note that when using HTML help\n# (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET)\n# there is already a search function so this one should typically be disabled.\n# For large projects the javascript based search engine can be slow, then\n# enabling SERVER_BASED_SEARCH may provide a better solution. It is possible to\n# search using the keyboard; to jump to the search box use <access key> + S\n# (what the <access key> is depends on the OS and browser, but it is typically\n# <CTRL>, <ALT>/<option>, or both). Inside the search box use the <cursor down\n# key> to jump into the search results window, the results can be navigated\n# using the <cursor keys>. Press <Enter> to select an item or <escape> to cancel\n# the search. The filter options can be selected when the cursor is inside the\n# search box by pressing <Shift>+<cursor down>. Also here use the <cursor keys>\n# to select a filter and <Enter> or <escape> to activate or cancel the filter\n# option.\n# The default value is: YES.\n# This tag requires that the tag GENERATE_HTML is set to YES.\n\nSEARCHENGINE           = YES\n\n# When the SERVER_BASED_SEARCH tag is enabled the search engine will be\n# implemented using a web server instead of a web client using Javascript. There\n# are two flavors of web server based searching depending on the EXTERNAL_SEARCH\n# setting. When disabled, doxygen will generate a PHP script for searching and\n# an index file used by the script. When EXTERNAL_SEARCH is enabled the indexing\n# and searching needs to be provided by external tools. See the section\n# \"External Indexing and Searching\" for details.\n# The default value is: NO.\n# This tag requires that the tag SEARCHENGINE is set to YES.\n\nSERVER_BASED_SEARCH    = NO\n\n# When EXTERNAL_SEARCH tag is enabled doxygen will no longer generate the PHP\n# script for searching. Instead the search results are written to an XML file\n# which needs to be processed by an external indexer. Doxygen will invoke an\n# external search engine pointed to by the SEARCHENGINE_URL option to obtain the\n# search results.\n#\n# Doxygen ships with an example indexer ( doxyindexer) and search engine\n# (doxysearch.cgi) which are based on the open source search engine library\n# Xapian (see: http://xapian.org/).\n#\n# See the section \"External Indexing and Searching\" for details.\n# The default value is: NO.\n# This tag requires that the tag SEARCHENGINE is set to YES.\n\nEXTERNAL_SEARCH        = NO\n\n# The SEARCHENGINE_URL should point to a search engine hosted by a web server\n# which will return the search results when EXTERNAL_SEARCH is enabled.\n#\n# Doxygen ships with an example indexer ( doxyindexer) and search engine\n# (doxysearch.cgi) which are based on the open source search engine library\n# Xapian (see: http://xapian.org/). See the section \"External Indexing and\n# Searching\" for details.\n# This tag requires that the tag SEARCHENGINE is set to YES.\n\nSEARCHENGINE_URL       = \n\n# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the unindexed\n# search data is written to a file for indexing by an external tool. With the\n# SEARCHDATA_FILE tag the name of this file can be specified.\n# The default file is: searchdata.xml.\n# This tag requires that the tag SEARCHENGINE is set to YES.\n\nSEARCHDATA_FILE        = searchdata.xml\n\n# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the\n# EXTERNAL_SEARCH_ID tag can be used as an identifier for the project. This is\n# useful in combination with EXTRA_SEARCH_MAPPINGS to search through multiple\n# projects and redirect the results back to the right project.\n# This tag requires that the tag SEARCHENGINE is set to YES.\n\nEXTERNAL_SEARCH_ID     = \n\n# The EXTRA_SEARCH_MAPPINGS tag can be used to enable searching through doxygen\n# projects other than the one defined by this configuration file, but that are\n# all added to the same external search index. Each project needs to have a\n# unique id set via EXTERNAL_SEARCH_ID. The search mapping then maps the id of\n# to a relative location where the documentation can be found. The format is:\n# EXTRA_SEARCH_MAPPINGS = tagname1=loc1 tagname2=loc2 ...\n# This tag requires that the tag SEARCHENGINE is set to YES.\n\nEXTRA_SEARCH_MAPPINGS  = \n\n#---------------------------------------------------------------------------\n# Configuration options related to the LaTeX output\n#---------------------------------------------------------------------------\n\n# If the GENERATE_LATEX tag is set to YES doxygen will generate LaTeX output.\n# The default value is: YES.\n\nGENERATE_LATEX         = YES\n\n# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. If a\n# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of\n# it.\n# The default directory is: latex.\n# This tag requires that the tag GENERATE_LATEX is set to YES.\n\nLATEX_OUTPUT           = latex\n\n# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be\n# invoked.\n#\n# Note that when enabling USE_PDFLATEX this option is only used for generating\n# bitmaps for formulas in the HTML output, but not in the Makefile that is\n# written to the output directory.\n# The default file is: latex.\n# This tag requires that the tag GENERATE_LATEX is set to YES.\n\nLATEX_CMD_NAME         = latex\n\n# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to generate\n# index for LaTeX.\n# The default file is: makeindex.\n# This tag requires that the tag GENERATE_LATEX is set to YES.\n\nMAKEINDEX_CMD_NAME     = makeindex\n\n# If the COMPACT_LATEX tag is set to YES doxygen generates more compact LaTeX\n# documents. This may be useful for small projects and may help to save some\n# trees in general.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_LATEX is set to YES.\n\nCOMPACT_LATEX          = NO\n\n# The PAPER_TYPE tag can be used to set the paper type that is used by the\n# printer.\n# Possible values are: a4 (210 x 297 mm), letter (8.5 x 11 inches), legal (8.5 x\n# 14 inches) and executive (7.25 x 10.5 inches).\n# The default value is: a4.\n# This tag requires that the tag GENERATE_LATEX is set to YES.\n\nPAPER_TYPE             = a4\n\n# The EXTRA_PACKAGES tag can be used to specify one or more LaTeX package names\n# that should be included in the LaTeX output. To get the times font for\n# instance you can specify\n# EXTRA_PACKAGES=times\n# If left blank no extra packages will be included.\n# This tag requires that the tag GENERATE_LATEX is set to YES.\n\nEXTRA_PACKAGES         = \n\n# The LATEX_HEADER tag can be used to specify a personal LaTeX header for the\n# generated LaTeX document. The header should contain everything until the first\n# chapter. If it is left blank doxygen will generate a standard header. See\n# section \"Doxygen usage\" for information on how to let doxygen write the\n# default header to a separate file.\n#\n# Note: Only use a user-defined header if you know what you are doing! The\n# following commands have a special meaning inside the header: $title,\n# $datetime, $date, $doxygenversion, $projectname, $projectnumber,\n# $projectbrief, $projectlogo. Doxygen will replace $title with the empy string,\n# for the replacement values of the other commands the user is refered to\n# HTML_HEADER.\n# This tag requires that the tag GENERATE_LATEX is set to YES.\n\nLATEX_HEADER           = \n\n# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for the\n# generated LaTeX document. The footer should contain everything after the last\n# chapter. If it is left blank doxygen will generate a standard footer. See\n# LATEX_HEADER for more information on how to generate a default footer and what\n# special commands can be used inside the footer.\n#\n# Note: Only use a user-defined footer if you know what you are doing!\n# This tag requires that the tag GENERATE_LATEX is set to YES.\n\nLATEX_FOOTER           = \n\n# The LATEX_EXTRA_FILES tag can be used to specify one or more extra images or\n# other source files which should be copied to the LATEX_OUTPUT output\n# directory. Note that the files will be copied as-is; there are no commands or\n# markers available.\n# This tag requires that the tag GENERATE_LATEX is set to YES.\n\nLATEX_EXTRA_FILES      = \n\n# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated is\n# prepared for conversion to PDF (using ps2pdf or pdflatex). The PDF file will\n# contain links (just like the HTML output) instead of page references. This\n# makes the output suitable for online browsing using a PDF viewer.\n# The default value is: YES.\n# This tag requires that the tag GENERATE_LATEX is set to YES.\n\nPDF_HYPERLINKS         = YES\n\n# If the USE_PDFLATEX tag is set to YES, doxygen will use pdflatex to generate\n# the PDF file directly from the LaTeX files. Set this option to YES to get a\n# higher quality PDF documentation.\n# The default value is: YES.\n# This tag requires that the tag GENERATE_LATEX is set to YES.\n\nUSE_PDFLATEX           = YES\n\n# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode\n# command to the generated LaTeX files. This will instruct LaTeX to keep running\n# if errors occur, instead of asking the user for help. This option is also used\n# when generating formulas in HTML.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_LATEX is set to YES.\n\nLATEX_BATCHMODE        = NO\n\n# If the LATEX_HIDE_INDICES tag is set to YES then doxygen will not include the\n# index chapters (such as File Index, Compound Index, etc.) in the output.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_LATEX is set to YES.\n\nLATEX_HIDE_INDICES     = NO\n\n# If the LATEX_SOURCE_CODE tag is set to YES then doxygen will include source\n# code with syntax highlighting in the LaTeX output.\n#\n# Note that which sources are shown also depends on other settings such as\n# SOURCE_BROWSER.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_LATEX is set to YES.\n\nLATEX_SOURCE_CODE      = NO\n\n# The LATEX_BIB_STYLE tag can be used to specify the style to use for the\n# bibliography, e.g. plainnat, or ieeetr. See\n# http://en.wikipedia.org/wiki/BibTeX and \\cite for more info.\n# The default value is: plain.\n# This tag requires that the tag GENERATE_LATEX is set to YES.\n\nLATEX_BIB_STYLE        = plain\n\n#---------------------------------------------------------------------------\n# Configuration options related to the RTF output\n#---------------------------------------------------------------------------\n\n# If the GENERATE_RTF tag is set to YES doxygen will generate RTF output. The\n# RTF output is optimized for Word 97 and may not look too pretty with other RTF\n# readers/editors.\n# The default value is: NO.\n\nGENERATE_RTF           = NO\n\n# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. If a\n# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of\n# it.\n# The default directory is: rtf.\n# This tag requires that the tag GENERATE_RTF is set to YES.\n\nRTF_OUTPUT             = rtf\n\n# If the COMPACT_RTF tag is set to YES doxygen generates more compact RTF\n# documents. This may be useful for small projects and may help to save some\n# trees in general.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_RTF is set to YES.\n\nCOMPACT_RTF            = NO\n\n# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated will\n# contain hyperlink fields. The RTF file will contain links (just like the HTML\n# output) instead of page references. This makes the output suitable for online\n# browsing using Word or some other Word compatible readers that support those\n# fields.\n#\n# Note: WordPad (write) and others do not support links.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_RTF is set to YES.\n\nRTF_HYPERLINKS         = NO\n\n# Load stylesheet definitions from file. Syntax is similar to doxygen's config\n# file, i.e. a series of assignments. You only have to provide replacements,\n# missing definitions are set to their default value.\n#\n# See also section \"Doxygen usage\" for information on how to generate the\n# default style sheet that doxygen normally uses.\n# This tag requires that the tag GENERATE_RTF is set to YES.\n\nRTF_STYLESHEET_FILE    = \n\n# Set optional variables used in the generation of an RTF document. Syntax is\n# similar to doxygen's config file. A template extensions file can be generated\n# using doxygen -e rtf extensionFile.\n# This tag requires that the tag GENERATE_RTF is set to YES.\n\nRTF_EXTENSIONS_FILE    = \n\n#---------------------------------------------------------------------------\n# Configuration options related to the man page output\n#---------------------------------------------------------------------------\n\n# If the GENERATE_MAN tag is set to YES doxygen will generate man pages for\n# classes and files.\n# The default value is: NO.\n\nGENERATE_MAN           = NO\n\n# The MAN_OUTPUT tag is used to specify where the man pages will be put. If a\n# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of\n# it. A directory man3 will be created inside the directory specified by\n# MAN_OUTPUT.\n# The default directory is: man.\n# This tag requires that the tag GENERATE_MAN is set to YES.\n\nMAN_OUTPUT             = man\n\n# The MAN_EXTENSION tag determines the extension that is added to the generated\n# man pages. In case the manual section does not start with a number, the number\n# 3 is prepended. The dot (.) at the beginning of the MAN_EXTENSION tag is\n# optional.\n# The default value is: .3.\n# This tag requires that the tag GENERATE_MAN is set to YES.\n\nMAN_EXTENSION          = .3\n\n# The MAN_SUBDIR tag determines the name of the directory created within\n# MAN_OUTPUT in which the man pages are placed. If defaults to man followed by\n# MAN_EXTENSION with the initial . removed.\n# This tag requires that the tag GENERATE_MAN is set to YES.\n\nMAN_SUBDIR             = \n\n# If the MAN_LINKS tag is set to YES and doxygen generates man output, then it\n# will generate one additional man file for each entity documented in the real\n# man page(s). These additional files only source the real man page, but without\n# them the man command would be unable to find the correct page.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_MAN is set to YES.\n\nMAN_LINKS              = NO\n\n#---------------------------------------------------------------------------\n# Configuration options related to the XML output\n#---------------------------------------------------------------------------\n\n# If the GENERATE_XML tag is set to YES doxygen will generate an XML file that\n# captures the structure of the code including all documentation.\n# The default value is: NO.\n\nGENERATE_XML           = NO\n\n# The XML_OUTPUT tag is used to specify where the XML pages will be put. If a\n# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of\n# it.\n# The default directory is: xml.\n# This tag requires that the tag GENERATE_XML is set to YES.\n\nXML_OUTPUT             = xml\n\n# If the XML_PROGRAMLISTING tag is set to YES doxygen will dump the program\n# listings (including syntax highlighting and cross-referencing information) to\n# the XML output. Note that enabling this will significantly increase the size\n# of the XML output.\n# The default value is: YES.\n# This tag requires that the tag GENERATE_XML is set to YES.\n\nXML_PROGRAMLISTING     = YES\n\n#---------------------------------------------------------------------------\n# Configuration options related to the DOCBOOK output\n#---------------------------------------------------------------------------\n\n# If the GENERATE_DOCBOOK tag is set to YES doxygen will generate Docbook files\n# that can be used to generate PDF.\n# The default value is: NO.\n\nGENERATE_DOCBOOK       = NO\n\n# The DOCBOOK_OUTPUT tag is used to specify where the Docbook pages will be put.\n# If a relative path is entered the value of OUTPUT_DIRECTORY will be put in\n# front of it.\n# The default directory is: docbook.\n# This tag requires that the tag GENERATE_DOCBOOK is set to YES.\n\nDOCBOOK_OUTPUT         = docbook\n\n# If the DOCBOOK_PROGRAMLISTING tag is set to YES doxygen will include the\n# program listings (including syntax highlighting and cross-referencing\n# information) to the DOCBOOK output. Note that enabling this will significantly\n# increase the size of the DOCBOOK output.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_DOCBOOK is set to YES.\n\nDOCBOOK_PROGRAMLISTING = NO\n\n#---------------------------------------------------------------------------\n# Configuration options for the AutoGen Definitions output\n#---------------------------------------------------------------------------\n\n# If the GENERATE_AUTOGEN_DEF tag is set to YES doxygen will generate an AutoGen\n# Definitions (see http://autogen.sf.net) file that captures the structure of\n# the code including all documentation. Note that this feature is still\n# experimental and incomplete at the moment.\n# The default value is: NO.\n\nGENERATE_AUTOGEN_DEF   = NO\n\n#---------------------------------------------------------------------------\n# Configuration options related to the Perl module output\n#---------------------------------------------------------------------------\n\n# If the GENERATE_PERLMOD tag is set to YES doxygen will generate a Perl module\n# file that captures the structure of the code including all documentation.\n#\n# Note that this feature is still experimental and incomplete at the moment.\n# The default value is: NO.\n\nGENERATE_PERLMOD       = NO\n\n# If the PERLMOD_LATEX tag is set to YES doxygen will generate the necessary\n# Makefile rules, Perl scripts and LaTeX code to be able to generate PDF and DVI\n# output from the Perl module output.\n# The default value is: NO.\n# This tag requires that the tag GENERATE_PERLMOD is set to YES.\n\nPERLMOD_LATEX          = NO\n\n# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be nicely\n# formatted so it can be parsed by a human reader. This is useful if you want to\n# understand what is going on. On the other hand, if this tag is set to NO the\n# size of the Perl module output will be much smaller and Perl will parse it\n# just the same.\n# The default value is: YES.\n# This tag requires that the tag GENERATE_PERLMOD is set to YES.\n\nPERLMOD_PRETTY         = YES\n\n# The names of the make variables in the generated doxyrules.make file are\n# prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. This is useful\n# so different doxyrules.make files included by the same Makefile don't\n# overwrite each other's variables.\n# This tag requires that the tag GENERATE_PERLMOD is set to YES.\n\nPERLMOD_MAKEVAR_PREFIX = \n\n#---------------------------------------------------------------------------\n# Configuration options related to the preprocessor\n#---------------------------------------------------------------------------\n\n# If the ENABLE_PREPROCESSING tag is set to YES doxygen will evaluate all\n# C-preprocessor directives found in the sources and include files.\n# The default value is: YES.\n\nENABLE_PREPROCESSING   = YES\n\n# If the MACRO_EXPANSION tag is set to YES doxygen will expand all macro names\n# in the source code. If set to NO only conditional compilation will be\n# performed. Macro expansion can be done in a controlled way by setting\n# EXPAND_ONLY_PREDEF to YES.\n# The default value is: NO.\n# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.\n\nMACRO_EXPANSION        = NO\n\n# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES then\n# the macro expansion is limited to the macros specified with the PREDEFINED and\n# EXPAND_AS_DEFINED tags.\n# The default value is: NO.\n# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.\n\nEXPAND_ONLY_PREDEF     = NO\n\n# If the SEARCH_INCLUDES tag is set to YES the includes files in the\n# INCLUDE_PATH will be searched if a #include is found.\n# The default value is: YES.\n# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.\n\nSEARCH_INCLUDES        = YES\n\n# The INCLUDE_PATH tag can be used to specify one or more directories that\n# contain include files that are not input files but should be processed by the\n# preprocessor.\n# This tag requires that the tag SEARCH_INCLUDES is set to YES.\n\nINCLUDE_PATH           = \n\n# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard\n# patterns (like *.h and *.hpp) to filter out the header-files in the\n# directories. If left blank, the patterns specified with FILE_PATTERNS will be\n# used.\n# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.\n\nINCLUDE_FILE_PATTERNS  = \n\n# The PREDEFINED tag can be used to specify one or more macro names that are\n# defined before the preprocessor is started (similar to the -D option of e.g.\n# gcc). The argument of the tag is a list of macros of the form: name or\n# name=definition (no spaces). If the definition and the \"=\" are omitted, \"=1\"\n# is assumed. To prevent a macro definition from being undefined via #undef or\n# recursively expanded use the := operator instead of the = operator.\n# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.\n\nPREDEFINED             =  __cplusplus=1\n\n# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this\n# tag can be used to specify a list of macro names that should be expanded. The\n# macro definition that is found in the sources will be used. Use the PREDEFINED\n# tag if you want to use a different macro definition that overrules the\n# definition found in the source code.\n# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.\n\nEXPAND_AS_DEFINED      = \n\n# If the SKIP_FUNCTION_MACROS tag is set to YES then doxygen's preprocessor will\n# remove all references to function-like macros that are alone on a line, have\n# an all uppercase name, and do not end with a semicolon. Such function macros\n# are typically used for boiler-plate code, and will confuse the parser if not\n# removed.\n# The default value is: YES.\n# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.\n\nSKIP_FUNCTION_MACROS   = YES\n\n#---------------------------------------------------------------------------\n# Configuration options related to external references\n#---------------------------------------------------------------------------\n\n# The TAGFILES tag can be used to specify one or more tag files. For each tag\n# file the location of the external documentation should be added. The format of\n# a tag file without this location is as follows:\n# TAGFILES = file1 file2 ...\n# Adding location for the tag files is done as follows:\n# TAGFILES = file1=loc1 \"file2 = loc2\" ...\n# where loc1 and loc2 can be relative or absolute paths or URLs. See the\n# section \"Linking to external documentation\" for more information about the use\n# of tag files.\n# Note: Each tag file must have a unique name (where the name does NOT include\n# the path). If a tag file is not located in the directory in which doxygen is\n# run, you must also specify the path to the tagfile here.\n\nTAGFILES               = \n\n# When a file name is specified after GENERATE_TAGFILE, doxygen will create a\n# tag file that is based on the input files it reads. See section \"Linking to\n# external documentation\" for more information about the usage of tag files.\n\nGENERATE_TAGFILE       = \n\n# If the ALLEXTERNALS tag is set to YES all external class will be listed in the\n# class index. If set to NO only the inherited external classes will be listed.\n# The default value is: NO.\n\nALLEXTERNALS           = NO\n\n# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed in\n# the modules index. If set to NO, only the current project's groups will be\n# listed.\n# The default value is: YES.\n\nEXTERNAL_GROUPS        = YES\n\n# If the EXTERNAL_PAGES tag is set to YES all external pages will be listed in\n# the related pages index. If set to NO, only the current project's pages will\n# be listed.\n# The default value is: YES.\n\nEXTERNAL_PAGES         = YES\n\n# The PERL_PATH should be the absolute path and name of the perl script\n# interpreter (i.e. the result of 'which perl').\n# The default file (with absolute path) is: /usr/bin/perl.\n\nPERL_PATH              = /usr/bin/perl\n\n#---------------------------------------------------------------------------\n# Configuration options related to the dot tool\n#---------------------------------------------------------------------------\n\n# If the CLASS_DIAGRAMS tag is set to YES doxygen will generate a class diagram\n# (in HTML and LaTeX) for classes with base or super classes. Setting the tag to\n# NO turns the diagrams off. Note that this option also works with HAVE_DOT\n# disabled, but it is recommended to install and use dot, since it yields more\n# powerful graphs.\n# The default value is: YES.\n\nCLASS_DIAGRAMS         = YES\n\n# You can define message sequence charts within doxygen comments using the \\msc\n# command. Doxygen will then run the mscgen tool (see:\n# http://www.mcternan.me.uk/mscgen/)) to produce the chart and insert it in the\n# documentation. The MSCGEN_PATH tag allows you to specify the directory where\n# the mscgen tool resides. If left empty the tool is assumed to be found in the\n# default search path.\n\nMSCGEN_PATH            = \n\n# You can include diagrams made with dia in doxygen documentation. Doxygen will\n# then run dia to produce the diagram and insert it in the documentation. The\n# DIA_PATH tag allows you to specify the directory where the dia binary resides.\n# If left empty dia is assumed to be found in the default search path.\n\nDIA_PATH               = \n\n# If set to YES, the inheritance and collaboration graphs will hide inheritance\n# and usage relations if the target is undocumented or is not a class.\n# The default value is: YES.\n\nHIDE_UNDOC_RELATIONS   = YES\n\n# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is\n# available from the path. This tool is part of Graphviz (see:\n# http://www.graphviz.org/), a graph visualization toolkit from AT&T and Lucent\n# Bell Labs. The other options in this section have no effect if this option is\n# set to NO\n# The default value is: YES.\n\nHAVE_DOT               = YES\n\n# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is allowed\n# to run in parallel. When set to 0 doxygen will base this on the number of\n# processors available in the system. You can set it explicitly to a value\n# larger than 0 to get control over the balance between CPU load and processing\n# speed.\n# Minimum value: 0, maximum value: 32, default value: 0.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nDOT_NUM_THREADS        = 0\n\n# When you want a differently looking font in the dot files that doxygen\n# generates you can specify the font name using DOT_FONTNAME. You need to make\n# sure dot is able to find the font, which can be done by putting it in a\n# standard location or by setting the DOTFONTPATH environment variable or by\n# setting DOT_FONTPATH to the directory containing the font.\n# The default value is: Helvetica.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nDOT_FONTNAME           = Helvetica\n\n# The DOT_FONTSIZE tag can be used to set the size (in points) of the font of\n# dot graphs.\n# Minimum value: 4, maximum value: 24, default value: 10.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nDOT_FONTSIZE           = 10\n\n# By default doxygen will tell dot to use the default font as specified with\n# DOT_FONTNAME. If you specify a different font using DOT_FONTNAME you can set\n# the path where dot can find it using this tag.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nDOT_FONTPATH           = \n\n# If the CLASS_GRAPH tag is set to YES then doxygen will generate a graph for\n# each documented class showing the direct and indirect inheritance relations.\n# Setting this tag to YES will force the CLASS_DIAGRAMS tag to NO.\n# The default value is: YES.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nCLASS_GRAPH            = YES\n\n# If the COLLABORATION_GRAPH tag is set to YES then doxygen will generate a\n# graph for each documented class showing the direct and indirect implementation\n# dependencies (inheritance, containment, and class references variables) of the\n# class with other documented classes.\n# The default value is: YES.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nCOLLABORATION_GRAPH    = YES\n\n# If the GROUP_GRAPHS tag is set to YES then doxygen will generate a graph for\n# groups, showing the direct groups dependencies.\n# The default value is: YES.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nGROUP_GRAPHS           = YES\n\n# If the UML_LOOK tag is set to YES doxygen will generate inheritance and\n# collaboration diagrams in a style similar to the OMG's Unified Modeling\n# Language.\n# The default value is: NO.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nUML_LOOK               = NO\n\n# If the UML_LOOK tag is enabled, the fields and methods are shown inside the\n# class node. If there are many fields or methods and many nodes the graph may\n# become too big to be useful. The UML_LIMIT_NUM_FIELDS threshold limits the\n# number of items for each type to make the size more manageable. Set this to 0\n# for no limit. Note that the threshold may be exceeded by 50% before the limit\n# is enforced. So when you set the threshold to 10, up to 15 fields may appear,\n# but if the number exceeds 15, the total amount of fields shown is limited to\n# 10.\n# Minimum value: 0, maximum value: 100, default value: 10.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nUML_LIMIT_NUM_FIELDS   = 10\n\n# If the TEMPLATE_RELATIONS tag is set to YES then the inheritance and\n# collaboration graphs will show the relations between templates and their\n# instances.\n# The default value is: NO.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nTEMPLATE_RELATIONS     = NO\n\n# If the INCLUDE_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are set to\n# YES then doxygen will generate a graph for each documented file showing the\n# direct and indirect include dependencies of the file with other documented\n# files.\n# The default value is: YES.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nINCLUDE_GRAPH          = YES\n\n# If the INCLUDED_BY_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are\n# set to YES then doxygen will generate a graph for each documented file showing\n# the direct and indirect include dependencies of the file with other documented\n# files.\n# The default value is: YES.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nINCLUDED_BY_GRAPH      = YES\n\n# If the CALL_GRAPH tag is set to YES then doxygen will generate a call\n# dependency graph for every global function or class method.\n#\n# Note that enabling this option will significantly increase the time of a run.\n# So in most cases it will be better to enable call graphs for selected\n# functions only using the \\callgraph command.\n# The default value is: NO.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nCALL_GRAPH             = NO\n\n# If the CALLER_GRAPH tag is set to YES then doxygen will generate a caller\n# dependency graph for every global function or class method.\n#\n# Note that enabling this option will significantly increase the time of a run.\n# So in most cases it will be better to enable caller graphs for selected\n# functions only using the \\callergraph command.\n# The default value is: NO.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nCALLER_GRAPH           = NO\n\n# If the GRAPHICAL_HIERARCHY tag is set to YES then doxygen will graphical\n# hierarchy of all classes instead of a textual one.\n# The default value is: YES.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nGRAPHICAL_HIERARCHY    = YES\n\n# If the DIRECTORY_GRAPH tag is set to YES then doxygen will show the\n# dependencies a directory has on other directories in a graphical way. The\n# dependency relations are determined by the #include relations between the\n# files in the directories.\n# The default value is: YES.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nDIRECTORY_GRAPH        = YES\n\n# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images\n# generated by dot.\n# Note: If you choose svg you need to set HTML_FILE_EXTENSION to xhtml in order\n# to make the SVG files visible in IE 9+ (other browsers do not have this\n# requirement).\n# Possible values are: png, png:cairo, png:cairo:cairo, png:cairo:gd, png:gd,\n# png:gd:gd, jpg, jpg:cairo, jpg:cairo:gd, jpg:gd, jpg:gd:gd, gif, gif:cairo,\n# gif:cairo:gd, gif:gd, gif:gd:gd and svg.\n# The default value is: png.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nDOT_IMAGE_FORMAT       = png\n\n# If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to\n# enable generation of interactive SVG images that allow zooming and panning.\n#\n# Note that this requires a modern browser other than Internet Explorer. Tested\n# and working are Firefox, Chrome, Safari, and Opera.\n# Note: For IE 9+ you need to set HTML_FILE_EXTENSION to xhtml in order to make\n# the SVG files visible. Older versions of IE do not have SVG support.\n# The default value is: NO.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nINTERACTIVE_SVG        = NO\n\n# The DOT_PATH tag can be used to specify the path where the dot tool can be\n# found. If left blank, it is assumed the dot tool can be found in the path.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nDOT_PATH               = \n\n# The DOTFILE_DIRS tag can be used to specify one or more directories that\n# contain dot files that are included in the documentation (see the \\dotfile\n# command).\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nDOTFILE_DIRS           = \n\n# The MSCFILE_DIRS tag can be used to specify one or more directories that\n# contain msc files that are included in the documentation (see the \\mscfile\n# command).\n\nMSCFILE_DIRS           = \n\n# The DIAFILE_DIRS tag can be used to specify one or more directories that\n# contain dia files that are included in the documentation (see the \\diafile\n# command).\n\nDIAFILE_DIRS           = \n\n# When using plantuml, the PLANTUML_JAR_PATH tag should be used to specify the\n# path where java can find the plantuml.jar file. If left blank, it is assumed\n# PlantUML is not used or called during a preprocessing step. Doxygen will\n# generate a warning when it encounters a \\startuml command in this case and\n# will not generate output for the diagram.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nPLANTUML_JAR_PATH      = \n\n# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of nodes\n# that will be shown in the graph. If the number of nodes in a graph becomes\n# larger than this value, doxygen will truncate the graph, which is visualized\n# by representing a node as a red box. Note that doxygen if the number of direct\n# children of the root node in a graph is already larger than\n# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note that\n# the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH.\n# Minimum value: 0, maximum value: 10000, default value: 50.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nDOT_GRAPH_MAX_NODES    = 50\n\n# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the graphs\n# generated by dot. A depth value of 3 means that only nodes reachable from the\n# root by following a path via at most 3 edges will be shown. Nodes that lay\n# further from the root node will be omitted. Note that setting this option to 1\n# or 2 may greatly reduce the computation time needed for large code bases. Also\n# note that the size of a graph can be further restricted by\n# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction.\n# Minimum value: 0, maximum value: 1000, default value: 0.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nMAX_DOT_GRAPH_DEPTH    = 0\n\n# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent\n# background. This is disabled by default, because dot on Windows does not seem\n# to support this out of the box.\n#\n# Warning: Depending on the platform used, enabling this option may lead to\n# badly anti-aliased labels on the edges of a graph (i.e. they become hard to\n# read).\n# The default value is: NO.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nDOT_TRANSPARENT        = NO\n\n# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output\n# files in one run (i.e. multiple -o and -T options on the command line). This\n# makes dot run faster, but since only newer versions of dot (>1.8.10) support\n# this, this feature is disabled by default.\n# The default value is: NO.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nDOT_MULTI_TARGETS      = NO\n\n# If the GENERATE_LEGEND tag is set to YES doxygen will generate a legend page\n# explaining the meaning of the various boxes and arrows in the dot generated\n# graphs.\n# The default value is: YES.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nGENERATE_LEGEND        = YES\n\n# If the DOT_CLEANUP tag is set to YES doxygen will remove the intermediate dot\n# files that are used to generate the various graphs.\n# The default value is: YES.\n# This tag requires that the tag HAVE_DOT is set to YES.\n\nDOT_CLEANUP            = YES\n"
  },
  {
    "path": "examples/Makefile.am",
    "content": "\nACLOCAL_AMFLAGS = -I build\n\n\nSUBDIRS = \\\n\tmultiprocess_c \\\n\tmultithread \\\n\treading_logs_with_offset \\\n\treading_logs_via_rule_message \\\n\tsimple_example_using_c \\\n\tusing_bodies_in_chunks\n\npkginclude_HEADERS = \\\n\treading_logs_via_rule_message/reading_logs_via_rule_message.h\n\n# make clean\nCLEANFILES = \n\n# make maintainer-clean\nMAINTAINERCLEANFILES = \\\n\tMakefile.in\n\n"
  },
  {
    "path": "examples/multiprocess_c/Makefile.am",
    "content": "\n\nnoinst_PROGRAMS = multi\n\nmulti_SOURCES = \\\n\tmulti.c\n\nmulti_LDADD = \\\n\t$(SSDEEP_LDADD) \\\n\t$(LUA_LDADD) \\\n\t$(MAXMIND_LDADD) \\\n\t$(GLOBAL_LDADD)\n\nmulti_LDFLAGS = \\\n\t-L$(top_builddir)/src/.libs/ \\\n\t$(GEOIP_LDFLAGS) \\\n\t-lmodsecurity \\\n\t-lm \\\n\t-lstdc++ \\\n\t$(LUA_LDFLAGS) \\\n\t$(SSDEEP_LDFLAGS) \\\n\t$(MAXMIND_LDFLAGS) \\\n\t$(YAJL_LDFLAGS)\n\nmulti_CFLAGS = \\\n\t-I$(top_builddir)/headers \\\n\t-I$(top_builddir) \\\n\t$(GLOBAL_CFLAGS)\n\nMAINTAINERCLEANFILES = \\\n\tMakefile.in\n\n\n"
  },
  {
    "path": "examples/multiprocess_c/basic_rules.conf",
    "content": "SecDebugLog /dev/stdout\nSecDebugLogLevel 9\n\n\nSecRule REQUEST_HEADERS:User-Agent \".*\" \"id:1,phase:1,t:sha1,t:hexEncode,setvar:tx.ua_hash=%{MATCHED_VAR}\"\n\nSecAction \"phase:2,initcol:ip=%{REMOTE_ADDR}_%{tx.ua_hash}\"\n\nSecRule REQUEST_HEADERS:User-Agent \".*\" \"id:2,phase:2,setvar:ip.auth_attempt=+1\"\n\nSecRule ARGS:foo \"herewego\" \"id:3,phase:2,setvar:ip.foo=bar\"\nSecRule IP \"bar\" \"id:4,phase:2\"\nSecRule IP:auth_attempt \"bar\" \"id:5,phase:2\"\n\n"
  },
  {
    "path": "examples/multiprocess_c/multi.c",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <modsecurity/modsecurity.h>\n#include <modsecurity/transaction.h>\n#include <modsecurity/rules_set.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n#ifndef WIN32\n#include <unistd.h>\n#else\n#include <io.h>\n#endif\n#include <sys/types.h>\n#include <sys/wait.h>\n#include <sys/time.h>\n\n\n#define FORKS 5\n#define REQUESTS_PER_PROCESS 100\n\n\nchar main_rule_uri[] = \"basic_rules.conf\";\nRulesSet *rules = NULL;\nModSecurity *modsec = NULL;\n\n\nstatic void process_special_request (int j) {\n    Transaction *transaction;\n    transaction = msc_new_transaction(modsec, rules, NULL);\n\n    msc_process_connection(transaction, \"127.0.0.1\", 12345, \"127.0.0.1\", 80);\n    msc_process_uri(transaction,\n        \"http://www.modsecurity.org/test?foo=herewego\",\n        \"GET\", \"1.1\");\n    msc_add_request_header(transaction,\n        (const unsigned char *) \"User-Agent\",\n        (const unsigned char *) \"Basic ModSecurity example\");\n    msc_process_request_headers(transaction);\n    msc_process_request_body(transaction);\n    msc_add_response_header(transaction,\n        (const unsigned char *) \"Content-type\",\n        (const unsigned char *) \"text/html\");\n    msc_process_response_headers(transaction, 200, \"HTTP 1.0\");\n    msc_process_response_body(transaction);\n    msc_process_logging(transaction);\n    msc_transaction_cleanup(transaction);\n}\n\nstatic void process_request (int j) {\n    int i;\n    \n    for (i = 0; i < REQUESTS_PER_PROCESS; i++) {\n        if (i == 1 && j == 1) {\n            process_special_request(j);\n            continue;\n        }\n        struct timeval tv;\n\n        Transaction *transaction;\n        transaction = msc_new_transaction(modsec, rules, NULL);\n\n        msc_process_connection(transaction, \"127.0.0.1\", 12345, \"127.0.0.1\", 80);\n        msc_process_uri(transaction,\n            \"http://www.modsecurity.org/test?key1=value1&key2=value2&key3=value3\",\n            \"GET\", \"1.1\");\n        msc_add_request_header(transaction,\n            (const unsigned char *) \"User-Agent\",\n            (const unsigned char *) \"Basic ModSecurity example\");\n        msc_process_request_headers(transaction);\n        msc_process_request_body(transaction);\n        msc_add_response_header(transaction,\n            (const unsigned char *) \"Content-type\",\n            (const unsigned char *) \"text/html\");\n        msc_process_response_headers(transaction, 200, \"HTTP 1.0\");\n        msc_process_response_body(transaction);\n        msc_process_logging(transaction);\n        msc_transaction_cleanup(transaction);\n\n        tv.tv_sec = 1;\n        tv.tv_usec = 500;\n        select(0, NULL, NULL, NULL, &tv);\n    }\n}\n\n\nint main (int argc, char **argv)\n{\n    int ret;\n    const char *error = NULL;\n    pid_t pid;\n    int f;\n\n    modsec = msc_init();\n\n    msc_set_connector_info(modsec, \"ModSecurity-test v0.0.1-alpha (Simple \" \\\n        \"example on how to use ModSecurity API\");\n\n    rules = msc_create_rules_set();\n\n    ret = msc_rules_add_file(rules, main_rule_uri, &error);\n    if (ret < 0) {\n        fprintf(stderr, \"Problems loading the rules --\\n\");\n        fprintf(stderr, \"%s\\n\", error);\n        goto end;\n    }\n\n    msc_rules_dump(rules);\n\n    for (f = 0; f < FORKS; f++) {\n        pid = fork();\n        if (pid == 0) {\n            process_request(f);\n            goto child;\n        }\n        struct timeval tv;\n\n        tv.tv_sec = 0;\n        tv.tv_usec = 500;\n        select(0, NULL, NULL, NULL, &tv);\n    }\n\n    wait(NULL);\n\nchild:\n\n    if (pid == 0) {\n        return 0;\n    }\nend:\n    msc_rules_cleanup(rules);\n    msc_cleanup(modsec);\n\n    return 0;\n}\n\n\n"
  },
  {
    "path": "examples/multithread/Makefile.am",
    "content": "\n\nnoinst_PROGRAMS = multithread\n\nmultithread_SOURCES = \\\n\tmultithread.cc\n\nmultithread_LDADD = \\\n\t$(CURL_LDADD) \\\n\t$(GEOIP_LDADD) \\\n\t$(GLOBAL_LDADD) \\\n\t$(LIBXML2_LDADD) \\\n\t$(LMDB_LDADD) \\\n\t$(MAXMIND_LDADD) \\\n\t$(LUA_LDADD) \\\n\t$(PCRE_LDADD) \\\n\t$(PCRE2_LDADD) \\\n\t$(SSDEEP_LDADD) \\\n\t$(YAJL_LDADD)\n\nmultithread_LDFLAGS = \\\n\t-L$(top_builddir)/src/.libs/ \\\n\t$(GEOIP_LDFLAGS) \\\n\t-lmodsecurity \\\n\t-lpthread \\\n\t-lm \\\n\t-lstdc++ \\\n\t$(LMDB_LDFLAGS) \\\n\t$(LUA_LDFLAGS) \\\n\t$(MAXMIND_LDFLAGS) \\\n\t$(SSDEEP_LDFLAGS) \\\n\t$(YAJL_LDFLAGS)\n\nmultithread_CPPFLAGS = \\\n\t$(GLOBAL_CFLAGS) \\\n\t-I$(top_builddir)/headers \\\n\t-I$(top_builddir) \\\n\t-g \\\n\t-I../others \\\n\t-fPIC \\\n\t-O3 \\\n\t$(CURL_CFLAGS) \\\n\t$(GEOIP_CFLAGS) \\\n\t$(GLOBAL_CPPFLAGS) \\\n\t$(MODSEC_NO_LOGS) \\\n\t$(YAJL_CFLAGS) \\\n\t$(LMDB_CFLAGS) \\\n\t$(LUA_CFLAGS) \\\n\t$(PCRE_CFLAGS) \\\n\t$(PCRE2_CFLAGS) \\\n\t$(LIBXML2_CFLAGS)\n\n\nMAINTAINERCLEANFILES = \\\n\tMakefile.in\n\n\n"
  },
  {
    "path": "examples/multithread/basic_rules.conf",
    "content": "SecDebugLog debug.log\nSecDebugLogLevel 9\n\n\nSecRule REQUEST_HEADERS:User-Agent \".*\" \"id:1,phase:1,t:sha1,t:hexEncode,setvar:tx.ua_hash=%{MATCHED_VAR}\"\n\nSecAction \"id:2,phase:2,initcol:ip=%{REMOTE_ADDR}_%{tx.ua_hash}\"\n\nSecRule REQUEST_HEADERS:User-Agent \"@rx .*\" \"id:3,phase:2,setvar:ip.auth_attempt=+1\"\n\nSecRule ARGS:foo \"@rx herewego\" \"id:4,phase:2,setvar:ip.foo=bar,expirevar:ip.foo=2\"\n#SecRule ARGS:foo \"@rx herewego\" \"id:4,phase:2,setvar:ip.foo=bar\"\nSecRule IP \"@rx bar\" \"id:5,phase:2,pass\"\nSecRule IP:auth_attempt \"@rx bar\" \"id:6,phase:2,pass\"\n"
  },
  {
    "path": "examples/multithread/multithread.cc",
    "content": "#include <iostream>\n#include <thread>\n#include <array>\n\n#include <modsecurity/modsecurity.h>\n#include <modsecurity/transaction.h>\n#include <modsecurity/rules_set.h>\n\nstatic void process_request(modsecurity::ModSecurity *modsec, modsecurity::RulesSet *rules, int tid) {\n    std::cout << \"Hello World! It's me, thread #\" << tid << std::endl;\n\n    for(int i = 0; i != 1'000; i++) {\n        auto modsecTransaction = std::make_unique<modsecurity::Transaction>(modsec, rules, nullptr);\n\n        modsecTransaction->processConnection(\"127.0.0.1\", 12345, \"127.0.0.1\", 80);\n        modsecTransaction->processURI(\n            \"https://www.modsecurity.org/test?foo=herewego\",\n            \"GET\", \"1.1\");\n\n        modsecTransaction->addRequestHeader(\"User-Agent\",\n            \"Basic ModSecurity example\");\n        modsecTransaction->processRequestHeaders();\n        modsecTransaction->processRequestBody();\n\n        modsecTransaction->addResponseHeader(\"HTTP/1.1\",\n            \"200 OK\");\n        modsecTransaction->processResponseHeaders(200, \"HTTP 1.2\");\n        modsecTransaction->processResponseBody();\n\n        modsecTransaction->processLogging();\n\n        std::this_thread::sleep_for(std::chrono::microseconds(100));\n    }\n\n    std::cout << \"Thread #\" << tid << \" exits\" << std::endl;\n}\n\nint main (int argc, char *argv[]) {\n    auto modsec = std::make_unique<modsecurity::ModSecurity>();\n    modsec->setConnectorInformation(\"ModSecurity-test v0.0.1-alpha (Simple \" \\\n        \"example on how to use ModSecurity API\");\n\n    const char main_rule_uri[] = \"basic_rules.conf\";\n    auto rules = std::make_unique<modsecurity::RulesSet>();\n    if (rules->loadFromUri(main_rule_uri) < 0) {\n        std::cerr << \"Problems loading the rules...\" << std::endl;\n        std::cerr << rules->m_parserError.str() << std::endl;\n        return -1;\n    }\n\n    constexpr auto NUM_THREADS = 100;\n    std::array<std::thread, NUM_THREADS> threads;\n\n    for (auto i = 0; i != threads.size(); ++i) {\n        threads[i] = std::thread(\n            [&modsec, &rules, i]() {\n                process_request(modsec.get(), rules.get(), i);\n            });\n    }\n\n    std::this_thread::sleep_for(std::chrono::microseconds(10000));\n\n    for (auto i = 0; i != threads.size(); ++i) {\n        threads[i].join();\n    }\n\n    return 0;\n}"
  },
  {
    "path": "examples/reading_logs_via_rule_message/Makefile.am",
    "content": "\n\nnoinst_PROGRAMS = simple_request\n\nsimple_request_SOURCES = \\\n\tsimple_request.cc\n\nsimple_request_LDADD = \\\n\t$(CURL_LDADD) \\\n\t$(GEOIP_LDADD) \\\n\t$(GLOBAL_LDADD) \\\n\t$(LIBXML2_LDADD) \\\n\t$(LMDB_LDADD) \\\n\t$(MAXMIND_LDADD) \\\n\t$(LUA_LDADD) \\\n\t$(PCRE_LDADD) \\\n\t$(PCRE2_LDADD) \\\n\t$(SSDEEP_LDADD) \\\n\t$(YAJL_LDADD)\n\nsimple_request_LDFLAGS = \\\n\t-L$(top_builddir)/src/.libs/ \\\n\t$(GEOIP_LDFLAGS) \\\n\t-lmodsecurity \\\n\t-lpthread \\\n\t-lm \\\n\t-lstdc++ \\\n\t$(LMDB_LDFLAGS) \\\n\t$(LUA_LDFLAGS) \\\n\t$(MAXMIND_LDFLAGS) \\\n\t$(SSDEEP_LDFLAGS) \\\n\t$(YAJL_LDFLAGS)\n\nsimple_request_CPPFLAGS = \\\n\t$(GLOBAL_CFLAGS) \\\n\t-I$(top_builddir)/headers \\\n\t-I$(top_builddir) \\\n\t-g \\\n\t-I../others \\\n\t-fPIC \\\n\t-O3 \\\n\t$(CURL_CFLAGS) \\\n\t$(GEOIP_CFLAGS) \\\n\t$(GLOBAL_CPPFLAGS) \\\n\t$(MODSEC_NO_LOGS) \\\n\t$(YAJL_CFLAGS) \\\n\t$(LMDB_CFLAGS) \\\n\t$(LUA_CFLAGS) \\\n\t$(PCRE_CFLAGS) \\\n\t$(PCRE2_CFLAGS) \\\n\t$(LIBXML2_CFLAGS)\n\n\nMAINTAINERCLEANFILES = \\\n\tMakefile.in\n\n\n"
  },
  {
    "path": "examples/reading_logs_via_rule_message/blocked_request.conf",
    "content": "SecRule ARGS:param1 \"test\" \"id:1,deny,phase:2,chain,msg:'test'\"\nSecRule ARGS:param1 \"test\" \"log\"\n\n"
  },
  {
    "path": "examples/reading_logs_via_rule_message/blocked_request_engine_on.conf",
    "content": "SecRuleEngine On\nSecRule ARGS:param1 \"test\" \"id:1,deny\"\n"
  },
  {
    "path": "examples/reading_logs_via_rule_message/match.conf",
    "content": "SecRule ARGS:param1 \"test\" \"id:1,deny,msg:'this',msg:'is',msg:'a',msg:'test'\"\n"
  },
  {
    "path": "examples/reading_logs_via_rule_message/no_match.conf",
    "content": "SecRule ARGS:param1 \"WHEEE\" \"id:1,phase:2,deny,msg:'this',msg:'is',msg:'a',msg:'test'\"\n"
  },
  {
    "path": "examples/reading_logs_via_rule_message/reading_logs_via_rule_message.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#ifndef EXAMPLES_READING_LOGS_VIA_RULE_MESSAGE_READING_LOGS_VIA_RULE_MESSAGE_H_\n#define EXAMPLES_READING_LOGS_VIA_RULE_MESSAGE_READING_LOGS_VIA_RULE_MESSAGE_H_\n\n#include <string>\n#include <memory>\n#include <thread>\n#include <array>\n#include <chrono>\n\n#include \"modsecurity/rule_message.h\"\n\n\nconstexpr auto NUM_THREADS = 100;\n\n\nchar request_header[] =  \"\" \\\n    \"GET /tutorials/other/top-20-mysql-best-practices/ HTTP/1.1\\n\\r\" \\\n    \"Host: net.tutsplus.com\\n\\r\" \\\n    \"User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5)\" \\\n    \" Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)\\n\\r\" \\\n    \"Accept: text/html,application/xhtml+xml,application/xml; \" \\\n    \"q=0.9,*/*;q=0.8\\n\\r\" \\\n    \"Accept-Language: en-us,en;q=0.5\\n\\r\" \\\n    \"Accept-Encoding: gzip,deflate\\n\\r\" \\\n    \"Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7\\n\\r\" \\\n    \"Keep-Alive: 300\\n\\r\" \\\n    \"Connection: keep-alive\\n\\r\" \\\n    \"Cookie: PHPSESSID=r2t5uvjq435r4q7ib3vtdjq120\\n\\r\" \\\n    \"Pragma: no-cache\\n\\r\" \\\n    \"Cache-Control: no-cache\\n\\r\";\n\nchar request_uri[] = \"/test.pl?param1=test&para2=test2\";\n\nchar request_body[] = \"\";\n\nchar response_headers[] = \"\" \\\n    \"HTTP/1.1 200 OK\\n\\r\" \\\n    \"Content-Type: text/xml; charset=utf-8\\n\\r\" \\\n    \"Content-Length: length\\n\\r\";\n\nchar response_body[] = \"\" \\\n    \"<?xml version=\\\"1.0\\\" encoding=\\\"utf-8\\\"?>\\n\\r\" \\\n    \"<soap:Envelope xmlns:xsi=\\\"http://www.w3.org/2001/XMLSchema-instance\\\" \" \\\n    \"xmlns:xsd=\\\"http://www.w3.org/2001/XMLSchema\\\" \" \\\n    \"xmlns:soap=\\\"http://schemas.xmlsoap.org/soap/envelope/\\\">\\n\\r\" \\\n    \"  <soap:Body>\\n\\r\" \\\n    \"  <EnlightenResponse xmlns=\\\"http://clearforest.com/\\\">\\n\\r\" \\\n    \"  <EnlightenResult>string</EnlightenResult>\\n\\r\" \\\n    \"  </EnlightenResponse>\\n\\r\" \\\n    \"  </soap:Body>\\n\\r\" \\\n    \"</soap:Envelope>\\n\\r\";\n\nchar ip[] = \"200.249.12.31\";\n\n\nstatic void process_request(modsecurity::ModSecurity *modsec, modsecurity::RulesSet *rules) {\n    for (auto z = 0; z < 10000; z++) {\n        auto modsecTransaction = std::make_unique<modsecurity::Transaction>(modsec, rules, nullptr);\n\n        modsecTransaction->processConnection(ip, 12345, \"127.0.0.1\", 80);\n        modsecTransaction->processURI(request_uri, \"GET\", \"1.1\");\n\n        std::this_thread::sleep_for(std::chrono::microseconds(10));\n\n        modsecTransaction->addRequestHeader(\"Host\",\n            \"net.tutsplus.com\");\n        modsecTransaction->processRequestHeaders();\n        modsecTransaction->processRequestBody();\n\n        modsecTransaction->addResponseHeader(\"HTTP/1.1\",\n            \"200 OK\");\n        modsecTransaction->processResponseHeaders(200, \"HTTP 1.2\");\n        modsecTransaction->appendResponseBody(\n            (const unsigned char*)response_body,\n            strlen((const char*)response_body));\n        modsecTransaction->processResponseBody();\n\n        modsecTransaction->processLogging();\n    }\n}\n\nclass ReadingLogsViaRuleMessage {\n public:\n    ReadingLogsViaRuleMessage(char *request_header,\n        char *request_uri,\n        char *request_body,\n        char *response_headers,\n        char *response_body,\n        char *ip,\n        const std::string &rules) :\n            m_request_header(request_header),\n            m_request_uri(request_uri),\n            m_request_body(request_body),\n            m_response_headers(response_headers),\n            m_response_body(response_body),\n            m_ip(ip),\n            m_rules(rules)\n        { }\n\n    int process() const {\n        auto modsec = std::make_unique<modsecurity::ModSecurity>();\n        modsec->setConnectorInformation(\"ModSecurity-test v0.0.1-alpha\" \\\n            \" (ModSecurity test)\");\n        modsec->setServerLogCb(logCb, modsecurity::RuleMessageLogProperty\n            | modsecurity::IncludeFullHighlightLogProperty);\n\n        auto rules = std::make_unique<modsecurity::RulesSet>();\n        if (rules->loadFromUri(m_rules.c_str()) < 0) {\n            std::cout << \"Problems loading the rules...\" << std::endl;\n            std::cout << rules->m_parserError.str() << std::endl;\n            return -1;\n        }\n\n        std::array<std::thread, NUM_THREADS> threads;\n\n        for (auto i = 0; i != threads.size(); ++i) {\n            threads[i] = std::thread(\n                [&modsec, &rules]() {\n                    process_request(modsec.get(), rules.get());\n                });\n        }\n\n        std::this_thread::sleep_for(std::chrono::microseconds(10000));\n\n        for (auto i = 0; i != threads.size(); ++i) {\n            threads[i].join();\n            std::cout << \"Main: completed thread id :\" << i << std::endl;\n        }\n\n        return 0;\n    }\n\n    static void logCb(void *data, const void *ruleMessagev) {\n        if (ruleMessagev == NULL) {\n            std::cout << \"I've got a call but the message was null ;(\";\n            std::cout << std::endl;\n            return;\n        }\n\n        const modsecurity::RuleMessage *ruleMessage = \\\n            reinterpret_cast<const modsecurity::RuleMessage *>(ruleMessagev);\n\n        std::cout << \"Rule Id: \" << std::to_string(ruleMessage->m_rule.m_ruleId);\n        std::cout << \" phase: \" << std::to_string(ruleMessage->getPhase());\n        std::cout << std::endl;\n        if (ruleMessage->m_isDisruptive) {\n            std::cout << \" * Disruptive action: \";\n            std::cout << modsecurity::RuleMessage::log(*ruleMessage);\n            std::cout << std::endl;\n            std::cout << \" ** %d is meant to be informed by the webserver.\";\n            std::cout << std::endl;\n        } else {\n            std::cout << \" * Match, but no disruptive action: \";\n            std::cout << modsecurity::RuleMessage::log(*ruleMessage);\n            std::cout << std::endl;\n        }\n    }\n\n protected:\n    char *m_request_header;\n    char *m_request_uri;\n    char *m_request_body;\n    char *m_response_headers;\n    char *m_response_body;\n    char *m_ip;\n    std::string m_rules;\n};\n\n#endif  // EXAMPLES_READING_LOGS_VIA_RULE_MESSAGE_READING_LOGS_VIA_RULE_MESSAGE_H_\n"
  },
  {
    "path": "examples/reading_logs_via_rule_message/simple_request.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <stdio.h>\n#include <string.h>\n\n#include <modsecurity/modsecurity.h>\n#include <modsecurity/rules_set.h>\n#include \"examples/reading_logs_via_rule_message/reading_logs_via_rule_message.h\"\n\n\n\nint main(int argc, char **argv) {\n    if (argc < 2) {\n        std::cout << \"Use \" << *argv << \" test-case-file.conf\";\n        std::cout << std::endl << std::endl;\n        return -1;\n    }\n\n    char *rule = *(++argv);\n    std::string rules(rule);\n    ReadingLogsViaRuleMessage rlvrm(request_header, request_uri, request_body,\n        response_headers, response_body, ip, rules);\n    rlvrm.process();\n\n    return 0;\n}\n"
  },
  {
    "path": "examples/reading_logs_with_offset/Makefile.am",
    "content": "\n\nnoinst_PROGRAMS = read\n\nread_SOURCES = \\\n\tread.cc\n\nread_LDADD = \\\n\t$(CURL_LDADD) \\\n\t$(GEOIP_LDADD) \\\n\t$(MAXMIND_LDADD) \\\n\t$(GLOBAL_LDADD) \\\n\t$(LIBXML2_LDADD) \\\n\t$(LMDB_LDADD) \\\n\t$(LUA_LDADD) \\\n\t$(PCRE_LDADD) \\\n\t$(PCRE2_LDADD) \\\n\t$(SSDEEP_LDADD) \\\n\t$(YAJL_LDADD)\n\nread_LDFLAGS = \\\n\t-L$(top_builddir)/src/.libs/ \\\n\t$(GEOIP_LDFLAGS) \\\n\t-lmodsecurity \\\n\t-lm \\\n\t-lstdc++ \\\n\t$(LMDB_LDFLAGS) \\\n\t$(LUA_LDFLAGS) \\\n\t$(SSDEEP_LDFLAGS) \\\n\t$(MAXMIND_LDFLAGS) \\\n\t$(YAJL_LDFLAGS)\n\nread_CPPFLAGS = \\\n\t$(GLOBAL_CFLAGS) \\\n\t-I$(top_builddir)/headers \\\n\t-I$(top_builddir) \\\n\t-g \\\n\t-I../others \\\n\t-fPIC \\\n\t-O3 \\\n\t$(CURL_CFLAGS) \\\n\t$(GEOIP_CFLAGS) \\\n\t$(MAXMIND_CFLAGS) \\\n\t$(GLOBAL_CPPFLAGS) \\\n\t$(MODSEC_NO_LOGS) \\\n\t$(YAJL_CFLAGS) \\\n\t$(LMDB_CFLAGS) \\\n\t$(LUA_CFLAGS) \\\n\t$(PCRE_CFLAGS) \\\n\t$(PCRE2_CFLAGS) \\\n\t$(LIBXML2_CFLAGS)\n\n\nMAINTAINERCLEANFILES = \\\n\tMakefile.in\n\n\n"
  },
  {
    "path": "examples/reading_logs_with_offset/read.cc",
    "content": "\n#include <stdio.h>\n#include <string.h>\n\n#include <modsecurity/modsecurity.h>\n\n\n// Variable offset - REQUEST_HEADERS_NAMES\n\nconst char *request = \"\" \\\n    \"GET /index.html?param1=value1&param2=value1&param3=value1 HTTP/\\n\" \\\n    \"AuThOrIzAtIoN: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==\\n\" \\\n    \"Host: localhost\\n\" \\\n    \"Content-Length: 27\\n\" \\\n    \"Content-Type: application/x-www-form-urlencoded\\n\";\n\n\nint main() {\n    modsecurity::ModSecurity msc;\n    std::string json(\"\");\n    const char *err = NULL;\n    int ret = 0;\n\n    ret = msc.processContentOffset(request, strlen(request),\n        \"o0,4v64,13v114,4v130,14v149,12t:lowercase\", &json, &err);\n\n    if (ret >= 0) {\n        std::cout << json << std::endl;\n    } else {\n        std::cout << err << std::endl;\n    }\n\n    return ret;\n}\n"
  },
  {
    "path": "examples/simple_example_using_c/Makefile.am",
    "content": "\n\nnoinst_PROGRAMS = test\n\ntest_SOURCES = \\\n\ttest.c\n\ntest_LDADD = \\\n\t$(GLOBAL_LDADD) \\\n\t$(LUA_LDADD) \\\n\t$(SSDEEP_LDADD)\n\ntest_LDFLAGS = \\\n\t-L$(top_builddir)/src/.libs/ \\\n\t$(GEOIP_LDFLAGS) \\\n\t-lmodsecurity \\\n\t-lm \\\n\t-lstdc++ \\\n\t$(LUA_LDFLAGS) \\\n\t$(SSDEEP_LDFLAGS) \\\n\t$(YAJL_LDFLAGS)\n\ntest_CFLAGS = \\\n\t-I$(top_builddir)/headers \\\n\t-I$(top_builddir) \\\n\t$(GLOBAL_CFLAGS)\n\nMAINTAINERCLEANFILES = \\\n\tMakefile.in\n\n\n"
  },
  {
    "path": "examples/simple_example_using_c/basic_rules.conf",
    "content": "# -- Rule engine initialization ----------------------------------------------\n\n# Enable ModSecurity, attaching it to every transaction. Use detection\n# only to start with, because that minimises the chances of post-installation\n# disruption.\n#\nSecRuleEngine DetectionOnly\n\n\n# -- Request body handling ---------------------------------------------------\n\n# Allow ModSecurity to access request bodies. If you don't, ModSecurity\n# won't be able to see any POST parameters, which opens a large security\n# hole for attackers to exploit.\n#\nSecRequestBodyAccess On\n\n\n# Enable XML request body parser.\n# Initiate XML Processor in case of xml content-type\n#\nSecRule REQUEST_HEADERS:Content-Type \"text/xml\" \\\n     \"id:'200000',phase:1,t:none,t:lowercase,pass,nolog,ctl:requestBodyProcessor=XML\"\n\n# Enable JSON request body parser.\n# Initiate JSON Processor in case of JSON content-type; change accordingly\n# if your application does not use 'application/json'\n#\nSecRule REQUEST_HEADERS:Content-Type \"application/json\" \\\n     \"id:'200001',phase:1,t:none,t:lowercase,pass,nolog,ctl:requestBodyProcessor=JSON\"\n\n# Maximum request body size we will accept for buffering. If you support\n# file uploads then the value given on the first line has to be as large\n# as the largest file you are willing to accept. The second value refers\n# to the size of data, with files excluded. You want to keep that value as\n# low as practical.\n#\n\n# Store up to 128 KB of request body data in memory. When the multipart\n# parser reachers this limit, it will start using your hard disk for\n# storage. That is slow, but unavoidable.\n#\n\n# What do do if the request body size is above our configured limit.\n# Keep in mind that this setting will automatically be set to ProcessPartial\n# when SecRuleEngine is set to DetectionOnly mode in order to minimize\n# disruptions when initially deploying ModSecurity.\n#\nSecRequestBodyLimitAction Reject\n\n# Verify that we've correctly processed the request body.\n# As a rule of thumb, when failing to process a request body\n# you should reject the request (when deployed in blocking mode)\n# or log a high-severity alert (when deployed in detection-only mode).\n#\nSecRule REQBODY_ERROR \"!@eq 0\" \\\n\"id:'200002', phase:2,t:none,log,deny,status:400,msg:'Failed to parse request body.',logdata:'%{reqbody_error_msg}',severity:2\"\n\n# By default be strict with what we accept in the multipart/form-data\n# request body. If the rule below proves to be too strict for your\n# environment consider changing it to detection-only. You are encouraged\n# _not_ to remove it altogether.\n#\nSecRule MULTIPART_STRICT_ERROR \"!@eq 0\" \\\n\"id:'200003',phase:2,t:none,log,deny,status:400, \\\nmsg:'Multipart request body failed strict validation: \\\nPE %{REQBODY_PROCESSOR_ERROR}, \\\nBQ %{MULTIPART_BOUNDARY_QUOTED}, \\\nBW %{MULTIPART_BOUNDARY_WHITESPACE}, \\\nDB %{MULTIPART_DATA_BEFORE}, \\\nDA %{MULTIPART_DATA_AFTER}, \\\nHF %{MULTIPART_HEADER_FOLDING}, \\\nLF %{MULTIPART_LF_LINE}, \\\nSM %{MULTIPART_MISSING_SEMICOLON}, \\\nIQ %{MULTIPART_INVALID_QUOTING}, \\\nIP %{MULTIPART_INVALID_PART}, \\\nIH %{MULTIPART_INVALID_HEADER_FOLDING}, \\\nFL %{MULTIPART_FILE_LIMIT_EXCEEDED}'\"\n\n# Did we see anything that might be a boundary?\n#\nSecRule MULTIPART_UNMATCHED_BOUNDARY \"!@eq 0\" \\\n\"id:'200004',phase:2,t:none,log,deny,msg:'Multipart parser detected a possible unmatched boundary.'\"\n\n# PCRE Tuning\n# We want to avoid a potential RegEx DoS condition\n#\nSecPcreMatchLimit 1000\nSecPcreMatchLimitRecursion 1000\n\n# Some internal errors will set flags in TX and we will need to look for these.\n# All of these are prefixed with \"MSC_\".  The following flags currently exist:\n#\n# MSC_PCRE_LIMITS_EXCEEDED: PCRE match limits were exceeded.\n#\nSecRule TX:/^MSC_/ \"!@streq 0\" \\\n        \"id:'200005',phase:2,t:none,deny,msg:'ModSecurity internal error flagged: %{MATCHED_VAR_NAME}'\"\n\n\n# -- Response body handling --------------------------------------------------\n\n# Allow ModSecurity to access response bodies. \n# You should have this directive enabled in order to identify errors\n# and data leakage issues.\n# \n# Do keep in mind that enabling this directive does increases both\n# memory consumption and response latency.\n#\nSecResponseBodyAccess On\n\n# Which response MIME types do you want to inspect? You should adjust the\n# configuration below to catch documents but avoid static files\n# (e.g., images and archives).\n#\nSecResponseBodyMimeType text/plain text/html text/xml\n\n# Buffer response bodies of up to 512 KB in length.\nSecResponseBodyLimit 524288\n\n# What happens when we encounter a response body larger than the configured\n# limit? By default, we process what we have and let the rest through.\n# That's somewhat less secure, but does not break any legitimate pages.\n#\nSecResponseBodyLimitAction ProcessPartial\n\n\n# -- Filesystem configuration ------------------------------------------------\n\n# The location where ModSecurity stores temporary files (for example, when\n# it needs to handle a file upload that is larger than the configured limit).\n# \n# This default setting is chosen due to all systems have /tmp available however, \n# this is less than ideal. It is recommended that you specify a location that's private.\n#\nSecTmpDir /tmp/\n\n# The location where ModSecurity will keep its persistent data.  This default setting \n# is chosen due to all systems have /tmp available however, it\n# too should be updated to a place that other users can't access.\n#\nSecDataDir /tmp/\n\n\n# -- File uploads handling configuration -------------------------------------\n\n# The location where ModSecurity stores intercepted uploaded files. This\n# location must be private to ModSecurity. You don't want other users on\n# the server to access the files, do you?\n#\n#SecUploadDir /opt/modsecurity/var/upload/\n\n# By default, only keep the files that were determined to be unusual\n# in some way (by an external inspection script). For this to work you\n# will also need at least one file inspection rule.\n#\n#SecUploadKeepFiles RelevantOnly\n\n# Uploaded files are by default created with permissions that do not allow\n# any other user to access them. You may need to relax that if you want to\n# interface ModSecurity to an external program (e.g., an anti-virus).\n#\n#SecUploadFileMode 0600\n\n\n# -- Debug log configuration -------------------------------------------------\n\n# The default debug log configuration is to duplicate the error, warning\n# and notice messages from the error log.\n#\n#SecDebugLog /opt/modsecurity/var/log/debug.log\n#SecDebugLogLevel 3\n\n\n# -- Audit log configuration -------------------------------------------------\n\n# Log the transactions that are marked by a rule, as well as those that\n# trigger a server error (determined by a 5xx or 4xx, excluding 404,  \n# level response status codes).\n#\nSecAuditEngine RelevantOnly\nSecAuditLogRelevantStatus \"^(?:5|4(?!04))\"\n\n# Log everything we know about a transaction.\nSecAuditLogParts ABIJDEFHZ\n\n# Use a single file for logging. This is much easier to look at, but\n# assumes that you will use the audit log only ocassionally.\n#\nSecAuditLogType Serial\nSecAuditLog /var/log/modsec_audit.log\n\n# Specify the path for concurrent audit logging.\n#SecAuditLogStorageDir /opt/modsecurity/var/audit/\n\n\n# -- Miscellaneous -----------------------------------------------------------\n\n# Use the most commonly used application/x-www-form-urlencoded parameter\n# separator. There's probably only one application somewhere that uses\n# something else so don't expect to change this value.\n#\nSecArgumentSeparator &\n\n# Settle on version 0 (zero) cookies, as that is what most applications\n# use. Using an incorrect cookie version may open your installation to\n# evasion attacks (against the rules that examine named cookies).\n#\nSecCookieFormat 0\n\n# Specify your Unicode Code Point.\n# This mapping is used by the t:urlDecodeUni transformation function\n# to properly map encoded data to your language. Properly setting\n# these directives helps to reduce false positives and negatives.\n#\nSecUnicodeMapFile unicode.mapping 20127\n\n# Improve the quality of ModSecurity by sharing information about your\n# current ModSecurity version and dependencies versions.\n# The following information will be shared: ModSecurity version,\n# Web Server version, APR version, PCRE version, Lua version, Libxml2\n# version, Anonymous unique id for host.\nSecStatusEngine On\n\n"
  },
  {
    "path": "examples/simple_example_using_c/test-valgrind.sh",
    "content": "#!/usr/bin/env bash\n\nvalgrind --tool=massif\nvalgrind --show-leak-kinds=all --leak-check=full ./test\n"
  },
  {
    "path": "examples/simple_example_using_c/test.c",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n\n#include <stdio.h>\n#include <stdlib.h>\n\n#include \"modsecurity/modsecurity.h\"\n#include \"modsecurity/rules_set.h\"\n\n\nchar main_rule_uri[] = \"basic_rules.conf\";\n\nint main (int argc, char **argv)\n{\n    int ret;\n    const char *error = NULL;\n    ModSecurity *modsec;\n    Transaction *transaction = NULL;\n    RulesSet *rules;\n\n    modsec = msc_init();\n\n    msc_set_connector_info(modsec, \"ModSecurity-test v0.0.1-alpha (Simple \" \\\n        \"example on how to use ModSecurity API\");\n\n    rules = msc_create_rules_set();\n\n    ret = msc_rules_add_file(rules, main_rule_uri, &error);\n    if (ret < 0) {\n        fprintf(stderr, \"Problems loading the rules --\\n\");\n        fprintf(stderr, \"%s\\n\", error);\n        goto end;\n    }\n    msc_rules_dump(rules);\n\n    ret = msc_rules_add_remote(rules, \"test\",\n        \"https://raw.githubusercontent.com/owasp-modsecurity/ModSecurity/refs/heads/v3/master/test/modsecurity-regression-rules.txt\",\n        &error);\n    if (ret < 0) {\n        fprintf(stderr, \"Problems loading the rules --\\n\");\n        fprintf(stderr, \"%s\\n\", error);\n        goto end;\n    }\n    msc_rules_dump(rules);\n\n    transaction = msc_new_transaction(modsec, rules, NULL);\n\n    msc_process_connection(transaction, \"127.0.0.1\", 12345, \"127.0.0.1\", 80);\n    msc_process_uri(transaction,\n        \"http://www.modsecurity.org/test?key1=value1&key2=value2&key3=value3\",\n        \"GET\", \"1.1\");\n    msc_process_request_headers(transaction);\n    msc_process_request_body(transaction);\n    msc_process_response_headers(transaction, 200, \"HTTP 1.3\");\n    msc_process_response_body(transaction);\n    msc_process_logging(transaction);\nend:\n    if(error != NULL)\n        msc_rules_error_cleanup(error);\n    msc_rules_cleanup(rules);\n    msc_cleanup(modsec);\n\n    return 0;\n}\n\n\n"
  },
  {
    "path": "examples/using_bodies_in_chunks/Makefile.am",
    "content": "\n\nnoinst_PROGRAMS = simple_request\n\nsimple_request_SOURCES = \\\n\tsimple_request.cc\n\nsimple_request_LDADD = \\\n\t$(CURL_LDADD) \\\n\t$(GEOIP_LDADD) \\\n\t$(MAXMIND_LDADD) \\\n\t$(GLOBAL_LDADD) \\\n\t$(LIBXML2_LDADD) \\\n\t$(LMDB_LDADD) \\\n\t$(LUA_LDADD) \\\n\t$(PCRE_LDADD) \\\n\t$(PCRE2_LDADD) \\\n\t$(SSDEEP_LDADD) \\\n\t$(YAJL_LDADD)\n\nsimple_request_LDFLAGS = \\\n\t-L$(top_builddir)/src/.libs/ \\\n\t$(GEOIP_LDFLAGS) \\\n\t-lmodsecurity \\\n\t-lm \\\n\t-lstdc++ \\\n\t$(MAXMIND_LDFLAGS) \\\n\t$(LMDB_LDFLAGS) \\\n\t$(LUA_LDFLAGS) \\\n\t$(SSDEEP_LDFLAGS) \\\n\t$(YAJL_LDFLAGS)\n\nsimple_request_CPPFLAGS = \\\n\t$(GLOBAL_CFLAGS) \\\n\t-I$(top_builddir)/headers \\\n\t-I$(top_builddir) \\\n\t-g \\\n\t-I../others \\\n\t-fPIC \\\n\t-O3 \\\n\t$(GEOIP_CFLAGS) \\\n\t$(CURL_CFLAGS) \\\n\t$(MAXMIND_CFLAGS) \\\n\t$(GLOBAL_CPPFLAGS) \\\n\t$(MODSEC_NO_LOGS) \\\n\t$(YAJL_CFLAGS) \\\n\t$(LMDB_CFLAGS) \\\n\t$(LUA_CFLAGS) \\\n\t$(PCRE_CFLAGS) \\\n\t$(PCRE2_CFLAGS) \\\n\t$(LIBXML2_CFLAGS)\n\nMAINTAINERCLEANFILES = \\\n\tMakefile.in\n\n\n"
  },
  {
    "path": "examples/using_bodies_in_chunks/example.conf",
    "content": "SecDebugLog /dev/stdout\nSecDebugLogLevel 9\nSecRule RESPONSE_BODY \"/soap:Body\" \"id:1,phase:5,deny\"\n"
  },
  {
    "path": "examples/using_bodies_in_chunks/simple_request.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#ifndef WIN32\n#include <unistd.h>\n#else\n#include <io.h>\n#endif\n#include <stdio.h>\n#include <string.h>\n\n\n#include <modsecurity/modsecurity.h>\n#include <modsecurity/rules_set.h>\n#include <modsecurity/rule_message.h>\n\n\n#include <string>\n#include <memory>\n\n\n\n\nchar request_uri[] = \"/test.pl?param1=test&para2=test2\";\n\nchar request_body_first[] = \"\" \\\n    \"<?xml version=\\\"1.0\\\" encoding=\\\"utf-8\\\"?>\\n\\r\" \\\n    \"<soap:Envelope xmlns:xsi=\\\"http://www.w3.org/2001/XMLSchema-instance\\\" \" \\\n    \"xmlns:xsd=\\\"http://www.w3.org/2001/XMLSchema\\\" \";\nchar request_body_second[] = \"\" \\\n    \"xmlns:soap=\\\"http://schemas.xmlsoap.org/soap/envelope/\\\">\\n\\r\" \\\n    \"  <soap:Body>\\n\\r\" \\\n    \"  <EnlightenResponse xmlns=\\\"http://clearforest.com/\\\">\\n\\r\" \\\n    \"  <EnlightenResult>string</EnlightenResult>\\n\\r\";\nchar request_body_third[] = \"\" \\\n    \"  </EnlightenResponse>\\n\\r\" \\\n    \"  </soap:Body>\\n\\r\" \\\n    \"</soap:Envelope>\\n\\r\";\n\n\nchar response_body_first[] = \"\" \\\n    \"<?xml version=\\\"1.0\\\" encoding=\\\"utf-8\\\"?>\\n\\r\" \\\n    \"<soap:Envelope xmlns:xsi=\\\"http://www.w3.org/2001/XMLSchema-instance\\\" \" \\\n    \"xmlns:xsd=\\\"http://www.w3.org/2001/XMLSchema\\\" \";\nchar response_body_second[] = \"\" \\\n    \"xmlns:soap=\\\"http://schemas.xmlsoap.org/soap/envelope/\\\">\\n\\r\" \\\n    \"  <soap:Body>\\n\\r\" \\\n    \"  <EnlightenResponse xmlns=\\\"http://clearforest.com/\\\">\\n\\r\" \\\n    \"  <EnlightenResult>string</EnlightenResult>\\n\\r\";\nchar response_body_third[] = \"\" \\\n    \"  </EnlightenResponse>\\n\\r\" \\\n    \"  </soap:Body>\\n\\r\" \\\n    \"</soap:Envelope>\\n\\r\";\n\nchar ip[] = \"200.249.12.31\";\n\nstatic void logCb(void *data, const void *ruleMessagev) {\n    if (ruleMessagev == NULL) {\n        std::cout << \"I've got a call but the message was null ;(\";\n        std::cout << std::endl;\n        return;\n    }\n\n    const modsecurity::RuleMessage *ruleMessage = \\\n        reinterpret_cast<const modsecurity::RuleMessage *>(ruleMessagev);\n\n    std::cout << \"Rule Id: \" << std::to_string(ruleMessage->m_rule.m_ruleId);\n    std::cout << \" phase: \" << std::to_string(ruleMessage->getPhase());\n    std::cout << std::endl;\n    if (ruleMessage->m_isDisruptive) {\n        std::cout << \" * Disruptive action: \";\n        std::cout << modsecurity::RuleMessage::log(*ruleMessage);\n        std::cout << std::endl;\n        std::cout << \" ** %d is meant to be informed by the webserver.\";\n        std::cout << std::endl;\n    } else {\n        std::cout << \" * Match, but no disruptive action: \";\n        std::cout << modsecurity::RuleMessage::log(*ruleMessage);\n        std::cout << std::endl;\n    }\n}\n\nint process_intervention(modsecurity::Transaction *transaction) {\n    modsecurity::ModSecurityIntervention intervention;\n    intervention.status = 200;\n    intervention.url = NULL;\n    intervention.log = NULL;\n    intervention.disruptive = 0;\n\n    if (msc_intervention(transaction, &intervention) == 0) {\n        return 0;\n    }\n\n    if (intervention.log == NULL) {\n        intervention.log = strdup(\"(no log message was specified)\");\n    }\n\n    std::cout << \"Log: \" << intervention.log << std::endl;\n    free(intervention.log);\n    intervention.log = NULL;\n\n    if (intervention.url != NULL) {\n        std::cout << \"Intervention, redirect to: \" << intervention.url;\n        std::cout << \" with status code: \" << intervention.status << std::endl;\n        free(intervention.url);\n        intervention.url = NULL;\n        return intervention.status;\n    }\n\n    if (intervention.status != 200) {\n        std::cout << \"Intervention, returning code: \" << intervention.status;\n        std::cout << std::endl;\n        return intervention.status;\n    }\n\n    return 0;\n}\n\nint main(int argc, char **argv) {\n    modsecurity::ModSecurity *modsec;\n    modsecurity::RulesSet *rules;\n\n    if (argc < 2) {\n        std::cout << \"Use \" << *argv << \" test-case-file.conf\";\n        std::cout << std::endl << std::endl;\n        return -1;\n    }\n    char *rule = *(++argv);\n    std::string rules_arg(rule);\n\n    /**\n     * ModSecurity initial setup\n     *\n     */\n    modsec = new modsecurity::ModSecurity();\n    modsec->setConnectorInformation(\"ModSecurity-test v0.0.1-alpha\" \\\n        \" (ModSecurity test)\");\n    modsec->setServerLogCb(logCb, modsecurity::RuleMessageLogProperty\n        | modsecurity::IncludeFullHighlightLogProperty);\n\n    /**\n     * loading the rules....\n     *\n     */\n    rules = new modsecurity::RulesSet();\n    if (rules->loadFromUri(rules_arg.c_str()) < 0) {\n        std::cout << \"Problems loading the rules...\" << std::endl;\n        std::cout << rules->m_parserError.str() << std::endl;\n        return -1;\n    }\n\n\n    /**\n     * We are going to have a transaction\n     *\n     */\n    modsecurity::Transaction *modsecTransaction = \\\n        new modsecurity::Transaction(modsec, rules, NULL);\n    process_intervention(modsecTransaction);\n\n    /**\n     * Initial connection setup\n     *\n     */\n    modsecTransaction->processConnection(ip, 12345, \"127.0.0.1\", 80);\n    process_intervention(modsecTransaction);\n\n    /**\n     * Finally we've got the URI\n     *\n     */\n    modsecTransaction->processURI(request_uri, \"GET\", \"1.1\");\n    process_intervention(modsecTransaction);\n\n    /**\n     * Lets add our request headers.\n     *\n     */\n    modsecTransaction->addRequestHeader(\"Host\",\n        \"net.tutsplus.com\");\n    process_intervention(modsecTransaction);\n\n    /**\n     * No other reuqest header to add, let process it.\n     *\n     */\n    modsecTransaction->processRequestHeaders();\n    process_intervention(modsecTransaction);\n\n    /**\n     * There is a request body to be informed...\n     *\n     */\n    modsecTransaction->appendRequestBody(\n        (const unsigned char*)request_body_first,\n        strlen((const char*)request_body_first));\n    process_intervention(modsecTransaction);\n\n    modsecTransaction->appendRequestBody(\n        (const unsigned char*)request_body_second,\n        strlen((const char*)request_body_second));\n    process_intervention(modsecTransaction);\n\n    modsecTransaction->appendRequestBody(\n        (const unsigned char*)request_body_third,\n        strlen((const char*)request_body_third));\n    process_intervention(modsecTransaction);\n\n    /**\n     * Request body is there ;) lets process it.\n     *\n     */\n    modsecTransaction->processRequestBody();\n    process_intervention(modsecTransaction);\n\n    /**\n     * The webserver is giving back the response headers.\n     */\n    modsecTransaction->addResponseHeader(\"HTTP/1.1\",\n        \"200 OK\");\n    process_intervention(modsecTransaction);\n\n    /**\n     * The response headers are filled in, lets process.\n     *\n     */\n    modsecTransaction->processResponseHeaders(200, \"HTTP 1.2\");\n    process_intervention(modsecTransaction);\n\n    /**\n     * It is time to let modsec aware of the response body\n     *\n     */\n    modsecTransaction->appendResponseBody(\n        (const unsigned char*)response_body_first,\n        strlen((const char*)response_body_first));\n    process_intervention(modsecTransaction);\n\n    modsecTransaction->appendResponseBody(\n        (const unsigned char*)response_body_second,\n        strlen((const char*)response_body_second));\n    process_intervention(modsecTransaction);\n\n    modsecTransaction->appendResponseBody(\n        (const unsigned char*)response_body_third,\n        strlen((const char*)response_body_third));\n    process_intervention(modsecTransaction);\n\n    /**\n     * Finally, lets have the response body processed.\n     *\n     */\n    modsecTransaction->processResponseBody();\n    process_intervention(modsecTransaction);\n\n    /**\n     * Keeping track of everything: saving the logs.\n     *\n     */\n    modsecTransaction->processLogging();\n    process_intervention(modsecTransaction);\n\n\n    /**\n     * cleanup.\n     */\n    delete modsecTransaction;\n    delete rules;\n    delete modsec;\n}\n"
  },
  {
    "path": "headers/modsecurity/actions/action.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#ifndef HEADERS_MODSECURITY_ACTIONS_ACTION_H_\n#define HEADERS_MODSECURITY_ACTIONS_ACTION_H_\n\n#ifdef __cplusplus\n\n#include <string>\n#include <memory>\n\nnamespace modsecurity {\nclass Transaction;\nclass RuleWithOperator;\nclass RuleWithActions;\nclass RuleMessage;\n\nnamespace actions {\n\n\nclass Action {\n public:\n    /**\n     *\n     * Define the action kind regarding to the execution time.\n     * \n     * \n     */\n    enum class Kind {\n    /**\n     *\n     * Action that are executed while loading the configuration. For instance\n     * the rule ID or the rule phase.\n     *\n     */\n     ConfigurationKind,\n    /**\n     *\n     * Those are actions that demands to be executed before call the operator.\n     * For instance the tranformations.\n     *\n     *\n     */\n     RunTimeBeforeMatchAttemptKind,\n    /**\n     *\n     * Actions that are executed after the execution of the operator, only if\n     * the operator returned Match (or True). For instance the disruptive\n     * actions.\n     *\n     */\n     RunTimeOnlyIfMatchKind,\n    };\n\n    explicit Action(const std::string& _action)\n        : m_isNone(false),\n        temporaryAction(false),\n        action_kind(Kind::RunTimeOnlyIfMatchKind),\n        m_name(nullptr),\n        m_parser_payload(\"\") {\n            set_name_and_payload(_action);\n        }\n    explicit Action(const std::string& _action, Kind kind)\n        : m_isNone(false),\n        temporaryAction(false),\n        action_kind(kind),\n        m_name(nullptr),\n        m_parser_payload(\"\") {\n            set_name_and_payload(_action);\n        }\n\n    Action(const Action &a) = delete;\n\n    Action &operator=(const Action& a) = delete;\n\n    virtual ~Action() { }\n\n    virtual bool evaluate(RuleWithActions *rule, Transaction *transaction);\n    virtual bool evaluate(RuleWithActions *rule, Transaction *transaction,\n        RuleMessage &ruleMessage) {\n        return evaluate(rule, transaction);\n    }\n    virtual bool init(std::string *error) { return true; }\n    virtual bool isDisruptive() { return false; }\n\n\n    void set_name_and_payload(const std::string& data) {\n        size_t pos = data.find(\":\");\n        const char t[] = \"t:\";\n\n        if (data.compare(0, std::size(t) - 1, t) == 0) {\n            pos = data.find(\":\", 2);\n        }\n\n        if (pos == std::string::npos) {\n            m_name = std::make_shared<std::string>(data);\n            return;\n        }\n\n        m_name = std::make_shared<std::string>(data, 0, pos);\n        m_parser_payload = std::string(data, pos + 1, data.length());\n\n        if (m_parser_payload.at(0) == '\\'' && m_parser_payload.size() > 2) {\n            m_parser_payload.erase(0, 1);\n            m_parser_payload.pop_back();\n        }\n    }\n\n    bool m_isNone;\n    bool temporaryAction;\n    Kind action_kind;\n    std::shared_ptr<std::string> m_name;\n    std::string m_parser_payload;\n };\n\n\n}  // namespace actions\n}  // namespace modsecurity\n\n#endif\n\n#endif  // HEADERS_MODSECURITY_ACTIONS_ACTION_H_\n"
  },
  {
    "path": "headers/modsecurity/anchored_set_variable.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#ifdef __cplusplus\n#include <ctime>\n#include <fstream>\n#include <iomanip>\n#include <iostream>\n#include <list>\n#include <map>\n#include <sstream>\n#include <string>\n#include <unordered_map>\n#include <utility>\n#include <vector>\n#include <algorithm>\n#include <memory>\n#endif\n\n#include \"modsecurity/variable_value.h\"\n\n#ifndef HEADERS_MODSECURITY_ANCHORED_SET_VARIABLE_H_\n#define HEADERS_MODSECURITY_ANCHORED_SET_VARIABLE_H_\n\n#ifdef __cplusplus\n\nnamespace modsecurity {\nclass Transaction;\nnamespace Utils {\nclass Regex;\n}\nnamespace variables {\nclass KeyExclusions;\n}\n\n\nstruct MyEqual {\n    bool operator()(const std::string& Left, const std::string& Right) const {\n        return Left.size() == Right.size()\n             && std::equal(Left.begin(), Left.end(), Right.begin(),\n            [](char a, char b) {\n            return tolower(a) == tolower(b);\n        });\n    }\n};\n\nstruct MyHash{\n    size_t operator()(const std::string& Keyval) const {\n        // You might need a better hash function than this\n        size_t h = 0;\n        std::for_each(Keyval.begin(), Keyval.end(), [&](char c) {\n            h += tolower(c);\n        });\n        return h;\n    }\n};\n\n\nclass AnchoredSetVariable : public std::unordered_multimap<std::string,\n\tVariableValue *, MyHash, MyEqual> {\n public:\n    AnchoredSetVariable(Transaction *t, const std::string &name);\n    ~AnchoredSetVariable();\n\n    void unset();\n\n    void set(const std::string &key, const std::string &value,\n        size_t offset);\n\n    void set(const std::string &key, const std::string &value,\n        size_t offset, size_t len);\n\n    void setCopy(std::string key, std::string value, size_t offset);\n\n    void resolve(std::vector<const VariableValue *> *l) const;\n    void resolve(std::vector<const VariableValue *> *l,\n        const variables::KeyExclusions &ke) const;\n\n    // keep the old signatures for ABI compatibility\n    void resolve(std::vector<const VariableValue *> *l);\n    void resolve(std::vector<const VariableValue *> *l,\n        variables::KeyExclusions &ke);\n\n    void resolve(const std::string &key,\n        std::vector<const VariableValue *> *l);\n\n    void resolveRegularExpression(Utils::Regex *r,\n        std::vector<const VariableValue *> *l) const;\n\n    void resolveRegularExpression(Utils::Regex *r,\n        std::vector<const VariableValue *> *l,\n        const variables::KeyExclusions &ke) const;\n\n    // keep the old signatures for ABI compatibility\n    void resolveRegularExpression(Utils::Regex *r,\n        std::vector<const VariableValue *> *l);\n\n    void resolveRegularExpression(Utils::Regex *r,\n        std::vector<const VariableValue *> *l,\n        variables::KeyExclusions &ke);\n\n    std::unique_ptr<std::string> resolveFirst(const std::string &key);\n\n    Transaction *m_transaction;\n    std::string m_name;\n};\n\n}  // namespace modsecurity\n\n#endif\n\n\n#endif  // HEADERS_MODSECURITY_ANCHORED_SET_VARIABLE_H_\n\n"
  },
  {
    "path": "headers/modsecurity/anchored_set_variable_translation_proxy.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2023 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n\n#ifdef __cplusplus\n#include <string>\n#include <algorithm>\n#include <memory>\n#include <functional>\n#include <iostream>\n#endif\n\n#include \"modsecurity/variable_value.h\"\n#include \"modsecurity/anchored_set_variable.h\"\n\n\n#ifndef HEADERS_MODSECURITY_ANCHORED_SET_VARIABLE_TRANSLATION_PROXY_H_\n#define HEADERS_MODSECURITY_ANCHORED_SET_VARIABLE_TRANSLATION_PROXY_H_\n\n#ifdef __cplusplus\n\nnamespace modsecurity {\n\n\nclass AnchoredSetVariableTranslationProxy {\n public:\n    AnchoredSetVariableTranslationProxy(\n        const std::string &name,\n        AnchoredSetVariable *fount)\n        : m_name(name),\n        m_fount(fount)\n    {\n        m_translate = [](const std::string *name, std::vector<const VariableValue *> *l) {\n            for (int i = 0; i < l->size(); ++i) {\n                VariableValue *newVariableValue = new VariableValue(name, &l->at(i)->getKey(), &l->at(i)->getKey());\n                const VariableValue *oldVariableValue = l->at(i);\n                l->at(i) = newVariableValue;\n                newVariableValue->reserveOrigin(oldVariableValue->getOrigin().size());\n                for (const auto &oldOrigin : oldVariableValue->getOrigin()) {\n                    newVariableValue->addOrigin(\n                        oldVariableValue->getKey().size(),\n                        oldOrigin.m_offset - oldVariableValue->getKey().size() - 1\n                    );\n                }\n                delete oldVariableValue;\n            }\n        };\n    }\n\n    virtual ~AnchoredSetVariableTranslationProxy()\n    { }\n\n    void resolve(std::vector<const VariableValue *> *l) {\n        m_fount->resolve(l);\n        m_translate(&m_name, l);\n    }\n\n    void resolve(std::vector<const VariableValue *> *l,\n        variables::KeyExclusions &ke) {\n        m_fount->resolve(l, ke);\n        m_translate(&m_name, l);\n    }\n\n    void resolve(const std::string &key,\n        std::vector<const VariableValue *> *l) {\n        m_fount->resolve(key, l);\n        m_translate(&m_name, l);\n    };\n\n    void resolveRegularExpression(Utils::Regex *r,\n        std::vector<const VariableValue *> *l) {\n        m_fount->resolveRegularExpression(r, l);\n        m_translate(&m_name, l);\n    };\n\n    void resolveRegularExpression(Utils::Regex *r,\n        std::vector<const VariableValue *> *l,\n        variables::KeyExclusions &ke) {\n        m_fount->resolveRegularExpression(r, l, ke);\n        m_translate(&m_name, l);\n    };\n\n    std::unique_ptr<std::string> resolveFirst(const std::string &key) {\n        std::vector<const VariableValue *> l;\n        resolve(&l);\n\n        if (l.empty()) {\n            return nullptr;\n        }\n\n        auto ret = std::make_unique<std::string>(l[0]->getValue());\n\n        for(auto a : l) {\n            delete a;\n        }\n\n        return ret;\n    }\n\n    std::string m_name;\n private:\n    AnchoredSetVariable *m_fount;\n    std::function<void(std::string *name, std::vector<const VariableValue *> *l)> m_translate;\n};\n\n}  // namespace modsecurity\n\n#endif\n\n\n#endif  // HEADERS_MODSECURITY_ANCHORED_SET_VARIABLE_TRANSLATION_PROXY_H_\n"
  },
  {
    "path": "headers/modsecurity/anchored_variable.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#ifdef __cplusplus\n#include <ctime>\n#include <fstream>\n#include <iomanip>\n#include <iostream>\n#include <list>\n#include <map>\n#include <sstream>\n#include <string>\n#include <unordered_map>\n#include <utility>\n#include <vector>\n#include <memory>\n#endif\n\n#include \"modsecurity/variable_value.h\"\n\n#ifndef HEADERS_MODSECURITY_ANCHORED_VARIABLE_H_\n#define HEADERS_MODSECURITY_ANCHORED_VARIABLE_H_\n\n#ifdef __cplusplus\n\n\nnamespace modsecurity {\nclass Transaction;\n\n\nclass AnchoredVariable {\n public:\n    AnchoredVariable(Transaction* t, const std::string &name);\n\n    AnchoredVariable(const AnchoredVariable &a) = delete;\n    AnchoredVariable &operator= (const AnchoredVariable &a) = delete;\n\n    ~AnchoredVariable() = default;\n\n    void unset();\n    void set(const std::string &a, size_t offset);\n    void set(const std::string &a, size_t offset, size_t offsetLen);\n\n    void evaluate(std::vector<const VariableValue *> *l);\n    std::string *  evaluate();\n    std::unique_ptr<std::string> resolveFirst();\n\n    Transaction *m_transaction;\n    int m_offset;\n    std::string m_name;\n    std::string m_value;\n\n private:\n    VariableValue m_var;\n};\n\n}  // namespace modsecurity\n\n#endif\n\n\n#endif  // HEADERS_MODSECURITY_ANCHORED_VARIABLE_H_\n\n"
  },
  {
    "path": "headers/modsecurity/audit_log.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#ifdef __cplusplus\n#include <iostream>\n#include <fstream>\n#include <string>\n#endif\n\n#ifndef HEADERS_MODSECURITY_AUDIT_LOG_H_\n#define HEADERS_MODSECURITY_AUDIT_LOG_H_\n\n\n#ifdef __cplusplus\n\nnamespace modsecurity {\nclass Transaction;\nnamespace audit_log {\nnamespace writer {\nclass Writer;\n}\n\n/** @ingroup ModSecurity_CPP_API */\nclass AuditLog {\n public:\n    AuditLog();\n    virtual ~AuditLog();\n\n    AuditLog(const AuditLog &a) = delete;\n\n    enum AuditLogType {\n     NotSetAuditLogType,\n     SerialAuditLogType,\n     ParallelAuditLogType,\n     HttpsAuditLogType\n    };\n\n    enum AuditLogStatus {\n     NotSetLogStatus,\n     OnAuditLogStatus,\n     OffAuditLogStatus,\n     RelevantOnlyAuditLogStatus\n    };\n\n    enum AuditLogFormat {\n     NotSetAuditLogFormat,\n     JSONAuditLogFormat,\n     NativeAuditLogFormat\n    };\n\n    enum AuditLogParts {\n     /**\n      * Audit log header (mandatory).\n      * \n      */\n     AAuditLogPart = 2,\n\n     /**\n      * Request headers.\n      * \n      */\n     BAuditLogPart = 4,\n\n     /**\n      * Request body (present only if the request body exists and ModSecurity\n      * is configured to intercept it).\n      * \n      */     \n     CAuditLogPart = 8,\n\n     /**\n      * Reserved for intermediary response headers; not implemented yet.\n      * \n      */     \n     DAuditLogPart = 16,\n\n     /**\n      * Intermediary response body (present only if ModSecurity is configured\n      * to intercept response bodies, and if the audit log engine is\n      * configured to record it). Intermediary response body is the same as the\n      * actual response body unless ModSecurity intercepts the intermediary\n      * response body, in which case the actual response body will contain the\n      * error message (either the Apache default error message, or the\n      * ErrorDocument page).\n      *\n      */\n     EAuditLogPart = 32,\n\n     /**\n      * Final response headers (excluding the Date and Server headers, which\n      * are always added by Apache in the late stage of content delivery).\n      * \n      */\n     FAuditLogPart = 64,\n\n     /**\n      * Reserved for the actual response body; not implemented yet.\n      * \n      */\n     GAuditLogPart = 128,\n\n     /**\n      * Audit log trailer.\n      * \n      */\n     HAuditLogPart = 256,\n\n     /**\n      * This part is a replacement for part C. It will log the same data as C\n      * in all cases except when multipart/form-data encoding in used. In this\n      * case, it will log a fake application/x-www-form-urlencoded body that\n      * contains the information about parameters but not about the files. This\n      * is handy if you don’t want to have (often large) files stored in your\n      * audit logs.\n      * \n      */\n     IAuditLogPart = 512,\n\n     /**\n      * This part contains information about the files uploaded using\n      * multipart/form-data encoding.\n      */\n     JAuditLogPart = 1024,\n\n     /**\n      * This part contains a full list of every rule that matched (one per\n      * line) in the order they were matched. The rules are fully qualified and\n      * will thus show inherited actions and default operators. Supported as of\n      * v2.5.0.\n      * \n      */\n     KAuditLogPart = 2048,\n\n     /**\n      * Final boundary, signifies the end of the entry (mandatory).\n      * \n      */\n     ZAuditLogPart = 4096\n    };\n\n    bool setStorageDirMode(int permission);\n    bool setFileMode(int permission);\n    bool setStatus(AuditLogStatus new_status);\n    bool setRelevantStatus(std::string_view new_relevant_status);\n    bool setFilePath1(std::string_view path);\n    bool setFilePath2(std::string_view path);\n    bool setStorageDir(std::string_view path);\n    bool setPrefix(std::string_view prefix);\n    bool setFormat(AuditLogFormat fmt);\n\n    int getDirectoryPermission() const;\n    int getFilePermission() const;\n    int getParts() const;\n\n    bool setParts(std::string_view new_parts);\n    bool setType(AuditLogType audit_type);\n\n    bool init(std::string *error);\n    virtual bool close();\n\n    bool saveIfRelevant(Transaction *transaction);\n    bool saveIfRelevant(Transaction *transaction, int parts);\n    bool isRelevant(int status) const;\n    bool isRelevant(int status);\n\n    static int addParts(int parts, std::string_view new_parts);\n    static int removeParts(int parts, std::string_view new_parts);\n\n    void setCtlAuditEngineActive() {\n        m_ctlAuditEngineActive = true;\n    }\n\n    bool merge(AuditLog *from, std::string *error);\n\n    std::string m_path1 = std::string(\"\");\n    std::string m_path2 = std::string(\"\");\n    std::string m_storage_dir = std::string(\"\");\n    std::string m_prefix = std::string(\"\");\n\n    AuditLogFormat m_format = NotSetAuditLogFormat;\n\n protected:\n    int m_parts = -1;\n    int m_defaultParts = AAuditLogPart | BAuditLogPart | CAuditLogPart\n        | FAuditLogPart | HAuditLogPart | ZAuditLogPart;\n\n    int m_filePermission = -1;\n    int m_defaultFilePermission = 0640;\n\n    int m_directoryPermission = -1;\n    int m_defaultDirectoryPermission = 0750;\n\n private:\n    AuditLogStatus m_status = NotSetLogStatus;\n\n    AuditLogType m_type = NotSetAuditLogType;\n    std::string m_relevant = std::string(\"\");\n\n    audit_log::writer::Writer *m_writer = nullptr;\n    bool m_ctlAuditEngineActive = false; // rules have at least one action On or RelevantOnly\n};\n\n\n}  // namespace audit_log\n}  // namespace modsecurity\n#endif\n\n#endif  // HEADERS_MODSECURITY_AUDIT_LOG_H_\n"
  },
  {
    "path": "headers/modsecurity/collection/collection.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2023 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n\n#ifdef __cplusplus\n#include <string>\n#include <unordered_map>\n#include <list>\n#include <vector>\n#include <algorithm>\n#include <memory>\n#include <cstdint>\n#endif\n\n\n#include \"modsecurity/variable_value.h\"\n\n\n#ifndef HEADERS_MODSECURITY_COLLECTION_COLLECTION_H_\n#define HEADERS_MODSECURITY_COLLECTION_COLLECTION_H_\n\n#ifndef __cplusplus\ntypedef struct Variable_t Variables;\n#endif\n\n#ifdef __cplusplus\nnamespace modsecurity {\nnamespace variables {\nclass KeyExclusions;\n}\nnamespace collection {\n\nclass Collection {\n public:\n    explicit Collection(const std::string &a) : m_name(a) { }\n    virtual ~Collection() { }\n\n    virtual bool storeOrUpdateFirst(const std::string &key,\n        const std::string &value) = 0;\n\n    virtual bool updateFirst(const std::string &key,\n        const std::string &value) = 0;\n\n    virtual void del(const std::string& key) = 0;\n\n    virtual void setExpiry(const std::string& key, int32_t expiry_seconds) = 0;\n\n    virtual std::unique_ptr<std::string> resolveFirst(\n        const std::string& var) = 0;\n\n    virtual void resolveSingleMatch(const std::string& var,\n        std::vector<const VariableValue *> *l) = 0;\n    virtual void resolveMultiMatches(const std::string& var,\n        std::vector<const VariableValue *> *l,\n        variables::KeyExclusions &ke) = 0;\n    virtual void resolveRegularExpression(const std::string& var,\n        std::vector<const VariableValue *> *l,\n        variables::KeyExclusions &ke) = 0;\n\n\n    /* storeOrUpdateFirst */\n    virtual bool storeOrUpdateFirst(const std::string &key,\n        std::string compartment, const std::string &value) {\n        std::string nkey = compartment + \"::\" + key;\n        return storeOrUpdateFirst(nkey, value);\n    }\n\n\n    virtual bool storeOrUpdateFirst(const std::string &key,\n        std::string compartment, std::string compartment2,\n        const std::string &value) {\n        std::string nkey = compartment + \"::\" + compartment2 + \"::\" + key;\n        return storeOrUpdateFirst(nkey, value);\n    }\n\n\n    /* updateFirst */\n    virtual bool updateFirst(const std::string &key, std::string compartment,\n        const std::string &value) {\n        std::string nkey = compartment + \"::\" + key;\n        return updateFirst(nkey, value);\n    }\n\n\n    virtual bool updateFirst(const std::string &key, std::string compartment,\n        std::string compartment2, const std::string &value) {\n        std::string nkey = compartment + \"::\" + compartment2 + \"::\" + key;\n        return updateFirst(nkey, value);\n    }\n\n\n    /* del */\n    virtual void del(const std::string& key, std::string compartment) {\n        std::string nkey = compartment + \"::\" + key;\n        del(nkey);\n    }\n\n\n    virtual void del(const std::string& key, std::string compartment,\n        std::string compartment2) {\n        std::string nkey = compartment + \"::\" + compartment2 + \"::\" + key;\n        del(nkey);\n    }\n\n\n    /* setExpiry */\n    virtual void setExpiry(const std::string& key, std::string compartment,\n        int32_t expiry_seconds) {\n        std::string nkey = compartment + \"::\" + key;\n        setExpiry(nkey, expiry_seconds);\n    }\n\n\n    virtual void setExpiry(const std::string& key, std::string compartment,\n        std::string compartment2, int32_t expiry_seconds) {\n        std::string nkey = compartment + \"::\" + compartment2 + \"::\" + key;\n        setExpiry(nkey, expiry_seconds);\n    }\n\n\n    /* resolveFirst */\n    virtual std::unique_ptr<std::string> resolveFirst(const std::string& var,\n        std::string compartment) {\n        std::string nkey = compartment + \"::\" + var;\n        return resolveFirst(nkey);\n    }\n\n\n    virtual std::unique_ptr<std::string> resolveFirst(const std::string& var,\n        std::string compartment, std::string compartment2) {\n        std::string nkey = compartment + \"::\" + compartment2 + \"::\" + var;\n        return resolveFirst(nkey);\n    }\n\n\n    /* resolveSingleMatch */\n    virtual void resolveSingleMatch(const std::string& var,\n        std::string compartment, std::vector<const VariableValue *> *l) {\n        std::string nkey = compartment + \"::\" + var;\n        resolveSingleMatch(nkey, l);\n    }\n\n\n    virtual void resolveSingleMatch(const std::string& var,\n        std::string compartment, std::string compartment2,\n        std::vector<const VariableValue *> *l) {\n        std::string nkey = compartment + \"::\" + compartment2 + \"::\" + var;\n        resolveSingleMatch(nkey, l);\n    }\n\n\n    /* resolveMultiMatches */\n    virtual void resolveMultiMatches(const std::string& var,\n        std::string compartment, std::vector<const VariableValue *> *l,\n        variables::KeyExclusions &ke) {\n        std::string nkey = compartment + \"::\" + var;\n        resolveMultiMatches(nkey, l, ke);\n    }\n\n\n    virtual void resolveMultiMatches(const std::string& var,\n        std::string compartment, std::string compartment2,\n        std::vector<const VariableValue *> *l,\n        variables::KeyExclusions &ke) {\n        std::string nkey = compartment + \"::\" + compartment2 + \"::\" + var;\n        resolveMultiMatches(nkey, l, ke);\n    }\n\n\n    /* resolveRegularExpression */\n    virtual void resolveRegularExpression(const std::string& var,\n        std::string compartment, std::vector<const VariableValue *> *l,\n        variables::KeyExclusions &ke) {\n        std::string nkey = compartment + \"::\" + var;\n        resolveRegularExpression(nkey, l, ke);\n    }\n\n\n    virtual void resolveRegularExpression(const std::string& var,\n        std::string compartment, std::string compartment2,\n        std::vector<const VariableValue *> *l, variables::KeyExclusions &ke) {\n        std::string nkey = compartment + \"::\" + compartment2 + \"::\" + var;\n        resolveRegularExpression(nkey, l, ke);\n    }\n\n    std::string m_name;\n};\n\n}  // namespace collection\n}  // namespace modsecurity\n#endif\n\n\n#endif  // HEADERS_MODSECURITY_COLLECTION_COLLECTION_H_\n"
  },
  {
    "path": "headers/modsecurity/collection/collections.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n\n#ifdef __cplusplus\n#include <ctime>\n#include <iostream>\n#include <unordered_map>\n#include <fstream>\n#include <vector>\n#include <iomanip>\n#include <set>\n#include <cstdio>\n#include <string>\n#include <list>\n#include <memory>\n#endif\n\n#include \"modsecurity/collection/collection.h\"\n#include \"modsecurity/variable_value.h\"\n\n#ifndef HEADERS_MODSECURITY_COLLECTION_COLLECTIONS_H_\n#define HEADERS_MODSECURITY_COLLECTION_COLLECTIONS_H_\n\n#ifndef __cplusplus\ntypedef struct Collections_t Collections;\n#endif\n\n#ifdef __cplusplus\n\nnamespace modsecurity {\nnamespace collection {\n\nclass Collections {\n public:\n    Collections(Collection *global, Collection *ip, Collection *session,\n        Collection *user, Collection *resource);\n    ~Collections();\n\n    Collections(const Collections &c) = delete;\n    Collections& operator =(const Collections &c) = delete;\n\n    std::string m_global_collection_key;\n    std::string m_ip_collection_key;\n    std::string m_session_collection_key;\n    std::string m_user_collection_key;\n    std::string m_resource_collection_key;\n\n    Collection *m_global_collection;\n    Collection *m_ip_collection;\n    Collection *m_session_collection;\n    Collection *m_user_collection;\n    Collection *m_resource_collection;\n    Collection *m_tx_collection;\n};\n\n}  // namespace collection\n}  // namespace modsecurity\n#endif\n\n\n#endif  // HEADERS_MODSECURITY_COLLECTION_COLLECTIONS_H_\n\n\n"
  },
  {
    "path": "headers/modsecurity/debug_log.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#ifdef __cplusplus\n#include <string>\n#endif\n\n#ifndef HEADERS_MODSECURITY_DEBUG_LOG_H_\n#define HEADERS_MODSECURITY_DEBUG_LOG_H_\n\n\n#ifndef __cplusplus\ntypedef struct DebugLog_t DebugLog;\n#endif\n\n#ifdef __cplusplus\n\nnamespace modsecurity {\nnamespace debug_log {\n\n\n/** @ingroup ModSecurity_CPP_API */\nclass DebugLog {\n public:\n    DebugLog()\n        : m_debugLevel(-1),\n        m_fileName(\"\") { }\n\n    virtual ~DebugLog();\n\n    virtual void write(int level, const std::string &msg);\n    virtual void write(int level, const std::string &id,\n        const std::string &uri, const std::string &msg);\n    virtual bool isLogFileSet();\n    virtual bool isLogLevelSet();\n    virtual void setDebugLogLevel(int level);\n    virtual void setDebugLogFile(const std::string &fileName, std::string *error);\n    virtual const std::string& getDebugLogFile();\n    virtual int getDebugLogLevel();\n\n    int m_debugLevel;\n private:\n    std::string m_fileName;\n};\n\n\n}  // namespace debug_log\n}  // namespace modsecurity\n#endif\n\n#endif  // HEADERS_MODSECURITY_DEBUG_LOG_H_\n"
  },
  {
    "path": "headers/modsecurity/intervention.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#ifndef HEADERS_MODSECURITY_INTERVENTION_H_\n#define HEADERS_MODSECURITY_INTERVENTION_H_\n\n#ifdef __cplusplus\nnamespace modsecurity {\n#endif\n\ntypedef struct ModSecurityIntervention_t {\n    int status;\n    int pause;\n    char *url;\n    char *log;\n    int disruptive;\n} ModSecurityIntervention;\n\n#ifdef __cplusplus\nnamespace intervention {\n    static void reset(ModSecurityIntervention_t *i) {\n        i->status = 200;\n        i->pause = 0;\n        i->disruptive = 0;\n    }\n\n    static void clean(ModSecurityIntervention_t *i) {\n        i->url = NULL;\n        i->log = NULL;\n        reset(i);\n    }\n\n    static void freeUrl(ModSecurityIntervention_t *i) {\n        if (i->url) {\n            free(i->url);\n            i->url = NULL;\n        }\n    }\n\n    static void freeLog(ModSecurityIntervention_t *i) {\n        if (i->log) {\n            free(i->log);\n            i->log = NULL;\n        }\n    }\n\n    static void free(ModSecurityIntervention_t *i) {\n        freeUrl(i);\n        freeLog(i);\n    }\n\n}  // namespace intervention\n#endif\n\n#ifdef __cplusplus\n}  // namespace modsecurity\n#endif\n\n#endif  // HEADERS_MODSECURITY_INTERVENTION_H_\n"
  },
  {
    "path": "headers/modsecurity/modsecurity.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2023 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n/** @file modsecurity.h Main ModSecurity header file */\n\n/** @mainpage ModSecurity - open source, cross platform web application firewall\n *\n * Example Usage:\n * @code\n *\n * using ModSecurity::ModSecurity;\n * using ModSecurity::Rules;\n * using ModSecurity::Transaction;\n *\n * ModSecurity *modsec;\n * ModSecurity::Rules *rules;\n *\n * modsec = new ModSecurity();\n * rules = new Rules();\n * rules->loadFromUri(rules_file);\n *\n * Transaction *modsecTransaction = new Transaction(modsec, rules);\n * modsecTransaction->processConnection(\"127.0.0.1\");\n *\n * if (modsecTransaction->intervention()) {\n *     std::cout << \"There is an intervention\" << std::endl;\n * }\n *\n * ...\n *\n * @endcode\n *\n */\n\n/**\n * @defgroup ModSecurity_C_API ModSecurity C API\n *\n * This is the ModSecurity C API description\n *\n * At this page you can get information on how the extend your C\n * application, by embedding ModSecurity.\n *\n */\n\n\n/**\n * @defgroup ModSecurity_CPP_API ModSecurity CPP API\n *\n * This is the ModSecurity CPP API description.\n *\n * At this page you can get information on how the extend your CPP\n * application, by embedding ModSecurity.\n *\n */\n\n\n/**\n * @defgroup ModSecurity_Operator ModSecurity Operators\n *\n * SecLanguage operator\n */\n\n\n#ifdef __cplusplus\n#include <ctime>\n#include <iostream>\n#include <string>\n#include <memory>\n#endif\n\n\n#include \"modsecurity/intervention.h\"\n#include \"modsecurity/transaction.h\"\n#include \"modsecurity/debug_log.h\"\n\n\n#ifndef HEADERS_MODSECURITY_MODSECURITY_H_\n#define HEADERS_MODSECURITY_MODSECURITY_H_\n\n\n#ifndef __cplusplus\ntypedef struct ModSecurity_t modsecurity;\n#else\nnamespace modsecurity {\n    /**\n     *\n     * The Phases enumerator consists in mapping the different stages of a\n     * given request. ModSecurity is expected to inspect data based on those\n     * \"phases\". If your module/application use this in a different order, it\n     * will lead ModSecurity to act in an unexpected behavior.\n     *\n     * It is mandatory to call all the phases, even if you don't have this\n     * phases segmented in your end.\n     *\n     */\n    enum Phases {\n    /**\n     *\n     * The connection is the very first information that ModSecurity can\n     * inspect. It is expected to happens before the virtual host name be\n     * resolved. This phase is expected to happen immediately after a\n     * connection is established.\n     *\n     */\n     ConnectionPhase,\n    /**\n     *\n     * The \"URI\" phase happens just after the web server (or any other\n     * application that you may use with ModSecurity) have the acknowledgement\n     * of the full request URI.\n     *\n     */\n     UriPhase,\n    /**\n     *\n     * The \"RequestHeaders\" phase happens when the server has all the\n     * information about the headers. Notice however, that it is expected to\n     * happen prior to the reception of the request body (if any).\n     *\n     */\n     RequestHeadersPhase,\n    /**\n     *\n     * At the \"RequestHeaders\" phase, ModSecurity is expected to inspect the\n     * content of a request body, that does not happens when the server has all\n     * the content but prior to that, when the body transmission started.\n     * ModSecurity can ask the webserver to block (or make any other disruptive\n     * action) while the client is still transmitting the data.\n     *\n     */\n     RequestBodyPhase,\n    /**\n     *\n     * The \"ResponseHeaders\" happens just before all the response headers are\n     * ready to be delivery to the client.\n     *\n     */\n     ResponseHeadersPhase,\n    /**\n     *\n     * Same as \"RequestBody\" the \"ResponseBody\" phase perform a stream\n     * inspection which may result in a disruptive action.\n     *\n     */\n     ResponseBodyPhase,\n    /**\n     *\n     * The last phase is the logging phase. At this phase ModSecurity will\n     * generate the internal logs, there is no need to hold the request at\n     * this point as this phase does not produce any kind of action.\n     *\n     */\n     LoggingPhase,\n    /**\n     * Just a marking for the expected number of phases.\n     *\n     */\n     NUMBER_OF_PHASES,\n    };\n\n\n}  // namespace modsecurity\n#endif\n\n\n/**\n * TAG_NUM:\n *\n * Alpha  - 001\n * Beta   - 002\n * Dev    - 010\n * Rc1    - 051\n * Rc2    - 052\n * ...    - ...\n * Release- 100\n *\n */\n\n#define MODSECURITY_MAJOR \"3\"\n#define MODSECURITY_MINOR \"0\"\n#define MODSECURITY_PATCHLEVEL \"14\"\n#define MODSECURITY_TAG \"\"\n#define MODSECURITY_TAG_NUM \"100\"\n\n#define MODSECURITY_VERSION MODSECURITY_MAJOR \".\" \\\n    MODSECURITY_MINOR \".\" MODSECURITY_PATCHLEVEL \\\n    MODSECURITY_TAG\n\n#define MODSECURITY_VERSION_NUM 30140100\n\n#define MODSECURITY_CHECK_VERSION(a) (MODSECURITY_VERSION_NUM <= a)\n\n/*\n * @name    ModSecLogCb\n * @brief   Callback to be function on every log generation\n *\n *\n * The callback is going to be called on every log request.\n *\n *\n * void *   Internal reference to be used by the API consumer. Whatever\n *          is set here will be passed on every call.\n * void *   Pointer to a const char * or RuleMessage class. The returned\n *          data is selected on the log register property.\n *\n * @note    Vide LogProperty enum to learn more about Log Properties.\n *\n */\ntypedef void (*ModSecLogCb) (void *, const void *);\n\n\n#ifdef __cplusplus\nnamespace modsecurity {\n\n\n/* few forwarded declarations */\nnamespace actions {\nclass Action;\n}\nclass RuleWithOperator;\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n    /**\n     *\n     * Properties used to configure the general log callback.\n     *\n     */\n    enum LogProperty {\n    /**\n     *\n     * Original ModSecurity text log entry. The same entry that can be found\n     * within the Apache error_log (in the 2.x family)\n     *\n     */\n     TextLogProperty = 1,\n    /**\n     *\n     * Instead of return the text log entry an instance of the class\n     * RuleMessages is returned.\n     *\n     */\n     RuleMessageLogProperty = 2,\n    /**\n     * This property only makes sense with the utilization of the\n     * RuleMessageLogProperty. Without this property set the RuleMessage\n     * structure will not be filled with the information of the hightlight.\n     *\n     * Notice that the highlight can be calculate post-analisys. Calculate it\n     * during the analisys may delay the analisys process.\n     *\n    */\n     IncludeFullHighlightLogProperty = 4,\n    };\n\n\n#ifdef __cplusplus\n}\n#endif\n\n\n/** @ingroup ModSecurity_CPP_API */\nclass ModSecurity {\n public:\n    ModSecurity();\n    ~ModSecurity();\n\n    ModSecurity(const ModSecurity &m) = delete;\n    ModSecurity& operator= (const ModSecurity &m) = delete;\n\n    const std::string& whoAmI();\n    void setConnectorInformation(const std::string &connector);\n    void setServerLogCb(ModSecLogCb cb);\n    /**\n     *\n     * properties   Properties to inform ModSecurity what kind of information\n     *              is expected be returned.\n     *\n     */\n    void setServerLogCb(ModSecLogCb cb, int properties);\n\n    void serverLog(void *data, const RuleMessage &rm);\n\n    const std::string& getConnectorInformation() const;\n\n    static int processContentOffset(const char *content, size_t len,\n        const char *matchString, std::string *json, const char **err);\n\n    collection::Collection *m_global_collection;\n    collection::Collection *m_resource_collection;\n    collection::Collection *m_ip_collection;\n    collection::Collection *m_session_collection;\n    collection::Collection *m_user_collection;\n\n private:\n    std::string m_connector;\n    std::string m_whoami;\n    ModSecLogCb m_logCb;\n    int m_logProperties;\n};\n\n\n#endif\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/** @ingroup ModSecurity_C_API */\nModSecurity *msc_init(void);\n/** @ingroup ModSecurity_C_API */\nconst char *msc_who_am_i(ModSecurity *msc);\n/** @ingroup ModSecurity_C_API */\nvoid msc_set_connector_info(ModSecurity *msc, const char *connector);\n/** @ingroup ModSecurity_C_API */\nvoid msc_set_log_cb(ModSecurity *msc, ModSecLogCb cb);\n/** @ingroup ModSecurity_C_API */\nvoid msc_cleanup(ModSecurity *msc);\n\n#ifdef __cplusplus\n}\n\n\n}  // namespace modsecurity\n#endif\n\n#endif  // HEADERS_MODSECURITY_MODSECURITY_H_\n"
  },
  {
    "path": "headers/modsecurity/rule.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#ifndef HEADERS_MODSECURITY_RULE_H_\n#define HEADERS_MODSECURITY_RULE_H_\n\n#include \"modsecurity/transaction.h\"\n#include \"modsecurity/modsecurity.h\"\n#include \"modsecurity/variable_value.h\"\n\n#ifdef __cplusplus\n\n#include <vector>\n#include <string>\n#include <list>\n#include <memory>\n#include <utility>\n\nnamespace modsecurity {\nnamespace variables {\nclass Variable;\nclass Variables;\n}\nnamespace actions {\nclass Action;\nclass Severity;\nclass LogData;\nclass Msg;\nclass Rev;\nclass SetVar;\nclass Tag;\nnamespace transformations {\nclass Transformation;\n}\n}\nnamespace operators {\nclass Operator;\n}\n\nusing TransformationResult = std::pair<std::string,\n    std::shared_ptr<std::string>>;\nusing TransformationResults = std::list<TransformationResult>;\n\nusing Transformation = actions::transformations::Transformation;\nusing Transformations = std::vector<Transformation *>;\n\nusing Actions = std::vector<actions::Action *>;\n\nusing Tags = std::vector<actions::Tag *>;\nusing SetVars = std::vector<actions::SetVar *>;\nusing MatchActions = std::vector<actions::Action *>;\n\nclass Rule {\n public:\n    Rule(const std::string &fileName, int lineNumber)\n        : m_fileName(fileName),\n        m_lineNumber(lineNumber),\n        m_phase(modsecurity::Phases::RequestHeadersPhase) {\n        }\n\n    Rule(const Rule &other) = delete;\n\n    Rule &operator=(const Rule &other) = delete;\n\n    virtual ~Rule() {}\n\n    virtual bool evaluate(Transaction *transaction) = 0;\n\n    virtual bool evaluate(Transaction *transaction, RuleMessage &ruleMessage) = 0;\n\n    const std::string& getFileName() const {\n        return m_fileName;\n    }\n\n    int getLineNumber() const {\n        return m_lineNumber;\n    }\n\n    int getPhase() const { return m_phase; }\n    void setPhase(int phase) { m_phase = phase; }\n\n    virtual std::string getReference() {\n        return m_fileName + \":\" + std::to_string(m_lineNumber);\n    }\n\n\n    virtual bool isMarker() { return false; }\n\n private:\n    const std::string m_fileName;\n    const int m_lineNumber;\n    // FIXME: phase may not be neede to SecMarker.\n    int m_phase;\n};\n\n\n}  // namespace modsecurity\n#endif\n\n\n#endif  // HEADERS_MODSECURITY_RULE_H_\n"
  },
  {
    "path": "headers/modsecurity/rule_marker.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#ifndef HEADERS_MODSECURITY_RULE_MARKER_H_\n#define HEADERS_MODSECURITY_RULE_MARKER_H_\n\n#include \"modsecurity/transaction.h\"\n#include \"modsecurity/modsecurity.h\"\n#include \"modsecurity/variable_value.h\"\n#include \"modsecurity/rule.h\"\n\n#ifdef __cplusplus\n\n#include <string>\n#include <memory>\n\nnamespace modsecurity {\n\n\nclass RuleMarker : public Rule {\n public:\n    RuleMarker(\n        const std::string &name,\n        const std::string &fileName,\n        int lineNumber)\n        : Rule(fileName, lineNumber),\n        m_name(name) { }\n\n    RuleMarker(const RuleMarker &r) = delete;\n\n    RuleMarker &operator=(const RuleMarker &r) = delete;\n   \n    virtual bool evaluate(Transaction *transaction, RuleMessage &ruleMessage) override {\n        return evaluate(transaction);\n    }\n\n    virtual bool evaluate(Transaction *transaction) override {\n        if (transaction->isInsideAMarker() &&\n            *transaction->getCurrentMarker() == m_name) {\n                transaction->removeMarker();\n                // FIXME: Move this to .cc\n                //        ms_dbg_a(transaction, 4, \"Out of a SecMarker \" + *m_name);\n        }\n\n        return true;\n    };\n\n    bool isMarker() override { return true; }\n\n private:\n    const std::string m_name;\n};\n\n\n}  // namespace modsecurity\n\n#endif\n\n#endif  // HEADERS_MODSECURITY_RULE_MARKER_H_\n"
  },
  {
    "path": "headers/modsecurity/rule_message.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#ifndef HEADERS_MODSECURITY_RULE_MESSAGE_H_\n#define HEADERS_MODSECURITY_RULE_MESSAGE_H_\n\n#include \"modsecurity/transaction.h\"\n#include \"modsecurity/rule.h\"\n#include \"modsecurity/rule_with_operator.h\"\n\n\n#ifdef __cplusplus\n\n#include <string>\n#include <list>\n\nnamespace modsecurity {\n\n\nclass RuleMessage {\n public:\n    enum LogMessageInfo {\n        ErrorLogTailLogMessageInfo = 2,\n        ClientLogMessageInfo = 4\n    };\n\n    RuleMessage(const RuleWithActions &rule, const Transaction &trans) :\n        m_rule(rule),\n        m_transaction(trans)\n    {\n        reset(true);\n    }\n\n    RuleMessage(const RuleMessage &ruleMessage) = default;\n    RuleMessage &operator=(const RuleMessage &ruleMessage) = delete;\n\n    void reset(const bool resetSaveMessage)\n    {\n        m_data.clear();\n        m_isDisruptive = false;\n        m_match.clear();\n        m_message.clear();\n        m_noAuditLog = false;\n        m_reference.clear();\n        if (resetSaveMessage == true)\n            m_saveMessage = true;\n        m_severity = 0;\n        m_tags.clear();\n    }\n\n    std::string log() const {\n        return log(*this, 0);\n    }\n    std::string log(int props) const {\n        return log(*this, props);\n    }\n    std::string log(int props, int responseCode) const {\n        return log(*this, props, responseCode);\n    }\n    std::string errorLog() const {\n        return log(*this,\n                   ClientLogMessageInfo | ErrorLogTailLogMessageInfo);\n    }\n\n    static std::string log(const RuleMessage &rm, int props, int code);\n    static std::string log(const RuleMessage &rm, int props) {\n        return log(rm, props, -1);\n    }\n    static std::string log(const RuleMessage &rm) {\n        return log(rm, 0);\n    }\n\n    static std::string _details(const RuleMessage &rm);\n    static std::string _errorLogTail(const RuleMessage &rm);\n\n    int getPhase() const { return m_rule.getPhase() - 1; }\n\n    const RuleWithActions &m_rule;\n    const Transaction &m_transaction;\n    std::string m_data;\n    bool m_isDisruptive = false;\n    std::string m_match;\n    std::string m_message;\n    bool m_noAuditLog = false;\n    std::string m_reference;\n    bool m_saveMessage = true;\n    int m_severity = 0;\n\n    std::list<std::string> m_tags;\n};\n\n\n}  // namespace modsecurity\n#endif\n\n\n#endif  // HEADERS_MODSECURITY_RULE_MESSAGE_H_\n"
  },
  {
    "path": "headers/modsecurity/rule_unconditional.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#ifndef HEADERS_MODSECURITY_RULE_UNCONDITIONAL_H_\n#define HEADERS_MODSECURITY_RULE_UNCONDITIONAL_H_\n\n#include \"modsecurity/modsecurity.h\"\n#include \"modsecurity/variable_value.h\"\n#include \"modsecurity/rule.h\"\n#include \"modsecurity/rules_set.h\"\n#include \"modsecurity/rule_with_actions.h\"\n#include \"modsecurity/actions/action.h\"\n\n#ifdef __cplusplus\n\n#include <vector>\n#include <string>\n#include <memory>\n\nnamespace modsecurity {\n\n\nclass RuleUnconditional : public RuleWithActions {\n public:\n    using RuleWithActions::RuleWithActions;\n\n    virtual bool evaluate(Transaction *transaction, RuleMessage &ruleMessage) override;\n};\n\n\n}  // namespace modsecurity\n\n#endif\n\n#endif  // HEADERS_MODSECURITY_RULE_UNCONDITIONAL_H_\n"
  },
  {
    "path": "headers/modsecurity/rule_with_actions.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#ifdef __cplusplus\n#include <stack>\n#include <vector>\n#include <string>\n#include <list>\n#include <memory>\n#include <utility>\n#endif\n\n#ifndef HEADERS_MODSECURITY_RULE_WITH_ACTIONS_H_\n#define HEADERS_MODSECURITY_RULE_WITH_ACTIONS_H_\n\n#include \"modsecurity/transaction.h\"\n#include \"modsecurity/modsecurity.h\"\n#include \"modsecurity/variable_value.h\"\n#include \"modsecurity/rule.h\"\n\n#ifdef __cplusplus\n\nnamespace modsecurity {\n\n\nclass RuleWithActions : public Rule {\n public:\n    RuleWithActions(\n        Actions *a,\n        Transformations *t,\n        const std::string &fileName,\n        int lineNumber);\n\n    ~RuleWithActions() override;\n\n    RuleWithActions(const RuleWithActions &r) = delete;\n\n    RuleWithActions &operator=(const RuleWithActions &r) = delete;\n\n    virtual bool evaluate(Transaction *transaction) override;\n\n    virtual bool evaluate(Transaction *transaction, RuleMessage &ruleMessage) override;\n\n    void executeActionsIndependentOfChainedRuleResult(\n        Transaction *trasn,\n        bool *containsDisruptive,\n        RuleMessage &ruleMessage);\n\n    void executeActionsAfterFullMatch(\n        Transaction *trasn,\n        bool containsDisruptive,\n        RuleMessage &ruleMessage);\n\n    void executeAction(Transaction *trans,\n        bool containsBlock,\n        RuleMessage &ruleMessage,\n        actions::Action *a,\n        bool context);\n\n\n    void executeTransformations(\n        const Transaction *trasn, const std::string &value, TransformationResults &ret);\n\n    void performLogging(Transaction *trans,\n        RuleMessage &ruleMessage,\n        bool lastLog = true,\n        bool chainedParentNull = false) const;\n\n    std::vector<actions::Action *> getActionsByName(const std::string& name,\n        const Transaction *t);\n    bool containsTag(const std::string& name, Transaction *t);\n    bool containsMsg(const std::string& name, Transaction *t);\n\n    inline bool isChained() const { return m_isChained == true; }\n    inline bool hasCaptureAction() const { return m_containsCaptureAction == true; }\n    inline void setChained(bool b) { m_isChained = b; }\n    inline bool hasDisruptiveAction() const { return m_disruptiveAction != NULL; }\n    inline bool hasBlockAction() const { return m_containsStaticBlockAction == true; }\n    inline bool hasMultimatch() const { return m_containsMultiMatchAction == true; }\n\n    inline bool hasLogData() const { return m_logData != NULL; }\n    std::string logData(Transaction *t);\n    inline bool hasMsg() const { return m_msg != NULL; }\n    std::string msg(Transaction *t);\n    inline bool hasSeverity() const { return m_severity != NULL; }\n    int severity() const;\n\n    std::string m_rev;\n    std::string m_ver;\n    int m_accuracy;\n    int m_maturity;\n\n\n    int64_t m_ruleId;\n\n    std::shared_ptr<RuleWithActions> m_chainedRuleChild;\n    RuleWithActions *m_chainedRuleParent;\n\n private:\n    inline void executeTransformation(\n        const actions::transformations::Transformation &a,\n        std::string &value,\n        const Transaction *trans,\n        TransformationResults &ret,\n        std::string &path,\n        int &nth) const;\n\n    /* actions */\n    actions::Action *m_disruptiveAction;\n    actions::LogData *m_logData;\n    actions::Msg *m_msg;\n    actions::Severity *m_severity;\n    MatchActions m_actionsRuntimePos;\n    SetVars m_actionsSetVar;\n    Tags m_actionsTag;\n\n    /* actions > transformations */\n    Transformations m_transformations;\n\n    bool m_containsCaptureAction:1;\n    bool m_containsMultiMatchAction:1;\n    bool m_containsStaticBlockAction:1;\n    bool m_isChained:1;\n};\n\n}  // namespace modsecurity\n#endif\n\n\n#endif  // HEADERS_MODSECURITY_RULE_WITH_ACTIONS_H_"
  },
  {
    "path": "headers/modsecurity/rule_with_operator.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#ifdef __cplusplus\n#include <stack>\n#include <vector>\n#include <string>\n#include <list>\n#include <memory>\n#include <utility>\n#endif\n\n#ifndef HEADERS_MODSECURITY_RULE_WITH_OPERATOR_H_\n#define HEADERS_MODSECURITY_RULE_WITH_OPERATOR_H_\n\n#include \"modsecurity/transaction.h\"\n#include \"modsecurity/modsecurity.h\"\n#include \"modsecurity/variable_value.h\"\n#include \"modsecurity/rule.h\"\n#include \"modsecurity/rule_with_actions.h\"\n\n#ifdef __cplusplus\n\nnamespace modsecurity {\n\n\nclass RuleWithOperator : public RuleWithActions {\n public:\n    RuleWithOperator(operators::Operator *op,\n        variables::Variables *variables,\n        std::vector<actions::Action *> *actions,\n        Transformations *transformations,\n        const std::string &fileName,\n        int lineNumber);\n\n    ~RuleWithOperator() override;\n\n    bool evaluate(Transaction *transaction, RuleMessage &ruleMessage) override;\n\n    void getVariablesExceptions(Transaction &t,\n        variables::Variables *exclusion, variables::Variables *addition);\n    inline void getFinalVars(variables::Variables *vars,\n        variables::Variables *eclusion, Transaction *trans);\n\n    bool executeOperatorAt(Transaction *trasn, const std::string &key,\n        const std::string &value, RuleMessage &ruleMessage);\n\n    static void updateMatchedVars(Transaction *trasn, const std::string &key,\n        const std::string &value);\n\n\n    const std::string& getOperatorName() const;\n\n    virtual std::string getReference() override {\n        return std::to_string(m_ruleId);\n    }\n\n private:\n    modsecurity::variables::Variables *m_variables;\n    operators::Operator *m_operator;\n};\n\n\n}  // namespace modsecurity\n#endif\n\n\n#endif  // HEADERS_MODSECURITY_RULE_WITH_OPERATOR_H_\n"
  },
  {
    "path": "headers/modsecurity/rules.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n\n#include <stdio.h>\n#include <string.h>\n\n#ifdef __cplusplus\n#include <ctime>\n#include <iostream>\n#include <string>\n#include <vector>\n#include <list>\n#include <memory>\n#endif\n\n#include \"modsecurity/rule.h\"\n#include \"modsecurity/rule_with_operator.h\"\n#include \"modsecurity/rule_with_actions.h\"\n\n#ifndef HEADERS_MODSECURITY_RULES_H_\n#define HEADERS_MODSECURITY_RULES_H_\n\n\n#ifdef __cplusplus\nnamespace modsecurity {\n\n\nclass Rules {\n public:\n    void dump() const {\n        for (const auto &r : m_rules) {\n            std::cout << \"    Rule ID: \" << r->getReference();\n            std::cout << \"--\" << r << std::endl;\n        }\n    }\n\n    int append(Rules *from, const std::vector<int64_t> &ids, std::ostringstream *err) {\n         size_t j = 0;\n         for (; j < from->size(); j++) {\n            const RuleWithOperator *rule = dynamic_cast<RuleWithOperator *>(from->at(j).get());\n            if (rule && std::binary_search(ids.begin(), ids.end(), rule->m_ruleId)) {\n                 if (err != NULL) {\n                     *err << \"Rule id: \" << std::to_string(rule->m_ruleId) \\\n                        << \" is duplicated\" << std::endl;\n                 }\n                 return -1;\n             }\n         }\n         m_rules.insert(m_rules.end(), from->m_rules.begin(), from->m_rules.end());\n         return j;\n    }\n\n    bool insert(const std::shared_ptr<Rule> &rule) {\n        return insert(rule, nullptr, nullptr);\n    }\n\n    bool insert(std::shared_ptr<Rule> rule, const std::vector<int64_t> *ids, std::ostringstream *err) {\n        const RuleWithOperator *r = dynamic_cast<RuleWithOperator *>(rule.get());\n        if (r && ids != nullptr && std::binary_search(ids->begin(), ids->end(), r->m_ruleId)) {\n            if (err != nullptr) {\n                *err << \"Rule id: \" << std::to_string(r->m_ruleId) \\\n                    << \" is duplicated\" << std::endl;\n            }\n            return false;\n        }\n        m_rules.push_back(rule);\n        return true;\n    }\n\n    size_t size() const { return m_rules.size(); }\n    std::shared_ptr<Rule> operator[](int index) const { return m_rules[index]; }\n    std::shared_ptr<Rule> at(int index) const { return m_rules[index]; }\n\n    std::vector<std::shared_ptr<Rule> > m_rules;\n};\n\n\n}  // namespace modsecurity\n#endif\n\n\n#endif  // HEADERS_MODSECURITY_RULES_H_\n\n"
  },
  {
    "path": "headers/modsecurity/rules_exceptions.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#ifdef __cplusplus\n#include <ctime>\n#include <fstream>\n#include <iomanip>\n#include <iostream>\n#include <list>\n#include <map>\n#include <sstream>\n#include <string>\n#include <unordered_map>\n#include <utility>\n#include <vector>\n#include <memory>\n#endif\n\n#ifndef HEADERS_MODSECURITY_RULES_EXCEPTIONS_H_\n#define HEADERS_MODSECURITY_RULES_EXCEPTIONS_H_\n\n#ifdef __cplusplus\n\n\nnamespace modsecurity {\nnamespace actions {\nclass Action;\n}\nnamespace variables {\nclass Variable;\n}\n\nclass RulesExceptions {\n public:\n    RulesExceptions();\n    ~RulesExceptions();\n\n    bool load(const std::string &data, std::string *error);\n    bool addRange(int a, int b);\n    bool addNumber(int a);\n    bool contains(int a);\n    bool merge(RulesExceptions *from);\n\n    bool loadRemoveRuleByMsg(const std::string &msg, const std::string *error);\n    bool loadRemoveRuleByTag(const std::string &msg, const std::string *error);\n\n    bool loadUpdateTargetByMsg(const std::string &msg,\n        std::unique_ptr<std::vector<std::unique_ptr<variables::Variable> > > v,\n        std::string *error);\n\n    bool loadUpdateTargetByTag(const std::string &tag,\n        std::unique_ptr<std::vector<std::unique_ptr<variables::Variable> > > v,\n        std::string *error);\n\n    bool loadUpdateTargetById(double id,\n        std::unique_ptr<std::vector<std::unique_ptr<variables::Variable> > > v,\n        std::string *error);\n\n    bool loadUpdateActionById(double id,\n        std::unique_ptr<std::vector<std::unique_ptr<actions::Action> > > actions,\n        std::string *error);\n\n    std::unordered_multimap<std::shared_ptr<std::string>,\n        std::shared_ptr<variables::Variable>> m_variable_update_target_by_tag;\n    std::unordered_multimap<std::shared_ptr<std::string>,\n        std::shared_ptr<variables::Variable>> m_variable_update_target_by_msg;\n    std::unordered_multimap<double,\n        std::shared_ptr<variables::Variable>> m_variable_update_target_by_id;\n    std::unordered_multimap<double,\n        std::shared_ptr<actions::Action>> m_action_pre_update_target_by_id;\n    std::unordered_multimap<double,\n        std::shared_ptr<actions::Action>> m_action_pos_update_target_by_id;\n    std::list<std::string> m_remove_rule_by_msg;\n    std::list<std::string> m_remove_rule_by_tag;\n\n private:\n    std::list<std::pair<int, int> > m_ranges;\n    std::list<int> m_numbers;\n};\n\n}  // namespace modsecurity\n#endif\n\n\n#endif  // HEADERS_MODSECURITY_RULES_EXCEPTIONS_H_\n\n"
  },
  {
    "path": "headers/modsecurity/rules_properties.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <modsecurity/rules_set_properties.h>\n\n\n"
  },
  {
    "path": "headers/modsecurity/rules_set.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <stdio.h>\n#include <string.h>\n\n#ifdef __cplusplus\n#include <ctime>\n#include <iostream>\n#include <string>\n#include <vector>\n#include <list>\n#include <cstdint>\n#endif\n\n\n#ifndef HEADERS_MODSECURITY_RULES_SET_H_\n#define HEADERS_MODSECURITY_RULES_SET_H_\n\n#include \"modsecurity/rules_set_properties.h\"\n#include \"modsecurity/modsecurity.h\"\n#include \"modsecurity/transaction.h\"\n#include \"modsecurity/rule.h\"\n#include \"modsecurity/rules_set_phases.h\"\n\n#ifdef __cplusplus\n\nnamespace modsecurity {\nclass RuleWithOperator;\nnamespace Parser {\nclass Driver;\n}\n\n\n\n/** @ingroup ModSecurity_CPP_API */\nclass RulesSet : public RulesSetProperties {\n public:\n    RulesSet()\n        : RulesSetProperties(new DebugLog())\n#ifndef NO_LOGS\n        ,m_secmarker_skipped(0)\n#endif\n        { }\n\n    explicit RulesSet(DebugLog *customLog)\n        : RulesSetProperties(customLog)\n#ifndef NO_LOGS\n        ,m_secmarker_skipped(0)\n#endif\n        { }\n\n    ~RulesSet() { }\n\n    int loadFromUri(const char *uri);\n    int loadRemote(const char *key, const char *uri);\n    int load(const char *rules);\n    int load(const char *rules, const std::string &ref);\n\n    void dump() const;\n\n    int merge(Parser::Driver *driver);\n    int merge(RulesSet *rules);\n\n    int evaluate(int phase, Transaction *transaction);\n    std::string getParserError() const;\n    std::string getParserError();\n\n    void debug(int level, const std::string &id, const std::string &uri,\n        const std::string &msg);\n\n    static void cleanMatchedVars(Transaction *trans);\n\n    RulesSetPhases m_rulesSetPhases;\n private:\n#ifndef NO_LOGS\n    uint8_t m_secmarker_skipped;\n#endif\n};\n\n#endif\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\nRulesSet *msc_create_rules_set(void);\nvoid msc_rules_dump(const RulesSet *rules);\nint msc_rules_merge(RulesSet *rules_dst, RulesSet *rules_from, const char **error);\nint msc_rules_add_remote(RulesSet *rules, const char *key, const char *uri,\n    const char **error);\nint msc_rules_add_file(RulesSet *rules, const char *file, const char **error);\nint msc_rules_add(RulesSet *rules, const char *plain_rules, const char **error);\nvoid msc_rules_error_cleanup(const char *error);\nint msc_rules_cleanup(RulesSet *rules);\n\n#ifdef __cplusplus\n}\n}  // namespace modsecurity\n#endif\n\n#endif  // HEADERS_MODSECURITY_RULES_SET_H_\n"
  },
  {
    "path": "headers/modsecurity/rules_set_phases.h",
    "content": "\n/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <stdio.h>\n#include <string.h>\n\n#ifdef __cplusplus\n#include <ctime>\n#include <iostream>\n#include <string>\n#include <vector>\n#include <list>\n#endif\n\n\n#ifndef HEADERS_MODSECURITY_RULES_SET_PHASES_H_\n#define HEADERS_MODSECURITY_RULES_SET_PHASES_H_\n\n#include \"modsecurity/rules.h\"\n\n#ifdef __cplusplus\n\nnamespace modsecurity {\nclass RuleWithOperator;\nnamespace Parser {\nclass Driver;\n}\n\n/** @ingroup ModSecurity_CPP_API */\nclass RulesSetPhases {\n public:\n\n    bool insert(std::shared_ptr<Rule> rule);\n\n    int append(RulesSetPhases *from, std::ostringstream *err);\n    void dump() const;\n\n    Rules *operator[](int index) { return &m_rulesAtPhase[index]; }\n    Rules *at(int index) { return &m_rulesAtPhase[index]; }\n\n private:\n    Rules m_rulesAtPhase[8];\n\n};\n\n\n}  // namespace modsecurity\n#endif\n\n#endif  // HEADERS_MODSECURITY_RULES_SET_PHASES_H_"
  },
  {
    "path": "headers/modsecurity/rules_set_properties.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#ifdef WIN32\n#ifdef max\n#undef max\n#endif\n#ifdef min\n#undef min\n#endif\n#endif\n\n#ifdef __cplusplus\n#include <ctime>\n#include <iostream>\n#include <string>\n#include <vector>\n#include <list>\n#include <set>\n#include <cstring>\n#include <limits>\n#include <cstdint>\n#endif\n\n\n#ifndef HEADERS_MODSECURITY_RULES_SET_PROPERTIES_H_\n#define HEADERS_MODSECURITY_RULES_SET_PROPERTIES_H_\n\n\n#include \"modsecurity/modsecurity.h\"\n#include \"modsecurity/rule.h\"\n#include \"modsecurity/rules_exceptions.h\"\n#include \"modsecurity/actions/action.h\"\n#include \"modsecurity/audit_log.h\"\n\n#define CODEPAGE_SEPARATORS  \" \\t\\n\\r\"\n\n#define merge_boolean_value(to, from, default)                               \\\n    if (to == PropertyNotSetConfigBoolean) {                                 \\\n        to = (from == PropertyNotSetConfigBoolean) ? default : from;         \\\n    }\n\n#define merge_ruleengine_value(to, from, default)                            \\\n    if (to == PropertyNotSetRuleEngine) {                                    \\\n        to = (from == PropertyNotSetRuleEngine) ? default : from;            \\\n    }\n\n#define merge_bodylimitaction_value(to, from, default)                       \\\n    if (to == PropertyNotSetBodyLimitAction) {                               \\\n        to = (from == PropertyNotSetBodyLimitAction) ? default : from;       \\\n    }\n\n#define merge_xmlargparse_value(to, from, default)                               \\\n    if (to == PropertyNotSetConfigXMLParseXmlIntoArgs) {                                 \\\n        to = (from == PropertyNotSetConfigXMLParseXmlIntoArgs) ? default : from;         \\\n    }\n\n#ifdef __cplusplus\n\nnamespace modsecurity {\nclass RulesExceptions;\nnamespace Parser {\nclass Driver;\n}\n\nusing modsecurity::debug_log::DebugLog;\nusing modsecurity::audit_log::AuditLog;\n\n// template for different numeric int types\ntemplate <typename T>\nclass ConfigValue {\npublic:\n    bool m_set = false;\n    T m_value = 0;\n\n    ConfigValue() = default;\n\n    void merge(const ConfigValue<T>* from) {\n        if (m_set || !from->m_set) {\n            return;\n        }\n        m_set = true;\n        m_value = from->m_value;\n    }\n\n    // default parser\n    bool parse(const std::string& a, std::string* errmsg = nullptr) {\n\n        // use an alias type because the template can convert both signed and unsigned int\n        using LimitSigned = std::conditional_t<std::is_signed_v<T>, std::int64_t, std::uint64_t>;\n        LimitSigned val;\n\n        // clear errno variable, wee need that later\n        errno = 0;\n\n        try {\n            if constexpr (std::is_signed_v<T>) {\n                val = static_cast<std::int64_t>(std::stoll(a));\n            } else {\n                val = static_cast<std::uint64_t>(std::stoull(a));\n            }\n        }\n        catch (const std::invalid_argument&) {\n            // probably can't occur, but we handle it anyway\n            set_error(errmsg, \"Invalid number format (not numeric)\");\n            return false;\n        }\n        catch (const std::out_of_range&) {\n            // the value is out of range, we can not handle it\n            set_error(errmsg, \"Number out of range\");\n            return false;\n        }\n        catch (...) { // NOSONAR\n            // we don't need to handle all exceptions, the engine's BISON parser\n            // does not allow other symbols than numbers\n            set_error(errmsg, \"An unknown error occurred while parsing number.\");\n            return false;\n        }\n\n        if (\n            // The first condition will be true when the value is bigger than int64/uint64 maximum value.\n            // The second condition checks whether the value fits into int64/uint64, but not\n            // into the designed type, e.g., uint32; in that case the errno will be 0, but\n            // we must check the value is not bigger than the defined maximum of the class.\n            (errno == ERANGE && val == std::numeric_limits<LimitSigned>::max())\n            ||\n            (val > static_cast<LimitSigned>(maxValue()))\n        ) {\n            set_error(errmsg, \"Value is too big.\");\n            return false;\n        }\n\n        if (\n            // same as above\n            (errno == ERANGE && val == std::numeric_limits<LimitSigned>::min())\n            ||\n            (val < static_cast<LimitSigned>(minValue()))\n        ) {\n            set_error(errmsg, \"Value is too small.\");\n            return false;\n        }\n\n        m_value = static_cast<T>(val);\n        m_set = true;\n        return true;\n\n    }\n\nprotected:\n    // derived classes must implement the maxValue\n    virtual T maxValue() const = 0;\n    // minValue is optional\n    virtual T minValue() const { return 0; }\n\nprivate:\n    static inline void set_error(std::string* err, const char* msg) {\n        if (err) {\n            *err = msg;\n        }\n    }\n};\n\n/** @ingroup ModSecurity_CPP_API */\n\nclass ConfigInt : public ConfigValue<int32_t> {\nprotected:\n    int32_t minValue() const override {\n        return std::numeric_limits<int32_t>::min();\n    }\n    int32_t maxValue() const override {\n        return std::numeric_limits<int32_t>::max();\n    }\n};\n\nclass ConfigUnsignedInt : public ConfigValue<uint32_t> {\nprotected:\n    uint32_t maxValue() const override {\n        return std::numeric_limits<uint32_t>::max();\n    }\n};\n\nclass ConfigUnsignedLong : public ConfigValue<uint64_t> {\nprotected:\n    uint64_t maxValue() const override {\n        return std::numeric_limits<uint64_t>::max();\n    }\n};\n\n\nclass ConfigString {\n public:\n    bool m_set = false;\n    std::string m_value = \"\";\n    ConfigString() = default;\n\n    void merge(const ConfigString *from) {\n        if (m_set == true || from->m_set == false) {\n            return;\n        }\n        m_set = true;\n        m_value = from->m_value;\n        return;\n    }\n};\n\n\nclass ConfigSet {\n public:\n    bool m_set = false;\n    bool m_clear = false;\n    std::set<std::string> m_value;\n    ConfigSet() = default;\n};\n\n\nclass UnicodeMapHolder {\n public:\n    UnicodeMapHolder() {\n        memset(m_data, -1, (sizeof(int)*65536));\n    };\n\n    int& operator[](int index) { return m_data[index]; }\n    int operator[](int index) const { return m_data[index]; }\n\n    int at(int index) const { return m_data[index]; }\n    void change(int i, int a) { m_data[i] = a; }\n\n    int m_data[65536];\n};\n\n\nclass RulesSetProperties;\nclass ConfigUnicodeMap {\n public:\n    ConfigUnicodeMap() : m_set(false),\n        m_unicodeCodePage(0),\n        m_unicodeMapTable(NULL) { }\n\n    static void loadConfig(std::string f, double codePage,\n        RulesSetProperties *driver, std::string *errg);\n\n    void merge(const ConfigUnicodeMap *from) {\n        if (from->m_set == false) {\n            return;\n        }\n\n        m_set = true;\n        m_unicodeCodePage = from->m_unicodeCodePage;\n        m_unicodeMapTable = from->m_unicodeMapTable;\n\n        return;\n    }\n\n    bool m_set;\n    double m_unicodeCodePage;\n    std::shared_ptr<modsecurity::UnicodeMapHolder> m_unicodeMapTable;\n};\n\n\nclass RulesSetProperties {\n public:\n    RulesSetProperties() :\n        m_auditLog(new AuditLog()),\n        m_requestBodyLimitAction(PropertyNotSetBodyLimitAction),\n        m_responseBodyLimitAction(PropertyNotSetBodyLimitAction),\n        m_secRequestBodyAccess(PropertyNotSetConfigBoolean),\n        m_secResponseBodyAccess(PropertyNotSetConfigBoolean),\n        m_secXMLExternalEntity(PropertyNotSetConfigBoolean),\n        m_secXMLParseXmlIntoArgs(PropertyNotSetConfigXMLParseXmlIntoArgs),\n        m_tmpSaveUploadedFiles(PropertyNotSetConfigBoolean),\n        m_uploadKeepFiles(PropertyNotSetConfigBoolean),\n        m_debugLog(new DebugLog()),\n        m_remoteRulesActionOnFailed(PropertyNotSetRemoteRulesAction),\n        m_secRuleEngine(PropertyNotSetRuleEngine) { }\n\n\n    explicit RulesSetProperties(DebugLog *debugLog) :\n        m_auditLog(new AuditLog()),\n        m_requestBodyLimitAction(PropertyNotSetBodyLimitAction),\n        m_responseBodyLimitAction(PropertyNotSetBodyLimitAction),\n        m_secRequestBodyAccess(PropertyNotSetConfigBoolean),\n        m_secResponseBodyAccess(PropertyNotSetConfigBoolean),\n        m_secXMLExternalEntity(PropertyNotSetConfigBoolean),\n        m_secXMLParseXmlIntoArgs(PropertyNotSetConfigXMLParseXmlIntoArgs),\n        m_tmpSaveUploadedFiles(PropertyNotSetConfigBoolean),\n        m_uploadKeepFiles(PropertyNotSetConfigBoolean),\n        m_debugLog(debugLog),\n        m_remoteRulesActionOnFailed(PropertyNotSetRemoteRulesAction),\n        m_secRuleEngine(PropertyNotSetRuleEngine) { }\n\n    RulesSetProperties(const RulesSetProperties &r) = delete;\n    RulesSetProperties &operator =(const RulesSetProperties &r) = delete;\n\n    ~RulesSetProperties() {\n        int i = 0;\n\n        for (i = 0; i < modsecurity::Phases::NUMBER_OF_PHASES; i++) {\n            std::vector<std::shared_ptr<actions::Action> > *tmp = \\\n                &m_defaultActions[i];\n            while (tmp->empty() == false) {\n                tmp->pop_back();\n            }\n        }\n\n        delete m_debugLog;\n        delete m_auditLog;\n    }\n\n\n    /**\n     *\n     * The ConfigBoolean enumerator defines the states for configuration boolean values.\n     * The default value is PropertyNotSetConfigBoolean.\n     */\n    enum ConfigBoolean {\n        TrueConfigBoolean,\n        FalseConfigBoolean,\n        PropertyNotSetConfigBoolean\n    };\n\n    /**\n     *\n     * The ConfigXMLParseXmlIntoArgs enumerator defines the states for the configuration\n     * XMLParseXmlIntoArgs values.\n     * The default value is PropertyNotSetConfigXMLParseXmlIntoArgs.\n     */\n    enum ConfigXMLParseXmlIntoArgs {\n        TrueConfigXMLParseXmlIntoArgs,\n        FalseConfigXMLParseXmlIntoArgs,\n        OnlyArgsConfigXMLParseXmlIntoArgs,\n        PropertyNotSetConfigXMLParseXmlIntoArgs\n    };\n\n    /**\n     *\n     * The RuleEngine enumerator consists in mapping the different states\n     * of the rule engine.\n     *\n     */\n    enum RuleEngine {\n     /**\n      *\n      * Rules won't be evaluated if Rule Engine is set to DisabledRuleEngine\n      *\n      */\n     DisabledRuleEngine,\n     /**\n      *\n      * Rules will be evaluated and disturb actions will take place if needed.\n      *\n      */\n     EnabledRuleEngine,\n     /**\n      * Rules will be evaluated but it won't generate any disruptive action.\n      *\n      */\n     DetectionOnlyRuleEngine,\n     /**\n      *\n      */\n     PropertyNotSetRuleEngine\n    };\n\n\n    /**\n     *\n     * Defines what actions should be taken in case the body (response or\n     * request) is bigger than the expected size.\n     *\n     */\n    enum BodyLimitAction {\n     /**\n      *\n      * Process partial\n      *\n      */\n     ProcessPartialBodyLimitAction,\n     /**\n      *\n      * Reject the request\n      *\n      */\n     RejectBodyLimitAction,\n     /**\n      *\n      */\n     PropertyNotSetBodyLimitAction\n    };\n\n\n    /**\n     *\n     * Defines what actions should be taken in case the remote rules failed to\n     * be downloaded (independent of the circumstances)\n     *\n     *\n     */\n    enum OnFailedRemoteRulesAction {\n     /**\n      *\n      * Abort\n      *\n      */\n     AbortOnFailedRemoteRulesAction,\n     /**\n      *\n      * Warn on logging\n      *\n      */\n     WarnOnFailedRemoteRulesAction,\n     /**\n      *\n      */\n     PropertyNotSetRemoteRulesAction\n    };\n\n\n    static std::string ruleEngineStateString(RuleEngine i) {\n        switch (i) {\n        case DisabledRuleEngine:\n            return \"Disabled\";\n        case EnabledRuleEngine:\n            return \"Enabled\";\n        case DetectionOnlyRuleEngine:\n            return \"DetectionOnly\";\n        case PropertyNotSetRuleEngine:\n            return \"PropertyNotSet/DetectionOnly\";\n        }\n        return std::string{};\n    }\n\n\n    static std::string configBooleanString(ConfigBoolean i) {\n        switch (i) {\n        case TrueConfigBoolean:\n            return \"True\";\n        case FalseConfigBoolean:\n            return \"False\";\n        case PropertyNotSetConfigBoolean:\n        default:\n            return \"Not set\";\n        }\n    }\n\n    static std::string configXMLParseXmlIntoArgsString(ConfigXMLParseXmlIntoArgs i) {\n        switch (i) {\n        case TrueConfigXMLParseXmlIntoArgs:\n            return \"True\";\n        case FalseConfigXMLParseXmlIntoArgs:\n            return \"False\";\n        case OnlyArgsConfigXMLParseXmlIntoArgs:\n            return \"OnlyArgs\";\n        case PropertyNotSetConfigXMLParseXmlIntoArgs:\n        default:\n            return \"Not set\";\n        }\n    }\n\n    static int mergeProperties(RulesSetProperties *from,\n        RulesSetProperties *to, std::ostringstream *err) {\n\n        merge_ruleengine_value(to->m_secRuleEngine, from->m_secRuleEngine,\n                               PropertyNotSetRuleEngine);\n\n        merge_boolean_value(to->m_secRequestBodyAccess,\n                            from->m_secRequestBodyAccess,\n                            PropertyNotSetConfigBoolean);\n\n        merge_boolean_value(to->m_secResponseBodyAccess,\n                            from->m_secResponseBodyAccess,\n                            PropertyNotSetConfigBoolean);\n\n        merge_boolean_value(to->m_secXMLExternalEntity,\n                            from->m_secXMLExternalEntity,\n                            PropertyNotSetConfigBoolean);\n\n        merge_xmlargparse_value(to->m_secXMLParseXmlIntoArgs,\n                            from->m_secXMLParseXmlIntoArgs,\n                            PropertyNotSetConfigXMLParseXmlIntoArgs);\n\n        merge_boolean_value(to->m_uploadKeepFiles,\n                            from->m_uploadKeepFiles,\n                            PropertyNotSetConfigBoolean);\n\n        merge_boolean_value(to->m_tmpSaveUploadedFiles,\n                            from->m_tmpSaveUploadedFiles,\n                            PropertyNotSetConfigBoolean);\n\n        to->m_argumentsLimit.merge(&from->m_argumentsLimit);\n        to->m_requestBodyJsonDepthLimit.merge(&from->m_requestBodyJsonDepthLimit);\n        to->m_requestBodyLimit.merge(&from->m_requestBodyLimit);\n        to->m_requestBodyNoFilesLimit.merge(&from->m_requestBodyNoFilesLimit);\n        to->m_responseBodyLimit.merge(&from->m_responseBodyLimit);\n\n        merge_bodylimitaction_value(to->m_requestBodyLimitAction,\n                                    from->m_requestBodyLimitAction,\n                                    PropertyNotSetBodyLimitAction);\n\n        merge_bodylimitaction_value(to->m_responseBodyLimitAction,\n                                    from->m_responseBodyLimitAction,\n                                    PropertyNotSetBodyLimitAction);\n\n        to->m_pcreMatchLimit.merge(&from->m_pcreMatchLimit);\n        to->m_uploadFileLimit.merge(&from->m_uploadFileLimit);\n        to->m_uploadFileMode.merge(&from->m_uploadFileMode);\n        to->m_uploadDirectory.merge(&from->m_uploadDirectory);\n        to->m_uploadTmpDirectory.merge(&from->m_uploadTmpDirectory);\n\n        to->m_secArgumentSeparator.merge(&from->m_secArgumentSeparator);\n\n        to->m_secWebAppId.merge(&from->m_secWebAppId);\n\n        to->m_unicodeMapTable.merge(&from->m_unicodeMapTable);\n\n        to->m_httpblKey.merge(&from->m_httpblKey);\n\n        to->m_exceptions.merge(&from->m_exceptions);\n\n        to->m_components.insert(to->m_components.end(),\n            from->m_components.begin(), from->m_components.end());\n\n        if (from->m_responseBodyTypeToBeInspected.m_set == true) {\n            if (from->m_responseBodyTypeToBeInspected.m_clear == true) {\n                to->m_responseBodyTypeToBeInspected.m_value.clear();\n                from->m_responseBodyTypeToBeInspected.m_value.clear();\n            } else {\n                for (std::set<std::string>::iterator\n                    it = from->m_responseBodyTypeToBeInspected.m_value.begin();\n                    it != from->m_responseBodyTypeToBeInspected.m_value.end();\n                    ++it) {\n                    to->m_responseBodyTypeToBeInspected.m_value.insert(*it);\n                }\n            }\n            to->m_responseBodyTypeToBeInspected.m_set = true;\n        }\n\n        for (int i = 0; i < modsecurity::Phases::NUMBER_OF_PHASES; i++) {\n            std::vector<std::shared_ptr<actions::Action> > *actions_from = \\\n                &from->m_defaultActions[i];\n            std::vector<std::shared_ptr<actions::Action> > *actions_to = \\\n                &to->m_defaultActions[i];\n            for (size_t j = 0; j < actions_from->size(); j++) {\n                actions_to->push_back(actions_from->at(j));\n            }\n        }\n\n        if (to->m_auditLog) {\n            std::string error;\n            to->m_auditLog->merge(from->m_auditLog, &error);\n            if (error.size() > 0) {\n                *err << error;\n                return -1;\n            }\n        }\n\n        if (from->m_debugLog && to->m_debugLog &&\n            from->m_debugLog->isLogFileSet()) {\n            if (to->m_debugLog->isLogFileSet() == false) {\n                std::string error;\n                to->m_debugLog->setDebugLogFile(\n                    from->m_debugLog->getDebugLogFile(),\n                    &error);\n                if (error.size() > 0) {\n                    *err << error;\n                    return -1;\n                }\n            }\n        }\n\n        if (from->m_debugLog && to->m_debugLog &&\n            from->m_debugLog->isLogLevelSet()) {\n            if (to->m_debugLog->isLogLevelSet() == false) {\n                to->m_debugLog->setDebugLogLevel(\n                    from->m_debugLog->getDebugLogLevel());\n            }\n        }\n\n        return 1;\n    }\n\n\n    audit_log::AuditLog *m_auditLog;\n    BodyLimitAction m_requestBodyLimitAction;\n    BodyLimitAction m_responseBodyLimitAction;\n    ConfigBoolean m_secRequestBodyAccess;\n    ConfigBoolean m_secResponseBodyAccess;\n    ConfigBoolean m_secXMLExternalEntity;\n    ConfigXMLParseXmlIntoArgs m_secXMLParseXmlIntoArgs;\n    ConfigBoolean m_tmpSaveUploadedFiles;\n    ConfigBoolean m_uploadKeepFiles;\n    ConfigUnsignedInt m_argumentsLimit;\n    ConfigUnsignedInt m_requestBodyJsonDepthLimit;\n    ConfigUnsignedLong m_requestBodyLimit;\n    ConfigUnsignedLong m_requestBodyNoFilesLimit;\n    ConfigUnsignedLong m_responseBodyLimit;\n    ConfigUnsignedInt m_pcreMatchLimit;\n    ConfigUnsignedInt m_uploadFileLimit;\n    ConfigUnsignedInt m_uploadFileMode;\n    DebugLog *m_debugLog;\n    OnFailedRemoteRulesAction m_remoteRulesActionOnFailed;\n    RuleEngine m_secRuleEngine;\n    RulesExceptions m_exceptions;\n    std::list<std::string> m_components;\n    std::ostringstream m_parserError;\n    ConfigSet m_responseBodyTypeToBeInspected;\n    ConfigString m_httpblKey;\n    ConfigString m_uploadDirectory;\n    ConfigString m_uploadTmpDirectory;\n    ConfigString m_secArgumentSeparator;\n    ConfigString m_secWebAppId;\n    std::vector<std::shared_ptr<actions::Action> > \\\n        m_defaultActions[modsecurity::Phases::NUMBER_OF_PHASES];\n    ConfigUnicodeMap m_unicodeMapTable;\n};\n\n\n#endif\n\n#ifdef __cplusplus\n}  // namespace modsecurity\n#endif\n\n#endif  // HEADERS_MODSECURITY_RULES_SET_PROPERTIES_H_\n"
  },
  {
    "path": "headers/modsecurity/transaction.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#ifndef HEADERS_MODSECURITY_TRANSACTION_H_\n#define HEADERS_MODSECURITY_TRANSACTION_H_\n\n#ifdef __cplusplus\n#include <cassert>\n#include <ctime>\n#include <fstream>\n#include <iomanip>\n#include <iostream>\n#include <list>\n#include <map>\n#include <sstream>\n#include <string>\n#include <unordered_map>\n#include <utility>\n#include <vector>\n#include <memory>\n#include <stack>\n#endif\n\n#include <stdlib.h>\n#include <stddef.h>\n\n#ifndef __cplusplus\ntypedef struct ModSecurity_t ModSecurity;\ntypedef struct Transaction_t Transaction;\ntypedef struct Rules_t RulesSet;\n#endif\n\n#include \"modsecurity/anchored_set_variable.h\"\n#include \"modsecurity/anchored_variable.h\"\n#include \"modsecurity/intervention.h\"\n#include \"modsecurity/collection/collections.h\"\n#include \"modsecurity/variable_value.h\"\n#include \"modsecurity/collection/collection.h\"\n#include \"modsecurity/variable_origin.h\"\n#include \"modsecurity/anchored_set_variable_translation_proxy.h\"\n#include \"modsecurity/audit_log.h\"\n\n\n#ifndef NO_LOGS\n#define ms_dbg(b, c) \\\n  do { \\\n      if (m_rules && m_rules->m_debugLog && m_rules->m_debugLog->m_debugLevel >= b) { \\\n          m_rules->debug(b, m_id, m_uri, c); \\\n      } \\\n  } while (0);\n#else\n#define ms_dbg(b, c) \\\n  do { } while (0);\n#endif\n\n#ifndef NO_LOGS\n#define ms_dbg_a(t, b, c) \\\n  do { \\\n      if (t && t->m_rules && t->m_rules->m_debugLog && t->m_rules->m_debugLog->m_debugLevel >= b) { \\\n          t->debug(b, c); \\\n      } \\\n  } while (0);\n#else\n#define ms_dbg_a(t, b, c) \\\n    do { } while (0);\n#endif\n\n\n#define LOGFY_ADD(a, b) \\\n    yajl_gen_string(g, reinterpret_cast<const unsigned char*>(a), strlen(a)); \\\n    if (b.data() == NULL) { \\\n      yajl_gen_string(g, reinterpret_cast<const unsigned char*>(\"\"), \\\n          strlen(\"\")); \\\n    } else { \\\n      yajl_gen_string(g, reinterpret_cast<const unsigned char*>(b.data()), \\\n          b.length()); \\\n    }\n\n#define LOGFY_ADD_INT(a, b) \\\n    yajl_gen_string(g, reinterpret_cast<const unsigned char*>(a), strlen(a)); \\\n    yajl_gen_number(g, reinterpret_cast<const char*>(b), strlen(b));\n\n#define LOGFY_ADD_NUM(a, b) \\\n    yajl_gen_string(g, reinterpret_cast<const unsigned char*>(a), strlen(a)); \\\n    yajl_gen_integer(g, b);\n\n#ifdef __cplusplus\n\nnamespace modsecurity {\n\nclass ModSecurity;\nclass Transaction;\nclass RulesSet;\nclass RuleMessage;\nnamespace actions {\nclass Action;\nnamespace disruptive {\nenum AllowType : int;\n}\n}\nnamespace RequestBodyProcessor {\nclass XML;\nclass JSON;\nclass MultipartPartTmpFile;\n}\nnamespace operators {\nclass Operator;\n}\n\n\nclass TransactionAnchoredVariables {\n public:\n    explicit TransactionAnchoredVariables(Transaction *t)\n        : m_variableRequestHeadersNames(t, \"REQUEST_HEADERS_NAMES\"),\n        m_variableResponseContentType(t, \"RESPONSE_CONTENT_TYPE\"),\n        m_variableResponseHeadersNames(t, \"RESPONSE_HEADERS_NAMES\"),\n        m_variableARGScombinedSize(t, \"ARGS_COMBINED_SIZE\"),\n        m_variableAuthType(t, \"AUTH_TYPE\"),\n        m_variableFilesCombinedSize(t, \"FILES_COMBINED_SIZE\"),\n        m_variableFullRequest(t, \"FULL_REQUEST\"),\n        m_variableFullRequestLength(t, \"FULL_REQUEST_LENGTH\"),\n        m_variableInboundDataError(t, \"INBOUND_DATA_ERROR\"),\n        m_variableMatchedVar(t, \"MATCHED_VAR\"),\n        m_variableMatchedVarName(t, \"MATCHED_VAR_NAME\"),\n        m_variableMscPcreError(t, \"MSC_PCRE_ERROR\"),\n        m_variableMscPcreLimitsExceeded(t, \"MSC_PCRE_LIMITS_EXCEEDED\"),\n        m_variableMultipartBoundaryQuoted(t, \"MULTIPART_BOUNDARY_QUOTED\"),\n        m_variableMultipartBoundaryWhiteSpace(t,\n            \"MULTIPART_BOUNDARY_WHITESPACE\"),\n        m_variableMultipartCrlfLFLines(t, \"MULTIPART_CRLF_LF_LINES\"),\n        m_variableMultipartDataAfter(t, \"MULTIPART_DATA_AFTER\"),\n        m_variableMultipartDataBefore(t, \"MULTIPART_DATA_BEFORE\"),\n        m_variableMultipartFileLimitExceeded(t,\n            \"MULTIPART_FILE_LIMIT_EXCEEDED\"),\n        m_variableMultipartHeaderFolding(t, \"MULTIPART_HEADER_FOLDING\"),\n        m_variableMultipartInvalidHeaderFolding(t,\n            \"MULTIPART_INVALID_HEADER_FOLDING\"),\n        m_variableMultipartInvalidPart(t, \"MULTIPART_INVALID_PART\"),\n        m_variableMultipartInvalidQuoting(t, \"MULTIPART_INVALID_QUOTING\"),\n        m_variableMultipartLFLine(t, \"MULTIPART_LF_LINE\"),\n        m_variableMultipartMissingSemicolon(t, \"MULTIPART_MISSING_SEMICOLON\"),\n        m_variableMultipartStrictError(t, \"MULTIPART_STRICT_ERROR\"),\n        m_variableMultipartUnmatchedBoundary(t,\n            \"MULTIPART_UNMATCHED_BOUNDARY\"),\n        m_variableOutboundDataError(t, \"OUTBOUND_DATA_ERROR\"),\n        m_variablePathInfo(t, \"PATH_INFO\"),\n        m_variableQueryString(t, \"QUERY_STRING\"),\n        m_variableRemoteAddr(t, \"REMOTE_ADDR\"),\n        m_variableRemoteHost(t, \"REMOTE_HOST\"),\n        m_variableRemotePort(t, \"REMOTE_PORT\"),\n        m_variableReqbodyError(t, \"REQBODY_ERROR\"),\n        m_variableReqbodyErrorMsg(t, \"REQBODY_ERROR_MSG\"),\n        m_variableReqbodyProcessorError(t, \"REQBODY_PROCESSOR_ERROR\"),\n        m_variableReqbodyProcessorErrorMsg(t, \"REQBODY_PROCESSOR_ERROR_MSG\"),\n        m_variableReqbodyProcessor(t, \"REQBODY_PROCESSOR\"),\n        m_variableRequestBasename(t, \"REQUEST_BASENAME\"),\n        m_variableRequestBody(t, \"REQUEST_BODY\"),\n        m_variableRequestBodyLength(t, \"REQUEST_BODY_LENGTH\"),\n        m_variableRequestFilename(t, \"REQUEST_FILENAME\"),\n        m_variableRequestLine(t, \"REQUEST_LINE\"),\n        m_variableRequestMethod(t, \"REQUEST_METHOD\"),\n        m_variableRequestProtocol(t, \"REQUEST_PROTOCOL\"),\n        m_variableRequestURI(t, \"REQUEST_URI\"),\n        m_variableRequestURIRaw(t, \"REQUEST_URI_RAW\"),\n        m_variableResource(t, \"RESOURCE\"),\n        m_variableResponseBody(t, \"RESPONSE_BODY\"),\n        m_variableResponseContentLength(t, \"RESPONSE_CONTENT_LENGTH\"),\n        m_variableResponseProtocol(t, \"RESPONSE_PROTOCOL\"),\n        m_variableResponseStatus(t, \"RESPONSE_STATUS\"),\n        m_variableServerAddr(t, \"SERVER_ADDR\"),\n        m_variableServerName(t, \"SERVER_NAME\"),\n        m_variableServerPort(t, \"SERVER_PORT\"),\n        m_variableSessionID(t, \"SESSIONID\"),\n        m_variableUniqueID(t, \"UNIQUE_ID\"),\n        m_variableUrlEncodedError(t, \"URLENCODED_ERROR\"),\n        m_variableUserID(t, \"USERID\"),\n        m_variableArgs(t, \"ARGS\"),\n        m_variableArgsGet(t, \"ARGS_GET\"),\n        m_variableArgsPost(t, \"ARGS_POST\"),\n        m_variableFilesSizes(t, \"FILES_SIZES\"),\n        m_variableFilesNames(t, \"FILES_NAMES\"),\n        m_variableFilesTmpContent(t, \"FILES_TMP_CONTENT\"),\n        m_variableMultipartFileName(t, \"MULTIPART_FILENAME\"),\n        m_variableMultipartName(t, \"MULTIPART_NAME\"),\n        m_variableMatchedVarsNames(t, \"MATCHED_VARS_NAMES\"),\n        m_variableMatchedVars(t, \"MATCHED_VARS\"),\n        m_variableFiles(t, \"FILES\"),\n        m_variableRequestCookies(t, \"REQUEST_COOKIES\"),\n        m_variableRequestHeaders(t, \"REQUEST_HEADERS\"),\n        m_variableResponseHeaders(t, \"RESPONSE_HEADERS\"),\n        m_variableGeo(t, \"GEO\"),\n        m_variableRequestCookiesNames(t, \"REQUEST_COOKIES_NAMES\"),\n        m_variableFilesTmpNames(t, \"FILES_TMPNAMES\"),\n        m_variableMultipartPartHeaders(t, \"MULTIPART_PART_HEADERS\"),\n        m_variableOffset(0),\n        m_variableArgsNames(\"ARGS_NAMES\", &m_variableArgs),\n        m_variableArgsGetNames(\"ARGS_GET_NAMES\", &m_variableArgsGet),\n        m_variableArgsPostNames(\"ARGS_POST_NAMES\", &m_variableArgsPost)\n        { }\n\n    AnchoredSetVariable m_variableRequestHeadersNames;\n    AnchoredVariable m_variableResponseContentType;\n    AnchoredSetVariable m_variableResponseHeadersNames;\n    AnchoredVariable m_variableARGScombinedSize;\n    AnchoredVariable m_variableAuthType;\n    AnchoredVariable m_variableFilesCombinedSize;\n    AnchoredVariable m_variableFullRequest;\n    AnchoredVariable m_variableFullRequestLength;\n    AnchoredVariable m_variableInboundDataError;\n    AnchoredVariable m_variableMatchedVar;\n    AnchoredVariable m_variableMatchedVarName;\n    AnchoredVariable m_variableMscPcreError;\n    AnchoredVariable m_variableMscPcreLimitsExceeded;\n    AnchoredVariable m_variableMultipartBoundaryQuoted;\n    AnchoredVariable m_variableMultipartBoundaryWhiteSpace;\n    AnchoredVariable m_variableMultipartCrlfLFLines;\n    AnchoredVariable m_variableMultipartDataAfter;\n    AnchoredVariable m_variableMultipartDataBefore;\n    AnchoredVariable m_variableMultipartFileLimitExceeded;\n    AnchoredVariable m_variableMultipartHeaderFolding;\n    AnchoredVariable m_variableMultipartInvalidHeaderFolding;\n    AnchoredVariable m_variableMultipartInvalidPart;\n    AnchoredVariable m_variableMultipartInvalidQuoting;\n    AnchoredVariable m_variableMultipartLFLine;\n    AnchoredVariable m_variableMultipartMissingSemicolon;\n    AnchoredVariable m_variableMultipartStrictError;\n    AnchoredVariable m_variableMultipartUnmatchedBoundary;\n    AnchoredVariable m_variableOutboundDataError;\n    AnchoredVariable m_variablePathInfo;\n    AnchoredVariable m_variableQueryString;\n    AnchoredVariable m_variableRemoteAddr;\n    AnchoredVariable m_variableRemoteHost;\n    AnchoredVariable m_variableRemotePort;\n    AnchoredVariable m_variableReqbodyError;\n    AnchoredVariable m_variableReqbodyErrorMsg;\n    AnchoredVariable m_variableReqbodyProcessorError;\n    AnchoredVariable m_variableReqbodyProcessorErrorMsg;\n    AnchoredVariable m_variableReqbodyProcessor;\n    AnchoredVariable m_variableRequestBasename;\n    AnchoredVariable m_variableRequestBody;\n    AnchoredVariable m_variableRequestBodyLength;\n    AnchoredVariable m_variableRequestFilename;\n    AnchoredVariable m_variableRequestLine;\n    AnchoredVariable m_variableRequestMethod;\n    AnchoredVariable m_variableRequestProtocol;\n    AnchoredVariable m_variableRequestURI;\n    AnchoredVariable m_variableRequestURIRaw;\n    AnchoredVariable m_variableResource;\n    AnchoredVariable m_variableResponseBody;\n    AnchoredVariable m_variableResponseContentLength;\n    AnchoredVariable m_variableResponseProtocol;\n    AnchoredVariable m_variableResponseStatus;\n    AnchoredVariable m_variableServerAddr;\n    AnchoredVariable m_variableServerName;\n    AnchoredVariable m_variableServerPort;\n    AnchoredVariable m_variableSessionID;\n    AnchoredVariable m_variableUniqueID;\n    AnchoredVariable m_variableUrlEncodedError;\n    AnchoredVariable m_variableUserID;\n\n    AnchoredSetVariable m_variableArgs;\n    AnchoredSetVariable m_variableArgsGet;\n    AnchoredSetVariable m_variableArgsPost;\n    AnchoredSetVariable m_variableFilesSizes;\n    AnchoredSetVariable m_variableFilesNames;\n    AnchoredSetVariable m_variableFilesTmpContent;\n    AnchoredSetVariable m_variableMultipartFileName;\n    AnchoredSetVariable m_variableMultipartName;\n    AnchoredSetVariable m_variableMatchedVarsNames;\n    AnchoredSetVariable m_variableMatchedVars;\n    AnchoredSetVariable m_variableFiles;\n    AnchoredSetVariable m_variableRequestCookies;\n    AnchoredSetVariable m_variableRequestHeaders;\n    AnchoredSetVariable m_variableResponseHeaders;\n    AnchoredSetVariable m_variableGeo;\n    AnchoredSetVariable m_variableRequestCookiesNames;\n    AnchoredSetVariable m_variableFilesTmpNames;\n    AnchoredSetVariable m_variableMultipartPartHeaders;\n\n    int m_variableOffset;\n\n    AnchoredSetVariableTranslationProxy m_variableArgsNames;\n    AnchoredSetVariableTranslationProxy m_variableArgsGetNames;\n    AnchoredSetVariableTranslationProxy m_variableArgsPostNames;\n};\n\nclass TransactionSecMarkerManagement {\n public:\n    bool isInsideAMarker() const {\n        if (m_marker) {\n            return true;\n        }\n\n        return false;\n    }\n\n    std::shared_ptr<std::string> getCurrentMarker() const {\n        assert((m_marker != nullptr) && \"You might have forgotten to call and evaluate isInsideAMarker() before calling getCurrentMarker().\");\n        return m_marker;\n    }\n\n    void removeMarker() {\n        m_marker.reset();\n    }\n\n    void addMarker(const std::shared_ptr<std::string> &name) {\n        m_marker = name;\n    }\n\n private:\n    std::shared_ptr<std::string> m_marker;\n};\n\n/** @ingroup ModSecurity_CPP_API */\nclass Transaction : public TransactionAnchoredVariables, public TransactionSecMarkerManagement {\n public:\n    Transaction(ModSecurity *ms, RulesSet *rules, void *logCbData);\n    Transaction(ModSecurity *ms, RulesSet *rules, const char *id,\n        void *logCbData);\n    ~Transaction();\n\n    Transaction ( const Transaction & ) = delete;\n    bool operator ==(const Transaction &b) const { return false; };\n    Transaction &operator =(const Transaction &b) const = delete;\n\n    /** TODO: Should be an structure that fits an IP address */\n    int processConnection(const char *client, int cPort,\n        const char *server, int sPort);\n    int processURI(const char *uri, const char *protocol,\n        const char *http_version);\n\n    /**\n     * Types of request body that ModSecurity may give a special treatment\n     * for the data.\n     */\n    enum RequestBodyType {\n      /**\n       *\n       */\n      UnknownFormat,\n      /**\n       *\n       */\n      MultiPartRequestBody,\n      /**\n       *\n       */\n      WWWFormUrlEncoded,\n      /**\n       *\n       */\n      JSONRequestBody,\n      /**\n       *\n       */\n      XMLRequestBody\n    };\n\n    int processRequestHeaders();\n    int addRequestHeader(const std::string& key, const std::string& value);\n    int addRequestHeader(const unsigned char *key, const unsigned char *value);\n    int addRequestHeader(const unsigned char *key, size_t len_key,\n        const unsigned char *value, size_t len_value);\n\n    int processRequestBody();\n    int appendRequestBody(const unsigned char *body, size_t size);\n    int requestBodyFromFile(const char *path);\n\n    int processResponseHeaders(int code, const std::string& proto);\n    int addResponseHeader(const std::string& key, const std::string& value);\n    int addResponseHeader(const unsigned char *key, const unsigned char *value);\n    int addResponseHeader(const unsigned char *key, size_t len_key,\n        const unsigned char *value, size_t len_value);\n\n    int processResponseBody();\n    int appendResponseBody(const unsigned char *body, size_t size);\n\n    int processLogging();\n    int updateStatusCode(int status);\n\n    int setRequestHostName(const std::string& hostname);\n\n    bool intervention(ModSecurityIntervention *it);\n\n    bool addArgument(const std::string& orig, const std::string& key,\n        const std::string& value, size_t offset);\n    bool extractArguments(const std::string &orig, const std::string& buf,\n        size_t offset);\n\n    const char *getResponseBody() const;\n    size_t getResponseBodyLength();\n    size_t getRequestBodyLength();\n\n#ifndef NO_LOGS\n    void debug(int, const std::string &) const;\n#endif\n    void serverLog(const RuleMessage &rm);\n\n    int getRuleEngineState() const;\n\n    std::string toJSON(int parts);\n    std::string toOldAuditLogFormat(int parts, const std::string &trailer, const std::string &header);\n    std::string toOldAuditLogFormatIndex(const std::string &filename,\n        double size, const std::string &md5);\n\n    /**\n     * Filled during the class instantiation, this variable can be later\n     * used to fill the SecRule variable `duration'. The variable `duration'\n     * is dynamic calculated, it is always relative to the value found in\n     * m_creationTimeStamp.\n     *\n     * @note There is space for performance improvement. This value don't\n\t *       need to be filled if there is no rule using the variable\n\t *       `duration'.\n     */\n    const clock_t m_creationTimeStamp;\n\n    /**\n     * Holds the client IP address.\n     */\n    std::string m_clientIpAddress;\n\n    /**\n     * Holds the HTTP version: 1.2, 2.0, 3.0 and so on....\n     */\n    std::string m_httpVersion;\n\n    /**\n     * Holds the server IP Address\n     */\n    std::string m_serverIpAddress;\n\n    /**\n     * Holds the request's hostname\n     */\n    std::string m_requestHostName;\n\n    /**\n     * Holds the raw URI that was requested.\n     */\n    std::string m_uri;\n\n    /**\n     * Holds the URI that was requests (without the query string).\n     */\n    std::string m_uri_no_query_string_decoded;\n\n    /**\n     * Holds the combined size of all arguments, later used to fill the\n     * variable  ARGS_COMBINED_SIZE.\n     */\n    double m_ARGScombinedSizeDouble;\n\n    /**\n     * Client tcp port.\n     */\n    int m_clientPort;\n\n    /**\n     * This variable is set by the action `severity' and later can be\n     * consulted via the SecLanguage variable HIGHEST_SEVERITY.\n     */\n    int m_highestSeverityAction;\n\n    /**\n     * Holds the HTTP return code when it is known. If 0 nothing was\n\t * set.\n     */\n    int m_httpCodeReturned;\n\n    /**\n     * Holds the server port.\n     */\n    int m_serverPort;\n\n    /**\n     * ModSecurity instance used to start this transaction. Basically used\n     * to fill the server log whenever is needed.\n     */\n    ModSecurity *m_ms;\n\n    /**\n     * Holds the type of the request body, in case there is one.\n     */\n    RequestBodyType m_requestBodyType;\n\n    /**\n     * Holds the request body \"processor\"\n     */\n    RequestBodyType m_requestBodyProcessor;\n\n    /**\n     * Rules object utilized during this specific transaction.\n     */\n    RulesSet * const m_rules;\n\n    /**\n     *\n     */\n    std::list<int > m_ruleRemoveById;\n    std::list<std::pair<int, int> > m_ruleRemoveByIdRange;\n\n    /**\n     *\n     */\n    std::list<std::string> m_ruleRemoveByTag;\n\n    /**\n     *\n     */\n    std::list< std::pair<std::string, std::string> > m_ruleRemoveTargetByTag;\n\n    /**\n     *\n     */\n    std::list< std::pair<int, std::string> > m_ruleRemoveTargetById;\n\n    /**\n     *\n     */\n    int m_requestBodyAccess;\n\n    /**\n     * The list m_auditLogModifier contains modifications to the `auditlogs'\n     * for this specific request, those modifications can happens via the\n     * utilization of the action: `ctl:auditLogParts='\n     *\n     */\n    std::list< std::pair<int, std::string> > m_auditLogModifier;\n\n    /**\n     * This transaction's most recent action ctl:auditEngine\n     *\n     */\n    audit_log::AuditLog::AuditLogStatus m_ctlAuditEngine;\n\n    /**\n     * This variable holds all the messages asked to be save by the utilization\n     * of the actions: `log_data' and `msg'. These should be included on the\n     * auditlogs.\n     */\n    std::list<modsecurity::RuleMessage> m_rulesMessages;\n\n    /**\n     * Holds the request body, in case of any.\n     */\n    std::ostringstream m_requestBody;\n\n    /**\n     * Holds the response body, in case of any.\n     */\n    std::ostringstream m_responseBody;\n\n    /**\n     * Contains the unique ID of the transaction. Use by the variable\n\t * `UNIQUE_ID'. This unique id is also saved as part of the AuditLog.\n     */\n    const std::string m_id;\n\n    /**\n     * Holds the amount of rules that should be skipped. If bigger than 0 the\n     * current rule should be skipped and the number needs to be decreased.\n     */\n    int m_skip_next;\n\n    /**\n     * If allow action was utilized, this variable holds the allow type.\n     */\n    modsecurity::actions::disruptive::AllowType m_allowType;\n\n    /**\n     * Holds the decode URI. Notice that m_uri holds the raw version\n     * of the URI.\n     */\n    std::string m_uri_decoded;\n\n    /**\n     * Actions (disruptive?) that should be taken by the connector related to\n     * that transaction.\n     */\n    std::vector<ModSecurityIntervention> m_actions;\n    ModSecurityIntervention m_it;\n\n    /**\n     * Holds the creation time stamp, using std::time.\n     *\n     * TODO: m_timeStamp and m_creationTimeStamp may be merged into a single\n     *       variable.\n     */\n    const time_t m_timeStamp;\n\n\n    /**\n     * Holds all the collections related to that transaction.\n     */\n    collection::Collections m_collections;\n\n    /**\n     * Holds the whatever matched in the operation utilization.\n     * That variable will be further used by the capture action.\n     *\n     */\n    std::list<std::string> m_matched;\n\n    RequestBodyProcessor::XML *m_xml;\n    RequestBodyProcessor::JSON *m_json;\n\n    int m_secRuleEngine;\n    int m_secXMLParseXmlIntoArgs;\n\n    std::string m_variableDuration;\n    std::map<std::string, std::string> m_variableEnvs;\n    std::string m_variableHighestSeverityAction;\n    std::string m_variableRemoteUser;\n    std::string m_variableTime;\n    std::string m_variableTimeDay;\n    std::string m_variableTimeEpoch;\n    std::string m_variableTimeHour;\n    std::string m_variableTimeMin;\n    std::string m_variableTimeSec;\n    std::string m_variableTimeWDay;\n    std::string m_variableTimeYear;\n\n    std::vector<std::shared_ptr<RequestBodyProcessor::MultipartPartTmpFile>> m_multipartPartTmpFiles;\n\n private:\n\n    Transaction(ModSecurity *ms, RulesSet *rules, const char *id,\n        void *logCbData, const time_t timestamp);\n\n    /**\n     * Pointer to the callback function that will be called to fill\n     * the web server (connector) log.\n     */\n    void *m_logCbData;\n};\n\n\n#endif\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n/** @ingroup ModSecurity_C_API */\nTransaction *msc_new_transaction(ModSecurity *ms,\n    RulesSet *rules, void *logCbData);\n\n/** @ingroup ModSecurity_C_API */\nTransaction *msc_new_transaction_with_id(ModSecurity *ms,\n    RulesSet *rules, const char *id, void *logCbData);\n\n/** @ingroup ModSecurity_C_API */\nint msc_process_connection(Transaction *transaction,\n    const char *client, int cPort, const char *server, int sPort);\n\n/** @ingroup ModSecurity_C_API */\nint msc_process_request_headers(Transaction *transaction);\n\n/** @ingroup ModSecurity_C_API */\nint msc_add_request_header(Transaction *transaction, const unsigned char *key,\n    const unsigned char *value);\n\n/** @ingroup ModSecurity_C_API */\nint msc_add_n_request_header(Transaction *transaction,\n    const unsigned char *key, size_t len_key, const unsigned char *value,\n    size_t len_value);\n\n/** @ingroup ModSecurity_C_API */\nint msc_process_request_body(Transaction *transaction);\n\n/** @ingroup ModSecurity_C_API */\nint msc_append_request_body(Transaction *transaction,\n    const unsigned char *body, size_t size);\n\n/** @ingroup ModSecurity_C_API */\nint msc_request_body_from_file(Transaction *transaction, const char *path);\n\n/** @ingroup ModSecurity_C_API */\nint msc_process_response_headers(Transaction *transaction, int code,\n    const char* protocol);\n\n/** @ingroup ModSecurity_C_API */\nint msc_add_response_header(Transaction *transaction,\n    const unsigned char *key, const unsigned char *value);\n\n/** @ingroup ModSecurity_C_API */\nint msc_add_n_response_header(Transaction *transaction,\n    const unsigned char *key, size_t len_key, const unsigned char *value,\n    size_t len_value);\n\n/** @ingroup ModSecurity_C_API */\nint msc_process_response_body(Transaction *transaction);\n\n/** @ingroup ModSecurity_C_API */\nint msc_append_response_body(Transaction *transaction,\n    const unsigned char *body, size_t size);\n\n/** @ingroup ModSecurity_C_API */\nint msc_process_uri(Transaction *transaction, const char *uri,\n    const char *protocol, const char *http_version);\n\n/** @ingroup ModSecurity_C_API */\nconst char *msc_get_response_body(const Transaction *transaction);\n\n/** @ingroup ModSecurity_C_API */\nsize_t msc_get_response_body_length(Transaction *transaction);\n\n/** @ingroup ModSecurity_C_API */\nsize_t msc_get_request_body_length(Transaction *transaction);\n\n/** @ingroup ModSecurity_C_API */\nvoid msc_transaction_cleanup(Transaction *transaction);\n\n/** @ingroup ModSecurity_C_API */\nint msc_intervention(Transaction *transaction, ModSecurityIntervention *it);\n\n/** @ingroup ModSecurity_C_API */\nvoid msc_intervention_cleanup(ModSecurityIntervention *it);\n\n/** @ingroup ModSecurity_C_API */\nint msc_process_logging(Transaction *transaction);\n\n/** @ingroup ModSecurity_C_API */\nint msc_update_status_code(Transaction *transaction, int status);\n\n/** @ingroup ModSecurity_C_API */\nint msc_set_request_hostname(Transaction *transaction, const unsigned char *hostname);\n\n#ifdef __cplusplus\n}\n}  // namespace modsecurity\n#endif\n\n\n#endif  // HEADERS_MODSECURITY_TRANSACTION_H_\n"
  },
  {
    "path": "headers/modsecurity/variable_origin.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#ifdef __cplusplus\n#include <string>\n#include <memory>\n#endif\n\n#ifndef HEADERS_MODSECURITY_VARIABLE_ORIGIN_H_\n#define HEADERS_MODSECURITY_VARIABLE_ORIGIN_H_\n\n\n#ifndef __cplusplus\ntypedef struct DebugLog_t DebugLog;\n#endif\n\n#ifdef __cplusplus\n\nnamespace modsecurity {\n\n\n/** @ingroup ModSecurity_CPP_API */\nclass VariableOrigin {\n public:\n    VariableOrigin()\n        : m_length(0),\n        m_offset(0) { }\n    VariableOrigin(size_t length, size_t offset)\n        : m_length(length),\n        m_offset(offset) { } \n\n    std::string toText() const {\n        const auto offset = std::to_string(m_offset);\n        const auto len = std::to_string(m_length);\n        return \"v\" + offset + \",\" + len;\n    }\n\n    size_t m_length;\n    size_t m_offset;\n};\n\n\n}  // namespace modsecurity\n#endif\n\n#endif  // HEADERS_MODSECURITY_VARIABLE_ORIGIN_H_\n\n\n"
  },
  {
    "path": "headers/modsecurity/variable_value.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2023 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n\n#ifdef __cplusplus\n#include <string>\n#include <iostream>\n#include <memory>\n#include <vector>\n#include <utility>\n#endif\n\n#include \"modsecurity/variable_origin.h\"\n\n#ifndef HEADERS_MODSECURITY_VARIABLE_VALUE_H_\n#define HEADERS_MODSECURITY_VARIABLE_VALUE_H_\n\n#ifndef __cplusplus\ntypedef struct Variable_t VariableValue;\n#endif\n\n#ifdef __cplusplus\nnamespace modsecurity {\n\nclass Collection;\nclass VariableValue {\n public:\n    using Origins = std::vector<VariableOrigin>;\n\n    explicit VariableValue(const std::string *key,\n        const std::string *value = nullptr)\n        : m_collection(\"\"),\n        m_key(*key),\n        m_keyWithCollection(*key),\n        m_value(value != nullptr?*value:\"\")\n    { }\n\n    VariableValue(const std::string *collection,\n        const std::string *key,\n        const std::string *value)\n        : m_collection(*collection),\n        m_key(*key),\n        m_keyWithCollection(*collection + \":\" + *key),\n        m_value(*value)\n    { }\n\n    explicit VariableValue(const VariableValue *o) :\n        m_collection(o->m_collection),\n        m_key(o->m_key),\n        m_keyWithCollection(o->m_keyWithCollection),\n        m_value(o->m_value)\n    {\n        reserveOrigin(o->m_orign.size());\n        for (const auto &i : o->m_orign) {\n            addOrigin(i);\n        }\n    }\n\n    VariableValue(const VariableValue &v) = delete;\n\n\n    const std::string& getKey() const {\n        return m_key;\n    }\n\n\n    const std::string& getKeyWithCollection() const {\n        return m_keyWithCollection;\n    }\n\n\n    const std::string& getCollection() const {\n        return m_collection;\n    }\n\n\n    const std::string& getValue() const {\n        return m_value;\n    }\n\n\n    void setValue(const std::string &value) {\n        m_value = value;\n    }\n\n\n    void addOrigin(const VariableOrigin &origin) {\n        m_orign.emplace_back(origin);\n    }\n\n\n    template<typename... Args>\n    void addOrigin(Args&&... args) {\n        m_orign.emplace_back(args...);\n    }\n\n\n    const Origins& getOrigin() const {\n        return m_orign;\n    }\n\n\n    void reserveOrigin(Origins::size_type additionalSize) {\n        m_orign.reserve(m_orign.size() + additionalSize);\n    }\n\n\n private:\n    Origins m_orign;\n    std::string m_collection;\n    std::string m_key;\n    std::string m_keyWithCollection;\n    std::string m_value;\n};\n\n}  // namespace modsecurity\n#endif\n\n#endif  // HEADERS_MODSECURITY_VARIABLE_VALUE_H_\n"
  },
  {
    "path": "modsecurity.conf-recommended",
    "content": "# -- Rule engine initialization ----------------------------------------------\n\n# Enable ModSecurity, attaching it to every transaction. Use detection\n# only to start with, because that minimises the chances of post-installation\n# disruption.\n#\nSecRuleEngine DetectionOnly\n\n\n# -- Request body handling ---------------------------------------------------\n\n# Allow ModSecurity to access request bodies. If you don't, ModSecurity\n# won't be able to see any POST parameters, which opens a large security\n# hole for attackers to exploit.\n#\nSecRequestBodyAccess On\n\n\n# Enable XML request body parser.\n# Initiate XML Processor in case of xml content-type\n#\nSecRule REQUEST_HEADERS:Content-Type \"^(?:application(?:/soap\\+|/)|text/)xml\" \\\n     \"id:'200000',phase:1,t:none,t:lowercase,pass,nolog,ctl:requestBodyProcessor=XML\"\n\n# Enable JSON request body parser.\n# Initiate JSON Processor in case of JSON content-type; change accordingly\n# if your application does not use 'application/json'\n#\nSecRule REQUEST_HEADERS:Content-Type \"^application/json\" \\\n     \"id:'200001',phase:1,t:none,t:lowercase,pass,nolog,ctl:requestBodyProcessor=JSON\"\n\n# Sample rule to enable JSON request body parser for more subtypes.\n# Uncomment or adapt this rule if you want to engage the JSON\n# Processor for \"+json\" subtypes\n#\n#SecRule REQUEST_HEADERS:Content-Type \"^application/[a-z0-9.-]+[+]json\" \\\n#     \"id:'200006',phase:1,t:none,t:lowercase,pass,nolog,ctl:requestBodyProcessor=JSON\"\n\n# Maximum request body size we will accept for buffering. If you support\n# file uploads then the value given on the first line has to be as large\n# as the largest file you are willing to accept. The second value refers\n# to the size of data, with files excluded. You want to keep that value as\n# low as practical.\n#\nSecRequestBodyLimit 13107200\nSecRequestBodyNoFilesLimit 131072\n\n# What to do if the request body size is above our configured limit.\n# Keep in mind that this setting will automatically be set to ProcessPartial\n# when SecRuleEngine is set to DetectionOnly mode in order to minimize\n# disruptions when initially deploying ModSecurity.\n#\nSecRequestBodyLimitAction Reject\n\n# Maximum parsing depth allowed for JSON objects. You want to keep this\n# value as low as practical.\n#\nSecRequestBodyJsonDepthLimit 512\n\n# Maximum number of args allowed per request. You want to keep this\n# value as low as practical. The value should match that in rule 200007.\nSecArgumentsLimit 1000\n\n# If SecArgumentsLimit has been set, you probably want to reject any\n# request body that has only been partly parsed. The value used in this\n# rule should match what was used with SecArgumentsLimit\nSecRule &ARGS \"@ge 1000\" \\\n\"id:'200007', phase:2,t:none,log,deny,status:400,msg:'Failed to fully parse request body due to large argument count',severity:2\"\n\n# Verify that we've correctly processed the request body.\n# As a rule of thumb, when failing to process a request body\n# you should reject the request (when deployed in blocking mode)\n# or log a high-severity alert (when deployed in detection-only mode).\n#\nSecRule REQBODY_ERROR \"!@eq 0\" \\\n\"id:'200002', phase:2,t:none,log,deny,status:400,msg:'Failed to parse request body.',logdata:'%{reqbody_error_msg}',severity:2\"\n\n# By default be strict with what we accept in the multipart/form-data\n# request body. If the rule below proves to be too strict for your\n# environment consider changing it to detection-only. You are encouraged\n# _not_ to remove it altogether.\n#\nSecRule MULTIPART_STRICT_ERROR \"!@eq 0\" \\\n\"id:'200003',phase:2,t:none,log,deny,status:400, \\\nmsg:'Multipart request body failed strict validation: \\\nPE %{REQBODY_PROCESSOR_ERROR}, \\\nBQ %{MULTIPART_BOUNDARY_QUOTED}, \\\nBW %{MULTIPART_BOUNDARY_WHITESPACE}, \\\nDB %{MULTIPART_DATA_BEFORE}, \\\nDA %{MULTIPART_DATA_AFTER}, \\\nHF %{MULTIPART_HEADER_FOLDING}, \\\nLF %{MULTIPART_LF_LINE}, \\\nSM %{MULTIPART_MISSING_SEMICOLON}, \\\nIQ %{MULTIPART_INVALID_QUOTING}, \\\nIP %{MULTIPART_INVALID_PART}, \\\nIH %{MULTIPART_INVALID_HEADER_FOLDING}, \\\nFL %{MULTIPART_FILE_LIMIT_EXCEEDED}'\"\n\n# Did we see anything that might be a boundary?\n#\n# Here is a short description about the ModSecurity Multipart parser: the\n# parser returns with value 0, if all \"boundary-like\" line matches with\n# the boundary string which given in MIME header. In any other cases it returns\n# with different value, eg. 1 or 2.\n#\n# The RFC 1341 descript the multipart content-type and its syntax must contains\n# only three mandatory lines (above the content):\n# * Content-Type: multipart/mixed; boundary=BOUNDARY_STRING\n# * --BOUNDARY_STRING\n# * --BOUNDARY_STRING--\n#\n# First line indicates, that this is a multipart content, second shows that\n# here starts a part of the multipart content, third shows the end of content.\n#\n# If there are any other lines, which starts with \"--\", then it should be\n# another boundary id - or not.\n#\n# After 3.0.3, there are two kinds of types of boundary errors: strict and permissive.\n#\n# If multipart content contains the three necessary lines with correct order, but\n# there are one or more lines with \"--\", then parser returns with value 2 (non-zero).\n#\n# If some of the necessary lines (usually the start or end) misses, or the order\n# is wrong, then parser returns with value 1 (also a non-zero).\n#\n# You can choose, which one is what you need. The example below contains the\n# 'strict' mode, which means if there are any lines with start of \"--\", then\n# ModSecurity blocked the content. But the next, commented example contains\n# the 'permissive' mode, then you check only if the necessary lines exists in\n# correct order. Whit this, you can enable to upload PEM files (eg \"----BEGIN..\"),\n# or other text files, which contains eg. HTTP headers.\n#\n# The difference is only the operator - in strict mode (first) the content blocked\n# in case of any non-zero value. In permissive mode (second, commented) the\n# content blocked only if the value is explicit 1. If it 0 or 2, the content will\n# allowed.\n#\n\n#\n# See #1747 and #1924 for further information on the possible values for\n# MULTIPART_UNMATCHED_BOUNDARY.\n#\nSecRule MULTIPART_UNMATCHED_BOUNDARY \"@eq 1\" \\\n    \"id:'200004',phase:2,t:none,log,deny,msg:'Multipart parser detected a possible unmatched boundary.'\"\n\n\n# PCRE Tuning\n# We want to avoid a potential RegEx DoS condition\n#\nSecPcreMatchLimit 1000\nSecPcreMatchLimitRecursion 1000\n\n# Some internal errors will set flags in TX and we will need to look for these.\n# All of these are prefixed with \"MSC_\".  The following flags currently exist:\n#\n# MSC_PCRE_LIMITS_EXCEEDED: PCRE match limits were exceeded.\n#\nSecRule TX:/^MSC_/ \"!@streq 0\" \\\n    \"id:'200005',phase:2,t:none,log,deny,msg:'ModSecurity internal error flagged: %{MATCHED_VAR_NAME}'\"\n\n\n# -- Response body handling --------------------------------------------------\n\n# Allow ModSecurity to access response bodies. \n# You should have this directive enabled in order to identify errors\n# and data leakage issues.\n# \n# Do keep in mind that enabling this directive does increases both\n# memory consumption and response latency.\n#\nSecResponseBodyAccess On\n\n# Which response MIME types do you want to inspect? You should adjust the\n# configuration below to catch documents but avoid static files\n# (e.g., images and archives).\n#\nSecResponseBodyMimeType text/plain text/html text/xml\n\n# Buffer response bodies of up to 512 KB in length.\nSecResponseBodyLimit 524288\n\n# What happens when we encounter a response body larger than the configured\n# limit? By default, we process what we have and let the rest through.\n# That's somewhat less secure, but does not break any legitimate pages.\n#\nSecResponseBodyLimitAction ProcessPartial\n\n\n# -- Filesystem configuration ------------------------------------------------\n\n# The location where ModSecurity stores temporary files (for example, when\n# it needs to handle a file upload that is larger than the configured limit).\n# \n# This default setting is chosen due to all systems have /tmp available however, \n# this is less than ideal. It is recommended that you specify a location that's private.\n#\nSecTmpDir /tmp/\n\n# The location where ModSecurity will keep its persistent data.  This default setting \n# is chosen due to all systems have /tmp available however, it\n# too should be updated to a place that other users can't access.\n#\nSecDataDir /tmp/\n\n\n# -- File uploads handling configuration -------------------------------------\n\n# The location where ModSecurity stores intercepted uploaded files. This\n# location must be private to ModSecurity. You don't want other users on\n# the server to access the files, do you?\n#\n#SecUploadDir /opt/modsecurity/var/upload/\n\n# By default, only keep the files that were determined to be unusual\n# in some way (by an external inspection script). For this to work you\n# will also need at least one file inspection rule.\n#\n#SecUploadKeepFiles RelevantOnly\n\n# Uploaded files are by default created with permissions that do not allow\n# any other user to access them. You may need to relax that if you want to\n# interface ModSecurity to an external program (e.g., an anti-virus).\n#\n#SecUploadFileMode 0600\n\n\n# -- Debug log configuration -------------------------------------------------\n\n# The default debug log configuration is to duplicate the error, warning\n# and notice messages from the error log.\n#\n#SecDebugLog /opt/modsecurity/var/log/debug.log\n#SecDebugLogLevel 3\n\n\n# -- Audit log configuration -------------------------------------------------\n\n# Log the transactions that are marked by a rule, as well as those that\n# trigger a server error (determined by a 5xx or 4xx, excluding 404,  \n# level response status codes).\n#\nSecAuditEngine RelevantOnly\nSecAuditLogRelevantStatus \"^(?:5|4(?!04))\"\n\n# Log everything we know about a transaction.\nSecAuditLogParts ABIJDEFHZ\n\n# Use a single file for logging. This is much easier to look at, but\n# assumes that you will use the audit log only ocassionally.\n#\nSecAuditLogType Serial\nSecAuditLog /var/log/modsec_audit.log\n\n# Specify the path for concurrent audit logging.\n#SecAuditLogStorageDir /opt/modsecurity/var/audit/\n\n\n# -- Miscellaneous -----------------------------------------------------------\n\n# Use the most commonly used application/x-www-form-urlencoded parameter\n# separator. There's probably only one application somewhere that uses\n# something else so don't expect to change this value.\n#\nSecArgumentSeparator &\n\n# Settle on version 0 (zero) cookies, as that is what most applications\n# use. Using an incorrect cookie version may open your installation to\n# evasion attacks (against the rules that examine named cookies).\n#\nSecCookieFormat 0\n\n# Specify your Unicode Code Point.\n# This mapping is used by the t:urlDecodeUni transformation function\n# to properly map encoded data to your language. Properly setting\n# these directives helps to reduce false positives and negatives.\n#\nSecUnicodeMapFile unicode.mapping 20127\n\n# Improve the quality of ModSecurity by sharing information about your\n# current ModSecurity version and dependencies versions.\n# The following information will be shared: ModSecurity version,\n# Web Server version, APR version, PCRE version, Lua version, Libxml2\n# version, Anonymous unique id for host.\n# NB: As of April 2022, there is no longer any advantage to turning this\n# setting On, as there is no active receiver for the information.\nSecStatusEngine Off\n\n"
  },
  {
    "path": "modsecurity.pc.in",
    "content": "prefix=@prefix@\nexec_prefix=@exec_prefix@\nlibdir=@libdir@\nincludedir=@includedir@\n\nName: ModSecurity\nDescription: ModSecurity API\nVersion: @MSC_VERSION_WITH_PATCHLEVEL@\nCflags: -I@includedir@\nLibs: -L@libdir@ -lmodsecurity\nLibs.private: @CURL_LDADD@ @GEOIP_LDADD@ @MAXMIND_LDADD@ @GLOBAL_LDADD@ @LIBXML2_LDADD@ @LMDB_LDADD@ @LUA_LDADD@ @PCRE_LDADD@ @PCRE2_LDADD@ @SSDEEP_LDADD@ @YAJL_LDADD@\n"
  },
  {
    "path": "others/Makefile.am",
    "content": "\nnoinst_LTLIBRARIES = libinjection.la libmbedtls.la\n\nlibinjection_la_SOURCES = \\\n\tlibinjection/src/libinjection_html5.c \\\n\tlibinjection/src/libinjection_sqli.c \\\n\tlibinjection/src/libinjection_xss.c\n\nlibinjection_la_CFLAGS = -D LIBINJECTION_VERSION=\\\"${LIBINJECTION_VERSION}\\\"\nlibinjection_la_LIBADD =\n\nnoinst_HEADERS = \\\n\tlibinjection/src/libinjection.h \\\n\tlibinjection/src/libinjection_html5.h \\\n\tlibinjection/src/libinjection_sqli.h \\\n\tlibinjection/src/libinjection_sqli_data.h \\\n\tlibinjection/src/libinjection_xss.h \\\n\tmbedtls/include/mbedtls/base64.h \\\n\tmbedtls/include/mbedtls/check_config.h \\\n\tmbedtls/include/mbedtls/mbedtls_config.h \\\n\tmbedtls/include/mbedtls/md5.h \\\n\tmbedtls/include/mbedtls/platform.h \\\n\tmbedtls/include/mbedtls/sha1.h\n\nlibmbedtls_la_SOURCES = \\\n\tmbedtls/library/base64.c \\\n\tmbedtls/library/md5.c \\\n\tmbedtls/library/sha1.c \\\n\tmbedtls/library/platform_util.c\n\nlibmbedtls_la_CFLAGS = -DMBEDTLS_CONFIG_FILE=\\\"mbedtls/mbedtls_config.h\\\" -I$(top_srcdir)/others/mbedtls/include\nlibmbedtls_la_CPPFLAGS =\nlibmbedtls_la_LIBADD =\n"
  },
  {
    "path": "src/Makefile.am",
    "content": "\nif BUILD_PARSER\nexport MAYBE_PARSER = parser\nendif\n\n\nSUBDIRS = \\\n\t$(MAYBE_PARSER)\n\n\nlib_LTLIBRARIES = libmodsecurity.la\nlibmodsecurity_ladir = $(prefix)/include\nlibmodsecurity_includesub_collectiondir = $(pkgincludedir)/collection/\nlibmodsecurity_includesub_actionsdir = $(pkgincludedir)/actions/\n\n\n# pregenerated parser + parser sources\nEXTRA_DIST = \\\n\tparser/Makefile.am \\\n\tparser/Makefile.in \\\n\tparser/location.hh \\\n\tparser/position.hh \\\n\tparser/seclang-parser.cc \\\n\tparser/seclang-parser.hh \\\n\tparser/seclang-parser.yy \\\n\tparser/seclang-scanner.cc \\\n\tparser/seclang-scanner.ll \\\n\tparser/stack.hh\n\n\nMAINTAINERCLEANFILES = \\\n\tMakefile.in \\\n\tconfig.h.in \\\n\tconfig.h.in~\n\n\npkginclude_HEADERS = \\\n\t../headers/modsecurity/anchored_set_variable_translation_proxy.h \\\n\t../headers/modsecurity/anchored_set_variable.h \\\n\t../headers/modsecurity/anchored_variable.h \\\n\t../headers/modsecurity/audit_log.h \\\n\t../headers/modsecurity/debug_log.h \\\n\t../headers/modsecurity/intervention.h \\\n\t../headers/modsecurity/modsecurity.h \\\n\t../headers/modsecurity/rule.h \\\n\t../headers/modsecurity/rule_marker.h \\\n\t../headers/modsecurity/rule_unconditional.h \\\n\t../headers/modsecurity/rule_with_actions.h \\\n\t../headers/modsecurity/rule_with_operator.h \\\n\t../headers/modsecurity/rules.h \\\n\t../headers/modsecurity/rule_message.h \\\n\t../headers/modsecurity/rules_set.h \\\n\t../headers/modsecurity/rules_set_phases.h \\\n\t../headers/modsecurity/rules_set_properties.h \\\n\t../headers/modsecurity/rules_exceptions.h \\\n\t../headers/modsecurity/transaction.h \\\n\t../headers/modsecurity/variable_origin.h \\\n\t../headers/modsecurity/variable_value.h\n\n\nlibmodsecurity_includesub_collection_HEADERS = \\\n\t../headers/modsecurity/collection/collection.h \\\n\t../headers/modsecurity/collection/collections.h\n\n\nlibmodsecurity_includesub_actions_HEADERS = \\\n\t../headers/modsecurity/actions/action.h\n\ninclude headers.mk\n\nENGINES = \\\n\tengine/lua.cc\n\n\nVARIABLES = \\\n\tvariables/duration.cc \\\n\tvariables/env.cc \\\n\tvariables/highest_severity.cc \\\n\tvariables/modsec_build.cc \\\n\tvariables/remote_user.cc \\\n\tvariables/rule.cc \\\n\tvariables/time.cc \\\n\tvariables/time_day.cc \\\n\tvariables/time_epoch.cc \\\n\tvariables/time_hour.cc \\\n\tvariables/time_min.cc \\\n\tvariables/time_mon.cc \\\n\tvariables/time_sec.cc \\\n\tvariables/time_wday.cc \\\n\tvariables/time_year.cc \\\n\tvariables/tx.cc \\\n\tvariables/variable.cc \\\n\tvariables/xml.cc\n\n\nACTIONS = \\\n\tactions/accuracy.cc \\\n\tactions/action.cc \\\n\tactions/audit_log.cc \\\n\tactions/block.cc \\\n\tactions/capture.cc \\\n\tactions/chain.cc \\\n\tactions/ctl/audit_log_parts.cc \\\n\tactions/ctl/audit_engine.cc \\\n\tactions/ctl/parse_xml_into_args.cc \\\n\tactions/ctl/rule_engine.cc \\\n\tactions/ctl/request_body_processor_json.cc \\\n\tactions/ctl/request_body_processor_xml.cc \\\n\tactions/ctl/request_body_processor_urlencoded.cc \\\n\tactions/ctl/rule_remove_target_by_tag.cc \\\n\tactions/ctl/rule_remove_target_by_id.cc \\\n\tactions/ctl/rule_remove_by_id.cc \\\n\tactions/ctl/rule_remove_by_tag.cc \\\n\tactions/ctl/request_body_access.cc\\\n\tactions/disruptive/allow.cc \\\n\tactions/disruptive/deny.cc \\\n\tactions/disruptive/drop.cc \\\n\tactions/disruptive/redirect.cc \\\n\tactions/disruptive/pass.cc \\\n\tactions/exec.cc \\\n\tactions/expire_var.cc \\\n\tactions/init_col.cc \\\n\tactions/log.cc \\\n\tactions/log_data.cc \\\n\tactions/maturity.cc \\\n\tactions/msg.cc \\\n\tactions/multi_match.cc \\\n\tactions/no_audit_log.cc \\\n\tactions/no_log.cc \\\n\tactions/phase.cc \\\n\tactions/rev.cc \\\n\tactions/rule_id.cc \\\n\tactions/severity.cc \\\n\tactions/set_env.cc \\\n\tactions/set_rsc.cc \\\n\tactions/set_sid.cc \\\n\tactions/set_uid.cc \\\n\tactions/set_var.cc \\\n\tactions/data/status.cc \\\n\tactions/skip.cc \\\n\tactions/skip_after.cc \\\n\tactions/tag.cc \\\n\tactions/transformations/base64_decode.cc \\\n\tactions/transformations/base64_encode.cc \\\n\tactions/transformations/base64_decode_ext.cc \\\n\tactions/transformations/cmd_line.cc \\\n\tactions/transformations/compress_whitespace.cc \\\n\tactions/transformations/css_decode.cc \\\n\tactions/transformations/escape_seq_decode.cc \\\n\tactions/transformations/hex_decode.cc \\\n\tactions/transformations/hex_encode.cc \\\n\tactions/transformations/html_entity_decode.cc \\\n\tactions/transformations/js_decode.cc \\\n\tactions/transformations/length.cc \\\n\tactions/transformations/lower_case.cc \\\n\tactions/transformations/md5.cc \\\n\tactions/transformations/none.cc \\\n\tactions/transformations/normalise_path.cc \\\n\tactions/transformations/normalise_path_win.cc \\\n\tactions/transformations/parity_even_7bit.cc \\\n\tactions/transformations/parity_odd_7bit.cc \\\n\tactions/transformations/parity_zero_7bit.cc \\\n\tactions/transformations/remove_comments.cc \\\n\tactions/transformations/remove_comments_char.cc \\\n\tactions/transformations/remove_nulls.cc \\\n\tactions/transformations/remove_whitespace.cc \\\n\tactions/transformations/replace_comments.cc \\\n\tactions/transformations/replace_nulls.cc \\\n\tactions/transformations/sha1.cc \\\n\tactions/transformations/sql_hex_decode.cc \\\n\tactions/transformations/transformation.cc \\\n\tactions/transformations/trim.cc \\\n\tactions/transformations/trim_left.cc \\\n\tactions/transformations/trim_right.cc \\\n\tactions/transformations/upper_case.cc \\\n\tactions/transformations/url_decode.cc \\\n\tactions/transformations/url_decode_uni.cc \\\n\tactions/transformations/url_encode.cc \\\n\tactions/transformations/utf8_to_unicode.cc \\\n\tactions/ver.cc \\\n\tactions/xmlns.cc\n\n\nOPERATORS = \\\n\toperators/begins_with.cc \\\n\toperators/contains.cc \\\n\toperators/contains_word.cc \\\n\toperators/detect_sqli.cc \\\n\toperators/detect_xss.cc \\\n\toperators/ends_with.cc \\\n\toperators/eq.cc \\\n\toperators/fuzzy_hash.cc \\\n\toperators/ge.cc \\\n\toperators/geo_lookup.cc \\\n\toperators/gsblookup.cc \\\n\toperators/gt.cc \\\n\toperators/inspect_file.cc \\\n\toperators/ip_match.cc \\\n\toperators/ip_match_f.cc \\\n\toperators/ip_match_from_file.cc \\\n\toperators/le.cc \\\n\toperators/lt.cc \\\n\toperators/no_match.cc \\\n\toperators/operator.cc \\\n\toperators/pm.cc \\\n\toperators/pm_from_file.cc \\\n\toperators/rbl.cc \\\n\toperators/rsub.cc \\\n\toperators/rx.cc \\\n\toperators/rx_global.cc \\\n\toperators/str_eq.cc \\\n\toperators/str_match.cc \\\n\toperators/validate_byte_range.cc \\\n\toperators/validate_dtd.cc \\\n\toperators/validate_hash.cc \\\n\toperators/validate_schema.cc \\\n\toperators/validate_url_encoding.cc \\\n\toperators/validate_utf8_encoding.cc \\\n\toperators/verify_cc.cc \\\n\toperators/verify_cpf.cc \\\n\toperators/verify_ssn.cc \\\n\toperators/verify_svnr.cc \\\n\toperators/within.cc \\\n\toperators/unconditional_match.cc\n\n\nUTILS = \\\n\tutils/acmp.cc \\\n\tutils/base64.cc \\\n\tutils/decode.cc \\\n\tutils/geo_lookup.cc \\\n\tutils/https_client.cc \\\n\tutils/ip_tree.cc \\\n\tutils/msc_tree.cc \\\n\tutils/random.cc \\\n\tutils/regex.cc \\\n\tutils/system.cc \\\n\tutils/shared_files.cc\n\n\nCOLLECTION = \\\n\tcollection/collections.cc \\\n\tcollection/backend/collection_data.cc \\\n\tcollection/backend/in_memory-per_process.cc \\\n\tcollection/backend/lmdb.cc\n\n\nBODY_PROCESSORS = \\\n\trequest_body_processor/multipart.cc \\\n\trequest_body_processor/xml.cc \\\n\trequest_body_processor/json.cc\n\n\nlibmodsecurity_la_SOURCES = \\\n\tparser/seclang-parser.cc \\\n\tparser/seclang-scanner.cc \\\n\tparser/driver.cc \\\n\ttransaction.cc \\\n\tanchored_set_variable.cc \\\n\tanchored_variable.cc \\\n\taudit_log/audit_log.cc \\\n\taudit_log/writer/writer.cc \\\n\taudit_log/writer/https.cc \\\n\taudit_log/writer/serial.cc \\\n\taudit_log/writer/parallel.cc \\\n\tmodsecurity.cc \\\n\trules_set.cc \\\n\trules_set_phases.cc \\\n\trules_set_properties.cc \\\n\tdebug_log/debug_log.cc \\\n\tdebug_log/debug_log_writer.cc \\\n\trun_time_string.cc \\\n\trule.cc \\\n\trule_unconditional.cc \\\n\trule_with_actions.cc \\\n\trule_with_operator.cc \\\n\trule_message.cc \\\n\trule_script.cc \\\n\tunique_id.cc \\\n\trules_exceptions.cc \\\n\t${BODY_PROCESSORS} \\\n\t${ACTIONS} \\\n\t${ENGINES} \\\n\t${COLLECTION} \\\n\t${OPERATORS} \\\n\t${UTILS} \\\n\t${VARIABLES}\n\n\nlibmodsecurity_la_CFLAGS = \n\n\nlibmodsecurity_la_CPPFLAGS = \\\n\t-I$(top_srcdir) \\\n\t-I$(top_builddir) \\\n\t-g \\\n\t-I$(top_srcdir)/others \\\n\t-I$(top_srcdir)/others/mbedtls/include \\\n\t-fPIC \\\n\t-O3 \\\n\t-I$(top_srcdir)/headers \\\n\t$(CURL_CFLAGS) \\\n\t$(GEOIP_CFLAGS) \\\n\t$(GLOBAL_CPPFLAGS) \\\n\t$(MODSEC_NO_LOGS) \\\n\t$(YAJL_CFLAGS) \\\n\t$(LMDB_CFLAGS) \\\n\t$(PCRE_CFLAGS) \\\n\t$(PCRE2_CFLAGS) \\\n\t$(SSDEEP_CFLAGS) \\\n\t$(MAXMIND_CFLAGS) \\\n\t$(LUA_CFLAGS) \\\n\t$(LIBXML2_CFLAGS)\n\n\nlibmodsecurity_la_LDFLAGS = \\\n\t$(CURL_LDFLAGS) \\\n\t$(GEOIP_LDFLAGS) \\\n\t$(GLOBAL_LDFLAGS) \\\n\t$(LDFLAGS) \\\n\t$(LIBXML2_LDFLAGS) \\\n\t$(LMDB_LDFLAGS) \\\n\t$(LUA_LDFLAGS) \\\n\t$(PCRE_LDFLAGS) \\\n\t$(PCRE2_LDFLAGS) \\\n\t$(SSDEEP_LDFLAGS) \\\n\t$(MAXMIND_LDFLAGS) \\\n\t$(YAJL_LDFLAGS) \\\n\t-version-info @MSC_VERSION_INFO@\n\n\nlibmodsecurity_la_LIBADD = \\\n\t$(CURL_LDADD) \\\n\t$(GEOIP_LDADD) \\\n\t$(GLOBAL_LDADD) \\\n\t$(LIBXML2_LDADD) \\\n\t$(LMDB_LDADD) \\\n\t$(LUA_LDADD) \\\n\t../others/libinjection.la \\\n\t../others/libmbedtls.la \\\n\t$(PCRE_LDADD) \\\n\t$(PCRE2_LDADD) \\\n\t$(MAXMIND_LDADD) \\\n\t$(SSDEEP_LDADD) \\\n\t$(YAJL_LDADD)\n\n"
  },
  {
    "path": "src/actions/accuracy.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"src/actions/accuracy.h\"\n\n#include \"modsecurity/rule_with_actions.h\"\n\n\nnamespace modsecurity::actions {\n\n\nbool Accuracy::init(std::string *error) {\n    try {\n        m_accuracy = std::stoi(m_parser_payload);\n    }  catch (...) {\n        error->assign(\"Accuracy: The input \\\"\" + m_parser_payload + \"\\\" is \" \\\n            \"not a number.\");\n        return false;\n    }\n    return true;\n}\n\n\nbool Accuracy::evaluate(RuleWithActions *rule, Transaction *transaction) {\n    rule->m_accuracy = m_accuracy;\n    return true;\n}\n\n\n}  // namespace modsecurity::actions\n"
  },
  {
    "path": "src/actions/accuracy.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <string>\n\n#include \"modsecurity/actions/action.h\"\n\n#ifndef SRC_ACTIONS_ACCURACY_H_\n#define SRC_ACTIONS_ACCURACY_H_\n\nclass Transaction;\n\nnamespace modsecurity {\nclass Transaction;\nnamespace actions {\n\n\nclass Accuracy : public Action {\n public:\n    explicit Accuracy(const std::string &action) \n        : Action(action, Kind::ConfigurationKind),\n        m_accuracy(0) { }\n\n    bool evaluate(RuleWithActions *rule, Transaction *transaction) override;\n    bool init(std::string *error) override;\n\n private:\n    int m_accuracy;\n};\n\n\n}  // namespace actions\n}  // namespace modsecurity\n\n#endif  // SRC_ACTIONS_ACCURACY_H_\n"
  },
  {
    "path": "src/actions/action.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"modsecurity/actions/action.h\"\n\n#include <iostream>\n#include <string>\n\n#include \"modsecurity/transaction.h\"\n#include \"modsecurity/rule.h\"\n#include \"src/utils/string.h\"\n\n#include \"src/actions/block.h\"\n#include \"src/actions/chain.h\"\n#include \"src/actions/disruptive/deny.h\"\n#include \"src/actions/disruptive/redirect.h\"\n#include \"src/actions/data/status.h\"\n#include \"src/actions/rule_id.h\"\n#include \"src/actions/phase.h\"\n#include \"src/actions/severity.h\"\n#include \"src/actions/capture.h\"\n#include \"src/actions/disruptive/pass.h\"\n#include \"src/actions/log.h\"\n#include \"src/actions/no_log.h\"\n#include \"src/actions/no_audit_log.h\"\n#include \"src/actions/multi_match.h\"\n\n\n#define IF_MATCH(a) \\\n    if (op.compare(1, std::strlen(#a), #a) == 0)\n\nnamespace modsecurity {\nnamespace actions {\n\n\nbool Action::evaluate(RuleWithActions *rule, Transaction *transaction) {\n    return true;\n}\n\n\n}  // namespace actions\n}  // namespace modsecurity\n"
  },
  {
    "path": "src/actions/audit_log.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"src/actions/audit_log.h\"\n\n#include <iostream>\n#include <string>\n#include <memory>\n\n#include \"modsecurity/transaction.h\"\n#include \"modsecurity/rule_message.h\"\n#include \"modsecurity/rules_set.h\"\n\nnamespace modsecurity {\nnamespace actions {\n\n\nbool AuditLog::evaluate(RuleWithActions *rule, Transaction *transaction, RuleMessage &ruleMessage) {\n    ruleMessage.m_noAuditLog = false;\n    ms_dbg_a(transaction, 9, \"Saving transaction to logs\");\n    ruleMessage.m_saveMessage = true;\n\n    return true;\n}\n\n\n}  // namespace actions\n}  // namespace modsecurity\n"
  },
  {
    "path": "src/actions/audit_log.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <string>\n#include <memory>\n\n#include \"modsecurity/actions/action.h\"\n\n#ifndef SRC_ACTIONS_AUDIT_LOG_H_\n#define SRC_ACTIONS_AUDIT_LOG_H_\n\n#ifdef __cplusplus\nclass Transaction;\n\nnamespace modsecurity {\nclass Transaction;\n\nnamespace actions {\n\n\nclass AuditLog : public Action {\n public:\n    explicit AuditLog(const std::string &action) \n        : Action(action) { }\n\n    bool evaluate(RuleWithActions *rule, Transaction *transaction, RuleMessage &ruleMessage) override;\n};\n\n\n}  // namespace actions\n}  // namespace modsecurity\n#endif\n\n#endif  // SRC_ACTIONS_AUDIT_LOG_H_\n"
  },
  {
    "path": "src/actions/block.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"src/actions/block.h\"\n\n#include <iostream>\n#include <string>\n#include <memory>\n\n#include \"modsecurity/rules_set.h\"\n#include \"modsecurity/transaction.h\"\n#include \"modsecurity/rule.h\"\n#include \"modsecurity/intervention.h\"\n#include \"src/actions/data/status.h\"\n\nnamespace modsecurity {\nnamespace actions {\n\n\nbool Block::evaluate(RuleWithActions *rule, Transaction *transaction, RuleMessage &ruleMessage) {\n    ms_dbg_a(transaction, 8, \"Marking request as disruptive.\");\n\n    for (auto &a : transaction->m_rules->m_defaultActions[rule->getPhase()]) {\n        if (a->isDisruptive() == false) {\n            continue;\n        }\n        a->evaluate(rule, transaction, ruleMessage);\n    }\n\n    return true;\n}\n\n\n}  // namespace actions\n}  // namespace modsecurity\n"
  },
  {
    "path": "src/actions/block.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <string>\n#include <memory>\n\n#include \"modsecurity/actions/action.h\"\n#include \"modsecurity/rule_message.h\"\n\n#ifndef SRC_ACTIONS_DISRUPTIVE_BLOCK_H_\n#define SRC_ACTIONS_DISRUPTIVE_BLOCK_H_\n\n#ifdef __cplusplus\nclass Transaction;\n\nnamespace modsecurity {\nclass Transaction;\n\nnamespace actions {\n\n\nclass Block : public Action {\n public:\n    explicit Block(const std::string &action) : Action(action) { }\n\n    bool evaluate(RuleWithActions *rule, Transaction *transaction, RuleMessage &ruleMessage) override;\n};\n\n\n}  // namespace actions\n}  // namespace modsecurity\n#endif\n\n#endif  // SRC_ACTIONS_DISRUPTIVE_BLOCK_H_\n"
  },
  {
    "path": "src/actions/capture.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"src/actions/capture.h\"\n\n#include <iostream>\n#include <string>\n#include <list>\n\n#include \"modsecurity/transaction.h\"\n\n#include \"modsecurity/rule.h\"\n#include \"src/operators/operator.h\"\n#include \"src/operators/pm.h\"\n#include \"src/operators/rx.h\"\n#include \"src/operators/contains.h\"\n#include \"src/operators/detect_sqli.h\"\n\nnamespace modsecurity {\nnamespace actions {\n\n\nbool Capture::evaluate(RuleWithActions *rule, Transaction *transaction) {\n    return true;\n}\n\n\n}  // namespace actions\n}  // namespace modsecurity\n"
  },
  {
    "path": "src/actions/capture.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <string>\n\n#include \"modsecurity/actions/action.h\"\n\n#ifndef SRC_ACTIONS_CAPTURE_H_\n#define SRC_ACTIONS_CAPTURE_H_\n\n\nnamespace modsecurity {\nclass RuleWithOperator;\nnamespace actions {\n\n\nclass Capture : public Action {\n public:\n    explicit Capture(const std::string &action) \n        : Action(action) { }\n\n    bool evaluate(RuleWithActions *rule, Transaction *transaction) override;\n};\n\n\n}  // namespace actions\n}  // namespace modsecurity\n\n#endif  // SRC_ACTIONS_CAPTURE_H_\n"
  },
  {
    "path": "src/actions/chain.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"src/actions/chain.h\"\n\n#include \"modsecurity/rule_with_actions.h\"\n\nnamespace modsecurity::actions {\n\n\nbool Chain::evaluate(RuleWithActions *rule, Transaction *transaction) {\n    rule->setChained(true);\n    return true;\n}\n\n\n}  // namespace modsecurity::actions\n"
  },
  {
    "path": "src/actions/chain.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <string>\n\n#include \"modsecurity/actions/action.h\"\n\n#ifndef SRC_ACTIONS_CHAIN_H_\n#define SRC_ACTIONS_CHAIN_H_\n\n#ifdef __cplusplus\nclass Transaction;\n\nnamespace modsecurity {\nclass Transaction;\nclass RuleWithOperator;\n\nnamespace actions {\n\n\nclass Chain : public Action {\n public:\n    explicit Chain(const std::string &action) \n        : Action(action, Kind::ConfigurationKind) { }\n\n    bool evaluate(RuleWithActions *rule, Transaction *transaction) override;\n};\n\n}  // namespace actions\n}  // namespace modsecurity\n#endif\n\n#endif  // SRC_ACTIONS_CHAIN_H_\n"
  },
  {
    "path": "src/actions/ctl/audit_engine.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2022 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"src/actions/ctl/audit_engine.h\"\n\n#include <string>\n\n#include \"modsecurity/rules_set_properties.h\"\n#include \"modsecurity/rules_set.h\"\n#include \"modsecurity/transaction.h\"\n\nnamespace modsecurity {\nnamespace actions {\nnamespace ctl {\n\n\nbool AuditEngine::init(std::string *error) {\n\n    std::string what(m_parser_payload, 12, m_parser_payload.size() - 12);\n\n    if (what == \"on\") {\n        m_auditEngine = audit_log::AuditLog::AuditLogStatus::OnAuditLogStatus;\n    } else if (what == \"off\") {\n        m_auditEngine = audit_log::AuditLog::AuditLogStatus::OffAuditLogStatus;\n    } else if (what == \"relevantonly\") {\n        m_auditEngine = audit_log::AuditLog::AuditLogStatus::RelevantOnlyAuditLogStatus;\n    } else {\n        error->assign(\"Internal error. Expected: On, Off or RelevantOnly; \" \\\n            \"got: \" + m_parser_payload);\n        return false;\n    }\n\n    return true;\n}\n\nbool AuditEngine::evaluate(RuleWithActions *rule, Transaction *transaction) {\n    std::stringstream a;\n    a << \"Setting SecAuditEngine to \";\n    a << std::to_string(m_auditEngine);\n    a << \" as requested by a ctl:auditEngine action\";\n\n    ms_dbg_a(transaction, 8, a.str());\n\n    transaction->m_ctlAuditEngine = m_auditEngine;\n    return true;\n}\n\n\n}  // namespace ctl\n}  // namespace actions\n}  // namespace modsecurity\n"
  },
  {
    "path": "src/actions/ctl/audit_engine.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2022 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <string>\n\n#include \"modsecurity/rules_set_properties.h\"\n#include \"modsecurity/actions/action.h\"\n\n#include \"modsecurity/audit_log.h\"\n\n\n#ifndef SRC_ACTIONS_CTL_AUDIT_ENGINE_H_\n#define SRC_ACTIONS_CTL_AUDIT_ENGINE_H_\n\nnamespace modsecurity {\nclass Transaction;\n\nnamespace actions {\nnamespace ctl {\n\n\nclass AuditEngine : public Action {\n public:\n    explicit AuditEngine(const std::string &action)\n        : Action(action),\n        m_auditEngine(audit_log::AuditLog::AuditLogStatus::NotSetLogStatus) { }\n\n    bool init(std::string *error) override;\n    bool evaluate(RuleWithActions *rule, Transaction *transaction) override;\n\n    audit_log::AuditLog::AuditLogStatus m_auditEngine;\n};\n\n\n}  // namespace ctl\n}  // namespace actions\n}  // namespace modsecurity\n\n#endif  // SRC_ACTIONS_CTL_AUDIT_ENGINE_H_\n"
  },
  {
    "path": "src/actions/ctl/audit_log_parts.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"src/actions/ctl/audit_log_parts.h\"\n\n#include <iostream>\n#include <string>\n#include <utility>\n\n#include \"modsecurity/transaction.h\"\n\nnamespace modsecurity {\nnamespace actions {\nnamespace ctl {\n\n\nbool AuditLogParts::init(std::string *error) {\n    std::string what(m_parser_payload, 14, 1);\n    mParts = std::string(m_parser_payload, 15, m_parser_payload.length()-15);\n    if (what == \"+\") {\n        mPartsAction = 0;\n    } else {\n        mPartsAction = 1;\n    }\n\n    return true;\n}\n\nbool AuditLogParts::evaluate(RuleWithActions *rule, Transaction *transaction) {\n    transaction->m_auditLogModifier.push_back(\n        std::make_pair(mPartsAction, mParts));\n    return true;\n}\n\n\n}  // namespace ctl\n}  // namespace actions\n}  // namespace modsecurity\n"
  },
  {
    "path": "src/actions/ctl/audit_log_parts.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <string>\n\n#include \"modsecurity/actions/action.h\"\n#include \"modsecurity/transaction.h\"\n\n#ifndef SRC_ACTIONS_CTL_AUDIT_LOG_PARTS_H_\n#define SRC_ACTIONS_CTL_AUDIT_LOG_PARTS_H_\n\nnamespace modsecurity {\nnamespace actions {\nnamespace ctl {\n\n\nclass AuditLogParts : public Action {\n public:\n    explicit AuditLogParts(const std::string &action) \n        : Action(action),\n        mPartsAction(0),\n        mParts(\"\") { }\n\n    bool evaluate(RuleWithActions *rule, Transaction *transaction) override;\n    bool init(std::string *error) override;\n\n protected:\n    int mPartsAction;\n    std::string mParts;\n};\n\n\n}  // namespace ctl\n}  // namespace actions\n}  // namespace modsecurity\n\n#endif  // SRC_ACTIONS_CTL_AUDIT_LOG_PARTS_H_\n"
  },
  {
    "path": "src/actions/ctl/parse_xml_into_args.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2025 OWASP ModSecurity project\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact OWASP.\n * directly using the email address modsecurity@owasp.org.\n *\n */\n\n#include \"src/actions/ctl/parse_xml_into_args.h\"\n\n#include <iostream>\n#include <string>\n\n#include \"modsecurity/rules_set_properties.h\"\n#include \"modsecurity/rules_set.h\"\n#include \"modsecurity/transaction.h\"\n\nnamespace modsecurity {\nnamespace actions {\nnamespace ctl {\n\n\nbool ParseXmlIntoArgs::init(std::string *error) {\n    std::string what(m_parser_payload, 17, m_parser_payload.size() - 17);\n\n    if (what == \"on\") {\n        m_secXMLParseXmlIntoArgs = RulesSetProperties::TrueConfigXMLParseXmlIntoArgs;\n    } else if (what == \"off\") {\n        m_secXMLParseXmlIntoArgs = RulesSetProperties::FalseConfigXMLParseXmlIntoArgs;\n    } else if (what == \"onlyargs\") {\n        m_secXMLParseXmlIntoArgs = RulesSetProperties::OnlyArgsConfigXMLParseXmlIntoArgs;\n    } else {\n        error->assign(\"Internal error. Expected: On, Off or OnlyArgs; \" \\\n            \"got: \" + m_parser_payload);\n        return false;\n    }\n\n    return true;\n}\n\nbool ParseXmlIntoArgs::evaluate(RuleWithActions *rule, Transaction *transaction) {\n    std::stringstream a;\n    a << \"Setting SecParseXmlIntoArgs to \";\n    a << modsecurity::RulesSetProperties::configXMLParseXmlIntoArgsString(m_secXMLParseXmlIntoArgs);\n    a << \" as requested by a ctl:parseXmlIntoArgs action\";\n\n    ms_dbg_a(transaction, 8, a.str());\n\n    transaction->m_secXMLParseXmlIntoArgs = m_secXMLParseXmlIntoArgs;\n    return true;\n}\n\n\n}  // namespace ctl\n}  // namespace actions\n}  // namespace modsecurity\n"
  },
  {
    "path": "src/actions/ctl/parse_xml_into_args.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2025 OWASP ModSecurity Project\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact OWASP.\n * directly using the email address modsecurity@owasp.org\n *\n */\n\n#include <string>\n\n#include \"modsecurity/rules_set_properties.h\"\n#include \"modsecurity/actions/action.h\"\n#include \"modsecurity/transaction.h\"\n\n\n#ifndef SRC_ACTIONS_CTL_PARSE_XML_INTO_ARGS_H_\n#define SRC_ACTIONS_CTL_PARSE_XML_INTO_ARGS_H_\n\nnamespace modsecurity {\nnamespace actions {\nnamespace ctl {\n\n\nclass ParseXmlIntoArgs : public Action {\n public:\n    explicit ParseXmlIntoArgs(const std::string &action) \n        : Action(action),\n        m_secXMLParseXmlIntoArgs(RulesSetProperties::PropertyNotSetConfigXMLParseXmlIntoArgs) { }\n\n    bool init(std::string *error) override;\n    bool evaluate(RuleWithActions *rule, Transaction *transaction) override;\n\n    RulesSetProperties::ConfigXMLParseXmlIntoArgs m_secXMLParseXmlIntoArgs;\n};\n\n\n}  // namespace ctl\n}  // namespace actions\n}  // namespace modsecurity\n\n#endif  // SRC_ACTIONS_CTL_PARSE_XML_INTO_ARGS_H_\n"
  },
  {
    "path": "src/actions/ctl/request_body_access.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"src/actions/ctl/request_body_access.h\"\n\n#include <iostream>\n#include <string>\n\n#include \"modsecurity/rules_set_properties.h\"\n#include \"modsecurity/transaction.h\"\n\nnamespace modsecurity {\nnamespace actions {\nnamespace ctl {\n\n\nbool RequestBodyAccess::init(std::string *error) {\n    std::string what(m_parser_payload, 18, m_parser_payload.size() - 18);\n\n    if (what == \"true\") {\n        m_request_body_access = true;\n    } else if (what == \"false\") {\n        m_request_body_access = false;\n    } else {\n        error->assign(\"Internal error. Expected: true or false, got: \" \\\n            + m_parser_payload);\n        return false;\n    }\n\n    return true;\n}\n\nbool RequestBodyAccess::evaluate(RuleWithActions *rule, Transaction *transaction) {\n    if (m_request_body_access) {\n        transaction->m_requestBodyAccess = RulesSetProperties::TrueConfigBoolean;\n    } else {\n        transaction->m_requestBodyAccess = RulesSetProperties::FalseConfigBoolean;\n    }\n\n    return true;\n}\n\n\n}  // namespace ctl\n}  // namespace actions\n}  // namespace modsecurity\n"
  },
  {
    "path": "src/actions/ctl/request_body_access.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <string>\n\n#include \"modsecurity/actions/action.h\"\n#include \"modsecurity/transaction.h\"\n\n\n#ifndef SRC_ACTIONS_CTL_REQUEST_BODY_ACCESS_H_\n#define SRC_ACTIONS_CTL_REQUEST_BODY_ACCESS_H_\n\nnamespace modsecurity {\nnamespace actions {\nnamespace ctl {\n\n\nclass RequestBodyAccess : public Action {\n public:\n    explicit RequestBodyAccess(const std::string &action) \n        : Action(action),\n        m_request_body_access(false) { }\n\n    bool init(std::string *error) override;\n    bool evaluate(RuleWithActions *rule, Transaction *transaction) override;\n\n    bool m_request_body_access;\n};\n\n\n}  // namespace ctl\n}  // namespace actions\n}  // namespace modsecurity\n\n#endif  // SRC_ACTIONS_CTL_REQUEST_BODY_ACCESS_H_\n"
  },
  {
    "path": "src/actions/ctl/request_body_processor_json.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"src/actions/ctl/request_body_processor_json.h\"\n\n#include <iostream>\n#include <string>\n\n#include \"modsecurity/transaction.h\"\n\nnamespace modsecurity {\nnamespace actions {\nnamespace ctl {\n\n\nbool RequestBodyProcessorJSON::evaluate(RuleWithActions *rule,\n    Transaction *transaction) {\n    transaction->m_requestBodyProcessor = Transaction::JSONRequestBody;\n    transaction->m_variableReqbodyProcessor.set(\"JSON\",\n        transaction->m_variableOffset);\n\n    return true;\n}\n\n\n}  // namespace ctl\n}  // namespace actions\n}  // namespace modsecurity\n"
  },
  {
    "path": "src/actions/ctl/request_body_processor_json.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <string>\n\n#include \"modsecurity/actions/action.h\"\n#include \"modsecurity/transaction.h\"\n\n#ifndef SRC_ACTIONS_CTL_REQUEST_BODY_PROCESSOR_JSON_H_\n#define SRC_ACTIONS_CTL_REQUEST_BODY_PROCESSOR_JSON_H_\n\nnamespace modsecurity {\nnamespace actions {\nnamespace ctl {\n\n\nclass RequestBodyProcessorJSON : public Action {\n public:\n    explicit RequestBodyProcessorJSON(const std::string &action) \n        : Action(action) { }\n\n    bool evaluate(RuleWithActions *rule, Transaction *transaction) override;\n};\n\n\n}  // namespace ctl\n}  // namespace actions\n}  // namespace modsecurity\n\n#endif  // SRC_ACTIONS_CTL_REQUEST_BODY_PROCESSOR_JSON_H_\n"
  },
  {
    "path": "src/actions/ctl/request_body_processor_urlencoded.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"src/actions/ctl/request_body_processor_urlencoded.h\"\n\n#include <iostream>\n#include <string>\n\n#include \"modsecurity/transaction.h\"\n\nnamespace modsecurity {\nnamespace actions {\nnamespace ctl {\n\n\nbool RequestBodyProcessorURLENCODED::evaluate(RuleWithActions *rule,\n    Transaction *transaction) {\n    transaction->m_requestBodyType = Transaction::WWWFormUrlEncoded;\n    transaction->m_variableReqbodyProcessor.set(\"URLENCODED\",\n        transaction->m_variableOffset);\n\n    return true;\n}\n\n\n}  // namespace ctl\n}  // namespace actions\n}  // namespace modsecurity\n"
  },
  {
    "path": "src/actions/ctl/request_body_processor_urlencoded.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <string>\n\n#include \"modsecurity/actions/action.h\"\n#include \"modsecurity/transaction.h\"\n\n#ifndef SRC_ACTIONS_CTL_REQUEST_BODY_PROCESSOR_URLENCODED_H_\n#define SRC_ACTIONS_CTL_REQUEST_BODY_PROCESSOR_URLENCODED_H_\n\nnamespace modsecurity {\nnamespace actions {\nnamespace ctl {\n\n\nclass RequestBodyProcessorURLENCODED : public Action {\n public:\n    explicit RequestBodyProcessorURLENCODED(const std::string &action) \n        : Action(action) { }\n\n    bool evaluate(RuleWithActions *rule, Transaction *transaction) override;\n};\n\n\n}  // namespace ctl\n}  // namespace actions\n}  // namespace modsecurity\n\n#endif  // SRC_ACTIONS_CTL_REQUEST_BODY_PROCESSOR_URLENCODED_H_\n"
  },
  {
    "path": "src/actions/ctl/request_body_processor_xml.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"src/actions/ctl/request_body_processor_xml.h\"\n\n#include <iostream>\n#include <string>\n\n#include \"modsecurity/transaction.h\"\n\nnamespace modsecurity {\nnamespace actions {\nnamespace ctl {\n\n\nbool RequestBodyProcessorXML::evaluate(RuleWithActions *rule,\n    Transaction *transaction) {\n    transaction->m_requestBodyProcessor = Transaction::XMLRequestBody;\n    transaction->m_variableReqbodyProcessor.set(\"XML\",\n        transaction->m_variableOffset);\n\n    return true;\n}\n\n\n}  // namespace ctl\n}  // namespace actions\n}  // namespace modsecurity\n"
  },
  {
    "path": "src/actions/ctl/request_body_processor_xml.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <string>\n\n#include \"modsecurity/actions/action.h\"\n#include \"modsecurity/transaction.h\"\n\n#ifndef SRC_ACTIONS_CTL_REQUEST_BODY_PROCESSOR_XML_H_\n#define SRC_ACTIONS_CTL_REQUEST_BODY_PROCESSOR_XML_H_\n\nnamespace modsecurity {\nnamespace actions {\nnamespace ctl {\n\n\nclass RequestBodyProcessorXML : public Action {\n public:\n    explicit RequestBodyProcessorXML(const std::string &action) \n        : Action(action) { }\n\n    bool evaluate(RuleWithActions *rule, Transaction *transaction) override;\n};\n\n\n}  // namespace ctl\n}  // namespace actions\n}  // namespace modsecurity\n\n#endif  // SRC_ACTIONS_CTL_REQUEST_BODY_PROCESSOR_XML_H_\n"
  },
  {
    "path": "src/actions/ctl/rule_engine.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"src/actions/ctl/rule_engine.h\"\n\n#include <iostream>\n#include <string>\n\n#include \"modsecurity/rules_set_properties.h\"\n#include \"modsecurity/rules_set.h\"\n#include \"modsecurity/transaction.h\"\n\nnamespace modsecurity {\nnamespace actions {\nnamespace ctl {\n\n\nbool RuleEngine::init(std::string *error) {\n    std::string what(m_parser_payload, 11, m_parser_payload.size() - 11);\n\n    if (what == \"on\") {\n        m_ruleEngine = RulesSetProperties::EnabledRuleEngine;\n    } else if (what == \"off\") {\n        m_ruleEngine = RulesSetProperties::DisabledRuleEngine;\n    } else if (what == \"detectiononly\") {\n        m_ruleEngine = RulesSetProperties::DetectionOnlyRuleEngine;\n    } else {\n        error->assign(\"Internal error. Expected: On, Off or DetectionOnly; \" \\\n            \"got: \" + m_parser_payload);\n        return false;\n    }\n\n    return true;\n}\n\nbool RuleEngine::evaluate(RuleWithActions *rule, Transaction *transaction) {\n    std::stringstream a;\n    a << \"Setting SecRuleEngine to \";\n    a << modsecurity::RulesSetProperties::ruleEngineStateString(m_ruleEngine);\n    a << \" as requested by a ctl:ruleEngine action\";\n\n    ms_dbg_a(transaction, 8, a.str());\n\n    transaction->m_secRuleEngine = m_ruleEngine;\n    return true;\n}\n\n\n}  // namespace ctl\n}  // namespace actions\n}  // namespace modsecurity\n"
  },
  {
    "path": "src/actions/ctl/rule_engine.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <string>\n\n#include \"modsecurity/rules_set_properties.h\"\n#include \"modsecurity/actions/action.h\"\n#include \"modsecurity/transaction.h\"\n\n\n#ifndef SRC_ACTIONS_CTL_RULE_ENGINE_H_\n#define SRC_ACTIONS_CTL_RULE_ENGINE_H_\n\nnamespace modsecurity {\nnamespace actions {\nnamespace ctl {\n\n\nclass RuleEngine : public Action {\n public:\n    explicit RuleEngine(const std::string &action) \n        : Action(action),\n        m_ruleEngine(RulesSetProperties::PropertyNotSetRuleEngine) { }\n\n    bool init(std::string *error) override;\n    bool evaluate(RuleWithActions *rule, Transaction *transaction) override;\n\n    RulesSetProperties::RuleEngine m_ruleEngine;\n};\n\n\n}  // namespace ctl\n}  // namespace actions\n}  // namespace modsecurity\n\n#endif  // SRC_ACTIONS_CTL_RULE_ENGINE_H_\n"
  },
  {
    "path": "src/actions/ctl/rule_remove_by_id.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2023 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"src/actions/ctl/rule_remove_by_id.h\"\n\n#include <iostream>\n#include <string>\n\n#include \"modsecurity/transaction.h\"\n#include \"src/utils/string.h\"\n\nnamespace modsecurity {\nnamespace actions {\nnamespace ctl {\n\n\nbool RuleRemoveById::init(std::string *error) {\n    std::string what(m_parser_payload, 15, m_parser_payload.size() - 15);\n    bool added = false;\n    std::vector<std::string> toRemove = utils::string::ssplit(what, ' ');\n    for (const std::string &a : toRemove) {\n        std::string b = modsecurity::utils::string::parserSanitizer(a);\n        if (b.size() == 0) {\n            continue;\n        }\n\n        size_t dash = b.find('-');\n        if (dash != std::string::npos) {\n            std::string n1s = std::string(b, 0, dash);\n            std::string n2s = std::string(b, dash + 1, b.size() - (dash + 1));\n            int n1n = 0;\n            int n2n = 0;\n            try {\n                n1n = std::stoi(n1s);\n                added = true;\n            } catch (...) {\n                error->assign(\"Not a number: \" + n1s);\n                return false;\n            }\n            try {\n                n2n = std::stoi(n2s);\n                added = true;\n            } catch (...) {\n                error->assign(\"Not a number: \" + n2s);\n                return false;\n            }\n\n            if (n1n > n2n) {\n                error->assign(\"Invalid range: \" + b);\n                return false;\n            }\n            m_ranges.push_back(std::make_pair(n1n, n2n));\n            added = true;\n        } else {\n            try {\n                int num = std::stoi(b);\n                m_ids.push_back(num);\n                added = true;\n            } catch (...) {\n                error->assign(\"Not a number or range: \" + b);\n                return false;\n            }\n        }\n    }\n\n    if (added) {\n        return true;\n    }\n\n    error->assign(\"Not a number or range: \" + what);\n    return false;\n}\n\nbool RuleRemoveById::evaluate(RuleWithActions *rule, Transaction *transaction) {\n    for (const auto &i : m_ids) {\n        transaction->m_ruleRemoveById.push_back(i);\n    }\n    for (const auto &i : m_ranges) {\n        transaction->m_ruleRemoveByIdRange.push_back(i);\n    }\n\n    return true;\n}\n\n\n}  // namespace ctl\n}  // namespace actions\n}  // namespace modsecurity\n"
  },
  {
    "path": "src/actions/ctl/rule_remove_by_id.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <string>\n\n#include \"modsecurity/actions/action.h\"\n#include \"modsecurity/transaction.h\"\n\n\n#ifndef SRC_ACTIONS_CTL_RULE_REMOVE_BY_ID_H_\n#define SRC_ACTIONS_CTL_RULE_REMOVE_BY_ID_H_\n\nnamespace modsecurity {\nnamespace actions {\nnamespace ctl {\n\n\nclass RuleRemoveById : public Action {\n public:\n    explicit RuleRemoveById(const std::string &action) \n        : Action(action) { }\n\n    bool init(std::string *error) override;\n    bool evaluate(RuleWithActions *rule, Transaction *transaction) override;\n\n    std::list<std::pair<int, int> > m_ranges;\n    std::list<int> m_ids;\n};\n\n\n}  // namespace ctl\n}  // namespace actions\n}  // namespace modsecurity\n\n#endif  // SRC_ACTIONS_CTL_RULE_REMOVE_BY_ID_H_\n"
  },
  {
    "path": "src/actions/ctl/rule_remove_by_tag.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"src/actions/ctl/rule_remove_by_tag.h\"\n\n#include <iostream>\n#include <string>\n\n#include \"modsecurity/transaction.h\"\n\nnamespace modsecurity {\nnamespace actions {\nnamespace ctl {\n\n\nbool RuleRemoveByTag::init(std::string *error) {\n    std::string what(m_parser_payload, 16, m_parser_payload.size() - 16);\n    m_tag = what;\n\n    return true;\n}\n\nbool RuleRemoveByTag::evaluate(RuleWithActions *rule, Transaction *transaction) {\n    transaction->m_ruleRemoveByTag.push_back(m_tag);\n    return true;\n}\n\n\n}  // namespace ctl\n}  // namespace actions\n}  // namespace modsecurity\n"
  },
  {
    "path": "src/actions/ctl/rule_remove_by_tag.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <string>\n\n#include \"modsecurity/actions/action.h\"\n#include \"modsecurity/transaction.h\"\n\n\n#ifndef SRC_ACTIONS_CTL_RULE_REMOVE_BY_TAG_H_\n#define SRC_ACTIONS_CTL_RULE_REMOVE_BY_TAG_H_\n\nnamespace modsecurity {\nnamespace actions {\nnamespace ctl {\n\n\nclass RuleRemoveByTag : public Action {\n public:\n    explicit RuleRemoveByTag(const std::string &action) \n        : Action(action),\n        m_tag(\"\") { }\n\n    bool init(std::string *error) override;\n    bool evaluate(RuleWithActions *rule, Transaction *transaction) override;\n\n    std::string m_tag;\n};\n\n\n}  // namespace ctl\n}  // namespace actions\n}  // namespace modsecurity\n\n#endif  // SRC_ACTIONS_CTL_RULE_REMOVE_BY_TAG_H_\n"
  },
  {
    "path": "src/actions/ctl/rule_remove_target_by_id.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"src/actions/ctl/rule_remove_target_by_id.h\"\n\n#include <iostream>\n#include <string>\n#include <vector>\n#include <utility>\n\n#include \"modsecurity/transaction.h\"\n#include \"src/utils/string.h\"\n\n\nnamespace modsecurity {\nnamespace actions {\nnamespace ctl {\n\n\nbool RuleRemoveTargetById::init(std::string *error) {\n    std::string what(m_parser_payload, 21, m_parser_payload.size() - 21);\n    std::vector<std::string> param = utils::string::split(what, ';');\n\n    if (param.size() < 2) {\n        error->assign(what + \" is not a valid `ID;VARIABLE'\");\n        return false;\n    }\n\n    try {\n        m_id = std::stoi(param[0]);\n    } catch(...) {\n        error->assign(\"Not able to convert '\" + param[0] +\n            \"' into a number\");\n        return false;\n    }\n\n    m_target = param[1];\n\n    return true;\n}\n\nbool RuleRemoveTargetById::evaluate(RuleWithActions *rule, Transaction *transaction) {\n    transaction->m_ruleRemoveTargetById.push_back(\n        std::make_pair(m_id, m_target));\n    return true;\n}\n\n\n}  // namespace ctl\n}  // namespace actions\n}  // namespace modsecurity\n"
  },
  {
    "path": "src/actions/ctl/rule_remove_target_by_id.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <string>\n\n#include \"modsecurity/actions/action.h\"\n#include \"modsecurity/transaction.h\"\n\n\n#ifndef SRC_ACTIONS_CTL_RULE_REMOVE_TARGET_BY_ID_H_\n#define SRC_ACTIONS_CTL_RULE_REMOVE_TARGET_BY_ID_H_\n\nnamespace modsecurity {\nnamespace actions {\nnamespace ctl {\n\n\nclass RuleRemoveTargetById : public Action {\n public:\n    explicit RuleRemoveTargetById(const std::string &action) \n        : Action(action),\n        m_id(0),\n        m_target(\"\") { }\n\n    bool init(std::string *error) override;\n    bool evaluate(RuleWithActions *rule, Transaction *transaction) override;\n\n    int m_id;\n    std::string m_target;\n};\n\n\n}  // namespace ctl\n}  // namespace actions\n}  // namespace modsecurity\n\n#endif  // SRC_ACTIONS_CTL_RULE_REMOVE_TARGET_BY_ID_H_\n"
  },
  {
    "path": "src/actions/ctl/rule_remove_target_by_tag.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"src/actions/ctl/rule_remove_target_by_tag.h\"\n\n#include <iostream>\n#include <string>\n#include <vector>\n#include <utility>\n\n#include \"modsecurity/transaction.h\"\n#include \"src/utils/string.h\"\n\n\nnamespace modsecurity {\nnamespace actions {\nnamespace ctl {\n\n\nbool RuleRemoveTargetByTag::init(std::string *error) {\n    std::string what(m_parser_payload, 22, m_parser_payload.size() - 22);\n    std::vector<std::string> param = utils::string::split(what, ';');\n\n    if (param.size() < 2) {\n        error->assign(what + \" is not a valid `TAG;VARIABLE'\");\n        return false;\n    }\n\n    m_tag = param[0];\n    m_target = param[1];\n\n    return true;\n}\n\nbool RuleRemoveTargetByTag::evaluate(RuleWithActions *rule, Transaction *transaction) {\n    transaction->m_ruleRemoveTargetByTag.push_back(\n        std::make_pair(m_tag, m_target));\n    return true;\n}\n\n\n}  // namespace ctl\n}  // namespace actions\n}  // namespace modsecurity\n"
  },
  {
    "path": "src/actions/ctl/rule_remove_target_by_tag.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <string>\n\n#include \"modsecurity/actions/action.h\"\n#include \"modsecurity/transaction.h\"\n\n\n#ifndef SRC_ACTIONS_CTL_RULE_REMOVE_TARGET_BY_TAG_H_\n#define SRC_ACTIONS_CTL_RULE_REMOVE_TARGET_BY_TAG_H_\n\nnamespace modsecurity {\nnamespace actions {\nnamespace ctl {\n\n\nclass RuleRemoveTargetByTag : public Action {\n public:\n    explicit RuleRemoveTargetByTag(const std::string &action) \n        : Action(action) { }\n\n    bool init(std::string *error) override;\n    bool evaluate(RuleWithActions *rule, Transaction *transaction) override;\n\n    std::string m_tag;\n    std::string m_target;\n};\n\n\n}  // namespace ctl\n}  // namespace actions\n}  // namespace modsecurity\n\n#endif  // SRC_ACTIONS_CTL_RULE_REMOVE_TARGET_BY_TAG_H_\n"
  },
  {
    "path": "src/actions/data/status.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"src/actions/data/status.h\"\n\n#include <iostream>\n#include <string>\n#include <memory>\n\n#include \"modsecurity/transaction.h\"\n\n\nnamespace modsecurity {\nnamespace actions {\nnamespace data {\n\nbool Status::init(std::string *error) {\n    try {\n        m_status = std::stoi(m_parser_payload);\n    } catch (...) {\n        error->assign(\"Not a valid number: \" + m_parser_payload);\n        return false;\n    }\n\n    return true;\n}\n\n\nbool Status::evaluate(RuleWithActions *rule, Transaction *transaction,\n    RuleMessage &ruleMessage) {\n    transaction->m_it.status = m_status;\n    return true;\n}\n\n\n}  // namespace data\n}  // namespace actions\n}  // namespace modsecurity\n"
  },
  {
    "path": "src/actions/data/status.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <string>\n#include <memory>\n\n#include \"modsecurity/actions/action.h\"\n#include \"modsecurity/rule_message.h\"\n\n#ifndef SRC_ACTIONS_DATA_STATUS_H_\n#define SRC_ACTIONS_DATA_STATUS_H_\n\n#ifdef __cplusplus\nclass Transaction;\n\nnamespace modsecurity {\nclass Transaction;\nnamespace actions {\nnamespace data {\n\n\nclass Status : public Action {\n public:\n    explicit Status(const std::string &action)\n        : Action(action), m_status(0) { }\n\n    bool init(std::string *error) override;\n    bool evaluate(RuleWithActions *rule, Transaction *transaction, RuleMessage &ruleMessage) override;\n\n    int m_status;\n};\n\n\n}  // namespace data\n}  // namespace actions\n}  // namespace modsecurity\n#endif\n\n#endif  // SRC_ACTIONS_DATA_STATUS_H_\n"
  },
  {
    "path": "src/actions/disruptive/allow.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"src/actions/disruptive/allow.h\"\n\n#include <iostream>\n#include <string>\n\n#include \"modsecurity/rules_set.h\"\n#include \"modsecurity/transaction.h\"\n#include \"modsecurity/rule.h\"\n#include \"src/utils/string.h\"\n#include \"modsecurity/modsecurity.h\"\n\n\nnamespace modsecurity {\nnamespace actions {\nnamespace disruptive {\n\n\nbool Allow::init(std::string *error) {\n    std::string a = utils::string::tolower(m_parser_payload);\n\n    if (a == \"phase\") {\n        m_allowType = PhaseAllowType;\n    } else if (a == \"request\") {\n        m_allowType = RequestAllowType;\n    } else if (a == \"\") {\n        m_allowType = FromNowOnAllowType;\n    } else {\n        error->assign(\"Allow: if specified, the parameter \" \\\n            \"most be: phase, request\");\n        return false;\n    }\n\n    return true;\n}\n\n\nbool Allow::evaluate(RuleWithActions *rule, Transaction *transaction) {\n    ms_dbg_a(transaction, 4, \"Dropping the evaluation of upcoming rules \" \\\n        \"in favor of an `allow' action of type: \" \\\n        + allowTypeToName(m_allowType));\n\n    transaction->m_allowType = m_allowType;\n\n    return true;\n}\n\n\n}  // namespace disruptive\n}  // namespace actions\n}  // namespace modsecurity\n"
  },
  {
    "path": "src/actions/disruptive/allow.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <string>\n\n#include \"modsecurity/actions/action.h\"\n\n#ifndef SRC_ACTIONS_DISRUPTIVE_ALLOW_H_\n#define SRC_ACTIONS_DISRUPTIVE_ALLOW_H_\n\n#ifdef __cplusplus\nclass Transaction;\n\nnamespace modsecurity {\nclass Transaction;\nclass RuleWithOperator;\n\nnamespace actions {\nnamespace disruptive {\n\n\nenum AllowType : int {\n  /**\n   *\n   */\n  NoneAllowType,\n  /**\n   *\n   */\n  RequestAllowType,\n  /**\n   *\n   */\n  PhaseAllowType,\n  /**\n   *\n   */\n  FromNowOnAllowType,\n};\n\n\nclass Allow : public Action {\n public:\n    explicit Allow(const std::string &action) \n        : Action(action),\n        m_allowType(NoneAllowType) { }\n\n\n    bool init(std::string *error) override;\n    bool evaluate(RuleWithActions *rule, Transaction *transaction) override;\n    bool isDisruptive() override { return true; }\n\n    AllowType m_allowType;\n\n    static std::string allowTypeToName(AllowType a) {\n        if (a == NoneAllowType) {\n            return \"None\";\n        } else if (a == RequestAllowType) {\n            return \"Request\";\n        } else if (a == PhaseAllowType) {\n            return \"Phase\";\n        } else if (a == FromNowOnAllowType) {\n            return \"FromNowOn\";\n        } else {\n            return \"Unknown\";\n        }\n    }\n};\n\n\n}  // namespace disruptive\n}  // namespace actions\n}  // namespace modsecurity\n#endif\n\n#endif  // SRC_ACTIONS_DISRUPTIVE_ALLOW_H_\n"
  },
  {
    "path": "src/actions/disruptive/deny.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"src/actions/disruptive/deny.h\"\n\n#include <string.h>\n#include <iostream>\n#include <string>\n#include <cstring>\n#include <memory>\n\n#include \"modsecurity/transaction.h\"\n\nnamespace modsecurity {\nnamespace actions {\nnamespace disruptive {\n\n\nbool Deny::evaluate(RuleWithActions *rule, Transaction *transaction,\n    RuleMessage &ruleMessage) {\n    ms_dbg_a(transaction, 8, \"Running action deny\");\n\n    if (transaction->m_it.status == 200) {\n        transaction->m_it.status = 403;\n    }\n\n    transaction->m_it.disruptive = true;\n    intervention::freeLog(&transaction->m_it);\n    ruleMessage.m_isDisruptive = true;\n    transaction->m_it.log = strdup(\n        ruleMessage.log(RuleMessage::LogMessageInfo::ClientLogMessageInfo).c_str());\n\n    return true;\n}\n\n\n}  // namespace disruptive\n}  // namespace actions\n}  // namespace modsecurity\n"
  },
  {
    "path": "src/actions/disruptive/deny.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <string>\n#include <memory>\n\n#include \"modsecurity/rules_set.h\"\n#include \"modsecurity/actions/action.h\"\n#include \"modsecurity/transaction.h\"\n#include \"modsecurity/rule_message.h\"\n\n#ifndef SRC_ACTIONS_DISRUPTIVE_DENY_H_\n#define SRC_ACTIONS_DISRUPTIVE_DENY_H_\n\nnamespace modsecurity {\nnamespace actions {\nnamespace disruptive {\n\n\nclass Deny : public Action {\n public:\n    explicit Deny(const std::string &action) : Action(action) { }\n\n    bool evaluate(RuleWithActions *rule, Transaction *transaction, RuleMessage &ruleMessage) override;\n    bool isDisruptive() override { return true; }\n};\n\n\n}  // namespace disruptive\n}  // namespace actions\n}  // namespace modsecurity\n\n#endif  // SRC_ACTIONS_DISRUPTIVE_DENY_H_\n"
  },
  {
    "path": "src/actions/disruptive/drop.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"src/actions/disruptive/drop.h\"\n\n#include <string.h>\n#include <iostream>\n#include <string>\n#include <cstring>\n#include <memory>\n\n#include \"modsecurity/rules_set.h\"\n#include \"modsecurity/transaction.h\"\n#include \"modsecurity/rule.h\"\n#include \"src/utils/string.h\"\n#include \"modsecurity/modsecurity.h\"\n\nnamespace modsecurity {\nnamespace actions {\nnamespace disruptive {\n\n\nbool Drop::evaluate(RuleWithActions *rule, Transaction *transaction,\n    RuleMessage &ruleMessage) {\n    ms_dbg_a(transaction, 8, \"Running action drop \" \\\n        \"[executing deny instead of drop.]\");\n\n    if (transaction->m_it.status == 200) {\n        transaction->m_it.status = 403;\n    }\n\n    transaction->m_it.disruptive = true;\n    intervention::freeLog(&transaction->m_it);\n    ruleMessage.m_isDisruptive = true;\n    transaction->m_it.log = strdup(\n        ruleMessage.log(RuleMessage::LogMessageInfo::ClientLogMessageInfo).c_str());\n\n    return true;\n}\n\n\n}  // namespace disruptive\n}  // namespace actions\n}  // namespace modsecurity\n"
  },
  {
    "path": "src/actions/disruptive/drop.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <string>\n#include <memory>\n\n#include \"modsecurity/actions/action.h\"\n#include \"modsecurity/transaction.h\"\n#include \"modsecurity/rule_message.h\"\n\n#ifndef SRC_ACTIONS_DISRUPTIVE_DROP_H_\n#define SRC_ACTIONS_DISRUPTIVE_DROP_H_\n\nnamespace modsecurity {\nnamespace actions {\nnamespace disruptive {\n\n\nclass Drop : public Action {\n public:\n    explicit Drop(const std::string &action) : Action(action) { }\n\n    bool evaluate(RuleWithActions *rule, Transaction *transaction, RuleMessage &ruleMessage) override;\n    bool isDisruptive() override { return true; }\n};\n\n\n}  // namespace disruptive\n}  // namespace actions\n}  // namespace modsecurity\n\n#endif  // SRC_ACTIONS_DISRUPTIVE_DROP_H_\n"
  },
  {
    "path": "src/actions/disruptive/pass.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"src/actions/disruptive/pass.h\"\n\n#include <iostream>\n#include <string>\n#include <memory>\n\n#include \"modsecurity/rules_set.h\"\n#include \"modsecurity/transaction.h\"\n#include \"modsecurity/rule.h\"\n#include \"modsecurity/rule_message.h\"\n\nnamespace modsecurity {\nnamespace actions {\nnamespace disruptive {\n\n\nbool Pass::evaluate(RuleWithActions *rule, Transaction *transaction,\n    RuleMessage &ruleMessage) {\n    intervention::free(&transaction->m_it);\n    intervention::reset(&transaction->m_it);\n\n    ms_dbg_a(transaction, 8, \"Running action pass\");\n\n    return true;\n}\n\n\n}  // namespace disruptive\n}  // namespace actions\n}  // namespace modsecurity\n"
  },
  {
    "path": "src/actions/disruptive/pass.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <string>\n#include <memory>\n\n#include \"modsecurity/actions/action.h\"\n#include \"modsecurity/transaction.h\"\n\n#ifndef SRC_ACTIONS_DISRUPTIVE_PASS_H_\n#define SRC_ACTIONS_DISRUPTIVE_PASS_H_\n\nnamespace modsecurity {\nnamespace actions {\nnamespace disruptive {\n\n\nclass Pass : public Action {\n public:\n    explicit Pass(const std::string &action) : Action(action) { }\n\n    bool evaluate(RuleWithActions *rule, Transaction *transaction, RuleMessage &ruleMessage) override;\n    bool isDisruptive() override { return true; }\n};\n\n\n}  // namespace disruptive\n}  // namespace actions\n}  // namespace modsecurity\n\n\n#endif  // SRC_ACTIONS_DISRUPTIVE_PASS_H_\n"
  },
  {
    "path": "src/actions/disruptive/redirect.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"src/actions/disruptive/redirect.h\"\n\n#include <string.h>\n#include <iostream>\n#include <string>\n#include <memory>\n\n#include \"modsecurity/transaction.h\"\n#include \"src/utils/string.h\"\n\nnamespace modsecurity {\nnamespace actions {\nnamespace disruptive {\n\n\nbool Redirect::init(std::string *error) {\n    m_status = 302;\n    return true;\n}\n\n\nbool Redirect::evaluate(RuleWithActions *rule, Transaction *transaction,\n    RuleMessage &ruleMessage) {\n    std::string m_urlExpanded(m_string->evaluate(transaction));\n    /* if it was changed before, lets keep it. */\n    if (transaction->m_it.status == 200\n        || (!(transaction->m_it.status <= 307 && transaction->m_it.status >= 301))) {\n        transaction->m_it.status = m_status;\n    }\n\n    intervention::freeUrl(&transaction->m_it);\n    transaction->m_it.url = strdup(m_urlExpanded.c_str());\n    transaction->m_it.disruptive = true;\n    intervention::freeLog(&transaction->m_it);\n    ruleMessage.m_isDisruptive = true;\n    transaction->m_it.log = strdup(\n        ruleMessage.log(RuleMessage::LogMessageInfo::ClientLogMessageInfo).c_str());\n\n    return true;\n}\n\n\n}  // namespace disruptive\n}  // namespace actions\n}  // namespace modsecurity\n"
  },
  {
    "path": "src/actions/disruptive/redirect.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <string>\n#include <memory>\n#include <utility>\n\n#include \"modsecurity/actions/action.h\"\n#include \"modsecurity/rule_message.h\"\n#include \"src/run_time_string.h\"\n\n#ifndef SRC_ACTIONS_DISRUPTIVE_REDIRECT_H_\n#define SRC_ACTIONS_DISRUPTIVE_REDIRECT_H_\n\n#ifdef __cplusplus\nclass Transaction;\n\nnamespace modsecurity {\nclass Transaction;\n\nnamespace actions {\nnamespace disruptive {\n\n\nclass Redirect : public Action {\n public:\n    explicit Redirect(const std::string &action)\n        : Action(action),\n        m_status(0),\n        m_string(nullptr) { }\n\n    explicit Redirect(std::unique_ptr<RunTimeString> z)\n        : Action(\"redirert\"),\n            m_status(0),\n            m_string(std::move(z)) { }\n\n    bool evaluate(RuleWithActions *rule, Transaction *transaction, RuleMessage &ruleMessage) override;\n    bool init(std::string *error) override;\n    bool isDisruptive() override { return true; }\n\n private:\n    int m_status;\n    std::unique_ptr<RunTimeString> m_string;\n};\n\n\n}  // namespace disruptive\n}  // namespace actions\n}  // namespace modsecurity\n#endif\n\n#endif  // SRC_ACTIONS_DISRUPTIVE_REDIRECT_H_\n"
  },
  {
    "path": "src/actions/exec.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"src/actions/exec.h\"\n\n#include <iostream>\n#include <string>\n\n#include \"modsecurity/rules_set.h\"\n#include \"modsecurity/actions/action.h\"\n#include \"modsecurity/transaction.h\"\n#include \"modsecurity/rule.h\"\n#include \"src/utils/system.h\"\n#include \"src/engine/lua.h\"\n\n\nnamespace modsecurity {\nnamespace actions {\n\n\nbool Exec::init(std::string *error) {\n    std::string err;\n\n    m_script = utils::find_resource(m_parser_payload, \"\", &err);\n\n    if (m_script.size() == 0) {\n        error->assign(\"exec: Script not found: \" + err);\n        return false;\n    }\n\n    if (engine::Lua::isCompatible(m_script, &m_lua, &err) == false) {\n        error->assign(\"exec: \" + err);\n        return false;\n    }\n\n    return true;\n}\n\n\nbool Exec::evaluate(RuleWithActions *rule, Transaction *t) {\n    ms_dbg_a(t, 8, \"Running script... \" + m_script);\n    m_lua.run(t);\n    return true;\n}\n\n\n}  // namespace actions\n}  // namespace modsecurity\n"
  },
  {
    "path": "src/actions/exec.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <string>\n\n#include \"modsecurity/actions/action.h\"\n#include \"src/engine/lua.h\"\n\n#ifndef SRC_ACTIONS_EXEC_H_\n#define SRC_ACTIONS_EXEC_H_\n\nclass Transaction;\n\nnamespace modsecurity {\nclass Transaction;\nnamespace actions {\n\n\nclass Exec : public Action {\n public:\n    explicit Exec(const std::string &action) \n        : Action(action) { }\n\n    bool evaluate(RuleWithActions *rule, Transaction *transaction) override;\n    bool init(std::string *error) override;\n\n private:\n    std::string m_script;\n    engine::Lua m_lua;\n};\n\n\n}  // namespace actions\n}  // namespace modsecurity\n\n#endif  // SRC_ACTIONS_EXEC_H_\n"
  },
  {
    "path": "src/actions/expire_var.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2023 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"src/actions/expire_var.h\"\n\n#include <string>\n\n#include \"modsecurity/rules_set.h\"\n#include \"modsecurity/transaction.h\"\n#include \"modsecurity/rule.h\"\n#include \"src/utils/string.h\"\n#include \"src/variables/global.h\"\n#include \"src/variables/ip.h\"\n#include \"src/variables/resource.h\"\n#include \"src/variables/session.h\"\n#include \"src/variables/user.h\"\n#include \"src/variables/variable.h\"\n\nnamespace modsecurity {\nnamespace actions {\n\n\nbool ExpireVar::evaluate(RuleWithActions *rule, Transaction *t) {\n\n    std::string expireExpressionExpanded(m_string->evaluate(t));\n\n    std::string fully_qualified_var;\n    int expirySeconds = 0;\n    size_t posEquals = expireExpressionExpanded.find(\"=\");\n    if (posEquals == std::string::npos) {\n        fully_qualified_var = expireExpressionExpanded;\n    } else {\n        fully_qualified_var = expireExpressionExpanded.substr(0, posEquals);\n\tstd::string expiry = expireExpressionExpanded.substr(posEquals+1);\n\tif (expiry.find_first_not_of(\"0123456789\") == std::string::npos) {\n            expirySeconds = atoi(expiry.c_str());\n\t} else {\n            ms_dbg_a(t, 5, \"Non-numeric expiry seconds found in expirevar expression.\");\n            return true;\n\t}\n    }\n\n    size_t posDot = fully_qualified_var.find(\".\");\n    if (posDot == std::string::npos) {\n        ms_dbg_a(t, 5, \"No collection found in expirevar expression.\");\n\treturn true;\n    }\n\n    std::string collection = fully_qualified_var.substr(0, posDot);\n    std::string variable_name = fully_qualified_var.substr(posDot+1);\n    auto runTimeString = std::make_unique<RunTimeString>();\n    runTimeString->appendText(fully_qualified_var);\n\n    if (collection == \"ip\") {\n        auto ip_dynamicElement = std::make_unique<modsecurity::variables::Ip_DynamicElement>(std::move(runTimeString));\n        ip_dynamicElement->setExpiry(t, variable_name, expirySeconds);\n    } else if (collection == \"global\") {\n        auto global_dynamicElement = std::make_unique<modsecurity::variables::Global_DynamicElement>(std::move(runTimeString));\n        global_dynamicElement->setExpiry(t, variable_name, expirySeconds);\n    } else if (collection == \"resource\") {\n        auto resource_dynamicElement = std::make_unique<modsecurity::variables::Resource_DynamicElement>(std::move(runTimeString));\n        resource_dynamicElement->setExpiry(t, variable_name, expirySeconds);\n    } else if (collection == \"session\") {\n        auto session_dynamicElement = std::make_unique<modsecurity::variables::Session_DynamicElement>(std::move(runTimeString));\n        session_dynamicElement->setExpiry(t, variable_name, expirySeconds);\n    } else if (collection == \"user\") {\n        auto user_dynamicElement = std::make_unique<modsecurity::variables::User_DynamicElement>(std::move(runTimeString));\n        user_dynamicElement->setExpiry(t, variable_name, expirySeconds);\n    } else {\n        ms_dbg_a(t, 5, \"Invalid collection found in expirevar expression: collection must be `ip', `global', `resource', `user' or `session'\");\n    }\n    ms_dbg_a(t, 9, \"Setting variable `\" + variable_name + \"' to expire in \" + std::to_string(expirySeconds) + \" seconds.\");\n\n    return true;\n}\n\n}  // namespace actions\n}  // namespace modsecurity\n"
  },
  {
    "path": "src/actions/expire_var.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2023 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <memory>\n#include <string>\n#include <utility>\n\n#include \"modsecurity/actions/action.h\"\n#include \"src/run_time_string.h\"\n\n#ifndef SRC_ACTIONS_EXPIRE_VAR_H_\n#define SRC_ACTIONS_EXPIRE_VAR_H_\n\nclass Transaction;\n\nnamespace modsecurity {\nclass Transaction;\nclass RuleWithOperator;\n\nnamespace actions {\n\nclass ExpireVar : public Action {\n public:\n    explicit ExpireVar(const std::string &action) : Action(action) { }\n\n    explicit ExpireVar(std::unique_ptr<RunTimeString> z)\n        : Action(\"expirevar\"),\n            m_string(std::move(z)) { }\n\n    bool evaluate(RuleWithActions *rule, Transaction *transaction) override;\n\n private:\n\n    std::unique_ptr<RunTimeString> m_string;\n};\n\n}  // namespace actions\n}  // namespace modsecurity\n\n\n#endif  // SRC_ACTIONS_EXPIRE_VAR_H_\n"
  },
  {
    "path": "src/actions/init_col.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"src/actions/init_col.h\"\n\n#include <iostream>\n#include <string>\n\n#include \"modsecurity/actions/action.h\"\n#include \"modsecurity/transaction.h\"\n#include \"modsecurity/rule.h\"\n\n\nnamespace modsecurity {\nnamespace actions {\n\n\nbool InitCol::init(std::string *error) {\n    int posEquals = m_parser_payload.find(\"=\");\n\n    if (m_parser_payload.size() < 2) {\n        error->assign(\"Something wrong with initcol format: too small\");\n        return false;\n    }\n    if (posEquals == std::string::npos) {\n        error->assign(\"Something wrong with initcol format: missing \" \\\n                \"equals sign\");\n        return false;\n    }\n\n    m_collection_key = std::string(m_parser_payload, 0,  posEquals);\n\n    if (m_collection_key != \"ip\" &&\n        m_collection_key != \"global\" &&\n        m_collection_key != \"resource\") {\n        error->assign(\"Something wrong with initcol: collection must be \" \\\n            \"`ip', `global' or `resource'\");\n        return false;\n    }\n\n    return true;\n}\n\n\nbool InitCol::evaluate(RuleWithActions *rule, Transaction *t) {\n    std::string collectionName(m_string->evaluate(t));\n\n    if (m_collection_key == \"ip\") {\n        t->m_collections.m_ip_collection_key = collectionName;\n    } else if (m_collection_key == \"global\") {\n        t->m_collections.m_global_collection_key = collectionName;\n    } else if (m_collection_key == \"resource\") {\n        t->m_collections.m_resource_collection_key = collectionName;\n    } else {\n        return false;\n    }\n\n    ms_dbg_a(t, 5, \"Collection `\" + m_collection_key + \"' initialized with \" \\\n        \"value: \" + collectionName);\n\n    return true;\n}\n\n}  // namespace actions\n}  // namespace modsecurity\n"
  },
  {
    "path": "src/actions/init_col.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <string>\n#include <utility>\n#include <memory>\n\n#include \"modsecurity/actions/action.h\"\n#include \"src/run_time_string.h\"\n\n#ifndef SRC_ACTIONS_INIT_COL_H_\n#define SRC_ACTIONS_INIT_COL_H_\n\nclass Transaction;\n\nnamespace modsecurity {\nclass Transaction;\nnamespace actions {\n\n\nclass InitCol : public Action {\n public:\n    explicit InitCol(const std::string &action) : Action(action) { }\n\n    InitCol(const std::string &action, std::unique_ptr<RunTimeString> z)\n        : Action(action),\n            m_string(std::move(z)) { }\n\n    bool evaluate(RuleWithActions *rule, Transaction *transaction) override;\n    bool init(std::string *error) override;\n private:\n    std::string m_collection_key;\n    std::unique_ptr<RunTimeString> m_string;\n};\n\n\n}  // namespace actions\n}  // namespace modsecurity\n\n#endif  // SRC_ACTIONS_INIT_COL_H_\n"
  },
  {
    "path": "src/actions/log.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"src/actions/log.h\"\n\n#include <iostream>\n#include <string>\n#include <memory>\n\n#include \"modsecurity/actions/action.h\"\n#include \"modsecurity/transaction.h\"\n#include \"src/operators/operator.h\"\n#include \"modsecurity/rule_message.h\"\n\nnamespace modsecurity {\nnamespace actions {\n\n\nbool Log::evaluate(RuleWithActions *rule, Transaction *transaction, RuleMessage &ruleMessage) {\n    ms_dbg_a(transaction, 9, \"Saving transaction to logs\");\n    ruleMessage.m_saveMessage = true;\n    return true;\n}\n\n\n}  // namespace actions\n}  // namespace modsecurity\n"
  },
  {
    "path": "src/actions/log.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <string>\n#include <memory>\n\n#include \"modsecurity/actions/action.h\"\n\n#ifndef SRC_ACTIONS_LOG_H_\n#define SRC_ACTIONS_LOG_H_\n\nclass Transaction;\n\nnamespace modsecurity {\nclass Transaction;\nnamespace actions {\n\n\nclass Log : public Action {\n public:\n    explicit Log(const std::string &action) \n        : Action(action) { }\n\n    bool evaluate(RuleWithActions *rule, Transaction *transaction, RuleMessage &ruleMessage) override;\n};\n\n}  // namespace actions\n}  // namespace modsecurity\n\n\n#endif  // SRC_ACTIONS_LOG_H_\n"
  },
  {
    "path": "src/actions/log_data.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"src/actions/log_data.h\"\n\n#include <iostream>\n#include <string>\n#include <memory>\n\n#include \"modsecurity/actions/action.h\"\n#include \"modsecurity/transaction.h\"\n#include \"modsecurity/rule.h\"\n#include \"modsecurity/rule_message.h\"\n\n\nnamespace modsecurity {\nnamespace actions {\n\n\nbool LogData::evaluate(RuleWithActions *rule, Transaction *transaction, RuleMessage &ruleMessage) {\n    ruleMessage.m_data = data(transaction);\n\n    return true;\n}\n\nstd::string LogData::data(Transaction *transaction) {\n    std::string a(m_string->evaluate(transaction));\n    return a;\n}\n\n\n}  // namespace actions\n}  // namespace modsecurity\n"
  },
  {
    "path": "src/actions/log_data.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <string>\n#include <memory>\n#include <utility>\n\n#include \"modsecurity/actions/action.h\"\n#include \"src/run_time_string.h\"\n\n#ifndef SRC_ACTIONS_LOG_DATA_H_\n#define SRC_ACTIONS_LOG_DATA_H_\n\nclass Transaction;\n\nnamespace modsecurity {\nclass Transaction;\nnamespace actions {\n\n\nclass LogData : public Action {\n public:\n    explicit LogData(const std::string &action) \n        : Action(action) { }\n\n    explicit LogData(std::unique_ptr<RunTimeString> z)\n        : Action(\"logdata\"),\n            m_string(std::move(z)) { }\n\n    bool evaluate(RuleWithActions *rule, Transaction *transaction, RuleMessage &ruleMessage) override;\n\n    std::string data(Transaction *Transaction);\n\n    std::unique_ptr<RunTimeString> m_string;\n};\n\n\n}  // namespace actions\n}  // namespace modsecurity\n\n#endif  // SRC_ACTIONS_LOG_DATA_H_\n"
  },
  {
    "path": "src/actions/maturity.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"src/actions/maturity.h\"\n\n#include \"modsecurity/rule_with_actions.h\"\n\n\nnamespace modsecurity::actions {\n\n\nbool Maturity::init(std::string *error) {\n    try {\n        m_maturity = std::stoi(m_parser_payload);\n    }  catch (...) {\n        error->assign(\"Maturity: The input \\\"\" + m_parser_payload + \"\\\" is \" \\\n            \"not a number.\");\n        return false;\n    }\n    return true;\n}\n\n\nbool Maturity::evaluate(RuleWithActions *rule, Transaction *transaction) {\n    rule->m_maturity = m_maturity;\n    return true;\n}\n\n\n}  // namespace modsecurity::actions\n"
  },
  {
    "path": "src/actions/maturity.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <string>\n\n#include \"modsecurity/actions/action.h\"\n\n#ifndef SRC_ACTIONS_MATURITY_H_\n#define SRC_ACTIONS_MATURITY_H_\n\nclass Transaction;\n\nnamespace modsecurity {\nclass Transaction;\nnamespace actions {\n\n\nclass Maturity : public Action {\n public:\n    explicit Maturity(const std::string &action) \n        : Action(action, Kind::ConfigurationKind),\n        m_maturity(0) { }\n\n    bool evaluate(RuleWithActions *rule, Transaction *transaction) override;\n    bool init(std::string *error) override;\n\n private:\n    int m_maturity;\n};\n\n\n}  // namespace actions\n}  // namespace modsecurity\n\n#endif  // SRC_ACTIONS_MATURITY_H_\n"
  },
  {
    "path": "src/actions/msg.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"src/actions/msg.h\"\n\n#include <iostream>\n#include <string>\n#include <memory>\n\n#include \"modsecurity/actions/action.h\"\n#include \"modsecurity/transaction.h\"\n#include \"modsecurity/rule.h\"\n#include \"modsecurity/rule_message.h\"\n\n/*\n * Description: Assigns a custom message to the rule or chain in which it\n * appears. The message will be logged along with every alert.\n *\n * Action Group: Meta-data\n *\n * Example:\n * SecRule &REQUEST_HEADERS:Host \"@eq 0\" \"log,id:60008,severity:2,msg:'Request Missing a Host Header'\"\n *\n * Note  : The msg information appears in the error and/or audit log files\n *         and is not sent back to the client in response headers.\n *\n * Note 2: The msg action can appear multiple times in the SecRule, however\n *         just the last one will be take into consideration.\n *\n */\n\n\nnamespace modsecurity {\nnamespace actions {\n\n\nbool Msg::evaluate(RuleWithActions *rule, Transaction *transaction, RuleMessage &ruleMessage) {\n    const auto msg = data(transaction);\n    ruleMessage.m_message = msg;\n    ms_dbg_a(transaction, 9, \"Saving msg: \" + msg);\n\n    return true;\n}\n\n\nstd::string Msg::data(Transaction *t) {\n    std::string a(m_string->evaluate(t));\n    return a;\n}\n\n\n}  // namespace actions\n}  // namespace modsecurity\n"
  },
  {
    "path": "src/actions/msg.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <string>\n#include <memory>\n#include <utility>\n\n#include \"modsecurity/actions/action.h\"\n#include \"modsecurity/rule_message.h\"\n#include \"src/run_time_string.h\"\n\n#ifndef SRC_ACTIONS_MSG_H_\n#define SRC_ACTIONS_MSG_H_\n\nclass Transaction;\n\nnamespace modsecurity {\nclass Transaction;\nnamespace actions {\n\n\nclass Msg : public Action {\n public:\n    explicit Msg(const std::string &action) \n        : Action(action) { }\n\n    explicit Msg(std::unique_ptr<RunTimeString> z)\n        : Action(\"msg\"),\n            m_string(std::move(z)) { }\n\n    bool evaluate(RuleWithActions *rule, Transaction *transaction, RuleMessage &ruleMessage) override;\n\n    std::string data(Transaction *Transaction);\n    std::unique_ptr<RunTimeString> m_string;\n};\n\n\n}  // namespace actions\n}  // namespace modsecurity\n\n#endif  // SRC_ACTIONS_MSG_H_\n"
  },
  {
    "path": "src/actions/multi_match.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"src/actions/multi_match.h\"\n\n#include <iostream>\n#include <string>\n\n#include \"modsecurity/transaction.h\"\n#include \"modsecurity/rule.h\"\n\nnamespace modsecurity {\nnamespace actions {\n\n\nbool MultiMatch::evaluate(RuleWithActions *rule, Transaction *transaction) {\n    return true;\n}\n\n\n}  // namespace actions\n}  // namespace modsecurity\n"
  },
  {
    "path": "src/actions/multi_match.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <string>\n\n#include \"modsecurity/actions/action.h\"\n\n#ifndef SRC_ACTIONS_MULTI_MATCH_H_\n#define SRC_ACTIONS_MULTI_MATCH_H_\n\n#ifdef __cplusplus\nclass Transaction;\n\nnamespace modsecurity {\nclass Transaction;\nclass RuleWithOperator;\n\nnamespace actions {\n\n\nclass MultiMatch : public Action {\n public:\n    explicit MultiMatch(const std::string &action) \n        : Action(action) { }\n\n    bool evaluate(RuleWithActions *rule, Transaction *transaction) override;\n};\n\n}  // namespace actions\n}  // namespace modsecurity\n#endif\n\n#endif  // SRC_ACTIONS_MULTI_MATCH_H_\n"
  },
  {
    "path": "src/actions/no_audit_log.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"src/actions/no_audit_log.h\"\n\n#include <iostream>\n#include <string>\n\n#include \"modsecurity/transaction.h\"\n#include \"modsecurity/rule.h\"\n#include \"modsecurity/rule_message.h\"\n\nnamespace modsecurity {\nnamespace actions {\n\n\nbool NoAuditLog::evaluate(RuleWithActions *rule, Transaction *transaction, RuleMessage &ruleMessage) {\n    ruleMessage.m_noAuditLog = true;\n    ruleMessage.m_saveMessage = false;\n\n    return true;\n}\n\n\n}  // namespace actions\n}  // namespace modsecurity\n"
  },
  {
    "path": "src/actions/no_audit_log.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <string>\n#include <memory>\n\n#include \"modsecurity/actions/action.h\"\n\n#ifndef SRC_ACTIONS_NO_AUDIT_LOG_H_\n#define SRC_ACTIONS_NO_AUDIT_LOG_H_\n\n#ifdef __cplusplus\nclass Transaction;\n\nnamespace modsecurity {\nclass Transaction;\n\nnamespace actions {\n\n\nclass NoAuditLog : public Action {\n public:\n    explicit NoAuditLog(const std::string &action) \n        : Action(action) { }\n\n    bool evaluate(RuleWithActions *rule, Transaction *transaction, RuleMessage &ruleMessage) override;\n};\n\n}  // namespace actions\n}  // namespace modsecurity\n#endif\n\n#endif  // SRC_ACTIONS_NO_AUDIT_LOG_H_\n"
  },
  {
    "path": "src/actions/no_log.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"src/actions/no_log.h\"\n\n#include <iostream>\n#include <string>\n#include <memory>\n\n#include \"modsecurity/actions/action.h\"\n#include \"modsecurity/transaction.h\"\n#include \"src/operators/operator.h\"\n#include \"modsecurity/rule_message.h\"\n\n\nnamespace modsecurity {\nnamespace actions {\n\n\nbool NoLog::evaluate(RuleWithActions *rule, Transaction *transaction, RuleMessage &ruleMessage) {\n    ruleMessage.m_saveMessage = false;\n    return true;\n}\n\n\n}  // namespace actions\n}  // namespace modsecurity\n"
  },
  {
    "path": "src/actions/no_log.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <string>\n#include <memory>\n\n#include \"modsecurity/actions/action.h\"\n\n#ifndef SRC_ACTIONS_NO_LOG_H_\n#define SRC_ACTIONS_NO_LOG_H_\n\nclass Transaction;\n\nnamespace modsecurity {\nclass Transaction;\nnamespace actions {\n\n\nclass NoLog : public Action {\n public:\n    explicit NoLog(const std::string &action) \n        : Action(action) { }\n\n    bool evaluate(RuleWithActions *rule, Transaction *transaction, RuleMessage &ruleMessage) override;\n};\n\n}  // namespace actions\n}  // namespace modsecurity\n\n\n#endif  // SRC_ACTIONS_NO_LOG_H_\n"
  },
  {
    "path": "src/actions/phase.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"src/actions/phase.h\"\n\n#include \"modsecurity/rule_with_actions.h\"\n#include \"src/utils/string.h\"\n\n\nnamespace modsecurity::actions {\n\n\nbool Phase::init(std::string *error) {\n    const auto a = utils::string::tolower(m_parser_payload);\n    m_phase = -1;\n\n    try {\n        m_phase = std::stoi(m_parser_payload);\n        if (m_phase == 0) {\n            m_phase = modsecurity::Phases::ConnectionPhase;\n            m_secRulesPhase = 0;\n        } else if (m_phase == 1) {\n            m_phase = modsecurity::Phases::RequestHeadersPhase;\n            m_secRulesPhase = 1;\n        } else if (m_phase == 2) {\n            m_phase = modsecurity::Phases::RequestBodyPhase;\n            m_secRulesPhase = 2;\n        } else if (m_phase == 3) {\n            m_phase = modsecurity::Phases::ResponseHeadersPhase;\n            m_secRulesPhase = 3;\n        } else if (m_phase == 4) {\n            m_phase = modsecurity::Phases::ResponseBodyPhase;\n            m_secRulesPhase = 4;\n        } else if (m_phase == 5) {\n            m_phase = modsecurity::Phases::LoggingPhase;\n            m_secRulesPhase = 5;\n        } else {\n            error->assign(\"Unknown phase: \" + m_parser_payload);\n            return false;\n        }\n    } catch (...) {\n        if (a == \"request\") {\n            m_phase = modsecurity::Phases::RequestBodyPhase;\n            m_secRulesPhase = 2;\n        } else if (a == \"response\") {\n            m_phase = modsecurity::Phases::ResponseBodyPhase;\n            m_secRulesPhase = 4;\n        } else if (a == \"logging\") {\n            m_phase = modsecurity::Phases::LoggingPhase;\n            m_secRulesPhase = 5;\n        }\n    }\n\n    return true;\n}\n\n\nbool Phase::evaluate(RuleWithActions *rule, Transaction *transaction) {\n    rule->setPhase(m_phase);\n    return true;\n}\n\n\n}  // namespace modsecurity::actions\n"
  },
  {
    "path": "src/actions/phase.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <string>\n\n#include \"modsecurity/actions/action.h\"\n\n#ifndef SRC_ACTIONS_PHASE_H_\n#define SRC_ACTIONS_PHASE_H_\n\n#ifdef __cplusplus\nclass Transaction;\n\nnamespace modsecurity {\nclass Transaction;\nclass RuleWithOperator;\n\nnamespace actions {\n\n\nclass Phase : public Action {\n public:\n    explicit Phase(const std::string &action) : Action(action, Kind::ConfigurationKind),\n        m_phase(0),\n        m_secRulesPhase(0) { }\n\n    bool init(std::string *error) override;\n    bool evaluate(RuleWithActions *rule, Transaction *transaction) override;\n\n    int m_phase;\n    int m_secRulesPhase;\n};\n\n}  // namespace actions\n}  // namespace modsecurity\n#endif\n\n#endif  // SRC_ACTIONS_PHASE_H_\n"
  },
  {
    "path": "src/actions/rev.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"src/actions/rev.h\"\n\n#include \"modsecurity/rule_with_actions.h\"\n\n\nnamespace modsecurity::actions {\n\n\nbool Rev::init(std::string *error) {\n    m_rev = m_parser_payload;\n    return true;\n}\n\n\nbool Rev::evaluate(RuleWithActions *rule, Transaction *transaction) {\n    rule->m_rev = m_rev;\n    return true;\n}\n\n\n}  // namespace modsecurity::actions\n"
  },
  {
    "path": "src/actions/rev.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <string>\n\n#include \"modsecurity/actions/action.h\"\n\n#ifndef SRC_ACTIONS_REV_H_\n#define SRC_ACTIONS_REV_H_\n\nclass Transaction;\n\nnamespace modsecurity {\nclass Transaction;\nnamespace actions {\n\n\nclass Rev : public Action {\n public:\n    explicit Rev(const std::string &action) : Action(action, Kind::ConfigurationKind) { }\n\n    bool evaluate(RuleWithActions *rule, Transaction *transaction) override;\n    bool init(std::string *error) override;\n\n private:\n    std::string m_rev;\n};\n\n\n}  // namespace actions\n}  // namespace modsecurity\n\n#endif  // SRC_ACTIONS_REV_H_\n"
  },
  {
    "path": "src/actions/rule_id.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"src/actions/rule_id.h\"\n\n#include \"modsecurity/rule_with_actions.h\"\n\n\nnamespace modsecurity::actions {\n\n\nbool RuleId::init(std::string *error) {\n    std::string a = m_parser_payload;\n\n    try {\n        m_ruleId = std::stod(a);\n    } catch (...) {\n        m_ruleId = 0;\n        error->assign(\"The input \\\"\" + a + \"\\\" does not \" \\\n            \"seems to be a valid rule id.\");\n        return false;\n    }\n\n    std::ostringstream oss;\n    oss << std::setprecision(40) << m_ruleId;\n    if (a != oss.str() || m_ruleId < 0) {\n        error->assign(\"The input \\\"\" + a + \"\\\" does not seems \" \\\n            \"to be a valid rule id.\");\n        return false;\n    }\n    return true;\n}\n\n\nbool RuleId::evaluate(RuleWithActions *rule, Transaction *transaction) {\n    rule->m_ruleId = m_ruleId;\n    return true;\n}\n\n\n}  // namespace modsecurity::actions\n"
  },
  {
    "path": "src/actions/rule_id.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <string>\n\n#include \"modsecurity/actions/action.h\"\n\n#ifndef SRC_ACTIONS_RULE_ID_H_\n#define SRC_ACTIONS_RULE_ID_H_\n\n#ifdef __cplusplus\nclass Transaction;\n\nnamespace modsecurity {\nclass Transaction;\nclass RuleWithOperator;\n\nnamespace actions {\n\n\nclass RuleId : public Action {\n public:\n    explicit RuleId(const std::string &action) \n        : Action(action, Kind::ConfigurationKind),\n        m_ruleId(0) { }\n\n    bool init(std::string *error) override;\n    bool evaluate(RuleWithActions *rule, Transaction *transaction) override;\n\n private:\n    double m_ruleId;\n};\n\n}  // namespace actions\n}  // namespace modsecurity\n#endif\n\n#endif  // SRC_ACTIONS_RULE_ID_H_\n"
  },
  {
    "path": "src/actions/set_env.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"src/actions/set_env.h\"\n\n#include <iostream>\n#include <string>\n\n#include \"modsecurity/transaction.h\"\n#include \"modsecurity/rule.h\"\n#include \"src/utils/string.h\"\n\nnamespace modsecurity {\nnamespace actions {\n\n\nbool SetENV::evaluate(RuleWithActions *rule, Transaction *t) {\n    std::string colNameExpanded(m_string->evaluate(t));\n\n    auto pair = utils::string::ssplit_pair(colNameExpanded, '=');\n    ms_dbg_a(t, 8, \"Setting environment variable: \"\n        + pair.first + \" to \" + pair.second);\n#ifndef WIN32\n    setenv(pair.first.c_str(), pair.second.c_str(), /*overwrite*/ 1);\n#else\n    _putenv_s(pair.first.c_str(), pair.second.c_str());\n#endif\n\n    return true;\n}\n\n}  // namespace actions\n}  // namespace modsecurity\n"
  },
  {
    "path": "src/actions/set_env.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <string>\n#include <utility>\n#include <memory>\n\n#include \"modsecurity/actions/action.h\"\n#include \"src/run_time_string.h\"\n\n#ifndef SRC_ACTIONS_SET_ENV_H_\n#define SRC_ACTIONS_SET_ENV_H_\n\nclass Transaction;\n\nnamespace modsecurity {\nclass Transaction;\nnamespace actions {\n\n\nclass SetENV : public Action {\n public:\n    explicit SetENV(const std::string &_action)\n        : Action(_action) { }\n\n    explicit SetENV(std::unique_ptr<RunTimeString> z)\n        : Action(\"setenv\"),\n            m_string(std::move(z)) { }\n\n    bool evaluate(RuleWithActions *rule, Transaction *transaction) override;\n\n private:\n    std::unique_ptr<RunTimeString> m_string;\n};\n\n\n}  // namespace actions\n}  // namespace modsecurity\n\n#endif  // SRC_ACTIONS_SET_ENV_H_\n"
  },
  {
    "path": "src/actions/set_rsc.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"src/actions/set_rsc.h\"\n\n#include <iostream>\n#include <string>\n\n#include \"modsecurity/transaction.h\"\n#include \"modsecurity/rule.h\"\n\n\nnamespace modsecurity {\nnamespace actions {\n\n\nbool SetRSC::evaluate(RuleWithActions *rule, Transaction *t) {\n    std::string colNameExpanded(m_string->evaluate(t));\n    ms_dbg_a(t, 8, \"RESOURCE initiated with value: \\'\"\n        + colNameExpanded + \"\\'.\");\n\n    t->m_collections.m_resource_collection_key = colNameExpanded;\n    t->m_variableResource.set(colNameExpanded, t->m_variableOffset);\n\n    return true;\n}\n\n}  // namespace actions\n}  // namespace modsecurity\n"
  },
  {
    "path": "src/actions/set_rsc.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <string>\n#include <utility>\n#include <memory>\n\n#include \"modsecurity/actions/action.h\"\n#include \"src/run_time_string.h\"\n\n#ifndef SRC_ACTIONS_SET_RSC_H_\n#define SRC_ACTIONS_SET_RSC_H_\n\nclass Transaction;\n\nnamespace modsecurity {\nclass Transaction;\nnamespace actions {\n\n\nclass SetRSC : public Action {\n public:\n    explicit SetRSC(const std::string &_action)\n        : Action(_action) { }\n\n    explicit SetRSC(std::unique_ptr<RunTimeString> z)\n        : Action(\"setsrc\"),\n            m_string(std::move(z)) { }\n\n    bool evaluate(RuleWithActions *rule, Transaction *transaction) override;\n\n private:\n    std::unique_ptr<RunTimeString> m_string;\n};\n\n\n}  // namespace actions\n}  // namespace modsecurity\n\n#endif  // SRC_ACTIONS_SET_RSC_H_\n"
  },
  {
    "path": "src/actions/set_sid.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"src/actions/set_sid.h\"\n\n#include <iostream>\n#include <string>\n\n#include \"modsecurity/transaction.h\"\n#include \"modsecurity/rule.h\"\n\n\nnamespace modsecurity {\nnamespace actions {\n\n\nbool SetSID::evaluate(RuleWithActions *rule, Transaction *t) {\n    std::string colNameExpanded(m_string->evaluate(t));\n    ms_dbg_a(t, 8, \"Session ID initiated with value: \\'\"\n        + colNameExpanded + \"\\'.\");\n\n    t->m_collections.m_session_collection_key = colNameExpanded;\n    t->m_variableSessionID.set(colNameExpanded, t->m_variableOffset);\n\n    return true;\n}\n\n}  // namespace actions\n}  // namespace modsecurity\n"
  },
  {
    "path": "src/actions/set_sid.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <string>\n#include <utility>\n#include <memory>\n\n#include \"modsecurity/actions/action.h\"\n#include \"src/run_time_string.h\"\n\n#ifndef SRC_ACTIONS_SET_SID_H_\n#define SRC_ACTIONS_SET_SID_H_\n\nclass Transaction;\n\nnamespace modsecurity {\nclass Transaction;\nnamespace actions {\n\n\nclass SetSID : public Action {\n public:\n    explicit SetSID(const std::string &_action)\n        : Action(_action) { }\n\n    explicit SetSID(std::unique_ptr<RunTimeString> z)\n        : Action(\"setsid\"),\n            m_string(std::move(z)) { }\n\n    bool evaluate(RuleWithActions *rule, Transaction *transaction) override;\n\n private:\n    std::unique_ptr<RunTimeString> m_string;\n};\n\n\n}  // namespace actions\n}  // namespace modsecurity\n\n#endif  // SRC_ACTIONS_SET_SID_H_\n"
  },
  {
    "path": "src/actions/set_uid.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"src/actions/set_uid.h\"\n\n#include <iostream>\n#include <string>\n\n#include \"modsecurity/transaction.h\"\n#include \"modsecurity/rule.h\"\n\n\nnamespace modsecurity {\nnamespace actions {\n\n\nbool SetUID::evaluate(RuleWithActions *rule, Transaction *t) {\n    std::string colNameExpanded(m_string->evaluate(t));\n    ms_dbg_a(t, 8, \"User collection initiated with value: \\'\"\n        + colNameExpanded + \"\\'.\");\n\n    t->m_collections.m_user_collection_key = colNameExpanded;\n    t->m_variableUserID.set(colNameExpanded, t->m_variableOffset);\n\n    return true;\n}\n\n}  // namespace actions\n}  // namespace modsecurity\n"
  },
  {
    "path": "src/actions/set_uid.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <string>\n#include <memory>\n#include <utility>\n\n#include \"modsecurity/actions/action.h\"\n#include \"src/run_time_string.h\"\n\n#ifndef SRC_ACTIONS_SET_UID_H_\n#define SRC_ACTIONS_SET_UID_H_\n\nclass Transaction;\n\nnamespace modsecurity {\nclass Transaction;\nnamespace actions {\n\n\nclass SetUID : public Action {\n public:\n    explicit SetUID(const std::string &_action)\n        : Action(_action) { }\n\n    explicit SetUID(std::unique_ptr<RunTimeString> z)\n        : Action(\"setuid\"),\n            m_string(std::move(z)) { }\n\n    bool evaluate(RuleWithActions *rule, Transaction *transaction) override;\n\n private:\n    std::unique_ptr<RunTimeString> m_string;\n};\n\n\n}  // namespace actions\n}  // namespace modsecurity\n\n#endif  // SRC_ACTIONS_SET_UID_H_\n"
  },
  {
    "path": "src/actions/set_var.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"src/actions/set_var.h\"\n\n#include <iostream>\n#include <string>\n#include <memory>\n\n#include \"modsecurity/rules_set.h\"\n#include \"modsecurity/transaction.h\"\n#include \"modsecurity/rule.h\"\n#include \"src/utils/string.h\"\n#include \"src/variables/global.h\"\n#include \"src/variables/ip.h\"\n#include \"src/variables/resource.h\"\n#include \"src/variables/session.h\"\n#include \"src/variables/tx.h\"\n#include \"src/variables/user.h\"\n#include \"src/variables/variable.h\"\n\nnamespace modsecurity {\nnamespace actions {\n\n\nbool SetVar::evaluate(RuleWithActions *rule, Transaction *t) {\n    std::string targetValue;\n    std::string resolvedPre;\n\n    if (m_string) {\n        resolvedPre = m_string->evaluate(t, rule);\n    }\n\n    std::string m_variableNameExpanded;\n\n    auto *v = m_variable.get();\n    auto tx = dynamic_cast<variables::Tx_DynamicElement *> (v);\n    auto session = dynamic_cast<variables::Session_DynamicElement *> (v);\n    auto ip = dynamic_cast<variables::Ip_DynamicElement *> (v);\n    auto resource = dynamic_cast<variables::Resource_DynamicElement *> (v);\n    auto global = dynamic_cast<variables::Global_DynamicElement *> (v);\n    auto user = dynamic_cast<variables::User_DynamicElement *> (v);\n    if (tx) {\n        m_variableNameExpanded = tx->m_string->evaluate(t, rule);\n    } else if (session) {\n        m_variableNameExpanded = session->m_string->evaluate(t, rule);\n    } else if (ip) {\n        m_variableNameExpanded = ip->m_string->evaluate(t, rule);\n    } else if (resource) {\n        m_variableNameExpanded = resource->m_string->evaluate(t, rule);\n    } else if (global) {\n        m_variableNameExpanded = global->m_string->evaluate(t, rule);\n    } else if (user) {\n        m_variableNameExpanded = user->m_string->evaluate(t, rule);\n    } else {\n        m_variableNameExpanded = m_variable->m_name;\n    }\n\n    if (m_operation == setOperation) {\n        targetValue = resolvedPre;\n    } else if (m_operation == setToOneOperation) {\n        targetValue = std::string(\"1\");\n    } else if (m_operation == unsetOperation) {\n        if (tx) {\n            tx->del(t, m_variableNameExpanded);\n        } else if (session) {\n            session->del(t, m_variableNameExpanded);\n        } else if (ip) {\n            ip->del(t, m_variableNameExpanded);\n        } else if (resource) {\n            resource->del(t, m_variableNameExpanded);\n        } else if (global) {\n            global->del(t, m_variableNameExpanded);\n        } else if (user) {\n            user->del(t, m_variableNameExpanded);\n        } else {\n            // ?\n        }\n        goto end;\n    } else {\n        int pre = 0;\n        int value = 0;\n\n        try {\n            pre = stoi(resolvedPre);\n        } catch (...) {\n            pre = 0;\n        }\n\n        try {\n            std::vector<const VariableValue *> l;\n            RuleWithOperator *rr = dynamic_cast<RuleWithOperator *>(rule);\n            m_variable->evaluate(t, rr, &l);\n            if (l.size() == 0) {\n                value = 0;\n            } else {\n                value = stoi(l[0]->getValue());\n                for (auto &i : l) {\n                    delete i;\n                }\n            }\n        } catch (...) {\n            value = 0;\n        }\n\n        if (m_operation == sumAndSetOperation) {\n            targetValue = std::to_string(value + pre);\n        } else if (m_operation == substractAndSetOperation) {\n            targetValue = std::to_string(value - pre);\n        }\n    }\n\n    ms_dbg_a(t, 8, \"Saving variable: \" + m_variable->m_collectionName \\\n        + \":\" + m_variableNameExpanded + \" with value: \" + targetValue);\n\n    if (tx) {\n        tx->storeOrUpdateFirst(t, m_variableNameExpanded, targetValue);\n    } else if (session) {\n        session->storeOrUpdateFirst(t, m_variableNameExpanded, targetValue);\n    } else if (ip) {\n        ip->storeOrUpdateFirst(t, m_variableNameExpanded, targetValue);\n    } else if (resource) {\n        resource->storeOrUpdateFirst(t, m_variableNameExpanded, targetValue);\n    } else if (global) {\n        global->storeOrUpdateFirst(t, m_variableNameExpanded, targetValue);\n    } else if (user) {\n        user->storeOrUpdateFirst(t, m_variableNameExpanded, targetValue);\n    } else {\n        // ?\n    }\n\n    /*\n    t->m_collections.storeOrUpdateFirst(m_variable->m_collectionName,\n        m_variableNameExpanded,\n        t->m_rules->m_secWebAppId.m_value, targetValue);\n    */\nend:\n    return true;\n}\n\n}  // namespace actions\n}  // namespace modsecurity\n"
  },
  {
    "path": "src/actions/set_var.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <memory>\n#include <string>\n#include <utility>\n\n#include \"modsecurity/actions/action.h\"\n#include \"src/run_time_string.h\"\n\n#ifndef SRC_ACTIONS_SET_VAR_H_\n#define SRC_ACTIONS_SET_VAR_H_\n\nnamespace modsecurity {\nclass Transaction;\nclass RuleWithOperator;\n\nnamespace actions {\n\nenum SetVarOperation {\n    /* Set variable to something */\n    setOperation,\n    /* read variable, sum predicate and set */\n    sumAndSetOperation,\n    /* read variable, substract predicate and set */\n    substractAndSetOperation,\n    /* set variable to 1 */\n    setToOneOperation,\n    /* unset operation */\n    unsetOperation,\n};\n\nclass SetVar : public Action {\n public:\n    SetVar(SetVarOperation operation,\n        std::unique_ptr<modsecurity::variables::Variable> variable,\n        std::unique_ptr<RunTimeString> predicate)\n        : Action(\"setvar\"),\n        m_operation(operation),\n        m_variable(std::move(variable)),\n        m_string(std::move(predicate)) { }\n\n    SetVar(SetVarOperation operation,\n        std::unique_ptr<modsecurity::variables::Variable> variable)\n        : Action(\"setvar\"),\n        m_operation(operation),\n        m_variable(std::move(variable)) { }\n\n    bool evaluate(RuleWithActions *rule, Transaction *transaction) override;\n\n private:\n    SetVarOperation m_operation;\n    std::unique_ptr<modsecurity::variables::Variable> m_variable;\n    std::unique_ptr<RunTimeString> m_string;\n};\n\n}  // namespace actions\n}  // namespace modsecurity\n\n\n#endif  // SRC_ACTIONS_SET_VAR_H_\n"
  },
  {
    "path": "src/actions/severity.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"src/actions/severity.h\"\n\n#include <iostream>\n#include <string>\n#include <memory>\n\n#include \"modsecurity/rules_set.h\"\n#include \"modsecurity/actions/action.h\"\n#include \"modsecurity/transaction.h\"\n#include \"modsecurity/rule.h\"\n#include \"src/utils/string.h\"\n#include \"modsecurity/rule_message.h\"\n\n\nnamespace modsecurity {\nnamespace actions {\n\n\nbool Severity::init(std::string *error) {\n    std::string a = utils::string::tolower(m_parser_payload);\n    if (a == \"emergency\") {\n        m_severity = 0;\n        return true;\n    } else if (a == \"alert\") {\n        m_severity = 1;\n        return true;\n    } else if (a == \"critical\") {\n        m_severity = 2;\n        return true;\n    } else if (a == \"error\") {\n        m_severity = 3;\n        return true;\n    } else if (a == \"warning\") {\n        m_severity = 4;\n        return true;\n    } else if (a == \"notice\") {\n        m_severity = 5;\n        return true;\n    } else if (a == \"info\") {\n        m_severity = 6;\n        return true;\n    } else if (a == \"debug\") {\n        m_severity = 7;\n        return true;\n    } else {\n        try {\n            m_severity = std::stoi(a);\n            return true;\n        }  catch (...) {\n            error->assign(\"Severity: The input \\\"\" + a + \"\\\" is \" \\\n                \"not a number.\");\n        }\n    }\n\n    return false;\n}\n\n\nbool Severity::evaluate(RuleWithActions *rule, Transaction *transaction, RuleMessage &ruleMessage) {\n    ms_dbg_a(transaction, 9, \"This rule severity is: \" + \\\n        std::to_string(this->m_severity) + \" current transaction is: \" + \\\n        std::to_string(transaction->m_highestSeverityAction));\n\n    ruleMessage.m_severity = m_severity;\n\n    if (transaction->m_highestSeverityAction > this->m_severity) {\n        transaction->m_highestSeverityAction = this->m_severity;\n    }\n\n    return true;\n}\n\n\n}  // namespace actions\n}  // namespace modsecurity\n"
  },
  {
    "path": "src/actions/severity.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <string>\n#include <memory>\n\n#include \"modsecurity/actions/action.h\"\n\n#ifndef SRC_ACTIONS_SEVERITY_H_\n#define SRC_ACTIONS_SEVERITY_H_\n\n#ifdef __cplusplus\n\nnamespace modsecurity {\nclass Transaction;\n\nnamespace actions {\n\n\nclass Severity : public Action {\n public:\n    explicit Severity(const std::string &action) \n        : Action(action),\n        m_severity(0) { }\n\n    bool evaluate(RuleWithActions *rule, Transaction *transaction, RuleMessage &ruleMessage) override;\n    bool init(std::string *error) override;\n\n    int m_severity;\n};\n\n\n}  // namespace actions\n}  // namespace modsecurity\n#endif\n\n#endif  // SRC_ACTIONS_SEVERITY_H_\n"
  },
  {
    "path": "src/actions/skip.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"src/actions/skip.h\"\n\n#include <iostream>\n#include <string>\n\n#include \"modsecurity/rules_set.h\"\n#include \"modsecurity/actions/action.h\"\n#include \"modsecurity/transaction.h\"\n\nnamespace modsecurity {\nnamespace actions {\n\n\nbool Skip::init(std::string *error) {\n    try {\n        m_skip_next = std::stoi(m_parser_payload);\n    }  catch (...) {\n        error->assign(\"Skip: The input \\\"\" + m_parser_payload + \"\\\" is \" \\\n            \"not a number.\");\n        return false;\n    }\n    return true;\n}\n\n\nbool Skip::evaluate(RuleWithActions *rule, Transaction *transaction) {\n    ms_dbg_a(transaction, 5, \"Skipping the next \" + \\\n        std::to_string(m_skip_next) + \" rules.\");\n\n    transaction->m_skip_next = m_skip_next;\n\n    return true;\n}\n\n\n}  // namespace actions\n}  // namespace modsecurity\n"
  },
  {
    "path": "src/actions/skip.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <string>\n\n#include \"modsecurity/actions/action.h\"\n\n#ifndef SRC_ACTIONS_SKIP_H_\n#define SRC_ACTIONS_SKIP_H_\n\nclass Transaction;\n\nnamespace modsecurity {\nclass Transaction;\nnamespace actions {\n\n\nclass Skip : public Action {\n public:\n    explicit Skip(const std::string &action) \n        : Action(action),\n        m_skip_next(0) { }\n\n    bool init(std::string *error) override;\n    bool evaluate(RuleWithActions *rule, Transaction *transaction) override;\n\n    int m_skip_next;\n};\n\n\n}  // namespace actions\n}  // namespace modsecurity\n\n#endif  // SRC_ACTIONS_SKIP_H_\n"
  },
  {
    "path": "src/actions/skip_after.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"src/actions/skip_after.h\"\n\n#include <iostream>\n#include <string>\n\n#include \"modsecurity/rules_set.h\"\n#include \"modsecurity/actions/action.h\"\n#include \"modsecurity/transaction.h\"\n\n\nnamespace modsecurity {\nnamespace actions {\n\n\nbool SkipAfter::evaluate(RuleWithActions *rule, Transaction *transaction) {\n    ms_dbg_a(transaction, 5, \"Setting skipAfter for: \" + *m_skipName);\n    transaction->addMarker(m_skipName);\n    return true;\n}\n\n\n}  // namespace actions\n}  // namespace modsecurity\n"
  },
  {
    "path": "src/actions/skip_after.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <string>\n#include <memory>\n\n#include \"modsecurity/actions/action.h\"\n\n#ifndef SRC_ACTIONS_SKIP_AFTER_H_\n#define SRC_ACTIONS_SKIP_AFTER_H_\n\nclass Transaction;\n\nnamespace modsecurity {\nclass Transaction;\nnamespace actions {\n\n\nclass SkipAfter : public Action {\n public:\n    explicit SkipAfter(const std::string &action) \n        : Action(action),\n        m_skipName(std::make_shared<std::string>(m_parser_payload)) { }\n\n    bool evaluate(RuleWithActions *rule, Transaction *transaction) override;\n private:\n     std::shared_ptr<std::string> m_skipName;\n};\n\n\n}  // namespace actions\n}  // namespace modsecurity\n\n#endif  // SRC_ACTIONS_SKIP_AFTER_H_\n"
  },
  {
    "path": "src/actions/tag.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"src/actions/tag.h\"\n\n#include <iostream>\n#include <string>\n#include <memory>\n\n#include \"modsecurity/actions/action.h\"\n#include \"modsecurity/transaction.h\"\n#include \"modsecurity/rule.h\"\n#include \"modsecurity/rule_message.h\"\n\n#ifdef MSC_DOCUMENTATION\n/**\n * Description: Assigns a tag (category) to a rule or a chain.\n *\n * Action Group: Meta-data\n *\n * Example:\n *\n * SecRule REQUEST_FILENAME|ARGS_NAMES|ARGS|XML:/* \"\\bgetparentfolder\\b\" \\\n *         \"phase:2,rev:'2.1.3',capture,t:none,t:htmlEntityDecode,t:compressWhiteSpace,t:lowercase,ctl:auditLogParts=+E,block,msg:'Cross-site Scripting (XSS) Attack',id:'958016',tag:'WEB_ATTACK/XSS',tag:'WASCTC/WASC-8',tag:'WASCTC/WASC-22',tag:'OWASP_TOP_10/A2',tag:'OWASP_AppSensor/IE1',tag:'PCI/6.5.1',logdata:'% \\\n *         {TX.0}',severity:'2',setvar:'tx.msg=%{rule.msg}',setvar:tx.xss_score=+%{tx.critical_anomaly_score},setvar:tx.anomaly_score=+%{tx.critical_anomaly_score},setvar:tx.%{rule.id}-WEB_ATTACK/XSS-%{matched_var_name}=%{tx.0}\"\n *\n *\n * The tag information appears along with other rule metadata. The\n * purpose of the tagging mechanism to allow easy automated categorization\n * of events. Multiple tags can be specified on the same rule. Use forward\n * slashes to create a hierarchy of categories (as in the example). Since\n * ModSecurity 2.6.0 tag supports macro expansion.\n *\n *\n */\n#endif\n\nnamespace modsecurity {\nnamespace actions {\n\n\nstd::string Tag::getName(Transaction *transaction) {\n    std::string tag(m_string->evaluate(transaction));\n    return tag;\n}\n\n\nbool Tag::evaluate(RuleWithActions *rule, Transaction *transaction, RuleMessage &ruleMessage) {\n    std::string tag = getName(transaction);\n    ms_dbg_a(transaction, 9, \"Rule tag: \" + tag);\n\n    ruleMessage.m_tags.push_back(tag);\n\n    return true;\n}\n\n\n}  // namespace actions\n}  // namespace modsecurity\n"
  },
  {
    "path": "src/actions/tag.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <string>\n#include <memory>\n#include <utility>\n\n#include \"modsecurity/actions/action.h\"\n#include \"src/run_time_string.h\"\n\n#ifndef SRC_ACTIONS_TAG_H_\n#define SRC_ACTIONS_TAG_H_\n\nclass Transaction;\n\nnamespace modsecurity {\nclass Transaction;\nnamespace actions {\n\n\nclass Tag : public Action {\n public:\n    explicit Tag(std::unique_ptr<RunTimeString> z)\n        : Action(\"tag\"),\n        m_string(std::move(z)) { }\n\n    std::string getName(Transaction *transaction);\n\n    bool evaluate(RuleWithActions *rule, Transaction *transaction, RuleMessage &ruleMessage) override;\n\n protected:\n    std::unique_ptr<RunTimeString> m_string;\n};\n\n\n}  // namespace actions\n}  // namespace modsecurity\n\n#endif  // SRC_ACTIONS_TAG_H_\n"
  },
  {
    "path": "src/actions/transformations/base64_decode.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"base64_decode.h\"\n\n#include \"src/utils/base64.h\"\n\n\nnamespace modsecurity::actions::transformations {\n\n\nbool Base64Decode::transform(std::string &value, const Transaction *trans) const {\n    if (value.empty()) return false;\n    value = Utils::Base64::decode(value);\n    return true;\n}\n\n\n}  // namespace modsecurity::actions::transformations\n"
  },
  {
    "path": "src/actions/transformations/base64_decode.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#ifndef SRC_ACTIONS_TRANSFORMATIONS_BASE64_DECODE_H_\n#define SRC_ACTIONS_TRANSFORMATIONS_BASE64_DECODE_H_\n\n#include \"transformation.h\"\n\nnamespace modsecurity::actions::transformations {\n\nclass Base64Decode : public Transformation {\n public:\n    using Transformation::Transformation;\n\n    bool transform(std::string &value, const Transaction *trans) const override;\n};\n\n}  // namespace modsecurity::actions::transformations\n\n#endif  // SRC_ACTIONS_TRANSFORMATIONS_BASE64_DECODE_H_\n"
  },
  {
    "path": "src/actions/transformations/base64_decode_ext.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"base64_decode_ext.h\"\n\n#include \"src/utils/base64.h\"\n\n\nnamespace modsecurity::actions::transformations {\n\n\nbool Base64DecodeExt::transform(std::string &value, const Transaction *trans) const {\n    if (value.empty()) return false;\n    value = Utils::Base64::decode_forgiven(value);\n    return true;\n}\n\n\n}  // namespace modsecurity::actions::transformations\n"
  },
  {
    "path": "src/actions/transformations/base64_decode_ext.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#ifndef SRC_ACTIONS_TRANSFORMATIONS_BASE64_DECODE_EXT_H_\n#define SRC_ACTIONS_TRANSFORMATIONS_BASE64_DECODE_EXT_H_\n\n#include \"transformation.h\"\n\nnamespace modsecurity::actions::transformations {\n\nclass Base64DecodeExt : public Transformation {\n public:\n    using Transformation::Transformation;\n\n    bool transform(std::string &value, const Transaction *trans) const override;\n};\n\n}  // namespace modsecurity::actions::transformations\n\n#endif  // SRC_ACTIONS_TRANSFORMATIONS_BASE64_DECODE_EXT_H_\n"
  },
  {
    "path": "src/actions/transformations/base64_encode.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"base64_encode.h\"\n\n#include \"src/utils/base64.h\"\n\n\nnamespace modsecurity::actions::transformations {\n\n\nbool Base64Encode::transform(std::string &value, const Transaction *trans) const {\n    if (value.empty()) return false;\n    value = Utils::Base64::encode(value);\n    return true;\n}\n\n\n}  // namespace modsecurity::actions::transformations\n"
  },
  {
    "path": "src/actions/transformations/base64_encode.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#ifndef SRC_ACTIONS_TRANSFORMATIONS_BASE64_ENCODE_H_\n#define SRC_ACTIONS_TRANSFORMATIONS_BASE64_ENCODE_H_\n\n#include \"transformation.h\"\n\nnamespace modsecurity::actions::transformations {\n\nclass Base64Encode : public Transformation {\n public:\n    using Transformation::Transformation;\n\n    bool transform(std::string &value, const Transaction *trans) const override;\n};\n\n}  // namespace modsecurity::actions::transformations\n\n#endif  // SRC_ACTIONS_TRANSFORMATIONS_BASE64_ENCODE_H_\n"
  },
  {
    "path": "src/actions/transformations/cmd_line.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"cmd_line.h\"\n\n\nnamespace modsecurity::actions::transformations {\n\n\nbool CmdLine::transform(std::string &value, const Transaction *trans) const {\n    char *d = value.data();\n    bool space = false;\n\n    for (const auto& a : value) {\n        switch (a) {\n            /* remove some characters */\n            case '\"':\n            case '\\'':\n            case '\\\\':\n            case '^':\n                break;\n\n            /* replace some characters to space (only one) */\n            case ' ':\n            case ',':\n            case ';':\n            case '\\t':\n            case '\\r':\n            case '\\n':\n                if (space == false) {\n                    *d++ = ' ';\n                    space = true;\n                }\n                break;\n\n            /* remove space before / or ( */\n            case '/':\n            case '(':\n                if (space) {\n                    d--;\n                }\n                space = false;\n                *d++ = a;\n                break;\n\n            /* copy normal characters */\n            default :\n                char b = std::tolower(a);\n                *d++ = b;\n                space = false;\n                break;\n        }\n    }\n\n    const auto new_len = d - value.c_str();\n    const auto changed = new_len != value.length();\n    value.resize(new_len);\n    return changed;\n}\n\n\n}  // namespace modsecurity::actions::transformations\n\n"
  },
  {
    "path": "src/actions/transformations/cmd_line.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#ifndef SRC_ACTIONS_TRANSFORMATIONS_CMD_LINE_H_\n#define SRC_ACTIONS_TRANSFORMATIONS_CMD_LINE_H_\n\n#include \"transformation.h\"\n\nnamespace modsecurity::actions::transformations {\n\nclass CmdLine : public Transformation {\n public:\n    using Transformation::Transformation;\n\n    bool transform(std::string &value, const Transaction *trans) const override;\n};\n\n}  // modsecurity::namespace actions::transformations\n\n#endif  // SRC_ACTIONS_TRANSFORMATIONS_CMD_LINE_H_\n\n"
  },
  {
    "path": "src/actions/transformations/compress_whitespace.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"compress_whitespace.h\"\n\n\nnamespace modsecurity::actions::transformations {\n\n\nbool CompressWhitespace::transform(std::string &value, const Transaction *trans) const {\n    bool inWhiteSpace = false;\n\n    auto d = value.data();\n\n    for(const auto c : value) {\n        if (isspace(c)) {\n            if (inWhiteSpace) {\n                continue;\n            } else {\n                inWhiteSpace = true;\n                *d++ = ' ';\n            }\n        } else {\n            inWhiteSpace = false;\n            *d++ = c;\n        }\n    }\n\n    const auto new_len = d - value.c_str();\n    const auto changed = new_len != value.length();\n    value.resize(new_len);\n    return changed;\n}\n\n\n}  // namespace modsecurity::actions::transformations\n"
  },
  {
    "path": "src/actions/transformations/compress_whitespace.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#ifndef SRC_ACTIONS_TRANSFORMATIONS_COMPRESS_WHITESPACE_H_\n#define SRC_ACTIONS_TRANSFORMATIONS_COMPRESS_WHITESPACE_H_\n\n#include \"transformation.h\"\n\nnamespace modsecurity::actions::transformations {\n\nclass CompressWhitespace : public Transformation {\n public:\n    using Transformation::Transformation;\n\n    bool transform(std::string &value, const Transaction *trans) const override;\n};\n\n}  // namespace modsecurity::actions::transformations\n\n#endif  // SRC_ACTIONS_TRANSFORMATIONS_COMPRESS_WHITESPACE_H_\n"
  },
  {
    "path": "src/actions/transformations/css_decode.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"css_decode.h\"\n\n#include \"src/utils/string.h\"\n\nusing namespace modsecurity::utils::string;\n\nnamespace modsecurity::actions::transformations {\n\n\n/**\n * Decode a string that contains CSS-escaped characters.\n *\n * References:\n *     http://www.w3.org/TR/REC-CSS2/syndata.html#q4\n *     http://www.unicode.org/roadmaps/\n */\nstatic inline bool css_decode_inplace(std::string &val) {\n    const auto input_len = val.length();\n    auto input = reinterpret_cast<unsigned char *>(val.data());\n    auto d = input;\n    bool changed = false;\n\n    std::string::size_type i = 0;\n    while (i < input_len) {\n        /* Is the character a backslash? */\n        if (input[i] == '\\\\') {\n            /* Is there at least one more byte? */\n            if (i + 1 < input_len) {\n                i++; /* We are not going to need the backslash. */\n\n                /* Check for 1-6 hex characters following the backslash */\n                std::string::size_type j = 0;\n                while ((j < 6)\n                        && (i + j < input_len)\n                        && (VALID_HEX(input[i + j]))) {\n                    j++;\n                }\n\n                if (j > 0) {\n                    /* We have at least one valid hexadecimal character. */\n                    int fullcheck = 0;\n\n                    /* For now just use the last two bytes. */\n                    switch (j) {\n                        /* Number of hex characters */\n                        case 1:\n                            *d++ = utils::string::xsingle2c(&input[i]);\n                            break;\n\n                        case 2:\n                        case 3:\n                            /* Use the last two from the end. */\n                            *d++ = utils::string::x2c(&input[i + j - 2]);\n                            break;\n\n                        case 4:\n                            /* Use the last two from the end, but request\n                             * a full width check.\n                             */\n                            *d = utils::string::x2c(&input[i + j - 2]);\n                            fullcheck = 1;\n                            break;\n\n                        case 5:\n                            /* Use the last two from the end, but request\n                             * a full width check if the number is greater\n                             * or equal to 0xFFFF.\n                             */\n                            *d = utils::string::x2c(&input[i + j - 2]);\n                            /* Do full check if first byte is 0 */\n                            if (input[i] == '0') {\n                                fullcheck = 1;\n                            } else {\n                                d++;\n                            }\n                            break;\n\n                        case 6:\n                            /* Use the last two from the end, but request\n                             * a full width check if the number is greater\n                             * or equal to 0xFFFF.\n                             */\n                            *d = utils::string::x2c(&input[i + j - 2]);\n\n                            /* Do full check if first/second bytes are 0 */\n                            if ((input[i] == '0')\n                                    && (input[i + 1] == '0')) {\n                                fullcheck = 1;\n                            } else {\n                                d++;\n                            }\n                            break;\n                    }\n\n                    /* Full width ASCII (0xff01 - 0xff5e) needs 0x20 added */\n                    if (fullcheck) {\n                        if ((*d > 0x00) && (*d < 0x5f)\n                                && ((input[i + j - 3] == 'f') ||\n                                    (input[i + j - 3] == 'F'))\n                                && ((input[i + j - 4] == 'f') ||\n                                    (input[i + j - 4] == 'F'))) {\n                            (*d) += 0x20;\n                        }\n\n                        d++;\n                    }\n\n                    /* We must ignore a single whitespace after a hex escape */\n                    if ((i + j < input_len) && isspace(input[i + j])) {\n                        j++;\n                    }\n\n                    /* Move over. */\n                    i += j;\n\n                    changed = true;\n                } else if (input[i] == '\\n') {\n                /* No hexadecimal digits after backslash */\n                    /* A newline character following backslash is ignored. */\n                    i++;\n                    changed = true;\n                } else {\n                /* The character after backslash is not a hexadecimal digit,\n                 * nor a newline. */\n                    /* Use one character after backslash as is. */\n                    *d++ = input[i++];\n                }\n            } else {\n            /* No characters after backslash. */\n                /* Do not include backslash in output\n                 *(continuation to nothing) */\n                i++;\n                changed = true;\n            }\n        } else {\n        /* Character is not a backslash. */\n            /* Copy one normal character to output. */\n            *d++ = input[i++];\n        }\n    }\n\n    /* Terminate output string. */\n    *d = '\\0';\n\n    val.resize(d - input);\n    return changed;\n}\n\n\nbool CssDecode::transform(std::string &value, const Transaction *trans) const {\n    return css_decode_inplace(value);\n}\n\n\n}  // namespace modsecurity::actions::transformations\n"
  },
  {
    "path": "src/actions/transformations/css_decode.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#ifndef SRC_ACTIONS_TRANSFORMATIONS_CSS_DECODE_H_\n#define SRC_ACTIONS_TRANSFORMATIONS_CSS_DECODE_H_\n\n#include \"transformation.h\"\n\nnamespace modsecurity::actions::transformations {\n\nclass CssDecode : public Transformation {\n public:\n    using Transformation::Transformation;\n\n    bool transform(std::string &value, const Transaction *trans) const override;\n};\n\n}  // namespace modsecurity::actions::transformations\n\n#endif  // SRC_ACTIONS_TRANSFORMATIONS_CSS_DECODE_H_\n"
  },
  {
    "path": "src/actions/transformations/escape_seq_decode.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"escape_seq_decode.h\"\n\n#include \"src/utils/string.h\"\n\nusing namespace modsecurity::utils::string;\n\nnamespace modsecurity::actions::transformations {\n\n\nstatic inline int ansi_c_sequences_decode_inplace(std::string &value) {\n    auto d = reinterpret_cast<unsigned char *>(value.data());\n    const unsigned char* input = d;\n    const auto input_len = value.length();\n\n    bool changed = false;\n    std::string::size_type i = 0;\n    while (i < input_len) {\n        if ((input[i] == '\\\\') && (i + 1 < input_len)) {\n            int c = -1;\n\n            switch (input[i + 1]) {\n                case 'a' :\n                    c = '\\a';\n                    break;\n                case 'b' :\n                    c = '\\b';\n                    break;\n                case 'f' :\n                    c = '\\f';\n                    break;\n                case 'n' :\n                    c = '\\n';\n                    break;\n                case 'r' :\n                    c = '\\r';\n                    break;\n                case 't' :\n                    c = '\\t';\n                    break;\n                case 'v' :\n                    c = '\\v';\n                    break;\n                case '\\\\' :\n                    c = '\\\\';\n                    break;\n                case '?' :\n                    c = '?';\n                    break;\n                case '\\'' :\n                    c = '\\'';\n                    break;\n                case '\"' :\n                    c = '\"';\n                    break;\n            }\n\n            if (c != -1) i += 2;\n\n            /* Hexadecimal or octal? */\n            if (c == -1) {\n                if ((input[i + 1] == 'x') || (input[i + 1] == 'X')) {\n                    /* Hexadecimal. */\n                    if ((i + 3 < input_len) && (isxdigit(input[i + 2]))\n                        && (isxdigit(input[i + 3]))) {\n                        /* Two digits. */\n                        c = utils::string::x2c(&input[i + 2]);\n                        i += 4;\n                    } else {\n                        /* Invalid encoding, do nothing. */\n                    }\n                } else {\n                    if (ISODIGIT(input[i + 1])) { /* Octal. */\n                        char buf[4];\n                        int j = 0;\n\n                        while ((i + 1 + j < input_len) && (j < 3)) {\n                            buf[j] = input[i + 1 + j];\n                            j++;\n                            if (!ISODIGIT(input[i + 1 + j])) break;\n                        }\n                        buf[j] = '\\0';\n\n                        if (j > 0) {\n                            c = strtol(buf, NULL, 8);\n                            i += 1 + j;\n                        }\n                    }\n                }\n            }\n\n            if (c == -1) {\n                /* Didn't recognise encoding, copy raw bytes. */\n                *d++ = input[i + 1];\n                i += 2;\n            } else {\n                /* Converted the encoding. */\n                *d++ = c;\n            }\n\n            changed = true;\n        } else {\n            /* Input character not a backslash, copy it. */\n            *d++ = input[i++];\n        }\n    }\n\n    *d = '\\0';\n\n    value.resize(d - input);\n    return changed;\n}\n\n\nbool EscapeSeqDecode::transform(std::string &value, const Transaction *trans) const {\n    return ansi_c_sequences_decode_inplace(value);\n}\n\n\n}  // namespace modsecurity::actions::transformations\n"
  },
  {
    "path": "src/actions/transformations/escape_seq_decode.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#ifndef SRC_ACTIONS_TRANSFORMATIONS_ESCAPE_SEQ_DECODE_H_\n#define SRC_ACTIONS_TRANSFORMATIONS_ESCAPE_SEQ_DECODE_H_\n\n#include \"transformation.h\"\n\nnamespace modsecurity::actions::transformations {\n\nclass EscapeSeqDecode : public Transformation {\n public:\n    using Transformation::Transformation;\n\n    bool transform(std::string &value, const Transaction *trans) const override;\n};\n\n}  // namespace modsecurity::actions::transformations\n\n#endif  // SRC_ACTIONS_TRANSFORMATIONS_ESCAPE_SEQ_DECODE_H_\n"
  },
  {
    "path": "src/actions/transformations/hex_decode.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"hex_decode.h\"\n\n#include \"src/utils/string.h\"\n\n\nnamespace modsecurity::actions::transformations {\n\n\nstatic inline int inplace(std::string &value) {\n    if (value.empty()) return false;\n\n    const auto len = value.length();\n    auto d = reinterpret_cast<unsigned char *>(value.data());\n    const auto *data = d;\n\n    for (int i = 0; i <= len - 2; i += 2) {\n        *d++ = utils::string::x2c(&data[i]);\n    }\n\n    *d = '\\0';\n\n    value.resize(d - data);\n    return true;\n}\n\n\nbool HexDecode::transform(std::string &value, const Transaction *trans) const {\n    return inplace(value);\n}\n\n\n}  // namespace modsecurity::actions::transformations\n"
  },
  {
    "path": "src/actions/transformations/hex_decode.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#ifndef SRC_ACTIONS_TRANSFORMATIONS_HEX_DECODE_H_\n#define SRC_ACTIONS_TRANSFORMATIONS_HEX_DECODE_H_\n\n#include \"transformation.h\"\n\nnamespace modsecurity::actions::transformations {\n\nclass HexDecode : public Transformation {\n public:\n    using Transformation::Transformation;\n\n    bool transform(std::string &value, const Transaction *trans) const override;\n};\n\n}  // namespace modsecurity::actions::transformations\n\n#endif  // SRC_ACTIONS_TRANSFORMATIONS_HEX_DECODE_H_\n"
  },
  {
    "path": "src/actions/transformations/hex_encode.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"hex_encode.h\"\n\n#include \"modsecurity/rule_with_actions.h\"\n\n\nnamespace modsecurity::actions::transformations {\n\n\nbool HexEncode::transform(std::string &value, const Transaction *trans) const {\n    if (value.empty()) return false;\n\n    std::stringstream result;\n    for (const auto c : value) {\n        unsigned int ii = (unsigned char)c;\n        result << std::setw(2) << std::setfill('0') << std::hex << ii;\n    }\n\n    value = result.str();\n    return true;\n}\n\n}  // namespace modsecurity::actions::transformations\n"
  },
  {
    "path": "src/actions/transformations/hex_encode.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#ifndef SRC_ACTIONS_TRANSFORMATIONS_HEX_ENCODE_H_\n#define SRC_ACTIONS_TRANSFORMATIONS_HEX_ENCODE_H_\n\n#include \"transformation.h\"\n\nnamespace modsecurity::actions::transformations {\n\nclass HexEncode : public Transformation {\n public:\n    using Transformation::Transformation;\n\n    bool transform(std::string &value, const Transaction *trans) const override;\n};\n\n}  // namespace modsecurity::actions::transformations\n\n#endif  // SRC_ACTIONS_TRANSFORMATIONS_HEX_ENCODE_H_\n"
  },
  {
    "path": "src/actions/transformations/html_entity_decode.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"html_entity_decode.h\"\n\n#include <cstring>\n\n#include \"src/utils/string.h\"\n\n#ifdef WIN32\n#include \"src/compat/msvc.h\"\n#endif\n\nusing namespace modsecurity::utils::string;\n\nnamespace modsecurity::actions::transformations {\n\n\nstatic inline bool inplace(std::string &value) {\n    const auto input_len = value.length();\n    auto d = reinterpret_cast<unsigned char*>(value.data());\n    const unsigned char *input = d;\n    const unsigned char *end = input + input_len;\n\n    std::string::size_type i = 0;\n    while (i < input_len) {\n        std::string::size_type copy = 1;\n\n        /* Require an ampersand and at least one character to\n         * start looking into the entity.\n         */\n        if ((input[i] == '&') && (i + 1 < input_len)) {\n            auto j = i + 1;\n\n            if (input[j] == '#') {\n                /* Numerical entity. */\n                copy++;\n\n                if (!(j + 1 < input_len)) {\n                    goto HTML_ENT_OUT; /* Not enough bytes. */\n                }\n                j++;\n\n                if ((input[j] == 'x') || (input[j] == 'X')) {\n                    /* Hexadecimal entity. */\n                    copy++;\n\n                    if (!(j + 1 < input_len)) {\n                        goto HTML_ENT_OUT; /* Not enough bytes. */\n                    }\n                    j++; /* j is the position of the first digit now. */\n\n                    auto k = j;\n                    while ((j < input_len) && (isxdigit(input[j]))) {\n                        j++;\n                    }\n                    if (j > k) { /* Do we have at least one digit? */\n                        /* Decode the entity. */\n                        char *x = new char[(j - k) + 1];\n                        std::copy(input + k, input + j, x);\n                        x[j - k] = '\\0';\n\n                        *d++ = (unsigned char)strtol(x, nullptr, 16);\n                        delete[] x;\n\n                        /* Skip over the semicolon if it's there. */\n                        if ((j < input_len) && (input[j] == ';')) {\n                            i = j + 1;\n                        } else {\n                            i = j;\n                        }\n                        continue;\n                    } else {\n                        goto HTML_ENT_OUT;\n                    }\n                } else {\n                    /* Decimal entity. */\n                    auto k = j;\n\n                    while ((j < input_len) && (isdigit(input[j]))) {\n                        j++;\n                    }\n                    if (j > k) { /* Do we have at least one digit? */\n                        /* Decode the entity. */\n                        char *x = new char[j - k + 1];\n                        std::copy(input + k, input + j, x);\n\n                        x[j - k] = '\\0';\n                        *d++ = (unsigned char)strtol(x, nullptr, 10);\n                        delete[] x;\n\n                        /* Skip over the semicolon if it's there. */\n                        if ((j < input_len) && (input[j] == ';')) {\n                            i = j + 1;\n                        } else {\n                            i = j;\n                        }\n                        continue;\n                    } else {\n                        goto HTML_ENT_OUT;\n                    }\n                }\n            } else {\n                /* Text entity. */\n                auto k = j;\n                while ((j < input_len) && (isalnum(input[j]))) {\n                    j++;\n                }\n                if (j > k) { /* Do we have at least one digit? */\n                    const auto *x = reinterpret_cast<const char*>(&input[k]);\n\n                    /* Decode the entity. */\n                    /* ENH What about others? */\n                    if (strncasecmp(x, \"quot\", 4) == 0) {\n                        *d++ = '\"';\n                    } else if (strncasecmp(x, \"amp\", 3) == 0) {\n                        *d++ = '&';\n                    } else if (strncasecmp(x, \"lt\", 2) == 0) {\n                        *d++ = '<';\n                    } else if (strncasecmp(x, \"gt\", 2) == 0) {\n                        *d++ = '>';\n                    } else if (strncasecmp(x, \"nbsp\", 4) == 0) {\n                        *d++ = NBSP;\n                    } else {\n                        /* We do no want to convert this entity,\n                         * copy the raw data over. */\n                        copy = j - k + 1;\n                        goto HTML_ENT_OUT;\n                    }\n\n                    /* Skip over the semicolon if it's there. */\n                    if ((j < input_len) && (input[j] == ';')) {\n                        i = j + 1;\n                    } else {\n                        i = j;\n                    }\n\n                    continue;\n                }\n            }\n        }\n\nHTML_ENT_OUT:\n\n        for (auto z = 0; z < copy; z++) {\n            *d++ = input[i++];\n        }\n    }\n\n    *d = '\\0';\n\n    value.resize(d - input);\n    return d != end;\n}\n\n\nbool HtmlEntityDecode::transform(std::string &value, const Transaction *trans) const {\n    return inplace(value);\n}\n\n\n}  // namespace modsecurity::actions::transformations\n"
  },
  {
    "path": "src/actions/transformations/html_entity_decode.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#ifndef SRC_ACTIONS_TRANSFORMATIONS_HTML_ENTITY_DECODE_H_\n#define SRC_ACTIONS_TRANSFORMATIONS_HTML_ENTITY_DECODE_H_\n\n#include \"transformation.h\"\n\nnamespace modsecurity::actions::transformations {\n\nclass HtmlEntityDecode : public Transformation {\n public:\n    using Transformation::Transformation;\n\n    bool transform(std::string &value, const Transaction *trans) const override;\n};\n\n}  // namespace modsecurity::actions::transformations\n\n#endif  // SRC_ACTIONS_TRANSFORMATIONS_HTML_ENTITY_DECODE_H_\n"
  },
  {
    "path": "src/actions/transformations/js_decode.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"js_decode.h\"\n\n#include \"src/utils/string.h\"\n\nusing namespace modsecurity::utils::string;\n\nnamespace modsecurity::actions::transformations {\n\n\nstatic inline int inplace(std::string &value) {\n    auto d = reinterpret_cast<unsigned char*>(value.data());\n    const unsigned char *input = d;\n    const auto input_len = value.length();\n\n    bool changed = false;\n    std::string::size_type i = 0;\n    while (i < input_len) {\n        if (input[i] == '\\\\') {\n            /* Character is an escape. */\n\n            if ((i + 5 < input_len) && (input[i + 1] == 'u')\n                && (VALID_HEX(input[i + 2])) && (VALID_HEX(input[i + 3]))\n                && (VALID_HEX(input[i + 4])) && (VALID_HEX(input[i + 5]))) {\n                /* \\uHHHH */\n\n                /* Use only the lower byte. */\n                *d = utils::string::x2c(&input[i + 4]);\n\n                /* Full width ASCII (ff01 - ff5e) needs 0x20 added */\n                if ((*d > 0x00) && (*d < 0x5f)\n                    && ((input[i + 2] == 'f') || (input[i + 2] == 'F'))\n                    && ((input[i + 3] == 'f') || (input[i + 3] == 'F'))) {\n                    (*d) += 0x20;\n                }\n\n                d++;\n                i += 6;\n                changed = true;\n            } else if ((i + 3 < input_len) && (input[i + 1] == 'x')\n                    && VALID_HEX(input[i + 2]) && VALID_HEX(input[i + 3])) {\n                /* \\xHH */\n                *d++ = utils::string::x2c(&input[i + 2]);\n                i += 4;\n                changed = true;\n            } else if ((i + 1 < input_len) && ISODIGIT(input[i + 1])) {\n                /* \\OOO (only one byte, \\000 - \\377) */\n                char buf[4];\n                int j = 0;\n\n                while ((i + 1 + j < input_len) && (j < 3)) {\n                    buf[j] = input[i + 1 + j];\n                    j++;\n                    if (!ISODIGIT(input[i + 1 + j])) break;\n                }\n                buf[j] = '\\0';\n\n                if (j > 0) {\n                    /* Do not use 3 characters if we will be > 1 byte */\n                    if ((j == 3) && (buf[0] > '3')) {\n                        j = 2;\n                        buf[j] = '\\0';\n                    }\n                    *d++ = (unsigned char)strtol(buf, NULL, 8);\n                    i += 1 + j;\n                    changed = true;\n                }\n            } else if (i + 1 < input_len) {\n                /* \\C */\n                unsigned char c = input[i + 1];\n                switch (input[i + 1]) {\n                    case 'a' :\n                        c = '\\a';\n                        break;\n                    case 'b' :\n                        c = '\\b';\n                        break;\n                    case 'f' :\n                        c = '\\f';\n                        break;\n                    case 'n' :\n                        c = '\\n';\n                        break;\n                    case 'r' :\n                        c = '\\r';\n                        break;\n                    case 't' :\n                        c = '\\t';\n                        break;\n                    case 'v' :\n                        c = '\\v';\n                        break;\n                        /* The remaining (\\?,\\\\,\\',\\\") are just a removal\n                         * of the escape char which is default.\n                         */\n                }\n\n                *d++ = c;\n                i += 2;\n                changed = true;\n            } else {\n                /* Not enough bytes */\n                while (i < input_len) {\n                    *d++ = input[i++];\n                }\n            }\n        } else {\n            *d++ = input[i++];\n        }\n    }\n\n    *d = '\\0';\n\n    value.resize(d - input);\n    return changed;\n}\n\n\nbool JsDecode::transform(std::string &value, const Transaction *trans) const {\n    return inplace(value);\n}\n\n\n}  // namespace modsecurity::actions::transformations\n"
  },
  {
    "path": "src/actions/transformations/js_decode.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#ifndef SRC_ACTIONS_TRANSFORMATIONS_JS_DECODE_H_\n#define SRC_ACTIONS_TRANSFORMATIONS_JS_DECODE_H_\n\n#include \"transformation.h\"\n\nnamespace modsecurity::actions::transformations {\n\nclass JsDecode : public Transformation {\n public:\n    using Transformation::Transformation;\n\n    bool transform(std::string &value, const Transaction *trans) const override;\n};\n\n}  // namespace modsecurity::actions::transformations\n\n#endif  // SRC_ACTIONS_TRANSFORMATIONS_JS_DECODE_H_\n"
  },
  {
    "path": "src/actions/transformations/length.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"length.h\"\n\n\nnamespace modsecurity::actions::transformations {\n\n\nbool Length::transform(std::string &value, const Transaction *trans) const {\n    value = std::to_string(value.size());\n    return true;\n}\n\n\n}  // namespace modsecurity::actions::transformations\n"
  },
  {
    "path": "src/actions/transformations/length.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#ifndef SRC_ACTIONS_TRANSFORMATIONS_LENGTH_H_\n#define SRC_ACTIONS_TRANSFORMATIONS_LENGTH_H_\n\n#include \"transformation.h\"\n\nnamespace modsecurity::actions::transformations {\n\nclass Length : public Transformation {\n public:\n    using Transformation::Transformation;\n\n    bool transform(std::string &value, const Transaction *trans) const override;\n};\n\n}  // namespace modsecurity::actions::transformations\n\n#endif  // SRC_ACTIONS_TRANSFORMATIONS_LENGTH_H_\n"
  },
  {
    "path": "src/actions/transformations/lower_case.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n\n#include \"lower_case.h\"\n\n#include <cctype>\n\n\nnamespace modsecurity::actions::transformations {\n\n\nbool LowerCase::transform(std::string &value, const Transaction *trans) const {\n    return convert(value, [](auto c) {\n                    return std::tolower(c); });\n}\n\n\n}  // namespace modsecurity::actions::transformations\n"
  },
  {
    "path": "src/actions/transformations/lower_case.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#ifndef SRC_ACTIONS_TRANSFORMATIONS_LOWER_CASE_H_\n#define SRC_ACTIONS_TRANSFORMATIONS_LOWER_CASE_H_\n\n#include \"transformation.h\"\n\n#include <algorithm>\n\nnamespace modsecurity::actions::transformations {\n\nclass LowerCase : public Transformation {\n public:\n    using Transformation::Transformation;\n\n    bool transform(std::string &value, const Transaction *trans) const override;\n\n    template<typename Operation>\n    static bool convert(std::string &val, Operation op) {\n        bool changed = false;\n\n        std::transform(val.begin(), val.end(), val.data(),\n                       [&](auto c) { \n                            const auto nc = op(c);\n                            if(nc != c) changed = true; \n                            return nc; });\n\n        return changed;\n    }\n};\n\n}  // namespace modsecurity::actions::transformations\n\n#endif  // SRC_ACTIONS_TRANSFORMATIONS_LOWER_CASE_H_\n"
  },
  {
    "path": "src/actions/transformations/md5.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"md5.h\"\n\n#include \"src/utils/md5.h\"\n\nnamespace modsecurity::actions::transformations {\n\n\nbool Md5::transform(std::string &value, const Transaction *trans) const {\n    value = Utils::Md5::digest(value);\n    return true;\n}\n\n\n}  // namespace modsecurity::actions::transformations\n"
  },
  {
    "path": "src/actions/transformations/md5.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#ifndef SRC_ACTIONS_TRANSFORMATIONS_MD5_H_\n#define SRC_ACTIONS_TRANSFORMATIONS_MD5_H_\n\n#include \"transformation.h\"\n\nnamespace modsecurity::actions::transformations {\n\nclass Md5 : public Transformation {\n public:\n    using Transformation::Transformation;\n\n    bool transform(std::string &value, const Transaction *trans) const override;\n};\n\n}  // namespace modsecurity::actions::transformations\n\n#endif  // SRC_ACTIONS_TRANSFORMATIONS_MD5_H_\n"
  },
  {
    "path": "src/actions/transformations/none.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"none.h\"\n\n\nnamespace modsecurity::actions::transformations {\n\n\nbool None::transform(std::string &value, const Transaction *trans) const {\n    return false;\n}\n\n\n}  // namespace modsecurity::actions::transformations\n"
  },
  {
    "path": "src/actions/transformations/none.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#ifndef SRC_ACTIONS_TRANSFORMATIONS_NONE_H_\n#define SRC_ACTIONS_TRANSFORMATIONS_NONE_H_\n\n#include \"transformation.h\"\n\nnamespace modsecurity::actions::transformations {\n\nclass None : public Transformation {\n public:\n    explicit None(const std::string &action) \n        : Transformation(action)\n        { m_isNone = true; }\n\n    bool transform(std::string &value, const Transaction *trans) const override;\n};\n\n}  // namespace modsecurity::actions::transformations\n\n#endif  // SRC_ACTIONS_TRANSFORMATIONS_NONE_H_\n"
  },
  {
    "path": "src/actions/transformations/normalise_path.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"normalise_path.h\"\n\n\nnamespace modsecurity::actions::transformations {\n\n\nbool NormalisePath::transform(std::string &value, const Transaction *trans) const {\n    return normalize_path_inplace(value, false);\n}\n\n\n/**\n *\n * IMP1 Assumes NUL-terminated\n */\nbool NormalisePath::normalize_path_inplace(std::string &val, const bool win) {\n    int hitroot = 0;\n    int done = 0;\n    int relative;\n    int trailing;\n\n    bool changed = false;\n\n    /* Need at least one byte to normalize */\n    if(val.empty()) return false;\n\n    auto input = reinterpret_cast<unsigned char*>(val.data());\n    const auto input_len = val.length();\n\n    /*\n     * ENH: Deal with UNC and drive letters?\n     */\n\n    auto src = input;\n    auto dst = input;\n    const auto *end = input + (input_len - 1);\n\n    relative = ((*input == '/') || (win && (*input == '\\\\'))) ? 0 : 1;\n    trailing = ((*end == '/') || (win && (*end == '\\\\'))) ? 1 : 0;\n\n    while (!done && (src <= end) && (dst <= end)) {\n        /* Convert backslash to forward slash on Windows only. */\n        if (win) {\n            if (*src == '\\\\') {\n                *src = '/';\n                changed = true;\n            }\n            if ((src < end) && (*(src + 1) == '\\\\')) {\n                *(src + 1) = '/';\n                changed = true;\n            }\n        }\n\n        /* Always normalize at the end of the input. */\n        if (src == end) {\n            done = 1;\n        } else if (*(src + 1) != '/') {\n        /* Skip normalization if this is NOT the\n         *end of the path segment. */\n            goto copy; /* Skip normalization. */\n        }\n\n        /*** Normalize the path segment. ***/\n\n        /* Could it be an empty path segment? */\n        if ((src != end) && *src == '/') {\n            /* Ignore */\n            changed = true;\n            goto copy; /* Copy will take care of this. */\n        } else if (*src == '.') {\n        /* Could it be a back or self reference? */\n            /* Back-reference? */\n            if ((dst > input) && (*(dst - 1) == '.')) {\n                /* If a relative path and either our normalization has\n                 * already hit the rootdir, or this is a backref with no\n                 * previous path segment, then mark that the rootdir was hit\n                 * and just copy the backref as no normilization is possible.\n                 */\n                if (relative && (hitroot || ((dst - 2) <= input))) {\n                    hitroot = 1;\n\n                    goto copy; /* Skip normalization. */\n                }\n\n                /* Remove backreference and the previous path segment. */\n                dst -= 3;\n                while ((dst > input) && (*dst != '/')) {\n                    dst--;\n                }\n\n                /* But do not allow going above rootdir. */\n                if (dst <= input) {\n                    hitroot = 1;\n                    dst = input;\n\n                    /* Need to leave the root slash if this\n                     * is not a relative path and the end was reached\n                     * on a backreference.\n                     */\n                    if (!relative && (src == end)) {\n                        dst++;\n                    }\n                }\n\n                if (done) goto skip_copy; /* Skip the copy. */\n                src++;\n\n                changed = true;\n            } else if (dst == input) {\n                /* Relative Self-reference? */\n                changed = true;\n\n                /* Ignore. */\n\n                if (done) goto skip_copy; /* Skip the copy. */\n                src++;\n            } else if (*(dst - 1) == '/') {\n            /* Self-reference? */\n                changed = true;\n\n                /* Ignore. */\n\n                if (done) goto skip_copy; /* Skip the copy. */\n                dst--;\n                src++;\n            }\n        } else if (dst > input) {\n        /* Found a regular path segment. */\n            hitroot = 0;\n        }\n\ncopy:\n        /*** Copy the byte if required. ***/\n\n        /* Skip to the last forward slash when multiple are used. */\n        if (*src == '/') {\n            const unsigned char *oldsrc = src;\n\n            while ((src < end)\n                && ((*(src + 1) == '/') || (win && (*(src + 1) == '\\\\'))) ) {\n                src++;\n            }\n            if (oldsrc != src) changed = true;\n\n            /* Do not copy the forward slash to the root\n             * if it is not a relative path.  Instead\n             * move over the slash to the next segment.\n             */\n            if (relative && (dst == input)) {\n                src++;\n                goto skip_copy; /* Skip the copy */\n            }\n        }\n\n        *(dst++) = *(src++);\n\nskip_copy:\n        ;   // nop for the goto label to work\n    }\n    /* Make sure that there is not a trailing slash in the\n     * normalized form if there was not one in the original form.\n     */\n    if (!trailing && (dst > input) && *(dst - 1) == '/') {\n        dst--;\n    }\n\n    /* Always NUL terminate */\n    *dst = '\\0';\n\n    val.resize(dst - input);\n    return changed;\n}\n\n\n}  // namespace modsecurity::actions::transformations\n"
  },
  {
    "path": "src/actions/transformations/normalise_path.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#ifndef SRC_ACTIONS_TRANSFORMATIONS_NORMALISE_PATH_H_\n#define SRC_ACTIONS_TRANSFORMATIONS_NORMALISE_PATH_H_\n\n#include \"transformation.h\"\n\nnamespace modsecurity::actions::transformations {\n\nclass NormalisePath : public Transformation {\n public:\n    using Transformation::Transformation;\n\n    bool transform(std::string &value, const Transaction *trans) const override;\n\n    static bool normalize_path_inplace(std::string &val, const bool win);\n};\n\n}  // namespace modsecurity::actions::transformations\n\n#endif  // SRC_ACTIONS_TRANSFORMATIONS_NORMALISE_PATH_H_\n"
  },
  {
    "path": "src/actions/transformations/normalise_path_win.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"normalise_path_win.h\"\n\n#include \"normalise_path.h\"\n\n\nnamespace modsecurity::actions::transformations {\n\n\nbool NormalisePathWin::transform(std::string &value, const Transaction *trans) const {\n    return NormalisePath::normalize_path_inplace(value, true);\n}\n\n\n}  // namespace modsecurity::actions::transformations\n"
  },
  {
    "path": "src/actions/transformations/normalise_path_win.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#ifndef SRC_ACTIONS_TRANSFORMATIONS_NORMALISE_PATH_WIN_H_\n#define SRC_ACTIONS_TRANSFORMATIONS_NORMALISE_PATH_WIN_H_\n\n#include \"transformation.h\"\n\nnamespace modsecurity::actions::transformations {\n\nclass NormalisePathWin : public Transformation {\n public:\n    using Transformation::Transformation;\n\n    bool transform(std::string &value, const Transaction *trans) const override;\n};\n\n}  // namespace modsecurity::actions::transformations\n\n#endif  // SRC_ACTIONS_TRANSFORMATIONS_NORMALISE_PATH_WIN_H_\n"
  },
  {
    "path": "src/actions/transformations/parity_even_7bit.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"parity_even_7bit.h\"\n\n\nnamespace modsecurity::actions::transformations {\n\n\nbool ParityEven7bit::transform(std::string &value, const Transaction *trans) const {\n    return ParityEven7bit::inplace<true>(value);\n}\n\n\n}  // namespace modsecurity::actions::transformations\n"
  },
  {
    "path": "src/actions/transformations/parity_even_7bit.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#ifndef SRC_ACTIONS_TRANSFORMATIONS_PARITY_EVEN_7BIT_H_\n#define SRC_ACTIONS_TRANSFORMATIONS_PARITY_EVEN_7BIT_H_\n\n#include \"transformation.h\"\n\nnamespace modsecurity::actions::transformations {\n\nclass ParityEven7bit : public Transformation {\n public:\n    using Transformation::Transformation;\n\n    bool transform(std::string &value, const Transaction *trans) const override;\n\n    template<bool even>\n    static bool inplace(std::string &value) {\n        if (value.empty()) return false;\n\n        for(auto &c : value) {\n            auto &uc = reinterpret_cast<unsigned char&>(c);\n            unsigned int x = uc;\n\n            uc ^= uc >> 4;\n            uc &= 0xf;\n\n            const bool condition = (0x6996 >> uc) & 1;\n            if (even ? condition : !condition) {\n                uc = x | 0x80;\n            } else {\n                uc = x & 0x7f;\n            }\n        }\n\n        return true;\n    }\n};\n\n}  // namespace modsecurity::actions::transformations\n\n#endif  // SRC_ACTIONS_TRANSFORMATIONS_PARITY_EVEN_7BIT_H_\n"
  },
  {
    "path": "src/actions/transformations/parity_odd_7bit.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"parity_odd_7bit.h\"\n#include \"parity_even_7bit.h\"\n\n\nnamespace modsecurity::actions::transformations {\n\n\nbool ParityOdd7bit::transform(std::string &value, const Transaction *trans) const {\n    return ParityEven7bit::inplace<false>(value);\n}\n\n\n}  // namespace modsecurity::actions::transformations\n"
  },
  {
    "path": "src/actions/transformations/parity_odd_7bit.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#ifndef SRC_ACTIONS_TRANSFORMATIONS_PARITY_ODD_7BIT_H_\n#define SRC_ACTIONS_TRANSFORMATIONS_PARITY_ODD_7BIT_H_\n\n#include \"transformation.h\"\n\nnamespace modsecurity::actions::transformations {\n\nclass ParityOdd7bit : public Transformation {\n public:\n    using Transformation::Transformation;\n\n    bool transform(std::string &value, const Transaction *trans) const override;\n};\n\n}  // namespace modsecurity::actions::transformations\n\n#endif  // SRC_ACTIONS_TRANSFORMATIONS_PARITY_ODD_7BIT_H_\n"
  },
  {
    "path": "src/actions/transformations/parity_zero_7bit.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"parity_zero_7bit.h\"\n\n\nnamespace modsecurity::actions::transformations {\n\n\nstatic inline bool inplace(std::string &value) {\n    if (value.empty()) return false;\n\n    for(auto &c : value) { // cppcheck-suppress constVariableReference ; false positive\n        ((unsigned char&)c) &= 0x7f;\n    }\n\n    return true;\n}\n\n\nbool ParityZero7bit::transform(std::string &value, const Transaction *trans) const {\n    return inplace(value);\n}\n\n\n}  // namespace modsecurity::actions::transformations\n"
  },
  {
    "path": "src/actions/transformations/parity_zero_7bit.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#ifndef SRC_ACTIONS_TRANSFORMATIONS_PARITY_ZERO_7BIT_H_\n#define SRC_ACTIONS_TRANSFORMATIONS_PARITY_ZERO_7BIT_H_\n\n#include \"transformation.h\"\n\nnamespace modsecurity::actions::transformations {\n\nclass ParityZero7bit : public Transformation {\n public:\n    using Transformation::Transformation;\n\n    bool transform(std::string &value, const Transaction *trans) const override;\n};\n\n}  // namespace modsecurity::actions::transformations\n\n#endif  // SRC_ACTIONS_TRANSFORMATIONS_PARITY_ZERO_7BIT_H_\n"
  },
  {
    "path": "src/actions/transformations/remove_comments.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"remove_comments.h\"\n\n\nnamespace modsecurity::actions::transformations {\n\n\nstatic inline int inplace(std::string &value) {\n    auto input = reinterpret_cast<unsigned char*>(value.data());\n    const auto input_len = value.length();\n    bool changed = false, incomment = false;\n    std::string::size_type i = 0, j = 0;\n\n    while (i < input_len) {\n        if (!incomment) {\n            if ((input[i] == '/') && (i + 1 < input_len)\n                && (input[i + 1] == '*')) {\n                incomment = true;\n                changed = true;\n                i += 2;\n            } else if ((input[i] == '<') && (i + 1 < input_len)\n                && (input[i + 1] == '!') && (i + 2 < input_len)\n                && (input[i+2] == '-') && (i + 3 < input_len)\n                && (input[i + 3] == '-')) {\n                incomment = true;\n                changed = true;\n                i += 4;\n            } else if ((input[i] == '-') && (i + 1 < input_len)\n                && (input[i + 1] == '-')) {\n                input[i] = ' ';\n                changed = true;\n                break;\n            } else if (input[i] == '#') {\n                input[i] = ' ';\n                changed = true;\n                break;\n            } else {\n                input[j] = input[i];\n                i++;\n                j++;\n            }\n        } else {\n            if ((input[i] == '*') && (i + 1 < input_len)\n                && (input[i + 1] == '/')) {\n                incomment = false;\n                i += 2;\n                input[j] = input[i];\n                i++;\n                j++;\n            } else if ((input[i] == '-') && (i + 1 < input_len)\n                && (input[i + 1] == '-') && (i + 2 < input_len)\n                && (input[i+2] == '>'))   {\n                incomment = false;\n                i += 3;\n                input[j] = input[i];\n                i++;\n                j++;\n            } else {\n                i++;\n            }\n        }\n    }\n\n    if (incomment) {\n        input[j++] = ' ';\n    }\n\n    value.resize(j);\n    return changed;\n}\n\n\nbool RemoveComments::transform(std::string &value, const Transaction *trans) const {\n    return inplace(value);\n}\n\n\n}  // namespace modsecurity::actions::transformations\n"
  },
  {
    "path": "src/actions/transformations/remove_comments.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#ifndef SRC_ACTIONS_TRANSFORMATIONS_REMOVE_COMMENTS_H_\n#define SRC_ACTIONS_TRANSFORMATIONS_REMOVE_COMMENTS_H_\n\n#include \"transformation.h\"\n\nnamespace modsecurity::actions::transformations {\n\nclass RemoveComments : public Transformation {\n public:\n    using Transformation::Transformation;\n\n    bool transform(std::string &value, const Transaction *trans) const override;\n};\n\n}  // namespace modsecurity::actions::transformations\n\n#endif  // SRC_ACTIONS_TRANSFORMATIONS_REMOVE_COMMENTS_H_\n"
  },
  {
    "path": "src/actions/transformations/remove_comments_char.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2023 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"remove_comments_char.h\"\n\n\nnamespace modsecurity::actions::transformations {\n\n\nbool RemoveCommentsChar::transform(std::string &value, const Transaction *trans) const {\n    char *d = value.data();\n    const char *s = d;\n    const char *e = s + value.size();\n\n    while (s < e) {\n        if (*s == '/'\n            && (s+1 < e) && *(s+1) == '*') {\n            s += 2;\n        } else if (*s == '*'\n            && (s+1 < e) && *(s+1) == '/') {\n            s += 2;\n        } else if (*s == '<'\n            && (s+1 < e)\n            && *(s+1) == '!'\n            && (s+2 < e)\n            && *(s+2) == '-'\n            && (s+3 < e)\n            && *(s+3) == '-') {\n            s += 4;\n        } else if (*s == '-'\n            && (s+1 < e) && *(s+1) == '-'\n            && (s+2 < e) && *(s+2) == '>') {\n            s += 3;\n        } else if (*s == '-'\n            && (s+1 < e) && *(s+1) == '-') {\n            s += 2;\n        } else if (*s == '#') {\n            s += 1;\n        } else {\n            *d++ = *s++;\n        }\n    }\n\n    const auto changed = d != s;\n    const auto new_len = d - value.c_str();\n    value.resize(new_len);\n    return changed;\n}\n\n}  // namespace modsecurity::actions::transformations\n\n"
  },
  {
    "path": "src/actions/transformations/remove_comments_char.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#ifndef SRC_ACTIONS_TRANSFORMATIONS_REMOVE_COMMENTS_CHAR_H_\n#define SRC_ACTIONS_TRANSFORMATIONS_REMOVE_COMMENTS_CHAR_H_\n\n#include \"transformation.h\"\n\nnamespace modsecurity::actions::transformations {\n\nclass RemoveCommentsChar : public Transformation {\n public:\n    using Transformation::Transformation;\n\n    bool transform(std::string &value, const Transaction *trans) const override;\n};\n\n}  // namespace modsecurity::actions::transformations\n\n#endif  // SRC_ACTIONS_TRANSFORMATIONS_REMOVE_COMMENTS_CHAR_H_\n"
  },
  {
    "path": "src/actions/transformations/remove_nulls.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2023 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"remove_nulls.h\"\n\n\nnamespace modsecurity::actions::transformations {\n\n\nbool RemoveNulls::transform(std::string &value, const Transaction *trans) const {\n    return remove_if(value, [](const auto c) { return c == '\\0'; });\n}\n\n\n}  // namespace modsecurity::actions::transformations\n"
  },
  {
    "path": "src/actions/transformations/remove_nulls.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#ifndef SRC_ACTIONS_TRANSFORMATIONS_REMOVE_NULLS_H_\n#define SRC_ACTIONS_TRANSFORMATIONS_REMOVE_NULLS_H_\n\n#include \"transformation.h\"\n\n#include <algorithm>\n\nnamespace modsecurity::actions::transformations {\n\nclass RemoveNulls : public Transformation {\n public:\n    using Transformation::Transformation;\n\n    bool transform(std::string &value, const Transaction *trans) const override;\n\n    template<typename Pred>\n    static bool remove_if(std::string &val, Pred pred) {\n        const auto old_size = val.size();\n\n        val.erase(\n            std::remove_if(\n                val.begin(), val.end(), pred),\n            val.end());\n\n        return val.size() != old_size;\n    }\n};\n\n}  // namespace modsecurity::actions::transformations\n\n#endif  // SRC_ACTIONS_TRANSFORMATIONS_REMOVE_NULLS_H_\n"
  },
  {
    "path": "src/actions/transformations/remove_whitespace.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2023 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"remove_whitespace.h\"\n\n#include \"remove_nulls.h\"\n\nnamespace modsecurity::actions::transformations {\n\n\nbool RemoveWhitespace::transform(std::string &value, const Transaction *trans) const {\n    const char nonBreakingSpaces = 0xa0;\n    const char nonBreakingSpaces2 = 0xc2;\n\n    auto pred = [](const auto c) {\n        // remove whitespaces and non breaking spaces (NBSP)\n        return std::isspace(static_cast<unsigned char>(c))\n            || c == nonBreakingSpaces\n            || c == nonBreakingSpaces2;\n    };\n\n    return RemoveNulls::remove_if(value, pred);\n}\n\n\n}  // namespace modsecurity::actions::transformations\n\n"
  },
  {
    "path": "src/actions/transformations/remove_whitespace.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#ifndef SRC_ACTIONS_TRANSFORMATIONS_REMOVE_WHITESPACE_H_\n#define SRC_ACTIONS_TRANSFORMATIONS_REMOVE_WHITESPACE_H_\n\n#include \"transformation.h\"\n\nnamespace modsecurity::actions::transformations {\n\nclass RemoveWhitespace : public Transformation {\n public:\n    using Transformation::Transformation;\n\n    bool transform(std::string &value, const Transaction *trans) const override;\n};\n\n}  // namespace modsecurity::actions::transformations\n\n#endif  // SRC_ACTIONS_TRANSFORMATIONS_REMOVE_WHITESPACE_H_\n"
  },
  {
    "path": "src/actions/transformations/replace_comments.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"replace_comments.h\"\n\n\nnamespace modsecurity::actions::transformations {\n\n\nstatic inline bool inplace(std::string &value) {\n    auto input = reinterpret_cast<unsigned char*>(value.data());\n    const auto input_len = value.length();\n    bool changed = false, incomment = false;\n    std::string::size_type i = 0, j = 0;\n\n    while (i < input_len) {\n        if (!incomment) {\n            if ((input[i] == '/') && (i + 1 < input_len)\n                && (input[i + 1] == '*')) {\n                incomment = true;\n                i += 2;\n                changed = true;\n            } else {\n                input[j] = input[i];\n                i++;\n                j++;\n            }\n        } else {\n            if ((input[i] == '*') && (i + 1 < input_len)\n                && (input[i + 1] == '/')) {\n                incomment = false;\n                i += 2;\n                input[j] = ' ';\n                j++;\n            } else {\n                i++;\n            }\n        }\n    }\n\n    if (incomment) {\n        input[j++] = ' ';\n    }\n\n    value.resize(j);\n    return changed;\n}\n\n\nbool ReplaceComments::transform(std::string &value, const Transaction *trans) const {\n    return inplace(value);\n}\n\n\n}  // namespace modsecurity::actions::transformations\n"
  },
  {
    "path": "src/actions/transformations/replace_comments.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#ifndef SRC_ACTIONS_TRANSFORMATIONS_REPLACE_COMMENTS_H_\n#define SRC_ACTIONS_TRANSFORMATIONS_REPLACE_COMMENTS_H_\n\n#include \"transformation.h\"\n\nnamespace modsecurity::actions::transformations {\n\nclass ReplaceComments : public Transformation {\n public:\n    using Transformation::Transformation;\n\n    bool transform(std::string &value, const Transaction *trans) const override;\n};\n\n}  // namespace modsecurity::actions::transformations\n\n#endif  // SRC_ACTIONS_TRANSFORMATIONS_REPLACE_COMMENTS_H_\n"
  },
  {
    "path": "src/actions/transformations/replace_nulls.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2023 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"replace_nulls.h\"\n\n\nnamespace modsecurity::actions::transformations {\n\n\nbool ReplaceNulls::transform(std::string &value, const Transaction *trans) const {\n    bool changed = false;\n\n    for(auto &c : value) {\n        if (c == '\\0') {\n            c = ' ';\n            changed = true;\n        }\n    }\n\n    return changed;\n}\n\n}  // namespace modsecurity::actions::transformations\n"
  },
  {
    "path": "src/actions/transformations/replace_nulls.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#ifndef SRC_ACTIONS_TRANSFORMATIONS_REPLACE_NULLS_H_\n#define SRC_ACTIONS_TRANSFORMATIONS_REPLACE_NULLS_H_\n\n#include \"transformation.h\"\n\nnamespace modsecurity::actions::transformations {\n\nclass ReplaceNulls : public Transformation {\n public:\n    using Transformation::Transformation;\n\n    bool transform(std::string &value, const Transaction *trans) const override;\n};\n\n}  // namespace modsecurity::actions::transformations\n\n#endif  // SRC_ACTIONS_TRANSFORMATIONS_REPLACE_NULLS_H_\n"
  },
  {
    "path": "src/actions/transformations/sha1.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"sha1.h\"\n\n#include \"src/utils/sha1.h\"\n\n\nnamespace modsecurity::actions::transformations {\n\n\nbool Sha1::transform(std::string &value, const Transaction *trans) const {\n    value = Utils::Sha1::digest(value);\n    return true;\n}\n\n\n}  // namespace modsecurity::actions::transformations\n"
  },
  {
    "path": "src/actions/transformations/sha1.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#ifndef SRC_ACTIONS_TRANSFORMATIONS_SHA1_H_\n#define SRC_ACTIONS_TRANSFORMATIONS_SHA1_H_\n\n#include \"transformation.h\"\n\nnamespace modsecurity::actions::transformations {\n\nclass Sha1 : public Transformation {\n public:\n    using Transformation::Transformation;\n\n    bool transform(std::string &value, const Transaction *trans) const override;\n};\n\n}  // namespace modsecurity::actions::transformations\n\n#endif  // SRC_ACTIONS_TRANSFORMATIONS_SHA1_H_\n"
  },
  {
    "path": "src/actions/transformations/sql_hex_decode.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"sql_hex_decode.h\"\n\n#include <cstring>\n\n#include \"src/utils/string.h\"\n\nusing namespace modsecurity::utils::string;\n\nnamespace modsecurity::actions::transformations {\n\n\nstatic inline int mytolower(int ch) {\n    if (ch >= 'A' && ch <= 'Z')\n        return ('a' + ch - 'A');\n    else\n        return ch;\n}\n\nstatic inline bool inplace(std::string &value) {\n    if (value.empty()) {\n        return false;\n    }\n\n    auto d = reinterpret_cast<unsigned char*>(value.data());\n    const unsigned char *data = d;\n    const auto *end = data + value.size();\n\n    bool changed = false;\n\n    while (data < end) {\n        if (data + 3 < end\n            && *data == '0'\n            && mytolower(*(data + 1)) == 'x'\n            && VALID_HEX(*(data + 2)) && VALID_HEX(*(data + 3))) {\n            data += 2;  // skip '0x'\n            do {\n                *d++ = utils::string::x2c(data);\n                data += 2;\n            } while ((data + 1 < end) && VALID_HEX(*data) && VALID_HEX(*(data + 1)));\n            changed = true;\n        }\n        else {\n            *d++ = *data++;\n        }\n    }\n\n    *d = '\\0';\n\n    value.resize(d - reinterpret_cast<const unsigned char*>(value.c_str()));\n    return changed;\n}\n\n\nbool SqlHexDecode::transform(std::string &value, const Transaction *trans) const {\n    return inplace(value);\n}\n\n\n}  // namespace modsecurity::actions::transformations\n"
  },
  {
    "path": "src/actions/transformations/sql_hex_decode.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#ifndef SRC_ACTIONS_TRANSFORMATIONS_SQL_HEX_DECODE_H_\n#define SRC_ACTIONS_TRANSFORMATIONS_SQL_HEX_DECODE_H_\n\n#include \"transformation.h\"\n\nnamespace modsecurity::actions::transformations {\n\nclass SqlHexDecode : public Transformation {\n public:\n    using Transformation::Transformation;\n\n    bool transform(std::string &value, const Transaction *trans) const override;\n};\n\n}  // namespace modsecurity::actions::transformations\n\n#endif  // SRC_ACTIONS_TRANSFORMATIONS_SQL_HEX_DECODE_H_\n"
  },
  {
    "path": "src/actions/transformations/transformation.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"transformation.h\"\n\n#include <cstring>\n#include <iostream>\n#include <string>\n\n#include \"modsecurity/transaction.h\"\n#include \"modsecurity/actions/action.h\"\n\n#include \"base64_decode_ext.h\"\n#include \"base64_decode.h\"\n#include \"base64_encode.h\"\n#include \"cmd_line.h\"\n#include \"compress_whitespace.h\"\n#include \"css_decode.h\"\n#include \"escape_seq_decode.h\"\n#include \"hex_decode.h\"\n#include \"hex_encode.h\"\n#include \"html_entity_decode.h\"\n#include \"js_decode.h\"\n#include \"length.h\"\n#include \"lower_case.h\"\n#include \"md5.h\"\n#include \"none.h\"\n#include \"normalise_path.h\"\n#include \"normalise_path_win.h\"\n#include \"parity_even_7bit.h\"\n#include \"parity_odd_7bit.h\"\n#include \"parity_zero_7bit.h\"\n#include \"remove_comments_char.h\"\n#include \"remove_comments.h\"\n#include \"remove_nulls.h\"\n#include \"remove_whitespace.h\"\n#include \"replace_comments.h\"\n#include \"replace_nulls.h\"\n#include \"sha1.h\"\n#include \"sql_hex_decode.h\"\n#include \"trim.h\"\n#include \"trim_left.h\"\n#include \"trim_right.h\"\n#include \"upper_case.h\"\n#include \"url_decode.h\"\n#include \"url_decode_uni.h\"\n#include \"url_encode.h\"\n#include \"utf8_to_unicode.h\"\n\n\n#define IF_MATCH(b) \\\n    if (a.compare(2, std::strlen(#b), #b) == 0)\n\n\nnamespace modsecurity::actions::transformations {\n\n\nbool Transformation::transform(std::string &value, const Transaction *trans) const {\n    return false;\n}\n\nTransformation* Transformation::instantiate(std::string a) {\n    IF_MATCH(base64DecodeExt) { return new Base64DecodeExt(a); }\n    IF_MATCH(base64Decode) { return new Base64Decode(a); }\n    IF_MATCH(base64Encode) { return new Base64Encode(a); }\n    IF_MATCH(cmd_line) { return new CmdLine(a); }\n    IF_MATCH(compress_whitespace) { return new CompressWhitespace(a); }\n    IF_MATCH(cssDecode) { return new CssDecode(a); }\n    IF_MATCH(escapeSeqDecode) { return new EscapeSeqDecode(a); }\n    IF_MATCH(hexDecode) { return new HexDecode(a); }\n    IF_MATCH(hexEncode) { return new HexEncode(a); }\n    IF_MATCH(htmlEntityDecode) { return new HtmlEntityDecode(a); }\n    IF_MATCH(jsDecode) { return new JsDecode(a); }\n    IF_MATCH(length) { return new Length(a); }\n    IF_MATCH(lowercase) { return new LowerCase(a); }\n    IF_MATCH(md5) { return new Md5(a); }\n    IF_MATCH(none) { return new None(a); }\n    IF_MATCH(normalizePathWin) { return new NormalisePathWin(a); }\n    IF_MATCH(normalisePathWin) { return new NormalisePathWin(a); }\n    IF_MATCH(normalizePath) { return new NormalisePath(a); }\n    IF_MATCH(normalisePath) { return new NormalisePath(a); }\n    IF_MATCH(parityEven7bit) { return new ParityEven7bit(a); }\n    IF_MATCH(parityOdd7bit) { return new ParityOdd7bit(a); }\n    IF_MATCH(parityZero7bit) { return new ParityZero7bit(a); }\n    IF_MATCH(removeCommentsChar) { return new RemoveCommentsChar(a); }\n    IF_MATCH(removeComments) { return new RemoveComments(a); }\n    IF_MATCH(removeNulls) { return new RemoveNulls(a); }\n    IF_MATCH(removeWhitespace) { return new RemoveWhitespace(a); }\n    IF_MATCH(compressWhitespace) { return new CompressWhitespace(a); }\n    IF_MATCH(replaceComments) { return new ReplaceComments(a); }\n    IF_MATCH(replaceNulls) { return new ReplaceNulls(a); }\n    IF_MATCH(sha1) { return new Sha1(a); }\n    IF_MATCH(sqlHexDecode) { return new SqlHexDecode(a); }\n    IF_MATCH(transformation) { return new Transformation(a); }\n    IF_MATCH(trimLeft) { return new TrimLeft(a); }\n    IF_MATCH(trimRight) { return new TrimRight(a); }\n    IF_MATCH(trim) { return new Trim(a); }\n    IF_MATCH(uppercase) { return new UpperCase(a); }\n    IF_MATCH(urlDecodeUni) { return new UrlDecodeUni(a); }\n    IF_MATCH(urlDecode) { return new UrlDecode(a); }\n    IF_MATCH(urlEncode) { return new UrlEncode(a); }\n    IF_MATCH(utf8toUnicode) { return new Utf8ToUnicode(a); }\n\n    return new Transformation(a);\n}\n\n\n}  // namespace modsecurity::actions::transformations\n"
  },
  {
    "path": "src/actions/transformations/transformation.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#ifndef SRC_ACTIONS_TRANSFORMATIONS_TRANSFORMATION_H_\n#define SRC_ACTIONS_TRANSFORMATIONS_TRANSFORMATION_H_\n\n#include \"modsecurity/actions/action.h\"\n\nnamespace modsecurity::actions::transformations {\n\nclass Transformation : public Action {\n public:\n    explicit Transformation(const std::string& _action)\n        : Action(_action, Kind::RunTimeBeforeMatchAttemptKind) { }\n\n    static Transformation* instantiate(std::string a);\n\n    virtual bool transform(std::string &value, const Transaction *trans) const;\n};\n\n}  // namespace modsecurity::actions::transformations\n\n#endif  // SRC_ACTIONS_TRANSFORMATIONS_TRANSFORMATION_H_\n"
  },
  {
    "path": "src/actions/transformations/trim.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"trim.h\"\n\n#include <algorithm>\n\n\nnamespace modsecurity::actions::transformations {\n\n\nbool Trim::ltrim(std::string &s) {\n    auto it = std::find_if(s.begin(), s.end(), [](unsigned char c) {\n            return !std::isspace(c);\n        });\n\n    const bool changed = it != s.begin();\n\n    s.erase(s.begin(), it);\n\n    return changed;\n}\n\n\nbool Trim::rtrim(std::string &s) {\n    auto it = std::find_if(s.rbegin(), s.rend(), [](unsigned char c) {\n            return !std::isspace(c);\n        }).base();\n\n    const bool changed = it != s.end();\n\n    s.erase(it, s.end());\n\n    return changed;\n}\n\n\nbool Trim::trim(std::string &s) {\n    bool changed = false;\n    changed |= rtrim(s);\n    changed |= ltrim(s);\n    return changed;\n}\n\n\nbool Trim::transform(std::string &value, const Transaction *trans) const {\n    return trim(value);\n}\n\n\n}  // namespace modsecurity::actions::transformations\n"
  },
  {
    "path": "src/actions/transformations/trim.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#ifndef SRC_ACTIONS_TRANSFORMATIONS_TRIM_H_\n#define SRC_ACTIONS_TRANSFORMATIONS_TRIM_H_\n\n#include \"transformation.h\"\n\nnamespace modsecurity::actions::transformations {\n\nclass Trim : public Transformation {\n public:\n    using Transformation::Transformation;\n\n    bool transform(std::string &value, const Transaction *trans) const override;\n\n    static bool ltrim(std::string &s);\n    static bool rtrim(std::string &s);\n    static bool trim(std::string &s);\n};\n\n}  // namespace modsecurity::actions::transformations\n\n#endif  // SRC_ACTIONS_TRANSFORMATIONS_TRIM_H_\n"
  },
  {
    "path": "src/actions/transformations/trim_left.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"trim_left.h\"\n#include \"trim.h\"\n\n\nnamespace modsecurity::actions::transformations {\n\n\nbool TrimLeft::transform(std::string &value, const Transaction *trans) const {\n    return Trim::ltrim(value);\n}\n\n\n}  // namespace modsecurity::actions::transformations\n"
  },
  {
    "path": "src/actions/transformations/trim_left.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#ifndef SRC_ACTIONS_TRANSFORMATIONS_TRIM_LEFT_H_\n#define SRC_ACTIONS_TRANSFORMATIONS_TRIM_LEFT_H_\n\n#include \"transformation.h\"\n\nnamespace modsecurity::actions::transformations {\n\nclass TrimLeft : public Transformation {\n public:\n    using Transformation::Transformation;\n\n    bool transform(std::string &value, const Transaction *trans) const override;\n};\n\n}  // namespace modsecurity::actions::transformations\n\n#endif  // SRC_ACTIONS_TRANSFORMATIONS_TRIM_LEFT_H_\n"
  },
  {
    "path": "src/actions/transformations/trim_right.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"trim_right.h\"\n#include \"trim.h\"\n\n\nnamespace modsecurity::actions::transformations {\n\n\nbool TrimRight::transform(std::string &value, const Transaction *trans) const {\n    return Trim::rtrim(value);\n}\n\n\n}  // namespace modsecurity::actions::transformations\n"
  },
  {
    "path": "src/actions/transformations/trim_right.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#ifndef SRC_ACTIONS_TRANSFORMATIONS_TRIM_RIGHT_H_\n#define SRC_ACTIONS_TRANSFORMATIONS_TRIM_RIGHT_H_\n\n#include \"transformation.h\"\n\nnamespace modsecurity::actions::transformations {\n\nclass TrimRight : public Transformation {\n public:\n    using Transformation::Transformation;\n\n    bool transform(std::string &value, const Transaction *trans) const override;\n};\n\n}  // namespace modsecurity::actions::transformations\n\n#endif  // SRC_ACTIONS_TRANSFORMATIONS_TRIM_RIGHT_H_\n"
  },
  {
    "path": "src/actions/transformations/upper_case.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n\n#include \"upper_case.h\"\n\n#include <cctype>\n\n#include \"lower_case.h\"\n\n\nnamespace modsecurity::actions::transformations {\n\n\nbool UpperCase::transform(std::string &value, const Transaction *trans) const {\n    return LowerCase::convert(value, [](auto c)\n                              { return std::toupper(c); });\n}\n\n\n}  // namespace modsecurity::actions::transformations\n"
  },
  {
    "path": "src/actions/transformations/upper_case.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#ifndef SRC_ACTIONS_TRANSFORMATIONS_UPPER_CASE_H_\n#define SRC_ACTIONS_TRANSFORMATIONS_UPPER_CASE_H_\n\n#include \"transformation.h\"\n\nnamespace modsecurity::actions::transformations {\n\nclass UpperCase : public Transformation {\n public:\n    using Transformation::Transformation;\n\n    bool transform(std::string &value, const Transaction *trans) const override;\n};\n\n}  // namespace modsecurity::actions::transformations\n\n#endif  // SRC_ACTIONS_TRANSFORMATIONS_UPPER_CASE_H_\n"
  },
  {
    "path": "src/actions/transformations/url_decode.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"url_decode.h\"\n\n#include \"src/utils/decode.h\"\n\n\nnamespace modsecurity::actions::transformations {\n\n\nbool UrlDecode::transform(std::string &value, const Transaction *trans) const {\n    int invalid_count;\n    return utils::urldecode_nonstrict_inplace(value, invalid_count);\n}\n\n\n}  // namespace modsecurity::actions::transformations\n"
  },
  {
    "path": "src/actions/transformations/url_decode.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#ifndef SRC_ACTIONS_TRANSFORMATIONS_URL_DECODE_H_\n#define SRC_ACTIONS_TRANSFORMATIONS_URL_DECODE_H_\n\n#include \"transformation.h\"\n\nnamespace modsecurity::actions::transformations {\n\nclass UrlDecode : public Transformation {\n public:\n    using Transformation::Transformation;\n\n    bool transform(std::string &value, const Transaction *trans) const override;\n};\n\n}  // namespace modsecurity::actions::transformations\n\n#endif  // SRC_ACTIONS_TRANSFORMATIONS_URL_DECODE_H_\n"
  },
  {
    "path": "src/actions/transformations/url_decode_uni.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"url_decode_uni.h\"\n\n#include \"modsecurity/rules_set.h\"\n#include \"src/utils/string.h\"\n\nusing namespace modsecurity::utils::string;\n\nnamespace modsecurity::actions::transformations {\n\n\n/**\n *\n * IMP1 Assumes NUL-terminated\n */\nstatic inline bool inplace(std::string &value,\n    const Transaction *t) {\n    bool changed = false;\n    auto d = reinterpret_cast<unsigned char*>(value.data());\n    const unsigned char *input = d;\n    const auto input_len = value.length();\n\n    std::string::size_type i, count, fact, j, xv;\n    int hmap = -1;\n\n    i = count = 0;\n    while (i < input_len) {\n        if (input[i] == '%') {\n            if ((i + 1 < input_len) &&\n                ((input[i + 1] == 'u') || (input[i + 1] == 'U'))) {\n            /* Character is a percent sign. */\n                /* IIS-specific %u encoding. */\n                if (i + 5 < input_len) {\n                    /* We have at least 4 data bytes. */\n                    if ((VALID_HEX(input[i + 2])) &&\n                        (VALID_HEX(input[i + 3])) &&\n                        (VALID_HEX(input[i + 4])) &&\n                        (VALID_HEX(input[i + 5]))) {\n\n                        fact = 1;\n\n                        if (t\n                            && t->m_rules->m_unicodeMapTable.m_set == true\n                            && t->m_rules->m_unicodeMapTable.m_unicodeMapTable != NULL\n                            && t->m_rules->m_unicodeMapTable.m_unicodeCodePage > 0)  {\n\n                            int Code = 0;\n\n                            for (j = 5; j >= 2; j--) {\n                                if (isxdigit((input[i+j]))) {\n                                    if (input[i+j] >= 97) {\n                                        xv = (input[i+j] - 97) + 10;\n                                    } else if (input[i+j] >= 65)  {\n                                        xv = (input[i+j] - 65) + 10;\n                                    } else {\n                                        xv = (input[i+j]) - 48;\n                                    }\n                                    Code += (xv * fact);\n                                    fact *= 16;\n                                }\n                            }\n\n                            if (Code >= 0 && Code <= 65535)  {\n                                RulesSet *r = t->m_rules;\n                                hmap = r->m_unicodeMapTable.m_unicodeMapTable->at(Code);\n                            }\n                        }\n\n                        if (hmap != -1)  {\n                            *d = hmap;\n                        } else {\n                            /* We first make use of the lower byte here,\n                             * ignoring the higher byte. */\n                            *d = utils::string::x2c(&input[i + 4]);\n\n                            /* Full width ASCII (ff01 - ff5e)\n                             * needs 0x20 added */\n                            if ((*d > 0x00) && (*d < 0x5f)\n                                    && ((input[i + 2] == 'f')\n                                    || (input[i + 2] == 'F'))\n                                    && ((input[i + 3] == 'f')\n                                    || (input[i + 3] == 'F'))) {\n                                (*d) += 0x20;\n                            }\n                        }\n                        d++;\n                        i += 6;\n                        changed = true;\n                    } else {\n                        /* Invalid data, skip %u. */\n                        *d++ = input[i++];\n                        *d++ = input[i++];\n                    }\n                } else {\n                    /* Not enough bytes (4 data bytes), skip %u. */\n                    *d++ = input[i++];\n                    *d++ = input[i++];\n                }\n            } else {\n                /* Standard URL encoding. */\n                /* Are there enough bytes available? */\n                if (i + 2 < input_len) {\n                    /* Yes. */\n\n                    /* Decode a %xx combo only if it is valid.\n                     */\n                    char c1 = input[i + 1];\n                    char c2 = input[i + 2];\n\n                    if (VALID_HEX(c1) && VALID_HEX(c2)) {\n                        *d++ = utils::string::x2c(&input[i + 1]);\n                        i += 3;\n                        changed = true;\n                    } else {\n                        /* Not a valid encoding, skip this % */\n                        *d++ = input[i++];\n                        count++;\n                    }\n                } else {\n                    /* Not enough bytes available, skip this % */\n                    *d++ = input[i++];\n                }\n            }\n        } else {\n            /* Character is not a percent sign. */\n            if (input[i] == '+') {\n                *d++ = ' ';\n                changed = true;\n            } else {\n                *d++ = input[i];\n            }\n\n            i++;\n        }\n    }\n\n    *d = '\\0';\n\n    value.resize(d - input);\n    return changed;\n}\n\n\n\nbool UrlDecodeUni::transform(std::string &value, const Transaction *trans) const {\n    return inplace(value, trans);\n}\n\n\n}  // namespace modsecurity::actions::transformations\n"
  },
  {
    "path": "src/actions/transformations/url_decode_uni.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#ifndef SRC_ACTIONS_TRANSFORMATIONS_URL_DECODE_UNI_H_\n#define SRC_ACTIONS_TRANSFORMATIONS_URL_DECODE_UNI_H_\n\n#include \"transformation.h\"\n\nnamespace modsecurity::actions::transformations {\n\nclass UrlDecodeUni : public Transformation {\n public:\n    using Transformation::Transformation;\n\n    bool transform(std::string &value, const Transaction *trans) const override;\n};\n\n}  // namespace modsecurity::actions::transformations\n\n#endif  // SRC_ACTIONS_TRANSFORMATIONS_URL_DECODE_UNI_H_\n"
  },
  {
    "path": "src/actions/transformations/url_encode.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"url_encode.h\"\n\n#include \"src/utils/string.h\"\n\nnamespace modsecurity::actions::transformations {\n\n\nstatic inline bool url_enc(std::string &value) {\n    const auto len = value.size() * 3 + 1;\n    std::string ret(len, {});\n\n    bool changed = false;\n\n    /* ENH Only encode the characters that really need to be encoded. */\n\n    char *d = ret.data();\n    for (const auto c : value) {\n        if (c == ' ') {\n            *d++ = '+';\n            changed = true;\n        } else {\n            if ( (c == 42) || ((c >= 48) && (c <= 57))\n                || ((c >= 65) && (c <= 90))\n                || ((c >= 97) && (c <= 122))) {\n                *d++ = c;\n            }\n            else\n            {\n                *d++ = '%';\n                d = (char *)utils::string::c2x(c, (unsigned char *)d);\n                changed = true;\n            }\n        }\n    }\n\n    ret.resize(d - ret.c_str());\n    std::swap(value, ret);\n    return changed;\n}\n\n\nbool UrlEncode::transform(std::string &value, const Transaction *trans) const {\n    return url_enc(value);\n}\n\n\n}  // namespace modsecurity::actions::transformations\n"
  },
  {
    "path": "src/actions/transformations/url_encode.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#ifndef SRC_ACTIONS_TRANSFORMATIONS_URL_ENCODE_H_\n#define SRC_ACTIONS_TRANSFORMATIONS_URL_ENCODE_H_\n\n#include \"transformation.h\"\n\nnamespace modsecurity::actions::transformations {\n\nclass UrlEncode : public Transformation {\n public:\n    using Transformation::Transformation;\n\n    bool transform(std::string &value, const Transaction *trans) const override;\n};\n\n}  // namespace modsecurity::actions::transformations\n\n#endif  // SRC_ACTIONS_TRANSFORMATIONS_URL_ENCODE_H_\n"
  },
  {
    "path": "src/actions/transformations/utf8_to_unicode.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"utf8_to_unicode.h\"\n\n#include <cstring>\n\n#include \"src/utils/string.h\"\n\n\nconstexpr int UNICODE_ERROR_CHARACTERS_MISSING   = -1;\nconstexpr int UNICODE_ERROR_INVALID_ENCODING     = -2;\n\n\nnamespace modsecurity::actions::transformations {\n\n\nstatic inline bool encode(std::string &value) {\n    auto input = reinterpret_cast<unsigned char*>(value.data());\n    const auto input_len = value.length();\n\n    bool changed = false;\n    std::string::size_type count = 0;\n    auto bytes_left = input_len;\n    unsigned char unicode[8];\n\n    /* RFC3629 states that UTF-8 are encoded using sequences of 1 to 4 octets. */\n    /* Max size per character should fit in 4 bytes */\n    const auto len = input_len * 4 + 1;\n    std::string ret(len, {});\n    auto data = ret.data();\n\n    for (std::string::size_type i = 0; i < bytes_left;)  {\n        int unicode_len = 0;\n        unsigned int d = 0;\n        unsigned char c;\n        const auto* utf = &input[i];\n\n        c = *utf;\n\n        /* If first byte begins with binary 0 it is single byte encoding */\n        if ((c & 0x80) == 0) {\n            /* single byte unicode (7 bit ASCII equivilent) has no validation */\n            count++;\n            if (count <= len) {\n                if (c == 0 && input_len > i + 1) {\n                    unsigned char z[2];\n                    z[0] = *utf;\n                    z[1] = *(utf + 1);\n                    *data = utils::string::x2c((unsigned char*) &z);\n                } else {\n                    *data++ = c;\n                }\n            }\n        } else if ((c & 0xE0) == 0xC0) {\n            /* If first byte begins with binary 110 it is two byte encoding*/\n            /* check we have at least two bytes */\n            if (bytes_left < 2) {\n                /* check second byte starts with binary 10 */\n                unicode_len = UNICODE_ERROR_CHARACTERS_MISSING;\n            } else if (((*(utf + 1)) & 0xC0) != 0x80) {\n                unicode_len = UNICODE_ERROR_INVALID_ENCODING;\n            } else {\n                unicode_len = 2;\n                count += 6;\n                if (count <= len) {\n                    int length = 0;\n                    /* compute character number */\n                    d = ((c & 0x1F) << 6) | (*(utf + 1) & 0x3F);\n                    *data++ = '%';\n                    *data++ = 'u';\n                    snprintf(reinterpret_cast<char *>(unicode),\n                             sizeof(reinterpret_cast<char *>(unicode)),\n                             \"%x\", d);\n                    length = strlen(reinterpret_cast<char *>(unicode));\n\n                    switch (length) {\n                        case 1:\n                            *data++ = '0';\n                            *data++ = '0';\n                            *data++ = '0';\n                            break;\n                        case 2:\n                            *data++ = '0';\n                            *data++ = '0';\n                            break;\n                        case 3:\n                            *data++ = '0';\n                            break;\n                        case 4:\n                        case 5:\n                            break;\n                    }\n\n                    for (std::string::size_type j = 0; j < length; j++) {\n                        *data++ = unicode[j];\n                    }\n\n                    changed = true;\n                }\n            }\n        } else if ((c & 0xF0) == 0xE0) {\n        /* If first byte begins with binary 1110 it is three byte encoding */\n            /* check we have at least three bytes */\n            if (bytes_left < 3) {\n                /* check second byte starts with binary 10 */\n                unicode_len = UNICODE_ERROR_CHARACTERS_MISSING;\n            } else if (((*(utf + 1)) & 0xC0) != 0x80) {\n                /* check third byte starts with binary 10 */\n                unicode_len = UNICODE_ERROR_INVALID_ENCODING;\n            } else if (((*(utf + 2)) & 0xC0) != 0x80) {\n                unicode_len = UNICODE_ERROR_INVALID_ENCODING;\n            } else {\n                unicode_len = 3;\n                count+=6;\n                if (count <= len) {\n                    int length = 0;\n                    /* compute character number */\n                    d = ((c & 0x0F) << 12)\n                        | ((*(utf + 1) & 0x3F) << 6)\n                        | (*(utf + 2) & 0x3F);\n                    *data++ = '%';\n                    *data++ = 'u';\n                    snprintf(reinterpret_cast<char *>(unicode),\n                             sizeof(reinterpret_cast<char *>(unicode)),\n                             \"%x\", d);\n                    length = strlen(reinterpret_cast<char *>(unicode));\n\n                    switch (length)  {\n                        case 1:\n                            *data++ = '0';\n                            *data++ = '0';\n                            *data++ = '0';\n                            break;\n                        case 2:\n                            *data++ = '0';\n                            *data++ = '0';\n                            break;\n                        case 3:\n                            *data++ = '0';\n                            break;\n                        case 4:\n                        case 5:\n                            break;\n                    }\n\n                    for (std::string::size_type j = 0; j < length; j++) {\n                        *data++ = unicode[j];\n                    }\n\n                    changed = true;\n                }\n            }\n        } else if ((c & 0xF8) == 0xF0) {\n            /* If first byte begins with binary 11110 it\n             * is four byte encoding\n             */\n            /* restrict characters to UTF-8 range (U+0000 - U+10FFFF) */\n            if (c >= 0xF5) {\n                *data++ = c;\n            }\n            /* check we have at least four bytes */\n            if (bytes_left < 4) {\n                /* check second byte starts with binary 10 */\n                unicode_len = UNICODE_ERROR_CHARACTERS_MISSING;\n            } else if (((*(utf + 1)) & 0xC0) != 0x80) {\n                /* check third byte starts with binary 10 */\n                unicode_len = UNICODE_ERROR_INVALID_ENCODING;\n            } else if (((*(utf + 2)) & 0xC0) != 0x80) {\n                /* check forth byte starts with binary 10 */\n                unicode_len = UNICODE_ERROR_INVALID_ENCODING;\n            } else if (((*(utf + 3)) & 0xC0) != 0x80) {\n                unicode_len = UNICODE_ERROR_INVALID_ENCODING;\n            } else {\n                unicode_len = 4;\n                count+=7;\n                if (count <= len) {\n                    int length = 0;\n                    /* compute character number */\n                    d = ((c & 0x07) << 18)\n                        | ((*(utf + 1) & 0x3F) << 12)\n                        | ((*(utf + 2) & 0x3F) << 6)\n                        | (*(utf + 3) & 0x3F);\n                    *data++ = '%';\n                    *data++ = 'u';\n                    snprintf(reinterpret_cast<char *>(unicode),\n                             sizeof(reinterpret_cast<char *>(unicode)),\n                             \"%x\", d);\n                    length = strlen(reinterpret_cast<char *>(unicode));\n\n                    switch (length)  {\n                        case 1:\n                            *data++ = '0';\n                            *data++ = '0';\n                            *data++ = '0';\n                            break;\n                        case 2:\n                            *data++ = '0';\n                            *data++ = '0';\n                            break;\n                        case 3:\n                            *data++ = '0';\n                            break;\n                        case 4:\n                        case 5:\n                            break;\n                    }\n\n                    for (std::string::size_type j = 0; j < length; j++) {\n                        *data++ = unicode[j];\n                    }\n\n                    changed = true;\n                }\n            }\n        } else {\n            /* any other first byte is invalid (RFC 3629) */\n            count++;\n            if (count <= len)\n                *data++ = c;\n        }\n\n        /* invalid UTF-8 character number range (RFC 3629) */\n        if ((d >= 0xD800) && (d <= 0xDFFF)) {\n            count++;\n            if (count <= len)\n                *data++ = c;\n        }\n\n        /* check for overlong */\n        if ((unicode_len == 4) && (d < 0x010000)) {\n            /* four byte could be represented with less bytes */\n            count++;\n            if (count <= len)\n                *data++ = c;\n        } else if ((unicode_len == 3) && (d < 0x0800)) {\n            /* three byte could be represented with less bytes */\n            count++;\n            if (count <= len)\n                *data++ = c;\n        } else if ((unicode_len == 2) && (d < 0x80)) {\n            /* two byte could be represented with less bytes */\n            count++;\n            if (count <= len)\n                *data++ = c;\n        }\n\n        if (unicode_len > 0) {\n            i += unicode_len;\n        } else {\n            i++;\n        }\n    }\n\n    *data ='\\0';\n\n    ret.resize(data - ret.c_str());\n    std::swap(value, ret);\n    return changed;\n}\n\n\nbool Utf8ToUnicode::transform(std::string &value, const Transaction *trans) const {\n    return encode(value);\n}\n\n\n}  // namespace modsecurity::actions::transformations\n"
  },
  {
    "path": "src/actions/transformations/utf8_to_unicode.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#ifndef SRC_ACTIONS_TRANSFORMATIONS_UTF8_TO_UNICODE_H_\n#define SRC_ACTIONS_TRANSFORMATIONS_UTF8_TO_UNICODE_H_\n\n#include \"transformation.h\"\n\nnamespace modsecurity::actions::transformations {\n\nclass Utf8ToUnicode : public Transformation {\n public:\n    using Transformation::Transformation;\n\n    bool transform(std::string &value, const Transaction *trans) const override;\n};\n\n}  // namespace modsecurity::actions::transformations\n\n#endif  // SRC_ACTIONS_TRANSFORMATIONS_UTF8_TO_UNICODE_H_\n"
  },
  {
    "path": "src/actions/ver.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"src/actions/ver.h\"\n\n#include \"modsecurity/rule_with_actions.h\"\n\n\nnamespace modsecurity::actions {\n\n\nbool Ver::evaluate(RuleWithActions *rule, Transaction *transaction) {\n    rule->m_ver = m_parser_payload;\n    return true;\n}\n\n\n}  // namespace modsecurity::actions\n"
  },
  {
    "path": "src/actions/ver.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <string>\n\n#include \"modsecurity/actions/action.h\"\n\n#ifndef SRC_ACTIONS_VER_H_\n#define SRC_ACTIONS_VER_H_\n\nclass Transaction;\n\nnamespace modsecurity {\nclass Transaction;\nnamespace actions {\n\n\nclass Ver : public Action {\n public:\n    explicit Ver(const std::string &action) : Action(action, Kind::ConfigurationKind) { }\n\n    bool evaluate(RuleWithActions *rule, Transaction *transaction) override;\n\n private:\n    std::string m_ver;\n};\n\n\n}  // namespace actions\n}  // namespace modsecurity\n\n#endif  // SRC_ACTIONS_VER_H_\n"
  },
  {
    "path": "src/actions/xmlns.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"src/actions/xmlns.h\"\n\n#include <iostream>\n#include <string>\n\n#include \"modsecurity/actions/action.h\"\n#include \"modsecurity/transaction.h\"\n\nnamespace modsecurity {\nnamespace actions {\n\n\nbool XmlNS::init(std::string *error) {\n    size_t pos;\n    std::string http = \"http://\";\n\n    pos = m_parser_payload.find(\"=\");\n    if (pos == std::string::npos) {\n        error->assign(\"XMLS: Bad format, missing equals sign.\");\n        return false;\n    }\n    m_scope = std::string(m_parser_payload, 0, pos);\n    m_href = std::string(m_parser_payload, pos+1, m_parser_payload.size());\n\n    if (m_href.empty() || m_scope.empty()) {\n        error->assign(\"XMLS: XMLNS is invalid. Expecting a \" \\\n            \"name=value format.\");\n        return false;\n    }\n\n    if (m_href[0] == '\\'' && m_href.size() > 3) {\n        m_href.erase(0, 1);\n        m_href.pop_back();\n    }\n\n    if (m_href.compare(0, http.length(), http) != 0) {\n        error->assign(\"XMLS: Missing xmlns href for prefix: \" \\\n            \"`\" + m_href + \"'.\");\n        return false;\n    }\n\n    return true;\n}\n\n\n}  // namespace actions\n}  // namespace modsecurity\n"
  },
  {
    "path": "src/actions/xmlns.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <string>\n\n#include \"modsecurity/actions/action.h\"\n\n#ifndef SRC_ACTIONS_XMLNS_H_\n#define SRC_ACTIONS_XMLNS_H_\n\nclass Transaction;\n\nnamespace modsecurity {\nclass Transaction;\nnamespace actions {\n\n\nclass XmlNS : public Action {\n public:\n    explicit XmlNS(const std::string &action) : Action(action) { }\n\n    bool evaluate(RuleWithActions *rule, Transaction *transaction) override {\n        return true;\n    }\n\n    bool init(std::string *error) override;\n\n    std::string m_scope;\n    std::string m_href;\n};\n\n\n}  // namespace actions\n}  // namespace modsecurity\n\n#endif  // SRC_ACTIONS_XMLNS_H_\n"
  },
  {
    "path": "src/anchored_set_variable.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <ctime>\n#include <iostream>\n#include <fstream>\n#include <string>\n#include <vector>\n\n#include \"modsecurity/anchored_set_variable.h\"\n#include \"modsecurity/modsecurity.h\"\n#include \"modsecurity/transaction.h\"\n#include \"src/utils/regex.h\"\n#include \"src/variables/variable.h\"\n\nnamespace modsecurity {\n\n\nAnchoredSetVariable::AnchoredSetVariable(Transaction *t,\n    const std::string &name)\n    : m_transaction(t),\n    m_name(name) {\n        reserve(10);\n    }\n\n\nAnchoredSetVariable::~AnchoredSetVariable() {\n    unset();\n}\n\n\nvoid AnchoredSetVariable::unset() {\n    for (const auto& x : *this) {\n        VariableValue *var = x.second;\n        delete var;\n    }\n    clear();\n}\n\n\nvoid AnchoredSetVariable::set(const std::string &key,\n    const std::string &value, size_t offset, size_t len) {\n    VariableValue *var = new VariableValue(&m_name, &key, &value);\n    var->addOrigin(len, offset);\n    emplace(key, var);\n}\n\n\nvoid AnchoredSetVariable::set(const std::string &key,\n    const std::string &value, size_t offset) {\n    VariableValue *var = new VariableValue(&m_name, &key, &value);\n    var->addOrigin(value.size(), offset);\n    emplace(key, var);\n}\n\n\nvoid AnchoredSetVariable::resolve(\n    std::vector<const VariableValue *> *l) const {\n    for (const auto& x : *this) {\n        l->insert(l->begin(), new VariableValue(x.second));\n    }\n}\n\n\nvoid AnchoredSetVariable::resolve(\n    std::vector<const VariableValue *> *l) {\n    static_cast<const AnchoredSetVariable&>(*this).resolve(l);\n}\n\n\nvoid AnchoredSetVariable::resolve(\n    std::vector<const VariableValue *> *l,\n    const variables::KeyExclusions &ke) const {\n    for (const auto& x : *this) {\n        if (!ke.toOmit(x.first)) {\n            l->insert(l->begin(), new VariableValue(x.second));\n        } else {\n            ms_dbg_a(m_transaction, 7, \"Excluding key: \" + x.first\n                + \" from target value.\");\n        }\n    }\n}\n\n\nvoid AnchoredSetVariable::resolve(\n    std::vector<const VariableValue *> *l,\n    variables::KeyExclusions &ke) {  // cppcheck-suppress constParameterReference\n    static_cast<const AnchoredSetVariable&>(*this).resolve(l, ke);\n}\n\n\nvoid AnchoredSetVariable::resolve(const std::string &key,\n    std::vector<const VariableValue *> *l) {\n    auto range = this->equal_range(key);\n    for (auto it = range.first; it != range.second; ++it) {\n        l->push_back(new VariableValue(it->second));\n    }\n}\n\n\nstd::unique_ptr<std::string> AnchoredSetVariable::resolveFirst(\n    const std::string &key) {\n\n    if (auto search = this->find(key); search != this->end()) {\n        return std::make_unique<std::string>(search->second->getValue());\n    }\n\n    return nullptr;\n}\n\n\nvoid AnchoredSetVariable::resolveRegularExpression(Utils::Regex *r,\n    std::vector<const VariableValue *> *l) const {\n    for (const auto& x : *this) {\n        int ret = Utils::regex_search(x.first, *r);\n        if (ret <= 0) {\n            continue;\n        }\n        l->insert(l->begin(), new VariableValue(x.second));\n    }\n}\n\n\nvoid AnchoredSetVariable::resolveRegularExpression(Utils::Regex *r,\n    std::vector<const VariableValue *> *l) {\n    static_cast<const AnchoredSetVariable&>(*this).resolveRegularExpression(r, l);\n}\n\n\nvoid AnchoredSetVariable::resolveRegularExpression(Utils::Regex *r,\n    std::vector<const VariableValue *> *l,\n    const variables::KeyExclusions &ke) const {\n    for (const auto& x : *this) {\n        int ret = Utils::regex_search(x.first, *r);\n        if (ret <= 0) {\n            continue;\n        }\n        if (!ke.toOmit(x.first)) {\n            l->insert(l->begin(), new VariableValue(x.second));\n        } else {\n            ms_dbg_a(m_transaction, 7, \"Excluding key: \" + x.first\n                + \" from target value.\");\n        }\n    }\n}\n\n\nvoid AnchoredSetVariable::resolveRegularExpression(Utils::Regex *r,\n    std::vector<const VariableValue *> *l,\n    variables::KeyExclusions &ke) {  // cppcheck-suppress constParameterReference\n    static_cast<const AnchoredSetVariable&>(*this).resolveRegularExpression(r, l, ke);\n}\n\n\n}  // namespace modsecurity\n"
  },
  {
    "path": "src/anchored_variable.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <ctime>\n#include <iostream>\n#include <fstream>\n#include <string>\n#include <vector>\n\n#include \"../headers/modsecurity/anchored_variable.h\"\n#include \"modsecurity/modsecurity.h\"\n#include \"modsecurity/transaction.h\"\n#include \"src/utils/regex.h\"\n\nnamespace modsecurity {\n\n\nAnchoredVariable::AnchoredVariable(Transaction *t,\n    const std::string &name)\n    : m_transaction(t),\n    m_offset(0),\n    m_name(name),\n    m_value(\"\"),\n    m_var(&name) {\n}\n\n\nvoid AnchoredVariable::unset() {\n    m_value.clear();\n}\n\n\nvoid AnchoredVariable::set(const std::string &a, size_t offset,\n    size_t offsetLen) {\n    m_offset = offset;\n    m_value.assign(a.c_str(), a.size());\n    m_var.addOrigin(offsetLen, offset);\n}\n\n\nvoid AnchoredVariable::set(const std::string &a, size_t offset) {\n    m_offset = offset;\n    m_value.assign(a.c_str(), a.size());\n    m_var.addOrigin(m_value.size(), offset);\n}\n\n\nvoid AnchoredVariable::evaluate(std::vector<const VariableValue *> *l) {\n    if (m_name.empty()) {\n        return;\n    }\n\n    m_var.setValue(m_value);\n    l->push_back(new VariableValue(&m_var));\n}\n\n\nstd::string * AnchoredVariable::evaluate() {\n    return &m_value;\n}\n\n\nstd::unique_ptr<std::string> AnchoredVariable::resolveFirst() {\n    if (m_value.empty()) {\n        return nullptr;\n    }\n    return std::make_unique<std::string>(m_value);\n}\n\n\n}  // namespace modsecurity\n"
  },
  {
    "path": "src/audit_log/audit_log.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2023 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"modsecurity/audit_log.h\"\n\n#include <stddef.h>\n#include <stdio.h>\n#include <ctype.h>\n\n#include <fstream>\n\n#include \"modsecurity/transaction.h\"\n#include \"modsecurity/rule_message.h\"\n#include \"src/audit_log/writer/https.h\"\n#include \"src/audit_log/writer/parallel.h\"\n#include \"src/audit_log/writer/serial.h\"\n#include \"src/audit_log/writer/writer.h\"\n#include \"src/utils/regex.h\"\n\n#define PARTS_CONSTAINS(a, c) \\\n    if (new_parts.find(toupper(a)) != std::string::npos \\\n        || new_parts.find(tolower(a)) != std::string::npos) { \\\n          parts = parts | c; \\\n    }\n\n#define PARTS_CONSTAINS_REM(a, c) \\\n    if (new_parts.find(toupper(a)) != std::string::npos \\\n        || new_parts.find(tolower(a)) != std::string::npos) { \\\n          parts = parts & ~c; \\\n    }\n\n#define AL_MERGE_STRING_CONF(a, c) \\\n    if (a.empty() == false) { \\\n        c = a; \\\n    }\n\n\nnamespace modsecurity {\nnamespace audit_log {\n\n\nAuditLog::AuditLog() = default;\n\n\nAuditLog::~AuditLog() {\n    if (m_writer) {\n        delete m_writer;\n        m_writer = nullptr;\n    }\n}\n\n\nbool AuditLog::setStorageDirMode(int permission) {\n    this->m_directoryPermission = permission;\n    return true;\n}\n\n\nbool AuditLog::setFileMode(int permission) {\n    this->m_filePermission = permission;\n    return true;\n}\n\n\nint AuditLog::getFilePermission() const {\n    if (m_filePermission == -1) {\n        return m_defaultFilePermission;\n    }\n\n    return m_filePermission;\n}\n\nint AuditLog::getDirectoryPermission() const {\n    if (m_directoryPermission == -1) {\n        return m_defaultDirectoryPermission;\n    }\n\n    return m_directoryPermission;\n}\n\nbool AuditLog::setStatus(AuditLogStatus status) {\n    this->m_status = status;\n    return true;\n}\n\n\nbool AuditLog::setRelevantStatus(std::string_view status) {\n    this->m_relevant = std::string(status);\n    return true;\n}\n\n\nbool AuditLog::setStorageDir(std::string_view path) {\n    this->m_storage_dir = path;\n    return true;\n}\n\n\nbool AuditLog::setFilePath1(std::string_view path) {\n    this->m_path1 = path;\n    return true;\n}\n\n\nbool AuditLog::setFilePath2(std::string_view path) {\n    this->m_path2 = path;\n    return true;\n}\n\n\nbool AuditLog::setPrefix(std::string_view prefix) {\n    this->m_prefix = prefix;\n    return true;\n}\n\n\nbool AuditLog::setFormat(AuditLogFormat fmt) {\n    this->m_format = fmt;\n    return true;\n}\n\nint AuditLog::addParts(int parts, std::string_view new_parts) {\n    PARTS_CONSTAINS('A', AAuditLogPart)\n    PARTS_CONSTAINS('B', BAuditLogPart)\n    PARTS_CONSTAINS('C', CAuditLogPart)\n    PARTS_CONSTAINS('D', DAuditLogPart)\n    PARTS_CONSTAINS('E', EAuditLogPart)\n    PARTS_CONSTAINS('F', FAuditLogPart)\n    PARTS_CONSTAINS('G', GAuditLogPart)\n    PARTS_CONSTAINS('H', HAuditLogPart)\n    PARTS_CONSTAINS('I', IAuditLogPart)\n    PARTS_CONSTAINS('J', JAuditLogPart)\n    PARTS_CONSTAINS('K', KAuditLogPart)\n    PARTS_CONSTAINS('Z', ZAuditLogPart)\n\n    return parts;\n}\n\n\nint AuditLog::removeParts(int parts, std::string_view new_parts) {\n    PARTS_CONSTAINS_REM('A', AAuditLogPart)\n    PARTS_CONSTAINS_REM('B', BAuditLogPart)\n    PARTS_CONSTAINS_REM('C', CAuditLogPart)\n    PARTS_CONSTAINS_REM('D', DAuditLogPart)\n    PARTS_CONSTAINS_REM('E', EAuditLogPart)\n    PARTS_CONSTAINS_REM('F', FAuditLogPart)\n    PARTS_CONSTAINS_REM('G', GAuditLogPart)\n    PARTS_CONSTAINS_REM('H', HAuditLogPart)\n    PARTS_CONSTAINS_REM('I', IAuditLogPart)\n    PARTS_CONSTAINS_REM('J', JAuditLogPart)\n    PARTS_CONSTAINS_REM('K', KAuditLogPart)\n    PARTS_CONSTAINS_REM('Z', ZAuditLogPart)\n\n    return parts;\n}\n\n\nbool AuditLog::setParts(std::string_view new_parts) {\n    int parts = 0;\n\n    PARTS_CONSTAINS('A', AAuditLogPart)\n    PARTS_CONSTAINS('B', BAuditLogPart)\n    PARTS_CONSTAINS('C', CAuditLogPart)\n    PARTS_CONSTAINS('D', DAuditLogPart)\n    PARTS_CONSTAINS('E', EAuditLogPart)\n    PARTS_CONSTAINS('F', FAuditLogPart)\n    PARTS_CONSTAINS('G', GAuditLogPart)\n    PARTS_CONSTAINS('H', HAuditLogPart)\n    PARTS_CONSTAINS('I', IAuditLogPart)\n    PARTS_CONSTAINS('J', JAuditLogPart)\n    PARTS_CONSTAINS('K', KAuditLogPart)\n    PARTS_CONSTAINS('Z', ZAuditLogPart)\n\n    m_parts = parts;\n    return true;\n}\n\n\nint AuditLog::getParts() const {\n    if (m_parts == -1) {\n        return m_defaultParts;\n    }\n\n    return m_parts;\n}\n\n\nbool AuditLog::setType(AuditLogType audit_type) {\n    this->m_type = audit_type;\n    return true;\n}\n\n\nbool AuditLog::init(std::string *error) {\n    audit_log::writer::Writer *tmp_writer;\n\n    if ((m_status == OffAuditLogStatus || m_status == NotSetLogStatus)\n        && !m_ctlAuditEngineActive) {\n        if (m_writer) {\n            delete m_writer;\n            m_writer = nullptr;\n        }\n        return true;\n    }\n\n    if (m_type == ParallelAuditLogType) {\n        tmp_writer = new audit_log::writer::Parallel(this);\n    } else if (m_type == HttpsAuditLogType) {\n        tmp_writer = new audit_log::writer::Https(this);\n    } else {\n        /*\n         * if (m_type == SerialAuditLogType\n         * || m_type == NotSetAuditLogType)\n         *\n         */\n        tmp_writer = new audit_log::writer::Serial(this);\n    }\n\n    if (tmp_writer == nullptr) {\n        error->assign(\"Writer memory alloc failed!\");\n        return false;\n    }\n\n    if (tmp_writer->init(error) == false) {\n        delete tmp_writer;\n        return false;\n    }\n\n    if (m_writer) {\n        delete m_writer;\n    }\n\n    m_writer = tmp_writer;\n\n    return true;\n}\n\n\nbool AuditLog::isRelevant(int status) const {\n    std::string sstatus = std::to_string(status);\n\n    if (m_relevant.empty()) {\n        return false;\n    }\n\n\n    if (sstatus.empty()) {\n        return true;\n    }\n\n    return Utils::regex_search(sstatus,\n        Utils::Regex(m_relevant)) != 0;\n}\n\nbool AuditLog::isRelevant(int status) {\n    return static_cast<const AuditLog&>(*this).isRelevant(status);\n}\n\n\nbool AuditLog::saveIfRelevant(Transaction *transaction) {\n    return saveIfRelevant(transaction, -1);\n}\n\n\nbool AuditLog::saveIfRelevant(Transaction *transaction, int parts) {\n    bool saveAnyway = false;\n\n    AuditLogStatus transactionAuditLogStatus(m_status);\n    if (transaction->m_ctlAuditEngine != NotSetLogStatus) {\n        transactionAuditLogStatus = transaction->m_ctlAuditEngine;\n    }\n\n    if (transactionAuditLogStatus == OffAuditLogStatus || transactionAuditLogStatus == NotSetLogStatus) {\n        ms_dbg_a(transaction, 5, \"Audit log engine was not set.\");\n        return true;\n    }\n\n    for (const RuleMessage &i : transaction->m_rulesMessages) {\n        if (i.m_noAuditLog == false) {\n            saveAnyway = true;\n            break;\n        }\n    }\n\n    if ((transactionAuditLogStatus == RelevantOnlyAuditLogStatus\n        && this->isRelevant(transaction->m_httpCodeReturned) == false)\n        && saveAnyway == false) {\n        ms_dbg_a(transaction, 9, \"Return code `\" +\n            std::to_string(transaction->m_httpCodeReturned) + \"'\" \\\n            \" is not interesting to audit logs, relevant code(s): `\" +\n            m_relevant + \"'.\");\n\n        return false;\n    }\n\n    if (parts == -1) {\n        parts = m_parts;\n    }\n    ms_dbg_a(transaction, 5, \"Saving this request as part \" \\\n            \"of the audit logs.\");\n    if (m_writer == nullptr) {\n        ms_dbg_a(transaction, 1, \"Internal error, audit log writer is null\");\n    } else {\n        std::string error;\n        bool a = m_writer->write(transaction, parts, &error);\n        if (a == false) {\n            ms_dbg_a(transaction, 1, \"Cannot save the audit log: \" + error);\n            return false;\n        }\n    }\n\n    return true;\n}\n\n\nbool AuditLog::close() {\n    return true;\n}\n\n\nbool AuditLog::merge(AuditLog *from, std::string *error) {\n    AL_MERGE_STRING_CONF(from->m_path1, m_path1);\n    AL_MERGE_STRING_CONF(from->m_path2, m_path2);\n    AL_MERGE_STRING_CONF(from->m_storage_dir, m_storage_dir);\n    AL_MERGE_STRING_CONF(from->m_relevant, m_relevant);\n    AL_MERGE_STRING_CONF(from->m_prefix, m_prefix);\n\n    if (from->m_filePermission != -1) {\n        m_filePermission = from->m_filePermission;\n    }\n\n    if (from->m_directoryPermission != -1) {\n        m_directoryPermission = from->m_directoryPermission;\n    }\n\n    if (from->m_type != NotSetAuditLogType) {\n        m_type = from->m_type;\n    }\n\n    if (from->m_status != NotSetLogStatus) {\n        m_status = from->m_status;\n    }\n\n    if (from->m_parts != -1) {\n        m_parts = from->m_parts;\n    }\n\n    if (from->m_format != NotSetAuditLogFormat) {\n        m_format = from->m_format;\n    }\n\n    if (from->m_ctlAuditEngineActive) {\n        m_ctlAuditEngineActive = from->m_ctlAuditEngineActive;\n    }\n\n    return init(error);\n}\n\n\n}  // namespace audit_log\n}  // namespace modsecurity\n"
  },
  {
    "path": "src/audit_log/writer/https.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"src/audit_log/writer/https.h\"\n\n#include <time.h>\n#include <stdio.h>\n#include <string.h>\n#include <sys/types.h>\n#include <sys/stat.h>\n#include <fcntl.h>\n\n#include <fstream>\n#include <mutex>\n\n#include \"modsecurity/rules_set.h\"\n#include \"modsecurity/audit_log.h\"\n#include \"modsecurity/transaction.h\"\n#include \"src/utils/md5.h\"\n#include \"src/utils/https_client.h\"\n\n\n\nnamespace modsecurity {\nnamespace audit_log {\nnamespace writer {\n\n\nHttps::~Https() {\n}\n\n\nbool Https::init(std::string *error) {\n    return true;\n}\n\n\nbool Https::write(Transaction *transaction, int parts, std::string *error) {\n    Utils::HttpsClient m_http_client;\n    ms_dbg_a(transaction, 7, \"Sending logs to: \" + m_audit->m_path1);\n\n    std::string log = transaction->toJSON(parts);\n    m_http_client.setRequestType(\"application/json\");\n    m_http_client.setRequestBody(log);\n    m_http_client.download(m_audit->m_path1);\n    return true;\n}\n\n}  // namespace writer\n}  // namespace audit_log\n}  // namespace modsecurity\n"
  },
  {
    "path": "src/audit_log/writer/https.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#ifdef __cplusplus\n#include <iostream>\n#include <fstream>\n#include <string>\n#endif\n\n#ifndef SRC_AUDIT_LOG_WRITER_HTTPS_H_\n#define SRC_AUDIT_LOG_WRITER_HTTPS_H_\n\n#include \"src/audit_log/writer/writer.h\"\n#include \"modsecurity/transaction.h\"\n\n#ifdef __cplusplus\n\nnamespace modsecurity {\nnamespace audit_log {\nnamespace writer {\n\n/** @ingroup ModSecurity_CPP_API */\nclass Https : public Writer {\n public:\n    explicit Https(audit_log::AuditLog *audit)\n        : audit_log::writer::Writer(audit) { }\n\n    ~Https() override;\n\n    bool init(std::string *error) override;\n    bool write(Transaction *transaction, int parts,\n        std::string *error) override;\n};\n\n}  // namespace writer\n}  // namespace audit_log\n}  // namespace modsecurity\n#endif\n\n#endif  // SRC_AUDIT_LOG_WRITER_HTTPS_H_\n"
  },
  {
    "path": "src/audit_log/writer/parallel.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"src/audit_log/writer/parallel.h\"\n\n#include <time.h>\n#include <stdio.h>\n#include <string.h>\n#include <sys/types.h>\n#include <sys/stat.h>\n#include <fcntl.h>\n#ifndef WIN32\n#include <unistd.h>\n#else\n#include <io.h>\n#include \"src/compat/msvc.h\"\n#endif\n#include <stdlib.h>\n\n#include <fstream>\n#include <mutex>\n\n#include \"modsecurity/audit_log.h\"\n#include \"modsecurity/transaction.h\"\n#include \"src/utils/system.h\"\n#include \"src/utils/md5.h\"\n\n\nnamespace modsecurity {\nnamespace audit_log {\nnamespace writer {\n\n\nParallel::~Parallel() {\n    utils::SharedFiles::getInstance().close(m_audit->m_path1);\n    utils::SharedFiles::getInstance().close(m_audit->m_path2);\n}\n\n\ninline std::string Parallel::logFilePath(const time_t *t,\n    int part) {\n    std::string name;\n\n    struct tm timeinfo;\n    localtime_r(t, &timeinfo);\n\n    if (part & YearMonthDayDirectory) {\n        char tstr[std::size(\"/yyyymmdd\")];\n        strftime(tstr, std::size(tstr), \"/%Y%m%d\", &timeinfo);\n        name.append(tstr);\n    }\n\n    if (part & YearMonthDayAndTimeDirectory) {\n        char tstr[std::size(\"/yyyymmdd-hhmm\")];\n        strftime(tstr, std::size(tstr), \"/%Y%m%d-%H%M\", &timeinfo);\n        name.append(tstr);\n    }\n\n    if (part & YearMonthDayAndTimeFileName) {\n        char tstr[std::size(\"/yyyymmdd-hhmmss\")];\n        strftime(tstr, std::size(tstr), \"/%Y%m%d-%H%M%S\", &timeinfo);\n        name.append(tstr);\n    }\n\n    return name;\n}\n\n\nbool Parallel::init(std::string *error) {\n    bool ret;\n    if (!m_audit->m_path1.empty()) {\n        ret = utils::SharedFiles::getInstance().open(m_audit->m_path1, error);\n        if (!ret) {\n            return false;\n        }\n    }\n\n    if (!m_audit->m_path2.empty()) {\n        ret = utils::SharedFiles::getInstance().open(m_audit->m_path2, error);\n        if (!ret) {\n            return false;\n        }\n    }\n\n    if (m_audit->m_storage_dir.empty() == false) {\n        if (utils::createDir(m_audit->m_storage_dir,\n            m_audit->getDirectoryPermission(), error) == false) {\n            return false;\n        }\n    }\n\n    return true;\n}\n\n\nbool Parallel::write(Transaction *transaction, int parts, std::string *error) {\n    int fd;\n    std::string log;\n    std::string fileName = logFilePath(&transaction->m_timeStamp,\n        YearMonthDayDirectory | YearMonthDayAndTimeDirectory\n        | YearMonthDayAndTimeFileName);\n    bool ret;\n\n    if (transaction->m_rules->m_auditLog->m_format ==\n            audit_log::AuditLog::JSONAuditLogFormat) {\n        log = transaction->toJSON(parts);\n    } else {\n        std::string boundary;\n        generateBoundary(&boundary);\n        log = transaction->toOldAuditLogFormat(parts, \"-\" + boundary + \"--\", m_audit->m_prefix);\n    }\n\n    const auto &logPath = m_audit->m_storage_dir;\n    fileName = logPath + fileName + \"-\" + transaction->m_id;\n\n    if (logPath.empty()) {\n        error->assign(\"Log path is not valid.\");\n        return false;\n    }\n\n    ret = utils::createDir((logPath +\n        logFilePath(&transaction->m_timeStamp, YearMonthDayDirectory)).c_str(),\n        m_audit->getDirectoryPermission(),\n        error);\n    if (ret == false) {\n        return false;\n    }\n    ret = utils::createDir((logPath +\n        logFilePath(&transaction->m_timeStamp, YearMonthDayDirectory\n            | YearMonthDayAndTimeDirectory)).c_str(),\n        m_audit->getDirectoryPermission(),\n        error);\n    if (ret == false) {\n        return false;\n    }\n\n    fd = open(fileName.c_str(), O_CREAT | O_WRONLY | O_APPEND,\n        m_audit->getFilePermission());\n    if (fd < 0) {\n        error->assign(\"Not able to open: \" + fileName + \". \" \\\n            + strerror(errno));\n        return false;\n    }\n    close(fd);\n\n    std::ofstream myfile;\n    std::string a(fileName.c_str());\n    myfile.open(a, std::ofstream::out | std::ofstream::app);\n    myfile << log;\n    myfile.close();\n\n    if (m_audit->m_path1.empty() == false\n        && m_audit->m_path2.empty() == false) {\n        std::string msg = transaction->toOldAuditLogFormatIndex(fileName,\n            log.length(), Utils::Md5::hexdigest(log));\n        ret = utils::SharedFiles::getInstance().write(m_audit->m_path2, msg,\n            error);\n        if (ret == false) {\n            return false;\n        }\n    }\n    if (m_audit->m_path1.empty() == false\n        && m_audit->m_path2.empty() == true) {\n        std::string msg = transaction->toOldAuditLogFormatIndex(fileName,\n            log.length(), Utils::Md5::hexdigest(log));\n        ret = utils::SharedFiles::getInstance().write(m_audit->m_path1, msg,\n            error);\n        if (ret == false) {\n            return false;\n        }\n    }\n    if (m_audit->m_path1.empty() == true\n        && m_audit->m_path2.empty() == false) {\n        std::string msg = transaction->toOldAuditLogFormatIndex(fileName,\n            log.length(), Utils::Md5::hexdigest(log));\n        ret = utils::SharedFiles::getInstance().write(m_audit->m_path2, msg,\n            error);\n        if (ret == false) {\n            return false;\n        }\n    }\n\n    return true;\n}\n\n}  // namespace writer\n}  // namespace audit_log\n}  // namespace modsecurity\n"
  },
  {
    "path": "src/audit_log/writer/parallel.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <string>\n\n#ifndef SRC_AUDIT_LOG_WRITER_PARALLEL_H_\n#define SRC_AUDIT_LOG_WRITER_PARALLEL_H_\n\n#include \"src/audit_log/writer/writer.h\"\n#include \"modsecurity/transaction.h\"\n#include \"modsecurity/audit_log.h\"\n#include \"src/utils/shared_files.h\"\n#include \"modsecurity/rules_set.h\"\n\n#ifdef __cplusplus\n\nnamespace modsecurity {\nnamespace audit_log {\nnamespace writer {\n\n/** @ingroup ModSecurity_CPP_API */\nclass Parallel : public Writer {\n public:\n    explicit Parallel(AuditLog *audit)\n        : audit_log::writer::Writer(audit) { }\n\n    ~Parallel() override;\n    bool init(std::string *error) override;\n    bool write(Transaction *transaction, int parts,\n        std::string *error) override;\n\n\n    /**\n     *\n     * Audit log file is saved into a directory structure. This directory\n     * structure is based on the timestamp of the transaction creation, at\n     * the exact moment that ModSecurity be aware of a particular\n     * request/transaction.\n     * The expect fromat is:\n     *\n     * [...]/YearMonthDay/YearMonthDayAndTime/YearMonthDayAndTime-RequestId\n     *\n     * Example:\n     *\n     * /20150710/20150710-1353/20150710-135353-143654723362.584244\n     *\n     * This enumeration describes the subpaths of this structure.\n     *\n     */\n    enum AuditLogFilePath {\n     YearMonthDayDirectory = 2,\n     YearMonthDayAndTimeDirectory = 4,\n     YearMonthDayAndTimeFileName = 8,\n    };\n\n    static inline std::string logFilePath(const time_t *t, int part);\n};\n\n}  // namespace writer\n}  // namespace audit_log\n}  // namespace modsecurity\n#endif\n\n#endif  // SRC_AUDIT_LOG_WRITER_PARALLEL_H_\n"
  },
  {
    "path": "src/audit_log/writer/serial.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"src/audit_log/writer/serial.h\"\n\n#include \"modsecurity/audit_log.h\"\n\nnamespace modsecurity {\nnamespace audit_log {\nnamespace writer {\n// static std::mutex serialLoggingMutex;\n\n\nSerial::~Serial() {\n    utils::SharedFiles::getInstance().close(m_audit->m_path1);\n}\n\n\nbool Serial::init(std::string *error) {\n    return utils::SharedFiles::getInstance().open(m_audit->m_path1, error);\n}\n\n\nbool Serial::write(Transaction *transaction, int parts, std::string *error) {\n    std::string msg;\n\n    if (transaction->m_rules->m_auditLog->m_format ==\n            audit_log::AuditLog::JSONAuditLogFormat) {\n        msg = transaction->toJSON(parts);\n    } else {\n        std::string boundary;\n        generateBoundary(&boundary);\n        msg = transaction->toOldAuditLogFormat(parts, \"-\" + boundary + \"--\", m_audit->m_prefix);\n    }\n\n    return utils::SharedFiles::getInstance().write(m_audit->m_path1, msg,\n        error);\n}\n\n}  // namespace writer\n}  // namespace audit_log\n}  // namespace modsecurity\n"
  },
  {
    "path": "src/audit_log/writer/serial.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#ifdef __cplusplus\n#include <iostream>\n#include <fstream>\n#include <string>\n#endif\n\n#ifndef SRC_AUDIT_LOG_WRITER_SERIAL_H_\n#define SRC_AUDIT_LOG_WRITER_SERIAL_H_\n\n#include \"src/audit_log/writer/writer.h\"\n#include \"src/utils/shared_files.h\"\n#include \"modsecurity/transaction.h\"\n#include \"modsecurity/audit_log.h\"\n#include \"modsecurity/rules_set.h\"\n\n#ifdef __cplusplus\n\nnamespace modsecurity {\nnamespace audit_log {\nnamespace writer {\n\n\n/** @ingroup ModSecurity_CPP_API */\nclass Serial : public Writer {\n public:\n    explicit Serial(audit_log::AuditLog *audit)\n        : audit_log::writer::Writer(audit) { }\n\n    ~Serial() override;\n\n\n    bool init(std::string *error) override;\n    bool write(Transaction *transaction, int parts,\n        std::string *error) override;\n};\n\n}  // namespace writer\n}  // namespace audit_log\n}  // namespace modsecurity\n#endif\n\n#endif  // SRC_AUDIT_LOG_WRITER_SERIAL_H_\n"
  },
  {
    "path": "src/audit_log/writer/writer.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"src/audit_log/writer/writer.h\"\n\n#include <string>\n\n#include \"modsecurity/audit_log.h\"\n\nnamespace modsecurity {\nnamespace audit_log {\nnamespace writer {\n\nvoid Writer::generateBoundary(std::string *boundary) {\n    static const char alphanum[] =\n        \"0123456789\"\n        \"ABCDEFGHIJKLMNOPQRSTUVWXYZ\"\n        \"abcdefghijklmnopqrstuvwxyz\";\n\n    for (int i = 0; i < SERIAL_AUDIT_LOG_BOUNDARY_LENGTH; ++i) {\n        boundary->append(1, alphanum[rand() % (sizeof(alphanum) - 1)]);\n    }\n}\n\n}  // namespace writer\n}  // namespace audit_log\n}  // namespace modsecurity\n"
  },
  {
    "path": "src/audit_log/writer/writer.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#ifndef SRC_AUDIT_LOG_WRITER_WRITER_H_\n#define SRC_AUDIT_LOG_WRITER_WRITER_H_\n\n\n#include <stdio.h>\n#ifndef WIN32\n#include <sys/ipc.h>\n#include <sys/shm.h>\n#endif\n#include <sys/types.h>\n\n#include <iostream>\n#include <string>\n#include <map>\n#include <cstring>\n\n\n#include \"modsecurity/transaction.h\"\n#include \"modsecurity/audit_log.h\"\n\n#define SERIAL_AUDIT_LOG_BOUNDARY_LENGTH 8\n\nnamespace modsecurity {\nnamespace audit_log {\nnamespace writer {\n\n\n/** @ingroup ModSecurity_CPP_API */\nclass Writer {\n public:\n    explicit Writer(AuditLog *audit)\n        : m_audit(audit) { }\n\n    virtual ~Writer() { }\n\n    virtual bool init(std::string *error) = 0;\n    virtual bool write(Transaction *transaction, int parts,\n        std::string *error) = 0;\n\n    static void generateBoundary(std::string *boundary);\n\n protected:\n    AuditLog *m_audit;\n};\n\n\n}  // namespace writer\n}  // namespace audit_log\n}  // namespace modsecurity\n\n#endif  // SRC_AUDIT_LOG_WRITER_WRITER_H_\n"
  },
  {
    "path": "src/collection/backend/collection_data.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2023 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"src/collection/backend/collection_data.h\"\n\n\nnamespace modsecurity {\nnamespace collection {\nnamespace backend {\n\n\nbool CollectionData::isExpired() const {\n    if (m_hasExpiryTime == false) {\n        return false;\n    }\n    auto now = std::chrono::system_clock::now();\n    return (now >= m_expiryTime);\n}\n\n\nvoid CollectionData::setExpiry(int32_t seconds_until_expiry) {\n    m_expiryTime = std::chrono::system_clock::now() + std::chrono::seconds(seconds_until_expiry);\n    m_hasExpiryTime = true;\n}\n\nstd::string CollectionData::getSerialized() const {\n    std::string serialized;\n    if (hasValue()) {\n        serialized.reserve(30 + 10 + getValue().size());\n    } else {\n        serialized.reserve(16+10);\n    }\n\n    serialized.assign(\"{\");\n\n    if (hasExpiry()) {\n        serialized.append(\"\\\"__expire_\\\":\");\n        uint64_t expiryEpochSeconds = std::chrono::duration_cast<std::chrono::seconds>(m_expiryTime.time_since_epoch()).count();\n        serialized.append(std::to_string(expiryEpochSeconds));\n\tif (hasValue()) {\n            serialized.append(\",\");\n\t}\n    }\n    if (hasValue()) {\n        serialized.append(\"\\\"__value_\\\":\\\"\");\n        serialized.append(getValue());\n        serialized.append(\"\\\"\");\n    }\n\n    serialized.append(\"}\");\n\n    return serialized;\n}\n\nvoid CollectionData::setFromSerialized(const char* serializedData, size_t length) {\n    const static std::string expiryPrefix(\"\\\"__expire_\\\":\");\n    const static std::string valuePrefix(\"\\\"__value_\\\":\\\"\");\n    m_hasValue = false;\n    m_hasExpiryTime = false;\n\n    std::string serializedString(serializedData, length);\n    if ((serializedString.find(\"{\") == 0) && (serializedString.substr(serializedString.length()-1) == \"}\")) {\n        size_t currentPos = 1;\n        uint64_t expiryEpochSeconds = 0;\n        bool invalidSerializedFormat = false;\n        bool doneParsing = false;\n\n        // Extract the expiry time, if it exists\n        if (serializedString.find(expiryPrefix, currentPos) == currentPos) {\n            currentPos += expiryPrefix.length();\n            std::string expiryDigits = serializedString.substr(currentPos, 10);\n            if (expiryDigits.find_first_not_of(\"0123456789\") == std::string::npos) {\n                expiryEpochSeconds = strtoll(expiryDigits.c_str(), NULL, 10);\n            } else {\n                invalidSerializedFormat = true;\n\t    }\n            currentPos += 10;\n        }\n\n        if ((!invalidSerializedFormat) && (expiryEpochSeconds > 0)) {\n            if (serializedString.find(\",\", currentPos) == currentPos) {\n                currentPos++;\n            } else if (currentPos == serializedString.length()-1) {\n\t        doneParsing = true;\n\t    } else {\n                invalidSerializedFormat = true;\n\t    }\n\t}\n\n        if ((!invalidSerializedFormat) && (!doneParsing)) {\n            // Extract the value\n            if ((serializedString.find(valuePrefix, currentPos) == currentPos)) {\n                currentPos += valuePrefix.length();\n                size_t expectedCloseQuotePos = serializedString.length() - 2;\n                if ((serializedString.substr(expectedCloseQuotePos, 1) == \"\\\"\") && (expectedCloseQuotePos >= currentPos)) {\n                    m_value = serializedString.substr(currentPos);\n                    m_value.resize(m_value.length()-2);\n                    m_hasValue = true;\n                } else {\n                    invalidSerializedFormat = true;\n                }\n            } else {\n                invalidSerializedFormat = true;\n            }\n        }\n\n        // Set the object's expiry time, if we found one\n        if ((!invalidSerializedFormat) && (expiryEpochSeconds > 0)) {\n            std::chrono::seconds expiryDuration(expiryEpochSeconds);\n            std::chrono::system_clock::time_point expiryTimePoint(expiryDuration);\n            m_expiryTime = expiryTimePoint;\n            m_hasExpiryTime = true;\n\t}\n        if (!invalidSerializedFormat) {\n            return;\n\t}\n    }\n\n    // this is the residual case; the entire string is a simple value (not JSON-ish encoded)\n    // the foreseen case here is lmdb content from prior to the serialization support\n    m_value.assign(serializedData, length);\n    m_hasValue = true;\n    return;\n}\n\n}  // namespace backend\n}  // namespace collection\n}  // namespace modsecurity\n"
  },
  {
    "path": "src/collection/backend/collection_data.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2023 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n\n#ifdef __cplusplus\n#include <string>\n#include <chrono>\n#endif\n\n\n#ifndef SRC_COLLECTION_DATA_H_\n#define SRC_COLLECTION_DATA_H_\n\n#ifdef __cplusplus\nnamespace modsecurity {\nnamespace collection {\nnamespace backend {\n\nclass CollectionData {\npublic:\n    CollectionData() :\n        m_hasValue(false),\n\tm_hasExpiryTime(false) { }\n\n    CollectionData(const std::string &value) :\n        m_hasValue(true),\n\tm_hasExpiryTime(false),\n\tm_value(value) { }\n\n    void setValue(const std::string &value) {\n        m_value = value;\n        m_hasValue = true;\n    }\n    bool hasValue() const { return m_hasValue;}\n    const std::string& getValue() const { return m_value;}\n\n    void setExpiry(int32_t seconds_until_expiry);\n    bool hasExpiry() const { return m_hasExpiryTime;}\n    bool isExpired() const;\n\n    std::string getSerialized() const;\n    void setFromSerialized(const char* serializedData, size_t length);\n\nprivate:\n    bool m_hasValue;\n    bool m_hasExpiryTime;\n    std::string m_value;\n    std::chrono::system_clock::time_point m_expiryTime;\n};\n\n}  // namespace backend\n}  // namespace collection\n}  // namespace modsecurity\n#endif\n\n#endif  // SRC_COLLECTION_DATA_H_\n"
  },
  {
    "path": "src/collection/backend/in_memory-per_process.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2023 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n\n#include \"src/collection/backend/in_memory-per_process.h\"\n#include \"src/collection/backend/collection_data.h\"\n\n#ifdef __cplusplus\n#include <string>\n#include <iostream>\n#include <unordered_map>\n#include <list>\n#include <memory>\n#endif\n\n#include \"modsecurity/variable_value.h\"\n#include \"src/utils/regex.h\"\n#include \"src/utils/string.h\"\n\n\nnamespace modsecurity {\nnamespace collection {\nnamespace backend {\n\n\nInMemoryPerProcess::InMemoryPerProcess(const std::string &name) :\n    Collection(name) {\n    m_map.reserve(1000);\n}\n\nInMemoryPerProcess::~InMemoryPerProcess() {\n    m_map.clear();\n}\n\n\ntemplate<typename Map>\ninline void __store(Map &map, std::string key, std::string value) {\n    // NOTE: should be called with write-lock previously acquired\n\n    map.emplace(key, value);\n}\n\n\ntemplate<typename Map>\ninline bool __updateFirst(Map &map,\n    const std::string &key,\n    const std::string &value) {\n    // NOTE: should be called with write-lock previously acquired\n\n    if (auto search = map.find(key); search != map.end()) {\n        search->second.setValue(value);\n        return true;\n    }\n\n    return false;\n}\n\n\nvoid InMemoryPerProcess::store(const std::string &key, const std::string &value) {\n    const std::lock_guard lock(m_mutex); // write lock (exclusive access)\n    __store(m_map, key, value);\n}\n\n\nbool InMemoryPerProcess::storeOrUpdateFirst(const std::string &key,\n    const std::string &value) {\n    const std::lock_guard lock(m_mutex); // write lock (exclusive access)\n    if (__updateFirst(m_map, key, value) == false) {\n        __store(m_map, key, value);\n    }\n    return true;\n}\n\n\nbool InMemoryPerProcess::updateFirst(const std::string &key,\n    const std::string &value) {\n    const std::lock_guard lock(m_mutex); // write lock (exclusive access)\n    return __updateFirst(m_map, key, value);\n}\n\n\nvoid InMemoryPerProcess::del(const std::string& key) {\n    const std::lock_guard lock(m_mutex); // write lock (exclusive access)\n    m_map.erase(key);\n}\n\nvoid InMemoryPerProcess::delIfExpired(const std::string& key) {\n    const std::lock_guard lock(m_mutex); // write lock (exclusive access)\n    // Double check the status while within the mutex\n    const auto iter = std::find_if(m_map.begin(), m_map.end(),\n        [&key](const auto &x) { return x.first == key && x.second.isExpired(); });\n    if (iter != m_map.end()) {\n        m_map.erase(key);\n    }\n}\n\nvoid InMemoryPerProcess::setExpiry(const std::string& key, int32_t expiry_seconds) {\n    const std::lock_guard lock(m_mutex); // write lock (exclusive access)\n\n    if (const auto search = m_map.find(key); search != m_map.end()) {\n        search->second.setExpiry(expiry_seconds);\n        return;\n    }\n\n    // We allow an expiry value to be set for a key that has not (yet) had a value set.\n    const auto iter = m_map.emplace(key, CollectionData());\n    iter->second.setExpiry(expiry_seconds);\n}\n\n\nvoid InMemoryPerProcess::resolveSingleMatch(const std::string& var,\n    std::vector<const VariableValue *> *l) {\n    std::list<std::string> expiredVars;\n\n    {\n        const std::shared_lock lock(m_mutex); // read lock (shared access)\n\n        const auto range = m_map.equal_range(var);\n        for (auto it = range.first; it != range.second; ++it) {\n            if (it->second.isExpired()) {\n                expiredVars.push_back(it->first);\n            } else if (it->second.hasValue() == false) {\n                // No-op. A non-expired expiry exists for the key but there is no actual value\n            } else {\n                l->push_back(new VariableValue(&m_name, &it->first, &it->second.getValue()));\n            }\n        }\n    }\n\n    for (const auto& expiredVar : expiredVars) {\n        delIfExpired(expiredVar);\n    }\n}\n\n\nvoid InMemoryPerProcess::resolveMultiMatches(const std::string& var,\n    std::vector<const VariableValue *> *l, variables::KeyExclusions &ke) {\n    const auto keySize = var.size();\n    l->reserve(15);\n    std::list<std::string> expiredVars;\n\n    {\n        const std::shared_lock lock(m_mutex); // read lock (shared access)\n\n        if (keySize == 0) {\n            for (auto &i : m_map) {\n                if (ke.toOmit(i.first)) {\n                    continue;\n                }\n                if (i.second.isExpired()) {\n                    expiredVars.push_back(i.first);\n                } else if (i.second.hasValue() == false) {\n                    // No-op. A non-expired expiry exists for the key but there is no actual value\n                } else {\n                    l->insert(l->begin(), new VariableValue(&m_name, &i.first,\n                        &i.second.getValue()));\n                }\n            }\n        } else {\n            const auto range = m_map.equal_range(var);\n            for (auto it = range.first; it != range.second; ++it) {\n                if (ke.toOmit(var)) {\n                    continue;\n                }\n                if (it->second.isExpired()) {\n                    expiredVars.push_back(it->first);\n                } else if (it->second.hasValue() == false) {\n                    // No-op. A non-expired expiry exists for the key but there is no actual value\n                } else {\n                    l->insert(l->begin(), new VariableValue(&m_name, &var,\n                        &it->second.getValue()));\n                }\n            }\n        }\n    }\n\n    for (const auto& expiredVar : expiredVars) {\n        delIfExpired(expiredVar);\n    }\n}\n\n\nvoid InMemoryPerProcess::resolveRegularExpression(const std::string& var,\n    std::vector<const VariableValue *> *l, variables::KeyExclusions &ke) {\n    Utils::Regex r(var, true);\n    std::list<std::string> expiredVars;\n\n    {\n        const std::shared_lock lock(m_mutex); // read lock (shared access)\n\n        for (const auto& x : m_map) {\n            const auto ret = Utils::regex_search(x.first, r);\n            if (ret <= 0) {\n                continue;\n            }\n            if (ke.toOmit(x.first)) {\n                continue;\n            }\n            if (x.second.isExpired()) {\n                expiredVars.push_back(x.first);\n            } else if (x.second.hasValue() == false) {\n                // No-op. A non-expired expiry exists for the key but there is no actual value\n            } else {\n                l->insert(l->begin(), new VariableValue(&m_name, &x.first, &x.second.getValue()));\n            }\n        }\n    }\n\n    for (const auto& expiredVar : expiredVars) {\n        delIfExpired(expiredVar);\n    }\n}\n\n\nstd::unique_ptr<std::string> InMemoryPerProcess::resolveFirst(\n    const std::string& var) {\n    std::unique_ptr<std::string> ret;\n    std::list<std::string> expiredVars;\n\n    {\n        const std::shared_lock lock(m_mutex); // read lock (shared access)\n\n        const auto range = m_map.equal_range(var);\n        for (auto it = range.first; it != range.second; ++it) {\n            if (it->second.isExpired()) {\n                expiredVars.push_back(it->first);\n            } else if (it->second.hasValue() == false) {\n                // No-op. A non-expired expiry exists for the key but there is no actual value\n            } else {\n                ret = std::make_unique<std::string>(it->second.getValue());\n            }\n        }\n    }\n\n    for (const auto& expiredVar : expiredVars) {\n        delIfExpired(expiredVar);\n    }\n\n    return ret;\n}\n\n\n}  // namespace backend\n}  // namespace collection\n}  // namespace modsecurity\n"
  },
  {
    "path": "src/collection/backend/in_memory-per_process.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2023 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n\n#ifdef __cplusplus\n#include <string>\n#include <iostream>\n#include <unordered_map>\n#include <chrono>\n#include <list>\n#include <vector>\n#include <algorithm>\n#include <memory>\n#include <shared_mutex>\n#endif\n\n\n#include \"modsecurity/variable_value.h\"\n#include \"modsecurity/collection/collection.h\"\n#include \"src/collection/backend/collection_data.h\"\n#include \"src/variables/variable.h\"\n\n#ifndef SRC_COLLECTION_BACKEND_IN_MEMORY_PER_PROCESS_H_\n#define SRC_COLLECTION_BACKEND_IN_MEMORY_PER_PROCESS_H_\n\n#ifdef __cplusplus\nnamespace modsecurity {\nnamespace collection {\nnamespace backend {\n\n/*\n * FIXME:\n *\n * This was an example grabbed from:\n * http://stackoverflow.com/questions/8627698/case-insensitive-stl-containers-e-g-stdunordered-set\n *\n * We have to have a better hash function, maybe based on the std::hash.\n *\n */\nstruct MyEqual {\n    bool operator()(const std::string& Left, const std::string& Right) const {\n        return Left.size() == Right.size()\n             && std::equal(Left.begin(), Left.end(), Right.begin(),\n            [](char a, char b) {\n            return tolower(a) == tolower(b);\n        });\n    }\n};\n\nstruct MyHash{\n    size_t operator()(const std::string& Keyval) const {\n        // You might need a better hash function than this\n        size_t h = 0;\n        std::for_each(Keyval.begin(), Keyval.end(), [&](char c) {\n            h += tolower(c);\n        });\n        return h;\n    }\n};\n\nclass InMemoryPerProcess :\n    public Collection {\n public:\n    explicit InMemoryPerProcess(const std::string &name);\n    ~InMemoryPerProcess() override;\n    void store(const std::string &key, const std::string &value);\n\n    bool storeOrUpdateFirst(const std::string &key,\n        const std::string &value) override;\n\n    bool updateFirst(const std::string &key,\n        const std::string &value) override;\n\n    void del(const std::string& key) override;\n\n    void delIfExpired(const std::string& key);\n\n    void setExpiry(const std::string& key, int32_t expiry_seconds) override;\n\n    std::unique_ptr<std::string> resolveFirst(const std::string& var) override;\n\n    void resolveSingleMatch(const std::string& var,\n        std::vector<const VariableValue *> *l) override;\n    void resolveMultiMatches(const std::string& var,\n        std::vector<const VariableValue *> *l,\n        variables::KeyExclusions &ke) override;\n    void resolveRegularExpression(const std::string& var,\n        std::vector<const VariableValue *> *l,\n        variables::KeyExclusions &ke) override;\n\n    /* store */\n    virtual void store(const std::string &key, std::string &compartment,\n        std::string value) {\n        const auto nkey = compartment + \"::\" + key;\n        store(nkey, value);\n    }\n\n\n    virtual void store(const std::string &key, const std::string &compartment,\n        std::string compartment2, std::string value) {\n        const auto nkey = compartment + \"::\" + compartment2 + \"::\" + key;\n        store(nkey, value);\n    }\n\n private:\n    std::unordered_multimap<std::string, CollectionData,\n        /*std::hash<std::string>*/MyHash, MyEqual> m_map;\n    std::shared_mutex m_mutex;\n};\n\n}  // namespace backend\n}  // namespace collection\n}  // namespace modsecurity\n#endif\n\n\n#endif  // SRC_COLLECTION_BACKEND_IN_MEMORY_PER_PROCESS_H_\n"
  },
  {
    "path": "src/collection/backend/lmdb.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2023 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n\n#include \"src/collection/backend/lmdb.h\"\n#include \"src/collection/backend/collection_data.h\"\n\n#include <sys/types.h>\n#ifndef WIN32\n#include <unistd.h>\n#else\n#include <io.h>\n#endif\n\n#include <string>\n#include <memory>\n\n#include \"modsecurity/variable_value.h\"\n#include \"src/utils/regex.h\"\n#include \"src/variables/variable.h\"\n\n#undef LMDB_STDOUT_COUT\n\nnamespace modsecurity {\nnamespace collection {\nnamespace backend {\n\n\n#ifdef WITH_LMDB\n\nLMDB::LMDB(const std::string &name) :\n    Collection(name), m_env(NULL), isOpen(false) {}\n\nint LMDB::txn_begin(unsigned int flags, MDB_txn **ret) {\n    if (!isOpen) {\n        m_env = MDBEnvProvider::GetInstance().GetEnv();\n        m_dbi = *(MDBEnvProvider::GetInstance().GetDBI());\n        isOpen = true;\n    }\n\n    if (MDBEnvProvider::GetInstance().isValid()) {\n        return mdb_txn_begin(m_env, NULL, flags, ret);\n    } else {\n        return -1;\n    }\n}\n\nvoid LMDB::string2val(const std::string& str, MDB_val *val) {\n    val->mv_size = sizeof(char)*(str.size());\n    val->mv_data = const_cast<char *>(str.c_str());\n}\n\n\nvoid LMDB::lmdb_debug(int rc, const std::string &op, const std::string &scope) {\n#ifndef LMDB_STDOUT_COUT\n    return;\n#else\n    if (rc == 0) {\n        return;\n    }\n\n    if (op == \"txn\") {\n        std::cout << scope << \", LMDB failure while starting txn: \";\n        switch (rc) {\n            case MDB_PANIC:\n                std::cout << \"panic: a fatal error occurred earlier \";\n                std::cout << \"and the environment must be shut down.\";\n                break;\n            case MDB_MAP_RESIZED:\n                std::cout << \"map resized: another process wrote data \";\n                std::cout << \"beyond this MDB_env's mapsize and this \";\n                std::cout << \"environment's map must be resized as well. \";\n                std::cout << \"See mdb_env_set_mapsize().\";\n                break;\n            case MDB_READERS_FULL:\n                std::cout << \"max readers: a read-only transaction was \";\n                std::cout << \"requested and the reader lock table is full. \";\n                std::cout << \"See mdb_env_set_maxreaders().\";\n                break;\n            case ENOMEM:\n                std::cout << \"out of memory.\";\n                break;\n            default:\n                std::cout << \"not sure what is wrong, code: \" +\n                    std::to_string(rc);\n                break;\n        }\n        std::cout << std::endl;\n    } else if (op == \"get\") {\n        std::cout << scope << \", LMDB failure while getting the key: \";\n        switch (rc) {\n            case MDB_NOTFOUND:\n                std::cout << \"not found: the key was not in the database.\";\n                break;\n            case EINVAL:\n                std::cout << \"an invalid parameter was specified.\";\n                break;\n            default:\n                std::cout << \"not sure what is wrong.\";\n                break;\n        }\n        std::cout << std::endl;\n    } else if (op == \"del\") {\n        std::cout << scope << \", delete procedure failed: \";\n        switch (rc) {\n            case EACCES:\n                std::cout << \"an attempt was made to write in a \";\n                std::cout << \"read-only transaction.\";\n                break;\n            case EINVAL:\n                std::cout << \"an invalid parameter was specified.\";\n                break;\n            default:\n                std::cout << \"not sure what is wrong. Code: \" +\n                std::to_string(rc);\n                break;\n        }\n        std::cout << std::endl;\n    } else if (op == \"commit\") {\n        std::cout << scope << \", commit procedure failed: \";\n        switch (rc) {\n            case EINVAL:\n                std::cout << \"an invalid parameter was specified.\";\n                break;\n            case ENOSPC:\n                std::cout << \"no more disk space.\";\n                break;\n            case EIO:\n                std::cout << \"a low-level I/O error occurred while writing.\";\n                break;\n            case ENOMEM:\n                std::cout << \"out of memory.\";\n                break;\n            default:\n                std::cout << \"not sure what is wrong. Code: \" +\n                    std::to_string(rc);\n                break;\n        }\n        std::cout << std::endl;\n    }\n#endif\n}\n\n\nstd::unique_ptr<std::string> LMDB::resolveFirst(const std::string& var) {\n    int rc;\n    MDB_val mdb_key;\n    MDB_val mdb_value;\n    MDB_val mdb_value_ret;\n    std::unique_ptr<std::string> ret = NULL;\n    MDB_txn *txn = NULL;\n    CollectionData collectionData;\n\n    string2val(var, &mdb_key);\n\n    rc = txn_begin(MDB_RDONLY, &txn);\n    lmdb_debug(rc, \"txn\", \"resolveFirst\");\n    if (rc != 0) {\n        goto end_txn;\n    }\n    rc = mdb_get(txn, m_dbi, &mdb_key, &mdb_value_ret);\n    lmdb_debug(rc, \"get\", \"resolveFirst\");\n    if (rc != 0) {\n        goto end_get;\n    }\n\n    collectionData.setFromSerialized(reinterpret_cast<char *>(mdb_value_ret.mv_data), mdb_value_ret.mv_size);\n    if ((!collectionData.isExpired()) && (collectionData.hasValue())) {\n        ret = std::make_unique<std::string>(collectionData.getValue());\n    }\n\nend_get:\n    mdb_txn_abort(txn);\nend_txn:\n    // The read-only transaction is complete. Now we can do a delete if the item was expired.\n    if (collectionData.isExpired()) {\n        delIfExpired(var);\n    }\n    return ret;\n}\n\n\nvoid LMDB::setExpiry(const std::string &key, int32_t expiry_seconds) {\n    int rc;\n    MDB_txn *txn;\n    MDB_val mdb_key;\n    MDB_val mdb_value;\n    MDB_val mdb_value_ret;\n    CollectionData previous_data;\n    CollectionData new_data;\n    std::string serializedData;\n\n    string2val(key, &mdb_key);\n\n    rc = txn_begin(0, &txn);\n    lmdb_debug(rc, \"txn\", \"setExpiry\");\n    if (rc != 0) {\n        goto end_txn;\n    }\n\n    rc = mdb_get(txn, m_dbi, &mdb_key, &mdb_value_ret);\n    lmdb_debug(rc, \"get\", \"setExpiry\");\n    if (rc == 0) {\n        previous_data.setFromSerialized(reinterpret_cast<char *>(mdb_value_ret.mv_data), mdb_value_ret.mv_size);\n        rc = mdb_del(txn, m_dbi, &mdb_key, &mdb_value_ret);\n        lmdb_debug(rc, \"del\", \"setExpiry\");\n        if (rc != 0) {\n            goto end_del;\n        }\n    }\n\n    if (previous_data.hasValue()) {\n        new_data = previous_data;\n    };\n    new_data.setExpiry(expiry_seconds);\n    serializedData = new_data.getSerialized();\n    string2val(serializedData, &mdb_value);\n\n    rc = mdb_put(txn, m_dbi, &mdb_key, &mdb_value, 0);\n    lmdb_debug(rc, \"put\", \"setExpiry\");\n    if (rc != 0) {\n        goto end_put;\n    }\n\n    rc = mdb_txn_commit(txn);\n    lmdb_debug(rc, \"commit\", \"setExpiry\");\n    if (rc != 0) {\n        goto end_commit;\n    }\n\nend_put:\nend_del:\n    if (rc != 0) {\n        mdb_txn_abort(txn);\n    }\nend_commit:\nend_txn:\n    return;\n}\n\nvoid LMDB::delIfExpired(const std::string& key) {\n    MDB_txn *txn;\n    MDB_val mdb_key;\n    MDB_val mdb_value_ret;\n    CollectionData collectionData;\n\n    int rc = txn_begin(0, &txn);\n    lmdb_debug(rc, \"txn\", \"del\");\n    if (rc != 0) {\n        goto end_txn;\n    }\n\n    string2val(key, &mdb_key);\n\n    rc = mdb_get(txn, m_dbi, &mdb_key, &mdb_value_ret);\n    lmdb_debug(rc, \"get\", \"del\");\n    if (rc != 0) {\n        goto end_get;\n    }\n\n    collectionData.setFromSerialized(reinterpret_cast<char *>(mdb_value_ret.mv_data), mdb_value_ret.mv_size);\n    if (collectionData.isExpired()) {\n        rc = mdb_del(txn, m_dbi, &mdb_key, &mdb_value_ret);\n        lmdb_debug(rc, \"del\", \"del\");\n        if (rc != 0) {\n            goto end_del;\n        }\n    }\n\n    rc = mdb_txn_commit(txn);\n    lmdb_debug(rc, \"commit\", \"del\");\n    if (rc != 0) {\n        goto end_commit;\n    }\n\nend_del:\nend_get:\n    if (rc != 0) {\n        mdb_txn_abort(txn);\n    }\nend_commit:\nend_txn:\n    return;\n}\n\nbool LMDB::storeOrUpdateFirst(const std::string &key,\n    const std::string &value) {\n    int rc;\n    MDB_txn *txn;\n    MDB_val mdb_key;\n    MDB_val mdb_value;\n    MDB_val mdb_value_ret;\n    CollectionData previous_data;\n    CollectionData new_data;\n    std::string serializedData;\n\n    string2val(key, &mdb_key);\n\n    rc = txn_begin(0, &txn);\n    lmdb_debug(rc, \"txn\", \"storeOrUpdateFirst\");\n    if (rc != 0) {\n        goto end_txn;\n    }\n\n    rc = mdb_get(txn, m_dbi, &mdb_key, &mdb_value_ret);\n    lmdb_debug(rc, \"get\", \"storeOrUpdateFirst\");\n    if (rc == 0) {\n        previous_data.setFromSerialized(reinterpret_cast<char *>(mdb_value_ret.mv_data), mdb_value_ret.mv_size);\n        rc = mdb_del(txn, m_dbi, &mdb_key, &mdb_value_ret);\n        lmdb_debug(rc, \"del\", \"storeOrUpdateFirst\");\n        if (rc != 0) {\n            goto end_del;\n        }\n    }\n\n    if (previous_data.hasExpiry()) {\n        new_data = previous_data;\n    };\n    new_data.setValue(value);\n    serializedData = new_data.getSerialized();\n    string2val(serializedData, &mdb_value);\n\n    rc = mdb_put(txn, m_dbi, &mdb_key, &mdb_value, 0);\n    lmdb_debug(rc, \"put\", \"storeOrUpdateFirst\");\n    if (rc != 0) {\n        goto end_put;\n    }\n\n    rc = mdb_txn_commit(txn);\n    lmdb_debug(rc, \"commit\", \"storeOrUpdateFirst\");\n    if (rc != 0) {\n        goto end_commit;\n    }\n\nend_put:\nend_del:\n    if (rc != 0) {\n        mdb_txn_abort(txn);\n    }\nend_commit:\nend_txn:\n    return true;\n}\n\n\nvoid LMDB::resolveSingleMatch(const std::string& var,\n    std::vector<const VariableValue *> *l) {\n    int rc;\n    MDB_txn *txn;\n    MDB_val mdb_key;\n    MDB_val mdb_value;\n    MDB_val mdb_value_ret;\n    MDB_cursor *cursor;\n    CollectionData collectionData;\n    std::list<std::string> expiredVars;\n\n    rc = txn_begin(MDB_RDONLY, &txn);\n    lmdb_debug(rc, \"txn\", \"resolveSingleMatch\");\n    if (rc != 0) {\n        goto end_txn;\n    }\n\n    string2val(var, &mdb_key);\n\n    mdb_cursor_open(txn, m_dbi, &cursor);\n    while ((rc = mdb_cursor_get(cursor, &mdb_key,\n            &mdb_value_ret, MDB_NEXT_DUP)) == 0) {\n        collectionData.setFromSerialized(reinterpret_cast<char *>(mdb_value_ret.mv_data), mdb_value_ret.mv_size);\n        if (collectionData.isExpired()) {\n            expiredVars.push_back(std::string(reinterpret_cast<char *>(mdb_key.mv_data), mdb_key.mv_size));\n            continue;\n        }\n        if (!collectionData.hasValue()) {\n            continue;\n        }\n        VariableValue *v = new VariableValue(&var, &collectionData.getValue());\n        l->push_back(v);\n    }\n\n    mdb_cursor_close(cursor);\n    mdb_txn_abort(txn);\nend_txn:\n    for (const auto& expiredVar : expiredVars) {\n        delIfExpired(expiredVar);\n    }\n    return;\n}\n\n\nbool LMDB::updateFirst(const std::string &key,\n    const std::string &value) {\n    int rc;\n    MDB_txn *txn;\n    MDB_val mdb_key;\n    MDB_val mdb_value;\n    MDB_val mdb_value_ret;\n    CollectionData previous_data;\n    CollectionData new_data;\n    std::string serializedData;\n\n    rc = txn_begin(0, &txn);\n    lmdb_debug(rc, \"txn\", \"updateFirst\");\n    if (rc != 0) {\n        goto end_txn;\n    }\n\n    string2val(key, &mdb_key);\n\n    rc = mdb_get(txn, m_dbi, &mdb_key, &mdb_value_ret);\n    lmdb_debug(rc, \"get\", \"updateFirst\");\n    if (rc != 0) {\n        goto end_get;\n    }\n\n    previous_data.setFromSerialized(reinterpret_cast<char *>(mdb_value_ret.mv_data), mdb_value_ret.mv_size);\n    rc = mdb_del(txn, m_dbi, &mdb_key, &mdb_value_ret);\n    lmdb_debug(rc, \"del\", \"updateFirst\");\n    if (rc != 0) {\n        goto end_del;\n    }\n\n    if (previous_data.hasExpiry()) {\n        new_data = previous_data;\n    };\n    new_data.setValue(value);\n    serializedData = new_data.getSerialized();\n    string2val(serializedData, &mdb_value);\n\n    rc = mdb_put(txn, m_dbi, &mdb_key, &mdb_value, 0);\n    lmdb_debug(rc, \"put\", \"updateFirst\");\n    if (rc != 0) {\n        goto end_put;\n    }\n\n    rc = mdb_txn_commit(txn);\n    lmdb_debug(rc, \"commit\", \"updateFirst\");\n    if (rc != 0) {\n        goto end_commit;\n    }\n\nend_put:\nend_del:\nend_get:\n    if (rc != 0) {\n        mdb_txn_abort(txn);\n    }\nend_commit:\nend_txn:\n\n    return rc == 0;\n}\n\n\nvoid LMDB::del(const std::string& key) {\n    int rc;\n    MDB_txn *txn;\n    MDB_val mdb_key;\n    MDB_val mdb_value;\n    MDB_val mdb_value_ret;\n    MDB_stat mst;\n\n    rc = txn_begin(0, &txn);\n    lmdb_debug(rc, \"txn\", \"del\");\n    if (rc != 0) {\n        goto end_txn;\n    }\n\n    string2val(key, &mdb_key);\n\n    rc = mdb_get(txn, m_dbi, &mdb_key, &mdb_value_ret);\n    lmdb_debug(rc, \"get\", \"del\");\n    if (rc != 0) {\n        goto end_get;\n    }\n\n    rc = mdb_del(txn, m_dbi, &mdb_key, &mdb_value_ret);\n    lmdb_debug(rc, \"del\", \"del\");\n    if (rc != 0) {\n        goto end_del;\n    }\n\n    rc = mdb_txn_commit(txn);\n    lmdb_debug(rc, \"commit\", \"del\");\n    if (rc != 0) {\n        goto end_commit;\n    }\n\nend_del:\nend_get:\n    if (rc != 0) {\n        mdb_txn_abort(txn);\n    }\nend_commit:\nend_txn:\n    return;\n}\n\nvoid LMDB::resolveMultiMatches(const std::string& var,\n    std::vector<const VariableValue *> *l,\n    variables::KeyExclusions &ke) {\n    MDB_val key, data;\n    MDB_txn *txn = NULL;\n    int rc;\n    MDB_stat mst;\n    size_t keySize = var.size();\n    MDB_cursor *cursor;\n    CollectionData collectionData;\n    std::list<std::string> expiredVars;\n\n    rc = txn_begin(MDB_RDONLY, &txn);\n    lmdb_debug(rc, \"txn\", \"resolveMultiMatches\");\n    if (rc != 0) {\n        goto end_txn;\n    }\n\n    rc = mdb_cursor_open(txn, m_dbi, &cursor);\n    lmdb_debug(rc, \"cursor_open\", \"resolveMultiMatches\");\n    if (rc != 0) {\n        goto end_cursor_open;\n    }\n\n    if (keySize == 0) {\n        while ((rc = mdb_cursor_get(cursor, &key, &data, MDB_NEXT)) == 0) {\n            collectionData.setFromSerialized(reinterpret_cast<char *>(data.mv_data), data.mv_size);\n\n            if (collectionData.isExpired()) {\n                expiredVars.push_back(std::string(reinterpret_cast<char *>(key.mv_data), key.mv_size));\n                continue;\n            }\n            if (!collectionData.hasValue()) {\n                continue;\n            }\n\n            std::string key_to_insert(reinterpret_cast<char *>(key.mv_data), key.mv_size);\n            l->insert(l->begin(), new VariableValue(\n                &m_name, &key_to_insert, &collectionData.getValue()));\n        }\n    } else {\n        while ((rc = mdb_cursor_get(cursor, &key, &data, MDB_NEXT)) == 0) {\n            collectionData.setFromSerialized(reinterpret_cast<char *>(data.mv_data), data.mv_size);\n\n            if (collectionData.isExpired()) {\n                expiredVars.push_back(std::string(reinterpret_cast<char *>(key.mv_data), key.mv_size));\n                continue;\n            }\n            if (!collectionData.hasValue()) {\n                continue;\n            }\n\n            const char *a = reinterpret_cast<char *>(key.mv_data);\n            if (strncmp(var.c_str(), a, keySize) == 0) {\n                std::string key_to_insert(reinterpret_cast<char *>(key.mv_data), key.mv_size);\n                l->insert(l->begin(), new VariableValue(&m_name, &key_to_insert, &collectionData.getValue()));\n            }\n        }\n    }\n\n    mdb_cursor_close(cursor);\nend_cursor_open:\n    mdb_txn_abort(txn);\nend_txn:\n    for (const auto& expiredVar : expiredVars) {\n        delIfExpired(expiredVar);\n    }\n    return;\n}\n\n\nvoid LMDB::resolveRegularExpression(const std::string& var,\n    std::vector<const VariableValue *> *l,\n    variables::KeyExclusions &ke) {\n    MDB_val key, data;\n    MDB_txn *txn = NULL;\n    int rc;\n    MDB_stat mst;\n    MDB_cursor *cursor;\n    CollectionData collectionData;\n    std::list<std::string> expiredVars;\n\n    Utils::Regex r(var, true);\n\n    rc = txn_begin(MDB_RDONLY, &txn);\n    lmdb_debug(rc, \"txn\", \"resolveRegularExpression\");\n    if (rc != 0) {\n        goto end_txn;\n    }\n\n    rc = mdb_cursor_open(txn, m_dbi, &cursor);\n    lmdb_debug(rc, \"cursor_open\", \"resolveRegularExpression\");\n    if (rc != 0) {\n        goto end_cursor_open;\n    }\n\n    while ((rc = mdb_cursor_get(cursor, &key, &data, MDB_NEXT)) == 0) {\n        collectionData.setFromSerialized(reinterpret_cast<char *>(data.mv_data), data.mv_size);\n\n\tif (collectionData.isExpired()) {\n            expiredVars.push_back(std::string(reinterpret_cast<char *>(key.mv_data), key.mv_size));\n            continue;\n        }\n        if (!collectionData.hasValue()) {\n            continue;\n        }\n\n        std::string key_to_insert(reinterpret_cast<char *>(key.mv_data), key.mv_size);\n        int ret = Utils::regex_search(key_to_insert, r);\n        if (ret <= 0) {\n            continue;\n        }\n        if (ke.toOmit(key_to_insert)) {\n            continue;\n        }\n\n        VariableValue *v = new VariableValue(&key_to_insert, &collectionData.getValue());\n        l->insert(l->begin(), v);\n    }\n\n    mdb_cursor_close(cursor);\nend_cursor_open:\n    mdb_txn_abort(txn);\nend_txn:\n    for (const auto& expiredVar : expiredVars) {\n        delIfExpired(expiredVar);\n    }\n    return;\n}\n\n\nMDBEnvProvider::MDBEnvProvider() : m_env(NULL), valid(false) {\n    int rc;\n    MDB_txn *txn;\n    mdb_env_create(&m_env);\n    rc = mdb_env_open(m_env, \"./modsec-shared-collections\",\n        MDB_WRITEMAP | MDB_NOSUBDIR, 0664);\n\n    if (rc == 0) {\n        valid = true;\n        mdb_txn_begin(m_env, NULL, 0, &txn);\n        mdb_dbi_open(txn, NULL, MDB_CREATE | MDB_DUPSORT, &m_dbi);\n        mdb_txn_commit(txn);\n    }\n}\n\nMDB_env* MDBEnvProvider::GetEnv() {\n    return m_env;\n}\n\nMDB_dbi* MDBEnvProvider::GetDBI() {\n    return &m_dbi;\n}\n\nbool MDBEnvProvider::isValid() const {\n    return valid;\n}\n\nMDBEnvProvider::~MDBEnvProvider() {\n    mdb_dbi_close(m_env, m_dbi);\n    mdb_env_close(m_env);\n}\n\n#endif\n\n}  // namespace backend\n}  // namespace collection\n}  // namespace modsecurity\n"
  },
  {
    "path": "src/collection/backend/lmdb.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2023 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n\n#ifdef __cplusplus\n#include <string>\n#include <cstring>\n#include <iostream>\n#include <unordered_map>\n#include <list>\n#include <vector>\n#include <algorithm>\n#include <memory>\n#endif\n\n#ifdef WITH_LMDB\n#include <lmdb.h>\n#endif  // WITH_LMDB\n#include <sys/stat.h>\n#include <sys/types.h>\n#include <fcntl.h>\n\n#include \"modsecurity/variable_value.h\"\n#include \"modsecurity/collection/collection.h\"\n#include \"src/variables/variable.h\"\n\n#ifndef SRC_COLLECTION_BACKEND_LMDB_H_\n#define SRC_COLLECTION_BACKEND_LMDB_H_\n\n#ifdef WITH_LMDB\n\n#ifdef __cplusplus\nnamespace modsecurity {\nnamespace collection {\nnamespace backend {\n\n\n/**\n * The MDBEnvProvider class defines the `GetInstance` method that serves as an\n * alternative to constructor and lets clients access the same instance of this\n * class over and over. Its used to provide single MDB_env instance for each collection\n * that uses lmdb to store and retrieve data. That approach satisfies lmdb requirement:\n *\n *   \"LMDB uses POSIX locks on files, and these locks have issues if one process opens\n *    a file multiple times. Because of this, do not mdb_env_open() a file multiple\n *    times from a single process.\"\n *\n * Creation of MDB_env is delayed to moment when first transaction is opened.\n * This approach prevents passing env object to forked processes.\n * In that way next lmdb requirement be satisfied:\n *\n *   \"Use an MDB_env* in the process which opened it, without fork()ing.\"\n */\nclass MDBEnvProvider {\n\n public:\n    MDBEnvProvider(MDBEnvProvider &other) = delete;\n    void operator=(const MDBEnvProvider &) = delete;\n\n    /**\n     * This is the static method that controls the access to the singleton\n     * instance. On the first run, it creates a singleton object and places it\n     * into the static field. On subsequent runs, it returns the client existing\n     * object stored in the static field (Meyers Singleton implementation).\n     */\n    static MDBEnvProvider& GetInstance() {\n        static MDBEnvProvider instance;\n        return instance;\n    }\n    MDB_env* GetEnv();\n    MDB_dbi* GetDBI();\n    bool isValid() const;\n\n    ~MDBEnvProvider();\n private:\n    MDB_env *m_env;\n    MDB_dbi m_dbi;\n    bool valid;\n\n    MDBEnvProvider();\n};\n\nclass LMDB :\n    public Collection {\n public:\n    explicit LMDB(const std::string &name);\n\n    bool storeOrUpdateFirst(const std::string &key,\n        const std::string &value) override;\n\n    bool updateFirst(const std::string &key,\n        const std::string &value) override;\n\n    void del(const std::string& key) override;\n\n    void setExpiry(const std::string& key, int32_t expiry_seconds) override;\n\n    std::unique_ptr<std::string> resolveFirst(const std::string& var) override;\n\n    void resolveSingleMatch(const std::string& var,\n        std::vector<const VariableValue *> *l) override;\n    void resolveMultiMatches(const std::string& var,\n        std::vector<const VariableValue *> *l,\n        variables::KeyExclusions &ke) override;\n    void resolveRegularExpression(const std::string& var,\n        std::vector<const VariableValue *> *l,\n        variables::KeyExclusions &ke) override;\n\n private:\n    int txn_begin(unsigned int flags, MDB_txn **ret);\n    void string2val(const std::string& str, MDB_val *val);\n    void inline lmdb_debug(int rc, const std::string &op, const std::string &scope);\n\n    void delIfExpired(const std::string& key);\n\n    MDB_env *m_env;\n    MDB_dbi m_dbi;\n    bool isOpen;\n};\n\n}  // namespace backend\n}  // namespace collection\n}  // namespace modsecurity\n#endif\n\n#endif  // WITH_LMDB\n\n#endif  // SRC_COLLECTION_BACKEND_LMDB_H_\n"
  },
  {
    "path": "src/collection/collections.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n\n#include \"modsecurity/collection/collections.h\"\n\n#ifdef __cplusplus\n#include <string>\n#include <iostream>\n#include <unordered_map>\n#include <list>\n#include <vector>\n#endif\n\n#include \"modsecurity/variable_value.h\"\n#include \"modsecurity/collection/collection.h\"\n#include \"src/collection/backend/in_memory-per_process.h\"\n#include \"src/utils/string.h\"\n\n\nnamespace modsecurity {\nnamespace collection {\n\n\nCollections::Collections(Collection *global,\n    Collection *ip, Collection *session, Collection *user,\n    Collection *resource)\n    : m_global_collection_key(\"\"),\n    m_ip_collection_key(\"\"),\n    m_session_collection_key(\"\"),\n    m_user_collection_key(\"\"),\n    m_resource_collection_key(\"\"),\n    m_global_collection(global),\n    m_ip_collection(ip),\n    m_session_collection(session),\n    m_user_collection(user),\n    m_resource_collection(resource),\n    m_tx_collection(new backend::InMemoryPerProcess(\"TX\")) {\n    }\n\n\nCollections::~Collections() {\n    delete m_tx_collection;\n}\n\n\n}  // namespace collection\n}  // namespace modsecurity\n"
  },
  {
    "path": "src/compat/msvc.h",
    "content": "#ifndef __COMPAT_MSVC\n#define __COMPAT_MSVC\n\n#include <time.h>\n\n#if !defined(S_ISREG) && defined(S_IFMT) && defined(S_IFREG)\n#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)\n#endif\n\n#define strcasecmp   _stricmp\n#define strncasecmp  _strnicmp\n#define strtok_r     strtok_s\n#define popen        _popen\n#define pclose       _pclose\n\ninline tm* localtime_r(const time_t* tin, tm* tout) {\n  // cppcheck-suppress[uninitvar, ctuuninitvar]\n  if (!localtime_s(tout, tin)) return tout;\n\n  return nullptr;\n}\n\n#endif\n"
  },
  {
    "path": "src/debug_log/debug_log.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"modsecurity/debug_log.h\"\n\n#include \"src/debug_log/debug_log_writer.h\"\n#include \"src/debug_log_writer_agent.h\"\n\n\nnamespace modsecurity {\nnamespace debug_log {\n\n\nDebugLog::~DebugLog() {\n    DebugLogWriter::getInstance().close(m_fileName);\n}\n\nvoid DebugLog::setDebugLogFile(const std::string& fileName,\n    std::string *error) {\n    if (isLogFileSet()) {\n        DebugLogWriter::getInstance().close(m_fileName);\n    }\n\n    m_fileName = fileName;\n\n    DebugLogWriter::getInstance().open(m_fileName, error);\n}\n\n\nvoid DebugLog::setDebugLogLevel(int level) {\n    m_debugLevel = level;\n}\n\n\nbool DebugLog::isLogFileSet() {\n    return m_fileName.empty() == false;\n}\n\n\nbool DebugLog::isLogLevelSet() {\n    return m_debugLevel != -1;\n}\n\n\nconst std::string& DebugLog::getDebugLogFile() {\n    return m_fileName;\n}\n\n\nint DebugLog::getDebugLogLevel() {\n    if (m_debugLevel < 0) {\n        return 0;\n    }\n\n    return m_debugLevel;\n}\n\n\nvoid DebugLog::write(int level, const std::string &id,\n    const std::string &uri, const std::string &msg) {\n    if (level <= m_debugLevel) {\n        std::string msgf = \"[\" + std::to_string(level) + \"] \" + msg;\n        msgf = \"[\" + id + \"] [\" + uri + \"] \" + msgf;\n\n        DebugLogWriter &d = DebugLogWriter::getInstance();\n        d.write_log(m_fileName, msgf);\n    }\n}\n\n\nvoid DebugLog::write(int level, const std::string &msg) {\n    if (level <= m_debugLevel) {\n        std::string msgf = \"[\" + std::to_string(level) + \"] \" + msg;\n        DebugLogWriter &d = DebugLogWriter::getInstance();\n        d.write_log(m_fileName, msgf);\n    }\n}\n\n\n}  // namespace debug_log\n}  // namespace modsecurity\n"
  },
  {
    "path": "src/debug_log/debug_log_writer.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"src/debug_log/debug_log_writer.h\"\n\n#include \"src/utils/shared_files.h\"\n\nnamespace modsecurity {\nnamespace debug_log {\n\n\nint DebugLogWriter::open(const std::string& fileName, std::string *error) {\n    return utils::SharedFiles::getInstance().open(fileName, error);\n}\n\n\nvoid DebugLogWriter::close(const std::string& fileName) {\n     utils::SharedFiles::getInstance().close(fileName);\n}\n\n\nvoid DebugLogWriter::write_log(const std::string& fileName,\n    const std::string &msg) {\n    std::string err;\n    std::string lmsg = msg + \"\\n\";\n    utils::SharedFiles::getInstance().write(fileName, lmsg, &err);\n}\n\n\n}  // namespace debug_log\n}  // namespace modsecurity\n"
  },
  {
    "path": "src/debug_log/debug_log_writer.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <string>\n\n\n#ifndef SRC_DEBUG_LOG_DEBUG_LOG_WRITER_H_\n#define SRC_DEBUG_LOG_DEBUG_LOG_WRITER_H_\n\n\nnamespace modsecurity {\nnamespace debug_log {\n\n\n/** @ingroup ModSecurity_CPP_API */\nclass DebugLogWriter {\n public:\n    static DebugLogWriter& getInstance() {\n        static DebugLogWriter instance;\n        return instance;\n    }\n\n    static void write_log(const std::string& file, const std::string& msg);\n    static void close(const std::string& m_fileName);\n    static int open(const std::string& m_fileName, std::string *error);\n\n private:\n    DebugLogWriter() = default;\n    ~DebugLogWriter() = default;\n\n    // C++ 03\n    // ========\n    // Dont forget to declare these two. You want to make sure they\n    // are unacceptable otherwise you may accidentally get copies of\n    // your singleton appearing.\n    DebugLogWriter(DebugLogWriter const&) = delete;\n    void operator=(DebugLogWriter const&) = delete;\n};\n\n\n}  // namespace debug_log\n}  // namespace modsecurity\n\n#endif  // SRC_DEBUG_LOG_DEBUG_LOG_WRITER_H_\n"
  },
  {
    "path": "src/debug_log_writer_agent.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <iostream>\n#include <fstream>\n#include <string>\n\n#ifndef SRC_DEBUG_LOG_WRITER_AGENT_H_\n#define SRC_DEBUG_LOG_WRITER_AGENT_H_\n\nnamespace modsecurity {\n\n/** @ingroup ModSecurity_CPP_API */\nclass DebugLogWriterAgent : public std::ofstream {\n public:\n    explicit DebugLogWriterAgent(const std::string& fileName);\n    ~DebugLogWriterAgent() {\n        if (is_open()) {\n            close();\n        }\n    }\n\n    void write(const std::string& msg);\n\n    std::string m_fileName;\n};\n\n\n}  // namespace modsecurity\n\n#endif  // SRC_DEBUG_LOG_WRITER_AGENT_H_\n"
  },
  {
    "path": "src/engine/lua.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n\n#include \"src/engine/lua.h\"\n\n#include <stdio.h>\n#include <string.h>\n\n#include <vector>\n#include <string>\n#include <algorithm>\n#include <sstream>\n#include <iterator>\n#include <iostream>\n\n#include \"modsecurity/variable_value.h\"\n#include \"modsecurity/modsecurity.h\"\n#include \"src/utils/string.h\"\n#include \"modsecurity/transaction.h\"\n#include \"src/variables/variable.h\"\n#include \"src/variables/highest_severity.h\"\n#include \"src/actions/transformations/transformation.h\"\n\n\nnamespace modsecurity {\nnamespace engine {\n\n\nbool Lua::isCompatible(const std::string &script, Lua *l, std::string *error) {\n#ifdef WITH_LUA\n    std::string lua(\".lua\");\n    std::string err;\n\n    if (!(script.size() >= lua.size() &&\n        script.compare(script.size() - lua.size(), lua.size(), lua) == 0)) {\n        error->assign(\"Expecting a Lua script: \" + script);\n        return false;\n    }\n\n    if (l->load(script, &err) == false) {\n        error->assign(\"Problems load script: \" + err);\n        return false;\n    }\n\n    return true;\n#else\n    error->assign(\"Lua support was not enabled.\");\n    return false;\n#endif\n}\n\n\nbool Lua::load(const std::string &script, std::string *err) {\n#ifdef WITH_LUA\n    lua_State *L = luaL_newstate();\n    luaL_openlibs(L);\n\n    m_scriptName = script;\n    if (luaL_loadfile(L, script.c_str())) {\n        const char *luaerr = lua_tostring(L, -1);\n        err->assign(\"Failed to compile script '\" + script + \"\");\n        if (luaerr) {\n            err->append(\": \" + std::string(luaerr));\n        }\n        err->append(\".\");\n        lua_close(L);\n\n        return false;\n    }\n\n#if defined (WITH_LUA_5_2) || defined (WITH_LUA_5_1)\n    if (lua_dump(L, Lua::blob_keeper, reinterpret_cast<void *>(&m_blob))) {\n#else\n    if (lua_dump(L, Lua::blob_keeper, reinterpret_cast<void *>(&m_blob), 0)) {\n#endif\n        const char *luaerr = lua_tostring(L, -1);\n        err->assign(\"Failed to compile script '\" + script + \"\");\n        if (luaerr) {\n            err->append(\": \" + std::string(luaerr));\n        }\n        err->append(\".\");\n        lua_close(L);\n\n        return false;\n    }\n\n    lua_close(L);\n    return true;\n#else\n    err->assign(\"Lua support was not enabled.\");\n    return false;\n#endif\n}\n\n#ifdef WITH_LUA\nint Lua::blob_keeper(lua_State *L, const void *p, size_t sz, void *ud) {\n    LuaScriptBlob *lsb = static_cast<LuaScriptBlob *>(ud);\n    lsb->write(p, sz);\n    return 0;\n}\n\n\nconst char *Lua::blob_reader(lua_State *L, void *ud, size_t *size) {\n    const LuaScriptBlob *lsb = static_cast<LuaScriptBlob *>(ud);\n    const char *data = lsb->read(size);\n    return data;\n}\n#endif\n\n\nint Lua::run(Transaction *t, const std::string &str) { // cppcheck-suppress constParameterPointer\n#ifdef WITH_LUA\n    std::string luaRet;\n    const char *a = NULL;\n    int ret = true;\n    lua_State *L = luaL_newstate();\n    luaL_openlibs(L);\n\n    luaL_newmetatable(L, \"luaL_msc\");\n    lua_newtable(L);\n\n    lua_pushlightuserdata(L, reinterpret_cast<void *>(t));\n    lua_setglobal(L, \"__transaction\");\n\n    luaL_setfuncs(L, mscLuaLib, 0);\n    lua_setglobal(L, \"m\");\n\n#ifdef WITH_LUA_5_1\n    int rc = lua_load(L, Lua::blob_reader, &m_blob, m_scriptName.c_str());\n#else\n    int rc = lua_load(L, Lua::blob_reader, &m_blob, m_scriptName.c_str(),\n        NULL);\n#endif\n    if (rc != LUA_OK) {\n        std::string e;\n        e.assign(\"Failed to execute lua script: \" + m_scriptName + \". \");\n        switch (rc) {\n            case LUA_ERRSYNTAX:\n                e.assign(\"Syntax error. \");\n                break;\n            case LUA_ERRMEM:\n                e.assign(\"Memory error. \");\n                break;\n#if !defined(WITH_LUA_5_1) and !defined(WITH_LUA_5_4)\n            case LUA_ERRGCMM:\n                e.assign(\"Garbage Collector error. \");\n                break;\n#endif\n        }\n        e.append(lua_tostring(L, -1));\n        ms_dbg_a(t, 2, e);\n        ret = false;\n        goto err;\n    }\n\n    if (lua_pcall(L, 0, 0, 0)) {\n        std::string e;\n        const char *luaerr = lua_tostring(L, -1);\n        e.assign(\"Failed to execute lua script: \" + m_scriptName \\\n            + \" (before main)\");\n        if (luaerr != NULL) {\n            e.append(\" - \");\n            e.append(luaerr);\n        }\n        ms_dbg_a(t, 2, e);\n\n        ret = false;\n        goto err;\n    }\n\n    lua_setglobal(L, \"modsec\");\n\n    lua_getglobal(L, \"main\");\n\n    ms_dbg_a(t, 9, str);\n\n    /* Put the parameter on the stack. */\n    if (!str.empty() ) {\n        lua_pushlstring(L, str.c_str(), str.length());\n    }\n\n    if (lua_pcall(L, ((!str.empty()) ? 1 : 0), 1, 0)) {\n        std::string e;\n        const char *luaerr = lua_tostring(L, -1);\n        e.assign(\"Failed to execute lua script: \" + m_scriptName + \" (main)\");\n        if (luaerr != NULL) {\n            e.append(\" - \");\n            e.append(luaerr);\n        }\n        ms_dbg_a(t, 2, e);\n\n        ret = false;\n        goto err;\n    }\n\n    a = reinterpret_cast<const char *>(lua_tostring(L, -1));\n    if (a != NULL) {\n        luaRet.assign(a);\n    }\n\n    ms_dbg_a(t, 9, \"Returning from lua script: \" + luaRet);\n\n    if (luaRet.size() == 0) {\n        ret = false;\n    }\n\n\nerr:\n    lua_pop(L, 1);\n    lua_close(L);\n\n    return ret;\n#else\n    ms_dbg_a(t, 9, \"Lua support was not enabled.\");\n\n    return false;\n#endif\n}\n\n\n#ifdef WITH_LUA\nint Lua::log(lua_State *L) {\n    const Transaction *t(NULL);\n    const char *text;\n    int level;\n\n    /* Retrieve parameters. */\n    level = luaL_checknumber(L, 1);\n    text = luaL_checkstring(L, 2);\n\n    /* Retrieve msr. */\n    lua_getglobal(L, \"__transaction\");\n    t = reinterpret_cast<const Transaction *>(lua_topointer(L, -1));\n\n    /* Log message. */\n    if (t != NULL) {\n        ms_dbg_a(t, level, text);\n    }\n\n    return 0;\n}\n\n\nint Lua::getvar(lua_State *L) {\n    const char *varname(NULL);\n    Transaction *t(NULL);\n    void *z(NULL);\n\n    /* Retrieve parameters. */\n    varname = reinterpret_cast<const char *>(luaL_checkstring(L, 1));\n\n    lua_getglobal(L, \"__transaction\");\n    z = const_cast<void *>(lua_topointer(L, -1));\n    t = reinterpret_cast<Transaction *>(z);\n\n    std::string var = variables::Variable::stringMatchResolve(t, varname);\n    applyTransformations(L, t, 2, var);\n\n    if (var.size() == 0) {\n        lua_pushnil(L);\n        return 0;\n    }\n\n    lua_pushlstring(L, var.c_str(), var.size());\n\n    return 1;\n}\n\n\nint Lua::getvars(lua_State *L) {\n    const char *varname(NULL);\n    Transaction *t(NULL);\n    void *z(NULL);\n    std::vector<const VariableValue *> l;\n    int idx = 1;\n\n    /* Retrieve parameters. */\n    varname = reinterpret_cast<const char *>(luaL_checkstring(L, 1));\n\n    lua_getglobal(L, \"__transaction\");\n    z = const_cast<void *>(lua_topointer(L, -1));\n    t = reinterpret_cast<Transaction *>(z);\n\n    variables::Variable::stringMatchResolveMulti(t, varname, &l);\n\n    lua_newtable(L);\n    for (auto i : l) {\n        lua_pushnumber(L, idx);\n        lua_newtable(L);\n\n        lua_pushstring(L, \"name\");\n        lua_pushlstring(L, i->getKeyWithCollection().c_str(), i->getKeyWithCollection().size());\n        lua_settable(L, -3);\n\n        lua_pushstring(L, \"value\");\n        lua_pushlstring(L, i->getValue().c_str(), i->getValue().size());\n        lua_settable(L, -3);\n\n        lua_settable(L, -3);\n        idx++;\n    }\n\n    for (const VariableValue * i : l) {\n        delete i;\n    }\n\n    return 1;\n}\n\n\nint Lua::setvar(lua_State *L) {\n    Transaction *t(NULL);\n    const char *var_value(NULL);\n    const char *var_name(NULL);\n    std::string vname;\n    std::string collection;\n    std::string variableName;\n    int nargs = lua_gettop(L);\n    size_t pos;\n    void *z(NULL);\n\n    lua_getglobal(L, \"__transaction\");\n    z = const_cast<void *>(lua_topointer(L, -1));\n    t = reinterpret_cast<Transaction *>(z);\n\n\n    if (nargs != 2) {\n        ms_dbg_a(t, 8,\n            \"m.setvar: Failed m.setvar funtion must has 2 arguments\");\n        return -1;\n    }\n    var_value = luaL_checkstring(L, 2);\n    var_name = luaL_checkstring(L, 1);\n\n    lua_pop(L, 2);\n\n    if (var_value == NULL || var_name == NULL) {\n        return -1;\n    }\n\n    vname.assign(var_name);\n    pos = vname.find(\".\");\n    if (pos != std::string::npos) {\n        collection = std::string(vname, 0, pos);\n        collection = utils::string::toupper(collection);\n        variableName = std::string(vname, pos + 1,\n            std::string::npos);\n\n    } else {\n        ms_dbg_a(t, 8,\n            \"m.setvar: Must specify a collection using dot character\" \\\n            \" - ie m.setvar(tx.myvar,mydata)\");\n        return -1;\n    }\n\n    if (collection == \"TX\") {\n        t->m_collections.m_tx_collection->storeOrUpdateFirst(\n            variableName,\n            var_value);\n    }\n    else if (collection == \"IP\") {\n        t->m_collections.m_ip_collection->storeOrUpdateFirst(\n            variableName, t->m_collections.m_ip_collection_key,\n            t->m_rules->m_secWebAppId.m_value,\n            var_value);\n    }\n    else if (collection == \"GLOBAL\") {\n        t->m_collections.m_global_collection->storeOrUpdateFirst(\n            variableName, t->m_collections.m_global_collection_key,\n            t->m_rules->m_secWebAppId.m_value,\n            var_value);\n    }\n    else if (collection == \"RESOURCE\") {\n        t->m_collections.m_resource_collection->storeOrUpdateFirst(\n            variableName,\n            t->m_collections.m_resource_collection_key, \n            t->m_rules->m_secWebAppId.m_value,\n            var_value);\n    }\n    else if (collection == \"SESSION\") {\n         t->m_collections.m_session_collection->storeOrUpdateFirst(\n            variableName, t->m_collections.m_session_collection_key,\n                    t->m_rules->m_secWebAppId.m_value,\n            var_value);\n    }\n    else if (collection == \"USER\") {\n        t->m_collections.m_user_collection->storeOrUpdateFirst(\n            variableName, t->m_collections.m_user_collection_key,\n                    t->m_rules->m_secWebAppId.m_value,\n            var_value);\n\n    }\n    return 0;\n}\n\n\nvoid Lua::applyTransformations(lua_State *L, const Transaction *t,\n    int idx, std::string &var) {\n    if (lua_isuserdata(L, idx) || lua_isnoneornil(L, idx)) {\n        return;\n    }\n\n    if (lua_istable(L, idx)) {\n        const char *name = NULL;\n#ifdef WITH_LUA_5_1\n        int i, n = lua_objlen(L, idx);\n#else\n        int i, n = lua_rawlen(L, idx);\n#endif\n\n        for (i = 1; i <= n; i++) {\n            lua_rawgeti(L, idx, i);\n            name = reinterpret_cast<const char *>(luaL_checkstring(L, -1));\n\n            /* A \"none\" means start over */\n            if (strcmp(\"none\", name) == 0) {\n                continue;\n            }\n\n            auto tfn = \\\n                actions::transformations::Transformation::instantiate(\n                    \"t:\" + std::string(name));\n            // FIXME: transformation is not yet returning null.\n            if (tfn) {\n                tfn->transform(var, t);\n            } else {\n                ms_dbg_a(t, 1,\n                    \"SecRuleScript: Invalid transformation function: \" \\\n                    + std::string(name));\n            }\n            delete tfn;\n        }\n\n        return;\n    }\n\n    if (lua_isstring(L, idx)) {\n        const char *name(NULL);\n        name = reinterpret_cast<const char *>(luaL_checkstring(L, idx));\n\n        auto tfn = \\\n            actions::transformations::Transformation::instantiate(\n                \"t:\" + std::string(name));\n\n        // FIXME: transformation is not yet returning null.\n        if (tfn) {\n            tfn->transform(var, t);\n            delete tfn;\n        } else {\n            ms_dbg_a(t, 1, \"SecRuleScript: Invalid transformation function: \" \\\n                + std::string(name));\n        }\n        return;\n    }\n    ms_dbg_a(t, 8, \"SecRuleScript: Transformation parameter must be a \" \\\n        \"transformation name or array of transformation names, but found \" \\\n        \"\" + std::string(lua_typename(L, idx)) + \" (type \" \\\n        + std::to_string(lua_type(L, idx)) + \")\");\n}\n#endif\n\n}  //  namespace engine\n}  //  namespace modsecurity\n\n"
  },
  {
    "path": "src/engine/lua.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#ifdef WITH_LUA\n#include <lua.hpp>\n#endif\n\n#include <iostream>\n#include <cstdint>\n#include <cstring>\n#include <string>\n\n#ifndef SRC_ENGINE_LUA_H_\n#define SRC_ENGINE_LUA_H_\n\nnamespace modsecurity {\nclass Transaction;\nnamespace engine {\n\n#ifdef WITH_LUA\nclass LuaScriptBlob {\n public:\n    LuaScriptBlob() :\n        m_data(NULL),\n        m_len(0) { }\n\n    LuaScriptBlob(const LuaScriptBlob&) = delete;\n    LuaScriptBlob& operator=(const LuaScriptBlob&) = delete;\n\n    ~LuaScriptBlob() {\n        if (m_data) {\n            free(m_data);\n            m_data = NULL;\n        }\n    }\n\n\n    void write(const void *data, size_t len) {\n        unsigned char *d = (unsigned char *)realloc((unsigned char *)m_data, len + m_len);\n        std::memcpy(d + m_len, data, len);\n        m_len = m_len + len;\n        m_data = d;\n    }\n\n\n    const char *read(size_t *len) const {\n        *len = m_len;\n        return (const char *)m_data;\n    }\n\n\n    unsigned char *m_data;\n    size_t m_len;\n};\n#endif\n\nclass Lua {\n public:\n    Lua() { }\n\n    bool load(const std::string &script, std::string *err);\n    int run(Transaction *t, const std::string &str = \"\");\n    static bool isCompatible(const std::string &script, Lua *l, std::string *error);\n\n#ifdef WITH_LUA\n    static int blob_keeper(lua_State *L, const void *p, size_t sz, void *ud);\n    static const char *blob_reader(lua_State *L, void *us, size_t *size);\n\n    static int log(lua_State *L);\n    static int getvar(lua_State *L);\n    static int getvars(lua_State *L);\n    static int setvar(lua_State *L);\n    static void applyTransformations(lua_State *L, const Transaction *t,\n        int idx, std::string &var);\n\n    LuaScriptBlob m_blob;\n#endif\n    std::string m_scriptName;\n};\n\n#ifdef WITH_LUA\nstatic const struct luaL_Reg mscLuaLib[] = {\n    { \"log\", Lua::log },\n    { \"getvar\", Lua::getvar },\n    { \"getvars\", Lua::getvars },\n    { \"setvar\", Lua::setvar },\n    { NULL, NULL }\n};\n#endif\n\n}  // namespace engine\n}  // namespace modsecurity\n\n#ifdef WITH_LUA\n#if defined LUA_VERSION_NUM && LUA_VERSION_NUM < 502 && !defined WITH_LUA_JIT_2_1\n/*\n** Adapted from Lua 5.2.0\n*/\n#define LUA_OK 0\n\nstatic void luaL_setfuncs(lua_State *L, const luaL_Reg *l, int nup) {\n    luaL_checkstack(L, nup + 1, \"too many upvalues\");\n\n    for (; l->name != NULL; l++) {  /* fill the table with given functions */\n        int i;\n        lua_pushstring(L, l->name);\n        for (i = 0; i < nup; i++)  /* copy upvalues to the top */\n          lua_pushvalue(L, -(nup + 1));\n        lua_pushcclosure(L, l->func, nup);  /* closure with those upvalues */\n        lua_settable(L, -(nup + 3));\n    }\n\n    lua_pop(L, nup);  /* remove upvalues */\n}\n#endif\n#endif\n\n\n#endif  // SRC_ENGINE_LUA_H_\n"
  },
  {
    "path": "src/modsecurity.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n\n#include \"modsecurity/modsecurity.h\"\n#include \"src/config.h\"\n\n#ifdef WITH_YAJL\n#include <yajl/yajl_tree.h>\n#include <yajl/yajl_gen.h>\n#endif\n#ifdef WITH_LIBXML2\n#include <libxml/xmlschemas.h>\n#include <libxml/xpath.h>\n#endif\n#ifdef MSC_WITH_CURL\n#include <curl/curl.h>\n#endif\n\n\n#include <ctime>\n#include <iostream>\n\n#include \"modsecurity/rule.h\"\n#include \"modsecurity/rule_message.h\"\n#include \"src/collection/backend/in_memory-per_process.h\"\n#include \"src/collection/backend/lmdb.h\"\n#include \"src/unique_id.h\"\n#include \"src/utils/regex.h\"\n#include \"src/utils/geo_lookup.h\"\n#include \"src/actions/transformations/transformation.h\"\n\nnamespace modsecurity {\n\n/**\n * @name    ModSecurity\n * @brief   Initilizes ModSecurity CPP API\n *\n * ModSecurity initializer.\n *\n * Example Usage:\n * @code\n *\n * using ModSecurity::ModSecurity;\n *\n * ModSecurity *msc = new ModSecurity();\n *\n * @endcode\n */\nModSecurity::ModSecurity()\n    :\n#ifdef WITH_LMDB\n    m_global_collection(new collection::backend::LMDB(\"GLOBAL\")),\n    m_resource_collection(new collection::backend::LMDB(\"RESOURCE\")),\n    m_ip_collection(new collection::backend::LMDB(\"IP\")),\n    m_session_collection(new collection::backend::LMDB(\"SESSION\")),\n    m_user_collection(new collection::backend::LMDB(\"USER\")),\n#else\n    m_global_collection(new collection::backend::InMemoryPerProcess(\"GLOBAL\")),\n    m_resource_collection(\n        new collection::backend::InMemoryPerProcess(\"RESOURCE\")),\n    m_ip_collection(new collection::backend::InMemoryPerProcess(\"IP\")),\n    m_session_collection(\n        new collection::backend::InMemoryPerProcess(\"SESSION\")),\n    m_user_collection(new collection::backend::InMemoryPerProcess(\"USER\")),\n#endif\n    m_connector(\"\"),\n    m_whoami(\"\"),\n    m_logCb(NULL),\n    m_logProperties(0) {\n    UniqueId::uniqueId();\n    srand(time(NULL));\n#ifdef MSC_WITH_CURL\n    curl_global_init(CURL_GLOBAL_ALL);\n#endif\n#ifdef WITH_LIBXML2\n    xmlInitParser();\n#endif\n}\n\n\nModSecurity::~ModSecurity() {\n#ifdef MSC_WITH_CURL\n    curl_global_cleanup();\n#endif\n#ifdef WITH_GEOIP\n    Utils::GeoLookup::getInstance().cleanUp();\n#endif\n#ifdef WITH_LIBXML2\n    xmlCleanupParser();\n#endif\n    delete m_global_collection;\n    delete m_resource_collection;\n    delete m_ip_collection;\n    delete m_session_collection;\n    delete m_user_collection;\n}\n\n\n/**\n * @name    whoAmI\n * @brief   Return information about this ModSecurity version and platform.\n *\n * Platform and version are two questions that community will ask prior to\n * provide support. Making it available internally and to the connector as\n * well.\n *\n * @note This information maybe will be used by a log parser. If you want to\n *       update it, make it in a fashion that won't break the existent parsers.\n *       (e.g. adding extra information _only_ to the end of the string)\n */\nconst std::string& ModSecurity::whoAmI() {\n    std::string platform(\"Unknown platform\");\n\n#if AIX\n    platform = \"AIX\";\n#elif LINUX\n    platform = \"Linux\";\n#elif OPENBSD\n    platform = \"OpenBSD\";\n#elif SOLARIS\n    platform = \"Solaris\";\n#elif HPUX\n    platform = \"HPUX\";\n#elif MACOSX\n    platform = \"MacOSX\";\n#elif FREEBSD\n    platform = \"FreeBSD\";\n#elif DRAGONFLY\n    platform = \"DragonFlyBSD\";\n#elif NETBSD\n    platform = \"NetBSD\";\n#elif WIN32\n    platform = \"Windows\";\n#endif\n\n    if (m_whoami.empty()) {\n        m_whoami = \"ModSecurity v\" MODSECURITY_VERSION \" (\" + platform + \")\";\n    }\n\n    return m_whoami;\n}\n\n\n/**\n * @name    setConnectorInformation\n * @brief   Set information about the connector that is using the library.\n *\n * For the purpose of log it is necessary for modsecurity to understand which\n * 'connector' is consuming the API.\n *\n * @note It is strongly recommended to set a information in the following\n *       pattern:\n *\n *       ConnectorName vX.Y.Z-tag (something else)\n *\n *       For instance: ModSecurity-nginx v0.0.1-alpha (Whee)\n *\n * @param connector Information about the connector.\n *\n */\nvoid ModSecurity::setConnectorInformation(const std::string &connector) {\n    m_connector = connector;\n}\n\n\n/**\n * @name    getConnectorInformation\n * @brief   Returns the connector information.\n *\n * Returns whatever was set by 'setConnectorInformation'. Check\n * setConnectorInformation documentation to understand the expected format.\n *\n * @retval \"\" Nothing was informed about the connector.\n * @retval !=\"\" Connector information.\n */\nconst std::string& ModSecurity::getConnectorInformation() const {\n    return m_connector;\n}\n\nvoid ModSecurity::serverLog(void *data, const RuleMessage &rm) {\n    if (m_logCb == NULL) {\n        std::cerr << \"Server log callback is not set -- \" << rm.errorLog();\n        std::cerr << std::endl;\n        return;\n    }\n\n    if (m_logProperties & TextLogProperty) {\n        auto d = rm.log();\n        auto a = static_cast<const void *>(d.c_str());\n        m_logCb(data, a);\n        return;\n    }\n\n    if (m_logProperties & RuleMessageLogProperty) {\n        auto a = static_cast<const void *>(&rm);\n        m_logCb(data, a);\n        return;\n    }\n}\n\n\nint ModSecurity::processContentOffset(const char *content, size_t len,\n    const char *matchString, std::string *json, const char **err) {\n#ifdef WITH_YAJL\n    Utils::Regex variables(\"v([0-9]+),([0-9]+)\");\n    Utils::Regex operators(\"o([0-9]+),([0-9]+)\");\n    Utils::Regex transformations(\"t:(?:(?!t:).)+\");\n    yajl_gen g;\n    std::string varValue;\n    const unsigned char *buf;\n    size_t jsonSize;\n\n    std::list<Utils::SMatch> vars = variables.searchAll(matchString);\n    std::list<Utils::SMatch> ops = operators.searchAll(matchString);\n    std::list<Utils::SMatch> trans = transformations.searchAll(matchString);\n\n    g = yajl_gen_alloc(NULL);\n    if (g == NULL) {\n        *err = \"Failed to allocate memory for the JSON creation.\";\n        return -1;\n    }\n\n    yajl_gen_config(g, yajl_gen_beautify, 0);\n\n    yajl_gen_map_open(g);\n    yajl_gen_string(g, reinterpret_cast<const unsigned char*>(\"match\"),\n        strlen(\"match\"));\n\n    yajl_gen_array_open(g);\n    yajl_gen_map_open(g);\n\n    yajl_gen_string(g, reinterpret_cast<const unsigned char*>(\"variable\"),\n            strlen(\"variable\"));\n\n    yajl_gen_map_open(g);\n        yajl_gen_string(g, reinterpret_cast<const unsigned char*>(\"highlight\"),\n            strlen(\"highlight\"));\n\n        yajl_gen_array_open(g);\n    for(auto [it, pending] = std::tuple{vars.rbegin(), vars.size()}; pending > 3; pending -= 3) {\n        yajl_gen_map_open(g);\n        it++;\n        const std::string &startingAt = it->str(); it++;\n        const std::string &size = it->str(); it++;\n        yajl_gen_string(g,\n            reinterpret_cast<const unsigned char*>(\"startingAt\"),\n            strlen(\"startingAt\"));\n        yajl_gen_string(g,\n            reinterpret_cast<const unsigned char*>(startingAt.c_str()),\n            startingAt.size());\n        yajl_gen_string(g, reinterpret_cast<const unsigned char*>(\"size\"),\n            strlen(\"size\"));\n        yajl_gen_string(g,\n            reinterpret_cast<const unsigned char*>(size.c_str()),\n            size.size());\n        yajl_gen_map_close(g);\n\n        if (stoi(startingAt) >= len) {\n            *err = \"Offset is out of the content limits.\";\n            return -1;\n        }\n\n        const auto value = std::string(content, stoi(startingAt), stoi(size));\n        if (varValue.size() > 0) {\n            varValue.append(\" \" + value);\n        } else {\n            varValue.append(value);\n        }\n    }\n    yajl_gen_array_close(g);\n\n    yajl_gen_string(g, reinterpret_cast<const unsigned char*>(\"value\"),\n            strlen(\"value\"));\n\n    yajl_gen_array_open(g);\n\n    yajl_gen_map_open(g);\n    yajl_gen_string(g, reinterpret_cast<const unsigned char*>(\"value\"),\n            strlen(\"value\"));\n    yajl_gen_string(g, reinterpret_cast<const unsigned char*>(varValue.c_str()),\n            varValue.size());\n    yajl_gen_map_close(g);\n\n    while (!trans.empty()) {\n        modsecurity::actions::transformations::Transformation *t;\n        yajl_gen_map_open(g);\n        yajl_gen_string(g,\n            reinterpret_cast<const unsigned char*>(\"transformation\"),\n            strlen(\"transformation\"));\n\n        yajl_gen_string(g,\n            reinterpret_cast<const unsigned char*>(trans.back().str().c_str()),\n            trans.back().str().size());\n\n        t = modsecurity::actions::transformations::Transformation::instantiate(\n            trans.back().str().c_str());\n        t->transform(varValue, nullptr);\n        trans.pop_back();\n\n        yajl_gen_string(g, reinterpret_cast<const unsigned char*>(\"value\"),\n            strlen(\"value\"));\n        yajl_gen_string(g, reinterpret_cast<const unsigned char*>(\n            varValue.c_str()),\n            varValue.size());\n        yajl_gen_map_close(g);\n\n        delete t;\n    }\n\n    yajl_gen_array_close(g);\n\n    yajl_gen_string(g, reinterpret_cast<const unsigned char*>(\"operator\"),\n            strlen(\"operator\"));\n\n    yajl_gen_map_open(g);\n\n    for(auto [it, pending] = std::tuple{ops.rbegin(), ops.size()}; pending > 3; pending -= 3) {\n        yajl_gen_string(g, reinterpret_cast<const unsigned char*>(\"highlight\"),\n            strlen(\"highlight\"));\n        yajl_gen_map_open(g);\n        it++;\n        const std::string &startingAt = it->str(); it++;\n        const std::string &size = ops.back().str(); it++;\n        yajl_gen_string(g,\n            reinterpret_cast<const unsigned char*>(\"startingAt\"),\n            strlen(\"startingAt\"));\n        yajl_gen_string(g,\n            reinterpret_cast<const unsigned char*>(startingAt.c_str()),\n            startingAt.size());\n        yajl_gen_string(g, reinterpret_cast<const unsigned char*>(\"size\"),\n            strlen(\"size\"));\n        yajl_gen_string(g,\n            reinterpret_cast<const unsigned char*>(size.c_str()),\n            size.size());\n        yajl_gen_map_close(g);\n\n        if (stoi(startingAt) >= varValue.size()) {\n            *err = \"Offset is out of the variable limits.\";\n            return -1;\n        }\n        yajl_gen_string(g,\n            reinterpret_cast<const unsigned char*>(\"value\"),\n            strlen(\"value\"));\n\n        const auto value = std::string(varValue, stoi(startingAt), stoi(size));\n\n        yajl_gen_string(g,\n            reinterpret_cast<const unsigned char*>(value.c_str()),\n            value.size());\n    }\n\n    yajl_gen_map_close(g);\n\n\n    yajl_gen_map_close(g);\n    yajl_gen_array_close(g);\n\n    yajl_gen_map_close(g);\n    yajl_gen_array_close(g);\n    yajl_gen_map_close(g);\n\n    yajl_gen_get_buf(g, &buf, &jsonSize);\n\n    json->assign(reinterpret_cast<const char*>(buf), jsonSize);\n    json->append(\"\\n\");\n\n    yajl_gen_free(g);\n    return 0;\n#else\n    *err = \"Without YAJL support, we cannot generate JSON.\";\n    return -1;\n#endif\n}\n\n\nvoid ModSecurity::setServerLogCb(ModSecLogCb cb) {\n    setServerLogCb(cb, TextLogProperty);\n}\n\n\nvoid ModSecurity::setServerLogCb(ModSecLogCb cb, int properties) {\n    m_logCb = (ModSecLogCb) cb;\n    m_logProperties = properties;\n}\n\n/**\n * @name    msc_set_log_cb\n * @brief   Set the log callback functiond\n *\n * It is neccessary to indicate to libModSecurity which function within the\n * connector should be called when logging is required.\n *\n * @oarm msc The current ModSecurity instance\n * @param ModSecLogCb The callback function to which a reference to the log msgs \n * will be passed.\n *\n */\nextern \"C\" void msc_set_log_cb(ModSecurity *msc, ModSecLogCb cb) {\n    msc->setServerLogCb(cb);\n}\n\n/**\n * @name    msc_set_connector_info\n * @brief   Set information about the connector that is using the library.\n *\n * For the purpose of log it is necessary for modsecurity to understand which\n * 'connector' is consuming the API.\n *\n * @note It is strongly recommended to set a information in the following\n *       pattern:\n *\n *       ConnectorName vX.Y.Z-tag (something else)\n *\n *       For instance: ModSecurity-nginx v0.0.1-alpha\n *\n * @param connector Information about the connector.\n *\n */\nextern \"C\" void msc_set_connector_info(ModSecurity *msc,\n    const char *connector) {\n    msc->setConnectorInformation(std::string(connector));\n}\n\n\n/**\n * @name    msc_who_am_i\n * @brief   Return information about this ModSecurity version and platform.\n *\n * Platform and version are two questions that community will ask prior to\n * provide support. Making it available internally and to the connector as\n * well.\n *\n * @note This information maybe will be used by a log parser. If you want to\n *       update it, make it in a fashion that won't break the existent parsers.\n *       (e.g. adding extra information _only_ to the end of the string)\n */\nextern \"C\" const char *msc_who_am_i(ModSecurity *msc) {\n    return msc->whoAmI().c_str();\n}\n\n\n/**\n * @name    msc_cleanup\n * @brief   Cleanup ModSecurity C API\n *\n * Cleanup ModSecurity instance.\n *\n */\nextern \"C\" void msc_cleanup(ModSecurity *msc) {\n    delete msc;\n}\n\n\n/**\n * @name    msc_init\n * @brief   Initilizes ModSecurity C API\n *\n * ModSecurity initializer.\n *\n * Example Usage:\n * @code\n *\n * ModSecurity msc = msc_init();\n *\n * @endcode\n */\nextern \"C\" ModSecurity *msc_init(void) {\n    return new ModSecurity();\n}\n\n\n}  // namespace modsecurity\n"
  },
  {
    "path": "src/operators/.directory",
    "content": "[Dolphin]\nSortRole=type\nTimestamp=2015,6,11,13,57,39\nVersion=3\nViewMode=1\nVisibleRoles=Details_text,Details_size,Details_date,Details_type,CustomizedDetails\n"
  },
  {
    "path": "src/operators/begins_with.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"src/operators/begins_with.h\"\n\n#include <string>\n\n#include \"src/operators/operator.h\"\n\n\nnamespace modsecurity {\nnamespace operators {\n\n\nbool BeginsWith::evaluate(Transaction *transaction, RuleWithActions *rule,\n    const std::string &str, RuleMessage &ruleMessage) {\n    std::string p(m_string->evaluate(transaction));\n\n    if (str.size() < p.size()) {\n        return false;\n    } else if (!str.compare(0, p.size(), p)) {\n        logOffset(ruleMessage, 0, p.size());\n        return true;\n    }\n\n    return false;\n}\n\n\n}  // namespace operators\n}  // namespace modsecurity\n"
  },
  {
    "path": "src/operators/begins_with.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n * \n */\n\n#ifndef SRC_OPERATORS_BEGINS_WITH_H_\n#define SRC_OPERATORS_BEGINS_WITH_H_\n\n#include <string>\n#include <memory>\n#include <utility>\n\n#include \"src/operators/operator.h\"\n\n\nnamespace modsecurity {\nnamespace operators {\n\nclass BeginsWith : public Operator {\n public:\n    /** @ingroup ModSecurity_Operator */\n    explicit BeginsWith(std::unique_ptr<RunTimeString> param)\n        : Operator(\"BeginsWith\", std::move(param)) { }\n\n    bool evaluate(Transaction *transaction, RuleWithActions *rule, const std::string &str,\n        RuleMessage &ruleMessage) override;\n};\n\n}  // namespace operators\n}  // namespace modsecurity\n\n\n#endif  // SRC_OPERATORS_BEGINS_WITH_H_\n"
  },
  {
    "path": "src/operators/contains.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n * \n */\n\n#include \"src/operators/contains.h\"\n\n#include <string>\n\n\nnamespace modsecurity {\nnamespace operators {\n\nbool Contains::evaluate(Transaction *transaction, RuleWithActions *rule,\n        const std::string &input, RuleMessage &ruleMessage) {\n    std::string p(m_string->evaluate(transaction));\n    size_t offset = input.find(p);\n\n    bool contains = offset != std::string::npos;\n\n    if (contains && transaction) {\n        logOffset(ruleMessage, offset, p.size());\n        transaction->m_matched.push_back(p);\n    }\n\n    return contains;\n}\n\n}  // namespace operators\n}  // namespace modsecurity\n"
  },
  {
    "path": "src/operators/contains.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#ifndef SRC_OPERATORS_CONTAINS_H_\n#define SRC_OPERATORS_CONTAINS_H_\n\n#include <string>\n#include <list>\n#include <memory>\n#include <utility>\n\n#include \"modsecurity/transaction.h\"\n#include \"modsecurity/rule_message.h\"\n#include \"src/operators/operator.h\"\n\n\nnamespace modsecurity {\nnamespace operators {\n\nclass Contains : public Operator {\n public:\n    /** @ingroup ModSecurity_Operator */\n    explicit Contains(std::unique_ptr<RunTimeString> param)\n        : Operator(\"Contains\", std::move(param)) { }\n    bool evaluate(Transaction *transaction, RuleWithActions *rule,\n        const std::string &str,\n        RuleMessage &ruleMessage) override;\n};\n\n}  // namespace operators\n}  // namespace modsecurity\n\n\n#endif  // SRC_OPERATORS_CONTAINS_H_\n"
  },
  {
    "path": "src/operators/contains_word.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n * \n */\n\n#include \"src/operators/contains_word.h\"\n\n#include <string>\n\n#include \"src/operators/operator.h\"\n#include \"modsecurity/rule_message.h\"\n\nnamespace modsecurity {\nnamespace operators {\n\ninline bool ContainsWord::acceptableChar(const std::string& a, size_t pos) {\n    if (a.size() - 1 < pos) {\n        return false;\n    }\n\n    const auto ch = a[pos];\n    if ((ch >= 65 && ch <= 90) ||\n        (ch >= 97 && ch <= 122)) {\n        return false;\n    }\n\n    return true;\n}\n\nbool ContainsWord::evaluate(Transaction *transaction, RuleWithActions *rule,\n    const std::string &str, RuleMessage &ruleMessage) {\n    std::string paramTarget(m_string->evaluate(transaction));\n\n    if (paramTarget.empty()) {\n        return true;\n    }\n    if (str.empty()) {\n        return false;\n    }\n    if (str == paramTarget) {\n        return true;\n    }\n\n    size_t pos = str.find(paramTarget);\n    while (pos != std::string::npos) {\n        if (pos == 0 && acceptableChar(str, paramTarget.size())) {\n            logOffset(ruleMessage, 0, paramTarget.size());\n            return true;\n        }\n        if (pos + paramTarget.size() == str.size() &&\n            acceptableChar(str, pos - 1)) {\n            logOffset(ruleMessage, pos, paramTarget.size());\n            return true;\n        }\n        if (acceptableChar(str, pos - 1) &&\n            acceptableChar(str, pos + paramTarget.size())) {\n            logOffset(ruleMessage, pos, paramTarget.size());\n            return true;\n        }\n        pos = str.find(paramTarget, pos + 1);\n    }\n\n    return false;\n}\n\n\n}  // namespace operators\n}  // namespace modsecurity\n"
  },
  {
    "path": "src/operators/contains_word.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#ifndef SRC_OPERATORS_CONTAINS_WORD_H_\n#define SRC_OPERATORS_CONTAINS_WORD_H_\n\n#include <string>\n#include <memory>\n#include <utility>\n\n#include \"src/operators/operator.h\"\n#include \"modsecurity/rule_message.h\"\n\nnamespace modsecurity {\nnamespace operators {\n\nclass ContainsWord : public Operator {\n public:\n    /** @ingroup ModSecurity_Operator */\n    explicit ContainsWord(std::unique_ptr<RunTimeString> param)\n        : Operator(\"ContainsWord\", std::move(param)) { }\n\n    bool evaluate(Transaction *transaction, RuleWithActions *rule,\n        const std::string &str,\n        RuleMessage &ruleMessage) override;\n\n private:\n    static bool acceptableChar(const std::string& a, size_t pos);\n};\n\n}  // namespace operators\n}  // namespace modsecurity\n\n\n#endif  // SRC_OPERATORS_CONTAINS_WORD_H_\n"
  },
  {
    "path": "src/operators/detect_sqli.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"src/operators/detect_sqli.h\"\n\n#include <string>\n#include <list>\n\n#include \"src/operators/operator.h\"\n#include \"libinjection/src/libinjection.h\"\n\nnamespace modsecurity {\nnamespace operators {\n\n\nbool DetectSQLi::evaluate(Transaction *t, RuleWithActions *rule,\n    const std::string& input, RuleMessage &ruleMessage) {\n    char fingerprint[8];\n    int issqli;\n\n    issqli = libinjection_sqli(input.c_str(), input.length(), fingerprint);\n\n    if (!t) {\n        goto tisempty;\n    }\n\n    if (issqli) {\n        t->m_matched.push_back(fingerprint);\n        ms_dbg_a(t, 4, \"detected SQLi using libinjection with \" \\\n            \"fingerprint '\" + std::string(fingerprint) + \"' at: '\" +\n            input + \"'\");\n        if (rule && rule->hasCaptureAction()) {\n            t->m_collections.m_tx_collection->storeOrUpdateFirst(\n                \"0\", std::string(fingerprint));\n            ms_dbg_a(t, 7, \"Added DetectSQLi match TX.0: \" + \\\n                std::string(fingerprint));\n        }\n    } else {\n        ms_dbg_a(t, 9, \"detected SQLi: not able to find an \" \\\n            \"inject on '\" + input + \"'\");\n    }\n\ntisempty:\n    return issqli != 0;\n}\n\n\n}  // namespace operators\n}  // namespace modsecurity\n"
  },
  {
    "path": "src/operators/detect_sqli.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#ifndef SRC_OPERATORS_DETECT_SQLI_H_\n#define SRC_OPERATORS_DETECT_SQLI_H_\n\n#include <string>\n#include <list>\n\n#include \"src/operators/operator.h\"\n\nnamespace modsecurity {\nnamespace operators {\n\nclass DetectSQLi : public Operator {\n public:\n    /** @ingroup ModSecurity_Operator */\n    DetectSQLi()\n        : Operator(\"DetectSQLi\") {\n            m_match_message.assign(\"detected SQLi using libinjection.\");\n        }\n\n    bool evaluate(Transaction *t, RuleWithActions *rule,\n        const std::string& input,\n        RuleMessage &ruleMessage) override;\n};\n\n}  // namespace operators\n}  // namespace modsecurity\n\n\n#endif  // SRC_OPERATORS_DETECT_SQLI_H_\n"
  },
  {
    "path": "src/operators/detect_xss.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"src/operators/detect_xss.h\"\n\n#include <string>\n\n#include \"src/operators/operator.h\"\n#include \"libinjection/src/libinjection.h\"\n\n\nnamespace modsecurity {\nnamespace operators {\n\n\nbool DetectXSS::evaluate(Transaction *t, RuleWithActions *rule,\n    const std::string& input, RuleMessage &ruleMessage) {\n    int is_xss;\n\n    is_xss = libinjection_xss(input.c_str(), input.length());\n\n    if (t) {\n        if (is_xss) {\n            ms_dbg_a(t, 5, \"detected XSS using libinjection.\");\n            if (rule && rule->hasCaptureAction()) {\n                t->m_collections.m_tx_collection->storeOrUpdateFirst(\n                    \"0\", std::string(input));\n                ms_dbg_a(t, 7, \"Added DetectXSS match TX.0: \" + \\\n                    std::string(input));\n            }\n        } else {\n            ms_dbg_a(t, 9, \"libinjection was not able to \" \\\n                \"find any XSS in: \" + input);\n            }\n    }\n    return is_xss != 0;\n}\n\n\n}  // namespace operators\n}  // namespace modsecurity\n"
  },
  {
    "path": "src/operators/detect_xss.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#ifndef SRC_OPERATORS_DETECT_XSS_H_\n#define SRC_OPERATORS_DETECT_XSS_H_\n\n#include <string>\n\n#include \"src/operators/operator.h\"\n\nnamespace modsecurity {\nnamespace operators {\n\nclass DetectXSS : public Operator {\n public:\n    /** @ingroup ModSecurity_Operator */\n    DetectXSS()\n        : Operator(\"DetectXSS\") {\n            m_match_message.assign(\"detected XSS using libinjection.\");\n        }\n\n    bool evaluate(Transaction *t, RuleWithActions *rule,\n        const std::string& input,\n        RuleMessage &ruleMessage) override;\n};\n\n}  // namespace operators\n}  // namespace modsecurity\n\n\n#endif  // SRC_OPERATORS_DETECT_XSS_H_\n"
  },
  {
    "path": "src/operators/ends_with.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"src/operators/ends_with.h\"\n\n#include <string>\n\n#include \"src/operators/operator.h\"\n\nnamespace modsecurity {\nnamespace operators {\n\n\nbool EndsWith::evaluate(Transaction *transaction, RuleWithActions *rule,\n    const std::string &str, RuleMessage &ruleMessage) {\n    bool ret = false;\n    std::string p(m_string->evaluate(transaction));\n\n    if (str.length() >= p.length()) {\n        ret = (0 == str.compare(str.length() - p.length(),\n            p.length(), p));\n        if (ret) {\n            logOffset(ruleMessage, str.length() - p.length(),\n                      p.size());\n        }\n    }\n\n    return ret;\n}\n\n\n}  // namespace operators\n}  // namespace modsecurity\n"
  },
  {
    "path": "src/operators/ends_with.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#ifndef SRC_OPERATORS_ENDS_WITH_H_\n#define SRC_OPERATORS_ENDS_WITH_H_\n\n#include <string>\n#include <memory>\n#include <utility>\n\n#include \"src/operators/operator.h\"\n\n\nnamespace modsecurity {\nnamespace operators {\n\nclass EndsWith : public Operator {\n public:\n    /** @ingroup ModSecurity_Operator */\n    explicit EndsWith(std::unique_ptr<RunTimeString> param)\n        : Operator(\"EndsWith\", std::move(param)) {\n            m_couldContainsMacro = true;\n        }\n    bool evaluate(Transaction *transaction, RuleWithActions *rule,\n        const std::string &str,\n        RuleMessage &ruleMessage) override;\n};\n\n\n}  // namespace operators\n}  // namespace modsecurity\n\n\n#endif  // SRC_OPERATORS_ENDS_WITH_H_\n"
  },
  {
    "path": "src/operators/eq.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"src/operators/eq.h\"\n\n#include <string>\n\n#include \"src/operators/operator.h\"\n\n\nnamespace modsecurity {\nnamespace operators {\n\n\nbool Eq::evaluate(Transaction *transaction, const std::string &input) {\n    int p = 0;\n    int i = 0;\n    std::string pt(m_string->evaluate(transaction));\n\n    try {\n        p = std::stoi(pt);\n    } catch (...) {\n        p = 0;\n    }\n    try {\n        i = std::stoi(input);\n    } catch (...) {\n        i = 0;\n    }\n\n    return p == i;\n}\n\n\n}  // namespace operators\n}  // namespace modsecurity\n"
  },
  {
    "path": "src/operators/eq.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#ifndef SRC_OPERATORS_EQ_H_\n#define SRC_OPERATORS_EQ_H_\n\n#include <string>\n#include <memory>\n#include <utility>\n\n#include \"src/operators/operator.h\"\n\n\nnamespace modsecurity {\nnamespace operators {\n\nclass Eq : public Operator {\n public:\n    /** @ingroup ModSecurity_Operator */\n    explicit Eq(std::unique_ptr<RunTimeString> param)\n        : Operator(\"Eq\", std::move(param)) { }\n    bool evaluate(Transaction *transaction, const std::string &input) override;\n};\n\n}  // namespace operators\n}  // namespace modsecurity\n\n\n#endif  // SRC_OPERATORS_EQ_H_\n"
  },
  {
    "path": "src/operators/fuzzy_hash.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"src/operators/fuzzy_hash.h\"\n\n#include <string>\n\n#include \"src/operators/operator.h\"\n#include \"src/utils/system.h\"\n\nnamespace modsecurity {\nnamespace operators {\n\nbool FuzzyHash::init(const std::string &param2, std::string *error) {\n#ifdef WITH_SSDEEP\n    std::string digit;\n    std::string file;\n    std::ifstream *iss;\n    std::shared_ptr<fuzzy_hash_chunk> chunk, t;\n    std::string err;\n\n    auto pos = m_param.find_last_of(' ');\n    if (pos == std::string::npos) {\n        error->assign(\"Please use @fuzzyHash with filename and value\");\n        return false;\n    }\n    digit.append(std::string(m_param, pos+1));\n    file.append(std::string(m_param, 0, pos));\n    try {\n        m_threshold = std::stoi(digit);\n    } catch (...) {\n        error->assign(\"Expecting a digit, got: \" + digit);\n        return false;\n    }\n\n    std::string resource = utils::find_resource(file, param2, &err);\n    iss = new std::ifstream(resource, std::ios::in);\n\n    if (iss->is_open() == false) {\n        error->assign(\"Failed to open file: \" + m_param + \". \" + err);\n        delete iss;\n        return false;\n    }\n\n    for (std::string line; std::getline(*iss, line); ) {\n        chunk = std::make_shared<fuzzy_hash_chunk>();\n\n        chunk->data = std::shared_ptr<char>(strdup(line.c_str()), free);\n        chunk->next = nullptr;\n\n        if (m_head == NULL) {\n            m_head = chunk;\n        } else {\n            t = m_head;\n\n            while (t->next) {\n                t = t->next;\n            }\n\n            t->next = chunk;\n        }\n    }\n\n    delete iss;\n    return true;\n#else\n    error->assign(\"@fuzzyHash: SSDEEP support was not enabled \" \\\n        \"during the compilation.\");\n    return false;\n#endif\n}\n\nbool FuzzyHash::evaluate(Transaction *t, const std::string &str) {\n#ifdef WITH_SSDEEP\n    char result[FUZZY_MAX_RESULT];\n    std::shared_ptr<fuzzy_hash_chunk> chunk = m_head;\n\n\n    if (fuzzy_hash_buf((const unsigned char*)str.c_str(),\n        str.size(), result)) {\n        ms_dbg_a(t, 4, \"Problems generating fuzzy hash\");\n        return false;\n    }\n\n    while (chunk != NULL) {\n        int i = fuzzy_compare(chunk->data.get(), result);\n        if (i >= m_threshold) {\n            ms_dbg_a(t, 4, \"Fuzzy hash: matched \" \\\n                \"with score: \" + std::to_string(i) + \".\");\n            return true;\n        }\n        chunk = chunk->next;\n    }\n#endif\n    /* No match. */\n    return false;\n}\n\n}  // namespace operators\n}  // namespace modsecurity\n"
  },
  {
    "path": "src/operators/fuzzy_hash.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#ifndef SRC_OPERATORS_FUZZY_HASH_H_\n#define SRC_OPERATORS_FUZZY_HASH_H_\n\n#include <string>\n#include <memory>\n#include <utility>\n\n#ifdef WITH_SSDEEP\n#include <fuzzy.h>\n#endif\n\n#include \"src/operators/operator.h\"\n\nnamespace modsecurity {\nnamespace operators {\n\n\nstruct fuzzy_hash_chunk {\n    std::shared_ptr<char> data;\n    std::shared_ptr<fuzzy_hash_chunk> next;\n};\n\nclass FuzzyHash : public Operator {\n public:\n    /** @ingroup ModSecurity_Operator */\n    explicit FuzzyHash(std::unique_ptr<RunTimeString> param)\n        : Operator(\"FuzzyHash\", std::move(param)),\n        m_threshold(0),\n        m_head(NULL) { }\n    ~FuzzyHash() override = default;\n\n    bool evaluate(Transaction *transaction, const std::string &std) override;\n\n    bool init(const std::string &param, std::string *error) override;\n private:\n    int m_threshold;\n    std::shared_ptr<fuzzy_hash_chunk> m_head;\n};\n\n}  // namespace operators\n}  // namespace modsecurity\n\n\n#endif  // SRC_OPERATORS_FUZZY_HASH_H_\n"
  },
  {
    "path": "src/operators/ge.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"src/operators/ge.h\"\n\n#include <string>\n\n#include \"src/operators/operator.h\"\n\n\nnamespace modsecurity {\nnamespace operators {\n\nbool Ge::evaluate(Transaction *transaction, const std::string &input) {\n    std::string p(m_string->evaluate(transaction));\n    std::string i = input;\n\n    bool ge = atoll(i.c_str()) >= atoll(p.c_str());\n\n    return ge;\n}\n\n\n}  // namespace operators\n}  // namespace modsecurity\n"
  },
  {
    "path": "src/operators/ge.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#ifndef SRC_OPERATORS_GE_H_\n#define SRC_OPERATORS_GE_H_\n\n#include <string>\n#include <memory>\n#include <utility>\n\n#include \"src/operators/operator.h\"\n\nnamespace modsecurity {\nnamespace operators {\n\nclass Ge : public Operator {\n public:\n    /** @ingroup ModSecurity_Operator */\n    explicit Ge(std::unique_ptr<RunTimeString> param)\n        : Operator(\"Ge\", std::move(param)) {\n            m_couldContainsMacro = true;\n        }\n    bool evaluate(Transaction *transaction, const std::string &input) override;\n};\n\n}  // namespace operators\n}  // namespace modsecurity\n\n\n#endif  // SRC_OPERATORS_GE_H_\n"
  },
  {
    "path": "src/operators/geo_lookup.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"src/operators/geo_lookup.h\"\n\n#if WITH_MAXMIND\n#include <maxminddb.h>\n#endif\n\n#if WITH_GEOIP\n#include <GeoIPCity.h>\n#endif\n\n#include <string>\n#include <functional>\n\n#include \"src/operators/operator.h\"\n#include \"src/utils/geo_lookup.h\"\n\n\nnamespace modsecurity::operators {\n\n\nstatic bool debug(const Transaction *transaction, int x, const std::string &a) {\n    ms_dbg_a(transaction, x, a);\n    return true;\n}\n\n\nbool GeoLookup::evaluate(Transaction *trans, const std::string &exp) {\n    using std::placeholders::_1;\n    using std::placeholders::_2;\n    bool ret = true;\n\n    if (trans) {\n        ret = Utils::GeoLookup::getInstance().lookup(exp, trans,\n            std::bind(debug, trans, _1, _2));\n    } else {\n        ret = Utils::GeoLookup::getInstance().lookup(exp, nullptr,\n            nullptr);\n    }\n\n    return ret;\n}\n\n\n}  // namespace modsecurity::operators\n"
  },
  {
    "path": "src/operators/geo_lookup.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#ifndef SRC_OPERATORS_GEO_LOOKUP_H_\n#define SRC_OPERATORS_GEO_LOOKUP_H_\n\n#include <string>\n\n#include \"src/operators/operator.h\"\n\n\nnamespace modsecurity::operators {\n\n\nclass GeoLookup : public Operator {\n public:\n    /** @ingroup ModSecurity_Operator */\n    GeoLookup()\n        : Operator(\"GeoLookup\") { }\n    bool evaluate(Transaction *transaction, const std::string &exp) override;\n};\n\n\n}  // namespace modsecurity::operators\n\n\n#endif  // SRC_OPERATORS_GEO_LOOKUP_H_\n"
  },
  {
    "path": "src/operators/gsblookup.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"src/operators/gsblookup.h\"\n\n#include <string>\n\n#include \"src/operators/operator.h\"\n\nnamespace modsecurity {\nnamespace operators {\n\n\nbool GsbLookup::evaluate(Transaction *transaction, const std::string &str) {\n    /**\n     * @todo Implement the operator GeoLookup.\n     *       Reference: https://github.com/SpiderLabs/ModSecurity/wiki/Reference-Manual#gsblookup\n     */\n    return true;\n}\n\n\n}  // namespace operators\n}  // namespace modsecurity\n"
  },
  {
    "path": "src/operators/gsblookup.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#ifndef SRC_OPERATORS_GSBLOOKUP_H_\n#define SRC_OPERATORS_GSBLOOKUP_H_\n\n#include <string>\n#include <memory>\n#include <utility>\n\n#include \"src/operators/operator.h\"\n\nnamespace modsecurity {\nnamespace operators {\n\nclass GsbLookup : public Operator {\n public:\n    /** @ingroup ModSecurity_Operator */\n    explicit GsbLookup(std::unique_ptr<RunTimeString> param)\n        : Operator(\"GsbLookup\", std::move(param)) { }\n\n    bool evaluate(Transaction *transaction, const std::string &str) override;\n};\n\n}  // namespace operators\n}  // namespace modsecurity\n\n\n#endif  // SRC_OPERATORS_GSBLOOKUP_H_\n"
  },
  {
    "path": "src/operators/gt.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"src/operators/gt.h\"\n\n#include <string>\n\n#include \"src/operators/operator.h\"\n\n\nnamespace modsecurity {\nnamespace operators {\n\nbool Gt::evaluate(Transaction *transaction, const std::string &input) {\n    std::string p(m_string->evaluate(transaction));\n\n    bool gt = atoll(input.c_str()) > atoll(p.c_str());\n\n    return gt;\n}\n\n\n}  // namespace operators\n}  // namespace modsecurity\n"
  },
  {
    "path": "src/operators/gt.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#ifndef SRC_OPERATORS_GT_H_\n#define SRC_OPERATORS_GT_H_\n\n#include <string>\n#include <memory>\n#include <utility>\n\n#include \"src/operators/operator.h\"\n\n\nnamespace modsecurity {\nnamespace operators {\n\nclass Gt : public Operator {\n public:\n    /** @ingroup ModSecurity_Operator */\n    explicit Gt(std::unique_ptr<RunTimeString> param)\n        : Operator(\"Gt\", std::move(param)) {\n            m_couldContainsMacro = true;\n        }\n    bool evaluate(Transaction *transaction, const std::string &input) override;\n};\n\n}  // namespace operators\n}  // namespace modsecurity\n\n\n#endif  // SRC_OPERATORS_GT_H_\n"
  },
  {
    "path": "src/operators/inspect_file.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"src/operators/inspect_file.h\"\n\n#include <stdio.h>\n\n#include <string>\n#include <iostream>\n\n#include \"src/operators/operator.h\"\n#include \"src/utils/system.h\"\n\n#ifdef WIN32\n#include \"src/compat/msvc.h\"\n#endif\n\nnamespace modsecurity {\nnamespace operators {\n\nbool InspectFile::init(const std::string &param2, std::string *error) {\n    std::ifstream *iss;\n    std::string err;\n    std::string err_lua;\n\n    m_file = utils::find_resource(m_param, param2, &err);\n    iss = new std::ifstream(m_file, std::ios::in);\n\n    if (iss->is_open() == false) {\n        error->assign(\"Failed to open file: \" + m_param + \". \" + err);\n        delete iss;\n        return false;\n    }\n\n    if (engine::Lua::isCompatible(m_file, &m_lua, &err_lua) == true) {\n        m_isScript = true;\n    }\n\n    delete iss;\n    return true;\n}\n\n\nbool InspectFile::evaluate(Transaction *transaction, const std::string &str) {\n    if (m_isScript) {\n        return m_lua.run(transaction, str);\n    } else {\n        FILE *in;\n        char buff[512];\n        std::stringstream s;\n        std::string res;\n        std::string openstr;\n\n        openstr.append(m_param);\n        openstr.append(\" \");\n        openstr.append(str);\n        if (!(in = popen(openstr.c_str(), \"r\"))) {\n            return false;\n        }\n\n        while (fgets(buff, sizeof(buff), in) != NULL) {\n            s << buff;\n        }\n\n        pclose(in);\n\n        res.append(s.str());\n        if (res.size() > 1 && res[0] != '1') {\n            return true; /* match */\n        }\n\n        /* no match */\n        return false;\n    }\n}\n\n\n}  // namespace operators\n}  // namespace modsecurity\n"
  },
  {
    "path": "src/operators/inspect_file.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#ifndef SRC_OPERATORS_INSPECT_FILE_H_\n#define SRC_OPERATORS_INSPECT_FILE_H_\n\n#include <string>\n#include <memory>\n#include <utility>\n\n#include \"src/operators/operator.h\"\n#include \"src/engine/lua.h\"\n\n\nnamespace modsecurity {\nnamespace operators {\n\nclass InspectFile : public Operator {\n public:\n    /** @ingroup ModSecurity_Operator */\n    explicit InspectFile(std::unique_ptr<RunTimeString> param)\n        : Operator(\"InspectFile\", std::move(param)),\n        m_file(\"\"),\n        m_isScript(false) { }\n\n    bool init(const std::string &param, std::string *error) override;\n    bool evaluate(Transaction *transaction, const std::string &str) override;\n private:\n    std::string m_file;\n    bool m_isScript;\n    engine::Lua m_lua;\n};\n\n}  // namespace operators\n}  // namespace modsecurity\n\n\n#endif  // SRC_OPERATORS_INSPECT_FILE_H_\n"
  },
  {
    "path": "src/operators/ip_match.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"src/operators/ip_match.h\"\n\n#include <string.h>\n#include <string>\n\n#include \"src/utils/msc_tree.h\"\n#include \"src/operators/operator.h\"\n\nnamespace modsecurity {\nnamespace operators {\n\n\nbool IpMatch::init(const std::string &file, std::string *error) {\n    std::string e(\"\");\n    bool res = m_tree.addFromBuffer(m_param, &e);\n\n    if (res == false) {\n        error->assign(e);\n    }\n\n    return res;\n}\n\n\nbool IpMatch::evaluate(Transaction *transaction, const std::string &input) {\n    return m_tree.contains(input);\n}\n\n\n}  // namespace operators\n}  // namespace modsecurity\n"
  },
  {
    "path": "src/operators/ip_match.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#ifndef SRC_OPERATORS_IP_MATCH_H_\n#define SRC_OPERATORS_IP_MATCH_H_\n\n#include <string>\n#include <memory>\n#include <utility>\n\n#include \"src/operators/operator.h\"\n#include \"src/utils/ip_tree.h\"\n\nnamespace modsecurity {\nnamespace operators {\n\nclass IpMatch : public Operator {\n public:\n    /** @ingroup ModSecurity_Operator */\n    explicit IpMatch(std::unique_ptr<RunTimeString> param)\n        : Operator(\"IpMatch\", std::move(param)) { }\n    IpMatch(const std::string &n, std::unique_ptr<RunTimeString> param)\n        : Operator(n, std::move(param)) { }\n\n    bool evaluate(Transaction *transaction, const std::string &input) override;\n\n    bool init(const std::string &file, std::string *error) override;\n\n protected:\n    Utils::IpTree m_tree;\n};\n\n}  // namespace operators\n}  // namespace modsecurity\n\n\n#endif  // SRC_OPERATORS_IP_MATCH_H_\n"
  },
  {
    "path": "src/operators/ip_match_f.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"src/operators/ip_match_f.h\"\n\n#include <string>\n\n#include \"src/operators/operator.h\"\n\nnamespace modsecurity {\nnamespace operators {\n\n\n}  // namespace operators\n}  // namespace modsecurity\n"
  },
  {
    "path": "src/operators/ip_match_f.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#ifndef SRC_OPERATORS_IP_MATCH_F_H_\n#define SRC_OPERATORS_IP_MATCH_F_H_\n\n#include <string>\n#include <memory>\n#include <utility>\n\n#include \"src/operators/ip_match_from_file.h\"\n\n\nnamespace modsecurity {\nnamespace operators {\n\nclass IpMatchF : public IpMatchFromFile {\n public:\n    explicit IpMatchF(std::unique_ptr<RunTimeString> param)\n        : IpMatchFromFile(std::move(param)) { }\n};\n\n}  // namespace operators\n}  // namespace modsecurity\n\n\n#endif  // SRC_OPERATORS_IP_MATCH_F_H_\n"
  },
  {
    "path": "src/operators/ip_match_from_file.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"src/operators/ip_match_from_file.h\"\n#include \"src/utils/system.h\"\n\n#include <string>\n\n#include <string.h>\n\n#include \"src/operators/operator.h\"\n\nnamespace modsecurity {\nnamespace operators {\n\n\nbool IpMatchFromFile::init(const std::string &file,\n    std::string *error) {\n    std::string e(\"\");\n    bool res = false;\n\n    if (m_param.compare(0, 8, \"https://\") == 0) {\n        res = m_tree.addFromUrl(m_param, &e);\n    } else {\n        std::string resf = utils::find_resource(m_param, file, error);\n        if (resf == \"\") {\n            return false;\n        }\n        res = m_tree.addFromFile(resf, &e);\n    }\n\n    if (res == false) {\n        error->assign(e);\n    }\n\n    return res;\n}\n\n\n}  // namespace operators\n}  // namespace modsecurity\n"
  },
  {
    "path": "src/operators/ip_match_from_file.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n#ifndef SRC_OPERATORS_IP_MATCH_FROM_FILE_H_\n#define SRC_OPERATORS_IP_MATCH_FROM_FILE_H_\n\n#include <string>\n#include <memory>\n#include <utility>\n\n#include \"src/operators/ip_match.h\"\n\nnamespace modsecurity {\nnamespace operators {\n\nclass IpMatchFromFile : public IpMatch {\n public:\n    /** @ingroup ModSecurity_Operator */\n    explicit IpMatchFromFile(std::unique_ptr<RunTimeString> param)\n        : IpMatch(\"IpMatchFromFile\", std::move(param)) { }\n    IpMatchFromFile(const std::string &n, std::unique_ptr<RunTimeString> param)\n        : IpMatch(n, std::move(param)) { }\n    bool init(const std::string& file, std::string *error) override;\n};\n\n}  // namespace operators\n}  // namespace modsecurity\n\n\n#endif  // SRC_OPERATORS_IP_MATCH_FROM_FILE_H_\n"
  },
  {
    "path": "src/operators/le.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"src/operators/le.h\"\n\n#include <string>\n\n#include \"src/operators/operator.h\"\n\n\nnamespace modsecurity {\nnamespace operators {\n\nbool Le::evaluate(Transaction *transaction, const std::string &input) {\n    std::string p(m_string->evaluate(transaction));\n\n    bool le = atoll(input.c_str()) <= atoll(p.c_str());\n\n    return le;\n}\n\n\n}  // namespace operators\n}  // namespace modsecurity\n"
  },
  {
    "path": "src/operators/le.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#ifndef SRC_OPERATORS_LE_H_\n#define SRC_OPERATORS_LE_H_\n\n#include <string>\n#include <memory>\n#include <utility>\n\n#include \"src/operators/operator.h\"\n\n\nnamespace modsecurity {\nnamespace operators {\n\nclass Le : public Operator {\n public:\n    /** @ingroup ModSecurity_Operator */\n    explicit Le(std::unique_ptr<RunTimeString> param)\n        : Operator(\"Le\", std::move(param)) {\n            m_couldContainsMacro = true;\n        }\n\n    bool evaluate(Transaction *transaction, const std::string &input) override;\n};\n\n\n}  // namespace operators\n}  // namespace modsecurity\n\n\n#endif  // SRC_OPERATORS_LE_H_\n"
  },
  {
    "path": "src/operators/lt.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"src/operators/lt.h\"\n\n#include <string>\n\n#include \"src/operators/operator.h\"\n\nnamespace modsecurity {\nnamespace operators {\n\nbool Lt::evaluate(Transaction *transaction, const std::string &input) {\n    std::string p(m_string->evaluate(transaction));\n\n    bool lt = atoll(input.c_str()) < atoll(p.c_str());\n\n    return lt;\n}\n\n\n}  // namespace operators\n}  // namespace modsecurity\n"
  },
  {
    "path": "src/operators/lt.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#ifndef SRC_OPERATORS_LT_H_\n#define SRC_OPERATORS_LT_H_\n\n#include <string>\n#include <memory>\n#include <utility>\n\n#include \"src/operators/operator.h\"\n\n\nnamespace modsecurity {\nnamespace operators {\n\nclass Lt : public Operator {\n public:\n    /** @ingroup ModSecurity_Operator */\n    explicit Lt(std::unique_ptr<RunTimeString> param)\n        : Operator(\"Lt\", std::move(param)) {\n             m_couldContainsMacro = true;\n        }\n\n    bool evaluate(Transaction *transaction, const std::string &input) override;\n};\n\n}  // namespace operators\n}  // namespace modsecurity\n\n\n#endif  // SRC_OPERATORS_LT_H_\n"
  },
  {
    "path": "src/operators/no_match.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"src/operators/no_match.h\"\n\n#include <string>\n\nnamespace modsecurity {\nnamespace operators {\n\nbool NoMatch::evaluate(Transaction *transaction, const std::string &str) {\n    return false;\n}\n\n\n}  // namespace operators\n}  // namespace modsecurity\n"
  },
  {
    "path": "src/operators/no_match.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <string>\n\n#include \"modsecurity/transaction.h\"\n#include \"src/operators/operator.h\"\n\n\n#ifndef SRC_OPERATORS_NO_MATCH_H_\n#define SRC_OPERATORS_NO_MATCH_H_\n\n\nnamespace modsecurity {\nnamespace operators {\n\nclass NoMatch : public Operator {\n public:\n    /** @ingroup ModSecurity_Operator */\n    NoMatch()\n        : Operator(\"NoMatch\") { }\n\n    bool evaluate(Transaction *transaction, const std::string &str) override;\n};\n\n}  // namespace operators\n}  // namespace modsecurity\n\n\n#endif  // SRC_OPERATORS_NO_MATCH_H_\n"
  },
  {
    "path": "src/operators/operator.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"src/operators/operator.h\"\n\n#include <cstring>\n#include <memory>\n#include <string>\n\n#include \"modsecurity/transaction.h\"\n#include \"src/run_time_string.h\"\n#include \"src/utils/string.h\"\n#include \"src/operators/begins_with.h\"\n#include \"src/operators/contains.h\"\n#include \"src/operators/contains_word.h\"\n#include \"src/operators/detect_sqli.h\"\n#include \"src/operators/detect_xss.h\"\n#include \"src/operators/ends_with.h\"\n#include \"src/operators/eq.h\"\n#include \"src/operators/fuzzy_hash.h\"\n#include \"src/operators/ge.h\"\n#include \"src/operators/geo_lookup.h\"\n#include \"src/operators/gsblookup.h\"\n#include \"src/operators/gt.h\"\n#include \"src/operators/inspect_file.h\"\n#include \"src/operators/ip_match_f.h\"\n#include \"src/operators/ip_match_from_file.h\"\n#include \"src/operators/ip_match.h\"\n#include \"src/operators/le.h\"\n#include \"src/operators/lt.h\"\n#include \"src/operators/no_match.h\"\n#include \"src/operators/pm_f.h\"\n#include \"src/operators/pm_from_file.h\"\n#include \"src/operators/pm.h\"\n#include \"src/operators/rbl.h\"\n#include \"src/operators/rsub.h\"\n#include \"src/operators/rx.h\"\n#include \"src/operators/rx_global.h\"\n#include \"src/operators/str_eq.h\"\n#include \"src/operators/str_match.h\"\n#include \"src/operators/validate_byte_range.h\"\n#include \"src/operators/validate_dtd.h\"\n#include \"src/operators/validate_hash.h\"\n#include \"src/operators/validate_schema.h\"\n#include \"src/operators/validate_url_encoding.h\"\n#include \"src/operators/validate_utf8_encoding.h\"\n#include \"src/operators/verify_cc.h\"\n#include \"src/operators/verify_cpf.h\"\n#include \"src/operators/verify_ssn.h\"\n#include \"src/operators/verify_svnr.h\"\n#include \"src/operators/within.h\"\n#include \"src/operators/unconditional_match.h\"\n\n#define IF_MATCH(a) \\\n    if (op_ == #a)\n\nnamespace modsecurity {\nnamespace operators {\n\n\nbool Operator::evaluateInternal(Transaction *transaction,\n    RuleWithActions *rule, const std::string& a, RuleMessage &ruleMessage) {\n    bool res = evaluate(transaction, rule, a, ruleMessage);\n\n    if (m_negation) {\n        return !res;\n    }\n\n    return res;\n}\n\nbool Operator::evaluateInternal(Transaction *transaction,\n    RuleWithActions *rule, const std::string& a) {\n    bool res = evaluate(transaction, rule, a);\n\n    if (m_negation) {\n        return !res;\n    }\n\n    return res;\n}\n\nbool Operator::evaluateInternal(Transaction *transaction,\n    const std::string& a) {\n    bool res = evaluate(transaction, a);\n\n    if (m_negation) {\n        return !res;\n    }\n\n    return res;\n}\n\n\nstd::string Operator::resolveMatchMessage(Transaction *t,\n    std::string key, std::string value) {\n    std::string ret = m_match_message;\n\n    if (ret.empty() == true) {\n        if (m_couldContainsMacro == false) {\n            ret = \"Matched \\\"Operator `\" + m_op + \"' with parameter `\" +\n                utils::string::limitTo(200, m_param) +\n                \"' against variable `\" + utils::string::toHexIfNeeded(key) + \"' (Value: `\" +\n                utils::string::limitTo(100,\n                    utils::string::toHexIfNeeded(value)) + \\\n                \"' )\";\n        } else {\n            std::string p(m_string->evaluate(t));\n            ret = \"Matched \\\"Operator `\" + m_op + \"' with parameter `\" +\n                utils::string::limitTo(200, p) +\n                \"' against variable `\" + utils::string::toHexIfNeeded(key) + \"' (Value: `\" +\n                utils::string::limitTo(100,\n                    utils::string::toHexIfNeeded(value)) +\n                \"' )\";\n        }\n    }\n\n\n    return ret;\n}\n\n\nbool Operator::evaluate(Transaction *transaction, const std::string& a) {\n    ms_dbg_a(transaction, 2, \"Operator: \" + m_op + \\\n        \" is not implemented or malfunctioning.\");\n    return true;\n}\n\nOperator *Operator::instantiate(const std::string& op, const std::string& param_str) {\n    std::string op_ = utils::string::tolower(op);\n    auto param = std::make_unique<RunTimeString>();\n    param->appendText(param_str);\n\n    IF_MATCH(beginswith) { return new BeginsWith(std::move(param)); }\n    IF_MATCH(contains) { return new Contains(std::move(param)); }\n    IF_MATCH(containsword) { return new ContainsWord(std::move(param)); }\n    IF_MATCH(detectsqli) { return new DetectSQLi(); }\n    IF_MATCH(detectxss) { return new DetectXSS(); }\n    IF_MATCH(endswith) { return new EndsWith(std::move(param)); }\n    IF_MATCH(eq) { return new Eq(std::move(param)); }\n    IF_MATCH(fuzzyhash) { return new FuzzyHash(std::move(param)); }\n    IF_MATCH(geolookup) { return new GeoLookup(); }\n    IF_MATCH(ge) { return new Ge(std::move(param)); }\n    IF_MATCH(gsblookup) { return new GsbLookup(std::move(param)); }\n    IF_MATCH(gt) { return new Gt(std::move(param)); }\n    IF_MATCH(inspectfile) { return new InspectFile(std::move(param)); }\n    IF_MATCH(ipmatchf) { return new IpMatchF(std::move(param)); }\n    IF_MATCH(ipmatchfromfile) {\n        return new IpMatchFromFile(std::move(param));\n    }\n    IF_MATCH(ipmatch) { return new IpMatch(std::move(param)); }\n    IF_MATCH(le) { return new Le(std::move(param)); }\n    IF_MATCH(lt) { return new Lt(std::move(param)); }\n    IF_MATCH(nomatch) { return new NoMatch(); }\n    IF_MATCH(pmfromfile) { return new PmFromFile(std::move(param)); }\n    IF_MATCH(pmf) { return new PmF(std::move(param)); }\n    IF_MATCH(pm) { return new Pm(std::move(param)); }\n    IF_MATCH(rbl) { return new Rbl(std::move(param)); }\n    IF_MATCH(rsub) { return new Rsub(std::move(param)); }\n    IF_MATCH(rx) { return new Rx(std::move(param)); }\n    IF_MATCH(rxglobal) { return new RxGlobal(std::move(param)); }\n    IF_MATCH(streq) { return new StrEq(std::move(param)); }\n    IF_MATCH(strmatch) { return new StrMatch(std::move(param)); }\n    IF_MATCH(validatebyterange) {\n        return new ValidateByteRange(std::move(param));\n    }\n    IF_MATCH(validatedtd) { return new ValidateDTD(std::move(param)); }\n    IF_MATCH(validatehash) { return new ValidateHash(std::move(param)); }\n    IF_MATCH(validateschema) { return new ValidateSchema(std::move(param)); }\n    IF_MATCH(validateurlencoding) {\n        return new ValidateUrlEncoding();\n    }\n    IF_MATCH(validateutf8encoding) {\n        return new ValidateUtf8Encoding();\n    }\n    IF_MATCH(verifycc) { return new VerifyCC(std::move(param)); }\n    IF_MATCH(verifycpf) { return new VerifyCPF(std::move(param)); }\n    IF_MATCH(verifyssn) { return new VerifySSN(std::move(param)); }\n    IF_MATCH(verifysvnr) { return new VerifySVNR(std::move(param)); }\n    IF_MATCH(within) { return new Within(std::move(param)); }\n\n    IF_MATCH(unconditionalmatch) {\n        return new UnconditionalMatch();\n    }\n\n    throw std::invalid_argument(\"Operator not found.\");\n}\n\n}  // namespace operators\n}  // namespace modsecurity\n"
  },
  {
    "path": "src/operators/operator.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <string>\n#include <memory>\n#include <utility>\n\n#ifndef SRC_OPERATORS_OPERATOR_H__\n#define SRC_OPERATORS_OPERATOR_H__\n\n#include \"modsecurity/transaction.h\"\n#include \"modsecurity/rule.h\"\n#include \"modsecurity/rule_message.h\"\n#include \"src/run_time_string.h\"\n\nnamespace modsecurity {\nnamespace operators {\n\nclass Operator {\n public:\n    /** @ingroup ModSecurity_Operator */\n    Operator()\n        : m_match_message(\"\"),\n        m_negation(false),\n        m_op(\"\"),\n        m_param(\"\"),\n        m_couldContainsMacro(false) {\n            if (m_couldContainsMacro == false && m_string) {\n                m_param = m_string->evaluate();\n            }\n        }\n\n    Operator(const std::string &opName, const std::string &param, bool negation)\n        : m_match_message(\"\"),\n        m_negation(negation),\n        m_op(opName),\n        m_param(param),\n        m_couldContainsMacro(false) {\n            if (m_couldContainsMacro == false && m_string) {\n                m_param = m_string->evaluate();\n            }\n        }\n\n    Operator(const std::string &opName, std::unique_ptr<RunTimeString> param,\n        bool negation)\n        : m_match_message(\"\"),\n        m_negation(negation),\n        m_op(opName),\n        m_param(\"\"),\n        m_string(std::move(param)),\n        m_couldContainsMacro(false) {\n            if (m_couldContainsMacro == false && m_string) {\n                m_param = m_string->evaluate();\n            }\n        }\n\n    Operator(const std::string &opName, const std::string &param)\n        : m_match_message(\"\"),\n        m_negation(false),\n        m_op(opName),\n        m_param(param),\n        m_couldContainsMacro(false) {\n            if (m_couldContainsMacro == false && m_string) {\n                m_param = m_string->evaluate();\n            }\n        }\n\n    Operator(const std::string &opName, std::unique_ptr<RunTimeString> param)\n        : m_match_message(\"\"),\n        m_negation(false),\n        m_op(opName),\n        m_param(\"\"),\n        m_string(std::move(param)),\n        m_couldContainsMacro(false) {\n            if (m_couldContainsMacro == false && m_string) {\n                m_param = m_string->evaluate();\n            }\n        }\n\n    explicit Operator(const std::string &opName)\n        : m_match_message(\"\"),\n        m_negation(false),\n        m_op(opName),\n        m_param(),\n        m_couldContainsMacro(false) {\n            if (m_couldContainsMacro == false && m_string) {\n                m_param = m_string->evaluate();\n            }\n        }\n\n    virtual ~Operator() { }\n    static Operator *instantiate(const std::string& opName,\n        const std::string& param);\n\n    virtual bool init(const std::string &arg, std::string *error) {\n        return true;\n    }\n\n    virtual std::string resolveMatchMessage(Transaction *t,\n        std::string key, std::string value);\n\n    bool evaluateInternal(Transaction *t, const std::string& a);\n    bool evaluateInternal(Transaction *t, RuleWithActions *rule,\n        const std::string& a);\n    bool evaluateInternal(Transaction *t, RuleWithActions *rule,\n        const std::string& a, RuleMessage &ruleMessage);\n\n\n    virtual bool evaluate(Transaction *transaction, const std::string &str);\n    virtual bool evaluate(Transaction *transaction, RuleWithActions *rule,\n        const std::string &str) {\n        return evaluate(transaction, str);\n    }\n    virtual bool evaluate(Transaction *transaction, RuleWithActions *rule,\n        const std::string &str, RuleMessage &ruleMessage) {\n        return evaluate(transaction, str);\n    }\n\n    static void logOffset(RuleMessage &ruleMessage, int offset, int len) {\n        ruleMessage.m_reference.append(\"o\"\n            + std::to_string(offset) + \",\"\n            + std::to_string(len));\n    }\n\n    std::string m_match_message;\n    bool m_negation;\n    const std::string m_op;\n    std::string m_param;\n    std::unique_ptr<RunTimeString> m_string;\n    bool m_couldContainsMacro;\n};\n\n}  // namespace operators\n}  // namespace modsecurity\n\n\n#endif  // SRC_OPERATORS_OPERATOR_H__\n"
  },
  {
    "path": "src/operators/pm.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"src/operators/pm.h\"\n\n#include <algorithm>\n#include <iterator>\n#include <sstream>\n\n#include \"src/utils/acmp.h\"\n#include \"src/utils/string.h\"\n\nusing namespace modsecurity::utils::string;\n\nstatic inline std::string parse_pm_content(const std::string &op_parm) {\n    auto offset = op_parm.find_first_not_of(\" \\t\");\n    if (offset == std::string::npos) {\n        return op_parm;\n    }\n\n    auto size = op_parm.size() - offset;\n    if (size >= 2 &&\n        op_parm[offset] == '\\\"' && op_parm.back() == '\\\"') {\n        offset++;\n        size -= 2;\n    }\n\n    if (size == 0) {\n        return op_parm;\n    }\n\n    std::string parsed_parm(op_parm.c_str() + offset, size);\n\n    unsigned char bin_offset = 0;\n    unsigned char bin_parm[3] = { 0 };\n    bool bin = false, esc = false;\n\n    char *d = parsed_parm.data();\n    for(const char *s = d, *e = d + size; s != e; ++s) {\n        if (*s == '|') {\n            bin = !bin;\n        } else if(!esc && *s == '\\\\') {\n            esc = true;\n        } else {\n            if (bin) {\n                if (VALID_HEX(*s)) {\n                    bin_parm[bin_offset] = (char)*s;\n                    bin_offset++;\n                    if (bin_offset == 2) {\n                        unsigned char c = strtol((char *)bin_parm, (char **) nullptr, 16) & 0xFF;\n                        bin_offset = 0;\n                        *d++ = c;\n                    }\n                } else {\n                    // Invalid hex character\n                    return op_parm;\n                }\n            } else if (esc) {\n                if (*s == ':' ||\n                        *s == ';' ||\n                        *s == '\\\\' ||\n                        *s == '\\\"')\n                {\n                    *d++ = *s;\n                } else {\n                    // Unsupported escape sequence\n                    return op_parm;\n                }\n                esc = false;\n            } else {\n                *d++ = *s;\n            }\n        }\n    }\n\n    parsed_parm.resize(d - parsed_parm.c_str());\n    return parsed_parm;\n}\n\n\nnamespace modsecurity {\nnamespace operators {\n\nPm::~Pm() {\n    acmp_node_t *root = m_p->root_node;\n\n    cleanup(root);\n\n    free(m_p);\n    m_p = NULL;\n}\n\n\nvoid Pm::cleanup(acmp_node_t *n) {\n    if (n == NULL) {\n        return;\n    }\n\n    cleanup(n->sibling);\n    cleanup(n->child);\n\n    postOrderTraversal(n->btree);\n\n    if (n->text && strlen(n->text) > 0) {\n        free(n->text);\n        n->text = NULL;\n    }\n\n    if (n->pattern && strlen(n->pattern) > 0) {\n        free(n->pattern);\n        n->pattern = NULL;\n    }\n\n    free(n);\n}\n\n\nvoid Pm::postOrderTraversal(acmp_btree_node_t *node) {\n    if (node == NULL) {\n        return;\n    }\n\n    postOrderTraversal(node->right);\n    postOrderTraversal(node->left);\n\n    free(node);\n}\n\n\nbool Pm::evaluate(Transaction *transaction, RuleWithActions *rule,\n    const std::string &input, RuleMessage &ruleMessage) {\n    int rc;\n    ACMPT pt;\n    pt.parser = m_p;\n    pt.ptr = NULL;\n    const char *match = NULL;\n    rc = acmp_process_quick(&pt, &match, input.c_str(), input.length());\n\n    if (rc >= 0 && transaction) {\n        std::string match_(match?match:\"\");\n        logOffset(ruleMessage, rc - match_.size() + 1, match_.size());\n        transaction->m_matched.push_back(match_);\n\n        if (rule && rule->hasCaptureAction()) {\n            transaction->m_collections.m_tx_collection->storeOrUpdateFirst(\"0\",\n                match_);\n            ms_dbg_a(transaction, 7, \"Added pm match TX.0: \" + \\\n                match_);\n        }\n    }\n\n    return rc >= 0;\n}\n\n\nbool Pm::init(const std::string &file, std::string *error) {\n    const auto op_parm = parse_pm_content(m_param);\n\n    std::istringstream iss{op_parm};\n    std::for_each(std::istream_iterator<std::string>(iss),\n        std::istream_iterator<std::string>(),\n        [this](const auto &a) {\n            acmp_add_pattern(m_p, a.c_str(), NULL, NULL, a.length());\n        });\n\n    while (m_p->is_failtree_done == 0) {\n        acmp_prepare(m_p);\n    }\n\n    return true;\n}\n\n\n}  // namespace operators\n}  // namespace modsecurity\n"
  },
  {
    "path": "src/operators/pm.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#ifndef SRC_OPERATORS_PM_H_\n#define SRC_OPERATORS_PM_H_\n\n#include <string>\n#include <memory>\n#include <utility>\n#include <mutex>\n\n#include \"src/operators/operator.h\"\n#include \"src/utils/acmp.h\"\n\n\nnamespace modsecurity {\nnamespace operators {\n\n\nclass Pm : public Operator {\n public:\n    /** @ingroup ModSecurity_Operator */\n    explicit Pm(std::unique_ptr<RunTimeString> param)\n        : Operator(\"Pm\", std::move(param)) {\n        m_p = acmp_create(0);\n    }\n    explicit Pm(const std::string &n, std::unique_ptr<RunTimeString> param)\n        : Operator(n, std::move(param)) {\n        m_p = acmp_create(0);\n    }\n\n    Pm(const Pm&) = delete;\n    Pm& operator=(const Pm&) = delete;\n\n    ~Pm() override;\n    bool evaluate(Transaction *transaction, RuleWithActions *rule,\n        const std::string &str,\n        RuleMessage &ruleMessage) override;\n\n\n    bool init(const std::string &file, std::string *error) override;\n    void postOrderTraversal(acmp_btree_node_t *node);\n    void cleanup(acmp_node_t *n);\n\n protected:\n    ACMP *m_p;\n};\n\n\n}  // namespace operators\n}  // namespace modsecurity\n\n\n#endif  // SRC_OPERATORS_PM_H_\n"
  },
  {
    "path": "src/operators/pm_f.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#ifndef SRC_OPERATORS_PM_F_H_\n#define SRC_OPERATORS_PM_F_H_\n\n#include <string>\n#include <memory>\n#include <utility>\n\n#include \"src/operators/pm_from_file.h\"\n\n\nnamespace modsecurity {\nnamespace operators {\n\n\nclass PmF : public PmFromFile {\n public:\n    /** @ingroup ModSecurity_Operator */\n    explicit PmF(std::unique_ptr<RunTimeString> param)\n        : PmFromFile(\"PmFromF\", std::move(param)) { }\n};\n\n\n}  // namespace operators\n}  // namespace modsecurity\n\n\n#endif  // SRC_OPERATORS_PM_F_H_\n"
  },
  {
    "path": "src/operators/pm_from_file.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"src/operators/pm_from_file.h\"\n\n#include <string>\n\n#include \"src/operators/operator.h\"\n#include \"src/utils/https_client.h\"\n#include \"src/utils/system.h\"\n#include \"src/utils/string.h\"\n\nusing namespace modsecurity::utils::string;\n\nnamespace modsecurity {\nnamespace operators {\n\nbool PmFromFile::isComment(const std::string &s) {\n    if (s.size() == 0) {\n\t  return true;\n    }\n    size_t pos = s.find(\"#\");\n    if (pos != std::string::npos) {\n        for (int i = 0; i < pos; i++) {\n\t    if (!std::isspace(s[i])) {\n\t\treturn false;\n\t    }\n\t}\n    } else {\n\treturn false;\n    }\n\n    return true;\n}\n\nbool PmFromFile::init(const std::string &config, std::string *error) {\n    std::vector<std::string> tokens = split(m_param, ' ');\n\n    for (const auto& token : tokens) {\n        if (token.empty()) {\n            continue;\n        }\n\n        std::unique_ptr<std::istream> iss;\n\n        if (token.compare(0, 8, \"https://\") == 0) {\n            Utils::HttpsClient client;\n            bool ret = client.download(token);\n            if (ret == false) {\n                error->assign(client.error);\n                return false;\n            }\n            iss = std::make_unique<std::stringstream>(client.content);\n        } else {\n            std::string err;\n            std::string resource = utils::find_resource(token, config, &err);\n            auto file = std::make_unique<std::ifstream>(resource, std::ios::in);\n            if (file->is_open() == false) {\n                error->assign(\"Failed to open file: '\" + token + \"'. \" + err);\n                return false;\n            }\n            iss = std::move(file);\n        }\n        for (std::string line; std::getline(*iss, line); ) {\n            if (isComment(line) == false) {\n                acmp_add_pattern(m_p, line.c_str(), NULL, NULL, line.length());\n            }\n        }\n    }\n\n    while (m_p->is_failtree_done == 0) {\n        acmp_prepare(m_p);\n    }\n\n    return true;\n}\n\n\n}  // namespace operators\n}  // namespace modsecurity\n"
  },
  {
    "path": "src/operators/pm_from_file.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#ifndef SRC_OPERATORS_PM_FROM_FILE_H_\n#define SRC_OPERATORS_PM_FROM_FILE_H_\n\n#include <string>\n#include <memory>\n#include <utility>\n\n#include \"src/operators/pm.h\"\n\n\nnamespace modsecurity {\nnamespace operators {\n\n\nclass PmFromFile : public Pm {\n public:\n    /** @ingroup ModSecurity_Operator */\n    explicit PmFromFile(std::unique_ptr<RunTimeString> param)\n        : Pm(\"PmFromFile\", std::move(param)) { }\n    explicit PmFromFile(const std::string &n, std::unique_ptr<RunTimeString> param)\n        : Pm(n, std::move(param)) { }\n\n    bool init(const std::string &file, std::string *error) override;\n\nprivate:\n    static bool isComment(const std::string &s);\n};\n\n\n}  // namespace operators\n}  // namespace modsecurity\n\n\n#endif  // SRC_OPERATORS_PM_FROM_FILE_H_\n"
  },
  {
    "path": "src/operators/rbl.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"src/operators/rbl.h\"\n\n#include <sys/types.h>\n#ifndef WIN32\n#include <sys/socket.h>\n#include <netdb.h>\n#include <netinet/in.h>\n#include <arpa/inet.h>\n#else\n#include <WinSock2.h>\n#include <WS2tcpip.h>\n#endif\n\n#include <string>\n\n#include \"modsecurity/rules_set.h\"\n#include \"src/operators/operator.h\"\n\nnamespace modsecurity {\nnamespace operators {\n\n\nstd::string Rbl::mapIpToAddress(const std::string &ipStr, Transaction *trans) const {\n    std::string addr;\n    int h0, h1, h2, h3;\n    std::string key;\n    if (trans && trans->m_rules->m_httpblKey.m_set == true) {\n        key = trans->m_rules->m_httpblKey.m_value;\n    }\n\n    if (sscanf(ipStr.c_str(), \"%d.%d.%d.%d\", &h0, &h1, &h2, &h3) != 4) {\n        ms_dbg_a(trans, 0, std::string(\"Failed to understand `\" + ipStr +\n            \"' as a valid IP address, assuming domain format input\"));\n\n        addr = ipStr + \".\" + m_service;\n        return addr;\n    }\n\n    if (m_demandsPassword && key.empty()) {\n        ms_dbg_a(trans, 0, std::string(\"Missing RBL key, cannot continue \" \\\n            \"with the operator execution, please set the key using: \" \\\n            \"SecHttpBlKey\"));\n        return addr;\n    }\n\n    addr = std::to_string(h3) + \".\" +\n        std::to_string(h2) + \".\" +\n        std::to_string(h1) + \".\" +\n        std::to_string(h0) + \".\" +\n        m_service;\n\n    if (m_demandsPassword) {\n        addr = key + \".\" + addr;\n    }\n\n    return addr;\n}\n\n\nvoid Rbl::futherInfo_httpbl(struct sockaddr_in *sin, const std::string &ipStr,\n    const Transaction *trans) {\n    const char *respBl;\n    int first, days, score, type;\n#ifndef NO_LOGS\n    std::string ptype;\n#endif\n\n    respBl = inet_ntoa(sin->sin_addr);\n\n    if (sscanf(respBl, \"%d.%d.%d.%d\", &first, &days, &score, &type) != 4) {\n        ms_dbg_a(trans, 4, \"RBL lookup of \" + ipStr + \" failed: bad response\");\n        return;\n    }\n\n    if (first != 127) {\n        ms_dbg_a(trans, 4, \"RBL lookup of \" + ipStr + \" failed: bad response\");\n        return;\n    }\n\n#ifndef NO_LOGS\n    switch (type) {\n        case 0:\n            ptype = \"Search Engine\";\n            break;\n        case 1:\n            ptype = \"Suspicious IP\";\n            break;\n        case 2:\n            ptype = \"Harvester IP\";\n            break;\n        case 3:\n            ptype = \"Suspicious harvester IP\";\n            break;\n        case 4:\n            ptype = \"Comment spammer IP\";\n            break;\n        case 5:\n            ptype = \"Suspicious comment spammer IP\";\n            break;\n        case 6:\n            ptype = \"Harvester and comment spammer IP\";\n            break;\n        case 7:\n            ptype = \"Suspicious harvester comment spammer IP\";\n            break;\n        default:\n            ptype = \" \";\n    }\n#endif\n\n    ms_dbg_a(trans, 4, \"RBL lookup of \" + ipStr + \" succeeded. %s: \" \\\n        + std::to_string(days) + \" \" \\\n        \"days since last activity, threat score \" \\\n        + std::to_string(score) +  \". Case: \" + ptype);\n}\n\n\nvoid Rbl::futherInfo_spamhaus(unsigned int high8bits, const std::string &ipStr,\n    const Transaction *trans) {\n    switch (high8bits) {\n        case 2:\n        case 3:\n            ms_dbg_a(trans, 4, \"RBL lookup of \" + ipStr + \" succeeded \" \\\n                \"(Static UBE sources).\");\n            break;\n        case 4:\n        case 5:\n        case 6:\n        case 7:\n            ms_dbg_a(trans, 4, \"RBL lookup of \" + ipStr + \" succeeded \" \\\n                \"(Illegal 3rd party exploits).\");\n            break;\n        case 10:\n        case 11:\n            ms_dbg_a(trans, 4, \"RBL lookup of \" + ipStr + \" succeeded \" \\\n                \"(Delivering unauthenticated SMTP email).\");\n            break;\n        default:\n            ms_dbg_a(trans, 4, \"RBL lookup of \" + ipStr + \" succeeded \");\n            break;\n    }\n}\n\n\nvoid Rbl::futherInfo_uribl(unsigned int high8bits, const std::string &ipStr,\n    const Transaction *trans) {\n    switch (high8bits) {\n        case 2:\n            ms_dbg_a(trans, 4, \"RBL lookup of \" + ipStr + \" succeeded (BLACK).\");\n        break;\n        case 4:\n            ms_dbg_a(trans, 4, \"RBL lookup of \" + ipStr + \" succeeded (GREY).\");\n            break;\n        case 8:\n            ms_dbg_a(trans, 4, \"RBL lookup of \" + ipStr + \" succeeded (RED).\");\n            break;\n        case 14:\n            ms_dbg_a(trans, 4, \"RBL lookup of \" + ipStr + \" succeeded \" \\\n                \"(BLACK,GREY,RED).\");\n            break;\n        case 255:\n            ms_dbg_a(trans, 4, \"RBL lookup of \" + ipStr + \" succeeded \" \\\n                \"(DNS IS BLOCKED).\");\n            break;\n        default:\n            ms_dbg_a(trans, 4, \"RBL lookup of \" + ipStr + \" succeeded (WHITE).\");\n            break;\n    }\n}\n\n\nvoid Rbl::furtherInfo(struct sockaddr_in *sin, const std::string &ipStr,\n    const Transaction *trans, RblProvider provider) {\n    unsigned int high8bits = sin->sin_addr.s_addr >> 24;\n\n    switch (provider) {\n        case RblProvider::UnknownProvider:\n            ms_dbg_a(trans, 2, \"RBL lookup of \" + ipStr + \" succeeded.\");\n            break;\n        case RblProvider::httpbl:\n            futherInfo_httpbl(sin, ipStr, trans);\n            break;\n        case RblProvider::uribl:\n            futherInfo_uribl(high8bits, ipStr, trans);\n            break;\n        case RblProvider::spamhaus:\n            futherInfo_spamhaus(high8bits, ipStr, trans);\n            break;\n    }\n}\n\n\nbool Rbl::evaluate(Transaction *t, RuleWithActions *rule,\n        const std::string& ipStr,\n        RuleMessage &ruleMessage) {\n    struct addrinfo *info = NULL;\n    std::string host = Rbl::mapIpToAddress(ipStr, t);\n    int rc = 0;\n\n    if (host.empty()) {\n        return false;\n    }\n\n    rc = getaddrinfo(host.c_str(), NULL, NULL, &info);\n\n    if (rc != 0) {\n        if (info != NULL) {\n            freeaddrinfo(info);\n        }\n        ms_dbg_a(t, 5, \"RBL lookup of \" + ipStr + \" failed.\");\n        return false;\n    }\n\n    // SonarCloud suggested to use the init-statement to declare \"addr\" inside the if statement.\n    // I think that's not good here, because we need that in the else block\n    const struct sockaddr *addr = info->ai_addr;  // NOSONAR\n    if (addr->sa_family == AF_INET) {  // NOSONAR\n        struct sockaddr_in sin{};  // initialize an empty struct; we don't need port info\n        memcpy(&sin.sin_addr, addr->sa_data + 2, sizeof(sin.sin_addr));\n        sin.sin_family = AF_INET;\n        furtherInfo(&sin, ipStr, t, m_provider);\n    }\n    else {\n        ms_dbg_a(t, 7,  \"Unsupported address family: \" + std::to_string(addr->sa_family));\n        freeaddrinfo(info);\n        return false;\n    }\n\n    freeaddrinfo(info);\n    if (rule && t && rule->hasCaptureAction()) {\n        t->m_collections.m_tx_collection->storeOrUpdateFirst(\n        \"0\", std::string(ipStr));\n        ms_dbg_a(t, 7, \"Added RXL match TX.0: \" + \\\n            std::string(ipStr));\n    }\n\n    return true;\n}\n\n\n}  // namespace operators\n}  // namespace modsecurity\n"
  },
  {
    "path": "src/operators/rbl.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#ifndef SRC_OPERATORS_RBL_H_\n#define SRC_OPERATORS_RBL_H_\n\n#include <sys/types.h>\n#ifndef WIN32\n#include <sys/socket.h>\n#include <netdb.h>\n#include <netinet/in.h>\n#include <arpa/inet.h>\n#else\n#include <WinSock2.h>\n#endif\n\n#include <string>\n#include <memory>\n#include <utility>\n\n#include \"src/operators/operator.h\"\n\n\nnamespace modsecurity::operators {\n\n\nclass Rbl : public Operator {\n public:\n    /**\n     *\n     */\n    enum RblProvider {\n        /**\n         * UnknownProvider\n         *\n         */\n        UnknownProvider,\n        /**\n         * httpbl.org\n         *\n         */\n        httpbl,\n        /**\n         * uribl.com\n         *\n         */\n        uribl,\n        /**\n         * spamhaus.org\n         *\n         */\n        spamhaus,\n    };\n\n    /** @ingroup ModSecurity_Operator */\n    explicit Rbl(std::unique_ptr<RunTimeString> param)\n        : Operator(\"Rbl\", std::move(param)),\n        m_service(m_string->evaluate()) {\n        if (m_service.find(\"httpbl.org\") != std::string::npos)\n        {\n            m_demandsPassword = true;\n            m_provider = RblProvider::httpbl;\n        } else if (m_service.find(\"uribl.com\") != std::string::npos) {\n            m_provider = RblProvider::uribl;\n        } else if (m_service.find(\"spamhaus.org\") != std::string::npos) {\n            m_provider = RblProvider::spamhaus;\n        }\n    }\n    bool evaluate(Transaction *transaction, RuleWithActions *rule,\n        const std::string& input,\n        RuleMessage &ruleMessage) override;\n\n    std::string mapIpToAddress(const std::string &ipStr, Transaction *trans) const;\n\n    static void futherInfo_httpbl(struct sockaddr_in *sin, const std::string &ipStr,\n        const Transaction *trans);\n    static void futherInfo_spamhaus(unsigned int high8bits, const std::string &ipStr,\n        const Transaction *trans);\n    static void futherInfo_uribl(unsigned int high8bits, const std::string &ipStr,\n        const Transaction *trans);\n    static void furtherInfo(struct sockaddr_in *sin, const std::string &ipStr,\n        const Transaction *trans, RblProvider provider);\n\n private:\n    std::string m_service;\n    bool m_demandsPassword = false;\n    RblProvider m_provider = RblProvider::UnknownProvider;\n};\n\n\n}  // namespace modsecurity::operators\n\n\n#endif  // SRC_OPERATORS_RBL_H_\n"
  },
  {
    "path": "src/operators/rsub.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"src/operators/rsub.h\"\n\n#include <string>\n\n#include \"src/operators/operator.h\"\n\nnamespace modsecurity {\nnamespace operators {\n\n\nbool Rsub::evaluate(Transaction *transaction, const std::string &str) {\n    /**\n     * @todo Implement the operator Rsub.\n     *       Reference: https://github.com/SpiderLabs/ModSecurity/wiki/Reference-Manual#rsub\n     */\n    return true;\n}\n\n\n}  // namespace operators\n}  // namespace modsecurity\n"
  },
  {
    "path": "src/operators/rsub.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#ifndef SRC_OPERATORS_RSUB_H_\n#define SRC_OPERATORS_RSUB_H_\n\n#include <string>\n#include <memory>\n#include <utility>\n\n#include \"src/operators/operator.h\"\n\n\nnamespace modsecurity {\nnamespace operators {\n\n\nclass Rsub : public Operator {\n public:\n    /** @ingroup ModSecurity_Operator */\n    explicit Rsub(std::unique_ptr<RunTimeString> param)\n        : Operator(\"Rsub\", std::move(param)) { }\n    bool evaluate(Transaction *transaction, const std::string  &str) override;\n};\n\n\n}  // namespace operators\n}  // namespace modsecurity\n\n\n#endif  // SRC_OPERATORS_RSUB_H_\n"
  },
  {
    "path": "src/operators/rx.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"src/operators/rx.h\"\n\n#include <string>\n#include <list>\n#include <memory>\n\n#include \"src/operators/operator.h\"\n#include \"modsecurity/rule.h\"\n#include \"modsecurity/rule_message.h\"\n\nnamespace modsecurity {\nnamespace operators {\n\n\nbool Rx::init(const std::string &arg, std::string *error) {\n    if (m_string->m_containsMacro == false) {\n        m_re = new Regex(m_param);\n    }\n\n    return true;\n}\n\n\nbool Rx::evaluate(Transaction *transaction, RuleWithActions *rule,\n    const std::string& input, RuleMessage &ruleMessage) {\n    Regex *re;\n\n    if (m_param.empty() && !m_string->m_containsMacro) {\n        return true;\n    }\n\n    if (m_string->m_containsMacro) {\n        std::string eparam(m_string->evaluate(transaction));\n        re = new Regex(eparam);\n    } else {\n        re = m_re;\n    }\n\n    if (re->hasError()) {\n        ms_dbg_a(transaction, 3, \"Error with regular expression: \\\"\" + re->pattern + \"\\\"\");\n        return false;\n    }\n\n    Utils::RegexResult regex_result;\n    std::vector<Utils::SMatchCapture> captures;\n\n    if (transaction && transaction->m_rules->m_pcreMatchLimit.m_set) {\n        unsigned long match_limit = transaction->m_rules->m_pcreMatchLimit.m_value;\n        regex_result = re->searchOneMatch(input, captures, match_limit);\n    } else {\n        regex_result = re->searchOneMatch(input, captures);\n    }\n\n    // FIXME: DRY regex error reporting. This logic is currently duplicated in other operators.\n    if (regex_result != Utils::RegexResult::Ok) {\n        if (transaction) {\n            transaction->m_variableMscPcreError.set(\"1\", transaction->m_variableOffset);\n\n            std::string regex_error_str = \"OTHER\";\n            if (regex_result == Utils::RegexResult::ErrorMatchLimit) {\n                regex_error_str = \"MATCH_LIMIT\";\n                transaction->m_variableMscPcreLimitsExceeded.set(\"1\", transaction->m_variableOffset);\n                transaction->m_collections.m_tx_collection->storeOrUpdateFirst(\"MSC_PCRE_LIMITS_EXCEEDED\", \"1\");\n                ms_dbg_a(transaction, 7, \"Set TX.MSC_PCRE_LIMITS_EXCEEDED to 1\");\n            }\n\n            ms_dbg_a(transaction, 1, \"rx: regex error '\" + regex_error_str + \"' for pattern '\" + re->pattern + \"'\");\n        }\n\n        return false;\n    }\n\n    if (rule && rule->hasCaptureAction() && transaction) {\n        for (const Utils::SMatchCapture& capture : captures) {\n            const std::string capture_substring(input.substr(capture.m_offset,capture.m_length));\n            transaction->m_collections.m_tx_collection->storeOrUpdateFirst(\n                std::to_string(capture.m_group), capture_substring);\n            ms_dbg_a(transaction, 7, \"Added regex subexpression TX.\" +\n                std::to_string(capture.m_group) + \": \" + capture_substring);\n            transaction->m_matched.push_back(capture_substring);\n        }\n    }\n\n    for (const auto & capture : captures) {\n        logOffset(ruleMessage, capture.m_offset, capture.m_length);\n    }\n\n    if (m_string->m_containsMacro) {\n        delete re;\n    }\n\n    if (!captures.empty()) {\n        return true;\n    }\n\n    return false;\n}\n\n\n}  // namespace operators\n}  // namespace modsecurity\n"
  },
  {
    "path": "src/operators/rx.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#ifndef SRC_OPERATORS_RX_H_\n#define SRC_OPERATORS_RX_H_\n\n#include <string>\n#include <list>\n#include <memory>\n#include <utility>\n\n#include \"src/operators/operator.h\"\n#include \"src/utils/regex.h\"\n\n\nnamespace modsecurity {\nusing Utils::SMatch;\nusing Utils::regex_search;\nusing Utils::Regex;\n\nnamespace operators {\n\n\nclass Rx : public Operator {\n public:\n    /** @ingroup ModSecurity_Operator */\n    explicit Rx(std::unique_ptr<RunTimeString> param)\n        : m_re(nullptr),\n        Operator(\"Rx\", std::move(param)) {\n            m_couldContainsMacro = true;\n        }\n\n    Rx(const Rx&) = delete;\n    Rx& operator=(const Rx&) = delete;\n\n    ~Rx() override {\n        if (m_string->m_containsMacro == false && m_re != NULL) {\n            delete m_re;\n            m_re = NULL;\n        }\n    }\n\n    bool evaluate(Transaction *transaction, RuleWithActions *rule,\n        const std::string& input,\n        RuleMessage &ruleMessage) override;\n\n    bool init(const std::string &arg, std::string *error) override;\n\n private:\n    Regex *m_re;\n};\n\n\n}  // namespace operators\n}  // namespace modsecurity\n\n\n#endif  // SRC_OPERATORS_RX_H_\n"
  },
  {
    "path": "src/operators/rx_global.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"src/operators/rx_global.h\"\n\n#include <string>\n#include <list>\n#include <memory>\n\n#include \"src/operators/operator.h\"\n#include \"modsecurity/rule.h\"\n#include \"modsecurity/rule_message.h\"\n\nnamespace modsecurity {\nnamespace operators {\n\n\nbool RxGlobal::init(const std::string &arg, std::string *error) {\n    if (m_string->m_containsMacro == false) {\n        m_re = new Regex(m_param);\n    }\n\n    return true;\n}\n\n\nbool RxGlobal::evaluate(Transaction *transaction, RuleWithActions *rule,\n    const std::string& input, RuleMessage &ruleMessage) {\n    Regex *re;\n\n    if (m_param.empty() && !m_string->m_containsMacro) {\n        return true;\n    }\n\n    if (m_string->m_containsMacro) {\n        std::string eparam(m_string->evaluate(transaction));\n        re = new Regex(eparam);\n    } else {\n        re = m_re;\n    }\n\n    Utils::RegexResult regex_result;\n    std::vector<Utils::SMatchCapture> captures;\n    if (transaction && transaction->m_rules->m_pcreMatchLimit.m_set) {\n        unsigned long match_limit = transaction->m_rules->m_pcreMatchLimit.m_value;\n        regex_result = re->searchGlobal(input, captures, match_limit);\n    } else {\n        regex_result = re->searchGlobal(input, captures);\n    }\n\n    // FIXME: DRY regex error reporting. This logic is currently duplicated in other operators.\n    if (regex_result != Utils::RegexResult::Ok) {\n        if (transaction) {\n            transaction->m_variableMscPcreError.set(\"1\", transaction->m_variableOffset);\n\n            std::string regex_error_str = \"OTHER\";\n            if (regex_result == Utils::RegexResult::ErrorMatchLimit) {\n                regex_error_str = \"MATCH_LIMIT\";\n                transaction->m_variableMscPcreLimitsExceeded.set(\"1\", transaction->m_variableOffset);\n                transaction->m_collections.m_tx_collection->storeOrUpdateFirst(\"MSC_PCRE_LIMITS_EXCEEDED\", \"1\");\n                ms_dbg_a(transaction, 7, \"Set TX.MSC_PCRE_LIMITS_EXCEEDED to 1\");\n            }\n\n            ms_dbg_a(transaction, 1, \"rxGlobal: regex error '\" + regex_error_str + \"' for pattern '\" + re->pattern + \"'\");\n        }\n\n        return false;\n    }\n\n\n    if (rule && rule->hasCaptureAction() && transaction) {\n        for (const Utils::SMatchCapture& capture : captures) {\n            const std::string capture_substring(input.substr(capture.m_offset,capture.m_length));\n            transaction->m_collections.m_tx_collection->storeOrUpdateFirst(\n                std::to_string(capture.m_group), capture_substring);\n            ms_dbg_a(transaction, 7, \"Added regex subexpression TX.\" +\n                std::to_string(capture.m_group) + \": \" + capture_substring);\n            transaction->m_matched.push_back(capture_substring);\n        }\n    }\n\n    for (const auto & capture : captures) {\n        logOffset(ruleMessage, capture.m_offset, capture.m_length);\n    }\n\n    if (m_string->m_containsMacro) {\n        delete re;\n    }\n\n    if (captures.size() > 0) {\n        return true;\n    }\n\n    return false;\n}\n\n\n}  // namespace operators\n}  // namespace modsecurity\n"
  },
  {
    "path": "src/operators/rx_global.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#ifndef SRC_OPERATORS_RX_GLOBAL_H_\n#define SRC_OPERATORS_RX_GLOBAL_H_\n\n#include <string>\n//#include <list>\n#include <memory>\n#include <utility>\n\n#include \"src/operators/operator.h\"\n#include \"src/utils/regex.h\"\n\n\nnamespace modsecurity {\nusing Utils::SMatch;\nusing Utils::regex_search;\nusing Utils::Regex;\n\nnamespace operators {\n\n\nclass RxGlobal : public Operator {\n public:\n    /** @ingroup ModSecurity_Operator */\n    explicit RxGlobal(std::unique_ptr<RunTimeString> param)\n        : m_re(nullptr),\n        Operator(\"RxGlobal\", std::move(param)) {\n            m_couldContainsMacro = true;\n        }\n\n    RxGlobal(const RxGlobal&) = delete;\n    RxGlobal& operator=(const RxGlobal&) = delete;\n\n    ~RxGlobal() override {\n        if (m_string->m_containsMacro == false && m_re != NULL) {\n            delete m_re;\n            m_re = NULL;\n        }\n    }\n\n    bool evaluate(Transaction *transaction, RuleWithActions *rule,\n        const std::string& input,\n        RuleMessage &ruleMessage) override;\n\n    bool init(const std::string &arg, std::string *error) override;\n\n private:\n    Regex *m_re;\n};\n\n\n}  // namespace operators\n}  // namespace modsecurity\n\n\n#endif  // SRC_OPERATORS_RX_GLOBAL_H_\n"
  },
  {
    "path": "src/operators/str_eq.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"src/operators/str_eq.h\"\n\n#include <string>\n\nnamespace modsecurity {\nnamespace operators {\n\nbool StrEq::evaluate(Transaction *transaction, const std::string &str) {\n    std::string pt(m_string->evaluate(transaction));\n    return !pt.compare(str);\n}\n\n\n}  // namespace operators\n}  // namespace modsecurity\n"
  },
  {
    "path": "src/operators/str_eq.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <string>\n#include <memory>\n#include <utility>\n\n#include \"modsecurity/transaction.h\"\n#include \"src/operators/operator.h\"\n\n\n#ifndef SRC_OPERATORS_STR_EQ_H_\n#define SRC_OPERATORS_STR_EQ_H_\n\n\nnamespace modsecurity {\nnamespace operators {\n\nclass StrEq : public Operator {\n public:\n    /** @ingroup ModSecurity_Operator */\n    explicit StrEq(std::unique_ptr<RunTimeString> param)\n        : Operator(\"StrEq\", std::move(param)) { }\n\n    bool evaluate(Transaction *transaction, const std::string &str) override;\n};\n\n}  // namespace operators\n}  // namespace modsecurity\n\n\n#endif  // SRC_OPERATORS_STR_EQ_H_\n"
  },
  {
    "path": "src/operators/str_match.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"src/operators/str_match.h\"\n\n#include <string>\n\n#include \"src/operators/operator.h\"\n\n\nnamespace modsecurity {\nnamespace operators {\n\n\nbool StrMatch::evaluate(Transaction *transaction, const std::string &input) {\n    std::string p(m_string->evaluate(transaction));\n    bool ret = input.find(p) != std::string::npos;\n\n    return ret;\n}\n\n\n}  // namespace operators\n}  // namespace modsecurity\n"
  },
  {
    "path": "src/operators/str_match.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#ifndef SRC_OPERATORS_STR_MATCH_H_\n#define SRC_OPERATORS_STR_MATCH_H_\n\n#include <string>\n#include <memory>\n#include <utility>\n\n#include \"src/operators/operator.h\"\n\n\nnamespace modsecurity {\nnamespace operators {\n\nclass StrMatch : public Operator {\n public:\n    /** @ingroup ModSecurity_Operator */\n    explicit StrMatch(std::unique_ptr<RunTimeString> param)\n        : Operator(\"StrMatch\", std::move(param)) {\n            m_couldContainsMacro = true;\n        }\n\n    bool evaluate(Transaction *transaction, const std::string &input) override;\n};\n\n}  // namespace operators\n}  // namespace modsecurity\n\n\n#endif  // SRC_OPERATORS_STR_MATCH_H_\n"
  },
  {
    "path": "src/operators/unconditional_match.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n * \n */\n\n#include \"src/operators/unconditional_match.h\"\n\nnamespace modsecurity {\nnamespace operators {\n\nbool UnconditionalMatch::evaluate(Transaction *transaction,\n    const std::string &input) {\n    return true;\n}\n\n}  // namespace operators\n}  // namespace modsecurity\n"
  },
  {
    "path": "src/operators/unconditional_match.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#ifndef SRC_OPERATORS_UNCONDITIONAL_MATCH_H_\n#define SRC_OPERATORS_UNCONDITIONAL_MATCH_H_\n\n#include <string>\n#include <list>\n\n#include \"modsecurity/transaction.h\"\n#include \"src/operators/operator.h\"\n\nnamespace modsecurity {\nnamespace operators {\n\nclass UnconditionalMatch : public Operator {\n public:\n    /** @ingroup ModSecurity_Operator */\n    UnconditionalMatch()\n        : Operator(\"UnconditionalMatch\") { }\n\n    bool evaluate(Transaction *transaction, const std::string &exp) override;\n};\n\n}  // namespace operators\n}  // namespace modsecurity\n\n\n#endif  // SRC_OPERATORS_UNCONDITIONAL_MATCH_H_\n"
  },
  {
    "path": "src/operators/validate_byte_range.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"src/operators/validate_byte_range.h\"\n\n#include <string>\n#include <memory>\n\n#include \"src/operators/operator.h\"\n\nnamespace modsecurity {\nnamespace operators {\n\nbool ValidateByteRange::getRange(const std::string &rangeRepresentation,\n    std::string *error) {\n    size_t pos = rangeRepresentation.find_first_of(\"-\");\n    int start;\n    int end;\n\n    if (pos == std::string::npos) {\n        try {\n            start = std::stoi(rangeRepresentation);\n        } catch(...) {\n            error->assign(\"Not able to convert '\" + rangeRepresentation +\n                \"' into a number\");\n            return false;\n        }\n        if ((start < 0) || (start > 255)) {\n            error->assign(\"Invalid byte value: \" +\n                std::to_string(start));\n            return false;\n        }\n        table[start >> 3] = (table[start >> 3] | (1 << (start & 0x7)));\n        return true;\n    }\n\n    try {\n        start = std::stoi(std::string(rangeRepresentation, 0, pos));\n    } catch (...) {\n        error->assign(\"Not able to convert '\" +\n            std::string(rangeRepresentation, 0, pos) +\n            \"' into a number\");\n        return false;\n    }\n\n    try {\n        end = std::stoi(std::string(rangeRepresentation, pos + 1,\n            rangeRepresentation.length() - (pos + 1)));\n    } catch (...) {\n        error->assign(\"Not able to convert '\" + std::string(rangeRepresentation,\n            pos + 1, rangeRepresentation.length() - (pos + 1)) +\n            \"' into a number\");\n        return false;\n    }\n\n    if ((start < 0) || (start > 255)) {\n        error->assign(\"Invalid range start value: \" +\n            std::to_string(start));\n        return false;\n    }\n    if ((end < 0) || (end > 255)) {\n       error->assign(\"Invalid range end value: \" + std::to_string(end));\n       return false;\n    }\n    if (start > end) {\n       error->assign(\"Invalid range: \" + std::to_string(start) + \"-\" +\n           std::to_string(end));\n       return false;\n    }\n\n    while (start <= end) {\n        table[start >> 3] = (table[start >> 3] | (1 << (start & 0x7)));\n        start++;\n    }\n\n    return true;\n}\n\n\nbool ValidateByteRange::init(const std::string &file,\n    std::string *error) {\n    size_t pos = m_param.find_first_of(\",\");\n    bool rc;\n\n    if (pos == std::string::npos) {\n        rc = getRange(m_param, error);\n    } else {\n        rc = getRange(std::string(m_param, 0, pos), error);\n    }\n\n    if (rc == false) {\n        return false;\n    }\n\n    while (pos != std::string::npos) {\n        size_t next_pos = m_param.find_first_of(\",\", pos + 1);\n\n        if (next_pos == std::string::npos) {\n            rc = getRange(std::string(m_param, pos + 1, m_param.length() -\n                (pos + 1)), error);\n        } else {\n            rc = getRange(std::string(m_param, pos + 1, next_pos - (pos + 1)), error);\n        }\n        if (rc == false) {\n            return false;\n        }\n        pos = next_pos;\n    }\n\n    return true;\n}\n\n\nbool ValidateByteRange::evaluate(Transaction *transaction, RuleWithActions *rule,\n    const std::string &input, RuleMessage &ruleMessage) {\n    bool ret = true;\n\n    size_t count = 0;\n    for (std::string::size_type i = 0; i < input.length(); i++) {\n        int x = (unsigned char) input[i];\n        if (!(table[x >> 3] & (1 << (x & 0x7)))) {\n            // debug(9, \"Value \" + std::to_string(x) + \" in \" +\n            //     input + \" ouside range: \" + param);\n            logOffset(ruleMessage, i, 1);\n            count++;\n        }\n    }\n\n    ret = (count != 0);\n\n    // debug(9, \"Found %d byte(s) in %s outside range: %s.\",\n    //     count, var->name, rule->op_param);\n\n    return ret;\n}\n\n\n}  // namespace operators\n}  // namespace modsecurity\n"
  },
  {
    "path": "src/operators/validate_byte_range.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#ifndef SRC_OPERATORS_VALIDATE_BYTE_RANGE_H_\n#define SRC_OPERATORS_VALIDATE_BYTE_RANGE_H_\n\n#include <string>\n#include <vector>\n#include <cstring>\n#include <memory>\n#include <utility>\n\n#include \"src/operators/operator.h\"\n\n\nnamespace modsecurity {\nnamespace operators {\n\nclass ValidateByteRange : public Operator {\n public:\n    /** @ingroup ModSecurity_Operator */\n    explicit ValidateByteRange(std::unique_ptr<RunTimeString> param)\n        : Operator(\"ValidateByteRange\", std::move(param)) {\n            std::memset(table, '\\0', sizeof(char) * 32);\n        }\n    ~ValidateByteRange() override { }\n\n    bool evaluate(Transaction *transaction, RuleWithActions *rule,\n        const std::string &input,\n        RuleMessage &ruleMessage) override;\n    bool getRange(const std::string &rangeRepresentation, std::string *error);\n    bool init(const std::string& file, std::string *error) override;\n private:\n    std::vector<std::string> ranges;\n    char table[32];\n};\n\n}  // namespace operators\n}  // namespace modsecurity\n\n\n#endif  // SRC_OPERATORS_VALIDATE_BYTE_RANGE_H_\n"
  },
  {
    "path": "src/operators/validate_dtd.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2023 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"src/operators/validate_dtd.h\"\n\n#include <string>\n\n#include \"src/request_body_processor/xml.h\"\n#include \"src/utils/system.h\"\n#include \"src/operators/operator.h\"\n\nnamespace modsecurity {\nnamespace operators {\n\n#ifdef WITH_LIBXML2\nbool ValidateDTD::init(const std::string &file, std::string *error) {\n    std::string err;\n    m_resource = utils::find_resource(m_param, file, &err);\n    if (m_resource == \"\") {\n        error->assign(\"XML: File not found: \" + m_param + \". \" + err);\n        return false;\n    }\n\n    return true;\n}\n\n\nbool ValidateDTD::evaluate(Transaction *transaction, const std::string &str) {\n\n    XmlDtdPtrManager dtd(xmlParseDTD(NULL, reinterpret_cast<const xmlChar *>(m_resource.c_str())));\n    if (dtd.get() == NULL) {\n        std::string err = std::string(\"XML: Failed to load DTD: \") \\\n            + m_resource;\n        ms_dbg_a(transaction, 4, err);\n        return true;\n    }\n\n    if (transaction->m_xml->m_data.doc == NULL) {\n        ms_dbg_a(transaction, 4, \"XML document tree could not \"\\\n            \"be found for DTD validation.\");\n        return true;\n    }\n\n    if (transaction->m_xml->m_data.well_formed != 1) {\n        ms_dbg_a(transaction, 4, \"XML: DTD validation failed because \" \\\n            \"content is not well formed.\");\n        return true;\n    }\n\n#if 0\n    /* Make sure there were no other generic processing errors */\n    if (msr->msc_reqbody_error) {\n        *error_msg = apr_psprintf(msr->mp,\n                \"XML: DTD validation could not proceed due to previous\"\n                \" processing errors.\");\n        return 1;\n    }\n#endif\n\n    xmlValidCtxtPtr cvp = xmlNewValidCtxt();\n    if (cvp == NULL) {\n        ms_dbg_a(transaction, 4, \"XML: Failed to create a validation context.\");\n        return true;\n    }\n\n    /* Send validator errors/warnings to msr_log */\n    cvp->error = (xmlSchemaValidityErrorFunc)error_runtime;\n    cvp->warning = (xmlSchemaValidityErrorFunc)warn_runtime;\n    cvp->userData = transaction;\n\n    if (!xmlValidateDtd(cvp, transaction->m_xml->m_data.doc, dtd.get())) {\n        ms_dbg_a(transaction, 4, \"XML: DTD validation failed.\");\n        xmlFreeValidCtxt(cvp);\n        return true;\n    }\n\n    ms_dbg_a(transaction, 4, std::string(\"XML: Successfully validated \" \\\n        \"payload against DTD: \") + m_resource);\n\n    xmlFreeValidCtxt(cvp);\n\n    return false;\n}\n#endif\n\n}  // namespace operators\n}  // namespace modsecurity\n"
  },
  {
    "path": "src/operators/validate_dtd.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2023 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#ifndef SRC_OPERATORS_VALIDATE_DTD_H_\n#define SRC_OPERATORS_VALIDATE_DTD_H_\n\n#include <stdio.h>\n#include <stdarg.h>\n#include <string.h>\n#ifdef WITH_LIBXML2\n#include <libxml/xmlschemas.h>\n#include <libxml/xpath.h>\n#endif\n#include <string>\n#include <memory>\n#include <utility>\n\n#include \"src/operators/operator.h\"\n#include \"validate_schema.h\"\n\n\nnamespace modsecurity {\nnamespace operators {\n\n#ifdef WITH_LIBXML2\nclass XmlDtdPtrManager {\n public:\n    /** @ingroup ModSecurity_Operator */\n    explicit XmlDtdPtrManager(xmlDtdPtr dtd)\n        : m_dtd(dtd) { }\n    ~XmlDtdPtrManager() {\n        if (m_dtd != NULL) {\n            xmlFreeDtd(m_dtd);\n            m_dtd = NULL;\n        }\n    }\n    xmlDtdPtr get() const {return m_dtd;}\n private:\n    xmlDtdPtr m_dtd; // The resource being managed\n};\n#endif\n\nclass ValidateDTD : public Operator {\n public:\n    /** @ingroup ModSecurity_Operator */\n    explicit ValidateDTD(std::unique_ptr<RunTimeString> param)\n        : Operator(\"ValidateDTD\", std::move(param)) { }\n#ifdef WITH_LIBXML2\n    bool evaluate(Transaction *transaction, const std::string  &str) override;\n    bool init(const std::string &file, std::string *error) override;\n\n\n    static void error_runtime(void *ctx, const char *msg, ...) {\n        va_list args;\n        va_start(args, msg);\n        ValidateSchema::callback_func(ctx, ValidateSchema::log_msg, ValidateSchema::PREFIX_ERROR, msg, args);\n        va_end(args);\n    }\n\n\n    static void warn_runtime(void *ctx, const char *msg, ...) {\n        va_list args;\n        va_start(args, msg);\n        ValidateSchema::callback_func(ctx, ValidateSchema::log_msg, ValidateSchema::PREFIX_WARNING, msg, args);\n        va_end(args);\n    }\n\n\n private:\n    std::string m_resource;\n#endif\n};\n\n}  // namespace operators\n}  // namespace modsecurity\n\n\n#endif  // SRC_OPERATORS_VALIDATE_DTD_H_\n"
  },
  {
    "path": "src/operators/validate_hash.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"src/operators/validate_hash.h\"\n\n#include <string>\n\n#include \"src/operators/operator.h\"\n\nnamespace modsecurity {\nnamespace operators {\n\nbool ValidateHash::evaluate(Transaction *transaction, const std::string &str) {\n    /**\n     * @todo Implement the operator ValidateHash.\n     *       Reference: https://github.com/SpiderLabs/ModSecurity/wiki/Reference-Manual#validateHash\n     */\n    return true;\n}\n\n\n}  // namespace operators\n}  // namespace modsecurity\n"
  },
  {
    "path": "src/operators/validate_hash.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#ifndef SRC_OPERATORS_VALIDATE_HASH_H_\n#define SRC_OPERATORS_VALIDATE_HASH_H_\n\n#include <string>\n#include <memory>\n#include <utility>\n\n#include \"src/operators/operator.h\"\n\n\nnamespace modsecurity {\nnamespace operators {\n\nclass ValidateHash : public Operator {\n public:\n    /** @ingroup ModSecurity_Operator */\n    explicit ValidateHash(std::unique_ptr<RunTimeString> param)\n        : Operator(\"ValidateHash\", std::move(param)) { }\n    bool evaluate(Transaction *transaction, const std::string  &str) override;\n};\n\n}  // namespace operators\n}  // namespace modsecurity\n\n\n#endif  // SRC_OPERATORS_VALIDATE_HASH_H_\n"
  },
  {
    "path": "src/operators/validate_schema.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2023 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"src/operators/validate_schema.h\"\n\n#include <string>\n\n#include \"src/operators/operator.h\"\n#include \"src/request_body_processor/xml.h\"\n#include \"src/utils/system.h\"\n\n\nnamespace modsecurity {\nnamespace operators {\n\n#ifdef WITH_LIBXML2\n\nbool ValidateSchema::init(const std::string &file, std::string *error) {\n    std::string err;\n    m_resource = utils::find_resource(m_param, file, &err);\n    if (m_resource == \"\") {\n        error->assign(\"XML: File not found: \" + m_param + \". \" + err);\n        return false;\n    }\n\n    return true;\n}\n\n\nbool ValidateSchema::evaluate(Transaction *transaction,\n    const std::string &str) {\n\n    if (transaction->m_xml->m_data.doc == NULL) {\n        ms_dbg_a(transaction, 4, \"XML document tree could not be found for \" \\\n            \"schema validation.\");\n        return true;\n    }\n\n    if (transaction->m_xml->m_data.well_formed != 1) {\n        ms_dbg_a(transaction, 4, \"XML: Schema validation failed because \" \\\n            \"content is not well formed.\");\n        return true;\n    }\n\n    xmlSchemaParserCtxtPtr parserCtx = xmlSchemaNewParserCtxt(m_resource.c_str());\n    if (parserCtx == NULL) {\n        std::stringstream err;\n        err << \"XML: Failed to load Schema from file: \";\n        err << m_resource;\n        err << \". \";\n        if (m_err.empty() == false) {\n            err << m_err;\n        }\n        ms_dbg_a(transaction, 4, err.str());\n        return true;\n    }\n\n    xmlSchemaSetParserErrors(parserCtx,\n        (xmlSchemaValidityErrorFunc)error_load,\n        (xmlSchemaValidityWarningFunc)warn_load, &m_err);\n\n    xmlSchemaPtr schema = xmlSchemaParse(parserCtx);\n    if (schema == NULL) {\n        std::stringstream err;\n        err << \"XML: Failed to load Schema: \";\n        err << m_resource;\n        err << \".\";\n        if (m_err.empty() == false) {\n            err << \" \" << m_err;\n        }\n        ms_dbg_a(transaction, 4, err.str());\n        xmlSchemaFreeParserCtxt(parserCtx);\n        return true;\n    }\n\n    xmlSchemaValidCtxtPtr validCtx = xmlSchemaNewValidCtxt(schema);\n    if (validCtx == NULL) {\n        std::stringstream err(\"XML: Failed to create validation context.\");\n        if (m_err.empty() == false) {\n            err << \" \" << m_err;\n        }\n        ms_dbg_a(transaction, 4, err.str());\n        xmlSchemaFree(schema);\n        xmlSchemaFreeParserCtxt(parserCtx);\n        return true;\n    }\n\n    /* Send validator errors/warnings to msr_log */\n    xmlSchemaSetValidErrors(validCtx,\n        (xmlSchemaValidityErrorFunc)error_runtime,\n        (xmlSchemaValidityWarningFunc)warn_runtime, transaction);\n\n    int rc = xmlSchemaValidateDoc(validCtx, transaction->m_xml->m_data.doc);\n\n    xmlSchemaFreeValidCtxt(validCtx);\n    xmlSchemaFree(schema);\n    xmlSchemaFreeParserCtxt(parserCtx);\n    if (rc != 0) {\n        ms_dbg_a(transaction, 4, \"XML: Schema validation failed.\");\n        return true; /* No match. */\n    } else {\n        ms_dbg_a(transaction, 4, \"XML: Successfully validated payload against \" \\\n            \"Schema: \" + m_resource);\n        return false;\n    }\n}\n\n#endif\n\n}  // namespace operators\n}  // namespace modsecurity\n"
  },
  {
    "path": "src/operators/validate_schema.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2023 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#ifndef SRC_OPERATORS_VALIDATE_SCHEMA_H_\n#define SRC_OPERATORS_VALIDATE_SCHEMA_H_\n\n#include <stdio.h>\n#include <stdarg.h>\n#include <string.h>\n#ifdef WITH_LIBXML2\n#include <libxml/xmlschemas.h>\n#include <libxml/xpath.h>\n#endif\n#include <string>\n#include <memory>\n#include <utility>\n\n#include \"src/operators/operator.h\"\n\n\nnamespace modsecurity {\nnamespace operators {\n\nclass ValidateSchema : public Operator {\n public:\n    /** @ingroup ModSecurity_Operator */\n    explicit ValidateSchema(std::unique_ptr<RunTimeString> param)\n        : Operator(\"ValidateSchema\", std::move(param)) { }\n#ifdef WITH_LIBXML2\n\n    bool evaluate(Transaction *transaction, const std::string  &str) override;\n    bool init(const std::string &file, std::string *error) override;\n\n\n    static void error_load(void *ctx, const char *msg, ...) {\n        va_list args;\n        va_start(args, msg);\n        callback_func(ctx, append_msg, PREFIX_ERROR, msg, args);\n        va_end(args);\n    }\n\n\n    static void warn_load(void *ctx, const char *msg, ...) {\n        va_list args;\n        va_start(args, msg);\n        callback_func(ctx, append_msg, PREFIX_WARNING, msg, args);\n        va_end(args);\n    }\n\n\n    static void error_runtime(void *ctx, const char *msg, ...) {\n        va_list args;\n        va_start(args, msg);\n        callback_func(ctx, log_msg, PREFIX_ERROR, msg, args);\n        va_end(args);\n    }\n\n\n    static void warn_runtime(void *ctx, const char *msg, ...) {\n        va_list args;\n        va_start(args, msg);\n        callback_func(ctx, log_msg, PREFIX_WARNING, msg, args);\n        va_end(args);\n    }\n\n\n    template<typename Pred>\n    static void callback_func(void *ctx, Pred pred, const char *base_msg, const char *msg, va_list args) {\n        char buf[1024];\n        const auto len = vsnprintf(buf, sizeof(buf), msg, args);\n\n        if (len > 0)\n            pred(ctx, base_msg + std::string(buf));\n    }\n\n    static void log_msg(const void *ctx, const std::string &msg) {\n        auto t = reinterpret_cast<const Transaction *>(ctx);\n        ms_dbg_a(t, 4, msg);\n    }\n\n    static void append_msg(void *ctx, const std::string &msg) {\n        auto s = reinterpret_cast<std::string*>(ctx);\n        s->append(msg);\n    }\n\n    static constexpr auto PREFIX_WARNING = \"XML Warning: \";\n    static constexpr auto PREFIX_ERROR = \"XML Error: \";\n\n private:\n    std::string m_resource;\n    std::string m_err;\n#endif\n};\n\n}  // namespace operators\n}  // namespace modsecurity\n\n\n#endif  // SRC_OPERATORS_VALIDATE_SCHEMA_H_\n"
  },
  {
    "path": "src/operators/validate_url_encoding.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"src/operators/validate_url_encoding.h\"\n\n#include <string>\n\n#include \"src/operators/operator.h\"\n\nnamespace modsecurity {\nnamespace operators {\n\n\nint ValidateUrlEncoding::validate_url_encoding(const char *input,\n    uint64_t input_length, size_t *offset) {\n    int i;\n    *offset = 0;\n\n    if ((input == NULL) || (input_length == 0)) {\n        return -1;\n    }\n\n    i = 0;\n    while (i < input_length) {\n        if (input[i] == '%') {\n            if (i + 2 >= input_length) {\n                *offset = i;\n                /* Not enough bytes. */\n                return -3;\n            } else {\n                /* Here we only decode a %xx combination if it is valid,\n                 * leaving it as is otherwise.\n                 */\n                char c1 = input[i + 1];\n                char c2 = input[i + 2];\n\n                if ( (((c1 >= '0') && (c1 <= '9'))\n                    || ((c1 >= 'a') && (c1 <= 'f'))\n                    || ((c1 >= 'A') && (c1 <= 'F')))\n                    && (((c2 >= '0') && (c2 <= '9'))\n                    || ((c2 >= 'a') && (c2 <= 'f'))\n                    || ((c2 >= 'A') && (c2 <= 'F'))) ) {\n                    i += 3;\n                } else {\n                    /* Non-hexadecimal characters used in encoding. */\n                    *offset = i;\n                    return -2;\n                }\n            }\n        } else {\n            i++;\n        }\n    }\n\n    return 1;\n}\n\n\nbool ValidateUrlEncoding::evaluate(Transaction *transaction, RuleWithActions *rule,\n    const std::string &input, RuleMessage &ruleMessage) {\n    size_t offset = 0;\n    bool res = false;\n\n    if (input.empty() == true) {\n        return res;\n    }\n\n    int rc = validate_url_encoding(input.c_str(), input.size(), &offset);\n    switch (rc) {\n        case 1 :\n            /* Encoding is valid */\n            if (transaction) {\n                ms_dbg_a(transaction, 7, \"Valid URL Encoding at '\" +input + \"'\");\n            }\n            res = false;\n            break;\n        case -2 :\n            if (transaction) {\n                ms_dbg_a(transaction, 7, \"Invalid URL Encoding: Non-hexadecimal \"\n                    \"digits used at '\" + input + \"'\");\n                logOffset(ruleMessage, offset, input.size());\n            }\n            res = true; /* Invalid match. */\n            break;\n        case -3 :\n            if (transaction) {\n                ms_dbg_a(transaction, 7, \"Invalid URL Encoding: Not enough \" \\\n                \"characters at the end of input at '\" + input + \"'\");\n                logOffset(ruleMessage, offset, input.size());\n            }\n            res = true; /* Invalid match. */\n            break;\n        case -1 :\n        default :\n            if (transaction) {\n                ms_dbg_a(transaction, 7, \"Invalid URL Encoding: Internal \" \\\n                    \"Error (rc = \" + std::to_string(rc) + \") at '\" +\n                    input + \"'\");\n                logOffset(ruleMessage, offset, input.size());\n            }\n            res = true;\n            break;\n    }\n\n    return res;\n}\n\n\n}  // namespace operators\n}  // namespace modsecurity\n"
  },
  {
    "path": "src/operators/validate_url_encoding.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#ifndef SRC_OPERATORS_VALIDATE_URL_ENCODING_H_\n#define SRC_OPERATORS_VALIDATE_URL_ENCODING_H_\n\n#include <string>\n#include <memory>\n\n#include \"src/operators/operator.h\"\n\n\nnamespace modsecurity {\nnamespace operators {\n\nclass ValidateUrlEncoding : public Operator {\n public:\n    /** @ingroup ModSecurity_Operator */\n    ValidateUrlEncoding()\n        : Operator(\"ValidateUrlEncoding\") { }\n\n    bool evaluate(Transaction *transaction, RuleWithActions *rule,\n        const std::string &input,\n        RuleMessage &ruleMessage) override;\n\n    static int validate_url_encoding(const char *input, uint64_t input_length,\n        size_t *offset);\n};\n\n}  // namespace operators\n}  // namespace modsecurity\n\n\n#endif  // SRC_OPERATORS_VALIDATE_URL_ENCODING_H_\n"
  },
  {
    "path": "src/operators/validate_utf8_encoding.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"src/operators/validate_utf8_encoding.h\"\n\n#include <string>\n\n#include \"src/operators/operator.h\"\n\n\nconstexpr int UNICODE_ERROR_CHARACTERS_MISSING   = -1;\nconstexpr int UNICODE_ERROR_INVALID_ENCODING     = -2;\nconstexpr int UNICODE_ERROR_OVERLONG_CHARACTER   = -3;\nconstexpr int UNICODE_ERROR_RESTRICTED_CHARACTER = -4;\nconstexpr int UNICODE_ERROR_DECODING_ERROR       = -5;\n\n\nnamespace modsecurity {\nnamespace operators {\n\nint ValidateUtf8Encoding::detect_utf8_character(\n    const unsigned char *p_read, unsigned int length) {\n    int unicode_len = 0;\n    unsigned int d = 0;\n    unsigned char c;\n\n    if (p_read == NULL) {\n        return UNICODE_ERROR_DECODING_ERROR;\n    }\n    c = *p_read;\n\n    /* If first byte begins with binary 0 it is single byte encoding */\n    if ((c & 0x80) == 0) {\n        /* single byte unicode (7 bit ASCII equivilent) has no validation */\n        return 1;\n    } else if ((c & 0xE0) == 0xC0) {\n        /* If first byte begins with binary 110 it is two byte encoding*/\n        /* check we have at least two bytes */\n        if (length < 2) {\n            unicode_len = UNICODE_ERROR_CHARACTERS_MISSING;\n        } else if (((*(p_read + 1)) & 0xC0) != 0x80) {\n            /* check second byte starts with binary 10 */\n            unicode_len = UNICODE_ERROR_INVALID_ENCODING;\n        } else {\n            unicode_len = 2;\n            /* compute character number */\n            d = ((c & 0x1F) << 6) | (*(p_read + 1) & 0x3F);\n        }\n    } else if ((c & 0xF0) == 0xE0) {\n        /* If first byte begins with binary 1110 it is three byte encoding */\n        /* check we have at least three bytes */\n        if (length < 3) {\n            unicode_len = UNICODE_ERROR_CHARACTERS_MISSING;\n        } else if (((*(p_read + 1)) & 0xC0) != 0x80) {\n            /* check second byte starts with binary 10 */\n            unicode_len = UNICODE_ERROR_INVALID_ENCODING;\n        } else if (((*(p_read + 2)) & 0xC0) != 0x80) {\n            /* check third byte starts with binary 10 */\n            unicode_len = UNICODE_ERROR_INVALID_ENCODING;\n        } else {\n            unicode_len = 3;\n            /* compute character number */\n            d = ((c & 0x0F) << 12) | ((*(p_read + 1) & 0x3F) << 6)\n                | (*(p_read + 2) & 0x3F);\n        }\n    } else if ((c & 0xF8) == 0xF0) {\n        /* If first byte begins with binary 11110 it is four byte encoding */\n        /* restrict characters to UTF-8 range (U+0000 - U+10FFFF)*/\n        if (c >= 0xF5) {\n            return UNICODE_ERROR_RESTRICTED_CHARACTER;\n        }\n        /* check we have at least four bytes */\n        if (length < 4) {\n            unicode_len = UNICODE_ERROR_CHARACTERS_MISSING;\n        } else if (((*(p_read + 1)) & 0xC0) != 0x80) {\n            unicode_len = UNICODE_ERROR_INVALID_ENCODING;\n        } else if (((*(p_read + 2)) & 0xC0) != 0x80) {\n            unicode_len = UNICODE_ERROR_INVALID_ENCODING;\n        } else if (((*(p_read + 3)) & 0xC0) != 0x80) {\n            unicode_len = UNICODE_ERROR_INVALID_ENCODING;\n        } else {\n            unicode_len = 4;\n            /* compute character number */\n            d = ((c & 0x07) << 18) | ((*(p_read + 1) & 0x3F) << 12)\n                | ((*(p_read + 2) & 0x3F) << 6) | (*(p_read + 3) & 0x3F);\n        }\n    } else {\n        /* any other first byte is invalid (RFC 3629) */\n        return UNICODE_ERROR_INVALID_ENCODING;\n    }\n\n    /* invalid UTF-8 character number range (RFC 3629) */\n    if ((d >= 0xD800) && (d <= 0xDFFF)) {\n        return UNICODE_ERROR_RESTRICTED_CHARACTER;\n    }\n\n    /* check for overlong */\n    if ((unicode_len == 4) && (d < 0x010000)) {\n        /* four byte could be represented with less bytes */\n        return UNICODE_ERROR_OVERLONG_CHARACTER;\n    } else if ((unicode_len == 3) && (d < 0x0800)) {\n        /* three byte could be represented with less bytes */\n        return UNICODE_ERROR_OVERLONG_CHARACTER;\n    } else if ((unicode_len == 2) && (d < 0x80)) {\n        /* two byte could be represented with less bytes */\n        return UNICODE_ERROR_OVERLONG_CHARACTER;\n    }\n\n    return unicode_len;\n}\n\nbool ValidateUtf8Encoding::evaluate(Transaction *transaction, RuleWithActions *rule,\n    const std::string &str, RuleMessage &ruleMessage) {\n    unsigned int i, bytes_left;\n\n    const char *str_c = str.c_str();\n    bytes_left = str.size();\n\n    for (i = 0; i < str.size();) {\n        int rc = detect_utf8_character((unsigned char *)&str_c[i], bytes_left);\n\n        switch (rc) {\n            case UNICODE_ERROR_CHARACTERS_MISSING :\n                if (transaction) {\n                    ms_dbg_a(transaction, 8, \"Invalid UTF-8 encoding: \"\n                        \"not enough bytes in character \"\n                        \"at \" + str + \". [offset \\\"\" +\n                        std::to_string(i) + \"\\\"]\");\n                }\n                return true;\n            case UNICODE_ERROR_INVALID_ENCODING :\n                if (transaction) {\n                    ms_dbg_a(transaction, 8, \"Invalid UTF-8 encoding: \"\n                        \"invalid byte value in character \"\n                        \"at \" + str + \". [offset \\\"\" +\n                        std::to_string(i) + \"\\\"]\");\n                    logOffset(ruleMessage, i, str.size());\n                }\n                return true;\n            case UNICODE_ERROR_OVERLONG_CHARACTER :\n                if (transaction) {\n                    ms_dbg_a(transaction, 8, \"Invalid UTF-8 encoding: \"\n                        \"overlong character detected \"\n                        \"at \" + str + \". [offset \\\"\" +\n                        std::to_string(i) + \"\\\"]\");\n                    logOffset(ruleMessage, i, str.size());\n                }\n                return true;\n            case UNICODE_ERROR_RESTRICTED_CHARACTER :\n                if (transaction) {\n                    ms_dbg_a(transaction, 8, \"Invalid UTF-8 encoding: \"\n                        \"use of restricted character \"\n                        \"at \" + str + \". [offset \\\"\" +\n                        std::to_string(i) + \"\\\"]\");\n                    logOffset(ruleMessage, i, str.size());\n                }\n                return true;\n            case UNICODE_ERROR_DECODING_ERROR :\n                if (transaction) {\n                    ms_dbg_a(transaction, 8, \"Error validating UTF-8 decoding \"\n                        \"at \" + str + \". [offset \\\"\" +\n                        std::to_string(i) + \"\\\"]\");\n                    logOffset(ruleMessage, i, str.size());\n                }\n                return true;\n        }\n\n        if (rc <= 0) {\n            if (transaction) {\n                ms_dbg_a(transaction, 8, \"Internal error during UTF-8 validation \"\n                    \"at \" + str + \". [offset \\\"\" +\n                    std::to_string(i) + \"\\\"]\");\n                logOffset(ruleMessage, i, str.size());\n            }\n            return true;\n        }\n\n        i += rc;\n        bytes_left -= rc;\n    }\n\n    return false;\n}\n\n\n}  // namespace operators\n}  // namespace modsecurity\n"
  },
  {
    "path": "src/operators/validate_utf8_encoding.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#ifndef SRC_OPERATORS_VALIDATE_UTF8_ENCODING_H_\n#define SRC_OPERATORS_VALIDATE_UTF8_ENCODING_H_\n\n#include <string>\n#include <memory>\n\n#include \"src/operators/operator.h\"\n\n\nnamespace modsecurity {\nnamespace operators {\n\nclass ValidateUtf8Encoding : public Operator {\n public:\n    /** @ingroup ModSecurity_Operator */\n    ValidateUtf8Encoding()\n        : Operator(\"ValidateUtf8Encoding\") { }\n\n    bool evaluate(Transaction *transaction, RuleWithActions *rule,\n        const std::string &str,\n        RuleMessage &ruleMessage) override;\n\n    static int detect_utf8_character(const unsigned char *p_read,\n        unsigned int length);\n};\n\n}  // namespace operators\n}  // namespace modsecurity\n\n\n\n#endif  // SRC_OPERATORS_VALIDATE_UTF8_ENCODING_H_\n"
  },
  {
    "path": "src/operators/verify_cc.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"src/operators/verify_cc.h\"\n\n#include <iostream>\n#include <cstring>\n#include <vector>\n\n#include \"src/operators/operator.h\"\n\n#ifdef WITH_PCRE\n#if PCRE_HAVE_JIT\n#define pcre_study_opt PCRE_STUDY_JIT_COMPILE\n#else\nconstexpr int pcre_study_opt = 0;\n#endif\n#endif\n\n\nnamespace modsecurity {\nnamespace operators {\n\nVerifyCC::~VerifyCC() {\n#ifndef WITH_PCRE\n    pcre2_code_free(m_pc);\n#else\n    if (m_pc != nullptr) {\n        pcre_free(m_pc);\n        m_pc = nullptr;\n    }\n    if (m_pce != nullptr) {\n#if PCRE_HAVE_JIT\n        pcre_free_study(m_pce);\n#else\n        pcre_free(m_pce);\n#endif\n        m_pce = nullptr;\n    }\n#endif\n}\n\n/**\n * Luhn Mod-10 Method (ISO 2894/ANSI 4.13)\n */\nint VerifyCC::luhnVerify(const char *ccnumber, int len) {\n    int sum[2] = { 0, 0 };\n    int odd = 0;\n    int digits = 0;\n\n    /* Weighted lookup table which is just a precalculated (i = index):\n     *   i*2 + (( (i*2) > 9 ) ? -9 : 0)\n     */\n    /* weight lookup table */\n    static const int wtable[10] = {0, 2, 4, 6, 8, 1, 3, 5, 7, 9};\n\n\n    /* Add up only digits (weighted digits via lookup table)\n     * for both odd and even CC numbers to avoid 2 passes.\n     */\n    for (int i = 0;i < len;i++) {\n        if (ccnumber[i] >= (0 + 48) && ccnumber[i] <= (9 + 48)) {\n            sum[0] += (!odd ? wtable[ccnumber[i] - '0'] : (ccnumber[i] - '0'));\n            sum[1] += (odd ? wtable[ccnumber[i] - '0'] : (ccnumber[i] - '0'));\n            odd = 1 - odd; /* alternate weights */\n            digits++;\n        }\n    }\n\n    /* No digits extracted */\n    if (digits == 0) {\n        return 0;\n    }\n\n    /* Do a mod 10 on the sum */\n    sum[odd] %= 10;\n\n    /* If the result is a zero the card is valid. */\n    return sum[odd] ? 0 : 1;\n}\n\n\n\nbool VerifyCC::init(const std::string &param2, std::string *error) {\n#ifndef WITH_PCRE\n    PCRE2_SPTR pcre2_pattern = reinterpret_cast<PCRE2_SPTR>(m_param.c_str());\n    uint32_t pcre2_options = (PCRE2_DOTALL|PCRE2_MULTILINE);\n    int errornumber = 0;\n    PCRE2_SIZE erroroffset = 0;\n    m_pc = pcre2_compile(pcre2_pattern, PCRE2_ZERO_TERMINATED,\n        pcre2_options, &errornumber, &erroroffset, nullptr);\n    if (m_pc == nullptr) {\n        return false;\n    }\n    m_pcje = pcre2_jit_compile(m_pc, PCRE2_JIT_COMPLETE);\n#else\n    const char *errptr = nullptr;\n    int erroffset = 0;\n\n    m_pc = pcre_compile(m_param.c_str(), PCRE_DOTALL|PCRE_MULTILINE,\n        &errptr, &erroffset, nullptr);\n    if (m_pc == nullptr) {\n        error->assign(errptr);\n        return false;\n    }\n\n    m_pce = pcre_study(m_pc, pcre_study_opt, &errptr);\n    if (m_pce == nullptr) {\n        if (errptr == nullptr) {\n            /*\n             * Per pcre_study(3) m_pce == nullptr && errptr == nullptr means\n             * that no addional information is found, so no need to study\n             */\n            return true;\n        }\n        error->assign(errptr);\n        return false;\n    }\n#endif\n\n    return true;\n}\n\n\nbool VerifyCC::evaluate(Transaction *t, RuleWithActions *rule,\n    const std::string& i, RuleMessage &ruleMessage) {\n#ifndef WITH_PCRE\n    PCRE2_SIZE offset = 0;\n    size_t target_length = i.length();\n    PCRE2_SPTR pcre2_i = reinterpret_cast<PCRE2_SPTR>(i.c_str());\n    pcre2_match_data *match_data = pcre2_match_data_create_from_pattern(m_pc, nullptr);\n\n    int ret;\n    for (offset = 0; offset < target_length; offset++) {\n\n        if (m_pcje == 0) {\n            ret = pcre2_jit_match(m_pc, pcre2_i, target_length, offset, 0, match_data, nullptr);\n        }\n        \n        if (m_pcje != 0 || ret == PCRE2_ERROR_JIT_STACKLIMIT) {\n            ret = pcre2_match(m_pc, pcre2_i, target_length, offset, PCRE2_NO_JIT, match_data, nullptr);\n        }\n\n        /* If there was no match, then we are done. */\n        if (ret < 0) {\n            break;\n        }\n\tPCRE2_SIZE *ovector = pcre2_get_ovector_pointer(match_data);\n\n#else\n    int offset = 0;\n    int target_length = i.length();\n\n    for (offset = 0; offset < target_length; offset++) {\n        int ovector[33];\n        memset(ovector, 0, sizeof(ovector));\n        int ret = pcre_exec(m_pc, m_pce, i.c_str(), i.size(), offset,\n            0, ovector, 33) > 0;\n\n        /* If there was no match, then we are done. */\n        if (ret == PCRE_ERROR_NOMATCH) {\n            break;\n        }\n        if (ret < 0) {\n            return false;\n        }\n#endif\n        if (ret > 0) {\n            std::string match = std::string(i, ovector[0], ovector[1] - ovector[0]);\n            int is_cc = luhnVerify(match.c_str(), match.size());\n            if (is_cc) {\n                if (t) {\n                    if (rule && rule->hasCaptureAction()) {\n                        t->m_collections.m_tx_collection->storeOrUpdateFirst(\n                            \"0\", std::string(match));\n                        ms_dbg_a(t, 7, \"Added VerifyCC match TX.0: \" + \\\n                            std::string(match));\n                    }\n                    ms_dbg_a(t, 9, \"CC# match \\\"\" + m_param +\n                        \"\\\" at \" + i + \". [offset \" +\n                        std::to_string(offset) + \"]\");\n                }\n#ifndef WITH_PCRE\n                pcre2_match_data_free(match_data);\n#endif\n                return true;\n            }\n        }\n    }\n\n#ifndef WITH_PCRE\n    pcre2_match_data_free(match_data);\n#endif\n\n    return false;\n}\n\n\n}  // namespace operators\n}  // namespace modsecurity\n\n"
  },
  {
    "path": "src/operators/verify_cc.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#ifndef SRC_OPERATORS_VERIFY_CC_H_\n#define SRC_OPERATORS_VERIFY_CC_H_\n\n#ifndef WITH_PCRE\n#define PCRE2_CODE_UNIT_WIDTH 8\n#include <pcre2.h>\n#else\n#include <pcre.h>\n#endif\n\n\n#include <string>\n#include <memory>\n#include <utility>\n\n#include \"src/operators/operator.h\"\n\nnamespace modsecurity {\nnamespace operators {\n\nclass VerifyCC : public Operator {\n public:\n    /** @ingroup ModSecurity_Operator */\n    explicit VerifyCC(std::unique_ptr<RunTimeString> param)\n        : Operator(\"VerifyCC\", std::move(param)),\n#ifndef WITH_PCRE\n        m_pc(nullptr),\n        m_pcje(PCRE2_ERROR_JIT_BADOPTION) { }\n#else\n        m_pc(nullptr),\n        m_pce(nullptr) { }\n#endif\n    ~VerifyCC() override;\n\n    bool evaluate(Transaction *t, RuleWithActions *rule,\n        const std::string& input,\n        RuleMessage &ruleMessage)  override;\n    bool init(const std::string &param, std::string *error) override;\n private:\n#ifndef WITH_PCRE\n    pcre2_code *m_pc;\n    int m_pcje;\n#else\n    pcre *m_pc;\n    pcre_extra *m_pce;\n#endif\n    static int luhnVerify(const char *ccnumber, int len);\n};\n\n}  // namespace operators\n}  // namespace modsecurity\n\n\n#endif  // SRC_OPERATORS_VERIFY_CC_H_\n"
  },
  {
    "path": "src/operators/verify_cpf.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"src/operators/verify_cpf.h\"\n\n#include <string>\n#include <list>\n\n#include \"src/operators/operator.h\"\n\nnamespace modsecurity {\nnamespace operators {\n\nint VerifyCPF::convert_to_int(const char c) {\n    int n;\n    if ((c >= '0') && (c <= '9')) {\n        n = c - '0';\n    } else if ((c >= 'A') && (c <= 'F')) {\n        n = c - 'A' + 10;\n    } else if ((c >= 'a') && (c <= 'f')) {\n        n = c - 'a' + 10;\n    } else {\n        n = 0;\n    }\n    return n;\n}\n\n\nbool VerifyCPF::verify(const char *cpfnumber, int len) const {\n    int factor, part_1, part_2, var_len = len;\n    unsigned int sum = 0, i = 0, cpf_len = 11, c;\n    int cpf[11];\n    char s_cpf[11];\n\n    while ((*cpfnumber != '\\0') && (var_len > 0)) {\n        // Always true.\n        //if (*cpfnumber != '-' || *cpfnumber != '.') {\n            if (i < cpf_len && isdigit(*cpfnumber)) {\n                s_cpf[i] = *cpfnumber;\n                cpf[i] = convert_to_int(*cpfnumber);\n                i++;\n            }\n        //}\n        cpfnumber++;\n        var_len--;\n    }\n\n\n    if (i != cpf_len) {\n        return 0;\n    } else {\n        for (i = 0; i< cpf_len; i++) {\n            if (strncmp(s_cpf, bad_cpf[i], cpf_len) == 0) {\n                return 0;\n            }\n        }\n    }\n\n    part_1 = convert_to_int(s_cpf[cpf_len-2]);\n    part_2 = convert_to_int(s_cpf[cpf_len-1]);\n\n    c = cpf_len;\n\n    for (i = 0; i < 9; i++) {\n        sum += (cpf[i] * --c);\n    }\n\n    factor = (sum % cpf_len);\n\n    if (factor < 2) {\n        cpf[9] = 0;\n    } else {\n        cpf[9] = cpf_len-factor;\n    }\n\n    sum = 0;\n    c = cpf_len;\n\n    for (i = 0; i < 10; i++) {\n        sum += (cpf[i] * c--);\n    }\n\n    factor = (sum % cpf_len);\n\n    if (factor < 2) {\n        cpf[10] = 0;\n    } else {\n        cpf[10] = cpf_len-factor;\n    }\n\n    if (part_1 == cpf[9] && part_2 == cpf[10]) {\n        return true;\n    }\n\n    return false;\n}\n\n\nbool VerifyCPF::evaluate(Transaction *t, RuleWithActions *rule,\n    const std::string& input, RuleMessage &ruleMessage) {\n    std::list<SMatch> matches;\n    bool is_cpf = false;\n    int i;\n\n    if (m_param.empty()) {\n        return false;\n    }\n\n    for (i = 0; i < input.size() - 1 && is_cpf == false; i++) {\n        matches = m_re->searchAll(input.substr(i, input.size()));\n        for (const auto & m : matches) {\n            is_cpf = verify(m.str().c_str(), m.str().size());\n            if (is_cpf) {\n                logOffset(ruleMessage, m.offset(), m.str().size());\n                if (rule && t && rule->hasCaptureAction()) {\n                    t->m_collections.m_tx_collection->storeOrUpdateFirst(\n                        \"0\", m.str());\n                    ms_dbg_a(t, 7, \"Added VerifyCPF match TX.0: \" + \\\n                        m.str());\n                }\n\n                goto out;\n            }\n        }\n    }\n\nout:\n    return is_cpf;\n}\n\n\n}  // namespace operators\n}  // namespace modsecurity\n"
  },
  {
    "path": "src/operators/verify_cpf.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#ifndef SRC_OPERATORS_VERIFY_CPF_H_\n#define SRC_OPERATORS_VERIFY_CPF_H_\n\n#include <string>\n#include <memory>\n#include <utility>\n\n#include \"src/operators/operator.h\"\n#include \"src/utils/regex.h\"\n\n\nnamespace modsecurity {\nusing Utils::SMatch;\nusing Utils::regex_search;\nusing Utils::Regex;\n\nnamespace operators {\n\nclass VerifyCPF : public Operator {\n public:\n    /** @ingroup ModSecurity_Operator */\n    explicit VerifyCPF(std::unique_ptr<RunTimeString> param)\n        : Operator(\"VerifyCPF\", std::move(param))\n        , m_re(std::make_unique<Regex>(m_param)) { }\n\n    bool operator=(const VerifyCPF &a) = delete;\n    VerifyCPF(const VerifyCPF &a) = delete;\n\n    bool evaluate(Transaction *transaction, RuleWithActions *rule,\n        const std::string& input,\n        RuleMessage &ruleMessage) override;\n\n    bool verify(const char *ssnumber, int len) const;\n\n private:\n    static int convert_to_int(const char c);\n    std::unique_ptr<Regex> m_re;\n    const char bad_cpf[12][12] = { \"00000000000\",\n        \"01234567890\",\n        \"11111111111\",\n        \"22222222222\",\n        \"33333333333\",\n        \"44444444444\",\n        \"55555555555\",\n        \"66666666666\",\n        \"77777777777\",\n        \"88888888888\",\n        \"99999999999\"};\n};\n\n}  // namespace operators\n}  // namespace modsecurity\n\n\n#endif  // SRC_OPERATORS_VERIFY_CPF_H_\n"
  },
  {
    "path": "src/operators/verify_ssn.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"src/operators/verify_ssn.h\"\n\n#include <string>\n#include <memory>\n#include <list>\n\n#include \"src/operators/operator.h\"\n\nnamespace modsecurity {\nnamespace operators {\n\n\nint VerifySSN::convert_to_int(const char c) {\n    int n;\n    if ((c >= '0') && (c <= '9')) {\n        n = c - '0';\n    } else if ((c >= 'A') && (c <= 'F')) {\n        n = c - 'A' + 10;\n    } else if ((c >= 'a') && (c <= 'f')) {\n        n = c - 'a' + 10;\n    } else {\n        n = 0;\n    }\n    return n;\n}\n\n\nbool VerifySSN::verify(const char *ssnumber, int len) {\n    int i;\n    int num[9];\n    int digits = 0;\n    int area, serial, grp;\n    int sequencial = 0;\n    int repetitions = 0;\n    std::string str_area;\n    std::string str_grp;\n    std::string str_serial;\n\n    for (i = 0; i < len; i++) {\n        if (isdigit(ssnumber[i])) {\n            if (digits < 9)\n                num[digits] = convert_to_int(ssnumber[i]);\n            digits++;\n        }\n    }\n\n    /* Not a valid number */\n    if (digits != 9)\n        goto invalid;\n\n    for (i=0; i < 8; i++)   {\n        if (num[i] == (num[i+1]-1))\n            sequencial++;\n\n        if (num[i] == num[i+1])\n            repetitions++;\n    }\n\n    /* We are blocking when all numbers were sequencial or repeated */\n    if (sequencial == 8)\n        goto invalid;\n\n    if (repetitions == 8)\n        goto invalid;\n\n    str_area.append(std::to_string(num[0]) + std::to_string(num[1]) +\n        std::to_string(num[2]));\n\n    str_grp.append(std::to_string(num[3]) + std::to_string(num[4]));\n\n    str_serial.append(std::to_string(num[5]) + std::to_string(num[6])\n        + std::to_string(num[7]) + std::to_string(num[8]));\n\n    if (str_area.size() == 0 || str_grp.size() == 0\n        || str_serial.size() == 0) {\n        goto invalid;\n    }\n\n    area = atoi(str_area.c_str());\n    grp = atoi(str_grp.c_str());\n    serial = atoi(str_serial.c_str());\n\n    /* Cannot has seroed fields */\n    if (area == 0 || serial == 0 || grp == 0)\n        goto invalid;\n\n    /* More tests */\n    if (area >= 740 || area == 666)\n        goto invalid;\n\n    return true;\n\ninvalid:\n    return false;\n}\n\n\nbool VerifySSN::evaluate(Transaction *t, RuleWithActions *rule,\n    const std::string& input, RuleMessage &ruleMessage) {\n    std::list<SMatch> matches;\n    bool is_ssn = false;\n    int i;\n\n    if (m_param.empty()) {\n        return false;\n    }\n\n    for (i = 0; i < input.size() - 1 && is_ssn == false; i++) {\n        matches = m_re->searchAll(input.substr(i, input.size()));\n        for (const auto & j : matches) {\n            is_ssn = verify(j.str().c_str(), j.str().size());\n            if (is_ssn) {\n                logOffset(ruleMessage, j.offset(), j.str().size());\n                if (rule && t && rule->hasCaptureAction()) {\n                    t->m_collections.m_tx_collection->storeOrUpdateFirst(\n                        \"0\", j.str());\n                    ms_dbg_a(t, 7, \"Added VerifySSN match TX.0: \" + \\\n                        j.str());\n                }\n\n                goto out;\n            }\n        }\n    }\n\nout:\n    return is_ssn;\n}\n\n\n}  // namespace operators\n}  // namespace modsecurity\n"
  },
  {
    "path": "src/operators/verify_ssn.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#ifndef SRC_OPERATORS_VERIFY_SSN_H_\n#define SRC_OPERATORS_VERIFY_SSN_H_\n\n#include <string>\n#include <memory>\n#include <utility>\n\n#include \"src/operators/operator.h\"\n#include \"src/utils/regex.h\"\n\n\nnamespace modsecurity {\nusing Utils::SMatch;\nusing Utils::regex_search;\nusing Utils::Regex;\n\nnamespace operators {\n\nclass VerifySSN : public Operator {\n public:\n    /** @ingroup ModSecurity_Operator */\n    explicit VerifySSN(std::unique_ptr<RunTimeString> param)\n        : Operator(\"VerifySSN\", std::move(param))\n        , m_re(std::make_unique<Regex>(m_param)) { }\n\n    bool operator=(const VerifySSN &a) = delete;\n    VerifySSN(const VerifySSN &a) = delete;\n\n    bool evaluate(Transaction *transaction, RuleWithActions *rule,\n        const std::string& input,\n        RuleMessage &ruleMessage) override;\n\n\n\n private:\n    static bool verify(const char *ssnumber, int len);\n    static int convert_to_int(const char c);\n\n    std::unique_ptr<Regex> m_re;\n};\n\n}  // namespace operators\n}  // namespace modsecurity\n\n\n#endif  // SRC_OPERATORS_VERIFY_SSN_H_\n"
  },
  {
    "path": "src/operators/verify_svnr.cc",
    "content": "\n#include \"src/operators/verify_svnr.h\"\n\n#include <string>\n\n#include \"src/operators/operator.h\"\n\n#include \"modsecurity/rule.h\"\n#include \"modsecurity/rule_message.h\"\n#include \"modsecurity/rules_set_properties.h\"\n\n\nnamespace modsecurity {\nnamespace operators {\n\n\nint VerifySVNR::convert_to_int(const char c) {\n    int n;\n    if ((c>='0') && (c<='9'))\n        n = c - '0';\n    else\n        n = 0;\n    return n;\n}\n\n\nbool VerifySVNR::verify(const char *svnrnumber, int len) const {\n    int var_len = len;\n    int sum = 0;\n    unsigned int i = 0, svnr_len = 10;\n    int svnr[11];\n    char s_svnr[11];\n\n    while ((*svnrnumber != '\\0') && ( var_len > 0))\n    {\n        // Always true on the original code.\n        //if (*svnrnumber != '-' || *svnrnumber != '.')\n        {\n            if (i < svnr_len && isdigit(*svnrnumber))\n            {\n                s_svnr[i] = *svnrnumber;\n                svnr[i] = convert_to_int(*svnrnumber);\n                i++;\n            }\n        }\n        svnrnumber++;\n        var_len--;\n    }\n\n\n    if (i != svnr_len)\n    {\n        return 0;\n    }\n    else\n    {\n        for (i = 0; i< svnr_len; i++)\n        {\n            if (strncmp(s_svnr,bad_svnr[i],svnr_len) == 0)\n            {\n                return 0;\n            }\n        }\n    }\n    //Laufnummer mit 3, 7, 9\n    //Geburtsdatum mit 5, 8, 4, 2, 1, 6\n    sum = svnr[0] * 3 + svnr[1] * 7 + svnr[2] * 9 + svnr[4] * 5 + svnr[5] * 8 + svnr[6] * 4 + svnr[7] * 2 + svnr[8] * 1 + svnr[9] * 6;\n    sum %= 11;\n    if(sum == 10){\n    \tsum = 0;\n    }\n    if (sum == svnr[3])\n    {\n        return true;\n    }\n    return false;\n}\n\n\nbool VerifySVNR::evaluate(Transaction *t, RuleWithActions *rule,\n    const std::string& input, RuleMessage &ruleMessage) {\n    std::list<SMatch> matches;\n    bool is_svnr = false;\n    int i;\n\n    if (m_param.empty()) {\n        return is_svnr;\n    }\n\n    for (i = 0; i < input.size() - 1 && is_svnr == false; i++) {\n        matches = m_re->searchAll(input.substr(i, input.size()));\n\n        for (const auto & j : matches) {\n            is_svnr = verify(j.str().c_str(), j.str().size());\n            if (is_svnr) {\n                logOffset(ruleMessage, j.offset(), j.str().size());\n                if (rule && t && rule->hasCaptureAction()) {\n                    t->m_collections.m_tx_collection->storeOrUpdateFirst(\n                        \"0\", j.str());\n                    ms_dbg_a(t, 7, \"Added VerifySVNR match TX.0: \" + \\\n                        j.str());\n                }\n\n                goto out;\n            }\n        }\n    }\n\nout:\n    return is_svnr;\n}\n\n\n}  // namespace operators\n}  // namespace modsecurity\n"
  },
  {
    "path": "src/operators/verify_svnr.h",
    "content": "\n#ifndef SRC_OPERATORS_VERIFY_SVNR_H_\n#define SRC_OPERATORS_VERIFY_SVNR_H_\n\n#include <string>\n#include <memory>\n#include <utility>\n\n#include \"src/operators/operator.h\"\n#include \"src/utils/regex.h\"\n\n\nnamespace modsecurity {\nusing Utils::SMatch;\nusing Utils::regex_search;\nusing Utils::Regex;\n\nnamespace operators {\n\nclass VerifySVNR : public Operator {\n public:\n    /** @ingroup ModSecurity_Operator */\n    explicit VerifySVNR(std::unique_ptr<RunTimeString> param)\n        : Operator(\"VerifySVNR\", std::move(param))\n        , m_re(std::make_unique<Regex>(m_param)) { }\n\n    bool operator=(const VerifySVNR &a) = delete;\n    VerifySVNR(const VerifySVNR &a) = delete;\n\n    bool evaluate(Transaction *transaction, RuleWithActions *rule,\n        const std::string& input,\n        RuleMessage &ruleMessage) override;\n\n    bool verify(const char *ssnumber, int len) const;\n\n private:\n    std::unique_ptr<Regex> m_re;\n    static int convert_to_int(const char c);\n    const char bad_svnr[12][11] = { \"0000000000\",\n        \"0123456789\",\n        \"1234567890\",\n        \"1111111111\",\n        \"2222222222\",\n        \"3333333333\",\n        \"4444444444\",\n        \"5555555555\",\n        \"6666666666\",\n        \"7777777777\",\n        \"8888888888\",\n        \"9999999999\"};\n};\n\n}  // namespace operators\n}  // namespace modsecurity\n\n\n#endif  // SRC_OPERATORS_VERIFY_SVNR_H_\n\n"
  },
  {
    "path": "src/operators/within.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"src/operators/within.h\"\n\n#include <string>\n\n#include \"src/operators/operator.h\"\n\n\nnamespace modsecurity {\nnamespace operators {\n\n\nbool Within::evaluate(Transaction *transaction, RuleWithActions *rule,\n    const std::string &str, RuleMessage &ruleMessage) {\n    bool res = false;\n    size_t pos = 0;\n    std::string paramTarget(m_string->evaluate(transaction));\n\n    if (str.empty()) {\n        return true;\n    }\n\n    pos = paramTarget.find(str);\n    res = pos != std::string::npos;\n    if (res) {\n        logOffset(ruleMessage, pos, str.size());\n    }\n\n    return res;\n}\n\n\n}  // namespace operators\n}  // namespace modsecurity\n"
  },
  {
    "path": "src/operators/within.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#ifndef SRC_OPERATORS_WITHIN_H_\n#define SRC_OPERATORS_WITHIN_H_\n\n#include <string>\n#include <memory>\n#include <utility>\n\n#include \"src/operators/operator.h\"\n\n\nnamespace modsecurity {\nnamespace operators {\n\nclass Within : public Operator {\n public:\n    /** @ingroup ModSecurity_Operator */\n    explicit Within(std::unique_ptr<RunTimeString> param)\n        : Operator(\"Within\", std::move(param)) {\n            m_couldContainsMacro = true;\n        }\n    bool evaluate(Transaction *transaction, RuleWithActions *rule,\n        const std::string &str, RuleMessage &ruleMessage) override;\n};\n\n}  // namespace operators\n}  // namespace modsecurity\n\n\n#endif  // SRC_OPERATORS_WITHIN_H_\n"
  },
  {
    "path": "src/parser/Makefile.am",
    "content": "\nnoinst_LTLIBRARIES = libmodsec_parser.la\n\nBUILT_SOURCES = \\\n\tseclang-parser.cc \\\n\ttest.cc\n\nlibmodsec_parser_la_SOURCES = \\\n\tseclang-parser.yy \\\n\tseclang-scanner.ll \\\n\ttest.cc\n\nlibmodsec_parser_la_CPPFLAGS = \\\n\t-I../.. \\\n\t-I../../headers \\\n\t-I../../others \\\n\t-I.. \\\n\t-g \\\n\t-fPIC \\\n\t-O3 \\\n\t$(CURL_CFLAGS) \\\n\t$(GEOIP_CFLAGS) \\\n\t$(GLOBAL_CPPFLAGS) \\\n\t$(MODSEC_NO_LOGS) \\\n\t$(YAJL_CFLAGS) \\\n\t$(LMDB_CFLAGS) \\\n\t$(PCRE_CFLAGS) \\\n\t$(PCRE2_CFLAGS) \\\n\t$(LIBXML2_CFLAGS)\n\ntest.cc: seclang-parser.hh\n\tcat seclang-parser.hh | sed \"s/return \\*new (yyas_<T> ()) T (t)/return *new (yyas_<T> ()) T (std::move((T\\&)t))/g\"  > seclang-parser.hh.fix && mv seclang-parser.hh.fix seclang-parser.hh\n\ttouch test.cc\n\nCLEANFILES = test.cc \\\n\tseclang-scanner.cc \\\n\tseclang-parser.cc \\\n\tseclang-parser.hh \\\n\tlocation.hh \\\n\tposition.hh \\\n\tstack.hh\n\nEXTRA_DIST = $(CLEANFILES)\n\nDISTCLAEN =\n"
  },
  {
    "path": "src/parser/driver.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2023 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"src/parser/driver.h\"\n\n#include \"modsecurity/rules_set_properties.h\"\n#include \"src/parser/seclang-parser.hh\"\n#include \"modsecurity/audit_log.h\"\n#include \"modsecurity/rule_marker.h\"\n\nusing modsecurity::audit_log::AuditLog;\nusing modsecurity::RuleWithOperator;\n\nnamespace modsecurity {\nnamespace Parser {\n\nDriver::Driver()\n  : RulesSetProperties(),\n  trace_scanning(false),\n  trace_parsing(false),\n  m_lastRule(nullptr) { }\n\n\nDriver::~Driver() {\n\n    while (loc.empty() == false) {\n        yy::location *a = loc.back();\n        loc.pop_back();\n        delete a;\n    }\n}\n\n\nint Driver::addSecMarker(const std::string& marker, const std::string &fileName, int lineNumber) {\n    // FIXME: we might move this to the parser.\n    for (int i = 0; i < modsecurity::Phases::NUMBER_OF_PHASES; i++) {\n        auto rule = std::make_unique<RuleMarker>(marker, fileName, lineNumber);\n        rule->setPhase(i);\n        m_rulesSetPhases.insert(std::move(rule));\n    }\n    return 0;\n}\n\n\nint Driver::addSecAction(std::unique_ptr<RuleWithActions> rule) {\n    if (rule->getPhase() >= modsecurity::Phases::NUMBER_OF_PHASES) {\n        m_parserError << \"Unknown phase: \" << std::to_string(rule->getPhase());\n        m_parserError << std::endl;\n        return false;\n    }\n\n    m_rulesSetPhases.insert(std::move(rule));\n\n    return true;\n}\n\n\nint Driver::addSecRuleScript(std::unique_ptr<RuleScript> rule) {\n    m_rulesSetPhases.insert(std::move(rule));\n    return true;\n}\n\n\nint Driver::addSecRule(std::unique_ptr<RuleWithActions> r) {\n    if (r->getPhase() >= modsecurity::Phases::NUMBER_OF_PHASES) {\n        m_parserError << \"Unknown phase: \" << std::to_string(r->getPhase());\n        m_parserError << std::endl;\n        return false;\n    }\n\n    /* is it a chained rule? */\n    if (m_lastRule != nullptr && m_lastRule->isChained()) {\n        r->setPhase(m_lastRule->getPhase());\n        if (r->hasDisruptiveAction()) {\n            m_parserError << \"Disruptive actions can only be specified by\";\n            m_parserError << \" chain starter rules.\";\n            return false;\n        }\n        m_lastRule->m_chainedRuleChild = std::move(r);\n        m_lastRule->m_chainedRuleChild->m_chainedRuleParent = m_lastRule;\n        m_lastRule = m_lastRule->m_chainedRuleChild.get();\n        return true;\n    }\n\n    std::shared_ptr<RuleWithActions> rule(std::move(r));\n    /*\n     * Checking if the rule has an ID and also checking if this ID is not used\n     * by other rule\n     */\n    if (rule->m_ruleId == 0) {\n        m_parserError << \"Rules must have an ID. File: \";\n        m_parserError << rule->getFileName() << \" at line: \";\n        m_parserError << std::to_string(rule->getLineNumber()) << std::endl;\n        return false;\n    }\n\n    for (int i = 0; i < modsecurity::Phases::NUMBER_OF_PHASES; i++) {\n        const Rules *rules = m_rulesSetPhases[i];\n        for (int j = 0; j < rules->size(); j++) {\n            const RuleWithOperator *lr = dynamic_cast<RuleWithOperator *>(rules->at(j).get());\n            if (lr && lr->m_ruleId == rule->m_ruleId) {\n                m_parserError << \"Rule id: \" << std::to_string(rule->m_ruleId) \\\n                    << \" is duplicated\" << std::endl;\n                return false;\n            }\n        }\n    }\n\n    m_lastRule = rule.get();\n    m_rulesSetPhases.insert(rule);\n\n    return true;\n}\n\n\nint Driver::parse(const std::string &f, const std::string &ref) {\n    m_lastRule = nullptr;\n    loc.push_back(new yy::location());\n    if (ref.empty()) {\n        m_filenames.push_back(\"<<reference missing or not informed>>\");\n        loc.back()->begin.filename = loc.back()->end.filename = &(m_filenames.back());\n    } else {\n        m_filenames.push_back(ref);\n        loc.back()->begin.filename = loc.back()->end.filename = &(m_filenames.back());\n    }\n\n    if (f.empty()) {\n        return 1;\n    }\n\n    buffer = f;\n    scan_begin();\n    yy::seclang_parser parser(*this);\n    parser.set_debug_level(trace_parsing);\n    int res = parser.parse();\n    scan_end();\n\n    /*\n     * need to check for rules marked as chained but without\n     * a chained rule.\n     *\n     */\n    /*\n    if (m_lastRule != nullptr && m_lastRule->isChained()) {\n        m_parserError << \"Last rule is marked as chained but there \" \\\n            \"isn't a subsequent rule.\" << std::endl;\n        return false;\n    }\n    */\n\n    /*\n    if (m_auditLog->init(&error) == false) {\n        m_parserError << \"Problems while initializing the audit logs: \" \\\n            << error << std::endl;\n        return false;\n    }\n    */\n\n    return res == 0;\n}\n\n\nint Driver::parseFile(const std::string &f) {\n    std::ifstream t(f);\n    std::string str;\n\n    if (utils::isFile(f) == false) {\n        m_parserError << \"Failed to open the file: \" << f << std::endl;\n        return false;\n    }\n\n    t.seekg(0, std::ios::end);\n    str.reserve(t.tellg());\n    t.seekg(0, std::ios::beg);\n\n    str.assign((std::istreambuf_iterator<char>(t)),\n        std::istreambuf_iterator<char>());\n\n    return parse(str, f);\n}\n\n\nvoid Driver::error(const yy::location& l, const std::string& m) {\n    error(l, m, \"\");\n}\n\n\nvoid Driver::error(const yy::location& l, const std::string& m,\n    const std::string& c) {\n    if (m_parserError.tellp() == 0) {\n        m_parserError << \"Rules error. \";\n        m_parserError << \"File: \" << *l.end.filename << \". \";\n        m_parserError << \"Line: \" << l.end.line << \". \";\n        m_parserError << \"Column: \" << l.end.column - 1 << \". \";\n    }\n\n    if (m.empty() == false) {\n        m_parserError << \"\" << m << \" \";\n    }\n\n    if (c.empty() == false) {\n        m_parserError << c;\n    }\n}\n\n\n}  // namespace Parser\n}  // namespace modsecurity\n"
  },
  {
    "path": "src/parser/driver.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2023 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#ifdef __cplusplus\n#include <string>\n#include <map>\n#include <stack>\n#include <vector>\n#include <list>\n#endif\n\n\n#ifndef SRC_PARSER_DRIVER_H_\n#define SRC_PARSER_DRIVER_H_\n\n#include \"modsecurity/modsecurity.h\"\n#include \"modsecurity/rules_set.h\"\n#include \"modsecurity/rules_set_properties.h\"\n#include \"modsecurity/audit_log.h\"\n#include \"src/rule_script.h\"\n#ifndef MS_CPPCHECK_DISABLED_FOR_PARSER\n#include \"src/parser/seclang-parser.hh\"\n#endif\n\nusing modsecurity::RuleWithOperator;\nusing modsecurity::RulesSet;\n\n\n# define YY_DECL \\\n  yy::seclang_parser::symbol_type yylex(modsecurity::Parser::Driver& driver)\n\nYY_DECL;\n\nnamespace modsecurity {\nnamespace Parser {\n\n#ifdef __cplusplus\nclass Driver;\n#else\ntypedef struct Driver_t Driver;\n#endif\n\n\nclass Driver : public RulesSetProperties {\n public:\n    Driver();\n    virtual ~Driver();\n\n    int addSecRule(std::unique_ptr<RuleWithActions> rule);\n    int addSecAction(std::unique_ptr<RuleWithActions> rule);\n    int addSecMarker(const std::string& marker, const std::string &fileName, int lineNumber);\n    int addSecRuleScript(std::unique_ptr<RuleScript> rule);\n\n    bool scan_begin();\n    void scan_end();\n    bool trace_scanning;\n\n    int parseFile(const std::string& f);\n    int parse(const std::string& f, const std::string &ref);\n\n    std::string file;\n\n    bool trace_parsing;\n\n    void error(const yy::location& l, const std::string& m);\n    void error(const yy::location& l, const std::string& m,\n        const std::string& c);\n\n    std::list<yy::location *> loc;\n\n    std::string buffer;\n    RuleWithActions *m_lastRule;\n\n    RulesSetPhases m_rulesSetPhases;\n\n    // Retain a list of new'd filenames so that they are available during the lifetime\n    // of the Driver object, but so that they will get cleaned up by the Driver\n    // destructor. This is to resolve a memory leak of  yy.position.filename in location.hh.\n    // Ordinarily other solutions would have been preferable, but location.hh is a\n    // bison-generated file, which makes some alternative solutions impractical.\n    std::list<std::string> m_filenames;\n};\n\n\n}  // namespace Parser\n}  // namespace modsecurity\n\n#endif  // SRC_PARSER_DRIVER_H_\n"
  },
  {
    "path": "src/parser/location.hh",
    "content": "// A Bison parser, made by GNU Bison 3.8.2.\n\n// Locations for Bison parsers in C++\n\n// Copyright (C) 2002-2015, 2018-2021 Free Software Foundation, Inc.\n\n// This program is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n\n// You should have received a copy of the GNU General Public License\n// along with this program.  If not, see <https://www.gnu.org/licenses/>.\n\n// As a special exception, you may create a larger work that contains\n// part or all of the Bison parser skeleton and distribute that work\n// under terms of your choice, so long as that work isn't itself a\n// parser generator using the skeleton or a modified version thereof\n// as a parser skeleton.  Alternatively, if you modify or redistribute\n// the parser skeleton itself, you may (at your option) remove this\n// special exception, which will cause the skeleton and the resulting\n// Bison output files to be licensed under the GNU General Public\n// License without this special exception.\n\n// This special exception was added by the Free Software Foundation in\n// version 2.2 of Bison.\n\n/**\n ** \\file location.hh\n ** Define the yy::location class.\n */\n\n#ifndef YY_YY_LOCATION_HH_INCLUDED\n# define YY_YY_LOCATION_HH_INCLUDED\n\n# include <iostream>\n# include <string>\n\n# ifndef YY_NULLPTR\n#  if defined __cplusplus\n#   if 201103L <= __cplusplus\n#    define YY_NULLPTR nullptr\n#   else\n#    define YY_NULLPTR 0\n#   endif\n#  else\n#   define YY_NULLPTR ((void*)0)\n#  endif\n# endif\n\nnamespace yy {\n#line 58 \"location.hh\"\n\n  /// A point in a source file.\n  class position\n  {\n  public:\n    /// Type for file name.\n    typedef const std::string filename_type;\n    /// Type for line and column numbers.\n    typedef int counter_type;\n\n    /// Construct a position.\n    explicit position (filename_type* f = YY_NULLPTR,\n                       counter_type l = 1,\n                       counter_type c = 1)\n      : filename (f)\n      , line (l)\n      , column (c)\n    {}\n\n\n    /// Initialization.\n    void initialize (filename_type* fn = YY_NULLPTR,\n                     counter_type l = 1,\n                     counter_type c = 1)\n    {\n      filename = fn;\n      line = l;\n      column = c;\n    }\n\n    /** \\name Line and Column related manipulators\n     ** \\{ */\n    /// (line related) Advance to the COUNT next lines.\n    void lines (counter_type count = 1)\n    {\n      if (count)\n        {\n          column = 1;\n          line = add_ (line, count, 1);\n        }\n    }\n\n    /// (column related) Advance to the COUNT next columns.\n    void columns (counter_type count = 1)\n    {\n      column = add_ (column, count, 1);\n    }\n    /** \\} */\n\n    /// File name to which this position refers.\n    filename_type* filename;\n    /// Current line number.\n    counter_type line;\n    /// Current column number.\n    counter_type column;\n\n  private:\n    /// Compute max (min, lhs+rhs).\n    static counter_type add_ (counter_type lhs, counter_type rhs, counter_type min)\n    {\n      return lhs + rhs < min ? min : lhs + rhs;\n    }\n  };\n\n  /// Add \\a width columns, in place.\n  inline position&\n  operator+= (position& res, position::counter_type width)\n  {\n    res.columns (width);\n    return res;\n  }\n\n  /// Add \\a width columns.\n  inline position\n  operator+ (position res, position::counter_type width)\n  {\n    return res += width;\n  }\n\n  /// Subtract \\a width columns, in place.\n  inline position&\n  operator-= (position& res, position::counter_type width)\n  {\n    return res += -width;\n  }\n\n  /// Subtract \\a width columns.\n  inline position\n  operator- (position res, position::counter_type width)\n  {\n    return res -= width;\n  }\n\n  /** \\brief Intercept output stream redirection.\n   ** \\param ostr the destination output stream\n   ** \\param pos a reference to the position to redirect\n   */\n  template <typename YYChar>\n  std::basic_ostream<YYChar>&\n  operator<< (std::basic_ostream<YYChar>& ostr, const position& pos)\n  {\n    if (pos.filename)\n      ostr << *pos.filename << ':';\n    return ostr << pos.line << '.' << pos.column;\n  }\n\n  /// Two points in a source file.\n  class location\n  {\n  public:\n    /// Type for file name.\n    typedef position::filename_type filename_type;\n    /// Type for line and column numbers.\n    typedef position::counter_type counter_type;\n\n    /// Construct a location from \\a b to \\a e.\n    location (const position& b, const position& e)\n      : begin (b)\n      , end (e)\n    {}\n\n    /// Construct a 0-width location in \\a p.\n    explicit location (const position& p = position ())\n      : begin (p)\n      , end (p)\n    {}\n\n    /// Construct a 0-width location in \\a f, \\a l, \\a c.\n    explicit location (filename_type* f,\n                       counter_type l = 1,\n                       counter_type c = 1)\n      : begin (f, l, c)\n      , end (f, l, c)\n    {}\n\n\n    /// Initialization.\n    void initialize (filename_type* f = YY_NULLPTR,\n                     counter_type l = 1,\n                     counter_type c = 1)\n    {\n      begin.initialize (f, l, c);\n      end = begin;\n    }\n\n    /** \\name Line and Column related manipulators\n     ** \\{ */\n  public:\n    /// Reset initial location to final location.\n    void step ()\n    {\n      begin = end;\n    }\n\n    /// Extend the current location to the COUNT next columns.\n    void columns (counter_type count = 1)\n    {\n      end += count;\n    }\n\n    /// Extend the current location to the COUNT next lines.\n    void lines (counter_type count = 1)\n    {\n      end.lines (count);\n    }\n    /** \\} */\n\n\n  public:\n    /// Beginning of the located region.\n    position begin;\n    /// End of the located region.\n    position end;\n  };\n\n  /// Join two locations, in place.\n  inline location&\n  operator+= (location& res, const location& end)\n  {\n    res.end = end.end;\n    return res;\n  }\n\n  /// Join two locations.\n  inline location\n  operator+ (location res, const location& end)\n  {\n    return res += end;\n  }\n\n  /// Add \\a width columns to the end position, in place.\n  inline location&\n  operator+= (location& res, location::counter_type width)\n  {\n    res.columns (width);\n    return res;\n  }\n\n  /// Add \\a width columns to the end position.\n  inline location\n  operator+ (location res, location::counter_type width)\n  {\n    return res += width;\n  }\n\n  /// Subtract \\a width columns to the end position, in place.\n  inline location&\n  operator-= (location& res, location::counter_type width)\n  {\n    return res += -width;\n  }\n\n  /// Subtract \\a width columns to the end position.\n  inline location\n  operator- (location res, location::counter_type width)\n  {\n    return res -= width;\n  }\n\n  /** \\brief Intercept output stream redirection.\n   ** \\param ostr the destination output stream\n   ** \\param loc a reference to the location to redirect\n   **\n   ** Avoid duplicate information.\n   */\n  template <typename YYChar>\n  std::basic_ostream<YYChar>&\n  operator<< (std::basic_ostream<YYChar>& ostr, const location& loc)\n  {\n    location::counter_type end_col\n      = 0 < loc.end.column ? loc.end.column - 1 : 0;\n    ostr << loc.begin;\n    if (loc.end.filename\n        && (!loc.begin.filename\n            || *loc.begin.filename != *loc.end.filename))\n      ostr << '-' << loc.end.filename << ':' << loc.end.line << '.' << end_col;\n    else if (loc.begin.line < loc.end.line)\n      ostr << '-' << loc.end.line << '.' << end_col;\n    else if (loc.begin.column < end_col)\n      ostr << '-' << end_col;\n    return ostr;\n  }\n\n} // yy\n#line 303 \"location.hh\"\n\n#endif // !YY_YY_LOCATION_HH_INCLUDED\n"
  },
  {
    "path": "src/parser/position.hh",
    "content": "// A Bison parser, made by GNU Bison 3.8.2.\n\n// Starting with Bison 3.2, this file is useless: the structure it\n// used to define is now defined in \"location.hh\".\n//\n// To get rid of this file:\n// 1. add '%require \"3.2\"' (or newer) to your grammar file\n// 2. remove references to this file from your build system\n// 3. if you used to include it, include \"location.hh\" instead.\n\n#include \"location.hh\"\n"
  },
  {
    "path": "src/parser/seclang-parser.cc",
    "content": "// A Bison parser, made by GNU Bison 3.8.2.\n\n// Skeleton implementation for Bison LALR(1) parsers in C++\n\n// Copyright (C) 2002-2015, 2018-2021 Free Software Foundation, Inc.\n\n// This program is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n\n// You should have received a copy of the GNU General Public License\n// along with this program.  If not, see <https://www.gnu.org/licenses/>.\n\n// As a special exception, you may create a larger work that contains\n// part or all of the Bison parser skeleton and distribute that work\n// under terms of your choice, so long as that work isn't itself a\n// parser generator using the skeleton or a modified version thereof\n// as a parser skeleton.  Alternatively, if you modify or redistribute\n// the parser skeleton itself, you may (at your option) remove this\n// special exception, which will cause the skeleton and the resulting\n// Bison output files to be licensed under the GNU General Public\n// License without this special exception.\n\n// This special exception was added by the Free Software Foundation in\n// version 2.2 of Bison.\n\n// DO NOT RELY ON FEATURES THAT ARE NOT DOCUMENTED in the manual,\n// especially those whose name start with YY_ or yy_.  They are\n// private implementation details that can be changed or removed.\n\n\n\n\n\n#include \"seclang-parser.hh\"\n\n\n// Unqualified %code blocks.\n#line 332 \"seclang-parser.yy\"\n\n#include \"src/parser/driver.h\"\n\n#line 50 \"seclang-parser.cc\"\n\n\n#ifndef YY_\n# if defined YYENABLE_NLS && YYENABLE_NLS\n#  if ENABLE_NLS\n#   include <libintl.h> // FIXME: INFRINGES ON USER NAME SPACE.\n#   define YY_(msgid) dgettext (\"bison-runtime\", msgid)\n#  endif\n# endif\n# ifndef YY_\n#  define YY_(msgid) msgid\n# endif\n#endif\n\n\n// Whether we are compiled with exception support.\n#ifndef YY_EXCEPTIONS\n# if defined __GNUC__ && !defined __EXCEPTIONS\n#  define YY_EXCEPTIONS 0\n# else\n#  define YY_EXCEPTIONS 1\n# endif\n#endif\n\n#define YYRHSLOC(Rhs, K) ((Rhs)[K].location)\n/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N].\n   If N is 0, then set CURRENT to the empty location which ends\n   the previous symbol: RHS[0] (always defined).  */\n\n# ifndef YYLLOC_DEFAULT\n#  define YYLLOC_DEFAULT(Current, Rhs, N)                               \\\n    do                                                                  \\\n      if (N)                                                            \\\n        {                                                               \\\n          (Current).begin  = YYRHSLOC (Rhs, 1).begin;                   \\\n          (Current).end    = YYRHSLOC (Rhs, N).end;                     \\\n        }                                                               \\\n      else                                                              \\\n        {                                                               \\\n          (Current).begin = (Current).end = YYRHSLOC (Rhs, 0).end;      \\\n        }                                                               \\\n    while (false)\n# endif\n\n\n// Enable debugging if requested.\n#if YYDEBUG\n\n// A pseudo ostream that takes yydebug_ into account.\n# define YYCDEBUG if (yydebug_) (*yycdebug_)\n\n# define YY_SYMBOL_PRINT(Title, Symbol)         \\\n  do {                                          \\\n    if (yydebug_)                               \\\n    {                                           \\\n      *yycdebug_ << Title << ' ';               \\\n      yy_print_ (*yycdebug_, Symbol);           \\\n      *yycdebug_ << '\\n';                       \\\n    }                                           \\\n  } while (false)\n\n# define YY_REDUCE_PRINT(Rule)          \\\n  do {                                  \\\n    if (yydebug_)                       \\\n      yy_reduce_print_ (Rule);          \\\n  } while (false)\n\n# define YY_STACK_PRINT()               \\\n  do {                                  \\\n    if (yydebug_)                       \\\n      yy_stack_print_ ();                \\\n  } while (false)\n\n#else // !YYDEBUG\n\n# define YYCDEBUG if (false) std::cerr\n# define YY_SYMBOL_PRINT(Title, Symbol)  YY_USE (Symbol)\n# define YY_REDUCE_PRINT(Rule)           static_cast<void> (0)\n# define YY_STACK_PRINT()                static_cast<void> (0)\n\n#endif // !YYDEBUG\n\n#define yyerrok         (yyerrstatus_ = 0)\n#define yyclearin       (yyla.clear ())\n\n#define YYACCEPT        goto yyacceptlab\n#define YYABORT         goto yyabortlab\n#define YYERROR         goto yyerrorlab\n#define YYRECOVERING()  (!!yyerrstatus_)\n\nnamespace yy {\n#line 142 \"seclang-parser.cc\"\n\n  /// Build a parser object.\n  seclang_parser::seclang_parser (modsecurity::Parser::Driver& driver_yyarg)\n#if YYDEBUG\n    : yydebug_ (false),\n      yycdebug_ (&std::cerr),\n#else\n    :\n#endif\n      driver (driver_yyarg)\n  {}\n\n  seclang_parser::~seclang_parser ()\n  {}\n\n  seclang_parser::syntax_error::~syntax_error () YY_NOEXCEPT YY_NOTHROW\n  {}\n\n  /*---------.\n  | symbol.  |\n  `---------*/\n\n\n\n  // by_state.\n  seclang_parser::by_state::by_state () YY_NOEXCEPT\n    : state (empty_state)\n  {}\n\n  seclang_parser::by_state::by_state (const by_state& that) YY_NOEXCEPT\n    : state (that.state)\n  {}\n\n  void\n  seclang_parser::by_state::clear () YY_NOEXCEPT\n  {\n    state = empty_state;\n  }\n\n  void\n  seclang_parser::by_state::move (by_state& that)\n  {\n    state = that.state;\n    that.clear ();\n  }\n\n  seclang_parser::by_state::by_state (state_type s) YY_NOEXCEPT\n    : state (s)\n  {}\n\n  seclang_parser::symbol_kind_type\n  seclang_parser::by_state::kind () const YY_NOEXCEPT\n  {\n    if (state == empty_state)\n      return symbol_kind::S_YYEMPTY;\n    else\n      return YY_CAST (symbol_kind_type, yystos_[+state]);\n  }\n\n  seclang_parser::stack_symbol_type::stack_symbol_type ()\n  {}\n\n  seclang_parser::stack_symbol_type::stack_symbol_type (YY_RVREF (stack_symbol_type) that)\n    : super_type (YY_MOVE (that.state), YY_MOVE (that.location))\n  {\n    switch (that.kind ())\n    {\n      case symbol_kind::S_ACTION_ACCURACY: // \"Accuracy\"\n      case symbol_kind::S_ACTION_ALLOW: // \"Allow\"\n      case symbol_kind::S_ACTION_APPEND: // \"Append\"\n      case symbol_kind::S_ACTION_AUDIT_LOG: // \"AuditLog\"\n      case symbol_kind::S_ACTION_BLOCK: // \"Block\"\n      case symbol_kind::S_ACTION_CAPTURE: // \"Capture\"\n      case symbol_kind::S_ACTION_CHAIN: // \"Chain\"\n      case symbol_kind::S_ACTION_CTL_AUDIT_ENGINE: // \"ACTION_CTL_AUDIT_ENGINE\"\n      case symbol_kind::S_ACTION_CTL_AUDIT_LOG_PARTS: // \"ACTION_CTL_AUDIT_LOG_PARTS\"\n      case symbol_kind::S_ACTION_CTL_BDY_JSON: // \"ACTION_CTL_BDY_JSON\"\n      case symbol_kind::S_ACTION_CTL_BDY_XML: // \"ACTION_CTL_BDY_XML\"\n      case symbol_kind::S_ACTION_CTL_BDY_URLENCODED: // \"ACTION_CTL_BDY_URLENCODED\"\n      case symbol_kind::S_ACTION_CTL_FORCE_REQ_BODY_VAR: // \"ACTION_CTL_FORCE_REQ_BODY_VAR\"\n      case symbol_kind::S_ACTION_CTL_PARSE_XML_INTO_ARGS: // \"ACTION_CTL_PARSE_XML_INTO_ARGS\"\n      case symbol_kind::S_ACTION_CTL_REQUEST_BODY_ACCESS: // \"ACTION_CTL_REQUEST_BODY_ACCESS\"\n      case symbol_kind::S_ACTION_CTL_RULE_REMOVE_BY_ID: // \"ACTION_CTL_RULE_REMOVE_BY_ID\"\n      case symbol_kind::S_ACTION_CTL_RULE_REMOVE_BY_TAG: // \"ACTION_CTL_RULE_REMOVE_BY_TAG\"\n      case symbol_kind::S_ACTION_CTL_RULE_REMOVE_TARGET_BY_ID: // \"ACTION_CTL_RULE_REMOVE_TARGET_BY_ID\"\n      case symbol_kind::S_ACTION_CTL_RULE_REMOVE_TARGET_BY_TAG: // \"ACTION_CTL_RULE_REMOVE_TARGET_BY_TAG\"\n      case symbol_kind::S_ACTION_DENY: // \"Deny\"\n      case symbol_kind::S_ACTION_DEPRECATE_VAR: // \"DeprecateVar\"\n      case symbol_kind::S_ACTION_DROP: // \"Drop\"\n      case symbol_kind::S_ACTION_EXEC: // \"Exec\"\n      case symbol_kind::S_ACTION_EXPIRE_VAR: // \"ExpireVar\"\n      case symbol_kind::S_ACTION_ID: // \"Id\"\n      case symbol_kind::S_ACTION_INITCOL: // \"InitCol\"\n      case symbol_kind::S_ACTION_LOG: // \"Log\"\n      case symbol_kind::S_ACTION_LOG_DATA: // \"LogData\"\n      case symbol_kind::S_ACTION_MATURITY: // \"Maturity\"\n      case symbol_kind::S_ACTION_MSG: // \"Msg\"\n      case symbol_kind::S_ACTION_MULTI_MATCH: // \"MultiMatch\"\n      case symbol_kind::S_ACTION_NO_AUDIT_LOG: // \"NoAuditLog\"\n      case symbol_kind::S_ACTION_NO_LOG: // \"NoLog\"\n      case symbol_kind::S_ACTION_PASS: // \"Pass\"\n      case symbol_kind::S_ACTION_PAUSE: // \"Pause\"\n      case symbol_kind::S_ACTION_PHASE: // \"Phase\"\n      case symbol_kind::S_ACTION_PREPEND: // \"Prepend\"\n      case symbol_kind::S_ACTION_PROXY: // \"Proxy\"\n      case symbol_kind::S_ACTION_REDIRECT: // \"Redirect\"\n      case symbol_kind::S_ACTION_REV: // \"Rev\"\n      case symbol_kind::S_ACTION_SANITISE_ARG: // \"SanitiseArg\"\n      case symbol_kind::S_ACTION_SANITISE_MATCHED: // \"SanitiseMatched\"\n      case symbol_kind::S_ACTION_SANITISE_MATCHED_BYTES: // \"SanitiseMatchedBytes\"\n      case symbol_kind::S_ACTION_SANITISE_REQUEST_HEADER: // \"SanitiseRequestHeader\"\n      case symbol_kind::S_ACTION_SANITISE_RESPONSE_HEADER: // \"SanitiseResponseHeader\"\n      case symbol_kind::S_ACTION_SETENV: // \"SetEnv\"\n      case symbol_kind::S_ACTION_SETRSC: // \"SetRsc\"\n      case symbol_kind::S_ACTION_SETSID: // \"SetSid\"\n      case symbol_kind::S_ACTION_SETUID: // \"SetUID\"\n      case symbol_kind::S_ACTION_SEVERITY: // \"Severity\"\n      case symbol_kind::S_ACTION_SKIP: // \"Skip\"\n      case symbol_kind::S_ACTION_SKIP_AFTER: // \"SkipAfter\"\n      case symbol_kind::S_ACTION_STATUS: // \"Status\"\n      case symbol_kind::S_ACTION_TAG: // \"Tag\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_BASE_64_ENCODE: // \"ACTION_TRANSFORMATION_BASE_64_ENCODE\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_BASE_64_DECODE: // \"ACTION_TRANSFORMATION_BASE_64_DECODE\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_BASE_64_DECODE_EXT: // \"ACTION_TRANSFORMATION_BASE_64_DECODE_EXT\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_CMD_LINE: // \"ACTION_TRANSFORMATION_CMD_LINE\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_COMPRESS_WHITESPACE: // \"ACTION_TRANSFORMATION_COMPRESS_WHITESPACE\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_CSS_DECODE: // \"ACTION_TRANSFORMATION_CSS_DECODE\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_ESCAPE_SEQ_DECODE: // \"ACTION_TRANSFORMATION_ESCAPE_SEQ_DECODE\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_HEX_ENCODE: // \"ACTION_TRANSFORMATION_HEX_ENCODE\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_HEX_DECODE: // \"ACTION_TRANSFORMATION_HEX_DECODE\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_HTML_ENTITY_DECODE: // \"ACTION_TRANSFORMATION_HTML_ENTITY_DECODE\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_JS_DECODE: // \"ACTION_TRANSFORMATION_JS_DECODE\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_LENGTH: // \"ACTION_TRANSFORMATION_LENGTH\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_LOWERCASE: // \"ACTION_TRANSFORMATION_LOWERCASE\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_MD5: // \"ACTION_TRANSFORMATION_MD5\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_NONE: // \"ACTION_TRANSFORMATION_NONE\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_NORMALISE_PATH: // \"ACTION_TRANSFORMATION_NORMALISE_PATH\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_NORMALISE_PATH_WIN: // \"ACTION_TRANSFORMATION_NORMALISE_PATH_WIN\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_PARITY_EVEN_7_BIT: // \"ACTION_TRANSFORMATION_PARITY_EVEN_7_BIT\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_PARITY_ODD_7_BIT: // \"ACTION_TRANSFORMATION_PARITY_ODD_7_BIT\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_PARITY_ZERO_7_BIT: // \"ACTION_TRANSFORMATION_PARITY_ZERO_7_BIT\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_REMOVE_COMMENTS: // \"ACTION_TRANSFORMATION_REMOVE_COMMENTS\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_REMOVE_COMMENTS_CHAR: // \"ACTION_TRANSFORMATION_REMOVE_COMMENTS_CHAR\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_REMOVE_NULLS: // \"ACTION_TRANSFORMATION_REMOVE_NULLS\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_REMOVE_WHITESPACE: // \"ACTION_TRANSFORMATION_REMOVE_WHITESPACE\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_REPLACE_COMMENTS: // \"ACTION_TRANSFORMATION_REPLACE_COMMENTS\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_REPLACE_NULLS: // \"ACTION_TRANSFORMATION_REPLACE_NULLS\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_SHA1: // \"ACTION_TRANSFORMATION_SHA1\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_SQL_HEX_DECODE: // \"ACTION_TRANSFORMATION_SQL_HEX_DECODE\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_TRIM: // \"ACTION_TRANSFORMATION_TRIM\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_TRIM_LEFT: // \"ACTION_TRANSFORMATION_TRIM_LEFT\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_TRIM_RIGHT: // \"ACTION_TRANSFORMATION_TRIM_RIGHT\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_UPPERCASE: // \"ACTION_TRANSFORMATION_UPPERCASE\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_URL_ENCODE: // \"ACTION_TRANSFORMATION_URL_ENCODE\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_URL_DECODE: // \"ACTION_TRANSFORMATION_URL_DECODE\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_URL_DECODE_UNI: // \"ACTION_TRANSFORMATION_URL_DECODE_UNI\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_UTF8_TO_UNICODE: // \"ACTION_TRANSFORMATION_UTF8_TO_UNICODE\"\n      case symbol_kind::S_ACTION_VER: // \"Ver\"\n      case symbol_kind::S_ACTION_XMLNS: // \"xmlns\"\n      case symbol_kind::S_CONFIG_COMPONENT_SIG: // \"CONFIG_COMPONENT_SIG\"\n      case symbol_kind::S_CONFIG_CONN_ENGINE: // \"CONFIG_CONN_ENGINE\"\n      case symbol_kind::S_CONFIG_SEC_ARGUMENT_SEPARATOR: // \"CONFIG_SEC_ARGUMENT_SEPARATOR\"\n      case symbol_kind::S_CONFIG_SEC_WEB_APP_ID: // \"CONFIG_SEC_WEB_APP_ID\"\n      case symbol_kind::S_CONFIG_SEC_SERVER_SIG: // \"CONFIG_SEC_SERVER_SIG\"\n      case symbol_kind::S_CONFIG_DIR_AUDIT_DIR: // \"CONFIG_DIR_AUDIT_DIR\"\n      case symbol_kind::S_CONFIG_DIR_AUDIT_DIR_MOD: // \"CONFIG_DIR_AUDIT_DIR_MOD\"\n      case symbol_kind::S_CONFIG_DIR_AUDIT_ENG: // \"CONFIG_DIR_AUDIT_ENG\"\n      case symbol_kind::S_CONFIG_DIR_AUDIT_FLE_MOD: // \"CONFIG_DIR_AUDIT_FLE_MOD\"\n      case symbol_kind::S_CONFIG_DIR_AUDIT_LOG: // \"CONFIG_DIR_AUDIT_LOG\"\n      case symbol_kind::S_CONFIG_DIR_AUDIT_LOG2: // \"CONFIG_DIR_AUDIT_LOG2\"\n      case symbol_kind::S_CONFIG_DIR_AUDIT_LOG_P: // \"CONFIG_DIR_AUDIT_LOG_P\"\n      case symbol_kind::S_CONFIG_DIR_AUDIT_STS: // \"CONFIG_DIR_AUDIT_STS\"\n      case symbol_kind::S_CONFIG_DIR_AUDIT_PREFIX: // \"CONFIG_DIR_AUDIT_PREFIX\"\n      case symbol_kind::S_CONFIG_DIR_AUDIT_TPE: // \"CONFIG_DIR_AUDIT_TPE\"\n      case symbol_kind::S_CONFIG_DIR_DEBUG_LOG: // \"CONFIG_DIR_DEBUG_LOG\"\n      case symbol_kind::S_CONFIG_DIR_DEBUG_LVL: // \"CONFIG_DIR_DEBUG_LVL\"\n      case symbol_kind::S_CONFIG_SEC_CACHE_TRANSFORMATIONS: // \"CONFIG_SEC_CACHE_TRANSFORMATIONS\"\n      case symbol_kind::S_CONFIG_SEC_DISABLE_BACKEND_COMPRESS: // \"CONFIG_SEC_DISABLE_BACKEND_COMPRESS\"\n      case symbol_kind::S_CONFIG_SEC_HASH_ENGINE: // \"CONFIG_SEC_HASH_ENGINE\"\n      case symbol_kind::S_CONFIG_SEC_HASH_KEY: // \"CONFIG_SEC_HASH_KEY\"\n      case symbol_kind::S_CONFIG_SEC_HASH_PARAM: // \"CONFIG_SEC_HASH_PARAM\"\n      case symbol_kind::S_CONFIG_SEC_HASH_METHOD_RX: // \"CONFIG_SEC_HASH_METHOD_RX\"\n      case symbol_kind::S_CONFIG_SEC_HASH_METHOD_PM: // \"CONFIG_SEC_HASH_METHOD_PM\"\n      case symbol_kind::S_CONFIG_SEC_CHROOT_DIR: // \"CONFIG_SEC_CHROOT_DIR\"\n      case symbol_kind::S_CONFIG_DIR_GEO_DB: // \"CONFIG_DIR_GEO_DB\"\n      case symbol_kind::S_CONFIG_DIR_GSB_DB: // \"CONFIG_DIR_GSB_DB\"\n      case symbol_kind::S_CONFIG_SEC_GUARDIAN_LOG: // \"CONFIG_SEC_GUARDIAN_LOG\"\n      case symbol_kind::S_CONFIG_DIR_PCRE_MATCH_LIMIT: // \"CONFIG_DIR_PCRE_MATCH_LIMIT\"\n      case symbol_kind::S_CONFIG_DIR_PCRE_MATCH_LIMIT_RECURSION: // \"CONFIG_DIR_PCRE_MATCH_LIMIT_RECURSION\"\n      case symbol_kind::S_CONFIG_SEC_CONN_R_STATE_LIMIT: // \"CONFIG_SEC_CONN_R_STATE_LIMIT\"\n      case symbol_kind::S_CONFIG_SEC_CONN_W_STATE_LIMIT: // \"CONFIG_SEC_CONN_W_STATE_LIMIT\"\n      case symbol_kind::S_CONFIG_SEC_SENSOR_ID: // \"CONFIG_SEC_SENSOR_ID\"\n      case symbol_kind::S_CONFIG_DIR_ARGS_LIMIT: // \"CONFIG_DIR_ARGS_LIMIT\"\n      case symbol_kind::S_CONFIG_DIR_REQ_BODY_JSON_DEPTH_LIMIT: // \"CONFIG_DIR_REQ_BODY_JSON_DEPTH_LIMIT\"\n      case symbol_kind::S_CONFIG_DIR_REQ_BODY: // \"CONFIG_DIR_REQ_BODY\"\n      case symbol_kind::S_CONFIG_DIR_REQ_BODY_IN_MEMORY_LIMIT: // \"CONFIG_DIR_REQ_BODY_IN_MEMORY_LIMIT\"\n      case symbol_kind::S_CONFIG_DIR_REQ_BODY_LIMIT: // \"CONFIG_DIR_REQ_BODY_LIMIT\"\n      case symbol_kind::S_CONFIG_DIR_REQ_BODY_LIMIT_ACTION: // \"CONFIG_DIR_REQ_BODY_LIMIT_ACTION\"\n      case symbol_kind::S_CONFIG_DIR_REQ_BODY_NO_FILES_LIMIT: // \"CONFIG_DIR_REQ_BODY_NO_FILES_LIMIT\"\n      case symbol_kind::S_CONFIG_DIR_RES_BODY: // \"CONFIG_DIR_RES_BODY\"\n      case symbol_kind::S_CONFIG_DIR_RES_BODY_LIMIT: // \"CONFIG_DIR_RES_BODY_LIMIT\"\n      case symbol_kind::S_CONFIG_DIR_RES_BODY_LIMIT_ACTION: // \"CONFIG_DIR_RES_BODY_LIMIT_ACTION\"\n      case symbol_kind::S_CONFIG_SEC_RULE_INHERITANCE: // \"CONFIG_SEC_RULE_INHERITANCE\"\n      case symbol_kind::S_CONFIG_SEC_RULE_PERF_TIME: // \"CONFIG_SEC_RULE_PERF_TIME\"\n      case symbol_kind::S_CONFIG_DIR_RULE_ENG: // \"CONFIG_DIR_RULE_ENG\"\n      case symbol_kind::S_CONFIG_DIR_SEC_ACTION: // \"CONFIG_DIR_SEC_ACTION\"\n      case symbol_kind::S_CONFIG_DIR_SEC_DEFAULT_ACTION: // \"CONFIG_DIR_SEC_DEFAULT_ACTION\"\n      case symbol_kind::S_CONFIG_DIR_SEC_MARKER: // \"CONFIG_DIR_SEC_MARKER\"\n      case symbol_kind::S_CONFIG_DIR_UNICODE_MAP_FILE: // \"CONFIG_DIR_UNICODE_MAP_FILE\"\n      case symbol_kind::S_CONFIG_DIR_UNICODE_CODE_PAGE: // \"CONFIG_DIR_UNICODE_CODE_PAGE\"\n      case symbol_kind::S_CONFIG_SEC_COLLECTION_TIMEOUT: // \"CONFIG_SEC_COLLECTION_TIMEOUT\"\n      case symbol_kind::S_CONFIG_SEC_HTTP_BLKEY: // \"CONFIG_SEC_HTTP_BLKEY\"\n      case symbol_kind::S_CONFIG_SEC_INTERCEPT_ON_ERROR: // \"CONFIG_SEC_INTERCEPT_ON_ERROR\"\n      case symbol_kind::S_CONFIG_SEC_REMOTE_RULES_FAIL_ACTION: // \"CONFIG_SEC_REMOTE_RULES_FAIL_ACTION\"\n      case symbol_kind::S_CONFIG_SEC_RULE_REMOVE_BY_ID: // \"CONFIG_SEC_RULE_REMOVE_BY_ID\"\n      case symbol_kind::S_CONFIG_SEC_RULE_REMOVE_BY_MSG: // \"CONFIG_SEC_RULE_REMOVE_BY_MSG\"\n      case symbol_kind::S_CONFIG_SEC_RULE_REMOVE_BY_TAG: // \"CONFIG_SEC_RULE_REMOVE_BY_TAG\"\n      case symbol_kind::S_CONFIG_SEC_RULE_UPDATE_TARGET_BY_TAG: // \"CONFIG_SEC_RULE_UPDATE_TARGET_BY_TAG\"\n      case symbol_kind::S_CONFIG_SEC_RULE_UPDATE_TARGET_BY_MSG: // \"CONFIG_SEC_RULE_UPDATE_TARGET_BY_MSG\"\n      case symbol_kind::S_CONFIG_SEC_RULE_UPDATE_TARGET_BY_ID: // \"CONFIG_SEC_RULE_UPDATE_TARGET_BY_ID\"\n      case symbol_kind::S_CONFIG_SEC_RULE_UPDATE_ACTION_BY_ID: // \"CONFIG_SEC_RULE_UPDATE_ACTION_BY_ID\"\n      case symbol_kind::S_CONFIG_UPDLOAD_KEEP_FILES: // \"CONFIG_UPDLOAD_KEEP_FILES\"\n      case symbol_kind::S_CONFIG_UPDLOAD_SAVE_TMP_FILES: // \"CONFIG_UPDLOAD_SAVE_TMP_FILES\"\n      case symbol_kind::S_CONFIG_UPLOAD_DIR: // \"CONFIG_UPLOAD_DIR\"\n      case symbol_kind::S_CONFIG_UPLOAD_FILE_LIMIT: // \"CONFIG_UPLOAD_FILE_LIMIT\"\n      case symbol_kind::S_CONFIG_UPLOAD_FILE_MODE: // \"CONFIG_UPLOAD_FILE_MODE\"\n      case symbol_kind::S_CONFIG_VALUE_ABORT: // \"CONFIG_VALUE_ABORT\"\n      case symbol_kind::S_CONFIG_VALUE_DETC: // \"CONFIG_VALUE_DETC\"\n      case symbol_kind::S_CONFIG_VALUE_HTTPS: // \"CONFIG_VALUE_HTTPS\"\n      case symbol_kind::S_CONFIG_VALUE_ONLYARGS: // \"CONFIG_VALUE_ONLYARGS\"\n      case symbol_kind::S_CONFIG_VALUE_OFF: // \"CONFIG_VALUE_OFF\"\n      case symbol_kind::S_CONFIG_VALUE_ON: // \"CONFIG_VALUE_ON\"\n      case symbol_kind::S_CONFIG_VALUE_PARALLEL: // \"CONFIG_VALUE_PARALLEL\"\n      case symbol_kind::S_CONFIG_VALUE_PROCESS_PARTIAL: // \"CONFIG_VALUE_PROCESS_PARTIAL\"\n      case symbol_kind::S_CONFIG_VALUE_REJECT: // \"CONFIG_VALUE_REJECT\"\n      case symbol_kind::S_CONFIG_VALUE_RELEVANT_ONLY: // \"CONFIG_VALUE_RELEVANT_ONLY\"\n      case symbol_kind::S_CONFIG_VALUE_SERIAL: // \"CONFIG_VALUE_SERIAL\"\n      case symbol_kind::S_CONFIG_VALUE_WARN: // \"CONFIG_VALUE_WARN\"\n      case symbol_kind::S_CONFIG_XML_EXTERNAL_ENTITY: // \"CONFIG_XML_EXTERNAL_ENTITY\"\n      case symbol_kind::S_CONFIG_XML_PARSE_XML_INTO_ARGS: // \"CONFIG_XML_PARSE_XML_INTO_ARGS\"\n      case symbol_kind::S_CONGIG_DIR_RESPONSE_BODY_MP: // \"CONGIG_DIR_RESPONSE_BODY_MP\"\n      case symbol_kind::S_CONGIG_DIR_SEC_ARG_SEP: // \"CONGIG_DIR_SEC_ARG_SEP\"\n      case symbol_kind::S_CONGIG_DIR_SEC_COOKIE_FORMAT: // \"CONGIG_DIR_SEC_COOKIE_FORMAT\"\n      case symbol_kind::S_CONFIG_SEC_COOKIEV0_SEPARATOR: // \"CONFIG_SEC_COOKIEV0_SEPARATOR\"\n      case symbol_kind::S_CONGIG_DIR_SEC_DATA_DIR: // \"CONGIG_DIR_SEC_DATA_DIR\"\n      case symbol_kind::S_CONGIG_DIR_SEC_STATUS_ENGINE: // \"CONGIG_DIR_SEC_STATUS_ENGINE\"\n      case symbol_kind::S_CONFIG_SEC_STREAM_IN_BODY_INSPECTION: // \"CONFIG_SEC_STREAM_IN_BODY_INSPECTION\"\n      case symbol_kind::S_CONFIG_SEC_STREAM_OUT_BODY_INSPECTION: // \"CONFIG_SEC_STREAM_OUT_BODY_INSPECTION\"\n      case symbol_kind::S_CONGIG_DIR_SEC_TMP_DIR: // \"CONGIG_DIR_SEC_TMP_DIR\"\n      case symbol_kind::S_DIRECTIVE: // \"DIRECTIVE\"\n      case symbol_kind::S_DIRECTIVE_SECRULESCRIPT: // \"DIRECTIVE_SECRULESCRIPT\"\n      case symbol_kind::S_FREE_TEXT_QUOTE_MACRO_EXPANSION: // \"FREE_TEXT_QUOTE_MACRO_EXPANSION\"\n      case symbol_kind::S_QUOTATION_MARK: // \"QUOTATION_MARK\"\n      case symbol_kind::S_RUN_TIME_VAR_BLD: // \"RUN_TIME_VAR_BLD\"\n      case symbol_kind::S_RUN_TIME_VAR_DUR: // \"RUN_TIME_VAR_DUR\"\n      case symbol_kind::S_RUN_TIME_VAR_HSV: // \"RUN_TIME_VAR_HSV\"\n      case symbol_kind::S_RUN_TIME_VAR_REMOTE_USER: // \"RUN_TIME_VAR_REMOTE_USER\"\n      case symbol_kind::S_RUN_TIME_VAR_TIME: // \"RUN_TIME_VAR_TIME\"\n      case symbol_kind::S_RUN_TIME_VAR_TIME_DAY: // \"RUN_TIME_VAR_TIME_DAY\"\n      case symbol_kind::S_RUN_TIME_VAR_TIME_EPOCH: // \"RUN_TIME_VAR_TIME_EPOCH\"\n      case symbol_kind::S_RUN_TIME_VAR_TIME_HOUR: // \"RUN_TIME_VAR_TIME_HOUR\"\n      case symbol_kind::S_RUN_TIME_VAR_TIME_MIN: // \"RUN_TIME_VAR_TIME_MIN\"\n      case symbol_kind::S_RUN_TIME_VAR_TIME_MON: // \"RUN_TIME_VAR_TIME_MON\"\n      case symbol_kind::S_RUN_TIME_VAR_TIME_SEC: // \"RUN_TIME_VAR_TIME_SEC\"\n      case symbol_kind::S_RUN_TIME_VAR_TIME_WDAY: // \"RUN_TIME_VAR_TIME_WDAY\"\n      case symbol_kind::S_RUN_TIME_VAR_TIME_YEAR: // \"RUN_TIME_VAR_TIME_YEAR\"\n      case symbol_kind::S_VARIABLE: // \"VARIABLE\"\n      case symbol_kind::S_DICT_ELEMENT: // \"Dictionary element\"\n      case symbol_kind::S_DICT_ELEMENT_WITH_EQUALS: // \"Dictionary element, with equals\"\n      case symbol_kind::S_DICT_ELEMENT_REGEXP: // \"Dictionary element, selected by regexp\"\n        value.YY_MOVE_OR_COPY< std::string > (YY_MOVE (that.value));\n        break;\n\n      case symbol_kind::S_op: // op\n      case symbol_kind::S_op_before_init: // op_before_init\n        value.YY_MOVE_OR_COPY< std::unique_ptr<Operator> > (YY_MOVE (that.value));\n        break;\n\n      case symbol_kind::S_run_time_string: // run_time_string\n        value.YY_MOVE_OR_COPY< std::unique_ptr<RunTimeString> > (YY_MOVE (that.value));\n        break;\n\n      case symbol_kind::S_var: // var\n        value.YY_MOVE_OR_COPY< std::unique_ptr<Variable> > (YY_MOVE (that.value));\n        break;\n\n      case symbol_kind::S_act: // act\n      case symbol_kind::S_setvar_action: // setvar_action\n        value.YY_MOVE_OR_COPY< std::unique_ptr<actions::Action> > (YY_MOVE (that.value));\n        break;\n\n      case symbol_kind::S_variables: // variables\n      case symbol_kind::S_variables_pre_process: // variables_pre_process\n      case symbol_kind::S_variables_may_be_quoted: // variables_may_be_quoted\n        value.YY_MOVE_OR_COPY< std::unique_ptr<std::vector<std::unique_ptr<Variable> > >  > (YY_MOVE (that.value));\n        break;\n\n      case symbol_kind::S_actions: // actions\n      case symbol_kind::S_actions_may_quoted: // actions_may_quoted\n        value.YY_MOVE_OR_COPY< std::unique_ptr<std::vector<std::unique_ptr<actions::Action> > >  > (YY_MOVE (that.value));\n        break;\n\n      default:\n        break;\n    }\n\n#if 201103L <= YY_CPLUSPLUS\n    // that is emptied.\n    that.state = empty_state;\n#endif\n  }\n\n  seclang_parser::stack_symbol_type::stack_symbol_type (state_type s, YY_MOVE_REF (symbol_type) that)\n    : super_type (s, YY_MOVE (that.location))\n  {\n    switch (that.kind ())\n    {\n      case symbol_kind::S_ACTION_ACCURACY: // \"Accuracy\"\n      case symbol_kind::S_ACTION_ALLOW: // \"Allow\"\n      case symbol_kind::S_ACTION_APPEND: // \"Append\"\n      case symbol_kind::S_ACTION_AUDIT_LOG: // \"AuditLog\"\n      case symbol_kind::S_ACTION_BLOCK: // \"Block\"\n      case symbol_kind::S_ACTION_CAPTURE: // \"Capture\"\n      case symbol_kind::S_ACTION_CHAIN: // \"Chain\"\n      case symbol_kind::S_ACTION_CTL_AUDIT_ENGINE: // \"ACTION_CTL_AUDIT_ENGINE\"\n      case symbol_kind::S_ACTION_CTL_AUDIT_LOG_PARTS: // \"ACTION_CTL_AUDIT_LOG_PARTS\"\n      case symbol_kind::S_ACTION_CTL_BDY_JSON: // \"ACTION_CTL_BDY_JSON\"\n      case symbol_kind::S_ACTION_CTL_BDY_XML: // \"ACTION_CTL_BDY_XML\"\n      case symbol_kind::S_ACTION_CTL_BDY_URLENCODED: // \"ACTION_CTL_BDY_URLENCODED\"\n      case symbol_kind::S_ACTION_CTL_FORCE_REQ_BODY_VAR: // \"ACTION_CTL_FORCE_REQ_BODY_VAR\"\n      case symbol_kind::S_ACTION_CTL_PARSE_XML_INTO_ARGS: // \"ACTION_CTL_PARSE_XML_INTO_ARGS\"\n      case symbol_kind::S_ACTION_CTL_REQUEST_BODY_ACCESS: // \"ACTION_CTL_REQUEST_BODY_ACCESS\"\n      case symbol_kind::S_ACTION_CTL_RULE_REMOVE_BY_ID: // \"ACTION_CTL_RULE_REMOVE_BY_ID\"\n      case symbol_kind::S_ACTION_CTL_RULE_REMOVE_BY_TAG: // \"ACTION_CTL_RULE_REMOVE_BY_TAG\"\n      case symbol_kind::S_ACTION_CTL_RULE_REMOVE_TARGET_BY_ID: // \"ACTION_CTL_RULE_REMOVE_TARGET_BY_ID\"\n      case symbol_kind::S_ACTION_CTL_RULE_REMOVE_TARGET_BY_TAG: // \"ACTION_CTL_RULE_REMOVE_TARGET_BY_TAG\"\n      case symbol_kind::S_ACTION_DENY: // \"Deny\"\n      case symbol_kind::S_ACTION_DEPRECATE_VAR: // \"DeprecateVar\"\n      case symbol_kind::S_ACTION_DROP: // \"Drop\"\n      case symbol_kind::S_ACTION_EXEC: // \"Exec\"\n      case symbol_kind::S_ACTION_EXPIRE_VAR: // \"ExpireVar\"\n      case symbol_kind::S_ACTION_ID: // \"Id\"\n      case symbol_kind::S_ACTION_INITCOL: // \"InitCol\"\n      case symbol_kind::S_ACTION_LOG: // \"Log\"\n      case symbol_kind::S_ACTION_LOG_DATA: // \"LogData\"\n      case symbol_kind::S_ACTION_MATURITY: // \"Maturity\"\n      case symbol_kind::S_ACTION_MSG: // \"Msg\"\n      case symbol_kind::S_ACTION_MULTI_MATCH: // \"MultiMatch\"\n      case symbol_kind::S_ACTION_NO_AUDIT_LOG: // \"NoAuditLog\"\n      case symbol_kind::S_ACTION_NO_LOG: // \"NoLog\"\n      case symbol_kind::S_ACTION_PASS: // \"Pass\"\n      case symbol_kind::S_ACTION_PAUSE: // \"Pause\"\n      case symbol_kind::S_ACTION_PHASE: // \"Phase\"\n      case symbol_kind::S_ACTION_PREPEND: // \"Prepend\"\n      case symbol_kind::S_ACTION_PROXY: // \"Proxy\"\n      case symbol_kind::S_ACTION_REDIRECT: // \"Redirect\"\n      case symbol_kind::S_ACTION_REV: // \"Rev\"\n      case symbol_kind::S_ACTION_SANITISE_ARG: // \"SanitiseArg\"\n      case symbol_kind::S_ACTION_SANITISE_MATCHED: // \"SanitiseMatched\"\n      case symbol_kind::S_ACTION_SANITISE_MATCHED_BYTES: // \"SanitiseMatchedBytes\"\n      case symbol_kind::S_ACTION_SANITISE_REQUEST_HEADER: // \"SanitiseRequestHeader\"\n      case symbol_kind::S_ACTION_SANITISE_RESPONSE_HEADER: // \"SanitiseResponseHeader\"\n      case symbol_kind::S_ACTION_SETENV: // \"SetEnv\"\n      case symbol_kind::S_ACTION_SETRSC: // \"SetRsc\"\n      case symbol_kind::S_ACTION_SETSID: // \"SetSid\"\n      case symbol_kind::S_ACTION_SETUID: // \"SetUID\"\n      case symbol_kind::S_ACTION_SEVERITY: // \"Severity\"\n      case symbol_kind::S_ACTION_SKIP: // \"Skip\"\n      case symbol_kind::S_ACTION_SKIP_AFTER: // \"SkipAfter\"\n      case symbol_kind::S_ACTION_STATUS: // \"Status\"\n      case symbol_kind::S_ACTION_TAG: // \"Tag\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_BASE_64_ENCODE: // \"ACTION_TRANSFORMATION_BASE_64_ENCODE\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_BASE_64_DECODE: // \"ACTION_TRANSFORMATION_BASE_64_DECODE\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_BASE_64_DECODE_EXT: // \"ACTION_TRANSFORMATION_BASE_64_DECODE_EXT\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_CMD_LINE: // \"ACTION_TRANSFORMATION_CMD_LINE\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_COMPRESS_WHITESPACE: // \"ACTION_TRANSFORMATION_COMPRESS_WHITESPACE\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_CSS_DECODE: // \"ACTION_TRANSFORMATION_CSS_DECODE\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_ESCAPE_SEQ_DECODE: // \"ACTION_TRANSFORMATION_ESCAPE_SEQ_DECODE\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_HEX_ENCODE: // \"ACTION_TRANSFORMATION_HEX_ENCODE\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_HEX_DECODE: // \"ACTION_TRANSFORMATION_HEX_DECODE\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_HTML_ENTITY_DECODE: // \"ACTION_TRANSFORMATION_HTML_ENTITY_DECODE\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_JS_DECODE: // \"ACTION_TRANSFORMATION_JS_DECODE\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_LENGTH: // \"ACTION_TRANSFORMATION_LENGTH\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_LOWERCASE: // \"ACTION_TRANSFORMATION_LOWERCASE\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_MD5: // \"ACTION_TRANSFORMATION_MD5\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_NONE: // \"ACTION_TRANSFORMATION_NONE\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_NORMALISE_PATH: // \"ACTION_TRANSFORMATION_NORMALISE_PATH\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_NORMALISE_PATH_WIN: // \"ACTION_TRANSFORMATION_NORMALISE_PATH_WIN\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_PARITY_EVEN_7_BIT: // \"ACTION_TRANSFORMATION_PARITY_EVEN_7_BIT\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_PARITY_ODD_7_BIT: // \"ACTION_TRANSFORMATION_PARITY_ODD_7_BIT\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_PARITY_ZERO_7_BIT: // \"ACTION_TRANSFORMATION_PARITY_ZERO_7_BIT\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_REMOVE_COMMENTS: // \"ACTION_TRANSFORMATION_REMOVE_COMMENTS\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_REMOVE_COMMENTS_CHAR: // \"ACTION_TRANSFORMATION_REMOVE_COMMENTS_CHAR\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_REMOVE_NULLS: // \"ACTION_TRANSFORMATION_REMOVE_NULLS\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_REMOVE_WHITESPACE: // \"ACTION_TRANSFORMATION_REMOVE_WHITESPACE\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_REPLACE_COMMENTS: // \"ACTION_TRANSFORMATION_REPLACE_COMMENTS\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_REPLACE_NULLS: // \"ACTION_TRANSFORMATION_REPLACE_NULLS\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_SHA1: // \"ACTION_TRANSFORMATION_SHA1\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_SQL_HEX_DECODE: // \"ACTION_TRANSFORMATION_SQL_HEX_DECODE\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_TRIM: // \"ACTION_TRANSFORMATION_TRIM\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_TRIM_LEFT: // \"ACTION_TRANSFORMATION_TRIM_LEFT\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_TRIM_RIGHT: // \"ACTION_TRANSFORMATION_TRIM_RIGHT\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_UPPERCASE: // \"ACTION_TRANSFORMATION_UPPERCASE\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_URL_ENCODE: // \"ACTION_TRANSFORMATION_URL_ENCODE\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_URL_DECODE: // \"ACTION_TRANSFORMATION_URL_DECODE\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_URL_DECODE_UNI: // \"ACTION_TRANSFORMATION_URL_DECODE_UNI\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_UTF8_TO_UNICODE: // \"ACTION_TRANSFORMATION_UTF8_TO_UNICODE\"\n      case symbol_kind::S_ACTION_VER: // \"Ver\"\n      case symbol_kind::S_ACTION_XMLNS: // \"xmlns\"\n      case symbol_kind::S_CONFIG_COMPONENT_SIG: // \"CONFIG_COMPONENT_SIG\"\n      case symbol_kind::S_CONFIG_CONN_ENGINE: // \"CONFIG_CONN_ENGINE\"\n      case symbol_kind::S_CONFIG_SEC_ARGUMENT_SEPARATOR: // \"CONFIG_SEC_ARGUMENT_SEPARATOR\"\n      case symbol_kind::S_CONFIG_SEC_WEB_APP_ID: // \"CONFIG_SEC_WEB_APP_ID\"\n      case symbol_kind::S_CONFIG_SEC_SERVER_SIG: // \"CONFIG_SEC_SERVER_SIG\"\n      case symbol_kind::S_CONFIG_DIR_AUDIT_DIR: // \"CONFIG_DIR_AUDIT_DIR\"\n      case symbol_kind::S_CONFIG_DIR_AUDIT_DIR_MOD: // \"CONFIG_DIR_AUDIT_DIR_MOD\"\n      case symbol_kind::S_CONFIG_DIR_AUDIT_ENG: // \"CONFIG_DIR_AUDIT_ENG\"\n      case symbol_kind::S_CONFIG_DIR_AUDIT_FLE_MOD: // \"CONFIG_DIR_AUDIT_FLE_MOD\"\n      case symbol_kind::S_CONFIG_DIR_AUDIT_LOG: // \"CONFIG_DIR_AUDIT_LOG\"\n      case symbol_kind::S_CONFIG_DIR_AUDIT_LOG2: // \"CONFIG_DIR_AUDIT_LOG2\"\n      case symbol_kind::S_CONFIG_DIR_AUDIT_LOG_P: // \"CONFIG_DIR_AUDIT_LOG_P\"\n      case symbol_kind::S_CONFIG_DIR_AUDIT_STS: // \"CONFIG_DIR_AUDIT_STS\"\n      case symbol_kind::S_CONFIG_DIR_AUDIT_PREFIX: // \"CONFIG_DIR_AUDIT_PREFIX\"\n      case symbol_kind::S_CONFIG_DIR_AUDIT_TPE: // \"CONFIG_DIR_AUDIT_TPE\"\n      case symbol_kind::S_CONFIG_DIR_DEBUG_LOG: // \"CONFIG_DIR_DEBUG_LOG\"\n      case symbol_kind::S_CONFIG_DIR_DEBUG_LVL: // \"CONFIG_DIR_DEBUG_LVL\"\n      case symbol_kind::S_CONFIG_SEC_CACHE_TRANSFORMATIONS: // \"CONFIG_SEC_CACHE_TRANSFORMATIONS\"\n      case symbol_kind::S_CONFIG_SEC_DISABLE_BACKEND_COMPRESS: // \"CONFIG_SEC_DISABLE_BACKEND_COMPRESS\"\n      case symbol_kind::S_CONFIG_SEC_HASH_ENGINE: // \"CONFIG_SEC_HASH_ENGINE\"\n      case symbol_kind::S_CONFIG_SEC_HASH_KEY: // \"CONFIG_SEC_HASH_KEY\"\n      case symbol_kind::S_CONFIG_SEC_HASH_PARAM: // \"CONFIG_SEC_HASH_PARAM\"\n      case symbol_kind::S_CONFIG_SEC_HASH_METHOD_RX: // \"CONFIG_SEC_HASH_METHOD_RX\"\n      case symbol_kind::S_CONFIG_SEC_HASH_METHOD_PM: // \"CONFIG_SEC_HASH_METHOD_PM\"\n      case symbol_kind::S_CONFIG_SEC_CHROOT_DIR: // \"CONFIG_SEC_CHROOT_DIR\"\n      case symbol_kind::S_CONFIG_DIR_GEO_DB: // \"CONFIG_DIR_GEO_DB\"\n      case symbol_kind::S_CONFIG_DIR_GSB_DB: // \"CONFIG_DIR_GSB_DB\"\n      case symbol_kind::S_CONFIG_SEC_GUARDIAN_LOG: // \"CONFIG_SEC_GUARDIAN_LOG\"\n      case symbol_kind::S_CONFIG_DIR_PCRE_MATCH_LIMIT: // \"CONFIG_DIR_PCRE_MATCH_LIMIT\"\n      case symbol_kind::S_CONFIG_DIR_PCRE_MATCH_LIMIT_RECURSION: // \"CONFIG_DIR_PCRE_MATCH_LIMIT_RECURSION\"\n      case symbol_kind::S_CONFIG_SEC_CONN_R_STATE_LIMIT: // \"CONFIG_SEC_CONN_R_STATE_LIMIT\"\n      case symbol_kind::S_CONFIG_SEC_CONN_W_STATE_LIMIT: // \"CONFIG_SEC_CONN_W_STATE_LIMIT\"\n      case symbol_kind::S_CONFIG_SEC_SENSOR_ID: // \"CONFIG_SEC_SENSOR_ID\"\n      case symbol_kind::S_CONFIG_DIR_ARGS_LIMIT: // \"CONFIG_DIR_ARGS_LIMIT\"\n      case symbol_kind::S_CONFIG_DIR_REQ_BODY_JSON_DEPTH_LIMIT: // \"CONFIG_DIR_REQ_BODY_JSON_DEPTH_LIMIT\"\n      case symbol_kind::S_CONFIG_DIR_REQ_BODY: // \"CONFIG_DIR_REQ_BODY\"\n      case symbol_kind::S_CONFIG_DIR_REQ_BODY_IN_MEMORY_LIMIT: // \"CONFIG_DIR_REQ_BODY_IN_MEMORY_LIMIT\"\n      case symbol_kind::S_CONFIG_DIR_REQ_BODY_LIMIT: // \"CONFIG_DIR_REQ_BODY_LIMIT\"\n      case symbol_kind::S_CONFIG_DIR_REQ_BODY_LIMIT_ACTION: // \"CONFIG_DIR_REQ_BODY_LIMIT_ACTION\"\n      case symbol_kind::S_CONFIG_DIR_REQ_BODY_NO_FILES_LIMIT: // \"CONFIG_DIR_REQ_BODY_NO_FILES_LIMIT\"\n      case symbol_kind::S_CONFIG_DIR_RES_BODY: // \"CONFIG_DIR_RES_BODY\"\n      case symbol_kind::S_CONFIG_DIR_RES_BODY_LIMIT: // \"CONFIG_DIR_RES_BODY_LIMIT\"\n      case symbol_kind::S_CONFIG_DIR_RES_BODY_LIMIT_ACTION: // \"CONFIG_DIR_RES_BODY_LIMIT_ACTION\"\n      case symbol_kind::S_CONFIG_SEC_RULE_INHERITANCE: // \"CONFIG_SEC_RULE_INHERITANCE\"\n      case symbol_kind::S_CONFIG_SEC_RULE_PERF_TIME: // \"CONFIG_SEC_RULE_PERF_TIME\"\n      case symbol_kind::S_CONFIG_DIR_RULE_ENG: // \"CONFIG_DIR_RULE_ENG\"\n      case symbol_kind::S_CONFIG_DIR_SEC_ACTION: // \"CONFIG_DIR_SEC_ACTION\"\n      case symbol_kind::S_CONFIG_DIR_SEC_DEFAULT_ACTION: // \"CONFIG_DIR_SEC_DEFAULT_ACTION\"\n      case symbol_kind::S_CONFIG_DIR_SEC_MARKER: // \"CONFIG_DIR_SEC_MARKER\"\n      case symbol_kind::S_CONFIG_DIR_UNICODE_MAP_FILE: // \"CONFIG_DIR_UNICODE_MAP_FILE\"\n      case symbol_kind::S_CONFIG_DIR_UNICODE_CODE_PAGE: // \"CONFIG_DIR_UNICODE_CODE_PAGE\"\n      case symbol_kind::S_CONFIG_SEC_COLLECTION_TIMEOUT: // \"CONFIG_SEC_COLLECTION_TIMEOUT\"\n      case symbol_kind::S_CONFIG_SEC_HTTP_BLKEY: // \"CONFIG_SEC_HTTP_BLKEY\"\n      case symbol_kind::S_CONFIG_SEC_INTERCEPT_ON_ERROR: // \"CONFIG_SEC_INTERCEPT_ON_ERROR\"\n      case symbol_kind::S_CONFIG_SEC_REMOTE_RULES_FAIL_ACTION: // \"CONFIG_SEC_REMOTE_RULES_FAIL_ACTION\"\n      case symbol_kind::S_CONFIG_SEC_RULE_REMOVE_BY_ID: // \"CONFIG_SEC_RULE_REMOVE_BY_ID\"\n      case symbol_kind::S_CONFIG_SEC_RULE_REMOVE_BY_MSG: // \"CONFIG_SEC_RULE_REMOVE_BY_MSG\"\n      case symbol_kind::S_CONFIG_SEC_RULE_REMOVE_BY_TAG: // \"CONFIG_SEC_RULE_REMOVE_BY_TAG\"\n      case symbol_kind::S_CONFIG_SEC_RULE_UPDATE_TARGET_BY_TAG: // \"CONFIG_SEC_RULE_UPDATE_TARGET_BY_TAG\"\n      case symbol_kind::S_CONFIG_SEC_RULE_UPDATE_TARGET_BY_MSG: // \"CONFIG_SEC_RULE_UPDATE_TARGET_BY_MSG\"\n      case symbol_kind::S_CONFIG_SEC_RULE_UPDATE_TARGET_BY_ID: // \"CONFIG_SEC_RULE_UPDATE_TARGET_BY_ID\"\n      case symbol_kind::S_CONFIG_SEC_RULE_UPDATE_ACTION_BY_ID: // \"CONFIG_SEC_RULE_UPDATE_ACTION_BY_ID\"\n      case symbol_kind::S_CONFIG_UPDLOAD_KEEP_FILES: // \"CONFIG_UPDLOAD_KEEP_FILES\"\n      case symbol_kind::S_CONFIG_UPDLOAD_SAVE_TMP_FILES: // \"CONFIG_UPDLOAD_SAVE_TMP_FILES\"\n      case symbol_kind::S_CONFIG_UPLOAD_DIR: // \"CONFIG_UPLOAD_DIR\"\n      case symbol_kind::S_CONFIG_UPLOAD_FILE_LIMIT: // \"CONFIG_UPLOAD_FILE_LIMIT\"\n      case symbol_kind::S_CONFIG_UPLOAD_FILE_MODE: // \"CONFIG_UPLOAD_FILE_MODE\"\n      case symbol_kind::S_CONFIG_VALUE_ABORT: // \"CONFIG_VALUE_ABORT\"\n      case symbol_kind::S_CONFIG_VALUE_DETC: // \"CONFIG_VALUE_DETC\"\n      case symbol_kind::S_CONFIG_VALUE_HTTPS: // \"CONFIG_VALUE_HTTPS\"\n      case symbol_kind::S_CONFIG_VALUE_ONLYARGS: // \"CONFIG_VALUE_ONLYARGS\"\n      case symbol_kind::S_CONFIG_VALUE_OFF: // \"CONFIG_VALUE_OFF\"\n      case symbol_kind::S_CONFIG_VALUE_ON: // \"CONFIG_VALUE_ON\"\n      case symbol_kind::S_CONFIG_VALUE_PARALLEL: // \"CONFIG_VALUE_PARALLEL\"\n      case symbol_kind::S_CONFIG_VALUE_PROCESS_PARTIAL: // \"CONFIG_VALUE_PROCESS_PARTIAL\"\n      case symbol_kind::S_CONFIG_VALUE_REJECT: // \"CONFIG_VALUE_REJECT\"\n      case symbol_kind::S_CONFIG_VALUE_RELEVANT_ONLY: // \"CONFIG_VALUE_RELEVANT_ONLY\"\n      case symbol_kind::S_CONFIG_VALUE_SERIAL: // \"CONFIG_VALUE_SERIAL\"\n      case symbol_kind::S_CONFIG_VALUE_WARN: // \"CONFIG_VALUE_WARN\"\n      case symbol_kind::S_CONFIG_XML_EXTERNAL_ENTITY: // \"CONFIG_XML_EXTERNAL_ENTITY\"\n      case symbol_kind::S_CONFIG_XML_PARSE_XML_INTO_ARGS: // \"CONFIG_XML_PARSE_XML_INTO_ARGS\"\n      case symbol_kind::S_CONGIG_DIR_RESPONSE_BODY_MP: // \"CONGIG_DIR_RESPONSE_BODY_MP\"\n      case symbol_kind::S_CONGIG_DIR_SEC_ARG_SEP: // \"CONGIG_DIR_SEC_ARG_SEP\"\n      case symbol_kind::S_CONGIG_DIR_SEC_COOKIE_FORMAT: // \"CONGIG_DIR_SEC_COOKIE_FORMAT\"\n      case symbol_kind::S_CONFIG_SEC_COOKIEV0_SEPARATOR: // \"CONFIG_SEC_COOKIEV0_SEPARATOR\"\n      case symbol_kind::S_CONGIG_DIR_SEC_DATA_DIR: // \"CONGIG_DIR_SEC_DATA_DIR\"\n      case symbol_kind::S_CONGIG_DIR_SEC_STATUS_ENGINE: // \"CONGIG_DIR_SEC_STATUS_ENGINE\"\n      case symbol_kind::S_CONFIG_SEC_STREAM_IN_BODY_INSPECTION: // \"CONFIG_SEC_STREAM_IN_BODY_INSPECTION\"\n      case symbol_kind::S_CONFIG_SEC_STREAM_OUT_BODY_INSPECTION: // \"CONFIG_SEC_STREAM_OUT_BODY_INSPECTION\"\n      case symbol_kind::S_CONGIG_DIR_SEC_TMP_DIR: // \"CONGIG_DIR_SEC_TMP_DIR\"\n      case symbol_kind::S_DIRECTIVE: // \"DIRECTIVE\"\n      case symbol_kind::S_DIRECTIVE_SECRULESCRIPT: // \"DIRECTIVE_SECRULESCRIPT\"\n      case symbol_kind::S_FREE_TEXT_QUOTE_MACRO_EXPANSION: // \"FREE_TEXT_QUOTE_MACRO_EXPANSION\"\n      case symbol_kind::S_QUOTATION_MARK: // \"QUOTATION_MARK\"\n      case symbol_kind::S_RUN_TIME_VAR_BLD: // \"RUN_TIME_VAR_BLD\"\n      case symbol_kind::S_RUN_TIME_VAR_DUR: // \"RUN_TIME_VAR_DUR\"\n      case symbol_kind::S_RUN_TIME_VAR_HSV: // \"RUN_TIME_VAR_HSV\"\n      case symbol_kind::S_RUN_TIME_VAR_REMOTE_USER: // \"RUN_TIME_VAR_REMOTE_USER\"\n      case symbol_kind::S_RUN_TIME_VAR_TIME: // \"RUN_TIME_VAR_TIME\"\n      case symbol_kind::S_RUN_TIME_VAR_TIME_DAY: // \"RUN_TIME_VAR_TIME_DAY\"\n      case symbol_kind::S_RUN_TIME_VAR_TIME_EPOCH: // \"RUN_TIME_VAR_TIME_EPOCH\"\n      case symbol_kind::S_RUN_TIME_VAR_TIME_HOUR: // \"RUN_TIME_VAR_TIME_HOUR\"\n      case symbol_kind::S_RUN_TIME_VAR_TIME_MIN: // \"RUN_TIME_VAR_TIME_MIN\"\n      case symbol_kind::S_RUN_TIME_VAR_TIME_MON: // \"RUN_TIME_VAR_TIME_MON\"\n      case symbol_kind::S_RUN_TIME_VAR_TIME_SEC: // \"RUN_TIME_VAR_TIME_SEC\"\n      case symbol_kind::S_RUN_TIME_VAR_TIME_WDAY: // \"RUN_TIME_VAR_TIME_WDAY\"\n      case symbol_kind::S_RUN_TIME_VAR_TIME_YEAR: // \"RUN_TIME_VAR_TIME_YEAR\"\n      case symbol_kind::S_VARIABLE: // \"VARIABLE\"\n      case symbol_kind::S_DICT_ELEMENT: // \"Dictionary element\"\n      case symbol_kind::S_DICT_ELEMENT_WITH_EQUALS: // \"Dictionary element, with equals\"\n      case symbol_kind::S_DICT_ELEMENT_REGEXP: // \"Dictionary element, selected by regexp\"\n        value.move< std::string > (YY_MOVE (that.value));\n        break;\n\n      case symbol_kind::S_op: // op\n      case symbol_kind::S_op_before_init: // op_before_init\n        value.move< std::unique_ptr<Operator> > (YY_MOVE (that.value));\n        break;\n\n      case symbol_kind::S_run_time_string: // run_time_string\n        value.move< std::unique_ptr<RunTimeString> > (YY_MOVE (that.value));\n        break;\n\n      case symbol_kind::S_var: // var\n        value.move< std::unique_ptr<Variable> > (YY_MOVE (that.value));\n        break;\n\n      case symbol_kind::S_act: // act\n      case symbol_kind::S_setvar_action: // setvar_action\n        value.move< std::unique_ptr<actions::Action> > (YY_MOVE (that.value));\n        break;\n\n      case symbol_kind::S_variables: // variables\n      case symbol_kind::S_variables_pre_process: // variables_pre_process\n      case symbol_kind::S_variables_may_be_quoted: // variables_may_be_quoted\n        value.move< std::unique_ptr<std::vector<std::unique_ptr<Variable> > >  > (YY_MOVE (that.value));\n        break;\n\n      case symbol_kind::S_actions: // actions\n      case symbol_kind::S_actions_may_quoted: // actions_may_quoted\n        value.move< std::unique_ptr<std::vector<std::unique_ptr<actions::Action> > >  > (YY_MOVE (that.value));\n        break;\n\n      default:\n        break;\n    }\n\n    // that is emptied.\n    that.kind_ = symbol_kind::S_YYEMPTY;\n  }\n\n#if YY_CPLUSPLUS < 201103L\n  seclang_parser::stack_symbol_type&\n  seclang_parser::stack_symbol_type::operator= (const stack_symbol_type& that)\n  {\n    state = that.state;\n    switch (that.kind ())\n    {\n      case symbol_kind::S_ACTION_ACCURACY: // \"Accuracy\"\n      case symbol_kind::S_ACTION_ALLOW: // \"Allow\"\n      case symbol_kind::S_ACTION_APPEND: // \"Append\"\n      case symbol_kind::S_ACTION_AUDIT_LOG: // \"AuditLog\"\n      case symbol_kind::S_ACTION_BLOCK: // \"Block\"\n      case symbol_kind::S_ACTION_CAPTURE: // \"Capture\"\n      case symbol_kind::S_ACTION_CHAIN: // \"Chain\"\n      case symbol_kind::S_ACTION_CTL_AUDIT_ENGINE: // \"ACTION_CTL_AUDIT_ENGINE\"\n      case symbol_kind::S_ACTION_CTL_AUDIT_LOG_PARTS: // \"ACTION_CTL_AUDIT_LOG_PARTS\"\n      case symbol_kind::S_ACTION_CTL_BDY_JSON: // \"ACTION_CTL_BDY_JSON\"\n      case symbol_kind::S_ACTION_CTL_BDY_XML: // \"ACTION_CTL_BDY_XML\"\n      case symbol_kind::S_ACTION_CTL_BDY_URLENCODED: // \"ACTION_CTL_BDY_URLENCODED\"\n      case symbol_kind::S_ACTION_CTL_FORCE_REQ_BODY_VAR: // \"ACTION_CTL_FORCE_REQ_BODY_VAR\"\n      case symbol_kind::S_ACTION_CTL_PARSE_XML_INTO_ARGS: // \"ACTION_CTL_PARSE_XML_INTO_ARGS\"\n      case symbol_kind::S_ACTION_CTL_REQUEST_BODY_ACCESS: // \"ACTION_CTL_REQUEST_BODY_ACCESS\"\n      case symbol_kind::S_ACTION_CTL_RULE_REMOVE_BY_ID: // \"ACTION_CTL_RULE_REMOVE_BY_ID\"\n      case symbol_kind::S_ACTION_CTL_RULE_REMOVE_BY_TAG: // \"ACTION_CTL_RULE_REMOVE_BY_TAG\"\n      case symbol_kind::S_ACTION_CTL_RULE_REMOVE_TARGET_BY_ID: // \"ACTION_CTL_RULE_REMOVE_TARGET_BY_ID\"\n      case symbol_kind::S_ACTION_CTL_RULE_REMOVE_TARGET_BY_TAG: // \"ACTION_CTL_RULE_REMOVE_TARGET_BY_TAG\"\n      case symbol_kind::S_ACTION_DENY: // \"Deny\"\n      case symbol_kind::S_ACTION_DEPRECATE_VAR: // \"DeprecateVar\"\n      case symbol_kind::S_ACTION_DROP: // \"Drop\"\n      case symbol_kind::S_ACTION_EXEC: // \"Exec\"\n      case symbol_kind::S_ACTION_EXPIRE_VAR: // \"ExpireVar\"\n      case symbol_kind::S_ACTION_ID: // \"Id\"\n      case symbol_kind::S_ACTION_INITCOL: // \"InitCol\"\n      case symbol_kind::S_ACTION_LOG: // \"Log\"\n      case symbol_kind::S_ACTION_LOG_DATA: // \"LogData\"\n      case symbol_kind::S_ACTION_MATURITY: // \"Maturity\"\n      case symbol_kind::S_ACTION_MSG: // \"Msg\"\n      case symbol_kind::S_ACTION_MULTI_MATCH: // \"MultiMatch\"\n      case symbol_kind::S_ACTION_NO_AUDIT_LOG: // \"NoAuditLog\"\n      case symbol_kind::S_ACTION_NO_LOG: // \"NoLog\"\n      case symbol_kind::S_ACTION_PASS: // \"Pass\"\n      case symbol_kind::S_ACTION_PAUSE: // \"Pause\"\n      case symbol_kind::S_ACTION_PHASE: // \"Phase\"\n      case symbol_kind::S_ACTION_PREPEND: // \"Prepend\"\n      case symbol_kind::S_ACTION_PROXY: // \"Proxy\"\n      case symbol_kind::S_ACTION_REDIRECT: // \"Redirect\"\n      case symbol_kind::S_ACTION_REV: // \"Rev\"\n      case symbol_kind::S_ACTION_SANITISE_ARG: // \"SanitiseArg\"\n      case symbol_kind::S_ACTION_SANITISE_MATCHED: // \"SanitiseMatched\"\n      case symbol_kind::S_ACTION_SANITISE_MATCHED_BYTES: // \"SanitiseMatchedBytes\"\n      case symbol_kind::S_ACTION_SANITISE_REQUEST_HEADER: // \"SanitiseRequestHeader\"\n      case symbol_kind::S_ACTION_SANITISE_RESPONSE_HEADER: // \"SanitiseResponseHeader\"\n      case symbol_kind::S_ACTION_SETENV: // \"SetEnv\"\n      case symbol_kind::S_ACTION_SETRSC: // \"SetRsc\"\n      case symbol_kind::S_ACTION_SETSID: // \"SetSid\"\n      case symbol_kind::S_ACTION_SETUID: // \"SetUID\"\n      case symbol_kind::S_ACTION_SEVERITY: // \"Severity\"\n      case symbol_kind::S_ACTION_SKIP: // \"Skip\"\n      case symbol_kind::S_ACTION_SKIP_AFTER: // \"SkipAfter\"\n      case symbol_kind::S_ACTION_STATUS: // \"Status\"\n      case symbol_kind::S_ACTION_TAG: // \"Tag\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_BASE_64_ENCODE: // \"ACTION_TRANSFORMATION_BASE_64_ENCODE\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_BASE_64_DECODE: // \"ACTION_TRANSFORMATION_BASE_64_DECODE\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_BASE_64_DECODE_EXT: // \"ACTION_TRANSFORMATION_BASE_64_DECODE_EXT\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_CMD_LINE: // \"ACTION_TRANSFORMATION_CMD_LINE\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_COMPRESS_WHITESPACE: // \"ACTION_TRANSFORMATION_COMPRESS_WHITESPACE\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_CSS_DECODE: // \"ACTION_TRANSFORMATION_CSS_DECODE\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_ESCAPE_SEQ_DECODE: // \"ACTION_TRANSFORMATION_ESCAPE_SEQ_DECODE\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_HEX_ENCODE: // \"ACTION_TRANSFORMATION_HEX_ENCODE\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_HEX_DECODE: // \"ACTION_TRANSFORMATION_HEX_DECODE\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_HTML_ENTITY_DECODE: // \"ACTION_TRANSFORMATION_HTML_ENTITY_DECODE\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_JS_DECODE: // \"ACTION_TRANSFORMATION_JS_DECODE\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_LENGTH: // \"ACTION_TRANSFORMATION_LENGTH\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_LOWERCASE: // \"ACTION_TRANSFORMATION_LOWERCASE\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_MD5: // \"ACTION_TRANSFORMATION_MD5\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_NONE: // \"ACTION_TRANSFORMATION_NONE\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_NORMALISE_PATH: // \"ACTION_TRANSFORMATION_NORMALISE_PATH\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_NORMALISE_PATH_WIN: // \"ACTION_TRANSFORMATION_NORMALISE_PATH_WIN\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_PARITY_EVEN_7_BIT: // \"ACTION_TRANSFORMATION_PARITY_EVEN_7_BIT\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_PARITY_ODD_7_BIT: // \"ACTION_TRANSFORMATION_PARITY_ODD_7_BIT\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_PARITY_ZERO_7_BIT: // \"ACTION_TRANSFORMATION_PARITY_ZERO_7_BIT\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_REMOVE_COMMENTS: // \"ACTION_TRANSFORMATION_REMOVE_COMMENTS\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_REMOVE_COMMENTS_CHAR: // \"ACTION_TRANSFORMATION_REMOVE_COMMENTS_CHAR\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_REMOVE_NULLS: // \"ACTION_TRANSFORMATION_REMOVE_NULLS\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_REMOVE_WHITESPACE: // \"ACTION_TRANSFORMATION_REMOVE_WHITESPACE\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_REPLACE_COMMENTS: // \"ACTION_TRANSFORMATION_REPLACE_COMMENTS\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_REPLACE_NULLS: // \"ACTION_TRANSFORMATION_REPLACE_NULLS\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_SHA1: // \"ACTION_TRANSFORMATION_SHA1\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_SQL_HEX_DECODE: // \"ACTION_TRANSFORMATION_SQL_HEX_DECODE\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_TRIM: // \"ACTION_TRANSFORMATION_TRIM\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_TRIM_LEFT: // \"ACTION_TRANSFORMATION_TRIM_LEFT\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_TRIM_RIGHT: // \"ACTION_TRANSFORMATION_TRIM_RIGHT\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_UPPERCASE: // \"ACTION_TRANSFORMATION_UPPERCASE\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_URL_ENCODE: // \"ACTION_TRANSFORMATION_URL_ENCODE\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_URL_DECODE: // \"ACTION_TRANSFORMATION_URL_DECODE\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_URL_DECODE_UNI: // \"ACTION_TRANSFORMATION_URL_DECODE_UNI\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_UTF8_TO_UNICODE: // \"ACTION_TRANSFORMATION_UTF8_TO_UNICODE\"\n      case symbol_kind::S_ACTION_VER: // \"Ver\"\n      case symbol_kind::S_ACTION_XMLNS: // \"xmlns\"\n      case symbol_kind::S_CONFIG_COMPONENT_SIG: // \"CONFIG_COMPONENT_SIG\"\n      case symbol_kind::S_CONFIG_CONN_ENGINE: // \"CONFIG_CONN_ENGINE\"\n      case symbol_kind::S_CONFIG_SEC_ARGUMENT_SEPARATOR: // \"CONFIG_SEC_ARGUMENT_SEPARATOR\"\n      case symbol_kind::S_CONFIG_SEC_WEB_APP_ID: // \"CONFIG_SEC_WEB_APP_ID\"\n      case symbol_kind::S_CONFIG_SEC_SERVER_SIG: // \"CONFIG_SEC_SERVER_SIG\"\n      case symbol_kind::S_CONFIG_DIR_AUDIT_DIR: // \"CONFIG_DIR_AUDIT_DIR\"\n      case symbol_kind::S_CONFIG_DIR_AUDIT_DIR_MOD: // \"CONFIG_DIR_AUDIT_DIR_MOD\"\n      case symbol_kind::S_CONFIG_DIR_AUDIT_ENG: // \"CONFIG_DIR_AUDIT_ENG\"\n      case symbol_kind::S_CONFIG_DIR_AUDIT_FLE_MOD: // \"CONFIG_DIR_AUDIT_FLE_MOD\"\n      case symbol_kind::S_CONFIG_DIR_AUDIT_LOG: // \"CONFIG_DIR_AUDIT_LOG\"\n      case symbol_kind::S_CONFIG_DIR_AUDIT_LOG2: // \"CONFIG_DIR_AUDIT_LOG2\"\n      case symbol_kind::S_CONFIG_DIR_AUDIT_LOG_P: // \"CONFIG_DIR_AUDIT_LOG_P\"\n      case symbol_kind::S_CONFIG_DIR_AUDIT_STS: // \"CONFIG_DIR_AUDIT_STS\"\n      case symbol_kind::S_CONFIG_DIR_AUDIT_PREFIX: // \"CONFIG_DIR_AUDIT_PREFIX\"\n      case symbol_kind::S_CONFIG_DIR_AUDIT_TPE: // \"CONFIG_DIR_AUDIT_TPE\"\n      case symbol_kind::S_CONFIG_DIR_DEBUG_LOG: // \"CONFIG_DIR_DEBUG_LOG\"\n      case symbol_kind::S_CONFIG_DIR_DEBUG_LVL: // \"CONFIG_DIR_DEBUG_LVL\"\n      case symbol_kind::S_CONFIG_SEC_CACHE_TRANSFORMATIONS: // \"CONFIG_SEC_CACHE_TRANSFORMATIONS\"\n      case symbol_kind::S_CONFIG_SEC_DISABLE_BACKEND_COMPRESS: // \"CONFIG_SEC_DISABLE_BACKEND_COMPRESS\"\n      case symbol_kind::S_CONFIG_SEC_HASH_ENGINE: // \"CONFIG_SEC_HASH_ENGINE\"\n      case symbol_kind::S_CONFIG_SEC_HASH_KEY: // \"CONFIG_SEC_HASH_KEY\"\n      case symbol_kind::S_CONFIG_SEC_HASH_PARAM: // \"CONFIG_SEC_HASH_PARAM\"\n      case symbol_kind::S_CONFIG_SEC_HASH_METHOD_RX: // \"CONFIG_SEC_HASH_METHOD_RX\"\n      case symbol_kind::S_CONFIG_SEC_HASH_METHOD_PM: // \"CONFIG_SEC_HASH_METHOD_PM\"\n      case symbol_kind::S_CONFIG_SEC_CHROOT_DIR: // \"CONFIG_SEC_CHROOT_DIR\"\n      case symbol_kind::S_CONFIG_DIR_GEO_DB: // \"CONFIG_DIR_GEO_DB\"\n      case symbol_kind::S_CONFIG_DIR_GSB_DB: // \"CONFIG_DIR_GSB_DB\"\n      case symbol_kind::S_CONFIG_SEC_GUARDIAN_LOG: // \"CONFIG_SEC_GUARDIAN_LOG\"\n      case symbol_kind::S_CONFIG_DIR_PCRE_MATCH_LIMIT: // \"CONFIG_DIR_PCRE_MATCH_LIMIT\"\n      case symbol_kind::S_CONFIG_DIR_PCRE_MATCH_LIMIT_RECURSION: // \"CONFIG_DIR_PCRE_MATCH_LIMIT_RECURSION\"\n      case symbol_kind::S_CONFIG_SEC_CONN_R_STATE_LIMIT: // \"CONFIG_SEC_CONN_R_STATE_LIMIT\"\n      case symbol_kind::S_CONFIG_SEC_CONN_W_STATE_LIMIT: // \"CONFIG_SEC_CONN_W_STATE_LIMIT\"\n      case symbol_kind::S_CONFIG_SEC_SENSOR_ID: // \"CONFIG_SEC_SENSOR_ID\"\n      case symbol_kind::S_CONFIG_DIR_ARGS_LIMIT: // \"CONFIG_DIR_ARGS_LIMIT\"\n      case symbol_kind::S_CONFIG_DIR_REQ_BODY_JSON_DEPTH_LIMIT: // \"CONFIG_DIR_REQ_BODY_JSON_DEPTH_LIMIT\"\n      case symbol_kind::S_CONFIG_DIR_REQ_BODY: // \"CONFIG_DIR_REQ_BODY\"\n      case symbol_kind::S_CONFIG_DIR_REQ_BODY_IN_MEMORY_LIMIT: // \"CONFIG_DIR_REQ_BODY_IN_MEMORY_LIMIT\"\n      case symbol_kind::S_CONFIG_DIR_REQ_BODY_LIMIT: // \"CONFIG_DIR_REQ_BODY_LIMIT\"\n      case symbol_kind::S_CONFIG_DIR_REQ_BODY_LIMIT_ACTION: // \"CONFIG_DIR_REQ_BODY_LIMIT_ACTION\"\n      case symbol_kind::S_CONFIG_DIR_REQ_BODY_NO_FILES_LIMIT: // \"CONFIG_DIR_REQ_BODY_NO_FILES_LIMIT\"\n      case symbol_kind::S_CONFIG_DIR_RES_BODY: // \"CONFIG_DIR_RES_BODY\"\n      case symbol_kind::S_CONFIG_DIR_RES_BODY_LIMIT: // \"CONFIG_DIR_RES_BODY_LIMIT\"\n      case symbol_kind::S_CONFIG_DIR_RES_BODY_LIMIT_ACTION: // \"CONFIG_DIR_RES_BODY_LIMIT_ACTION\"\n      case symbol_kind::S_CONFIG_SEC_RULE_INHERITANCE: // \"CONFIG_SEC_RULE_INHERITANCE\"\n      case symbol_kind::S_CONFIG_SEC_RULE_PERF_TIME: // \"CONFIG_SEC_RULE_PERF_TIME\"\n      case symbol_kind::S_CONFIG_DIR_RULE_ENG: // \"CONFIG_DIR_RULE_ENG\"\n      case symbol_kind::S_CONFIG_DIR_SEC_ACTION: // \"CONFIG_DIR_SEC_ACTION\"\n      case symbol_kind::S_CONFIG_DIR_SEC_DEFAULT_ACTION: // \"CONFIG_DIR_SEC_DEFAULT_ACTION\"\n      case symbol_kind::S_CONFIG_DIR_SEC_MARKER: // \"CONFIG_DIR_SEC_MARKER\"\n      case symbol_kind::S_CONFIG_DIR_UNICODE_MAP_FILE: // \"CONFIG_DIR_UNICODE_MAP_FILE\"\n      case symbol_kind::S_CONFIG_DIR_UNICODE_CODE_PAGE: // \"CONFIG_DIR_UNICODE_CODE_PAGE\"\n      case symbol_kind::S_CONFIG_SEC_COLLECTION_TIMEOUT: // \"CONFIG_SEC_COLLECTION_TIMEOUT\"\n      case symbol_kind::S_CONFIG_SEC_HTTP_BLKEY: // \"CONFIG_SEC_HTTP_BLKEY\"\n      case symbol_kind::S_CONFIG_SEC_INTERCEPT_ON_ERROR: // \"CONFIG_SEC_INTERCEPT_ON_ERROR\"\n      case symbol_kind::S_CONFIG_SEC_REMOTE_RULES_FAIL_ACTION: // \"CONFIG_SEC_REMOTE_RULES_FAIL_ACTION\"\n      case symbol_kind::S_CONFIG_SEC_RULE_REMOVE_BY_ID: // \"CONFIG_SEC_RULE_REMOVE_BY_ID\"\n      case symbol_kind::S_CONFIG_SEC_RULE_REMOVE_BY_MSG: // \"CONFIG_SEC_RULE_REMOVE_BY_MSG\"\n      case symbol_kind::S_CONFIG_SEC_RULE_REMOVE_BY_TAG: // \"CONFIG_SEC_RULE_REMOVE_BY_TAG\"\n      case symbol_kind::S_CONFIG_SEC_RULE_UPDATE_TARGET_BY_TAG: // \"CONFIG_SEC_RULE_UPDATE_TARGET_BY_TAG\"\n      case symbol_kind::S_CONFIG_SEC_RULE_UPDATE_TARGET_BY_MSG: // \"CONFIG_SEC_RULE_UPDATE_TARGET_BY_MSG\"\n      case symbol_kind::S_CONFIG_SEC_RULE_UPDATE_TARGET_BY_ID: // \"CONFIG_SEC_RULE_UPDATE_TARGET_BY_ID\"\n      case symbol_kind::S_CONFIG_SEC_RULE_UPDATE_ACTION_BY_ID: // \"CONFIG_SEC_RULE_UPDATE_ACTION_BY_ID\"\n      case symbol_kind::S_CONFIG_UPDLOAD_KEEP_FILES: // \"CONFIG_UPDLOAD_KEEP_FILES\"\n      case symbol_kind::S_CONFIG_UPDLOAD_SAVE_TMP_FILES: // \"CONFIG_UPDLOAD_SAVE_TMP_FILES\"\n      case symbol_kind::S_CONFIG_UPLOAD_DIR: // \"CONFIG_UPLOAD_DIR\"\n      case symbol_kind::S_CONFIG_UPLOAD_FILE_LIMIT: // \"CONFIG_UPLOAD_FILE_LIMIT\"\n      case symbol_kind::S_CONFIG_UPLOAD_FILE_MODE: // \"CONFIG_UPLOAD_FILE_MODE\"\n      case symbol_kind::S_CONFIG_VALUE_ABORT: // \"CONFIG_VALUE_ABORT\"\n      case symbol_kind::S_CONFIG_VALUE_DETC: // \"CONFIG_VALUE_DETC\"\n      case symbol_kind::S_CONFIG_VALUE_HTTPS: // \"CONFIG_VALUE_HTTPS\"\n      case symbol_kind::S_CONFIG_VALUE_ONLYARGS: // \"CONFIG_VALUE_ONLYARGS\"\n      case symbol_kind::S_CONFIG_VALUE_OFF: // \"CONFIG_VALUE_OFF\"\n      case symbol_kind::S_CONFIG_VALUE_ON: // \"CONFIG_VALUE_ON\"\n      case symbol_kind::S_CONFIG_VALUE_PARALLEL: // \"CONFIG_VALUE_PARALLEL\"\n      case symbol_kind::S_CONFIG_VALUE_PROCESS_PARTIAL: // \"CONFIG_VALUE_PROCESS_PARTIAL\"\n      case symbol_kind::S_CONFIG_VALUE_REJECT: // \"CONFIG_VALUE_REJECT\"\n      case symbol_kind::S_CONFIG_VALUE_RELEVANT_ONLY: // \"CONFIG_VALUE_RELEVANT_ONLY\"\n      case symbol_kind::S_CONFIG_VALUE_SERIAL: // \"CONFIG_VALUE_SERIAL\"\n      case symbol_kind::S_CONFIG_VALUE_WARN: // \"CONFIG_VALUE_WARN\"\n      case symbol_kind::S_CONFIG_XML_EXTERNAL_ENTITY: // \"CONFIG_XML_EXTERNAL_ENTITY\"\n      case symbol_kind::S_CONFIG_XML_PARSE_XML_INTO_ARGS: // \"CONFIG_XML_PARSE_XML_INTO_ARGS\"\n      case symbol_kind::S_CONGIG_DIR_RESPONSE_BODY_MP: // \"CONGIG_DIR_RESPONSE_BODY_MP\"\n      case symbol_kind::S_CONGIG_DIR_SEC_ARG_SEP: // \"CONGIG_DIR_SEC_ARG_SEP\"\n      case symbol_kind::S_CONGIG_DIR_SEC_COOKIE_FORMAT: // \"CONGIG_DIR_SEC_COOKIE_FORMAT\"\n      case symbol_kind::S_CONFIG_SEC_COOKIEV0_SEPARATOR: // \"CONFIG_SEC_COOKIEV0_SEPARATOR\"\n      case symbol_kind::S_CONGIG_DIR_SEC_DATA_DIR: // \"CONGIG_DIR_SEC_DATA_DIR\"\n      case symbol_kind::S_CONGIG_DIR_SEC_STATUS_ENGINE: // \"CONGIG_DIR_SEC_STATUS_ENGINE\"\n      case symbol_kind::S_CONFIG_SEC_STREAM_IN_BODY_INSPECTION: // \"CONFIG_SEC_STREAM_IN_BODY_INSPECTION\"\n      case symbol_kind::S_CONFIG_SEC_STREAM_OUT_BODY_INSPECTION: // \"CONFIG_SEC_STREAM_OUT_BODY_INSPECTION\"\n      case symbol_kind::S_CONGIG_DIR_SEC_TMP_DIR: // \"CONGIG_DIR_SEC_TMP_DIR\"\n      case symbol_kind::S_DIRECTIVE: // \"DIRECTIVE\"\n      case symbol_kind::S_DIRECTIVE_SECRULESCRIPT: // \"DIRECTIVE_SECRULESCRIPT\"\n      case symbol_kind::S_FREE_TEXT_QUOTE_MACRO_EXPANSION: // \"FREE_TEXT_QUOTE_MACRO_EXPANSION\"\n      case symbol_kind::S_QUOTATION_MARK: // \"QUOTATION_MARK\"\n      case symbol_kind::S_RUN_TIME_VAR_BLD: // \"RUN_TIME_VAR_BLD\"\n      case symbol_kind::S_RUN_TIME_VAR_DUR: // \"RUN_TIME_VAR_DUR\"\n      case symbol_kind::S_RUN_TIME_VAR_HSV: // \"RUN_TIME_VAR_HSV\"\n      case symbol_kind::S_RUN_TIME_VAR_REMOTE_USER: // \"RUN_TIME_VAR_REMOTE_USER\"\n      case symbol_kind::S_RUN_TIME_VAR_TIME: // \"RUN_TIME_VAR_TIME\"\n      case symbol_kind::S_RUN_TIME_VAR_TIME_DAY: // \"RUN_TIME_VAR_TIME_DAY\"\n      case symbol_kind::S_RUN_TIME_VAR_TIME_EPOCH: // \"RUN_TIME_VAR_TIME_EPOCH\"\n      case symbol_kind::S_RUN_TIME_VAR_TIME_HOUR: // \"RUN_TIME_VAR_TIME_HOUR\"\n      case symbol_kind::S_RUN_TIME_VAR_TIME_MIN: // \"RUN_TIME_VAR_TIME_MIN\"\n      case symbol_kind::S_RUN_TIME_VAR_TIME_MON: // \"RUN_TIME_VAR_TIME_MON\"\n      case symbol_kind::S_RUN_TIME_VAR_TIME_SEC: // \"RUN_TIME_VAR_TIME_SEC\"\n      case symbol_kind::S_RUN_TIME_VAR_TIME_WDAY: // \"RUN_TIME_VAR_TIME_WDAY\"\n      case symbol_kind::S_RUN_TIME_VAR_TIME_YEAR: // \"RUN_TIME_VAR_TIME_YEAR\"\n      case symbol_kind::S_VARIABLE: // \"VARIABLE\"\n      case symbol_kind::S_DICT_ELEMENT: // \"Dictionary element\"\n      case symbol_kind::S_DICT_ELEMENT_WITH_EQUALS: // \"Dictionary element, with equals\"\n      case symbol_kind::S_DICT_ELEMENT_REGEXP: // \"Dictionary element, selected by regexp\"\n        value.copy< std::string > (that.value);\n        break;\n\n      case symbol_kind::S_op: // op\n      case symbol_kind::S_op_before_init: // op_before_init\n        value.copy< std::unique_ptr<Operator> > (that.value);\n        break;\n\n      case symbol_kind::S_run_time_string: // run_time_string\n        value.copy< std::unique_ptr<RunTimeString> > (that.value);\n        break;\n\n      case symbol_kind::S_var: // var\n        value.copy< std::unique_ptr<Variable> > (that.value);\n        break;\n\n      case symbol_kind::S_act: // act\n      case symbol_kind::S_setvar_action: // setvar_action\n        value.copy< std::unique_ptr<actions::Action> > (that.value);\n        break;\n\n      case symbol_kind::S_variables: // variables\n      case symbol_kind::S_variables_pre_process: // variables_pre_process\n      case symbol_kind::S_variables_may_be_quoted: // variables_may_be_quoted\n        value.copy< std::unique_ptr<std::vector<std::unique_ptr<Variable> > >  > (that.value);\n        break;\n\n      case symbol_kind::S_actions: // actions\n      case symbol_kind::S_actions_may_quoted: // actions_may_quoted\n        value.copy< std::unique_ptr<std::vector<std::unique_ptr<actions::Action> > >  > (that.value);\n        break;\n\n      default:\n        break;\n    }\n\n    location = that.location;\n    return *this;\n  }\n\n  seclang_parser::stack_symbol_type&\n  seclang_parser::stack_symbol_type::operator= (stack_symbol_type& that)\n  {\n    state = that.state;\n    switch (that.kind ())\n    {\n      case symbol_kind::S_ACTION_ACCURACY: // \"Accuracy\"\n      case symbol_kind::S_ACTION_ALLOW: // \"Allow\"\n      case symbol_kind::S_ACTION_APPEND: // \"Append\"\n      case symbol_kind::S_ACTION_AUDIT_LOG: // \"AuditLog\"\n      case symbol_kind::S_ACTION_BLOCK: // \"Block\"\n      case symbol_kind::S_ACTION_CAPTURE: // \"Capture\"\n      case symbol_kind::S_ACTION_CHAIN: // \"Chain\"\n      case symbol_kind::S_ACTION_CTL_AUDIT_ENGINE: // \"ACTION_CTL_AUDIT_ENGINE\"\n      case symbol_kind::S_ACTION_CTL_AUDIT_LOG_PARTS: // \"ACTION_CTL_AUDIT_LOG_PARTS\"\n      case symbol_kind::S_ACTION_CTL_BDY_JSON: // \"ACTION_CTL_BDY_JSON\"\n      case symbol_kind::S_ACTION_CTL_BDY_XML: // \"ACTION_CTL_BDY_XML\"\n      case symbol_kind::S_ACTION_CTL_BDY_URLENCODED: // \"ACTION_CTL_BDY_URLENCODED\"\n      case symbol_kind::S_ACTION_CTL_FORCE_REQ_BODY_VAR: // \"ACTION_CTL_FORCE_REQ_BODY_VAR\"\n      case symbol_kind::S_ACTION_CTL_PARSE_XML_INTO_ARGS: // \"ACTION_CTL_PARSE_XML_INTO_ARGS\"\n      case symbol_kind::S_ACTION_CTL_REQUEST_BODY_ACCESS: // \"ACTION_CTL_REQUEST_BODY_ACCESS\"\n      case symbol_kind::S_ACTION_CTL_RULE_REMOVE_BY_ID: // \"ACTION_CTL_RULE_REMOVE_BY_ID\"\n      case symbol_kind::S_ACTION_CTL_RULE_REMOVE_BY_TAG: // \"ACTION_CTL_RULE_REMOVE_BY_TAG\"\n      case symbol_kind::S_ACTION_CTL_RULE_REMOVE_TARGET_BY_ID: // \"ACTION_CTL_RULE_REMOVE_TARGET_BY_ID\"\n      case symbol_kind::S_ACTION_CTL_RULE_REMOVE_TARGET_BY_TAG: // \"ACTION_CTL_RULE_REMOVE_TARGET_BY_TAG\"\n      case symbol_kind::S_ACTION_DENY: // \"Deny\"\n      case symbol_kind::S_ACTION_DEPRECATE_VAR: // \"DeprecateVar\"\n      case symbol_kind::S_ACTION_DROP: // \"Drop\"\n      case symbol_kind::S_ACTION_EXEC: // \"Exec\"\n      case symbol_kind::S_ACTION_EXPIRE_VAR: // \"ExpireVar\"\n      case symbol_kind::S_ACTION_ID: // \"Id\"\n      case symbol_kind::S_ACTION_INITCOL: // \"InitCol\"\n      case symbol_kind::S_ACTION_LOG: // \"Log\"\n      case symbol_kind::S_ACTION_LOG_DATA: // \"LogData\"\n      case symbol_kind::S_ACTION_MATURITY: // \"Maturity\"\n      case symbol_kind::S_ACTION_MSG: // \"Msg\"\n      case symbol_kind::S_ACTION_MULTI_MATCH: // \"MultiMatch\"\n      case symbol_kind::S_ACTION_NO_AUDIT_LOG: // \"NoAuditLog\"\n      case symbol_kind::S_ACTION_NO_LOG: // \"NoLog\"\n      case symbol_kind::S_ACTION_PASS: // \"Pass\"\n      case symbol_kind::S_ACTION_PAUSE: // \"Pause\"\n      case symbol_kind::S_ACTION_PHASE: // \"Phase\"\n      case symbol_kind::S_ACTION_PREPEND: // \"Prepend\"\n      case symbol_kind::S_ACTION_PROXY: // \"Proxy\"\n      case symbol_kind::S_ACTION_REDIRECT: // \"Redirect\"\n      case symbol_kind::S_ACTION_REV: // \"Rev\"\n      case symbol_kind::S_ACTION_SANITISE_ARG: // \"SanitiseArg\"\n      case symbol_kind::S_ACTION_SANITISE_MATCHED: // \"SanitiseMatched\"\n      case symbol_kind::S_ACTION_SANITISE_MATCHED_BYTES: // \"SanitiseMatchedBytes\"\n      case symbol_kind::S_ACTION_SANITISE_REQUEST_HEADER: // \"SanitiseRequestHeader\"\n      case symbol_kind::S_ACTION_SANITISE_RESPONSE_HEADER: // \"SanitiseResponseHeader\"\n      case symbol_kind::S_ACTION_SETENV: // \"SetEnv\"\n      case symbol_kind::S_ACTION_SETRSC: // \"SetRsc\"\n      case symbol_kind::S_ACTION_SETSID: // \"SetSid\"\n      case symbol_kind::S_ACTION_SETUID: // \"SetUID\"\n      case symbol_kind::S_ACTION_SEVERITY: // \"Severity\"\n      case symbol_kind::S_ACTION_SKIP: // \"Skip\"\n      case symbol_kind::S_ACTION_SKIP_AFTER: // \"SkipAfter\"\n      case symbol_kind::S_ACTION_STATUS: // \"Status\"\n      case symbol_kind::S_ACTION_TAG: // \"Tag\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_BASE_64_ENCODE: // \"ACTION_TRANSFORMATION_BASE_64_ENCODE\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_BASE_64_DECODE: // \"ACTION_TRANSFORMATION_BASE_64_DECODE\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_BASE_64_DECODE_EXT: // \"ACTION_TRANSFORMATION_BASE_64_DECODE_EXT\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_CMD_LINE: // \"ACTION_TRANSFORMATION_CMD_LINE\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_COMPRESS_WHITESPACE: // \"ACTION_TRANSFORMATION_COMPRESS_WHITESPACE\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_CSS_DECODE: // \"ACTION_TRANSFORMATION_CSS_DECODE\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_ESCAPE_SEQ_DECODE: // \"ACTION_TRANSFORMATION_ESCAPE_SEQ_DECODE\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_HEX_ENCODE: // \"ACTION_TRANSFORMATION_HEX_ENCODE\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_HEX_DECODE: // \"ACTION_TRANSFORMATION_HEX_DECODE\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_HTML_ENTITY_DECODE: // \"ACTION_TRANSFORMATION_HTML_ENTITY_DECODE\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_JS_DECODE: // \"ACTION_TRANSFORMATION_JS_DECODE\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_LENGTH: // \"ACTION_TRANSFORMATION_LENGTH\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_LOWERCASE: // \"ACTION_TRANSFORMATION_LOWERCASE\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_MD5: // \"ACTION_TRANSFORMATION_MD5\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_NONE: // \"ACTION_TRANSFORMATION_NONE\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_NORMALISE_PATH: // \"ACTION_TRANSFORMATION_NORMALISE_PATH\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_NORMALISE_PATH_WIN: // \"ACTION_TRANSFORMATION_NORMALISE_PATH_WIN\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_PARITY_EVEN_7_BIT: // \"ACTION_TRANSFORMATION_PARITY_EVEN_7_BIT\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_PARITY_ODD_7_BIT: // \"ACTION_TRANSFORMATION_PARITY_ODD_7_BIT\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_PARITY_ZERO_7_BIT: // \"ACTION_TRANSFORMATION_PARITY_ZERO_7_BIT\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_REMOVE_COMMENTS: // \"ACTION_TRANSFORMATION_REMOVE_COMMENTS\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_REMOVE_COMMENTS_CHAR: // \"ACTION_TRANSFORMATION_REMOVE_COMMENTS_CHAR\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_REMOVE_NULLS: // \"ACTION_TRANSFORMATION_REMOVE_NULLS\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_REMOVE_WHITESPACE: // \"ACTION_TRANSFORMATION_REMOVE_WHITESPACE\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_REPLACE_COMMENTS: // \"ACTION_TRANSFORMATION_REPLACE_COMMENTS\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_REPLACE_NULLS: // \"ACTION_TRANSFORMATION_REPLACE_NULLS\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_SHA1: // \"ACTION_TRANSFORMATION_SHA1\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_SQL_HEX_DECODE: // \"ACTION_TRANSFORMATION_SQL_HEX_DECODE\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_TRIM: // \"ACTION_TRANSFORMATION_TRIM\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_TRIM_LEFT: // \"ACTION_TRANSFORMATION_TRIM_LEFT\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_TRIM_RIGHT: // \"ACTION_TRANSFORMATION_TRIM_RIGHT\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_UPPERCASE: // \"ACTION_TRANSFORMATION_UPPERCASE\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_URL_ENCODE: // \"ACTION_TRANSFORMATION_URL_ENCODE\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_URL_DECODE: // \"ACTION_TRANSFORMATION_URL_DECODE\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_URL_DECODE_UNI: // \"ACTION_TRANSFORMATION_URL_DECODE_UNI\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_UTF8_TO_UNICODE: // \"ACTION_TRANSFORMATION_UTF8_TO_UNICODE\"\n      case symbol_kind::S_ACTION_VER: // \"Ver\"\n      case symbol_kind::S_ACTION_XMLNS: // \"xmlns\"\n      case symbol_kind::S_CONFIG_COMPONENT_SIG: // \"CONFIG_COMPONENT_SIG\"\n      case symbol_kind::S_CONFIG_CONN_ENGINE: // \"CONFIG_CONN_ENGINE\"\n      case symbol_kind::S_CONFIG_SEC_ARGUMENT_SEPARATOR: // \"CONFIG_SEC_ARGUMENT_SEPARATOR\"\n      case symbol_kind::S_CONFIG_SEC_WEB_APP_ID: // \"CONFIG_SEC_WEB_APP_ID\"\n      case symbol_kind::S_CONFIG_SEC_SERVER_SIG: // \"CONFIG_SEC_SERVER_SIG\"\n      case symbol_kind::S_CONFIG_DIR_AUDIT_DIR: // \"CONFIG_DIR_AUDIT_DIR\"\n      case symbol_kind::S_CONFIG_DIR_AUDIT_DIR_MOD: // \"CONFIG_DIR_AUDIT_DIR_MOD\"\n      case symbol_kind::S_CONFIG_DIR_AUDIT_ENG: // \"CONFIG_DIR_AUDIT_ENG\"\n      case symbol_kind::S_CONFIG_DIR_AUDIT_FLE_MOD: // \"CONFIG_DIR_AUDIT_FLE_MOD\"\n      case symbol_kind::S_CONFIG_DIR_AUDIT_LOG: // \"CONFIG_DIR_AUDIT_LOG\"\n      case symbol_kind::S_CONFIG_DIR_AUDIT_LOG2: // \"CONFIG_DIR_AUDIT_LOG2\"\n      case symbol_kind::S_CONFIG_DIR_AUDIT_LOG_P: // \"CONFIG_DIR_AUDIT_LOG_P\"\n      case symbol_kind::S_CONFIG_DIR_AUDIT_STS: // \"CONFIG_DIR_AUDIT_STS\"\n      case symbol_kind::S_CONFIG_DIR_AUDIT_PREFIX: // \"CONFIG_DIR_AUDIT_PREFIX\"\n      case symbol_kind::S_CONFIG_DIR_AUDIT_TPE: // \"CONFIG_DIR_AUDIT_TPE\"\n      case symbol_kind::S_CONFIG_DIR_DEBUG_LOG: // \"CONFIG_DIR_DEBUG_LOG\"\n      case symbol_kind::S_CONFIG_DIR_DEBUG_LVL: // \"CONFIG_DIR_DEBUG_LVL\"\n      case symbol_kind::S_CONFIG_SEC_CACHE_TRANSFORMATIONS: // \"CONFIG_SEC_CACHE_TRANSFORMATIONS\"\n      case symbol_kind::S_CONFIG_SEC_DISABLE_BACKEND_COMPRESS: // \"CONFIG_SEC_DISABLE_BACKEND_COMPRESS\"\n      case symbol_kind::S_CONFIG_SEC_HASH_ENGINE: // \"CONFIG_SEC_HASH_ENGINE\"\n      case symbol_kind::S_CONFIG_SEC_HASH_KEY: // \"CONFIG_SEC_HASH_KEY\"\n      case symbol_kind::S_CONFIG_SEC_HASH_PARAM: // \"CONFIG_SEC_HASH_PARAM\"\n      case symbol_kind::S_CONFIG_SEC_HASH_METHOD_RX: // \"CONFIG_SEC_HASH_METHOD_RX\"\n      case symbol_kind::S_CONFIG_SEC_HASH_METHOD_PM: // \"CONFIG_SEC_HASH_METHOD_PM\"\n      case symbol_kind::S_CONFIG_SEC_CHROOT_DIR: // \"CONFIG_SEC_CHROOT_DIR\"\n      case symbol_kind::S_CONFIG_DIR_GEO_DB: // \"CONFIG_DIR_GEO_DB\"\n      case symbol_kind::S_CONFIG_DIR_GSB_DB: // \"CONFIG_DIR_GSB_DB\"\n      case symbol_kind::S_CONFIG_SEC_GUARDIAN_LOG: // \"CONFIG_SEC_GUARDIAN_LOG\"\n      case symbol_kind::S_CONFIG_DIR_PCRE_MATCH_LIMIT: // \"CONFIG_DIR_PCRE_MATCH_LIMIT\"\n      case symbol_kind::S_CONFIG_DIR_PCRE_MATCH_LIMIT_RECURSION: // \"CONFIG_DIR_PCRE_MATCH_LIMIT_RECURSION\"\n      case symbol_kind::S_CONFIG_SEC_CONN_R_STATE_LIMIT: // \"CONFIG_SEC_CONN_R_STATE_LIMIT\"\n      case symbol_kind::S_CONFIG_SEC_CONN_W_STATE_LIMIT: // \"CONFIG_SEC_CONN_W_STATE_LIMIT\"\n      case symbol_kind::S_CONFIG_SEC_SENSOR_ID: // \"CONFIG_SEC_SENSOR_ID\"\n      case symbol_kind::S_CONFIG_DIR_ARGS_LIMIT: // \"CONFIG_DIR_ARGS_LIMIT\"\n      case symbol_kind::S_CONFIG_DIR_REQ_BODY_JSON_DEPTH_LIMIT: // \"CONFIG_DIR_REQ_BODY_JSON_DEPTH_LIMIT\"\n      case symbol_kind::S_CONFIG_DIR_REQ_BODY: // \"CONFIG_DIR_REQ_BODY\"\n      case symbol_kind::S_CONFIG_DIR_REQ_BODY_IN_MEMORY_LIMIT: // \"CONFIG_DIR_REQ_BODY_IN_MEMORY_LIMIT\"\n      case symbol_kind::S_CONFIG_DIR_REQ_BODY_LIMIT: // \"CONFIG_DIR_REQ_BODY_LIMIT\"\n      case symbol_kind::S_CONFIG_DIR_REQ_BODY_LIMIT_ACTION: // \"CONFIG_DIR_REQ_BODY_LIMIT_ACTION\"\n      case symbol_kind::S_CONFIG_DIR_REQ_BODY_NO_FILES_LIMIT: // \"CONFIG_DIR_REQ_BODY_NO_FILES_LIMIT\"\n      case symbol_kind::S_CONFIG_DIR_RES_BODY: // \"CONFIG_DIR_RES_BODY\"\n      case symbol_kind::S_CONFIG_DIR_RES_BODY_LIMIT: // \"CONFIG_DIR_RES_BODY_LIMIT\"\n      case symbol_kind::S_CONFIG_DIR_RES_BODY_LIMIT_ACTION: // \"CONFIG_DIR_RES_BODY_LIMIT_ACTION\"\n      case symbol_kind::S_CONFIG_SEC_RULE_INHERITANCE: // \"CONFIG_SEC_RULE_INHERITANCE\"\n      case symbol_kind::S_CONFIG_SEC_RULE_PERF_TIME: // \"CONFIG_SEC_RULE_PERF_TIME\"\n      case symbol_kind::S_CONFIG_DIR_RULE_ENG: // \"CONFIG_DIR_RULE_ENG\"\n      case symbol_kind::S_CONFIG_DIR_SEC_ACTION: // \"CONFIG_DIR_SEC_ACTION\"\n      case symbol_kind::S_CONFIG_DIR_SEC_DEFAULT_ACTION: // \"CONFIG_DIR_SEC_DEFAULT_ACTION\"\n      case symbol_kind::S_CONFIG_DIR_SEC_MARKER: // \"CONFIG_DIR_SEC_MARKER\"\n      case symbol_kind::S_CONFIG_DIR_UNICODE_MAP_FILE: // \"CONFIG_DIR_UNICODE_MAP_FILE\"\n      case symbol_kind::S_CONFIG_DIR_UNICODE_CODE_PAGE: // \"CONFIG_DIR_UNICODE_CODE_PAGE\"\n      case symbol_kind::S_CONFIG_SEC_COLLECTION_TIMEOUT: // \"CONFIG_SEC_COLLECTION_TIMEOUT\"\n      case symbol_kind::S_CONFIG_SEC_HTTP_BLKEY: // \"CONFIG_SEC_HTTP_BLKEY\"\n      case symbol_kind::S_CONFIG_SEC_INTERCEPT_ON_ERROR: // \"CONFIG_SEC_INTERCEPT_ON_ERROR\"\n      case symbol_kind::S_CONFIG_SEC_REMOTE_RULES_FAIL_ACTION: // \"CONFIG_SEC_REMOTE_RULES_FAIL_ACTION\"\n      case symbol_kind::S_CONFIG_SEC_RULE_REMOVE_BY_ID: // \"CONFIG_SEC_RULE_REMOVE_BY_ID\"\n      case symbol_kind::S_CONFIG_SEC_RULE_REMOVE_BY_MSG: // \"CONFIG_SEC_RULE_REMOVE_BY_MSG\"\n      case symbol_kind::S_CONFIG_SEC_RULE_REMOVE_BY_TAG: // \"CONFIG_SEC_RULE_REMOVE_BY_TAG\"\n      case symbol_kind::S_CONFIG_SEC_RULE_UPDATE_TARGET_BY_TAG: // \"CONFIG_SEC_RULE_UPDATE_TARGET_BY_TAG\"\n      case symbol_kind::S_CONFIG_SEC_RULE_UPDATE_TARGET_BY_MSG: // \"CONFIG_SEC_RULE_UPDATE_TARGET_BY_MSG\"\n      case symbol_kind::S_CONFIG_SEC_RULE_UPDATE_TARGET_BY_ID: // \"CONFIG_SEC_RULE_UPDATE_TARGET_BY_ID\"\n      case symbol_kind::S_CONFIG_SEC_RULE_UPDATE_ACTION_BY_ID: // \"CONFIG_SEC_RULE_UPDATE_ACTION_BY_ID\"\n      case symbol_kind::S_CONFIG_UPDLOAD_KEEP_FILES: // \"CONFIG_UPDLOAD_KEEP_FILES\"\n      case symbol_kind::S_CONFIG_UPDLOAD_SAVE_TMP_FILES: // \"CONFIG_UPDLOAD_SAVE_TMP_FILES\"\n      case symbol_kind::S_CONFIG_UPLOAD_DIR: // \"CONFIG_UPLOAD_DIR\"\n      case symbol_kind::S_CONFIG_UPLOAD_FILE_LIMIT: // \"CONFIG_UPLOAD_FILE_LIMIT\"\n      case symbol_kind::S_CONFIG_UPLOAD_FILE_MODE: // \"CONFIG_UPLOAD_FILE_MODE\"\n      case symbol_kind::S_CONFIG_VALUE_ABORT: // \"CONFIG_VALUE_ABORT\"\n      case symbol_kind::S_CONFIG_VALUE_DETC: // \"CONFIG_VALUE_DETC\"\n      case symbol_kind::S_CONFIG_VALUE_HTTPS: // \"CONFIG_VALUE_HTTPS\"\n      case symbol_kind::S_CONFIG_VALUE_ONLYARGS: // \"CONFIG_VALUE_ONLYARGS\"\n      case symbol_kind::S_CONFIG_VALUE_OFF: // \"CONFIG_VALUE_OFF\"\n      case symbol_kind::S_CONFIG_VALUE_ON: // \"CONFIG_VALUE_ON\"\n      case symbol_kind::S_CONFIG_VALUE_PARALLEL: // \"CONFIG_VALUE_PARALLEL\"\n      case symbol_kind::S_CONFIG_VALUE_PROCESS_PARTIAL: // \"CONFIG_VALUE_PROCESS_PARTIAL\"\n      case symbol_kind::S_CONFIG_VALUE_REJECT: // \"CONFIG_VALUE_REJECT\"\n      case symbol_kind::S_CONFIG_VALUE_RELEVANT_ONLY: // \"CONFIG_VALUE_RELEVANT_ONLY\"\n      case symbol_kind::S_CONFIG_VALUE_SERIAL: // \"CONFIG_VALUE_SERIAL\"\n      case symbol_kind::S_CONFIG_VALUE_WARN: // \"CONFIG_VALUE_WARN\"\n      case symbol_kind::S_CONFIG_XML_EXTERNAL_ENTITY: // \"CONFIG_XML_EXTERNAL_ENTITY\"\n      case symbol_kind::S_CONFIG_XML_PARSE_XML_INTO_ARGS: // \"CONFIG_XML_PARSE_XML_INTO_ARGS\"\n      case symbol_kind::S_CONGIG_DIR_RESPONSE_BODY_MP: // \"CONGIG_DIR_RESPONSE_BODY_MP\"\n      case symbol_kind::S_CONGIG_DIR_SEC_ARG_SEP: // \"CONGIG_DIR_SEC_ARG_SEP\"\n      case symbol_kind::S_CONGIG_DIR_SEC_COOKIE_FORMAT: // \"CONGIG_DIR_SEC_COOKIE_FORMAT\"\n      case symbol_kind::S_CONFIG_SEC_COOKIEV0_SEPARATOR: // \"CONFIG_SEC_COOKIEV0_SEPARATOR\"\n      case symbol_kind::S_CONGIG_DIR_SEC_DATA_DIR: // \"CONGIG_DIR_SEC_DATA_DIR\"\n      case symbol_kind::S_CONGIG_DIR_SEC_STATUS_ENGINE: // \"CONGIG_DIR_SEC_STATUS_ENGINE\"\n      case symbol_kind::S_CONFIG_SEC_STREAM_IN_BODY_INSPECTION: // \"CONFIG_SEC_STREAM_IN_BODY_INSPECTION\"\n      case symbol_kind::S_CONFIG_SEC_STREAM_OUT_BODY_INSPECTION: // \"CONFIG_SEC_STREAM_OUT_BODY_INSPECTION\"\n      case symbol_kind::S_CONGIG_DIR_SEC_TMP_DIR: // \"CONGIG_DIR_SEC_TMP_DIR\"\n      case symbol_kind::S_DIRECTIVE: // \"DIRECTIVE\"\n      case symbol_kind::S_DIRECTIVE_SECRULESCRIPT: // \"DIRECTIVE_SECRULESCRIPT\"\n      case symbol_kind::S_FREE_TEXT_QUOTE_MACRO_EXPANSION: // \"FREE_TEXT_QUOTE_MACRO_EXPANSION\"\n      case symbol_kind::S_QUOTATION_MARK: // \"QUOTATION_MARK\"\n      case symbol_kind::S_RUN_TIME_VAR_BLD: // \"RUN_TIME_VAR_BLD\"\n      case symbol_kind::S_RUN_TIME_VAR_DUR: // \"RUN_TIME_VAR_DUR\"\n      case symbol_kind::S_RUN_TIME_VAR_HSV: // \"RUN_TIME_VAR_HSV\"\n      case symbol_kind::S_RUN_TIME_VAR_REMOTE_USER: // \"RUN_TIME_VAR_REMOTE_USER\"\n      case symbol_kind::S_RUN_TIME_VAR_TIME: // \"RUN_TIME_VAR_TIME\"\n      case symbol_kind::S_RUN_TIME_VAR_TIME_DAY: // \"RUN_TIME_VAR_TIME_DAY\"\n      case symbol_kind::S_RUN_TIME_VAR_TIME_EPOCH: // \"RUN_TIME_VAR_TIME_EPOCH\"\n      case symbol_kind::S_RUN_TIME_VAR_TIME_HOUR: // \"RUN_TIME_VAR_TIME_HOUR\"\n      case symbol_kind::S_RUN_TIME_VAR_TIME_MIN: // \"RUN_TIME_VAR_TIME_MIN\"\n      case symbol_kind::S_RUN_TIME_VAR_TIME_MON: // \"RUN_TIME_VAR_TIME_MON\"\n      case symbol_kind::S_RUN_TIME_VAR_TIME_SEC: // \"RUN_TIME_VAR_TIME_SEC\"\n      case symbol_kind::S_RUN_TIME_VAR_TIME_WDAY: // \"RUN_TIME_VAR_TIME_WDAY\"\n      case symbol_kind::S_RUN_TIME_VAR_TIME_YEAR: // \"RUN_TIME_VAR_TIME_YEAR\"\n      case symbol_kind::S_VARIABLE: // \"VARIABLE\"\n      case symbol_kind::S_DICT_ELEMENT: // \"Dictionary element\"\n      case symbol_kind::S_DICT_ELEMENT_WITH_EQUALS: // \"Dictionary element, with equals\"\n      case symbol_kind::S_DICT_ELEMENT_REGEXP: // \"Dictionary element, selected by regexp\"\n        value.move< std::string > (that.value);\n        break;\n\n      case symbol_kind::S_op: // op\n      case symbol_kind::S_op_before_init: // op_before_init\n        value.move< std::unique_ptr<Operator> > (that.value);\n        break;\n\n      case symbol_kind::S_run_time_string: // run_time_string\n        value.move< std::unique_ptr<RunTimeString> > (that.value);\n        break;\n\n      case symbol_kind::S_var: // var\n        value.move< std::unique_ptr<Variable> > (that.value);\n        break;\n\n      case symbol_kind::S_act: // act\n      case symbol_kind::S_setvar_action: // setvar_action\n        value.move< std::unique_ptr<actions::Action> > (that.value);\n        break;\n\n      case symbol_kind::S_variables: // variables\n      case symbol_kind::S_variables_pre_process: // variables_pre_process\n      case symbol_kind::S_variables_may_be_quoted: // variables_may_be_quoted\n        value.move< std::unique_ptr<std::vector<std::unique_ptr<Variable> > >  > (that.value);\n        break;\n\n      case symbol_kind::S_actions: // actions\n      case symbol_kind::S_actions_may_quoted: // actions_may_quoted\n        value.move< std::unique_ptr<std::vector<std::unique_ptr<actions::Action> > >  > (that.value);\n        break;\n\n      default:\n        break;\n    }\n\n    location = that.location;\n    // that is emptied.\n    that.state = empty_state;\n    return *this;\n  }\n#endif\n\n  template <typename Base>\n  void\n  seclang_parser::yy_destroy_ (const char* yymsg, basic_symbol<Base>& yysym) const\n  {\n    if (yymsg)\n      YY_SYMBOL_PRINT (yymsg, yysym);\n  }\n\n#if YYDEBUG\n  template <typename Base>\n  void\n  seclang_parser::yy_print_ (std::ostream& yyo, const basic_symbol<Base>& yysym) const\n  {\n    std::ostream& yyoutput = yyo;\n    YY_USE (yyoutput);\n    if (yysym.empty ())\n      yyo << \"empty symbol\";\n    else\n      {\n        symbol_kind_type yykind = yysym.kind ();\n        yyo << (yykind < YYNTOKENS ? \"token\" : \"nterm\")\n            << ' ' << yysym.name () << \" (\"\n            << yysym.location << \": \";\n        YY_USE (yykind);\n        yyo << ')';\n      }\n  }\n#endif\n\n  void\n  seclang_parser::yypush_ (const char* m, YY_MOVE_REF (stack_symbol_type) sym)\n  {\n    if (m)\n      YY_SYMBOL_PRINT (m, sym);\n    yystack_.push (YY_MOVE (sym));\n  }\n\n  void\n  seclang_parser::yypush_ (const char* m, state_type s, YY_MOVE_REF (symbol_type) sym)\n  {\n#if 201103L <= YY_CPLUSPLUS\n    yypush_ (m, stack_symbol_type (s, std::move (sym)));\n#else\n    stack_symbol_type ss (s, sym);\n    yypush_ (m, ss);\n#endif\n  }\n\n  void\n  seclang_parser::yypop_ (int n) YY_NOEXCEPT\n  {\n    yystack_.pop (n);\n  }\n\n#if YYDEBUG\n  std::ostream&\n  seclang_parser::debug_stream () const\n  {\n    return *yycdebug_;\n  }\n\n  void\n  seclang_parser::set_debug_stream (std::ostream& o)\n  {\n    yycdebug_ = &o;\n  }\n\n\n  seclang_parser::debug_level_type\n  seclang_parser::debug_level () const\n  {\n    return yydebug_;\n  }\n\n  void\n  seclang_parser::set_debug_level (debug_level_type l)\n  {\n    yydebug_ = l;\n  }\n#endif // YYDEBUG\n\n  seclang_parser::state_type\n  seclang_parser::yy_lr_goto_state_ (state_type yystate, int yysym)\n  {\n    int yyr = yypgoto_[yysym - YYNTOKENS] + yystate;\n    if (0 <= yyr && yyr <= yylast_ && yycheck_[yyr] == yystate)\n      return yytable_[yyr];\n    else\n      return yydefgoto_[yysym - YYNTOKENS];\n  }\n\n  bool\n  seclang_parser::yy_pact_value_is_default_ (int yyvalue) YY_NOEXCEPT\n  {\n    return yyvalue == yypact_ninf_;\n  }\n\n  bool\n  seclang_parser::yy_table_value_is_error_ (int yyvalue) YY_NOEXCEPT\n  {\n    return yyvalue == yytable_ninf_;\n  }\n\n  int\n  seclang_parser::operator() ()\n  {\n    return parse ();\n  }\n\n  int\n  seclang_parser::parse ()\n  {\n    int yyn;\n    /// Length of the RHS of the rule being reduced.\n    int yylen = 0;\n\n    // Error handling.\n    int yynerrs_ = 0;\n    int yyerrstatus_ = 0;\n\n    /// The lookahead symbol.\n    symbol_type yyla;\n\n    /// The locations where the error started and ended.\n    stack_symbol_type yyerror_range[3];\n\n    /// The return value of parse ().\n    int yyresult;\n\n#if YY_EXCEPTIONS\n    try\n#endif // YY_EXCEPTIONS\n      {\n    YYCDEBUG << \"Starting parse\\n\";\n\n\n    // User initialization code.\n#line 324 \"seclang-parser.yy\"\n{\n  // Initialize the initial location.\n  driver.m_filenames.push_back(driver.file);\n  yyla.location.begin.filename = yyla.location.end.filename = &(driver.m_filenames.back());\n}\n\n#line 1349 \"seclang-parser.cc\"\n\n\n    /* Initialize the stack.  The initial state will be set in\n       yynewstate, since the latter expects the semantical and the\n       location values to have been already stored, initialize these\n       stacks with a primary value.  */\n    yystack_.clear ();\n    yypush_ (YY_NULLPTR, 0, YY_MOVE (yyla));\n\n  /*-----------------------------------------------.\n  | yynewstate -- push a new symbol on the stack.  |\n  `-----------------------------------------------*/\n  yynewstate:\n    YYCDEBUG << \"Entering state \" << int (yystack_[0].state) << '\\n';\n    YY_STACK_PRINT ();\n\n    // Accept?\n    if (yystack_[0].state == yyfinal_)\n      YYACCEPT;\n\n    goto yybackup;\n\n\n  /*-----------.\n  | yybackup.  |\n  `-----------*/\n  yybackup:\n    // Try to take a decision without lookahead.\n    yyn = yypact_[+yystack_[0].state];\n    if (yy_pact_value_is_default_ (yyn))\n      goto yydefault;\n\n    // Read a lookahead token.\n    if (yyla.empty ())\n      {\n        YYCDEBUG << \"Reading a token\\n\";\n#if YY_EXCEPTIONS\n        try\n#endif // YY_EXCEPTIONS\n          {\n            symbol_type yylookahead (yylex (driver));\n            yyla.move (yylookahead);\n          }\n#if YY_EXCEPTIONS\n        catch (const syntax_error& yyexc)\n          {\n            YYCDEBUG << \"Caught exception: \" << yyexc.what() << '\\n';\n            error (yyexc);\n            goto yyerrlab1;\n          }\n#endif // YY_EXCEPTIONS\n      }\n    YY_SYMBOL_PRINT (\"Next token is\", yyla);\n\n    if (yyla.kind () == symbol_kind::S_YYerror)\n    {\n      // The scanner already issued an error message, process directly\n      // to error recovery.  But do not keep the error token as\n      // lookahead, it is too special and may lead us to an endless\n      // loop in error recovery. */\n      yyla.kind_ = symbol_kind::S_YYUNDEF;\n      goto yyerrlab1;\n    }\n\n    /* If the proper action on seeing token YYLA.TYPE is to reduce or\n       to detect an error, take that action.  */\n    yyn += yyla.kind ();\n    if (yyn < 0 || yylast_ < yyn || yycheck_[yyn] != yyla.kind ())\n      {\n        goto yydefault;\n      }\n\n    // Reduce or error.\n    yyn = yytable_[yyn];\n    if (yyn <= 0)\n      {\n        if (yy_table_value_is_error_ (yyn))\n          goto yyerrlab;\n        yyn = -yyn;\n        goto yyreduce;\n      }\n\n    // Count tokens shifted since error; after three, turn off error status.\n    if (yyerrstatus_)\n      --yyerrstatus_;\n\n    // Shift the lookahead token.\n    yypush_ (\"Shifting\", state_type (yyn), YY_MOVE (yyla));\n    goto yynewstate;\n\n\n  /*-----------------------------------------------------------.\n  | yydefault -- do the default action for the current state.  |\n  `-----------------------------------------------------------*/\n  yydefault:\n    yyn = yydefact_[+yystack_[0].state];\n    if (yyn == 0)\n      goto yyerrlab;\n    goto yyreduce;\n\n\n  /*-----------------------------.\n  | yyreduce -- do a reduction.  |\n  `-----------------------------*/\n  yyreduce:\n    yylen = yyr2_[yyn];\n    {\n      stack_symbol_type yylhs;\n      yylhs.state = yy_lr_goto_state_ (yystack_[yylen].state, yyr1_[yyn]);\n      /* Variants are always initialized to an empty instance of the\n         correct type. The default '$$ = $1' action is NOT applied\n         when using variants.  */\n      switch (yyr1_[yyn])\n    {\n      case symbol_kind::S_ACTION_ACCURACY: // \"Accuracy\"\n      case symbol_kind::S_ACTION_ALLOW: // \"Allow\"\n      case symbol_kind::S_ACTION_APPEND: // \"Append\"\n      case symbol_kind::S_ACTION_AUDIT_LOG: // \"AuditLog\"\n      case symbol_kind::S_ACTION_BLOCK: // \"Block\"\n      case symbol_kind::S_ACTION_CAPTURE: // \"Capture\"\n      case symbol_kind::S_ACTION_CHAIN: // \"Chain\"\n      case symbol_kind::S_ACTION_CTL_AUDIT_ENGINE: // \"ACTION_CTL_AUDIT_ENGINE\"\n      case symbol_kind::S_ACTION_CTL_AUDIT_LOG_PARTS: // \"ACTION_CTL_AUDIT_LOG_PARTS\"\n      case symbol_kind::S_ACTION_CTL_BDY_JSON: // \"ACTION_CTL_BDY_JSON\"\n      case symbol_kind::S_ACTION_CTL_BDY_XML: // \"ACTION_CTL_BDY_XML\"\n      case symbol_kind::S_ACTION_CTL_BDY_URLENCODED: // \"ACTION_CTL_BDY_URLENCODED\"\n      case symbol_kind::S_ACTION_CTL_FORCE_REQ_BODY_VAR: // \"ACTION_CTL_FORCE_REQ_BODY_VAR\"\n      case symbol_kind::S_ACTION_CTL_PARSE_XML_INTO_ARGS: // \"ACTION_CTL_PARSE_XML_INTO_ARGS\"\n      case symbol_kind::S_ACTION_CTL_REQUEST_BODY_ACCESS: // \"ACTION_CTL_REQUEST_BODY_ACCESS\"\n      case symbol_kind::S_ACTION_CTL_RULE_REMOVE_BY_ID: // \"ACTION_CTL_RULE_REMOVE_BY_ID\"\n      case symbol_kind::S_ACTION_CTL_RULE_REMOVE_BY_TAG: // \"ACTION_CTL_RULE_REMOVE_BY_TAG\"\n      case symbol_kind::S_ACTION_CTL_RULE_REMOVE_TARGET_BY_ID: // \"ACTION_CTL_RULE_REMOVE_TARGET_BY_ID\"\n      case symbol_kind::S_ACTION_CTL_RULE_REMOVE_TARGET_BY_TAG: // \"ACTION_CTL_RULE_REMOVE_TARGET_BY_TAG\"\n      case symbol_kind::S_ACTION_DENY: // \"Deny\"\n      case symbol_kind::S_ACTION_DEPRECATE_VAR: // \"DeprecateVar\"\n      case symbol_kind::S_ACTION_DROP: // \"Drop\"\n      case symbol_kind::S_ACTION_EXEC: // \"Exec\"\n      case symbol_kind::S_ACTION_EXPIRE_VAR: // \"ExpireVar\"\n      case symbol_kind::S_ACTION_ID: // \"Id\"\n      case symbol_kind::S_ACTION_INITCOL: // \"InitCol\"\n      case symbol_kind::S_ACTION_LOG: // \"Log\"\n      case symbol_kind::S_ACTION_LOG_DATA: // \"LogData\"\n      case symbol_kind::S_ACTION_MATURITY: // \"Maturity\"\n      case symbol_kind::S_ACTION_MSG: // \"Msg\"\n      case symbol_kind::S_ACTION_MULTI_MATCH: // \"MultiMatch\"\n      case symbol_kind::S_ACTION_NO_AUDIT_LOG: // \"NoAuditLog\"\n      case symbol_kind::S_ACTION_NO_LOG: // \"NoLog\"\n      case symbol_kind::S_ACTION_PASS: // \"Pass\"\n      case symbol_kind::S_ACTION_PAUSE: // \"Pause\"\n      case symbol_kind::S_ACTION_PHASE: // \"Phase\"\n      case symbol_kind::S_ACTION_PREPEND: // \"Prepend\"\n      case symbol_kind::S_ACTION_PROXY: // \"Proxy\"\n      case symbol_kind::S_ACTION_REDIRECT: // \"Redirect\"\n      case symbol_kind::S_ACTION_REV: // \"Rev\"\n      case symbol_kind::S_ACTION_SANITISE_ARG: // \"SanitiseArg\"\n      case symbol_kind::S_ACTION_SANITISE_MATCHED: // \"SanitiseMatched\"\n      case symbol_kind::S_ACTION_SANITISE_MATCHED_BYTES: // \"SanitiseMatchedBytes\"\n      case symbol_kind::S_ACTION_SANITISE_REQUEST_HEADER: // \"SanitiseRequestHeader\"\n      case symbol_kind::S_ACTION_SANITISE_RESPONSE_HEADER: // \"SanitiseResponseHeader\"\n      case symbol_kind::S_ACTION_SETENV: // \"SetEnv\"\n      case symbol_kind::S_ACTION_SETRSC: // \"SetRsc\"\n      case symbol_kind::S_ACTION_SETSID: // \"SetSid\"\n      case symbol_kind::S_ACTION_SETUID: // \"SetUID\"\n      case symbol_kind::S_ACTION_SEVERITY: // \"Severity\"\n      case symbol_kind::S_ACTION_SKIP: // \"Skip\"\n      case symbol_kind::S_ACTION_SKIP_AFTER: // \"SkipAfter\"\n      case symbol_kind::S_ACTION_STATUS: // \"Status\"\n      case symbol_kind::S_ACTION_TAG: // \"Tag\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_BASE_64_ENCODE: // \"ACTION_TRANSFORMATION_BASE_64_ENCODE\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_BASE_64_DECODE: // \"ACTION_TRANSFORMATION_BASE_64_DECODE\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_BASE_64_DECODE_EXT: // \"ACTION_TRANSFORMATION_BASE_64_DECODE_EXT\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_CMD_LINE: // \"ACTION_TRANSFORMATION_CMD_LINE\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_COMPRESS_WHITESPACE: // \"ACTION_TRANSFORMATION_COMPRESS_WHITESPACE\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_CSS_DECODE: // \"ACTION_TRANSFORMATION_CSS_DECODE\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_ESCAPE_SEQ_DECODE: // \"ACTION_TRANSFORMATION_ESCAPE_SEQ_DECODE\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_HEX_ENCODE: // \"ACTION_TRANSFORMATION_HEX_ENCODE\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_HEX_DECODE: // \"ACTION_TRANSFORMATION_HEX_DECODE\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_HTML_ENTITY_DECODE: // \"ACTION_TRANSFORMATION_HTML_ENTITY_DECODE\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_JS_DECODE: // \"ACTION_TRANSFORMATION_JS_DECODE\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_LENGTH: // \"ACTION_TRANSFORMATION_LENGTH\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_LOWERCASE: // \"ACTION_TRANSFORMATION_LOWERCASE\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_MD5: // \"ACTION_TRANSFORMATION_MD5\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_NONE: // \"ACTION_TRANSFORMATION_NONE\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_NORMALISE_PATH: // \"ACTION_TRANSFORMATION_NORMALISE_PATH\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_NORMALISE_PATH_WIN: // \"ACTION_TRANSFORMATION_NORMALISE_PATH_WIN\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_PARITY_EVEN_7_BIT: // \"ACTION_TRANSFORMATION_PARITY_EVEN_7_BIT\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_PARITY_ODD_7_BIT: // \"ACTION_TRANSFORMATION_PARITY_ODD_7_BIT\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_PARITY_ZERO_7_BIT: // \"ACTION_TRANSFORMATION_PARITY_ZERO_7_BIT\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_REMOVE_COMMENTS: // \"ACTION_TRANSFORMATION_REMOVE_COMMENTS\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_REMOVE_COMMENTS_CHAR: // \"ACTION_TRANSFORMATION_REMOVE_COMMENTS_CHAR\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_REMOVE_NULLS: // \"ACTION_TRANSFORMATION_REMOVE_NULLS\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_REMOVE_WHITESPACE: // \"ACTION_TRANSFORMATION_REMOVE_WHITESPACE\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_REPLACE_COMMENTS: // \"ACTION_TRANSFORMATION_REPLACE_COMMENTS\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_REPLACE_NULLS: // \"ACTION_TRANSFORMATION_REPLACE_NULLS\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_SHA1: // \"ACTION_TRANSFORMATION_SHA1\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_SQL_HEX_DECODE: // \"ACTION_TRANSFORMATION_SQL_HEX_DECODE\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_TRIM: // \"ACTION_TRANSFORMATION_TRIM\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_TRIM_LEFT: // \"ACTION_TRANSFORMATION_TRIM_LEFT\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_TRIM_RIGHT: // \"ACTION_TRANSFORMATION_TRIM_RIGHT\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_UPPERCASE: // \"ACTION_TRANSFORMATION_UPPERCASE\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_URL_ENCODE: // \"ACTION_TRANSFORMATION_URL_ENCODE\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_URL_DECODE: // \"ACTION_TRANSFORMATION_URL_DECODE\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_URL_DECODE_UNI: // \"ACTION_TRANSFORMATION_URL_DECODE_UNI\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_UTF8_TO_UNICODE: // \"ACTION_TRANSFORMATION_UTF8_TO_UNICODE\"\n      case symbol_kind::S_ACTION_VER: // \"Ver\"\n      case symbol_kind::S_ACTION_XMLNS: // \"xmlns\"\n      case symbol_kind::S_CONFIG_COMPONENT_SIG: // \"CONFIG_COMPONENT_SIG\"\n      case symbol_kind::S_CONFIG_CONN_ENGINE: // \"CONFIG_CONN_ENGINE\"\n      case symbol_kind::S_CONFIG_SEC_ARGUMENT_SEPARATOR: // \"CONFIG_SEC_ARGUMENT_SEPARATOR\"\n      case symbol_kind::S_CONFIG_SEC_WEB_APP_ID: // \"CONFIG_SEC_WEB_APP_ID\"\n      case symbol_kind::S_CONFIG_SEC_SERVER_SIG: // \"CONFIG_SEC_SERVER_SIG\"\n      case symbol_kind::S_CONFIG_DIR_AUDIT_DIR: // \"CONFIG_DIR_AUDIT_DIR\"\n      case symbol_kind::S_CONFIG_DIR_AUDIT_DIR_MOD: // \"CONFIG_DIR_AUDIT_DIR_MOD\"\n      case symbol_kind::S_CONFIG_DIR_AUDIT_ENG: // \"CONFIG_DIR_AUDIT_ENG\"\n      case symbol_kind::S_CONFIG_DIR_AUDIT_FLE_MOD: // \"CONFIG_DIR_AUDIT_FLE_MOD\"\n      case symbol_kind::S_CONFIG_DIR_AUDIT_LOG: // \"CONFIG_DIR_AUDIT_LOG\"\n      case symbol_kind::S_CONFIG_DIR_AUDIT_LOG2: // \"CONFIG_DIR_AUDIT_LOG2\"\n      case symbol_kind::S_CONFIG_DIR_AUDIT_LOG_P: // \"CONFIG_DIR_AUDIT_LOG_P\"\n      case symbol_kind::S_CONFIG_DIR_AUDIT_STS: // \"CONFIG_DIR_AUDIT_STS\"\n      case symbol_kind::S_CONFIG_DIR_AUDIT_PREFIX: // \"CONFIG_DIR_AUDIT_PREFIX\"\n      case symbol_kind::S_CONFIG_DIR_AUDIT_TPE: // \"CONFIG_DIR_AUDIT_TPE\"\n      case symbol_kind::S_CONFIG_DIR_DEBUG_LOG: // \"CONFIG_DIR_DEBUG_LOG\"\n      case symbol_kind::S_CONFIG_DIR_DEBUG_LVL: // \"CONFIG_DIR_DEBUG_LVL\"\n      case symbol_kind::S_CONFIG_SEC_CACHE_TRANSFORMATIONS: // \"CONFIG_SEC_CACHE_TRANSFORMATIONS\"\n      case symbol_kind::S_CONFIG_SEC_DISABLE_BACKEND_COMPRESS: // \"CONFIG_SEC_DISABLE_BACKEND_COMPRESS\"\n      case symbol_kind::S_CONFIG_SEC_HASH_ENGINE: // \"CONFIG_SEC_HASH_ENGINE\"\n      case symbol_kind::S_CONFIG_SEC_HASH_KEY: // \"CONFIG_SEC_HASH_KEY\"\n      case symbol_kind::S_CONFIG_SEC_HASH_PARAM: // \"CONFIG_SEC_HASH_PARAM\"\n      case symbol_kind::S_CONFIG_SEC_HASH_METHOD_RX: // \"CONFIG_SEC_HASH_METHOD_RX\"\n      case symbol_kind::S_CONFIG_SEC_HASH_METHOD_PM: // \"CONFIG_SEC_HASH_METHOD_PM\"\n      case symbol_kind::S_CONFIG_SEC_CHROOT_DIR: // \"CONFIG_SEC_CHROOT_DIR\"\n      case symbol_kind::S_CONFIG_DIR_GEO_DB: // \"CONFIG_DIR_GEO_DB\"\n      case symbol_kind::S_CONFIG_DIR_GSB_DB: // \"CONFIG_DIR_GSB_DB\"\n      case symbol_kind::S_CONFIG_SEC_GUARDIAN_LOG: // \"CONFIG_SEC_GUARDIAN_LOG\"\n      case symbol_kind::S_CONFIG_DIR_PCRE_MATCH_LIMIT: // \"CONFIG_DIR_PCRE_MATCH_LIMIT\"\n      case symbol_kind::S_CONFIG_DIR_PCRE_MATCH_LIMIT_RECURSION: // \"CONFIG_DIR_PCRE_MATCH_LIMIT_RECURSION\"\n      case symbol_kind::S_CONFIG_SEC_CONN_R_STATE_LIMIT: // \"CONFIG_SEC_CONN_R_STATE_LIMIT\"\n      case symbol_kind::S_CONFIG_SEC_CONN_W_STATE_LIMIT: // \"CONFIG_SEC_CONN_W_STATE_LIMIT\"\n      case symbol_kind::S_CONFIG_SEC_SENSOR_ID: // \"CONFIG_SEC_SENSOR_ID\"\n      case symbol_kind::S_CONFIG_DIR_ARGS_LIMIT: // \"CONFIG_DIR_ARGS_LIMIT\"\n      case symbol_kind::S_CONFIG_DIR_REQ_BODY_JSON_DEPTH_LIMIT: // \"CONFIG_DIR_REQ_BODY_JSON_DEPTH_LIMIT\"\n      case symbol_kind::S_CONFIG_DIR_REQ_BODY: // \"CONFIG_DIR_REQ_BODY\"\n      case symbol_kind::S_CONFIG_DIR_REQ_BODY_IN_MEMORY_LIMIT: // \"CONFIG_DIR_REQ_BODY_IN_MEMORY_LIMIT\"\n      case symbol_kind::S_CONFIG_DIR_REQ_BODY_LIMIT: // \"CONFIG_DIR_REQ_BODY_LIMIT\"\n      case symbol_kind::S_CONFIG_DIR_REQ_BODY_LIMIT_ACTION: // \"CONFIG_DIR_REQ_BODY_LIMIT_ACTION\"\n      case symbol_kind::S_CONFIG_DIR_REQ_BODY_NO_FILES_LIMIT: // \"CONFIG_DIR_REQ_BODY_NO_FILES_LIMIT\"\n      case symbol_kind::S_CONFIG_DIR_RES_BODY: // \"CONFIG_DIR_RES_BODY\"\n      case symbol_kind::S_CONFIG_DIR_RES_BODY_LIMIT: // \"CONFIG_DIR_RES_BODY_LIMIT\"\n      case symbol_kind::S_CONFIG_DIR_RES_BODY_LIMIT_ACTION: // \"CONFIG_DIR_RES_BODY_LIMIT_ACTION\"\n      case symbol_kind::S_CONFIG_SEC_RULE_INHERITANCE: // \"CONFIG_SEC_RULE_INHERITANCE\"\n      case symbol_kind::S_CONFIG_SEC_RULE_PERF_TIME: // \"CONFIG_SEC_RULE_PERF_TIME\"\n      case symbol_kind::S_CONFIG_DIR_RULE_ENG: // \"CONFIG_DIR_RULE_ENG\"\n      case symbol_kind::S_CONFIG_DIR_SEC_ACTION: // \"CONFIG_DIR_SEC_ACTION\"\n      case symbol_kind::S_CONFIG_DIR_SEC_DEFAULT_ACTION: // \"CONFIG_DIR_SEC_DEFAULT_ACTION\"\n      case symbol_kind::S_CONFIG_DIR_SEC_MARKER: // \"CONFIG_DIR_SEC_MARKER\"\n      case symbol_kind::S_CONFIG_DIR_UNICODE_MAP_FILE: // \"CONFIG_DIR_UNICODE_MAP_FILE\"\n      case symbol_kind::S_CONFIG_DIR_UNICODE_CODE_PAGE: // \"CONFIG_DIR_UNICODE_CODE_PAGE\"\n      case symbol_kind::S_CONFIG_SEC_COLLECTION_TIMEOUT: // \"CONFIG_SEC_COLLECTION_TIMEOUT\"\n      case symbol_kind::S_CONFIG_SEC_HTTP_BLKEY: // \"CONFIG_SEC_HTTP_BLKEY\"\n      case symbol_kind::S_CONFIG_SEC_INTERCEPT_ON_ERROR: // \"CONFIG_SEC_INTERCEPT_ON_ERROR\"\n      case symbol_kind::S_CONFIG_SEC_REMOTE_RULES_FAIL_ACTION: // \"CONFIG_SEC_REMOTE_RULES_FAIL_ACTION\"\n      case symbol_kind::S_CONFIG_SEC_RULE_REMOVE_BY_ID: // \"CONFIG_SEC_RULE_REMOVE_BY_ID\"\n      case symbol_kind::S_CONFIG_SEC_RULE_REMOVE_BY_MSG: // \"CONFIG_SEC_RULE_REMOVE_BY_MSG\"\n      case symbol_kind::S_CONFIG_SEC_RULE_REMOVE_BY_TAG: // \"CONFIG_SEC_RULE_REMOVE_BY_TAG\"\n      case symbol_kind::S_CONFIG_SEC_RULE_UPDATE_TARGET_BY_TAG: // \"CONFIG_SEC_RULE_UPDATE_TARGET_BY_TAG\"\n      case symbol_kind::S_CONFIG_SEC_RULE_UPDATE_TARGET_BY_MSG: // \"CONFIG_SEC_RULE_UPDATE_TARGET_BY_MSG\"\n      case symbol_kind::S_CONFIG_SEC_RULE_UPDATE_TARGET_BY_ID: // \"CONFIG_SEC_RULE_UPDATE_TARGET_BY_ID\"\n      case symbol_kind::S_CONFIG_SEC_RULE_UPDATE_ACTION_BY_ID: // \"CONFIG_SEC_RULE_UPDATE_ACTION_BY_ID\"\n      case symbol_kind::S_CONFIG_UPDLOAD_KEEP_FILES: // \"CONFIG_UPDLOAD_KEEP_FILES\"\n      case symbol_kind::S_CONFIG_UPDLOAD_SAVE_TMP_FILES: // \"CONFIG_UPDLOAD_SAVE_TMP_FILES\"\n      case symbol_kind::S_CONFIG_UPLOAD_DIR: // \"CONFIG_UPLOAD_DIR\"\n      case symbol_kind::S_CONFIG_UPLOAD_FILE_LIMIT: // \"CONFIG_UPLOAD_FILE_LIMIT\"\n      case symbol_kind::S_CONFIG_UPLOAD_FILE_MODE: // \"CONFIG_UPLOAD_FILE_MODE\"\n      case symbol_kind::S_CONFIG_VALUE_ABORT: // \"CONFIG_VALUE_ABORT\"\n      case symbol_kind::S_CONFIG_VALUE_DETC: // \"CONFIG_VALUE_DETC\"\n      case symbol_kind::S_CONFIG_VALUE_HTTPS: // \"CONFIG_VALUE_HTTPS\"\n      case symbol_kind::S_CONFIG_VALUE_ONLYARGS: // \"CONFIG_VALUE_ONLYARGS\"\n      case symbol_kind::S_CONFIG_VALUE_OFF: // \"CONFIG_VALUE_OFF\"\n      case symbol_kind::S_CONFIG_VALUE_ON: // \"CONFIG_VALUE_ON\"\n      case symbol_kind::S_CONFIG_VALUE_PARALLEL: // \"CONFIG_VALUE_PARALLEL\"\n      case symbol_kind::S_CONFIG_VALUE_PROCESS_PARTIAL: // \"CONFIG_VALUE_PROCESS_PARTIAL\"\n      case symbol_kind::S_CONFIG_VALUE_REJECT: // \"CONFIG_VALUE_REJECT\"\n      case symbol_kind::S_CONFIG_VALUE_RELEVANT_ONLY: // \"CONFIG_VALUE_RELEVANT_ONLY\"\n      case symbol_kind::S_CONFIG_VALUE_SERIAL: // \"CONFIG_VALUE_SERIAL\"\n      case symbol_kind::S_CONFIG_VALUE_WARN: // \"CONFIG_VALUE_WARN\"\n      case symbol_kind::S_CONFIG_XML_EXTERNAL_ENTITY: // \"CONFIG_XML_EXTERNAL_ENTITY\"\n      case symbol_kind::S_CONFIG_XML_PARSE_XML_INTO_ARGS: // \"CONFIG_XML_PARSE_XML_INTO_ARGS\"\n      case symbol_kind::S_CONGIG_DIR_RESPONSE_BODY_MP: // \"CONGIG_DIR_RESPONSE_BODY_MP\"\n      case symbol_kind::S_CONGIG_DIR_SEC_ARG_SEP: // \"CONGIG_DIR_SEC_ARG_SEP\"\n      case symbol_kind::S_CONGIG_DIR_SEC_COOKIE_FORMAT: // \"CONGIG_DIR_SEC_COOKIE_FORMAT\"\n      case symbol_kind::S_CONFIG_SEC_COOKIEV0_SEPARATOR: // \"CONFIG_SEC_COOKIEV0_SEPARATOR\"\n      case symbol_kind::S_CONGIG_DIR_SEC_DATA_DIR: // \"CONGIG_DIR_SEC_DATA_DIR\"\n      case symbol_kind::S_CONGIG_DIR_SEC_STATUS_ENGINE: // \"CONGIG_DIR_SEC_STATUS_ENGINE\"\n      case symbol_kind::S_CONFIG_SEC_STREAM_IN_BODY_INSPECTION: // \"CONFIG_SEC_STREAM_IN_BODY_INSPECTION\"\n      case symbol_kind::S_CONFIG_SEC_STREAM_OUT_BODY_INSPECTION: // \"CONFIG_SEC_STREAM_OUT_BODY_INSPECTION\"\n      case symbol_kind::S_CONGIG_DIR_SEC_TMP_DIR: // \"CONGIG_DIR_SEC_TMP_DIR\"\n      case symbol_kind::S_DIRECTIVE: // \"DIRECTIVE\"\n      case symbol_kind::S_DIRECTIVE_SECRULESCRIPT: // \"DIRECTIVE_SECRULESCRIPT\"\n      case symbol_kind::S_FREE_TEXT_QUOTE_MACRO_EXPANSION: // \"FREE_TEXT_QUOTE_MACRO_EXPANSION\"\n      case symbol_kind::S_QUOTATION_MARK: // \"QUOTATION_MARK\"\n      case symbol_kind::S_RUN_TIME_VAR_BLD: // \"RUN_TIME_VAR_BLD\"\n      case symbol_kind::S_RUN_TIME_VAR_DUR: // \"RUN_TIME_VAR_DUR\"\n      case symbol_kind::S_RUN_TIME_VAR_HSV: // \"RUN_TIME_VAR_HSV\"\n      case symbol_kind::S_RUN_TIME_VAR_REMOTE_USER: // \"RUN_TIME_VAR_REMOTE_USER\"\n      case symbol_kind::S_RUN_TIME_VAR_TIME: // \"RUN_TIME_VAR_TIME\"\n      case symbol_kind::S_RUN_TIME_VAR_TIME_DAY: // \"RUN_TIME_VAR_TIME_DAY\"\n      case symbol_kind::S_RUN_TIME_VAR_TIME_EPOCH: // \"RUN_TIME_VAR_TIME_EPOCH\"\n      case symbol_kind::S_RUN_TIME_VAR_TIME_HOUR: // \"RUN_TIME_VAR_TIME_HOUR\"\n      case symbol_kind::S_RUN_TIME_VAR_TIME_MIN: // \"RUN_TIME_VAR_TIME_MIN\"\n      case symbol_kind::S_RUN_TIME_VAR_TIME_MON: // \"RUN_TIME_VAR_TIME_MON\"\n      case symbol_kind::S_RUN_TIME_VAR_TIME_SEC: // \"RUN_TIME_VAR_TIME_SEC\"\n      case symbol_kind::S_RUN_TIME_VAR_TIME_WDAY: // \"RUN_TIME_VAR_TIME_WDAY\"\n      case symbol_kind::S_RUN_TIME_VAR_TIME_YEAR: // \"RUN_TIME_VAR_TIME_YEAR\"\n      case symbol_kind::S_VARIABLE: // \"VARIABLE\"\n      case symbol_kind::S_DICT_ELEMENT: // \"Dictionary element\"\n      case symbol_kind::S_DICT_ELEMENT_WITH_EQUALS: // \"Dictionary element, with equals\"\n      case symbol_kind::S_DICT_ELEMENT_REGEXP: // \"Dictionary element, selected by regexp\"\n        yylhs.value.emplace< std::string > ();\n        break;\n\n      case symbol_kind::S_op: // op\n      case symbol_kind::S_op_before_init: // op_before_init\n        yylhs.value.emplace< std::unique_ptr<Operator> > ();\n        break;\n\n      case symbol_kind::S_run_time_string: // run_time_string\n        yylhs.value.emplace< std::unique_ptr<RunTimeString> > ();\n        break;\n\n      case symbol_kind::S_var: // var\n        yylhs.value.emplace< std::unique_ptr<Variable> > ();\n        break;\n\n      case symbol_kind::S_act: // act\n      case symbol_kind::S_setvar_action: // setvar_action\n        yylhs.value.emplace< std::unique_ptr<actions::Action> > ();\n        break;\n\n      case symbol_kind::S_variables: // variables\n      case symbol_kind::S_variables_pre_process: // variables_pre_process\n      case symbol_kind::S_variables_may_be_quoted: // variables_may_be_quoted\n        yylhs.value.emplace< std::unique_ptr<std::vector<std::unique_ptr<Variable> > >  > ();\n        break;\n\n      case symbol_kind::S_actions: // actions\n      case symbol_kind::S_actions_may_quoted: // actions_may_quoted\n        yylhs.value.emplace< std::unique_ptr<std::vector<std::unique_ptr<actions::Action> > >  > ();\n        break;\n\n      default:\n        break;\n    }\n\n\n      // Default location.\n      {\n        stack_type::slice range (yystack_, yylen);\n        YYLLOC_DEFAULT (yylhs.location, range, yylen);\n        yyerror_range[1].location = yylhs.location;\n      }\n\n      // Perform the reduction.\n      YY_REDUCE_PRINT (yyn);\n#if YY_EXCEPTIONS\n      try\n#endif // YY_EXCEPTIONS\n        {\n          switch (yyn)\n            {\n  case 2: // input: \"end of file\"\n#line 737 \"seclang-parser.yy\"\n      {\n        return 0;\n      }\n#line 1724 \"seclang-parser.cc\"\n    break;\n\n  case 6: // audit_log: \"CONFIG_DIR_AUDIT_DIR_MOD\"\n#line 750 \"seclang-parser.yy\"\n      {\n        driver.m_auditLog->setStorageDirMode(strtol(yystack_[0].value.as < std::string > ().c_str(), NULL, 8));\n      }\n#line 1732 \"seclang-parser.cc\"\n    break;\n\n  case 7: // audit_log: \"CONFIG_DIR_AUDIT_DIR\"\n#line 756 \"seclang-parser.yy\"\n      {\n        driver.m_auditLog->setStorageDir(yystack_[0].value.as < std::string > ());\n      }\n#line 1740 \"seclang-parser.cc\"\n    break;\n\n  case 8: // audit_log: \"CONFIG_DIR_AUDIT_ENG\" \"CONFIG_VALUE_RELEVANT_ONLY\"\n#line 762 \"seclang-parser.yy\"\n      {\n        driver.m_auditLog->setStatus(modsecurity::audit_log::AuditLog::RelevantOnlyAuditLogStatus);\n      }\n#line 1748 \"seclang-parser.cc\"\n    break;\n\n  case 9: // audit_log: \"CONFIG_DIR_AUDIT_ENG\" \"CONFIG_VALUE_OFF\"\n#line 766 \"seclang-parser.yy\"\n      {\n        driver.m_auditLog->setStatus(modsecurity::audit_log::AuditLog::OffAuditLogStatus);\n      }\n#line 1756 \"seclang-parser.cc\"\n    break;\n\n  case 10: // audit_log: \"CONFIG_DIR_AUDIT_ENG\" \"CONFIG_VALUE_ON\"\n#line 770 \"seclang-parser.yy\"\n      {\n        driver.m_auditLog->setStatus(modsecurity::audit_log::AuditLog::OnAuditLogStatus);\n      }\n#line 1764 \"seclang-parser.cc\"\n    break;\n\n  case 11: // audit_log: \"CONFIG_DIR_AUDIT_FLE_MOD\"\n#line 776 \"seclang-parser.yy\"\n      {\n        driver.m_auditLog->setFileMode(strtol(yystack_[0].value.as < std::string > ().c_str(), NULL, 8));\n      }\n#line 1772 \"seclang-parser.cc\"\n    break;\n\n  case 12: // audit_log: \"CONFIG_DIR_AUDIT_LOG2\"\n#line 782 \"seclang-parser.yy\"\n      {\n        driver.m_auditLog->setFilePath2(yystack_[0].value.as < std::string > ());\n      }\n#line 1780 \"seclang-parser.cc\"\n    break;\n\n  case 13: // audit_log: \"CONFIG_DIR_AUDIT_LOG_P\"\n#line 788 \"seclang-parser.yy\"\n      {\n        driver.m_auditLog->setParts(yystack_[0].value.as < std::string > ());\n      }\n#line 1788 \"seclang-parser.cc\"\n    break;\n\n  case 14: // audit_log: \"CONFIG_DIR_AUDIT_LOG\"\n#line 794 \"seclang-parser.yy\"\n      {\n        driver.m_auditLog->setFilePath1(yystack_[0].value.as < std::string > ());\n      }\n#line 1796 \"seclang-parser.cc\"\n    break;\n\n  case 15: // audit_log: CONFIG_DIR_AUDIT_LOG_FMT JSON\n#line 799 \"seclang-parser.yy\"\n      {\n        driver.m_auditLog->setFormat(modsecurity::audit_log::AuditLog::JSONAuditLogFormat);\n      }\n#line 1804 \"seclang-parser.cc\"\n    break;\n\n  case 16: // audit_log: CONFIG_DIR_AUDIT_LOG_FMT NATIVE\n#line 804 \"seclang-parser.yy\"\n      {\n        driver.m_auditLog->setFormat(modsecurity::audit_log::AuditLog::NativeAuditLogFormat);\n      }\n#line 1812 \"seclang-parser.cc\"\n    break;\n\n  case 17: // audit_log: \"CONFIG_DIR_AUDIT_STS\"\n#line 810 \"seclang-parser.yy\"\n      {\n        std::string relevant_status(yystack_[0].value.as < std::string > ());\n        driver.m_auditLog->setRelevantStatus(relevant_status);\n      }\n#line 1821 \"seclang-parser.cc\"\n    break;\n\n  case 18: // audit_log: \"CONFIG_DIR_AUDIT_PREFIX\"\n#line 817 \"seclang-parser.yy\"\n      {\n        std::string prefix(yystack_[0].value.as < std::string > ());\n        driver.m_auditLog->setPrefix(prefix);\n      }\n#line 1830 \"seclang-parser.cc\"\n    break;\n\n  case 19: // audit_log: \"CONFIG_DIR_AUDIT_TPE\" \"CONFIG_VALUE_SERIAL\"\n#line 824 \"seclang-parser.yy\"\n      {\n        driver.m_auditLog->setType(modsecurity::audit_log::AuditLog::SerialAuditLogType);\n      }\n#line 1838 \"seclang-parser.cc\"\n    break;\n\n  case 20: // audit_log: \"CONFIG_DIR_AUDIT_TPE\" \"CONFIG_VALUE_PARALLEL\"\n#line 828 \"seclang-parser.yy\"\n      {\n        driver.m_auditLog->setType(modsecurity::audit_log::AuditLog::ParallelAuditLogType);\n      }\n#line 1846 \"seclang-parser.cc\"\n    break;\n\n  case 21: // audit_log: \"CONFIG_DIR_AUDIT_TPE\" \"CONFIG_VALUE_HTTPS\"\n#line 832 \"seclang-parser.yy\"\n      {\n        driver.m_auditLog->setType(modsecurity::audit_log::AuditLog::HttpsAuditLogType);\n      }\n#line 1854 \"seclang-parser.cc\"\n    break;\n\n  case 22: // audit_log: \"CONFIG_UPDLOAD_KEEP_FILES\" \"CONFIG_VALUE_ON\"\n#line 838 \"seclang-parser.yy\"\n      {\n        driver.m_uploadKeepFiles = modsecurity::RulesSetProperties::TrueConfigBoolean;\n      }\n#line 1862 \"seclang-parser.cc\"\n    break;\n\n  case 23: // audit_log: \"CONFIG_UPDLOAD_KEEP_FILES\" \"CONFIG_VALUE_OFF\"\n#line 842 \"seclang-parser.yy\"\n      {\n        driver.m_uploadKeepFiles = modsecurity::RulesSetProperties::FalseConfigBoolean;\n      }\n#line 1870 \"seclang-parser.cc\"\n    break;\n\n  case 24: // audit_log: \"CONFIG_UPDLOAD_KEEP_FILES\" \"CONFIG_VALUE_RELEVANT_ONLY\"\n#line 846 \"seclang-parser.yy\"\n      {\n        driver.error(yystack_[2].location, \"SecUploadKeepFiles RelevantOnly is not currently supported. Accepted values are On or Off\");\n        YYERROR;\n      }\n#line 1879 \"seclang-parser.cc\"\n    break;\n\n  case 25: // audit_log: \"CONFIG_UPLOAD_FILE_LIMIT\"\n#line 851 \"seclang-parser.yy\"\n      {\n        std::string errmsg = \"\";\n        if (driver.m_uploadFileLimit.parse(std::string(yystack_[0].value.as < std::string > ()), &errmsg) != true) {\n          driver.error(yystack_[1].location, \"Failed to parse SecUploadFileLimit: \" + errmsg);\n          YYERROR;\n        }\n      }\n#line 1891 \"seclang-parser.cc\"\n    break;\n\n  case 26: // audit_log: \"CONFIG_UPLOAD_FILE_MODE\"\n#line 859 \"seclang-parser.yy\"\n      {\n        std::string errmsg = \"\";\n        if (driver.m_uploadFileMode.parse(std::string(yystack_[0].value.as < std::string > ()), &errmsg) != true) {\n          driver.error(yystack_[1].location, \"Failed to parse SecUploadFileMode: \" + errmsg);\n          YYERROR;\n        }\n      }\n#line 1903 \"seclang-parser.cc\"\n    break;\n\n  case 27: // audit_log: \"CONFIG_UPLOAD_DIR\"\n#line 867 \"seclang-parser.yy\"\n      {\n        driver.m_uploadDirectory.m_set = true;\n        driver.m_uploadDirectory.m_value = yystack_[0].value.as < std::string > ();\n      }\n#line 1912 \"seclang-parser.cc\"\n    break;\n\n  case 28: // audit_log: \"CONFIG_UPDLOAD_SAVE_TMP_FILES\" \"CONFIG_VALUE_ON\"\n#line 872 \"seclang-parser.yy\"\n      {\n        driver.m_tmpSaveUploadedFiles = modsecurity::RulesSetProperties::TrueConfigBoolean;\n      }\n#line 1920 \"seclang-parser.cc\"\n    break;\n\n  case 29: // audit_log: \"CONFIG_UPDLOAD_SAVE_TMP_FILES\" \"CONFIG_VALUE_OFF\"\n#line 876 \"seclang-parser.yy\"\n      {\n        driver.m_tmpSaveUploadedFiles = modsecurity::RulesSetProperties::FalseConfigBoolean;\n      }\n#line 1928 \"seclang-parser.cc\"\n    break;\n\n  case 30: // actions: \"QUOTATION_MARK\" actions_may_quoted \"QUOTATION_MARK\"\n#line 883 \"seclang-parser.yy\"\n      {\n        yylhs.value.as < std::unique_ptr<std::vector<std::unique_ptr<actions::Action> > >  > () = std::move(yystack_[1].value.as < std::unique_ptr<std::vector<std::unique_ptr<actions::Action> > >  > ());\n      }\n#line 1936 \"seclang-parser.cc\"\n    break;\n\n  case 31: // actions: actions_may_quoted\n#line 887 \"seclang-parser.yy\"\n      {\n        yylhs.value.as < std::unique_ptr<std::vector<std::unique_ptr<actions::Action> > >  > () = std::move(yystack_[0].value.as < std::unique_ptr<std::vector<std::unique_ptr<actions::Action> > >  > ());\n      }\n#line 1944 \"seclang-parser.cc\"\n    break;\n\n  case 32: // actions_may_quoted: actions_may_quoted \",\" act\n#line 894 \"seclang-parser.yy\"\n      {\n        ACTION_INIT(yystack_[0].value.as < std::unique_ptr<actions::Action> > (), yystack_[3].location)\n        yystack_[2].value.as < std::unique_ptr<std::vector<std::unique_ptr<actions::Action> > >  > ()->push_back(std::move(yystack_[0].value.as < std::unique_ptr<actions::Action> > ()));\n        yylhs.value.as < std::unique_ptr<std::vector<std::unique_ptr<actions::Action> > >  > () = std::move(yystack_[2].value.as < std::unique_ptr<std::vector<std::unique_ptr<actions::Action> > >  > ());\n      }\n#line 1954 \"seclang-parser.cc\"\n    break;\n\n  case 33: // actions_may_quoted: act\n#line 900 \"seclang-parser.yy\"\n      {\n        std::unique_ptr<std::vector<std::unique_ptr<actions::Action>>> b(new std::vector<std::unique_ptr<actions::Action>>());\n        ACTION_INIT(yystack_[0].value.as < std::unique_ptr<actions::Action> > (), yystack_[1].location)\n        b->push_back(std::move(yystack_[0].value.as < std::unique_ptr<actions::Action> > ()));\n        yylhs.value.as < std::unique_ptr<std::vector<std::unique_ptr<actions::Action> > >  > () = std::move(b);\n      }\n#line 1965 \"seclang-parser.cc\"\n    break;\n\n  case 34: // op: op_before_init\n#line 910 \"seclang-parser.yy\"\n      {\n        yylhs.value.as < std::unique_ptr<Operator> > () = std::move(yystack_[0].value.as < std::unique_ptr<Operator> > ());\n        std::string error;\n        if (yylhs.value.as < std::unique_ptr<Operator> > ()->init(*yystack_[0].location.end.filename, &error) == false) {\n            driver.error(yystack_[1].location, error);\n            YYERROR;\n        }\n      }\n#line 1978 \"seclang-parser.cc\"\n    break;\n\n  case 35: // op: \"NOT\" op_before_init\n#line 919 \"seclang-parser.yy\"\n      {\n        yylhs.value.as < std::unique_ptr<Operator> > () = std::move(yystack_[0].value.as < std::unique_ptr<Operator> > ());\n        yylhs.value.as < std::unique_ptr<Operator> > ()->m_negation = true;\n        std::string error;\n        if (yylhs.value.as < std::unique_ptr<Operator> > ()->init(*yystack_[1].location.end.filename, &error) == false) {\n            driver.error(yystack_[2].location, error);\n            YYERROR;\n        }\n      }\n#line 1992 \"seclang-parser.cc\"\n    break;\n\n  case 36: // op: run_time_string\n#line 929 \"seclang-parser.yy\"\n      {\n        OPERATOR_CONTAINER(yylhs.value.as < std::unique_ptr<Operator> > (), new operators::Rx(std::move(yystack_[0].value.as < std::unique_ptr<RunTimeString> > ())));\n        std::string error;\n        if (yylhs.value.as < std::unique_ptr<Operator> > ()->init(*yystack_[0].location.end.filename, &error) == false) {\n            driver.error(yystack_[1].location, error);\n            YYERROR;\n        }\n      }\n#line 2005 \"seclang-parser.cc\"\n    break;\n\n  case 37: // op: \"NOT\" run_time_string\n#line 938 \"seclang-parser.yy\"\n      {\n        OPERATOR_CONTAINER(yylhs.value.as < std::unique_ptr<Operator> > (), new operators::Rx(std::move(yystack_[0].value.as < std::unique_ptr<RunTimeString> > ())));\n        yylhs.value.as < std::unique_ptr<Operator> > ()->m_negation = true;\n        std::string error;\n        if (yylhs.value.as < std::unique_ptr<Operator> > ()->init(*yystack_[1].location.end.filename, &error) == false) {\n            driver.error(yystack_[2].location, error);\n            YYERROR;\n        }\n      }\n#line 2019 \"seclang-parser.cc\"\n    break;\n\n  case 38: // op_before_init: \"OPERATOR_UNCONDITIONAL_MATCH\"\n#line 951 \"seclang-parser.yy\"\n      {\n        OPERATOR_CONTAINER(yylhs.value.as < std::unique_ptr<Operator> > (), new operators::UnconditionalMatch());\n      }\n#line 2027 \"seclang-parser.cc\"\n    break;\n\n  case 39: // op_before_init: \"OPERATOR_DETECT_SQLI\"\n#line 955 \"seclang-parser.yy\"\n      {\n        OPERATOR_CONTAINER(yylhs.value.as < std::unique_ptr<Operator> > (), new operators::DetectSQLi());\n      }\n#line 2035 \"seclang-parser.cc\"\n    break;\n\n  case 40: // op_before_init: \"OPERATOR_DETECT_XSS\"\n#line 959 \"seclang-parser.yy\"\n      {\n        OPERATOR_CONTAINER(yylhs.value.as < std::unique_ptr<Operator> > (), new operators::DetectXSS());\n      }\n#line 2043 \"seclang-parser.cc\"\n    break;\n\n  case 41: // op_before_init: \"OPERATOR_VALIDATE_URL_ENCODING\"\n#line 963 \"seclang-parser.yy\"\n      {\n        OPERATOR_CONTAINER(yylhs.value.as < std::unique_ptr<Operator> > (), new operators::ValidateUrlEncoding());\n      }\n#line 2051 \"seclang-parser.cc\"\n    break;\n\n  case 42: // op_before_init: \"OPERATOR_VALIDATE_UTF8_ENCODING\"\n#line 967 \"seclang-parser.yy\"\n      {\n        OPERATOR_CONTAINER(yylhs.value.as < std::unique_ptr<Operator> > (), new operators::ValidateUtf8Encoding());\n      }\n#line 2059 \"seclang-parser.cc\"\n    break;\n\n  case 43: // op_before_init: \"OPERATOR_INSPECT_FILE\" run_time_string\n#line 971 \"seclang-parser.yy\"\n      {\n        OPERATOR_CONTAINER(yylhs.value.as < std::unique_ptr<Operator> > (), new operators::InspectFile(std::move(yystack_[0].value.as < std::unique_ptr<RunTimeString> > ())));\n      }\n#line 2067 \"seclang-parser.cc\"\n    break;\n\n  case 44: // op_before_init: \"OPERATOR_FUZZY_HASH\" run_time_string\n#line 975 \"seclang-parser.yy\"\n      {\n        OPERATOR_CONTAINER(yylhs.value.as < std::unique_ptr<Operator> > (), new operators::FuzzyHash(std::move(yystack_[0].value.as < std::unique_ptr<RunTimeString> > ())));\n      }\n#line 2075 \"seclang-parser.cc\"\n    break;\n\n  case 45: // op_before_init: \"OPERATOR_VALIDATE_BYTE_RANGE\" run_time_string\n#line 979 \"seclang-parser.yy\"\n      {\n        OPERATOR_CONTAINER(yylhs.value.as < std::unique_ptr<Operator> > (), new operators::ValidateByteRange(std::move(yystack_[0].value.as < std::unique_ptr<RunTimeString> > ())));\n      }\n#line 2083 \"seclang-parser.cc\"\n    break;\n\n  case 46: // op_before_init: \"OPERATOR_VALIDATE_DTD\" run_time_string\n#line 983 \"seclang-parser.yy\"\n      {\n        OPERATOR_CONTAINER(yylhs.value.as < std::unique_ptr<Operator> > (), new operators::ValidateDTD(std::move(yystack_[0].value.as < std::unique_ptr<RunTimeString> > ())));\n      }\n#line 2091 \"seclang-parser.cc\"\n    break;\n\n  case 47: // op_before_init: \"OPERATOR_VALIDATE_HASH\" run_time_string\n#line 987 \"seclang-parser.yy\"\n      {\n        /* $$ = new operators::ValidateHash($1); */\n        OPERATOR_NOT_SUPPORTED(\"ValidateHash\", yystack_[2].location);\n      }\n#line 2100 \"seclang-parser.cc\"\n    break;\n\n  case 48: // op_before_init: \"OPERATOR_VALIDATE_SCHEMA\" run_time_string\n#line 992 \"seclang-parser.yy\"\n      {\n        OPERATOR_CONTAINER(yylhs.value.as < std::unique_ptr<Operator> > (), new operators::ValidateSchema(std::move(yystack_[0].value.as < std::unique_ptr<RunTimeString> > ())));\n      }\n#line 2108 \"seclang-parser.cc\"\n    break;\n\n  case 49: // op_before_init: \"OPERATOR_VERIFY_CC\" run_time_string\n#line 996 \"seclang-parser.yy\"\n      {\n        OPERATOR_CONTAINER(yylhs.value.as < std::unique_ptr<Operator> > (), new operators::VerifyCC(std::move(yystack_[0].value.as < std::unique_ptr<RunTimeString> > ())));\n      }\n#line 2116 \"seclang-parser.cc\"\n    break;\n\n  case 50: // op_before_init: \"OPERATOR_VERIFY_CPF\" run_time_string\n#line 1000 \"seclang-parser.yy\"\n      {\n        OPERATOR_CONTAINER(yylhs.value.as < std::unique_ptr<Operator> > (), new operators::VerifyCPF(std::move(yystack_[0].value.as < std::unique_ptr<RunTimeString> > ())));\n      }\n#line 2124 \"seclang-parser.cc\"\n    break;\n\n  case 51: // op_before_init: \"OPERATOR_VERIFY_SSN\" run_time_string\n#line 1004 \"seclang-parser.yy\"\n      {\n        OPERATOR_CONTAINER(yylhs.value.as < std::unique_ptr<Operator> > (), new operators::VerifySSN(std::move(yystack_[0].value.as < std::unique_ptr<RunTimeString> > ())));\n      }\n#line 2132 \"seclang-parser.cc\"\n    break;\n\n  case 52: // op_before_init: \"OPERATOR_VERIFY_SVNR\" run_time_string\n#line 1008 \"seclang-parser.yy\"\n      {\n        OPERATOR_CONTAINER(yylhs.value.as < std::unique_ptr<Operator> > (), new operators::VerifySVNR(std::move(yystack_[0].value.as < std::unique_ptr<RunTimeString> > ())));\n      }\n#line 2140 \"seclang-parser.cc\"\n    break;\n\n  case 53: // op_before_init: \"OPERATOR_GSB_LOOKUP\" run_time_string\n#line 1012 \"seclang-parser.yy\"\n      {\n        /* $$ = new operators::GsbLookup($1); */\n        OPERATOR_NOT_SUPPORTED(\"GsbLookup\", yystack_[2].location);\n      }\n#line 2149 \"seclang-parser.cc\"\n    break;\n\n  case 54: // op_before_init: \"OPERATOR_RSUB\" run_time_string\n#line 1017 \"seclang-parser.yy\"\n      {\n        /* $$ = new operators::Rsub($1); */\n        OPERATOR_NOT_SUPPORTED(\"Rsub\", yystack_[2].location);\n      }\n#line 2158 \"seclang-parser.cc\"\n    break;\n\n  case 55: // op_before_init: \"OPERATOR_WITHIN\" run_time_string\n#line 1022 \"seclang-parser.yy\"\n      {\n        OPERATOR_CONTAINER(yylhs.value.as < std::unique_ptr<Operator> > (), new operators::Within(std::move(yystack_[0].value.as < std::unique_ptr<RunTimeString> > ())));\n      }\n#line 2166 \"seclang-parser.cc\"\n    break;\n\n  case 56: // op_before_init: \"OPERATOR_CONTAINS_WORD\" run_time_string\n#line 1026 \"seclang-parser.yy\"\n      {\n        OPERATOR_CONTAINER(yylhs.value.as < std::unique_ptr<Operator> > (), new operators::ContainsWord(std::move(yystack_[0].value.as < std::unique_ptr<RunTimeString> > ())));\n      }\n#line 2174 \"seclang-parser.cc\"\n    break;\n\n  case 57: // op_before_init: \"OPERATOR_CONTAINS\" run_time_string\n#line 1030 \"seclang-parser.yy\"\n      {\n        OPERATOR_CONTAINER(yylhs.value.as < std::unique_ptr<Operator> > (), new operators::Contains(std::move(yystack_[0].value.as < std::unique_ptr<RunTimeString> > ())));\n      }\n#line 2182 \"seclang-parser.cc\"\n    break;\n\n  case 58: // op_before_init: \"OPERATOR_ENDS_WITH\" run_time_string\n#line 1034 \"seclang-parser.yy\"\n      {\n        OPERATOR_CONTAINER(yylhs.value.as < std::unique_ptr<Operator> > (), new operators::EndsWith(std::move(yystack_[0].value.as < std::unique_ptr<RunTimeString> > ())));\n      }\n#line 2190 \"seclang-parser.cc\"\n    break;\n\n  case 59: // op_before_init: \"OPERATOR_EQ\" run_time_string\n#line 1038 \"seclang-parser.yy\"\n      {\n        OPERATOR_CONTAINER(yylhs.value.as < std::unique_ptr<Operator> > (), new operators::Eq(std::move(yystack_[0].value.as < std::unique_ptr<RunTimeString> > ())));\n      }\n#line 2198 \"seclang-parser.cc\"\n    break;\n\n  case 60: // op_before_init: \"OPERATOR_GE\" run_time_string\n#line 1042 \"seclang-parser.yy\"\n      {\n        OPERATOR_CONTAINER(yylhs.value.as < std::unique_ptr<Operator> > (), new operators::Ge(std::move(yystack_[0].value.as < std::unique_ptr<RunTimeString> > ())));\n      }\n#line 2206 \"seclang-parser.cc\"\n    break;\n\n  case 61: // op_before_init: \"OPERATOR_GT\" run_time_string\n#line 1046 \"seclang-parser.yy\"\n      {\n        OPERATOR_CONTAINER(yylhs.value.as < std::unique_ptr<Operator> > (), new operators::Gt(std::move(yystack_[0].value.as < std::unique_ptr<RunTimeString> > ())));\n      }\n#line 2214 \"seclang-parser.cc\"\n    break;\n\n  case 62: // op_before_init: \"OPERATOR_IP_MATCH_FROM_FILE\" run_time_string\n#line 1050 \"seclang-parser.yy\"\n      {\n        OPERATOR_CONTAINER(yylhs.value.as < std::unique_ptr<Operator> > (), new operators::IpMatchF(std::move(yystack_[0].value.as < std::unique_ptr<RunTimeString> > ())));\n      }\n#line 2222 \"seclang-parser.cc\"\n    break;\n\n  case 63: // op_before_init: \"OPERATOR_IP_MATCH\" run_time_string\n#line 1054 \"seclang-parser.yy\"\n      {\n        OPERATOR_CONTAINER(yylhs.value.as < std::unique_ptr<Operator> > (), new operators::IpMatch(std::move(yystack_[0].value.as < std::unique_ptr<RunTimeString> > ())));\n      }\n#line 2230 \"seclang-parser.cc\"\n    break;\n\n  case 64: // op_before_init: \"OPERATOR_LE\" run_time_string\n#line 1058 \"seclang-parser.yy\"\n      {\n        OPERATOR_CONTAINER(yylhs.value.as < std::unique_ptr<Operator> > (), new operators::Le(std::move(yystack_[0].value.as < std::unique_ptr<RunTimeString> > ())));\n      }\n#line 2238 \"seclang-parser.cc\"\n    break;\n\n  case 65: // op_before_init: \"OPERATOR_LT\" run_time_string\n#line 1062 \"seclang-parser.yy\"\n      {\n        OPERATOR_CONTAINER(yylhs.value.as < std::unique_ptr<Operator> > (), new operators::Lt(std::move(yystack_[0].value.as < std::unique_ptr<RunTimeString> > ())));\n      }\n#line 2246 \"seclang-parser.cc\"\n    break;\n\n  case 66: // op_before_init: \"OPERATOR_PM_FROM_FILE\" run_time_string\n#line 1066 \"seclang-parser.yy\"\n      {\n        OPERATOR_CONTAINER(yylhs.value.as < std::unique_ptr<Operator> > (), new operators::PmFromFile(std::move(yystack_[0].value.as < std::unique_ptr<RunTimeString> > ())));\n      }\n#line 2254 \"seclang-parser.cc\"\n    break;\n\n  case 67: // op_before_init: \"OPERATOR_PM\" run_time_string\n#line 1070 \"seclang-parser.yy\"\n      {\n        OPERATOR_CONTAINER(yylhs.value.as < std::unique_ptr<Operator> > (), new operators::Pm(std::move(yystack_[0].value.as < std::unique_ptr<RunTimeString> > ())));\n      }\n#line 2262 \"seclang-parser.cc\"\n    break;\n\n  case 68: // op_before_init: \"OPERATOR_RBL\" run_time_string\n#line 1074 \"seclang-parser.yy\"\n      {\n        OPERATOR_CONTAINER(yylhs.value.as < std::unique_ptr<Operator> > (), new operators::Rbl(std::move(yystack_[0].value.as < std::unique_ptr<RunTimeString> > ())));\n      }\n#line 2270 \"seclang-parser.cc\"\n    break;\n\n  case 69: // op_before_init: \"OPERATOR_RX\" run_time_string\n#line 1078 \"seclang-parser.yy\"\n      {\n        OPERATOR_CONTAINER(yylhs.value.as < std::unique_ptr<Operator> > (), new operators::Rx(std::move(yystack_[0].value.as < std::unique_ptr<RunTimeString> > ())));\n      }\n#line 2278 \"seclang-parser.cc\"\n    break;\n\n  case 70: // op_before_init: \"OPERATOR_RX_GLOBAL\" run_time_string\n#line 1082 \"seclang-parser.yy\"\n      {\n        OPERATOR_CONTAINER(yylhs.value.as < std::unique_ptr<Operator> > (), new operators::RxGlobal(std::move(yystack_[0].value.as < std::unique_ptr<RunTimeString> > ())));\n      }\n#line 2286 \"seclang-parser.cc\"\n    break;\n\n  case 71: // op_before_init: \"OPERATOR_STR_EQ\" run_time_string\n#line 1086 \"seclang-parser.yy\"\n      {\n        OPERATOR_CONTAINER(yylhs.value.as < std::unique_ptr<Operator> > (), new operators::StrEq(std::move(yystack_[0].value.as < std::unique_ptr<RunTimeString> > ())));\n      }\n#line 2294 \"seclang-parser.cc\"\n    break;\n\n  case 72: // op_before_init: \"OPERATOR_STR_MATCH\" run_time_string\n#line 1090 \"seclang-parser.yy\"\n      {\n        OPERATOR_CONTAINER(yylhs.value.as < std::unique_ptr<Operator> > (), new operators::StrMatch(std::move(yystack_[0].value.as < std::unique_ptr<RunTimeString> > ())));\n      }\n#line 2302 \"seclang-parser.cc\"\n    break;\n\n  case 73: // op_before_init: \"OPERATOR_BEGINS_WITH\" run_time_string\n#line 1094 \"seclang-parser.yy\"\n      {\n        OPERATOR_CONTAINER(yylhs.value.as < std::unique_ptr<Operator> > (), new operators::BeginsWith(std::move(yystack_[0].value.as < std::unique_ptr<RunTimeString> > ())));\n      }\n#line 2310 \"seclang-parser.cc\"\n    break;\n\n  case 74: // op_before_init: \"OPERATOR_GEOLOOKUP\"\n#line 1098 \"seclang-parser.yy\"\n      {\n#if defined(WITH_GEOIP) or defined(WITH_MAXMIND)\n        OPERATOR_CONTAINER(yylhs.value.as < std::unique_ptr<Operator> > (), new operators::GeoLookup());\n#else\n        std::stringstream ss;\n            ss << \"This version of ModSecurity was not compiled with GeoIP or MaxMind support.\";\n            driver.error(yystack_[1].location, ss.str());\n            YYERROR;\n#endif  // WITH_GEOIP\n      }\n#line 2325 \"seclang-parser.cc\"\n    break;\n\n  case 76: // expression: \"DIRECTIVE\" variables op actions\n#line 1113 \"seclang-parser.yy\"\n      {\n        std::vector<actions::Action *> *a = new std::vector<actions::Action *>();\n        std::vector<actions::transformations::Transformation *> *t = new std::vector<actions::transformations::Transformation *>();\n        for (auto &i : *yystack_[0].value.as < std::unique_ptr<std::vector<std::unique_ptr<actions::Action> > >  > ().get()) {\n            if (auto pt = dynamic_cast<actions::transformations::Transformation *>(i.get())) {\n              t->push_back(pt);\n              i.release();\n            } else {\n              a->push_back(i.release());\n            }\n        }\n        variables::Variables *v = new variables::Variables();\n        for (auto &i : *yystack_[2].value.as < std::unique_ptr<std::vector<std::unique_ptr<Variable> > >  > ().get()) {\n            v->push_back(i.release());\n        }\n\n        Operator *op = yystack_[1].value.as < std::unique_ptr<Operator> > ().release();\n        std::unique_ptr<RuleWithOperator> rule(new RuleWithOperator(\n            /* op */ op,\n            /* variables */ v,\n            /* actions */ a,\n            /* transformations */ t,\n            /* file name */ std::string(*yystack_[3].location.end.filename),\n            /* line number */ yystack_[3].location.end.line\n            ));\n\n        if (driver.addSecRule(std::move(rule)) == false) {\n            YYERROR;\n        }\n      }\n#line 2360 \"seclang-parser.cc\"\n    break;\n\n  case 77: // expression: \"DIRECTIVE\" variables op\n#line 1144 \"seclang-parser.yy\"\n      {\n        variables::Variables *v = new variables::Variables();\n        for (auto &i : *yystack_[1].value.as < std::unique_ptr<std::vector<std::unique_ptr<Variable> > >  > ().get()) {\n            v->push_back(i.release());\n        }\n\n        std::unique_ptr<RuleWithOperator> rule(new RuleWithOperator(\n            /* op */ yystack_[0].value.as < std::unique_ptr<Operator> > ().release(),\n            /* variables */ v,\n            /* actions */ NULL,\n            /* transformations */ NULL,\n            /* file name */ std::string(*yystack_[2].location.end.filename),\n            /* line number */ yystack_[2].location.end.line\n            ));\n        if (driver.addSecRule(std::move(rule)) == false) {\n            YYERROR;\n        }\n      }\n#line 2383 \"seclang-parser.cc\"\n    break;\n\n  case 78: // expression: \"CONFIG_DIR_SEC_ACTION\" actions\n#line 1163 \"seclang-parser.yy\"\n      {\n        std::vector<actions::Action *> *a = new std::vector<actions::Action *>();\n        std::vector<actions::transformations::Transformation *> *t = new std::vector<actions::transformations::Transformation *>();\n        for (auto &i : *yystack_[0].value.as < std::unique_ptr<std::vector<std::unique_ptr<actions::Action> > >  > ().get()) {\n            if (auto pt = dynamic_cast<actions::transformations::Transformation *>(i.get())) {\n              t->push_back(pt);\n              i.release();\n            } else {\n              a->push_back(i.release());\n            }\n        }\n        std::unique_ptr<RuleUnconditional> rule(new RuleUnconditional(\n            /* actions */ a,\n            /* transformations */ t,\n            /* file name */ std::string(*yystack_[1].location.end.filename),\n            /* line number */ yystack_[1].location.end.line\n            ));\n        driver.addSecAction(std::move(rule));\n      }\n#line 2407 \"seclang-parser.cc\"\n    break;\n\n  case 79: // expression: \"DIRECTIVE_SECRULESCRIPT\" actions\n#line 1183 \"seclang-parser.yy\"\n      {\n        std::string err;\n        std::vector<actions::Action *> *a = new std::vector<actions::Action *>();\n        std::vector<actions::transformations::Transformation *> *t = new std::vector<actions::transformations::Transformation *>();\n        for (auto &i : *yystack_[0].value.as < std::unique_ptr<std::vector<std::unique_ptr<actions::Action> > >  > ().get()) {\n            if (auto pt = dynamic_cast<actions::transformations::Transformation *>(i.get())) {\n              t->push_back(pt);\n              i.release();\n            } else {\n              a->push_back(i.release());\n            }\n        }\n        std::unique_ptr<RuleScript> r(new RuleScript(\n            /* path to script */ yystack_[1].value.as < std::string > (),\n            /* actions */ a,\n            /* transformations */ t,\n            /* file name */ std::string(*yystack_[1].location.end.filename),\n            /* line number */ yystack_[1].location.end.line\n            ));\n\n        if (r->init(&err) == false) {\n            driver.error(yystack_[2].location, \"Failed to load script: \" + err);\n            YYERROR;\n        }\n        if (driver.addSecRuleScript(std::move(r)) == false) {\n            YYERROR;\n        }\n      }\n#line 2440 \"seclang-parser.cc\"\n    break;\n\n  case 80: // expression: \"CONFIG_DIR_SEC_DEFAULT_ACTION\" actions\n#line 1212 \"seclang-parser.yy\"\n      {\n        bool hasDisruptive = false;\n        std::vector<actions::Action *> *actions = new std::vector<actions::Action *>();\n        for (auto &i : *yystack_[0].value.as < std::unique_ptr<std::vector<std::unique_ptr<actions::Action> > >  > ().get()) {\n            actions->push_back(i.release());\n        }\n        std::vector<actions::Action *> checkedActions;\n        int definedPhase = -1;\n        int secRuleDefinedPhase = -1;\n        for (actions::Action *a : *actions) {\n            actions::Phase *phase = dynamic_cast<actions::Phase *>(a);\n            if (a->isDisruptive() == true && dynamic_cast<actions::Block *>(a) == NULL) {\n                hasDisruptive = true;\n            }\n            if (phase != NULL) {\n                definedPhase = phase->m_phase;\n                secRuleDefinedPhase = phase->m_secRulesPhase;\n                delete phase;\n            } else if (a->action_kind == actions::Action::Kind::RunTimeOnlyIfMatchKind ||\n                a->action_kind == actions::Action::Kind::RunTimeBeforeMatchAttemptKind) {\n                                actions::transformations::None *none = dynamic_cast<actions::transformations::None *>(a);\n                if (none != NULL) {\n                    driver.error(yystack_[2].location, \"The transformation none is not suitable to be part of the SecDefaultActions\");\n                    YYERROR;\n                }\n                checkedActions.push_back(a);\n            } else {\n                driver.error(yystack_[2].location, \"The action '\" + *a->m_name.get() + \"' is not suitable to be part of the SecDefaultActions\");\n                YYERROR;\n            }\n        }\n        if (definedPhase == -1) {\n            definedPhase = modsecurity::Phases::RequestHeadersPhase;\n        }\n\n        if (hasDisruptive == false) {\n            driver.error(yystack_[2].location, \"SecDefaultAction must specify a disruptive action.\");\n            YYERROR;\n        }\n\n        if (!driver.m_defaultActions[definedPhase].empty()) {\n            std::stringstream ss;\n            ss << \"SecDefaultActions can only be placed once per phase and configuration context. Phase \";\n            ss << secRuleDefinedPhase;\n            ss << \" was informed already.\";\n            driver.error(yystack_[2].location, ss.str());\n            YYERROR;\n        }\n\n        for (actions::Action *a : checkedActions) {\n            driver.m_defaultActions[definedPhase].push_back(\n                std::unique_ptr<actions::Action>(a));\n        }\n\n        delete actions;\n      }\n#line 2501 \"seclang-parser.cc\"\n    break;\n\n  case 81: // expression: \"CONFIG_DIR_SEC_MARKER\"\n#line 1269 \"seclang-parser.yy\"\n      {\n        driver.addSecMarker(modsecurity::utils::string::removeBracketsIfNeeded(yystack_[0].value.as < std::string > ()),\n            /* file name */ std::string(*yystack_[0].location.end.filename),\n            /* line number */ yystack_[0].location.end.line\n        );\n      }\n#line 2512 \"seclang-parser.cc\"\n    break;\n\n  case 82: // expression: \"CONFIG_DIR_RULE_ENG\" \"CONFIG_VALUE_OFF\"\n#line 1276 \"seclang-parser.yy\"\n      {\n        driver.m_secRuleEngine = modsecurity::RulesSet::DisabledRuleEngine;\n      }\n#line 2520 \"seclang-parser.cc\"\n    break;\n\n  case 83: // expression: \"CONFIG_DIR_RULE_ENG\" \"CONFIG_VALUE_ON\"\n#line 1280 \"seclang-parser.yy\"\n      {\n        driver.m_secRuleEngine = modsecurity::RulesSet::EnabledRuleEngine;\n      }\n#line 2528 \"seclang-parser.cc\"\n    break;\n\n  case 84: // expression: \"CONFIG_DIR_RULE_ENG\" \"CONFIG_VALUE_DETC\"\n#line 1284 \"seclang-parser.yy\"\n      {\n        driver.m_secRuleEngine = modsecurity::RulesSet::DetectionOnlyRuleEngine;\n      }\n#line 2536 \"seclang-parser.cc\"\n    break;\n\n  case 85: // expression: \"CONFIG_DIR_REQ_BODY\" \"CONFIG_VALUE_ON\"\n#line 1288 \"seclang-parser.yy\"\n      {\n        driver.m_secRequestBodyAccess = modsecurity::RulesSetProperties::TrueConfigBoolean;\n      }\n#line 2544 \"seclang-parser.cc\"\n    break;\n\n  case 86: // expression: \"CONFIG_DIR_REQ_BODY\" \"CONFIG_VALUE_OFF\"\n#line 1292 \"seclang-parser.yy\"\n      {\n        driver.m_secRequestBodyAccess = modsecurity::RulesSetProperties::FalseConfigBoolean;\n      }\n#line 2552 \"seclang-parser.cc\"\n    break;\n\n  case 87: // expression: \"CONFIG_DIR_RES_BODY\" \"CONFIG_VALUE_ON\"\n#line 1296 \"seclang-parser.yy\"\n      {\n        driver.m_secResponseBodyAccess = modsecurity::RulesSetProperties::TrueConfigBoolean;\n      }\n#line 2560 \"seclang-parser.cc\"\n    break;\n\n  case 88: // expression: \"CONFIG_DIR_RES_BODY\" \"CONFIG_VALUE_OFF\"\n#line 1300 \"seclang-parser.yy\"\n      {\n        driver.m_secResponseBodyAccess = modsecurity::RulesSetProperties::FalseConfigBoolean;\n      }\n#line 2568 \"seclang-parser.cc\"\n    break;\n\n  case 89: // expression: \"CONFIG_SEC_ARGUMENT_SEPARATOR\"\n#line 1304 \"seclang-parser.yy\"\n      {\n        if (yystack_[0].value.as < std::string > ().length() != 1) {\n          driver.error(yystack_[1].location, \"Argument separator should be set to a single character.\");\n          YYERROR;\n        }\n        driver.m_secArgumentSeparator.m_value = yystack_[0].value.as < std::string > ();\n        driver.m_secArgumentSeparator.m_set = true;\n      }\n#line 2581 \"seclang-parser.cc\"\n    break;\n\n  case 90: // expression: \"CONFIG_COMPONENT_SIG\"\n#line 1313 \"seclang-parser.yy\"\n      {\n        driver.m_components.push_back(yystack_[0].value.as < std::string > ());\n      }\n#line 2589 \"seclang-parser.cc\"\n    break;\n\n  case 91: // expression: \"CONFIG_CONN_ENGINE\" \"CONFIG_VALUE_ON\"\n#line 1317 \"seclang-parser.yy\"\n      {\n        driver.error(yystack_[2].location, \"SecConnEngine is not yet supported.\");\n        YYERROR;\n      }\n#line 2598 \"seclang-parser.cc\"\n    break;\n\n  case 92: // expression: \"CONFIG_CONN_ENGINE\" \"CONFIG_VALUE_OFF\"\n#line 1322 \"seclang-parser.yy\"\n      {\n      }\n#line 2605 \"seclang-parser.cc\"\n    break;\n\n  case 93: // expression: \"CONFIG_SEC_WEB_APP_ID\"\n#line 1325 \"seclang-parser.yy\"\n      {\n        driver.m_secWebAppId.m_value = yystack_[0].value.as < std::string > ();\n        driver.m_secWebAppId.m_set = true;\n      }\n#line 2614 \"seclang-parser.cc\"\n    break;\n\n  case 94: // expression: \"CONFIG_SEC_SERVER_SIG\"\n#line 1330 \"seclang-parser.yy\"\n      {\n        driver.error(yystack_[1].location, \"SecServerSignature is not supported.\");\n        YYERROR;\n      }\n#line 2623 \"seclang-parser.cc\"\n    break;\n\n  case 95: // expression: \"CONFIG_SEC_CACHE_TRANSFORMATIONS\"\n#line 1335 \"seclang-parser.yy\"\n      {\n        driver.error(yystack_[1].location, \"SecCacheTransformations is not supported.\");\n        YYERROR;\n      }\n#line 2632 \"seclang-parser.cc\"\n    break;\n\n  case 96: // expression: \"CONFIG_SEC_DISABLE_BACKEND_COMPRESS\" \"CONFIG_VALUE_ON\"\n#line 1340 \"seclang-parser.yy\"\n      {\n        driver.error(yystack_[2].location, \"SecDisableBackendCompression is not supported.\");\n        YYERROR;\n      }\n#line 2641 \"seclang-parser.cc\"\n    break;\n\n  case 97: // expression: \"CONFIG_SEC_DISABLE_BACKEND_COMPRESS\" \"CONFIG_VALUE_OFF\"\n#line 1345 \"seclang-parser.yy\"\n      {\n      }\n#line 2648 \"seclang-parser.cc\"\n    break;\n\n  case 98: // expression: \"CONFIG_CONTENT_INJECTION\" \"CONFIG_VALUE_ON\"\n#line 1348 \"seclang-parser.yy\"\n      {\n        driver.error(yystack_[2].location, \"SecContentInjection is not yet supported.\");\n        YYERROR;\n      }\n#line 2657 \"seclang-parser.cc\"\n    break;\n\n  case 99: // expression: \"CONFIG_CONTENT_INJECTION\" \"CONFIG_VALUE_OFF\"\n#line 1353 \"seclang-parser.yy\"\n      {\n      }\n#line 2664 \"seclang-parser.cc\"\n    break;\n\n  case 100: // expression: \"CONFIG_SEC_CHROOT_DIR\"\n#line 1356 \"seclang-parser.yy\"\n      {\n        driver.error(yystack_[1].location, \"SecChrootDir is not supported.\");\n        YYERROR;\n      }\n#line 2673 \"seclang-parser.cc\"\n    break;\n\n  case 101: // expression: \"CONFIG_SEC_HASH_ENGINE\" \"CONFIG_VALUE_ON\"\n#line 1361 \"seclang-parser.yy\"\n      {\n        driver.error(yystack_[2].location, \"SecHashEngine is not yet supported.\");\n        YYERROR;\n      }\n#line 2682 \"seclang-parser.cc\"\n    break;\n\n  case 102: // expression: \"CONFIG_SEC_HASH_ENGINE\" \"CONFIG_VALUE_OFF\"\n#line 1366 \"seclang-parser.yy\"\n      {\n      }\n#line 2689 \"seclang-parser.cc\"\n    break;\n\n  case 103: // expression: \"CONFIG_SEC_HASH_KEY\"\n#line 1369 \"seclang-parser.yy\"\n      {\n        driver.error(yystack_[1].location, \"SecHashKey is not yet supported.\");\n        YYERROR;\n      }\n#line 2698 \"seclang-parser.cc\"\n    break;\n\n  case 104: // expression: \"CONFIG_SEC_HASH_PARAM\"\n#line 1374 \"seclang-parser.yy\"\n      {\n        driver.error(yystack_[1].location, \"SecHashParam is not yet supported.\");\n        YYERROR;\n      }\n#line 2707 \"seclang-parser.cc\"\n    break;\n\n  case 105: // expression: \"CONFIG_SEC_HASH_METHOD_RX\"\n#line 1379 \"seclang-parser.yy\"\n      {\n        driver.error(yystack_[1].location, \"SecHashMethodRx is not yet supported.\");\n        YYERROR;\n      }\n#line 2716 \"seclang-parser.cc\"\n    break;\n\n  case 106: // expression: \"CONFIG_SEC_HASH_METHOD_PM\"\n#line 1384 \"seclang-parser.yy\"\n      {\n        driver.error(yystack_[1].location, \"SecHashMethodPm is not yet supported.\");\n        YYERROR;\n      }\n#line 2725 \"seclang-parser.cc\"\n    break;\n\n  case 107: // expression: \"CONFIG_DIR_GSB_DB\"\n#line 1389 \"seclang-parser.yy\"\n      {\n        driver.error(yystack_[1].location, \"SecGsbLookupDb is not supported.\");\n        YYERROR;\n      }\n#line 2734 \"seclang-parser.cc\"\n    break;\n\n  case 108: // expression: \"CONFIG_SEC_GUARDIAN_LOG\"\n#line 1394 \"seclang-parser.yy\"\n      {\n        driver.error(yystack_[1].location, \"SecGuardianLog is not supported.\");\n        YYERROR;\n      }\n#line 2743 \"seclang-parser.cc\"\n    break;\n\n  case 109: // expression: \"CONFIG_SEC_INTERCEPT_ON_ERROR\" \"CONFIG_VALUE_ON\"\n#line 1399 \"seclang-parser.yy\"\n      {\n        driver.error(yystack_[2].location, \"SecInterceptOnError is not yet supported.\");\n        YYERROR;\n      }\n#line 2752 \"seclang-parser.cc\"\n    break;\n\n  case 110: // expression: \"CONFIG_SEC_INTERCEPT_ON_ERROR\" \"CONFIG_VALUE_OFF\"\n#line 1404 \"seclang-parser.yy\"\n      {\n      }\n#line 2759 \"seclang-parser.cc\"\n    break;\n\n  case 111: // expression: \"CONFIG_SEC_CONN_R_STATE_LIMIT\"\n#line 1407 \"seclang-parser.yy\"\n      {\n        driver.error(yystack_[1].location, \"SecConnReadStateLimit is not yet supported.\");\n        YYERROR;\n      }\n#line 2768 \"seclang-parser.cc\"\n    break;\n\n  case 112: // expression: \"CONFIG_SEC_CONN_W_STATE_LIMIT\"\n#line 1412 \"seclang-parser.yy\"\n      {\n        driver.error(yystack_[1].location, \"SecConnWriteStateLimit is not yet supported.\");\n        YYERROR;\n      }\n#line 2777 \"seclang-parser.cc\"\n    break;\n\n  case 113: // expression: \"CONFIG_SEC_SENSOR_ID\"\n#line 1417 \"seclang-parser.yy\"\n      {\n        driver.error(yystack_[1].location, \"SecSensorId is not yet supported.\");\n        YYERROR;\n      }\n#line 2786 \"seclang-parser.cc\"\n    break;\n\n  case 114: // expression: \"CONFIG_SEC_RULE_INHERITANCE\" \"CONFIG_VALUE_ON\"\n#line 1422 \"seclang-parser.yy\"\n      {\n        driver.error(yystack_[2].location, \"SecRuleInheritance is not yet supported.\");\n        YYERROR;\n      }\n#line 2795 \"seclang-parser.cc\"\n    break;\n\n  case 115: // expression: \"CONFIG_SEC_RULE_INHERITANCE\" \"CONFIG_VALUE_OFF\"\n#line 1427 \"seclang-parser.yy\"\n      {\n      }\n#line 2802 \"seclang-parser.cc\"\n    break;\n\n  case 116: // expression: \"CONFIG_SEC_RULE_PERF_TIME\"\n#line 1430 \"seclang-parser.yy\"\n      {\n        driver.error(yystack_[1].location, \"SecRulePerfTime is not yet supported.\");\n        YYERROR;\n      }\n#line 2811 \"seclang-parser.cc\"\n    break;\n\n  case 117: // expression: \"CONFIG_SEC_STREAM_IN_BODY_INSPECTION\"\n#line 1435 \"seclang-parser.yy\"\n      {\n        driver.error(yystack_[1].location, \"SecStreamInBodyInspection is not supported.\");\n        YYERROR;\n      }\n#line 2820 \"seclang-parser.cc\"\n    break;\n\n  case 118: // expression: \"CONFIG_SEC_STREAM_OUT_BODY_INSPECTION\"\n#line 1440 \"seclang-parser.yy\"\n      {\n        driver.error(yystack_[1].location, \"SecStreamOutBodyInspection is not supported.\");\n        YYERROR;\n      }\n#line 2829 \"seclang-parser.cc\"\n    break;\n\n  case 119: // expression: \"CONFIG_SEC_RULE_REMOVE_BY_ID\"\n#line 1445 \"seclang-parser.yy\"\n      {\n        std::string error;\n        if (driver.m_exceptions.load(yystack_[0].value.as < std::string > (), &error) == false) {\n            std::stringstream ss;\n            ss << \"SecRuleRemoveById: failed to load:\";\n            ss << yystack_[0].value.as < std::string > ();\n            ss << \". \";\n            ss << error;\n            driver.error(yystack_[1].location, ss.str());\n            YYERROR;\n        }\n      }\n#line 2846 \"seclang-parser.cc\"\n    break;\n\n  case 120: // expression: \"CONFIG_SEC_RULE_REMOVE_BY_TAG\"\n#line 1458 \"seclang-parser.yy\"\n      {\n        std::string error;\n        if (driver.m_exceptions.loadRemoveRuleByTag(yystack_[0].value.as < std::string > (), &error) == false) {\n            std::stringstream ss;\n            ss << \"SecRuleRemoveByTag: failed to load:\";\n            ss << yystack_[0].value.as < std::string > ();\n            ss << \". \";\n            ss << error;\n            driver.error(yystack_[1].location, ss.str());\n            YYERROR;\n        }\n      }\n#line 2863 \"seclang-parser.cc\"\n    break;\n\n  case 121: // expression: \"CONFIG_SEC_RULE_REMOVE_BY_MSG\"\n#line 1471 \"seclang-parser.yy\"\n      {\n        std::string error;\n        if (driver.m_exceptions.loadRemoveRuleByMsg(yystack_[0].value.as < std::string > (), &error) == false) {\n            std::stringstream ss;\n            ss << \"SecRuleRemoveByMsg: failed to load:\";\n            ss << yystack_[0].value.as < std::string > ();\n            ss << \". \";\n            ss << error;\n            driver.error(yystack_[1].location, ss.str());\n            YYERROR;\n        }\n      }\n#line 2880 \"seclang-parser.cc\"\n    break;\n\n  case 122: // expression: \"CONFIG_SEC_RULE_UPDATE_TARGET_BY_TAG\" variables_pre_process\n#line 1484 \"seclang-parser.yy\"\n      {\n        std::string error;\n        if (driver.m_exceptions.loadUpdateTargetByTag(yystack_[1].value.as < std::string > (), std::move(yystack_[0].value.as < std::unique_ptr<std::vector<std::unique_ptr<Variable> > >  > ()), &error) == false) {\n            std::stringstream ss;\n            ss << \"SecRuleUpdateTargetByTag: failed to load:\";\n            ss << yystack_[1].value.as < std::string > ();\n            ss << \". \";\n            ss << error;\n            driver.error(yystack_[2].location, ss.str());\n            YYERROR;\n        }\n      }\n#line 2897 \"seclang-parser.cc\"\n    break;\n\n  case 123: // expression: \"CONFIG_SEC_RULE_UPDATE_TARGET_BY_MSG\" variables_pre_process\n#line 1497 \"seclang-parser.yy\"\n      {\n        std::string error;\n        if (driver.m_exceptions.loadUpdateTargetByMsg(yystack_[1].value.as < std::string > (), std::move(yystack_[0].value.as < std::unique_ptr<std::vector<std::unique_ptr<Variable> > >  > ()), &error) == false) {\n            std::stringstream ss;\n            ss << \"SecRuleUpdateTargetByMsg: failed to load:\";\n            ss << yystack_[1].value.as < std::string > ();\n            ss << \". \";\n            ss << error;\n            driver.error(yystack_[2].location, ss.str());\n            YYERROR;\n        }\n      }\n#line 2914 \"seclang-parser.cc\"\n    break;\n\n  case 124: // expression: \"CONFIG_SEC_RULE_UPDATE_TARGET_BY_ID\" variables_pre_process\n#line 1510 \"seclang-parser.yy\"\n      {\n        std::string error;\n        double ruleId;\n        try {\n            ruleId = std::stod(yystack_[1].value.as < std::string > ());\n        } catch (...) {\n            std::stringstream ss;\n            ss << \"SecRuleUpdateTargetById: failed to load:\";\n            ss << \"The input \\\"\" + yystack_[1].value.as < std::string > () + \"\\\" does not \";\n            ss << \"seems to be a valid rule id.\";\n            ss << \". \";\n            driver.error(yystack_[2].location, ss.str());\n            YYERROR;\n        }\n\n        if (driver.m_exceptions.loadUpdateTargetById(ruleId, std::move(yystack_[0].value.as < std::unique_ptr<std::vector<std::unique_ptr<Variable> > >  > ()), &error) == false) {\n            std::stringstream ss;\n            ss << \"SecRuleUpdateTargetById: failed to load:\";\n            ss << yystack_[1].value.as < std::string > ();\n            ss << \". \";\n            ss << error;\n            driver.error(yystack_[2].location, ss.str());\n            YYERROR;\n        }\n      }\n#line 2944 \"seclang-parser.cc\"\n    break;\n\n  case 125: // expression: \"CONFIG_SEC_RULE_UPDATE_ACTION_BY_ID\" actions\n#line 1536 \"seclang-parser.yy\"\n      {\n        std::string error;\n        double ruleId;\n        try {\n            ruleId = std::stod(yystack_[1].value.as < std::string > ());\n        } catch (...) {\n            std::stringstream ss;\n            ss << \"SecRuleUpdateActionById: failed to load:\";\n            ss << \"The input \\\"\" + yystack_[1].value.as < std::string > () + \"\\\" does not \";\n            ss << \"seems to be a valid rule id.\";\n            ss << \". \";\n            driver.error(yystack_[2].location, ss.str());\n            YYERROR;\n        }\n\n\n        if (driver.m_exceptions.loadUpdateActionById(ruleId, std::move(yystack_[0].value.as < std::unique_ptr<std::vector<std::unique_ptr<actions::Action> > >  > ()), &error) == false) {\n            std::stringstream ss;\n            ss << \"SecRuleUpdateActionById: failed to load:\";\n            ss << yystack_[1].value.as < std::string > ();\n            ss << \". \";\n            ss << error;\n            driver.error(yystack_[2].location, ss.str());\n            YYERROR;\n        }\n      }\n#line 2975 \"seclang-parser.cc\"\n    break;\n\n  case 126: // expression: \"CONFIG_DIR_DEBUG_LVL\"\n#line 1564 \"seclang-parser.yy\"\n      {\n        if (driver.m_debugLog != NULL) {\n          driver.m_debugLog->setDebugLogLevel(atoi(yystack_[0].value.as < std::string > ().c_str()));\n        } else {\n            std::stringstream ss;\n            ss << \"Internal error, there is no DebugLog \";\n            ss << \"object associated with the driver class\";\n            driver.error(yystack_[1].location, ss.str());\n            YYERROR;\n        }\n      }\n#line 2991 \"seclang-parser.cc\"\n    break;\n\n  case 127: // expression: \"CONFIG_DIR_DEBUG_LOG\"\n#line 1576 \"seclang-parser.yy\"\n      {\n        if (driver.m_debugLog != NULL) {\n            std::string error;\n            driver.m_debugLog->setDebugLogFile(yystack_[0].value.as < std::string > (), &error);\n            if (error.size() > 0) {\n                std::stringstream ss;\n                ss << \"Failed to start DebugLog: \" << error;\n                driver.error(yystack_[1].location, ss.str());\n                YYERROR;\n            }\n        } else {\n            std::stringstream ss;\n            ss << \"Internal error, there is no DebugLog \";\n            ss << \"object associated with the driver class\";\n            driver.error(yystack_[1].location, ss.str());\n            YYERROR;\n        }\n      }\n#line 3014 \"seclang-parser.cc\"\n    break;\n\n  case 128: // expression: \"CONFIG_DIR_GEO_DB\"\n#line 1596 \"seclang-parser.yy\"\n      {\n#if defined(WITH_GEOIP) or defined(WITH_MAXMIND)\n        std::string err;\n        std::string file = modsecurity::utils::find_resource(yystack_[0].value.as < std::string > (),\n            *yystack_[0].location.end.filename, &err);\n        if (file.empty()) {\n            std::stringstream ss;\n            ss << \"Failed to load locate the GeoDB file from: \" << yystack_[0].value.as < std::string > () << \" \";\n            ss << err;\n            driver.error(yystack_[1].location, ss.str());\n            YYERROR;\n        }\n        if (Utils::GeoLookup::getInstance().setDataBase(file, &err) == false) {\n            std::stringstream ss;\n            ss << \"Failed to load the GeoDB from: \";\n            ss << file << \". \" << err;\n            driver.error(yystack_[1].location, ss.str());\n            YYERROR;\n        }\n#else\n        std::stringstream ss;\n        ss << \"This version of ModSecurity was not compiled with GeoIP or MaxMind support.\";\n        driver.error(yystack_[1].location, ss.str());\n        YYERROR;\n#endif  // WITH_GEOIP\n      }\n#line 3045 \"seclang-parser.cc\"\n    break;\n\n  case 129: // expression: \"CONFIG_DIR_ARGS_LIMIT\"\n#line 1623 \"seclang-parser.yy\"\n      {\n        driver.m_argumentsLimit.m_set = true;\n        driver.m_argumentsLimit.m_value = atoi(yystack_[0].value.as < std::string > ().c_str());\n      }\n#line 3054 \"seclang-parser.cc\"\n    break;\n\n  case 130: // expression: \"CONFIG_DIR_REQ_BODY_JSON_DEPTH_LIMIT\"\n#line 1628 \"seclang-parser.yy\"\n      {\n        driver.m_requestBodyJsonDepthLimit.m_set = true;\n        driver.m_requestBodyJsonDepthLimit.m_value = atoi(yystack_[0].value.as < std::string > ().c_str());\n      }\n#line 3063 \"seclang-parser.cc\"\n    break;\n\n  case 131: // expression: \"CONFIG_DIR_REQ_BODY_LIMIT\"\n#line 1634 \"seclang-parser.yy\"\n      {\n        std::string errmsg = \"\";\n        if (driver.m_requestBodyLimit.parse(std::string(yystack_[0].value.as < std::string > ()), &errmsg) != true) {\n          driver.error(yystack_[1].location, \"Failed to parse SecRequestBodyLimit: \" + errmsg);\n          YYERROR;\n        }\n      }\n#line 3075 \"seclang-parser.cc\"\n    break;\n\n  case 132: // expression: \"CONFIG_DIR_REQ_BODY_NO_FILES_LIMIT\"\n#line 1642 \"seclang-parser.yy\"\n      {\n        std::string errmsg = \"\";\n        if (driver.m_requestBodyNoFilesLimit.parse(std::string(yystack_[0].value.as < std::string > ()), &errmsg) != true) {\n          driver.error(yystack_[1].location, \"Failed to parse SecRequestsBodyNoFilesLimit: \" + errmsg);\n          YYERROR;\n        }\n      }\n#line 3087 \"seclang-parser.cc\"\n    break;\n\n  case 133: // expression: \"CONFIG_DIR_REQ_BODY_IN_MEMORY_LIMIT\"\n#line 1650 \"seclang-parser.yy\"\n      {\n        std::stringstream ss;\n        ss << \"As of ModSecurity version 3.0, SecRequestBodyInMemoryLimit is no longer \";\n        ss << \"supported. Instead, you can use your web server configurations to control \";\n        ss << \"those values. ModSecurity will follow the web server decision.\";\n        driver.error(yystack_[1].location, ss.str());\n        YYERROR;\n      }\n#line 3100 \"seclang-parser.cc\"\n    break;\n\n  case 134: // expression: \"CONFIG_DIR_RES_BODY_LIMIT\"\n#line 1659 \"seclang-parser.yy\"\n      {\n        std::string errmsg = \"\";\n        if (driver.m_responseBodyLimit.parse(std::string(yystack_[0].value.as < std::string > ()), &errmsg) != true) {\n          driver.error(yystack_[1].location, \"Failed to parse SecResponseBodyLimit: \" + errmsg);\n          YYERROR;\n        }\n      }\n#line 3112 \"seclang-parser.cc\"\n    break;\n\n  case 135: // expression: \"CONFIG_DIR_REQ_BODY_LIMIT_ACTION\" \"CONFIG_VALUE_PROCESS_PARTIAL\"\n#line 1667 \"seclang-parser.yy\"\n      {\n        driver.m_requestBodyLimitAction = modsecurity::RulesSet::BodyLimitAction::ProcessPartialBodyLimitAction;\n      }\n#line 3120 \"seclang-parser.cc\"\n    break;\n\n  case 136: // expression: \"CONFIG_DIR_REQ_BODY_LIMIT_ACTION\" \"CONFIG_VALUE_REJECT\"\n#line 1671 \"seclang-parser.yy\"\n      {\n        driver.m_requestBodyLimitAction = modsecurity::RulesSet::BodyLimitAction::RejectBodyLimitAction;\n      }\n#line 3128 \"seclang-parser.cc\"\n    break;\n\n  case 137: // expression: \"CONFIG_DIR_RES_BODY_LIMIT_ACTION\" \"CONFIG_VALUE_PROCESS_PARTIAL\"\n#line 1675 \"seclang-parser.yy\"\n      {\n        driver.m_responseBodyLimitAction = modsecurity::RulesSet::BodyLimitAction::ProcessPartialBodyLimitAction;\n      }\n#line 3136 \"seclang-parser.cc\"\n    break;\n\n  case 138: // expression: \"CONFIG_DIR_RES_BODY_LIMIT_ACTION\" \"CONFIG_VALUE_REJECT\"\n#line 1679 \"seclang-parser.yy\"\n      {\n        driver.m_responseBodyLimitAction = modsecurity::RulesSet::BodyLimitAction::RejectBodyLimitAction;\n      }\n#line 3144 \"seclang-parser.cc\"\n    break;\n\n  case 139: // expression: \"CONFIG_SEC_REMOTE_RULES_FAIL_ACTION\" \"CONFIG_VALUE_ABORT\"\n#line 1683 \"seclang-parser.yy\"\n      {\n        driver.m_remoteRulesActionOnFailed = RulesSet::OnFailedRemoteRulesAction::AbortOnFailedRemoteRulesAction;\n      }\n#line 3152 \"seclang-parser.cc\"\n    break;\n\n  case 140: // expression: \"CONFIG_SEC_REMOTE_RULES_FAIL_ACTION\" \"CONFIG_VALUE_WARN\"\n#line 1687 \"seclang-parser.yy\"\n      {\n        driver.m_remoteRulesActionOnFailed = RulesSet::OnFailedRemoteRulesAction::WarnOnFailedRemoteRulesAction;\n      }\n#line 3160 \"seclang-parser.cc\"\n    break;\n\n  case 142: // expression: \"CONFIG_DIR_PCRE_MATCH_LIMIT\"\n#line 1696 \"seclang-parser.yy\"\n      {\n        std::string errmsg = \"\";\n        if (driver.m_pcreMatchLimit.parse(std::string(yystack_[0].value.as < std::string > ()), &errmsg) != true) {\n          driver.error(yystack_[1].location, \"Failed to parse SecPcreMatchLimit: \" + errmsg);\n          YYERROR;\n        }\n      }\n#line 3172 \"seclang-parser.cc\"\n    break;\n\n  case 143: // expression: \"CONGIG_DIR_RESPONSE_BODY_MP\"\n#line 1704 \"seclang-parser.yy\"\n      {\n        std::istringstream buf(yystack_[0].value.as < std::string > ());\n        std::istream_iterator<std::string> beg(buf), end;\n        std::set<std::string> tokens(beg, end);\n        driver.m_responseBodyTypeToBeInspected.m_set = true;\n        for (std::set<std::string>::iterator it=tokens.begin();\n            it!=tokens.end(); ++it)\n        {\n            driver.m_responseBodyTypeToBeInspected.m_value.insert(*it);\n        }\n      }\n#line 3188 \"seclang-parser.cc\"\n    break;\n\n  case 144: // expression: \"CONGIG_DIR_RESPONSE_BODY_MP_CLEAR\"\n#line 1716 \"seclang-parser.yy\"\n      {\n        driver.m_responseBodyTypeToBeInspected.m_set = true;\n        driver.m_responseBodyTypeToBeInspected.m_clear = true;\n        driver.m_responseBodyTypeToBeInspected.m_value.clear();\n      }\n#line 3198 \"seclang-parser.cc\"\n    break;\n\n  case 145: // expression: \"CONFIG_XML_EXTERNAL_ENTITY\" \"CONFIG_VALUE_OFF\"\n#line 1722 \"seclang-parser.yy\"\n      {\n        driver.m_secXMLExternalEntity = modsecurity::RulesSetProperties::FalseConfigBoolean;\n      }\n#line 3206 \"seclang-parser.cc\"\n    break;\n\n  case 146: // expression: \"CONFIG_XML_EXTERNAL_ENTITY\" \"CONFIG_VALUE_ON\"\n#line 1726 \"seclang-parser.yy\"\n      {\n        driver.m_secXMLExternalEntity = modsecurity::RulesSetProperties::TrueConfigBoolean;\n      }\n#line 3214 \"seclang-parser.cc\"\n    break;\n\n  case 147: // expression: \"CONFIG_XML_PARSE_XML_INTO_ARGS\" \"CONFIG_VALUE_ONLYARGS\"\n#line 1730 \"seclang-parser.yy\"\n      {\n        driver.m_secXMLParseXmlIntoArgs = modsecurity::RulesSetProperties::OnlyArgsConfigXMLParseXmlIntoArgs;\n      }\n#line 3222 \"seclang-parser.cc\"\n    break;\n\n  case 148: // expression: \"CONFIG_XML_PARSE_XML_INTO_ARGS\" \"CONFIG_VALUE_OFF\"\n#line 1734 \"seclang-parser.yy\"\n      {\n        driver.m_secXMLParseXmlIntoArgs = modsecurity::RulesSetProperties::FalseConfigXMLParseXmlIntoArgs;\n      }\n#line 3230 \"seclang-parser.cc\"\n    break;\n\n  case 149: // expression: \"CONFIG_XML_PARSE_XML_INTO_ARGS\" \"CONFIG_VALUE_ON\"\n#line 1738 \"seclang-parser.yy\"\n      {\n        driver.m_secXMLParseXmlIntoArgs = modsecurity::RulesSetProperties::TrueConfigXMLParseXmlIntoArgs;\n      }\n#line 3238 \"seclang-parser.cc\"\n    break;\n\n  case 150: // expression: \"CONGIG_DIR_SEC_TMP_DIR\"\n#line 1742 \"seclang-parser.yy\"\n      {\n/* Parser error disabled to avoid breaking default installations with modsecurity.conf-recommended\n        std::stringstream ss;\n        ss << \"As of ModSecurity version 3.0, SecTmpDir is no longer supported.\";\n        ss << \" Instead, you can use your web server configurations to control when\";\n        ss << \"and where to swap. ModSecurity will follow the web server decision.\";\n        driver.error(@0, ss.str());\n        YYERROR;\n*/\n      }\n#line 3253 \"seclang-parser.cc\"\n    break;\n\n  case 153: // expression: \"CONGIG_DIR_SEC_COOKIE_FORMAT\"\n#line 1763 \"seclang-parser.yy\"\n      {\n        if (atoi(yystack_[0].value.as < std::string > ().c_str()) == 1) {\n          driver.error(yystack_[1].location, \"SecCookieFormat 1 is not yet supported.\");\n          YYERROR;\n        }\n      }\n#line 3264 \"seclang-parser.cc\"\n    break;\n\n  case 154: // expression: \"CONFIG_SEC_COOKIEV0_SEPARATOR\"\n#line 1770 \"seclang-parser.yy\"\n      {\n        driver.error(yystack_[1].location, \"SecCookieV0Separator is not yet supported.\");\n        YYERROR;\n      }\n#line 3273 \"seclang-parser.cc\"\n    break;\n\n  case 156: // expression: \"CONFIG_DIR_UNICODE_MAP_FILE\"\n#line 1780 \"seclang-parser.yy\"\n      {\n        std::string error;\n        std::vector<std::string> param;\n        double num = 0;\n        std::string f;\n        std::string file;\n        std::string err;\n        param = utils::string::ssplit(yystack_[0].value.as < std::string > (), ' ');\n        if (param.size() <= 1) {\n            std::stringstream ss;\n            ss << \"Failed to process unicode map, missing \";\n            ss << \"parameter: \" << yystack_[0].value.as < std::string > () << \" \";\n            driver.error(yystack_[1].location, ss.str());\n            YYERROR;\n        }\n\n        try {\n            num = std::stod(param.back());\n        } catch (...) {\n            std::stringstream ss;\n            ss << \"Failed to process unicode map, last parameter is \";\n            ss << \"expected to be a number: \" << param.back() << \" \";\n            driver.error(yystack_[1].location, ss.str());\n            YYERROR;\n        }\n        param.pop_back();\n\n        while (param.size() > 0) {\n            if (f.empty()) {\n                f = param.back();\n            } else {\n                f = param.back() + \" \" + f;\n            }\n            param.pop_back();\n        }\n\n        file = modsecurity::utils::find_resource(f, *yystack_[0].location.end.filename, &err);\n        if (file.empty()) {\n            std::stringstream ss;\n            ss << \"Failed to locate the unicode map file from: \" << f << \" \";\n            ss << err;\n            driver.error(yystack_[1].location, ss.str());\n            YYERROR;\n        }\n\n        ConfigUnicodeMap::loadConfig(file, num, &driver, &error);\n\n        if (!error.empty()) {\n            driver.error(yystack_[1].location, error);\n            YYERROR;\n        }\n\n      }\n#line 3331 \"seclang-parser.cc\"\n    break;\n\n  case 157: // expression: \"CONFIG_SEC_COLLECTION_TIMEOUT\"\n#line 1834 \"seclang-parser.yy\"\n      {\n/* Parser error disabled to avoid breaking default CRS installations with crs-setup.conf-recommended\n        driver.error(@0, \"SecCollectionTimeout is not yet supported.\");\n        YYERROR;\n*/\n      }\n#line 3342 \"seclang-parser.cc\"\n    break;\n\n  case 158: // expression: \"CONFIG_SEC_HTTP_BLKEY\"\n#line 1841 \"seclang-parser.yy\"\n      {\n        driver.m_httpblKey.m_set = true;\n        driver.m_httpblKey.m_value = yystack_[0].value.as < std::string > ();\n      }\n#line 3351 \"seclang-parser.cc\"\n    break;\n\n  case 159: // variables: variables_pre_process\n#line 1849 \"seclang-parser.yy\"\n      {\n        std::unique_ptr<std::vector<std::unique_ptr<Variable> > > originalList = std::move(yystack_[0].value.as < std::unique_ptr<std::vector<std::unique_ptr<Variable> > >  > ());\n        std::unique_ptr<std::vector<std::unique_ptr<Variable>>> newList(new std::vector<std::unique_ptr<Variable>>());\n        std::unique_ptr<std::vector<std::unique_ptr<Variable>>> newNewList(new std::vector<std::unique_ptr<Variable>>());\n        std::unique_ptr<std::vector<std::unique_ptr<Variable>>> exclusionVars(new std::vector<std::unique_ptr<Variable>>());\n        while (!originalList->empty()) {\n            std::unique_ptr<Variable> var = std::move(originalList->back());\n            originalList->pop_back();\n            if (dynamic_cast<VariableModificatorExclusion*>(var.get())) {\n                exclusionVars->push_back(std::move(var));\n            } else {\n                newList->push_back(std::move(var));\n            }\n        }\n\n        while (!newList->empty()) {\n            bool doNotAdd = false;\n            std::unique_ptr<Variable> var = std::move(newList->back());\n            newList->pop_back();\n            for (auto &i : *exclusionVars) {\n                if (*var == *i) {\n                    doNotAdd = true;\n                }\n                if (i->belongsToCollection(var.get())) {\n                    var->addsKeyExclusion(i.get());\n                }\n            }\n            if (!doNotAdd) {\n                newNewList->push_back(std::move(var));\n            }\n        }\n        yylhs.value.as < std::unique_ptr<std::vector<std::unique_ptr<Variable> > >  > () = std::move(newNewList);\n      }\n#line 3389 \"seclang-parser.cc\"\n    break;\n\n  case 160: // variables_pre_process: variables_may_be_quoted\n#line 1886 \"seclang-parser.yy\"\n      {\n        yylhs.value.as < std::unique_ptr<std::vector<std::unique_ptr<Variable> > >  > () = std::move(yystack_[0].value.as < std::unique_ptr<std::vector<std::unique_ptr<Variable> > >  > ());\n      }\n#line 3397 \"seclang-parser.cc\"\n    break;\n\n  case 161: // variables_pre_process: \"QUOTATION_MARK\" variables_may_be_quoted \"QUOTATION_MARK\"\n#line 1890 \"seclang-parser.yy\"\n      {\n        yylhs.value.as < std::unique_ptr<std::vector<std::unique_ptr<Variable> > >  > () = std::move(yystack_[1].value.as < std::unique_ptr<std::vector<std::unique_ptr<Variable> > >  > ());\n      }\n#line 3405 \"seclang-parser.cc\"\n    break;\n\n  case 162: // variables_may_be_quoted: variables_may_be_quoted PIPE var\n#line 1897 \"seclang-parser.yy\"\n      {\n        yystack_[2].value.as < std::unique_ptr<std::vector<std::unique_ptr<Variable> > >  > ()->push_back(std::move(yystack_[0].value.as < std::unique_ptr<Variable> > ()));\n        yylhs.value.as < std::unique_ptr<std::vector<std::unique_ptr<Variable> > >  > () = std::move(yystack_[2].value.as < std::unique_ptr<std::vector<std::unique_ptr<Variable> > >  > ());\n      }\n#line 3414 \"seclang-parser.cc\"\n    break;\n\n  case 163: // variables_may_be_quoted: variables_may_be_quoted PIPE VAR_EXCLUSION var\n#line 1902 \"seclang-parser.yy\"\n      {\n        std::unique_ptr<Variable> c(new VariableModificatorExclusion(std::move(yystack_[0].value.as < std::unique_ptr<Variable> > ())));\n        yystack_[3].value.as < std::unique_ptr<std::vector<std::unique_ptr<Variable> > >  > ()->push_back(std::move(c));\n        yylhs.value.as < std::unique_ptr<std::vector<std::unique_ptr<Variable> > >  > () = std::move(yystack_[3].value.as < std::unique_ptr<std::vector<std::unique_ptr<Variable> > >  > ());\n      }\n#line 3424 \"seclang-parser.cc\"\n    break;\n\n  case 164: // variables_may_be_quoted: variables_may_be_quoted PIPE VAR_COUNT var\n#line 1908 \"seclang-parser.yy\"\n      {\n        std::unique_ptr<Variable> c(new VariableModificatorCount(std::move(yystack_[0].value.as < std::unique_ptr<Variable> > ())));\n        yystack_[3].value.as < std::unique_ptr<std::vector<std::unique_ptr<Variable> > >  > ()->push_back(std::move(c));\n        yylhs.value.as < std::unique_ptr<std::vector<std::unique_ptr<Variable> > >  > () = std::move(yystack_[3].value.as < std::unique_ptr<std::vector<std::unique_ptr<Variable> > >  > ());\n      }\n#line 3434 \"seclang-parser.cc\"\n    break;\n\n  case 165: // variables_may_be_quoted: var\n#line 1914 \"seclang-parser.yy\"\n      {\n        std::unique_ptr<std::vector<std::unique_ptr<Variable>>> b(new std::vector<std::unique_ptr<Variable>>());\n        b->push_back(std::move(yystack_[0].value.as < std::unique_ptr<Variable> > ()));\n        yylhs.value.as < std::unique_ptr<std::vector<std::unique_ptr<Variable> > >  > () = std::move(b);\n      }\n#line 3444 \"seclang-parser.cc\"\n    break;\n\n  case 166: // variables_may_be_quoted: VAR_EXCLUSION var\n#line 1920 \"seclang-parser.yy\"\n      {\n        std::unique_ptr<std::vector<std::unique_ptr<Variable>>> b(new std::vector<std::unique_ptr<Variable>>());\n        std::unique_ptr<Variable> c(new VariableModificatorExclusion(std::move(yystack_[0].value.as < std::unique_ptr<Variable> > ())));\n        b->push_back(std::move(c));\n        yylhs.value.as < std::unique_ptr<std::vector<std::unique_ptr<Variable> > >  > () = std::move(b);\n      }\n#line 3455 \"seclang-parser.cc\"\n    break;\n\n  case 167: // variables_may_be_quoted: VAR_COUNT var\n#line 1927 \"seclang-parser.yy\"\n      {\n        std::unique_ptr<std::vector<std::unique_ptr<Variable>>> b(new std::vector<std::unique_ptr<Variable>>());\n        std::unique_ptr<Variable> c(new VariableModificatorCount(std::move(yystack_[0].value.as < std::unique_ptr<Variable> > ())));\n        b->push_back(std::move(c));\n        yylhs.value.as < std::unique_ptr<std::vector<std::unique_ptr<Variable> > >  > () = std::move(b);\n      }\n#line 3466 \"seclang-parser.cc\"\n    break;\n\n  case 168: // var: VARIABLE_ARGS \"Dictionary element\"\n#line 1937 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::Args_DictElement(yystack_[0].value.as < std::string > ()));\n      }\n#line 3474 \"seclang-parser.cc\"\n    break;\n\n  case 169: // var: VARIABLE_ARGS \"Dictionary element, selected by regexp\"\n#line 1941 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::Args_DictElementRegexp(yystack_[0].value.as < std::string > ()));\n      }\n#line 3482 \"seclang-parser.cc\"\n    break;\n\n  case 170: // var: VARIABLE_ARGS\n#line 1945 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::Args_NoDictElement());\n      }\n#line 3490 \"seclang-parser.cc\"\n    break;\n\n  case 171: // var: VARIABLE_ARGS_POST \"Dictionary element\"\n#line 1949 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::ArgsPost_DictElement(yystack_[0].value.as < std::string > ()));\n      }\n#line 3498 \"seclang-parser.cc\"\n    break;\n\n  case 172: // var: VARIABLE_ARGS_POST \"Dictionary element, selected by regexp\"\n#line 1953 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::ArgsPost_DictElementRegexp(yystack_[0].value.as < std::string > ()));\n      }\n#line 3506 \"seclang-parser.cc\"\n    break;\n\n  case 173: // var: VARIABLE_ARGS_POST\n#line 1957 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::ArgsPost_NoDictElement());\n      }\n#line 3514 \"seclang-parser.cc\"\n    break;\n\n  case 174: // var: VARIABLE_ARGS_GET \"Dictionary element\"\n#line 1961 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::ArgsGet_DictElement(yystack_[0].value.as < std::string > ()));\n      }\n#line 3522 \"seclang-parser.cc\"\n    break;\n\n  case 175: // var: VARIABLE_ARGS_GET \"Dictionary element, selected by regexp\"\n#line 1965 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::ArgsGet_DictElementRegexp(yystack_[0].value.as < std::string > ()));\n      }\n#line 3530 \"seclang-parser.cc\"\n    break;\n\n  case 176: // var: VARIABLE_ARGS_GET\n#line 1969 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::ArgsGet_NoDictElement());\n      }\n#line 3538 \"seclang-parser.cc\"\n    break;\n\n  case 177: // var: VARIABLE_FILES_SIZES \"Dictionary element\"\n#line 1973 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::FilesSizes_DictElement(yystack_[0].value.as < std::string > ()));\n      }\n#line 3546 \"seclang-parser.cc\"\n    break;\n\n  case 178: // var: VARIABLE_FILES_SIZES \"Dictionary element, selected by regexp\"\n#line 1977 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::FilesSizes_DictElementRegexp(yystack_[0].value.as < std::string > ()));\n      }\n#line 3554 \"seclang-parser.cc\"\n    break;\n\n  case 179: // var: VARIABLE_FILES_SIZES\n#line 1981 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::FilesSizes_NoDictElement());\n      }\n#line 3562 \"seclang-parser.cc\"\n    break;\n\n  case 180: // var: VARIABLE_FILES_NAMES \"Dictionary element\"\n#line 1985 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::FilesNames_DictElement(yystack_[0].value.as < std::string > ()));\n      }\n#line 3570 \"seclang-parser.cc\"\n    break;\n\n  case 181: // var: VARIABLE_FILES_NAMES \"Dictionary element, selected by regexp\"\n#line 1989 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::FilesNames_DictElementRegexp(yystack_[0].value.as < std::string > ()));\n      }\n#line 3578 \"seclang-parser.cc\"\n    break;\n\n  case 182: // var: VARIABLE_FILES_NAMES\n#line 1993 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::FilesNames_NoDictElement());\n      }\n#line 3586 \"seclang-parser.cc\"\n    break;\n\n  case 183: // var: VARIABLE_FILES_TMP_CONTENT \"Dictionary element\"\n#line 1997 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::FilesTmpContent_DictElement(yystack_[0].value.as < std::string > ()));\n      }\n#line 3594 \"seclang-parser.cc\"\n    break;\n\n  case 184: // var: VARIABLE_FILES_TMP_CONTENT \"Dictionary element, selected by regexp\"\n#line 2001 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::FilesTmpContent_DictElementRegexp(yystack_[0].value.as < std::string > ()));\n      }\n#line 3602 \"seclang-parser.cc\"\n    break;\n\n  case 185: // var: VARIABLE_FILES_TMP_CONTENT\n#line 2005 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::FilesTmpContent_NoDictElement());\n      }\n#line 3610 \"seclang-parser.cc\"\n    break;\n\n  case 186: // var: VARIABLE_MULTIPART_FILENAME \"Dictionary element\"\n#line 2009 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::MultiPartFileName_DictElement(yystack_[0].value.as < std::string > ()));\n      }\n#line 3618 \"seclang-parser.cc\"\n    break;\n\n  case 187: // var: VARIABLE_MULTIPART_FILENAME \"Dictionary element, selected by regexp\"\n#line 2013 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::MultiPartFileName_DictElementRegexp(yystack_[0].value.as < std::string > ()));\n      }\n#line 3626 \"seclang-parser.cc\"\n    break;\n\n  case 188: // var: VARIABLE_MULTIPART_FILENAME\n#line 2017 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::MultiPartFileName_NoDictElement());\n      }\n#line 3634 \"seclang-parser.cc\"\n    break;\n\n  case 189: // var: VARIABLE_MULTIPART_NAME \"Dictionary element\"\n#line 2021 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::MultiPartName_DictElement(yystack_[0].value.as < std::string > ()));\n      }\n#line 3642 \"seclang-parser.cc\"\n    break;\n\n  case 190: // var: VARIABLE_MULTIPART_NAME \"Dictionary element, selected by regexp\"\n#line 2025 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::MultiPartName_DictElementRegexp(yystack_[0].value.as < std::string > ()));\n      }\n#line 3650 \"seclang-parser.cc\"\n    break;\n\n  case 191: // var: VARIABLE_MULTIPART_NAME\n#line 2029 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::MultiPartName_NoDictElement());\n      }\n#line 3658 \"seclang-parser.cc\"\n    break;\n\n  case 192: // var: VARIABLE_MATCHED_VARS_NAMES \"Dictionary element\"\n#line 2033 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::MatchedVarsNames_DictElement(yystack_[0].value.as < std::string > ()));\n      }\n#line 3666 \"seclang-parser.cc\"\n    break;\n\n  case 193: // var: VARIABLE_MATCHED_VARS_NAMES \"Dictionary element, selected by regexp\"\n#line 2037 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::MatchedVarsNames_DictElementRegexp(yystack_[0].value.as < std::string > ()));\n      }\n#line 3674 \"seclang-parser.cc\"\n    break;\n\n  case 194: // var: VARIABLE_MATCHED_VARS_NAMES\n#line 2041 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::MatchedVarsNames_NoDictElement());\n      }\n#line 3682 \"seclang-parser.cc\"\n    break;\n\n  case 195: // var: VARIABLE_MATCHED_VARS \"Dictionary element\"\n#line 2045 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::MatchedVars_DictElement(yystack_[0].value.as < std::string > ()));\n      }\n#line 3690 \"seclang-parser.cc\"\n    break;\n\n  case 196: // var: VARIABLE_MATCHED_VARS \"Dictionary element, selected by regexp\"\n#line 2049 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::MatchedVars_DictElementRegexp(yystack_[0].value.as < std::string > ()));\n      }\n#line 3698 \"seclang-parser.cc\"\n    break;\n\n  case 197: // var: VARIABLE_MATCHED_VARS\n#line 2053 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::MatchedVars_NoDictElement());\n      }\n#line 3706 \"seclang-parser.cc\"\n    break;\n\n  case 198: // var: VARIABLE_FILES \"Dictionary element\"\n#line 2057 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::Files_DictElement(yystack_[0].value.as < std::string > ()));\n      }\n#line 3714 \"seclang-parser.cc\"\n    break;\n\n  case 199: // var: VARIABLE_FILES \"Dictionary element, selected by regexp\"\n#line 2061 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::Files_DictElementRegexp(yystack_[0].value.as < std::string > ()));\n      }\n#line 3722 \"seclang-parser.cc\"\n    break;\n\n  case 200: // var: VARIABLE_FILES\n#line 2065 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::Files_NoDictElement());\n      }\n#line 3730 \"seclang-parser.cc\"\n    break;\n\n  case 201: // var: VARIABLE_REQUEST_COOKIES \"Dictionary element\"\n#line 2069 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::RequestCookies_DictElement(yystack_[0].value.as < std::string > ()));\n      }\n#line 3738 \"seclang-parser.cc\"\n    break;\n\n  case 202: // var: VARIABLE_REQUEST_COOKIES \"Dictionary element, selected by regexp\"\n#line 2073 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::RequestCookies_DictElementRegexp(yystack_[0].value.as < std::string > ()));\n      }\n#line 3746 \"seclang-parser.cc\"\n    break;\n\n  case 203: // var: VARIABLE_REQUEST_COOKIES\n#line 2077 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::RequestCookies_NoDictElement());\n      }\n#line 3754 \"seclang-parser.cc\"\n    break;\n\n  case 204: // var: VARIABLE_REQUEST_HEADERS \"Dictionary element\"\n#line 2081 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::RequestHeaders_DictElement(yystack_[0].value.as < std::string > ()));\n      }\n#line 3762 \"seclang-parser.cc\"\n    break;\n\n  case 205: // var: VARIABLE_REQUEST_HEADERS \"Dictionary element, selected by regexp\"\n#line 2085 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::RequestHeaders_DictElementRegexp(yystack_[0].value.as < std::string > ()));\n      }\n#line 3770 \"seclang-parser.cc\"\n    break;\n\n  case 206: // var: VARIABLE_REQUEST_HEADERS\n#line 2089 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::RequestHeaders_NoDictElement());\n      }\n#line 3778 \"seclang-parser.cc\"\n    break;\n\n  case 207: // var: VARIABLE_RESPONSE_HEADERS \"Dictionary element\"\n#line 2093 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::ResponseHeaders_DictElement(yystack_[0].value.as < std::string > ()));\n      }\n#line 3786 \"seclang-parser.cc\"\n    break;\n\n  case 208: // var: VARIABLE_RESPONSE_HEADERS \"Dictionary element, selected by regexp\"\n#line 2097 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::ResponseHeaders_DictElementRegexp(yystack_[0].value.as < std::string > ()));\n      }\n#line 3794 \"seclang-parser.cc\"\n    break;\n\n  case 209: // var: VARIABLE_RESPONSE_HEADERS\n#line 2101 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::ResponseHeaders_NoDictElement());\n      }\n#line 3802 \"seclang-parser.cc\"\n    break;\n\n  case 210: // var: VARIABLE_GEO \"Dictionary element\"\n#line 2105 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::Geo_DictElement(yystack_[0].value.as < std::string > ()));\n      }\n#line 3810 \"seclang-parser.cc\"\n    break;\n\n  case 211: // var: VARIABLE_GEO \"Dictionary element, selected by regexp\"\n#line 2109 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::Geo_DictElementRegexp(yystack_[0].value.as < std::string > ()));\n      }\n#line 3818 \"seclang-parser.cc\"\n    break;\n\n  case 212: // var: VARIABLE_GEO\n#line 2113 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::Geo_NoDictElement());\n      }\n#line 3826 \"seclang-parser.cc\"\n    break;\n\n  case 213: // var: VARIABLE_REQUEST_COOKIES_NAMES \"Dictionary element\"\n#line 2117 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::RequestCookiesNames_DictElement(yystack_[0].value.as < std::string > ()));\n      }\n#line 3834 \"seclang-parser.cc\"\n    break;\n\n  case 214: // var: VARIABLE_REQUEST_COOKIES_NAMES \"Dictionary element, selected by regexp\"\n#line 2121 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::RequestCookiesNames_DictElementRegexp(yystack_[0].value.as < std::string > ()));\n      }\n#line 3842 \"seclang-parser.cc\"\n    break;\n\n  case 215: // var: VARIABLE_REQUEST_COOKIES_NAMES\n#line 2125 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::RequestCookiesNames_NoDictElement());\n      }\n#line 3850 \"seclang-parser.cc\"\n    break;\n\n  case 216: // var: VARIABLE_MULTIPART_PART_HEADERS \"Dictionary element\"\n#line 2129 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::MultipartPartHeaders_DictElement(yystack_[0].value.as < std::string > ()));\n      }\n#line 3858 \"seclang-parser.cc\"\n    break;\n\n  case 217: // var: VARIABLE_MULTIPART_PART_HEADERS \"Dictionary element, selected by regexp\"\n#line 2133 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::MultipartPartHeaders_DictElementRegexp(yystack_[0].value.as < std::string > ()));\n      }\n#line 3866 \"seclang-parser.cc\"\n    break;\n\n  case 218: // var: VARIABLE_MULTIPART_PART_HEADERS\n#line 2137 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::MultipartPartHeaders_NoDictElement());\n      }\n#line 3874 \"seclang-parser.cc\"\n    break;\n\n  case 219: // var: VARIABLE_RULE \"Dictionary element\"\n#line 2141 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::Rule_DictElement(yystack_[0].value.as < std::string > ()));\n      }\n#line 3882 \"seclang-parser.cc\"\n    break;\n\n  case 220: // var: VARIABLE_RULE \"Dictionary element, selected by regexp\"\n#line 2145 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::Rule_DictElementRegexp(yystack_[0].value.as < std::string > ()));\n      }\n#line 3890 \"seclang-parser.cc\"\n    break;\n\n  case 221: // var: VARIABLE_RULE\n#line 2149 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::Rule_NoDictElement());\n      }\n#line 3898 \"seclang-parser.cc\"\n    break;\n\n  case 222: // var: \"RUN_TIME_VAR_ENV\" \"Dictionary element\"\n#line 2153 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::Env(\"ENV:\" + yystack_[0].value.as < std::string > ()));\n      }\n#line 3906 \"seclang-parser.cc\"\n    break;\n\n  case 223: // var: \"RUN_TIME_VAR_ENV\" \"Dictionary element, selected by regexp\"\n#line 2157 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::Env(\"ENV:\" + yystack_[0].value.as < std::string > ()));\n      }\n#line 3914 \"seclang-parser.cc\"\n    break;\n\n  case 224: // var: \"RUN_TIME_VAR_ENV\"\n#line 2161 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::Env(\"ENV\"));\n      }\n#line 3922 \"seclang-parser.cc\"\n    break;\n\n  case 225: // var: \"RUN_TIME_VAR_XML\" \"Dictionary element\"\n#line 2165 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::XML(\"XML:\" + yystack_[0].value.as < std::string > ()));\n      }\n#line 3930 \"seclang-parser.cc\"\n    break;\n\n  case 226: // var: \"RUN_TIME_VAR_XML\" \"Dictionary element, selected by regexp\"\n#line 2169 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::XML(\"XML:\" + yystack_[0].value.as < std::string > ()));\n      }\n#line 3938 \"seclang-parser.cc\"\n    break;\n\n  case 227: // var: \"RUN_TIME_VAR_XML\"\n#line 2173 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::XML_NoDictElement());\n      }\n#line 3946 \"seclang-parser.cc\"\n    break;\n\n  case 228: // var: \"FILES_TMPNAMES\" \"Dictionary element\"\n#line 2177 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::FilesTmpNames_DictElement(yystack_[0].value.as < std::string > ()));\n      }\n#line 3954 \"seclang-parser.cc\"\n    break;\n\n  case 229: // var: \"FILES_TMPNAMES\" \"Dictionary element, selected by regexp\"\n#line 2181 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::FilesTmpNames_DictElementRegexp(yystack_[0].value.as < std::string > ()));\n      }\n#line 3962 \"seclang-parser.cc\"\n    break;\n\n  case 230: // var: \"FILES_TMPNAMES\"\n#line 2185 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::FilesTmpNames_NoDictElement());\n      }\n#line 3970 \"seclang-parser.cc\"\n    break;\n\n  case 231: // var: \"RESOURCE\" run_time_string\n#line 2189 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::Resource_DynamicElement(std::move(yystack_[0].value.as < std::unique_ptr<RunTimeString> > ())));\n      }\n#line 3978 \"seclang-parser.cc\"\n    break;\n\n  case 232: // var: \"RESOURCE\" \"Dictionary element\"\n#line 2193 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::Resource_DictElement(yystack_[0].value.as < std::string > ()));\n      }\n#line 3986 \"seclang-parser.cc\"\n    break;\n\n  case 233: // var: \"RESOURCE\" \"Dictionary element, selected by regexp\"\n#line 2197 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::Resource_DictElementRegexp(yystack_[0].value.as < std::string > ()));\n      }\n#line 3994 \"seclang-parser.cc\"\n    break;\n\n  case 234: // var: \"RESOURCE\"\n#line 2201 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::Resource_NoDictElement());\n      }\n#line 4002 \"seclang-parser.cc\"\n    break;\n\n  case 235: // var: \"VARIABLE_IP\" run_time_string\n#line 2205 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::Ip_DynamicElement(std::move(yystack_[0].value.as < std::unique_ptr<RunTimeString> > ())));\n      }\n#line 4010 \"seclang-parser.cc\"\n    break;\n\n  case 236: // var: \"VARIABLE_IP\" \"Dictionary element\"\n#line 2209 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::Ip_DictElement(yystack_[0].value.as < std::string > ()));\n      }\n#line 4018 \"seclang-parser.cc\"\n    break;\n\n  case 237: // var: \"VARIABLE_IP\" \"Dictionary element, selected by regexp\"\n#line 2213 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::Ip_DictElementRegexp(yystack_[0].value.as < std::string > ()));\n      }\n#line 4026 \"seclang-parser.cc\"\n    break;\n\n  case 238: // var: \"VARIABLE_IP\"\n#line 2217 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::Ip_NoDictElement());\n      }\n#line 4034 \"seclang-parser.cc\"\n    break;\n\n  case 239: // var: \"VARIABLE_GLOBAL\" run_time_string\n#line 2221 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::Global_DynamicElement(std::move(yystack_[0].value.as < std::unique_ptr<RunTimeString> > ())));\n      }\n#line 4042 \"seclang-parser.cc\"\n    break;\n\n  case 240: // var: \"VARIABLE_GLOBAL\" \"Dictionary element\"\n#line 2225 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::Global_DictElement(yystack_[0].value.as < std::string > ()));\n      }\n#line 4050 \"seclang-parser.cc\"\n    break;\n\n  case 241: // var: \"VARIABLE_GLOBAL\" \"Dictionary element, selected by regexp\"\n#line 2229 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::Global_DictElementRegexp(yystack_[0].value.as < std::string > ()));\n      }\n#line 4058 \"seclang-parser.cc\"\n    break;\n\n  case 242: // var: \"VARIABLE_GLOBAL\"\n#line 2233 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::Global_NoDictElement());\n      }\n#line 4066 \"seclang-parser.cc\"\n    break;\n\n  case 243: // var: \"VARIABLE_USER\" run_time_string\n#line 2237 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::User_DynamicElement(std::move(yystack_[0].value.as < std::unique_ptr<RunTimeString> > ())));\n      }\n#line 4074 \"seclang-parser.cc\"\n    break;\n\n  case 244: // var: \"VARIABLE_USER\" \"Dictionary element\"\n#line 2241 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::User_DictElement(yystack_[0].value.as < std::string > ()));\n      }\n#line 4082 \"seclang-parser.cc\"\n    break;\n\n  case 245: // var: \"VARIABLE_USER\" \"Dictionary element, selected by regexp\"\n#line 2245 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::User_DictElementRegexp(yystack_[0].value.as < std::string > ()));\n      }\n#line 4090 \"seclang-parser.cc\"\n    break;\n\n  case 246: // var: \"VARIABLE_USER\"\n#line 2249 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::User_NoDictElement());\n      }\n#line 4098 \"seclang-parser.cc\"\n    break;\n\n  case 247: // var: \"VARIABLE_TX\" run_time_string\n#line 2253 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::Tx_DynamicElement(std::move(yystack_[0].value.as < std::unique_ptr<RunTimeString> > ())));\n      }\n#line 4106 \"seclang-parser.cc\"\n    break;\n\n  case 248: // var: \"VARIABLE_TX\" \"Dictionary element\"\n#line 2257 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::Tx_DictElement(yystack_[0].value.as < std::string > ()));\n      }\n#line 4114 \"seclang-parser.cc\"\n    break;\n\n  case 249: // var: \"VARIABLE_TX\" \"Dictionary element, selected by regexp\"\n#line 2261 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::Tx_DictElementRegexp(yystack_[0].value.as < std::string > ()));\n      }\n#line 4122 \"seclang-parser.cc\"\n    break;\n\n  case 250: // var: \"VARIABLE_TX\"\n#line 2265 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::Tx_NoDictElement());\n      }\n#line 4130 \"seclang-parser.cc\"\n    break;\n\n  case 251: // var: \"VARIABLE_SESSION\" run_time_string\n#line 2269 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::Session_DynamicElement(std::move(yystack_[0].value.as < std::unique_ptr<RunTimeString> > ())));\n      }\n#line 4138 \"seclang-parser.cc\"\n    break;\n\n  case 252: // var: \"VARIABLE_SESSION\" \"Dictionary element\"\n#line 2273 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::Session_DictElement(yystack_[0].value.as < std::string > ()));\n      }\n#line 4146 \"seclang-parser.cc\"\n    break;\n\n  case 253: // var: \"VARIABLE_SESSION\" \"Dictionary element, selected by regexp\"\n#line 2277 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::Session_DictElementRegexp(yystack_[0].value.as < std::string > ()));\n      }\n#line 4154 \"seclang-parser.cc\"\n    break;\n\n  case 254: // var: \"VARIABLE_SESSION\"\n#line 2281 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::Session_NoDictElement());\n      }\n#line 4162 \"seclang-parser.cc\"\n    break;\n\n  case 255: // var: \"Variable ARGS_NAMES\" \"Dictionary element\"\n#line 2285 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::ArgsNames_DictElement(yystack_[0].value.as < std::string > ()));\n      }\n#line 4170 \"seclang-parser.cc\"\n    break;\n\n  case 256: // var: \"Variable ARGS_NAMES\" \"Dictionary element, selected by regexp\"\n#line 2289 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::ArgsNames_DictElementRegexp(yystack_[0].value.as < std::string > ()));\n      }\n#line 4178 \"seclang-parser.cc\"\n    break;\n\n  case 257: // var: \"Variable ARGS_NAMES\"\n#line 2293 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::ArgsNames_NoDictElement());\n      }\n#line 4186 \"seclang-parser.cc\"\n    break;\n\n  case 258: // var: VARIABLE_ARGS_GET_NAMES \"Dictionary element\"\n#line 2297 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::ArgsGetNames_DictElement(yystack_[0].value.as < std::string > ()));\n      }\n#line 4194 \"seclang-parser.cc\"\n    break;\n\n  case 259: // var: VARIABLE_ARGS_GET_NAMES \"Dictionary element, selected by regexp\"\n#line 2301 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::ArgsGetNames_DictElementRegexp(yystack_[0].value.as < std::string > ()));\n      }\n#line 4202 \"seclang-parser.cc\"\n    break;\n\n  case 260: // var: VARIABLE_ARGS_GET_NAMES\n#line 2305 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::ArgsGetNames_NoDictElement());\n      }\n#line 4210 \"seclang-parser.cc\"\n    break;\n\n  case 261: // var: VARIABLE_ARGS_POST_NAMES \"Dictionary element\"\n#line 2310 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::ArgsPostNames_DictElement(yystack_[0].value.as < std::string > ()));\n      }\n#line 4218 \"seclang-parser.cc\"\n    break;\n\n  case 262: // var: VARIABLE_ARGS_POST_NAMES \"Dictionary element, selected by regexp\"\n#line 2314 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::ArgsPostNames_DictElementRegexp(yystack_[0].value.as < std::string > ()));\n      }\n#line 4226 \"seclang-parser.cc\"\n    break;\n\n  case 263: // var: VARIABLE_ARGS_POST_NAMES\n#line 2318 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::ArgsPostNames_NoDictElement());\n      }\n#line 4234 \"seclang-parser.cc\"\n    break;\n\n  case 264: // var: VARIABLE_REQUEST_HEADERS_NAMES \"Dictionary element\"\n#line 2323 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::RequestHeadersNames_DictElement(yystack_[0].value.as < std::string > ()));\n      }\n#line 4242 \"seclang-parser.cc\"\n    break;\n\n  case 265: // var: VARIABLE_REQUEST_HEADERS_NAMES \"Dictionary element, selected by regexp\"\n#line 2327 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::RequestHeadersNames_DictElementRegexp(yystack_[0].value.as < std::string > ()));\n      }\n#line 4250 \"seclang-parser.cc\"\n    break;\n\n  case 266: // var: VARIABLE_REQUEST_HEADERS_NAMES\n#line 2331 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::RequestHeadersNames_NoDictElement());\n      }\n#line 4258 \"seclang-parser.cc\"\n    break;\n\n  case 267: // var: VARIABLE_RESPONSE_CONTENT_TYPE\n#line 2336 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::ResponseContentType());\n      }\n#line 4266 \"seclang-parser.cc\"\n    break;\n\n  case 268: // var: VARIABLE_RESPONSE_HEADERS_NAMES \"Dictionary element\"\n#line 2341 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::ResponseHeadersNames_DictElement(yystack_[0].value.as < std::string > ()));\n      }\n#line 4274 \"seclang-parser.cc\"\n    break;\n\n  case 269: // var: VARIABLE_RESPONSE_HEADERS_NAMES \"Dictionary element, selected by regexp\"\n#line 2345 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::ResponseHeadersNames_DictElementRegexp(yystack_[0].value.as < std::string > ()));\n      }\n#line 4282 \"seclang-parser.cc\"\n    break;\n\n  case 270: // var: VARIABLE_RESPONSE_HEADERS_NAMES\n#line 2349 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::ResponseHeadersNames_NoDictElement());\n      }\n#line 4290 \"seclang-parser.cc\"\n    break;\n\n  case 271: // var: VARIABLE_ARGS_COMBINED_SIZE\n#line 2353 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::ArgsCombinedSize());\n      }\n#line 4298 \"seclang-parser.cc\"\n    break;\n\n  case 272: // var: \"AUTH_TYPE\"\n#line 2357 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::AuthType());\n      }\n#line 4306 \"seclang-parser.cc\"\n    break;\n\n  case 273: // var: \"FILES_COMBINED_SIZE\"\n#line 2361 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::FilesCombinedSize());\n      }\n#line 4314 \"seclang-parser.cc\"\n    break;\n\n  case 274: // var: \"FULL_REQUEST\"\n#line 2365 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::FullRequest());\n      }\n#line 4322 \"seclang-parser.cc\"\n    break;\n\n  case 275: // var: \"FULL_REQUEST_LENGTH\"\n#line 2369 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::FullRequestLength());\n      }\n#line 4330 \"seclang-parser.cc\"\n    break;\n\n  case 276: // var: \"INBOUND_DATA_ERROR\"\n#line 2373 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::InboundDataError());\n      }\n#line 4338 \"seclang-parser.cc\"\n    break;\n\n  case 277: // var: \"MATCHED_VAR\"\n#line 2377 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::MatchedVar());\n      }\n#line 4346 \"seclang-parser.cc\"\n    break;\n\n  case 278: // var: \"MATCHED_VAR_NAME\"\n#line 2381 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::MatchedVarName());\n      }\n#line 4354 \"seclang-parser.cc\"\n    break;\n\n  case 279: // var: \"MSC_PCRE_ERROR\"\n#line 2385 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::MscPcreError());\n      }\n#line 4362 \"seclang-parser.cc\"\n    break;\n\n  case 280: // var: \"MSC_PCRE_LIMITS_EXCEEDED\"\n#line 2389 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::MscPcreLimitsExceeded());\n      }\n#line 4370 \"seclang-parser.cc\"\n    break;\n\n  case 281: // var: VARIABLE_MULTIPART_BOUNDARY_QUOTED\n#line 2393 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::MultipartBoundaryQuoted());\n      }\n#line 4378 \"seclang-parser.cc\"\n    break;\n\n  case 282: // var: VARIABLE_MULTIPART_BOUNDARY_WHITESPACE\n#line 2397 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::MultipartBoundaryWhiteSpace());\n      }\n#line 4386 \"seclang-parser.cc\"\n    break;\n\n  case 283: // var: \"MULTIPART_CRLF_LF_LINES\"\n#line 2401 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::MultipartCrlfLFLines());\n      }\n#line 4394 \"seclang-parser.cc\"\n    break;\n\n  case 284: // var: \"MULTIPART_DATA_AFTER\"\n#line 2405 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::MultipartDateAfter());\n      }\n#line 4402 \"seclang-parser.cc\"\n    break;\n\n  case 285: // var: VARIABLE_MULTIPART_DATA_BEFORE\n#line 2409 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::MultipartDateBefore());\n      }\n#line 4410 \"seclang-parser.cc\"\n    break;\n\n  case 286: // var: \"MULTIPART_FILE_LIMIT_EXCEEDED\"\n#line 2413 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::MultipartFileLimitExceeded());\n      }\n#line 4418 \"seclang-parser.cc\"\n    break;\n\n  case 287: // var: \"MULTIPART_HEADER_FOLDING\"\n#line 2417 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::MultipartHeaderFolding());\n      }\n#line 4426 \"seclang-parser.cc\"\n    break;\n\n  case 288: // var: \"MULTIPART_INVALID_HEADER_FOLDING\"\n#line 2421 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::MultipartInvalidHeaderFolding());\n      }\n#line 4434 \"seclang-parser.cc\"\n    break;\n\n  case 289: // var: VARIABLE_MULTIPART_INVALID_PART\n#line 2425 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::MultipartInvalidPart());\n      }\n#line 4442 \"seclang-parser.cc\"\n    break;\n\n  case 290: // var: \"MULTIPART_INVALID_QUOTING\"\n#line 2429 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::MultipartInvalidQuoting());\n      }\n#line 4450 \"seclang-parser.cc\"\n    break;\n\n  case 291: // var: VARIABLE_MULTIPART_LF_LINE\n#line 2433 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::MultipartLFLine());\n      }\n#line 4458 \"seclang-parser.cc\"\n    break;\n\n  case 292: // var: VARIABLE_MULTIPART_MISSING_SEMICOLON\n#line 2437 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::MultipartMissingSemicolon());\n      }\n#line 4466 \"seclang-parser.cc\"\n    break;\n\n  case 293: // var: VARIABLE_MULTIPART_SEMICOLON_MISSING\n#line 2441 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::MultipartMissingSemicolon());\n      }\n#line 4474 \"seclang-parser.cc\"\n    break;\n\n  case 294: // var: \"MULTIPART_STRICT_ERROR\"\n#line 2445 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::MultipartStrictError());\n      }\n#line 4482 \"seclang-parser.cc\"\n    break;\n\n  case 295: // var: \"MULTIPART_UNMATCHED_BOUNDARY\"\n#line 2449 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::MultipartUnmatchedBoundary());\n      }\n#line 4490 \"seclang-parser.cc\"\n    break;\n\n  case 296: // var: \"OUTBOUND_DATA_ERROR\"\n#line 2453 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::OutboundDataError());\n      }\n#line 4498 \"seclang-parser.cc\"\n    break;\n\n  case 297: // var: \"PATH_INFO\"\n#line 2457 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::PathInfo());\n      }\n#line 4506 \"seclang-parser.cc\"\n    break;\n\n  case 298: // var: \"QUERY_STRING\"\n#line 2461 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::QueryString());\n      }\n#line 4514 \"seclang-parser.cc\"\n    break;\n\n  case 299: // var: \"REMOTE_ADDR\"\n#line 2465 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::RemoteAddr());\n      }\n#line 4522 \"seclang-parser.cc\"\n    break;\n\n  case 300: // var: \"REMOTE_HOST\"\n#line 2469 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::RemoteHost());\n      }\n#line 4530 \"seclang-parser.cc\"\n    break;\n\n  case 301: // var: \"REMOTE_PORT\"\n#line 2473 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::RemotePort());\n      }\n#line 4538 \"seclang-parser.cc\"\n    break;\n\n  case 302: // var: \"REQBODY_ERROR\"\n#line 2477 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::ReqbodyError());\n      }\n#line 4546 \"seclang-parser.cc\"\n    break;\n\n  case 303: // var: \"REQBODY_ERROR_MSG\"\n#line 2481 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::ReqbodyErrorMsg());\n      }\n#line 4554 \"seclang-parser.cc\"\n    break;\n\n  case 304: // var: \"REQBODY_PROCESSOR\"\n#line 2485 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::ReqbodyProcessor());\n      }\n#line 4562 \"seclang-parser.cc\"\n    break;\n\n  case 305: // var: \"REQBODY_PROCESSOR_ERROR\"\n#line 2489 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::ReqbodyProcessorError());\n      }\n#line 4570 \"seclang-parser.cc\"\n    break;\n\n  case 306: // var: \"REQBODY_PROCESSOR_ERROR_MSG\"\n#line 2493 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::ReqbodyProcessorErrorMsg());\n      }\n#line 4578 \"seclang-parser.cc\"\n    break;\n\n  case 307: // var: \"REQUEST_BASENAME\"\n#line 2497 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::RequestBasename());\n      }\n#line 4586 \"seclang-parser.cc\"\n    break;\n\n  case 308: // var: \"REQUEST_BODY\"\n#line 2501 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::RequestBody());\n      }\n#line 4594 \"seclang-parser.cc\"\n    break;\n\n  case 309: // var: \"REQUEST_BODY_LENGTH\"\n#line 2505 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::RequestBodyLength());\n      }\n#line 4602 \"seclang-parser.cc\"\n    break;\n\n  case 310: // var: \"REQUEST_FILENAME\"\n#line 2509 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::RequestFilename());\n      }\n#line 4610 \"seclang-parser.cc\"\n    break;\n\n  case 311: // var: \"REQUEST_LINE\"\n#line 2513 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::RequestLine());\n      }\n#line 4618 \"seclang-parser.cc\"\n    break;\n\n  case 312: // var: \"REQUEST_METHOD\"\n#line 2517 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::RequestMethod());\n      }\n#line 4626 \"seclang-parser.cc\"\n    break;\n\n  case 313: // var: \"REQUEST_PROTOCOL\"\n#line 2521 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::RequestProtocol());\n      }\n#line 4634 \"seclang-parser.cc\"\n    break;\n\n  case 314: // var: \"REQUEST_URI\"\n#line 2525 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::RequestURI());\n      }\n#line 4642 \"seclang-parser.cc\"\n    break;\n\n  case 315: // var: \"REQUEST_URI_RAW\"\n#line 2529 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::RequestURIRaw());\n      }\n#line 4650 \"seclang-parser.cc\"\n    break;\n\n  case 316: // var: \"RESPONSE_BODY\"\n#line 2533 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::ResponseBody());\n      }\n#line 4658 \"seclang-parser.cc\"\n    break;\n\n  case 317: // var: \"RESPONSE_CONTENT_LENGTH\"\n#line 2537 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::ResponseContentLength());\n      }\n#line 4666 \"seclang-parser.cc\"\n    break;\n\n  case 318: // var: \"RESPONSE_PROTOCOL\"\n#line 2541 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::ResponseProtocol());\n      }\n#line 4674 \"seclang-parser.cc\"\n    break;\n\n  case 319: // var: \"RESPONSE_STATUS\"\n#line 2545 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::ResponseStatus());\n      }\n#line 4682 \"seclang-parser.cc\"\n    break;\n\n  case 320: // var: \"SERVER_ADDR\"\n#line 2549 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::ServerAddr());\n      }\n#line 4690 \"seclang-parser.cc\"\n    break;\n\n  case 321: // var: \"SERVER_NAME\"\n#line 2553 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::ServerName());\n      }\n#line 4698 \"seclang-parser.cc\"\n    break;\n\n  case 322: // var: \"SERVER_PORT\"\n#line 2557 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::ServerPort());\n      }\n#line 4706 \"seclang-parser.cc\"\n    break;\n\n  case 323: // var: \"SESSIONID\"\n#line 2561 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::SessionID());\n      }\n#line 4714 \"seclang-parser.cc\"\n    break;\n\n  case 324: // var: \"UNIQUE_ID\"\n#line 2565 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::UniqueID());\n      }\n#line 4722 \"seclang-parser.cc\"\n    break;\n\n  case 325: // var: \"URLENCODED_ERROR\"\n#line 2569 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::UrlEncodedError());\n      }\n#line 4730 \"seclang-parser.cc\"\n    break;\n\n  case 326: // var: \"USERID\"\n#line 2573 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::UserID());\n      }\n#line 4738 \"seclang-parser.cc\"\n    break;\n\n  case 327: // var: \"VARIABLE_STATUS\"\n#line 2577 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::Status());\n      }\n#line 4746 \"seclang-parser.cc\"\n    break;\n\n  case 328: // var: \"VARIABLE_STATUS_LINE\"\n#line 2581 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::Status());\n      }\n#line 4754 \"seclang-parser.cc\"\n    break;\n\n  case 329: // var: \"WEBAPPID\"\n#line 2585 \"seclang-parser.yy\"\n      {\n        VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::WebAppId());\n      }\n#line 4762 \"seclang-parser.cc\"\n    break;\n\n  case 330: // var: \"RUN_TIME_VAR_DUR\"\n#line 2589 \"seclang-parser.yy\"\n      {\n        std::string name(yystack_[0].value.as < std::string > ());\n        char z = name.at(0);\n        std::unique_ptr<Variable> c(new Duration(name));\n        yylhs.value.as < std::unique_ptr<Variable> > () = std::move(c);\n      }\n#line 4773 \"seclang-parser.cc\"\n    break;\n\n  case 331: // var: \"RUN_TIME_VAR_BLD\"\n#line 2597 \"seclang-parser.yy\"\n      {\n        std::string name(yystack_[0].value.as < std::string > ());\n        char z = name.at(0);\n        std::unique_ptr<Variable> c(new ModsecBuild(name));\n        yylhs.value.as < std::unique_ptr<Variable> > () = std::move(c);\n      }\n#line 4784 \"seclang-parser.cc\"\n    break;\n\n  case 332: // var: \"RUN_TIME_VAR_HSV\"\n#line 2604 \"seclang-parser.yy\"\n      {\n        std::string name(yystack_[0].value.as < std::string > ());\n        char z = name.at(0);\n        std::unique_ptr<Variable> c(new HighestSeverity(name));\n        yylhs.value.as < std::unique_ptr<Variable> > () = std::move(c);\n      }\n#line 4795 \"seclang-parser.cc\"\n    break;\n\n  case 333: // var: \"RUN_TIME_VAR_REMOTE_USER\"\n#line 2611 \"seclang-parser.yy\"\n      {\n        std::string name(yystack_[0].value.as < std::string > ());\n        char z = name.at(0);\n        std::unique_ptr<Variable> c(new RemoteUser(name));\n        yylhs.value.as < std::unique_ptr<Variable> > () = std::move(c);\n      }\n#line 4806 \"seclang-parser.cc\"\n    break;\n\n  case 334: // var: \"RUN_TIME_VAR_TIME\"\n#line 2618 \"seclang-parser.yy\"\n      {\n        std::string name(yystack_[0].value.as < std::string > ());\n        char z = name.at(0);\n        std::unique_ptr<Variable> c(new Time(name));\n        yylhs.value.as < std::unique_ptr<Variable> > () = std::move(c);\n      }\n#line 4817 \"seclang-parser.cc\"\n    break;\n\n  case 335: // var: \"RUN_TIME_VAR_TIME_DAY\"\n#line 2625 \"seclang-parser.yy\"\n      {\n        std::string name(yystack_[0].value.as < std::string > ());\n        char z = name.at(0);\n        std::unique_ptr<Variable> c(new TimeDay(name));\n        yylhs.value.as < std::unique_ptr<Variable> > () = std::move(c);\n      }\n#line 4828 \"seclang-parser.cc\"\n    break;\n\n  case 336: // var: \"RUN_TIME_VAR_TIME_EPOCH\"\n#line 2632 \"seclang-parser.yy\"\n      {\n        std::string name(yystack_[0].value.as < std::string > ());\n        char z = name.at(0);\n        std::unique_ptr<Variable> c(new TimeEpoch(name));\n        yylhs.value.as < std::unique_ptr<Variable> > () = std::move(c);\n      }\n#line 4839 \"seclang-parser.cc\"\n    break;\n\n  case 337: // var: \"RUN_TIME_VAR_TIME_HOUR\"\n#line 2639 \"seclang-parser.yy\"\n      {\n        std::string name(yystack_[0].value.as < std::string > ());\n        char z = name.at(0);\n        std::unique_ptr<Variable> c(new TimeHour(name));\n        yylhs.value.as < std::unique_ptr<Variable> > () = std::move(c);\n      }\n#line 4850 \"seclang-parser.cc\"\n    break;\n\n  case 338: // var: \"RUN_TIME_VAR_TIME_MIN\"\n#line 2646 \"seclang-parser.yy\"\n      {\n        std::string name(yystack_[0].value.as < std::string > ());\n        char z = name.at(0);\n        std::unique_ptr<Variable> c(new TimeMin(name));\n        yylhs.value.as < std::unique_ptr<Variable> > () = std::move(c);\n      }\n#line 4861 \"seclang-parser.cc\"\n    break;\n\n  case 339: // var: \"RUN_TIME_VAR_TIME_MON\"\n#line 2653 \"seclang-parser.yy\"\n      {\n        std::string name(yystack_[0].value.as < std::string > ());\n        char z = name.at(0);\n        std::unique_ptr<Variable> c(new TimeMon(name));\n        yylhs.value.as < std::unique_ptr<Variable> > () = std::move(c);\n      }\n#line 4872 \"seclang-parser.cc\"\n    break;\n\n  case 340: // var: \"RUN_TIME_VAR_TIME_SEC\"\n#line 2660 \"seclang-parser.yy\"\n      {\n        std::string name(yystack_[0].value.as < std::string > ());\n        char z = name.at(0);\n            std::unique_ptr<Variable> c(new TimeSec(name));\n            yylhs.value.as < std::unique_ptr<Variable> > () = std::move(c);\n      }\n#line 4883 \"seclang-parser.cc\"\n    break;\n\n  case 341: // var: \"RUN_TIME_VAR_TIME_WDAY\"\n#line 2667 \"seclang-parser.yy\"\n      {\n        std::string name(yystack_[0].value.as < std::string > ());\n        char z = name.at(0);\n        std::unique_ptr<Variable> c(new TimeWDay(name));\n        yylhs.value.as < std::unique_ptr<Variable> > () = std::move(c);\n      }\n#line 4894 \"seclang-parser.cc\"\n    break;\n\n  case 342: // var: \"RUN_TIME_VAR_TIME_YEAR\"\n#line 2674 \"seclang-parser.yy\"\n      {\n        std::string name(yystack_[0].value.as < std::string > ());\n        char z = name.at(0);\n        std::unique_ptr<Variable> c(new TimeYear(name));\n        yylhs.value.as < std::unique_ptr<Variable> > () = std::move(c);\n      }\n#line 4905 \"seclang-parser.cc\"\n    break;\n\n  case 343: // act: \"Accuracy\"\n#line 2684 \"seclang-parser.yy\"\n      {\n        ACTION_CONTAINER(yylhs.value.as < std::unique_ptr<actions::Action> > (), new actions::Accuracy(yystack_[0].value.as < std::string > ()));\n      }\n#line 4913 \"seclang-parser.cc\"\n    break;\n\n  case 344: // act: \"Allow\"\n#line 2688 \"seclang-parser.yy\"\n      {\n        ACTION_CONTAINER(yylhs.value.as < std::unique_ptr<actions::Action> > (), new actions::disruptive::Allow(yystack_[0].value.as < std::string > ()));\n      }\n#line 4921 \"seclang-parser.cc\"\n    break;\n\n  case 345: // act: \"Append\"\n#line 2692 \"seclang-parser.yy\"\n      {\n        ACTION_NOT_SUPPORTED(\"Append\", yystack_[1].location);\n      }\n#line 4929 \"seclang-parser.cc\"\n    break;\n\n  case 346: // act: \"AuditLog\"\n#line 2696 \"seclang-parser.yy\"\n      {\n        ACTION_CONTAINER(yylhs.value.as < std::unique_ptr<actions::Action> > (), new actions::AuditLog(yystack_[0].value.as < std::string > ()));\n      }\n#line 4937 \"seclang-parser.cc\"\n    break;\n\n  case 347: // act: \"Block\"\n#line 2700 \"seclang-parser.yy\"\n      {\n        ACTION_CONTAINER(yylhs.value.as < std::unique_ptr<actions::Action> > (), new actions::Block(yystack_[0].value.as < std::string > ()));\n      }\n#line 4945 \"seclang-parser.cc\"\n    break;\n\n  case 348: // act: \"Capture\"\n#line 2704 \"seclang-parser.yy\"\n      {\n        ACTION_CONTAINER(yylhs.value.as < std::unique_ptr<actions::Action> > (), new actions::Capture(yystack_[0].value.as < std::string > ()));\n      }\n#line 4953 \"seclang-parser.cc\"\n    break;\n\n  case 349: // act: \"Chain\"\n#line 2708 \"seclang-parser.yy\"\n      {\n        ACTION_CONTAINER(yylhs.value.as < std::unique_ptr<actions::Action> > (), new actions::Chain(yystack_[0].value.as < std::string > ()));\n      }\n#line 4961 \"seclang-parser.cc\"\n    break;\n\n  case 350: // act: \"ACTION_CTL_AUDIT_ENGINE\" \"CONFIG_VALUE_ON\"\n#line 2712 \"seclang-parser.yy\"\n      {\n        ACTION_CONTAINER(yylhs.value.as < std::unique_ptr<actions::Action> > (), new actions::ctl::AuditEngine(\"ctl:auditengine=on\"));\n        driver.m_auditLog->setCtlAuditEngineActive();\n      }\n#line 4970 \"seclang-parser.cc\"\n    break;\n\n  case 351: // act: \"ACTION_CTL_AUDIT_ENGINE\" \"CONFIG_VALUE_OFF\"\n#line 2717 \"seclang-parser.yy\"\n      {\n        ACTION_CONTAINER(yylhs.value.as < std::unique_ptr<actions::Action> > (), new actions::ctl::AuditEngine(\"ctl:auditengine=off\"));\n      }\n#line 4978 \"seclang-parser.cc\"\n    break;\n\n  case 352: // act: \"ACTION_CTL_AUDIT_ENGINE\" \"CONFIG_VALUE_RELEVANT_ONLY\"\n#line 2721 \"seclang-parser.yy\"\n      {\n        ACTION_CONTAINER(yylhs.value.as < std::unique_ptr<actions::Action> > (), new actions::ctl::AuditEngine(\"ctl:auditengine=relevantonly\"));\n        driver.m_auditLog->setCtlAuditEngineActive();\n      }\n#line 4987 \"seclang-parser.cc\"\n    break;\n\n  case 353: // act: \"ACTION_CTL_AUDIT_LOG_PARTS\"\n#line 2726 \"seclang-parser.yy\"\n      {\n        ACTION_CONTAINER(yylhs.value.as < std::unique_ptr<actions::Action> > (), new actions::ctl::AuditLogParts(yystack_[0].value.as < std::string > ()));\n      }\n#line 4995 \"seclang-parser.cc\"\n    break;\n\n  case 354: // act: \"ACTION_CTL_BDY_JSON\"\n#line 2730 \"seclang-parser.yy\"\n      {\n        ACTION_CONTAINER(yylhs.value.as < std::unique_ptr<actions::Action> > (), new actions::ctl::RequestBodyProcessorJSON(yystack_[0].value.as < std::string > ()));\n      }\n#line 5003 \"seclang-parser.cc\"\n    break;\n\n  case 355: // act: \"ACTION_CTL_BDY_XML\"\n#line 2734 \"seclang-parser.yy\"\n      {\n        ACTION_CONTAINER(yylhs.value.as < std::unique_ptr<actions::Action> > (), new actions::ctl::RequestBodyProcessorXML(yystack_[0].value.as < std::string > ()));\n      }\n#line 5011 \"seclang-parser.cc\"\n    break;\n\n  case 356: // act: \"ACTION_CTL_BDY_URLENCODED\"\n#line 2738 \"seclang-parser.yy\"\n      {\n        ACTION_CONTAINER(yylhs.value.as < std::unique_ptr<actions::Action> > (), new actions::ctl::RequestBodyProcessorURLENCODED(yystack_[0].value.as < std::string > ()));\n      }\n#line 5019 \"seclang-parser.cc\"\n    break;\n\n  case 357: // act: \"ACTION_CTL_FORCE_REQ_BODY_VAR\" \"CONFIG_VALUE_ON\"\n#line 2742 \"seclang-parser.yy\"\n      {\n        //ACTION_NOT_SUPPORTED(\"CtlForceReequestBody\", @0);\n        ACTION_CONTAINER(yylhs.value.as < std::unique_ptr<actions::Action> > (), new actions::Action(yystack_[1].value.as < std::string > ()));\n      }\n#line 5028 \"seclang-parser.cc\"\n    break;\n\n  case 358: // act: \"ACTION_CTL_FORCE_REQ_BODY_VAR\" \"CONFIG_VALUE_OFF\"\n#line 2747 \"seclang-parser.yy\"\n      {\n        //ACTION_NOT_SUPPORTED(\"CtlForceReequestBody\", @0);\n        ACTION_CONTAINER(yylhs.value.as < std::unique_ptr<actions::Action> > (), new actions::Action(yystack_[1].value.as < std::string > ()));\n      }\n#line 5037 \"seclang-parser.cc\"\n    break;\n\n  case 359: // act: \"ACTION_CTL_PARSE_XML_INTO_ARGS\" \"CONFIG_VALUE_ON\"\n#line 2752 \"seclang-parser.yy\"\n      {\n        ACTION_CONTAINER(yylhs.value.as < std::unique_ptr<actions::Action> > (), new actions::ctl::ParseXmlIntoArgs(\"ctl:parseXmlIntoArgs=on\"));\n      }\n#line 5045 \"seclang-parser.cc\"\n    break;\n\n  case 360: // act: \"ACTION_CTL_PARSE_XML_INTO_ARGS\" \"CONFIG_VALUE_OFF\"\n#line 2756 \"seclang-parser.yy\"\n      {\n        ACTION_CONTAINER(yylhs.value.as < std::unique_ptr<actions::Action> > (), new actions::ctl::ParseXmlIntoArgs(\"ctl:parseXmlIntoArgs=off\"));\n      }\n#line 5053 \"seclang-parser.cc\"\n    break;\n\n  case 361: // act: \"ACTION_CTL_PARSE_XML_INTO_ARGS\" \"CONFIG_VALUE_ONLYARGS\"\n#line 2760 \"seclang-parser.yy\"\n      {\n        ACTION_CONTAINER(yylhs.value.as < std::unique_ptr<actions::Action> > (), new actions::ctl::ParseXmlIntoArgs(\"ctl:parseXmlIntoArgs=onlyargs\"));\n      }\n#line 5061 \"seclang-parser.cc\"\n    break;\n\n  case 362: // act: \"ACTION_CTL_REQUEST_BODY_ACCESS\" \"CONFIG_VALUE_ON\"\n#line 2764 \"seclang-parser.yy\"\n      {\n        ACTION_CONTAINER(yylhs.value.as < std::unique_ptr<actions::Action> > (), new actions::ctl::RequestBodyAccess(yystack_[1].value.as < std::string > () + \"true\"));\n      }\n#line 5069 \"seclang-parser.cc\"\n    break;\n\n  case 363: // act: \"ACTION_CTL_REQUEST_BODY_ACCESS\" \"CONFIG_VALUE_OFF\"\n#line 2768 \"seclang-parser.yy\"\n      {\n        ACTION_CONTAINER(yylhs.value.as < std::unique_ptr<actions::Action> > (), new actions::ctl::RequestBodyAccess(yystack_[1].value.as < std::string > () + \"false\"));\n      }\n#line 5077 \"seclang-parser.cc\"\n    break;\n\n  case 364: // act: \"ACTION_CTL_RULE_ENGINE\" \"CONFIG_VALUE_ON\"\n#line 2772 \"seclang-parser.yy\"\n      {\n        ACTION_CONTAINER(yylhs.value.as < std::unique_ptr<actions::Action> > (), new actions::ctl::RuleEngine(\"ctl:RuleEngine=on\"));\n      }\n#line 5085 \"seclang-parser.cc\"\n    break;\n\n  case 365: // act: \"ACTION_CTL_RULE_ENGINE\" \"CONFIG_VALUE_OFF\"\n#line 2776 \"seclang-parser.yy\"\n      {\n        ACTION_CONTAINER(yylhs.value.as < std::unique_ptr<actions::Action> > (), new actions::ctl::RuleEngine(\"ctl:RuleEngine=off\"));\n      }\n#line 5093 \"seclang-parser.cc\"\n    break;\n\n  case 366: // act: \"ACTION_CTL_RULE_ENGINE\" \"CONFIG_VALUE_DETC\"\n#line 2780 \"seclang-parser.yy\"\n      {\n        ACTION_CONTAINER(yylhs.value.as < std::unique_ptr<actions::Action> > (), new actions::ctl::RuleEngine(\"ctl:RuleEngine=detectiononly\"));\n      }\n#line 5101 \"seclang-parser.cc\"\n    break;\n\n  case 367: // act: \"ACTION_CTL_RULE_REMOVE_BY_ID\"\n#line 2784 \"seclang-parser.yy\"\n      {\n        ACTION_CONTAINER(yylhs.value.as < std::unique_ptr<actions::Action> > (), new actions::ctl::RuleRemoveById(yystack_[0].value.as < std::string > ()));\n      }\n#line 5109 \"seclang-parser.cc\"\n    break;\n\n  case 368: // act: \"ACTION_CTL_RULE_REMOVE_BY_TAG\"\n#line 2788 \"seclang-parser.yy\"\n      {\n        ACTION_CONTAINER(yylhs.value.as < std::unique_ptr<actions::Action> > (), new actions::ctl::RuleRemoveByTag(yystack_[0].value.as < std::string > ()));\n      }\n#line 5117 \"seclang-parser.cc\"\n    break;\n\n  case 369: // act: \"ACTION_CTL_RULE_REMOVE_TARGET_BY_ID\"\n#line 2792 \"seclang-parser.yy\"\n      {\n        ACTION_CONTAINER(yylhs.value.as < std::unique_ptr<actions::Action> > (), new actions::ctl::RuleRemoveTargetById(yystack_[0].value.as < std::string > ()));\n      }\n#line 5125 \"seclang-parser.cc\"\n    break;\n\n  case 370: // act: \"ACTION_CTL_RULE_REMOVE_TARGET_BY_TAG\"\n#line 2796 \"seclang-parser.yy\"\n      {\n        ACTION_CONTAINER(yylhs.value.as < std::unique_ptr<actions::Action> > (), new actions::ctl::RuleRemoveTargetByTag(yystack_[0].value.as < std::string > ()));\n      }\n#line 5133 \"seclang-parser.cc\"\n    break;\n\n  case 371: // act: \"Deny\"\n#line 2800 \"seclang-parser.yy\"\n      {\n        ACTION_CONTAINER(yylhs.value.as < std::unique_ptr<actions::Action> > (), new actions::disruptive::Deny(yystack_[0].value.as < std::string > ()));\n      }\n#line 5141 \"seclang-parser.cc\"\n    break;\n\n  case 372: // act: \"DeprecateVar\"\n#line 2804 \"seclang-parser.yy\"\n      {\n        ACTION_NOT_SUPPORTED(\"DeprecateVar\", yystack_[1].location);\n      }\n#line 5149 \"seclang-parser.cc\"\n    break;\n\n  case 373: // act: \"Drop\"\n#line 2808 \"seclang-parser.yy\"\n      {\n        ACTION_CONTAINER(yylhs.value.as < std::unique_ptr<actions::Action> > (), new actions::disruptive::Drop(yystack_[0].value.as < std::string > ()));\n      }\n#line 5157 \"seclang-parser.cc\"\n    break;\n\n  case 374: // act: \"Exec\"\n#line 2812 \"seclang-parser.yy\"\n      {\n        ACTION_CONTAINER(yylhs.value.as < std::unique_ptr<actions::Action> > (), new actions::Exec(yystack_[0].value.as < std::string > ()));\n      }\n#line 5165 \"seclang-parser.cc\"\n    break;\n\n  case 375: // act: \"ExpireVar\" run_time_string\n#line 2816 \"seclang-parser.yy\"\n      {\n        ACTION_CONTAINER(yylhs.value.as < std::unique_ptr<actions::Action> > (), new actions::ExpireVar(std::move(yystack_[0].value.as < std::unique_ptr<RunTimeString> > ())));\n      }\n#line 5173 \"seclang-parser.cc\"\n    break;\n\n  case 376: // act: \"Id\"\n#line 2820 \"seclang-parser.yy\"\n      {\n        ACTION_CONTAINER(yylhs.value.as < std::unique_ptr<actions::Action> > (), new actions::RuleId(yystack_[0].value.as < std::string > ()));\n      }\n#line 5181 \"seclang-parser.cc\"\n    break;\n\n  case 377: // act: \"InitCol\" run_time_string\n#line 2824 \"seclang-parser.yy\"\n      {\n        ACTION_CONTAINER(yylhs.value.as < std::unique_ptr<actions::Action> > (), new actions::InitCol(yystack_[1].value.as < std::string > (), std::move(yystack_[0].value.as < std::unique_ptr<RunTimeString> > ())));\n      }\n#line 5189 \"seclang-parser.cc\"\n    break;\n\n  case 378: // act: \"LogData\" run_time_string\n#line 2828 \"seclang-parser.yy\"\n      {\n        ACTION_CONTAINER(yylhs.value.as < std::unique_ptr<actions::Action> > (), new actions::LogData(std::move(yystack_[0].value.as < std::unique_ptr<RunTimeString> > ())));\n      }\n#line 5197 \"seclang-parser.cc\"\n    break;\n\n  case 379: // act: \"Log\"\n#line 2832 \"seclang-parser.yy\"\n      {\n        ACTION_CONTAINER(yylhs.value.as < std::unique_ptr<actions::Action> > (), new actions::Log(yystack_[0].value.as < std::string > ()));\n      }\n#line 5205 \"seclang-parser.cc\"\n    break;\n\n  case 380: // act: \"Maturity\"\n#line 2836 \"seclang-parser.yy\"\n      {\n        ACTION_CONTAINER(yylhs.value.as < std::unique_ptr<actions::Action> > (), new actions::Maturity(yystack_[0].value.as < std::string > ()));\n      }\n#line 5213 \"seclang-parser.cc\"\n    break;\n\n  case 381: // act: \"Msg\" run_time_string\n#line 2840 \"seclang-parser.yy\"\n      {\n        ACTION_CONTAINER(yylhs.value.as < std::unique_ptr<actions::Action> > (), new actions::Msg(std::move(yystack_[0].value.as < std::unique_ptr<RunTimeString> > ())));\n      }\n#line 5221 \"seclang-parser.cc\"\n    break;\n\n  case 382: // act: \"MultiMatch\"\n#line 2844 \"seclang-parser.yy\"\n      {\n        ACTION_CONTAINER(yylhs.value.as < std::unique_ptr<actions::Action> > (), new actions::MultiMatch(yystack_[0].value.as < std::string > ()));\n      }\n#line 5229 \"seclang-parser.cc\"\n    break;\n\n  case 383: // act: \"NoAuditLog\"\n#line 2848 \"seclang-parser.yy\"\n      {\n        ACTION_CONTAINER(yylhs.value.as < std::unique_ptr<actions::Action> > (), new actions::NoAuditLog(yystack_[0].value.as < std::string > ()));\n      }\n#line 5237 \"seclang-parser.cc\"\n    break;\n\n  case 384: // act: \"NoLog\"\n#line 2852 \"seclang-parser.yy\"\n      {\n        ACTION_CONTAINER(yylhs.value.as < std::unique_ptr<actions::Action> > (), new actions::NoLog(yystack_[0].value.as < std::string > ()));\n      }\n#line 5245 \"seclang-parser.cc\"\n    break;\n\n  case 385: // act: \"Pass\"\n#line 2856 \"seclang-parser.yy\"\n      {\n        ACTION_CONTAINER(yylhs.value.as < std::unique_ptr<actions::Action> > (), new actions::disruptive::Pass(yystack_[0].value.as < std::string > ()));\n      }\n#line 5253 \"seclang-parser.cc\"\n    break;\n\n  case 386: // act: \"Pause\"\n#line 2860 \"seclang-parser.yy\"\n      {\n        ACTION_NOT_SUPPORTED(\"Pause\", yystack_[1].location);\n      }\n#line 5261 \"seclang-parser.cc\"\n    break;\n\n  case 387: // act: \"Phase\"\n#line 2864 \"seclang-parser.yy\"\n      {\n        ACTION_CONTAINER(yylhs.value.as < std::unique_ptr<actions::Action> > (), new actions::Phase(yystack_[0].value.as < std::string > ()));\n      }\n#line 5269 \"seclang-parser.cc\"\n    break;\n\n  case 388: // act: \"Prepend\"\n#line 2868 \"seclang-parser.yy\"\n      {\n        ACTION_NOT_SUPPORTED(\"Prepend\", yystack_[1].location);\n      }\n#line 5277 \"seclang-parser.cc\"\n    break;\n\n  case 389: // act: \"Proxy\"\n#line 2872 \"seclang-parser.yy\"\n      {\n        ACTION_NOT_SUPPORTED(\"Proxy\", yystack_[1].location);\n      }\n#line 5285 \"seclang-parser.cc\"\n    break;\n\n  case 390: // act: \"Redirect\" run_time_string\n#line 2876 \"seclang-parser.yy\"\n      {\n        ACTION_CONTAINER(yylhs.value.as < std::unique_ptr<actions::Action> > (), new actions::disruptive::Redirect(std::move(yystack_[0].value.as < std::unique_ptr<RunTimeString> > ())));\n      }\n#line 5293 \"seclang-parser.cc\"\n    break;\n\n  case 391: // act: \"Rev\"\n#line 2880 \"seclang-parser.yy\"\n      {\n        ACTION_CONTAINER(yylhs.value.as < std::unique_ptr<actions::Action> > (), new actions::Rev(yystack_[0].value.as < std::string > ()));\n      }\n#line 5301 \"seclang-parser.cc\"\n    break;\n\n  case 392: // act: \"SanitiseArg\"\n#line 2884 \"seclang-parser.yy\"\n      {\n        ACTION_NOT_SUPPORTED(\"SanitiseArg\", yystack_[1].location);\n      }\n#line 5309 \"seclang-parser.cc\"\n    break;\n\n  case 393: // act: \"SanitiseMatched\"\n#line 2888 \"seclang-parser.yy\"\n      {\n        ACTION_NOT_SUPPORTED(\"SanitiseMatched\", yystack_[1].location);\n      }\n#line 5317 \"seclang-parser.cc\"\n    break;\n\n  case 394: // act: \"SanitiseMatchedBytes\"\n#line 2892 \"seclang-parser.yy\"\n      {\n        ACTION_NOT_SUPPORTED(\"SanitiseMatchedBytes\", yystack_[1].location);\n      }\n#line 5325 \"seclang-parser.cc\"\n    break;\n\n  case 395: // act: \"SanitiseRequestHeader\"\n#line 2896 \"seclang-parser.yy\"\n      {\n        ACTION_NOT_SUPPORTED(\"SanitiseRequestHeader\", yystack_[1].location);\n      }\n#line 5333 \"seclang-parser.cc\"\n    break;\n\n  case 396: // act: \"SanitiseResponseHeader\"\n#line 2900 \"seclang-parser.yy\"\n      {\n        ACTION_NOT_SUPPORTED(\"SanitiseResponseHeader\", yystack_[1].location);\n      }\n#line 5341 \"seclang-parser.cc\"\n    break;\n\n  case 397: // act: \"SetEnv\" run_time_string\n#line 2904 \"seclang-parser.yy\"\n      {\n        ACTION_CONTAINER(yylhs.value.as < std::unique_ptr<actions::Action> > (), new actions::SetENV(std::move(yystack_[0].value.as < std::unique_ptr<RunTimeString> > ())));\n      }\n#line 5349 \"seclang-parser.cc\"\n    break;\n\n  case 398: // act: \"SetRsc\" run_time_string\n#line 2908 \"seclang-parser.yy\"\n      {\n        ACTION_CONTAINER(yylhs.value.as < std::unique_ptr<actions::Action> > (), new actions::SetRSC(std::move(yystack_[0].value.as < std::unique_ptr<RunTimeString> > ())));\n      }\n#line 5357 \"seclang-parser.cc\"\n    break;\n\n  case 399: // act: \"SetSid\" run_time_string\n#line 2912 \"seclang-parser.yy\"\n      {\n        ACTION_CONTAINER(yylhs.value.as < std::unique_ptr<actions::Action> > (), new actions::SetSID(std::move(yystack_[0].value.as < std::unique_ptr<RunTimeString> > ())));\n      }\n#line 5365 \"seclang-parser.cc\"\n    break;\n\n  case 400: // act: \"SetUID\" run_time_string\n#line 2916 \"seclang-parser.yy\"\n      {\n        ACTION_CONTAINER(yylhs.value.as < std::unique_ptr<actions::Action> > (), new actions::SetUID(std::move(yystack_[0].value.as < std::unique_ptr<RunTimeString> > ())));\n      }\n#line 5373 \"seclang-parser.cc\"\n    break;\n\n  case 401: // act: \"SetVar\" setvar_action\n#line 2920 \"seclang-parser.yy\"\n      {\n        yylhs.value.as < std::unique_ptr<actions::Action> > () = std::move(yystack_[0].value.as < std::unique_ptr<actions::Action> > ());\n      }\n#line 5381 \"seclang-parser.cc\"\n    break;\n\n  case 402: // act: \"Severity\"\n#line 2924 \"seclang-parser.yy\"\n      {\n        ACTION_CONTAINER(yylhs.value.as < std::unique_ptr<actions::Action> > (), new actions::Severity(yystack_[0].value.as < std::string > ()));\n      }\n#line 5389 \"seclang-parser.cc\"\n    break;\n\n  case 403: // act: \"Skip\"\n#line 2928 \"seclang-parser.yy\"\n      {\n        ACTION_CONTAINER(yylhs.value.as < std::unique_ptr<actions::Action> > (), new actions::Skip(yystack_[0].value.as < std::string > ()));\n      }\n#line 5397 \"seclang-parser.cc\"\n    break;\n\n  case 404: // act: \"SkipAfter\"\n#line 2932 \"seclang-parser.yy\"\n      {\n        ACTION_CONTAINER(yylhs.value.as < std::unique_ptr<actions::Action> > (), new actions::SkipAfter(yystack_[0].value.as < std::string > ()));\n      }\n#line 5405 \"seclang-parser.cc\"\n    break;\n\n  case 405: // act: \"Status\"\n#line 2936 \"seclang-parser.yy\"\n      {\n        ACTION_CONTAINER(yylhs.value.as < std::unique_ptr<actions::Action> > (), new actions::data::Status(yystack_[0].value.as < std::string > ()));\n      }\n#line 5413 \"seclang-parser.cc\"\n    break;\n\n  case 406: // act: \"Tag\" run_time_string\n#line 2940 \"seclang-parser.yy\"\n      {\n        ACTION_CONTAINER(yylhs.value.as < std::unique_ptr<actions::Action> > (), new actions::Tag(std::move(yystack_[0].value.as < std::unique_ptr<RunTimeString> > ())));\n      }\n#line 5421 \"seclang-parser.cc\"\n    break;\n\n  case 407: // act: \"Ver\"\n#line 2944 \"seclang-parser.yy\"\n      {\n        ACTION_CONTAINER(yylhs.value.as < std::unique_ptr<actions::Action> > (), new actions::Ver(yystack_[0].value.as < std::string > ()));\n      }\n#line 5429 \"seclang-parser.cc\"\n    break;\n\n  case 408: // act: \"xmlns\"\n#line 2948 \"seclang-parser.yy\"\n      {\n        ACTION_CONTAINER(yylhs.value.as < std::unique_ptr<actions::Action> > (), new actions::XmlNS(yystack_[0].value.as < std::string > ()));\n      }\n#line 5437 \"seclang-parser.cc\"\n    break;\n\n  case 409: // act: \"ACTION_TRANSFORMATION_PARITY_ZERO_7_BIT\"\n#line 2952 \"seclang-parser.yy\"\n      {\n        ACTION_CONTAINER(yylhs.value.as < std::unique_ptr<actions::Action> > (), new actions::transformations::ParityZero7bit(yystack_[0].value.as < std::string > ()));\n      }\n#line 5445 \"seclang-parser.cc\"\n    break;\n\n  case 410: // act: \"ACTION_TRANSFORMATION_PARITY_ODD_7_BIT\"\n#line 2956 \"seclang-parser.yy\"\n      {\n        ACTION_CONTAINER(yylhs.value.as < std::unique_ptr<actions::Action> > (), new actions::transformations::ParityOdd7bit(yystack_[0].value.as < std::string > ()));\n      }\n#line 5453 \"seclang-parser.cc\"\n    break;\n\n  case 411: // act: \"ACTION_TRANSFORMATION_PARITY_EVEN_7_BIT\"\n#line 2960 \"seclang-parser.yy\"\n      {\n        ACTION_CONTAINER(yylhs.value.as < std::unique_ptr<actions::Action> > (), new actions::transformations::ParityEven7bit(yystack_[0].value.as < std::string > ()));\n      }\n#line 5461 \"seclang-parser.cc\"\n    break;\n\n  case 412: // act: \"ACTION_TRANSFORMATION_SQL_HEX_DECODE\"\n#line 2964 \"seclang-parser.yy\"\n      {\n        ACTION_CONTAINER(yylhs.value.as < std::unique_ptr<actions::Action> > (), new actions::transformations::SqlHexDecode(yystack_[0].value.as < std::string > ()));\n      }\n#line 5469 \"seclang-parser.cc\"\n    break;\n\n  case 413: // act: \"ACTION_TRANSFORMATION_BASE_64_ENCODE\"\n#line 2968 \"seclang-parser.yy\"\n      {\n        ACTION_CONTAINER(yylhs.value.as < std::unique_ptr<actions::Action> > (), new actions::transformations::Base64Encode(yystack_[0].value.as < std::string > ()));\n      }\n#line 5477 \"seclang-parser.cc\"\n    break;\n\n  case 414: // act: \"ACTION_TRANSFORMATION_BASE_64_DECODE\"\n#line 2972 \"seclang-parser.yy\"\n      {\n        ACTION_CONTAINER(yylhs.value.as < std::unique_ptr<actions::Action> > (), new actions::transformations::Base64Decode(yystack_[0].value.as < std::string > ()));\n      }\n#line 5485 \"seclang-parser.cc\"\n    break;\n\n  case 415: // act: \"ACTION_TRANSFORMATION_BASE_64_DECODE_EXT\"\n#line 2976 \"seclang-parser.yy\"\n      {\n        ACTION_CONTAINER(yylhs.value.as < std::unique_ptr<actions::Action> > (), new actions::transformations::Base64DecodeExt(yystack_[0].value.as < std::string > ()));\n      }\n#line 5493 \"seclang-parser.cc\"\n    break;\n\n  case 416: // act: \"ACTION_TRANSFORMATION_CMD_LINE\"\n#line 2980 \"seclang-parser.yy\"\n      {\n        ACTION_CONTAINER(yylhs.value.as < std::unique_ptr<actions::Action> > (), new actions::transformations::CmdLine(yystack_[0].value.as < std::string > ()));\n      }\n#line 5501 \"seclang-parser.cc\"\n    break;\n\n  case 417: // act: \"ACTION_TRANSFORMATION_SHA1\"\n#line 2984 \"seclang-parser.yy\"\n      {\n        ACTION_CONTAINER(yylhs.value.as < std::unique_ptr<actions::Action> > (), new actions::transformations::Sha1(yystack_[0].value.as < std::string > ()));\n      }\n#line 5509 \"seclang-parser.cc\"\n    break;\n\n  case 418: // act: \"ACTION_TRANSFORMATION_MD5\"\n#line 2988 \"seclang-parser.yy\"\n      {\n        ACTION_CONTAINER(yylhs.value.as < std::unique_ptr<actions::Action> > (), new actions::transformations::Md5(yystack_[0].value.as < std::string > ()));\n      }\n#line 5517 \"seclang-parser.cc\"\n    break;\n\n  case 419: // act: \"ACTION_TRANSFORMATION_ESCAPE_SEQ_DECODE\"\n#line 2992 \"seclang-parser.yy\"\n      {\n        ACTION_CONTAINER(yylhs.value.as < std::unique_ptr<actions::Action> > (), new actions::transformations::EscapeSeqDecode(yystack_[0].value.as < std::string > ()));\n      }\n#line 5525 \"seclang-parser.cc\"\n    break;\n\n  case 420: // act: \"ACTION_TRANSFORMATION_HEX_ENCODE\"\n#line 2996 \"seclang-parser.yy\"\n      {\n        ACTION_CONTAINER(yylhs.value.as < std::unique_ptr<actions::Action> > (), new actions::transformations::HexEncode(yystack_[0].value.as < std::string > ()));\n      }\n#line 5533 \"seclang-parser.cc\"\n    break;\n\n  case 421: // act: \"ACTION_TRANSFORMATION_HEX_DECODE\"\n#line 3000 \"seclang-parser.yy\"\n      {\n        ACTION_CONTAINER(yylhs.value.as < std::unique_ptr<actions::Action> > (), new actions::transformations::HexDecode(yystack_[0].value.as < std::string > ()));\n      }\n#line 5541 \"seclang-parser.cc\"\n    break;\n\n  case 422: // act: \"ACTION_TRANSFORMATION_LOWERCASE\"\n#line 3004 \"seclang-parser.yy\"\n      {\n        ACTION_CONTAINER(yylhs.value.as < std::unique_ptr<actions::Action> > (), new actions::transformations::LowerCase(yystack_[0].value.as < std::string > ()));\n      }\n#line 5549 \"seclang-parser.cc\"\n    break;\n\n  case 423: // act: \"ACTION_TRANSFORMATION_UPPERCASE\"\n#line 3008 \"seclang-parser.yy\"\n      {\n        ACTION_CONTAINER(yylhs.value.as < std::unique_ptr<actions::Action> > (), new actions::transformations::UpperCase(yystack_[0].value.as < std::string > ()));\n      }\n#line 5557 \"seclang-parser.cc\"\n    break;\n\n  case 424: // act: \"ACTION_TRANSFORMATION_URL_DECODE_UNI\"\n#line 3012 \"seclang-parser.yy\"\n      {\n        ACTION_CONTAINER(yylhs.value.as < std::unique_ptr<actions::Action> > (), new actions::transformations::UrlDecodeUni(yystack_[0].value.as < std::string > ()));\n      }\n#line 5565 \"seclang-parser.cc\"\n    break;\n\n  case 425: // act: \"ACTION_TRANSFORMATION_URL_DECODE\"\n#line 3016 \"seclang-parser.yy\"\n      {\n        ACTION_CONTAINER(yylhs.value.as < std::unique_ptr<actions::Action> > (), new actions::transformations::UrlDecode(yystack_[0].value.as < std::string > ()));\n      }\n#line 5573 \"seclang-parser.cc\"\n    break;\n\n  case 426: // act: \"ACTION_TRANSFORMATION_URL_ENCODE\"\n#line 3020 \"seclang-parser.yy\"\n      {\n        ACTION_CONTAINER(yylhs.value.as < std::unique_ptr<actions::Action> > (), new actions::transformations::UrlEncode(yystack_[0].value.as < std::string > ()));\n      }\n#line 5581 \"seclang-parser.cc\"\n    break;\n\n  case 427: // act: \"ACTION_TRANSFORMATION_NONE\"\n#line 3024 \"seclang-parser.yy\"\n      {\n        ACTION_CONTAINER(yylhs.value.as < std::unique_ptr<actions::Action> > (), new actions::transformations::None(yystack_[0].value.as < std::string > ()));\n      }\n#line 5589 \"seclang-parser.cc\"\n    break;\n\n  case 428: // act: \"ACTION_TRANSFORMATION_COMPRESS_WHITESPACE\"\n#line 3028 \"seclang-parser.yy\"\n      {\n        ACTION_CONTAINER(yylhs.value.as < std::unique_ptr<actions::Action> > (), new actions::transformations::CompressWhitespace(yystack_[0].value.as < std::string > ()));\n      }\n#line 5597 \"seclang-parser.cc\"\n    break;\n\n  case 429: // act: \"ACTION_TRANSFORMATION_REMOVE_WHITESPACE\"\n#line 3032 \"seclang-parser.yy\"\n      {\n        ACTION_CONTAINER(yylhs.value.as < std::unique_ptr<actions::Action> > (), new actions::transformations::RemoveWhitespace(yystack_[0].value.as < std::string > ()));\n      }\n#line 5605 \"seclang-parser.cc\"\n    break;\n\n  case 430: // act: \"ACTION_TRANSFORMATION_REPLACE_NULLS\"\n#line 3036 \"seclang-parser.yy\"\n      {\n        ACTION_CONTAINER(yylhs.value.as < std::unique_ptr<actions::Action> > (), new actions::transformations::ReplaceNulls(yystack_[0].value.as < std::string > ()));\n      }\n#line 5613 \"seclang-parser.cc\"\n    break;\n\n  case 431: // act: \"ACTION_TRANSFORMATION_REMOVE_NULLS\"\n#line 3040 \"seclang-parser.yy\"\n      {\n        ACTION_CONTAINER(yylhs.value.as < std::unique_ptr<actions::Action> > (), new actions::transformations::RemoveNulls(yystack_[0].value.as < std::string > ()));\n      }\n#line 5621 \"seclang-parser.cc\"\n    break;\n\n  case 432: // act: \"ACTION_TRANSFORMATION_HTML_ENTITY_DECODE\"\n#line 3044 \"seclang-parser.yy\"\n      {\n        ACTION_CONTAINER(yylhs.value.as < std::unique_ptr<actions::Action> > (), new actions::transformations::HtmlEntityDecode(yystack_[0].value.as < std::string > ()));\n      }\n#line 5629 \"seclang-parser.cc\"\n    break;\n\n  case 433: // act: \"ACTION_TRANSFORMATION_JS_DECODE\"\n#line 3048 \"seclang-parser.yy\"\n      {\n        ACTION_CONTAINER(yylhs.value.as < std::unique_ptr<actions::Action> > (), new actions::transformations::JsDecode(yystack_[0].value.as < std::string > ()));\n      }\n#line 5637 \"seclang-parser.cc\"\n    break;\n\n  case 434: // act: \"ACTION_TRANSFORMATION_CSS_DECODE\"\n#line 3052 \"seclang-parser.yy\"\n      {\n        ACTION_CONTAINER(yylhs.value.as < std::unique_ptr<actions::Action> > (), new actions::transformations::CssDecode(yystack_[0].value.as < std::string > ()));\n      }\n#line 5645 \"seclang-parser.cc\"\n    break;\n\n  case 435: // act: \"ACTION_TRANSFORMATION_TRIM\"\n#line 3056 \"seclang-parser.yy\"\n      {\n        ACTION_CONTAINER(yylhs.value.as < std::unique_ptr<actions::Action> > (), new actions::transformations::Trim(yystack_[0].value.as < std::string > ()));\n      }\n#line 5653 \"seclang-parser.cc\"\n    break;\n\n  case 436: // act: \"ACTION_TRANSFORMATION_TRIM_LEFT\"\n#line 3060 \"seclang-parser.yy\"\n      {\n        ACTION_CONTAINER(yylhs.value.as < std::unique_ptr<actions::Action> > (), new actions::transformations::TrimLeft(yystack_[0].value.as < std::string > ()));\n      }\n#line 5661 \"seclang-parser.cc\"\n    break;\n\n  case 437: // act: \"ACTION_TRANSFORMATION_TRIM_RIGHT\"\n#line 3064 \"seclang-parser.yy\"\n      {\n        ACTION_CONTAINER(yylhs.value.as < std::unique_ptr<actions::Action> > (), new actions::transformations::TrimRight(yystack_[0].value.as < std::string > ()));\n      }\n#line 5669 \"seclang-parser.cc\"\n    break;\n\n  case 438: // act: \"ACTION_TRANSFORMATION_NORMALISE_PATH_WIN\"\n#line 3068 \"seclang-parser.yy\"\n      {\n        ACTION_CONTAINER(yylhs.value.as < std::unique_ptr<actions::Action> > (), new actions::transformations::NormalisePathWin(yystack_[0].value.as < std::string > ()));\n      }\n#line 5677 \"seclang-parser.cc\"\n    break;\n\n  case 439: // act: \"ACTION_TRANSFORMATION_NORMALISE_PATH\"\n#line 3072 \"seclang-parser.yy\"\n      {\n        ACTION_CONTAINER(yylhs.value.as < std::unique_ptr<actions::Action> > (), new actions::transformations::NormalisePath(yystack_[0].value.as < std::string > ()));\n      }\n#line 5685 \"seclang-parser.cc\"\n    break;\n\n  case 440: // act: \"ACTION_TRANSFORMATION_LENGTH\"\n#line 3076 \"seclang-parser.yy\"\n      {\n        ACTION_CONTAINER(yylhs.value.as < std::unique_ptr<actions::Action> > (), new actions::transformations::Length(yystack_[0].value.as < std::string > ()));\n      }\n#line 5693 \"seclang-parser.cc\"\n    break;\n\n  case 441: // act: \"ACTION_TRANSFORMATION_UTF8_TO_UNICODE\"\n#line 3080 \"seclang-parser.yy\"\n      {\n        ACTION_CONTAINER(yylhs.value.as < std::unique_ptr<actions::Action> > (), new actions::transformations::Utf8ToUnicode(yystack_[0].value.as < std::string > ()));\n      }\n#line 5701 \"seclang-parser.cc\"\n    break;\n\n  case 442: // act: \"ACTION_TRANSFORMATION_REMOVE_COMMENTS_CHAR\"\n#line 3084 \"seclang-parser.yy\"\n      {\n        ACTION_CONTAINER(yylhs.value.as < std::unique_ptr<actions::Action> > (), new actions::transformations::RemoveCommentsChar(yystack_[0].value.as < std::string > ()));\n      }\n#line 5709 \"seclang-parser.cc\"\n    break;\n\n  case 443: // act: \"ACTION_TRANSFORMATION_REMOVE_COMMENTS\"\n#line 3088 \"seclang-parser.yy\"\n      {\n        ACTION_CONTAINER(yylhs.value.as < std::unique_ptr<actions::Action> > (), new actions::transformations::RemoveComments(yystack_[0].value.as < std::string > ()));\n      }\n#line 5717 \"seclang-parser.cc\"\n    break;\n\n  case 444: // act: \"ACTION_TRANSFORMATION_REPLACE_COMMENTS\"\n#line 3092 \"seclang-parser.yy\"\n      {\n        ACTION_CONTAINER(yylhs.value.as < std::unique_ptr<actions::Action> > (), new actions::transformations::ReplaceComments(yystack_[0].value.as < std::string > ()));\n      }\n#line 5725 \"seclang-parser.cc\"\n    break;\n\n  case 445: // setvar_action: \"NOT\" var\n#line 3099 \"seclang-parser.yy\"\n      {\n        ACTION_CONTAINER(yylhs.value.as < std::unique_ptr<actions::Action> > (), new actions::SetVar(actions::SetVarOperation::unsetOperation, std::move(yystack_[0].value.as < std::unique_ptr<Variable> > ())));\n      }\n#line 5733 \"seclang-parser.cc\"\n    break;\n\n  case 446: // setvar_action: var\n#line 3103 \"seclang-parser.yy\"\n      {\n        ACTION_CONTAINER(yylhs.value.as < std::unique_ptr<actions::Action> > (), new actions::SetVar(actions::SetVarOperation::setToOneOperation, std::move(yystack_[0].value.as < std::unique_ptr<Variable> > ())));\n      }\n#line 5741 \"seclang-parser.cc\"\n    break;\n\n  case 447: // setvar_action: var SETVAR_OPERATION_EQUALS run_time_string\n#line 3107 \"seclang-parser.yy\"\n      {\n        ACTION_CONTAINER(yylhs.value.as < std::unique_ptr<actions::Action> > (), new actions::SetVar(actions::SetVarOperation::setOperation, std::move(yystack_[2].value.as < std::unique_ptr<Variable> > ()), std::move(yystack_[0].value.as < std::unique_ptr<RunTimeString> > ())));\n      }\n#line 5749 \"seclang-parser.cc\"\n    break;\n\n  case 448: // setvar_action: var SETVAR_OPERATION_EQUALS_PLUS run_time_string\n#line 3111 \"seclang-parser.yy\"\n      {\n        ACTION_CONTAINER(yylhs.value.as < std::unique_ptr<actions::Action> > (), new actions::SetVar(actions::SetVarOperation::sumAndSetOperation, std::move(yystack_[2].value.as < std::unique_ptr<Variable> > ()), std::move(yystack_[0].value.as < std::unique_ptr<RunTimeString> > ())));\n      }\n#line 5757 \"seclang-parser.cc\"\n    break;\n\n  case 449: // setvar_action: var SETVAR_OPERATION_EQUALS_MINUS run_time_string\n#line 3115 \"seclang-parser.yy\"\n      {\n        ACTION_CONTAINER(yylhs.value.as < std::unique_ptr<actions::Action> > (), new actions::SetVar(actions::SetVarOperation::substractAndSetOperation, std::move(yystack_[2].value.as < std::unique_ptr<Variable> > ()), std::move(yystack_[0].value.as < std::unique_ptr<RunTimeString> > ())));\n      }\n#line 5765 \"seclang-parser.cc\"\n    break;\n\n  case 450: // run_time_string: run_time_string \"FREE_TEXT_QUOTE_MACRO_EXPANSION\"\n#line 3122 \"seclang-parser.yy\"\n      {\n        yystack_[1].value.as < std::unique_ptr<RunTimeString> > ()->appendText(yystack_[0].value.as < std::string > ());\n        yylhs.value.as < std::unique_ptr<RunTimeString> > () = std::move(yystack_[1].value.as < std::unique_ptr<RunTimeString> > ());\n      }\n#line 5774 \"seclang-parser.cc\"\n    break;\n\n  case 451: // run_time_string: run_time_string var\n#line 3127 \"seclang-parser.yy\"\n      {\n        yystack_[1].value.as < std::unique_ptr<RunTimeString> > ()->appendVar(std::move(yystack_[0].value.as < std::unique_ptr<Variable> > ()));\n        yylhs.value.as < std::unique_ptr<RunTimeString> > () = std::move(yystack_[1].value.as < std::unique_ptr<RunTimeString> > ());\n      }\n#line 5783 \"seclang-parser.cc\"\n    break;\n\n  case 452: // run_time_string: \"FREE_TEXT_QUOTE_MACRO_EXPANSION\"\n#line 3132 \"seclang-parser.yy\"\n      {\n        std::unique_ptr<RunTimeString> r(new RunTimeString());\n        r->appendText(yystack_[0].value.as < std::string > ());\n        yylhs.value.as < std::unique_ptr<RunTimeString> > () = std::move(r);\n      }\n#line 5793 \"seclang-parser.cc\"\n    break;\n\n  case 453: // run_time_string: var\n#line 3138 \"seclang-parser.yy\"\n      {\n        std::unique_ptr<RunTimeString> r(new RunTimeString());\n        r->appendVar(std::move(yystack_[0].value.as < std::unique_ptr<Variable> > ()));\n        yylhs.value.as < std::unique_ptr<RunTimeString> > () = std::move(r);\n      }\n#line 5803 \"seclang-parser.cc\"\n    break;\n\n\n#line 5807 \"seclang-parser.cc\"\n\n            default:\n              break;\n            }\n        }\n#if YY_EXCEPTIONS\n      catch (const syntax_error& yyexc)\n        {\n          YYCDEBUG << \"Caught exception: \" << yyexc.what() << '\\n';\n          error (yyexc);\n          YYERROR;\n        }\n#endif // YY_EXCEPTIONS\n      YY_SYMBOL_PRINT (\"-> $$ =\", yylhs);\n      yypop_ (yylen);\n      yylen = 0;\n\n      // Shift the result of the reduction.\n      yypush_ (YY_NULLPTR, YY_MOVE (yylhs));\n    }\n    goto yynewstate;\n\n\n  /*--------------------------------------.\n  | yyerrlab -- here on detecting error.  |\n  `--------------------------------------*/\n  yyerrlab:\n    // If not already recovering from an error, report this error.\n    if (!yyerrstatus_)\n      {\n        ++yynerrs_;\n        context yyctx (*this, yyla);\n        std::string msg = yysyntax_error_ (yyctx);\n        error (yyla.location, YY_MOVE (msg));\n      }\n\n\n    yyerror_range[1].location = yyla.location;\n    if (yyerrstatus_ == 3)\n      {\n        /* If just tried and failed to reuse lookahead token after an\n           error, discard it.  */\n\n        // Return failure if at end of input.\n        if (yyla.kind () == symbol_kind::S_YYEOF)\n          YYABORT;\n        else if (!yyla.empty ())\n          {\n            yy_destroy_ (\"Error: discarding\", yyla);\n            yyla.clear ();\n          }\n      }\n\n    // Else will try to reuse lookahead token after shifting the error token.\n    goto yyerrlab1;\n\n\n  /*---------------------------------------------------.\n  | yyerrorlab -- error raised explicitly by YYERROR.  |\n  `---------------------------------------------------*/\n  yyerrorlab:\n    /* Pacify compilers when the user code never invokes YYERROR and\n       the label yyerrorlab therefore never appears in user code.  */\n    if (false)\n      YYERROR;\n\n    /* Do not reclaim the symbols of the rule whose action triggered\n       this YYERROR.  */\n    yypop_ (yylen);\n    yylen = 0;\n    YY_STACK_PRINT ();\n    goto yyerrlab1;\n\n\n  /*-------------------------------------------------------------.\n  | yyerrlab1 -- common code for both syntax error and YYERROR.  |\n  `-------------------------------------------------------------*/\n  yyerrlab1:\n    yyerrstatus_ = 3;   // Each real token shifted decrements this.\n    // Pop stack until we find a state that shifts the error token.\n    for (;;)\n      {\n        yyn = yypact_[+yystack_[0].state];\n        if (!yy_pact_value_is_default_ (yyn))\n          {\n            yyn += symbol_kind::S_YYerror;\n            if (0 <= yyn && yyn <= yylast_\n                && yycheck_[yyn] == symbol_kind::S_YYerror)\n              {\n                yyn = yytable_[yyn];\n                if (0 < yyn)\n                  break;\n              }\n          }\n\n        // Pop the current state because it cannot handle the error token.\n        if (yystack_.size () == 1)\n          YYABORT;\n\n        yyerror_range[1].location = yystack_[0].location;\n        yy_destroy_ (\"Error: popping\", yystack_[0]);\n        yypop_ ();\n        YY_STACK_PRINT ();\n      }\n    {\n      stack_symbol_type error_token;\n\n      yyerror_range[2].location = yyla.location;\n      YYLLOC_DEFAULT (error_token.location, yyerror_range, 2);\n\n      // Shift the error token.\n      error_token.state = state_type (yyn);\n      yypush_ (\"Shifting\", YY_MOVE (error_token));\n    }\n    goto yynewstate;\n\n\n  /*-------------------------------------.\n  | yyacceptlab -- YYACCEPT comes here.  |\n  `-------------------------------------*/\n  yyacceptlab:\n    yyresult = 0;\n    goto yyreturn;\n\n\n  /*-----------------------------------.\n  | yyabortlab -- YYABORT comes here.  |\n  `-----------------------------------*/\n  yyabortlab:\n    yyresult = 1;\n    goto yyreturn;\n\n\n  /*-----------------------------------------------------.\n  | yyreturn -- parsing is finished, return the result.  |\n  `-----------------------------------------------------*/\n  yyreturn:\n    if (!yyla.empty ())\n      yy_destroy_ (\"Cleanup: discarding lookahead\", yyla);\n\n    /* Do not reclaim the symbols of the rule whose action triggered\n       this YYABORT or YYACCEPT.  */\n    yypop_ (yylen);\n    YY_STACK_PRINT ();\n    while (1 < yystack_.size ())\n      {\n        yy_destroy_ (\"Cleanup: popping\", yystack_[0]);\n        yypop_ ();\n      }\n\n    return yyresult;\n  }\n#if YY_EXCEPTIONS\n    catch (...)\n      {\n        YYCDEBUG << \"Exception caught: cleaning lookahead and stack\\n\";\n        // Do not try to display the values of the reclaimed symbols,\n        // as their printers might throw an exception.\n        if (!yyla.empty ())\n          yy_destroy_ (YY_NULLPTR, yyla);\n\n        while (1 < yystack_.size ())\n          {\n            yy_destroy_ (YY_NULLPTR, yystack_[0]);\n            yypop_ ();\n          }\n        throw;\n      }\n#endif // YY_EXCEPTIONS\n  }\n\n  void\n  seclang_parser::error (const syntax_error& yyexc)\n  {\n    error (yyexc.location, yyexc.what ());\n  }\n\n  /* Return YYSTR after stripping away unnecessary quotes and\n     backslashes, so that it's suitable for yyerror.  The heuristic is\n     that double-quoting is unnecessary unless the string contains an\n     apostrophe, a comma, or backslash (other than backslash-backslash).\n     YYSTR is taken from yytname.  */\n  std::string\n  seclang_parser::yytnamerr_ (const char *yystr)\n  {\n    if (*yystr == '\"')\n      {\n        std::string yyr;\n        char const *yyp = yystr;\n\n        for (;;)\n          switch (*++yyp)\n            {\n            case '\\'':\n            case ',':\n              goto do_not_strip_quotes;\n\n            case '\\\\':\n              if (*++yyp != '\\\\')\n                goto do_not_strip_quotes;\n              else\n                goto append;\n\n            append:\n            default:\n              yyr += *yyp;\n              break;\n\n            case '\"':\n              return yyr;\n            }\n      do_not_strip_quotes: ;\n      }\n\n    return yystr;\n  }\n\n  std::string\n  seclang_parser::symbol_name (symbol_kind_type yysymbol)\n  {\n    return yytnamerr_ (yytname_[yysymbol]);\n  }\n\n\n\n  // seclang_parser::context.\n  seclang_parser::context::context (const seclang_parser& yyparser, const symbol_type& yyla)\n    : yyparser_ (yyparser)\n    , yyla_ (yyla)\n  {}\n\n  int\n  seclang_parser::context::expected_tokens (symbol_kind_type yyarg[], int yyargn) const\n  {\n    // Actual number of expected tokens\n    int yycount = 0;\n\n    const int yyn = yypact_[+yyparser_.yystack_[0].state];\n    if (!yy_pact_value_is_default_ (yyn))\n      {\n        /* Start YYX at -YYN if negative to avoid negative indexes in\n           YYCHECK.  In other words, skip the first -YYN actions for\n           this state because they are default actions.  */\n        const int yyxbegin = yyn < 0 ? -yyn : 0;\n        // Stay within bounds of both yycheck and yytname.\n        const int yychecklim = yylast_ - yyn + 1;\n        const int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;\n        for (int yyx = yyxbegin; yyx < yyxend; ++yyx)\n          if (yycheck_[yyx + yyn] == yyx && yyx != symbol_kind::S_YYerror\n              && !yy_table_value_is_error_ (yytable_[yyx + yyn]))\n            {\n              if (!yyarg)\n                ++yycount;\n              else if (yycount == yyargn)\n                return 0;\n              else\n                yyarg[yycount++] = YY_CAST (symbol_kind_type, yyx);\n            }\n      }\n\n    if (yyarg && yycount == 0 && 0 < yyargn)\n      yyarg[0] = symbol_kind::S_YYEMPTY;\n    return yycount;\n  }\n\n\n\n\n\n\n  int\n  seclang_parser::yy_syntax_error_arguments_ (const context& yyctx,\n                                                 symbol_kind_type yyarg[], int yyargn) const\n  {\n    /* There are many possibilities here to consider:\n       - If this state is a consistent state with a default action, then\n         the only way this function was invoked is if the default action\n         is an error action.  In that case, don't check for expected\n         tokens because there are none.\n       - The only way there can be no lookahead present (in yyla) is\n         if this state is a consistent state with a default action.\n         Thus, detecting the absence of a lookahead is sufficient to\n         determine that there is no unexpected or expected token to\n         report.  In that case, just report a simple \"syntax error\".\n       - Don't assume there isn't a lookahead just because this state is\n         a consistent state with a default action.  There might have\n         been a previous inconsistent state, consistent state with a\n         non-default action, or user semantic action that manipulated\n         yyla.  (However, yyla is currently not documented for users.)\n       - Of course, the expected token list depends on states to have\n         correct lookahead information, and it depends on the parser not\n         to perform extra reductions after fetching a lookahead from the\n         scanner and before detecting a syntax error.  Thus, state merging\n         (from LALR or IELR) and default reductions corrupt the expected\n         token list.  However, the list is correct for canonical LR with\n         one exception: it will still contain any token that will not be\n         accepted due to an error action in a later state.\n    */\n\n    if (!yyctx.lookahead ().empty ())\n      {\n        if (yyarg)\n          yyarg[0] = yyctx.token ();\n        int yyn = yyctx.expected_tokens (yyarg ? yyarg + 1 : yyarg, yyargn - 1);\n        return yyn + 1;\n      }\n    return 0;\n  }\n\n  // Generate an error message.\n  std::string\n  seclang_parser::yysyntax_error_ (const context& yyctx) const\n  {\n    // Its maximum.\n    enum { YYARGS_MAX = 5 };\n    // Arguments of yyformat.\n    symbol_kind_type yyarg[YYARGS_MAX];\n    int yycount = yy_syntax_error_arguments_ (yyctx, yyarg, YYARGS_MAX);\n\n    char const* yyformat = YY_NULLPTR;\n    switch (yycount)\n      {\n#define YYCASE_(N, S)                         \\\n        case N:                               \\\n          yyformat = S;                       \\\n        break\n      default: // Avoid compiler warnings.\n        YYCASE_ (0, YY_(\"syntax error\"));\n        YYCASE_ (1, YY_(\"syntax error, unexpected %s\"));\n        YYCASE_ (2, YY_(\"syntax error, unexpected %s, expecting %s\"));\n        YYCASE_ (3, YY_(\"syntax error, unexpected %s, expecting %s or %s\"));\n        YYCASE_ (4, YY_(\"syntax error, unexpected %s, expecting %s or %s or %s\"));\n        YYCASE_ (5, YY_(\"syntax error, unexpected %s, expecting %s or %s or %s or %s\"));\n#undef YYCASE_\n      }\n\n    std::string yyres;\n    // Argument number.\n    std::ptrdiff_t yyi = 0;\n    for (char const* yyp = yyformat; *yyp; ++yyp)\n      if (yyp[0] == '%' && yyp[1] == 's' && yyi < yycount)\n        {\n          yyres += symbol_name (yyarg[yyi++]);\n          ++yyp;\n        }\n      else\n        yyres += *yyp;\n    return yyres;\n  }\n\n\n  const short seclang_parser::yypact_ninf_ = -412;\n\n  const signed char seclang_parser::yytable_ninf_ = -1;\n\n  const short\n  seclang_parser::yypact_[] =\n  {\n    2834,  -412,   -96,  -412,    72,  -412,   -92,  -412,  -412,  -412,\n    -412,  -412,  -281,  -412,  -412,  -412,  -412,  -412,  -412,  -277,\n    -412,  -412,  -412,   -90,   -88,  -412,  -412,  -412,  -412,  -412,\n    -412,  -412,  -412,  -412,  -412,  -412,  -412,  -412,  -412,  -412,\n     -86,  -412,  -412,   -87,  -412,   -82,  -412,   -83,   -78,  -412,\n    -262,   -91,   -91,  -412,  -412,  -412,  -412,   -76,  -305,  -412,\n    -412,  -412,  1525,  1525,  1525,   -91,  -274,   -74,  -412,  -412,\n    -412,   -72,  -288,  -412,  -412,  -412,  -412,  -412,  -412,  -412,\n    -412,  -412,  1525,   -91,  2980,  -412,  -412,  -412,  -412,  -412,\n    -412,  -412,  -412,  -412,  -412,  -412,  -412,  -412,  -412,  -412,\n    -412,  -412,  -412,  -412,  -412,  -412,  -412,  -412,  -412,  -412,\n    -412,  -412,  -412,  -412,  -412,  -412,  -412,  2389,  -159,  -412,\n    -412,  -412,  -412,  -412,  -412,  -412,  -268,  -412,  -412,  -412,\n    -412,   -68,  -259,   -66,  -412,  -412,  -412,  -412,  -412,  -412,\n    -412,  -412,  2524,  -412,  2524,  -412,  2524,  -412,  2524,  -412,\n    -412,  -412,  -412,  -412,  -412,  -412,  -412,  2524,  -412,  -412,\n    -412,  -412,  -412,  -412,  2524,  2524,  2524,  2524,  -412,  -412,\n    -412,  -412,  2524,  -412,  -412,  -412,  -412,  -412,  -412,  -412,\n    -412,  -412,  -412,  -412,  -412,  -412,  -412,  -412,  -412,  -412,\n    -412,  -412,  -412,  -412,  -412,  -412,  -412,  -412,  -412,  -412,\n    -412,  -412,  -412,  -412,  -412,  -412,  -412,  -412,  -412,  -412,\n    -412,  3169,  -412,     6,  -412,  -412,  -412,  -412,  -412,  -412,\n    2727,  2727,  -344,  -333,  -303,  -189,  -188,  -185,  -184,  -175,\n    -174,  -171,  -170,  -167,  -166,  -163,  -162,  -158,  -157,  -412,\n    -154,  -153,  -150,  -149,  -412,  -412,  -146,  -412,  -412,  -412,\n    -412,  -412,  -412,  -412,  -412,  -412,  -412,  -412,  -412,  -412,\n    -412,  -412,  -412,  -412,  -412,  -412,  -412,  -412,  -412,  -412,\n    -412,  -412,  -412,  -412,  -412,  -412,  -412,  -412,  -412,  -412,\n    -412,  -412,  -412,  -412,  -142,  -412,  -412,  -412,  -412,  -412,\n     471,  -412,  -412,  -412,  -141,  -412,  -412,  -412,  -412,  -412,\n    -412,  -412,  -412,  -412,  -412,  -412,  -412,   563,   655,   997,\n    1089,  1181,  -137,  -136,  1619,  -412,  -412,  -412,  -412,  -412,\n    -412,  -412,  -412,  -412,  -412,  -412,  -412,  -412,  -412,    24,\n    -412,  -412,  -412,  -412,  -412,  -412,  -412,  -412,  -412,  -412,\n    -412,  -412,  -412,  -412,  2051,  -412,  -412,  -412,  -412,  2727,\n      52,  -412,  -412,  -412,  -412,  -412,  -412,  -412,  -412,  -412,\n    -412,  -412,  -412,  -412,  -412,  -412,  -412,  2616,  2616,  2616,\n    2616,  2616,  2616,  2616,  2616,  2616,  2616,    12,  3169,  -412,\n    -412,  -412,  -412,  -412,  -412,  -412,  -412,  -412,  -412,  -412,\n    -412,  -412,  -412,  -412,  -412,  -412,  -412,  -412,  -412,  -412,\n    -412,  -412,  -412,  -412,  -412,  -412,  -412,  -412,  -412,  -412,\n    -412,  -412,  -412,  -412,  -412,  -412,  -412,  -412,  -412,  -412,\n    -412,  -412,  -412,  -412,  -412,  -412,  -412,  -412,  -412,  2616,\n    -412,  -412,  -412,  -412,  2616,  -412,  -412,  2616,  -412,  -412,\n    2616,  -412,  -412,  2616,  -412,  -412,  2616,  -412,  -412,  -412,\n    -412,     7,  1713,  2186,  2524,  2524,  2524,  -412,  -412,  2524,\n    2524,  2524,  -412,  2524,  2524,  2524,  2524,  2524,  2524,  2524,\n    2524,  2524,  2524,  2524,  2524,  2524,  2524,  2524,  2524,  -412,\n    2524,  2524,  2524,  2524,  -412,  -412,  2524,  2524,  2524,  2524,\n    2524,   -91,  -412,  2616,  -412,  2524,  2524,  2524,  -412,  -412,\n    -412,  -412,  -412,  2727,  2727,  -412,  -412,  2616,  2616,  2616,\n    2616,  2616,  2616,  2616,  2616,  2616,  2616,  2616,  2616,  2616,\n    2616,  2616,  2616,  2616,  2616,  2616,  2616,  2616,  2616,  2616,\n    2616,  2616,  2616,  2616,  2616,  2616,  2616,  2616,  2616,  -412,\n    2616,  2616,  2616,  -412,  -412\n  };\n\n  const short\n  seclang_parser::yydefact_[] =\n  {\n       0,     2,     0,   144,     0,    90,     0,    89,    93,    94,\n       7,     6,     0,    11,    14,    12,    13,    17,    18,     0,\n     127,   126,    95,     0,     0,   103,   104,   105,   106,   100,\n     128,   107,   108,   142,   141,   111,   112,   113,   129,   130,\n       0,   133,   131,     0,   132,     0,   134,     0,     0,   116,\n       0,     0,     0,    81,   156,   157,   158,     0,     0,   119,\n     121,   120,     0,     0,     0,     0,     0,     0,    27,    25,\n      26,     0,     0,   143,   152,   153,   154,   151,   155,   117,\n     118,   150,     0,     0,     0,     4,    75,     5,    99,    98,\n      15,    16,    92,    91,     9,    10,     8,    21,    20,    19,\n      97,    96,   102,   101,    86,    85,   135,   136,    88,    87,\n     137,   138,   115,   114,    84,    82,    83,     0,     0,   343,\n     344,   345,   346,   347,   348,   349,     0,   353,   354,   355,\n     356,     0,     0,     0,   367,   368,   369,   370,   371,   372,\n     373,   374,     0,   376,     0,   379,     0,   380,     0,   382,\n     383,   384,   385,   386,   387,   388,   389,     0,   391,   392,\n     393,   394,   395,   396,     0,     0,     0,     0,   402,   403,\n     404,   405,     0,   413,   414,   415,   416,   428,   434,   419,\n     420,   421,   432,   433,   440,   422,   418,   427,   439,   438,\n     411,   410,   409,   443,   442,   431,   429,   444,   430,   417,\n     412,   435,   436,   437,   423,   426,   425,   424,   441,   407,\n     408,     0,    78,    31,    33,    80,   110,   109,   139,   140,\n       0,     0,   170,   173,   176,   179,   182,   185,   188,   191,\n     194,   197,   200,   203,   206,   209,   212,   215,   218,   271,\n     260,   221,   257,   263,   272,   273,   230,   274,   275,   276,\n     277,   278,   279,   280,   281,   282,   283,   284,   285,   286,\n     287,   288,   289,   290,   291,   292,   293,   294,   295,   296,\n     297,   298,   299,   300,   301,   303,   302,   306,   305,   304,\n     307,   309,   308,   310,   266,   311,   312,   313,   315,   314,\n     234,   316,   317,   267,   270,   318,   319,   320,   321,   322,\n     323,   324,   325,   326,   329,   327,   328,   238,   242,   250,\n     254,   246,   224,   227,     0,   331,   330,   332,   333,   334,\n     335,   336,   337,   338,   339,   340,   341,   342,   122,   160,\n     165,   123,   124,   125,    23,    22,    24,    29,    28,   145,\n     146,   147,   148,   149,     0,   159,    79,     1,     3,     0,\n     446,   401,   366,   365,   364,   351,   350,   352,   358,   357,\n     361,   360,   359,   363,   362,   452,   453,   375,   377,   378,\n     381,   390,   397,   398,   399,   400,   406,     0,     0,   167,\n     166,   168,   169,   171,   172,   174,   175,   177,   178,   180,\n     181,   183,   184,   186,   187,   189,   190,   192,   193,   195,\n     196,   198,   199,   201,   202,   204,   205,   207,   208,   210,\n     211,   213,   214,   216,   217,   258,   259,   219,   220,   255,\n     256,   261,   262,   228,   229,   264,   265,   232,   233,   231,\n     268,   269,   236,   237,   235,   240,   241,   239,   248,   249,\n     247,   252,   253,   251,   244,   245,   243,   222,   223,   225,\n     226,     0,     0,     0,     0,     0,     0,    39,    40,     0,\n       0,     0,    74,     0,     0,     0,     0,     0,     0,     0,\n       0,     0,     0,     0,     0,     0,     0,     0,     0,    38,\n       0,     0,     0,     0,    41,    42,     0,     0,     0,     0,\n       0,    77,    34,    36,   445,     0,     0,     0,   450,   451,\n      30,    32,   161,     0,     0,   162,    35,    37,    73,    57,\n      56,    58,    59,    44,    60,    53,    61,    43,    62,    63,\n      64,    65,    66,    67,    68,    54,    69,    70,    71,    72,\n      45,    46,    47,    48,    49,    50,    51,    52,    55,    76,\n     447,   448,   449,   164,   163\n  };\n\n  const short\n  seclang_parser::yypgoto_[] =\n  {\n    -412,  -412,   -28,  -412,   -48,  -199,  -412,  -411,  -412,  -412,\n     -42,  -124,   -62,  -227,  -412,  -138\n  };\n\n  const short\n  seclang_parser::yydefgoto_[] =\n  {\n       0,    84,    85,    86,   212,   213,   491,   492,    87,   344,\n     328,   329,   366,   214,   351,   367\n  };\n\n  const short\n  seclang_parser::yytable_[] =\n  {\n     330,   330,   330,   218,   215,   381,   368,   382,   369,   378,\n     370,   117,   377,   452,   219,   378,   383,   333,   384,   371,\n     330,   331,   332,   341,   342,   343,   372,   373,   374,   375,\n     452,    94,    95,    97,   376,   346,    96,    98,   334,   335,\n     345,    99,   506,   336,   355,   356,   385,   114,   386,   357,\n     115,   116,   360,   361,   362,   350,   348,   118,   119,   120,\n     121,   122,   123,   124,   125,   126,   127,   128,   129,   130,\n     131,   132,   133,   134,   135,   136,   137,   138,   139,   140,\n     141,   142,   143,   144,   145,   146,   147,   148,   149,   150,\n     151,   152,   153,   154,   155,   156,   157,   158,   159,   160,\n     161,   162,   163,   164,   165,   166,   167,   168,   169,   170,\n     171,   172,   173,   174,   175,   176,   177,   178,   179,   180,\n     181,   182,   183,   184,   185,   186,   187,   188,   189,   190,\n     191,   192,   193,   194,   195,   196,   197,   198,   199,   200,\n     201,   202,   203,   204,   205,   206,   207,   208,   209,   210,\n     352,   501,   429,   353,   354,   495,   496,   497,   379,   380,\n     387,   389,   388,   390,   391,   393,   392,   394,     0,   434,\n     437,   440,   443,   446,   395,   397,   396,   398,   399,   401,\n     400,   402,   403,   405,   404,   406,   407,   409,   408,   410,\n     451,   411,   413,   412,   414,   415,   417,   416,   418,   419,\n     421,   420,   422,   423,     0,   424,   493,   425,   430,   426,\n     431,     0,   447,   449,   448,   450,    88,    89,    90,    91,\n      92,    93,   100,   101,   102,   103,   104,   105,   106,   107,\n     108,   109,   110,   111,   112,   113,   216,   217,   337,   338,\n     339,   340,     0,   211,   358,   359,   363,   364,     0,     0,\n       0,     0,   330,     0,     0,     0,     0,     0,     0,     0,\n       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,\n       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,\n       0,     0,     0,     0,     0,     0,     0,   494,     0,     0,\n       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,\n       0,     0,     0,     0,     0,   499,   499,   499,   499,   499,\n     499,   499,   499,   499,   499,   507,   508,   509,   510,     0,\n       0,   511,   512,   513,     0,   514,   515,   516,   517,   518,\n     519,   520,   521,   522,   523,   524,   525,   526,   527,   528,\n     529,   502,   530,   531,   532,   533,   500,     0,   534,   535,\n     536,   537,   538,     0,     0,     0,     0,   540,   541,   542,\n       0,     0,     0,     0,     0,     0,     0,   499,     0,     0,\n       0,     0,   499,     0,     0,   499,     0,     0,   499,     0,\n       0,   499,     0,     0,   499,     0,     0,     0,     0,     0,\n     505,     0,     0,     0,     0,     0,     0,     0,     0,     0,\n       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,\n       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,\n       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,\n       0,   499,     0,     0,     0,     0,     0,     0,     0,     0,\n       0,   543,   544,   539,     0,   499,   499,   499,   499,   499,\n     499,   499,   499,   499,   499,   499,   499,   499,   499,   499,\n     499,   499,   499,   499,   499,   499,   499,   499,   499,   499,\n     499,   499,   499,   499,   499,   499,   499,     0,   499,   499,\n     499,   222,   223,   224,   225,   226,   227,   228,   229,   230,\n     231,   232,   233,   234,   235,   236,   237,   238,   239,   240,\n     241,   242,   243,   244,   245,   246,   247,   248,   249,   250,\n     251,   252,   253,   254,   255,   256,   257,   258,   259,   260,\n     261,   262,   263,   264,   265,   266,   267,   268,   269,   270,\n     271,   272,   273,   274,   275,   276,   277,   278,   279,   280,\n     281,   282,   283,   284,   285,   286,   287,   288,   289,   290,\n     291,   292,   293,   294,   295,   296,   297,   298,   299,   300,\n     301,   302,   303,   304,   305,   306,   307,   308,   309,   310,\n     311,   312,   313,   222,   223,   224,   225,   226,   227,   228,\n     229,   230,   231,   232,   233,   234,   235,   236,   237,   238,\n     239,   240,   241,   242,   243,   244,   245,   246,   247,   248,\n     249,   250,   251,   252,   253,   254,   255,   256,   257,   258,\n     259,   260,   261,   262,   263,   264,   265,   266,   267,   268,\n     269,   270,   271,   272,   273,   274,   275,   276,   277,   278,\n     279,   280,   281,   282,   283,   284,   285,   286,   287,   288,\n     289,   290,   291,   292,   293,   294,   295,   296,   297,   298,\n     299,   300,   301,   302,   303,   304,   305,   306,   307,   308,\n     309,   310,   311,   312,   313,   222,   223,   224,   225,   226,\n     227,   228,   229,   230,   231,   232,   233,   234,   235,   236,\n     237,   238,   239,   240,   241,   242,   243,   244,   245,   246,\n     247,   248,   249,   250,   251,   252,   253,   254,   255,   256,\n     257,   258,   259,   260,   261,   262,   263,   264,   265,   266,\n     267,   268,   269,   270,   271,   272,   273,   274,   275,   276,\n     277,   278,   279,   280,   281,   282,   283,   284,   285,   286,\n     287,   288,   289,   290,   291,   292,   293,   294,   295,   296,\n     297,   298,   299,   300,   301,   302,   303,   304,   305,   306,\n     307,   308,   309,   310,   311,   312,   313,     0,     0,     0,\n       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,\n       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,\n       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,\n       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,\n       0,     0,     0,     0,   365,     0,   315,   316,   317,   318,\n     319,   320,   321,   322,   323,   324,   325,   326,   327,     0,\n     427,     0,   428,     0,     0,     0,     0,     0,     0,     0,\n       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,\n       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,\n       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,\n       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,\n       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,\n       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,\n       0,     0,     0,     0,     0,     0,   365,     0,   315,   316,\n     317,   318,   319,   320,   321,   322,   323,   324,   325,   326,\n     327,     0,   432,     0,   433,     0,     0,     0,     0,     0,\n       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,\n       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,\n       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,\n       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,\n       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,\n       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,\n       0,     0,     0,     0,     0,     0,     0,     0,   365,     0,\n     315,   316,   317,   318,   319,   320,   321,   322,   323,   324,\n     325,   326,   327,     0,   435,     0,   436,   222,   223,   224,\n     225,   226,   227,   228,   229,   230,   231,   232,   233,   234,\n     235,   236,   237,   238,   239,   240,   241,   242,   243,   244,\n     245,   246,   247,   248,   249,   250,   251,   252,   253,   254,\n     255,   256,   257,   258,   259,   260,   261,   262,   263,   264,\n     265,   266,   267,   268,   269,   270,   271,   272,   273,   274,\n     275,   276,   277,   278,   279,   280,   281,   282,   283,   284,\n     285,   286,   287,   288,   289,   290,   291,   292,   293,   294,\n     295,   296,   297,   298,   299,   300,   301,   302,   303,   304,\n     305,   306,   307,   308,   309,   310,   311,   312,   313,   222,\n     223,   224,   225,   226,   227,   228,   229,   230,   231,   232,\n     233,   234,   235,   236,   237,   238,   239,   240,   241,   242,\n     243,   244,   245,   246,   247,   248,   249,   250,   251,   252,\n     253,   254,   255,   256,   257,   258,   259,   260,   261,   262,\n     263,   264,   265,   266,   267,   268,   269,   270,   271,   272,\n     273,   274,   275,   276,   277,   278,   279,   280,   281,   282,\n     283,   284,   285,   286,   287,   288,   289,   290,   291,   292,\n     293,   294,   295,   296,   297,   298,   299,   300,   301,   302,\n     303,   304,   305,   306,   307,   308,   309,   310,   311,   312,\n     313,   222,   223,   224,   225,   226,   227,   228,   229,   230,\n     231,   232,   233,   234,   235,   236,   237,   238,   239,   240,\n     241,   242,   243,   244,   245,   246,   247,   248,   249,   250,\n     251,   252,   253,   254,   255,   256,   257,   258,   259,   260,\n     261,   262,   263,   264,   265,   266,   267,   268,   269,   270,\n     271,   272,   273,   274,   275,   276,   277,   278,   279,   280,\n     281,   282,   283,   284,   285,   286,   287,   288,   289,   290,\n     291,   292,   293,   294,   295,   296,   297,   298,   299,   300,\n     301,   302,   303,   304,   305,   306,   307,   308,   309,   310,\n     311,   312,   313,     0,     0,     0,     0,     0,     0,     0,\n       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,\n       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,\n       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,\n       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,\n     365,     0,   315,   316,   317,   318,   319,   320,   321,   322,\n     323,   324,   325,   326,   327,     0,   438,     0,   439,     0,\n       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,\n       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,\n       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,\n       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,\n       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,\n       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,\n       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,\n       0,     0,   365,     0,   315,   316,   317,   318,   319,   320,\n     321,   322,   323,   324,   325,   326,   327,     0,   441,     0,\n     442,     0,     0,     0,     0,     0,     0,     0,     0,     0,\n       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,\n       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,\n       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,\n       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,\n       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,\n       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,\n       0,     0,     0,     0,   365,     0,   315,   316,   317,   318,\n     319,   320,   321,   322,   323,   324,   325,   326,   327,     0,\n     444,     0,   445,   220,   221,   222,   223,   224,   225,   226,\n     227,   228,   229,   230,   231,   232,   233,   234,   235,   236,\n     237,   238,   239,   240,   241,   242,   243,   244,   245,   246,\n     247,   248,   249,   250,   251,   252,   253,   254,   255,   256,\n     257,   258,   259,   260,   261,   262,   263,   264,   265,   266,\n     267,   268,   269,   270,   271,   272,   273,   274,   275,   276,\n     277,   278,   279,   280,   281,   282,   283,   284,   285,   286,\n     287,   288,   289,   290,   291,   292,   293,   294,   295,   296,\n     297,   298,   299,   300,   301,   302,   303,   304,   305,   306,\n     307,   308,   309,   310,   311,   312,   313,   220,   221,   222,\n     223,   224,   225,   226,   227,   228,   229,   230,   231,   232,\n     233,   234,   235,   236,   237,   238,   239,   240,   241,   242,\n     243,   244,   245,   246,   247,   248,   249,   250,   251,   252,\n     253,   254,   255,   256,   257,   258,   259,   260,   261,   262,\n     263,   264,   265,   266,   267,   268,   269,   270,   271,   272,\n     273,   274,   275,   276,   277,   278,   279,   280,   281,   282,\n     283,   284,   285,   286,   287,   288,   289,   290,   291,   292,\n     293,   294,   295,   296,   297,   298,   299,   300,   301,   302,\n     303,   304,   305,   306,   307,   308,   309,   310,   311,   312,\n     313,   503,   504,   222,   223,   224,   225,   226,   227,   228,\n     229,   230,   231,   232,   233,   234,   235,   236,   237,   238,\n     239,   240,   241,   242,   243,   244,   245,   246,   247,   248,\n     249,   250,   251,   252,   253,   254,   255,   256,   257,   258,\n     259,   260,   261,   262,   263,   264,   265,   266,   267,   268,\n     269,   270,   271,   272,   273,   274,   275,   276,   277,   278,\n     279,   280,   281,   282,   283,   284,   285,   286,   287,   288,\n     289,   290,   291,   292,   293,   294,   295,   296,   297,   298,\n     299,   300,   301,   302,   303,   304,   305,   306,   307,   308,\n     309,   310,   311,   312,   313,     0,     0,     0,     0,     0,\n       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,\n       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,\n       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,\n       0,     0,     0,     0,     0,     0,     0,     0,     0,   314,\n     315,   316,   317,   318,   319,   320,   321,   322,   323,   324,\n     325,   326,   327,     0,     0,     0,     0,     0,     0,     0,\n       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,\n       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,\n       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,\n       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,\n       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,\n       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,\n       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,\n       0,     0,     0,     0,   315,   316,   317,   318,   319,   320,\n     321,   322,   323,   324,   325,   326,   327,     0,     0,     0,\n       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,\n       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,\n       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,\n       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,\n       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,\n       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,\n       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,\n       0,     0,     0,     0,     0,     0,     0,     0,   315,   316,\n     317,   318,   319,   320,   321,   322,   323,   324,   325,   326,\n     327,   222,   223,   224,   225,   226,   227,   228,   229,   230,\n     231,   232,   233,   234,   235,   236,   237,   238,   239,   240,\n     241,   242,   243,   244,   245,   246,   247,   248,   249,   250,\n     251,   252,   253,   254,   255,   256,   257,   258,   259,   260,\n     261,   262,   263,   264,   265,   266,   267,   268,   269,   270,\n     271,   272,   273,   274,   275,   276,   277,   278,   279,   280,\n     281,   282,   283,   284,   285,   286,   287,   288,   289,   290,\n     291,   292,   293,   294,   295,   296,   297,   298,   299,   300,\n     301,   302,   303,   304,   305,   306,   307,   308,   309,   310,\n     311,   312,   313,     0,     0,     0,     0,   453,   454,   455,\n     456,   457,   458,   459,   460,   461,   462,   463,   464,   465,\n     466,   467,   468,   469,   470,   471,   472,   473,   474,     0,\n     475,   476,   477,   478,   479,   480,   481,   482,   483,   484,\n     485,   486,   487,   488,   489,   490,   222,   223,   224,   225,\n     226,   227,   228,   229,   230,   231,   232,   233,   234,   235,\n     236,   237,   238,   239,   240,   241,   242,   243,   244,   245,\n     246,   247,   248,   249,   250,   251,   252,   253,   254,   255,\n     256,   257,   258,   259,   260,   261,   262,   263,   264,   265,\n     266,   267,   268,   269,   270,   271,   272,   273,   274,   275,\n     276,   277,   278,   279,   280,   281,   282,   283,   284,   285,\n     286,   287,   288,   289,   290,   291,   292,   293,   294,   295,\n     296,   297,   298,   299,   300,   301,   302,   303,   304,   305,\n     306,   307,   308,   309,   310,   311,   312,   313,     0,     0,\n       0,     0,     0,   454,   455,   456,   457,   458,   459,   460,\n     461,   462,   463,   464,   465,   466,   467,   468,   469,   470,\n     471,   472,   473,   474,     0,   475,   476,   477,   478,   479,\n     480,   481,   482,   483,   484,   485,   486,   487,   488,   489,\n     490,     0,     0,     0,     0,     0,     0,     0,     0,     0,\n       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,\n       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,\n       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,\n       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,\n       0,     0,     0,     0,   365,     0,   315,   316,   317,   318,\n     319,   320,   321,   322,   323,   324,   325,   326,   327,   222,\n     223,   224,   225,   226,   227,   228,   229,   230,   231,   232,\n     233,   234,   235,   236,   237,   238,   239,   240,   241,   242,\n     243,   244,   245,   246,   247,   248,   249,   250,   251,   252,\n     253,   254,   255,   256,   257,   258,   259,   260,   261,   262,\n     263,   264,   265,   266,   267,   268,   269,   270,   271,   272,\n     273,   274,   275,   276,   277,   278,   279,   280,   281,   282,\n     283,   284,   285,   286,   287,   288,   289,   290,   291,   292,\n     293,   294,   295,   296,   297,   298,   299,   300,   301,   302,\n     303,   304,   305,   306,   307,   308,   309,   310,   311,   312,\n     313,     0,     0,     0,     0,   349,     0,     0,     0,     0,\n       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,\n       0,     0,     0,     0,     0,     0,     0,     0,     0,   365,\n       0,   315,   316,   317,   318,   319,   320,   321,   322,   323,\n     324,   325,   326,   327,   222,   223,   224,   225,   226,   227,\n     228,   229,   230,   231,   232,   233,   234,   235,   236,   237,\n     238,   239,   240,   241,   242,   243,   244,   245,   246,   247,\n     248,   249,   250,   251,   252,   253,   254,   255,   256,   257,\n     258,   259,   260,   261,   262,   263,   264,   265,   266,   267,\n     268,   269,   270,   271,   272,   273,   274,   275,   276,   277,\n     278,   279,   280,   281,   282,   283,   284,   285,   286,   287,\n     288,   289,   290,   291,   292,   293,   294,   295,   296,   297,\n     298,   299,   300,   301,   302,   303,   304,   305,   306,   307,\n     308,   309,   310,   311,   312,   313,   222,   223,   224,   225,\n     226,   227,   228,   229,   230,   231,   232,   233,   234,   235,\n     236,   237,   238,   239,   240,   241,   242,   243,   244,   245,\n     246,   247,   248,   249,   250,   251,   252,   253,   254,   255,\n     256,   257,   258,   259,   260,   261,   262,   263,   264,   265,\n     266,   267,   268,   269,   270,   271,   272,   273,   274,   275,\n     276,   277,   278,   279,   280,   281,   282,   283,   284,   285,\n     286,   287,   288,   289,   290,   291,   292,   293,   294,   295,\n     296,   297,   298,   299,   300,   301,   302,   303,   304,   305,\n     306,   307,   308,   309,   310,   311,   312,   313,     0,     0,\n       0,     0,     0,     0,   315,   316,   317,   318,   319,   320,\n     321,   322,   323,   324,   325,   326,   327,   222,   223,   224,\n     225,   226,   227,   228,   229,   230,   231,   232,   233,   234,\n     235,   236,   237,   238,   239,   240,   241,   242,   243,   244,\n     245,   246,   247,   248,   249,   250,   251,   252,   253,   254,\n     255,   256,   257,   258,   259,   260,   261,   262,   263,   264,\n     265,   266,   267,   268,   269,   270,   271,   272,   273,   274,\n     275,   276,   277,   278,   279,   280,   281,   282,   283,   284,\n     285,   286,   287,   288,   289,   290,   291,   292,   293,   294,\n     295,   296,   297,   298,   299,   300,   301,   302,   303,   304,\n     305,   306,   307,   308,   309,   310,   311,   312,   313,     0,\n       0,     0,     0,     0,     1,     0,     0,     0,     2,     3,\n       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,\n       0,     0,     0,     0,     0,     0,     0,   365,     0,   315,\n     316,   317,   318,   319,   320,   321,   322,   323,   324,   325,\n     326,   327,     0,     0,     0,     0,     0,     0,     0,     0,\n       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,\n       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,\n       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,\n       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,\n       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,\n       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,\n       0,     0,     0,     0,     0,     0,     0,     0,     0,   498,\n       0,   315,   316,   317,   318,   319,   320,   321,   322,   323,\n     324,   325,   326,   327,     0,     0,     0,     0,     0,     0,\n       0,     0,     0,     0,     0,     0,     0,     0,     0,     4,\n     347,     0,     0,     0,     2,     3,     0,     0,     0,     0,\n       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,\n       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,\n       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,\n       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,\n       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,\n       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,\n       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,\n       0,     0,   315,   316,   317,   318,   319,   320,   321,   322,\n     323,   324,   325,   326,   327,     5,     6,     7,     8,     9,\n      10,    11,    12,    13,    14,    15,    16,    17,    18,    19,\n      20,    21,    22,    23,    24,    25,    26,    27,    28,    29,\n      30,    31,    32,    33,    34,    35,    36,    37,    38,    39,\n      40,    41,    42,    43,    44,    45,    46,    47,    48,    49,\n      50,    51,    52,    53,    54,     4,    55,    56,    57,    58,\n      59,    60,    61,    62,    63,    64,    65,    66,    67,    68,\n      69,    70,     0,     0,     0,     0,     0,     0,     0,     0,\n       0,     0,     0,     0,    71,    72,    73,    74,    75,    76,\n      77,    78,    79,    80,    81,    82,    83,     0,     0,     0,\n       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,\n       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,\n       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,\n       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,\n       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,\n       0,     5,     6,     7,     8,     9,    10,    11,    12,    13,\n      14,    15,    16,    17,    18,    19,    20,    21,    22,    23,\n      24,    25,    26,    27,    28,    29,    30,    31,    32,    33,\n      34,    35,    36,    37,    38,    39,    40,    41,    42,    43,\n      44,    45,    46,    47,    48,    49,    50,    51,    52,    53,\n      54,   117,    55,    56,    57,    58,    59,    60,    61,    62,\n      63,    64,    65,    66,    67,    68,    69,    70,     0,     0,\n       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,\n      71,    72,    73,    74,    75,    76,    77,    78,    79,    80,\n      81,    82,    83,     0,     0,     0,     0,   118,   119,   120,\n     121,   122,   123,   124,   125,   126,   127,   128,   129,   130,\n     131,   132,   133,   134,   135,   136,   137,   138,   139,   140,\n     141,   142,   143,   144,   145,   146,   147,   148,   149,   150,\n     151,   152,   153,   154,   155,   156,   157,   158,   159,   160,\n     161,   162,   163,   164,   165,   166,   167,   168,   169,   170,\n     171,   172,   173,   174,   175,   176,   177,   178,   179,   180,\n     181,   182,   183,   184,   185,   186,   187,   188,   189,   190,\n     191,   192,   193,   194,   195,   196,   197,   198,   199,   200,\n     201,   202,   203,   204,   205,   206,   207,   208,   209,   210\n  };\n\n  const short\n  seclang_parser::yycheck_[] =\n  {\n      62,    63,    64,   308,    52,   349,   144,   351,   146,     3,\n     148,   102,   211,     6,   319,     3,   349,    65,   351,   157,\n      82,    63,    64,   311,   312,   313,   164,   165,   166,   167,\n       6,   312,   313,   310,   172,    83,   317,   314,   312,   313,\n      82,   318,   453,   317,   312,   313,   349,   309,   351,   317,\n     312,   313,   311,   312,   313,   117,    84,   148,   149,   150,\n     151,   152,   153,   154,   155,   156,   157,   158,   159,   160,\n     161,   162,   163,   164,   165,   166,   167,   168,   169,   170,\n     171,   172,   173,   174,   175,   176,   177,   178,   179,   180,\n     181,   182,   183,   184,   185,   186,   187,   188,   189,   190,\n     191,   192,   193,   194,   195,   196,   197,   198,   199,   200,\n     201,   202,   203,   204,   205,   206,   207,   208,   209,   210,\n     211,   212,   213,   214,   215,   216,   217,   218,   219,   220,\n     221,   222,   223,   224,   225,   226,   227,   228,   229,   230,\n     231,   232,   233,   234,   235,   236,   237,   238,   239,   240,\n     309,   378,   290,   312,   313,   103,   104,   105,   220,   221,\n     349,   349,   351,   351,   349,   349,   351,   351,    -1,   307,\n     308,   309,   310,   311,   349,   349,   351,   351,   349,   349,\n     351,   351,   349,   349,   351,   351,   349,   349,   351,   351,\n     314,   349,   349,   351,   351,   349,   349,   351,   351,   349,\n     349,   351,   351,   349,    -1,   351,   344,   349,   349,   351,\n     351,    -1,   349,   349,   351,   351,   312,   313,   146,   147,\n     312,   313,   312,   313,   312,   313,   312,   313,   315,   316,\n     312,   313,   315,   316,   312,   313,   312,   313,   312,   313,\n     312,   313,    -1,   334,   312,   313,   312,   313,    -1,    -1,\n      -1,    -1,   314,    -1,    -1,    -1,    -1,    -1,    -1,    -1,\n      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,\n      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,\n      -1,    -1,    -1,    -1,    -1,    -1,    -1,   349,    -1,    -1,\n      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,\n      -1,    -1,    -1,    -1,    -1,   367,   368,   369,   370,   371,\n     372,   373,   374,   375,   376,   453,   454,   455,   456,    -1,\n      -1,   459,   460,   461,    -1,   463,   464,   465,   466,   467,\n     468,   469,   470,   471,   472,   473,   474,   475,   476,   477,\n     478,   334,   480,   481,   482,   483,   334,    -1,   486,   487,\n     488,   489,   490,    -1,    -1,    -1,    -1,   495,   496,   497,\n      -1,    -1,    -1,    -1,    -1,    -1,    -1,   429,    -1,    -1,\n      -1,    -1,   434,    -1,    -1,   437,    -1,    -1,   440,    -1,\n      -1,   443,    -1,    -1,   446,    -1,    -1,    -1,    -1,    -1,\n     452,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,\n      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,\n      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,\n      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,\n      -1,   493,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,\n      -1,   503,   504,   491,    -1,   507,   508,   509,   510,   511,\n     512,   513,   514,   515,   516,   517,   518,   519,   520,   521,\n     522,   523,   524,   525,   526,   527,   528,   529,   530,   531,\n     532,   533,   534,   535,   536,   537,   538,    -1,   540,   541,\n     542,    10,    11,    12,    13,    14,    15,    16,    17,    18,\n      19,    20,    21,    22,    23,    24,    25,    26,    27,    28,\n      29,    30,    31,    32,    33,    34,    35,    36,    37,    38,\n      39,    40,    41,    42,    43,    44,    45,    46,    47,    48,\n      49,    50,    51,    52,    53,    54,    55,    56,    57,    58,\n      59,    60,    61,    62,    63,    64,    65,    66,    67,    68,\n      69,    70,    71,    72,    73,    74,    75,    76,    77,    78,\n      79,    80,    81,    82,    83,    84,    85,    86,    87,    88,\n      89,    90,    91,    92,    93,    94,    95,    96,    97,    98,\n      99,   100,   101,    10,    11,    12,    13,    14,    15,    16,\n      17,    18,    19,    20,    21,    22,    23,    24,    25,    26,\n      27,    28,    29,    30,    31,    32,    33,    34,    35,    36,\n      37,    38,    39,    40,    41,    42,    43,    44,    45,    46,\n      47,    48,    49,    50,    51,    52,    53,    54,    55,    56,\n      57,    58,    59,    60,    61,    62,    63,    64,    65,    66,\n      67,    68,    69,    70,    71,    72,    73,    74,    75,    76,\n      77,    78,    79,    80,    81,    82,    83,    84,    85,    86,\n      87,    88,    89,    90,    91,    92,    93,    94,    95,    96,\n      97,    98,    99,   100,   101,    10,    11,    12,    13,    14,\n      15,    16,    17,    18,    19,    20,    21,    22,    23,    24,\n      25,    26,    27,    28,    29,    30,    31,    32,    33,    34,\n      35,    36,    37,    38,    39,    40,    41,    42,    43,    44,\n      45,    46,    47,    48,    49,    50,    51,    52,    53,    54,\n      55,    56,    57,    58,    59,    60,    61,    62,    63,    64,\n      65,    66,    67,    68,    69,    70,    71,    72,    73,    74,\n      75,    76,    77,    78,    79,    80,    81,    82,    83,    84,\n      85,    86,    87,    88,    89,    90,    91,    92,    93,    94,\n      95,    96,    97,    98,    99,   100,   101,    -1,    -1,    -1,\n      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,\n      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,\n      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,\n      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,\n      -1,    -1,    -1,    -1,   333,    -1,   335,   336,   337,   338,\n     339,   340,   341,   342,   343,   344,   345,   346,   347,    -1,\n     349,    -1,   351,    -1,    -1,    -1,    -1,    -1,    -1,    -1,\n      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,\n      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,\n      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,\n      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,\n      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,\n      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,\n      -1,    -1,    -1,    -1,    -1,    -1,   333,    -1,   335,   336,\n     337,   338,   339,   340,   341,   342,   343,   344,   345,   346,\n     347,    -1,   349,    -1,   351,    -1,    -1,    -1,    -1,    -1,\n      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,\n      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,\n      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,\n      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,\n      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,\n      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,\n      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,   333,    -1,\n     335,   336,   337,   338,   339,   340,   341,   342,   343,   344,\n     345,   346,   347,    -1,   349,    -1,   351,    10,    11,    12,\n      13,    14,    15,    16,    17,    18,    19,    20,    21,    22,\n      23,    24,    25,    26,    27,    28,    29,    30,    31,    32,\n      33,    34,    35,    36,    37,    38,    39,    40,    41,    42,\n      43,    44,    45,    46,    47,    48,    49,    50,    51,    52,\n      53,    54,    55,    56,    57,    58,    59,    60,    61,    62,\n      63,    64,    65,    66,    67,    68,    69,    70,    71,    72,\n      73,    74,    75,    76,    77,    78,    79,    80,    81,    82,\n      83,    84,    85,    86,    87,    88,    89,    90,    91,    92,\n      93,    94,    95,    96,    97,    98,    99,   100,   101,    10,\n      11,    12,    13,    14,    15,    16,    17,    18,    19,    20,\n      21,    22,    23,    24,    25,    26,    27,    28,    29,    30,\n      31,    32,    33,    34,    35,    36,    37,    38,    39,    40,\n      41,    42,    43,    44,    45,    46,    47,    48,    49,    50,\n      51,    52,    53,    54,    55,    56,    57,    58,    59,    60,\n      61,    62,    63,    64,    65,    66,    67,    68,    69,    70,\n      71,    72,    73,    74,    75,    76,    77,    78,    79,    80,\n      81,    82,    83,    84,    85,    86,    87,    88,    89,    90,\n      91,    92,    93,    94,    95,    96,    97,    98,    99,   100,\n     101,    10,    11,    12,    13,    14,    15,    16,    17,    18,\n      19,    20,    21,    22,    23,    24,    25,    26,    27,    28,\n      29,    30,    31,    32,    33,    34,    35,    36,    37,    38,\n      39,    40,    41,    42,    43,    44,    45,    46,    47,    48,\n      49,    50,    51,    52,    53,    54,    55,    56,    57,    58,\n      59,    60,    61,    62,    63,    64,    65,    66,    67,    68,\n      69,    70,    71,    72,    73,    74,    75,    76,    77,    78,\n      79,    80,    81,    82,    83,    84,    85,    86,    87,    88,\n      89,    90,    91,    92,    93,    94,    95,    96,    97,    98,\n      99,   100,   101,    -1,    -1,    -1,    -1,    -1,    -1,    -1,\n      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,\n      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,\n      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,\n      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,\n     333,    -1,   335,   336,   337,   338,   339,   340,   341,   342,\n     343,   344,   345,   346,   347,    -1,   349,    -1,   351,    -1,\n      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,\n      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,\n      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,\n      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,\n      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,\n      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,\n      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,\n      -1,    -1,   333,    -1,   335,   336,   337,   338,   339,   340,\n     341,   342,   343,   344,   345,   346,   347,    -1,   349,    -1,\n     351,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,\n      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,\n      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,\n      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,\n      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,\n      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,\n      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,\n      -1,    -1,    -1,    -1,   333,    -1,   335,   336,   337,   338,\n     339,   340,   341,   342,   343,   344,   345,   346,   347,    -1,\n     349,    -1,   351,     8,     9,    10,    11,    12,    13,    14,\n      15,    16,    17,    18,    19,    20,    21,    22,    23,    24,\n      25,    26,    27,    28,    29,    30,    31,    32,    33,    34,\n      35,    36,    37,    38,    39,    40,    41,    42,    43,    44,\n      45,    46,    47,    48,    49,    50,    51,    52,    53,    54,\n      55,    56,    57,    58,    59,    60,    61,    62,    63,    64,\n      65,    66,    67,    68,    69,    70,    71,    72,    73,    74,\n      75,    76,    77,    78,    79,    80,    81,    82,    83,    84,\n      85,    86,    87,    88,    89,    90,    91,    92,    93,    94,\n      95,    96,    97,    98,    99,   100,   101,     8,     9,    10,\n      11,    12,    13,    14,    15,    16,    17,    18,    19,    20,\n      21,    22,    23,    24,    25,    26,    27,    28,    29,    30,\n      31,    32,    33,    34,    35,    36,    37,    38,    39,    40,\n      41,    42,    43,    44,    45,    46,    47,    48,    49,    50,\n      51,    52,    53,    54,    55,    56,    57,    58,    59,    60,\n      61,    62,    63,    64,    65,    66,    67,    68,    69,    70,\n      71,    72,    73,    74,    75,    76,    77,    78,    79,    80,\n      81,    82,    83,    84,    85,    86,    87,    88,    89,    90,\n      91,    92,    93,    94,    95,    96,    97,    98,    99,   100,\n     101,     8,     9,    10,    11,    12,    13,    14,    15,    16,\n      17,    18,    19,    20,    21,    22,    23,    24,    25,    26,\n      27,    28,    29,    30,    31,    32,    33,    34,    35,    36,\n      37,    38,    39,    40,    41,    42,    43,    44,    45,    46,\n      47,    48,    49,    50,    51,    52,    53,    54,    55,    56,\n      57,    58,    59,    60,    61,    62,    63,    64,    65,    66,\n      67,    68,    69,    70,    71,    72,    73,    74,    75,    76,\n      77,    78,    79,    80,    81,    82,    83,    84,    85,    86,\n      87,    88,    89,    90,    91,    92,    93,    94,    95,    96,\n      97,    98,    99,   100,   101,    -1,    -1,    -1,    -1,    -1,\n      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,\n      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,\n      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,\n      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,   334,\n     335,   336,   337,   338,   339,   340,   341,   342,   343,   344,\n     345,   346,   347,    -1,    -1,    -1,    -1,    -1,    -1,    -1,\n      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,\n      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,\n      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,\n      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,\n      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,\n      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,\n      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,\n      -1,    -1,    -1,    -1,   335,   336,   337,   338,   339,   340,\n     341,   342,   343,   344,   345,   346,   347,    -1,    -1,    -1,\n      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,\n      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,\n      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,\n      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,\n      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,\n      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,\n      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,\n      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,   335,   336,\n     337,   338,   339,   340,   341,   342,   343,   344,   345,   346,\n     347,    10,    11,    12,    13,    14,    15,    16,    17,    18,\n      19,    20,    21,    22,    23,    24,    25,    26,    27,    28,\n      29,    30,    31,    32,    33,    34,    35,    36,    37,    38,\n      39,    40,    41,    42,    43,    44,    45,    46,    47,    48,\n      49,    50,    51,    52,    53,    54,    55,    56,    57,    58,\n      59,    60,    61,    62,    63,    64,    65,    66,    67,    68,\n      69,    70,    71,    72,    73,    74,    75,    76,    77,    78,\n      79,    80,    81,    82,    83,    84,    85,    86,    87,    88,\n      89,    90,    91,    92,    93,    94,    95,    96,    97,    98,\n      99,   100,   101,    -1,    -1,    -1,    -1,   106,   107,   108,\n     109,   110,   111,   112,   113,   114,   115,   116,   117,   118,\n     119,   120,   121,   122,   123,   124,   125,   126,   127,    -1,\n     129,   130,   131,   132,   133,   134,   135,   136,   137,   138,\n     139,   140,   141,   142,   143,   144,    10,    11,    12,    13,\n      14,    15,    16,    17,    18,    19,    20,    21,    22,    23,\n      24,    25,    26,    27,    28,    29,    30,    31,    32,    33,\n      34,    35,    36,    37,    38,    39,    40,    41,    42,    43,\n      44,    45,    46,    47,    48,    49,    50,    51,    52,    53,\n      54,    55,    56,    57,    58,    59,    60,    61,    62,    63,\n      64,    65,    66,    67,    68,    69,    70,    71,    72,    73,\n      74,    75,    76,    77,    78,    79,    80,    81,    82,    83,\n      84,    85,    86,    87,    88,    89,    90,    91,    92,    93,\n      94,    95,    96,    97,    98,    99,   100,   101,    -1,    -1,\n      -1,    -1,    -1,   107,   108,   109,   110,   111,   112,   113,\n     114,   115,   116,   117,   118,   119,   120,   121,   122,   123,\n     124,   125,   126,   127,    -1,   129,   130,   131,   132,   133,\n     134,   135,   136,   137,   138,   139,   140,   141,   142,   143,\n     144,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,\n      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,\n      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,\n      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,\n      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,\n      -1,    -1,    -1,    -1,   333,    -1,   335,   336,   337,   338,\n     339,   340,   341,   342,   343,   344,   345,   346,   347,    10,\n      11,    12,    13,    14,    15,    16,    17,    18,    19,    20,\n      21,    22,    23,    24,    25,    26,    27,    28,    29,    30,\n      31,    32,    33,    34,    35,    36,    37,    38,    39,    40,\n      41,    42,    43,    44,    45,    46,    47,    48,    49,    50,\n      51,    52,    53,    54,    55,    56,    57,    58,    59,    60,\n      61,    62,    63,    64,    65,    66,    67,    68,    69,    70,\n      71,    72,    73,    74,    75,    76,    77,    78,    79,    80,\n      81,    82,    83,    84,    85,    86,    87,    88,    89,    90,\n      91,    92,    93,    94,    95,    96,    97,    98,    99,   100,\n     101,    -1,    -1,    -1,    -1,   106,    -1,    -1,    -1,    -1,\n      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,\n      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,   333,\n      -1,   335,   336,   337,   338,   339,   340,   341,   342,   343,\n     344,   345,   346,   347,    10,    11,    12,    13,    14,    15,\n      16,    17,    18,    19,    20,    21,    22,    23,    24,    25,\n      26,    27,    28,    29,    30,    31,    32,    33,    34,    35,\n      36,    37,    38,    39,    40,    41,    42,    43,    44,    45,\n      46,    47,    48,    49,    50,    51,    52,    53,    54,    55,\n      56,    57,    58,    59,    60,    61,    62,    63,    64,    65,\n      66,    67,    68,    69,    70,    71,    72,    73,    74,    75,\n      76,    77,    78,    79,    80,    81,    82,    83,    84,    85,\n      86,    87,    88,    89,    90,    91,    92,    93,    94,    95,\n      96,    97,    98,    99,   100,   101,    10,    11,    12,    13,\n      14,    15,    16,    17,    18,    19,    20,    21,    22,    23,\n      24,    25,    26,    27,    28,    29,    30,    31,    32,    33,\n      34,    35,    36,    37,    38,    39,    40,    41,    42,    43,\n      44,    45,    46,    47,    48,    49,    50,    51,    52,    53,\n      54,    55,    56,    57,    58,    59,    60,    61,    62,    63,\n      64,    65,    66,    67,    68,    69,    70,    71,    72,    73,\n      74,    75,    76,    77,    78,    79,    80,    81,    82,    83,\n      84,    85,    86,    87,    88,    89,    90,    91,    92,    93,\n      94,    95,    96,    97,    98,    99,   100,   101,    -1,    -1,\n      -1,    -1,    -1,    -1,   335,   336,   337,   338,   339,   340,\n     341,   342,   343,   344,   345,   346,   347,    10,    11,    12,\n      13,    14,    15,    16,    17,    18,    19,    20,    21,    22,\n      23,    24,    25,    26,    27,    28,    29,    30,    31,    32,\n      33,    34,    35,    36,    37,    38,    39,    40,    41,    42,\n      43,    44,    45,    46,    47,    48,    49,    50,    51,    52,\n      53,    54,    55,    56,    57,    58,    59,    60,    61,    62,\n      63,    64,    65,    66,    67,    68,    69,    70,    71,    72,\n      73,    74,    75,    76,    77,    78,    79,    80,    81,    82,\n      83,    84,    85,    86,    87,    88,    89,    90,    91,    92,\n      93,    94,    95,    96,    97,    98,    99,   100,   101,    -1,\n      -1,    -1,    -1,    -1,     0,    -1,    -1,    -1,     4,     5,\n      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,\n      -1,    -1,    -1,    -1,    -1,    -1,    -1,   333,    -1,   335,\n     336,   337,   338,   339,   340,   341,   342,   343,   344,   345,\n     346,   347,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,\n      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,\n      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,\n      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,\n      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,\n      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,\n      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,\n      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,   333,\n      -1,   335,   336,   337,   338,   339,   340,   341,   342,   343,\n     344,   345,   346,   347,    -1,    -1,    -1,    -1,    -1,    -1,\n      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,   145,\n       0,    -1,    -1,    -1,     4,     5,    -1,    -1,    -1,    -1,\n      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,\n      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,\n      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,\n      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,\n      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,\n      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,\n      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,\n      -1,    -1,   335,   336,   337,   338,   339,   340,   341,   342,\n     343,   344,   345,   346,   347,   241,   242,   243,   244,   245,\n     246,   247,   248,   249,   250,   251,   252,   253,   254,   255,\n     256,   257,   258,   259,   260,   261,   262,   263,   264,   265,\n     266,   267,   268,   269,   270,   271,   272,   273,   274,   275,\n     276,   277,   278,   279,   280,   281,   282,   283,   284,   285,\n     286,   287,   288,   289,   290,   145,   292,   293,   294,   295,\n     296,   297,   298,   299,   300,   301,   302,   303,   304,   305,\n     306,   307,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,\n      -1,    -1,    -1,    -1,   320,   321,   322,   323,   324,   325,\n     326,   327,   328,   329,   330,   331,   332,    -1,    -1,    -1,\n      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,\n      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,\n      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,\n      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,\n      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,\n      -1,   241,   242,   243,   244,   245,   246,   247,   248,   249,\n     250,   251,   252,   253,   254,   255,   256,   257,   258,   259,\n     260,   261,   262,   263,   264,   265,   266,   267,   268,   269,\n     270,   271,   272,   273,   274,   275,   276,   277,   278,   279,\n     280,   281,   282,   283,   284,   285,   286,   287,   288,   289,\n     290,   102,   292,   293,   294,   295,   296,   297,   298,   299,\n     300,   301,   302,   303,   304,   305,   306,   307,    -1,    -1,\n      -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,\n     320,   321,   322,   323,   324,   325,   326,   327,   328,   329,\n     330,   331,   332,    -1,    -1,    -1,    -1,   148,   149,   150,\n     151,   152,   153,   154,   155,   156,   157,   158,   159,   160,\n     161,   162,   163,   164,   165,   166,   167,   168,   169,   170,\n     171,   172,   173,   174,   175,   176,   177,   178,   179,   180,\n     181,   182,   183,   184,   185,   186,   187,   188,   189,   190,\n     191,   192,   193,   194,   195,   196,   197,   198,   199,   200,\n     201,   202,   203,   204,   205,   206,   207,   208,   209,   210,\n     211,   212,   213,   214,   215,   216,   217,   218,   219,   220,\n     221,   222,   223,   224,   225,   226,   227,   228,   229,   230,\n     231,   232,   233,   234,   235,   236,   237,   238,   239,   240\n  };\n\n  const short\n  seclang_parser::yystos_[] =\n  {\n       0,     0,     4,     5,   145,   241,   242,   243,   244,   245,\n     246,   247,   248,   249,   250,   251,   252,   253,   254,   255,\n     256,   257,   258,   259,   260,   261,   262,   263,   264,   265,\n     266,   267,   268,   269,   270,   271,   272,   273,   274,   275,\n     276,   277,   278,   279,   280,   281,   282,   283,   284,   285,\n     286,   287,   288,   289,   290,   292,   293,   294,   295,   296,\n     297,   298,   299,   300,   301,   302,   303,   304,   305,   306,\n     307,   320,   321,   322,   323,   324,   325,   326,   327,   328,\n     329,   330,   331,   332,   353,   354,   355,   360,   312,   313,\n     146,   147,   312,   313,   312,   313,   317,   310,   314,   318,\n     312,   313,   312,   313,   312,   313,   315,   316,   312,   313,\n     315,   316,   312,   313,   309,   312,   313,   102,   148,   149,\n     150,   151,   152,   153,   154,   155,   156,   157,   158,   159,\n     160,   161,   162,   163,   164,   165,   166,   167,   168,   169,\n     170,   171,   172,   173,   174,   175,   176,   177,   178,   179,\n     180,   181,   182,   183,   184,   185,   186,   187,   188,   189,\n     190,   191,   192,   193,   194,   195,   196,   197,   198,   199,\n     200,   201,   202,   203,   204,   205,   206,   207,   208,   209,\n     210,   211,   212,   213,   214,   215,   216,   217,   218,   219,\n     220,   221,   222,   223,   224,   225,   226,   227,   228,   229,\n     230,   231,   232,   233,   234,   235,   236,   237,   238,   239,\n     240,   334,   356,   357,   365,   356,   312,   313,   308,   319,\n       8,     9,    10,    11,    12,    13,    14,    15,    16,    17,\n      18,    19,    20,    21,    22,    23,    24,    25,    26,    27,\n      28,    29,    30,    31,    32,    33,    34,    35,    36,    37,\n      38,    39,    40,    41,    42,    43,    44,    45,    46,    47,\n      48,    49,    50,    51,    52,    53,    54,    55,    56,    57,\n      58,    59,    60,    61,    62,    63,    64,    65,    66,    67,\n      68,    69,    70,    71,    72,    73,    74,    75,    76,    77,\n      78,    79,    80,    81,    82,    83,    84,    85,    86,    87,\n      88,    89,    90,    91,    92,    93,    94,    95,    96,    97,\n      98,    99,   100,   101,   334,   335,   336,   337,   338,   339,\n     340,   341,   342,   343,   344,   345,   346,   347,   362,   363,\n     364,   362,   362,   356,   312,   313,   317,   312,   313,   312,\n     313,   311,   312,   313,   361,   362,   356,     0,   354,   106,\n     364,   366,   309,   312,   313,   312,   313,   317,   312,   313,\n     311,   312,   313,   312,   313,   333,   364,   367,   367,   367,\n     367,   367,   367,   367,   367,   367,   367,   357,     3,   364,\n     364,   349,   351,   349,   351,   349,   351,   349,   351,   349,\n     351,   349,   351,   349,   351,   349,   351,   349,   351,   349,\n     351,   349,   351,   349,   351,   349,   351,   349,   351,   349,\n     351,   349,   351,   349,   351,   349,   351,   349,   351,   349,\n     351,   349,   351,   349,   351,   349,   351,   349,   351,   367,\n     349,   351,   349,   351,   367,   349,   351,   367,   349,   351,\n     367,   349,   351,   367,   349,   351,   367,   349,   351,   349,\n     351,   363,     6,   106,   107,   108,   109,   110,   111,   112,\n     113,   114,   115,   116,   117,   118,   119,   120,   121,   122,\n     123,   124,   125,   126,   127,   129,   130,   131,   132,   133,\n     134,   135,   136,   137,   138,   139,   140,   141,   142,   143,\n     144,   358,   359,   367,   364,   103,   104,   105,   333,   364,\n     334,   365,   334,     8,     9,   364,   359,   367,   367,   367,\n     367,   367,   367,   367,   367,   367,   367,   367,   367,   367,\n     367,   367,   367,   367,   367,   367,   367,   367,   367,   367,\n     367,   367,   367,   367,   367,   367,   367,   367,   367,   356,\n     367,   367,   367,   364,   364\n  };\n\n  const short\n  seclang_parser::yyr1_[] =\n  {\n       0,   352,   353,   353,   353,   354,   355,   355,   355,   355,\n     355,   355,   355,   355,   355,   355,   355,   355,   355,   355,\n     355,   355,   355,   355,   355,   355,   355,   355,   355,   355,\n     356,   356,   357,   357,   358,   358,   358,   358,   359,   359,\n     359,   359,   359,   359,   359,   359,   359,   359,   359,   359,\n     359,   359,   359,   359,   359,   359,   359,   359,   359,   359,\n     359,   359,   359,   359,   359,   359,   359,   359,   359,   359,\n     359,   359,   359,   359,   359,   360,   360,   360,   360,   360,\n     360,   360,   360,   360,   360,   360,   360,   360,   360,   360,\n     360,   360,   360,   360,   360,   360,   360,   360,   360,   360,\n     360,   360,   360,   360,   360,   360,   360,   360,   360,   360,\n     360,   360,   360,   360,   360,   360,   360,   360,   360,   360,\n     360,   360,   360,   360,   360,   360,   360,   360,   360,   360,\n     360,   360,   360,   360,   360,   360,   360,   360,   360,   360,\n     360,   360,   360,   360,   360,   360,   360,   360,   360,   360,\n     360,   360,   360,   360,   360,   360,   360,   360,   360,   361,\n     362,   362,   363,   363,   363,   363,   363,   363,   364,   364,\n     364,   364,   364,   364,   364,   364,   364,   364,   364,   364,\n     364,   364,   364,   364,   364,   364,   364,   364,   364,   364,\n     364,   364,   364,   364,   364,   364,   364,   364,   364,   364,\n     364,   364,   364,   364,   364,   364,   364,   364,   364,   364,\n     364,   364,   364,   364,   364,   364,   364,   364,   364,   364,\n     364,   364,   364,   364,   364,   364,   364,   364,   364,   364,\n     364,   364,   364,   364,   364,   364,   364,   364,   364,   364,\n     364,   364,   364,   364,   364,   364,   364,   364,   364,   364,\n     364,   364,   364,   364,   364,   364,   364,   364,   364,   364,\n     364,   364,   364,   364,   364,   364,   364,   364,   364,   364,\n     364,   364,   364,   364,   364,   364,   364,   364,   364,   364,\n     364,   364,   364,   364,   364,   364,   364,   364,   364,   364,\n     364,   364,   364,   364,   364,   364,   364,   364,   364,   364,\n     364,   364,   364,   364,   364,   364,   364,   364,   364,   364,\n     364,   364,   364,   364,   364,   364,   364,   364,   364,   364,\n     364,   364,   364,   364,   364,   364,   364,   364,   364,   364,\n     364,   364,   364,   364,   364,   364,   364,   364,   364,   364,\n     364,   364,   364,   365,   365,   365,   365,   365,   365,   365,\n     365,   365,   365,   365,   365,   365,   365,   365,   365,   365,\n     365,   365,   365,   365,   365,   365,   365,   365,   365,   365,\n     365,   365,   365,   365,   365,   365,   365,   365,   365,   365,\n     365,   365,   365,   365,   365,   365,   365,   365,   365,   365,\n     365,   365,   365,   365,   365,   365,   365,   365,   365,   365,\n     365,   365,   365,   365,   365,   365,   365,   365,   365,   365,\n     365,   365,   365,   365,   365,   365,   365,   365,   365,   365,\n     365,   365,   365,   365,   365,   365,   365,   365,   365,   365,\n     365,   365,   365,   365,   365,   365,   365,   365,   365,   365,\n     365,   365,   365,   365,   365,   366,   366,   366,   366,   366,\n     367,   367,   367,   367\n  };\n\n  const signed char\n  seclang_parser::yyr2_[] =\n  {\n       0,     2,     1,     2,     1,     1,     1,     1,     2,     2,\n       2,     1,     1,     1,     1,     2,     2,     1,     1,     2,\n       2,     2,     2,     2,     2,     1,     1,     1,     2,     2,\n       3,     1,     3,     1,     1,     2,     1,     2,     1,     1,\n       1,     1,     1,     2,     2,     2,     2,     2,     2,     2,\n       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\n       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\n       2,     2,     2,     2,     1,     1,     4,     3,     2,     2,\n       2,     1,     2,     2,     2,     2,     2,     2,     2,     1,\n       1,     2,     2,     1,     1,     1,     2,     2,     2,     2,\n       1,     2,     2,     1,     1,     1,     1,     1,     1,     2,\n       2,     1,     1,     1,     2,     2,     1,     1,     1,     1,\n       1,     1,     2,     2,     2,     2,     1,     1,     1,     1,\n       1,     1,     1,     1,     1,     2,     2,     2,     2,     2,\n       2,     1,     1,     1,     1,     2,     2,     2,     2,     2,\n       1,     1,     1,     1,     1,     1,     1,     1,     1,     1,\n       1,     3,     3,     4,     4,     1,     2,     2,     2,     2,\n       1,     2,     2,     1,     2,     2,     1,     2,     2,     1,\n       2,     2,     1,     2,     2,     1,     2,     2,     1,     2,\n       2,     1,     2,     2,     1,     2,     2,     1,     2,     2,\n       1,     2,     2,     1,     2,     2,     1,     2,     2,     1,\n       2,     2,     1,     2,     2,     1,     2,     2,     1,     2,\n       2,     1,     2,     2,     1,     2,     2,     1,     2,     2,\n       1,     2,     2,     2,     1,     2,     2,     2,     1,     2,\n       2,     2,     1,     2,     2,     2,     1,     2,     2,     2,\n       1,     2,     2,     2,     1,     2,     2,     1,     2,     2,\n       1,     2,     2,     1,     2,     2,     1,     1,     2,     2,\n       1,     1,     1,     1,     1,     1,     1,     1,     1,     1,\n       1,     1,     1,     1,     1,     1,     1,     1,     1,     1,\n       1,     1,     1,     1,     1,     1,     1,     1,     1,     1,\n       1,     1,     1,     1,     1,     1,     1,     1,     1,     1,\n       1,     1,     1,     1,     1,     1,     1,     1,     1,     1,\n       1,     1,     1,     1,     1,     1,     1,     1,     1,     1,\n       1,     1,     1,     1,     1,     1,     1,     1,     1,     1,\n       1,     1,     1,     1,     1,     1,     1,     1,     1,     1,\n       2,     2,     2,     1,     1,     1,     1,     2,     2,     2,\n       2,     2,     2,     2,     2,     2,     2,     1,     1,     1,\n       1,     1,     1,     1,     1,     2,     1,     2,     2,     1,\n       1,     2,     1,     1,     1,     1,     1,     1,     1,     1,\n       2,     1,     1,     1,     1,     1,     1,     2,     2,     2,\n       2,     2,     1,     1,     1,     1,     2,     1,     1,     1,\n       1,     1,     1,     1,     1,     1,     1,     1,     1,     1,\n       1,     1,     1,     1,     1,     1,     1,     1,     1,     1,\n       1,     1,     1,     1,     1,     1,     1,     1,     1,     1,\n       1,     1,     1,     1,     1,     2,     1,     3,     3,     3,\n       2,     2,     1,     1\n  };\n\n\n#if YYDEBUG || 1\n  // YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.\n  // First, the terminals, then, starting at \\a YYNTOKENS, nonterminals.\n  const char*\n  const seclang_parser::yytname_[] =\n  {\n  \"\\\"end of file\\\"\", \"error\", \"\\\"invalid token\\\"\", \"\\\",\\\"\",\n  \"\\\"CONFIG_CONTENT_INJECTION\\\"\", \"\\\"CONGIG_DIR_RESPONSE_BODY_MP_CLEAR\\\"\",\n  \"PIPE\", \"NEW_LINE\", \"VAR_COUNT\", \"VAR_EXCLUSION\", \"VARIABLE_ARGS\",\n  \"VARIABLE_ARGS_POST\", \"VARIABLE_ARGS_GET\", \"VARIABLE_FILES_SIZES\",\n  \"VARIABLE_FILES_NAMES\", \"VARIABLE_FILES_TMP_CONTENT\",\n  \"VARIABLE_MULTIPART_FILENAME\", \"VARIABLE_MULTIPART_NAME\",\n  \"VARIABLE_MATCHED_VARS_NAMES\", \"VARIABLE_MATCHED_VARS\", \"VARIABLE_FILES\",\n  \"VARIABLE_REQUEST_COOKIES\", \"VARIABLE_REQUEST_HEADERS\",\n  \"VARIABLE_RESPONSE_HEADERS\", \"VARIABLE_GEO\",\n  \"VARIABLE_REQUEST_COOKIES_NAMES\", \"VARIABLE_MULTIPART_PART_HEADERS\",\n  \"VARIABLE_ARGS_COMBINED_SIZE\", \"VARIABLE_ARGS_GET_NAMES\",\n  \"VARIABLE_RULE\", \"\\\"Variable ARGS_NAMES\\\"\", \"VARIABLE_ARGS_POST_NAMES\",\n  \"\\\"AUTH_TYPE\\\"\", \"\\\"FILES_COMBINED_SIZE\\\"\", \"\\\"FILES_TMPNAMES\\\"\",\n  \"\\\"FULL_REQUEST\\\"\", \"\\\"FULL_REQUEST_LENGTH\\\"\", \"\\\"INBOUND_DATA_ERROR\\\"\",\n  \"\\\"MATCHED_VAR\\\"\", \"\\\"MATCHED_VAR_NAME\\\"\", \"\\\"MSC_PCRE_ERROR\\\"\",\n  \"\\\"MSC_PCRE_LIMITS_EXCEEDED\\\"\", \"VARIABLE_MULTIPART_BOUNDARY_QUOTED\",\n  \"VARIABLE_MULTIPART_BOUNDARY_WHITESPACE\", \"\\\"MULTIPART_CRLF_LF_LINES\\\"\",\n  \"\\\"MULTIPART_DATA_AFTER\\\"\", \"VARIABLE_MULTIPART_DATA_BEFORE\",\n  \"\\\"MULTIPART_FILE_LIMIT_EXCEEDED\\\"\", \"\\\"MULTIPART_HEADER_FOLDING\\\"\",\n  \"\\\"MULTIPART_INVALID_HEADER_FOLDING\\\"\",\n  \"VARIABLE_MULTIPART_INVALID_PART\", \"\\\"MULTIPART_INVALID_QUOTING\\\"\",\n  \"VARIABLE_MULTIPART_LF_LINE\", \"VARIABLE_MULTIPART_MISSING_SEMICOLON\",\n  \"VARIABLE_MULTIPART_SEMICOLON_MISSING\", \"\\\"MULTIPART_STRICT_ERROR\\\"\",\n  \"\\\"MULTIPART_UNMATCHED_BOUNDARY\\\"\", \"\\\"OUTBOUND_DATA_ERROR\\\"\",\n  \"\\\"PATH_INFO\\\"\", \"\\\"QUERY_STRING\\\"\", \"\\\"REMOTE_ADDR\\\"\",\n  \"\\\"REMOTE_HOST\\\"\", \"\\\"REMOTE_PORT\\\"\", \"\\\"REQBODY_ERROR_MSG\\\"\",\n  \"\\\"REQBODY_ERROR\\\"\", \"\\\"REQBODY_PROCESSOR_ERROR_MSG\\\"\",\n  \"\\\"REQBODY_PROCESSOR_ERROR\\\"\", \"\\\"REQBODY_PROCESSOR\\\"\",\n  \"\\\"REQUEST_BASENAME\\\"\", \"\\\"REQUEST_BODY_LENGTH\\\"\", \"\\\"REQUEST_BODY\\\"\",\n  \"\\\"REQUEST_FILENAME\\\"\", \"VARIABLE_REQUEST_HEADERS_NAMES\",\n  \"\\\"REQUEST_LINE\\\"\", \"\\\"REQUEST_METHOD\\\"\", \"\\\"REQUEST_PROTOCOL\\\"\",\n  \"\\\"REQUEST_URI_RAW\\\"\", \"\\\"REQUEST_URI\\\"\", \"\\\"RESOURCE\\\"\",\n  \"\\\"RESPONSE_BODY\\\"\", \"\\\"RESPONSE_CONTENT_LENGTH\\\"\",\n  \"VARIABLE_RESPONSE_CONTENT_TYPE\", \"VARIABLE_RESPONSE_HEADERS_NAMES\",\n  \"\\\"RESPONSE_PROTOCOL\\\"\", \"\\\"RESPONSE_STATUS\\\"\", \"\\\"SERVER_ADDR\\\"\",\n  \"\\\"SERVER_NAME\\\"\", \"\\\"SERVER_PORT\\\"\", \"\\\"SESSIONID\\\"\", \"\\\"UNIQUE_ID\\\"\",\n  \"\\\"URLENCODED_ERROR\\\"\", \"\\\"USERID\\\"\", \"\\\"WEBAPPID\\\"\",\n  \"\\\"VARIABLE_STATUS\\\"\", \"\\\"VARIABLE_STATUS_LINE\\\"\", \"\\\"VARIABLE_IP\\\"\",\n  \"\\\"VARIABLE_GLOBAL\\\"\", \"\\\"VARIABLE_TX\\\"\", \"\\\"VARIABLE_SESSION\\\"\",\n  \"\\\"VARIABLE_USER\\\"\", \"\\\"RUN_TIME_VAR_ENV\\\"\", \"\\\"RUN_TIME_VAR_XML\\\"\",\n  \"\\\"SetVar\\\"\", \"SETVAR_OPERATION_EQUALS\", \"SETVAR_OPERATION_EQUALS_PLUS\",\n  \"SETVAR_OPERATION_EQUALS_MINUS\", \"\\\"NOT\\\"\", \"\\\"OPERATOR_BEGINS_WITH\\\"\",\n  \"\\\"OPERATOR_CONTAINS\\\"\", \"\\\"OPERATOR_CONTAINS_WORD\\\"\",\n  \"\\\"OPERATOR_DETECT_SQLI\\\"\", \"\\\"OPERATOR_DETECT_XSS\\\"\",\n  \"\\\"OPERATOR_ENDS_WITH\\\"\", \"\\\"OPERATOR_EQ\\\"\", \"\\\"OPERATOR_FUZZY_HASH\\\"\",\n  \"\\\"OPERATOR_GEOLOOKUP\\\"\", \"\\\"OPERATOR_GE\\\"\", \"\\\"OPERATOR_GSB_LOOKUP\\\"\",\n  \"\\\"OPERATOR_GT\\\"\", \"\\\"OPERATOR_INSPECT_FILE\\\"\",\n  \"\\\"OPERATOR_IP_MATCH_FROM_FILE\\\"\", \"\\\"OPERATOR_IP_MATCH\\\"\",\n  \"\\\"OPERATOR_LE\\\"\", \"\\\"OPERATOR_LT\\\"\", \"\\\"OPERATOR_PM_FROM_FILE\\\"\",\n  \"\\\"OPERATOR_PM\\\"\", \"\\\"OPERATOR_RBL\\\"\", \"\\\"OPERATOR_RSUB\\\"\",\n  \"\\\"Operator RX (content only)\\\"\", \"\\\"OPERATOR_RX\\\"\",\n  \"\\\"OPERATOR_RX_GLOBAL\\\"\", \"\\\"OPERATOR_STR_EQ\\\"\",\n  \"\\\"OPERATOR_STR_MATCH\\\"\", \"\\\"OPERATOR_UNCONDITIONAL_MATCH\\\"\",\n  \"\\\"OPERATOR_VALIDATE_BYTE_RANGE\\\"\", \"\\\"OPERATOR_VALIDATE_DTD\\\"\",\n  \"\\\"OPERATOR_VALIDATE_HASH\\\"\", \"\\\"OPERATOR_VALIDATE_SCHEMA\\\"\",\n  \"\\\"OPERATOR_VALIDATE_URL_ENCODING\\\"\",\n  \"\\\"OPERATOR_VALIDATE_UTF8_ENCODING\\\"\", \"\\\"OPERATOR_VERIFY_CC\\\"\",\n  \"\\\"OPERATOR_VERIFY_CPF\\\"\", \"\\\"OPERATOR_VERIFY_SSN\\\"\",\n  \"\\\"OPERATOR_VERIFY_SVNR\\\"\", \"\\\"OPERATOR_WITHIN\\\"\",\n  \"CONFIG_DIR_AUDIT_LOG_FMT\", \"JSON\", \"NATIVE\",\n  \"\\\"ACTION_CTL_RULE_ENGINE\\\"\", \"\\\"Accuracy\\\"\", \"\\\"Allow\\\"\", \"\\\"Append\\\"\",\n  \"\\\"AuditLog\\\"\", \"\\\"Block\\\"\", \"\\\"Capture\\\"\", \"\\\"Chain\\\"\",\n  \"\\\"ACTION_CTL_AUDIT_ENGINE\\\"\", \"\\\"ACTION_CTL_AUDIT_LOG_PARTS\\\"\",\n  \"\\\"ACTION_CTL_BDY_JSON\\\"\", \"\\\"ACTION_CTL_BDY_XML\\\"\",\n  \"\\\"ACTION_CTL_BDY_URLENCODED\\\"\", \"\\\"ACTION_CTL_FORCE_REQ_BODY_VAR\\\"\",\n  \"\\\"ACTION_CTL_PARSE_XML_INTO_ARGS\\\"\",\n  \"\\\"ACTION_CTL_REQUEST_BODY_ACCESS\\\"\", \"\\\"ACTION_CTL_RULE_REMOVE_BY_ID\\\"\",\n  \"\\\"ACTION_CTL_RULE_REMOVE_BY_TAG\\\"\",\n  \"\\\"ACTION_CTL_RULE_REMOVE_TARGET_BY_ID\\\"\",\n  \"\\\"ACTION_CTL_RULE_REMOVE_TARGET_BY_TAG\\\"\", \"\\\"Deny\\\"\",\n  \"\\\"DeprecateVar\\\"\", \"\\\"Drop\\\"\", \"\\\"Exec\\\"\", \"\\\"ExpireVar\\\"\", \"\\\"Id\\\"\",\n  \"\\\"InitCol\\\"\", \"\\\"Log\\\"\", \"\\\"LogData\\\"\", \"\\\"Maturity\\\"\", \"\\\"Msg\\\"\",\n  \"\\\"MultiMatch\\\"\", \"\\\"NoAuditLog\\\"\", \"\\\"NoLog\\\"\", \"\\\"Pass\\\"\", \"\\\"Pause\\\"\",\n  \"\\\"Phase\\\"\", \"\\\"Prepend\\\"\", \"\\\"Proxy\\\"\", \"\\\"Redirect\\\"\", \"\\\"Rev\\\"\",\n  \"\\\"SanitiseArg\\\"\", \"\\\"SanitiseMatched\\\"\", \"\\\"SanitiseMatchedBytes\\\"\",\n  \"\\\"SanitiseRequestHeader\\\"\", \"\\\"SanitiseResponseHeader\\\"\", \"\\\"SetEnv\\\"\",\n  \"\\\"SetRsc\\\"\", \"\\\"SetSid\\\"\", \"\\\"SetUID\\\"\", \"\\\"Severity\\\"\", \"\\\"Skip\\\"\",\n  \"\\\"SkipAfter\\\"\", \"\\\"Status\\\"\", \"\\\"Tag\\\"\",\n  \"\\\"ACTION_TRANSFORMATION_BASE_64_ENCODE\\\"\",\n  \"\\\"ACTION_TRANSFORMATION_BASE_64_DECODE\\\"\",\n  \"\\\"ACTION_TRANSFORMATION_BASE_64_DECODE_EXT\\\"\",\n  \"\\\"ACTION_TRANSFORMATION_CMD_LINE\\\"\",\n  \"\\\"ACTION_TRANSFORMATION_COMPRESS_WHITESPACE\\\"\",\n  \"\\\"ACTION_TRANSFORMATION_CSS_DECODE\\\"\",\n  \"\\\"ACTION_TRANSFORMATION_ESCAPE_SEQ_DECODE\\\"\",\n  \"\\\"ACTION_TRANSFORMATION_HEX_ENCODE\\\"\",\n  \"\\\"ACTION_TRANSFORMATION_HEX_DECODE\\\"\",\n  \"\\\"ACTION_TRANSFORMATION_HTML_ENTITY_DECODE\\\"\",\n  \"\\\"ACTION_TRANSFORMATION_JS_DECODE\\\"\",\n  \"\\\"ACTION_TRANSFORMATION_LENGTH\\\"\",\n  \"\\\"ACTION_TRANSFORMATION_LOWERCASE\\\"\", \"\\\"ACTION_TRANSFORMATION_MD5\\\"\",\n  \"\\\"ACTION_TRANSFORMATION_NONE\\\"\",\n  \"\\\"ACTION_TRANSFORMATION_NORMALISE_PATH\\\"\",\n  \"\\\"ACTION_TRANSFORMATION_NORMALISE_PATH_WIN\\\"\",\n  \"\\\"ACTION_TRANSFORMATION_PARITY_EVEN_7_BIT\\\"\",\n  \"\\\"ACTION_TRANSFORMATION_PARITY_ODD_7_BIT\\\"\",\n  \"\\\"ACTION_TRANSFORMATION_PARITY_ZERO_7_BIT\\\"\",\n  \"\\\"ACTION_TRANSFORMATION_REMOVE_COMMENTS\\\"\",\n  \"\\\"ACTION_TRANSFORMATION_REMOVE_COMMENTS_CHAR\\\"\",\n  \"\\\"ACTION_TRANSFORMATION_REMOVE_NULLS\\\"\",\n  \"\\\"ACTION_TRANSFORMATION_REMOVE_WHITESPACE\\\"\",\n  \"\\\"ACTION_TRANSFORMATION_REPLACE_COMMENTS\\\"\",\n  \"\\\"ACTION_TRANSFORMATION_REPLACE_NULLS\\\"\",\n  \"\\\"ACTION_TRANSFORMATION_SHA1\\\"\",\n  \"\\\"ACTION_TRANSFORMATION_SQL_HEX_DECODE\\\"\",\n  \"\\\"ACTION_TRANSFORMATION_TRIM\\\"\", \"\\\"ACTION_TRANSFORMATION_TRIM_LEFT\\\"\",\n  \"\\\"ACTION_TRANSFORMATION_TRIM_RIGHT\\\"\",\n  \"\\\"ACTION_TRANSFORMATION_UPPERCASE\\\"\",\n  \"\\\"ACTION_TRANSFORMATION_URL_ENCODE\\\"\",\n  \"\\\"ACTION_TRANSFORMATION_URL_DECODE\\\"\",\n  \"\\\"ACTION_TRANSFORMATION_URL_DECODE_UNI\\\"\",\n  \"\\\"ACTION_TRANSFORMATION_UTF8_TO_UNICODE\\\"\", \"\\\"Ver\\\"\", \"\\\"xmlns\\\"\",\n  \"\\\"CONFIG_COMPONENT_SIG\\\"\", \"\\\"CONFIG_CONN_ENGINE\\\"\",\n  \"\\\"CONFIG_SEC_ARGUMENT_SEPARATOR\\\"\", \"\\\"CONFIG_SEC_WEB_APP_ID\\\"\",\n  \"\\\"CONFIG_SEC_SERVER_SIG\\\"\", \"\\\"CONFIG_DIR_AUDIT_DIR\\\"\",\n  \"\\\"CONFIG_DIR_AUDIT_DIR_MOD\\\"\", \"\\\"CONFIG_DIR_AUDIT_ENG\\\"\",\n  \"\\\"CONFIG_DIR_AUDIT_FLE_MOD\\\"\", \"\\\"CONFIG_DIR_AUDIT_LOG\\\"\",\n  \"\\\"CONFIG_DIR_AUDIT_LOG2\\\"\", \"\\\"CONFIG_DIR_AUDIT_LOG_P\\\"\",\n  \"\\\"CONFIG_DIR_AUDIT_STS\\\"\", \"\\\"CONFIG_DIR_AUDIT_PREFIX\\\"\",\n  \"\\\"CONFIG_DIR_AUDIT_TPE\\\"\", \"\\\"CONFIG_DIR_DEBUG_LOG\\\"\",\n  \"\\\"CONFIG_DIR_DEBUG_LVL\\\"\", \"\\\"CONFIG_SEC_CACHE_TRANSFORMATIONS\\\"\",\n  \"\\\"CONFIG_SEC_DISABLE_BACKEND_COMPRESS\\\"\", \"\\\"CONFIG_SEC_HASH_ENGINE\\\"\",\n  \"\\\"CONFIG_SEC_HASH_KEY\\\"\", \"\\\"CONFIG_SEC_HASH_PARAM\\\"\",\n  \"\\\"CONFIG_SEC_HASH_METHOD_RX\\\"\", \"\\\"CONFIG_SEC_HASH_METHOD_PM\\\"\",\n  \"\\\"CONFIG_SEC_CHROOT_DIR\\\"\", \"\\\"CONFIG_DIR_GEO_DB\\\"\",\n  \"\\\"CONFIG_DIR_GSB_DB\\\"\", \"\\\"CONFIG_SEC_GUARDIAN_LOG\\\"\",\n  \"\\\"CONFIG_DIR_PCRE_MATCH_LIMIT\\\"\",\n  \"\\\"CONFIG_DIR_PCRE_MATCH_LIMIT_RECURSION\\\"\",\n  \"\\\"CONFIG_SEC_CONN_R_STATE_LIMIT\\\"\", \"\\\"CONFIG_SEC_CONN_W_STATE_LIMIT\\\"\",\n  \"\\\"CONFIG_SEC_SENSOR_ID\\\"\", \"\\\"CONFIG_DIR_ARGS_LIMIT\\\"\",\n  \"\\\"CONFIG_DIR_REQ_BODY_JSON_DEPTH_LIMIT\\\"\", \"\\\"CONFIG_DIR_REQ_BODY\\\"\",\n  \"\\\"CONFIG_DIR_REQ_BODY_IN_MEMORY_LIMIT\\\"\",\n  \"\\\"CONFIG_DIR_REQ_BODY_LIMIT\\\"\", \"\\\"CONFIG_DIR_REQ_BODY_LIMIT_ACTION\\\"\",\n  \"\\\"CONFIG_DIR_REQ_BODY_NO_FILES_LIMIT\\\"\", \"\\\"CONFIG_DIR_RES_BODY\\\"\",\n  \"\\\"CONFIG_DIR_RES_BODY_LIMIT\\\"\", \"\\\"CONFIG_DIR_RES_BODY_LIMIT_ACTION\\\"\",\n  \"\\\"CONFIG_SEC_RULE_INHERITANCE\\\"\", \"\\\"CONFIG_SEC_RULE_PERF_TIME\\\"\",\n  \"\\\"CONFIG_DIR_RULE_ENG\\\"\", \"\\\"CONFIG_DIR_SEC_ACTION\\\"\",\n  \"\\\"CONFIG_DIR_SEC_DEFAULT_ACTION\\\"\", \"\\\"CONFIG_DIR_SEC_MARKER\\\"\",\n  \"\\\"CONFIG_DIR_UNICODE_MAP_FILE\\\"\", \"\\\"CONFIG_DIR_UNICODE_CODE_PAGE\\\"\",\n  \"\\\"CONFIG_SEC_COLLECTION_TIMEOUT\\\"\", \"\\\"CONFIG_SEC_HTTP_BLKEY\\\"\",\n  \"\\\"CONFIG_SEC_INTERCEPT_ON_ERROR\\\"\",\n  \"\\\"CONFIG_SEC_REMOTE_RULES_FAIL_ACTION\\\"\",\n  \"\\\"CONFIG_SEC_RULE_REMOVE_BY_ID\\\"\", \"\\\"CONFIG_SEC_RULE_REMOVE_BY_MSG\\\"\",\n  \"\\\"CONFIG_SEC_RULE_REMOVE_BY_TAG\\\"\",\n  \"\\\"CONFIG_SEC_RULE_UPDATE_TARGET_BY_TAG\\\"\",\n  \"\\\"CONFIG_SEC_RULE_UPDATE_TARGET_BY_MSG\\\"\",\n  \"\\\"CONFIG_SEC_RULE_UPDATE_TARGET_BY_ID\\\"\",\n  \"\\\"CONFIG_SEC_RULE_UPDATE_ACTION_BY_ID\\\"\",\n  \"\\\"CONFIG_UPDLOAD_KEEP_FILES\\\"\", \"\\\"CONFIG_UPDLOAD_SAVE_TMP_FILES\\\"\",\n  \"\\\"CONFIG_UPLOAD_DIR\\\"\", \"\\\"CONFIG_UPLOAD_FILE_LIMIT\\\"\",\n  \"\\\"CONFIG_UPLOAD_FILE_MODE\\\"\", \"\\\"CONFIG_VALUE_ABORT\\\"\",\n  \"\\\"CONFIG_VALUE_DETC\\\"\", \"\\\"CONFIG_VALUE_HTTPS\\\"\",\n  \"\\\"CONFIG_VALUE_ONLYARGS\\\"\", \"\\\"CONFIG_VALUE_OFF\\\"\",\n  \"\\\"CONFIG_VALUE_ON\\\"\", \"\\\"CONFIG_VALUE_PARALLEL\\\"\",\n  \"\\\"CONFIG_VALUE_PROCESS_PARTIAL\\\"\", \"\\\"CONFIG_VALUE_REJECT\\\"\",\n  \"\\\"CONFIG_VALUE_RELEVANT_ONLY\\\"\", \"\\\"CONFIG_VALUE_SERIAL\\\"\",\n  \"\\\"CONFIG_VALUE_WARN\\\"\", \"\\\"CONFIG_XML_EXTERNAL_ENTITY\\\"\",\n  \"\\\"CONFIG_XML_PARSE_XML_INTO_ARGS\\\"\", \"\\\"CONGIG_DIR_RESPONSE_BODY_MP\\\"\",\n  \"\\\"CONGIG_DIR_SEC_ARG_SEP\\\"\", \"\\\"CONGIG_DIR_SEC_COOKIE_FORMAT\\\"\",\n  \"\\\"CONFIG_SEC_COOKIEV0_SEPARATOR\\\"\", \"\\\"CONGIG_DIR_SEC_DATA_DIR\\\"\",\n  \"\\\"CONGIG_DIR_SEC_STATUS_ENGINE\\\"\",\n  \"\\\"CONFIG_SEC_STREAM_IN_BODY_INSPECTION\\\"\",\n  \"\\\"CONFIG_SEC_STREAM_OUT_BODY_INSPECTION\\\"\",\n  \"\\\"CONGIG_DIR_SEC_TMP_DIR\\\"\", \"\\\"DIRECTIVE\\\"\",\n  \"\\\"DIRECTIVE_SECRULESCRIPT\\\"\", \"\\\"FREE_TEXT_QUOTE_MACRO_EXPANSION\\\"\",\n  \"\\\"QUOTATION_MARK\\\"\", \"\\\"RUN_TIME_VAR_BLD\\\"\", \"\\\"RUN_TIME_VAR_DUR\\\"\",\n  \"\\\"RUN_TIME_VAR_HSV\\\"\", \"\\\"RUN_TIME_VAR_REMOTE_USER\\\"\",\n  \"\\\"RUN_TIME_VAR_TIME\\\"\", \"\\\"RUN_TIME_VAR_TIME_DAY\\\"\",\n  \"\\\"RUN_TIME_VAR_TIME_EPOCH\\\"\", \"\\\"RUN_TIME_VAR_TIME_HOUR\\\"\",\n  \"\\\"RUN_TIME_VAR_TIME_MIN\\\"\", \"\\\"RUN_TIME_VAR_TIME_MON\\\"\",\n  \"\\\"RUN_TIME_VAR_TIME_SEC\\\"\", \"\\\"RUN_TIME_VAR_TIME_WDAY\\\"\",\n  \"\\\"RUN_TIME_VAR_TIME_YEAR\\\"\", \"\\\"VARIABLE\\\"\", \"\\\"Dictionary element\\\"\",\n  \"\\\"Dictionary element, with equals\\\"\",\n  \"\\\"Dictionary element, selected by regexp\\\"\", \"$accept\", \"input\", \"line\",\n  \"audit_log\", \"actions\", \"actions_may_quoted\", \"op\", \"op_before_init\",\n  \"expression\", \"variables\", \"variables_pre_process\",\n  \"variables_may_be_quoted\", \"var\", \"act\", \"setvar_action\",\n  \"run_time_string\", YY_NULLPTR\n  };\n#endif\n\n\n#if YYDEBUG\n  const short\n  seclang_parser::yyrline_[] =\n  {\n       0,   736,   736,   740,   741,   744,   749,   755,   761,   765,\n     769,   775,   781,   787,   793,   798,   803,   809,   816,   823,\n     827,   831,   837,   841,   845,   850,   858,   866,   871,   875,\n     882,   886,   893,   899,   909,   918,   928,   937,   950,   954,\n     958,   962,   966,   970,   974,   978,   982,   986,   991,   995,\n     999,  1003,  1007,  1011,  1016,  1021,  1025,  1029,  1033,  1037,\n    1041,  1045,  1049,  1053,  1057,  1061,  1065,  1069,  1073,  1077,\n    1081,  1085,  1089,  1093,  1097,  1111,  1112,  1143,  1162,  1182,\n    1211,  1268,  1275,  1279,  1283,  1287,  1291,  1295,  1299,  1303,\n    1312,  1316,  1321,  1324,  1329,  1334,  1339,  1344,  1347,  1352,\n    1355,  1360,  1365,  1368,  1373,  1378,  1383,  1388,  1393,  1398,\n    1403,  1406,  1411,  1416,  1421,  1426,  1429,  1434,  1439,  1444,\n    1457,  1470,  1483,  1496,  1509,  1535,  1563,  1575,  1595,  1622,\n    1627,  1633,  1641,  1649,  1658,  1666,  1670,  1674,  1678,  1682,\n    1686,  1690,  1695,  1703,  1715,  1721,  1725,  1729,  1733,  1737,\n    1741,  1752,  1761,  1762,  1769,  1774,  1779,  1833,  1840,  1848,\n    1885,  1889,  1896,  1901,  1907,  1913,  1919,  1926,  1936,  1940,\n    1944,  1948,  1952,  1956,  1960,  1964,  1968,  1972,  1976,  1980,\n    1984,  1988,  1992,  1996,  2000,  2004,  2008,  2012,  2016,  2020,\n    2024,  2028,  2032,  2036,  2040,  2044,  2048,  2052,  2056,  2060,\n    2064,  2068,  2072,  2076,  2080,  2084,  2088,  2092,  2096,  2100,\n    2104,  2108,  2112,  2116,  2120,  2124,  2128,  2132,  2136,  2140,\n    2144,  2148,  2152,  2156,  2160,  2164,  2168,  2172,  2176,  2180,\n    2184,  2188,  2192,  2196,  2200,  2204,  2208,  2212,  2216,  2220,\n    2224,  2228,  2232,  2236,  2240,  2244,  2248,  2252,  2256,  2260,\n    2264,  2268,  2272,  2276,  2280,  2284,  2288,  2292,  2296,  2300,\n    2304,  2309,  2313,  2317,  2322,  2326,  2330,  2335,  2340,  2344,\n    2348,  2352,  2356,  2360,  2364,  2368,  2372,  2376,  2380,  2384,\n    2388,  2392,  2396,  2400,  2404,  2408,  2412,  2416,  2420,  2424,\n    2428,  2432,  2436,  2440,  2444,  2448,  2452,  2456,  2460,  2464,\n    2468,  2472,  2476,  2480,  2484,  2488,  2492,  2496,  2500,  2504,\n    2508,  2512,  2516,  2520,  2524,  2528,  2532,  2536,  2540,  2544,\n    2548,  2552,  2556,  2560,  2564,  2568,  2572,  2576,  2580,  2584,\n    2588,  2596,  2603,  2610,  2617,  2624,  2631,  2638,  2645,  2652,\n    2659,  2666,  2673,  2683,  2687,  2691,  2695,  2699,  2703,  2707,\n    2711,  2716,  2720,  2725,  2729,  2733,  2737,  2741,  2746,  2751,\n    2755,  2759,  2763,  2767,  2771,  2775,  2779,  2783,  2787,  2791,\n    2795,  2799,  2803,  2807,  2811,  2815,  2819,  2823,  2827,  2831,\n    2835,  2839,  2843,  2847,  2851,  2855,  2859,  2863,  2867,  2871,\n    2875,  2879,  2883,  2887,  2891,  2895,  2899,  2903,  2907,  2911,\n    2915,  2919,  2923,  2927,  2931,  2935,  2939,  2943,  2947,  2951,\n    2955,  2959,  2963,  2967,  2971,  2975,  2979,  2983,  2987,  2991,\n    2995,  2999,  3003,  3007,  3011,  3015,  3019,  3023,  3027,  3031,\n    3035,  3039,  3043,  3047,  3051,  3055,  3059,  3063,  3067,  3071,\n    3075,  3079,  3083,  3087,  3091,  3098,  3102,  3106,  3110,  3114,\n    3121,  3126,  3131,  3137\n  };\n\n  void\n  seclang_parser::yy_stack_print_ () const\n  {\n    *yycdebug_ << \"Stack now\";\n    for (stack_type::const_iterator\n           i = yystack_.begin (),\n           i_end = yystack_.end ();\n         i != i_end; ++i)\n      *yycdebug_ << ' ' << int (i->state);\n    *yycdebug_ << '\\n';\n  }\n\n  void\n  seclang_parser::yy_reduce_print_ (int yyrule) const\n  {\n    int yylno = yyrline_[yyrule];\n    int yynrhs = yyr2_[yyrule];\n    // Print the symbols being reduced, and their result.\n    *yycdebug_ << \"Reducing stack by rule \" << yyrule - 1\n               << \" (line \" << yylno << \"):\\n\";\n    // The symbols being reduced.\n    for (int yyi = 0; yyi < yynrhs; yyi++)\n      YY_SYMBOL_PRINT (\"   $\" << yyi + 1 << \" =\",\n                       yystack_[(yynrhs) - (yyi + 1)]);\n  }\n#endif // YYDEBUG\n\n\n} // yy\n#line 7421 \"seclang-parser.cc\"\n\n#line 3144 \"seclang-parser.yy\"\n\n\nvoid yy::seclang_parser::error (const location_type& l, const std::string& m) {\n    driver.error (l, m);\n}\n"
  },
  {
    "path": "src/parser/seclang-parser.hh",
    "content": "// A Bison parser, made by GNU Bison 3.8.2.\n\n// Skeleton interface for Bison LALR(1) parsers in C++\n\n// Copyright (C) 2002-2015, 2018-2021 Free Software Foundation, Inc.\n\n// This program is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n\n// This program is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n// GNU General Public License for more details.\n\n// You should have received a copy of the GNU General Public License\n// along with this program.  If not, see <https://www.gnu.org/licenses/>.\n\n// As a special exception, you may create a larger work that contains\n// part or all of the Bison parser skeleton and distribute that work\n// under terms of your choice, so long as that work isn't itself a\n// parser generator using the skeleton or a modified version thereof\n// as a parser skeleton.  Alternatively, if you modify or redistribute\n// the parser skeleton itself, you may (at your option) remove this\n// special exception, which will cause the skeleton and the resulting\n// Bison output files to be licensed under the GNU General Public\n// License without this special exception.\n\n// This special exception was added by the Free Software Foundation in\n// version 2.2 of Bison.\n\n\n/**\n ** \\file seclang-parser.tab.hh\n ** Define the yy::parser class.\n */\n\n// C++ LALR(1) parser skeleton written by Akim Demaille.\n\n// DO NOT RELY ON FEATURES THAT ARE NOT DOCUMENTED in the manual,\n// especially those whose name start with YY_ or yy_.  They are\n// private implementation details that can be changed or removed.\n\n#ifndef YY_YY_SECLANG_PARSER_TAB_HH_INCLUDED\n# define YY_YY_SECLANG_PARSER_TAB_HH_INCLUDED\n// \"%code requires\" blocks.\n#line 10 \"seclang-parser.yy\"\n\n#include <string>\n#include <iterator>\n\nnamespace ModSecurity {\nnamespace Parser {\nclass Driver;\n}\n}\n\n#include \"modsecurity/rule_unconditional.h\"\n#include \"src/rule_script.h\"\n\n#include \"src/actions/accuracy.h\"\n#include \"src/actions/audit_log.h\"\n#include \"src/actions/block.h\"\n#include \"src/actions/capture.h\"\n#include \"src/actions/chain.h\"\n#include \"src/actions/ctl/audit_engine.h\"\n#include \"src/actions/ctl/audit_log_parts.h\"\n#include \"src/actions/ctl/parse_xml_into_args.h\"\n#include \"src/actions/ctl/request_body_access.h\"\n#include \"src/actions/ctl/rule_engine.h\"\n#include \"src/actions/ctl/request_body_processor_json.h\"\n#include \"src/actions/ctl/request_body_processor_xml.h\"\n#include \"src/actions/ctl/request_body_processor_urlencoded.h\"\n#include \"src/actions/ctl/rule_remove_by_id.h\"\n#include \"src/actions/ctl/rule_remove_by_tag.h\"\n#include \"src/actions/ctl/rule_remove_target_by_id.h\"\n#include \"src/actions/ctl/rule_remove_target_by_tag.h\"\n#include \"src/actions/data/status.h\"\n#include \"src/actions/disruptive/allow.h\"\n#include \"src/actions/disruptive/deny.h\"\n#include \"src/actions/disruptive/drop.h\"\n#include \"src/actions/disruptive/pass.h\"\n#include \"src/actions/disruptive/redirect.h\"\n#include \"src/actions/init_col.h\"\n#include \"src/actions/exec.h\"\n#include \"src/actions/expire_var.h\"\n#include \"src/actions/log_data.h\"\n#include \"src/actions/log.h\"\n#include \"src/actions/maturity.h\"\n#include \"src/actions/msg.h\"\n#include \"src/actions/multi_match.h\"\n#include \"src/actions/no_audit_log.h\"\n#include \"src/actions/no_log.h\"\n#include \"src/actions/phase.h\"\n#include \"src/actions/rev.h\"\n#include \"src/actions/rule_id.h\"\n#include \"src/actions/set_env.h\"\n#include \"src/actions/set_rsc.h\"\n#include \"src/actions/set_sid.h\"\n#include \"src/actions/set_uid.h\"\n#include \"src/actions/set_var.h\"\n#include \"src/actions/severity.h\"\n#include \"src/actions/skip_after.h\"\n#include \"src/actions/skip.h\"\n#include \"src/actions/tag.h\"\n#include \"src/actions/ver.h\"\n#include \"src/actions/xmlns.h\"\n\n#include \"src/actions/transformations/none.h\"\n#include \"src/actions/transformations/transformation.h\"\n#include \"src/actions/transformations/url_decode_uni.h\"\n#include \"src/actions/transformations/hex_encode.h\"\n#include \"src/actions/transformations/parity_even_7bit.h\"\n#include \"src/actions/transformations/utf8_to_unicode.h\"\n#include \"src/actions/transformations/parity_zero_7bit.h\"\n#include \"src/actions/transformations/sql_hex_decode.h\"\n#include \"src/actions/transformations/replace_comments.h\"\n#include \"src/actions/transformations/none.h\"\n#include \"src/actions/transformations/url_decode.h\"\n#include \"src/actions/transformations/lower_case.h\"\n#include \"src/actions/transformations/upper_case.h\"\n#include \"src/actions/transformations/hex_decode.h\"\n#include \"src/actions/transformations/url_encode.h\"\n#include \"src/actions/transformations/js_decode.h\"\n#include \"src/actions/transformations/url_decode_uni.h\"\n#include \"src/actions/transformations/parity_odd_7bit.h\"\n#include \"src/actions/transformations/transformation.h\"\n#include \"src/actions/transformations/trim_right.h\"\n#include \"src/actions/transformations/escape_seq_decode.h\"\n#include \"src/actions/transformations/base64_decode_ext.h\"\n#include \"src/actions/transformations/base64_decode.h\"\n#include \"src/actions/transformations/trim.h\"\n#include \"src/actions/transformations/cmd_line.h\"\n#include \"src/actions/transformations/replace_nulls.h\"\n#include \"src/actions/transformations/md5.h\"\n#include \"src/actions/transformations/length.h\"\n#include \"src/actions/transformations/sha1.h\"\n#include \"src/actions/transformations/compress_whitespace.h\"\n#include \"src/actions/transformations/normalise_path_win.h\"\n#include \"src/actions/transformations/remove_nulls.h\"\n#include \"src/actions/transformations/remove_comments.h\"\n#include \"src/actions/transformations/normalise_path.h\"\n#include \"src/actions/transformations/html_entity_decode.h\"\n#include \"src/actions/transformations/trim_left.h\"\n#include \"src/actions/transformations/remove_comments_char.h\"\n#include \"src/actions/transformations/base64_encode.h\"\n#include \"src/actions/transformations/remove_whitespace.h\"\n#include \"src/actions/transformations/css_decode.h\"\n\n#include \"src/operators/begins_with.h\"\n#include \"src/operators/contains.h\"\n#include \"src/operators/contains_word.h\"\n#include \"src/operators/detect_sqli.h\"\n#include \"src/operators/detect_xss.h\"\n#include \"src/operators/ends_with.h\"\n#include \"src/operators/eq.h\"\n#include \"src/operators/fuzzy_hash.h\"\n#include \"src/operators/ge.h\"\n#include \"src/operators/geo_lookup.h\"\n#include \"src/operators/gsblookup.h\"\n#include \"src/operators/gt.h\"\n#include \"src/operators/inspect_file.h\"\n#include \"src/operators/ip_match_f.h\"\n#include \"src/operators/ip_match_from_file.h\"\n#include \"src/operators/ip_match.h\"\n#include \"src/operators/le.h\"\n#include \"src/operators/lt.h\"\n#include \"src/operators/no_match.h\"\n#include \"src/operators/operator.h\"\n#include \"src/operators/pm_f.h\"\n#include \"src/operators/pm_from_file.h\"\n#include \"src/operators/pm.h\"\n#include \"src/operators/rbl.h\"\n#include \"src/operators/rsub.h\"\n#include \"src/operators/rx.h\"\n#include \"src/operators/rx_global.h\"\n#include \"src/operators/str_eq.h\"\n#include \"src/operators/str_match.h\"\n#include \"src/operators/unconditional_match.h\"\n#include \"src/operators/validate_byte_range.h\"\n#include \"src/operators/validate_dtd.h\"\n#include \"src/operators/validate_hash.h\"\n#include \"src/operators/validate_schema.h\"\n#include \"src/operators/validate_url_encoding.h\"\n#include \"src/operators/validate_utf8_encoding.h\"\n#include \"src/operators/verify_cc.h\"\n#include \"src/operators/verify_cpf.h\"\n#include \"src/operators/verify_ssn.h\"\n#include \"src/operators/verify_svnr.h\"\n#include \"src/operators/within.h\"\n\n\n#include \"modsecurity/audit_log.h\"\n#include \"modsecurity/modsecurity.h\"\n#include \"modsecurity/rules_set_properties.h\"\n#include \"modsecurity/rule.h\"\n#include \"src/operators/operator.h\"\n#include \"src/utils/geo_lookup.h\"\n#include \"src/utils/string.h\"\n#include \"src/utils/system.h\"\n#include \"src/variables/args_combined_size.h\"\n#include \"src/variables/args_get.h\"\n#include \"src/variables/args_get_names.h\"\n#include \"src/variables/args.h\"\n#include \"src/variables/args_names.h\"\n#include \"src/variables/args_post.h\"\n#include \"src/variables/args_post_names.h\"\n#include \"src/variables/auth_type.h\"\n#include \"src/variables/duration.h\"\n#include \"src/variables/env.h\"\n#include \"src/variables/files_combined_size.h\"\n#include \"src/variables/files.h\"\n#include \"src/variables/files_names.h\"\n#include \"src/variables/files_sizes.h\"\n#include \"src/variables/files_tmp_content.h\"\n#include \"src/variables/files_tmp_names.h\"\n#include \"src/variables/full_request.h\"\n#include \"src/variables/full_request_length.h\"\n#include \"src/variables/geo.h\"\n#include \"src/variables/highest_severity.h\"\n#include \"src/variables/inbound_data_error.h\"\n#include \"src/variables/matched_var.h\"\n#include \"src/variables/matched_var_name.h\"\n#include \"src/variables/matched_vars.h\"\n#include \"src/variables/matched_vars_names.h\"\n#include \"src/variables/modsec_build.h\"\n#include \"src/variables/msc_pcre_error.h\"\n#include \"src/variables/msc_pcre_limits_exceeded.h\"\n#include \"src/variables/multipart_boundary_quoted.h\"\n#include \"src/variables/multipart_boundary_whitespace.h\"\n#include \"src/variables/multipart_crlf_lf_lines.h\"\n#include \"src/variables/multipart_data_after.h\"\n#include \"src/variables/multipart_data_before.h\"\n#include \"src/variables/multipart_file_limit_exceeded.h\"\n#include \"src/variables/multipart_file_name.h\"\n#include \"src/variables/multipart_header_folding.h\"\n#include \"src/variables/multipart_invalid_header_folding.h\"\n#include \"src/variables/multipart_invalid_part.h\"\n#include \"src/variables/multipart_invalid_quoting.h\"\n#include \"src/variables/multipart_lf_line.h\"\n#include \"src/variables/multipart_missing_semicolon.h\"\n#include \"src/variables/multipart_name.h\"\n#include \"src/variables/multipart_strict_error.h\"\n#include \"src/variables/multipart_unmatched_boundary.h\"\n#include \"src/variables/outbound_data_error.h\"\n#include \"src/variables/path_info.h\"\n#include \"src/variables/query_string.h\"\n#include \"src/variables/remote_addr.h\"\n#include \"src/variables/remote_host.h\"\n#include \"src/variables/remote_port.h\"\n#include \"src/variables/remote_user.h\"\n#include \"src/variables/reqbody_error.h\"\n#include \"src/variables/reqbody_error_msg.h\"\n#include \"src/variables/reqbody_processor_error.h\"\n#include \"src/variables/reqbody_processor_error_msg.h\"\n#include \"src/variables/reqbody_processor.h\"\n#include \"src/variables/request_base_name.h\"\n#include \"src/variables/request_body.h\"\n#include \"src/variables/request_body_length.h\"\n#include \"src/variables/request_cookies.h\"\n#include \"src/variables/request_cookies_names.h\"\n#include \"src/variables/multipart_part_headers.h\"\n#include \"src/variables/request_file_name.h\"\n#include \"src/variables/request_headers.h\"\n#include \"src/variables/request_headers_names.h\"\n#include \"src/variables/request_line.h\"\n#include \"src/variables/request_method.h\"\n#include \"src/variables/request_protocol.h\"\n#include \"src/variables/request_uri.h\"\n#include \"src/variables/request_uri_raw.h\"\n#include \"src/variables/resource.h\"\n#include \"src/variables/response_body.h\"\n#include \"src/variables/response_content_length.h\"\n#include \"src/variables/response_content_type.h\"\n#include \"src/variables/response_headers.h\"\n#include \"src/variables/response_headers_names.h\"\n#include \"src/variables/response_protocol.h\"\n#include \"src/variables/response_status.h\"\n#include \"src/variables/rule.h\"\n#include \"src/variables/server_addr.h\"\n#include \"src/variables/server_name.h\"\n#include \"src/variables/server_port.h\"\n#include \"src/variables/session_id.h\"\n#include \"src/variables/web_app_id.h\"\n#include \"src/variables/time_day.h\"\n#include \"src/variables/time_epoch.h\"\n#include \"src/variables/time.h\"\n#include \"src/variables/time_hour.h\"\n#include \"src/variables/time_min.h\"\n#include \"src/variables/time_mon.h\"\n#include \"src/variables/time_sec.h\"\n#include \"src/variables/time_wday.h\"\n#include \"src/variables/time_year.h\"\n#include \"src/variables/tx.h\"\n#include \"src/variables/unique_id.h\"\n#include \"src/variables/url_encoded_error.h\"\n#include \"src/variables/user.h\"\n#include \"src/variables/user_id.h\"\n#include \"src/variables/variable.h\"\n#include \"src/variables/xml.h\"\n#include \"src/variables/ip.h\"\n#include \"src/variables/global.h\"\n#include \"src/variables/session.h\"\n#include \"src/variables/status.h\"\n\nusing namespace modsecurity;\nusing namespace modsecurity::variables;\nusing namespace modsecurity::Utils;\nusing namespace modsecurity::operators;\n\n\n#define CHECK_VARIATION_DECL \\\n    Variable *var = NULL; \\\n    bool t = false;\n\n#define CHECK_VARIATION(a) \\\n    if (var == NULL) { \\\n        if (name.at(0) == std::string(#a).at(0)) { \\\n            name.erase(0, 1); \\\n            t = true ; \\\n        } \\\n    } else { \\\n        t = false; \\\n    } \\\n    if (t)\n\n\n#define ACTION_NOT_SUPPORTED(a, b) \\\n    driver.error(b, \"Action: \" + std::string(a) + \" is not yet supported.\"); \\\n    YYERROR;\n\n\n#define OPERATOR_NOT_SUPPORTED(a, b) \\\n    driver.error(b, \"Operator: \" + std::string(a) + \" is not yet supported.\"); \\\n    YYERROR;\n\n\n#define ACTION_INIT(a, b) \\\n    std::string error; \\\n    if (a->init(&error) == false) { \\\n        driver.error(b, error); \\\n        YYERROR; \\\n    }\n\n#define OPERATOR_CONTAINER(a, b) \\\n    std::unique_ptr<Operator> c(b); \\\n    a = std::move(c);\n\n#define ACTION_CONTAINER(a, b) \\\n    std::unique_ptr<actions::Action> c(b); \\\n    a = std::move(c);\n\n#define VARIABLE_CONTAINER(a, b) \\\n    std::unique_ptr<Variable> c(b); \\\n    a = std::move(c);\n\n\n#line 360 \"seclang-parser.hh\"\n\n# include <cassert>\n# include <cstdlib> // std::abort\n# include <iostream>\n# include <stdexcept>\n# include <string>\n# include <vector>\n\n#if defined __cplusplus\n# define YY_CPLUSPLUS __cplusplus\n#else\n# define YY_CPLUSPLUS 199711L\n#endif\n\n// Support move semantics when possible.\n#if 201103L <= YY_CPLUSPLUS\n# define YY_MOVE           std::move\n# define YY_MOVE_OR_COPY   move\n# define YY_MOVE_REF(Type) Type&&\n# define YY_RVREF(Type)    Type&&\n# define YY_COPY(Type)     Type\n#else\n# define YY_MOVE\n# define YY_MOVE_OR_COPY   copy\n# define YY_MOVE_REF(Type) Type&\n# define YY_RVREF(Type)    const Type&\n# define YY_COPY(Type)     const Type&\n#endif\n\n// Support noexcept when possible.\n#if 201103L <= YY_CPLUSPLUS\n# define YY_NOEXCEPT noexcept\n# define YY_NOTHROW\n#else\n# define YY_NOEXCEPT\n# define YY_NOTHROW throw ()\n#endif\n\n// Support constexpr when possible.\n#if 201703 <= YY_CPLUSPLUS\n# define YY_CONSTEXPR constexpr\n#else\n# define YY_CONSTEXPR\n#endif\n# include \"location.hh\"\n#include <typeinfo>\n#ifndef YY_ASSERT\n# include <cassert>\n# define YY_ASSERT assert\n#endif\n\n\n#ifndef YY_ATTRIBUTE_PURE\n# if defined __GNUC__ && 2 < __GNUC__ + (96 <= __GNUC_MINOR__)\n#  define YY_ATTRIBUTE_PURE __attribute__ ((__pure__))\n# else\n#  define YY_ATTRIBUTE_PURE\n# endif\n#endif\n\n#ifndef YY_ATTRIBUTE_UNUSED\n# if defined __GNUC__ && 2 < __GNUC__ + (7 <= __GNUC_MINOR__)\n#  define YY_ATTRIBUTE_UNUSED __attribute__ ((__unused__))\n# else\n#  define YY_ATTRIBUTE_UNUSED\n# endif\n#endif\n\n/* Suppress unused-variable warnings by \"using\" E.  */\n#if ! defined lint || defined __GNUC__\n# define YY_USE(E) ((void) (E))\n#else\n# define YY_USE(E) /* empty */\n#endif\n\n/* Suppress an incorrect diagnostic about yylval being uninitialized.  */\n#if defined __GNUC__ && ! defined __ICC && 406 <= __GNUC__ * 100 + __GNUC_MINOR__\n# if __GNUC__ * 100 + __GNUC_MINOR__ < 407\n#  define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN                           \\\n    _Pragma (\"GCC diagnostic push\")                                     \\\n    _Pragma (\"GCC diagnostic ignored \\\"-Wuninitialized\\\"\")\n# else\n#  define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN                           \\\n    _Pragma (\"GCC diagnostic push\")                                     \\\n    _Pragma (\"GCC diagnostic ignored \\\"-Wuninitialized\\\"\")              \\\n    _Pragma (\"GCC diagnostic ignored \\\"-Wmaybe-uninitialized\\\"\")\n# endif\n# define YY_IGNORE_MAYBE_UNINITIALIZED_END      \\\n    _Pragma (\"GCC diagnostic pop\")\n#else\n# define YY_INITIAL_VALUE(Value) Value\n#endif\n#ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN\n# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN\n# define YY_IGNORE_MAYBE_UNINITIALIZED_END\n#endif\n#ifndef YY_INITIAL_VALUE\n# define YY_INITIAL_VALUE(Value) /* Nothing. */\n#endif\n\n#if defined __cplusplus && defined __GNUC__ && ! defined __ICC && 6 <= __GNUC__\n# define YY_IGNORE_USELESS_CAST_BEGIN                          \\\n    _Pragma (\"GCC diagnostic push\")                            \\\n    _Pragma (\"GCC diagnostic ignored \\\"-Wuseless-cast\\\"\")\n# define YY_IGNORE_USELESS_CAST_END            \\\n    _Pragma (\"GCC diagnostic pop\")\n#endif\n#ifndef YY_IGNORE_USELESS_CAST_BEGIN\n# define YY_IGNORE_USELESS_CAST_BEGIN\n# define YY_IGNORE_USELESS_CAST_END\n#endif\n\n# ifndef YY_CAST\n#  ifdef __cplusplus\n#   define YY_CAST(Type, Val) static_cast<Type> (Val)\n#   define YY_REINTERPRET_CAST(Type, Val) reinterpret_cast<Type> (Val)\n#  else\n#   define YY_CAST(Type, Val) ((Type) (Val))\n#   define YY_REINTERPRET_CAST(Type, Val) ((Type) (Val))\n#  endif\n# endif\n# ifndef YY_NULLPTR\n#  if defined __cplusplus\n#   if 201103L <= __cplusplus\n#    define YY_NULLPTR nullptr\n#   else\n#    define YY_NULLPTR 0\n#   endif\n#  else\n#   define YY_NULLPTR ((void*)0)\n#  endif\n# endif\n\n/* Debug traces.  */\n#ifndef YYDEBUG\n# define YYDEBUG 1\n#endif\n\nnamespace yy {\n#line 500 \"seclang-parser.hh\"\n\n\n\n\n  /// A Bison parser.\n  class seclang_parser\n  {\n  public:\n#ifdef YYSTYPE\n# ifdef __GNUC__\n#  pragma GCC message \"bison: do not #define YYSTYPE in C++, use %define api.value.type\"\n# endif\n    typedef YYSTYPE value_type;\n#else\n  /// A buffer to store and retrieve objects.\n  ///\n  /// Sort of a variant, but does not keep track of the nature\n  /// of the stored data, since that knowledge is available\n  /// via the current parser state.\n  class value_type\n  {\n  public:\n    /// Type of *this.\n    typedef value_type self_type;\n\n    /// Empty construction.\n    value_type () YY_NOEXCEPT\n      : yyraw_ ()\n      , yytypeid_ (YY_NULLPTR)\n    {}\n\n    /// Construct and fill.\n    template <typename T>\n    value_type (YY_RVREF (T) t)\n      : yytypeid_ (&typeid (T))\n    {\n      YY_ASSERT (sizeof (T) <= size);\n      new (yyas_<T> ()) T (YY_MOVE (t));\n    }\n\n#if 201103L <= YY_CPLUSPLUS\n    /// Non copyable.\n    value_type (const self_type&) = delete;\n    /// Non copyable.\n    self_type& operator= (const self_type&) = delete;\n#endif\n\n    /// Destruction, allowed only if empty.\n    ~value_type () YY_NOEXCEPT\n    {\n      YY_ASSERT (!yytypeid_);\n    }\n\n# if 201103L <= YY_CPLUSPLUS\n    /// Instantiate a \\a T in here from \\a t.\n    template <typename T, typename... U>\n    T&\n    emplace (U&&... u)\n    {\n      YY_ASSERT (!yytypeid_);\n      YY_ASSERT (sizeof (T) <= size);\n      yytypeid_ = & typeid (T);\n      return *new (yyas_<T> ()) T (std::forward <U>(u)...);\n    }\n# else\n    /// Instantiate an empty \\a T in here.\n    template <typename T>\n    T&\n    emplace ()\n    {\n      YY_ASSERT (!yytypeid_);\n      YY_ASSERT (sizeof (T) <= size);\n      yytypeid_ = & typeid (T);\n      return *new (yyas_<T> ()) T ();\n    }\n\n    /// Instantiate a \\a T in here from \\a t.\n    template <typename T>\n    T&\n    emplace (const T& t)\n    {\n      YY_ASSERT (!yytypeid_);\n      YY_ASSERT (sizeof (T) <= size);\n      yytypeid_ = & typeid (T);\n      return *new (yyas_<T> ()) T (std::move((T&)t));\n    }\n# endif\n\n    /// Instantiate an empty \\a T in here.\n    /// Obsolete, use emplace.\n    template <typename T>\n    T&\n    build ()\n    {\n      return emplace<T> ();\n    }\n\n    /// Instantiate a \\a T in here from \\a t.\n    /// Obsolete, use emplace.\n    template <typename T>\n    T&\n    build (const T& t)\n    {\n      return emplace<T> (t);\n    }\n\n    /// Accessor to a built \\a T.\n    template <typename T>\n    T&\n    as () YY_NOEXCEPT\n    {\n      YY_ASSERT (yytypeid_);\n      YY_ASSERT (*yytypeid_ == typeid (T));\n      YY_ASSERT (sizeof (T) <= size);\n      return *yyas_<T> ();\n    }\n\n    /// Const accessor to a built \\a T (for %printer).\n    template <typename T>\n    const T&\n    as () const YY_NOEXCEPT\n    {\n      YY_ASSERT (yytypeid_);\n      YY_ASSERT (*yytypeid_ == typeid (T));\n      YY_ASSERT (sizeof (T) <= size);\n      return *yyas_<T> ();\n    }\n\n    /// Swap the content with \\a that, of same type.\n    ///\n    /// Both variants must be built beforehand, because swapping the actual\n    /// data requires reading it (with as()), and this is not possible on\n    /// unconstructed variants: it would require some dynamic testing, which\n    /// should not be the variant's responsibility.\n    /// Swapping between built and (possibly) non-built is done with\n    /// self_type::move ().\n    template <typename T>\n    void\n    swap (self_type& that) YY_NOEXCEPT\n    {\n      YY_ASSERT (yytypeid_);\n      YY_ASSERT (*yytypeid_ == *that.yytypeid_);\n      std::swap (as<T> (), that.as<T> ());\n    }\n\n    /// Move the content of \\a that to this.\n    ///\n    /// Destroys \\a that.\n    template <typename T>\n    void\n    move (self_type& that)\n    {\n# if 201103L <= YY_CPLUSPLUS\n      emplace<T> (std::move (that.as<T> ()));\n# else\n      emplace<T> ();\n      swap<T> (that);\n# endif\n      that.destroy<T> ();\n    }\n\n# if 201103L <= YY_CPLUSPLUS\n    /// Move the content of \\a that to this.\n    template <typename T>\n    void\n    move (self_type&& that)\n    {\n      emplace<T> (std::move (that.as<T> ()));\n      that.destroy<T> ();\n    }\n#endif\n\n    /// Copy the content of \\a that to this.\n    template <typename T>\n    void\n    copy (const self_type& that)\n    {\n      emplace<T> (that.as<T> ());\n    }\n\n    /// Destroy the stored \\a T.\n    template <typename T>\n    void\n    destroy ()\n    {\n      as<T> ().~T ();\n      yytypeid_ = YY_NULLPTR;\n    }\n\n  private:\n#if YY_CPLUSPLUS < 201103L\n    /// Non copyable.\n    value_type (const self_type&);\n    /// Non copyable.\n    self_type& operator= (const self_type&);\n#endif\n\n    /// Accessor to raw memory as \\a T.\n    template <typename T>\n    T*\n    yyas_ () YY_NOEXCEPT\n    {\n      void *yyp = yyraw_;\n      return static_cast<T*> (yyp);\n     }\n\n    /// Const accessor to raw memory as \\a T.\n    template <typename T>\n    const T*\n    yyas_ () const YY_NOEXCEPT\n    {\n      const void *yyp = yyraw_;\n      return static_cast<const T*> (yyp);\n     }\n\n    /// An auxiliary type to compute the largest semantic type.\n    union union_type\n    {\n      // \"Accuracy\"\n      // \"Allow\"\n      // \"Append\"\n      // \"AuditLog\"\n      // \"Block\"\n      // \"Capture\"\n      // \"Chain\"\n      // \"ACTION_CTL_AUDIT_ENGINE\"\n      // \"ACTION_CTL_AUDIT_LOG_PARTS\"\n      // \"ACTION_CTL_BDY_JSON\"\n      // \"ACTION_CTL_BDY_XML\"\n      // \"ACTION_CTL_BDY_URLENCODED\"\n      // \"ACTION_CTL_FORCE_REQ_BODY_VAR\"\n      // \"ACTION_CTL_PARSE_XML_INTO_ARGS\"\n      // \"ACTION_CTL_REQUEST_BODY_ACCESS\"\n      // \"ACTION_CTL_RULE_REMOVE_BY_ID\"\n      // \"ACTION_CTL_RULE_REMOVE_BY_TAG\"\n      // \"ACTION_CTL_RULE_REMOVE_TARGET_BY_ID\"\n      // \"ACTION_CTL_RULE_REMOVE_TARGET_BY_TAG\"\n      // \"Deny\"\n      // \"DeprecateVar\"\n      // \"Drop\"\n      // \"Exec\"\n      // \"ExpireVar\"\n      // \"Id\"\n      // \"InitCol\"\n      // \"Log\"\n      // \"LogData\"\n      // \"Maturity\"\n      // \"Msg\"\n      // \"MultiMatch\"\n      // \"NoAuditLog\"\n      // \"NoLog\"\n      // \"Pass\"\n      // \"Pause\"\n      // \"Phase\"\n      // \"Prepend\"\n      // \"Proxy\"\n      // \"Redirect\"\n      // \"Rev\"\n      // \"SanitiseArg\"\n      // \"SanitiseMatched\"\n      // \"SanitiseMatchedBytes\"\n      // \"SanitiseRequestHeader\"\n      // \"SanitiseResponseHeader\"\n      // \"SetEnv\"\n      // \"SetRsc\"\n      // \"SetSid\"\n      // \"SetUID\"\n      // \"Severity\"\n      // \"Skip\"\n      // \"SkipAfter\"\n      // \"Status\"\n      // \"Tag\"\n      // \"ACTION_TRANSFORMATION_BASE_64_ENCODE\"\n      // \"ACTION_TRANSFORMATION_BASE_64_DECODE\"\n      // \"ACTION_TRANSFORMATION_BASE_64_DECODE_EXT\"\n      // \"ACTION_TRANSFORMATION_CMD_LINE\"\n      // \"ACTION_TRANSFORMATION_COMPRESS_WHITESPACE\"\n      // \"ACTION_TRANSFORMATION_CSS_DECODE\"\n      // \"ACTION_TRANSFORMATION_ESCAPE_SEQ_DECODE\"\n      // \"ACTION_TRANSFORMATION_HEX_ENCODE\"\n      // \"ACTION_TRANSFORMATION_HEX_DECODE\"\n      // \"ACTION_TRANSFORMATION_HTML_ENTITY_DECODE\"\n      // \"ACTION_TRANSFORMATION_JS_DECODE\"\n      // \"ACTION_TRANSFORMATION_LENGTH\"\n      // \"ACTION_TRANSFORMATION_LOWERCASE\"\n      // \"ACTION_TRANSFORMATION_MD5\"\n      // \"ACTION_TRANSFORMATION_NONE\"\n      // \"ACTION_TRANSFORMATION_NORMALISE_PATH\"\n      // \"ACTION_TRANSFORMATION_NORMALISE_PATH_WIN\"\n      // \"ACTION_TRANSFORMATION_PARITY_EVEN_7_BIT\"\n      // \"ACTION_TRANSFORMATION_PARITY_ODD_7_BIT\"\n      // \"ACTION_TRANSFORMATION_PARITY_ZERO_7_BIT\"\n      // \"ACTION_TRANSFORMATION_REMOVE_COMMENTS\"\n      // \"ACTION_TRANSFORMATION_REMOVE_COMMENTS_CHAR\"\n      // \"ACTION_TRANSFORMATION_REMOVE_NULLS\"\n      // \"ACTION_TRANSFORMATION_REMOVE_WHITESPACE\"\n      // \"ACTION_TRANSFORMATION_REPLACE_COMMENTS\"\n      // \"ACTION_TRANSFORMATION_REPLACE_NULLS\"\n      // \"ACTION_TRANSFORMATION_SHA1\"\n      // \"ACTION_TRANSFORMATION_SQL_HEX_DECODE\"\n      // \"ACTION_TRANSFORMATION_TRIM\"\n      // \"ACTION_TRANSFORMATION_TRIM_LEFT\"\n      // \"ACTION_TRANSFORMATION_TRIM_RIGHT\"\n      // \"ACTION_TRANSFORMATION_UPPERCASE\"\n      // \"ACTION_TRANSFORMATION_URL_ENCODE\"\n      // \"ACTION_TRANSFORMATION_URL_DECODE\"\n      // \"ACTION_TRANSFORMATION_URL_DECODE_UNI\"\n      // \"ACTION_TRANSFORMATION_UTF8_TO_UNICODE\"\n      // \"Ver\"\n      // \"xmlns\"\n      // \"CONFIG_COMPONENT_SIG\"\n      // \"CONFIG_CONN_ENGINE\"\n      // \"CONFIG_SEC_ARGUMENT_SEPARATOR\"\n      // \"CONFIG_SEC_WEB_APP_ID\"\n      // \"CONFIG_SEC_SERVER_SIG\"\n      // \"CONFIG_DIR_AUDIT_DIR\"\n      // \"CONFIG_DIR_AUDIT_DIR_MOD\"\n      // \"CONFIG_DIR_AUDIT_ENG\"\n      // \"CONFIG_DIR_AUDIT_FLE_MOD\"\n      // \"CONFIG_DIR_AUDIT_LOG\"\n      // \"CONFIG_DIR_AUDIT_LOG2\"\n      // \"CONFIG_DIR_AUDIT_LOG_P\"\n      // \"CONFIG_DIR_AUDIT_STS\"\n      // \"CONFIG_DIR_AUDIT_PREFIX\"\n      // \"CONFIG_DIR_AUDIT_TPE\"\n      // \"CONFIG_DIR_DEBUG_LOG\"\n      // \"CONFIG_DIR_DEBUG_LVL\"\n      // \"CONFIG_SEC_CACHE_TRANSFORMATIONS\"\n      // \"CONFIG_SEC_DISABLE_BACKEND_COMPRESS\"\n      // \"CONFIG_SEC_HASH_ENGINE\"\n      // \"CONFIG_SEC_HASH_KEY\"\n      // \"CONFIG_SEC_HASH_PARAM\"\n      // \"CONFIG_SEC_HASH_METHOD_RX\"\n      // \"CONFIG_SEC_HASH_METHOD_PM\"\n      // \"CONFIG_SEC_CHROOT_DIR\"\n      // \"CONFIG_DIR_GEO_DB\"\n      // \"CONFIG_DIR_GSB_DB\"\n      // \"CONFIG_SEC_GUARDIAN_LOG\"\n      // \"CONFIG_DIR_PCRE_MATCH_LIMIT\"\n      // \"CONFIG_DIR_PCRE_MATCH_LIMIT_RECURSION\"\n      // \"CONFIG_SEC_CONN_R_STATE_LIMIT\"\n      // \"CONFIG_SEC_CONN_W_STATE_LIMIT\"\n      // \"CONFIG_SEC_SENSOR_ID\"\n      // \"CONFIG_DIR_ARGS_LIMIT\"\n      // \"CONFIG_DIR_REQ_BODY_JSON_DEPTH_LIMIT\"\n      // \"CONFIG_DIR_REQ_BODY\"\n      // \"CONFIG_DIR_REQ_BODY_IN_MEMORY_LIMIT\"\n      // \"CONFIG_DIR_REQ_BODY_LIMIT\"\n      // \"CONFIG_DIR_REQ_BODY_LIMIT_ACTION\"\n      // \"CONFIG_DIR_REQ_BODY_NO_FILES_LIMIT\"\n      // \"CONFIG_DIR_RES_BODY\"\n      // \"CONFIG_DIR_RES_BODY_LIMIT\"\n      // \"CONFIG_DIR_RES_BODY_LIMIT_ACTION\"\n      // \"CONFIG_SEC_RULE_INHERITANCE\"\n      // \"CONFIG_SEC_RULE_PERF_TIME\"\n      // \"CONFIG_DIR_RULE_ENG\"\n      // \"CONFIG_DIR_SEC_ACTION\"\n      // \"CONFIG_DIR_SEC_DEFAULT_ACTION\"\n      // \"CONFIG_DIR_SEC_MARKER\"\n      // \"CONFIG_DIR_UNICODE_MAP_FILE\"\n      // \"CONFIG_DIR_UNICODE_CODE_PAGE\"\n      // \"CONFIG_SEC_COLLECTION_TIMEOUT\"\n      // \"CONFIG_SEC_HTTP_BLKEY\"\n      // \"CONFIG_SEC_INTERCEPT_ON_ERROR\"\n      // \"CONFIG_SEC_REMOTE_RULES_FAIL_ACTION\"\n      // \"CONFIG_SEC_RULE_REMOVE_BY_ID\"\n      // \"CONFIG_SEC_RULE_REMOVE_BY_MSG\"\n      // \"CONFIG_SEC_RULE_REMOVE_BY_TAG\"\n      // \"CONFIG_SEC_RULE_UPDATE_TARGET_BY_TAG\"\n      // \"CONFIG_SEC_RULE_UPDATE_TARGET_BY_MSG\"\n      // \"CONFIG_SEC_RULE_UPDATE_TARGET_BY_ID\"\n      // \"CONFIG_SEC_RULE_UPDATE_ACTION_BY_ID\"\n      // \"CONFIG_UPDLOAD_KEEP_FILES\"\n      // \"CONFIG_UPDLOAD_SAVE_TMP_FILES\"\n      // \"CONFIG_UPLOAD_DIR\"\n      // \"CONFIG_UPLOAD_FILE_LIMIT\"\n      // \"CONFIG_UPLOAD_FILE_MODE\"\n      // \"CONFIG_VALUE_ABORT\"\n      // \"CONFIG_VALUE_DETC\"\n      // \"CONFIG_VALUE_HTTPS\"\n      // \"CONFIG_VALUE_ONLYARGS\"\n      // \"CONFIG_VALUE_OFF\"\n      // \"CONFIG_VALUE_ON\"\n      // \"CONFIG_VALUE_PARALLEL\"\n      // \"CONFIG_VALUE_PROCESS_PARTIAL\"\n      // \"CONFIG_VALUE_REJECT\"\n      // \"CONFIG_VALUE_RELEVANT_ONLY\"\n      // \"CONFIG_VALUE_SERIAL\"\n      // \"CONFIG_VALUE_WARN\"\n      // \"CONFIG_XML_EXTERNAL_ENTITY\"\n      // \"CONFIG_XML_PARSE_XML_INTO_ARGS\"\n      // \"CONGIG_DIR_RESPONSE_BODY_MP\"\n      // \"CONGIG_DIR_SEC_ARG_SEP\"\n      // \"CONGIG_DIR_SEC_COOKIE_FORMAT\"\n      // \"CONFIG_SEC_COOKIEV0_SEPARATOR\"\n      // \"CONGIG_DIR_SEC_DATA_DIR\"\n      // \"CONGIG_DIR_SEC_STATUS_ENGINE\"\n      // \"CONFIG_SEC_STREAM_IN_BODY_INSPECTION\"\n      // \"CONFIG_SEC_STREAM_OUT_BODY_INSPECTION\"\n      // \"CONGIG_DIR_SEC_TMP_DIR\"\n      // \"DIRECTIVE\"\n      // \"DIRECTIVE_SECRULESCRIPT\"\n      // \"FREE_TEXT_QUOTE_MACRO_EXPANSION\"\n      // \"QUOTATION_MARK\"\n      // \"RUN_TIME_VAR_BLD\"\n      // \"RUN_TIME_VAR_DUR\"\n      // \"RUN_TIME_VAR_HSV\"\n      // \"RUN_TIME_VAR_REMOTE_USER\"\n      // \"RUN_TIME_VAR_TIME\"\n      // \"RUN_TIME_VAR_TIME_DAY\"\n      // \"RUN_TIME_VAR_TIME_EPOCH\"\n      // \"RUN_TIME_VAR_TIME_HOUR\"\n      // \"RUN_TIME_VAR_TIME_MIN\"\n      // \"RUN_TIME_VAR_TIME_MON\"\n      // \"RUN_TIME_VAR_TIME_SEC\"\n      // \"RUN_TIME_VAR_TIME_WDAY\"\n      // \"RUN_TIME_VAR_TIME_YEAR\"\n      // \"VARIABLE\"\n      // \"Dictionary element\"\n      // \"Dictionary element, with equals\"\n      // \"Dictionary element, selected by regexp\"\n      char dummy1[sizeof (std::string)];\n\n      // op\n      // op_before_init\n      char dummy2[sizeof (std::unique_ptr<Operator>)];\n\n      // run_time_string\n      char dummy3[sizeof (std::unique_ptr<RunTimeString>)];\n\n      // var\n      char dummy4[sizeof (std::unique_ptr<Variable>)];\n\n      // act\n      // setvar_action\n      char dummy5[sizeof (std::unique_ptr<actions::Action>)];\n\n      // variables\n      // variables_pre_process\n      // variables_may_be_quoted\n      char dummy6[sizeof (std::unique_ptr<std::vector<std::unique_ptr<Variable> > > )];\n\n      // actions\n      // actions_may_quoted\n      char dummy7[sizeof (std::unique_ptr<std::vector<std::unique_ptr<actions::Action> > > )];\n    };\n\n    /// The size of the largest semantic type.\n    enum { size = sizeof (union_type) };\n\n    /// A buffer to store semantic values.\n    union\n    {\n      /// Strongest alignment constraints.\n      long double yyalign_me_;\n      /// A buffer large enough to store any of the semantic values.\n      char yyraw_[size];\n    };\n\n    /// Whether the content is built: if defined, the name of the stored type.\n    const std::type_info *yytypeid_;\n  };\n\n#endif\n    /// Backward compatibility (Bison 3.8).\n    typedef value_type semantic_type;\n\n    /// Symbol locations.\n    typedef location location_type;\n\n    /// Syntax errors thrown from user actions.\n    struct syntax_error : std::runtime_error\n    {\n      syntax_error (const location_type& l, const std::string& m)\n        : std::runtime_error (m)\n        , location (l)\n      {}\n\n      syntax_error (const syntax_error& s)\n        : std::runtime_error (s.what ())\n        , location (s.location)\n      {}\n\n      ~syntax_error () YY_NOEXCEPT YY_NOTHROW;\n\n      location_type location;\n    };\n\n    /// Token kinds.\n    struct token\n    {\n      enum token_kind_type\n      {\n        TOK_YYEMPTY = -2,\n    TOK_END = 0,                   // \"end of file\"\n    TOK_YYerror = 256,             // error\n    TOK_YYUNDEF = 257,             // \"invalid token\"\n    TOK_COMMA = 258,               // \",\"\n    TOK_CONFIG_CONTENT_INJECTION = 259, // \"CONFIG_CONTENT_INJECTION\"\n    TOK_CONGIG_DIR_RESPONSE_BODY_MP_CLEAR = 260, // \"CONGIG_DIR_RESPONSE_BODY_MP_CLEAR\"\n    TOK_PIPE = 261,                // PIPE\n    TOK_NEW_LINE = 262,            // NEW_LINE\n    TOK_VAR_COUNT = 263,           // VAR_COUNT\n    TOK_VAR_EXCLUSION = 264,       // VAR_EXCLUSION\n    TOK_VARIABLE_ARGS = 265,       // VARIABLE_ARGS\n    TOK_VARIABLE_ARGS_POST = 266,  // VARIABLE_ARGS_POST\n    TOK_VARIABLE_ARGS_GET = 267,   // VARIABLE_ARGS_GET\n    TOK_VARIABLE_FILES_SIZES = 268, // VARIABLE_FILES_SIZES\n    TOK_VARIABLE_FILES_NAMES = 269, // VARIABLE_FILES_NAMES\n    TOK_VARIABLE_FILES_TMP_CONTENT = 270, // VARIABLE_FILES_TMP_CONTENT\n    TOK_VARIABLE_MULTIPART_FILENAME = 271, // VARIABLE_MULTIPART_FILENAME\n    TOK_VARIABLE_MULTIPART_NAME = 272, // VARIABLE_MULTIPART_NAME\n    TOK_VARIABLE_MATCHED_VARS_NAMES = 273, // VARIABLE_MATCHED_VARS_NAMES\n    TOK_VARIABLE_MATCHED_VARS = 274, // VARIABLE_MATCHED_VARS\n    TOK_VARIABLE_FILES = 275,      // VARIABLE_FILES\n    TOK_VARIABLE_REQUEST_COOKIES = 276, // VARIABLE_REQUEST_COOKIES\n    TOK_VARIABLE_REQUEST_HEADERS = 277, // VARIABLE_REQUEST_HEADERS\n    TOK_VARIABLE_RESPONSE_HEADERS = 278, // VARIABLE_RESPONSE_HEADERS\n    TOK_VARIABLE_GEO = 279,        // VARIABLE_GEO\n    TOK_VARIABLE_REQUEST_COOKIES_NAMES = 280, // VARIABLE_REQUEST_COOKIES_NAMES\n    TOK_VARIABLE_MULTIPART_PART_HEADERS = 281, // VARIABLE_MULTIPART_PART_HEADERS\n    TOK_VARIABLE_ARGS_COMBINED_SIZE = 282, // VARIABLE_ARGS_COMBINED_SIZE\n    TOK_VARIABLE_ARGS_GET_NAMES = 283, // VARIABLE_ARGS_GET_NAMES\n    TOK_VARIABLE_RULE = 284,       // VARIABLE_RULE\n    TOK_VARIABLE_ARGS_NAMES = 285, // \"Variable ARGS_NAMES\"\n    TOK_VARIABLE_ARGS_POST_NAMES = 286, // VARIABLE_ARGS_POST_NAMES\n    TOK_VARIABLE_AUTH_TYPE = 287,  // \"AUTH_TYPE\"\n    TOK_VARIABLE_FILES_COMBINED_SIZE = 288, // \"FILES_COMBINED_SIZE\"\n    TOK_VARIABLE_FILES_TMP_NAMES = 289, // \"FILES_TMPNAMES\"\n    TOK_VARIABLE_FULL_REQUEST = 290, // \"FULL_REQUEST\"\n    TOK_VARIABLE_FULL_REQUEST_LENGTH = 291, // \"FULL_REQUEST_LENGTH\"\n    TOK_VARIABLE_INBOUND_DATA_ERROR = 292, // \"INBOUND_DATA_ERROR\"\n    TOK_VARIABLE_MATCHED_VAR = 293, // \"MATCHED_VAR\"\n    TOK_VARIABLE_MATCHED_VAR_NAME = 294, // \"MATCHED_VAR_NAME\"\n    TOK_VARIABLE_MSC_PCRE_ERROR = 295, // \"MSC_PCRE_ERROR\"\n    TOK_VARIABLE_MSC_PCRE_LIMITS_EXCEEDED = 296, // \"MSC_PCRE_LIMITS_EXCEEDED\"\n    TOK_VARIABLE_MULTIPART_BOUNDARY_QUOTED = 297, // VARIABLE_MULTIPART_BOUNDARY_QUOTED\n    TOK_VARIABLE_MULTIPART_BOUNDARY_WHITESPACE = 298, // VARIABLE_MULTIPART_BOUNDARY_WHITESPACE\n    TOK_VARIABLE_MULTIPART_CRLF_LF_LINES = 299, // \"MULTIPART_CRLF_LF_LINES\"\n    TOK_VARIABLE_MULTIPART_DATA_AFTER = 300, // \"MULTIPART_DATA_AFTER\"\n    TOK_VARIABLE_MULTIPART_DATA_BEFORE = 301, // VARIABLE_MULTIPART_DATA_BEFORE\n    TOK_VARIABLE_MULTIPART_FILE_LIMIT_EXCEEDED = 302, // \"MULTIPART_FILE_LIMIT_EXCEEDED\"\n    TOK_VARIABLE_MULTIPART_HEADER_FOLDING = 303, // \"MULTIPART_HEADER_FOLDING\"\n    TOK_VARIABLE_MULTIPART_INVALID_HEADER_FOLDING = 304, // \"MULTIPART_INVALID_HEADER_FOLDING\"\n    TOK_VARIABLE_MULTIPART_INVALID_PART = 305, // VARIABLE_MULTIPART_INVALID_PART\n    TOK_VARIABLE_MULTIPART_INVALID_QUOTING = 306, // \"MULTIPART_INVALID_QUOTING\"\n    TOK_VARIABLE_MULTIPART_LF_LINE = 307, // VARIABLE_MULTIPART_LF_LINE\n    TOK_VARIABLE_MULTIPART_MISSING_SEMICOLON = 308, // VARIABLE_MULTIPART_MISSING_SEMICOLON\n    TOK_VARIABLE_MULTIPART_SEMICOLON_MISSING = 309, // VARIABLE_MULTIPART_SEMICOLON_MISSING\n    TOK_VARIABLE_MULTIPART_STRICT_ERROR = 310, // \"MULTIPART_STRICT_ERROR\"\n    TOK_VARIABLE_MULTIPART_UNMATCHED_BOUNDARY = 311, // \"MULTIPART_UNMATCHED_BOUNDARY\"\n    TOK_VARIABLE_OUTBOUND_DATA_ERROR = 312, // \"OUTBOUND_DATA_ERROR\"\n    TOK_VARIABLE_PATH_INFO = 313,  // \"PATH_INFO\"\n    TOK_VARIABLE_QUERY_STRING = 314, // \"QUERY_STRING\"\n    TOK_VARIABLE_REMOTE_ADDR = 315, // \"REMOTE_ADDR\"\n    TOK_VARIABLE_REMOTE_HOST = 316, // \"REMOTE_HOST\"\n    TOK_VARIABLE_REMOTE_PORT = 317, // \"REMOTE_PORT\"\n    TOK_VARIABLE_REQBODY_ERROR_MSG = 318, // \"REQBODY_ERROR_MSG\"\n    TOK_VARIABLE_REQBODY_ERROR = 319, // \"REQBODY_ERROR\"\n    TOK_VARIABLE_REQBODY_PROCESSOR_ERROR_MSG = 320, // \"REQBODY_PROCESSOR_ERROR_MSG\"\n    TOK_VARIABLE_REQBODY_PROCESSOR_ERROR = 321, // \"REQBODY_PROCESSOR_ERROR\"\n    TOK_VARIABLE_REQBODY_PROCESSOR = 322, // \"REQBODY_PROCESSOR\"\n    TOK_VARIABLE_REQUEST_BASENAME = 323, // \"REQUEST_BASENAME\"\n    TOK_VARIABLE_REQUEST_BODY_LENGTH = 324, // \"REQUEST_BODY_LENGTH\"\n    TOK_VARIABLE_REQUEST_BODY = 325, // \"REQUEST_BODY\"\n    TOK_VARIABLE_REQUEST_FILE_NAME = 326, // \"REQUEST_FILENAME\"\n    TOK_VARIABLE_REQUEST_HEADERS_NAMES = 327, // VARIABLE_REQUEST_HEADERS_NAMES\n    TOK_VARIABLE_REQUEST_LINE = 328, // \"REQUEST_LINE\"\n    TOK_VARIABLE_REQUEST_METHOD = 329, // \"REQUEST_METHOD\"\n    TOK_VARIABLE_REQUEST_PROTOCOL = 330, // \"REQUEST_PROTOCOL\"\n    TOK_VARIABLE_REQUEST_URI_RAW = 331, // \"REQUEST_URI_RAW\"\n    TOK_VARIABLE_REQUEST_URI = 332, // \"REQUEST_URI\"\n    TOK_VARIABLE_RESOURCE = 333,   // \"RESOURCE\"\n    TOK_VARIABLE_RESPONSE_BODY = 334, // \"RESPONSE_BODY\"\n    TOK_VARIABLE_RESPONSE_CONTENT_LENGTH = 335, // \"RESPONSE_CONTENT_LENGTH\"\n    TOK_VARIABLE_RESPONSE_CONTENT_TYPE = 336, // VARIABLE_RESPONSE_CONTENT_TYPE\n    TOK_VARIABLE_RESPONSE_HEADERS_NAMES = 337, // VARIABLE_RESPONSE_HEADERS_NAMES\n    TOK_VARIABLE_RESPONSE_PROTOCOL = 338, // \"RESPONSE_PROTOCOL\"\n    TOK_VARIABLE_RESPONSE_STATUS = 339, // \"RESPONSE_STATUS\"\n    TOK_VARIABLE_SERVER_ADDR = 340, // \"SERVER_ADDR\"\n    TOK_VARIABLE_SERVER_NAME = 341, // \"SERVER_NAME\"\n    TOK_VARIABLE_SERVER_PORT = 342, // \"SERVER_PORT\"\n    TOK_VARIABLE_SESSION_ID = 343, // \"SESSIONID\"\n    TOK_VARIABLE_UNIQUE_ID = 344,  // \"UNIQUE_ID\"\n    TOK_VARIABLE_URL_ENCODED_ERROR = 345, // \"URLENCODED_ERROR\"\n    TOK_VARIABLE_USER_ID = 346,    // \"USERID\"\n    TOK_VARIABLE_WEB_APP_ID = 347, // \"WEBAPPID\"\n    TOK_VARIABLE_STATUS = 348,     // \"VARIABLE_STATUS\"\n    TOK_VARIABLE_STATUS_LINE = 349, // \"VARIABLE_STATUS_LINE\"\n    TOK_VARIABLE_IP = 350,         // \"VARIABLE_IP\"\n    TOK_VARIABLE_GLOBAL = 351,     // \"VARIABLE_GLOBAL\"\n    TOK_VARIABLE_TX = 352,         // \"VARIABLE_TX\"\n    TOK_VARIABLE_SESSION = 353,    // \"VARIABLE_SESSION\"\n    TOK_VARIABLE_USER = 354,       // \"VARIABLE_USER\"\n    TOK_RUN_TIME_VAR_ENV = 355,    // \"RUN_TIME_VAR_ENV\"\n    TOK_RUN_TIME_VAR_XML = 356,    // \"RUN_TIME_VAR_XML\"\n    TOK_ACTION_SETVAR = 357,       // \"SetVar\"\n    TOK_SETVAR_OPERATION_EQUALS = 358, // SETVAR_OPERATION_EQUALS\n    TOK_SETVAR_OPERATION_EQUALS_PLUS = 359, // SETVAR_OPERATION_EQUALS_PLUS\n    TOK_SETVAR_OPERATION_EQUALS_MINUS = 360, // SETVAR_OPERATION_EQUALS_MINUS\n    TOK_NOT = 361,                 // \"NOT\"\n    TOK_OPERATOR_BEGINS_WITH = 362, // \"OPERATOR_BEGINS_WITH\"\n    TOK_OPERATOR_CONTAINS = 363,   // \"OPERATOR_CONTAINS\"\n    TOK_OPERATOR_CONTAINS_WORD = 364, // \"OPERATOR_CONTAINS_WORD\"\n    TOK_OPERATOR_DETECT_SQLI = 365, // \"OPERATOR_DETECT_SQLI\"\n    TOK_OPERATOR_DETECT_XSS = 366, // \"OPERATOR_DETECT_XSS\"\n    TOK_OPERATOR_ENDS_WITH = 367,  // \"OPERATOR_ENDS_WITH\"\n    TOK_OPERATOR_EQ = 368,         // \"OPERATOR_EQ\"\n    TOK_OPERATOR_FUZZY_HASH = 369, // \"OPERATOR_FUZZY_HASH\"\n    TOK_OPERATOR_GEOLOOKUP = 370,  // \"OPERATOR_GEOLOOKUP\"\n    TOK_OPERATOR_GE = 371,         // \"OPERATOR_GE\"\n    TOK_OPERATOR_GSB_LOOKUP = 372, // \"OPERATOR_GSB_LOOKUP\"\n    TOK_OPERATOR_GT = 373,         // \"OPERATOR_GT\"\n    TOK_OPERATOR_INSPECT_FILE = 374, // \"OPERATOR_INSPECT_FILE\"\n    TOK_OPERATOR_IP_MATCH_FROM_FILE = 375, // \"OPERATOR_IP_MATCH_FROM_FILE\"\n    TOK_OPERATOR_IP_MATCH = 376,   // \"OPERATOR_IP_MATCH\"\n    TOK_OPERATOR_LE = 377,         // \"OPERATOR_LE\"\n    TOK_OPERATOR_LT = 378,         // \"OPERATOR_LT\"\n    TOK_OPERATOR_PM_FROM_FILE = 379, // \"OPERATOR_PM_FROM_FILE\"\n    TOK_OPERATOR_PM = 380,         // \"OPERATOR_PM\"\n    TOK_OPERATOR_RBL = 381,        // \"OPERATOR_RBL\"\n    TOK_OPERATOR_RSUB = 382,       // \"OPERATOR_RSUB\"\n    TOK_OPERATOR_RX_CONTENT_ONLY = 383, // \"Operator RX (content only)\"\n    TOK_OPERATOR_RX = 384,         // \"OPERATOR_RX\"\n    TOK_OPERATOR_RX_GLOBAL = 385,  // \"OPERATOR_RX_GLOBAL\"\n    TOK_OPERATOR_STR_EQ = 386,     // \"OPERATOR_STR_EQ\"\n    TOK_OPERATOR_STR_MATCH = 387,  // \"OPERATOR_STR_MATCH\"\n    TOK_OPERATOR_UNCONDITIONAL_MATCH = 388, // \"OPERATOR_UNCONDITIONAL_MATCH\"\n    TOK_OPERATOR_VALIDATE_BYTE_RANGE = 389, // \"OPERATOR_VALIDATE_BYTE_RANGE\"\n    TOK_OPERATOR_VALIDATE_DTD = 390, // \"OPERATOR_VALIDATE_DTD\"\n    TOK_OPERATOR_VALIDATE_HASH = 391, // \"OPERATOR_VALIDATE_HASH\"\n    TOK_OPERATOR_VALIDATE_SCHEMA = 392, // \"OPERATOR_VALIDATE_SCHEMA\"\n    TOK_OPERATOR_VALIDATE_URL_ENCODING = 393, // \"OPERATOR_VALIDATE_URL_ENCODING\"\n    TOK_OPERATOR_VALIDATE_UTF8_ENCODING = 394, // \"OPERATOR_VALIDATE_UTF8_ENCODING\"\n    TOK_OPERATOR_VERIFY_CC = 395,  // \"OPERATOR_VERIFY_CC\"\n    TOK_OPERATOR_VERIFY_CPF = 396, // \"OPERATOR_VERIFY_CPF\"\n    TOK_OPERATOR_VERIFY_SSN = 397, // \"OPERATOR_VERIFY_SSN\"\n    TOK_OPERATOR_VERIFY_SVNR = 398, // \"OPERATOR_VERIFY_SVNR\"\n    TOK_OPERATOR_WITHIN = 399,     // \"OPERATOR_WITHIN\"\n    TOK_CONFIG_DIR_AUDIT_LOG_FMT = 400, // CONFIG_DIR_AUDIT_LOG_FMT\n    TOK_JSON = 401,                // JSON\n    TOK_NATIVE = 402,              // NATIVE\n    TOK_ACTION_CTL_RULE_ENGINE = 403, // \"ACTION_CTL_RULE_ENGINE\"\n    TOK_ACTION_ACCURACY = 404,     // \"Accuracy\"\n    TOK_ACTION_ALLOW = 405,        // \"Allow\"\n    TOK_ACTION_APPEND = 406,       // \"Append\"\n    TOK_ACTION_AUDIT_LOG = 407,    // \"AuditLog\"\n    TOK_ACTION_BLOCK = 408,        // \"Block\"\n    TOK_ACTION_CAPTURE = 409,      // \"Capture\"\n    TOK_ACTION_CHAIN = 410,        // \"Chain\"\n    TOK_ACTION_CTL_AUDIT_ENGINE = 411, // \"ACTION_CTL_AUDIT_ENGINE\"\n    TOK_ACTION_CTL_AUDIT_LOG_PARTS = 412, // \"ACTION_CTL_AUDIT_LOG_PARTS\"\n    TOK_ACTION_CTL_BDY_JSON = 413, // \"ACTION_CTL_BDY_JSON\"\n    TOK_ACTION_CTL_BDY_XML = 414,  // \"ACTION_CTL_BDY_XML\"\n    TOK_ACTION_CTL_BDY_URLENCODED = 415, // \"ACTION_CTL_BDY_URLENCODED\"\n    TOK_ACTION_CTL_FORCE_REQ_BODY_VAR = 416, // \"ACTION_CTL_FORCE_REQ_BODY_VAR\"\n    TOK_ACTION_CTL_PARSE_XML_INTO_ARGS = 417, // \"ACTION_CTL_PARSE_XML_INTO_ARGS\"\n    TOK_ACTION_CTL_REQUEST_BODY_ACCESS = 418, // \"ACTION_CTL_REQUEST_BODY_ACCESS\"\n    TOK_ACTION_CTL_RULE_REMOVE_BY_ID = 419, // \"ACTION_CTL_RULE_REMOVE_BY_ID\"\n    TOK_ACTION_CTL_RULE_REMOVE_BY_TAG = 420, // \"ACTION_CTL_RULE_REMOVE_BY_TAG\"\n    TOK_ACTION_CTL_RULE_REMOVE_TARGET_BY_ID = 421, // \"ACTION_CTL_RULE_REMOVE_TARGET_BY_ID\"\n    TOK_ACTION_CTL_RULE_REMOVE_TARGET_BY_TAG = 422, // \"ACTION_CTL_RULE_REMOVE_TARGET_BY_TAG\"\n    TOK_ACTION_DENY = 423,         // \"Deny\"\n    TOK_ACTION_DEPRECATE_VAR = 424, // \"DeprecateVar\"\n    TOK_ACTION_DROP = 425,         // \"Drop\"\n    TOK_ACTION_EXEC = 426,         // \"Exec\"\n    TOK_ACTION_EXPIRE_VAR = 427,   // \"ExpireVar\"\n    TOK_ACTION_ID = 428,           // \"Id\"\n    TOK_ACTION_INITCOL = 429,      // \"InitCol\"\n    TOK_ACTION_LOG = 430,          // \"Log\"\n    TOK_ACTION_LOG_DATA = 431,     // \"LogData\"\n    TOK_ACTION_MATURITY = 432,     // \"Maturity\"\n    TOK_ACTION_MSG = 433,          // \"Msg\"\n    TOK_ACTION_MULTI_MATCH = 434,  // \"MultiMatch\"\n    TOK_ACTION_NO_AUDIT_LOG = 435, // \"NoAuditLog\"\n    TOK_ACTION_NO_LOG = 436,       // \"NoLog\"\n    TOK_ACTION_PASS = 437,         // \"Pass\"\n    TOK_ACTION_PAUSE = 438,        // \"Pause\"\n    TOK_ACTION_PHASE = 439,        // \"Phase\"\n    TOK_ACTION_PREPEND = 440,      // \"Prepend\"\n    TOK_ACTION_PROXY = 441,        // \"Proxy\"\n    TOK_ACTION_REDIRECT = 442,     // \"Redirect\"\n    TOK_ACTION_REV = 443,          // \"Rev\"\n    TOK_ACTION_SANITISE_ARG = 444, // \"SanitiseArg\"\n    TOK_ACTION_SANITISE_MATCHED = 445, // \"SanitiseMatched\"\n    TOK_ACTION_SANITISE_MATCHED_BYTES = 446, // \"SanitiseMatchedBytes\"\n    TOK_ACTION_SANITISE_REQUEST_HEADER = 447, // \"SanitiseRequestHeader\"\n    TOK_ACTION_SANITISE_RESPONSE_HEADER = 448, // \"SanitiseResponseHeader\"\n    TOK_ACTION_SETENV = 449,       // \"SetEnv\"\n    TOK_ACTION_SETRSC = 450,       // \"SetRsc\"\n    TOK_ACTION_SETSID = 451,       // \"SetSid\"\n    TOK_ACTION_SETUID = 452,       // \"SetUID\"\n    TOK_ACTION_SEVERITY = 453,     // \"Severity\"\n    TOK_ACTION_SKIP = 454,         // \"Skip\"\n    TOK_ACTION_SKIP_AFTER = 455,   // \"SkipAfter\"\n    TOK_ACTION_STATUS = 456,       // \"Status\"\n    TOK_ACTION_TAG = 457,          // \"Tag\"\n    TOK_ACTION_TRANSFORMATION_BASE_64_ENCODE = 458, // \"ACTION_TRANSFORMATION_BASE_64_ENCODE\"\n    TOK_ACTION_TRANSFORMATION_BASE_64_DECODE = 459, // \"ACTION_TRANSFORMATION_BASE_64_DECODE\"\n    TOK_ACTION_TRANSFORMATION_BASE_64_DECODE_EXT = 460, // \"ACTION_TRANSFORMATION_BASE_64_DECODE_EXT\"\n    TOK_ACTION_TRANSFORMATION_CMD_LINE = 461, // \"ACTION_TRANSFORMATION_CMD_LINE\"\n    TOK_ACTION_TRANSFORMATION_COMPRESS_WHITESPACE = 462, // \"ACTION_TRANSFORMATION_COMPRESS_WHITESPACE\"\n    TOK_ACTION_TRANSFORMATION_CSS_DECODE = 463, // \"ACTION_TRANSFORMATION_CSS_DECODE\"\n    TOK_ACTION_TRANSFORMATION_ESCAPE_SEQ_DECODE = 464, // \"ACTION_TRANSFORMATION_ESCAPE_SEQ_DECODE\"\n    TOK_ACTION_TRANSFORMATION_HEX_ENCODE = 465, // \"ACTION_TRANSFORMATION_HEX_ENCODE\"\n    TOK_ACTION_TRANSFORMATION_HEX_DECODE = 466, // \"ACTION_TRANSFORMATION_HEX_DECODE\"\n    TOK_ACTION_TRANSFORMATION_HTML_ENTITY_DECODE = 467, // \"ACTION_TRANSFORMATION_HTML_ENTITY_DECODE\"\n    TOK_ACTION_TRANSFORMATION_JS_DECODE = 468, // \"ACTION_TRANSFORMATION_JS_DECODE\"\n    TOK_ACTION_TRANSFORMATION_LENGTH = 469, // \"ACTION_TRANSFORMATION_LENGTH\"\n    TOK_ACTION_TRANSFORMATION_LOWERCASE = 470, // \"ACTION_TRANSFORMATION_LOWERCASE\"\n    TOK_ACTION_TRANSFORMATION_MD5 = 471, // \"ACTION_TRANSFORMATION_MD5\"\n    TOK_ACTION_TRANSFORMATION_NONE = 472, // \"ACTION_TRANSFORMATION_NONE\"\n    TOK_ACTION_TRANSFORMATION_NORMALISE_PATH = 473, // \"ACTION_TRANSFORMATION_NORMALISE_PATH\"\n    TOK_ACTION_TRANSFORMATION_NORMALISE_PATH_WIN = 474, // \"ACTION_TRANSFORMATION_NORMALISE_PATH_WIN\"\n    TOK_ACTION_TRANSFORMATION_PARITY_EVEN_7_BIT = 475, // \"ACTION_TRANSFORMATION_PARITY_EVEN_7_BIT\"\n    TOK_ACTION_TRANSFORMATION_PARITY_ODD_7_BIT = 476, // \"ACTION_TRANSFORMATION_PARITY_ODD_7_BIT\"\n    TOK_ACTION_TRANSFORMATION_PARITY_ZERO_7_BIT = 477, // \"ACTION_TRANSFORMATION_PARITY_ZERO_7_BIT\"\n    TOK_ACTION_TRANSFORMATION_REMOVE_COMMENTS = 478, // \"ACTION_TRANSFORMATION_REMOVE_COMMENTS\"\n    TOK_ACTION_TRANSFORMATION_REMOVE_COMMENTS_CHAR = 479, // \"ACTION_TRANSFORMATION_REMOVE_COMMENTS_CHAR\"\n    TOK_ACTION_TRANSFORMATION_REMOVE_NULLS = 480, // \"ACTION_TRANSFORMATION_REMOVE_NULLS\"\n    TOK_ACTION_TRANSFORMATION_REMOVE_WHITESPACE = 481, // \"ACTION_TRANSFORMATION_REMOVE_WHITESPACE\"\n    TOK_ACTION_TRANSFORMATION_REPLACE_COMMENTS = 482, // \"ACTION_TRANSFORMATION_REPLACE_COMMENTS\"\n    TOK_ACTION_TRANSFORMATION_REPLACE_NULLS = 483, // \"ACTION_TRANSFORMATION_REPLACE_NULLS\"\n    TOK_ACTION_TRANSFORMATION_SHA1 = 484, // \"ACTION_TRANSFORMATION_SHA1\"\n    TOK_ACTION_TRANSFORMATION_SQL_HEX_DECODE = 485, // \"ACTION_TRANSFORMATION_SQL_HEX_DECODE\"\n    TOK_ACTION_TRANSFORMATION_TRIM = 486, // \"ACTION_TRANSFORMATION_TRIM\"\n    TOK_ACTION_TRANSFORMATION_TRIM_LEFT = 487, // \"ACTION_TRANSFORMATION_TRIM_LEFT\"\n    TOK_ACTION_TRANSFORMATION_TRIM_RIGHT = 488, // \"ACTION_TRANSFORMATION_TRIM_RIGHT\"\n    TOK_ACTION_TRANSFORMATION_UPPERCASE = 489, // \"ACTION_TRANSFORMATION_UPPERCASE\"\n    TOK_ACTION_TRANSFORMATION_URL_ENCODE = 490, // \"ACTION_TRANSFORMATION_URL_ENCODE\"\n    TOK_ACTION_TRANSFORMATION_URL_DECODE = 491, // \"ACTION_TRANSFORMATION_URL_DECODE\"\n    TOK_ACTION_TRANSFORMATION_URL_DECODE_UNI = 492, // \"ACTION_TRANSFORMATION_URL_DECODE_UNI\"\n    TOK_ACTION_TRANSFORMATION_UTF8_TO_UNICODE = 493, // \"ACTION_TRANSFORMATION_UTF8_TO_UNICODE\"\n    TOK_ACTION_VER = 494,          // \"Ver\"\n    TOK_ACTION_XMLNS = 495,        // \"xmlns\"\n    TOK_CONFIG_COMPONENT_SIG = 496, // \"CONFIG_COMPONENT_SIG\"\n    TOK_CONFIG_CONN_ENGINE = 497,  // \"CONFIG_CONN_ENGINE\"\n    TOK_CONFIG_SEC_ARGUMENT_SEPARATOR = 498, // \"CONFIG_SEC_ARGUMENT_SEPARATOR\"\n    TOK_CONFIG_SEC_WEB_APP_ID = 499, // \"CONFIG_SEC_WEB_APP_ID\"\n    TOK_CONFIG_SEC_SERVER_SIG = 500, // \"CONFIG_SEC_SERVER_SIG\"\n    TOK_CONFIG_DIR_AUDIT_DIR = 501, // \"CONFIG_DIR_AUDIT_DIR\"\n    TOK_CONFIG_DIR_AUDIT_DIR_MOD = 502, // \"CONFIG_DIR_AUDIT_DIR_MOD\"\n    TOK_CONFIG_DIR_AUDIT_ENG = 503, // \"CONFIG_DIR_AUDIT_ENG\"\n    TOK_CONFIG_DIR_AUDIT_FLE_MOD = 504, // \"CONFIG_DIR_AUDIT_FLE_MOD\"\n    TOK_CONFIG_DIR_AUDIT_LOG = 505, // \"CONFIG_DIR_AUDIT_LOG\"\n    TOK_CONFIG_DIR_AUDIT_LOG2 = 506, // \"CONFIG_DIR_AUDIT_LOG2\"\n    TOK_CONFIG_DIR_AUDIT_LOG_P = 507, // \"CONFIG_DIR_AUDIT_LOG_P\"\n    TOK_CONFIG_DIR_AUDIT_STS = 508, // \"CONFIG_DIR_AUDIT_STS\"\n    TOK_CONFIG_DIR_AUDIT_PREFIX = 509, // \"CONFIG_DIR_AUDIT_PREFIX\"\n    TOK_CONFIG_DIR_AUDIT_TPE = 510, // \"CONFIG_DIR_AUDIT_TPE\"\n    TOK_CONFIG_DIR_DEBUG_LOG = 511, // \"CONFIG_DIR_DEBUG_LOG\"\n    TOK_CONFIG_DIR_DEBUG_LVL = 512, // \"CONFIG_DIR_DEBUG_LVL\"\n    TOK_CONFIG_SEC_CACHE_TRANSFORMATIONS = 513, // \"CONFIG_SEC_CACHE_TRANSFORMATIONS\"\n    TOK_CONFIG_SEC_DISABLE_BACKEND_COMPRESS = 514, // \"CONFIG_SEC_DISABLE_BACKEND_COMPRESS\"\n    TOK_CONFIG_SEC_HASH_ENGINE = 515, // \"CONFIG_SEC_HASH_ENGINE\"\n    TOK_CONFIG_SEC_HASH_KEY = 516, // \"CONFIG_SEC_HASH_KEY\"\n    TOK_CONFIG_SEC_HASH_PARAM = 517, // \"CONFIG_SEC_HASH_PARAM\"\n    TOK_CONFIG_SEC_HASH_METHOD_RX = 518, // \"CONFIG_SEC_HASH_METHOD_RX\"\n    TOK_CONFIG_SEC_HASH_METHOD_PM = 519, // \"CONFIG_SEC_HASH_METHOD_PM\"\n    TOK_CONFIG_SEC_CHROOT_DIR = 520, // \"CONFIG_SEC_CHROOT_DIR\"\n    TOK_CONFIG_DIR_GEO_DB = 521,   // \"CONFIG_DIR_GEO_DB\"\n    TOK_CONFIG_DIR_GSB_DB = 522,   // \"CONFIG_DIR_GSB_DB\"\n    TOK_CONFIG_SEC_GUARDIAN_LOG = 523, // \"CONFIG_SEC_GUARDIAN_LOG\"\n    TOK_CONFIG_DIR_PCRE_MATCH_LIMIT = 524, // \"CONFIG_DIR_PCRE_MATCH_LIMIT\"\n    TOK_CONFIG_DIR_PCRE_MATCH_LIMIT_RECURSION = 525, // \"CONFIG_DIR_PCRE_MATCH_LIMIT_RECURSION\"\n    TOK_CONFIG_SEC_CONN_R_STATE_LIMIT = 526, // \"CONFIG_SEC_CONN_R_STATE_LIMIT\"\n    TOK_CONFIG_SEC_CONN_W_STATE_LIMIT = 527, // \"CONFIG_SEC_CONN_W_STATE_LIMIT\"\n    TOK_CONFIG_SEC_SENSOR_ID = 528, // \"CONFIG_SEC_SENSOR_ID\"\n    TOK_CONFIG_DIR_ARGS_LIMIT = 529, // \"CONFIG_DIR_ARGS_LIMIT\"\n    TOK_CONFIG_DIR_REQ_BODY_JSON_DEPTH_LIMIT = 530, // \"CONFIG_DIR_REQ_BODY_JSON_DEPTH_LIMIT\"\n    TOK_CONFIG_DIR_REQ_BODY = 531, // \"CONFIG_DIR_REQ_BODY\"\n    TOK_CONFIG_DIR_REQ_BODY_IN_MEMORY_LIMIT = 532, // \"CONFIG_DIR_REQ_BODY_IN_MEMORY_LIMIT\"\n    TOK_CONFIG_DIR_REQ_BODY_LIMIT = 533, // \"CONFIG_DIR_REQ_BODY_LIMIT\"\n    TOK_CONFIG_DIR_REQ_BODY_LIMIT_ACTION = 534, // \"CONFIG_DIR_REQ_BODY_LIMIT_ACTION\"\n    TOK_CONFIG_DIR_REQ_BODY_NO_FILES_LIMIT = 535, // \"CONFIG_DIR_REQ_BODY_NO_FILES_LIMIT\"\n    TOK_CONFIG_DIR_RES_BODY = 536, // \"CONFIG_DIR_RES_BODY\"\n    TOK_CONFIG_DIR_RES_BODY_LIMIT = 537, // \"CONFIG_DIR_RES_BODY_LIMIT\"\n    TOK_CONFIG_DIR_RES_BODY_LIMIT_ACTION = 538, // \"CONFIG_DIR_RES_BODY_LIMIT_ACTION\"\n    TOK_CONFIG_SEC_RULE_INHERITANCE = 539, // \"CONFIG_SEC_RULE_INHERITANCE\"\n    TOK_CONFIG_SEC_RULE_PERF_TIME = 540, // \"CONFIG_SEC_RULE_PERF_TIME\"\n    TOK_CONFIG_DIR_RULE_ENG = 541, // \"CONFIG_DIR_RULE_ENG\"\n    TOK_CONFIG_DIR_SEC_ACTION = 542, // \"CONFIG_DIR_SEC_ACTION\"\n    TOK_CONFIG_DIR_SEC_DEFAULT_ACTION = 543, // \"CONFIG_DIR_SEC_DEFAULT_ACTION\"\n    TOK_CONFIG_DIR_SEC_MARKER = 544, // \"CONFIG_DIR_SEC_MARKER\"\n    TOK_CONFIG_DIR_UNICODE_MAP_FILE = 545, // \"CONFIG_DIR_UNICODE_MAP_FILE\"\n    TOK_CONFIG_DIR_UNICODE_CODE_PAGE = 546, // \"CONFIG_DIR_UNICODE_CODE_PAGE\"\n    TOK_CONFIG_SEC_COLLECTION_TIMEOUT = 547, // \"CONFIG_SEC_COLLECTION_TIMEOUT\"\n    TOK_CONFIG_SEC_HTTP_BLKEY = 548, // \"CONFIG_SEC_HTTP_BLKEY\"\n    TOK_CONFIG_SEC_INTERCEPT_ON_ERROR = 549, // \"CONFIG_SEC_INTERCEPT_ON_ERROR\"\n    TOK_CONFIG_SEC_REMOTE_RULES_FAIL_ACTION = 550, // \"CONFIG_SEC_REMOTE_RULES_FAIL_ACTION\"\n    TOK_CONFIG_SEC_RULE_REMOVE_BY_ID = 551, // \"CONFIG_SEC_RULE_REMOVE_BY_ID\"\n    TOK_CONFIG_SEC_RULE_REMOVE_BY_MSG = 552, // \"CONFIG_SEC_RULE_REMOVE_BY_MSG\"\n    TOK_CONFIG_SEC_RULE_REMOVE_BY_TAG = 553, // \"CONFIG_SEC_RULE_REMOVE_BY_TAG\"\n    TOK_CONFIG_SEC_RULE_UPDATE_TARGET_BY_TAG = 554, // \"CONFIG_SEC_RULE_UPDATE_TARGET_BY_TAG\"\n    TOK_CONFIG_SEC_RULE_UPDATE_TARGET_BY_MSG = 555, // \"CONFIG_SEC_RULE_UPDATE_TARGET_BY_MSG\"\n    TOK_CONFIG_SEC_RULE_UPDATE_TARGET_BY_ID = 556, // \"CONFIG_SEC_RULE_UPDATE_TARGET_BY_ID\"\n    TOK_CONFIG_SEC_RULE_UPDATE_ACTION_BY_ID = 557, // \"CONFIG_SEC_RULE_UPDATE_ACTION_BY_ID\"\n    TOK_CONFIG_UPDLOAD_KEEP_FILES = 558, // \"CONFIG_UPDLOAD_KEEP_FILES\"\n    TOK_CONFIG_UPDLOAD_SAVE_TMP_FILES = 559, // \"CONFIG_UPDLOAD_SAVE_TMP_FILES\"\n    TOK_CONFIG_UPLOAD_DIR = 560,   // \"CONFIG_UPLOAD_DIR\"\n    TOK_CONFIG_UPLOAD_FILE_LIMIT = 561, // \"CONFIG_UPLOAD_FILE_LIMIT\"\n    TOK_CONFIG_UPLOAD_FILE_MODE = 562, // \"CONFIG_UPLOAD_FILE_MODE\"\n    TOK_CONFIG_VALUE_ABORT = 563,  // \"CONFIG_VALUE_ABORT\"\n    TOK_CONFIG_VALUE_DETC = 564,   // \"CONFIG_VALUE_DETC\"\n    TOK_CONFIG_VALUE_HTTPS = 565,  // \"CONFIG_VALUE_HTTPS\"\n    TOK_CONFIG_VALUE_ONLYARGS = 566, // \"CONFIG_VALUE_ONLYARGS\"\n    TOK_CONFIG_VALUE_OFF = 567,    // \"CONFIG_VALUE_OFF\"\n    TOK_CONFIG_VALUE_ON = 568,     // \"CONFIG_VALUE_ON\"\n    TOK_CONFIG_VALUE_PARALLEL = 569, // \"CONFIG_VALUE_PARALLEL\"\n    TOK_CONFIG_VALUE_PROCESS_PARTIAL = 570, // \"CONFIG_VALUE_PROCESS_PARTIAL\"\n    TOK_CONFIG_VALUE_REJECT = 571, // \"CONFIG_VALUE_REJECT\"\n    TOK_CONFIG_VALUE_RELEVANT_ONLY = 572, // \"CONFIG_VALUE_RELEVANT_ONLY\"\n    TOK_CONFIG_VALUE_SERIAL = 573, // \"CONFIG_VALUE_SERIAL\"\n    TOK_CONFIG_VALUE_WARN = 574,   // \"CONFIG_VALUE_WARN\"\n    TOK_CONFIG_XML_EXTERNAL_ENTITY = 575, // \"CONFIG_XML_EXTERNAL_ENTITY\"\n    TOK_CONFIG_XML_PARSE_XML_INTO_ARGS = 576, // \"CONFIG_XML_PARSE_XML_INTO_ARGS\"\n    TOK_CONGIG_DIR_RESPONSE_BODY_MP = 577, // \"CONGIG_DIR_RESPONSE_BODY_MP\"\n    TOK_CONGIG_DIR_SEC_ARG_SEP = 578, // \"CONGIG_DIR_SEC_ARG_SEP\"\n    TOK_CONGIG_DIR_SEC_COOKIE_FORMAT = 579, // \"CONGIG_DIR_SEC_COOKIE_FORMAT\"\n    TOK_CONFIG_SEC_COOKIEV0_SEPARATOR = 580, // \"CONFIG_SEC_COOKIEV0_SEPARATOR\"\n    TOK_CONGIG_DIR_SEC_DATA_DIR = 581, // \"CONGIG_DIR_SEC_DATA_DIR\"\n    TOK_CONGIG_DIR_SEC_STATUS_ENGINE = 582, // \"CONGIG_DIR_SEC_STATUS_ENGINE\"\n    TOK_CONFIG_SEC_STREAM_IN_BODY_INSPECTION = 583, // \"CONFIG_SEC_STREAM_IN_BODY_INSPECTION\"\n    TOK_CONFIG_SEC_STREAM_OUT_BODY_INSPECTION = 584, // \"CONFIG_SEC_STREAM_OUT_BODY_INSPECTION\"\n    TOK_CONGIG_DIR_SEC_TMP_DIR = 585, // \"CONGIG_DIR_SEC_TMP_DIR\"\n    TOK_DIRECTIVE = 586,           // \"DIRECTIVE\"\n    TOK_DIRECTIVE_SECRULESCRIPT = 587, // \"DIRECTIVE_SECRULESCRIPT\"\n    TOK_FREE_TEXT_QUOTE_MACRO_EXPANSION = 588, // \"FREE_TEXT_QUOTE_MACRO_EXPANSION\"\n    TOK_QUOTATION_MARK = 589,      // \"QUOTATION_MARK\"\n    TOK_RUN_TIME_VAR_BLD = 590,    // \"RUN_TIME_VAR_BLD\"\n    TOK_RUN_TIME_VAR_DUR = 591,    // \"RUN_TIME_VAR_DUR\"\n    TOK_RUN_TIME_VAR_HSV = 592,    // \"RUN_TIME_VAR_HSV\"\n    TOK_RUN_TIME_VAR_REMOTE_USER = 593, // \"RUN_TIME_VAR_REMOTE_USER\"\n    TOK_RUN_TIME_VAR_TIME = 594,   // \"RUN_TIME_VAR_TIME\"\n    TOK_RUN_TIME_VAR_TIME_DAY = 595, // \"RUN_TIME_VAR_TIME_DAY\"\n    TOK_RUN_TIME_VAR_TIME_EPOCH = 596, // \"RUN_TIME_VAR_TIME_EPOCH\"\n    TOK_RUN_TIME_VAR_TIME_HOUR = 597, // \"RUN_TIME_VAR_TIME_HOUR\"\n    TOK_RUN_TIME_VAR_TIME_MIN = 598, // \"RUN_TIME_VAR_TIME_MIN\"\n    TOK_RUN_TIME_VAR_TIME_MON = 599, // \"RUN_TIME_VAR_TIME_MON\"\n    TOK_RUN_TIME_VAR_TIME_SEC = 600, // \"RUN_TIME_VAR_TIME_SEC\"\n    TOK_RUN_TIME_VAR_TIME_WDAY = 601, // \"RUN_TIME_VAR_TIME_WDAY\"\n    TOK_RUN_TIME_VAR_TIME_YEAR = 602, // \"RUN_TIME_VAR_TIME_YEAR\"\n    TOK_VARIABLE = 603,            // \"VARIABLE\"\n    TOK_DICT_ELEMENT = 604,        // \"Dictionary element\"\n    TOK_DICT_ELEMENT_WITH_EQUALS = 605, // \"Dictionary element, with equals\"\n    TOK_DICT_ELEMENT_REGEXP = 606  // \"Dictionary element, selected by regexp\"\n      };\n      /// Backward compatibility alias (Bison 3.6).\n      typedef token_kind_type yytokentype;\n    };\n\n    /// Token kind, as returned by yylex.\n    typedef token::token_kind_type token_kind_type;\n\n    /// Backward compatibility alias (Bison 3.6).\n    typedef token_kind_type token_type;\n\n    /// Symbol kinds.\n    struct symbol_kind\n    {\n      enum symbol_kind_type\n      {\n        YYNTOKENS = 352, ///< Number of tokens.\n        S_YYEMPTY = -2,\n        S_YYEOF = 0,                             // \"end of file\"\n        S_YYerror = 1,                           // error\n        S_YYUNDEF = 2,                           // \"invalid token\"\n        S_COMMA = 3,                             // \",\"\n        S_CONFIG_CONTENT_INJECTION = 4,          // \"CONFIG_CONTENT_INJECTION\"\n        S_CONGIG_DIR_RESPONSE_BODY_MP_CLEAR = 5, // \"CONGIG_DIR_RESPONSE_BODY_MP_CLEAR\"\n        S_PIPE = 6,                              // PIPE\n        S_NEW_LINE = 7,                          // NEW_LINE\n        S_VAR_COUNT = 8,                         // VAR_COUNT\n        S_VAR_EXCLUSION = 9,                     // VAR_EXCLUSION\n        S_VARIABLE_ARGS = 10,                    // VARIABLE_ARGS\n        S_VARIABLE_ARGS_POST = 11,               // VARIABLE_ARGS_POST\n        S_VARIABLE_ARGS_GET = 12,                // VARIABLE_ARGS_GET\n        S_VARIABLE_FILES_SIZES = 13,             // VARIABLE_FILES_SIZES\n        S_VARIABLE_FILES_NAMES = 14,             // VARIABLE_FILES_NAMES\n        S_VARIABLE_FILES_TMP_CONTENT = 15,       // VARIABLE_FILES_TMP_CONTENT\n        S_VARIABLE_MULTIPART_FILENAME = 16,      // VARIABLE_MULTIPART_FILENAME\n        S_VARIABLE_MULTIPART_NAME = 17,          // VARIABLE_MULTIPART_NAME\n        S_VARIABLE_MATCHED_VARS_NAMES = 18,      // VARIABLE_MATCHED_VARS_NAMES\n        S_VARIABLE_MATCHED_VARS = 19,            // VARIABLE_MATCHED_VARS\n        S_VARIABLE_FILES = 20,                   // VARIABLE_FILES\n        S_VARIABLE_REQUEST_COOKIES = 21,         // VARIABLE_REQUEST_COOKIES\n        S_VARIABLE_REQUEST_HEADERS = 22,         // VARIABLE_REQUEST_HEADERS\n        S_VARIABLE_RESPONSE_HEADERS = 23,        // VARIABLE_RESPONSE_HEADERS\n        S_VARIABLE_GEO = 24,                     // VARIABLE_GEO\n        S_VARIABLE_REQUEST_COOKIES_NAMES = 25,   // VARIABLE_REQUEST_COOKIES_NAMES\n        S_VARIABLE_MULTIPART_PART_HEADERS = 26,  // VARIABLE_MULTIPART_PART_HEADERS\n        S_VARIABLE_ARGS_COMBINED_SIZE = 27,      // VARIABLE_ARGS_COMBINED_SIZE\n        S_VARIABLE_ARGS_GET_NAMES = 28,          // VARIABLE_ARGS_GET_NAMES\n        S_VARIABLE_RULE = 29,                    // VARIABLE_RULE\n        S_VARIABLE_ARGS_NAMES = 30,              // \"Variable ARGS_NAMES\"\n        S_VARIABLE_ARGS_POST_NAMES = 31,         // VARIABLE_ARGS_POST_NAMES\n        S_VARIABLE_AUTH_TYPE = 32,               // \"AUTH_TYPE\"\n        S_VARIABLE_FILES_COMBINED_SIZE = 33,     // \"FILES_COMBINED_SIZE\"\n        S_VARIABLE_FILES_TMP_NAMES = 34,         // \"FILES_TMPNAMES\"\n        S_VARIABLE_FULL_REQUEST = 35,            // \"FULL_REQUEST\"\n        S_VARIABLE_FULL_REQUEST_LENGTH = 36,     // \"FULL_REQUEST_LENGTH\"\n        S_VARIABLE_INBOUND_DATA_ERROR = 37,      // \"INBOUND_DATA_ERROR\"\n        S_VARIABLE_MATCHED_VAR = 38,             // \"MATCHED_VAR\"\n        S_VARIABLE_MATCHED_VAR_NAME = 39,        // \"MATCHED_VAR_NAME\"\n        S_VARIABLE_MSC_PCRE_ERROR = 40,          // \"MSC_PCRE_ERROR\"\n        S_VARIABLE_MSC_PCRE_LIMITS_EXCEEDED = 41, // \"MSC_PCRE_LIMITS_EXCEEDED\"\n        S_VARIABLE_MULTIPART_BOUNDARY_QUOTED = 42, // VARIABLE_MULTIPART_BOUNDARY_QUOTED\n        S_VARIABLE_MULTIPART_BOUNDARY_WHITESPACE = 43, // VARIABLE_MULTIPART_BOUNDARY_WHITESPACE\n        S_VARIABLE_MULTIPART_CRLF_LF_LINES = 44, // \"MULTIPART_CRLF_LF_LINES\"\n        S_VARIABLE_MULTIPART_DATA_AFTER = 45,    // \"MULTIPART_DATA_AFTER\"\n        S_VARIABLE_MULTIPART_DATA_BEFORE = 46,   // VARIABLE_MULTIPART_DATA_BEFORE\n        S_VARIABLE_MULTIPART_FILE_LIMIT_EXCEEDED = 47, // \"MULTIPART_FILE_LIMIT_EXCEEDED\"\n        S_VARIABLE_MULTIPART_HEADER_FOLDING = 48, // \"MULTIPART_HEADER_FOLDING\"\n        S_VARIABLE_MULTIPART_INVALID_HEADER_FOLDING = 49, // \"MULTIPART_INVALID_HEADER_FOLDING\"\n        S_VARIABLE_MULTIPART_INVALID_PART = 50,  // VARIABLE_MULTIPART_INVALID_PART\n        S_VARIABLE_MULTIPART_INVALID_QUOTING = 51, // \"MULTIPART_INVALID_QUOTING\"\n        S_VARIABLE_MULTIPART_LF_LINE = 52,       // VARIABLE_MULTIPART_LF_LINE\n        S_VARIABLE_MULTIPART_MISSING_SEMICOLON = 53, // VARIABLE_MULTIPART_MISSING_SEMICOLON\n        S_VARIABLE_MULTIPART_SEMICOLON_MISSING = 54, // VARIABLE_MULTIPART_SEMICOLON_MISSING\n        S_VARIABLE_MULTIPART_STRICT_ERROR = 55,  // \"MULTIPART_STRICT_ERROR\"\n        S_VARIABLE_MULTIPART_UNMATCHED_BOUNDARY = 56, // \"MULTIPART_UNMATCHED_BOUNDARY\"\n        S_VARIABLE_OUTBOUND_DATA_ERROR = 57,     // \"OUTBOUND_DATA_ERROR\"\n        S_VARIABLE_PATH_INFO = 58,               // \"PATH_INFO\"\n        S_VARIABLE_QUERY_STRING = 59,            // \"QUERY_STRING\"\n        S_VARIABLE_REMOTE_ADDR = 60,             // \"REMOTE_ADDR\"\n        S_VARIABLE_REMOTE_HOST = 61,             // \"REMOTE_HOST\"\n        S_VARIABLE_REMOTE_PORT = 62,             // \"REMOTE_PORT\"\n        S_VARIABLE_REQBODY_ERROR_MSG = 63,       // \"REQBODY_ERROR_MSG\"\n        S_VARIABLE_REQBODY_ERROR = 64,           // \"REQBODY_ERROR\"\n        S_VARIABLE_REQBODY_PROCESSOR_ERROR_MSG = 65, // \"REQBODY_PROCESSOR_ERROR_MSG\"\n        S_VARIABLE_REQBODY_PROCESSOR_ERROR = 66, // \"REQBODY_PROCESSOR_ERROR\"\n        S_VARIABLE_REQBODY_PROCESSOR = 67,       // \"REQBODY_PROCESSOR\"\n        S_VARIABLE_REQUEST_BASENAME = 68,        // \"REQUEST_BASENAME\"\n        S_VARIABLE_REQUEST_BODY_LENGTH = 69,     // \"REQUEST_BODY_LENGTH\"\n        S_VARIABLE_REQUEST_BODY = 70,            // \"REQUEST_BODY\"\n        S_VARIABLE_REQUEST_FILE_NAME = 71,       // \"REQUEST_FILENAME\"\n        S_VARIABLE_REQUEST_HEADERS_NAMES = 72,   // VARIABLE_REQUEST_HEADERS_NAMES\n        S_VARIABLE_REQUEST_LINE = 73,            // \"REQUEST_LINE\"\n        S_VARIABLE_REQUEST_METHOD = 74,          // \"REQUEST_METHOD\"\n        S_VARIABLE_REQUEST_PROTOCOL = 75,        // \"REQUEST_PROTOCOL\"\n        S_VARIABLE_REQUEST_URI_RAW = 76,         // \"REQUEST_URI_RAW\"\n        S_VARIABLE_REQUEST_URI = 77,             // \"REQUEST_URI\"\n        S_VARIABLE_RESOURCE = 78,                // \"RESOURCE\"\n        S_VARIABLE_RESPONSE_BODY = 79,           // \"RESPONSE_BODY\"\n        S_VARIABLE_RESPONSE_CONTENT_LENGTH = 80, // \"RESPONSE_CONTENT_LENGTH\"\n        S_VARIABLE_RESPONSE_CONTENT_TYPE = 81,   // VARIABLE_RESPONSE_CONTENT_TYPE\n        S_VARIABLE_RESPONSE_HEADERS_NAMES = 82,  // VARIABLE_RESPONSE_HEADERS_NAMES\n        S_VARIABLE_RESPONSE_PROTOCOL = 83,       // \"RESPONSE_PROTOCOL\"\n        S_VARIABLE_RESPONSE_STATUS = 84,         // \"RESPONSE_STATUS\"\n        S_VARIABLE_SERVER_ADDR = 85,             // \"SERVER_ADDR\"\n        S_VARIABLE_SERVER_NAME = 86,             // \"SERVER_NAME\"\n        S_VARIABLE_SERVER_PORT = 87,             // \"SERVER_PORT\"\n        S_VARIABLE_SESSION_ID = 88,              // \"SESSIONID\"\n        S_VARIABLE_UNIQUE_ID = 89,               // \"UNIQUE_ID\"\n        S_VARIABLE_URL_ENCODED_ERROR = 90,       // \"URLENCODED_ERROR\"\n        S_VARIABLE_USER_ID = 91,                 // \"USERID\"\n        S_VARIABLE_WEB_APP_ID = 92,              // \"WEBAPPID\"\n        S_VARIABLE_STATUS = 93,                  // \"VARIABLE_STATUS\"\n        S_VARIABLE_STATUS_LINE = 94,             // \"VARIABLE_STATUS_LINE\"\n        S_VARIABLE_IP = 95,                      // \"VARIABLE_IP\"\n        S_VARIABLE_GLOBAL = 96,                  // \"VARIABLE_GLOBAL\"\n        S_VARIABLE_TX = 97,                      // \"VARIABLE_TX\"\n        S_VARIABLE_SESSION = 98,                 // \"VARIABLE_SESSION\"\n        S_VARIABLE_USER = 99,                    // \"VARIABLE_USER\"\n        S_RUN_TIME_VAR_ENV = 100,                // \"RUN_TIME_VAR_ENV\"\n        S_RUN_TIME_VAR_XML = 101,                // \"RUN_TIME_VAR_XML\"\n        S_ACTION_SETVAR = 102,                   // \"SetVar\"\n        S_SETVAR_OPERATION_EQUALS = 103,         // SETVAR_OPERATION_EQUALS\n        S_SETVAR_OPERATION_EQUALS_PLUS = 104,    // SETVAR_OPERATION_EQUALS_PLUS\n        S_SETVAR_OPERATION_EQUALS_MINUS = 105,   // SETVAR_OPERATION_EQUALS_MINUS\n        S_NOT = 106,                             // \"NOT\"\n        S_OPERATOR_BEGINS_WITH = 107,            // \"OPERATOR_BEGINS_WITH\"\n        S_OPERATOR_CONTAINS = 108,               // \"OPERATOR_CONTAINS\"\n        S_OPERATOR_CONTAINS_WORD = 109,          // \"OPERATOR_CONTAINS_WORD\"\n        S_OPERATOR_DETECT_SQLI = 110,            // \"OPERATOR_DETECT_SQLI\"\n        S_OPERATOR_DETECT_XSS = 111,             // \"OPERATOR_DETECT_XSS\"\n        S_OPERATOR_ENDS_WITH = 112,              // \"OPERATOR_ENDS_WITH\"\n        S_OPERATOR_EQ = 113,                     // \"OPERATOR_EQ\"\n        S_OPERATOR_FUZZY_HASH = 114,             // \"OPERATOR_FUZZY_HASH\"\n        S_OPERATOR_GEOLOOKUP = 115,              // \"OPERATOR_GEOLOOKUP\"\n        S_OPERATOR_GE = 116,                     // \"OPERATOR_GE\"\n        S_OPERATOR_GSB_LOOKUP = 117,             // \"OPERATOR_GSB_LOOKUP\"\n        S_OPERATOR_GT = 118,                     // \"OPERATOR_GT\"\n        S_OPERATOR_INSPECT_FILE = 119,           // \"OPERATOR_INSPECT_FILE\"\n        S_OPERATOR_IP_MATCH_FROM_FILE = 120,     // \"OPERATOR_IP_MATCH_FROM_FILE\"\n        S_OPERATOR_IP_MATCH = 121,               // \"OPERATOR_IP_MATCH\"\n        S_OPERATOR_LE = 122,                     // \"OPERATOR_LE\"\n        S_OPERATOR_LT = 123,                     // \"OPERATOR_LT\"\n        S_OPERATOR_PM_FROM_FILE = 124,           // \"OPERATOR_PM_FROM_FILE\"\n        S_OPERATOR_PM = 125,                     // \"OPERATOR_PM\"\n        S_OPERATOR_RBL = 126,                    // \"OPERATOR_RBL\"\n        S_OPERATOR_RSUB = 127,                   // \"OPERATOR_RSUB\"\n        S_OPERATOR_RX_CONTENT_ONLY = 128,        // \"Operator RX (content only)\"\n        S_OPERATOR_RX = 129,                     // \"OPERATOR_RX\"\n        S_OPERATOR_RX_GLOBAL = 130,              // \"OPERATOR_RX_GLOBAL\"\n        S_OPERATOR_STR_EQ = 131,                 // \"OPERATOR_STR_EQ\"\n        S_OPERATOR_STR_MATCH = 132,              // \"OPERATOR_STR_MATCH\"\n        S_OPERATOR_UNCONDITIONAL_MATCH = 133,    // \"OPERATOR_UNCONDITIONAL_MATCH\"\n        S_OPERATOR_VALIDATE_BYTE_RANGE = 134,    // \"OPERATOR_VALIDATE_BYTE_RANGE\"\n        S_OPERATOR_VALIDATE_DTD = 135,           // \"OPERATOR_VALIDATE_DTD\"\n        S_OPERATOR_VALIDATE_HASH = 136,          // \"OPERATOR_VALIDATE_HASH\"\n        S_OPERATOR_VALIDATE_SCHEMA = 137,        // \"OPERATOR_VALIDATE_SCHEMA\"\n        S_OPERATOR_VALIDATE_URL_ENCODING = 138,  // \"OPERATOR_VALIDATE_URL_ENCODING\"\n        S_OPERATOR_VALIDATE_UTF8_ENCODING = 139, // \"OPERATOR_VALIDATE_UTF8_ENCODING\"\n        S_OPERATOR_VERIFY_CC = 140,              // \"OPERATOR_VERIFY_CC\"\n        S_OPERATOR_VERIFY_CPF = 141,             // \"OPERATOR_VERIFY_CPF\"\n        S_OPERATOR_VERIFY_SSN = 142,             // \"OPERATOR_VERIFY_SSN\"\n        S_OPERATOR_VERIFY_SVNR = 143,            // \"OPERATOR_VERIFY_SVNR\"\n        S_OPERATOR_WITHIN = 144,                 // \"OPERATOR_WITHIN\"\n        S_CONFIG_DIR_AUDIT_LOG_FMT = 145,        // CONFIG_DIR_AUDIT_LOG_FMT\n        S_JSON = 146,                            // JSON\n        S_NATIVE = 147,                          // NATIVE\n        S_ACTION_CTL_RULE_ENGINE = 148,          // \"ACTION_CTL_RULE_ENGINE\"\n        S_ACTION_ACCURACY = 149,                 // \"Accuracy\"\n        S_ACTION_ALLOW = 150,                    // \"Allow\"\n        S_ACTION_APPEND = 151,                   // \"Append\"\n        S_ACTION_AUDIT_LOG = 152,                // \"AuditLog\"\n        S_ACTION_BLOCK = 153,                    // \"Block\"\n        S_ACTION_CAPTURE = 154,                  // \"Capture\"\n        S_ACTION_CHAIN = 155,                    // \"Chain\"\n        S_ACTION_CTL_AUDIT_ENGINE = 156,         // \"ACTION_CTL_AUDIT_ENGINE\"\n        S_ACTION_CTL_AUDIT_LOG_PARTS = 157,      // \"ACTION_CTL_AUDIT_LOG_PARTS\"\n        S_ACTION_CTL_BDY_JSON = 158,             // \"ACTION_CTL_BDY_JSON\"\n        S_ACTION_CTL_BDY_XML = 159,              // \"ACTION_CTL_BDY_XML\"\n        S_ACTION_CTL_BDY_URLENCODED = 160,       // \"ACTION_CTL_BDY_URLENCODED\"\n        S_ACTION_CTL_FORCE_REQ_BODY_VAR = 161,   // \"ACTION_CTL_FORCE_REQ_BODY_VAR\"\n        S_ACTION_CTL_PARSE_XML_INTO_ARGS = 162,  // \"ACTION_CTL_PARSE_XML_INTO_ARGS\"\n        S_ACTION_CTL_REQUEST_BODY_ACCESS = 163,  // \"ACTION_CTL_REQUEST_BODY_ACCESS\"\n        S_ACTION_CTL_RULE_REMOVE_BY_ID = 164,    // \"ACTION_CTL_RULE_REMOVE_BY_ID\"\n        S_ACTION_CTL_RULE_REMOVE_BY_TAG = 165,   // \"ACTION_CTL_RULE_REMOVE_BY_TAG\"\n        S_ACTION_CTL_RULE_REMOVE_TARGET_BY_ID = 166, // \"ACTION_CTL_RULE_REMOVE_TARGET_BY_ID\"\n        S_ACTION_CTL_RULE_REMOVE_TARGET_BY_TAG = 167, // \"ACTION_CTL_RULE_REMOVE_TARGET_BY_TAG\"\n        S_ACTION_DENY = 168,                     // \"Deny\"\n        S_ACTION_DEPRECATE_VAR = 169,            // \"DeprecateVar\"\n        S_ACTION_DROP = 170,                     // \"Drop\"\n        S_ACTION_EXEC = 171,                     // \"Exec\"\n        S_ACTION_EXPIRE_VAR = 172,               // \"ExpireVar\"\n        S_ACTION_ID = 173,                       // \"Id\"\n        S_ACTION_INITCOL = 174,                  // \"InitCol\"\n        S_ACTION_LOG = 175,                      // \"Log\"\n        S_ACTION_LOG_DATA = 176,                 // \"LogData\"\n        S_ACTION_MATURITY = 177,                 // \"Maturity\"\n        S_ACTION_MSG = 178,                      // \"Msg\"\n        S_ACTION_MULTI_MATCH = 179,              // \"MultiMatch\"\n        S_ACTION_NO_AUDIT_LOG = 180,             // \"NoAuditLog\"\n        S_ACTION_NO_LOG = 181,                   // \"NoLog\"\n        S_ACTION_PASS = 182,                     // \"Pass\"\n        S_ACTION_PAUSE = 183,                    // \"Pause\"\n        S_ACTION_PHASE = 184,                    // \"Phase\"\n        S_ACTION_PREPEND = 185,                  // \"Prepend\"\n        S_ACTION_PROXY = 186,                    // \"Proxy\"\n        S_ACTION_REDIRECT = 187,                 // \"Redirect\"\n        S_ACTION_REV = 188,                      // \"Rev\"\n        S_ACTION_SANITISE_ARG = 189,             // \"SanitiseArg\"\n        S_ACTION_SANITISE_MATCHED = 190,         // \"SanitiseMatched\"\n        S_ACTION_SANITISE_MATCHED_BYTES = 191,   // \"SanitiseMatchedBytes\"\n        S_ACTION_SANITISE_REQUEST_HEADER = 192,  // \"SanitiseRequestHeader\"\n        S_ACTION_SANITISE_RESPONSE_HEADER = 193, // \"SanitiseResponseHeader\"\n        S_ACTION_SETENV = 194,                   // \"SetEnv\"\n        S_ACTION_SETRSC = 195,                   // \"SetRsc\"\n        S_ACTION_SETSID = 196,                   // \"SetSid\"\n        S_ACTION_SETUID = 197,                   // \"SetUID\"\n        S_ACTION_SEVERITY = 198,                 // \"Severity\"\n        S_ACTION_SKIP = 199,                     // \"Skip\"\n        S_ACTION_SKIP_AFTER = 200,               // \"SkipAfter\"\n        S_ACTION_STATUS = 201,                   // \"Status\"\n        S_ACTION_TAG = 202,                      // \"Tag\"\n        S_ACTION_TRANSFORMATION_BASE_64_ENCODE = 203, // \"ACTION_TRANSFORMATION_BASE_64_ENCODE\"\n        S_ACTION_TRANSFORMATION_BASE_64_DECODE = 204, // \"ACTION_TRANSFORMATION_BASE_64_DECODE\"\n        S_ACTION_TRANSFORMATION_BASE_64_DECODE_EXT = 205, // \"ACTION_TRANSFORMATION_BASE_64_DECODE_EXT\"\n        S_ACTION_TRANSFORMATION_CMD_LINE = 206,  // \"ACTION_TRANSFORMATION_CMD_LINE\"\n        S_ACTION_TRANSFORMATION_COMPRESS_WHITESPACE = 207, // \"ACTION_TRANSFORMATION_COMPRESS_WHITESPACE\"\n        S_ACTION_TRANSFORMATION_CSS_DECODE = 208, // \"ACTION_TRANSFORMATION_CSS_DECODE\"\n        S_ACTION_TRANSFORMATION_ESCAPE_SEQ_DECODE = 209, // \"ACTION_TRANSFORMATION_ESCAPE_SEQ_DECODE\"\n        S_ACTION_TRANSFORMATION_HEX_ENCODE = 210, // \"ACTION_TRANSFORMATION_HEX_ENCODE\"\n        S_ACTION_TRANSFORMATION_HEX_DECODE = 211, // \"ACTION_TRANSFORMATION_HEX_DECODE\"\n        S_ACTION_TRANSFORMATION_HTML_ENTITY_DECODE = 212, // \"ACTION_TRANSFORMATION_HTML_ENTITY_DECODE\"\n        S_ACTION_TRANSFORMATION_JS_DECODE = 213, // \"ACTION_TRANSFORMATION_JS_DECODE\"\n        S_ACTION_TRANSFORMATION_LENGTH = 214,    // \"ACTION_TRANSFORMATION_LENGTH\"\n        S_ACTION_TRANSFORMATION_LOWERCASE = 215, // \"ACTION_TRANSFORMATION_LOWERCASE\"\n        S_ACTION_TRANSFORMATION_MD5 = 216,       // \"ACTION_TRANSFORMATION_MD5\"\n        S_ACTION_TRANSFORMATION_NONE = 217,      // \"ACTION_TRANSFORMATION_NONE\"\n        S_ACTION_TRANSFORMATION_NORMALISE_PATH = 218, // \"ACTION_TRANSFORMATION_NORMALISE_PATH\"\n        S_ACTION_TRANSFORMATION_NORMALISE_PATH_WIN = 219, // \"ACTION_TRANSFORMATION_NORMALISE_PATH_WIN\"\n        S_ACTION_TRANSFORMATION_PARITY_EVEN_7_BIT = 220, // \"ACTION_TRANSFORMATION_PARITY_EVEN_7_BIT\"\n        S_ACTION_TRANSFORMATION_PARITY_ODD_7_BIT = 221, // \"ACTION_TRANSFORMATION_PARITY_ODD_7_BIT\"\n        S_ACTION_TRANSFORMATION_PARITY_ZERO_7_BIT = 222, // \"ACTION_TRANSFORMATION_PARITY_ZERO_7_BIT\"\n        S_ACTION_TRANSFORMATION_REMOVE_COMMENTS = 223, // \"ACTION_TRANSFORMATION_REMOVE_COMMENTS\"\n        S_ACTION_TRANSFORMATION_REMOVE_COMMENTS_CHAR = 224, // \"ACTION_TRANSFORMATION_REMOVE_COMMENTS_CHAR\"\n        S_ACTION_TRANSFORMATION_REMOVE_NULLS = 225, // \"ACTION_TRANSFORMATION_REMOVE_NULLS\"\n        S_ACTION_TRANSFORMATION_REMOVE_WHITESPACE = 226, // \"ACTION_TRANSFORMATION_REMOVE_WHITESPACE\"\n        S_ACTION_TRANSFORMATION_REPLACE_COMMENTS = 227, // \"ACTION_TRANSFORMATION_REPLACE_COMMENTS\"\n        S_ACTION_TRANSFORMATION_REPLACE_NULLS = 228, // \"ACTION_TRANSFORMATION_REPLACE_NULLS\"\n        S_ACTION_TRANSFORMATION_SHA1 = 229,      // \"ACTION_TRANSFORMATION_SHA1\"\n        S_ACTION_TRANSFORMATION_SQL_HEX_DECODE = 230, // \"ACTION_TRANSFORMATION_SQL_HEX_DECODE\"\n        S_ACTION_TRANSFORMATION_TRIM = 231,      // \"ACTION_TRANSFORMATION_TRIM\"\n        S_ACTION_TRANSFORMATION_TRIM_LEFT = 232, // \"ACTION_TRANSFORMATION_TRIM_LEFT\"\n        S_ACTION_TRANSFORMATION_TRIM_RIGHT = 233, // \"ACTION_TRANSFORMATION_TRIM_RIGHT\"\n        S_ACTION_TRANSFORMATION_UPPERCASE = 234, // \"ACTION_TRANSFORMATION_UPPERCASE\"\n        S_ACTION_TRANSFORMATION_URL_ENCODE = 235, // \"ACTION_TRANSFORMATION_URL_ENCODE\"\n        S_ACTION_TRANSFORMATION_URL_DECODE = 236, // \"ACTION_TRANSFORMATION_URL_DECODE\"\n        S_ACTION_TRANSFORMATION_URL_DECODE_UNI = 237, // \"ACTION_TRANSFORMATION_URL_DECODE_UNI\"\n        S_ACTION_TRANSFORMATION_UTF8_TO_UNICODE = 238, // \"ACTION_TRANSFORMATION_UTF8_TO_UNICODE\"\n        S_ACTION_VER = 239,                      // \"Ver\"\n        S_ACTION_XMLNS = 240,                    // \"xmlns\"\n        S_CONFIG_COMPONENT_SIG = 241,            // \"CONFIG_COMPONENT_SIG\"\n        S_CONFIG_CONN_ENGINE = 242,              // \"CONFIG_CONN_ENGINE\"\n        S_CONFIG_SEC_ARGUMENT_SEPARATOR = 243,   // \"CONFIG_SEC_ARGUMENT_SEPARATOR\"\n        S_CONFIG_SEC_WEB_APP_ID = 244,           // \"CONFIG_SEC_WEB_APP_ID\"\n        S_CONFIG_SEC_SERVER_SIG = 245,           // \"CONFIG_SEC_SERVER_SIG\"\n        S_CONFIG_DIR_AUDIT_DIR = 246,            // \"CONFIG_DIR_AUDIT_DIR\"\n        S_CONFIG_DIR_AUDIT_DIR_MOD = 247,        // \"CONFIG_DIR_AUDIT_DIR_MOD\"\n        S_CONFIG_DIR_AUDIT_ENG = 248,            // \"CONFIG_DIR_AUDIT_ENG\"\n        S_CONFIG_DIR_AUDIT_FLE_MOD = 249,        // \"CONFIG_DIR_AUDIT_FLE_MOD\"\n        S_CONFIG_DIR_AUDIT_LOG = 250,            // \"CONFIG_DIR_AUDIT_LOG\"\n        S_CONFIG_DIR_AUDIT_LOG2 = 251,           // \"CONFIG_DIR_AUDIT_LOG2\"\n        S_CONFIG_DIR_AUDIT_LOG_P = 252,          // \"CONFIG_DIR_AUDIT_LOG_P\"\n        S_CONFIG_DIR_AUDIT_STS = 253,            // \"CONFIG_DIR_AUDIT_STS\"\n        S_CONFIG_DIR_AUDIT_PREFIX = 254,         // \"CONFIG_DIR_AUDIT_PREFIX\"\n        S_CONFIG_DIR_AUDIT_TPE = 255,            // \"CONFIG_DIR_AUDIT_TPE\"\n        S_CONFIG_DIR_DEBUG_LOG = 256,            // \"CONFIG_DIR_DEBUG_LOG\"\n        S_CONFIG_DIR_DEBUG_LVL = 257,            // \"CONFIG_DIR_DEBUG_LVL\"\n        S_CONFIG_SEC_CACHE_TRANSFORMATIONS = 258, // \"CONFIG_SEC_CACHE_TRANSFORMATIONS\"\n        S_CONFIG_SEC_DISABLE_BACKEND_COMPRESS = 259, // \"CONFIG_SEC_DISABLE_BACKEND_COMPRESS\"\n        S_CONFIG_SEC_HASH_ENGINE = 260,          // \"CONFIG_SEC_HASH_ENGINE\"\n        S_CONFIG_SEC_HASH_KEY = 261,             // \"CONFIG_SEC_HASH_KEY\"\n        S_CONFIG_SEC_HASH_PARAM = 262,           // \"CONFIG_SEC_HASH_PARAM\"\n        S_CONFIG_SEC_HASH_METHOD_RX = 263,       // \"CONFIG_SEC_HASH_METHOD_RX\"\n        S_CONFIG_SEC_HASH_METHOD_PM = 264,       // \"CONFIG_SEC_HASH_METHOD_PM\"\n        S_CONFIG_SEC_CHROOT_DIR = 265,           // \"CONFIG_SEC_CHROOT_DIR\"\n        S_CONFIG_DIR_GEO_DB = 266,               // \"CONFIG_DIR_GEO_DB\"\n        S_CONFIG_DIR_GSB_DB = 267,               // \"CONFIG_DIR_GSB_DB\"\n        S_CONFIG_SEC_GUARDIAN_LOG = 268,         // \"CONFIG_SEC_GUARDIAN_LOG\"\n        S_CONFIG_DIR_PCRE_MATCH_LIMIT = 269,     // \"CONFIG_DIR_PCRE_MATCH_LIMIT\"\n        S_CONFIG_DIR_PCRE_MATCH_LIMIT_RECURSION = 270, // \"CONFIG_DIR_PCRE_MATCH_LIMIT_RECURSION\"\n        S_CONFIG_SEC_CONN_R_STATE_LIMIT = 271,   // \"CONFIG_SEC_CONN_R_STATE_LIMIT\"\n        S_CONFIG_SEC_CONN_W_STATE_LIMIT = 272,   // \"CONFIG_SEC_CONN_W_STATE_LIMIT\"\n        S_CONFIG_SEC_SENSOR_ID = 273,            // \"CONFIG_SEC_SENSOR_ID\"\n        S_CONFIG_DIR_ARGS_LIMIT = 274,           // \"CONFIG_DIR_ARGS_LIMIT\"\n        S_CONFIG_DIR_REQ_BODY_JSON_DEPTH_LIMIT = 275, // \"CONFIG_DIR_REQ_BODY_JSON_DEPTH_LIMIT\"\n        S_CONFIG_DIR_REQ_BODY = 276,             // \"CONFIG_DIR_REQ_BODY\"\n        S_CONFIG_DIR_REQ_BODY_IN_MEMORY_LIMIT = 277, // \"CONFIG_DIR_REQ_BODY_IN_MEMORY_LIMIT\"\n        S_CONFIG_DIR_REQ_BODY_LIMIT = 278,       // \"CONFIG_DIR_REQ_BODY_LIMIT\"\n        S_CONFIG_DIR_REQ_BODY_LIMIT_ACTION = 279, // \"CONFIG_DIR_REQ_BODY_LIMIT_ACTION\"\n        S_CONFIG_DIR_REQ_BODY_NO_FILES_LIMIT = 280, // \"CONFIG_DIR_REQ_BODY_NO_FILES_LIMIT\"\n        S_CONFIG_DIR_RES_BODY = 281,             // \"CONFIG_DIR_RES_BODY\"\n        S_CONFIG_DIR_RES_BODY_LIMIT = 282,       // \"CONFIG_DIR_RES_BODY_LIMIT\"\n        S_CONFIG_DIR_RES_BODY_LIMIT_ACTION = 283, // \"CONFIG_DIR_RES_BODY_LIMIT_ACTION\"\n        S_CONFIG_SEC_RULE_INHERITANCE = 284,     // \"CONFIG_SEC_RULE_INHERITANCE\"\n        S_CONFIG_SEC_RULE_PERF_TIME = 285,       // \"CONFIG_SEC_RULE_PERF_TIME\"\n        S_CONFIG_DIR_RULE_ENG = 286,             // \"CONFIG_DIR_RULE_ENG\"\n        S_CONFIG_DIR_SEC_ACTION = 287,           // \"CONFIG_DIR_SEC_ACTION\"\n        S_CONFIG_DIR_SEC_DEFAULT_ACTION = 288,   // \"CONFIG_DIR_SEC_DEFAULT_ACTION\"\n        S_CONFIG_DIR_SEC_MARKER = 289,           // \"CONFIG_DIR_SEC_MARKER\"\n        S_CONFIG_DIR_UNICODE_MAP_FILE = 290,     // \"CONFIG_DIR_UNICODE_MAP_FILE\"\n        S_CONFIG_DIR_UNICODE_CODE_PAGE = 291,    // \"CONFIG_DIR_UNICODE_CODE_PAGE\"\n        S_CONFIG_SEC_COLLECTION_TIMEOUT = 292,   // \"CONFIG_SEC_COLLECTION_TIMEOUT\"\n        S_CONFIG_SEC_HTTP_BLKEY = 293,           // \"CONFIG_SEC_HTTP_BLKEY\"\n        S_CONFIG_SEC_INTERCEPT_ON_ERROR = 294,   // \"CONFIG_SEC_INTERCEPT_ON_ERROR\"\n        S_CONFIG_SEC_REMOTE_RULES_FAIL_ACTION = 295, // \"CONFIG_SEC_REMOTE_RULES_FAIL_ACTION\"\n        S_CONFIG_SEC_RULE_REMOVE_BY_ID = 296,    // \"CONFIG_SEC_RULE_REMOVE_BY_ID\"\n        S_CONFIG_SEC_RULE_REMOVE_BY_MSG = 297,   // \"CONFIG_SEC_RULE_REMOVE_BY_MSG\"\n        S_CONFIG_SEC_RULE_REMOVE_BY_TAG = 298,   // \"CONFIG_SEC_RULE_REMOVE_BY_TAG\"\n        S_CONFIG_SEC_RULE_UPDATE_TARGET_BY_TAG = 299, // \"CONFIG_SEC_RULE_UPDATE_TARGET_BY_TAG\"\n        S_CONFIG_SEC_RULE_UPDATE_TARGET_BY_MSG = 300, // \"CONFIG_SEC_RULE_UPDATE_TARGET_BY_MSG\"\n        S_CONFIG_SEC_RULE_UPDATE_TARGET_BY_ID = 301, // \"CONFIG_SEC_RULE_UPDATE_TARGET_BY_ID\"\n        S_CONFIG_SEC_RULE_UPDATE_ACTION_BY_ID = 302, // \"CONFIG_SEC_RULE_UPDATE_ACTION_BY_ID\"\n        S_CONFIG_UPDLOAD_KEEP_FILES = 303,       // \"CONFIG_UPDLOAD_KEEP_FILES\"\n        S_CONFIG_UPDLOAD_SAVE_TMP_FILES = 304,   // \"CONFIG_UPDLOAD_SAVE_TMP_FILES\"\n        S_CONFIG_UPLOAD_DIR = 305,               // \"CONFIG_UPLOAD_DIR\"\n        S_CONFIG_UPLOAD_FILE_LIMIT = 306,        // \"CONFIG_UPLOAD_FILE_LIMIT\"\n        S_CONFIG_UPLOAD_FILE_MODE = 307,         // \"CONFIG_UPLOAD_FILE_MODE\"\n        S_CONFIG_VALUE_ABORT = 308,              // \"CONFIG_VALUE_ABORT\"\n        S_CONFIG_VALUE_DETC = 309,               // \"CONFIG_VALUE_DETC\"\n        S_CONFIG_VALUE_HTTPS = 310,              // \"CONFIG_VALUE_HTTPS\"\n        S_CONFIG_VALUE_ONLYARGS = 311,           // \"CONFIG_VALUE_ONLYARGS\"\n        S_CONFIG_VALUE_OFF = 312,                // \"CONFIG_VALUE_OFF\"\n        S_CONFIG_VALUE_ON = 313,                 // \"CONFIG_VALUE_ON\"\n        S_CONFIG_VALUE_PARALLEL = 314,           // \"CONFIG_VALUE_PARALLEL\"\n        S_CONFIG_VALUE_PROCESS_PARTIAL = 315,    // \"CONFIG_VALUE_PROCESS_PARTIAL\"\n        S_CONFIG_VALUE_REJECT = 316,             // \"CONFIG_VALUE_REJECT\"\n        S_CONFIG_VALUE_RELEVANT_ONLY = 317,      // \"CONFIG_VALUE_RELEVANT_ONLY\"\n        S_CONFIG_VALUE_SERIAL = 318,             // \"CONFIG_VALUE_SERIAL\"\n        S_CONFIG_VALUE_WARN = 319,               // \"CONFIG_VALUE_WARN\"\n        S_CONFIG_XML_EXTERNAL_ENTITY = 320,      // \"CONFIG_XML_EXTERNAL_ENTITY\"\n        S_CONFIG_XML_PARSE_XML_INTO_ARGS = 321,  // \"CONFIG_XML_PARSE_XML_INTO_ARGS\"\n        S_CONGIG_DIR_RESPONSE_BODY_MP = 322,     // \"CONGIG_DIR_RESPONSE_BODY_MP\"\n        S_CONGIG_DIR_SEC_ARG_SEP = 323,          // \"CONGIG_DIR_SEC_ARG_SEP\"\n        S_CONGIG_DIR_SEC_COOKIE_FORMAT = 324,    // \"CONGIG_DIR_SEC_COOKIE_FORMAT\"\n        S_CONFIG_SEC_COOKIEV0_SEPARATOR = 325,   // \"CONFIG_SEC_COOKIEV0_SEPARATOR\"\n        S_CONGIG_DIR_SEC_DATA_DIR = 326,         // \"CONGIG_DIR_SEC_DATA_DIR\"\n        S_CONGIG_DIR_SEC_STATUS_ENGINE = 327,    // \"CONGIG_DIR_SEC_STATUS_ENGINE\"\n        S_CONFIG_SEC_STREAM_IN_BODY_INSPECTION = 328, // \"CONFIG_SEC_STREAM_IN_BODY_INSPECTION\"\n        S_CONFIG_SEC_STREAM_OUT_BODY_INSPECTION = 329, // \"CONFIG_SEC_STREAM_OUT_BODY_INSPECTION\"\n        S_CONGIG_DIR_SEC_TMP_DIR = 330,          // \"CONGIG_DIR_SEC_TMP_DIR\"\n        S_DIRECTIVE = 331,                       // \"DIRECTIVE\"\n        S_DIRECTIVE_SECRULESCRIPT = 332,         // \"DIRECTIVE_SECRULESCRIPT\"\n        S_FREE_TEXT_QUOTE_MACRO_EXPANSION = 333, // \"FREE_TEXT_QUOTE_MACRO_EXPANSION\"\n        S_QUOTATION_MARK = 334,                  // \"QUOTATION_MARK\"\n        S_RUN_TIME_VAR_BLD = 335,                // \"RUN_TIME_VAR_BLD\"\n        S_RUN_TIME_VAR_DUR = 336,                // \"RUN_TIME_VAR_DUR\"\n        S_RUN_TIME_VAR_HSV = 337,                // \"RUN_TIME_VAR_HSV\"\n        S_RUN_TIME_VAR_REMOTE_USER = 338,        // \"RUN_TIME_VAR_REMOTE_USER\"\n        S_RUN_TIME_VAR_TIME = 339,               // \"RUN_TIME_VAR_TIME\"\n        S_RUN_TIME_VAR_TIME_DAY = 340,           // \"RUN_TIME_VAR_TIME_DAY\"\n        S_RUN_TIME_VAR_TIME_EPOCH = 341,         // \"RUN_TIME_VAR_TIME_EPOCH\"\n        S_RUN_TIME_VAR_TIME_HOUR = 342,          // \"RUN_TIME_VAR_TIME_HOUR\"\n        S_RUN_TIME_VAR_TIME_MIN = 343,           // \"RUN_TIME_VAR_TIME_MIN\"\n        S_RUN_TIME_VAR_TIME_MON = 344,           // \"RUN_TIME_VAR_TIME_MON\"\n        S_RUN_TIME_VAR_TIME_SEC = 345,           // \"RUN_TIME_VAR_TIME_SEC\"\n        S_RUN_TIME_VAR_TIME_WDAY = 346,          // \"RUN_TIME_VAR_TIME_WDAY\"\n        S_RUN_TIME_VAR_TIME_YEAR = 347,          // \"RUN_TIME_VAR_TIME_YEAR\"\n        S_VARIABLE = 348,                        // \"VARIABLE\"\n        S_DICT_ELEMENT = 349,                    // \"Dictionary element\"\n        S_DICT_ELEMENT_WITH_EQUALS = 350,        // \"Dictionary element, with equals\"\n        S_DICT_ELEMENT_REGEXP = 351,             // \"Dictionary element, selected by regexp\"\n        S_YYACCEPT = 352,                        // $accept\n        S_input = 353,                           // input\n        S_line = 354,                            // line\n        S_audit_log = 355,                       // audit_log\n        S_actions = 356,                         // actions\n        S_actions_may_quoted = 357,              // actions_may_quoted\n        S_op = 358,                              // op\n        S_op_before_init = 359,                  // op_before_init\n        S_expression = 360,                      // expression\n        S_variables = 361,                       // variables\n        S_variables_pre_process = 362,           // variables_pre_process\n        S_variables_may_be_quoted = 363,         // variables_may_be_quoted\n        S_var = 364,                             // var\n        S_act = 365,                             // act\n        S_setvar_action = 366,                   // setvar_action\n        S_run_time_string = 367                  // run_time_string\n      };\n    };\n\n    /// (Internal) symbol kind.\n    typedef symbol_kind::symbol_kind_type symbol_kind_type;\n\n    /// The number of tokens.\n    static const symbol_kind_type YYNTOKENS = symbol_kind::YYNTOKENS;\n\n    /// A complete symbol.\n    ///\n    /// Expects its Base type to provide access to the symbol kind\n    /// via kind ().\n    ///\n    /// Provide access to semantic value and location.\n    template <typename Base>\n    struct basic_symbol : Base\n    {\n      /// Alias to Base.\n      typedef Base super_type;\n\n      /// Default constructor.\n      basic_symbol () YY_NOEXCEPT\n        : value ()\n        , location ()\n      {}\n\n#if 201103L <= YY_CPLUSPLUS\n      /// Move constructor.\n      basic_symbol (basic_symbol&& that)\n        : Base (std::move (that))\n        , value ()\n        , location (std::move (that.location))\n      {\n        switch (this->kind ())\n    {\n      case symbol_kind::S_ACTION_ACCURACY: // \"Accuracy\"\n      case symbol_kind::S_ACTION_ALLOW: // \"Allow\"\n      case symbol_kind::S_ACTION_APPEND: // \"Append\"\n      case symbol_kind::S_ACTION_AUDIT_LOG: // \"AuditLog\"\n      case symbol_kind::S_ACTION_BLOCK: // \"Block\"\n      case symbol_kind::S_ACTION_CAPTURE: // \"Capture\"\n      case symbol_kind::S_ACTION_CHAIN: // \"Chain\"\n      case symbol_kind::S_ACTION_CTL_AUDIT_ENGINE: // \"ACTION_CTL_AUDIT_ENGINE\"\n      case symbol_kind::S_ACTION_CTL_AUDIT_LOG_PARTS: // \"ACTION_CTL_AUDIT_LOG_PARTS\"\n      case symbol_kind::S_ACTION_CTL_BDY_JSON: // \"ACTION_CTL_BDY_JSON\"\n      case symbol_kind::S_ACTION_CTL_BDY_XML: // \"ACTION_CTL_BDY_XML\"\n      case symbol_kind::S_ACTION_CTL_BDY_URLENCODED: // \"ACTION_CTL_BDY_URLENCODED\"\n      case symbol_kind::S_ACTION_CTL_FORCE_REQ_BODY_VAR: // \"ACTION_CTL_FORCE_REQ_BODY_VAR\"\n      case symbol_kind::S_ACTION_CTL_PARSE_XML_INTO_ARGS: // \"ACTION_CTL_PARSE_XML_INTO_ARGS\"\n      case symbol_kind::S_ACTION_CTL_REQUEST_BODY_ACCESS: // \"ACTION_CTL_REQUEST_BODY_ACCESS\"\n      case symbol_kind::S_ACTION_CTL_RULE_REMOVE_BY_ID: // \"ACTION_CTL_RULE_REMOVE_BY_ID\"\n      case symbol_kind::S_ACTION_CTL_RULE_REMOVE_BY_TAG: // \"ACTION_CTL_RULE_REMOVE_BY_TAG\"\n      case symbol_kind::S_ACTION_CTL_RULE_REMOVE_TARGET_BY_ID: // \"ACTION_CTL_RULE_REMOVE_TARGET_BY_ID\"\n      case symbol_kind::S_ACTION_CTL_RULE_REMOVE_TARGET_BY_TAG: // \"ACTION_CTL_RULE_REMOVE_TARGET_BY_TAG\"\n      case symbol_kind::S_ACTION_DENY: // \"Deny\"\n      case symbol_kind::S_ACTION_DEPRECATE_VAR: // \"DeprecateVar\"\n      case symbol_kind::S_ACTION_DROP: // \"Drop\"\n      case symbol_kind::S_ACTION_EXEC: // \"Exec\"\n      case symbol_kind::S_ACTION_EXPIRE_VAR: // \"ExpireVar\"\n      case symbol_kind::S_ACTION_ID: // \"Id\"\n      case symbol_kind::S_ACTION_INITCOL: // \"InitCol\"\n      case symbol_kind::S_ACTION_LOG: // \"Log\"\n      case symbol_kind::S_ACTION_LOG_DATA: // \"LogData\"\n      case symbol_kind::S_ACTION_MATURITY: // \"Maturity\"\n      case symbol_kind::S_ACTION_MSG: // \"Msg\"\n      case symbol_kind::S_ACTION_MULTI_MATCH: // \"MultiMatch\"\n      case symbol_kind::S_ACTION_NO_AUDIT_LOG: // \"NoAuditLog\"\n      case symbol_kind::S_ACTION_NO_LOG: // \"NoLog\"\n      case symbol_kind::S_ACTION_PASS: // \"Pass\"\n      case symbol_kind::S_ACTION_PAUSE: // \"Pause\"\n      case symbol_kind::S_ACTION_PHASE: // \"Phase\"\n      case symbol_kind::S_ACTION_PREPEND: // \"Prepend\"\n      case symbol_kind::S_ACTION_PROXY: // \"Proxy\"\n      case symbol_kind::S_ACTION_REDIRECT: // \"Redirect\"\n      case symbol_kind::S_ACTION_REV: // \"Rev\"\n      case symbol_kind::S_ACTION_SANITISE_ARG: // \"SanitiseArg\"\n      case symbol_kind::S_ACTION_SANITISE_MATCHED: // \"SanitiseMatched\"\n      case symbol_kind::S_ACTION_SANITISE_MATCHED_BYTES: // \"SanitiseMatchedBytes\"\n      case symbol_kind::S_ACTION_SANITISE_REQUEST_HEADER: // \"SanitiseRequestHeader\"\n      case symbol_kind::S_ACTION_SANITISE_RESPONSE_HEADER: // \"SanitiseResponseHeader\"\n      case symbol_kind::S_ACTION_SETENV: // \"SetEnv\"\n      case symbol_kind::S_ACTION_SETRSC: // \"SetRsc\"\n      case symbol_kind::S_ACTION_SETSID: // \"SetSid\"\n      case symbol_kind::S_ACTION_SETUID: // \"SetUID\"\n      case symbol_kind::S_ACTION_SEVERITY: // \"Severity\"\n      case symbol_kind::S_ACTION_SKIP: // \"Skip\"\n      case symbol_kind::S_ACTION_SKIP_AFTER: // \"SkipAfter\"\n      case symbol_kind::S_ACTION_STATUS: // \"Status\"\n      case symbol_kind::S_ACTION_TAG: // \"Tag\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_BASE_64_ENCODE: // \"ACTION_TRANSFORMATION_BASE_64_ENCODE\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_BASE_64_DECODE: // \"ACTION_TRANSFORMATION_BASE_64_DECODE\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_BASE_64_DECODE_EXT: // \"ACTION_TRANSFORMATION_BASE_64_DECODE_EXT\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_CMD_LINE: // \"ACTION_TRANSFORMATION_CMD_LINE\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_COMPRESS_WHITESPACE: // \"ACTION_TRANSFORMATION_COMPRESS_WHITESPACE\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_CSS_DECODE: // \"ACTION_TRANSFORMATION_CSS_DECODE\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_ESCAPE_SEQ_DECODE: // \"ACTION_TRANSFORMATION_ESCAPE_SEQ_DECODE\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_HEX_ENCODE: // \"ACTION_TRANSFORMATION_HEX_ENCODE\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_HEX_DECODE: // \"ACTION_TRANSFORMATION_HEX_DECODE\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_HTML_ENTITY_DECODE: // \"ACTION_TRANSFORMATION_HTML_ENTITY_DECODE\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_JS_DECODE: // \"ACTION_TRANSFORMATION_JS_DECODE\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_LENGTH: // \"ACTION_TRANSFORMATION_LENGTH\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_LOWERCASE: // \"ACTION_TRANSFORMATION_LOWERCASE\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_MD5: // \"ACTION_TRANSFORMATION_MD5\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_NONE: // \"ACTION_TRANSFORMATION_NONE\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_NORMALISE_PATH: // \"ACTION_TRANSFORMATION_NORMALISE_PATH\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_NORMALISE_PATH_WIN: // \"ACTION_TRANSFORMATION_NORMALISE_PATH_WIN\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_PARITY_EVEN_7_BIT: // \"ACTION_TRANSFORMATION_PARITY_EVEN_7_BIT\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_PARITY_ODD_7_BIT: // \"ACTION_TRANSFORMATION_PARITY_ODD_7_BIT\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_PARITY_ZERO_7_BIT: // \"ACTION_TRANSFORMATION_PARITY_ZERO_7_BIT\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_REMOVE_COMMENTS: // \"ACTION_TRANSFORMATION_REMOVE_COMMENTS\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_REMOVE_COMMENTS_CHAR: // \"ACTION_TRANSFORMATION_REMOVE_COMMENTS_CHAR\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_REMOVE_NULLS: // \"ACTION_TRANSFORMATION_REMOVE_NULLS\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_REMOVE_WHITESPACE: // \"ACTION_TRANSFORMATION_REMOVE_WHITESPACE\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_REPLACE_COMMENTS: // \"ACTION_TRANSFORMATION_REPLACE_COMMENTS\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_REPLACE_NULLS: // \"ACTION_TRANSFORMATION_REPLACE_NULLS\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_SHA1: // \"ACTION_TRANSFORMATION_SHA1\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_SQL_HEX_DECODE: // \"ACTION_TRANSFORMATION_SQL_HEX_DECODE\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_TRIM: // \"ACTION_TRANSFORMATION_TRIM\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_TRIM_LEFT: // \"ACTION_TRANSFORMATION_TRIM_LEFT\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_TRIM_RIGHT: // \"ACTION_TRANSFORMATION_TRIM_RIGHT\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_UPPERCASE: // \"ACTION_TRANSFORMATION_UPPERCASE\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_URL_ENCODE: // \"ACTION_TRANSFORMATION_URL_ENCODE\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_URL_DECODE: // \"ACTION_TRANSFORMATION_URL_DECODE\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_URL_DECODE_UNI: // \"ACTION_TRANSFORMATION_URL_DECODE_UNI\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_UTF8_TO_UNICODE: // \"ACTION_TRANSFORMATION_UTF8_TO_UNICODE\"\n      case symbol_kind::S_ACTION_VER: // \"Ver\"\n      case symbol_kind::S_ACTION_XMLNS: // \"xmlns\"\n      case symbol_kind::S_CONFIG_COMPONENT_SIG: // \"CONFIG_COMPONENT_SIG\"\n      case symbol_kind::S_CONFIG_CONN_ENGINE: // \"CONFIG_CONN_ENGINE\"\n      case symbol_kind::S_CONFIG_SEC_ARGUMENT_SEPARATOR: // \"CONFIG_SEC_ARGUMENT_SEPARATOR\"\n      case symbol_kind::S_CONFIG_SEC_WEB_APP_ID: // \"CONFIG_SEC_WEB_APP_ID\"\n      case symbol_kind::S_CONFIG_SEC_SERVER_SIG: // \"CONFIG_SEC_SERVER_SIG\"\n      case symbol_kind::S_CONFIG_DIR_AUDIT_DIR: // \"CONFIG_DIR_AUDIT_DIR\"\n      case symbol_kind::S_CONFIG_DIR_AUDIT_DIR_MOD: // \"CONFIG_DIR_AUDIT_DIR_MOD\"\n      case symbol_kind::S_CONFIG_DIR_AUDIT_ENG: // \"CONFIG_DIR_AUDIT_ENG\"\n      case symbol_kind::S_CONFIG_DIR_AUDIT_FLE_MOD: // \"CONFIG_DIR_AUDIT_FLE_MOD\"\n      case symbol_kind::S_CONFIG_DIR_AUDIT_LOG: // \"CONFIG_DIR_AUDIT_LOG\"\n      case symbol_kind::S_CONFIG_DIR_AUDIT_LOG2: // \"CONFIG_DIR_AUDIT_LOG2\"\n      case symbol_kind::S_CONFIG_DIR_AUDIT_LOG_P: // \"CONFIG_DIR_AUDIT_LOG_P\"\n      case symbol_kind::S_CONFIG_DIR_AUDIT_STS: // \"CONFIG_DIR_AUDIT_STS\"\n      case symbol_kind::S_CONFIG_DIR_AUDIT_PREFIX: // \"CONFIG_DIR_AUDIT_PREFIX\"\n      case symbol_kind::S_CONFIG_DIR_AUDIT_TPE: // \"CONFIG_DIR_AUDIT_TPE\"\n      case symbol_kind::S_CONFIG_DIR_DEBUG_LOG: // \"CONFIG_DIR_DEBUG_LOG\"\n      case symbol_kind::S_CONFIG_DIR_DEBUG_LVL: // \"CONFIG_DIR_DEBUG_LVL\"\n      case symbol_kind::S_CONFIG_SEC_CACHE_TRANSFORMATIONS: // \"CONFIG_SEC_CACHE_TRANSFORMATIONS\"\n      case symbol_kind::S_CONFIG_SEC_DISABLE_BACKEND_COMPRESS: // \"CONFIG_SEC_DISABLE_BACKEND_COMPRESS\"\n      case symbol_kind::S_CONFIG_SEC_HASH_ENGINE: // \"CONFIG_SEC_HASH_ENGINE\"\n      case symbol_kind::S_CONFIG_SEC_HASH_KEY: // \"CONFIG_SEC_HASH_KEY\"\n      case symbol_kind::S_CONFIG_SEC_HASH_PARAM: // \"CONFIG_SEC_HASH_PARAM\"\n      case symbol_kind::S_CONFIG_SEC_HASH_METHOD_RX: // \"CONFIG_SEC_HASH_METHOD_RX\"\n      case symbol_kind::S_CONFIG_SEC_HASH_METHOD_PM: // \"CONFIG_SEC_HASH_METHOD_PM\"\n      case symbol_kind::S_CONFIG_SEC_CHROOT_DIR: // \"CONFIG_SEC_CHROOT_DIR\"\n      case symbol_kind::S_CONFIG_DIR_GEO_DB: // \"CONFIG_DIR_GEO_DB\"\n      case symbol_kind::S_CONFIG_DIR_GSB_DB: // \"CONFIG_DIR_GSB_DB\"\n      case symbol_kind::S_CONFIG_SEC_GUARDIAN_LOG: // \"CONFIG_SEC_GUARDIAN_LOG\"\n      case symbol_kind::S_CONFIG_DIR_PCRE_MATCH_LIMIT: // \"CONFIG_DIR_PCRE_MATCH_LIMIT\"\n      case symbol_kind::S_CONFIG_DIR_PCRE_MATCH_LIMIT_RECURSION: // \"CONFIG_DIR_PCRE_MATCH_LIMIT_RECURSION\"\n      case symbol_kind::S_CONFIG_SEC_CONN_R_STATE_LIMIT: // \"CONFIG_SEC_CONN_R_STATE_LIMIT\"\n      case symbol_kind::S_CONFIG_SEC_CONN_W_STATE_LIMIT: // \"CONFIG_SEC_CONN_W_STATE_LIMIT\"\n      case symbol_kind::S_CONFIG_SEC_SENSOR_ID: // \"CONFIG_SEC_SENSOR_ID\"\n      case symbol_kind::S_CONFIG_DIR_ARGS_LIMIT: // \"CONFIG_DIR_ARGS_LIMIT\"\n      case symbol_kind::S_CONFIG_DIR_REQ_BODY_JSON_DEPTH_LIMIT: // \"CONFIG_DIR_REQ_BODY_JSON_DEPTH_LIMIT\"\n      case symbol_kind::S_CONFIG_DIR_REQ_BODY: // \"CONFIG_DIR_REQ_BODY\"\n      case symbol_kind::S_CONFIG_DIR_REQ_BODY_IN_MEMORY_LIMIT: // \"CONFIG_DIR_REQ_BODY_IN_MEMORY_LIMIT\"\n      case symbol_kind::S_CONFIG_DIR_REQ_BODY_LIMIT: // \"CONFIG_DIR_REQ_BODY_LIMIT\"\n      case symbol_kind::S_CONFIG_DIR_REQ_BODY_LIMIT_ACTION: // \"CONFIG_DIR_REQ_BODY_LIMIT_ACTION\"\n      case symbol_kind::S_CONFIG_DIR_REQ_BODY_NO_FILES_LIMIT: // \"CONFIG_DIR_REQ_BODY_NO_FILES_LIMIT\"\n      case symbol_kind::S_CONFIG_DIR_RES_BODY: // \"CONFIG_DIR_RES_BODY\"\n      case symbol_kind::S_CONFIG_DIR_RES_BODY_LIMIT: // \"CONFIG_DIR_RES_BODY_LIMIT\"\n      case symbol_kind::S_CONFIG_DIR_RES_BODY_LIMIT_ACTION: // \"CONFIG_DIR_RES_BODY_LIMIT_ACTION\"\n      case symbol_kind::S_CONFIG_SEC_RULE_INHERITANCE: // \"CONFIG_SEC_RULE_INHERITANCE\"\n      case symbol_kind::S_CONFIG_SEC_RULE_PERF_TIME: // \"CONFIG_SEC_RULE_PERF_TIME\"\n      case symbol_kind::S_CONFIG_DIR_RULE_ENG: // \"CONFIG_DIR_RULE_ENG\"\n      case symbol_kind::S_CONFIG_DIR_SEC_ACTION: // \"CONFIG_DIR_SEC_ACTION\"\n      case symbol_kind::S_CONFIG_DIR_SEC_DEFAULT_ACTION: // \"CONFIG_DIR_SEC_DEFAULT_ACTION\"\n      case symbol_kind::S_CONFIG_DIR_SEC_MARKER: // \"CONFIG_DIR_SEC_MARKER\"\n      case symbol_kind::S_CONFIG_DIR_UNICODE_MAP_FILE: // \"CONFIG_DIR_UNICODE_MAP_FILE\"\n      case symbol_kind::S_CONFIG_DIR_UNICODE_CODE_PAGE: // \"CONFIG_DIR_UNICODE_CODE_PAGE\"\n      case symbol_kind::S_CONFIG_SEC_COLLECTION_TIMEOUT: // \"CONFIG_SEC_COLLECTION_TIMEOUT\"\n      case symbol_kind::S_CONFIG_SEC_HTTP_BLKEY: // \"CONFIG_SEC_HTTP_BLKEY\"\n      case symbol_kind::S_CONFIG_SEC_INTERCEPT_ON_ERROR: // \"CONFIG_SEC_INTERCEPT_ON_ERROR\"\n      case symbol_kind::S_CONFIG_SEC_REMOTE_RULES_FAIL_ACTION: // \"CONFIG_SEC_REMOTE_RULES_FAIL_ACTION\"\n      case symbol_kind::S_CONFIG_SEC_RULE_REMOVE_BY_ID: // \"CONFIG_SEC_RULE_REMOVE_BY_ID\"\n      case symbol_kind::S_CONFIG_SEC_RULE_REMOVE_BY_MSG: // \"CONFIG_SEC_RULE_REMOVE_BY_MSG\"\n      case symbol_kind::S_CONFIG_SEC_RULE_REMOVE_BY_TAG: // \"CONFIG_SEC_RULE_REMOVE_BY_TAG\"\n      case symbol_kind::S_CONFIG_SEC_RULE_UPDATE_TARGET_BY_TAG: // \"CONFIG_SEC_RULE_UPDATE_TARGET_BY_TAG\"\n      case symbol_kind::S_CONFIG_SEC_RULE_UPDATE_TARGET_BY_MSG: // \"CONFIG_SEC_RULE_UPDATE_TARGET_BY_MSG\"\n      case symbol_kind::S_CONFIG_SEC_RULE_UPDATE_TARGET_BY_ID: // \"CONFIG_SEC_RULE_UPDATE_TARGET_BY_ID\"\n      case symbol_kind::S_CONFIG_SEC_RULE_UPDATE_ACTION_BY_ID: // \"CONFIG_SEC_RULE_UPDATE_ACTION_BY_ID\"\n      case symbol_kind::S_CONFIG_UPDLOAD_KEEP_FILES: // \"CONFIG_UPDLOAD_KEEP_FILES\"\n      case symbol_kind::S_CONFIG_UPDLOAD_SAVE_TMP_FILES: // \"CONFIG_UPDLOAD_SAVE_TMP_FILES\"\n      case symbol_kind::S_CONFIG_UPLOAD_DIR: // \"CONFIG_UPLOAD_DIR\"\n      case symbol_kind::S_CONFIG_UPLOAD_FILE_LIMIT: // \"CONFIG_UPLOAD_FILE_LIMIT\"\n      case symbol_kind::S_CONFIG_UPLOAD_FILE_MODE: // \"CONFIG_UPLOAD_FILE_MODE\"\n      case symbol_kind::S_CONFIG_VALUE_ABORT: // \"CONFIG_VALUE_ABORT\"\n      case symbol_kind::S_CONFIG_VALUE_DETC: // \"CONFIG_VALUE_DETC\"\n      case symbol_kind::S_CONFIG_VALUE_HTTPS: // \"CONFIG_VALUE_HTTPS\"\n      case symbol_kind::S_CONFIG_VALUE_ONLYARGS: // \"CONFIG_VALUE_ONLYARGS\"\n      case symbol_kind::S_CONFIG_VALUE_OFF: // \"CONFIG_VALUE_OFF\"\n      case symbol_kind::S_CONFIG_VALUE_ON: // \"CONFIG_VALUE_ON\"\n      case symbol_kind::S_CONFIG_VALUE_PARALLEL: // \"CONFIG_VALUE_PARALLEL\"\n      case symbol_kind::S_CONFIG_VALUE_PROCESS_PARTIAL: // \"CONFIG_VALUE_PROCESS_PARTIAL\"\n      case symbol_kind::S_CONFIG_VALUE_REJECT: // \"CONFIG_VALUE_REJECT\"\n      case symbol_kind::S_CONFIG_VALUE_RELEVANT_ONLY: // \"CONFIG_VALUE_RELEVANT_ONLY\"\n      case symbol_kind::S_CONFIG_VALUE_SERIAL: // \"CONFIG_VALUE_SERIAL\"\n      case symbol_kind::S_CONFIG_VALUE_WARN: // \"CONFIG_VALUE_WARN\"\n      case symbol_kind::S_CONFIG_XML_EXTERNAL_ENTITY: // \"CONFIG_XML_EXTERNAL_ENTITY\"\n      case symbol_kind::S_CONFIG_XML_PARSE_XML_INTO_ARGS: // \"CONFIG_XML_PARSE_XML_INTO_ARGS\"\n      case symbol_kind::S_CONGIG_DIR_RESPONSE_BODY_MP: // \"CONGIG_DIR_RESPONSE_BODY_MP\"\n      case symbol_kind::S_CONGIG_DIR_SEC_ARG_SEP: // \"CONGIG_DIR_SEC_ARG_SEP\"\n      case symbol_kind::S_CONGIG_DIR_SEC_COOKIE_FORMAT: // \"CONGIG_DIR_SEC_COOKIE_FORMAT\"\n      case symbol_kind::S_CONFIG_SEC_COOKIEV0_SEPARATOR: // \"CONFIG_SEC_COOKIEV0_SEPARATOR\"\n      case symbol_kind::S_CONGIG_DIR_SEC_DATA_DIR: // \"CONGIG_DIR_SEC_DATA_DIR\"\n      case symbol_kind::S_CONGIG_DIR_SEC_STATUS_ENGINE: // \"CONGIG_DIR_SEC_STATUS_ENGINE\"\n      case symbol_kind::S_CONFIG_SEC_STREAM_IN_BODY_INSPECTION: // \"CONFIG_SEC_STREAM_IN_BODY_INSPECTION\"\n      case symbol_kind::S_CONFIG_SEC_STREAM_OUT_BODY_INSPECTION: // \"CONFIG_SEC_STREAM_OUT_BODY_INSPECTION\"\n      case symbol_kind::S_CONGIG_DIR_SEC_TMP_DIR: // \"CONGIG_DIR_SEC_TMP_DIR\"\n      case symbol_kind::S_DIRECTIVE: // \"DIRECTIVE\"\n      case symbol_kind::S_DIRECTIVE_SECRULESCRIPT: // \"DIRECTIVE_SECRULESCRIPT\"\n      case symbol_kind::S_FREE_TEXT_QUOTE_MACRO_EXPANSION: // \"FREE_TEXT_QUOTE_MACRO_EXPANSION\"\n      case symbol_kind::S_QUOTATION_MARK: // \"QUOTATION_MARK\"\n      case symbol_kind::S_RUN_TIME_VAR_BLD: // \"RUN_TIME_VAR_BLD\"\n      case symbol_kind::S_RUN_TIME_VAR_DUR: // \"RUN_TIME_VAR_DUR\"\n      case symbol_kind::S_RUN_TIME_VAR_HSV: // \"RUN_TIME_VAR_HSV\"\n      case symbol_kind::S_RUN_TIME_VAR_REMOTE_USER: // \"RUN_TIME_VAR_REMOTE_USER\"\n      case symbol_kind::S_RUN_TIME_VAR_TIME: // \"RUN_TIME_VAR_TIME\"\n      case symbol_kind::S_RUN_TIME_VAR_TIME_DAY: // \"RUN_TIME_VAR_TIME_DAY\"\n      case symbol_kind::S_RUN_TIME_VAR_TIME_EPOCH: // \"RUN_TIME_VAR_TIME_EPOCH\"\n      case symbol_kind::S_RUN_TIME_VAR_TIME_HOUR: // \"RUN_TIME_VAR_TIME_HOUR\"\n      case symbol_kind::S_RUN_TIME_VAR_TIME_MIN: // \"RUN_TIME_VAR_TIME_MIN\"\n      case symbol_kind::S_RUN_TIME_VAR_TIME_MON: // \"RUN_TIME_VAR_TIME_MON\"\n      case symbol_kind::S_RUN_TIME_VAR_TIME_SEC: // \"RUN_TIME_VAR_TIME_SEC\"\n      case symbol_kind::S_RUN_TIME_VAR_TIME_WDAY: // \"RUN_TIME_VAR_TIME_WDAY\"\n      case symbol_kind::S_RUN_TIME_VAR_TIME_YEAR: // \"RUN_TIME_VAR_TIME_YEAR\"\n      case symbol_kind::S_VARIABLE: // \"VARIABLE\"\n      case symbol_kind::S_DICT_ELEMENT: // \"Dictionary element\"\n      case symbol_kind::S_DICT_ELEMENT_WITH_EQUALS: // \"Dictionary element, with equals\"\n      case symbol_kind::S_DICT_ELEMENT_REGEXP: // \"Dictionary element, selected by regexp\"\n        value.move< std::string > (std::move (that.value));\n        break;\n\n      case symbol_kind::S_op: // op\n      case symbol_kind::S_op_before_init: // op_before_init\n        value.move< std::unique_ptr<Operator> > (std::move (that.value));\n        break;\n\n      case symbol_kind::S_run_time_string: // run_time_string\n        value.move< std::unique_ptr<RunTimeString> > (std::move (that.value));\n        break;\n\n      case symbol_kind::S_var: // var\n        value.move< std::unique_ptr<Variable> > (std::move (that.value));\n        break;\n\n      case symbol_kind::S_act: // act\n      case symbol_kind::S_setvar_action: // setvar_action\n        value.move< std::unique_ptr<actions::Action> > (std::move (that.value));\n        break;\n\n      case symbol_kind::S_variables: // variables\n      case symbol_kind::S_variables_pre_process: // variables_pre_process\n      case symbol_kind::S_variables_may_be_quoted: // variables_may_be_quoted\n        value.move< std::unique_ptr<std::vector<std::unique_ptr<Variable> > >  > (std::move (that.value));\n        break;\n\n      case symbol_kind::S_actions: // actions\n      case symbol_kind::S_actions_may_quoted: // actions_may_quoted\n        value.move< std::unique_ptr<std::vector<std::unique_ptr<actions::Action> > >  > (std::move (that.value));\n        break;\n\n      default:\n        break;\n    }\n\n      }\n#endif\n\n      /// Copy constructor.\n      basic_symbol (const basic_symbol& that);\n\n      /// Constructors for typed symbols.\n#if 201103L <= YY_CPLUSPLUS\n      basic_symbol (typename Base::kind_type t, location_type&& l)\n        : Base (t)\n        , location (std::move (l))\n      {}\n#else\n      basic_symbol (typename Base::kind_type t, const location_type& l)\n        : Base (t)\n        , location (l)\n      {}\n#endif\n\n#if 201103L <= YY_CPLUSPLUS\n      basic_symbol (typename Base::kind_type t, std::string&& v, location_type&& l)\n        : Base (t)\n        , value (std::move (v))\n        , location (std::move (l))\n      {}\n#else\n      basic_symbol (typename Base::kind_type t, const std::string& v, const location_type& l)\n        : Base (t)\n        , value (v)\n        , location (l)\n      {}\n#endif\n\n#if 201103L <= YY_CPLUSPLUS\n      basic_symbol (typename Base::kind_type t, std::unique_ptr<Operator>&& v, location_type&& l)\n        : Base (t)\n        , value (std::move (v))\n        , location (std::move (l))\n      {}\n#else\n      basic_symbol (typename Base::kind_type t, const std::unique_ptr<Operator>& v, const location_type& l)\n        : Base (t)\n        , value (v)\n        , location (l)\n      {}\n#endif\n\n#if 201103L <= YY_CPLUSPLUS\n      basic_symbol (typename Base::kind_type t, std::unique_ptr<RunTimeString>&& v, location_type&& l)\n        : Base (t)\n        , value (std::move (v))\n        , location (std::move (l))\n      {}\n#else\n      basic_symbol (typename Base::kind_type t, const std::unique_ptr<RunTimeString>& v, const location_type& l)\n        : Base (t)\n        , value (v)\n        , location (l)\n      {}\n#endif\n\n#if 201103L <= YY_CPLUSPLUS\n      basic_symbol (typename Base::kind_type t, std::unique_ptr<Variable>&& v, location_type&& l)\n        : Base (t)\n        , value (std::move (v))\n        , location (std::move (l))\n      {}\n#else\n      basic_symbol (typename Base::kind_type t, const std::unique_ptr<Variable>& v, const location_type& l)\n        : Base (t)\n        , value (v)\n        , location (l)\n      {}\n#endif\n\n#if 201103L <= YY_CPLUSPLUS\n      basic_symbol (typename Base::kind_type t, std::unique_ptr<actions::Action>&& v, location_type&& l)\n        : Base (t)\n        , value (std::move (v))\n        , location (std::move (l))\n      {}\n#else\n      basic_symbol (typename Base::kind_type t, const std::unique_ptr<actions::Action>& v, const location_type& l)\n        : Base (t)\n        , value (v)\n        , location (l)\n      {}\n#endif\n\n#if 201103L <= YY_CPLUSPLUS\n      basic_symbol (typename Base::kind_type t, std::unique_ptr<std::vector<std::unique_ptr<Variable> > > && v, location_type&& l)\n        : Base (t)\n        , value (std::move (v))\n        , location (std::move (l))\n      {}\n#else\n      basic_symbol (typename Base::kind_type t, const std::unique_ptr<std::vector<std::unique_ptr<Variable> > > & v, const location_type& l)\n        : Base (t)\n        , value (v)\n        , location (l)\n      {}\n#endif\n\n#if 201103L <= YY_CPLUSPLUS\n      basic_symbol (typename Base::kind_type t, std::unique_ptr<std::vector<std::unique_ptr<actions::Action> > > && v, location_type&& l)\n        : Base (t)\n        , value (std::move (v))\n        , location (std::move (l))\n      {}\n#else\n      basic_symbol (typename Base::kind_type t, const std::unique_ptr<std::vector<std::unique_ptr<actions::Action> > > & v, const location_type& l)\n        : Base (t)\n        , value (v)\n        , location (l)\n      {}\n#endif\n\n      /// Destroy the symbol.\n      ~basic_symbol ()\n      {\n        clear ();\n      }\n\n\n\n      /// Destroy contents, and record that is empty.\n      void clear () YY_NOEXCEPT\n      {\n        // User destructor.\n        symbol_kind_type yykind = this->kind ();\n        basic_symbol<Base>& yysym = *this;\n        (void) yysym;\n        switch (yykind)\n        {\n      case symbol_kind::S_actions: // actions\n#line 724 \"seclang-parser.yy\"\n                    { }\n#line 2145 \"seclang-parser.hh\"\n        break;\n\n      case symbol_kind::S_actions_may_quoted: // actions_may_quoted\n#line 724 \"seclang-parser.yy\"\n                    { }\n#line 2151 \"seclang-parser.hh\"\n        break;\n\n      case symbol_kind::S_op: // op\n#line 725 \"seclang-parser.yy\"\n                    { }\n#line 2157 \"seclang-parser.hh\"\n        break;\n\n      case symbol_kind::S_op_before_init: // op_before_init\n#line 725 \"seclang-parser.yy\"\n                    { }\n#line 2163 \"seclang-parser.hh\"\n        break;\n\n      case symbol_kind::S_variables: // variables\n#line 727 \"seclang-parser.yy\"\n                    { }\n#line 2169 \"seclang-parser.hh\"\n        break;\n\n      case symbol_kind::S_variables_pre_process: // variables_pre_process\n#line 727 \"seclang-parser.yy\"\n                    { }\n#line 2175 \"seclang-parser.hh\"\n        break;\n\n      case symbol_kind::S_variables_may_be_quoted: // variables_may_be_quoted\n#line 727 \"seclang-parser.yy\"\n                    { }\n#line 2181 \"seclang-parser.hh\"\n        break;\n\n      case symbol_kind::S_var: // var\n#line 726 \"seclang-parser.yy\"\n                    { }\n#line 2187 \"seclang-parser.hh\"\n        break;\n\n      case symbol_kind::S_act: // act\n#line 722 \"seclang-parser.yy\"\n                    { }\n#line 2193 \"seclang-parser.hh\"\n        break;\n\n      case symbol_kind::S_setvar_action: // setvar_action\n#line 722 \"seclang-parser.yy\"\n                    { }\n#line 2199 \"seclang-parser.hh\"\n        break;\n\n      case symbol_kind::S_run_time_string: // run_time_string\n#line 723 \"seclang-parser.yy\"\n                    { }\n#line 2205 \"seclang-parser.hh\"\n        break;\n\n       default:\n          break;\n        }\n\n        // Value type destructor.\nswitch (yykind)\n    {\n      case symbol_kind::S_ACTION_ACCURACY: // \"Accuracy\"\n      case symbol_kind::S_ACTION_ALLOW: // \"Allow\"\n      case symbol_kind::S_ACTION_APPEND: // \"Append\"\n      case symbol_kind::S_ACTION_AUDIT_LOG: // \"AuditLog\"\n      case symbol_kind::S_ACTION_BLOCK: // \"Block\"\n      case symbol_kind::S_ACTION_CAPTURE: // \"Capture\"\n      case symbol_kind::S_ACTION_CHAIN: // \"Chain\"\n      case symbol_kind::S_ACTION_CTL_AUDIT_ENGINE: // \"ACTION_CTL_AUDIT_ENGINE\"\n      case symbol_kind::S_ACTION_CTL_AUDIT_LOG_PARTS: // \"ACTION_CTL_AUDIT_LOG_PARTS\"\n      case symbol_kind::S_ACTION_CTL_BDY_JSON: // \"ACTION_CTL_BDY_JSON\"\n      case symbol_kind::S_ACTION_CTL_BDY_XML: // \"ACTION_CTL_BDY_XML\"\n      case symbol_kind::S_ACTION_CTL_BDY_URLENCODED: // \"ACTION_CTL_BDY_URLENCODED\"\n      case symbol_kind::S_ACTION_CTL_FORCE_REQ_BODY_VAR: // \"ACTION_CTL_FORCE_REQ_BODY_VAR\"\n      case symbol_kind::S_ACTION_CTL_PARSE_XML_INTO_ARGS: // \"ACTION_CTL_PARSE_XML_INTO_ARGS\"\n      case symbol_kind::S_ACTION_CTL_REQUEST_BODY_ACCESS: // \"ACTION_CTL_REQUEST_BODY_ACCESS\"\n      case symbol_kind::S_ACTION_CTL_RULE_REMOVE_BY_ID: // \"ACTION_CTL_RULE_REMOVE_BY_ID\"\n      case symbol_kind::S_ACTION_CTL_RULE_REMOVE_BY_TAG: // \"ACTION_CTL_RULE_REMOVE_BY_TAG\"\n      case symbol_kind::S_ACTION_CTL_RULE_REMOVE_TARGET_BY_ID: // \"ACTION_CTL_RULE_REMOVE_TARGET_BY_ID\"\n      case symbol_kind::S_ACTION_CTL_RULE_REMOVE_TARGET_BY_TAG: // \"ACTION_CTL_RULE_REMOVE_TARGET_BY_TAG\"\n      case symbol_kind::S_ACTION_DENY: // \"Deny\"\n      case symbol_kind::S_ACTION_DEPRECATE_VAR: // \"DeprecateVar\"\n      case symbol_kind::S_ACTION_DROP: // \"Drop\"\n      case symbol_kind::S_ACTION_EXEC: // \"Exec\"\n      case symbol_kind::S_ACTION_EXPIRE_VAR: // \"ExpireVar\"\n      case symbol_kind::S_ACTION_ID: // \"Id\"\n      case symbol_kind::S_ACTION_INITCOL: // \"InitCol\"\n      case symbol_kind::S_ACTION_LOG: // \"Log\"\n      case symbol_kind::S_ACTION_LOG_DATA: // \"LogData\"\n      case symbol_kind::S_ACTION_MATURITY: // \"Maturity\"\n      case symbol_kind::S_ACTION_MSG: // \"Msg\"\n      case symbol_kind::S_ACTION_MULTI_MATCH: // \"MultiMatch\"\n      case symbol_kind::S_ACTION_NO_AUDIT_LOG: // \"NoAuditLog\"\n      case symbol_kind::S_ACTION_NO_LOG: // \"NoLog\"\n      case symbol_kind::S_ACTION_PASS: // \"Pass\"\n      case symbol_kind::S_ACTION_PAUSE: // \"Pause\"\n      case symbol_kind::S_ACTION_PHASE: // \"Phase\"\n      case symbol_kind::S_ACTION_PREPEND: // \"Prepend\"\n      case symbol_kind::S_ACTION_PROXY: // \"Proxy\"\n      case symbol_kind::S_ACTION_REDIRECT: // \"Redirect\"\n      case symbol_kind::S_ACTION_REV: // \"Rev\"\n      case symbol_kind::S_ACTION_SANITISE_ARG: // \"SanitiseArg\"\n      case symbol_kind::S_ACTION_SANITISE_MATCHED: // \"SanitiseMatched\"\n      case symbol_kind::S_ACTION_SANITISE_MATCHED_BYTES: // \"SanitiseMatchedBytes\"\n      case symbol_kind::S_ACTION_SANITISE_REQUEST_HEADER: // \"SanitiseRequestHeader\"\n      case symbol_kind::S_ACTION_SANITISE_RESPONSE_HEADER: // \"SanitiseResponseHeader\"\n      case symbol_kind::S_ACTION_SETENV: // \"SetEnv\"\n      case symbol_kind::S_ACTION_SETRSC: // \"SetRsc\"\n      case symbol_kind::S_ACTION_SETSID: // \"SetSid\"\n      case symbol_kind::S_ACTION_SETUID: // \"SetUID\"\n      case symbol_kind::S_ACTION_SEVERITY: // \"Severity\"\n      case symbol_kind::S_ACTION_SKIP: // \"Skip\"\n      case symbol_kind::S_ACTION_SKIP_AFTER: // \"SkipAfter\"\n      case symbol_kind::S_ACTION_STATUS: // \"Status\"\n      case symbol_kind::S_ACTION_TAG: // \"Tag\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_BASE_64_ENCODE: // \"ACTION_TRANSFORMATION_BASE_64_ENCODE\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_BASE_64_DECODE: // \"ACTION_TRANSFORMATION_BASE_64_DECODE\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_BASE_64_DECODE_EXT: // \"ACTION_TRANSFORMATION_BASE_64_DECODE_EXT\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_CMD_LINE: // \"ACTION_TRANSFORMATION_CMD_LINE\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_COMPRESS_WHITESPACE: // \"ACTION_TRANSFORMATION_COMPRESS_WHITESPACE\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_CSS_DECODE: // \"ACTION_TRANSFORMATION_CSS_DECODE\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_ESCAPE_SEQ_DECODE: // \"ACTION_TRANSFORMATION_ESCAPE_SEQ_DECODE\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_HEX_ENCODE: // \"ACTION_TRANSFORMATION_HEX_ENCODE\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_HEX_DECODE: // \"ACTION_TRANSFORMATION_HEX_DECODE\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_HTML_ENTITY_DECODE: // \"ACTION_TRANSFORMATION_HTML_ENTITY_DECODE\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_JS_DECODE: // \"ACTION_TRANSFORMATION_JS_DECODE\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_LENGTH: // \"ACTION_TRANSFORMATION_LENGTH\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_LOWERCASE: // \"ACTION_TRANSFORMATION_LOWERCASE\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_MD5: // \"ACTION_TRANSFORMATION_MD5\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_NONE: // \"ACTION_TRANSFORMATION_NONE\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_NORMALISE_PATH: // \"ACTION_TRANSFORMATION_NORMALISE_PATH\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_NORMALISE_PATH_WIN: // \"ACTION_TRANSFORMATION_NORMALISE_PATH_WIN\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_PARITY_EVEN_7_BIT: // \"ACTION_TRANSFORMATION_PARITY_EVEN_7_BIT\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_PARITY_ODD_7_BIT: // \"ACTION_TRANSFORMATION_PARITY_ODD_7_BIT\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_PARITY_ZERO_7_BIT: // \"ACTION_TRANSFORMATION_PARITY_ZERO_7_BIT\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_REMOVE_COMMENTS: // \"ACTION_TRANSFORMATION_REMOVE_COMMENTS\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_REMOVE_COMMENTS_CHAR: // \"ACTION_TRANSFORMATION_REMOVE_COMMENTS_CHAR\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_REMOVE_NULLS: // \"ACTION_TRANSFORMATION_REMOVE_NULLS\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_REMOVE_WHITESPACE: // \"ACTION_TRANSFORMATION_REMOVE_WHITESPACE\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_REPLACE_COMMENTS: // \"ACTION_TRANSFORMATION_REPLACE_COMMENTS\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_REPLACE_NULLS: // \"ACTION_TRANSFORMATION_REPLACE_NULLS\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_SHA1: // \"ACTION_TRANSFORMATION_SHA1\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_SQL_HEX_DECODE: // \"ACTION_TRANSFORMATION_SQL_HEX_DECODE\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_TRIM: // \"ACTION_TRANSFORMATION_TRIM\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_TRIM_LEFT: // \"ACTION_TRANSFORMATION_TRIM_LEFT\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_TRIM_RIGHT: // \"ACTION_TRANSFORMATION_TRIM_RIGHT\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_UPPERCASE: // \"ACTION_TRANSFORMATION_UPPERCASE\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_URL_ENCODE: // \"ACTION_TRANSFORMATION_URL_ENCODE\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_URL_DECODE: // \"ACTION_TRANSFORMATION_URL_DECODE\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_URL_DECODE_UNI: // \"ACTION_TRANSFORMATION_URL_DECODE_UNI\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_UTF8_TO_UNICODE: // \"ACTION_TRANSFORMATION_UTF8_TO_UNICODE\"\n      case symbol_kind::S_ACTION_VER: // \"Ver\"\n      case symbol_kind::S_ACTION_XMLNS: // \"xmlns\"\n      case symbol_kind::S_CONFIG_COMPONENT_SIG: // \"CONFIG_COMPONENT_SIG\"\n      case symbol_kind::S_CONFIG_CONN_ENGINE: // \"CONFIG_CONN_ENGINE\"\n      case symbol_kind::S_CONFIG_SEC_ARGUMENT_SEPARATOR: // \"CONFIG_SEC_ARGUMENT_SEPARATOR\"\n      case symbol_kind::S_CONFIG_SEC_WEB_APP_ID: // \"CONFIG_SEC_WEB_APP_ID\"\n      case symbol_kind::S_CONFIG_SEC_SERVER_SIG: // \"CONFIG_SEC_SERVER_SIG\"\n      case symbol_kind::S_CONFIG_DIR_AUDIT_DIR: // \"CONFIG_DIR_AUDIT_DIR\"\n      case symbol_kind::S_CONFIG_DIR_AUDIT_DIR_MOD: // \"CONFIG_DIR_AUDIT_DIR_MOD\"\n      case symbol_kind::S_CONFIG_DIR_AUDIT_ENG: // \"CONFIG_DIR_AUDIT_ENG\"\n      case symbol_kind::S_CONFIG_DIR_AUDIT_FLE_MOD: // \"CONFIG_DIR_AUDIT_FLE_MOD\"\n      case symbol_kind::S_CONFIG_DIR_AUDIT_LOG: // \"CONFIG_DIR_AUDIT_LOG\"\n      case symbol_kind::S_CONFIG_DIR_AUDIT_LOG2: // \"CONFIG_DIR_AUDIT_LOG2\"\n      case symbol_kind::S_CONFIG_DIR_AUDIT_LOG_P: // \"CONFIG_DIR_AUDIT_LOG_P\"\n      case symbol_kind::S_CONFIG_DIR_AUDIT_STS: // \"CONFIG_DIR_AUDIT_STS\"\n      case symbol_kind::S_CONFIG_DIR_AUDIT_PREFIX: // \"CONFIG_DIR_AUDIT_PREFIX\"\n      case symbol_kind::S_CONFIG_DIR_AUDIT_TPE: // \"CONFIG_DIR_AUDIT_TPE\"\n      case symbol_kind::S_CONFIG_DIR_DEBUG_LOG: // \"CONFIG_DIR_DEBUG_LOG\"\n      case symbol_kind::S_CONFIG_DIR_DEBUG_LVL: // \"CONFIG_DIR_DEBUG_LVL\"\n      case symbol_kind::S_CONFIG_SEC_CACHE_TRANSFORMATIONS: // \"CONFIG_SEC_CACHE_TRANSFORMATIONS\"\n      case symbol_kind::S_CONFIG_SEC_DISABLE_BACKEND_COMPRESS: // \"CONFIG_SEC_DISABLE_BACKEND_COMPRESS\"\n      case symbol_kind::S_CONFIG_SEC_HASH_ENGINE: // \"CONFIG_SEC_HASH_ENGINE\"\n      case symbol_kind::S_CONFIG_SEC_HASH_KEY: // \"CONFIG_SEC_HASH_KEY\"\n      case symbol_kind::S_CONFIG_SEC_HASH_PARAM: // \"CONFIG_SEC_HASH_PARAM\"\n      case symbol_kind::S_CONFIG_SEC_HASH_METHOD_RX: // \"CONFIG_SEC_HASH_METHOD_RX\"\n      case symbol_kind::S_CONFIG_SEC_HASH_METHOD_PM: // \"CONFIG_SEC_HASH_METHOD_PM\"\n      case symbol_kind::S_CONFIG_SEC_CHROOT_DIR: // \"CONFIG_SEC_CHROOT_DIR\"\n      case symbol_kind::S_CONFIG_DIR_GEO_DB: // \"CONFIG_DIR_GEO_DB\"\n      case symbol_kind::S_CONFIG_DIR_GSB_DB: // \"CONFIG_DIR_GSB_DB\"\n      case symbol_kind::S_CONFIG_SEC_GUARDIAN_LOG: // \"CONFIG_SEC_GUARDIAN_LOG\"\n      case symbol_kind::S_CONFIG_DIR_PCRE_MATCH_LIMIT: // \"CONFIG_DIR_PCRE_MATCH_LIMIT\"\n      case symbol_kind::S_CONFIG_DIR_PCRE_MATCH_LIMIT_RECURSION: // \"CONFIG_DIR_PCRE_MATCH_LIMIT_RECURSION\"\n      case symbol_kind::S_CONFIG_SEC_CONN_R_STATE_LIMIT: // \"CONFIG_SEC_CONN_R_STATE_LIMIT\"\n      case symbol_kind::S_CONFIG_SEC_CONN_W_STATE_LIMIT: // \"CONFIG_SEC_CONN_W_STATE_LIMIT\"\n      case symbol_kind::S_CONFIG_SEC_SENSOR_ID: // \"CONFIG_SEC_SENSOR_ID\"\n      case symbol_kind::S_CONFIG_DIR_ARGS_LIMIT: // \"CONFIG_DIR_ARGS_LIMIT\"\n      case symbol_kind::S_CONFIG_DIR_REQ_BODY_JSON_DEPTH_LIMIT: // \"CONFIG_DIR_REQ_BODY_JSON_DEPTH_LIMIT\"\n      case symbol_kind::S_CONFIG_DIR_REQ_BODY: // \"CONFIG_DIR_REQ_BODY\"\n      case symbol_kind::S_CONFIG_DIR_REQ_BODY_IN_MEMORY_LIMIT: // \"CONFIG_DIR_REQ_BODY_IN_MEMORY_LIMIT\"\n      case symbol_kind::S_CONFIG_DIR_REQ_BODY_LIMIT: // \"CONFIG_DIR_REQ_BODY_LIMIT\"\n      case symbol_kind::S_CONFIG_DIR_REQ_BODY_LIMIT_ACTION: // \"CONFIG_DIR_REQ_BODY_LIMIT_ACTION\"\n      case symbol_kind::S_CONFIG_DIR_REQ_BODY_NO_FILES_LIMIT: // \"CONFIG_DIR_REQ_BODY_NO_FILES_LIMIT\"\n      case symbol_kind::S_CONFIG_DIR_RES_BODY: // \"CONFIG_DIR_RES_BODY\"\n      case symbol_kind::S_CONFIG_DIR_RES_BODY_LIMIT: // \"CONFIG_DIR_RES_BODY_LIMIT\"\n      case symbol_kind::S_CONFIG_DIR_RES_BODY_LIMIT_ACTION: // \"CONFIG_DIR_RES_BODY_LIMIT_ACTION\"\n      case symbol_kind::S_CONFIG_SEC_RULE_INHERITANCE: // \"CONFIG_SEC_RULE_INHERITANCE\"\n      case symbol_kind::S_CONFIG_SEC_RULE_PERF_TIME: // \"CONFIG_SEC_RULE_PERF_TIME\"\n      case symbol_kind::S_CONFIG_DIR_RULE_ENG: // \"CONFIG_DIR_RULE_ENG\"\n      case symbol_kind::S_CONFIG_DIR_SEC_ACTION: // \"CONFIG_DIR_SEC_ACTION\"\n      case symbol_kind::S_CONFIG_DIR_SEC_DEFAULT_ACTION: // \"CONFIG_DIR_SEC_DEFAULT_ACTION\"\n      case symbol_kind::S_CONFIG_DIR_SEC_MARKER: // \"CONFIG_DIR_SEC_MARKER\"\n      case symbol_kind::S_CONFIG_DIR_UNICODE_MAP_FILE: // \"CONFIG_DIR_UNICODE_MAP_FILE\"\n      case symbol_kind::S_CONFIG_DIR_UNICODE_CODE_PAGE: // \"CONFIG_DIR_UNICODE_CODE_PAGE\"\n      case symbol_kind::S_CONFIG_SEC_COLLECTION_TIMEOUT: // \"CONFIG_SEC_COLLECTION_TIMEOUT\"\n      case symbol_kind::S_CONFIG_SEC_HTTP_BLKEY: // \"CONFIG_SEC_HTTP_BLKEY\"\n      case symbol_kind::S_CONFIG_SEC_INTERCEPT_ON_ERROR: // \"CONFIG_SEC_INTERCEPT_ON_ERROR\"\n      case symbol_kind::S_CONFIG_SEC_REMOTE_RULES_FAIL_ACTION: // \"CONFIG_SEC_REMOTE_RULES_FAIL_ACTION\"\n      case symbol_kind::S_CONFIG_SEC_RULE_REMOVE_BY_ID: // \"CONFIG_SEC_RULE_REMOVE_BY_ID\"\n      case symbol_kind::S_CONFIG_SEC_RULE_REMOVE_BY_MSG: // \"CONFIG_SEC_RULE_REMOVE_BY_MSG\"\n      case symbol_kind::S_CONFIG_SEC_RULE_REMOVE_BY_TAG: // \"CONFIG_SEC_RULE_REMOVE_BY_TAG\"\n      case symbol_kind::S_CONFIG_SEC_RULE_UPDATE_TARGET_BY_TAG: // \"CONFIG_SEC_RULE_UPDATE_TARGET_BY_TAG\"\n      case symbol_kind::S_CONFIG_SEC_RULE_UPDATE_TARGET_BY_MSG: // \"CONFIG_SEC_RULE_UPDATE_TARGET_BY_MSG\"\n      case symbol_kind::S_CONFIG_SEC_RULE_UPDATE_TARGET_BY_ID: // \"CONFIG_SEC_RULE_UPDATE_TARGET_BY_ID\"\n      case symbol_kind::S_CONFIG_SEC_RULE_UPDATE_ACTION_BY_ID: // \"CONFIG_SEC_RULE_UPDATE_ACTION_BY_ID\"\n      case symbol_kind::S_CONFIG_UPDLOAD_KEEP_FILES: // \"CONFIG_UPDLOAD_KEEP_FILES\"\n      case symbol_kind::S_CONFIG_UPDLOAD_SAVE_TMP_FILES: // \"CONFIG_UPDLOAD_SAVE_TMP_FILES\"\n      case symbol_kind::S_CONFIG_UPLOAD_DIR: // \"CONFIG_UPLOAD_DIR\"\n      case symbol_kind::S_CONFIG_UPLOAD_FILE_LIMIT: // \"CONFIG_UPLOAD_FILE_LIMIT\"\n      case symbol_kind::S_CONFIG_UPLOAD_FILE_MODE: // \"CONFIG_UPLOAD_FILE_MODE\"\n      case symbol_kind::S_CONFIG_VALUE_ABORT: // \"CONFIG_VALUE_ABORT\"\n      case symbol_kind::S_CONFIG_VALUE_DETC: // \"CONFIG_VALUE_DETC\"\n      case symbol_kind::S_CONFIG_VALUE_HTTPS: // \"CONFIG_VALUE_HTTPS\"\n      case symbol_kind::S_CONFIG_VALUE_ONLYARGS: // \"CONFIG_VALUE_ONLYARGS\"\n      case symbol_kind::S_CONFIG_VALUE_OFF: // \"CONFIG_VALUE_OFF\"\n      case symbol_kind::S_CONFIG_VALUE_ON: // \"CONFIG_VALUE_ON\"\n      case symbol_kind::S_CONFIG_VALUE_PARALLEL: // \"CONFIG_VALUE_PARALLEL\"\n      case symbol_kind::S_CONFIG_VALUE_PROCESS_PARTIAL: // \"CONFIG_VALUE_PROCESS_PARTIAL\"\n      case symbol_kind::S_CONFIG_VALUE_REJECT: // \"CONFIG_VALUE_REJECT\"\n      case symbol_kind::S_CONFIG_VALUE_RELEVANT_ONLY: // \"CONFIG_VALUE_RELEVANT_ONLY\"\n      case symbol_kind::S_CONFIG_VALUE_SERIAL: // \"CONFIG_VALUE_SERIAL\"\n      case symbol_kind::S_CONFIG_VALUE_WARN: // \"CONFIG_VALUE_WARN\"\n      case symbol_kind::S_CONFIG_XML_EXTERNAL_ENTITY: // \"CONFIG_XML_EXTERNAL_ENTITY\"\n      case symbol_kind::S_CONFIG_XML_PARSE_XML_INTO_ARGS: // \"CONFIG_XML_PARSE_XML_INTO_ARGS\"\n      case symbol_kind::S_CONGIG_DIR_RESPONSE_BODY_MP: // \"CONGIG_DIR_RESPONSE_BODY_MP\"\n      case symbol_kind::S_CONGIG_DIR_SEC_ARG_SEP: // \"CONGIG_DIR_SEC_ARG_SEP\"\n      case symbol_kind::S_CONGIG_DIR_SEC_COOKIE_FORMAT: // \"CONGIG_DIR_SEC_COOKIE_FORMAT\"\n      case symbol_kind::S_CONFIG_SEC_COOKIEV0_SEPARATOR: // \"CONFIG_SEC_COOKIEV0_SEPARATOR\"\n      case symbol_kind::S_CONGIG_DIR_SEC_DATA_DIR: // \"CONGIG_DIR_SEC_DATA_DIR\"\n      case symbol_kind::S_CONGIG_DIR_SEC_STATUS_ENGINE: // \"CONGIG_DIR_SEC_STATUS_ENGINE\"\n      case symbol_kind::S_CONFIG_SEC_STREAM_IN_BODY_INSPECTION: // \"CONFIG_SEC_STREAM_IN_BODY_INSPECTION\"\n      case symbol_kind::S_CONFIG_SEC_STREAM_OUT_BODY_INSPECTION: // \"CONFIG_SEC_STREAM_OUT_BODY_INSPECTION\"\n      case symbol_kind::S_CONGIG_DIR_SEC_TMP_DIR: // \"CONGIG_DIR_SEC_TMP_DIR\"\n      case symbol_kind::S_DIRECTIVE: // \"DIRECTIVE\"\n      case symbol_kind::S_DIRECTIVE_SECRULESCRIPT: // \"DIRECTIVE_SECRULESCRIPT\"\n      case symbol_kind::S_FREE_TEXT_QUOTE_MACRO_EXPANSION: // \"FREE_TEXT_QUOTE_MACRO_EXPANSION\"\n      case symbol_kind::S_QUOTATION_MARK: // \"QUOTATION_MARK\"\n      case symbol_kind::S_RUN_TIME_VAR_BLD: // \"RUN_TIME_VAR_BLD\"\n      case symbol_kind::S_RUN_TIME_VAR_DUR: // \"RUN_TIME_VAR_DUR\"\n      case symbol_kind::S_RUN_TIME_VAR_HSV: // \"RUN_TIME_VAR_HSV\"\n      case symbol_kind::S_RUN_TIME_VAR_REMOTE_USER: // \"RUN_TIME_VAR_REMOTE_USER\"\n      case symbol_kind::S_RUN_TIME_VAR_TIME: // \"RUN_TIME_VAR_TIME\"\n      case symbol_kind::S_RUN_TIME_VAR_TIME_DAY: // \"RUN_TIME_VAR_TIME_DAY\"\n      case symbol_kind::S_RUN_TIME_VAR_TIME_EPOCH: // \"RUN_TIME_VAR_TIME_EPOCH\"\n      case symbol_kind::S_RUN_TIME_VAR_TIME_HOUR: // \"RUN_TIME_VAR_TIME_HOUR\"\n      case symbol_kind::S_RUN_TIME_VAR_TIME_MIN: // \"RUN_TIME_VAR_TIME_MIN\"\n      case symbol_kind::S_RUN_TIME_VAR_TIME_MON: // \"RUN_TIME_VAR_TIME_MON\"\n      case symbol_kind::S_RUN_TIME_VAR_TIME_SEC: // \"RUN_TIME_VAR_TIME_SEC\"\n      case symbol_kind::S_RUN_TIME_VAR_TIME_WDAY: // \"RUN_TIME_VAR_TIME_WDAY\"\n      case symbol_kind::S_RUN_TIME_VAR_TIME_YEAR: // \"RUN_TIME_VAR_TIME_YEAR\"\n      case symbol_kind::S_VARIABLE: // \"VARIABLE\"\n      case symbol_kind::S_DICT_ELEMENT: // \"Dictionary element\"\n      case symbol_kind::S_DICT_ELEMENT_WITH_EQUALS: // \"Dictionary element, with equals\"\n      case symbol_kind::S_DICT_ELEMENT_REGEXP: // \"Dictionary element, selected by regexp\"\n        value.template destroy< std::string > ();\n        break;\n\n      case symbol_kind::S_op: // op\n      case symbol_kind::S_op_before_init: // op_before_init\n        value.template destroy< std::unique_ptr<Operator> > ();\n        break;\n\n      case symbol_kind::S_run_time_string: // run_time_string\n        value.template destroy< std::unique_ptr<RunTimeString> > ();\n        break;\n\n      case symbol_kind::S_var: // var\n        value.template destroy< std::unique_ptr<Variable> > ();\n        break;\n\n      case symbol_kind::S_act: // act\n      case symbol_kind::S_setvar_action: // setvar_action\n        value.template destroy< std::unique_ptr<actions::Action> > ();\n        break;\n\n      case symbol_kind::S_variables: // variables\n      case symbol_kind::S_variables_pre_process: // variables_pre_process\n      case symbol_kind::S_variables_may_be_quoted: // variables_may_be_quoted\n        value.template destroy< std::unique_ptr<std::vector<std::unique_ptr<Variable> > >  > ();\n        break;\n\n      case symbol_kind::S_actions: // actions\n      case symbol_kind::S_actions_may_quoted: // actions_may_quoted\n        value.template destroy< std::unique_ptr<std::vector<std::unique_ptr<actions::Action> > >  > ();\n        break;\n\n      default:\n        break;\n    }\n\n        Base::clear ();\n      }\n\n      /// The user-facing name of this symbol.\n      std::string name () const YY_NOEXCEPT\n      {\n        return seclang_parser::symbol_name (this->kind ());\n      }\n\n      /// Backward compatibility (Bison 3.6).\n      symbol_kind_type type_get () const YY_NOEXCEPT;\n\n      /// Whether empty.\n      bool empty () const YY_NOEXCEPT;\n\n      /// Destructive move, \\a s is emptied into this.\n      void move (basic_symbol& s);\n\n      /// The semantic value.\n      value_type value;\n\n      /// The location.\n      location_type location;\n\n    private:\n#if YY_CPLUSPLUS < 201103L\n      /// Assignment operator.\n      basic_symbol& operator= (const basic_symbol& that);\n#endif\n    };\n\n    /// Type access provider for token (enum) based symbols.\n    struct by_kind\n    {\n      /// The symbol kind as needed by the constructor.\n      typedef token_kind_type kind_type;\n\n      /// Default constructor.\n      by_kind () YY_NOEXCEPT;\n\n#if 201103L <= YY_CPLUSPLUS\n      /// Move constructor.\n      by_kind (by_kind&& that) YY_NOEXCEPT;\n#endif\n\n      /// Copy constructor.\n      by_kind (const by_kind& that) YY_NOEXCEPT;\n\n      /// Constructor from (external) token numbers.\n      by_kind (kind_type t) YY_NOEXCEPT;\n\n\n\n      /// Record that this symbol is empty.\n      void clear () YY_NOEXCEPT;\n\n      /// Steal the symbol kind from \\a that.\n      void move (by_kind& that);\n\n      /// The (internal) type number (corresponding to \\a type).\n      /// \\a empty when empty.\n      symbol_kind_type kind () const YY_NOEXCEPT;\n\n      /// Backward compatibility (Bison 3.6).\n      symbol_kind_type type_get () const YY_NOEXCEPT;\n\n      /// The symbol kind.\n      /// \\a S_YYEMPTY when empty.\n      symbol_kind_type kind_;\n    };\n\n    /// Backward compatibility for a private implementation detail (Bison 3.6).\n    typedef by_kind by_type;\n\n    /// \"External\" symbols: returned by the scanner.\n    struct symbol_type : basic_symbol<by_kind>\n    {\n      /// Superclass.\n      typedef basic_symbol<by_kind> super_type;\n\n      /// Empty symbol.\n      symbol_type () YY_NOEXCEPT {}\n\n      /// Constructor for valueless symbols, and symbols from each type.\n#if 201103L <= YY_CPLUSPLUS\n      symbol_type (int tok, location_type l)\n        : super_type (token_kind_type (tok), std::move (l))\n#else\n      symbol_type (int tok, const location_type& l)\n        : super_type (token_kind_type (tok), l)\n#endif\n      {\n#if !defined _MSC_VER || defined __clang__\n        YY_ASSERT (tok == token::TOK_END\n                   || (token::TOK_YYerror <= tok && tok <= token::TOK_ACTION_CTL_RULE_ENGINE));\n#endif\n      }\n#if 201103L <= YY_CPLUSPLUS\n      symbol_type (int tok, std::string v, location_type l)\n        : super_type (token_kind_type (tok), std::move (v), std::move (l))\n#else\n      symbol_type (int tok, const std::string& v, const location_type& l)\n        : super_type (token_kind_type (tok), v, l)\n#endif\n      {\n#if !defined _MSC_VER || defined __clang__\n        YY_ASSERT ((token::TOK_ACTION_ACCURACY <= tok && tok <= token::TOK_DICT_ELEMENT_REGEXP));\n#endif\n      }\n    };\n\n    /// Build a parser object.\n    seclang_parser (modsecurity::Parser::Driver& driver_yyarg);\n    virtual ~seclang_parser ();\n\n#if 201103L <= YY_CPLUSPLUS\n    /// Non copyable.\n    seclang_parser (const seclang_parser&) = delete;\n    /// Non copyable.\n    seclang_parser& operator= (const seclang_parser&) = delete;\n#endif\n\n    /// Parse.  An alias for parse ().\n    /// \\returns  0 iff parsing succeeded.\n    int operator() ();\n\n    /// Parse.\n    /// \\returns  0 iff parsing succeeded.\n    virtual int parse ();\n\n#if YYDEBUG\n    /// The current debugging stream.\n    std::ostream& debug_stream () const YY_ATTRIBUTE_PURE;\n    /// Set the current debugging stream.\n    void set_debug_stream (std::ostream &);\n\n    /// Type for debugging levels.\n    typedef int debug_level_type;\n    /// The current debugging level.\n    debug_level_type debug_level () const YY_ATTRIBUTE_PURE;\n    /// Set the current debugging level.\n    void set_debug_level (debug_level_type l);\n#endif\n\n    /// Report a syntax error.\n    /// \\param loc    where the syntax error is found.\n    /// \\param msg    a description of the syntax error.\n    virtual void error (const location_type& loc, const std::string& msg);\n\n    /// Report a syntax error.\n    void error (const syntax_error& err);\n\n    /// The user-facing name of the symbol whose (internal) number is\n    /// YYSYMBOL.  No bounds checking.\n    static std::string symbol_name (symbol_kind_type yysymbol);\n\n    // Implementation of make_symbol for each token kind.\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_END (location_type l)\n      {\n        return symbol_type (token::TOK_END, std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_END (const location_type& l)\n      {\n        return symbol_type (token::TOK_END, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_YYerror (location_type l)\n      {\n        return symbol_type (token::TOK_YYerror, std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_YYerror (const location_type& l)\n      {\n        return symbol_type (token::TOK_YYerror, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_YYUNDEF (location_type l)\n      {\n        return symbol_type (token::TOK_YYUNDEF, std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_YYUNDEF (const location_type& l)\n      {\n        return symbol_type (token::TOK_YYUNDEF, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_COMMA (location_type l)\n      {\n        return symbol_type (token::TOK_COMMA, std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_COMMA (const location_type& l)\n      {\n        return symbol_type (token::TOK_COMMA, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_CONFIG_CONTENT_INJECTION (location_type l)\n      {\n        return symbol_type (token::TOK_CONFIG_CONTENT_INJECTION, std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_CONFIG_CONTENT_INJECTION (const location_type& l)\n      {\n        return symbol_type (token::TOK_CONFIG_CONTENT_INJECTION, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_CONGIG_DIR_RESPONSE_BODY_MP_CLEAR (location_type l)\n      {\n        return symbol_type (token::TOK_CONGIG_DIR_RESPONSE_BODY_MP_CLEAR, std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_CONGIG_DIR_RESPONSE_BODY_MP_CLEAR (const location_type& l)\n      {\n        return symbol_type (token::TOK_CONGIG_DIR_RESPONSE_BODY_MP_CLEAR, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_PIPE (location_type l)\n      {\n        return symbol_type (token::TOK_PIPE, std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_PIPE (const location_type& l)\n      {\n        return symbol_type (token::TOK_PIPE, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_NEW_LINE (location_type l)\n      {\n        return symbol_type (token::TOK_NEW_LINE, std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_NEW_LINE (const location_type& l)\n      {\n        return symbol_type (token::TOK_NEW_LINE, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_VAR_COUNT (location_type l)\n      {\n        return symbol_type (token::TOK_VAR_COUNT, std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_VAR_COUNT (const location_type& l)\n      {\n        return symbol_type (token::TOK_VAR_COUNT, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_VAR_EXCLUSION (location_type l)\n      {\n        return symbol_type (token::TOK_VAR_EXCLUSION, std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_VAR_EXCLUSION (const location_type& l)\n      {\n        return symbol_type (token::TOK_VAR_EXCLUSION, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_VARIABLE_ARGS (location_type l)\n      {\n        return symbol_type (token::TOK_VARIABLE_ARGS, std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_VARIABLE_ARGS (const location_type& l)\n      {\n        return symbol_type (token::TOK_VARIABLE_ARGS, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_VARIABLE_ARGS_POST (location_type l)\n      {\n        return symbol_type (token::TOK_VARIABLE_ARGS_POST, std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_VARIABLE_ARGS_POST (const location_type& l)\n      {\n        return symbol_type (token::TOK_VARIABLE_ARGS_POST, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_VARIABLE_ARGS_GET (location_type l)\n      {\n        return symbol_type (token::TOK_VARIABLE_ARGS_GET, std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_VARIABLE_ARGS_GET (const location_type& l)\n      {\n        return symbol_type (token::TOK_VARIABLE_ARGS_GET, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_VARIABLE_FILES_SIZES (location_type l)\n      {\n        return symbol_type (token::TOK_VARIABLE_FILES_SIZES, std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_VARIABLE_FILES_SIZES (const location_type& l)\n      {\n        return symbol_type (token::TOK_VARIABLE_FILES_SIZES, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_VARIABLE_FILES_NAMES (location_type l)\n      {\n        return symbol_type (token::TOK_VARIABLE_FILES_NAMES, std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_VARIABLE_FILES_NAMES (const location_type& l)\n      {\n        return symbol_type (token::TOK_VARIABLE_FILES_NAMES, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_VARIABLE_FILES_TMP_CONTENT (location_type l)\n      {\n        return symbol_type (token::TOK_VARIABLE_FILES_TMP_CONTENT, std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_VARIABLE_FILES_TMP_CONTENT (const location_type& l)\n      {\n        return symbol_type (token::TOK_VARIABLE_FILES_TMP_CONTENT, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_VARIABLE_MULTIPART_FILENAME (location_type l)\n      {\n        return symbol_type (token::TOK_VARIABLE_MULTIPART_FILENAME, std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_VARIABLE_MULTIPART_FILENAME (const location_type& l)\n      {\n        return symbol_type (token::TOK_VARIABLE_MULTIPART_FILENAME, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_VARIABLE_MULTIPART_NAME (location_type l)\n      {\n        return symbol_type (token::TOK_VARIABLE_MULTIPART_NAME, std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_VARIABLE_MULTIPART_NAME (const location_type& l)\n      {\n        return symbol_type (token::TOK_VARIABLE_MULTIPART_NAME, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_VARIABLE_MATCHED_VARS_NAMES (location_type l)\n      {\n        return symbol_type (token::TOK_VARIABLE_MATCHED_VARS_NAMES, std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_VARIABLE_MATCHED_VARS_NAMES (const location_type& l)\n      {\n        return symbol_type (token::TOK_VARIABLE_MATCHED_VARS_NAMES, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_VARIABLE_MATCHED_VARS (location_type l)\n      {\n        return symbol_type (token::TOK_VARIABLE_MATCHED_VARS, std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_VARIABLE_MATCHED_VARS (const location_type& l)\n      {\n        return symbol_type (token::TOK_VARIABLE_MATCHED_VARS, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_VARIABLE_FILES (location_type l)\n      {\n        return symbol_type (token::TOK_VARIABLE_FILES, std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_VARIABLE_FILES (const location_type& l)\n      {\n        return symbol_type (token::TOK_VARIABLE_FILES, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_VARIABLE_REQUEST_COOKIES (location_type l)\n      {\n        return symbol_type (token::TOK_VARIABLE_REQUEST_COOKIES, std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_VARIABLE_REQUEST_COOKIES (const location_type& l)\n      {\n        return symbol_type (token::TOK_VARIABLE_REQUEST_COOKIES, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_VARIABLE_REQUEST_HEADERS (location_type l)\n      {\n        return symbol_type (token::TOK_VARIABLE_REQUEST_HEADERS, std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_VARIABLE_REQUEST_HEADERS (const location_type& l)\n      {\n        return symbol_type (token::TOK_VARIABLE_REQUEST_HEADERS, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_VARIABLE_RESPONSE_HEADERS (location_type l)\n      {\n        return symbol_type (token::TOK_VARIABLE_RESPONSE_HEADERS, std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_VARIABLE_RESPONSE_HEADERS (const location_type& l)\n      {\n        return symbol_type (token::TOK_VARIABLE_RESPONSE_HEADERS, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_VARIABLE_GEO (location_type l)\n      {\n        return symbol_type (token::TOK_VARIABLE_GEO, std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_VARIABLE_GEO (const location_type& l)\n      {\n        return symbol_type (token::TOK_VARIABLE_GEO, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_VARIABLE_REQUEST_COOKIES_NAMES (location_type l)\n      {\n        return symbol_type (token::TOK_VARIABLE_REQUEST_COOKIES_NAMES, std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_VARIABLE_REQUEST_COOKIES_NAMES (const location_type& l)\n      {\n        return symbol_type (token::TOK_VARIABLE_REQUEST_COOKIES_NAMES, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_VARIABLE_MULTIPART_PART_HEADERS (location_type l)\n      {\n        return symbol_type (token::TOK_VARIABLE_MULTIPART_PART_HEADERS, std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_VARIABLE_MULTIPART_PART_HEADERS (const location_type& l)\n      {\n        return symbol_type (token::TOK_VARIABLE_MULTIPART_PART_HEADERS, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_VARIABLE_ARGS_COMBINED_SIZE (location_type l)\n      {\n        return symbol_type (token::TOK_VARIABLE_ARGS_COMBINED_SIZE, std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_VARIABLE_ARGS_COMBINED_SIZE (const location_type& l)\n      {\n        return symbol_type (token::TOK_VARIABLE_ARGS_COMBINED_SIZE, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_VARIABLE_ARGS_GET_NAMES (location_type l)\n      {\n        return symbol_type (token::TOK_VARIABLE_ARGS_GET_NAMES, std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_VARIABLE_ARGS_GET_NAMES (const location_type& l)\n      {\n        return symbol_type (token::TOK_VARIABLE_ARGS_GET_NAMES, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_VARIABLE_RULE (location_type l)\n      {\n        return symbol_type (token::TOK_VARIABLE_RULE, std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_VARIABLE_RULE (const location_type& l)\n      {\n        return symbol_type (token::TOK_VARIABLE_RULE, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_VARIABLE_ARGS_NAMES (location_type l)\n      {\n        return symbol_type (token::TOK_VARIABLE_ARGS_NAMES, std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_VARIABLE_ARGS_NAMES (const location_type& l)\n      {\n        return symbol_type (token::TOK_VARIABLE_ARGS_NAMES, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_VARIABLE_ARGS_POST_NAMES (location_type l)\n      {\n        return symbol_type (token::TOK_VARIABLE_ARGS_POST_NAMES, std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_VARIABLE_ARGS_POST_NAMES (const location_type& l)\n      {\n        return symbol_type (token::TOK_VARIABLE_ARGS_POST_NAMES, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_VARIABLE_AUTH_TYPE (location_type l)\n      {\n        return symbol_type (token::TOK_VARIABLE_AUTH_TYPE, std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_VARIABLE_AUTH_TYPE (const location_type& l)\n      {\n        return symbol_type (token::TOK_VARIABLE_AUTH_TYPE, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_VARIABLE_FILES_COMBINED_SIZE (location_type l)\n      {\n        return symbol_type (token::TOK_VARIABLE_FILES_COMBINED_SIZE, std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_VARIABLE_FILES_COMBINED_SIZE (const location_type& l)\n      {\n        return symbol_type (token::TOK_VARIABLE_FILES_COMBINED_SIZE, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_VARIABLE_FILES_TMP_NAMES (location_type l)\n      {\n        return symbol_type (token::TOK_VARIABLE_FILES_TMP_NAMES, std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_VARIABLE_FILES_TMP_NAMES (const location_type& l)\n      {\n        return symbol_type (token::TOK_VARIABLE_FILES_TMP_NAMES, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_VARIABLE_FULL_REQUEST (location_type l)\n      {\n        return symbol_type (token::TOK_VARIABLE_FULL_REQUEST, std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_VARIABLE_FULL_REQUEST (const location_type& l)\n      {\n        return symbol_type (token::TOK_VARIABLE_FULL_REQUEST, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_VARIABLE_FULL_REQUEST_LENGTH (location_type l)\n      {\n        return symbol_type (token::TOK_VARIABLE_FULL_REQUEST_LENGTH, std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_VARIABLE_FULL_REQUEST_LENGTH (const location_type& l)\n      {\n        return symbol_type (token::TOK_VARIABLE_FULL_REQUEST_LENGTH, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_VARIABLE_INBOUND_DATA_ERROR (location_type l)\n      {\n        return symbol_type (token::TOK_VARIABLE_INBOUND_DATA_ERROR, std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_VARIABLE_INBOUND_DATA_ERROR (const location_type& l)\n      {\n        return symbol_type (token::TOK_VARIABLE_INBOUND_DATA_ERROR, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_VARIABLE_MATCHED_VAR (location_type l)\n      {\n        return symbol_type (token::TOK_VARIABLE_MATCHED_VAR, std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_VARIABLE_MATCHED_VAR (const location_type& l)\n      {\n        return symbol_type (token::TOK_VARIABLE_MATCHED_VAR, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_VARIABLE_MATCHED_VAR_NAME (location_type l)\n      {\n        return symbol_type (token::TOK_VARIABLE_MATCHED_VAR_NAME, std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_VARIABLE_MATCHED_VAR_NAME (const location_type& l)\n      {\n        return symbol_type (token::TOK_VARIABLE_MATCHED_VAR_NAME, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_VARIABLE_MSC_PCRE_ERROR (location_type l)\n      {\n        return symbol_type (token::TOK_VARIABLE_MSC_PCRE_ERROR, std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_VARIABLE_MSC_PCRE_ERROR (const location_type& l)\n      {\n        return symbol_type (token::TOK_VARIABLE_MSC_PCRE_ERROR, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_VARIABLE_MSC_PCRE_LIMITS_EXCEEDED (location_type l)\n      {\n        return symbol_type (token::TOK_VARIABLE_MSC_PCRE_LIMITS_EXCEEDED, std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_VARIABLE_MSC_PCRE_LIMITS_EXCEEDED (const location_type& l)\n      {\n        return symbol_type (token::TOK_VARIABLE_MSC_PCRE_LIMITS_EXCEEDED, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_VARIABLE_MULTIPART_BOUNDARY_QUOTED (location_type l)\n      {\n        return symbol_type (token::TOK_VARIABLE_MULTIPART_BOUNDARY_QUOTED, std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_VARIABLE_MULTIPART_BOUNDARY_QUOTED (const location_type& l)\n      {\n        return symbol_type (token::TOK_VARIABLE_MULTIPART_BOUNDARY_QUOTED, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_VARIABLE_MULTIPART_BOUNDARY_WHITESPACE (location_type l)\n      {\n        return symbol_type (token::TOK_VARIABLE_MULTIPART_BOUNDARY_WHITESPACE, std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_VARIABLE_MULTIPART_BOUNDARY_WHITESPACE (const location_type& l)\n      {\n        return symbol_type (token::TOK_VARIABLE_MULTIPART_BOUNDARY_WHITESPACE, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_VARIABLE_MULTIPART_CRLF_LF_LINES (location_type l)\n      {\n        return symbol_type (token::TOK_VARIABLE_MULTIPART_CRLF_LF_LINES, std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_VARIABLE_MULTIPART_CRLF_LF_LINES (const location_type& l)\n      {\n        return symbol_type (token::TOK_VARIABLE_MULTIPART_CRLF_LF_LINES, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_VARIABLE_MULTIPART_DATA_AFTER (location_type l)\n      {\n        return symbol_type (token::TOK_VARIABLE_MULTIPART_DATA_AFTER, std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_VARIABLE_MULTIPART_DATA_AFTER (const location_type& l)\n      {\n        return symbol_type (token::TOK_VARIABLE_MULTIPART_DATA_AFTER, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_VARIABLE_MULTIPART_DATA_BEFORE (location_type l)\n      {\n        return symbol_type (token::TOK_VARIABLE_MULTIPART_DATA_BEFORE, std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_VARIABLE_MULTIPART_DATA_BEFORE (const location_type& l)\n      {\n        return symbol_type (token::TOK_VARIABLE_MULTIPART_DATA_BEFORE, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_VARIABLE_MULTIPART_FILE_LIMIT_EXCEEDED (location_type l)\n      {\n        return symbol_type (token::TOK_VARIABLE_MULTIPART_FILE_LIMIT_EXCEEDED, std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_VARIABLE_MULTIPART_FILE_LIMIT_EXCEEDED (const location_type& l)\n      {\n        return symbol_type (token::TOK_VARIABLE_MULTIPART_FILE_LIMIT_EXCEEDED, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_VARIABLE_MULTIPART_HEADER_FOLDING (location_type l)\n      {\n        return symbol_type (token::TOK_VARIABLE_MULTIPART_HEADER_FOLDING, std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_VARIABLE_MULTIPART_HEADER_FOLDING (const location_type& l)\n      {\n        return symbol_type (token::TOK_VARIABLE_MULTIPART_HEADER_FOLDING, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_VARIABLE_MULTIPART_INVALID_HEADER_FOLDING (location_type l)\n      {\n        return symbol_type (token::TOK_VARIABLE_MULTIPART_INVALID_HEADER_FOLDING, std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_VARIABLE_MULTIPART_INVALID_HEADER_FOLDING (const location_type& l)\n      {\n        return symbol_type (token::TOK_VARIABLE_MULTIPART_INVALID_HEADER_FOLDING, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_VARIABLE_MULTIPART_INVALID_PART (location_type l)\n      {\n        return symbol_type (token::TOK_VARIABLE_MULTIPART_INVALID_PART, std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_VARIABLE_MULTIPART_INVALID_PART (const location_type& l)\n      {\n        return symbol_type (token::TOK_VARIABLE_MULTIPART_INVALID_PART, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_VARIABLE_MULTIPART_INVALID_QUOTING (location_type l)\n      {\n        return symbol_type (token::TOK_VARIABLE_MULTIPART_INVALID_QUOTING, std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_VARIABLE_MULTIPART_INVALID_QUOTING (const location_type& l)\n      {\n        return symbol_type (token::TOK_VARIABLE_MULTIPART_INVALID_QUOTING, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_VARIABLE_MULTIPART_LF_LINE (location_type l)\n      {\n        return symbol_type (token::TOK_VARIABLE_MULTIPART_LF_LINE, std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_VARIABLE_MULTIPART_LF_LINE (const location_type& l)\n      {\n        return symbol_type (token::TOK_VARIABLE_MULTIPART_LF_LINE, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_VARIABLE_MULTIPART_MISSING_SEMICOLON (location_type l)\n      {\n        return symbol_type (token::TOK_VARIABLE_MULTIPART_MISSING_SEMICOLON, std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_VARIABLE_MULTIPART_MISSING_SEMICOLON (const location_type& l)\n      {\n        return symbol_type (token::TOK_VARIABLE_MULTIPART_MISSING_SEMICOLON, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_VARIABLE_MULTIPART_SEMICOLON_MISSING (location_type l)\n      {\n        return symbol_type (token::TOK_VARIABLE_MULTIPART_SEMICOLON_MISSING, std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_VARIABLE_MULTIPART_SEMICOLON_MISSING (const location_type& l)\n      {\n        return symbol_type (token::TOK_VARIABLE_MULTIPART_SEMICOLON_MISSING, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_VARIABLE_MULTIPART_STRICT_ERROR (location_type l)\n      {\n        return symbol_type (token::TOK_VARIABLE_MULTIPART_STRICT_ERROR, std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_VARIABLE_MULTIPART_STRICT_ERROR (const location_type& l)\n      {\n        return symbol_type (token::TOK_VARIABLE_MULTIPART_STRICT_ERROR, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_VARIABLE_MULTIPART_UNMATCHED_BOUNDARY (location_type l)\n      {\n        return symbol_type (token::TOK_VARIABLE_MULTIPART_UNMATCHED_BOUNDARY, std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_VARIABLE_MULTIPART_UNMATCHED_BOUNDARY (const location_type& l)\n      {\n        return symbol_type (token::TOK_VARIABLE_MULTIPART_UNMATCHED_BOUNDARY, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_VARIABLE_OUTBOUND_DATA_ERROR (location_type l)\n      {\n        return symbol_type (token::TOK_VARIABLE_OUTBOUND_DATA_ERROR, std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_VARIABLE_OUTBOUND_DATA_ERROR (const location_type& l)\n      {\n        return symbol_type (token::TOK_VARIABLE_OUTBOUND_DATA_ERROR, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_VARIABLE_PATH_INFO (location_type l)\n      {\n        return symbol_type (token::TOK_VARIABLE_PATH_INFO, std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_VARIABLE_PATH_INFO (const location_type& l)\n      {\n        return symbol_type (token::TOK_VARIABLE_PATH_INFO, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_VARIABLE_QUERY_STRING (location_type l)\n      {\n        return symbol_type (token::TOK_VARIABLE_QUERY_STRING, std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_VARIABLE_QUERY_STRING (const location_type& l)\n      {\n        return symbol_type (token::TOK_VARIABLE_QUERY_STRING, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_VARIABLE_REMOTE_ADDR (location_type l)\n      {\n        return symbol_type (token::TOK_VARIABLE_REMOTE_ADDR, std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_VARIABLE_REMOTE_ADDR (const location_type& l)\n      {\n        return symbol_type (token::TOK_VARIABLE_REMOTE_ADDR, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_VARIABLE_REMOTE_HOST (location_type l)\n      {\n        return symbol_type (token::TOK_VARIABLE_REMOTE_HOST, std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_VARIABLE_REMOTE_HOST (const location_type& l)\n      {\n        return symbol_type (token::TOK_VARIABLE_REMOTE_HOST, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_VARIABLE_REMOTE_PORT (location_type l)\n      {\n        return symbol_type (token::TOK_VARIABLE_REMOTE_PORT, std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_VARIABLE_REMOTE_PORT (const location_type& l)\n      {\n        return symbol_type (token::TOK_VARIABLE_REMOTE_PORT, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_VARIABLE_REQBODY_ERROR_MSG (location_type l)\n      {\n        return symbol_type (token::TOK_VARIABLE_REQBODY_ERROR_MSG, std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_VARIABLE_REQBODY_ERROR_MSG (const location_type& l)\n      {\n        return symbol_type (token::TOK_VARIABLE_REQBODY_ERROR_MSG, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_VARIABLE_REQBODY_ERROR (location_type l)\n      {\n        return symbol_type (token::TOK_VARIABLE_REQBODY_ERROR, std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_VARIABLE_REQBODY_ERROR (const location_type& l)\n      {\n        return symbol_type (token::TOK_VARIABLE_REQBODY_ERROR, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_VARIABLE_REQBODY_PROCESSOR_ERROR_MSG (location_type l)\n      {\n        return symbol_type (token::TOK_VARIABLE_REQBODY_PROCESSOR_ERROR_MSG, std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_VARIABLE_REQBODY_PROCESSOR_ERROR_MSG (const location_type& l)\n      {\n        return symbol_type (token::TOK_VARIABLE_REQBODY_PROCESSOR_ERROR_MSG, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_VARIABLE_REQBODY_PROCESSOR_ERROR (location_type l)\n      {\n        return symbol_type (token::TOK_VARIABLE_REQBODY_PROCESSOR_ERROR, std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_VARIABLE_REQBODY_PROCESSOR_ERROR (const location_type& l)\n      {\n        return symbol_type (token::TOK_VARIABLE_REQBODY_PROCESSOR_ERROR, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_VARIABLE_REQBODY_PROCESSOR (location_type l)\n      {\n        return symbol_type (token::TOK_VARIABLE_REQBODY_PROCESSOR, std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_VARIABLE_REQBODY_PROCESSOR (const location_type& l)\n      {\n        return symbol_type (token::TOK_VARIABLE_REQBODY_PROCESSOR, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_VARIABLE_REQUEST_BASENAME (location_type l)\n      {\n        return symbol_type (token::TOK_VARIABLE_REQUEST_BASENAME, std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_VARIABLE_REQUEST_BASENAME (const location_type& l)\n      {\n        return symbol_type (token::TOK_VARIABLE_REQUEST_BASENAME, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_VARIABLE_REQUEST_BODY_LENGTH (location_type l)\n      {\n        return symbol_type (token::TOK_VARIABLE_REQUEST_BODY_LENGTH, std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_VARIABLE_REQUEST_BODY_LENGTH (const location_type& l)\n      {\n        return symbol_type (token::TOK_VARIABLE_REQUEST_BODY_LENGTH, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_VARIABLE_REQUEST_BODY (location_type l)\n      {\n        return symbol_type (token::TOK_VARIABLE_REQUEST_BODY, std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_VARIABLE_REQUEST_BODY (const location_type& l)\n      {\n        return symbol_type (token::TOK_VARIABLE_REQUEST_BODY, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_VARIABLE_REQUEST_FILE_NAME (location_type l)\n      {\n        return symbol_type (token::TOK_VARIABLE_REQUEST_FILE_NAME, std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_VARIABLE_REQUEST_FILE_NAME (const location_type& l)\n      {\n        return symbol_type (token::TOK_VARIABLE_REQUEST_FILE_NAME, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_VARIABLE_REQUEST_HEADERS_NAMES (location_type l)\n      {\n        return symbol_type (token::TOK_VARIABLE_REQUEST_HEADERS_NAMES, std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_VARIABLE_REQUEST_HEADERS_NAMES (const location_type& l)\n      {\n        return symbol_type (token::TOK_VARIABLE_REQUEST_HEADERS_NAMES, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_VARIABLE_REQUEST_LINE (location_type l)\n      {\n        return symbol_type (token::TOK_VARIABLE_REQUEST_LINE, std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_VARIABLE_REQUEST_LINE (const location_type& l)\n      {\n        return symbol_type (token::TOK_VARIABLE_REQUEST_LINE, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_VARIABLE_REQUEST_METHOD (location_type l)\n      {\n        return symbol_type (token::TOK_VARIABLE_REQUEST_METHOD, std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_VARIABLE_REQUEST_METHOD (const location_type& l)\n      {\n        return symbol_type (token::TOK_VARIABLE_REQUEST_METHOD, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_VARIABLE_REQUEST_PROTOCOL (location_type l)\n      {\n        return symbol_type (token::TOK_VARIABLE_REQUEST_PROTOCOL, std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_VARIABLE_REQUEST_PROTOCOL (const location_type& l)\n      {\n        return symbol_type (token::TOK_VARIABLE_REQUEST_PROTOCOL, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_VARIABLE_REQUEST_URI_RAW (location_type l)\n      {\n        return symbol_type (token::TOK_VARIABLE_REQUEST_URI_RAW, std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_VARIABLE_REQUEST_URI_RAW (const location_type& l)\n      {\n        return symbol_type (token::TOK_VARIABLE_REQUEST_URI_RAW, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_VARIABLE_REQUEST_URI (location_type l)\n      {\n        return symbol_type (token::TOK_VARIABLE_REQUEST_URI, std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_VARIABLE_REQUEST_URI (const location_type& l)\n      {\n        return symbol_type (token::TOK_VARIABLE_REQUEST_URI, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_VARIABLE_RESOURCE (location_type l)\n      {\n        return symbol_type (token::TOK_VARIABLE_RESOURCE, std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_VARIABLE_RESOURCE (const location_type& l)\n      {\n        return symbol_type (token::TOK_VARIABLE_RESOURCE, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_VARIABLE_RESPONSE_BODY (location_type l)\n      {\n        return symbol_type (token::TOK_VARIABLE_RESPONSE_BODY, std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_VARIABLE_RESPONSE_BODY (const location_type& l)\n      {\n        return symbol_type (token::TOK_VARIABLE_RESPONSE_BODY, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_VARIABLE_RESPONSE_CONTENT_LENGTH (location_type l)\n      {\n        return symbol_type (token::TOK_VARIABLE_RESPONSE_CONTENT_LENGTH, std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_VARIABLE_RESPONSE_CONTENT_LENGTH (const location_type& l)\n      {\n        return symbol_type (token::TOK_VARIABLE_RESPONSE_CONTENT_LENGTH, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_VARIABLE_RESPONSE_CONTENT_TYPE (location_type l)\n      {\n        return symbol_type (token::TOK_VARIABLE_RESPONSE_CONTENT_TYPE, std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_VARIABLE_RESPONSE_CONTENT_TYPE (const location_type& l)\n      {\n        return symbol_type (token::TOK_VARIABLE_RESPONSE_CONTENT_TYPE, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_VARIABLE_RESPONSE_HEADERS_NAMES (location_type l)\n      {\n        return symbol_type (token::TOK_VARIABLE_RESPONSE_HEADERS_NAMES, std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_VARIABLE_RESPONSE_HEADERS_NAMES (const location_type& l)\n      {\n        return symbol_type (token::TOK_VARIABLE_RESPONSE_HEADERS_NAMES, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_VARIABLE_RESPONSE_PROTOCOL (location_type l)\n      {\n        return symbol_type (token::TOK_VARIABLE_RESPONSE_PROTOCOL, std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_VARIABLE_RESPONSE_PROTOCOL (const location_type& l)\n      {\n        return symbol_type (token::TOK_VARIABLE_RESPONSE_PROTOCOL, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_VARIABLE_RESPONSE_STATUS (location_type l)\n      {\n        return symbol_type (token::TOK_VARIABLE_RESPONSE_STATUS, std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_VARIABLE_RESPONSE_STATUS (const location_type& l)\n      {\n        return symbol_type (token::TOK_VARIABLE_RESPONSE_STATUS, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_VARIABLE_SERVER_ADDR (location_type l)\n      {\n        return symbol_type (token::TOK_VARIABLE_SERVER_ADDR, std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_VARIABLE_SERVER_ADDR (const location_type& l)\n      {\n        return symbol_type (token::TOK_VARIABLE_SERVER_ADDR, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_VARIABLE_SERVER_NAME (location_type l)\n      {\n        return symbol_type (token::TOK_VARIABLE_SERVER_NAME, std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_VARIABLE_SERVER_NAME (const location_type& l)\n      {\n        return symbol_type (token::TOK_VARIABLE_SERVER_NAME, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_VARIABLE_SERVER_PORT (location_type l)\n      {\n        return symbol_type (token::TOK_VARIABLE_SERVER_PORT, std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_VARIABLE_SERVER_PORT (const location_type& l)\n      {\n        return symbol_type (token::TOK_VARIABLE_SERVER_PORT, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_VARIABLE_SESSION_ID (location_type l)\n      {\n        return symbol_type (token::TOK_VARIABLE_SESSION_ID, std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_VARIABLE_SESSION_ID (const location_type& l)\n      {\n        return symbol_type (token::TOK_VARIABLE_SESSION_ID, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_VARIABLE_UNIQUE_ID (location_type l)\n      {\n        return symbol_type (token::TOK_VARIABLE_UNIQUE_ID, std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_VARIABLE_UNIQUE_ID (const location_type& l)\n      {\n        return symbol_type (token::TOK_VARIABLE_UNIQUE_ID, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_VARIABLE_URL_ENCODED_ERROR (location_type l)\n      {\n        return symbol_type (token::TOK_VARIABLE_URL_ENCODED_ERROR, std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_VARIABLE_URL_ENCODED_ERROR (const location_type& l)\n      {\n        return symbol_type (token::TOK_VARIABLE_URL_ENCODED_ERROR, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_VARIABLE_USER_ID (location_type l)\n      {\n        return symbol_type (token::TOK_VARIABLE_USER_ID, std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_VARIABLE_USER_ID (const location_type& l)\n      {\n        return symbol_type (token::TOK_VARIABLE_USER_ID, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_VARIABLE_WEB_APP_ID (location_type l)\n      {\n        return symbol_type (token::TOK_VARIABLE_WEB_APP_ID, std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_VARIABLE_WEB_APP_ID (const location_type& l)\n      {\n        return symbol_type (token::TOK_VARIABLE_WEB_APP_ID, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_VARIABLE_STATUS (location_type l)\n      {\n        return symbol_type (token::TOK_VARIABLE_STATUS, std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_VARIABLE_STATUS (const location_type& l)\n      {\n        return symbol_type (token::TOK_VARIABLE_STATUS, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_VARIABLE_STATUS_LINE (location_type l)\n      {\n        return symbol_type (token::TOK_VARIABLE_STATUS_LINE, std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_VARIABLE_STATUS_LINE (const location_type& l)\n      {\n        return symbol_type (token::TOK_VARIABLE_STATUS_LINE, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_VARIABLE_IP (location_type l)\n      {\n        return symbol_type (token::TOK_VARIABLE_IP, std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_VARIABLE_IP (const location_type& l)\n      {\n        return symbol_type (token::TOK_VARIABLE_IP, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_VARIABLE_GLOBAL (location_type l)\n      {\n        return symbol_type (token::TOK_VARIABLE_GLOBAL, std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_VARIABLE_GLOBAL (const location_type& l)\n      {\n        return symbol_type (token::TOK_VARIABLE_GLOBAL, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_VARIABLE_TX (location_type l)\n      {\n        return symbol_type (token::TOK_VARIABLE_TX, std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_VARIABLE_TX (const location_type& l)\n      {\n        return symbol_type (token::TOK_VARIABLE_TX, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_VARIABLE_SESSION (location_type l)\n      {\n        return symbol_type (token::TOK_VARIABLE_SESSION, std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_VARIABLE_SESSION (const location_type& l)\n      {\n        return symbol_type (token::TOK_VARIABLE_SESSION, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_VARIABLE_USER (location_type l)\n      {\n        return symbol_type (token::TOK_VARIABLE_USER, std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_VARIABLE_USER (const location_type& l)\n      {\n        return symbol_type (token::TOK_VARIABLE_USER, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_RUN_TIME_VAR_ENV (location_type l)\n      {\n        return symbol_type (token::TOK_RUN_TIME_VAR_ENV, std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_RUN_TIME_VAR_ENV (const location_type& l)\n      {\n        return symbol_type (token::TOK_RUN_TIME_VAR_ENV, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_RUN_TIME_VAR_XML (location_type l)\n      {\n        return symbol_type (token::TOK_RUN_TIME_VAR_XML, std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_RUN_TIME_VAR_XML (const location_type& l)\n      {\n        return symbol_type (token::TOK_RUN_TIME_VAR_XML, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_ACTION_SETVAR (location_type l)\n      {\n        return symbol_type (token::TOK_ACTION_SETVAR, std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_ACTION_SETVAR (const location_type& l)\n      {\n        return symbol_type (token::TOK_ACTION_SETVAR, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_SETVAR_OPERATION_EQUALS (location_type l)\n      {\n        return symbol_type (token::TOK_SETVAR_OPERATION_EQUALS, std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_SETVAR_OPERATION_EQUALS (const location_type& l)\n      {\n        return symbol_type (token::TOK_SETVAR_OPERATION_EQUALS, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_SETVAR_OPERATION_EQUALS_PLUS (location_type l)\n      {\n        return symbol_type (token::TOK_SETVAR_OPERATION_EQUALS_PLUS, std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_SETVAR_OPERATION_EQUALS_PLUS (const location_type& l)\n      {\n        return symbol_type (token::TOK_SETVAR_OPERATION_EQUALS_PLUS, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_SETVAR_OPERATION_EQUALS_MINUS (location_type l)\n      {\n        return symbol_type (token::TOK_SETVAR_OPERATION_EQUALS_MINUS, std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_SETVAR_OPERATION_EQUALS_MINUS (const location_type& l)\n      {\n        return symbol_type (token::TOK_SETVAR_OPERATION_EQUALS_MINUS, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_NOT (location_type l)\n      {\n        return symbol_type (token::TOK_NOT, std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_NOT (const location_type& l)\n      {\n        return symbol_type (token::TOK_NOT, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_OPERATOR_BEGINS_WITH (location_type l)\n      {\n        return symbol_type (token::TOK_OPERATOR_BEGINS_WITH, std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_OPERATOR_BEGINS_WITH (const location_type& l)\n      {\n        return symbol_type (token::TOK_OPERATOR_BEGINS_WITH, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_OPERATOR_CONTAINS (location_type l)\n      {\n        return symbol_type (token::TOK_OPERATOR_CONTAINS, std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_OPERATOR_CONTAINS (const location_type& l)\n      {\n        return symbol_type (token::TOK_OPERATOR_CONTAINS, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_OPERATOR_CONTAINS_WORD (location_type l)\n      {\n        return symbol_type (token::TOK_OPERATOR_CONTAINS_WORD, std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_OPERATOR_CONTAINS_WORD (const location_type& l)\n      {\n        return symbol_type (token::TOK_OPERATOR_CONTAINS_WORD, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_OPERATOR_DETECT_SQLI (location_type l)\n      {\n        return symbol_type (token::TOK_OPERATOR_DETECT_SQLI, std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_OPERATOR_DETECT_SQLI (const location_type& l)\n      {\n        return symbol_type (token::TOK_OPERATOR_DETECT_SQLI, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_OPERATOR_DETECT_XSS (location_type l)\n      {\n        return symbol_type (token::TOK_OPERATOR_DETECT_XSS, std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_OPERATOR_DETECT_XSS (const location_type& l)\n      {\n        return symbol_type (token::TOK_OPERATOR_DETECT_XSS, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_OPERATOR_ENDS_WITH (location_type l)\n      {\n        return symbol_type (token::TOK_OPERATOR_ENDS_WITH, std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_OPERATOR_ENDS_WITH (const location_type& l)\n      {\n        return symbol_type (token::TOK_OPERATOR_ENDS_WITH, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_OPERATOR_EQ (location_type l)\n      {\n        return symbol_type (token::TOK_OPERATOR_EQ, std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_OPERATOR_EQ (const location_type& l)\n      {\n        return symbol_type (token::TOK_OPERATOR_EQ, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_OPERATOR_FUZZY_HASH (location_type l)\n      {\n        return symbol_type (token::TOK_OPERATOR_FUZZY_HASH, std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_OPERATOR_FUZZY_HASH (const location_type& l)\n      {\n        return symbol_type (token::TOK_OPERATOR_FUZZY_HASH, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_OPERATOR_GEOLOOKUP (location_type l)\n      {\n        return symbol_type (token::TOK_OPERATOR_GEOLOOKUP, std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_OPERATOR_GEOLOOKUP (const location_type& l)\n      {\n        return symbol_type (token::TOK_OPERATOR_GEOLOOKUP, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_OPERATOR_GE (location_type l)\n      {\n        return symbol_type (token::TOK_OPERATOR_GE, std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_OPERATOR_GE (const location_type& l)\n      {\n        return symbol_type (token::TOK_OPERATOR_GE, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_OPERATOR_GSB_LOOKUP (location_type l)\n      {\n        return symbol_type (token::TOK_OPERATOR_GSB_LOOKUP, std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_OPERATOR_GSB_LOOKUP (const location_type& l)\n      {\n        return symbol_type (token::TOK_OPERATOR_GSB_LOOKUP, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_OPERATOR_GT (location_type l)\n      {\n        return symbol_type (token::TOK_OPERATOR_GT, std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_OPERATOR_GT (const location_type& l)\n      {\n        return symbol_type (token::TOK_OPERATOR_GT, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_OPERATOR_INSPECT_FILE (location_type l)\n      {\n        return symbol_type (token::TOK_OPERATOR_INSPECT_FILE, std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_OPERATOR_INSPECT_FILE (const location_type& l)\n      {\n        return symbol_type (token::TOK_OPERATOR_INSPECT_FILE, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_OPERATOR_IP_MATCH_FROM_FILE (location_type l)\n      {\n        return symbol_type (token::TOK_OPERATOR_IP_MATCH_FROM_FILE, std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_OPERATOR_IP_MATCH_FROM_FILE (const location_type& l)\n      {\n        return symbol_type (token::TOK_OPERATOR_IP_MATCH_FROM_FILE, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_OPERATOR_IP_MATCH (location_type l)\n      {\n        return symbol_type (token::TOK_OPERATOR_IP_MATCH, std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_OPERATOR_IP_MATCH (const location_type& l)\n      {\n        return symbol_type (token::TOK_OPERATOR_IP_MATCH, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_OPERATOR_LE (location_type l)\n      {\n        return symbol_type (token::TOK_OPERATOR_LE, std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_OPERATOR_LE (const location_type& l)\n      {\n        return symbol_type (token::TOK_OPERATOR_LE, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_OPERATOR_LT (location_type l)\n      {\n        return symbol_type (token::TOK_OPERATOR_LT, std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_OPERATOR_LT (const location_type& l)\n      {\n        return symbol_type (token::TOK_OPERATOR_LT, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_OPERATOR_PM_FROM_FILE (location_type l)\n      {\n        return symbol_type (token::TOK_OPERATOR_PM_FROM_FILE, std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_OPERATOR_PM_FROM_FILE (const location_type& l)\n      {\n        return symbol_type (token::TOK_OPERATOR_PM_FROM_FILE, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_OPERATOR_PM (location_type l)\n      {\n        return symbol_type (token::TOK_OPERATOR_PM, std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_OPERATOR_PM (const location_type& l)\n      {\n        return symbol_type (token::TOK_OPERATOR_PM, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_OPERATOR_RBL (location_type l)\n      {\n        return symbol_type (token::TOK_OPERATOR_RBL, std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_OPERATOR_RBL (const location_type& l)\n      {\n        return symbol_type (token::TOK_OPERATOR_RBL, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_OPERATOR_RSUB (location_type l)\n      {\n        return symbol_type (token::TOK_OPERATOR_RSUB, std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_OPERATOR_RSUB (const location_type& l)\n      {\n        return symbol_type (token::TOK_OPERATOR_RSUB, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_OPERATOR_RX_CONTENT_ONLY (location_type l)\n      {\n        return symbol_type (token::TOK_OPERATOR_RX_CONTENT_ONLY, std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_OPERATOR_RX_CONTENT_ONLY (const location_type& l)\n      {\n        return symbol_type (token::TOK_OPERATOR_RX_CONTENT_ONLY, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_OPERATOR_RX (location_type l)\n      {\n        return symbol_type (token::TOK_OPERATOR_RX, std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_OPERATOR_RX (const location_type& l)\n      {\n        return symbol_type (token::TOK_OPERATOR_RX, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_OPERATOR_RX_GLOBAL (location_type l)\n      {\n        return symbol_type (token::TOK_OPERATOR_RX_GLOBAL, std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_OPERATOR_RX_GLOBAL (const location_type& l)\n      {\n        return symbol_type (token::TOK_OPERATOR_RX_GLOBAL, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_OPERATOR_STR_EQ (location_type l)\n      {\n        return symbol_type (token::TOK_OPERATOR_STR_EQ, std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_OPERATOR_STR_EQ (const location_type& l)\n      {\n        return symbol_type (token::TOK_OPERATOR_STR_EQ, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_OPERATOR_STR_MATCH (location_type l)\n      {\n        return symbol_type (token::TOK_OPERATOR_STR_MATCH, std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_OPERATOR_STR_MATCH (const location_type& l)\n      {\n        return symbol_type (token::TOK_OPERATOR_STR_MATCH, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_OPERATOR_UNCONDITIONAL_MATCH (location_type l)\n      {\n        return symbol_type (token::TOK_OPERATOR_UNCONDITIONAL_MATCH, std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_OPERATOR_UNCONDITIONAL_MATCH (const location_type& l)\n      {\n        return symbol_type (token::TOK_OPERATOR_UNCONDITIONAL_MATCH, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_OPERATOR_VALIDATE_BYTE_RANGE (location_type l)\n      {\n        return symbol_type (token::TOK_OPERATOR_VALIDATE_BYTE_RANGE, std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_OPERATOR_VALIDATE_BYTE_RANGE (const location_type& l)\n      {\n        return symbol_type (token::TOK_OPERATOR_VALIDATE_BYTE_RANGE, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_OPERATOR_VALIDATE_DTD (location_type l)\n      {\n        return symbol_type (token::TOK_OPERATOR_VALIDATE_DTD, std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_OPERATOR_VALIDATE_DTD (const location_type& l)\n      {\n        return symbol_type (token::TOK_OPERATOR_VALIDATE_DTD, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_OPERATOR_VALIDATE_HASH (location_type l)\n      {\n        return symbol_type (token::TOK_OPERATOR_VALIDATE_HASH, std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_OPERATOR_VALIDATE_HASH (const location_type& l)\n      {\n        return symbol_type (token::TOK_OPERATOR_VALIDATE_HASH, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_OPERATOR_VALIDATE_SCHEMA (location_type l)\n      {\n        return symbol_type (token::TOK_OPERATOR_VALIDATE_SCHEMA, std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_OPERATOR_VALIDATE_SCHEMA (const location_type& l)\n      {\n        return symbol_type (token::TOK_OPERATOR_VALIDATE_SCHEMA, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_OPERATOR_VALIDATE_URL_ENCODING (location_type l)\n      {\n        return symbol_type (token::TOK_OPERATOR_VALIDATE_URL_ENCODING, std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_OPERATOR_VALIDATE_URL_ENCODING (const location_type& l)\n      {\n        return symbol_type (token::TOK_OPERATOR_VALIDATE_URL_ENCODING, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_OPERATOR_VALIDATE_UTF8_ENCODING (location_type l)\n      {\n        return symbol_type (token::TOK_OPERATOR_VALIDATE_UTF8_ENCODING, std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_OPERATOR_VALIDATE_UTF8_ENCODING (const location_type& l)\n      {\n        return symbol_type (token::TOK_OPERATOR_VALIDATE_UTF8_ENCODING, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_OPERATOR_VERIFY_CC (location_type l)\n      {\n        return symbol_type (token::TOK_OPERATOR_VERIFY_CC, std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_OPERATOR_VERIFY_CC (const location_type& l)\n      {\n        return symbol_type (token::TOK_OPERATOR_VERIFY_CC, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_OPERATOR_VERIFY_CPF (location_type l)\n      {\n        return symbol_type (token::TOK_OPERATOR_VERIFY_CPF, std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_OPERATOR_VERIFY_CPF (const location_type& l)\n      {\n        return symbol_type (token::TOK_OPERATOR_VERIFY_CPF, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_OPERATOR_VERIFY_SSN (location_type l)\n      {\n        return symbol_type (token::TOK_OPERATOR_VERIFY_SSN, std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_OPERATOR_VERIFY_SSN (const location_type& l)\n      {\n        return symbol_type (token::TOK_OPERATOR_VERIFY_SSN, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_OPERATOR_VERIFY_SVNR (location_type l)\n      {\n        return symbol_type (token::TOK_OPERATOR_VERIFY_SVNR, std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_OPERATOR_VERIFY_SVNR (const location_type& l)\n      {\n        return symbol_type (token::TOK_OPERATOR_VERIFY_SVNR, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_OPERATOR_WITHIN (location_type l)\n      {\n        return symbol_type (token::TOK_OPERATOR_WITHIN, std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_OPERATOR_WITHIN (const location_type& l)\n      {\n        return symbol_type (token::TOK_OPERATOR_WITHIN, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_CONFIG_DIR_AUDIT_LOG_FMT (location_type l)\n      {\n        return symbol_type (token::TOK_CONFIG_DIR_AUDIT_LOG_FMT, std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_CONFIG_DIR_AUDIT_LOG_FMT (const location_type& l)\n      {\n        return symbol_type (token::TOK_CONFIG_DIR_AUDIT_LOG_FMT, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_JSON (location_type l)\n      {\n        return symbol_type (token::TOK_JSON, std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_JSON (const location_type& l)\n      {\n        return symbol_type (token::TOK_JSON, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_NATIVE (location_type l)\n      {\n        return symbol_type (token::TOK_NATIVE, std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_NATIVE (const location_type& l)\n      {\n        return symbol_type (token::TOK_NATIVE, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_ACTION_CTL_RULE_ENGINE (location_type l)\n      {\n        return symbol_type (token::TOK_ACTION_CTL_RULE_ENGINE, std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_ACTION_CTL_RULE_ENGINE (const location_type& l)\n      {\n        return symbol_type (token::TOK_ACTION_CTL_RULE_ENGINE, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_ACTION_ACCURACY (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_ACTION_ACCURACY, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_ACTION_ACCURACY (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_ACTION_ACCURACY, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_ACTION_ALLOW (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_ACTION_ALLOW, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_ACTION_ALLOW (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_ACTION_ALLOW, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_ACTION_APPEND (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_ACTION_APPEND, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_ACTION_APPEND (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_ACTION_APPEND, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_ACTION_AUDIT_LOG (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_ACTION_AUDIT_LOG, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_ACTION_AUDIT_LOG (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_ACTION_AUDIT_LOG, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_ACTION_BLOCK (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_ACTION_BLOCK, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_ACTION_BLOCK (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_ACTION_BLOCK, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_ACTION_CAPTURE (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_ACTION_CAPTURE, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_ACTION_CAPTURE (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_ACTION_CAPTURE, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_ACTION_CHAIN (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_ACTION_CHAIN, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_ACTION_CHAIN (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_ACTION_CHAIN, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_ACTION_CTL_AUDIT_ENGINE (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_ACTION_CTL_AUDIT_ENGINE, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_ACTION_CTL_AUDIT_ENGINE (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_ACTION_CTL_AUDIT_ENGINE, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_ACTION_CTL_AUDIT_LOG_PARTS (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_ACTION_CTL_AUDIT_LOG_PARTS, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_ACTION_CTL_AUDIT_LOG_PARTS (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_ACTION_CTL_AUDIT_LOG_PARTS, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_ACTION_CTL_BDY_JSON (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_ACTION_CTL_BDY_JSON, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_ACTION_CTL_BDY_JSON (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_ACTION_CTL_BDY_JSON, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_ACTION_CTL_BDY_XML (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_ACTION_CTL_BDY_XML, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_ACTION_CTL_BDY_XML (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_ACTION_CTL_BDY_XML, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_ACTION_CTL_BDY_URLENCODED (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_ACTION_CTL_BDY_URLENCODED, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_ACTION_CTL_BDY_URLENCODED (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_ACTION_CTL_BDY_URLENCODED, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_ACTION_CTL_FORCE_REQ_BODY_VAR (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_ACTION_CTL_FORCE_REQ_BODY_VAR, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_ACTION_CTL_FORCE_REQ_BODY_VAR (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_ACTION_CTL_FORCE_REQ_BODY_VAR, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_ACTION_CTL_PARSE_XML_INTO_ARGS (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_ACTION_CTL_PARSE_XML_INTO_ARGS, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_ACTION_CTL_PARSE_XML_INTO_ARGS (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_ACTION_CTL_PARSE_XML_INTO_ARGS, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_ACTION_CTL_REQUEST_BODY_ACCESS (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_ACTION_CTL_REQUEST_BODY_ACCESS, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_ACTION_CTL_REQUEST_BODY_ACCESS (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_ACTION_CTL_REQUEST_BODY_ACCESS, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_ACTION_CTL_RULE_REMOVE_BY_ID (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_ACTION_CTL_RULE_REMOVE_BY_ID, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_ACTION_CTL_RULE_REMOVE_BY_ID (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_ACTION_CTL_RULE_REMOVE_BY_ID, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_ACTION_CTL_RULE_REMOVE_BY_TAG (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_ACTION_CTL_RULE_REMOVE_BY_TAG, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_ACTION_CTL_RULE_REMOVE_BY_TAG (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_ACTION_CTL_RULE_REMOVE_BY_TAG, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_ACTION_CTL_RULE_REMOVE_TARGET_BY_ID (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_ACTION_CTL_RULE_REMOVE_TARGET_BY_ID, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_ACTION_CTL_RULE_REMOVE_TARGET_BY_ID (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_ACTION_CTL_RULE_REMOVE_TARGET_BY_ID, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_ACTION_CTL_RULE_REMOVE_TARGET_BY_TAG (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_ACTION_CTL_RULE_REMOVE_TARGET_BY_TAG, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_ACTION_CTL_RULE_REMOVE_TARGET_BY_TAG (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_ACTION_CTL_RULE_REMOVE_TARGET_BY_TAG, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_ACTION_DENY (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_ACTION_DENY, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_ACTION_DENY (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_ACTION_DENY, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_ACTION_DEPRECATE_VAR (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_ACTION_DEPRECATE_VAR, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_ACTION_DEPRECATE_VAR (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_ACTION_DEPRECATE_VAR, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_ACTION_DROP (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_ACTION_DROP, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_ACTION_DROP (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_ACTION_DROP, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_ACTION_EXEC (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_ACTION_EXEC, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_ACTION_EXEC (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_ACTION_EXEC, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_ACTION_EXPIRE_VAR (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_ACTION_EXPIRE_VAR, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_ACTION_EXPIRE_VAR (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_ACTION_EXPIRE_VAR, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_ACTION_ID (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_ACTION_ID, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_ACTION_ID (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_ACTION_ID, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_ACTION_INITCOL (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_ACTION_INITCOL, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_ACTION_INITCOL (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_ACTION_INITCOL, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_ACTION_LOG (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_ACTION_LOG, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_ACTION_LOG (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_ACTION_LOG, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_ACTION_LOG_DATA (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_ACTION_LOG_DATA, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_ACTION_LOG_DATA (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_ACTION_LOG_DATA, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_ACTION_MATURITY (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_ACTION_MATURITY, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_ACTION_MATURITY (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_ACTION_MATURITY, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_ACTION_MSG (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_ACTION_MSG, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_ACTION_MSG (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_ACTION_MSG, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_ACTION_MULTI_MATCH (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_ACTION_MULTI_MATCH, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_ACTION_MULTI_MATCH (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_ACTION_MULTI_MATCH, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_ACTION_NO_AUDIT_LOG (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_ACTION_NO_AUDIT_LOG, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_ACTION_NO_AUDIT_LOG (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_ACTION_NO_AUDIT_LOG, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_ACTION_NO_LOG (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_ACTION_NO_LOG, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_ACTION_NO_LOG (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_ACTION_NO_LOG, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_ACTION_PASS (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_ACTION_PASS, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_ACTION_PASS (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_ACTION_PASS, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_ACTION_PAUSE (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_ACTION_PAUSE, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_ACTION_PAUSE (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_ACTION_PAUSE, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_ACTION_PHASE (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_ACTION_PHASE, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_ACTION_PHASE (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_ACTION_PHASE, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_ACTION_PREPEND (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_ACTION_PREPEND, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_ACTION_PREPEND (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_ACTION_PREPEND, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_ACTION_PROXY (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_ACTION_PROXY, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_ACTION_PROXY (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_ACTION_PROXY, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_ACTION_REDIRECT (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_ACTION_REDIRECT, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_ACTION_REDIRECT (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_ACTION_REDIRECT, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_ACTION_REV (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_ACTION_REV, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_ACTION_REV (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_ACTION_REV, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_ACTION_SANITISE_ARG (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_ACTION_SANITISE_ARG, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_ACTION_SANITISE_ARG (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_ACTION_SANITISE_ARG, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_ACTION_SANITISE_MATCHED (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_ACTION_SANITISE_MATCHED, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_ACTION_SANITISE_MATCHED (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_ACTION_SANITISE_MATCHED, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_ACTION_SANITISE_MATCHED_BYTES (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_ACTION_SANITISE_MATCHED_BYTES, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_ACTION_SANITISE_MATCHED_BYTES (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_ACTION_SANITISE_MATCHED_BYTES, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_ACTION_SANITISE_REQUEST_HEADER (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_ACTION_SANITISE_REQUEST_HEADER, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_ACTION_SANITISE_REQUEST_HEADER (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_ACTION_SANITISE_REQUEST_HEADER, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_ACTION_SANITISE_RESPONSE_HEADER (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_ACTION_SANITISE_RESPONSE_HEADER, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_ACTION_SANITISE_RESPONSE_HEADER (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_ACTION_SANITISE_RESPONSE_HEADER, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_ACTION_SETENV (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_ACTION_SETENV, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_ACTION_SETENV (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_ACTION_SETENV, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_ACTION_SETRSC (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_ACTION_SETRSC, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_ACTION_SETRSC (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_ACTION_SETRSC, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_ACTION_SETSID (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_ACTION_SETSID, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_ACTION_SETSID (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_ACTION_SETSID, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_ACTION_SETUID (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_ACTION_SETUID, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_ACTION_SETUID (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_ACTION_SETUID, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_ACTION_SEVERITY (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_ACTION_SEVERITY, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_ACTION_SEVERITY (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_ACTION_SEVERITY, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_ACTION_SKIP (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_ACTION_SKIP, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_ACTION_SKIP (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_ACTION_SKIP, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_ACTION_SKIP_AFTER (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_ACTION_SKIP_AFTER, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_ACTION_SKIP_AFTER (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_ACTION_SKIP_AFTER, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_ACTION_STATUS (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_ACTION_STATUS, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_ACTION_STATUS (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_ACTION_STATUS, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_ACTION_TAG (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_ACTION_TAG, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_ACTION_TAG (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_ACTION_TAG, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_ACTION_TRANSFORMATION_BASE_64_ENCODE (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_ACTION_TRANSFORMATION_BASE_64_ENCODE, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_ACTION_TRANSFORMATION_BASE_64_ENCODE (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_ACTION_TRANSFORMATION_BASE_64_ENCODE, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_ACTION_TRANSFORMATION_BASE_64_DECODE (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_ACTION_TRANSFORMATION_BASE_64_DECODE, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_ACTION_TRANSFORMATION_BASE_64_DECODE (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_ACTION_TRANSFORMATION_BASE_64_DECODE, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_ACTION_TRANSFORMATION_BASE_64_DECODE_EXT (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_ACTION_TRANSFORMATION_BASE_64_DECODE_EXT, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_ACTION_TRANSFORMATION_BASE_64_DECODE_EXT (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_ACTION_TRANSFORMATION_BASE_64_DECODE_EXT, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_ACTION_TRANSFORMATION_CMD_LINE (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_ACTION_TRANSFORMATION_CMD_LINE, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_ACTION_TRANSFORMATION_CMD_LINE (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_ACTION_TRANSFORMATION_CMD_LINE, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_ACTION_TRANSFORMATION_COMPRESS_WHITESPACE (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_ACTION_TRANSFORMATION_COMPRESS_WHITESPACE, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_ACTION_TRANSFORMATION_COMPRESS_WHITESPACE (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_ACTION_TRANSFORMATION_COMPRESS_WHITESPACE, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_ACTION_TRANSFORMATION_CSS_DECODE (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_ACTION_TRANSFORMATION_CSS_DECODE, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_ACTION_TRANSFORMATION_CSS_DECODE (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_ACTION_TRANSFORMATION_CSS_DECODE, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_ACTION_TRANSFORMATION_ESCAPE_SEQ_DECODE (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_ACTION_TRANSFORMATION_ESCAPE_SEQ_DECODE, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_ACTION_TRANSFORMATION_ESCAPE_SEQ_DECODE (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_ACTION_TRANSFORMATION_ESCAPE_SEQ_DECODE, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_ACTION_TRANSFORMATION_HEX_ENCODE (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_ACTION_TRANSFORMATION_HEX_ENCODE, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_ACTION_TRANSFORMATION_HEX_ENCODE (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_ACTION_TRANSFORMATION_HEX_ENCODE, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_ACTION_TRANSFORMATION_HEX_DECODE (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_ACTION_TRANSFORMATION_HEX_DECODE, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_ACTION_TRANSFORMATION_HEX_DECODE (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_ACTION_TRANSFORMATION_HEX_DECODE, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_ACTION_TRANSFORMATION_HTML_ENTITY_DECODE (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_ACTION_TRANSFORMATION_HTML_ENTITY_DECODE, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_ACTION_TRANSFORMATION_HTML_ENTITY_DECODE (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_ACTION_TRANSFORMATION_HTML_ENTITY_DECODE, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_ACTION_TRANSFORMATION_JS_DECODE (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_ACTION_TRANSFORMATION_JS_DECODE, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_ACTION_TRANSFORMATION_JS_DECODE (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_ACTION_TRANSFORMATION_JS_DECODE, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_ACTION_TRANSFORMATION_LENGTH (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_ACTION_TRANSFORMATION_LENGTH, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_ACTION_TRANSFORMATION_LENGTH (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_ACTION_TRANSFORMATION_LENGTH, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_ACTION_TRANSFORMATION_LOWERCASE (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_ACTION_TRANSFORMATION_LOWERCASE, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_ACTION_TRANSFORMATION_LOWERCASE (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_ACTION_TRANSFORMATION_LOWERCASE, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_ACTION_TRANSFORMATION_MD5 (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_ACTION_TRANSFORMATION_MD5, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_ACTION_TRANSFORMATION_MD5 (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_ACTION_TRANSFORMATION_MD5, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_ACTION_TRANSFORMATION_NONE (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_ACTION_TRANSFORMATION_NONE, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_ACTION_TRANSFORMATION_NONE (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_ACTION_TRANSFORMATION_NONE, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_ACTION_TRANSFORMATION_NORMALISE_PATH (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_ACTION_TRANSFORMATION_NORMALISE_PATH, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_ACTION_TRANSFORMATION_NORMALISE_PATH (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_ACTION_TRANSFORMATION_NORMALISE_PATH, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_ACTION_TRANSFORMATION_NORMALISE_PATH_WIN (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_ACTION_TRANSFORMATION_NORMALISE_PATH_WIN, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_ACTION_TRANSFORMATION_NORMALISE_PATH_WIN (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_ACTION_TRANSFORMATION_NORMALISE_PATH_WIN, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_ACTION_TRANSFORMATION_PARITY_EVEN_7_BIT (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_ACTION_TRANSFORMATION_PARITY_EVEN_7_BIT, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_ACTION_TRANSFORMATION_PARITY_EVEN_7_BIT (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_ACTION_TRANSFORMATION_PARITY_EVEN_7_BIT, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_ACTION_TRANSFORMATION_PARITY_ODD_7_BIT (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_ACTION_TRANSFORMATION_PARITY_ODD_7_BIT, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_ACTION_TRANSFORMATION_PARITY_ODD_7_BIT (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_ACTION_TRANSFORMATION_PARITY_ODD_7_BIT, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_ACTION_TRANSFORMATION_PARITY_ZERO_7_BIT (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_ACTION_TRANSFORMATION_PARITY_ZERO_7_BIT, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_ACTION_TRANSFORMATION_PARITY_ZERO_7_BIT (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_ACTION_TRANSFORMATION_PARITY_ZERO_7_BIT, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_ACTION_TRANSFORMATION_REMOVE_COMMENTS (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_ACTION_TRANSFORMATION_REMOVE_COMMENTS, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_ACTION_TRANSFORMATION_REMOVE_COMMENTS (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_ACTION_TRANSFORMATION_REMOVE_COMMENTS, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_ACTION_TRANSFORMATION_REMOVE_COMMENTS_CHAR (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_ACTION_TRANSFORMATION_REMOVE_COMMENTS_CHAR, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_ACTION_TRANSFORMATION_REMOVE_COMMENTS_CHAR (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_ACTION_TRANSFORMATION_REMOVE_COMMENTS_CHAR, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_ACTION_TRANSFORMATION_REMOVE_NULLS (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_ACTION_TRANSFORMATION_REMOVE_NULLS, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_ACTION_TRANSFORMATION_REMOVE_NULLS (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_ACTION_TRANSFORMATION_REMOVE_NULLS, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_ACTION_TRANSFORMATION_REMOVE_WHITESPACE (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_ACTION_TRANSFORMATION_REMOVE_WHITESPACE, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_ACTION_TRANSFORMATION_REMOVE_WHITESPACE (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_ACTION_TRANSFORMATION_REMOVE_WHITESPACE, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_ACTION_TRANSFORMATION_REPLACE_COMMENTS (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_ACTION_TRANSFORMATION_REPLACE_COMMENTS, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_ACTION_TRANSFORMATION_REPLACE_COMMENTS (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_ACTION_TRANSFORMATION_REPLACE_COMMENTS, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_ACTION_TRANSFORMATION_REPLACE_NULLS (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_ACTION_TRANSFORMATION_REPLACE_NULLS, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_ACTION_TRANSFORMATION_REPLACE_NULLS (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_ACTION_TRANSFORMATION_REPLACE_NULLS, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_ACTION_TRANSFORMATION_SHA1 (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_ACTION_TRANSFORMATION_SHA1, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_ACTION_TRANSFORMATION_SHA1 (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_ACTION_TRANSFORMATION_SHA1, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_ACTION_TRANSFORMATION_SQL_HEX_DECODE (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_ACTION_TRANSFORMATION_SQL_HEX_DECODE, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_ACTION_TRANSFORMATION_SQL_HEX_DECODE (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_ACTION_TRANSFORMATION_SQL_HEX_DECODE, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_ACTION_TRANSFORMATION_TRIM (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_ACTION_TRANSFORMATION_TRIM, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_ACTION_TRANSFORMATION_TRIM (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_ACTION_TRANSFORMATION_TRIM, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_ACTION_TRANSFORMATION_TRIM_LEFT (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_ACTION_TRANSFORMATION_TRIM_LEFT, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_ACTION_TRANSFORMATION_TRIM_LEFT (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_ACTION_TRANSFORMATION_TRIM_LEFT, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_ACTION_TRANSFORMATION_TRIM_RIGHT (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_ACTION_TRANSFORMATION_TRIM_RIGHT, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_ACTION_TRANSFORMATION_TRIM_RIGHT (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_ACTION_TRANSFORMATION_TRIM_RIGHT, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_ACTION_TRANSFORMATION_UPPERCASE (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_ACTION_TRANSFORMATION_UPPERCASE, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_ACTION_TRANSFORMATION_UPPERCASE (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_ACTION_TRANSFORMATION_UPPERCASE, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_ACTION_TRANSFORMATION_URL_ENCODE (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_ACTION_TRANSFORMATION_URL_ENCODE, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_ACTION_TRANSFORMATION_URL_ENCODE (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_ACTION_TRANSFORMATION_URL_ENCODE, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_ACTION_TRANSFORMATION_URL_DECODE (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_ACTION_TRANSFORMATION_URL_DECODE, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_ACTION_TRANSFORMATION_URL_DECODE (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_ACTION_TRANSFORMATION_URL_DECODE, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_ACTION_TRANSFORMATION_URL_DECODE_UNI (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_ACTION_TRANSFORMATION_URL_DECODE_UNI, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_ACTION_TRANSFORMATION_URL_DECODE_UNI (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_ACTION_TRANSFORMATION_URL_DECODE_UNI, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_ACTION_TRANSFORMATION_UTF8_TO_UNICODE (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_ACTION_TRANSFORMATION_UTF8_TO_UNICODE, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_ACTION_TRANSFORMATION_UTF8_TO_UNICODE (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_ACTION_TRANSFORMATION_UTF8_TO_UNICODE, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_ACTION_VER (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_ACTION_VER, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_ACTION_VER (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_ACTION_VER, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_ACTION_XMLNS (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_ACTION_XMLNS, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_ACTION_XMLNS (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_ACTION_XMLNS, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_CONFIG_COMPONENT_SIG (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_CONFIG_COMPONENT_SIG, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_CONFIG_COMPONENT_SIG (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_CONFIG_COMPONENT_SIG, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_CONFIG_CONN_ENGINE (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_CONFIG_CONN_ENGINE, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_CONFIG_CONN_ENGINE (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_CONFIG_CONN_ENGINE, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_CONFIG_SEC_ARGUMENT_SEPARATOR (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_CONFIG_SEC_ARGUMENT_SEPARATOR, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_CONFIG_SEC_ARGUMENT_SEPARATOR (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_CONFIG_SEC_ARGUMENT_SEPARATOR, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_CONFIG_SEC_WEB_APP_ID (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_CONFIG_SEC_WEB_APP_ID, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_CONFIG_SEC_WEB_APP_ID (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_CONFIG_SEC_WEB_APP_ID, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_CONFIG_SEC_SERVER_SIG (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_CONFIG_SEC_SERVER_SIG, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_CONFIG_SEC_SERVER_SIG (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_CONFIG_SEC_SERVER_SIG, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_CONFIG_DIR_AUDIT_DIR (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_CONFIG_DIR_AUDIT_DIR, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_CONFIG_DIR_AUDIT_DIR (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_CONFIG_DIR_AUDIT_DIR, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_CONFIG_DIR_AUDIT_DIR_MOD (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_CONFIG_DIR_AUDIT_DIR_MOD, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_CONFIG_DIR_AUDIT_DIR_MOD (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_CONFIG_DIR_AUDIT_DIR_MOD, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_CONFIG_DIR_AUDIT_ENG (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_CONFIG_DIR_AUDIT_ENG, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_CONFIG_DIR_AUDIT_ENG (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_CONFIG_DIR_AUDIT_ENG, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_CONFIG_DIR_AUDIT_FLE_MOD (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_CONFIG_DIR_AUDIT_FLE_MOD, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_CONFIG_DIR_AUDIT_FLE_MOD (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_CONFIG_DIR_AUDIT_FLE_MOD, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_CONFIG_DIR_AUDIT_LOG (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_CONFIG_DIR_AUDIT_LOG, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_CONFIG_DIR_AUDIT_LOG (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_CONFIG_DIR_AUDIT_LOG, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_CONFIG_DIR_AUDIT_LOG2 (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_CONFIG_DIR_AUDIT_LOG2, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_CONFIG_DIR_AUDIT_LOG2 (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_CONFIG_DIR_AUDIT_LOG2, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_CONFIG_DIR_AUDIT_LOG_P (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_CONFIG_DIR_AUDIT_LOG_P, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_CONFIG_DIR_AUDIT_LOG_P (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_CONFIG_DIR_AUDIT_LOG_P, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_CONFIG_DIR_AUDIT_STS (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_CONFIG_DIR_AUDIT_STS, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_CONFIG_DIR_AUDIT_STS (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_CONFIG_DIR_AUDIT_STS, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_CONFIG_DIR_AUDIT_PREFIX (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_CONFIG_DIR_AUDIT_PREFIX, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_CONFIG_DIR_AUDIT_PREFIX (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_CONFIG_DIR_AUDIT_PREFIX, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_CONFIG_DIR_AUDIT_TPE (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_CONFIG_DIR_AUDIT_TPE, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_CONFIG_DIR_AUDIT_TPE (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_CONFIG_DIR_AUDIT_TPE, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_CONFIG_DIR_DEBUG_LOG (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_CONFIG_DIR_DEBUG_LOG, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_CONFIG_DIR_DEBUG_LOG (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_CONFIG_DIR_DEBUG_LOG, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_CONFIG_DIR_DEBUG_LVL (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_CONFIG_DIR_DEBUG_LVL, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_CONFIG_DIR_DEBUG_LVL (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_CONFIG_DIR_DEBUG_LVL, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_CONFIG_SEC_CACHE_TRANSFORMATIONS (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_CONFIG_SEC_CACHE_TRANSFORMATIONS, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_CONFIG_SEC_CACHE_TRANSFORMATIONS (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_CONFIG_SEC_CACHE_TRANSFORMATIONS, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_CONFIG_SEC_DISABLE_BACKEND_COMPRESS (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_CONFIG_SEC_DISABLE_BACKEND_COMPRESS, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_CONFIG_SEC_DISABLE_BACKEND_COMPRESS (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_CONFIG_SEC_DISABLE_BACKEND_COMPRESS, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_CONFIG_SEC_HASH_ENGINE (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_CONFIG_SEC_HASH_ENGINE, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_CONFIG_SEC_HASH_ENGINE (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_CONFIG_SEC_HASH_ENGINE, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_CONFIG_SEC_HASH_KEY (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_CONFIG_SEC_HASH_KEY, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_CONFIG_SEC_HASH_KEY (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_CONFIG_SEC_HASH_KEY, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_CONFIG_SEC_HASH_PARAM (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_CONFIG_SEC_HASH_PARAM, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_CONFIG_SEC_HASH_PARAM (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_CONFIG_SEC_HASH_PARAM, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_CONFIG_SEC_HASH_METHOD_RX (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_CONFIG_SEC_HASH_METHOD_RX, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_CONFIG_SEC_HASH_METHOD_RX (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_CONFIG_SEC_HASH_METHOD_RX, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_CONFIG_SEC_HASH_METHOD_PM (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_CONFIG_SEC_HASH_METHOD_PM, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_CONFIG_SEC_HASH_METHOD_PM (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_CONFIG_SEC_HASH_METHOD_PM, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_CONFIG_SEC_CHROOT_DIR (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_CONFIG_SEC_CHROOT_DIR, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_CONFIG_SEC_CHROOT_DIR (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_CONFIG_SEC_CHROOT_DIR, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_CONFIG_DIR_GEO_DB (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_CONFIG_DIR_GEO_DB, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_CONFIG_DIR_GEO_DB (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_CONFIG_DIR_GEO_DB, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_CONFIG_DIR_GSB_DB (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_CONFIG_DIR_GSB_DB, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_CONFIG_DIR_GSB_DB (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_CONFIG_DIR_GSB_DB, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_CONFIG_SEC_GUARDIAN_LOG (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_CONFIG_SEC_GUARDIAN_LOG, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_CONFIG_SEC_GUARDIAN_LOG (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_CONFIG_SEC_GUARDIAN_LOG, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_CONFIG_DIR_PCRE_MATCH_LIMIT (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_CONFIG_DIR_PCRE_MATCH_LIMIT, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_CONFIG_DIR_PCRE_MATCH_LIMIT (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_CONFIG_DIR_PCRE_MATCH_LIMIT, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_CONFIG_DIR_PCRE_MATCH_LIMIT_RECURSION (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_CONFIG_DIR_PCRE_MATCH_LIMIT_RECURSION, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_CONFIG_DIR_PCRE_MATCH_LIMIT_RECURSION (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_CONFIG_DIR_PCRE_MATCH_LIMIT_RECURSION, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_CONFIG_SEC_CONN_R_STATE_LIMIT (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_CONFIG_SEC_CONN_R_STATE_LIMIT, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_CONFIG_SEC_CONN_R_STATE_LIMIT (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_CONFIG_SEC_CONN_R_STATE_LIMIT, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_CONFIG_SEC_CONN_W_STATE_LIMIT (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_CONFIG_SEC_CONN_W_STATE_LIMIT, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_CONFIG_SEC_CONN_W_STATE_LIMIT (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_CONFIG_SEC_CONN_W_STATE_LIMIT, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_CONFIG_SEC_SENSOR_ID (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_CONFIG_SEC_SENSOR_ID, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_CONFIG_SEC_SENSOR_ID (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_CONFIG_SEC_SENSOR_ID, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_CONFIG_DIR_ARGS_LIMIT (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_CONFIG_DIR_ARGS_LIMIT, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_CONFIG_DIR_ARGS_LIMIT (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_CONFIG_DIR_ARGS_LIMIT, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_CONFIG_DIR_REQ_BODY_JSON_DEPTH_LIMIT (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_CONFIG_DIR_REQ_BODY_JSON_DEPTH_LIMIT, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_CONFIG_DIR_REQ_BODY_JSON_DEPTH_LIMIT (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_CONFIG_DIR_REQ_BODY_JSON_DEPTH_LIMIT, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_CONFIG_DIR_REQ_BODY (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_CONFIG_DIR_REQ_BODY, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_CONFIG_DIR_REQ_BODY (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_CONFIG_DIR_REQ_BODY, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_CONFIG_DIR_REQ_BODY_IN_MEMORY_LIMIT (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_CONFIG_DIR_REQ_BODY_IN_MEMORY_LIMIT, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_CONFIG_DIR_REQ_BODY_IN_MEMORY_LIMIT (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_CONFIG_DIR_REQ_BODY_IN_MEMORY_LIMIT, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_CONFIG_DIR_REQ_BODY_LIMIT (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_CONFIG_DIR_REQ_BODY_LIMIT, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_CONFIG_DIR_REQ_BODY_LIMIT (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_CONFIG_DIR_REQ_BODY_LIMIT, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_CONFIG_DIR_REQ_BODY_LIMIT_ACTION (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_CONFIG_DIR_REQ_BODY_LIMIT_ACTION, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_CONFIG_DIR_REQ_BODY_LIMIT_ACTION (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_CONFIG_DIR_REQ_BODY_LIMIT_ACTION, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_CONFIG_DIR_REQ_BODY_NO_FILES_LIMIT (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_CONFIG_DIR_REQ_BODY_NO_FILES_LIMIT, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_CONFIG_DIR_REQ_BODY_NO_FILES_LIMIT (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_CONFIG_DIR_REQ_BODY_NO_FILES_LIMIT, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_CONFIG_DIR_RES_BODY (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_CONFIG_DIR_RES_BODY, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_CONFIG_DIR_RES_BODY (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_CONFIG_DIR_RES_BODY, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_CONFIG_DIR_RES_BODY_LIMIT (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_CONFIG_DIR_RES_BODY_LIMIT, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_CONFIG_DIR_RES_BODY_LIMIT (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_CONFIG_DIR_RES_BODY_LIMIT, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_CONFIG_DIR_RES_BODY_LIMIT_ACTION (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_CONFIG_DIR_RES_BODY_LIMIT_ACTION, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_CONFIG_DIR_RES_BODY_LIMIT_ACTION (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_CONFIG_DIR_RES_BODY_LIMIT_ACTION, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_CONFIG_SEC_RULE_INHERITANCE (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_CONFIG_SEC_RULE_INHERITANCE, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_CONFIG_SEC_RULE_INHERITANCE (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_CONFIG_SEC_RULE_INHERITANCE, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_CONFIG_SEC_RULE_PERF_TIME (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_CONFIG_SEC_RULE_PERF_TIME, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_CONFIG_SEC_RULE_PERF_TIME (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_CONFIG_SEC_RULE_PERF_TIME, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_CONFIG_DIR_RULE_ENG (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_CONFIG_DIR_RULE_ENG, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_CONFIG_DIR_RULE_ENG (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_CONFIG_DIR_RULE_ENG, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_CONFIG_DIR_SEC_ACTION (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_CONFIG_DIR_SEC_ACTION, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_CONFIG_DIR_SEC_ACTION (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_CONFIG_DIR_SEC_ACTION, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_CONFIG_DIR_SEC_DEFAULT_ACTION (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_CONFIG_DIR_SEC_DEFAULT_ACTION, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_CONFIG_DIR_SEC_DEFAULT_ACTION (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_CONFIG_DIR_SEC_DEFAULT_ACTION, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_CONFIG_DIR_SEC_MARKER (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_CONFIG_DIR_SEC_MARKER, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_CONFIG_DIR_SEC_MARKER (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_CONFIG_DIR_SEC_MARKER, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_CONFIG_DIR_UNICODE_MAP_FILE (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_CONFIG_DIR_UNICODE_MAP_FILE, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_CONFIG_DIR_UNICODE_MAP_FILE (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_CONFIG_DIR_UNICODE_MAP_FILE, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_CONFIG_DIR_UNICODE_CODE_PAGE (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_CONFIG_DIR_UNICODE_CODE_PAGE, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_CONFIG_DIR_UNICODE_CODE_PAGE (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_CONFIG_DIR_UNICODE_CODE_PAGE, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_CONFIG_SEC_COLLECTION_TIMEOUT (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_CONFIG_SEC_COLLECTION_TIMEOUT, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_CONFIG_SEC_COLLECTION_TIMEOUT (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_CONFIG_SEC_COLLECTION_TIMEOUT, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_CONFIG_SEC_HTTP_BLKEY (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_CONFIG_SEC_HTTP_BLKEY, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_CONFIG_SEC_HTTP_BLKEY (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_CONFIG_SEC_HTTP_BLKEY, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_CONFIG_SEC_INTERCEPT_ON_ERROR (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_CONFIG_SEC_INTERCEPT_ON_ERROR, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_CONFIG_SEC_INTERCEPT_ON_ERROR (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_CONFIG_SEC_INTERCEPT_ON_ERROR, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_CONFIG_SEC_REMOTE_RULES_FAIL_ACTION (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_CONFIG_SEC_REMOTE_RULES_FAIL_ACTION, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_CONFIG_SEC_REMOTE_RULES_FAIL_ACTION (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_CONFIG_SEC_REMOTE_RULES_FAIL_ACTION, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_CONFIG_SEC_RULE_REMOVE_BY_ID (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_CONFIG_SEC_RULE_REMOVE_BY_ID, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_CONFIG_SEC_RULE_REMOVE_BY_ID (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_CONFIG_SEC_RULE_REMOVE_BY_ID, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_CONFIG_SEC_RULE_REMOVE_BY_MSG (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_CONFIG_SEC_RULE_REMOVE_BY_MSG, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_CONFIG_SEC_RULE_REMOVE_BY_MSG (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_CONFIG_SEC_RULE_REMOVE_BY_MSG, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_CONFIG_SEC_RULE_REMOVE_BY_TAG (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_CONFIG_SEC_RULE_REMOVE_BY_TAG, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_CONFIG_SEC_RULE_REMOVE_BY_TAG (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_CONFIG_SEC_RULE_REMOVE_BY_TAG, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_CONFIG_SEC_RULE_UPDATE_TARGET_BY_TAG (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_CONFIG_SEC_RULE_UPDATE_TARGET_BY_TAG, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_CONFIG_SEC_RULE_UPDATE_TARGET_BY_TAG (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_CONFIG_SEC_RULE_UPDATE_TARGET_BY_TAG, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_CONFIG_SEC_RULE_UPDATE_TARGET_BY_MSG (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_CONFIG_SEC_RULE_UPDATE_TARGET_BY_MSG, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_CONFIG_SEC_RULE_UPDATE_TARGET_BY_MSG (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_CONFIG_SEC_RULE_UPDATE_TARGET_BY_MSG, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_CONFIG_SEC_RULE_UPDATE_TARGET_BY_ID (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_CONFIG_SEC_RULE_UPDATE_TARGET_BY_ID, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_CONFIG_SEC_RULE_UPDATE_TARGET_BY_ID (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_CONFIG_SEC_RULE_UPDATE_TARGET_BY_ID, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_CONFIG_SEC_RULE_UPDATE_ACTION_BY_ID (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_CONFIG_SEC_RULE_UPDATE_ACTION_BY_ID, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_CONFIG_SEC_RULE_UPDATE_ACTION_BY_ID (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_CONFIG_SEC_RULE_UPDATE_ACTION_BY_ID, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_CONFIG_UPDLOAD_KEEP_FILES (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_CONFIG_UPDLOAD_KEEP_FILES, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_CONFIG_UPDLOAD_KEEP_FILES (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_CONFIG_UPDLOAD_KEEP_FILES, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_CONFIG_UPDLOAD_SAVE_TMP_FILES (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_CONFIG_UPDLOAD_SAVE_TMP_FILES, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_CONFIG_UPDLOAD_SAVE_TMP_FILES (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_CONFIG_UPDLOAD_SAVE_TMP_FILES, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_CONFIG_UPLOAD_DIR (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_CONFIG_UPLOAD_DIR, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_CONFIG_UPLOAD_DIR (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_CONFIG_UPLOAD_DIR, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_CONFIG_UPLOAD_FILE_LIMIT (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_CONFIG_UPLOAD_FILE_LIMIT, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_CONFIG_UPLOAD_FILE_LIMIT (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_CONFIG_UPLOAD_FILE_LIMIT, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_CONFIG_UPLOAD_FILE_MODE (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_CONFIG_UPLOAD_FILE_MODE, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_CONFIG_UPLOAD_FILE_MODE (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_CONFIG_UPLOAD_FILE_MODE, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_CONFIG_VALUE_ABORT (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_CONFIG_VALUE_ABORT, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_CONFIG_VALUE_ABORT (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_CONFIG_VALUE_ABORT, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_CONFIG_VALUE_DETC (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_CONFIG_VALUE_DETC, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_CONFIG_VALUE_DETC (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_CONFIG_VALUE_DETC, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_CONFIG_VALUE_HTTPS (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_CONFIG_VALUE_HTTPS, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_CONFIG_VALUE_HTTPS (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_CONFIG_VALUE_HTTPS, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_CONFIG_VALUE_ONLYARGS (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_CONFIG_VALUE_ONLYARGS, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_CONFIG_VALUE_ONLYARGS (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_CONFIG_VALUE_ONLYARGS, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_CONFIG_VALUE_OFF (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_CONFIG_VALUE_OFF, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_CONFIG_VALUE_OFF (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_CONFIG_VALUE_OFF, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_CONFIG_VALUE_ON (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_CONFIG_VALUE_ON, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_CONFIG_VALUE_ON (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_CONFIG_VALUE_ON, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_CONFIG_VALUE_PARALLEL (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_CONFIG_VALUE_PARALLEL, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_CONFIG_VALUE_PARALLEL (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_CONFIG_VALUE_PARALLEL, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_CONFIG_VALUE_PROCESS_PARTIAL (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_CONFIG_VALUE_PROCESS_PARTIAL, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_CONFIG_VALUE_PROCESS_PARTIAL (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_CONFIG_VALUE_PROCESS_PARTIAL, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_CONFIG_VALUE_REJECT (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_CONFIG_VALUE_REJECT, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_CONFIG_VALUE_REJECT (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_CONFIG_VALUE_REJECT, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_CONFIG_VALUE_RELEVANT_ONLY (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_CONFIG_VALUE_RELEVANT_ONLY, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_CONFIG_VALUE_RELEVANT_ONLY (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_CONFIG_VALUE_RELEVANT_ONLY, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_CONFIG_VALUE_SERIAL (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_CONFIG_VALUE_SERIAL, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_CONFIG_VALUE_SERIAL (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_CONFIG_VALUE_SERIAL, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_CONFIG_VALUE_WARN (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_CONFIG_VALUE_WARN, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_CONFIG_VALUE_WARN (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_CONFIG_VALUE_WARN, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_CONFIG_XML_EXTERNAL_ENTITY (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_CONFIG_XML_EXTERNAL_ENTITY, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_CONFIG_XML_EXTERNAL_ENTITY (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_CONFIG_XML_EXTERNAL_ENTITY, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_CONFIG_XML_PARSE_XML_INTO_ARGS (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_CONFIG_XML_PARSE_XML_INTO_ARGS, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_CONFIG_XML_PARSE_XML_INTO_ARGS (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_CONFIG_XML_PARSE_XML_INTO_ARGS, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_CONGIG_DIR_RESPONSE_BODY_MP (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_CONGIG_DIR_RESPONSE_BODY_MP, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_CONGIG_DIR_RESPONSE_BODY_MP (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_CONGIG_DIR_RESPONSE_BODY_MP, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_CONGIG_DIR_SEC_ARG_SEP (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_CONGIG_DIR_SEC_ARG_SEP, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_CONGIG_DIR_SEC_ARG_SEP (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_CONGIG_DIR_SEC_ARG_SEP, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_CONGIG_DIR_SEC_COOKIE_FORMAT (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_CONGIG_DIR_SEC_COOKIE_FORMAT, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_CONGIG_DIR_SEC_COOKIE_FORMAT (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_CONGIG_DIR_SEC_COOKIE_FORMAT, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_CONFIG_SEC_COOKIEV0_SEPARATOR (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_CONFIG_SEC_COOKIEV0_SEPARATOR, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_CONFIG_SEC_COOKIEV0_SEPARATOR (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_CONFIG_SEC_COOKIEV0_SEPARATOR, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_CONGIG_DIR_SEC_DATA_DIR (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_CONGIG_DIR_SEC_DATA_DIR, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_CONGIG_DIR_SEC_DATA_DIR (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_CONGIG_DIR_SEC_DATA_DIR, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_CONGIG_DIR_SEC_STATUS_ENGINE (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_CONGIG_DIR_SEC_STATUS_ENGINE, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_CONGIG_DIR_SEC_STATUS_ENGINE (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_CONGIG_DIR_SEC_STATUS_ENGINE, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_CONFIG_SEC_STREAM_IN_BODY_INSPECTION (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_CONFIG_SEC_STREAM_IN_BODY_INSPECTION, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_CONFIG_SEC_STREAM_IN_BODY_INSPECTION (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_CONFIG_SEC_STREAM_IN_BODY_INSPECTION, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_CONFIG_SEC_STREAM_OUT_BODY_INSPECTION (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_CONFIG_SEC_STREAM_OUT_BODY_INSPECTION, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_CONFIG_SEC_STREAM_OUT_BODY_INSPECTION (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_CONFIG_SEC_STREAM_OUT_BODY_INSPECTION, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_CONGIG_DIR_SEC_TMP_DIR (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_CONGIG_DIR_SEC_TMP_DIR, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_CONGIG_DIR_SEC_TMP_DIR (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_CONGIG_DIR_SEC_TMP_DIR, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_DIRECTIVE (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_DIRECTIVE, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_DIRECTIVE (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_DIRECTIVE, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_DIRECTIVE_SECRULESCRIPT (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_DIRECTIVE_SECRULESCRIPT, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_DIRECTIVE_SECRULESCRIPT (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_DIRECTIVE_SECRULESCRIPT, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_FREE_TEXT_QUOTE_MACRO_EXPANSION (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_FREE_TEXT_QUOTE_MACRO_EXPANSION, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_FREE_TEXT_QUOTE_MACRO_EXPANSION (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_FREE_TEXT_QUOTE_MACRO_EXPANSION, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_QUOTATION_MARK (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_QUOTATION_MARK, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_QUOTATION_MARK (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_QUOTATION_MARK, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_RUN_TIME_VAR_BLD (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_RUN_TIME_VAR_BLD, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_RUN_TIME_VAR_BLD (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_RUN_TIME_VAR_BLD, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_RUN_TIME_VAR_DUR (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_RUN_TIME_VAR_DUR, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_RUN_TIME_VAR_DUR (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_RUN_TIME_VAR_DUR, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_RUN_TIME_VAR_HSV (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_RUN_TIME_VAR_HSV, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_RUN_TIME_VAR_HSV (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_RUN_TIME_VAR_HSV, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_RUN_TIME_VAR_REMOTE_USER (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_RUN_TIME_VAR_REMOTE_USER, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_RUN_TIME_VAR_REMOTE_USER (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_RUN_TIME_VAR_REMOTE_USER, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_RUN_TIME_VAR_TIME (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_RUN_TIME_VAR_TIME, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_RUN_TIME_VAR_TIME (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_RUN_TIME_VAR_TIME, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_RUN_TIME_VAR_TIME_DAY (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_RUN_TIME_VAR_TIME_DAY, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_RUN_TIME_VAR_TIME_DAY (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_RUN_TIME_VAR_TIME_DAY, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_RUN_TIME_VAR_TIME_EPOCH (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_RUN_TIME_VAR_TIME_EPOCH, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_RUN_TIME_VAR_TIME_EPOCH (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_RUN_TIME_VAR_TIME_EPOCH, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_RUN_TIME_VAR_TIME_HOUR (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_RUN_TIME_VAR_TIME_HOUR, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_RUN_TIME_VAR_TIME_HOUR (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_RUN_TIME_VAR_TIME_HOUR, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_RUN_TIME_VAR_TIME_MIN (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_RUN_TIME_VAR_TIME_MIN, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_RUN_TIME_VAR_TIME_MIN (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_RUN_TIME_VAR_TIME_MIN, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_RUN_TIME_VAR_TIME_MON (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_RUN_TIME_VAR_TIME_MON, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_RUN_TIME_VAR_TIME_MON (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_RUN_TIME_VAR_TIME_MON, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_RUN_TIME_VAR_TIME_SEC (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_RUN_TIME_VAR_TIME_SEC, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_RUN_TIME_VAR_TIME_SEC (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_RUN_TIME_VAR_TIME_SEC, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_RUN_TIME_VAR_TIME_WDAY (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_RUN_TIME_VAR_TIME_WDAY, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_RUN_TIME_VAR_TIME_WDAY (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_RUN_TIME_VAR_TIME_WDAY, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_RUN_TIME_VAR_TIME_YEAR (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_RUN_TIME_VAR_TIME_YEAR, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_RUN_TIME_VAR_TIME_YEAR (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_RUN_TIME_VAR_TIME_YEAR, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_VARIABLE (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_VARIABLE, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_VARIABLE (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_VARIABLE, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_DICT_ELEMENT (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_DICT_ELEMENT, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_DICT_ELEMENT (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_DICT_ELEMENT, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_DICT_ELEMENT_WITH_EQUALS (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_DICT_ELEMENT_WITH_EQUALS, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_DICT_ELEMENT_WITH_EQUALS (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_DICT_ELEMENT_WITH_EQUALS, v, l);\n      }\n#endif\n#if 201103L <= YY_CPLUSPLUS\n      static\n      symbol_type\n      make_DICT_ELEMENT_REGEXP (std::string v, location_type l)\n      {\n        return symbol_type (token::TOK_DICT_ELEMENT_REGEXP, std::move (v), std::move (l));\n      }\n#else\n      static\n      symbol_type\n      make_DICT_ELEMENT_REGEXP (const std::string& v, const location_type& l)\n      {\n        return symbol_type (token::TOK_DICT_ELEMENT_REGEXP, v, l);\n      }\n#endif\n\n\n    class context\n    {\n    public:\n      context (const seclang_parser& yyparser, const symbol_type& yyla);\n      const symbol_type& lookahead () const YY_NOEXCEPT { return yyla_; }\n      symbol_kind_type token () const YY_NOEXCEPT { return yyla_.kind (); }\n      const location_type& location () const YY_NOEXCEPT { return yyla_.location; }\n\n      /// Put in YYARG at most YYARGN of the expected tokens, and return the\n      /// number of tokens stored in YYARG.  If YYARG is null, return the\n      /// number of expected tokens (guaranteed to be less than YYNTOKENS).\n      int expected_tokens (symbol_kind_type yyarg[], int yyargn) const;\n\n    private:\n      const seclang_parser& yyparser_;\n      const symbol_type& yyla_;\n    };\n\n  private:\n#if YY_CPLUSPLUS < 201103L\n    /// Non copyable.\n    seclang_parser (const seclang_parser&);\n    /// Non copyable.\n    seclang_parser& operator= (const seclang_parser&);\n#endif\n\n\n    /// Stored state numbers (used for stacks).\n    typedef short state_type;\n\n    /// The arguments of the error message.\n    int yy_syntax_error_arguments_ (const context& yyctx,\n                                    symbol_kind_type yyarg[], int yyargn) const;\n\n    /// Generate an error message.\n    /// \\param yyctx     the context in which the error occurred.\n    virtual std::string yysyntax_error_ (const context& yyctx) const;\n    /// Compute post-reduction state.\n    /// \\param yystate   the current state\n    /// \\param yysym     the nonterminal to push on the stack\n    static state_type yy_lr_goto_state_ (state_type yystate, int yysym);\n\n    /// Whether the given \\c yypact_ value indicates a defaulted state.\n    /// \\param yyvalue   the value to check\n    static bool yy_pact_value_is_default_ (int yyvalue) YY_NOEXCEPT;\n\n    /// Whether the given \\c yytable_ value indicates a syntax error.\n    /// \\param yyvalue   the value to check\n    static bool yy_table_value_is_error_ (int yyvalue) YY_NOEXCEPT;\n\n    static const short yypact_ninf_;\n    static const signed char yytable_ninf_;\n\n    /// Convert a scanner token kind \\a t to a symbol kind.\n    /// In theory \\a t should be a token_kind_type, but character literals\n    /// are valid, yet not members of the token_kind_type enum.\n    static symbol_kind_type yytranslate_ (int t) YY_NOEXCEPT;\n\n    /// Convert the symbol name \\a n to a form suitable for a diagnostic.\n    static std::string yytnamerr_ (const char *yystr);\n\n    /// For a symbol, its name in clear.\n    static const char* const yytname_[];\n\n\n    // Tables.\n    // YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing\n    // STATE-NUM.\n    static const short yypact_[];\n\n    // YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM.\n    // Performed when YYTABLE does not specify something else to do.  Zero\n    // means the default is an error.\n    static const short yydefact_[];\n\n    // YYPGOTO[NTERM-NUM].\n    static const short yypgoto_[];\n\n    // YYDEFGOTO[NTERM-NUM].\n    static const short yydefgoto_[];\n\n    // YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM.  If\n    // positive, shift that token.  If negative, reduce the rule whose\n    // number is the opposite.  If YYTABLE_NINF, syntax error.\n    static const short yytable_[];\n\n    static const short yycheck_[];\n\n    // YYSTOS[STATE-NUM] -- The symbol kind of the accessing symbol of\n    // state STATE-NUM.\n    static const short yystos_[];\n\n    // YYR1[RULE-NUM] -- Symbol kind of the left-hand side of rule RULE-NUM.\n    static const short yyr1_[];\n\n    // YYR2[RULE-NUM] -- Number of symbols on the right-hand side of rule RULE-NUM.\n    static const signed char yyr2_[];\n\n\n#if YYDEBUG\n    // YYRLINE[YYN] -- Source line where rule number YYN was defined.\n    static const short yyrline_[];\n    /// Report on the debug stream that the rule \\a r is going to be reduced.\n    virtual void yy_reduce_print_ (int r) const;\n    /// Print the state stack on the debug stream.\n    virtual void yy_stack_print_ () const;\n\n    /// Debugging level.\n    int yydebug_;\n    /// Debug stream.\n    std::ostream* yycdebug_;\n\n    /// \\brief Display a symbol kind, value and location.\n    /// \\param yyo    The output stream.\n    /// \\param yysym  The symbol.\n    template <typename Base>\n    void yy_print_ (std::ostream& yyo, const basic_symbol<Base>& yysym) const;\n#endif\n\n    /// \\brief Reclaim the memory associated to a symbol.\n    /// \\param yymsg     Why this token is reclaimed.\n    ///                  If null, print nothing.\n    /// \\param yysym     The symbol.\n    template <typename Base>\n    void yy_destroy_ (const char* yymsg, basic_symbol<Base>& yysym) const;\n\n  private:\n    /// Type access provider for state based symbols.\n    struct by_state\n    {\n      /// Default constructor.\n      by_state () YY_NOEXCEPT;\n\n      /// The symbol kind as needed by the constructor.\n      typedef state_type kind_type;\n\n      /// Constructor.\n      by_state (kind_type s) YY_NOEXCEPT;\n\n      /// Copy constructor.\n      by_state (const by_state& that) YY_NOEXCEPT;\n\n      /// Record that this symbol is empty.\n      void clear () YY_NOEXCEPT;\n\n      /// Steal the symbol kind from \\a that.\n      void move (by_state& that);\n\n      /// The symbol kind (corresponding to \\a state).\n      /// \\a symbol_kind::S_YYEMPTY when empty.\n      symbol_kind_type kind () const YY_NOEXCEPT;\n\n      /// The state number used to denote an empty symbol.\n      /// We use the initial state, as it does not have a value.\n      enum { empty_state = 0 };\n\n      /// The state.\n      /// \\a empty when empty.\n      state_type state;\n    };\n\n    /// \"Internal\" symbol: element of the stack.\n    struct stack_symbol_type : basic_symbol<by_state>\n    {\n      /// Superclass.\n      typedef basic_symbol<by_state> super_type;\n      /// Construct an empty symbol.\n      stack_symbol_type ();\n      /// Move or copy construction.\n      stack_symbol_type (YY_RVREF (stack_symbol_type) that);\n      /// Steal the contents from \\a sym to build this.\n      stack_symbol_type (state_type s, YY_MOVE_REF (symbol_type) sym);\n#if YY_CPLUSPLUS < 201103L\n      /// Assignment, needed by push_back by some old implementations.\n      /// Moves the contents of that.\n      stack_symbol_type& operator= (stack_symbol_type& that);\n\n      /// Assignment, needed by push_back by other implementations.\n      /// Needed by some other old implementations.\n      stack_symbol_type& operator= (const stack_symbol_type& that);\n#endif\n    };\n\n    /// A stack with random access from its top.\n    template <typename T, typename S = std::vector<T> >\n    class stack\n    {\n    public:\n      // Hide our reversed order.\n      typedef typename S::iterator iterator;\n      typedef typename S::const_iterator const_iterator;\n      typedef typename S::size_type size_type;\n      typedef typename std::ptrdiff_t index_type;\n\n      stack (size_type n = 200) YY_NOEXCEPT\n        : seq_ (n)\n      {}\n\n#if 201103L <= YY_CPLUSPLUS\n      /// Non copyable.\n      stack (const stack&) = delete;\n      /// Non copyable.\n      stack& operator= (const stack&) = delete;\n#endif\n\n      /// Random access.\n      ///\n      /// Index 0 returns the topmost element.\n      const T&\n      operator[] (index_type i) const\n      {\n        return seq_[size_type (size () - 1 - i)];\n      }\n\n      /// Random access.\n      ///\n      /// Index 0 returns the topmost element.\n      T&\n      operator[] (index_type i)\n      {\n        return seq_[size_type (size () - 1 - i)];\n      }\n\n      /// Steal the contents of \\a t.\n      ///\n      /// Close to move-semantics.\n      void\n      push (YY_MOVE_REF (T) t)\n      {\n        seq_.push_back (T ());\n        operator[] (0).move (t);\n      }\n\n      /// Pop elements from the stack.\n      void\n      pop (std::ptrdiff_t n = 1) YY_NOEXCEPT\n      {\n        for (; 0 < n; --n)\n          seq_.pop_back ();\n      }\n\n      /// Pop all elements from the stack.\n      void\n      clear () YY_NOEXCEPT\n      {\n        seq_.clear ();\n      }\n\n      /// Number of elements on the stack.\n      index_type\n      size () const YY_NOEXCEPT\n      {\n        return index_type (seq_.size ());\n      }\n\n      /// Iterator on top of the stack (going downwards).\n      const_iterator\n      begin () const YY_NOEXCEPT\n      {\n        return seq_.begin ();\n      }\n\n      /// Bottom of the stack.\n      const_iterator\n      end () const YY_NOEXCEPT\n      {\n        return seq_.end ();\n      }\n\n      /// Present a slice of the top of a stack.\n      class slice\n      {\n      public:\n        slice (const stack& stack, index_type range) YY_NOEXCEPT\n          : stack_ (stack)\n          , range_ (range)\n        {}\n\n        const T&\n        operator[] (index_type i) const\n        {\n          return stack_[range_ - i];\n        }\n\n      private:\n        const stack& stack_;\n        index_type range_;\n      };\n\n    private:\n#if YY_CPLUSPLUS < 201103L\n      /// Non copyable.\n      stack (const stack&);\n      /// Non copyable.\n      stack& operator= (const stack&);\n#endif\n      /// The wrapped container.\n      S seq_;\n    };\n\n\n    /// Stack type.\n    typedef stack<stack_symbol_type> stack_type;\n\n    /// The stack.\n    stack_type yystack_;\n\n    /// Push a new state on the stack.\n    /// \\param m    a debug message to display\n    ///             if null, no trace is output.\n    /// \\param sym  the symbol\n    /// \\warning the contents of \\a s.value is stolen.\n    void yypush_ (const char* m, YY_MOVE_REF (stack_symbol_type) sym);\n\n    /// Push a new look ahead token on the state on the stack.\n    /// \\param m    a debug message to display\n    ///             if null, no trace is output.\n    /// \\param s    the state\n    /// \\param sym  the symbol (for its value and location).\n    /// \\warning the contents of \\a sym.value is stolen.\n    void yypush_ (const char* m, state_type s, YY_MOVE_REF (symbol_type) sym);\n\n    /// Pop \\a n symbols from the stack.\n    void yypop_ (int n = 1) YY_NOEXCEPT;\n\n    /// Constants.\n    enum\n    {\n      yylast_ = 3409,     ///< Last index in yytable_.\n      yynnts_ = 16,  ///< Number of nonterminal symbols.\n      yyfinal_ = 347 ///< Termination state number.\n    };\n\n\n    // User arguments.\n    modsecurity::Parser::Driver& driver;\n\n  };\n\n  inline\n  seclang_parser::symbol_kind_type\n  seclang_parser::yytranslate_ (int t) YY_NOEXCEPT\n  {\n    // YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to\n    // TOKEN-NUM as returned by yylex.\n    static\n    const short\n    translate_table[] =\n    {\n       0,     2,     2,     2,     2,     2,     2,     2,     2,     2,\n       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\n       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\n       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\n       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\n       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\n       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\n       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\n       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\n       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\n       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\n       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\n       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\n       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\n       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\n       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\n       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\n       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\n       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\n       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\n       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\n       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\n       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\n       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\n       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,\n       2,     2,     2,     2,     2,     2,     1,     2,     3,     4,\n       5,     6,     7,     8,     9,    10,    11,    12,    13,    14,\n      15,    16,    17,    18,    19,    20,    21,    22,    23,    24,\n      25,    26,    27,    28,    29,    30,    31,    32,    33,    34,\n      35,    36,    37,    38,    39,    40,    41,    42,    43,    44,\n      45,    46,    47,    48,    49,    50,    51,    52,    53,    54,\n      55,    56,    57,    58,    59,    60,    61,    62,    63,    64,\n      65,    66,    67,    68,    69,    70,    71,    72,    73,    74,\n      75,    76,    77,    78,    79,    80,    81,    82,    83,    84,\n      85,    86,    87,    88,    89,    90,    91,    92,    93,    94,\n      95,    96,    97,    98,    99,   100,   101,   102,   103,   104,\n     105,   106,   107,   108,   109,   110,   111,   112,   113,   114,\n     115,   116,   117,   118,   119,   120,   121,   122,   123,   124,\n     125,   126,   127,   128,   129,   130,   131,   132,   133,   134,\n     135,   136,   137,   138,   139,   140,   141,   142,   143,   144,\n     145,   146,   147,   148,   149,   150,   151,   152,   153,   154,\n     155,   156,   157,   158,   159,   160,   161,   162,   163,   164,\n     165,   166,   167,   168,   169,   170,   171,   172,   173,   174,\n     175,   176,   177,   178,   179,   180,   181,   182,   183,   184,\n     185,   186,   187,   188,   189,   190,   191,   192,   193,   194,\n     195,   196,   197,   198,   199,   200,   201,   202,   203,   204,\n     205,   206,   207,   208,   209,   210,   211,   212,   213,   214,\n     215,   216,   217,   218,   219,   220,   221,   222,   223,   224,\n     225,   226,   227,   228,   229,   230,   231,   232,   233,   234,\n     235,   236,   237,   238,   239,   240,   241,   242,   243,   244,\n     245,   246,   247,   248,   249,   250,   251,   252,   253,   254,\n     255,   256,   257,   258,   259,   260,   261,   262,   263,   264,\n     265,   266,   267,   268,   269,   270,   271,   272,   273,   274,\n     275,   276,   277,   278,   279,   280,   281,   282,   283,   284,\n     285,   286,   287,   288,   289,   290,   291,   292,   293,   294,\n     295,   296,   297,   298,   299,   300,   301,   302,   303,   304,\n     305,   306,   307,   308,   309,   310,   311,   312,   313,   314,\n     315,   316,   317,   318,   319,   320,   321,   322,   323,   324,\n     325,   326,   327,   328,   329,   330,   331,   332,   333,   334,\n     335,   336,   337,   338,   339,   340,   341,   342,   343,   344,\n     345,   346,   347,   348,   349,   350,   351\n    };\n    // Last valid token kind.\n    const int code_max = 606;\n\n    if (t <= 0)\n      return symbol_kind::S_YYEOF;\n    else if (t <= code_max)\n      return static_cast <symbol_kind_type> (translate_table[t]);\n    else\n      return symbol_kind::S_YYUNDEF;\n  }\n\n  // basic_symbol.\n  template <typename Base>\n  seclang_parser::basic_symbol<Base>::basic_symbol (const basic_symbol& that)\n    : Base (that)\n    , value ()\n    , location (that.location)\n  {\n    switch (this->kind ())\n    {\n      case symbol_kind::S_ACTION_ACCURACY: // \"Accuracy\"\n      case symbol_kind::S_ACTION_ALLOW: // \"Allow\"\n      case symbol_kind::S_ACTION_APPEND: // \"Append\"\n      case symbol_kind::S_ACTION_AUDIT_LOG: // \"AuditLog\"\n      case symbol_kind::S_ACTION_BLOCK: // \"Block\"\n      case symbol_kind::S_ACTION_CAPTURE: // \"Capture\"\n      case symbol_kind::S_ACTION_CHAIN: // \"Chain\"\n      case symbol_kind::S_ACTION_CTL_AUDIT_ENGINE: // \"ACTION_CTL_AUDIT_ENGINE\"\n      case symbol_kind::S_ACTION_CTL_AUDIT_LOG_PARTS: // \"ACTION_CTL_AUDIT_LOG_PARTS\"\n      case symbol_kind::S_ACTION_CTL_BDY_JSON: // \"ACTION_CTL_BDY_JSON\"\n      case symbol_kind::S_ACTION_CTL_BDY_XML: // \"ACTION_CTL_BDY_XML\"\n      case symbol_kind::S_ACTION_CTL_BDY_URLENCODED: // \"ACTION_CTL_BDY_URLENCODED\"\n      case symbol_kind::S_ACTION_CTL_FORCE_REQ_BODY_VAR: // \"ACTION_CTL_FORCE_REQ_BODY_VAR\"\n      case symbol_kind::S_ACTION_CTL_PARSE_XML_INTO_ARGS: // \"ACTION_CTL_PARSE_XML_INTO_ARGS\"\n      case symbol_kind::S_ACTION_CTL_REQUEST_BODY_ACCESS: // \"ACTION_CTL_REQUEST_BODY_ACCESS\"\n      case symbol_kind::S_ACTION_CTL_RULE_REMOVE_BY_ID: // \"ACTION_CTL_RULE_REMOVE_BY_ID\"\n      case symbol_kind::S_ACTION_CTL_RULE_REMOVE_BY_TAG: // \"ACTION_CTL_RULE_REMOVE_BY_TAG\"\n      case symbol_kind::S_ACTION_CTL_RULE_REMOVE_TARGET_BY_ID: // \"ACTION_CTL_RULE_REMOVE_TARGET_BY_ID\"\n      case symbol_kind::S_ACTION_CTL_RULE_REMOVE_TARGET_BY_TAG: // \"ACTION_CTL_RULE_REMOVE_TARGET_BY_TAG\"\n      case symbol_kind::S_ACTION_DENY: // \"Deny\"\n      case symbol_kind::S_ACTION_DEPRECATE_VAR: // \"DeprecateVar\"\n      case symbol_kind::S_ACTION_DROP: // \"Drop\"\n      case symbol_kind::S_ACTION_EXEC: // \"Exec\"\n      case symbol_kind::S_ACTION_EXPIRE_VAR: // \"ExpireVar\"\n      case symbol_kind::S_ACTION_ID: // \"Id\"\n      case symbol_kind::S_ACTION_INITCOL: // \"InitCol\"\n      case symbol_kind::S_ACTION_LOG: // \"Log\"\n      case symbol_kind::S_ACTION_LOG_DATA: // \"LogData\"\n      case symbol_kind::S_ACTION_MATURITY: // \"Maturity\"\n      case symbol_kind::S_ACTION_MSG: // \"Msg\"\n      case symbol_kind::S_ACTION_MULTI_MATCH: // \"MultiMatch\"\n      case symbol_kind::S_ACTION_NO_AUDIT_LOG: // \"NoAuditLog\"\n      case symbol_kind::S_ACTION_NO_LOG: // \"NoLog\"\n      case symbol_kind::S_ACTION_PASS: // \"Pass\"\n      case symbol_kind::S_ACTION_PAUSE: // \"Pause\"\n      case symbol_kind::S_ACTION_PHASE: // \"Phase\"\n      case symbol_kind::S_ACTION_PREPEND: // \"Prepend\"\n      case symbol_kind::S_ACTION_PROXY: // \"Proxy\"\n      case symbol_kind::S_ACTION_REDIRECT: // \"Redirect\"\n      case symbol_kind::S_ACTION_REV: // \"Rev\"\n      case symbol_kind::S_ACTION_SANITISE_ARG: // \"SanitiseArg\"\n      case symbol_kind::S_ACTION_SANITISE_MATCHED: // \"SanitiseMatched\"\n      case symbol_kind::S_ACTION_SANITISE_MATCHED_BYTES: // \"SanitiseMatchedBytes\"\n      case symbol_kind::S_ACTION_SANITISE_REQUEST_HEADER: // \"SanitiseRequestHeader\"\n      case symbol_kind::S_ACTION_SANITISE_RESPONSE_HEADER: // \"SanitiseResponseHeader\"\n      case symbol_kind::S_ACTION_SETENV: // \"SetEnv\"\n      case symbol_kind::S_ACTION_SETRSC: // \"SetRsc\"\n      case symbol_kind::S_ACTION_SETSID: // \"SetSid\"\n      case symbol_kind::S_ACTION_SETUID: // \"SetUID\"\n      case symbol_kind::S_ACTION_SEVERITY: // \"Severity\"\n      case symbol_kind::S_ACTION_SKIP: // \"Skip\"\n      case symbol_kind::S_ACTION_SKIP_AFTER: // \"SkipAfter\"\n      case symbol_kind::S_ACTION_STATUS: // \"Status\"\n      case symbol_kind::S_ACTION_TAG: // \"Tag\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_BASE_64_ENCODE: // \"ACTION_TRANSFORMATION_BASE_64_ENCODE\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_BASE_64_DECODE: // \"ACTION_TRANSFORMATION_BASE_64_DECODE\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_BASE_64_DECODE_EXT: // \"ACTION_TRANSFORMATION_BASE_64_DECODE_EXT\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_CMD_LINE: // \"ACTION_TRANSFORMATION_CMD_LINE\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_COMPRESS_WHITESPACE: // \"ACTION_TRANSFORMATION_COMPRESS_WHITESPACE\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_CSS_DECODE: // \"ACTION_TRANSFORMATION_CSS_DECODE\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_ESCAPE_SEQ_DECODE: // \"ACTION_TRANSFORMATION_ESCAPE_SEQ_DECODE\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_HEX_ENCODE: // \"ACTION_TRANSFORMATION_HEX_ENCODE\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_HEX_DECODE: // \"ACTION_TRANSFORMATION_HEX_DECODE\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_HTML_ENTITY_DECODE: // \"ACTION_TRANSFORMATION_HTML_ENTITY_DECODE\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_JS_DECODE: // \"ACTION_TRANSFORMATION_JS_DECODE\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_LENGTH: // \"ACTION_TRANSFORMATION_LENGTH\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_LOWERCASE: // \"ACTION_TRANSFORMATION_LOWERCASE\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_MD5: // \"ACTION_TRANSFORMATION_MD5\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_NONE: // \"ACTION_TRANSFORMATION_NONE\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_NORMALISE_PATH: // \"ACTION_TRANSFORMATION_NORMALISE_PATH\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_NORMALISE_PATH_WIN: // \"ACTION_TRANSFORMATION_NORMALISE_PATH_WIN\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_PARITY_EVEN_7_BIT: // \"ACTION_TRANSFORMATION_PARITY_EVEN_7_BIT\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_PARITY_ODD_7_BIT: // \"ACTION_TRANSFORMATION_PARITY_ODD_7_BIT\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_PARITY_ZERO_7_BIT: // \"ACTION_TRANSFORMATION_PARITY_ZERO_7_BIT\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_REMOVE_COMMENTS: // \"ACTION_TRANSFORMATION_REMOVE_COMMENTS\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_REMOVE_COMMENTS_CHAR: // \"ACTION_TRANSFORMATION_REMOVE_COMMENTS_CHAR\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_REMOVE_NULLS: // \"ACTION_TRANSFORMATION_REMOVE_NULLS\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_REMOVE_WHITESPACE: // \"ACTION_TRANSFORMATION_REMOVE_WHITESPACE\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_REPLACE_COMMENTS: // \"ACTION_TRANSFORMATION_REPLACE_COMMENTS\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_REPLACE_NULLS: // \"ACTION_TRANSFORMATION_REPLACE_NULLS\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_SHA1: // \"ACTION_TRANSFORMATION_SHA1\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_SQL_HEX_DECODE: // \"ACTION_TRANSFORMATION_SQL_HEX_DECODE\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_TRIM: // \"ACTION_TRANSFORMATION_TRIM\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_TRIM_LEFT: // \"ACTION_TRANSFORMATION_TRIM_LEFT\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_TRIM_RIGHT: // \"ACTION_TRANSFORMATION_TRIM_RIGHT\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_UPPERCASE: // \"ACTION_TRANSFORMATION_UPPERCASE\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_URL_ENCODE: // \"ACTION_TRANSFORMATION_URL_ENCODE\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_URL_DECODE: // \"ACTION_TRANSFORMATION_URL_DECODE\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_URL_DECODE_UNI: // \"ACTION_TRANSFORMATION_URL_DECODE_UNI\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_UTF8_TO_UNICODE: // \"ACTION_TRANSFORMATION_UTF8_TO_UNICODE\"\n      case symbol_kind::S_ACTION_VER: // \"Ver\"\n      case symbol_kind::S_ACTION_XMLNS: // \"xmlns\"\n      case symbol_kind::S_CONFIG_COMPONENT_SIG: // \"CONFIG_COMPONENT_SIG\"\n      case symbol_kind::S_CONFIG_CONN_ENGINE: // \"CONFIG_CONN_ENGINE\"\n      case symbol_kind::S_CONFIG_SEC_ARGUMENT_SEPARATOR: // \"CONFIG_SEC_ARGUMENT_SEPARATOR\"\n      case symbol_kind::S_CONFIG_SEC_WEB_APP_ID: // \"CONFIG_SEC_WEB_APP_ID\"\n      case symbol_kind::S_CONFIG_SEC_SERVER_SIG: // \"CONFIG_SEC_SERVER_SIG\"\n      case symbol_kind::S_CONFIG_DIR_AUDIT_DIR: // \"CONFIG_DIR_AUDIT_DIR\"\n      case symbol_kind::S_CONFIG_DIR_AUDIT_DIR_MOD: // \"CONFIG_DIR_AUDIT_DIR_MOD\"\n      case symbol_kind::S_CONFIG_DIR_AUDIT_ENG: // \"CONFIG_DIR_AUDIT_ENG\"\n      case symbol_kind::S_CONFIG_DIR_AUDIT_FLE_MOD: // \"CONFIG_DIR_AUDIT_FLE_MOD\"\n      case symbol_kind::S_CONFIG_DIR_AUDIT_LOG: // \"CONFIG_DIR_AUDIT_LOG\"\n      case symbol_kind::S_CONFIG_DIR_AUDIT_LOG2: // \"CONFIG_DIR_AUDIT_LOG2\"\n      case symbol_kind::S_CONFIG_DIR_AUDIT_LOG_P: // \"CONFIG_DIR_AUDIT_LOG_P\"\n      case symbol_kind::S_CONFIG_DIR_AUDIT_STS: // \"CONFIG_DIR_AUDIT_STS\"\n      case symbol_kind::S_CONFIG_DIR_AUDIT_PREFIX: // \"CONFIG_DIR_AUDIT_PREFIX\"\n      case symbol_kind::S_CONFIG_DIR_AUDIT_TPE: // \"CONFIG_DIR_AUDIT_TPE\"\n      case symbol_kind::S_CONFIG_DIR_DEBUG_LOG: // \"CONFIG_DIR_DEBUG_LOG\"\n      case symbol_kind::S_CONFIG_DIR_DEBUG_LVL: // \"CONFIG_DIR_DEBUG_LVL\"\n      case symbol_kind::S_CONFIG_SEC_CACHE_TRANSFORMATIONS: // \"CONFIG_SEC_CACHE_TRANSFORMATIONS\"\n      case symbol_kind::S_CONFIG_SEC_DISABLE_BACKEND_COMPRESS: // \"CONFIG_SEC_DISABLE_BACKEND_COMPRESS\"\n      case symbol_kind::S_CONFIG_SEC_HASH_ENGINE: // \"CONFIG_SEC_HASH_ENGINE\"\n      case symbol_kind::S_CONFIG_SEC_HASH_KEY: // \"CONFIG_SEC_HASH_KEY\"\n      case symbol_kind::S_CONFIG_SEC_HASH_PARAM: // \"CONFIG_SEC_HASH_PARAM\"\n      case symbol_kind::S_CONFIG_SEC_HASH_METHOD_RX: // \"CONFIG_SEC_HASH_METHOD_RX\"\n      case symbol_kind::S_CONFIG_SEC_HASH_METHOD_PM: // \"CONFIG_SEC_HASH_METHOD_PM\"\n      case symbol_kind::S_CONFIG_SEC_CHROOT_DIR: // \"CONFIG_SEC_CHROOT_DIR\"\n      case symbol_kind::S_CONFIG_DIR_GEO_DB: // \"CONFIG_DIR_GEO_DB\"\n      case symbol_kind::S_CONFIG_DIR_GSB_DB: // \"CONFIG_DIR_GSB_DB\"\n      case symbol_kind::S_CONFIG_SEC_GUARDIAN_LOG: // \"CONFIG_SEC_GUARDIAN_LOG\"\n      case symbol_kind::S_CONFIG_DIR_PCRE_MATCH_LIMIT: // \"CONFIG_DIR_PCRE_MATCH_LIMIT\"\n      case symbol_kind::S_CONFIG_DIR_PCRE_MATCH_LIMIT_RECURSION: // \"CONFIG_DIR_PCRE_MATCH_LIMIT_RECURSION\"\n      case symbol_kind::S_CONFIG_SEC_CONN_R_STATE_LIMIT: // \"CONFIG_SEC_CONN_R_STATE_LIMIT\"\n      case symbol_kind::S_CONFIG_SEC_CONN_W_STATE_LIMIT: // \"CONFIG_SEC_CONN_W_STATE_LIMIT\"\n      case symbol_kind::S_CONFIG_SEC_SENSOR_ID: // \"CONFIG_SEC_SENSOR_ID\"\n      case symbol_kind::S_CONFIG_DIR_ARGS_LIMIT: // \"CONFIG_DIR_ARGS_LIMIT\"\n      case symbol_kind::S_CONFIG_DIR_REQ_BODY_JSON_DEPTH_LIMIT: // \"CONFIG_DIR_REQ_BODY_JSON_DEPTH_LIMIT\"\n      case symbol_kind::S_CONFIG_DIR_REQ_BODY: // \"CONFIG_DIR_REQ_BODY\"\n      case symbol_kind::S_CONFIG_DIR_REQ_BODY_IN_MEMORY_LIMIT: // \"CONFIG_DIR_REQ_BODY_IN_MEMORY_LIMIT\"\n      case symbol_kind::S_CONFIG_DIR_REQ_BODY_LIMIT: // \"CONFIG_DIR_REQ_BODY_LIMIT\"\n      case symbol_kind::S_CONFIG_DIR_REQ_BODY_LIMIT_ACTION: // \"CONFIG_DIR_REQ_BODY_LIMIT_ACTION\"\n      case symbol_kind::S_CONFIG_DIR_REQ_BODY_NO_FILES_LIMIT: // \"CONFIG_DIR_REQ_BODY_NO_FILES_LIMIT\"\n      case symbol_kind::S_CONFIG_DIR_RES_BODY: // \"CONFIG_DIR_RES_BODY\"\n      case symbol_kind::S_CONFIG_DIR_RES_BODY_LIMIT: // \"CONFIG_DIR_RES_BODY_LIMIT\"\n      case symbol_kind::S_CONFIG_DIR_RES_BODY_LIMIT_ACTION: // \"CONFIG_DIR_RES_BODY_LIMIT_ACTION\"\n      case symbol_kind::S_CONFIG_SEC_RULE_INHERITANCE: // \"CONFIG_SEC_RULE_INHERITANCE\"\n      case symbol_kind::S_CONFIG_SEC_RULE_PERF_TIME: // \"CONFIG_SEC_RULE_PERF_TIME\"\n      case symbol_kind::S_CONFIG_DIR_RULE_ENG: // \"CONFIG_DIR_RULE_ENG\"\n      case symbol_kind::S_CONFIG_DIR_SEC_ACTION: // \"CONFIG_DIR_SEC_ACTION\"\n      case symbol_kind::S_CONFIG_DIR_SEC_DEFAULT_ACTION: // \"CONFIG_DIR_SEC_DEFAULT_ACTION\"\n      case symbol_kind::S_CONFIG_DIR_SEC_MARKER: // \"CONFIG_DIR_SEC_MARKER\"\n      case symbol_kind::S_CONFIG_DIR_UNICODE_MAP_FILE: // \"CONFIG_DIR_UNICODE_MAP_FILE\"\n      case symbol_kind::S_CONFIG_DIR_UNICODE_CODE_PAGE: // \"CONFIG_DIR_UNICODE_CODE_PAGE\"\n      case symbol_kind::S_CONFIG_SEC_COLLECTION_TIMEOUT: // \"CONFIG_SEC_COLLECTION_TIMEOUT\"\n      case symbol_kind::S_CONFIG_SEC_HTTP_BLKEY: // \"CONFIG_SEC_HTTP_BLKEY\"\n      case symbol_kind::S_CONFIG_SEC_INTERCEPT_ON_ERROR: // \"CONFIG_SEC_INTERCEPT_ON_ERROR\"\n      case symbol_kind::S_CONFIG_SEC_REMOTE_RULES_FAIL_ACTION: // \"CONFIG_SEC_REMOTE_RULES_FAIL_ACTION\"\n      case symbol_kind::S_CONFIG_SEC_RULE_REMOVE_BY_ID: // \"CONFIG_SEC_RULE_REMOVE_BY_ID\"\n      case symbol_kind::S_CONFIG_SEC_RULE_REMOVE_BY_MSG: // \"CONFIG_SEC_RULE_REMOVE_BY_MSG\"\n      case symbol_kind::S_CONFIG_SEC_RULE_REMOVE_BY_TAG: // \"CONFIG_SEC_RULE_REMOVE_BY_TAG\"\n      case symbol_kind::S_CONFIG_SEC_RULE_UPDATE_TARGET_BY_TAG: // \"CONFIG_SEC_RULE_UPDATE_TARGET_BY_TAG\"\n      case symbol_kind::S_CONFIG_SEC_RULE_UPDATE_TARGET_BY_MSG: // \"CONFIG_SEC_RULE_UPDATE_TARGET_BY_MSG\"\n      case symbol_kind::S_CONFIG_SEC_RULE_UPDATE_TARGET_BY_ID: // \"CONFIG_SEC_RULE_UPDATE_TARGET_BY_ID\"\n      case symbol_kind::S_CONFIG_SEC_RULE_UPDATE_ACTION_BY_ID: // \"CONFIG_SEC_RULE_UPDATE_ACTION_BY_ID\"\n      case symbol_kind::S_CONFIG_UPDLOAD_KEEP_FILES: // \"CONFIG_UPDLOAD_KEEP_FILES\"\n      case symbol_kind::S_CONFIG_UPDLOAD_SAVE_TMP_FILES: // \"CONFIG_UPDLOAD_SAVE_TMP_FILES\"\n      case symbol_kind::S_CONFIG_UPLOAD_DIR: // \"CONFIG_UPLOAD_DIR\"\n      case symbol_kind::S_CONFIG_UPLOAD_FILE_LIMIT: // \"CONFIG_UPLOAD_FILE_LIMIT\"\n      case symbol_kind::S_CONFIG_UPLOAD_FILE_MODE: // \"CONFIG_UPLOAD_FILE_MODE\"\n      case symbol_kind::S_CONFIG_VALUE_ABORT: // \"CONFIG_VALUE_ABORT\"\n      case symbol_kind::S_CONFIG_VALUE_DETC: // \"CONFIG_VALUE_DETC\"\n      case symbol_kind::S_CONFIG_VALUE_HTTPS: // \"CONFIG_VALUE_HTTPS\"\n      case symbol_kind::S_CONFIG_VALUE_ONLYARGS: // \"CONFIG_VALUE_ONLYARGS\"\n      case symbol_kind::S_CONFIG_VALUE_OFF: // \"CONFIG_VALUE_OFF\"\n      case symbol_kind::S_CONFIG_VALUE_ON: // \"CONFIG_VALUE_ON\"\n      case symbol_kind::S_CONFIG_VALUE_PARALLEL: // \"CONFIG_VALUE_PARALLEL\"\n      case symbol_kind::S_CONFIG_VALUE_PROCESS_PARTIAL: // \"CONFIG_VALUE_PROCESS_PARTIAL\"\n      case symbol_kind::S_CONFIG_VALUE_REJECT: // \"CONFIG_VALUE_REJECT\"\n      case symbol_kind::S_CONFIG_VALUE_RELEVANT_ONLY: // \"CONFIG_VALUE_RELEVANT_ONLY\"\n      case symbol_kind::S_CONFIG_VALUE_SERIAL: // \"CONFIG_VALUE_SERIAL\"\n      case symbol_kind::S_CONFIG_VALUE_WARN: // \"CONFIG_VALUE_WARN\"\n      case symbol_kind::S_CONFIG_XML_EXTERNAL_ENTITY: // \"CONFIG_XML_EXTERNAL_ENTITY\"\n      case symbol_kind::S_CONFIG_XML_PARSE_XML_INTO_ARGS: // \"CONFIG_XML_PARSE_XML_INTO_ARGS\"\n      case symbol_kind::S_CONGIG_DIR_RESPONSE_BODY_MP: // \"CONGIG_DIR_RESPONSE_BODY_MP\"\n      case symbol_kind::S_CONGIG_DIR_SEC_ARG_SEP: // \"CONGIG_DIR_SEC_ARG_SEP\"\n      case symbol_kind::S_CONGIG_DIR_SEC_COOKIE_FORMAT: // \"CONGIG_DIR_SEC_COOKIE_FORMAT\"\n      case symbol_kind::S_CONFIG_SEC_COOKIEV0_SEPARATOR: // \"CONFIG_SEC_COOKIEV0_SEPARATOR\"\n      case symbol_kind::S_CONGIG_DIR_SEC_DATA_DIR: // \"CONGIG_DIR_SEC_DATA_DIR\"\n      case symbol_kind::S_CONGIG_DIR_SEC_STATUS_ENGINE: // \"CONGIG_DIR_SEC_STATUS_ENGINE\"\n      case symbol_kind::S_CONFIG_SEC_STREAM_IN_BODY_INSPECTION: // \"CONFIG_SEC_STREAM_IN_BODY_INSPECTION\"\n      case symbol_kind::S_CONFIG_SEC_STREAM_OUT_BODY_INSPECTION: // \"CONFIG_SEC_STREAM_OUT_BODY_INSPECTION\"\n      case symbol_kind::S_CONGIG_DIR_SEC_TMP_DIR: // \"CONGIG_DIR_SEC_TMP_DIR\"\n      case symbol_kind::S_DIRECTIVE: // \"DIRECTIVE\"\n      case symbol_kind::S_DIRECTIVE_SECRULESCRIPT: // \"DIRECTIVE_SECRULESCRIPT\"\n      case symbol_kind::S_FREE_TEXT_QUOTE_MACRO_EXPANSION: // \"FREE_TEXT_QUOTE_MACRO_EXPANSION\"\n      case symbol_kind::S_QUOTATION_MARK: // \"QUOTATION_MARK\"\n      case symbol_kind::S_RUN_TIME_VAR_BLD: // \"RUN_TIME_VAR_BLD\"\n      case symbol_kind::S_RUN_TIME_VAR_DUR: // \"RUN_TIME_VAR_DUR\"\n      case symbol_kind::S_RUN_TIME_VAR_HSV: // \"RUN_TIME_VAR_HSV\"\n      case symbol_kind::S_RUN_TIME_VAR_REMOTE_USER: // \"RUN_TIME_VAR_REMOTE_USER\"\n      case symbol_kind::S_RUN_TIME_VAR_TIME: // \"RUN_TIME_VAR_TIME\"\n      case symbol_kind::S_RUN_TIME_VAR_TIME_DAY: // \"RUN_TIME_VAR_TIME_DAY\"\n      case symbol_kind::S_RUN_TIME_VAR_TIME_EPOCH: // \"RUN_TIME_VAR_TIME_EPOCH\"\n      case symbol_kind::S_RUN_TIME_VAR_TIME_HOUR: // \"RUN_TIME_VAR_TIME_HOUR\"\n      case symbol_kind::S_RUN_TIME_VAR_TIME_MIN: // \"RUN_TIME_VAR_TIME_MIN\"\n      case symbol_kind::S_RUN_TIME_VAR_TIME_MON: // \"RUN_TIME_VAR_TIME_MON\"\n      case symbol_kind::S_RUN_TIME_VAR_TIME_SEC: // \"RUN_TIME_VAR_TIME_SEC\"\n      case symbol_kind::S_RUN_TIME_VAR_TIME_WDAY: // \"RUN_TIME_VAR_TIME_WDAY\"\n      case symbol_kind::S_RUN_TIME_VAR_TIME_YEAR: // \"RUN_TIME_VAR_TIME_YEAR\"\n      case symbol_kind::S_VARIABLE: // \"VARIABLE\"\n      case symbol_kind::S_DICT_ELEMENT: // \"Dictionary element\"\n      case symbol_kind::S_DICT_ELEMENT_WITH_EQUALS: // \"Dictionary element, with equals\"\n      case symbol_kind::S_DICT_ELEMENT_REGEXP: // \"Dictionary element, selected by regexp\"\n        value.copy< std::string > (YY_MOVE (that.value));\n        break;\n\n      case symbol_kind::S_op: // op\n      case symbol_kind::S_op_before_init: // op_before_init\n        value.copy< std::unique_ptr<Operator> > (YY_MOVE (that.value));\n        break;\n\n      case symbol_kind::S_run_time_string: // run_time_string\n        value.copy< std::unique_ptr<RunTimeString> > (YY_MOVE (that.value));\n        break;\n\n      case symbol_kind::S_var: // var\n        value.copy< std::unique_ptr<Variable> > (YY_MOVE (that.value));\n        break;\n\n      case symbol_kind::S_act: // act\n      case symbol_kind::S_setvar_action: // setvar_action\n        value.copy< std::unique_ptr<actions::Action> > (YY_MOVE (that.value));\n        break;\n\n      case symbol_kind::S_variables: // variables\n      case symbol_kind::S_variables_pre_process: // variables_pre_process\n      case symbol_kind::S_variables_may_be_quoted: // variables_may_be_quoted\n        value.copy< std::unique_ptr<std::vector<std::unique_ptr<Variable> > >  > (YY_MOVE (that.value));\n        break;\n\n      case symbol_kind::S_actions: // actions\n      case symbol_kind::S_actions_may_quoted: // actions_may_quoted\n        value.copy< std::unique_ptr<std::vector<std::unique_ptr<actions::Action> > >  > (YY_MOVE (that.value));\n        break;\n\n      default:\n        break;\n    }\n\n  }\n\n\n\n\n  template <typename Base>\n  seclang_parser::symbol_kind_type\n  seclang_parser::basic_symbol<Base>::type_get () const YY_NOEXCEPT\n  {\n    return this->kind ();\n  }\n\n\n  template <typename Base>\n  bool\n  seclang_parser::basic_symbol<Base>::empty () const YY_NOEXCEPT\n  {\n    return this->kind () == symbol_kind::S_YYEMPTY;\n  }\n\n  template <typename Base>\n  void\n  seclang_parser::basic_symbol<Base>::move (basic_symbol& s)\n  {\n    super_type::move (s);\n    switch (this->kind ())\n    {\n      case symbol_kind::S_ACTION_ACCURACY: // \"Accuracy\"\n      case symbol_kind::S_ACTION_ALLOW: // \"Allow\"\n      case symbol_kind::S_ACTION_APPEND: // \"Append\"\n      case symbol_kind::S_ACTION_AUDIT_LOG: // \"AuditLog\"\n      case symbol_kind::S_ACTION_BLOCK: // \"Block\"\n      case symbol_kind::S_ACTION_CAPTURE: // \"Capture\"\n      case symbol_kind::S_ACTION_CHAIN: // \"Chain\"\n      case symbol_kind::S_ACTION_CTL_AUDIT_ENGINE: // \"ACTION_CTL_AUDIT_ENGINE\"\n      case symbol_kind::S_ACTION_CTL_AUDIT_LOG_PARTS: // \"ACTION_CTL_AUDIT_LOG_PARTS\"\n      case symbol_kind::S_ACTION_CTL_BDY_JSON: // \"ACTION_CTL_BDY_JSON\"\n      case symbol_kind::S_ACTION_CTL_BDY_XML: // \"ACTION_CTL_BDY_XML\"\n      case symbol_kind::S_ACTION_CTL_BDY_URLENCODED: // \"ACTION_CTL_BDY_URLENCODED\"\n      case symbol_kind::S_ACTION_CTL_FORCE_REQ_BODY_VAR: // \"ACTION_CTL_FORCE_REQ_BODY_VAR\"\n      case symbol_kind::S_ACTION_CTL_PARSE_XML_INTO_ARGS: // \"ACTION_CTL_PARSE_XML_INTO_ARGS\"\n      case symbol_kind::S_ACTION_CTL_REQUEST_BODY_ACCESS: // \"ACTION_CTL_REQUEST_BODY_ACCESS\"\n      case symbol_kind::S_ACTION_CTL_RULE_REMOVE_BY_ID: // \"ACTION_CTL_RULE_REMOVE_BY_ID\"\n      case symbol_kind::S_ACTION_CTL_RULE_REMOVE_BY_TAG: // \"ACTION_CTL_RULE_REMOVE_BY_TAG\"\n      case symbol_kind::S_ACTION_CTL_RULE_REMOVE_TARGET_BY_ID: // \"ACTION_CTL_RULE_REMOVE_TARGET_BY_ID\"\n      case symbol_kind::S_ACTION_CTL_RULE_REMOVE_TARGET_BY_TAG: // \"ACTION_CTL_RULE_REMOVE_TARGET_BY_TAG\"\n      case symbol_kind::S_ACTION_DENY: // \"Deny\"\n      case symbol_kind::S_ACTION_DEPRECATE_VAR: // \"DeprecateVar\"\n      case symbol_kind::S_ACTION_DROP: // \"Drop\"\n      case symbol_kind::S_ACTION_EXEC: // \"Exec\"\n      case symbol_kind::S_ACTION_EXPIRE_VAR: // \"ExpireVar\"\n      case symbol_kind::S_ACTION_ID: // \"Id\"\n      case symbol_kind::S_ACTION_INITCOL: // \"InitCol\"\n      case symbol_kind::S_ACTION_LOG: // \"Log\"\n      case symbol_kind::S_ACTION_LOG_DATA: // \"LogData\"\n      case symbol_kind::S_ACTION_MATURITY: // \"Maturity\"\n      case symbol_kind::S_ACTION_MSG: // \"Msg\"\n      case symbol_kind::S_ACTION_MULTI_MATCH: // \"MultiMatch\"\n      case symbol_kind::S_ACTION_NO_AUDIT_LOG: // \"NoAuditLog\"\n      case symbol_kind::S_ACTION_NO_LOG: // \"NoLog\"\n      case symbol_kind::S_ACTION_PASS: // \"Pass\"\n      case symbol_kind::S_ACTION_PAUSE: // \"Pause\"\n      case symbol_kind::S_ACTION_PHASE: // \"Phase\"\n      case symbol_kind::S_ACTION_PREPEND: // \"Prepend\"\n      case symbol_kind::S_ACTION_PROXY: // \"Proxy\"\n      case symbol_kind::S_ACTION_REDIRECT: // \"Redirect\"\n      case symbol_kind::S_ACTION_REV: // \"Rev\"\n      case symbol_kind::S_ACTION_SANITISE_ARG: // \"SanitiseArg\"\n      case symbol_kind::S_ACTION_SANITISE_MATCHED: // \"SanitiseMatched\"\n      case symbol_kind::S_ACTION_SANITISE_MATCHED_BYTES: // \"SanitiseMatchedBytes\"\n      case symbol_kind::S_ACTION_SANITISE_REQUEST_HEADER: // \"SanitiseRequestHeader\"\n      case symbol_kind::S_ACTION_SANITISE_RESPONSE_HEADER: // \"SanitiseResponseHeader\"\n      case symbol_kind::S_ACTION_SETENV: // \"SetEnv\"\n      case symbol_kind::S_ACTION_SETRSC: // \"SetRsc\"\n      case symbol_kind::S_ACTION_SETSID: // \"SetSid\"\n      case symbol_kind::S_ACTION_SETUID: // \"SetUID\"\n      case symbol_kind::S_ACTION_SEVERITY: // \"Severity\"\n      case symbol_kind::S_ACTION_SKIP: // \"Skip\"\n      case symbol_kind::S_ACTION_SKIP_AFTER: // \"SkipAfter\"\n      case symbol_kind::S_ACTION_STATUS: // \"Status\"\n      case symbol_kind::S_ACTION_TAG: // \"Tag\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_BASE_64_ENCODE: // \"ACTION_TRANSFORMATION_BASE_64_ENCODE\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_BASE_64_DECODE: // \"ACTION_TRANSFORMATION_BASE_64_DECODE\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_BASE_64_DECODE_EXT: // \"ACTION_TRANSFORMATION_BASE_64_DECODE_EXT\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_CMD_LINE: // \"ACTION_TRANSFORMATION_CMD_LINE\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_COMPRESS_WHITESPACE: // \"ACTION_TRANSFORMATION_COMPRESS_WHITESPACE\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_CSS_DECODE: // \"ACTION_TRANSFORMATION_CSS_DECODE\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_ESCAPE_SEQ_DECODE: // \"ACTION_TRANSFORMATION_ESCAPE_SEQ_DECODE\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_HEX_ENCODE: // \"ACTION_TRANSFORMATION_HEX_ENCODE\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_HEX_DECODE: // \"ACTION_TRANSFORMATION_HEX_DECODE\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_HTML_ENTITY_DECODE: // \"ACTION_TRANSFORMATION_HTML_ENTITY_DECODE\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_JS_DECODE: // \"ACTION_TRANSFORMATION_JS_DECODE\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_LENGTH: // \"ACTION_TRANSFORMATION_LENGTH\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_LOWERCASE: // \"ACTION_TRANSFORMATION_LOWERCASE\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_MD5: // \"ACTION_TRANSFORMATION_MD5\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_NONE: // \"ACTION_TRANSFORMATION_NONE\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_NORMALISE_PATH: // \"ACTION_TRANSFORMATION_NORMALISE_PATH\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_NORMALISE_PATH_WIN: // \"ACTION_TRANSFORMATION_NORMALISE_PATH_WIN\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_PARITY_EVEN_7_BIT: // \"ACTION_TRANSFORMATION_PARITY_EVEN_7_BIT\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_PARITY_ODD_7_BIT: // \"ACTION_TRANSFORMATION_PARITY_ODD_7_BIT\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_PARITY_ZERO_7_BIT: // \"ACTION_TRANSFORMATION_PARITY_ZERO_7_BIT\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_REMOVE_COMMENTS: // \"ACTION_TRANSFORMATION_REMOVE_COMMENTS\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_REMOVE_COMMENTS_CHAR: // \"ACTION_TRANSFORMATION_REMOVE_COMMENTS_CHAR\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_REMOVE_NULLS: // \"ACTION_TRANSFORMATION_REMOVE_NULLS\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_REMOVE_WHITESPACE: // \"ACTION_TRANSFORMATION_REMOVE_WHITESPACE\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_REPLACE_COMMENTS: // \"ACTION_TRANSFORMATION_REPLACE_COMMENTS\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_REPLACE_NULLS: // \"ACTION_TRANSFORMATION_REPLACE_NULLS\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_SHA1: // \"ACTION_TRANSFORMATION_SHA1\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_SQL_HEX_DECODE: // \"ACTION_TRANSFORMATION_SQL_HEX_DECODE\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_TRIM: // \"ACTION_TRANSFORMATION_TRIM\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_TRIM_LEFT: // \"ACTION_TRANSFORMATION_TRIM_LEFT\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_TRIM_RIGHT: // \"ACTION_TRANSFORMATION_TRIM_RIGHT\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_UPPERCASE: // \"ACTION_TRANSFORMATION_UPPERCASE\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_URL_ENCODE: // \"ACTION_TRANSFORMATION_URL_ENCODE\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_URL_DECODE: // \"ACTION_TRANSFORMATION_URL_DECODE\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_URL_DECODE_UNI: // \"ACTION_TRANSFORMATION_URL_DECODE_UNI\"\n      case symbol_kind::S_ACTION_TRANSFORMATION_UTF8_TO_UNICODE: // \"ACTION_TRANSFORMATION_UTF8_TO_UNICODE\"\n      case symbol_kind::S_ACTION_VER: // \"Ver\"\n      case symbol_kind::S_ACTION_XMLNS: // \"xmlns\"\n      case symbol_kind::S_CONFIG_COMPONENT_SIG: // \"CONFIG_COMPONENT_SIG\"\n      case symbol_kind::S_CONFIG_CONN_ENGINE: // \"CONFIG_CONN_ENGINE\"\n      case symbol_kind::S_CONFIG_SEC_ARGUMENT_SEPARATOR: // \"CONFIG_SEC_ARGUMENT_SEPARATOR\"\n      case symbol_kind::S_CONFIG_SEC_WEB_APP_ID: // \"CONFIG_SEC_WEB_APP_ID\"\n      case symbol_kind::S_CONFIG_SEC_SERVER_SIG: // \"CONFIG_SEC_SERVER_SIG\"\n      case symbol_kind::S_CONFIG_DIR_AUDIT_DIR: // \"CONFIG_DIR_AUDIT_DIR\"\n      case symbol_kind::S_CONFIG_DIR_AUDIT_DIR_MOD: // \"CONFIG_DIR_AUDIT_DIR_MOD\"\n      case symbol_kind::S_CONFIG_DIR_AUDIT_ENG: // \"CONFIG_DIR_AUDIT_ENG\"\n      case symbol_kind::S_CONFIG_DIR_AUDIT_FLE_MOD: // \"CONFIG_DIR_AUDIT_FLE_MOD\"\n      case symbol_kind::S_CONFIG_DIR_AUDIT_LOG: // \"CONFIG_DIR_AUDIT_LOG\"\n      case symbol_kind::S_CONFIG_DIR_AUDIT_LOG2: // \"CONFIG_DIR_AUDIT_LOG2\"\n      case symbol_kind::S_CONFIG_DIR_AUDIT_LOG_P: // \"CONFIG_DIR_AUDIT_LOG_P\"\n      case symbol_kind::S_CONFIG_DIR_AUDIT_STS: // \"CONFIG_DIR_AUDIT_STS\"\n      case symbol_kind::S_CONFIG_DIR_AUDIT_PREFIX: // \"CONFIG_DIR_AUDIT_PREFIX\"\n      case symbol_kind::S_CONFIG_DIR_AUDIT_TPE: // \"CONFIG_DIR_AUDIT_TPE\"\n      case symbol_kind::S_CONFIG_DIR_DEBUG_LOG: // \"CONFIG_DIR_DEBUG_LOG\"\n      case symbol_kind::S_CONFIG_DIR_DEBUG_LVL: // \"CONFIG_DIR_DEBUG_LVL\"\n      case symbol_kind::S_CONFIG_SEC_CACHE_TRANSFORMATIONS: // \"CONFIG_SEC_CACHE_TRANSFORMATIONS\"\n      case symbol_kind::S_CONFIG_SEC_DISABLE_BACKEND_COMPRESS: // \"CONFIG_SEC_DISABLE_BACKEND_COMPRESS\"\n      case symbol_kind::S_CONFIG_SEC_HASH_ENGINE: // \"CONFIG_SEC_HASH_ENGINE\"\n      case symbol_kind::S_CONFIG_SEC_HASH_KEY: // \"CONFIG_SEC_HASH_KEY\"\n      case symbol_kind::S_CONFIG_SEC_HASH_PARAM: // \"CONFIG_SEC_HASH_PARAM\"\n      case symbol_kind::S_CONFIG_SEC_HASH_METHOD_RX: // \"CONFIG_SEC_HASH_METHOD_RX\"\n      case symbol_kind::S_CONFIG_SEC_HASH_METHOD_PM: // \"CONFIG_SEC_HASH_METHOD_PM\"\n      case symbol_kind::S_CONFIG_SEC_CHROOT_DIR: // \"CONFIG_SEC_CHROOT_DIR\"\n      case symbol_kind::S_CONFIG_DIR_GEO_DB: // \"CONFIG_DIR_GEO_DB\"\n      case symbol_kind::S_CONFIG_DIR_GSB_DB: // \"CONFIG_DIR_GSB_DB\"\n      case symbol_kind::S_CONFIG_SEC_GUARDIAN_LOG: // \"CONFIG_SEC_GUARDIAN_LOG\"\n      case symbol_kind::S_CONFIG_DIR_PCRE_MATCH_LIMIT: // \"CONFIG_DIR_PCRE_MATCH_LIMIT\"\n      case symbol_kind::S_CONFIG_DIR_PCRE_MATCH_LIMIT_RECURSION: // \"CONFIG_DIR_PCRE_MATCH_LIMIT_RECURSION\"\n      case symbol_kind::S_CONFIG_SEC_CONN_R_STATE_LIMIT: // \"CONFIG_SEC_CONN_R_STATE_LIMIT\"\n      case symbol_kind::S_CONFIG_SEC_CONN_W_STATE_LIMIT: // \"CONFIG_SEC_CONN_W_STATE_LIMIT\"\n      case symbol_kind::S_CONFIG_SEC_SENSOR_ID: // \"CONFIG_SEC_SENSOR_ID\"\n      case symbol_kind::S_CONFIG_DIR_ARGS_LIMIT: // \"CONFIG_DIR_ARGS_LIMIT\"\n      case symbol_kind::S_CONFIG_DIR_REQ_BODY_JSON_DEPTH_LIMIT: // \"CONFIG_DIR_REQ_BODY_JSON_DEPTH_LIMIT\"\n      case symbol_kind::S_CONFIG_DIR_REQ_BODY: // \"CONFIG_DIR_REQ_BODY\"\n      case symbol_kind::S_CONFIG_DIR_REQ_BODY_IN_MEMORY_LIMIT: // \"CONFIG_DIR_REQ_BODY_IN_MEMORY_LIMIT\"\n      case symbol_kind::S_CONFIG_DIR_REQ_BODY_LIMIT: // \"CONFIG_DIR_REQ_BODY_LIMIT\"\n      case symbol_kind::S_CONFIG_DIR_REQ_BODY_LIMIT_ACTION: // \"CONFIG_DIR_REQ_BODY_LIMIT_ACTION\"\n      case symbol_kind::S_CONFIG_DIR_REQ_BODY_NO_FILES_LIMIT: // \"CONFIG_DIR_REQ_BODY_NO_FILES_LIMIT\"\n      case symbol_kind::S_CONFIG_DIR_RES_BODY: // \"CONFIG_DIR_RES_BODY\"\n      case symbol_kind::S_CONFIG_DIR_RES_BODY_LIMIT: // \"CONFIG_DIR_RES_BODY_LIMIT\"\n      case symbol_kind::S_CONFIG_DIR_RES_BODY_LIMIT_ACTION: // \"CONFIG_DIR_RES_BODY_LIMIT_ACTION\"\n      case symbol_kind::S_CONFIG_SEC_RULE_INHERITANCE: // \"CONFIG_SEC_RULE_INHERITANCE\"\n      case symbol_kind::S_CONFIG_SEC_RULE_PERF_TIME: // \"CONFIG_SEC_RULE_PERF_TIME\"\n      case symbol_kind::S_CONFIG_DIR_RULE_ENG: // \"CONFIG_DIR_RULE_ENG\"\n      case symbol_kind::S_CONFIG_DIR_SEC_ACTION: // \"CONFIG_DIR_SEC_ACTION\"\n      case symbol_kind::S_CONFIG_DIR_SEC_DEFAULT_ACTION: // \"CONFIG_DIR_SEC_DEFAULT_ACTION\"\n      case symbol_kind::S_CONFIG_DIR_SEC_MARKER: // \"CONFIG_DIR_SEC_MARKER\"\n      case symbol_kind::S_CONFIG_DIR_UNICODE_MAP_FILE: // \"CONFIG_DIR_UNICODE_MAP_FILE\"\n      case symbol_kind::S_CONFIG_DIR_UNICODE_CODE_PAGE: // \"CONFIG_DIR_UNICODE_CODE_PAGE\"\n      case symbol_kind::S_CONFIG_SEC_COLLECTION_TIMEOUT: // \"CONFIG_SEC_COLLECTION_TIMEOUT\"\n      case symbol_kind::S_CONFIG_SEC_HTTP_BLKEY: // \"CONFIG_SEC_HTTP_BLKEY\"\n      case symbol_kind::S_CONFIG_SEC_INTERCEPT_ON_ERROR: // \"CONFIG_SEC_INTERCEPT_ON_ERROR\"\n      case symbol_kind::S_CONFIG_SEC_REMOTE_RULES_FAIL_ACTION: // \"CONFIG_SEC_REMOTE_RULES_FAIL_ACTION\"\n      case symbol_kind::S_CONFIG_SEC_RULE_REMOVE_BY_ID: // \"CONFIG_SEC_RULE_REMOVE_BY_ID\"\n      case symbol_kind::S_CONFIG_SEC_RULE_REMOVE_BY_MSG: // \"CONFIG_SEC_RULE_REMOVE_BY_MSG\"\n      case symbol_kind::S_CONFIG_SEC_RULE_REMOVE_BY_TAG: // \"CONFIG_SEC_RULE_REMOVE_BY_TAG\"\n      case symbol_kind::S_CONFIG_SEC_RULE_UPDATE_TARGET_BY_TAG: // \"CONFIG_SEC_RULE_UPDATE_TARGET_BY_TAG\"\n      case symbol_kind::S_CONFIG_SEC_RULE_UPDATE_TARGET_BY_MSG: // \"CONFIG_SEC_RULE_UPDATE_TARGET_BY_MSG\"\n      case symbol_kind::S_CONFIG_SEC_RULE_UPDATE_TARGET_BY_ID: // \"CONFIG_SEC_RULE_UPDATE_TARGET_BY_ID\"\n      case symbol_kind::S_CONFIG_SEC_RULE_UPDATE_ACTION_BY_ID: // \"CONFIG_SEC_RULE_UPDATE_ACTION_BY_ID\"\n      case symbol_kind::S_CONFIG_UPDLOAD_KEEP_FILES: // \"CONFIG_UPDLOAD_KEEP_FILES\"\n      case symbol_kind::S_CONFIG_UPDLOAD_SAVE_TMP_FILES: // \"CONFIG_UPDLOAD_SAVE_TMP_FILES\"\n      case symbol_kind::S_CONFIG_UPLOAD_DIR: // \"CONFIG_UPLOAD_DIR\"\n      case symbol_kind::S_CONFIG_UPLOAD_FILE_LIMIT: // \"CONFIG_UPLOAD_FILE_LIMIT\"\n      case symbol_kind::S_CONFIG_UPLOAD_FILE_MODE: // \"CONFIG_UPLOAD_FILE_MODE\"\n      case symbol_kind::S_CONFIG_VALUE_ABORT: // \"CONFIG_VALUE_ABORT\"\n      case symbol_kind::S_CONFIG_VALUE_DETC: // \"CONFIG_VALUE_DETC\"\n      case symbol_kind::S_CONFIG_VALUE_HTTPS: // \"CONFIG_VALUE_HTTPS\"\n      case symbol_kind::S_CONFIG_VALUE_ONLYARGS: // \"CONFIG_VALUE_ONLYARGS\"\n      case symbol_kind::S_CONFIG_VALUE_OFF: // \"CONFIG_VALUE_OFF\"\n      case symbol_kind::S_CONFIG_VALUE_ON: // \"CONFIG_VALUE_ON\"\n      case symbol_kind::S_CONFIG_VALUE_PARALLEL: // \"CONFIG_VALUE_PARALLEL\"\n      case symbol_kind::S_CONFIG_VALUE_PROCESS_PARTIAL: // \"CONFIG_VALUE_PROCESS_PARTIAL\"\n      case symbol_kind::S_CONFIG_VALUE_REJECT: // \"CONFIG_VALUE_REJECT\"\n      case symbol_kind::S_CONFIG_VALUE_RELEVANT_ONLY: // \"CONFIG_VALUE_RELEVANT_ONLY\"\n      case symbol_kind::S_CONFIG_VALUE_SERIAL: // \"CONFIG_VALUE_SERIAL\"\n      case symbol_kind::S_CONFIG_VALUE_WARN: // \"CONFIG_VALUE_WARN\"\n      case symbol_kind::S_CONFIG_XML_EXTERNAL_ENTITY: // \"CONFIG_XML_EXTERNAL_ENTITY\"\n      case symbol_kind::S_CONFIG_XML_PARSE_XML_INTO_ARGS: // \"CONFIG_XML_PARSE_XML_INTO_ARGS\"\n      case symbol_kind::S_CONGIG_DIR_RESPONSE_BODY_MP: // \"CONGIG_DIR_RESPONSE_BODY_MP\"\n      case symbol_kind::S_CONGIG_DIR_SEC_ARG_SEP: // \"CONGIG_DIR_SEC_ARG_SEP\"\n      case symbol_kind::S_CONGIG_DIR_SEC_COOKIE_FORMAT: // \"CONGIG_DIR_SEC_COOKIE_FORMAT\"\n      case symbol_kind::S_CONFIG_SEC_COOKIEV0_SEPARATOR: // \"CONFIG_SEC_COOKIEV0_SEPARATOR\"\n      case symbol_kind::S_CONGIG_DIR_SEC_DATA_DIR: // \"CONGIG_DIR_SEC_DATA_DIR\"\n      case symbol_kind::S_CONGIG_DIR_SEC_STATUS_ENGINE: // \"CONGIG_DIR_SEC_STATUS_ENGINE\"\n      case symbol_kind::S_CONFIG_SEC_STREAM_IN_BODY_INSPECTION: // \"CONFIG_SEC_STREAM_IN_BODY_INSPECTION\"\n      case symbol_kind::S_CONFIG_SEC_STREAM_OUT_BODY_INSPECTION: // \"CONFIG_SEC_STREAM_OUT_BODY_INSPECTION\"\n      case symbol_kind::S_CONGIG_DIR_SEC_TMP_DIR: // \"CONGIG_DIR_SEC_TMP_DIR\"\n      case symbol_kind::S_DIRECTIVE: // \"DIRECTIVE\"\n      case symbol_kind::S_DIRECTIVE_SECRULESCRIPT: // \"DIRECTIVE_SECRULESCRIPT\"\n      case symbol_kind::S_FREE_TEXT_QUOTE_MACRO_EXPANSION: // \"FREE_TEXT_QUOTE_MACRO_EXPANSION\"\n      case symbol_kind::S_QUOTATION_MARK: // \"QUOTATION_MARK\"\n      case symbol_kind::S_RUN_TIME_VAR_BLD: // \"RUN_TIME_VAR_BLD\"\n      case symbol_kind::S_RUN_TIME_VAR_DUR: // \"RUN_TIME_VAR_DUR\"\n      case symbol_kind::S_RUN_TIME_VAR_HSV: // \"RUN_TIME_VAR_HSV\"\n      case symbol_kind::S_RUN_TIME_VAR_REMOTE_USER: // \"RUN_TIME_VAR_REMOTE_USER\"\n      case symbol_kind::S_RUN_TIME_VAR_TIME: // \"RUN_TIME_VAR_TIME\"\n      case symbol_kind::S_RUN_TIME_VAR_TIME_DAY: // \"RUN_TIME_VAR_TIME_DAY\"\n      case symbol_kind::S_RUN_TIME_VAR_TIME_EPOCH: // \"RUN_TIME_VAR_TIME_EPOCH\"\n      case symbol_kind::S_RUN_TIME_VAR_TIME_HOUR: // \"RUN_TIME_VAR_TIME_HOUR\"\n      case symbol_kind::S_RUN_TIME_VAR_TIME_MIN: // \"RUN_TIME_VAR_TIME_MIN\"\n      case symbol_kind::S_RUN_TIME_VAR_TIME_MON: // \"RUN_TIME_VAR_TIME_MON\"\n      case symbol_kind::S_RUN_TIME_VAR_TIME_SEC: // \"RUN_TIME_VAR_TIME_SEC\"\n      case symbol_kind::S_RUN_TIME_VAR_TIME_WDAY: // \"RUN_TIME_VAR_TIME_WDAY\"\n      case symbol_kind::S_RUN_TIME_VAR_TIME_YEAR: // \"RUN_TIME_VAR_TIME_YEAR\"\n      case symbol_kind::S_VARIABLE: // \"VARIABLE\"\n      case symbol_kind::S_DICT_ELEMENT: // \"Dictionary element\"\n      case symbol_kind::S_DICT_ELEMENT_WITH_EQUALS: // \"Dictionary element, with equals\"\n      case symbol_kind::S_DICT_ELEMENT_REGEXP: // \"Dictionary element, selected by regexp\"\n        value.move< std::string > (YY_MOVE (s.value));\n        break;\n\n      case symbol_kind::S_op: // op\n      case symbol_kind::S_op_before_init: // op_before_init\n        value.move< std::unique_ptr<Operator> > (YY_MOVE (s.value));\n        break;\n\n      case symbol_kind::S_run_time_string: // run_time_string\n        value.move< std::unique_ptr<RunTimeString> > (YY_MOVE (s.value));\n        break;\n\n      case symbol_kind::S_var: // var\n        value.move< std::unique_ptr<Variable> > (YY_MOVE (s.value));\n        break;\n\n      case symbol_kind::S_act: // act\n      case symbol_kind::S_setvar_action: // setvar_action\n        value.move< std::unique_ptr<actions::Action> > (YY_MOVE (s.value));\n        break;\n\n      case symbol_kind::S_variables: // variables\n      case symbol_kind::S_variables_pre_process: // variables_pre_process\n      case symbol_kind::S_variables_may_be_quoted: // variables_may_be_quoted\n        value.move< std::unique_ptr<std::vector<std::unique_ptr<Variable> > >  > (YY_MOVE (s.value));\n        break;\n\n      case symbol_kind::S_actions: // actions\n      case symbol_kind::S_actions_may_quoted: // actions_may_quoted\n        value.move< std::unique_ptr<std::vector<std::unique_ptr<actions::Action> > >  > (YY_MOVE (s.value));\n        break;\n\n      default:\n        break;\n    }\n\n    location = YY_MOVE (s.location);\n  }\n\n  // by_kind.\n  inline\n  seclang_parser::by_kind::by_kind () YY_NOEXCEPT\n    : kind_ (symbol_kind::S_YYEMPTY)\n  {}\n\n#if 201103L <= YY_CPLUSPLUS\n  inline\n  seclang_parser::by_kind::by_kind (by_kind&& that) YY_NOEXCEPT\n    : kind_ (that.kind_)\n  {\n    that.clear ();\n  }\n#endif\n\n  inline\n  seclang_parser::by_kind::by_kind (const by_kind& that) YY_NOEXCEPT\n    : kind_ (that.kind_)\n  {}\n\n  inline\n  seclang_parser::by_kind::by_kind (token_kind_type t) YY_NOEXCEPT\n    : kind_ (yytranslate_ (t))\n  {}\n\n\n\n  inline\n  void\n  seclang_parser::by_kind::clear () YY_NOEXCEPT\n  {\n    kind_ = symbol_kind::S_YYEMPTY;\n  }\n\n  inline\n  void\n  seclang_parser::by_kind::move (by_kind& that)\n  {\n    kind_ = that.kind_;\n    that.clear ();\n  }\n\n  inline\n  seclang_parser::symbol_kind_type\n  seclang_parser::by_kind::kind () const YY_NOEXCEPT\n  {\n    return kind_;\n  }\n\n\n  inline\n  seclang_parser::symbol_kind_type\n  seclang_parser::by_kind::type_get () const YY_NOEXCEPT\n  {\n    return this->kind ();\n  }\n\n\n} // yy\n#line 8891 \"seclang-parser.hh\"\n\n\n\n\n#endif // !YY_YY_SECLANG_PARSER_TAB_HH_INCLUDED\n"
  },
  {
    "path": "src/parser/seclang-parser.yy",
    "content": "%skeleton \"lalr1.cc\" /* -*- C++ -*- */\n%require \"3.0.2\"\n%defines\n%define parser_class_name {seclang_parser}\n%define api.token.constructor\n%define api.value.type variant\n//%define api.namespace {modsecurity::yy}\n%define parse.assert\n%code requires\n{\n#include <string>\n#include <iterator>\n\nnamespace ModSecurity {\nnamespace Parser {\nclass Driver;\n}\n}\n\n#include \"modsecurity/rule_unconditional.h\"\n#include \"src/rule_script.h\"\n\n#include \"src/actions/accuracy.h\"\n#include \"src/actions/audit_log.h\"\n#include \"src/actions/block.h\"\n#include \"src/actions/capture.h\"\n#include \"src/actions/chain.h\"\n#include \"src/actions/ctl/audit_engine.h\"\n#include \"src/actions/ctl/audit_log_parts.h\"\n#include \"src/actions/ctl/parse_xml_into_args.h\"\n#include \"src/actions/ctl/request_body_access.h\"\n#include \"src/actions/ctl/rule_engine.h\"\n#include \"src/actions/ctl/request_body_processor_json.h\"\n#include \"src/actions/ctl/request_body_processor_xml.h\"\n#include \"src/actions/ctl/request_body_processor_urlencoded.h\"\n#include \"src/actions/ctl/rule_remove_by_id.h\"\n#include \"src/actions/ctl/rule_remove_by_tag.h\"\n#include \"src/actions/ctl/rule_remove_target_by_id.h\"\n#include \"src/actions/ctl/rule_remove_target_by_tag.h\"\n#include \"src/actions/data/status.h\"\n#include \"src/actions/disruptive/allow.h\"\n#include \"src/actions/disruptive/deny.h\"\n#include \"src/actions/disruptive/drop.h\"\n#include \"src/actions/disruptive/pass.h\"\n#include \"src/actions/disruptive/redirect.h\"\n#include \"src/actions/init_col.h\"\n#include \"src/actions/exec.h\"\n#include \"src/actions/expire_var.h\"\n#include \"src/actions/log_data.h\"\n#include \"src/actions/log.h\"\n#include \"src/actions/maturity.h\"\n#include \"src/actions/msg.h\"\n#include \"src/actions/multi_match.h\"\n#include \"src/actions/no_audit_log.h\"\n#include \"src/actions/no_log.h\"\n#include \"src/actions/phase.h\"\n#include \"src/actions/rev.h\"\n#include \"src/actions/rule_id.h\"\n#include \"src/actions/set_env.h\"\n#include \"src/actions/set_rsc.h\"\n#include \"src/actions/set_sid.h\"\n#include \"src/actions/set_uid.h\"\n#include \"src/actions/set_var.h\"\n#include \"src/actions/severity.h\"\n#include \"src/actions/skip_after.h\"\n#include \"src/actions/skip.h\"\n#include \"src/actions/tag.h\"\n#include \"src/actions/ver.h\"\n#include \"src/actions/xmlns.h\"\n\n#include \"src/actions/transformations/none.h\"\n#include \"src/actions/transformations/transformation.h\"\n#include \"src/actions/transformations/url_decode_uni.h\"\n#include \"src/actions/transformations/hex_encode.h\"\n#include \"src/actions/transformations/parity_even_7bit.h\"\n#include \"src/actions/transformations/utf8_to_unicode.h\"\n#include \"src/actions/transformations/parity_zero_7bit.h\"\n#include \"src/actions/transformations/sql_hex_decode.h\"\n#include \"src/actions/transformations/replace_comments.h\"\n#include \"src/actions/transformations/none.h\"\n#include \"src/actions/transformations/url_decode.h\"\n#include \"src/actions/transformations/lower_case.h\"\n#include \"src/actions/transformations/upper_case.h\"\n#include \"src/actions/transformations/hex_decode.h\"\n#include \"src/actions/transformations/url_encode.h\"\n#include \"src/actions/transformations/js_decode.h\"\n#include \"src/actions/transformations/url_decode_uni.h\"\n#include \"src/actions/transformations/parity_odd_7bit.h\"\n#include \"src/actions/transformations/transformation.h\"\n#include \"src/actions/transformations/trim_right.h\"\n#include \"src/actions/transformations/escape_seq_decode.h\"\n#include \"src/actions/transformations/base64_decode_ext.h\"\n#include \"src/actions/transformations/base64_decode.h\"\n#include \"src/actions/transformations/trim.h\"\n#include \"src/actions/transformations/cmd_line.h\"\n#include \"src/actions/transformations/replace_nulls.h\"\n#include \"src/actions/transformations/md5.h\"\n#include \"src/actions/transformations/length.h\"\n#include \"src/actions/transformations/sha1.h\"\n#include \"src/actions/transformations/compress_whitespace.h\"\n#include \"src/actions/transformations/normalise_path_win.h\"\n#include \"src/actions/transformations/remove_nulls.h\"\n#include \"src/actions/transformations/remove_comments.h\"\n#include \"src/actions/transformations/normalise_path.h\"\n#include \"src/actions/transformations/html_entity_decode.h\"\n#include \"src/actions/transformations/trim_left.h\"\n#include \"src/actions/transformations/remove_comments_char.h\"\n#include \"src/actions/transformations/base64_encode.h\"\n#include \"src/actions/transformations/remove_whitespace.h\"\n#include \"src/actions/transformations/css_decode.h\"\n\n#include \"src/operators/begins_with.h\"\n#include \"src/operators/contains.h\"\n#include \"src/operators/contains_word.h\"\n#include \"src/operators/detect_sqli.h\"\n#include \"src/operators/detect_xss.h\"\n#include \"src/operators/ends_with.h\"\n#include \"src/operators/eq.h\"\n#include \"src/operators/fuzzy_hash.h\"\n#include \"src/operators/ge.h\"\n#include \"src/operators/geo_lookup.h\"\n#include \"src/operators/gsblookup.h\"\n#include \"src/operators/gt.h\"\n#include \"src/operators/inspect_file.h\"\n#include \"src/operators/ip_match_f.h\"\n#include \"src/operators/ip_match_from_file.h\"\n#include \"src/operators/ip_match.h\"\n#include \"src/operators/le.h\"\n#include \"src/operators/lt.h\"\n#include \"src/operators/no_match.h\"\n#include \"src/operators/operator.h\"\n#include \"src/operators/pm_f.h\"\n#include \"src/operators/pm_from_file.h\"\n#include \"src/operators/pm.h\"\n#include \"src/operators/rbl.h\"\n#include \"src/operators/rsub.h\"\n#include \"src/operators/rx.h\"\n#include \"src/operators/rx_global.h\"\n#include \"src/operators/str_eq.h\"\n#include \"src/operators/str_match.h\"\n#include \"src/operators/unconditional_match.h\"\n#include \"src/operators/validate_byte_range.h\"\n#include \"src/operators/validate_dtd.h\"\n#include \"src/operators/validate_hash.h\"\n#include \"src/operators/validate_schema.h\"\n#include \"src/operators/validate_url_encoding.h\"\n#include \"src/operators/validate_utf8_encoding.h\"\n#include \"src/operators/verify_cc.h\"\n#include \"src/operators/verify_cpf.h\"\n#include \"src/operators/verify_ssn.h\"\n#include \"src/operators/verify_svnr.h\"\n#include \"src/operators/within.h\"\n\n\n#include \"modsecurity/audit_log.h\"\n#include \"modsecurity/modsecurity.h\"\n#include \"modsecurity/rules_set_properties.h\"\n#include \"modsecurity/rule.h\"\n#include \"src/operators/operator.h\"\n#include \"src/utils/geo_lookup.h\"\n#include \"src/utils/string.h\"\n#include \"src/utils/system.h\"\n#include \"src/variables/args_combined_size.h\"\n#include \"src/variables/args_get.h\"\n#include \"src/variables/args_get_names.h\"\n#include \"src/variables/args.h\"\n#include \"src/variables/args_names.h\"\n#include \"src/variables/args_post.h\"\n#include \"src/variables/args_post_names.h\"\n#include \"src/variables/auth_type.h\"\n#include \"src/variables/duration.h\"\n#include \"src/variables/env.h\"\n#include \"src/variables/files_combined_size.h\"\n#include \"src/variables/files.h\"\n#include \"src/variables/files_names.h\"\n#include \"src/variables/files_sizes.h\"\n#include \"src/variables/files_tmp_content.h\"\n#include \"src/variables/files_tmp_names.h\"\n#include \"src/variables/full_request.h\"\n#include \"src/variables/full_request_length.h\"\n#include \"src/variables/geo.h\"\n#include \"src/variables/highest_severity.h\"\n#include \"src/variables/inbound_data_error.h\"\n#include \"src/variables/matched_var.h\"\n#include \"src/variables/matched_var_name.h\"\n#include \"src/variables/matched_vars.h\"\n#include \"src/variables/matched_vars_names.h\"\n#include \"src/variables/modsec_build.h\"\n#include \"src/variables/msc_pcre_error.h\"\n#include \"src/variables/msc_pcre_limits_exceeded.h\"\n#include \"src/variables/multipart_boundary_quoted.h\"\n#include \"src/variables/multipart_boundary_whitespace.h\"\n#include \"src/variables/multipart_crlf_lf_lines.h\"\n#include \"src/variables/multipart_data_after.h\"\n#include \"src/variables/multipart_data_before.h\"\n#include \"src/variables/multipart_file_limit_exceeded.h\"\n#include \"src/variables/multipart_file_name.h\"\n#include \"src/variables/multipart_header_folding.h\"\n#include \"src/variables/multipart_invalid_header_folding.h\"\n#include \"src/variables/multipart_invalid_part.h\"\n#include \"src/variables/multipart_invalid_quoting.h\"\n#include \"src/variables/multipart_lf_line.h\"\n#include \"src/variables/multipart_missing_semicolon.h\"\n#include \"src/variables/multipart_name.h\"\n#include \"src/variables/multipart_strict_error.h\"\n#include \"src/variables/multipart_unmatched_boundary.h\"\n#include \"src/variables/outbound_data_error.h\"\n#include \"src/variables/path_info.h\"\n#include \"src/variables/query_string.h\"\n#include \"src/variables/remote_addr.h\"\n#include \"src/variables/remote_host.h\"\n#include \"src/variables/remote_port.h\"\n#include \"src/variables/remote_user.h\"\n#include \"src/variables/reqbody_error.h\"\n#include \"src/variables/reqbody_error_msg.h\"\n#include \"src/variables/reqbody_processor_error.h\"\n#include \"src/variables/reqbody_processor_error_msg.h\"\n#include \"src/variables/reqbody_processor.h\"\n#include \"src/variables/request_base_name.h\"\n#include \"src/variables/request_body.h\"\n#include \"src/variables/request_body_length.h\"\n#include \"src/variables/request_cookies.h\"\n#include \"src/variables/request_cookies_names.h\"\n#include \"src/variables/multipart_part_headers.h\"\n#include \"src/variables/request_file_name.h\"\n#include \"src/variables/request_headers.h\"\n#include \"src/variables/request_headers_names.h\"\n#include \"src/variables/request_line.h\"\n#include \"src/variables/request_method.h\"\n#include \"src/variables/request_protocol.h\"\n#include \"src/variables/request_uri.h\"\n#include \"src/variables/request_uri_raw.h\"\n#include \"src/variables/resource.h\"\n#include \"src/variables/response_body.h\"\n#include \"src/variables/response_content_length.h\"\n#include \"src/variables/response_content_type.h\"\n#include \"src/variables/response_headers.h\"\n#include \"src/variables/response_headers_names.h\"\n#include \"src/variables/response_protocol.h\"\n#include \"src/variables/response_status.h\"\n#include \"src/variables/rule.h\"\n#include \"src/variables/server_addr.h\"\n#include \"src/variables/server_name.h\"\n#include \"src/variables/server_port.h\"\n#include \"src/variables/session_id.h\"\n#include \"src/variables/web_app_id.h\"\n#include \"src/variables/time_day.h\"\n#include \"src/variables/time_epoch.h\"\n#include \"src/variables/time.h\"\n#include \"src/variables/time_hour.h\"\n#include \"src/variables/time_min.h\"\n#include \"src/variables/time_mon.h\"\n#include \"src/variables/time_sec.h\"\n#include \"src/variables/time_wday.h\"\n#include \"src/variables/time_year.h\"\n#include \"src/variables/tx.h\"\n#include \"src/variables/unique_id.h\"\n#include \"src/variables/url_encoded_error.h\"\n#include \"src/variables/user.h\"\n#include \"src/variables/user_id.h\"\n#include \"src/variables/variable.h\"\n#include \"src/variables/xml.h\"\n#include \"src/variables/ip.h\"\n#include \"src/variables/global.h\"\n#include \"src/variables/session.h\"\n#include \"src/variables/status.h\"\n\nusing namespace modsecurity;\nusing namespace modsecurity::variables;\nusing namespace modsecurity::Utils;\nusing namespace modsecurity::operators;\n\n\n#define CHECK_VARIATION_DECL \\\n    Variable *var = NULL; \\\n    bool t = false;\n\n#define CHECK_VARIATION(a) \\\n    if (var == NULL) { \\\n        if (name.at(0) == std::string(#a).at(0)) { \\\n            name.erase(0, 1); \\\n            t = true ; \\\n        } \\\n    } else { \\\n        t = false; \\\n    } \\\n    if (t)\n\n\n#define ACTION_NOT_SUPPORTED(a, b) \\\n    driver.error(b, \"Action: \" + std::string(a) + \" is not yet supported.\"); \\\n    YYERROR;\n\n\n#define OPERATOR_NOT_SUPPORTED(a, b) \\\n    driver.error(b, \"Operator: \" + std::string(a) + \" is not yet supported.\"); \\\n    YYERROR;\n\n\n#define ACTION_INIT(a, b) \\\n    std::string error; \\\n    if (a->init(&error) == false) { \\\n        driver.error(b, error); \\\n        YYERROR; \\\n    }\n\n#define OPERATOR_CONTAINER(a, b) \\\n    std::unique_ptr<Operator> c(b); \\\n    a = std::move(c);\n\n#define ACTION_CONTAINER(a, b) \\\n    std::unique_ptr<actions::Action> c(b); \\\n    a = std::move(c);\n\n#define VARIABLE_CONTAINER(a, b) \\\n    std::unique_ptr<Variable> c(b); \\\n    a = std::move(c);\n\n}\n// The parsing context.\n%param { modsecurity::Parser::Driver& driver }\n%locations\n%initial-action\n{\n  // Initialize the initial location.\n  driver.m_filenames.push_back(driver.file);\n  @$.begin.filename = @$.end.filename = &(driver.m_filenames.back());\n};\n%define parse.trace\n%define parse.error verbose\n%code\n{\n#include \"src/parser/driver.h\"\n}\n%define api.token.prefix {TOK_}\n%token\n  END  0  \"end of file\"\n  COMMA    \",\"\n  CONFIG_CONTENT_INJECTION                     \"CONFIG_CONTENT_INJECTION\"\n  CONGIG_DIR_RESPONSE_BODY_MP_CLEAR            \"CONGIG_DIR_RESPONSE_BODY_MP_CLEAR\"\n  PIPE\n  NEW_LINE\n  VAR_COUNT\n  VAR_EXCLUSION\n  VARIABLE_ARGS\n  VARIABLE_ARGS_POST\n  VARIABLE_ARGS_GET\n  VARIABLE_FILES_SIZES\n  VARIABLE_FILES_NAMES\n  VARIABLE_FILES_TMP_CONTENT\n  VARIABLE_MULTIPART_FILENAME\n  VARIABLE_MULTIPART_NAME\n  VARIABLE_MATCHED_VARS_NAMES\n  VARIABLE_MATCHED_VARS\n  VARIABLE_FILES\n  VARIABLE_REQUEST_COOKIES\n  VARIABLE_REQUEST_HEADERS\n  VARIABLE_RESPONSE_HEADERS\n  VARIABLE_GEO\n  VARIABLE_REQUEST_COOKIES_NAMES\n  VARIABLE_MULTIPART_PART_HEADERS\n  VARIABLE_ARGS_COMBINED_SIZE\n  VARIABLE_ARGS_GET_NAMES\n  VARIABLE_RULE\n  VARIABLE_ARGS_NAMES           \"Variable ARGS_NAMES\"\n  VARIABLE_ARGS_POST_NAMES\n  VARIABLE_AUTH_TYPE            \"AUTH_TYPE\"\n  VARIABLE_FILES_COMBINED_SIZE  \"FILES_COMBINED_SIZE\"\n  VARIABLE_FILES_TMP_NAMES       \"FILES_TMPNAMES\"\n  VARIABLE_FULL_REQUEST         \"FULL_REQUEST\"\n  VARIABLE_FULL_REQUEST_LENGTH  \"FULL_REQUEST_LENGTH\"\n  VARIABLE_INBOUND_DATA_ERROR   \"INBOUND_DATA_ERROR\"\n  VARIABLE_MATCHED_VAR          \"MATCHED_VAR\"\n  VARIABLE_MATCHED_VAR_NAME     \"MATCHED_VAR_NAME\"\n  VARIABLE_MSC_PCRE_ERROR           \"MSC_PCRE_ERROR\"\n  VARIABLE_MSC_PCRE_LIMITS_EXCEEDED \"MSC_PCRE_LIMITS_EXCEEDED\"\n  VARIABLE_MULTIPART_BOUNDARY_QUOTED\n  VARIABLE_MULTIPART_BOUNDARY_WHITESPACE\n  VARIABLE_MULTIPART_CRLF_LF_LINES    \"MULTIPART_CRLF_LF_LINES\"\n  VARIABLE_MULTIPART_DATA_AFTER \"MULTIPART_DATA_AFTER\"\n  VARIABLE_MULTIPART_DATA_BEFORE\n  VARIABLE_MULTIPART_FILE_LIMIT_EXCEEDED       \"MULTIPART_FILE_LIMIT_EXCEEDED\"\n  VARIABLE_MULTIPART_HEADER_FOLDING            \"MULTIPART_HEADER_FOLDING\"\n  VARIABLE_MULTIPART_INVALID_HEADER_FOLDING    \"MULTIPART_INVALID_HEADER_FOLDING\"\n  VARIABLE_MULTIPART_INVALID_PART\n  VARIABLE_MULTIPART_INVALID_QUOTING           \"MULTIPART_INVALID_QUOTING\"\n  VARIABLE_MULTIPART_LF_LINE\n  VARIABLE_MULTIPART_MISSING_SEMICOLON\n  VARIABLE_MULTIPART_SEMICOLON_MISSING\n  VARIABLE_MULTIPART_STRICT_ERROR              \"MULTIPART_STRICT_ERROR\"\n  VARIABLE_MULTIPART_UNMATCHED_BOUNDARY        \"MULTIPART_UNMATCHED_BOUNDARY\"\n  VARIABLE_OUTBOUND_DATA_ERROR  \"OUTBOUND_DATA_ERROR\"\n  VARIABLE_PATH_INFO            \"PATH_INFO\"\n  VARIABLE_QUERY_STRING         \"QUERY_STRING\"\n  VARIABLE_REMOTE_ADDR          \"REMOTE_ADDR\"\n  VARIABLE_REMOTE_HOST          \"REMOTE_HOST\"\n  VARIABLE_REMOTE_PORT          \"REMOTE_PORT\"\n  VARIABLE_REQBODY_ERROR_MSG    \"REQBODY_ERROR_MSG\"\n  VARIABLE_REQBODY_ERROR        \"REQBODY_ERROR\"\n  VARIABLE_REQBODY_PROCESSOR_ERROR_MSG    \"REQBODY_PROCESSOR_ERROR_MSG\"\n  VARIABLE_REQBODY_PROCESSOR_ERROR        \"REQBODY_PROCESSOR_ERROR\"\n  VARIABLE_REQBODY_PROCESSOR    \"REQBODY_PROCESSOR\"\n  VARIABLE_REQUEST_BASENAME     \"REQUEST_BASENAME\"\n  VARIABLE_REQUEST_BODY_LENGTH  \"REQUEST_BODY_LENGTH\"\n  VARIABLE_REQUEST_BODY         \"REQUEST_BODY\"\n  VARIABLE_REQUEST_FILE_NAME     \"REQUEST_FILENAME\"\n  VARIABLE_REQUEST_HEADERS_NAMES\n  VARIABLE_REQUEST_LINE         \"REQUEST_LINE\"\n  VARIABLE_REQUEST_METHOD       \"REQUEST_METHOD\"\n  VARIABLE_REQUEST_PROTOCOL     \"REQUEST_PROTOCOL\"\n  VARIABLE_REQUEST_URI_RAW      \"REQUEST_URI_RAW\"\n  VARIABLE_REQUEST_URI          \"REQUEST_URI\"\n  VARIABLE_RESOURCE             \"RESOURCE\"\n  VARIABLE_RESPONSE_BODY        \"RESPONSE_BODY\"\n  VARIABLE_RESPONSE_CONTENT_LENGTH    \"RESPONSE_CONTENT_LENGTH\"\n  VARIABLE_RESPONSE_CONTENT_TYPE\n  VARIABLE_RESPONSE_HEADERS_NAMES\n  VARIABLE_RESPONSE_PROTOCOL    \"RESPONSE_PROTOCOL\"\n  VARIABLE_RESPONSE_STATUS      \"RESPONSE_STATUS\"\n  VARIABLE_SERVER_ADDR          \"SERVER_ADDR\"\n  VARIABLE_SERVER_NAME          \"SERVER_NAME\"\n  VARIABLE_SERVER_PORT          \"SERVER_PORT\"\n  VARIABLE_SESSION_ID           \"SESSIONID\"\n  VARIABLE_UNIQUE_ID            \"UNIQUE_ID\"\n  VARIABLE_URL_ENCODED_ERROR    \"URLENCODED_ERROR\"\n  VARIABLE_USER_ID               \"USERID\"\n  VARIABLE_WEB_APP_ID           \"WEBAPPID\"\n\n\n  VARIABLE_STATUS                              \"VARIABLE_STATUS\"\n  VARIABLE_STATUS_LINE                         \"VARIABLE_STATUS_LINE\"\n  VARIABLE_IP                                  \"VARIABLE_IP\"\n  VARIABLE_GLOBAL                              \"VARIABLE_GLOBAL\"\n  VARIABLE_TX                                  \"VARIABLE_TX\"\n  VARIABLE_SESSION                             \"VARIABLE_SESSION\"\n  VARIABLE_USER                                \"VARIABLE_USER\"\n  RUN_TIME_VAR_ENV                             \"RUN_TIME_VAR_ENV\"\n  RUN_TIME_VAR_XML                             \"RUN_TIME_VAR_XML\"\n\n  ACTION_SETVAR                                \"SetVar\"\n  SETVAR_OPERATION_EQUALS\n  SETVAR_OPERATION_EQUALS_PLUS\n  SETVAR_OPERATION_EQUALS_MINUS\n  NOT                                          \"NOT\"\n\n  OPERATOR_BEGINS_WITH                         \"OPERATOR_BEGINS_WITH\"\n  OPERATOR_CONTAINS                            \"OPERATOR_CONTAINS\"\n  OPERATOR_CONTAINS_WORD                       \"OPERATOR_CONTAINS_WORD\"\n  OPERATOR_DETECT_SQLI                         \"OPERATOR_DETECT_SQLI\"\n  OPERATOR_DETECT_XSS                          \"OPERATOR_DETECT_XSS\"\n  OPERATOR_ENDS_WITH                           \"OPERATOR_ENDS_WITH\"\n  OPERATOR_EQ                                  \"OPERATOR_EQ\"\n  OPERATOR_FUZZY_HASH                          \"OPERATOR_FUZZY_HASH\"\n  OPERATOR_GEOLOOKUP                           \"OPERATOR_GEOLOOKUP\"\n  OPERATOR_GE                                  \"OPERATOR_GE\"\n  OPERATOR_GSB_LOOKUP                          \"OPERATOR_GSB_LOOKUP\"\n  OPERATOR_GT                                  \"OPERATOR_GT\"\n  OPERATOR_INSPECT_FILE                        \"OPERATOR_INSPECT_FILE\"\n  OPERATOR_IP_MATCH_FROM_FILE                  \"OPERATOR_IP_MATCH_FROM_FILE\"\n  OPERATOR_IP_MATCH                            \"OPERATOR_IP_MATCH\"\n  OPERATOR_LE                                  \"OPERATOR_LE\"\n  OPERATOR_LT                                  \"OPERATOR_LT\"\n  OPERATOR_PM_FROM_FILE                        \"OPERATOR_PM_FROM_FILE\"\n  OPERATOR_PM                                  \"OPERATOR_PM\"\n  OPERATOR_RBL                                 \"OPERATOR_RBL\"\n  OPERATOR_RSUB                                \"OPERATOR_RSUB\"\n  OPERATOR_RX_CONTENT_ONLY                     \"Operator RX (content only)\"\n  OPERATOR_RX                                  \"OPERATOR_RX\"\n  OPERATOR_RX_GLOBAL                           \"OPERATOR_RX_GLOBAL\"\n  OPERATOR_STR_EQ                              \"OPERATOR_STR_EQ\"\n  OPERATOR_STR_MATCH                           \"OPERATOR_STR_MATCH\"\n  OPERATOR_UNCONDITIONAL_MATCH                 \"OPERATOR_UNCONDITIONAL_MATCH\"\n  OPERATOR_VALIDATE_BYTE_RANGE                 \"OPERATOR_VALIDATE_BYTE_RANGE\"\n  OPERATOR_VALIDATE_DTD                        \"OPERATOR_VALIDATE_DTD\"\n  OPERATOR_VALIDATE_HASH                       \"OPERATOR_VALIDATE_HASH\"\n  OPERATOR_VALIDATE_SCHEMA                     \"OPERATOR_VALIDATE_SCHEMA\"\n  OPERATOR_VALIDATE_URL_ENCODING               \"OPERATOR_VALIDATE_URL_ENCODING\"\n  OPERATOR_VALIDATE_UTF8_ENCODING              \"OPERATOR_VALIDATE_UTF8_ENCODING\"\n  OPERATOR_VERIFY_CC                           \"OPERATOR_VERIFY_CC\"\n  OPERATOR_VERIFY_CPF                          \"OPERATOR_VERIFY_CPF\"\n  OPERATOR_VERIFY_SSN                          \"OPERATOR_VERIFY_SSN\"\n  OPERATOR_VERIFY_SVNR                         \"OPERATOR_VERIFY_SVNR\"\n  OPERATOR_WITHIN                              \"OPERATOR_WITHIN\"\n\n  CONFIG_DIR_AUDIT_LOG_FMT\n  JSON\n  NATIVE\n\n  ACTION_CTL_RULE_ENGINE                       \"ACTION_CTL_RULE_ENGINE\"\n;\n\n%token <std::string>\n  ACTION_ACCURACY                              \"Accuracy\"\n  ACTION_ALLOW                                 \"Allow\"\n  ACTION_APPEND                                \"Append\"\n  ACTION_AUDIT_LOG                             \"AuditLog\"\n  ACTION_BLOCK                                 \"Block\"\n  ACTION_CAPTURE                               \"Capture\"\n  ACTION_CHAIN                                 \"Chain\"\n  ACTION_CTL_AUDIT_ENGINE                      \"ACTION_CTL_AUDIT_ENGINE\"\n  ACTION_CTL_AUDIT_LOG_PARTS                   \"ACTION_CTL_AUDIT_LOG_PARTS\"\n  ACTION_CTL_BDY_JSON                          \"ACTION_CTL_BDY_JSON\"\n  ACTION_CTL_BDY_XML                           \"ACTION_CTL_BDY_XML\"\n  ACTION_CTL_BDY_URLENCODED                    \"ACTION_CTL_BDY_URLENCODED\"\n  ACTION_CTL_FORCE_REQ_BODY_VAR                \"ACTION_CTL_FORCE_REQ_BODY_VAR\"\n  ACTION_CTL_PARSE_XML_INTO_ARGS               \"ACTION_CTL_PARSE_XML_INTO_ARGS\"\n  ACTION_CTL_REQUEST_BODY_ACCESS               \"ACTION_CTL_REQUEST_BODY_ACCESS\"\n  ACTION_CTL_RULE_REMOVE_BY_ID                 \"ACTION_CTL_RULE_REMOVE_BY_ID\"\n  ACTION_CTL_RULE_REMOVE_BY_TAG                \"ACTION_CTL_RULE_REMOVE_BY_TAG\"\n  ACTION_CTL_RULE_REMOVE_TARGET_BY_ID          \"ACTION_CTL_RULE_REMOVE_TARGET_BY_ID\"\n  ACTION_CTL_RULE_REMOVE_TARGET_BY_TAG         \"ACTION_CTL_RULE_REMOVE_TARGET_BY_TAG\"\n  ACTION_DENY                                  \"Deny\"\n  ACTION_DEPRECATE_VAR                         \"DeprecateVar\"\n  ACTION_DROP                                  \"Drop\"\n  ACTION_EXEC                                  \"Exec\"\n  ACTION_EXPIRE_VAR                            \"ExpireVar\"\n  ACTION_ID                                    \"Id\"\n  ACTION_INITCOL                               \"InitCol\"\n  ACTION_LOG                                   \"Log\"\n  ACTION_LOG_DATA                              \"LogData\"\n  ACTION_MATURITY                              \"Maturity\"\n  ACTION_MSG                                   \"Msg\"\n  ACTION_MULTI_MATCH                           \"MultiMatch\"\n  ACTION_NO_AUDIT_LOG                          \"NoAuditLog\"\n  ACTION_NO_LOG                                \"NoLog\"\n  ACTION_PASS                                  \"Pass\"\n  ACTION_PAUSE                                 \"Pause\"\n  ACTION_PHASE                                 \"Phase\"\n  ACTION_PREPEND                               \"Prepend\"\n  ACTION_PROXY                                 \"Proxy\"\n  ACTION_REDIRECT                              \"Redirect\"\n  ACTION_REV                                   \"Rev\"\n  ACTION_SANITISE_ARG                          \"SanitiseArg\"\n  ACTION_SANITISE_MATCHED                      \"SanitiseMatched\"\n  ACTION_SANITISE_MATCHED_BYTES                \"SanitiseMatchedBytes\"\n  ACTION_SANITISE_REQUEST_HEADER               \"SanitiseRequestHeader\"\n  ACTION_SANITISE_RESPONSE_HEADER              \"SanitiseResponseHeader\"\n  ACTION_SETENV                                \"SetEnv\"\n  ACTION_SETRSC                                \"SetRsc\"\n  ACTION_SETSID                                \"SetSid\"\n  ACTION_SETUID                                \"SetUID\"\n  ACTION_SEVERITY                              \"Severity\"\n  ACTION_SKIP                                  \"Skip\"\n  ACTION_SKIP_AFTER                            \"SkipAfter\"\n  ACTION_STATUS                                \"Status\"\n  ACTION_TAG                                   \"Tag\"\n  ACTION_TRANSFORMATION_BASE_64_ENCODE         \"ACTION_TRANSFORMATION_BASE_64_ENCODE\"\n  ACTION_TRANSFORMATION_BASE_64_DECODE         \"ACTION_TRANSFORMATION_BASE_64_DECODE\"\n  ACTION_TRANSFORMATION_BASE_64_DECODE_EXT     \"ACTION_TRANSFORMATION_BASE_64_DECODE_EXT\"\n  ACTION_TRANSFORMATION_CMD_LINE               \"ACTION_TRANSFORMATION_CMD_LINE\"\n  ACTION_TRANSFORMATION_COMPRESS_WHITESPACE    \"ACTION_TRANSFORMATION_COMPRESS_WHITESPACE\"\n  ACTION_TRANSFORMATION_CSS_DECODE             \"ACTION_TRANSFORMATION_CSS_DECODE\"\n  ACTION_TRANSFORMATION_ESCAPE_SEQ_DECODE      \"ACTION_TRANSFORMATION_ESCAPE_SEQ_DECODE\"\n  ACTION_TRANSFORMATION_HEX_ENCODE             \"ACTION_TRANSFORMATION_HEX_ENCODE\"\n  ACTION_TRANSFORMATION_HEX_DECODE             \"ACTION_TRANSFORMATION_HEX_DECODE\"\n  ACTION_TRANSFORMATION_HTML_ENTITY_DECODE     \"ACTION_TRANSFORMATION_HTML_ENTITY_DECODE\"\n  ACTION_TRANSFORMATION_JS_DECODE              \"ACTION_TRANSFORMATION_JS_DECODE\"\n  ACTION_TRANSFORMATION_LENGTH                 \"ACTION_TRANSFORMATION_LENGTH\"\n  ACTION_TRANSFORMATION_LOWERCASE              \"ACTION_TRANSFORMATION_LOWERCASE\"\n  ACTION_TRANSFORMATION_MD5                    \"ACTION_TRANSFORMATION_MD5\"\n  ACTION_TRANSFORMATION_NONE                   \"ACTION_TRANSFORMATION_NONE\"\n  ACTION_TRANSFORMATION_NORMALISE_PATH         \"ACTION_TRANSFORMATION_NORMALISE_PATH\"\n  ACTION_TRANSFORMATION_NORMALISE_PATH_WIN     \"ACTION_TRANSFORMATION_NORMALISE_PATH_WIN\"\n  ACTION_TRANSFORMATION_PARITY_EVEN_7_BIT      \"ACTION_TRANSFORMATION_PARITY_EVEN_7_BIT\"\n  ACTION_TRANSFORMATION_PARITY_ODD_7_BIT       \"ACTION_TRANSFORMATION_PARITY_ODD_7_BIT\"\n  ACTION_TRANSFORMATION_PARITY_ZERO_7_BIT      \"ACTION_TRANSFORMATION_PARITY_ZERO_7_BIT\"\n  ACTION_TRANSFORMATION_REMOVE_COMMENTS        \"ACTION_TRANSFORMATION_REMOVE_COMMENTS\"\n  ACTION_TRANSFORMATION_REMOVE_COMMENTS_CHAR   \"ACTION_TRANSFORMATION_REMOVE_COMMENTS_CHAR\"\n  ACTION_TRANSFORMATION_REMOVE_NULLS           \"ACTION_TRANSFORMATION_REMOVE_NULLS\"\n  ACTION_TRANSFORMATION_REMOVE_WHITESPACE      \"ACTION_TRANSFORMATION_REMOVE_WHITESPACE\"\n  ACTION_TRANSFORMATION_REPLACE_COMMENTS       \"ACTION_TRANSFORMATION_REPLACE_COMMENTS\"\n  ACTION_TRANSFORMATION_REPLACE_NULLS          \"ACTION_TRANSFORMATION_REPLACE_NULLS\"\n  ACTION_TRANSFORMATION_SHA1                   \"ACTION_TRANSFORMATION_SHA1\"\n  ACTION_TRANSFORMATION_SQL_HEX_DECODE         \"ACTION_TRANSFORMATION_SQL_HEX_DECODE\"\n  ACTION_TRANSFORMATION_TRIM                   \"ACTION_TRANSFORMATION_TRIM\"\n  ACTION_TRANSFORMATION_TRIM_LEFT              \"ACTION_TRANSFORMATION_TRIM_LEFT\"\n  ACTION_TRANSFORMATION_TRIM_RIGHT             \"ACTION_TRANSFORMATION_TRIM_RIGHT\"\n  ACTION_TRANSFORMATION_UPPERCASE              \"ACTION_TRANSFORMATION_UPPERCASE\"\n  ACTION_TRANSFORMATION_URL_ENCODE             \"ACTION_TRANSFORMATION_URL_ENCODE\"\n  ACTION_TRANSFORMATION_URL_DECODE             \"ACTION_TRANSFORMATION_URL_DECODE\"\n  ACTION_TRANSFORMATION_URL_DECODE_UNI         \"ACTION_TRANSFORMATION_URL_DECODE_UNI\"\n  ACTION_TRANSFORMATION_UTF8_TO_UNICODE        \"ACTION_TRANSFORMATION_UTF8_TO_UNICODE\"\n  ACTION_VER                                   \"Ver\"\n  ACTION_XMLNS                                 \"xmlns\"\n  CONFIG_COMPONENT_SIG                         \"CONFIG_COMPONENT_SIG\"\n  CONFIG_CONN_ENGINE                           \"CONFIG_CONN_ENGINE\"\n  CONFIG_SEC_ARGUMENT_SEPARATOR                \"CONFIG_SEC_ARGUMENT_SEPARATOR\"\n  CONFIG_SEC_WEB_APP_ID                        \"CONFIG_SEC_WEB_APP_ID\"\n  CONFIG_SEC_SERVER_SIG                        \"CONFIG_SEC_SERVER_SIG\"\n  CONFIG_DIR_AUDIT_DIR                         \"CONFIG_DIR_AUDIT_DIR\"\n  CONFIG_DIR_AUDIT_DIR_MOD                     \"CONFIG_DIR_AUDIT_DIR_MOD\"\n  CONFIG_DIR_AUDIT_ENG                         \"CONFIG_DIR_AUDIT_ENG\"\n  CONFIG_DIR_AUDIT_FLE_MOD                     \"CONFIG_DIR_AUDIT_FLE_MOD\"\n  CONFIG_DIR_AUDIT_LOG                         \"CONFIG_DIR_AUDIT_LOG\"\n  CONFIG_DIR_AUDIT_LOG2                        \"CONFIG_DIR_AUDIT_LOG2\"\n  CONFIG_DIR_AUDIT_LOG_P                       \"CONFIG_DIR_AUDIT_LOG_P\"\n  CONFIG_DIR_AUDIT_STS                         \"CONFIG_DIR_AUDIT_STS\"\n  CONFIG_DIR_AUDIT_PREFIX                      \"CONFIG_DIR_AUDIT_PREFIX\"\n  CONFIG_DIR_AUDIT_TPE                         \"CONFIG_DIR_AUDIT_TPE\"\n  CONFIG_DIR_DEBUG_LOG                         \"CONFIG_DIR_DEBUG_LOG\"\n  CONFIG_DIR_DEBUG_LVL                         \"CONFIG_DIR_DEBUG_LVL\"\n  CONFIG_SEC_CACHE_TRANSFORMATIONS             \"CONFIG_SEC_CACHE_TRANSFORMATIONS\"\n  CONFIG_SEC_DISABLE_BACKEND_COMPRESS          \"CONFIG_SEC_DISABLE_BACKEND_COMPRESS\"\n  CONFIG_SEC_HASH_ENGINE                       \"CONFIG_SEC_HASH_ENGINE\"\n  CONFIG_SEC_HASH_KEY                          \"CONFIG_SEC_HASH_KEY\"\n  CONFIG_SEC_HASH_PARAM                        \"CONFIG_SEC_HASH_PARAM\"\n  CONFIG_SEC_HASH_METHOD_RX                    \"CONFIG_SEC_HASH_METHOD_RX\"\n  CONFIG_SEC_HASH_METHOD_PM                    \"CONFIG_SEC_HASH_METHOD_PM\"\n  CONFIG_SEC_CHROOT_DIR                        \"CONFIG_SEC_CHROOT_DIR\"\n  CONFIG_DIR_GEO_DB                            \"CONFIG_DIR_GEO_DB\"\n  CONFIG_DIR_GSB_DB                            \"CONFIG_DIR_GSB_DB\"\n  CONFIG_SEC_GUARDIAN_LOG                      \"CONFIG_SEC_GUARDIAN_LOG\"\n  CONFIG_DIR_PCRE_MATCH_LIMIT                  \"CONFIG_DIR_PCRE_MATCH_LIMIT\"\n  CONFIG_DIR_PCRE_MATCH_LIMIT_RECURSION        \"CONFIG_DIR_PCRE_MATCH_LIMIT_RECURSION\"\n  CONFIG_SEC_CONN_R_STATE_LIMIT                \"CONFIG_SEC_CONN_R_STATE_LIMIT\"\n  CONFIG_SEC_CONN_W_STATE_LIMIT                \"CONFIG_SEC_CONN_W_STATE_LIMIT\"\n  CONFIG_SEC_SENSOR_ID                         \"CONFIG_SEC_SENSOR_ID\"\n  CONFIG_DIR_ARGS_LIMIT                        \"CONFIG_DIR_ARGS_LIMIT\"\n  CONFIG_DIR_REQ_BODY_JSON_DEPTH_LIMIT         \"CONFIG_DIR_REQ_BODY_JSON_DEPTH_LIMIT\"\n  CONFIG_DIR_REQ_BODY                          \"CONFIG_DIR_REQ_BODY\"\n  CONFIG_DIR_REQ_BODY_IN_MEMORY_LIMIT          \"CONFIG_DIR_REQ_BODY_IN_MEMORY_LIMIT\"\n  CONFIG_DIR_REQ_BODY_LIMIT                    \"CONFIG_DIR_REQ_BODY_LIMIT\"\n  CONFIG_DIR_REQ_BODY_LIMIT_ACTION             \"CONFIG_DIR_REQ_BODY_LIMIT_ACTION\"\n  CONFIG_DIR_REQ_BODY_NO_FILES_LIMIT           \"CONFIG_DIR_REQ_BODY_NO_FILES_LIMIT\"\n  CONFIG_DIR_RES_BODY                          \"CONFIG_DIR_RES_BODY\"\n  CONFIG_DIR_RES_BODY_LIMIT                    \"CONFIG_DIR_RES_BODY_LIMIT\"\n  CONFIG_DIR_RES_BODY_LIMIT_ACTION             \"CONFIG_DIR_RES_BODY_LIMIT_ACTION\"\n  CONFIG_SEC_RULE_INHERITANCE                  \"CONFIG_SEC_RULE_INHERITANCE\"\n  CONFIG_SEC_RULE_PERF_TIME                    \"CONFIG_SEC_RULE_PERF_TIME\"\n  CONFIG_DIR_RULE_ENG                          \"CONFIG_DIR_RULE_ENG\"\n  CONFIG_DIR_SEC_ACTION                        \"CONFIG_DIR_SEC_ACTION\"\n  CONFIG_DIR_SEC_DEFAULT_ACTION                \"CONFIG_DIR_SEC_DEFAULT_ACTION\"\n  CONFIG_DIR_SEC_MARKER                        \"CONFIG_DIR_SEC_MARKER\"\n  CONFIG_DIR_UNICODE_MAP_FILE                  \"CONFIG_DIR_UNICODE_MAP_FILE\"\n  CONFIG_DIR_UNICODE_CODE_PAGE                 \"CONFIG_DIR_UNICODE_CODE_PAGE\"\n  CONFIG_SEC_COLLECTION_TIMEOUT                \"CONFIG_SEC_COLLECTION_TIMEOUT\"\n  CONFIG_SEC_HTTP_BLKEY                        \"CONFIG_SEC_HTTP_BLKEY\"\n  CONFIG_SEC_INTERCEPT_ON_ERROR                \"CONFIG_SEC_INTERCEPT_ON_ERROR\"\n  CONFIG_SEC_REMOTE_RULES_FAIL_ACTION          \"CONFIG_SEC_REMOTE_RULES_FAIL_ACTION\"\n  CONFIG_SEC_RULE_REMOVE_BY_ID                 \"CONFIG_SEC_RULE_REMOVE_BY_ID\"\n  CONFIG_SEC_RULE_REMOVE_BY_MSG                \"CONFIG_SEC_RULE_REMOVE_BY_MSG\"\n  CONFIG_SEC_RULE_REMOVE_BY_TAG                \"CONFIG_SEC_RULE_REMOVE_BY_TAG\"\n  CONFIG_SEC_RULE_UPDATE_TARGET_BY_TAG         \"CONFIG_SEC_RULE_UPDATE_TARGET_BY_TAG\"\n  CONFIG_SEC_RULE_UPDATE_TARGET_BY_MSG         \"CONFIG_SEC_RULE_UPDATE_TARGET_BY_MSG\"\n  CONFIG_SEC_RULE_UPDATE_TARGET_BY_ID          \"CONFIG_SEC_RULE_UPDATE_TARGET_BY_ID\"\n  CONFIG_SEC_RULE_UPDATE_ACTION_BY_ID          \"CONFIG_SEC_RULE_UPDATE_ACTION_BY_ID\"\n  CONFIG_UPDLOAD_KEEP_FILES                    \"CONFIG_UPDLOAD_KEEP_FILES\"\n  CONFIG_UPDLOAD_SAVE_TMP_FILES                \"CONFIG_UPDLOAD_SAVE_TMP_FILES\"\n  CONFIG_UPLOAD_DIR                            \"CONFIG_UPLOAD_DIR\"\n  CONFIG_UPLOAD_FILE_LIMIT                     \"CONFIG_UPLOAD_FILE_LIMIT\"\n  CONFIG_UPLOAD_FILE_MODE                      \"CONFIG_UPLOAD_FILE_MODE\"\n  CONFIG_VALUE_ABORT                           \"CONFIG_VALUE_ABORT\"\n  CONFIG_VALUE_DETC                            \"CONFIG_VALUE_DETC\"\n  CONFIG_VALUE_HTTPS                           \"CONFIG_VALUE_HTTPS\"\n  CONFIG_VALUE_ONLYARGS                        \"CONFIG_VALUE_ONLYARGS\"\n  CONFIG_VALUE_OFF                             \"CONFIG_VALUE_OFF\"\n  CONFIG_VALUE_ON                              \"CONFIG_VALUE_ON\"\n  CONFIG_VALUE_PARALLEL                        \"CONFIG_VALUE_PARALLEL\"\n  CONFIG_VALUE_PROCESS_PARTIAL                 \"CONFIG_VALUE_PROCESS_PARTIAL\"\n  CONFIG_VALUE_REJECT                          \"CONFIG_VALUE_REJECT\"\n  CONFIG_VALUE_RELEVANT_ONLY                   \"CONFIG_VALUE_RELEVANT_ONLY\"\n  CONFIG_VALUE_SERIAL                          \"CONFIG_VALUE_SERIAL\"\n  CONFIG_VALUE_WARN                            \"CONFIG_VALUE_WARN\"\n  CONFIG_XML_EXTERNAL_ENTITY                   \"CONFIG_XML_EXTERNAL_ENTITY\"\n  CONFIG_XML_PARSE_XML_INTO_ARGS               \"CONFIG_XML_PARSE_XML_INTO_ARGS\"\n  CONGIG_DIR_RESPONSE_BODY_MP                  \"CONGIG_DIR_RESPONSE_BODY_MP\"\n  CONGIG_DIR_SEC_ARG_SEP                       \"CONGIG_DIR_SEC_ARG_SEP\"\n  CONGIG_DIR_SEC_COOKIE_FORMAT                 \"CONGIG_DIR_SEC_COOKIE_FORMAT\"\n  CONFIG_SEC_COOKIEV0_SEPARATOR                \"CONFIG_SEC_COOKIEV0_SEPARATOR\"\n  CONGIG_DIR_SEC_DATA_DIR                      \"CONGIG_DIR_SEC_DATA_DIR\"\n  CONGIG_DIR_SEC_STATUS_ENGINE                 \"CONGIG_DIR_SEC_STATUS_ENGINE\"\n  CONFIG_SEC_STREAM_IN_BODY_INSPECTION         \"CONFIG_SEC_STREAM_IN_BODY_INSPECTION\"\n  CONFIG_SEC_STREAM_OUT_BODY_INSPECTION        \"CONFIG_SEC_STREAM_OUT_BODY_INSPECTION\"\n  CONGIG_DIR_SEC_TMP_DIR                       \"CONGIG_DIR_SEC_TMP_DIR\"\n  DIRECTIVE                                    \"DIRECTIVE\"\n  DIRECTIVE_SECRULESCRIPT                      \"DIRECTIVE_SECRULESCRIPT\"\n  FREE_TEXT_QUOTE_MACRO_EXPANSION              \"FREE_TEXT_QUOTE_MACRO_EXPANSION\"\n  QUOTATION_MARK                               \"QUOTATION_MARK\"\n  RUN_TIME_VAR_BLD                             \"RUN_TIME_VAR_BLD\"\n  RUN_TIME_VAR_DUR                             \"RUN_TIME_VAR_DUR\"\n  RUN_TIME_VAR_HSV                             \"RUN_TIME_VAR_HSV\"\n  RUN_TIME_VAR_REMOTE_USER                     \"RUN_TIME_VAR_REMOTE_USER\"\n  RUN_TIME_VAR_TIME                            \"RUN_TIME_VAR_TIME\"\n  RUN_TIME_VAR_TIME_DAY                        \"RUN_TIME_VAR_TIME_DAY\"\n  RUN_TIME_VAR_TIME_EPOCH                      \"RUN_TIME_VAR_TIME_EPOCH\"\n  RUN_TIME_VAR_TIME_HOUR                       \"RUN_TIME_VAR_TIME_HOUR\"\n  RUN_TIME_VAR_TIME_MIN                        \"RUN_TIME_VAR_TIME_MIN\"\n  RUN_TIME_VAR_TIME_MON                        \"RUN_TIME_VAR_TIME_MON\"\n  RUN_TIME_VAR_TIME_SEC                        \"RUN_TIME_VAR_TIME_SEC\"\n  RUN_TIME_VAR_TIME_WDAY                       \"RUN_TIME_VAR_TIME_WDAY\"\n  RUN_TIME_VAR_TIME_YEAR                       \"RUN_TIME_VAR_TIME_YEAR\"\n  VARIABLE                                     \"VARIABLE\"\n  DICT_ELEMENT                                 \"Dictionary element\"\n  DICT_ELEMENT_WITH_EQUALS                     \"Dictionary element, with equals\"\n  DICT_ELEMENT_REGEXP                          \"Dictionary element, selected by regexp\"\n;\n\n%type <std::unique_ptr<actions::Action>> act\n\n%type <std::unique_ptr<actions::Action>> setvar_action\n%type <std::unique_ptr<RunTimeString>>   run_time_string\n\n%type <std::unique_ptr<std::vector<std::unique_ptr<actions::Action> > > >\n  actions_may_quoted\n  actions\n;\n\n%type <std::unique_ptr<Operator>>\n  op_before_init\n  op\n;\n\n%type <std::unique_ptr<std::vector<std::unique_ptr<Variable> > > > variables_pre_process\n%type <std::unique_ptr<std::vector<std::unique_ptr<Variable> > > > variables_may_be_quoted\n%type <std::unique_ptr<std::vector<std::unique_ptr<Variable> > > > variables\n%type <std::unique_ptr<Variable>> var\n\n// Destructor directives to prevent memory leaks on parse errors.\n// When YYERROR is called, these ensure proper cleanup of semantic values.\n// Empty bodies are correct: with api.value.type variant, the variant's\n// destructor automatically calls std::unique_ptr's destructor.\n%destructor { } <std::unique_ptr<actions::Action>>\n%destructor { } <std::unique_ptr<RunTimeString>>\n%destructor { } <std::unique_ptr<std::vector<std::unique_ptr<actions::Action> > > >\n%destructor { } <std::unique_ptr<Operator>>\n%destructor { } <std::unique_ptr<Variable>>\n%destructor { } <std::unique_ptr<std::vector<std::unique_ptr<Variable> > > >\n\n//%printer { yyoutput << $$; } <*>;\n\n%%\n%start input;\n\n\ninput:\n    END\n      {\n        return 0;\n      }\n    | input line\n    | line\n    ;\n\nline: expression\n    ;\n\naudit_log:\n    /* SecAuditLogDirMode */\n    CONFIG_DIR_AUDIT_DIR_MOD\n      {\n        driver.m_auditLog->setStorageDirMode(strtol($1.c_str(), NULL, 8));\n      }\n\n    /* SecAuditLogStorageDir */\n    | CONFIG_DIR_AUDIT_DIR\n      {\n        driver.m_auditLog->setStorageDir($1);\n      }\n\n    /* SecAuditEngine */\n    | CONFIG_DIR_AUDIT_ENG CONFIG_VALUE_RELEVANT_ONLY\n      {\n        driver.m_auditLog->setStatus(modsecurity::audit_log::AuditLog::RelevantOnlyAuditLogStatus);\n      }\n    | CONFIG_DIR_AUDIT_ENG CONFIG_VALUE_OFF\n      {\n        driver.m_auditLog->setStatus(modsecurity::audit_log::AuditLog::OffAuditLogStatus);\n      }\n    | CONFIG_DIR_AUDIT_ENG CONFIG_VALUE_ON\n      {\n        driver.m_auditLog->setStatus(modsecurity::audit_log::AuditLog::OnAuditLogStatus);\n      }\n\n    /* SecAuditLogFileMode */\n    | CONFIG_DIR_AUDIT_FLE_MOD\n      {\n        driver.m_auditLog->setFileMode(strtol($1.c_str(), NULL, 8));\n      }\n\n    /* SecAuditLog2 */\n    | CONFIG_DIR_AUDIT_LOG2\n      {\n        driver.m_auditLog->setFilePath2($1);\n      }\n\n    /* SecAuditLogParts */\n    | CONFIG_DIR_AUDIT_LOG_P\n      {\n        driver.m_auditLog->setParts($1);\n      }\n\n    /* SecAuditLog */\n    | CONFIG_DIR_AUDIT_LOG\n      {\n        driver.m_auditLog->setFilePath1($1);\n      }\n\n    | CONFIG_DIR_AUDIT_LOG_FMT JSON\n      {\n        driver.m_auditLog->setFormat(modsecurity::audit_log::AuditLog::JSONAuditLogFormat);\n      }\n\n    | CONFIG_DIR_AUDIT_LOG_FMT NATIVE\n      {\n        driver.m_auditLog->setFormat(modsecurity::audit_log::AuditLog::NativeAuditLogFormat);\n      }\n\n    /* SecAuditLogRelevantStatus */\n    | CONFIG_DIR_AUDIT_STS\n      {\n        std::string relevant_status($1);\n        driver.m_auditLog->setRelevantStatus(relevant_status);\n      }\n\n    /* SecAuditLogPrefix */\n    | CONFIG_DIR_AUDIT_PREFIX\n      {\n        std::string prefix($1);\n        driver.m_auditLog->setPrefix(prefix);\n      }\n\n    /* SecAuditLogType */\n    | CONFIG_DIR_AUDIT_TPE CONFIG_VALUE_SERIAL\n      {\n        driver.m_auditLog->setType(modsecurity::audit_log::AuditLog::SerialAuditLogType);\n      }\n    | CONFIG_DIR_AUDIT_TPE CONFIG_VALUE_PARALLEL\n      {\n        driver.m_auditLog->setType(modsecurity::audit_log::AuditLog::ParallelAuditLogType);\n      }\n    | CONFIG_DIR_AUDIT_TPE CONFIG_VALUE_HTTPS\n      {\n        driver.m_auditLog->setType(modsecurity::audit_log::AuditLog::HttpsAuditLogType);\n      }\n\n    /* Upload */\n    | CONFIG_UPDLOAD_KEEP_FILES CONFIG_VALUE_ON\n      {\n        driver.m_uploadKeepFiles = modsecurity::RulesSetProperties::TrueConfigBoolean;\n      }\n    | CONFIG_UPDLOAD_KEEP_FILES CONFIG_VALUE_OFF\n      {\n        driver.m_uploadKeepFiles = modsecurity::RulesSetProperties::FalseConfigBoolean;\n      }\n    | CONFIG_UPDLOAD_KEEP_FILES CONFIG_VALUE_RELEVANT_ONLY\n      {\n        driver.error(@0, \"SecUploadKeepFiles RelevantOnly is not currently supported. Accepted values are On or Off\");\n        YYERROR;\n      }\n    | CONFIG_UPLOAD_FILE_LIMIT\n      {\n        std::string errmsg = \"\";\n        if (driver.m_uploadFileLimit.parse(std::string($1), &errmsg) != true) {\n          driver.error(@0, \"Failed to parse SecUploadFileLimit: \" + errmsg);\n          YYERROR;\n        }\n      }\n    | CONFIG_UPLOAD_FILE_MODE\n      {\n        std::string errmsg = \"\";\n        if (driver.m_uploadFileMode.parse(std::string($1), &errmsg) != true) {\n          driver.error(@0, \"Failed to parse SecUploadFileMode: \" + errmsg);\n          YYERROR;\n        }\n      }\n    | CONFIG_UPLOAD_DIR\n      {\n        driver.m_uploadDirectory.m_set = true;\n        driver.m_uploadDirectory.m_value = $1;\n      }\n    | CONFIG_UPDLOAD_SAVE_TMP_FILES CONFIG_VALUE_ON\n      {\n        driver.m_tmpSaveUploadedFiles = modsecurity::RulesSetProperties::TrueConfigBoolean;\n      }\n    | CONFIG_UPDLOAD_SAVE_TMP_FILES CONFIG_VALUE_OFF\n      {\n        driver.m_tmpSaveUploadedFiles = modsecurity::RulesSetProperties::FalseConfigBoolean;\n      }\n    ;\n\nactions:\n    QUOTATION_MARK actions_may_quoted QUOTATION_MARK\n      {\n        $$ = std::move($2);\n      }\n    | actions_may_quoted\n      {\n        $$ = std::move($1);\n      }\n    ;\n\nactions_may_quoted:\n    actions_may_quoted COMMA act\n      {\n        ACTION_INIT($3, @0)\n        $1->push_back(std::move($3));\n        $$ = std::move($1);\n      }\n    | act\n      {\n        std::unique_ptr<std::vector<std::unique_ptr<actions::Action>>> b(new std::vector<std::unique_ptr<actions::Action>>());\n        ACTION_INIT($1, @0)\n        b->push_back(std::move($1));\n        $$ = std::move(b);\n      }\n    ;\n\nop:\n    op_before_init\n      {\n        $$ = std::move($1);\n        std::string error;\n        if ($$->init(*@1.end.filename, &error) == false) {\n            driver.error(@0, error);\n            YYERROR;\n        }\n      }\n    | NOT op_before_init\n      {\n        $$ = std::move($2);\n        $$->m_negation = true;\n        std::string error;\n        if ($$->init(*@1.end.filename, &error) == false) {\n            driver.error(@0, error);\n            YYERROR;\n        }\n      }\n    | run_time_string\n      {\n        OPERATOR_CONTAINER($$, new operators::Rx(std::move($1)));\n        std::string error;\n        if ($$->init(*@1.end.filename, &error) == false) {\n            driver.error(@0, error);\n            YYERROR;\n        }\n      }\n    | NOT run_time_string\n      {\n        OPERATOR_CONTAINER($$, new operators::Rx(std::move($2)));\n        $$->m_negation = true;\n        std::string error;\n        if ($$->init(*@1.end.filename, &error) == false) {\n            driver.error(@0, error);\n            YYERROR;\n        }\n      }\n    ;\n\nop_before_init:\n    OPERATOR_UNCONDITIONAL_MATCH\n      {\n        OPERATOR_CONTAINER($$, new operators::UnconditionalMatch());\n      }\n    | OPERATOR_DETECT_SQLI\n      {\n        OPERATOR_CONTAINER($$, new operators::DetectSQLi());\n      }\n    | OPERATOR_DETECT_XSS\n      {\n        OPERATOR_CONTAINER($$, new operators::DetectXSS());\n      }\n    | OPERATOR_VALIDATE_URL_ENCODING\n      {\n        OPERATOR_CONTAINER($$, new operators::ValidateUrlEncoding());\n      }\n    | OPERATOR_VALIDATE_UTF8_ENCODING\n      {\n        OPERATOR_CONTAINER($$, new operators::ValidateUtf8Encoding());\n      }\n    | OPERATOR_INSPECT_FILE run_time_string\n      {\n        OPERATOR_CONTAINER($$, new operators::InspectFile(std::move($2)));\n      }\n    | OPERATOR_FUZZY_HASH run_time_string\n      {\n        OPERATOR_CONTAINER($$, new operators::FuzzyHash(std::move($2)));\n      }\n    | OPERATOR_VALIDATE_BYTE_RANGE run_time_string\n      {\n        OPERATOR_CONTAINER($$, new operators::ValidateByteRange(std::move($2)));\n      }\n    | OPERATOR_VALIDATE_DTD run_time_string\n      {\n        OPERATOR_CONTAINER($$, new operators::ValidateDTD(std::move($2)));\n      }\n    | OPERATOR_VALIDATE_HASH run_time_string\n      {\n        /* $$ = new operators::ValidateHash($1); */\n        OPERATOR_NOT_SUPPORTED(\"ValidateHash\", @0);\n      }\n    | OPERATOR_VALIDATE_SCHEMA run_time_string\n      {\n        OPERATOR_CONTAINER($$, new operators::ValidateSchema(std::move($2)));\n      }\n    | OPERATOR_VERIFY_CC run_time_string\n      {\n        OPERATOR_CONTAINER($$, new operators::VerifyCC(std::move($2)));\n      }\n    | OPERATOR_VERIFY_CPF run_time_string\n      {\n        OPERATOR_CONTAINER($$, new operators::VerifyCPF(std::move($2)));\n      }\n    | OPERATOR_VERIFY_SSN run_time_string\n      {\n        OPERATOR_CONTAINER($$, new operators::VerifySSN(std::move($2)));\n      }\n    | OPERATOR_VERIFY_SVNR run_time_string\n      {\n        OPERATOR_CONTAINER($$, new operators::VerifySVNR(std::move($2)));\n      }\n    | OPERATOR_GSB_LOOKUP run_time_string\n      {\n        /* $$ = new operators::GsbLookup($1); */\n        OPERATOR_NOT_SUPPORTED(\"GsbLookup\", @0);\n      }\n    | OPERATOR_RSUB run_time_string\n      {\n        /* $$ = new operators::Rsub($1); */\n        OPERATOR_NOT_SUPPORTED(\"Rsub\", @0);\n      }\n    | OPERATOR_WITHIN run_time_string\n      {\n        OPERATOR_CONTAINER($$, new operators::Within(std::move($2)));\n      }\n    | OPERATOR_CONTAINS_WORD run_time_string\n      {\n        OPERATOR_CONTAINER($$, new operators::ContainsWord(std::move($2)));\n      }\n    | OPERATOR_CONTAINS run_time_string\n      {\n        OPERATOR_CONTAINER($$, new operators::Contains(std::move($2)));\n      }\n    | OPERATOR_ENDS_WITH run_time_string\n      {\n        OPERATOR_CONTAINER($$, new operators::EndsWith(std::move($2)));\n      }\n    | OPERATOR_EQ run_time_string\n      {\n        OPERATOR_CONTAINER($$, new operators::Eq(std::move($2)));\n      }\n    | OPERATOR_GE run_time_string\n      {\n        OPERATOR_CONTAINER($$, new operators::Ge(std::move($2)));\n      }\n    | OPERATOR_GT run_time_string\n      {\n        OPERATOR_CONTAINER($$, new operators::Gt(std::move($2)));\n      }\n    | OPERATOR_IP_MATCH_FROM_FILE run_time_string\n      {\n        OPERATOR_CONTAINER($$, new operators::IpMatchF(std::move($2)));\n      }\n    | OPERATOR_IP_MATCH run_time_string\n      {\n        OPERATOR_CONTAINER($$, new operators::IpMatch(std::move($2)));\n      }\n    | OPERATOR_LE run_time_string\n      {\n        OPERATOR_CONTAINER($$, new operators::Le(std::move($2)));\n      }\n    | OPERATOR_LT run_time_string\n      {\n        OPERATOR_CONTAINER($$, new operators::Lt(std::move($2)));\n      }\n    | OPERATOR_PM_FROM_FILE run_time_string\n      {\n        OPERATOR_CONTAINER($$, new operators::PmFromFile(std::move($2)));\n      }\n    | OPERATOR_PM run_time_string\n      {\n        OPERATOR_CONTAINER($$, new operators::Pm(std::move($2)));\n      }\n    | OPERATOR_RBL run_time_string\n      {\n        OPERATOR_CONTAINER($$, new operators::Rbl(std::move($2)));\n      }\n    | OPERATOR_RX run_time_string\n      {\n        OPERATOR_CONTAINER($$, new operators::Rx(std::move($2)));\n      }\n    | OPERATOR_RX_GLOBAL run_time_string\n      {\n        OPERATOR_CONTAINER($$, new operators::RxGlobal(std::move($2)));\n      }\n    | OPERATOR_STR_EQ run_time_string\n      {\n        OPERATOR_CONTAINER($$, new operators::StrEq(std::move($2)));\n      }\n    | OPERATOR_STR_MATCH run_time_string\n      {\n        OPERATOR_CONTAINER($$, new operators::StrMatch(std::move($2)));\n      }\n    | OPERATOR_BEGINS_WITH run_time_string\n      {\n        OPERATOR_CONTAINER($$, new operators::BeginsWith(std::move($2)));\n      }\n    | OPERATOR_GEOLOOKUP\n      {\n#if defined(WITH_GEOIP) or defined(WITH_MAXMIND)\n        OPERATOR_CONTAINER($$, new operators::GeoLookup());\n#else\n        std::stringstream ss;\n            ss << \"This version of ModSecurity was not compiled with GeoIP or MaxMind support.\";\n            driver.error(@0, ss.str());\n            YYERROR;\n#endif  // WITH_GEOIP\n      }\n    ;\n\nexpression:\n    audit_log\n    | DIRECTIVE variables op actions\n      {\n        std::vector<actions::Action *> *a = new std::vector<actions::Action *>();\n        std::vector<actions::transformations::Transformation *> *t = new std::vector<actions::transformations::Transformation *>();\n        for (auto &i : *$4.get()) {\n            if (auto pt = dynamic_cast<actions::transformations::Transformation *>(i.get())) {\n              t->push_back(pt);\n              i.release();\n            } else {\n              a->push_back(i.release());\n            }\n        }\n        variables::Variables *v = new variables::Variables();\n        for (auto &i : *$2.get()) {\n            v->push_back(i.release());\n        }\n\n        Operator *op = $3.release();\n        std::unique_ptr<RuleWithOperator> rule(new RuleWithOperator(\n            /* op */ op,\n            /* variables */ v,\n            /* actions */ a,\n            /* transformations */ t,\n            /* file name */ std::string(*@1.end.filename),\n            /* line number */ @1.end.line\n            ));\n\n        if (driver.addSecRule(std::move(rule)) == false) {\n            YYERROR;\n        }\n      }\n    | DIRECTIVE variables op\n      {\n        variables::Variables *v = new variables::Variables();\n        for (auto &i : *$2.get()) {\n            v->push_back(i.release());\n        }\n\n        std::unique_ptr<RuleWithOperator> rule(new RuleWithOperator(\n            /* op */ $3.release(),\n            /* variables */ v,\n            /* actions */ NULL,\n            /* transformations */ NULL,\n            /* file name */ std::string(*@1.end.filename),\n            /* line number */ @1.end.line\n            ));\n        if (driver.addSecRule(std::move(rule)) == false) {\n            YYERROR;\n        }\n      }\n    | CONFIG_DIR_SEC_ACTION actions\n      {\n        std::vector<actions::Action *> *a = new std::vector<actions::Action *>();\n        std::vector<actions::transformations::Transformation *> *t = new std::vector<actions::transformations::Transformation *>();\n        for (auto &i : *$2.get()) {\n            if (auto pt = dynamic_cast<actions::transformations::Transformation *>(i.get())) {\n              t->push_back(pt);\n              i.release();\n            } else {\n              a->push_back(i.release());\n            }\n        }\n        std::unique_ptr<RuleUnconditional> rule(new RuleUnconditional(\n            /* actions */ a,\n            /* transformations */ t,\n            /* file name */ std::string(*@1.end.filename),\n            /* line number */ @1.end.line\n            ));\n        driver.addSecAction(std::move(rule));\n      }\n    | DIRECTIVE_SECRULESCRIPT actions\n      {\n        std::string err;\n        std::vector<actions::Action *> *a = new std::vector<actions::Action *>();\n        std::vector<actions::transformations::Transformation *> *t = new std::vector<actions::transformations::Transformation *>();\n        for (auto &i : *$2.get()) {\n            if (auto pt = dynamic_cast<actions::transformations::Transformation *>(i.get())) {\n              t->push_back(pt);\n              i.release();\n            } else {\n              a->push_back(i.release());\n            }\n        }\n        std::unique_ptr<RuleScript> r(new RuleScript(\n            /* path to script */ $1,\n            /* actions */ a,\n            /* transformations */ t,\n            /* file name */ std::string(*@1.end.filename),\n            /* line number */ @1.end.line\n            ));\n\n        if (r->init(&err) == false) {\n            driver.error(@0, \"Failed to load script: \" + err);\n            YYERROR;\n        }\n        if (driver.addSecRuleScript(std::move(r)) == false) {\n            YYERROR;\n        }\n      }\n    | CONFIG_DIR_SEC_DEFAULT_ACTION actions\n      {\n        bool hasDisruptive = false;\n        std::vector<actions::Action *> *actions = new std::vector<actions::Action *>();\n        for (auto &i : *$2.get()) {\n            actions->push_back(i.release());\n        }\n        std::vector<actions::Action *> checkedActions;\n        int definedPhase = -1;\n        int secRuleDefinedPhase = -1;\n        for (actions::Action *a : *actions) {\n            actions::Phase *phase = dynamic_cast<actions::Phase *>(a);\n            if (a->isDisruptive() == true && dynamic_cast<actions::Block *>(a) == NULL) {\n                hasDisruptive = true;\n            }\n            if (phase != NULL) {\n                definedPhase = phase->m_phase;\n                secRuleDefinedPhase = phase->m_secRulesPhase;\n                delete phase;\n            } else if (a->action_kind == actions::Action::Kind::RunTimeOnlyIfMatchKind ||\n                a->action_kind == actions::Action::Kind::RunTimeBeforeMatchAttemptKind) {\n                                actions::transformations::None *none = dynamic_cast<actions::transformations::None *>(a);\n                if (none != NULL) {\n                    driver.error(@0, \"The transformation none is not suitable to be part of the SecDefaultActions\");\n                    YYERROR;\n                }\n                checkedActions.push_back(a);\n            } else {\n                driver.error(@0, \"The action '\" + *a->m_name.get() + \"' is not suitable to be part of the SecDefaultActions\");\n                YYERROR;\n            }\n        }\n        if (definedPhase == -1) {\n            definedPhase = modsecurity::Phases::RequestHeadersPhase;\n        }\n\n        if (hasDisruptive == false) {\n            driver.error(@0, \"SecDefaultAction must specify a disruptive action.\");\n            YYERROR;\n        }\n\n        if (!driver.m_defaultActions[definedPhase].empty()) {\n            std::stringstream ss;\n            ss << \"SecDefaultActions can only be placed once per phase and configuration context. Phase \";\n            ss << secRuleDefinedPhase;\n            ss << \" was informed already.\";\n            driver.error(@0, ss.str());\n            YYERROR;\n        }\n\n        for (actions::Action *a : checkedActions) {\n            driver.m_defaultActions[definedPhase].push_back(\n                std::unique_ptr<actions::Action>(a));\n        }\n\n        delete actions;\n      }\n    | CONFIG_DIR_SEC_MARKER\n      {\n        driver.addSecMarker(modsecurity::utils::string::removeBracketsIfNeeded($1),\n            /* file name */ std::string(*@1.end.filename),\n            /* line number */ @1.end.line\n        );\n      }\n    | CONFIG_DIR_RULE_ENG CONFIG_VALUE_OFF\n      {\n        driver.m_secRuleEngine = modsecurity::RulesSet::DisabledRuleEngine;\n      }\n    | CONFIG_DIR_RULE_ENG CONFIG_VALUE_ON\n      {\n        driver.m_secRuleEngine = modsecurity::RulesSet::EnabledRuleEngine;\n      }\n    | CONFIG_DIR_RULE_ENG CONFIG_VALUE_DETC\n      {\n        driver.m_secRuleEngine = modsecurity::RulesSet::DetectionOnlyRuleEngine;\n      }\n    | CONFIG_DIR_REQ_BODY CONFIG_VALUE_ON\n      {\n        driver.m_secRequestBodyAccess = modsecurity::RulesSetProperties::TrueConfigBoolean;\n      }\n    | CONFIG_DIR_REQ_BODY CONFIG_VALUE_OFF\n      {\n        driver.m_secRequestBodyAccess = modsecurity::RulesSetProperties::FalseConfigBoolean;\n      }\n    | CONFIG_DIR_RES_BODY CONFIG_VALUE_ON\n      {\n        driver.m_secResponseBodyAccess = modsecurity::RulesSetProperties::TrueConfigBoolean;\n      }\n    | CONFIG_DIR_RES_BODY CONFIG_VALUE_OFF\n      {\n        driver.m_secResponseBodyAccess = modsecurity::RulesSetProperties::FalseConfigBoolean;\n      }\n    | CONFIG_SEC_ARGUMENT_SEPARATOR\n      {\n        if ($1.length() != 1) {\n          driver.error(@0, \"Argument separator should be set to a single character.\");\n          YYERROR;\n        }\n        driver.m_secArgumentSeparator.m_value = $1;\n        driver.m_secArgumentSeparator.m_set = true;\n      }\n    | CONFIG_COMPONENT_SIG\n      {\n        driver.m_components.push_back($1);\n      }\n    | CONFIG_CONN_ENGINE CONFIG_VALUE_ON\n      {\n        driver.error(@0, \"SecConnEngine is not yet supported.\");\n        YYERROR;\n      }\n    | CONFIG_CONN_ENGINE CONFIG_VALUE_OFF\n      {\n      }\n    | CONFIG_SEC_WEB_APP_ID\n      {\n        driver.m_secWebAppId.m_value = $1;\n        driver.m_secWebAppId.m_set = true;\n      }\n    | CONFIG_SEC_SERVER_SIG\n      {\n        driver.error(@0, \"SecServerSignature is not supported.\");\n        YYERROR;\n      }\n    | CONFIG_SEC_CACHE_TRANSFORMATIONS\n      {\n        driver.error(@0, \"SecCacheTransformations is not supported.\");\n        YYERROR;\n      }\n    | CONFIG_SEC_DISABLE_BACKEND_COMPRESS CONFIG_VALUE_ON\n      {\n        driver.error(@0, \"SecDisableBackendCompression is not supported.\");\n        YYERROR;\n      }\n    | CONFIG_SEC_DISABLE_BACKEND_COMPRESS CONFIG_VALUE_OFF\n      {\n      }\n    | CONFIG_CONTENT_INJECTION CONFIG_VALUE_ON\n      {\n        driver.error(@0, \"SecContentInjection is not yet supported.\");\n        YYERROR;\n      }\n    | CONFIG_CONTENT_INJECTION CONFIG_VALUE_OFF\n      {\n      }\n    | CONFIG_SEC_CHROOT_DIR\n      {\n        driver.error(@0, \"SecChrootDir is not supported.\");\n        YYERROR;\n      }\n    | CONFIG_SEC_HASH_ENGINE CONFIG_VALUE_ON\n      {\n        driver.error(@0, \"SecHashEngine is not yet supported.\");\n        YYERROR;\n      }\n    | CONFIG_SEC_HASH_ENGINE CONFIG_VALUE_OFF\n      {\n      }\n    | CONFIG_SEC_HASH_KEY\n      {\n        driver.error(@0, \"SecHashKey is not yet supported.\");\n        YYERROR;\n      }\n    | CONFIG_SEC_HASH_PARAM\n      {\n        driver.error(@0, \"SecHashParam is not yet supported.\");\n        YYERROR;\n      }\n    | CONFIG_SEC_HASH_METHOD_RX\n      {\n        driver.error(@0, \"SecHashMethodRx is not yet supported.\");\n        YYERROR;\n      }\n    | CONFIG_SEC_HASH_METHOD_PM\n      {\n        driver.error(@0, \"SecHashMethodPm is not yet supported.\");\n        YYERROR;\n      }\n    | CONFIG_DIR_GSB_DB\n      {\n        driver.error(@0, \"SecGsbLookupDb is not supported.\");\n        YYERROR;\n      }\n    | CONFIG_SEC_GUARDIAN_LOG\n      {\n        driver.error(@0, \"SecGuardianLog is not supported.\");\n        YYERROR;\n      }\n    | CONFIG_SEC_INTERCEPT_ON_ERROR CONFIG_VALUE_ON\n      {\n        driver.error(@0, \"SecInterceptOnError is not yet supported.\");\n        YYERROR;\n      }\n    | CONFIG_SEC_INTERCEPT_ON_ERROR CONFIG_VALUE_OFF\n      {\n      }\n    | CONFIG_SEC_CONN_R_STATE_LIMIT\n      {\n        driver.error(@0, \"SecConnReadStateLimit is not yet supported.\");\n        YYERROR;\n      }\n    | CONFIG_SEC_CONN_W_STATE_LIMIT\n      {\n        driver.error(@0, \"SecConnWriteStateLimit is not yet supported.\");\n        YYERROR;\n      }\n    | CONFIG_SEC_SENSOR_ID\n      {\n        driver.error(@0, \"SecSensorId is not yet supported.\");\n        YYERROR;\n      }\n    | CONFIG_SEC_RULE_INHERITANCE CONFIG_VALUE_ON\n      {\n        driver.error(@0, \"SecRuleInheritance is not yet supported.\");\n        YYERROR;\n      }\n    | CONFIG_SEC_RULE_INHERITANCE CONFIG_VALUE_OFF\n      {\n      }\n    | CONFIG_SEC_RULE_PERF_TIME\n      {\n        driver.error(@0, \"SecRulePerfTime is not yet supported.\");\n        YYERROR;\n      }\n    | CONFIG_SEC_STREAM_IN_BODY_INSPECTION\n      {\n        driver.error(@0, \"SecStreamInBodyInspection is not supported.\");\n        YYERROR;\n      }\n    | CONFIG_SEC_STREAM_OUT_BODY_INSPECTION\n      {\n        driver.error(@0, \"SecStreamOutBodyInspection is not supported.\");\n        YYERROR;\n      }\n    | CONFIG_SEC_RULE_REMOVE_BY_ID\n      {\n        std::string error;\n        if (driver.m_exceptions.load($1, &error) == false) {\n            std::stringstream ss;\n            ss << \"SecRuleRemoveById: failed to load:\";\n            ss << $1;\n            ss << \". \";\n            ss << error;\n            driver.error(@0, ss.str());\n            YYERROR;\n        }\n      }\n    | CONFIG_SEC_RULE_REMOVE_BY_TAG\n      {\n        std::string error;\n        if (driver.m_exceptions.loadRemoveRuleByTag($1, &error) == false) {\n            std::stringstream ss;\n            ss << \"SecRuleRemoveByTag: failed to load:\";\n            ss << $1;\n            ss << \". \";\n            ss << error;\n            driver.error(@0, ss.str());\n            YYERROR;\n        }\n      }\n    | CONFIG_SEC_RULE_REMOVE_BY_MSG\n      {\n        std::string error;\n        if (driver.m_exceptions.loadRemoveRuleByMsg($1, &error) == false) {\n            std::stringstream ss;\n            ss << \"SecRuleRemoveByMsg: failed to load:\";\n            ss << $1;\n            ss << \". \";\n            ss << error;\n            driver.error(@0, ss.str());\n            YYERROR;\n        }\n      }\n    | CONFIG_SEC_RULE_UPDATE_TARGET_BY_TAG variables_pre_process\n      {\n        std::string error;\n        if (driver.m_exceptions.loadUpdateTargetByTag($1, std::move($2), &error) == false) {\n            std::stringstream ss;\n            ss << \"SecRuleUpdateTargetByTag: failed to load:\";\n            ss << $1;\n            ss << \". \";\n            ss << error;\n            driver.error(@0, ss.str());\n            YYERROR;\n        }\n      }\n    | CONFIG_SEC_RULE_UPDATE_TARGET_BY_MSG variables_pre_process\n      {\n        std::string error;\n        if (driver.m_exceptions.loadUpdateTargetByMsg($1, std::move($2), &error) == false) {\n            std::stringstream ss;\n            ss << \"SecRuleUpdateTargetByMsg: failed to load:\";\n            ss << $1;\n            ss << \". \";\n            ss << error;\n            driver.error(@0, ss.str());\n            YYERROR;\n        }\n      }\n    | CONFIG_SEC_RULE_UPDATE_TARGET_BY_ID variables_pre_process\n      {\n        std::string error;\n        double ruleId;\n        try {\n            ruleId = std::stod($1);\n        } catch (...) {\n            std::stringstream ss;\n            ss << \"SecRuleUpdateTargetById: failed to load:\";\n            ss << \"The input \\\"\" + $1 + \"\\\" does not \";\n            ss << \"seems to be a valid rule id.\";\n            ss << \". \";\n            driver.error(@0, ss.str());\n            YYERROR;\n        }\n\n        if (driver.m_exceptions.loadUpdateTargetById(ruleId, std::move($2), &error) == false) {\n            std::stringstream ss;\n            ss << \"SecRuleUpdateTargetById: failed to load:\";\n            ss << $1;\n            ss << \". \";\n            ss << error;\n            driver.error(@0, ss.str());\n            YYERROR;\n        }\n      }\n    | CONFIG_SEC_RULE_UPDATE_ACTION_BY_ID actions\n      {\n        std::string error;\n        double ruleId;\n        try {\n            ruleId = std::stod($1);\n        } catch (...) {\n            std::stringstream ss;\n            ss << \"SecRuleUpdateActionById: failed to load:\";\n            ss << \"The input \\\"\" + $1 + \"\\\" does not \";\n            ss << \"seems to be a valid rule id.\";\n            ss << \". \";\n            driver.error(@0, ss.str());\n            YYERROR;\n        }\n\n\n        if (driver.m_exceptions.loadUpdateActionById(ruleId, std::move($2), &error) == false) {\n            std::stringstream ss;\n            ss << \"SecRuleUpdateActionById: failed to load:\";\n            ss << $1;\n            ss << \". \";\n            ss << error;\n            driver.error(@0, ss.str());\n            YYERROR;\n        }\n      }\n    /* Debug log: start */\n    | CONFIG_DIR_DEBUG_LVL\n      {\n        if (driver.m_debugLog != NULL) {\n          driver.m_debugLog->setDebugLogLevel(atoi($1.c_str()));\n        } else {\n            std::stringstream ss;\n            ss << \"Internal error, there is no DebugLog \";\n            ss << \"object associated with the driver class\";\n            driver.error(@0, ss.str());\n            YYERROR;\n        }\n      }\n    | CONFIG_DIR_DEBUG_LOG\n      {\n        if (driver.m_debugLog != NULL) {\n            std::string error;\n            driver.m_debugLog->setDebugLogFile($1, &error);\n            if (error.size() > 0) {\n                std::stringstream ss;\n                ss << \"Failed to start DebugLog: \" << error;\n                driver.error(@0, ss.str());\n                YYERROR;\n            }\n        } else {\n            std::stringstream ss;\n            ss << \"Internal error, there is no DebugLog \";\n            ss << \"object associated with the driver class\";\n            driver.error(@0, ss.str());\n            YYERROR;\n        }\n      }\n    /* Debug log: end */\n    | CONFIG_DIR_GEO_DB\n      {\n#if defined(WITH_GEOIP) or defined(WITH_MAXMIND)\n        std::string err;\n        std::string file = modsecurity::utils::find_resource($1,\n            *@1.end.filename, &err);\n        if (file.empty()) {\n            std::stringstream ss;\n            ss << \"Failed to load locate the GeoDB file from: \" << $1 << \" \";\n            ss << err;\n            driver.error(@0, ss.str());\n            YYERROR;\n        }\n        if (Utils::GeoLookup::getInstance().setDataBase(file, &err) == false) {\n            std::stringstream ss;\n            ss << \"Failed to load the GeoDB from: \";\n            ss << file << \". \" << err;\n            driver.error(@0, ss.str());\n            YYERROR;\n        }\n#else\n        std::stringstream ss;\n        ss << \"This version of ModSecurity was not compiled with GeoIP or MaxMind support.\";\n        driver.error(@0, ss.str());\n        YYERROR;\n#endif  // WITH_GEOIP\n      }\n    | CONFIG_DIR_ARGS_LIMIT\n      {\n        driver.m_argumentsLimit.m_set = true;\n        driver.m_argumentsLimit.m_value = atoi($1.c_str());\n      }\n    | CONFIG_DIR_REQ_BODY_JSON_DEPTH_LIMIT\n      {\n        driver.m_requestBodyJsonDepthLimit.m_set = true;\n        driver.m_requestBodyJsonDepthLimit.m_value = atoi($1.c_str());\n      }\n    /* Body limits */\n    | CONFIG_DIR_REQ_BODY_LIMIT\n      {\n        std::string errmsg = \"\";\n        if (driver.m_requestBodyLimit.parse(std::string($1), &errmsg) != true) {\n          driver.error(@0, \"Failed to parse SecRequestBodyLimit: \" + errmsg);\n          YYERROR;\n        }\n      }\n    | CONFIG_DIR_REQ_BODY_NO_FILES_LIMIT\n      {\n        std::string errmsg = \"\";\n        if (driver.m_requestBodyNoFilesLimit.parse(std::string($1), &errmsg) != true) {\n          driver.error(@0, \"Failed to parse SecRequestsBodyNoFilesLimit: \" + errmsg);\n          YYERROR;\n        }\n      }\n    | CONFIG_DIR_REQ_BODY_IN_MEMORY_LIMIT\n      {\n        std::stringstream ss;\n        ss << \"As of ModSecurity version 3.0, SecRequestBodyInMemoryLimit is no longer \";\n        ss << \"supported. Instead, you can use your web server configurations to control \";\n        ss << \"those values. ModSecurity will follow the web server decision.\";\n        driver.error(@0, ss.str());\n        YYERROR;\n      }\n    | CONFIG_DIR_RES_BODY_LIMIT\n      {\n        std::string errmsg = \"\";\n        if (driver.m_responseBodyLimit.parse(std::string($1), &errmsg) != true) {\n          driver.error(@0, \"Failed to parse SecResponseBodyLimit: \" + errmsg);\n          YYERROR;\n        }\n      }\n    | CONFIG_DIR_REQ_BODY_LIMIT_ACTION CONFIG_VALUE_PROCESS_PARTIAL\n      {\n        driver.m_requestBodyLimitAction = modsecurity::RulesSet::BodyLimitAction::ProcessPartialBodyLimitAction;\n      }\n    | CONFIG_DIR_REQ_BODY_LIMIT_ACTION CONFIG_VALUE_REJECT\n      {\n        driver.m_requestBodyLimitAction = modsecurity::RulesSet::BodyLimitAction::RejectBodyLimitAction;\n      }\n    | CONFIG_DIR_RES_BODY_LIMIT_ACTION CONFIG_VALUE_PROCESS_PARTIAL\n      {\n        driver.m_responseBodyLimitAction = modsecurity::RulesSet::BodyLimitAction::ProcessPartialBodyLimitAction;\n      }\n    | CONFIG_DIR_RES_BODY_LIMIT_ACTION CONFIG_VALUE_REJECT\n      {\n        driver.m_responseBodyLimitAction = modsecurity::RulesSet::BodyLimitAction::RejectBodyLimitAction;\n      }\n    | CONFIG_SEC_REMOTE_RULES_FAIL_ACTION CONFIG_VALUE_ABORT\n      {\n        driver.m_remoteRulesActionOnFailed = RulesSet::OnFailedRemoteRulesAction::AbortOnFailedRemoteRulesAction;\n      }\n    | CONFIG_SEC_REMOTE_RULES_FAIL_ACTION CONFIG_VALUE_WARN\n      {\n        driver.m_remoteRulesActionOnFailed = RulesSet::OnFailedRemoteRulesAction::WarnOnFailedRemoteRulesAction;\n      }\n    | CONFIG_DIR_PCRE_MATCH_LIMIT_RECURSION\n/* Parser error disabled to avoid breaking default installations with modsecurity.conf-recommended\n        driver.error(@0, \"SecPcreMatchLimitRecursion is not currently supported. Default PCRE values are being used for now\");\n        YYERROR;\n*/\n    | CONFIG_DIR_PCRE_MATCH_LIMIT\n      {\n        std::string errmsg = \"\";\n        if (driver.m_pcreMatchLimit.parse(std::string($1), &errmsg) != true) {\n          driver.error(@0, \"Failed to parse SecPcreMatchLimit: \" + errmsg);\n          YYERROR;\n        }\n      }\n    | CONGIG_DIR_RESPONSE_BODY_MP\n      {\n        std::istringstream buf($1);\n        std::istream_iterator<std::string> beg(buf), end;\n        std::set<std::string> tokens(beg, end);\n        driver.m_responseBodyTypeToBeInspected.m_set = true;\n        for (std::set<std::string>::iterator it=tokens.begin();\n            it!=tokens.end(); ++it)\n        {\n            driver.m_responseBodyTypeToBeInspected.m_value.insert(*it);\n        }\n      }\n    | CONGIG_DIR_RESPONSE_BODY_MP_CLEAR\n      {\n        driver.m_responseBodyTypeToBeInspected.m_set = true;\n        driver.m_responseBodyTypeToBeInspected.m_clear = true;\n        driver.m_responseBodyTypeToBeInspected.m_value.clear();\n      }\n    | CONFIG_XML_EXTERNAL_ENTITY CONFIG_VALUE_OFF\n      {\n        driver.m_secXMLExternalEntity = modsecurity::RulesSetProperties::FalseConfigBoolean;\n      }\n    | CONFIG_XML_EXTERNAL_ENTITY CONFIG_VALUE_ON\n      {\n        driver.m_secXMLExternalEntity = modsecurity::RulesSetProperties::TrueConfigBoolean;\n      }\n    | CONFIG_XML_PARSE_XML_INTO_ARGS CONFIG_VALUE_ONLYARGS\n      {\n        driver.m_secXMLParseXmlIntoArgs = modsecurity::RulesSetProperties::OnlyArgsConfigXMLParseXmlIntoArgs;\n      }\n    | CONFIG_XML_PARSE_XML_INTO_ARGS CONFIG_VALUE_OFF\n      {\n        driver.m_secXMLParseXmlIntoArgs = modsecurity::RulesSetProperties::FalseConfigXMLParseXmlIntoArgs;\n      }\n    | CONFIG_XML_PARSE_XML_INTO_ARGS CONFIG_VALUE_ON\n      {\n        driver.m_secXMLParseXmlIntoArgs = modsecurity::RulesSetProperties::TrueConfigXMLParseXmlIntoArgs;\n      }\n    | CONGIG_DIR_SEC_TMP_DIR\n      {\n/* Parser error disabled to avoid breaking default installations with modsecurity.conf-recommended\n        std::stringstream ss;\n        ss << \"As of ModSecurity version 3.0, SecTmpDir is no longer supported.\";\n        ss << \" Instead, you can use your web server configurations to control when\";\n        ss << \"and where to swap. ModSecurity will follow the web server decision.\";\n        driver.error(@0, ss.str());\n        YYERROR;\n*/\n      }\n    | CONGIG_DIR_SEC_DATA_DIR\n/* Parser error disabled to avoid breaking default installations with modsecurity.conf-recommended\n        std::stringstream ss;\n        ss << \"SecDataDir is not currently supported.\";\n        ss << \" Collections are kept in memory (in_memory-per_process) for now.\";\n        ss << \" When using a backend such as LMDB, temp data path is currently defined by the backend.\";\n        driver.error(@0, ss.str());\n        YYERROR;\n*/\n    | CONGIG_DIR_SEC_ARG_SEP\n    | CONGIG_DIR_SEC_COOKIE_FORMAT\n      {\n        if (atoi($1.c_str()) == 1) {\n          driver.error(@0, \"SecCookieFormat 1 is not yet supported.\");\n          YYERROR;\n        }\n      }\n    | CONFIG_SEC_COOKIEV0_SEPARATOR\n      {\n        driver.error(@0, \"SecCookieV0Separator is not yet supported.\");\n        YYERROR;\n      }\n    | CONGIG_DIR_SEC_STATUS_ENGINE\n/* Parser error disabled to avoid breaking default installations with modsecurity.conf-recommended\n        driver.error(@0, \"SecStatusEngine is not yet supported.\");\n        YYERROR;\n*/\n    | CONFIG_DIR_UNICODE_MAP_FILE\n      {\n        std::string error;\n        std::vector<std::string> param;\n        double num = 0;\n        std::string f;\n        std::string file;\n        std::string err;\n        param = utils::string::ssplit($1, ' ');\n        if (param.size() <= 1) {\n            std::stringstream ss;\n            ss << \"Failed to process unicode map, missing \";\n            ss << \"parameter: \" << $1 << \" \";\n            driver.error(@0, ss.str());\n            YYERROR;\n        }\n\n        try {\n            num = std::stod(param.back());\n        } catch (...) {\n            std::stringstream ss;\n            ss << \"Failed to process unicode map, last parameter is \";\n            ss << \"expected to be a number: \" << param.back() << \" \";\n            driver.error(@0, ss.str());\n            YYERROR;\n        }\n        param.pop_back();\n\n        while (param.size() > 0) {\n            if (f.empty()) {\n                f = param.back();\n            } else {\n                f = param.back() + \" \" + f;\n            }\n            param.pop_back();\n        }\n\n        file = modsecurity::utils::find_resource(f, *@1.end.filename, &err);\n        if (file.empty()) {\n            std::stringstream ss;\n            ss << \"Failed to locate the unicode map file from: \" << f << \" \";\n            ss << err;\n            driver.error(@0, ss.str());\n            YYERROR;\n        }\n\n        ConfigUnicodeMap::loadConfig(file, num, &driver, &error);\n\n        if (!error.empty()) {\n            driver.error(@0, error);\n            YYERROR;\n        }\n\n      }\n    | CONFIG_SEC_COLLECTION_TIMEOUT\n      {\n/* Parser error disabled to avoid breaking default CRS installations with crs-setup.conf-recommended\n        driver.error(@0, \"SecCollectionTimeout is not yet supported.\");\n        YYERROR;\n*/\n      }\n    | CONFIG_SEC_HTTP_BLKEY\n      {\n        driver.m_httpblKey.m_set = true;\n        driver.m_httpblKey.m_value = $1;\n      }\n    ;\n\nvariables:\n    variables_pre_process\n      {\n        std::unique_ptr<std::vector<std::unique_ptr<Variable> > > originalList = std::move($1);\n        std::unique_ptr<std::vector<std::unique_ptr<Variable>>> newList(new std::vector<std::unique_ptr<Variable>>());\n        std::unique_ptr<std::vector<std::unique_ptr<Variable>>> newNewList(new std::vector<std::unique_ptr<Variable>>());\n        std::unique_ptr<std::vector<std::unique_ptr<Variable>>> exclusionVars(new std::vector<std::unique_ptr<Variable>>());\n        while (!originalList->empty()) {\n            std::unique_ptr<Variable> var = std::move(originalList->back());\n            originalList->pop_back();\n            if (dynamic_cast<VariableModificatorExclusion*>(var.get())) {\n                exclusionVars->push_back(std::move(var));\n            } else {\n                newList->push_back(std::move(var));\n            }\n        }\n\n        while (!newList->empty()) {\n            bool doNotAdd = false;\n            std::unique_ptr<Variable> var = std::move(newList->back());\n            newList->pop_back();\n            for (auto &i : *exclusionVars) {\n                if (*var == *i) {\n                    doNotAdd = true;\n                }\n                if (i->belongsToCollection(var.get())) {\n                    var->addsKeyExclusion(i.get());\n                }\n            }\n            if (!doNotAdd) {\n                newNewList->push_back(std::move(var));\n            }\n        }\n        $$ = std::move(newNewList);\n      }\n    ;\n\nvariables_pre_process:\n    variables_may_be_quoted\n      {\n        $$ = std::move($1);\n      }\n    | QUOTATION_MARK variables_may_be_quoted QUOTATION_MARK\n      {\n        $$ = std::move($2);\n      }\n    ;\n\nvariables_may_be_quoted:\n    variables_may_be_quoted PIPE var\n      {\n        $1->push_back(std::move($3));\n        $$ = std::move($1);\n      }\n    | variables_may_be_quoted PIPE VAR_EXCLUSION var\n      {\n        std::unique_ptr<Variable> c(new VariableModificatorExclusion(std::move($4)));\n        $1->push_back(std::move(c));\n        $$ = std::move($1);\n      }\n    | variables_may_be_quoted PIPE VAR_COUNT var\n      {\n        std::unique_ptr<Variable> c(new VariableModificatorCount(std::move($4)));\n        $1->push_back(std::move(c));\n        $$ = std::move($1);\n      }\n    | var\n      {\n        std::unique_ptr<std::vector<std::unique_ptr<Variable>>> b(new std::vector<std::unique_ptr<Variable>>());\n        b->push_back(std::move($1));\n        $$ = std::move(b);\n      }\n    | VAR_EXCLUSION var\n      {\n        std::unique_ptr<std::vector<std::unique_ptr<Variable>>> b(new std::vector<std::unique_ptr<Variable>>());\n        std::unique_ptr<Variable> c(new VariableModificatorExclusion(std::move($2)));\n        b->push_back(std::move(c));\n        $$ = std::move(b);\n      }\n    | VAR_COUNT var\n      {\n        std::unique_ptr<std::vector<std::unique_ptr<Variable>>> b(new std::vector<std::unique_ptr<Variable>>());\n        std::unique_ptr<Variable> c(new VariableModificatorCount(std::move($2)));\n        b->push_back(std::move(c));\n        $$ = std::move(b);\n      }\n    ;\n\nvar:\n    VARIABLE_ARGS DICT_ELEMENT\n      {\n        VARIABLE_CONTAINER($$, new variables::Args_DictElement($2));\n      }\n    | VARIABLE_ARGS DICT_ELEMENT_REGEXP\n      {\n        VARIABLE_CONTAINER($$, new variables::Args_DictElementRegexp($2));\n      }\n    | VARIABLE_ARGS\n      {\n        VARIABLE_CONTAINER($$, new variables::Args_NoDictElement());\n      }\n    | VARIABLE_ARGS_POST DICT_ELEMENT\n      {\n        VARIABLE_CONTAINER($$, new variables::ArgsPost_DictElement($2));\n      }\n    | VARIABLE_ARGS_POST DICT_ELEMENT_REGEXP\n      {\n        VARIABLE_CONTAINER($$, new variables::ArgsPost_DictElementRegexp($2));\n      }\n    | VARIABLE_ARGS_POST\n      {\n        VARIABLE_CONTAINER($$, new variables::ArgsPost_NoDictElement());\n      }\n    | VARIABLE_ARGS_GET DICT_ELEMENT\n      {\n        VARIABLE_CONTAINER($$, new variables::ArgsGet_DictElement($2));\n      }\n    | VARIABLE_ARGS_GET DICT_ELEMENT_REGEXP\n      {\n        VARIABLE_CONTAINER($$, new variables::ArgsGet_DictElementRegexp($2));\n      }\n    | VARIABLE_ARGS_GET\n      {\n        VARIABLE_CONTAINER($$, new variables::ArgsGet_NoDictElement());\n      }\n    | VARIABLE_FILES_SIZES DICT_ELEMENT\n      {\n        VARIABLE_CONTAINER($$, new variables::FilesSizes_DictElement($2));\n      }\n    | VARIABLE_FILES_SIZES DICT_ELEMENT_REGEXP\n      {\n        VARIABLE_CONTAINER($$, new variables::FilesSizes_DictElementRegexp($2));\n      }\n    | VARIABLE_FILES_SIZES\n      {\n        VARIABLE_CONTAINER($$, new variables::FilesSizes_NoDictElement());\n      }\n    | VARIABLE_FILES_NAMES DICT_ELEMENT\n      {\n        VARIABLE_CONTAINER($$, new variables::FilesNames_DictElement($2));\n      }\n    | VARIABLE_FILES_NAMES DICT_ELEMENT_REGEXP\n      {\n        VARIABLE_CONTAINER($$, new variables::FilesNames_DictElementRegexp($2));\n      }\n    | VARIABLE_FILES_NAMES\n      {\n        VARIABLE_CONTAINER($$, new variables::FilesNames_NoDictElement());\n      }\n    | VARIABLE_FILES_TMP_CONTENT DICT_ELEMENT\n      {\n        VARIABLE_CONTAINER($$, new variables::FilesTmpContent_DictElement($2));\n      }\n    | VARIABLE_FILES_TMP_CONTENT DICT_ELEMENT_REGEXP\n      {\n        VARIABLE_CONTAINER($$, new variables::FilesTmpContent_DictElementRegexp($2));\n      }\n    | VARIABLE_FILES_TMP_CONTENT\n      {\n        VARIABLE_CONTAINER($$, new variables::FilesTmpContent_NoDictElement());\n      }\n    | VARIABLE_MULTIPART_FILENAME DICT_ELEMENT\n      {\n        VARIABLE_CONTAINER($$, new variables::MultiPartFileName_DictElement($2));\n      }\n    | VARIABLE_MULTIPART_FILENAME DICT_ELEMENT_REGEXP\n      {\n        VARIABLE_CONTAINER($$, new variables::MultiPartFileName_DictElementRegexp($2));\n      }\n    | VARIABLE_MULTIPART_FILENAME\n      {\n        VARIABLE_CONTAINER($$, new variables::MultiPartFileName_NoDictElement());\n      }\n    | VARIABLE_MULTIPART_NAME DICT_ELEMENT\n      {\n        VARIABLE_CONTAINER($$, new variables::MultiPartName_DictElement($2));\n      }\n    | VARIABLE_MULTIPART_NAME DICT_ELEMENT_REGEXP\n      {\n        VARIABLE_CONTAINER($$, new variables::MultiPartName_DictElementRegexp($2));\n      }\n    | VARIABLE_MULTIPART_NAME\n      {\n        VARIABLE_CONTAINER($$, new variables::MultiPartName_NoDictElement());\n      }\n    | VARIABLE_MATCHED_VARS_NAMES DICT_ELEMENT\n      {\n        VARIABLE_CONTAINER($$, new variables::MatchedVarsNames_DictElement($2));\n      }\n    | VARIABLE_MATCHED_VARS_NAMES DICT_ELEMENT_REGEXP\n      {\n        VARIABLE_CONTAINER($$, new variables::MatchedVarsNames_DictElementRegexp($2));\n      }\n    | VARIABLE_MATCHED_VARS_NAMES\n      {\n        VARIABLE_CONTAINER($$, new variables::MatchedVarsNames_NoDictElement());\n      }\n    | VARIABLE_MATCHED_VARS DICT_ELEMENT\n      {\n        VARIABLE_CONTAINER($$, new variables::MatchedVars_DictElement($2));\n      }\n    | VARIABLE_MATCHED_VARS DICT_ELEMENT_REGEXP\n      {\n        VARIABLE_CONTAINER($$, new variables::MatchedVars_DictElementRegexp($2));\n      }\n    | VARIABLE_MATCHED_VARS\n      {\n        VARIABLE_CONTAINER($$, new variables::MatchedVars_NoDictElement());\n      }\n    | VARIABLE_FILES DICT_ELEMENT\n      {\n        VARIABLE_CONTAINER($$, new variables::Files_DictElement($2));\n      }\n    | VARIABLE_FILES DICT_ELEMENT_REGEXP\n      {\n        VARIABLE_CONTAINER($$, new variables::Files_DictElementRegexp($2));\n      }\n    | VARIABLE_FILES\n      {\n        VARIABLE_CONTAINER($$, new variables::Files_NoDictElement());\n      }\n    | VARIABLE_REQUEST_COOKIES DICT_ELEMENT\n      {\n        VARIABLE_CONTAINER($$, new variables::RequestCookies_DictElement($2));\n      }\n    | VARIABLE_REQUEST_COOKIES DICT_ELEMENT_REGEXP\n      {\n        VARIABLE_CONTAINER($$, new variables::RequestCookies_DictElementRegexp($2));\n      }\n    | VARIABLE_REQUEST_COOKIES\n      {\n        VARIABLE_CONTAINER($$, new variables::RequestCookies_NoDictElement());\n      }\n    | VARIABLE_REQUEST_HEADERS DICT_ELEMENT\n      {\n        VARIABLE_CONTAINER($$, new variables::RequestHeaders_DictElement($2));\n      }\n    | VARIABLE_REQUEST_HEADERS DICT_ELEMENT_REGEXP\n      {\n        VARIABLE_CONTAINER($$, new variables::RequestHeaders_DictElementRegexp($2));\n      }\n    | VARIABLE_REQUEST_HEADERS\n      {\n        VARIABLE_CONTAINER($$, new variables::RequestHeaders_NoDictElement());\n      }\n    | VARIABLE_RESPONSE_HEADERS DICT_ELEMENT\n      {\n        VARIABLE_CONTAINER($$, new variables::ResponseHeaders_DictElement($2));\n      }\n    | VARIABLE_RESPONSE_HEADERS DICT_ELEMENT_REGEXP\n      {\n        VARIABLE_CONTAINER($$, new variables::ResponseHeaders_DictElementRegexp($2));\n      }\n    | VARIABLE_RESPONSE_HEADERS\n      {\n        VARIABLE_CONTAINER($$, new variables::ResponseHeaders_NoDictElement());\n      }\n    | VARIABLE_GEO DICT_ELEMENT\n      {\n        VARIABLE_CONTAINER($$, new variables::Geo_DictElement($2));\n      }\n    | VARIABLE_GEO DICT_ELEMENT_REGEXP\n      {\n        VARIABLE_CONTAINER($$, new variables::Geo_DictElementRegexp($2));\n      }\n    | VARIABLE_GEO\n      {\n        VARIABLE_CONTAINER($$, new variables::Geo_NoDictElement());\n      }\n    | VARIABLE_REQUEST_COOKIES_NAMES DICT_ELEMENT\n      {\n        VARIABLE_CONTAINER($$, new variables::RequestCookiesNames_DictElement($2));\n      }\n    | VARIABLE_REQUEST_COOKIES_NAMES DICT_ELEMENT_REGEXP\n      {\n        VARIABLE_CONTAINER($$, new variables::RequestCookiesNames_DictElementRegexp($2));\n      }\n    | VARIABLE_REQUEST_COOKIES_NAMES\n      {\n        VARIABLE_CONTAINER($$, new variables::RequestCookiesNames_NoDictElement());\n      }\n    | VARIABLE_MULTIPART_PART_HEADERS DICT_ELEMENT\n      {\n        VARIABLE_CONTAINER($$, new variables::MultipartPartHeaders_DictElement($2));\n      }\n    | VARIABLE_MULTIPART_PART_HEADERS DICT_ELEMENT_REGEXP\n      {\n        VARIABLE_CONTAINER($$, new variables::MultipartPartHeaders_DictElementRegexp($2));\n      }\n    | VARIABLE_MULTIPART_PART_HEADERS\n      {\n        VARIABLE_CONTAINER($$, new variables::MultipartPartHeaders_NoDictElement());\n      }\n    | VARIABLE_RULE DICT_ELEMENT\n      {\n        VARIABLE_CONTAINER($$, new variables::Rule_DictElement($2));\n      }\n    | VARIABLE_RULE DICT_ELEMENT_REGEXP\n      {\n        VARIABLE_CONTAINER($$, new variables::Rule_DictElementRegexp($2));\n      }\n    | VARIABLE_RULE\n      {\n        VARIABLE_CONTAINER($$, new variables::Rule_NoDictElement());\n      }\n    | RUN_TIME_VAR_ENV DICT_ELEMENT\n      {\n        VARIABLE_CONTAINER($$, new variables::Env(\"ENV:\" + $2));\n      }\n    | RUN_TIME_VAR_ENV DICT_ELEMENT_REGEXP\n      {\n        VARIABLE_CONTAINER($$, new variables::Env(\"ENV:\" + $2));\n      }\n    | RUN_TIME_VAR_ENV\n      {\n        VARIABLE_CONTAINER($$, new variables::Env(\"ENV\"));\n      }\n    | RUN_TIME_VAR_XML DICT_ELEMENT\n      {\n        VARIABLE_CONTAINER($$, new variables::XML(\"XML:\" + $2));\n      }\n    | RUN_TIME_VAR_XML DICT_ELEMENT_REGEXP\n      {\n        VARIABLE_CONTAINER($$, new variables::XML(\"XML:\" + $2));\n      }\n    | RUN_TIME_VAR_XML\n      {\n        VARIABLE_CONTAINER($$, new variables::XML_NoDictElement());\n      }\n    | VARIABLE_FILES_TMP_NAMES DICT_ELEMENT\n      {\n        VARIABLE_CONTAINER($$, new variables::FilesTmpNames_DictElement($2));\n      }\n    | VARIABLE_FILES_TMP_NAMES DICT_ELEMENT_REGEXP\n      {\n        VARIABLE_CONTAINER($$, new variables::FilesTmpNames_DictElementRegexp($2));\n      }\n    | VARIABLE_FILES_TMP_NAMES\n      {\n        VARIABLE_CONTAINER($$, new variables::FilesTmpNames_NoDictElement());\n      }\n    | VARIABLE_RESOURCE run_time_string\n      {\n        VARIABLE_CONTAINER($$, new variables::Resource_DynamicElement(std::move($2)));\n      }\n    | VARIABLE_RESOURCE DICT_ELEMENT\n      {\n        VARIABLE_CONTAINER($$, new variables::Resource_DictElement($2));\n      }\n    | VARIABLE_RESOURCE DICT_ELEMENT_REGEXP\n      {\n        VARIABLE_CONTAINER($$, new variables::Resource_DictElementRegexp($2));\n      }\n    | VARIABLE_RESOURCE\n      {\n        VARIABLE_CONTAINER($$, new variables::Resource_NoDictElement());\n      }\n    | VARIABLE_IP run_time_string\n      {\n        VARIABLE_CONTAINER($$, new variables::Ip_DynamicElement(std::move($2)));\n      }\n    | VARIABLE_IP DICT_ELEMENT\n      {\n        VARIABLE_CONTAINER($$, new variables::Ip_DictElement($2));\n      }\n    | VARIABLE_IP DICT_ELEMENT_REGEXP\n      {\n        VARIABLE_CONTAINER($$, new variables::Ip_DictElementRegexp($2));\n      }\n    | VARIABLE_IP\n      {\n        VARIABLE_CONTAINER($$, new variables::Ip_NoDictElement());\n      }\n    | VARIABLE_GLOBAL run_time_string\n      {\n        VARIABLE_CONTAINER($$, new variables::Global_DynamicElement(std::move($2)));\n      }\n    | VARIABLE_GLOBAL DICT_ELEMENT\n      {\n        VARIABLE_CONTAINER($$, new variables::Global_DictElement($2));\n      }\n    | VARIABLE_GLOBAL DICT_ELEMENT_REGEXP\n      {\n        VARIABLE_CONTAINER($$, new variables::Global_DictElementRegexp($2));\n      }\n    | VARIABLE_GLOBAL\n      {\n        VARIABLE_CONTAINER($$, new variables::Global_NoDictElement());\n      }\n    | VARIABLE_USER run_time_string\n      {\n        VARIABLE_CONTAINER($$, new variables::User_DynamicElement(std::move($2)));\n      }\n    | VARIABLE_USER DICT_ELEMENT\n      {\n        VARIABLE_CONTAINER($$, new variables::User_DictElement($2));\n      }\n    | VARIABLE_USER DICT_ELEMENT_REGEXP\n      {\n        VARIABLE_CONTAINER($$, new variables::User_DictElementRegexp($2));\n      }\n    | VARIABLE_USER\n      {\n        VARIABLE_CONTAINER($$, new variables::User_NoDictElement());\n      }\n    | VARIABLE_TX run_time_string\n      {\n        VARIABLE_CONTAINER($$, new variables::Tx_DynamicElement(std::move($2)));\n      }\n    | VARIABLE_TX DICT_ELEMENT\n      {\n        VARIABLE_CONTAINER($$, new variables::Tx_DictElement($2));\n      }\n    | VARIABLE_TX DICT_ELEMENT_REGEXP\n      {\n        VARIABLE_CONTAINER($$, new variables::Tx_DictElementRegexp($2));\n      }\n    | VARIABLE_TX\n      {\n        VARIABLE_CONTAINER($$, new variables::Tx_NoDictElement());\n      }\n    | VARIABLE_SESSION run_time_string\n      {\n        VARIABLE_CONTAINER($$, new variables::Session_DynamicElement(std::move($2)));\n      }\n    | VARIABLE_SESSION DICT_ELEMENT\n      {\n        VARIABLE_CONTAINER($$, new variables::Session_DictElement($2));\n      }\n    | VARIABLE_SESSION DICT_ELEMENT_REGEXP\n      {\n        VARIABLE_CONTAINER($$, new variables::Session_DictElementRegexp($2));\n      }\n    | VARIABLE_SESSION\n      {\n        VARIABLE_CONTAINER($$, new variables::Session_NoDictElement());\n      }\n    | VARIABLE_ARGS_NAMES DICT_ELEMENT\n      {\n        VARIABLE_CONTAINER($$, new variables::ArgsNames_DictElement($2));\n      }\n    | VARIABLE_ARGS_NAMES DICT_ELEMENT_REGEXP\n      {\n        VARIABLE_CONTAINER($$, new variables::ArgsNames_DictElementRegexp($2));\n      }\n    | VARIABLE_ARGS_NAMES\n      {\n        VARIABLE_CONTAINER($$, new variables::ArgsNames_NoDictElement());\n      }\n    | VARIABLE_ARGS_GET_NAMES DICT_ELEMENT\n      {\n        VARIABLE_CONTAINER($$, new variables::ArgsGetNames_DictElement($2));\n      }\n    | VARIABLE_ARGS_GET_NAMES DICT_ELEMENT_REGEXP\n      {\n        VARIABLE_CONTAINER($$, new variables::ArgsGetNames_DictElementRegexp($2));\n      }\n    | VARIABLE_ARGS_GET_NAMES\n      {\n        VARIABLE_CONTAINER($$, new variables::ArgsGetNames_NoDictElement());\n      }\n\n    | VARIABLE_ARGS_POST_NAMES DICT_ELEMENT\n      {\n        VARIABLE_CONTAINER($$, new variables::ArgsPostNames_DictElement($2));\n      }\n    | VARIABLE_ARGS_POST_NAMES DICT_ELEMENT_REGEXP\n      {\n        VARIABLE_CONTAINER($$, new variables::ArgsPostNames_DictElementRegexp($2));\n      }\n    | VARIABLE_ARGS_POST_NAMES\n      {\n        VARIABLE_CONTAINER($$, new variables::ArgsPostNames_NoDictElement());\n      }\n\n    | VARIABLE_REQUEST_HEADERS_NAMES DICT_ELEMENT\n      {\n        VARIABLE_CONTAINER($$, new variables::RequestHeadersNames_DictElement($2));\n      }\n    | VARIABLE_REQUEST_HEADERS_NAMES DICT_ELEMENT_REGEXP\n      {\n        VARIABLE_CONTAINER($$, new variables::RequestHeadersNames_DictElementRegexp($2));\n      }\n    | VARIABLE_REQUEST_HEADERS_NAMES\n      {\n        VARIABLE_CONTAINER($$, new variables::RequestHeadersNames_NoDictElement());\n      }\n\n    | VARIABLE_RESPONSE_CONTENT_TYPE\n      {\n        VARIABLE_CONTAINER($$, new variables::ResponseContentType());\n      }\n\n    | VARIABLE_RESPONSE_HEADERS_NAMES DICT_ELEMENT\n      {\n        VARIABLE_CONTAINER($$, new variables::ResponseHeadersNames_DictElement($2));\n      }\n    | VARIABLE_RESPONSE_HEADERS_NAMES DICT_ELEMENT_REGEXP\n      {\n        VARIABLE_CONTAINER($$, new variables::ResponseHeadersNames_DictElementRegexp($2));\n      }\n    | VARIABLE_RESPONSE_HEADERS_NAMES\n      {\n        VARIABLE_CONTAINER($$, new variables::ResponseHeadersNames_NoDictElement());\n      }\n    | VARIABLE_ARGS_COMBINED_SIZE\n      {\n        VARIABLE_CONTAINER($$, new variables::ArgsCombinedSize());\n      }\n   | VARIABLE_AUTH_TYPE\n      {\n        VARIABLE_CONTAINER($$, new variables::AuthType());\n      }\n    | VARIABLE_FILES_COMBINED_SIZE\n      {\n        VARIABLE_CONTAINER($$, new variables::FilesCombinedSize());\n      }\n    | VARIABLE_FULL_REQUEST\n      {\n        VARIABLE_CONTAINER($$, new variables::FullRequest());\n      }\n    | VARIABLE_FULL_REQUEST_LENGTH\n      {\n        VARIABLE_CONTAINER($$, new variables::FullRequestLength());\n      }\n    | VARIABLE_INBOUND_DATA_ERROR\n      {\n        VARIABLE_CONTAINER($$, new variables::InboundDataError());\n      }\n    | VARIABLE_MATCHED_VAR\n      {\n        VARIABLE_CONTAINER($$, new variables::MatchedVar());\n      }\n    | VARIABLE_MATCHED_VAR_NAME\n      {\n        VARIABLE_CONTAINER($$, new variables::MatchedVarName());\n      }\n    | VARIABLE_MSC_PCRE_ERROR\n      {\n        VARIABLE_CONTAINER($$, new variables::MscPcreError());\n      }\n    | VARIABLE_MSC_PCRE_LIMITS_EXCEEDED\n      {\n        VARIABLE_CONTAINER($$, new variables::MscPcreLimitsExceeded());\n      }\n    | VARIABLE_MULTIPART_BOUNDARY_QUOTED\n      {\n        VARIABLE_CONTAINER($$, new variables::MultipartBoundaryQuoted());\n      }\n    | VARIABLE_MULTIPART_BOUNDARY_WHITESPACE\n      {\n        VARIABLE_CONTAINER($$, new variables::MultipartBoundaryWhiteSpace());\n      }\n    | VARIABLE_MULTIPART_CRLF_LF_LINES\n      {\n        VARIABLE_CONTAINER($$, new variables::MultipartCrlfLFLines());\n      }\n    | VARIABLE_MULTIPART_DATA_AFTER\n      {\n        VARIABLE_CONTAINER($$, new variables::MultipartDateAfter());\n      }\n    | VARIABLE_MULTIPART_DATA_BEFORE\n      {\n        VARIABLE_CONTAINER($$, new variables::MultipartDateBefore());\n      }\n    | VARIABLE_MULTIPART_FILE_LIMIT_EXCEEDED\n      {\n        VARIABLE_CONTAINER($$, new variables::MultipartFileLimitExceeded());\n      }\n    | VARIABLE_MULTIPART_HEADER_FOLDING\n      {\n        VARIABLE_CONTAINER($$, new variables::MultipartHeaderFolding());\n      }\n    | VARIABLE_MULTIPART_INVALID_HEADER_FOLDING\n      {\n        VARIABLE_CONTAINER($$, new variables::MultipartInvalidHeaderFolding());\n      }\n    | VARIABLE_MULTIPART_INVALID_PART\n      {\n        VARIABLE_CONTAINER($$, new variables::MultipartInvalidPart());\n      }\n    | VARIABLE_MULTIPART_INVALID_QUOTING\n      {\n        VARIABLE_CONTAINER($$, new variables::MultipartInvalidQuoting());\n      }\n    | VARIABLE_MULTIPART_LF_LINE\n      {\n        VARIABLE_CONTAINER($$, new variables::MultipartLFLine());\n      }\n    | VARIABLE_MULTIPART_MISSING_SEMICOLON\n      {\n        VARIABLE_CONTAINER($$, new variables::MultipartMissingSemicolon());\n      }\n    | VARIABLE_MULTIPART_SEMICOLON_MISSING\n      {\n        VARIABLE_CONTAINER($$, new variables::MultipartMissingSemicolon());\n      }\n    | VARIABLE_MULTIPART_STRICT_ERROR\n      {\n        VARIABLE_CONTAINER($$, new variables::MultipartStrictError());\n      }\n    | VARIABLE_MULTIPART_UNMATCHED_BOUNDARY\n      {\n        VARIABLE_CONTAINER($$, new variables::MultipartUnmatchedBoundary());\n      }\n    | VARIABLE_OUTBOUND_DATA_ERROR\n      {\n        VARIABLE_CONTAINER($$, new variables::OutboundDataError());\n      }\n    | VARIABLE_PATH_INFO\n      {\n        VARIABLE_CONTAINER($$, new variables::PathInfo());\n      }\n    | VARIABLE_QUERY_STRING\n      {\n        VARIABLE_CONTAINER($$, new variables::QueryString());\n      }\n    | VARIABLE_REMOTE_ADDR\n      {\n        VARIABLE_CONTAINER($$, new variables::RemoteAddr());\n      }\n    | VARIABLE_REMOTE_HOST\n      {\n        VARIABLE_CONTAINER($$, new variables::RemoteHost());\n      }\n    | VARIABLE_REMOTE_PORT\n      {\n        VARIABLE_CONTAINER($$, new variables::RemotePort());\n      }\n    | VARIABLE_REQBODY_ERROR\n      {\n        VARIABLE_CONTAINER($$, new variables::ReqbodyError());\n      }\n    | VARIABLE_REQBODY_ERROR_MSG\n      {\n        VARIABLE_CONTAINER($$, new variables::ReqbodyErrorMsg());\n      }\n    | VARIABLE_REQBODY_PROCESSOR\n      {\n        VARIABLE_CONTAINER($$, new variables::ReqbodyProcessor());\n      }\n    | VARIABLE_REQBODY_PROCESSOR_ERROR\n      {\n        VARIABLE_CONTAINER($$, new variables::ReqbodyProcessorError());\n      }\n    | VARIABLE_REQBODY_PROCESSOR_ERROR_MSG\n      {\n        VARIABLE_CONTAINER($$, new variables::ReqbodyProcessorErrorMsg());\n      }\n    | VARIABLE_REQUEST_BASENAME\n      {\n        VARIABLE_CONTAINER($$, new variables::RequestBasename());\n      }\n    | VARIABLE_REQUEST_BODY\n      {\n        VARIABLE_CONTAINER($$, new variables::RequestBody());\n      }\n    | VARIABLE_REQUEST_BODY_LENGTH\n      {\n        VARIABLE_CONTAINER($$, new variables::RequestBodyLength());\n      }\n    | VARIABLE_REQUEST_FILE_NAME\n      {\n        VARIABLE_CONTAINER($$, new variables::RequestFilename());\n      }\n    | VARIABLE_REQUEST_LINE\n      {\n        VARIABLE_CONTAINER($$, new variables::RequestLine());\n      }\n    | VARIABLE_REQUEST_METHOD\n      {\n        VARIABLE_CONTAINER($$, new variables::RequestMethod());\n      }\n    | VARIABLE_REQUEST_PROTOCOL\n      {\n        VARIABLE_CONTAINER($$, new variables::RequestProtocol());\n      }\n    | VARIABLE_REQUEST_URI\n      {\n        VARIABLE_CONTAINER($$, new variables::RequestURI());\n      }\n    | VARIABLE_REQUEST_URI_RAW\n      {\n        VARIABLE_CONTAINER($$, new variables::RequestURIRaw());\n      }\n    | VARIABLE_RESPONSE_BODY\n      {\n        VARIABLE_CONTAINER($$, new variables::ResponseBody());\n      }\n    | VARIABLE_RESPONSE_CONTENT_LENGTH\n      {\n        VARIABLE_CONTAINER($$, new variables::ResponseContentLength());\n      }\n    | VARIABLE_RESPONSE_PROTOCOL\n      {\n        VARIABLE_CONTAINER($$, new variables::ResponseProtocol());\n      }\n    | VARIABLE_RESPONSE_STATUS\n      {\n        VARIABLE_CONTAINER($$, new variables::ResponseStatus());\n      }\n    | VARIABLE_SERVER_ADDR\n      {\n        VARIABLE_CONTAINER($$, new variables::ServerAddr());\n      }\n    | VARIABLE_SERVER_NAME\n      {\n        VARIABLE_CONTAINER($$, new variables::ServerName());\n      }\n    | VARIABLE_SERVER_PORT\n      {\n        VARIABLE_CONTAINER($$, new variables::ServerPort());\n      }\n    | VARIABLE_SESSION_ID\n      {\n        VARIABLE_CONTAINER($$, new variables::SessionID());\n      }\n    | VARIABLE_UNIQUE_ID\n      {\n        VARIABLE_CONTAINER($$, new variables::UniqueID());\n      }\n    | VARIABLE_URL_ENCODED_ERROR\n      {\n        VARIABLE_CONTAINER($$, new variables::UrlEncodedError());\n      }\n    | VARIABLE_USER_ID\n      {\n        VARIABLE_CONTAINER($$, new variables::UserID());\n      }\n    | VARIABLE_STATUS\n      {\n        VARIABLE_CONTAINER($$, new variables::Status());\n      }\n    | VARIABLE_STATUS_LINE\n      {\n        VARIABLE_CONTAINER($$, new variables::Status());\n      }\n    | VARIABLE_WEB_APP_ID\n      {\n        VARIABLE_CONTAINER($$, new variables::WebAppId());\n      }\n    | RUN_TIME_VAR_DUR\n      {\n        std::string name($1);\n        char z = name.at(0);\n        std::unique_ptr<Variable> c(new Duration(name));\n        $$ = std::move(c);\n      }\n\n    | RUN_TIME_VAR_BLD\n      {\n        std::string name($1);\n        char z = name.at(0);\n        std::unique_ptr<Variable> c(new ModsecBuild(name));\n        $$ = std::move(c);\n      }\n    | RUN_TIME_VAR_HSV\n      {\n        std::string name($1);\n        char z = name.at(0);\n        std::unique_ptr<Variable> c(new HighestSeverity(name));\n        $$ = std::move(c);\n      }\n    | RUN_TIME_VAR_REMOTE_USER\n      {\n        std::string name($1);\n        char z = name.at(0);\n        std::unique_ptr<Variable> c(new RemoteUser(name));\n        $$ = std::move(c);\n      }\n    | RUN_TIME_VAR_TIME\n      {\n        std::string name($1);\n        char z = name.at(0);\n        std::unique_ptr<Variable> c(new Time(name));\n        $$ = std::move(c);\n      }\n    | RUN_TIME_VAR_TIME_DAY\n      {\n        std::string name($1);\n        char z = name.at(0);\n        std::unique_ptr<Variable> c(new TimeDay(name));\n        $$ = std::move(c);\n      }\n    | RUN_TIME_VAR_TIME_EPOCH\n      {\n        std::string name($1);\n        char z = name.at(0);\n        std::unique_ptr<Variable> c(new TimeEpoch(name));\n        $$ = std::move(c);\n      }\n    | RUN_TIME_VAR_TIME_HOUR\n      {\n        std::string name($1);\n        char z = name.at(0);\n        std::unique_ptr<Variable> c(new TimeHour(name));\n        $$ = std::move(c);\n      }\n    | RUN_TIME_VAR_TIME_MIN\n      {\n        std::string name($1);\n        char z = name.at(0);\n        std::unique_ptr<Variable> c(new TimeMin(name));\n        $$ = std::move(c);\n      }\n    | RUN_TIME_VAR_TIME_MON\n      {\n        std::string name($1);\n        char z = name.at(0);\n        std::unique_ptr<Variable> c(new TimeMon(name));\n        $$ = std::move(c);\n      }\n    | RUN_TIME_VAR_TIME_SEC\n      {\n        std::string name($1);\n        char z = name.at(0);\n            std::unique_ptr<Variable> c(new TimeSec(name));\n            $$ = std::move(c);\n      }\n    | RUN_TIME_VAR_TIME_WDAY\n      {\n        std::string name($1);\n        char z = name.at(0);\n        std::unique_ptr<Variable> c(new TimeWDay(name));\n        $$ = std::move(c);\n      }\n    | RUN_TIME_VAR_TIME_YEAR\n      {\n        std::string name($1);\n        char z = name.at(0);\n        std::unique_ptr<Variable> c(new TimeYear(name));\n        $$ = std::move(c);\n      }\n    ;\n\nact:\n    ACTION_ACCURACY\n      {\n        ACTION_CONTAINER($$, new actions::Accuracy($1));\n      }\n    | ACTION_ALLOW\n      {\n        ACTION_CONTAINER($$, new actions::disruptive::Allow($1));\n      }\n    | ACTION_APPEND\n      {\n        ACTION_NOT_SUPPORTED(\"Append\", @0);\n      }\n    | ACTION_AUDIT_LOG\n      {\n        ACTION_CONTAINER($$, new actions::AuditLog($1));\n      }\n    | ACTION_BLOCK\n      {\n        ACTION_CONTAINER($$, new actions::Block($1));\n      }\n    | ACTION_CAPTURE\n      {\n        ACTION_CONTAINER($$, new actions::Capture($1));\n      }\n    | ACTION_CHAIN\n      {\n        ACTION_CONTAINER($$, new actions::Chain($1));\n      }\n    | ACTION_CTL_AUDIT_ENGINE CONFIG_VALUE_ON\n      {\n        ACTION_CONTAINER($$, new actions::ctl::AuditEngine(\"ctl:auditengine=on\"));\n        driver.m_auditLog->setCtlAuditEngineActive();\n      }\n    | ACTION_CTL_AUDIT_ENGINE CONFIG_VALUE_OFF\n      {\n        ACTION_CONTAINER($$, new actions::ctl::AuditEngine(\"ctl:auditengine=off\"));\n      }\n    | ACTION_CTL_AUDIT_ENGINE CONFIG_VALUE_RELEVANT_ONLY\n      {\n        ACTION_CONTAINER($$, new actions::ctl::AuditEngine(\"ctl:auditengine=relevantonly\"));\n        driver.m_auditLog->setCtlAuditEngineActive();\n      }\n    | ACTION_CTL_AUDIT_LOG_PARTS\n      {\n        ACTION_CONTAINER($$, new actions::ctl::AuditLogParts($1));\n      }\n    | ACTION_CTL_BDY_JSON\n      {\n        ACTION_CONTAINER($$, new actions::ctl::RequestBodyProcessorJSON($1));\n      }\n    | ACTION_CTL_BDY_XML\n      {\n        ACTION_CONTAINER($$, new actions::ctl::RequestBodyProcessorXML($1));\n      }\n    | ACTION_CTL_BDY_URLENCODED\n      {\n        ACTION_CONTAINER($$, new actions::ctl::RequestBodyProcessorURLENCODED($1));\n      }\n    | ACTION_CTL_FORCE_REQ_BODY_VAR CONFIG_VALUE_ON\n      {\n        //ACTION_NOT_SUPPORTED(\"CtlForceReequestBody\", @0);\n        ACTION_CONTAINER($$, new actions::Action($1));\n      }\n    | ACTION_CTL_FORCE_REQ_BODY_VAR CONFIG_VALUE_OFF\n      {\n        //ACTION_NOT_SUPPORTED(\"CtlForceReequestBody\", @0);\n        ACTION_CONTAINER($$, new actions::Action($1));\n      }\n    | ACTION_CTL_PARSE_XML_INTO_ARGS CONFIG_VALUE_ON\n      {\n        ACTION_CONTAINER($$, new actions::ctl::ParseXmlIntoArgs(\"ctl:parseXmlIntoArgs=on\"));\n      }\n    | ACTION_CTL_PARSE_XML_INTO_ARGS CONFIG_VALUE_OFF\n      {\n        ACTION_CONTAINER($$, new actions::ctl::ParseXmlIntoArgs(\"ctl:parseXmlIntoArgs=off\"));\n      }\n    | ACTION_CTL_PARSE_XML_INTO_ARGS CONFIG_VALUE_ONLYARGS\n      {\n        ACTION_CONTAINER($$, new actions::ctl::ParseXmlIntoArgs(\"ctl:parseXmlIntoArgs=onlyargs\"));\n      }\n    | ACTION_CTL_REQUEST_BODY_ACCESS CONFIG_VALUE_ON\n      {\n        ACTION_CONTAINER($$, new actions::ctl::RequestBodyAccess($1 + \"true\"));\n      }\n    | ACTION_CTL_REQUEST_BODY_ACCESS CONFIG_VALUE_OFF\n      {\n        ACTION_CONTAINER($$, new actions::ctl::RequestBodyAccess($1 + \"false\"));\n      }\n    | ACTION_CTL_RULE_ENGINE CONFIG_VALUE_ON\n      {\n        ACTION_CONTAINER($$, new actions::ctl::RuleEngine(\"ctl:RuleEngine=on\"));\n      }\n    | ACTION_CTL_RULE_ENGINE CONFIG_VALUE_OFF\n      {\n        ACTION_CONTAINER($$, new actions::ctl::RuleEngine(\"ctl:RuleEngine=off\"));\n      }\n    | ACTION_CTL_RULE_ENGINE CONFIG_VALUE_DETC\n      {\n        ACTION_CONTAINER($$, new actions::ctl::RuleEngine(\"ctl:RuleEngine=detectiononly\"));\n      }\n    | ACTION_CTL_RULE_REMOVE_BY_ID\n      {\n        ACTION_CONTAINER($$, new actions::ctl::RuleRemoveById($1));\n      }\n    | ACTION_CTL_RULE_REMOVE_BY_TAG\n      {\n        ACTION_CONTAINER($$, new actions::ctl::RuleRemoveByTag($1));\n      }\n    | ACTION_CTL_RULE_REMOVE_TARGET_BY_ID\n      {\n        ACTION_CONTAINER($$, new actions::ctl::RuleRemoveTargetById($1));\n      }\n    | ACTION_CTL_RULE_REMOVE_TARGET_BY_TAG\n      {\n        ACTION_CONTAINER($$, new actions::ctl::RuleRemoveTargetByTag($1));\n      }\n    | ACTION_DENY\n      {\n        ACTION_CONTAINER($$, new actions::disruptive::Deny($1));\n      }\n    | ACTION_DEPRECATE_VAR\n      {\n        ACTION_NOT_SUPPORTED(\"DeprecateVar\", @0);\n      }\n    | ACTION_DROP\n      {\n        ACTION_CONTAINER($$, new actions::disruptive::Drop($1));\n      }\n    | ACTION_EXEC\n      {\n        ACTION_CONTAINER($$, new actions::Exec($1));\n      }\n    | ACTION_EXPIRE_VAR run_time_string\n      {\n        ACTION_CONTAINER($$, new actions::ExpireVar(std::move($2)));\n      }\n    | ACTION_ID\n      {\n        ACTION_CONTAINER($$, new actions::RuleId($1));\n      }\n    | ACTION_INITCOL run_time_string\n      {\n        ACTION_CONTAINER($$, new actions::InitCol($1, std::move($2)));\n      }\n    | ACTION_LOG_DATA run_time_string\n      {\n        ACTION_CONTAINER($$, new actions::LogData(std::move($2)));\n      }\n    | ACTION_LOG\n      {\n        ACTION_CONTAINER($$, new actions::Log($1));\n      }\n    | ACTION_MATURITY\n      {\n        ACTION_CONTAINER($$, new actions::Maturity($1));\n      }\n    | ACTION_MSG run_time_string\n      {\n        ACTION_CONTAINER($$, new actions::Msg(std::move($2)));\n      }\n    | ACTION_MULTI_MATCH\n      {\n        ACTION_CONTAINER($$, new actions::MultiMatch($1));\n      }\n    | ACTION_NO_AUDIT_LOG\n      {\n        ACTION_CONTAINER($$, new actions::NoAuditLog($1));\n      }\n    | ACTION_NO_LOG\n      {\n        ACTION_CONTAINER($$, new actions::NoLog($1));\n      }\n    | ACTION_PASS\n      {\n        ACTION_CONTAINER($$, new actions::disruptive::Pass($1));\n      }\n    | ACTION_PAUSE\n      {\n        ACTION_NOT_SUPPORTED(\"Pause\", @0);\n      }\n    | ACTION_PHASE\n      {\n        ACTION_CONTAINER($$, new actions::Phase($1));\n      }\n    | ACTION_PREPEND\n      {\n        ACTION_NOT_SUPPORTED(\"Prepend\", @0);\n      }\n    | ACTION_PROXY\n      {\n        ACTION_NOT_SUPPORTED(\"Proxy\", @0);\n      }\n    | ACTION_REDIRECT run_time_string\n      {\n        ACTION_CONTAINER($$, new actions::disruptive::Redirect(std::move($2)));\n      }\n    | ACTION_REV\n      {\n        ACTION_CONTAINER($$, new actions::Rev($1));\n      }\n    | ACTION_SANITISE_ARG\n      {\n        ACTION_NOT_SUPPORTED(\"SanitiseArg\", @0);\n      }\n    | ACTION_SANITISE_MATCHED\n      {\n        ACTION_NOT_SUPPORTED(\"SanitiseMatched\", @0);\n      }\n    | ACTION_SANITISE_MATCHED_BYTES\n      {\n        ACTION_NOT_SUPPORTED(\"SanitiseMatchedBytes\", @0);\n      }\n    | ACTION_SANITISE_REQUEST_HEADER\n      {\n        ACTION_NOT_SUPPORTED(\"SanitiseRequestHeader\", @0);\n      }\n    | ACTION_SANITISE_RESPONSE_HEADER\n      {\n        ACTION_NOT_SUPPORTED(\"SanitiseResponseHeader\", @0);\n      }\n    | ACTION_SETENV run_time_string\n      {\n        ACTION_CONTAINER($$, new actions::SetENV(std::move($2)));\n      }\n    | ACTION_SETRSC run_time_string\n      {\n        ACTION_CONTAINER($$, new actions::SetRSC(std::move($2)));\n      }\n    | ACTION_SETSID run_time_string\n      {\n        ACTION_CONTAINER($$, new actions::SetSID(std::move($2)));\n      }\n    | ACTION_SETUID run_time_string\n      {\n        ACTION_CONTAINER($$, new actions::SetUID(std::move($2)));\n      }\n    | ACTION_SETVAR setvar_action\n      {\n        $$ = std::move($2);\n      }\n    | ACTION_SEVERITY\n      {\n        ACTION_CONTAINER($$, new actions::Severity($1));\n      }\n    | ACTION_SKIP\n      {\n        ACTION_CONTAINER($$, new actions::Skip($1));\n      }\n    | ACTION_SKIP_AFTER\n      {\n        ACTION_CONTAINER($$, new actions::SkipAfter($1));\n      }\n    | ACTION_STATUS\n      {\n        ACTION_CONTAINER($$, new actions::data::Status($1));\n      }\n    | ACTION_TAG run_time_string\n      {\n        ACTION_CONTAINER($$, new actions::Tag(std::move($2)));\n      }\n    | ACTION_VER\n      {\n        ACTION_CONTAINER($$, new actions::Ver($1));\n      }\n    | ACTION_XMLNS\n      {\n        ACTION_CONTAINER($$, new actions::XmlNS($1));\n      }\n    | ACTION_TRANSFORMATION_PARITY_ZERO_7_BIT\n      {\n        ACTION_CONTAINER($$, new actions::transformations::ParityZero7bit($1));\n      }\n    | ACTION_TRANSFORMATION_PARITY_ODD_7_BIT\n      {\n        ACTION_CONTAINER($$, new actions::transformations::ParityOdd7bit($1));\n      }\n    | ACTION_TRANSFORMATION_PARITY_EVEN_7_BIT\n      {\n        ACTION_CONTAINER($$, new actions::transformations::ParityEven7bit($1));\n      }\n    | ACTION_TRANSFORMATION_SQL_HEX_DECODE\n      {\n        ACTION_CONTAINER($$, new actions::transformations::SqlHexDecode($1));\n      }\n      | ACTION_TRANSFORMATION_BASE_64_ENCODE\n      {\n        ACTION_CONTAINER($$, new actions::transformations::Base64Encode($1));\n      }\n    | ACTION_TRANSFORMATION_BASE_64_DECODE\n      {\n        ACTION_CONTAINER($$, new actions::transformations::Base64Decode($1));\n      }\n   | ACTION_TRANSFORMATION_BASE_64_DECODE_EXT\n      {\n        ACTION_CONTAINER($$, new actions::transformations::Base64DecodeExt($1));\n      }\n    | ACTION_TRANSFORMATION_CMD_LINE\n      {\n        ACTION_CONTAINER($$, new actions::transformations::CmdLine($1));\n      }\n    | ACTION_TRANSFORMATION_SHA1\n      {\n        ACTION_CONTAINER($$, new actions::transformations::Sha1($1));\n      }\n    | ACTION_TRANSFORMATION_MD5\n      {\n        ACTION_CONTAINER($$, new actions::transformations::Md5($1));\n      }\n    | ACTION_TRANSFORMATION_ESCAPE_SEQ_DECODE \n      {\n        ACTION_CONTAINER($$, new actions::transformations::EscapeSeqDecode($1));\n      }\n    | ACTION_TRANSFORMATION_HEX_ENCODE\n      {\n        ACTION_CONTAINER($$, new actions::transformations::HexEncode($1));\n      }\n    | ACTION_TRANSFORMATION_HEX_DECODE\n      {\n        ACTION_CONTAINER($$, new actions::transformations::HexDecode($1));\n      }\n    | ACTION_TRANSFORMATION_LOWERCASE\n      {\n        ACTION_CONTAINER($$, new actions::transformations::LowerCase($1));\n      }\n    | ACTION_TRANSFORMATION_UPPERCASE\n      {\n        ACTION_CONTAINER($$, new actions::transformations::UpperCase($1));\n      }\n    | ACTION_TRANSFORMATION_URL_DECODE_UNI\n      {\n        ACTION_CONTAINER($$, new actions::transformations::UrlDecodeUni($1));\n      }\n    | ACTION_TRANSFORMATION_URL_DECODE\n      {\n        ACTION_CONTAINER($$, new actions::transformations::UrlDecode($1));\n      }\n    | ACTION_TRANSFORMATION_URL_ENCODE\n      {\n        ACTION_CONTAINER($$, new actions::transformations::UrlEncode($1));\n      }\n    | ACTION_TRANSFORMATION_NONE\n      {\n        ACTION_CONTAINER($$, new actions::transformations::None($1));\n      }\n    | ACTION_TRANSFORMATION_COMPRESS_WHITESPACE\n      {\n        ACTION_CONTAINER($$, new actions::transformations::CompressWhitespace($1));\n      }\n    | ACTION_TRANSFORMATION_REMOVE_WHITESPACE\n      {\n        ACTION_CONTAINER($$, new actions::transformations::RemoveWhitespace($1));\n      }\n    | ACTION_TRANSFORMATION_REPLACE_NULLS\n      {\n        ACTION_CONTAINER($$, new actions::transformations::ReplaceNulls($1));\n      }\n    | ACTION_TRANSFORMATION_REMOVE_NULLS\n      {\n        ACTION_CONTAINER($$, new actions::transformations::RemoveNulls($1));\n      }\n    | ACTION_TRANSFORMATION_HTML_ENTITY_DECODE\n      {\n        ACTION_CONTAINER($$, new actions::transformations::HtmlEntityDecode($1));\n      }\n    | ACTION_TRANSFORMATION_JS_DECODE\n      {\n        ACTION_CONTAINER($$, new actions::transformations::JsDecode($1));\n      }\n    | ACTION_TRANSFORMATION_CSS_DECODE\n      {\n        ACTION_CONTAINER($$, new actions::transformations::CssDecode($1));\n      }\n    | ACTION_TRANSFORMATION_TRIM\n      {\n        ACTION_CONTAINER($$, new actions::transformations::Trim($1));\n      }\n    | ACTION_TRANSFORMATION_TRIM_LEFT\n      {\n        ACTION_CONTAINER($$, new actions::transformations::TrimLeft($1));\n      }\n    | ACTION_TRANSFORMATION_TRIM_RIGHT\n      {\n        ACTION_CONTAINER($$, new actions::transformations::TrimRight($1));\n      }\n    | ACTION_TRANSFORMATION_NORMALISE_PATH_WIN\n      {\n        ACTION_CONTAINER($$, new actions::transformations::NormalisePathWin($1));\n      }\n    | ACTION_TRANSFORMATION_NORMALISE_PATH\n      {\n        ACTION_CONTAINER($$, new actions::transformations::NormalisePath($1));\n      }\n    | ACTION_TRANSFORMATION_LENGTH\n      {\n        ACTION_CONTAINER($$, new actions::transformations::Length($1));\n      }\n    | ACTION_TRANSFORMATION_UTF8_TO_UNICODE\n      {\n        ACTION_CONTAINER($$, new actions::transformations::Utf8ToUnicode($1));\n      }\n    | ACTION_TRANSFORMATION_REMOVE_COMMENTS_CHAR\n      {\n        ACTION_CONTAINER($$, new actions::transformations::RemoveCommentsChar($1));\n      }\n    | ACTION_TRANSFORMATION_REMOVE_COMMENTS\n      {\n        ACTION_CONTAINER($$, new actions::transformations::RemoveComments($1));\n      }\n    | ACTION_TRANSFORMATION_REPLACE_COMMENTS\n      {\n        ACTION_CONTAINER($$, new actions::transformations::ReplaceComments($1));\n      }\n    ;\n\nsetvar_action:\n    NOT var\n      {\n        ACTION_CONTAINER($$, new actions::SetVar(actions::SetVarOperation::unsetOperation, std::move($2)));\n      }\n    | var\n      {\n        ACTION_CONTAINER($$, new actions::SetVar(actions::SetVarOperation::setToOneOperation, std::move($1)));\n      }\n    | var SETVAR_OPERATION_EQUALS run_time_string\n      {\n        ACTION_CONTAINER($$, new actions::SetVar(actions::SetVarOperation::setOperation, std::move($1), std::move($3)));\n      }\n    | var SETVAR_OPERATION_EQUALS_PLUS run_time_string\n      {\n        ACTION_CONTAINER($$, new actions::SetVar(actions::SetVarOperation::sumAndSetOperation, std::move($1), std::move($3)));\n      }\n    | var SETVAR_OPERATION_EQUALS_MINUS run_time_string\n      {\n        ACTION_CONTAINER($$, new actions::SetVar(actions::SetVarOperation::substractAndSetOperation, std::move($1), std::move($3)));\n      }\n    ;\n\nrun_time_string:\n    run_time_string FREE_TEXT_QUOTE_MACRO_EXPANSION\n      {\n        $1->appendText($2);\n        $$ = std::move($1);\n      }\n    | run_time_string var\n      {\n        $1->appendVar(std::move($2));\n        $$ = std::move($1);\n      }\n    | FREE_TEXT_QUOTE_MACRO_EXPANSION\n      {\n        std::unique_ptr<RunTimeString> r(new RunTimeString());\n        r->appendText($1);\n        $$ = std::move(r);\n      }\n    | var\n      {\n        std::unique_ptr<RunTimeString> r(new RunTimeString());\n        r->appendVar(std::move($1));\n        $$ = std::move(r);\n      }\n    ;\n%%\n\nvoid yy::seclang_parser::error (const location_type& l, const std::string& m) {\n    driver.error (l, m);\n}\n"
  },
  {
    "path": "src/parser/seclang-scanner.cc",
    "content": "\n#line 2 \"seclang-scanner.cc\"\n\n#define  YY_INT_ALIGNED short int\n\n/* A lexical scanner generated by flex */\n\n/* %not-for-header */\n/* %if-c-only */\n/* %if-not-reentrant */\n\n/* %endif */\n/* %endif */\n/* %ok-for-header */\n\n#define FLEX_SCANNER\n#define YY_FLEX_MAJOR_VERSION 2\n#define YY_FLEX_MINOR_VERSION 6\n#define YY_FLEX_SUBMINOR_VERSION 4\n#if YY_FLEX_SUBMINOR_VERSION > 0\n#define FLEX_BETA\n#endif\n\n/* %if-c++-only */\n/* %endif */\n\n/* %if-c-only */\n\n/* %endif */\n\n/* %if-c-only */\n\n/* %endif */\n\n/* First, we deal with  platform-specific or compiler-specific issues. */\n\n/* begin standard C headers. */\n/* %if-c-only */\n#include <stdio.h>\n#include <string.h>\n#include <errno.h>\n#include <stdlib.h>\n/* %endif */\n\n/* %if-tables-serialization */\n/* %endif */\n/* end standard C headers. */\n\n/* %if-c-or-c++ */\n/* flex integer type definitions */\n\n#ifndef FLEXINT_H\n#define FLEXINT_H\n\n/* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */\n\n#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L\n\n/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h,\n * if you want the limit (max/min) macros for int types. \n */\n#ifndef __STDC_LIMIT_MACROS\n#define __STDC_LIMIT_MACROS 1\n#endif\n\n#include <inttypes.h>\ntypedef int8_t flex_int8_t;\ntypedef uint8_t flex_uint8_t;\ntypedef int16_t flex_int16_t;\ntypedef uint16_t flex_uint16_t;\ntypedef int32_t flex_int32_t;\ntypedef uint32_t flex_uint32_t;\ntypedef uint64_t flex_uint64_t;\n#else\ntypedef signed char flex_int8_t;\ntypedef short int flex_int16_t;\ntypedef int flex_int32_t;\ntypedef unsigned char flex_uint8_t; \ntypedef unsigned short int flex_uint16_t;\ntypedef unsigned int flex_uint32_t;\n\n/* Limits of integral types. */\n#ifndef INT8_MIN\n#define INT8_MIN               (-128)\n#endif\n#ifndef INT16_MIN\n#define INT16_MIN              (-32767-1)\n#endif\n#ifndef INT32_MIN\n#define INT32_MIN              (-2147483647-1)\n#endif\n#ifndef INT8_MAX\n#define INT8_MAX               (127)\n#endif\n#ifndef INT16_MAX\n#define INT16_MAX              (32767)\n#endif\n#ifndef INT32_MAX\n#define INT32_MAX              (2147483647)\n#endif\n#ifndef UINT8_MAX\n#define UINT8_MAX              (255U)\n#endif\n#ifndef UINT16_MAX\n#define UINT16_MAX             (65535U)\n#endif\n#ifndef UINT32_MAX\n#define UINT32_MAX             (4294967295U)\n#endif\n\n#ifndef SIZE_MAX\n#define SIZE_MAX               (~(size_t)0)\n#endif\n\n#endif /* ! C99 */\n\n#endif /* ! FLEXINT_H */\n\n/* %endif */\n\n/* begin standard C++ headers. */\n/* %if-c++-only */\n/* %endif */\n\n/* TODO: this is always defined, so inline it */\n#define yyconst const\n\n#if defined(__GNUC__) && __GNUC__ >= 3\n#define yynoreturn __attribute__((__noreturn__))\n#else\n#define yynoreturn\n#endif\n\n/* %not-for-header */\n/* Returned upon end-of-file. */\n#define YY_NULL 0\n/* %ok-for-header */\n\n/* %not-for-header */\n/* Promotes a possibly negative, possibly signed char to an\n *   integer in range [0..255] for use as an array index.\n */\n#define YY_SC_TO_UI(c) ((YY_CHAR) (c))\n/* %ok-for-header */\n\n/* %if-reentrant */\n/* %endif */\n\n/* %if-not-reentrant */\n\n/* %endif */\n\n/* Enter a start condition.  This macro really ought to take a parameter,\n * but we do it the disgusting crufty way forced on us by the ()-less\n * definition of BEGIN.\n */\n#define BEGIN (yy_start) = 1 + 2 *\n/* Translate the current start state into a value that can be later handed\n * to BEGIN to return to the state.  The YYSTATE alias is for lex\n * compatibility.\n */\n#define YY_START (((yy_start) - 1) / 2)\n#define YYSTATE YY_START\n/* Action number for EOF rule of a given start state. */\n#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1)\n/* Special action meaning \"start processing a new file\". */\n#define YY_NEW_FILE yyrestart( yyin  )\n#define YY_END_OF_BUFFER_CHAR 0\n\n/* Size of default input buffer. */\n#ifndef YY_BUF_SIZE\n#ifdef __ia64__\n/* On IA-64, the buffer size is 16k, not 8k.\n * Moreover, YY_BUF_SIZE is 2*YY_READ_BUF_SIZE in the general case.\n * Ditto for the __ia64__ case accordingly.\n */\n#define YY_BUF_SIZE 32768\n#else\n#define YY_BUF_SIZE 16384\n#endif /* __ia64__ */\n#endif\n\n/* The state buf must be large enough to hold one state per character in the main buffer.\n */\n#define YY_STATE_BUF_SIZE   ((YY_BUF_SIZE + 2) * sizeof(yy_state_type))\n\n#ifndef YY_TYPEDEF_YY_BUFFER_STATE\n#define YY_TYPEDEF_YY_BUFFER_STATE\ntypedef struct yy_buffer_state *YY_BUFFER_STATE;\n#endif\n\n#ifndef YY_TYPEDEF_YY_SIZE_T\n#define YY_TYPEDEF_YY_SIZE_T\ntypedef size_t yy_size_t;\n#endif\n\n/* %if-not-reentrant */\nextern yy_size_t yyleng;\n/* %endif */\n\n/* %if-c-only */\n/* %if-not-reentrant */\nextern FILE *yyin, *yyout;\n/* %endif */\n/* %endif */\n\n#define EOB_ACT_CONTINUE_SCAN 0\n#define EOB_ACT_END_OF_FILE 1\n#define EOB_ACT_LAST_MATCH 2\n    \n    #define YY_LESS_LINENO(n)\n    #define YY_LINENO_REWIND_TO(ptr)\n    \n/* Return all but the first \"n\" matched characters back to the input stream. */\n#define yyless(n) \\\n\tdo \\\n\t\t{ \\\n\t\t/* Undo effects of setting up yytext. */ \\\n        int yyless_macro_arg = (n); \\\n        YY_LESS_LINENO(yyless_macro_arg);\\\n\t\t*yy_cp = (yy_hold_char); \\\n\t\tYY_RESTORE_YY_MORE_OFFSET \\\n\t\t(yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \\\n\t\tYY_DO_BEFORE_ACTION; /* set up yytext again */ \\\n\t\t} \\\n\twhile ( 0 )\n#define unput(c) yyunput( c, (yytext_ptr)  )\n\n#ifndef YY_STRUCT_YY_BUFFER_STATE\n#define YY_STRUCT_YY_BUFFER_STATE\nstruct yy_buffer_state\n\t{\n/* %if-c-only */\n\tFILE *yy_input_file;\n/* %endif */\n\n/* %if-c++-only */\n/* %endif */\n\n\tchar *yy_ch_buf;\t\t/* input buffer */\n\tchar *yy_buf_pos;\t\t/* current position in input buffer */\n\n\t/* Size of input buffer in bytes, not including room for EOB\n\t * characters.\n\t */\n\tint yy_buf_size;\n\n\t/* Number of characters read into yy_ch_buf, not including EOB\n\t * characters.\n\t */\n\tyy_size_t yy_n_chars;\n\n\t/* Whether we \"own\" the buffer - i.e., we know we created it,\n\t * and can realloc() it to grow it, and should free() it to\n\t * delete it.\n\t */\n\tint yy_is_our_buffer;\n\n\t/* Whether this is an \"interactive\" input source; if so, and\n\t * if we're using stdio for input, then we want to use getc()\n\t * instead of fread(), to make sure we stop fetching input after\n\t * each newline.\n\t */\n\tint yy_is_interactive;\n\n\t/* Whether we're considered to be at the beginning of a line.\n\t * If so, '^' rules will be active on the next match, otherwise\n\t * not.\n\t */\n\tint yy_at_bol;\n\n    int yy_bs_lineno; /**< The line count. */\n    int yy_bs_column; /**< The column count. */\n\n\t/* Whether to try to fill the input buffer when we reach the\n\t * end of it.\n\t */\n\tint yy_fill_buffer;\n\n\tint yy_buffer_status;\n\n#define YY_BUFFER_NEW 0\n#define YY_BUFFER_NORMAL 1\n\t/* When an EOF's been seen but there's still some text to process\n\t * then we mark the buffer as YY_EOF_PENDING, to indicate that we\n\t * shouldn't try reading from the input source any more.  We might\n\t * still have a bunch of tokens to match, though, because of\n\t * possible backing-up.\n\t *\n\t * When we actually see the EOF, we change the status to \"new\"\n\t * (via yyrestart()), so that the user can continue scanning by\n\t * just pointing yyin at a new input file.\n\t */\n#define YY_BUFFER_EOF_PENDING 2\n\n\t};\n#endif /* !YY_STRUCT_YY_BUFFER_STATE */\n\n/* %if-c-only Standard (non-C++) definition */\n/* %not-for-header */\n/* %if-not-reentrant */\n\n/* Stack of input buffers. */\nstatic size_t yy_buffer_stack_top = 0; /**< index of top of stack. */\nstatic size_t yy_buffer_stack_max = 0; /**< capacity of stack. */\nstatic YY_BUFFER_STATE * yy_buffer_stack = NULL; /**< Stack as an array. */\n/* %endif */\n/* %ok-for-header */\n\n/* %endif */\n\n/* We provide macros for accessing buffer states in case in the\n * future we want to put the buffer states in a more general\n * \"scanner state\".\n *\n * Returns the top of the stack, or NULL.\n */\n#define YY_CURRENT_BUFFER ( (yy_buffer_stack) \\\n                          ? (yy_buffer_stack)[(yy_buffer_stack_top)] \\\n                          : NULL)\n/* Same as previous macro, but useful when we know that the buffer stack is not\n * NULL or when we need an lvalue. For internal use only.\n */\n#define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)]\n\n/* %if-c-only Standard (non-C++) definition */\n\n/* %if-not-reentrant */\n/* %not-for-header */\n/* yy_hold_char holds the character lost when yytext is formed. */\nstatic char yy_hold_char;\nstatic yy_size_t yy_n_chars;\t\t/* number of characters read into yy_ch_buf */\nyy_size_t yyleng;\n\n/* Points to current character in buffer. */\nstatic char *yy_c_buf_p = NULL;\nstatic int yy_init = 0;\t\t/* whether we need to initialize */\nstatic int yy_start = 0;\t/* start state number */\n\n/* Flag which is used to allow yywrap()'s to do buffer switches\n * instead of setting up a fresh yyin.  A bit of a hack ...\n */\nstatic int yy_did_buffer_switch_on_eof;\n/* %ok-for-header */\n\n/* %endif */\n\nvoid yyrestart ( FILE *input_file  );\nvoid yy_switch_to_buffer ( YY_BUFFER_STATE new_buffer  );\nYY_BUFFER_STATE yy_create_buffer ( FILE *file, int size  );\nvoid yy_delete_buffer ( YY_BUFFER_STATE b  );\nvoid yy_flush_buffer ( YY_BUFFER_STATE b  );\nvoid yypush_buffer_state ( YY_BUFFER_STATE new_buffer  );\nvoid yypop_buffer_state ( void );\n\nstatic void yyensure_buffer_stack ( void );\nstatic void yy_load_buffer_state ( void );\nstatic void yy_init_buffer ( YY_BUFFER_STATE b, FILE *file  );\n#define YY_FLUSH_BUFFER yy_flush_buffer( YY_CURRENT_BUFFER )\n\nYY_BUFFER_STATE yy_scan_buffer ( char *base, yy_size_t size  );\nYY_BUFFER_STATE yy_scan_string ( const char *yy_str  );\nYY_BUFFER_STATE yy_scan_bytes ( const char *bytes, yy_size_t len  );\n\n/* %endif */\n\nvoid *yyalloc ( yy_size_t  );\nvoid *yyrealloc ( void *, yy_size_t  );\nvoid yyfree ( void *  );\n\n#define yy_new_buffer yy_create_buffer\n#define yy_set_interactive(is_interactive) \\\n\t{ \\\n\tif ( ! YY_CURRENT_BUFFER ){ \\\n        yyensure_buffer_stack (); \\\n\t\tYY_CURRENT_BUFFER_LVALUE =    \\\n            yy_create_buffer( yyin, YY_BUF_SIZE ); \\\n\t} \\\n\tYY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \\\n\t}\n#define yy_set_bol(at_bol) \\\n\t{ \\\n\tif ( ! YY_CURRENT_BUFFER ){\\\n        yyensure_buffer_stack (); \\\n\t\tYY_CURRENT_BUFFER_LVALUE =    \\\n            yy_create_buffer( yyin, YY_BUF_SIZE ); \\\n\t} \\\n\tYY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \\\n\t}\n#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol)\n\n/* %% [1.0] yytext/yyin/yyout/yy_state_type/yylineno etc. def's & init go here */\n/* Begin user sect3 */\n\n#define yywrap() (/*CONSTCOND*/1)\n#define YY_SKIP_YYWRAP\n\n#define FLEX_DEBUG\ntypedef flex_uint8_t YY_CHAR;\n\nFILE *yyin = NULL, *yyout = NULL;\n\ntypedef int yy_state_type;\n\nextern int yylineno;\nint yylineno = 1;\n\nextern char *yytext;\n#ifdef yytext_ptr\n#undef yytext_ptr\n#endif\n#define yytext_ptr yytext\n\n/* %% [1.5] DFA */\n\n/* %if-c-only Standard (non-C++) definition */\n\nstatic yy_state_type yy_get_previous_state ( void );\nstatic yy_state_type yy_try_NUL_trans ( yy_state_type current_state  );\nstatic int yy_get_next_buffer ( void );\nstatic void yynoreturn yy_fatal_error ( const char* msg  );\n\n/* %endif */\n\n/* Done after the current pattern has been matched and before the\n * corresponding action - sets up yytext.\n */\n#define YY_DO_BEFORE_ACTION \\\n\t(yytext_ptr) = yy_bp; \\\n/* %% [2.0] code to fiddle yytext and yyleng for yymore() goes here \\ */\\\n\tyyleng = (yy_size_t) (yy_cp - yy_bp); \\\n\t(yy_hold_char) = *yy_cp; \\\n\t*yy_cp = '\\0'; \\\n/* %% [3.0] code to copy yytext_ptr to yytext[] goes here, if %array \\ */\\\n\t(yy_c_buf_p) = yy_cp;\n/* %% [4.0] data tables for the DFA and the user's section 1 definitions go here */\n#define YY_NUM_RULES 549\n#define YY_END_OF_BUFFER 550\n/* This struct is not used in this scanner,\n   but its presence is necessary. */\nstruct yy_trans_info\n\t{\n\tflex_int32_t yy_verify;\n\tflex_int32_t yy_nxt;\n\t};\nstatic const flex_int16_t yy_accept[3973] =\n    {   0,\n        0,    0,    0,    0,  276,  276,  284,  284,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,  288,  288,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,  550,  542,  536,  269,  273,  274,\n      272,  275,  542,  542,  542,  542,  542,  542,  542,  542,\n      542,  542,  542,  542,  542,  292,  292,  549,  292,  292,\n\n      292,  292,  292,  292,  292,  292,  292,  292,  292,  292,\n      292,  292,  292,  292,  292,  292,  125,  276,  282,  284,\n      286,  280,  279,  281,  278,  284,  277,  500,  500,  499,\n      500,  500,  500,  120,  119,  118,  127,  127,  127,  134,\n      126,  127,  129,  129,  129,  128,  134,  129,  132,  132,\n      132,  131,  134,  130,  132,  541,  541,  541,  549,  502,\n      501,  451,  454,  549,  454,  451,  451,  451,  440,  440,\n      440,  443,  445,  440,  444,  440,  434,  440,  510,  510,\n      510,  509,  514,  510,  512,  512,  512,  511,  514,  512,\n      117,  117,  109,  117,  114,  108,  117,  117,  117,  117,\n\n      117,  117,  117,  117,  117,  117,  117,  117,  117,  117,\n      117,  117,  117,  117,  112,  117,  111,  549,  519,  549,\n      515,  528,  549,  288,  289,  549,  506,  506,  505,  508,\n      506,  504,  504,  503,  508,  504,  149,  543,  544,  545,\n      136,  135,  136,  136,  136,  136,  136,  136,  140,  139,\n      144,  145,  145,  144,  142,  141,  139,  147,  148,  148,\n      146,  147,  536,  269,    0,  272,  272,  272,    0,    0,\n        0,    0,    0,    0,    0,    0,  220,    0,    0,    0,\n        0,    0,  537,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,  419,    0,    0,    0,\n\n        0,    0,    0,    0,    0,    0,    0,    0,    0,  424,\n        0,    0,    0,    0,    0,  121,    0,  124,  276,  282,\n      284,  286,  283,  284,  285,  286,  287,  536,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,  127,    0,  127,  127,\n      127,    0,  133,  121,  127,  127,  129,    0,    0,  129,\n      129,  129,    0,  129,  121,  129,  132,    0,    0,  132,\n      132,  132,    0,  132,  121,  132,  541,  541,  541,    0,\n      539,  541,  451,    0,  451,    0,  451,  451,    0,  451,\n      451,  440,    0,    0,  439,  440,  440,  440,    0,  440,\n\n      513,  440,  440,    0,  439,    0,  440,  432,  433,  440,\n      440,  510,    0,    0,  510,  510,  510,    0,  510,  121,\n      510,  512,    0,  512,  512,    0,  512,    0,    0,  121,\n      512,  512,    0,  109,    0,  108,    0,  110,  114,  115,\n        0,  108,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,  104,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,  106,    0,    0,  112,    0,  113,\n      111,  111,    0,  519,    0,  528,    0,  519,  517,  527,\n        0,  515,  528,    0,    0,  535,    0,  518,    0,  288,\n\n      289,    0,  289,    0,    0,  506,    0,  506,    0,  507,\n      506,  504,    0,    0,  504,    0,  504,  543,  544,  545,\n        0,    0,    0,    0,    0,    0,  137,  138,  144,    0,\n        0,  144,    0,  144,  143,  147,    0,    0,  147,    0,\n      147,  272,    0,    0,    0,    0,    0,    0,    0,  219,\n        0,    0,    0,    0,    0,    0,    0,    0,  537,  538,\n        0,    0,    0,  402,    0,    0,  390,    0,    0,    0,\n      427,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,  430,    0,    0,    0,\n        0,  400,  121,  122,  123,    0,    0,    0,    0,  472,\n\n        0,  473,    0,  474,    0,    0,  477,  478,  480,    0,\n        0,  482,    0,    0,    0,    0,    0,    0,  473,    0,\n        0,    0,  127,    0,    0,  121,  122,    0,  129,    0,\n        0,  121,  122,    0,  132,    0,    0,  121,  122,  539,\n      540,  451,    0,  451,    0,  446,    0,  446,    0,  451,\n        0,  440,    0,    0,  440,    0,  439,    0,  440,  440,\n      440,  440,  440,    0,    0,    0,    0,  440,  440,  440,\n        0,  510,    0,    0,  121,  122,    0,  512,    0,    0,\n      121,  121,  122,  116,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n\n        9,    0,    0,    0,    0,    0,  103,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,  106,  107,  517,\n      527,  523,  526,    0,  530,    0,    0,  535,    0,    0,\n      518,  516,  525,    0,    0,  290,    0,    0,  506,    0,\n        0,    0,  504,    0,    0,    0,    0,    0,    0,    0,\n      144,    0,    0,    0,  147,    0,    0,  272,    0,    0,\n        0,    0,    0,  168,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n\n        0,    0,    0,    0,    0,  226,  538,  366,    0,    0,\n      403,    0,    0,  391,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,  396,\n        0,    0,    0,  415,    0,    0,  425,    0,    0,  401,\n      122,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n      479,  481,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,  127,    0,  122,  129,    0,  122,  132,\n        0,  122,  540,  451,    0,    0,    0,    0,  451,    0,\n        0,  447,  452,  448,  447,  452,  448,  440,    0,  440,\n      440,  440,    0,  440,    0,    0,    0,    0,  440,    0,\n\n      439,    0,  440,  440,  435,  441,  436,  435,  441,  436,\n        0,    0,  440,  440,  510,    0,  122,  512,    0,  122,\n      122,    0,    0,    0,    0,    0,    0,    0,    0,    5,\n        0,    0,    7,    0,    0,    0,    8,    0,    0,    0,\n       47,    0,    0,    0,    0,   13,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,   61,    0,    0,  107,  523,  526,  522,  530,\n        0,  533,    0,    0,  529,    0,    0,  516,  525,  521,\n\n      524,  290,    0,  291,  506,    0,  504,    0,    0,    0,\n        0,    0,  144,    0,  147,    0,  272,  272,  215,    0,\n        0,  217,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,  367,    0,    0,\n        0,  382,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,  397,    0,\n        0,    0,    0,    0,    0,  431,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,  498,\n\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,  449,  449,  449,\n        0,    0,  437,  437,    0,    0,    0,  440,  440,    0,\n      437,    0,  440,    0,    0,    0,    0,    0,    0,    0,\n       26,    0,    0,    2,    0,    4,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n       12,    0,   14,    0,    0,   16,    0,    0,   51,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n       73,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n\n        0,    0,    0,    0,  522,  533,    0,  534,  529,    0,\n      531,    0,  521,  524,  520,  291,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,  272,  272,    0,\n        0,    0,  169,    0,    0,    0,  223,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,  225,    0,    0,    0,    0,    0,    0,\n      383,    0,    0,  418,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n\n      422,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n      364,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,  484,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,  453,  450,  453,  450,  442,  438,\n      442,  438,    0,  437,    0,    0,    0,  440,    0,    0,\n        0,    1,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,   42,   42,    0,    8,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,   60,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,   82,    0,    0,\n\n        0,    0,   72,    0,   90,    0,    0,    0,    0,    0,\n        0,    0,    0,  534,  531,    0,  532,  520,    0,    0,\n        0,  272,  272,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,  263,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,  426,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,  421,    0,    0,    0,    0,    0,\n\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,  468,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    3,    0,    0,    0,    0,\n        0,    0,    0,   42,    0,   42,   42,    0,    0,    0,\n        0,    0,    0,    0,    0,   48,    0,    0,   15,    0,\n        0,   50,    0,   52,   22,   53,   54,   56,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,   62,    0,    0,   63,  532,    0,    0,\n\n      272,  272,    0,    0,    0,  218,  221,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,  368,    0,    0,\n        0,  405,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,  420,    0,    0,    0,    0,  429,    0,    0,\n      408,    0,    0,  411,  412,  413,    0,    0,    0,    0,\n\n      365,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,  476,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,   27,    0,\n        0,    0,    0,    0,    0,    0,   41,   42,   41,    0,\n       42,    0,    0,  100,    0,    0,    0,  102,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,   55,    0,    0,\n       23,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n       95,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,   62,    0,  272,  272,    0,    0,    0,\n      546,    0,  546,    0,    0,  265,    0,    0,    0,    0,\n\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,  369,    0,    0,  370,  300,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,  330,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,  428,    0,    0,\n        0,    0,  361,    0,    0,  410,  416,  414,  362,    0,\n        0,    0,  470,    0,    0,  471,    0,    0,    0,    0,\n\n      475,    0,  483,  485,    0,    0,  493,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,   41,    0,   41,    0,\n        0,    0,    0,    0,    0,   48,    0,    0,    0,    0,\n        0,    0,   49,    0,    0,    0,    0,    0,    0,    0,\n        0,   71,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,  272,  272,  270,    0,  270,\n      221,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n\n        0,    0,    0,    0,    0,    0,  247,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,  296,  371,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n      409,    0,    0,    0,    0,    0,    0,  488,    0,  497,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,  494,\n\n      495,    0,    0,    0,    0,    0,    0,   25,    0,   25,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,   43,   44,   46,    0,   46,   10,   11,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n       58,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,   88,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n       91,    0,    0,    0,    0,    0,  272,    0,  270,  270,\n      270,  270,  270,    0,  547,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,  194,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n      238,    0,  238,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,  297,    0,    0,  374,  372,    0,    0,    0,\n        0,    0,  306,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n      332,  333,  334,  407,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,  350,    0,    0,    0,    0,    0,\n      358,  359,  360,  423,    0,    0,  486,    0,    0,  459,\n\n      456,    0,    0,  479,    0,    0,    0,    0,    0,    0,\n        0,  496,    0,    0,  465,    0,  462,    0,    0,    0,\n        0,   25,    0,    0,    0,   26,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,   46,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,   17,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,   59,\n        0,    0,    0,   89,    0,   76,   75,    0,   77,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n       92,   78,   81,   79,    0,  272,  272,    0,    0,    0,\n\n        0,  224,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,  235,    0,  235,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,  248,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,  257,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,  375,  373,    0,    0,\n      303,    0,    0,  380,    0,  404,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,  331,    0,    0,    0,  342,    0,    0,    0,\n\n      346,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,  458,  487,    0,    0,    0,  490,    0,    0,\n        0,    0,    0,  464,    0,    0,    0,    0,   24,    0,\n        0,   24,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    6,    0,    0,   45,    0,    0,   45,    0,    0,\n        0,    0,    0,    0,    0,    0,  105,    0,    0,    0,\n       57,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,  271,  271,  271,  271,  271,\n\n      216,    0,    0,    0,    0,  166,    0,  166,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,  245,    0,    0,    0,    0,    0,    0,  176,    0,\n      176,    0,    0,    0,    0,    0,    0,  246,    0,    0,\n        0,  193,    0,    0,    0,    0,    0,  192,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,  239,    0,    0,\n        0,    0,    0,  153,  153,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,  381,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,  336,    0,    0,    0,    0,\n\n        0,    0,    0,    0,    0,  351,    0,    0,    0,    0,\n        0,    0,  469,    0,    0,    0,  491,    0,    0,    0,\n        0,    0,    0,   24,   25,   26,    0,    0,    0,    0,\n        0,    0,    0,  101,   45,   46,    0,    0,    0,   48,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,   58,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,   86,    0,    0,    0,    0,    0,    0,  222,    0,\n        0,  161,    0,  163,  163,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,  243,    0,  243,    0,    0,    0,\n\n        0,    0,    0,    0,  236,    0,    0,    0,    0,    0,\n        0,  253,    0,    0,  268,  268,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,  211,    0,  211,    0,    0,    0,\n        0,    0,    0,    0,    0,  294,    0,    0,  398,    0,\n        0,    0,    0,    0,    0,  307,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,  326,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,  347,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n\n        0,    0,    0,    0,    0,    0,    0,    0,   48,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n       58,    0,   58,    0,   58,    0,    0,   69,   68,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n       85,   67,   80,    0,    0,    0,  170,    0,    0,    0,\n        0,    0,    0,    0,  175,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,  177,    0,    0,    0,    0,    0,\n      250,  249,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,  240,    0,  240,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n\n        0,  152,    0,    0,    0,    0,  295,  298,    0,  399,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,  325,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,  384,    0,  386,    0,\n      349,    0,    0,    0,  357,    0,    0,    0,    0,    0,\n      492,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,   36,    0,    0,   26,    0,   18,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,   58,    0,\n        0,    0,    0,    0,   94,   94,    0,   65,    0,    0,\n        0,    0,   96,    0,    0,    0,    0,    0,    0,    0,\n\n        0,    0,    0,  244,    0,    0,    0,    0,    0,    0,\n        0,    0,  264,    0,  179,  179,  251,    0,  251,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,  212,    0,    0,    0,\n      152,    0,    0,  299,    0,    0,    0,  406,    0,    0,\n      305,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,  340,\n        0,  385,    0,  343,  387,    0,  348,    0,  388,    0,\n      363,    0,  475,    0,    0,    0,    0,    0,    0,    0,\n\n       28,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,   58,    0,    0,\n        0,    0,    0,    0,   66,   64,   98,    0,    0,    0,\n        0,    0,    0,  167,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,  232,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,  259,    0,    0,    0,  241,    0,    0,\n        0,  237,  237,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,  376,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,  322,    0,    0,    0,\n\n        0,    0,    0,  335,  339,    0,    0,    0,    0,  389,\n        0,  356,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,   58,    0,   70,    0,   74,    0,\n        0,    0,    0,    0,   99,    0,    0,    0,    0,    0,\n      164,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,  178,    0,  252,    0,    0,    0,    0,  548,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,  258,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,  209,    0,  293,    0,  377,    0,  304,  378,    0,\n\n        0,    0,    0,    0,  316,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,  489,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,   58,    0,   87,   93,   93,    0,   84,    0,\n      182,    0,    0,    0,  173,  173,    0,    0,    0,    0,\n        0,    0,    0,    0,  154,    0,    0,  254,  228,  181,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n      196,  196,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,  214,    0,  301,  302,  379,    0,    0,\n\n        0,    0,    0,  315,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,  329,    0,  341,    0,    0,    0,\n        0,    0,  417,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,  155,    0,  165,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n      188,    0,    0,    0,    0,    0,    0,    0,    0,  197,\n      197,    0,  199,  199,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,  213,  227,    0,    0,    0,    0,  312,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n\n        0,    0,    0,    0,    0,    0,    0,  457,    0,    0,\n        0,  463,    0,    0,   29,    0,    0,    0,    0,   37,\n        0,    0,   19,    0,    0,   83,   97,    0,    0,  162,\n      174,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,  186,    0,    0,  191,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,  195,    0,    0,    0,    0,  313,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,  392,  344,\n        0,  353,    0,  460,    0,    0,  466,    0,    0,   34,\n        0,    0,   38,    0,   20,    0,  160,  231,  231,    0,\n\n      160,  156,    0,    0,    0,  267,    0,  255,    0,  234,\n        0,    0,    0,    0,    0,    0,    0,    0,  190,    0,\n        0,  198,  200,    0,    0,    0,    0,  151,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n      320,    0,    0,  394,    0,  327,    0,    0,  393,  345,\n        0,  354,  461,    0,  467,    0,   35,    0,    0,   21,\n        0,    0,  157,    0,  157,    0,    0,  256,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,    0,  151,    0,    0,  210,    0,    0,    0,  311,\n        0,    0,    0,    0,    0,  395,    0,    0,  338,  352,\n\n      355,    0,    0,    0,    0,  159,    0,    0,  242,    0,\n        0,    0,  233,    0,    0,  266,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,    0,    0,    0,    0,  308,\n        0,    0,    0,  317,    0,    0,    0,    0,    0,    0,\n        0,    0,    0,    0,    0,  158,  150,    0,    0,    0,\n        0,    0,    0,  185,    0,    0,  229,  229,    0,  208,\n        0,  206,    0,    0,    0,  260,    0,  309,    0,    0,\n        0,  321,    0,    0,    0,    0,    0,    0,    0,    0,\n        0,  150,    0,    0,    0,    0,    0,  189,    0,    0,\n        0,  204,    0,  202,    0,  261,    0,    0,    0,    0,\n\n        0,    0,    0,    0,    0,    0,    0,   39,    0,  171,\n      171,    0,    0,    0,    0,    0,    0,    0,  207,  205,\n        0,    0,    0,    0,    0,  323,  324,    0,  337,    0,\n        0,    0,    0,   40,    0,  262,  180,    0,    0,  187,\n        0,  203,  201,    0,    0,    0,  328,    0,    0,    0,\n       31,  172,  184,    0,  230,  310,  314,    0,   33,   30,\n        0,  183,    0,    0,    0,    0,  319,    0,    0,    0,\n       32,    0\n    } ;\n\nstatic const YY_CHAR yy_ec[256] =\n    {   0,\n        1,    1,    1,    1,    1,    1,    1,    1,    2,    3,\n        1,    1,    4,    1,    1,    1,    1,    1,    1,    1,\n        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,\n        1,    5,    6,    7,    8,    9,   10,   11,   12,   13,\n       13,   14,   15,   16,   17,   18,   19,   20,   21,   22,\n       23,   24,   25,   26,   27,   28,   23,   29,    9,    1,\n       30,    1,    1,   31,   32,   33,   34,   35,   36,   37,\n       38,   39,   40,   41,   42,   43,   44,   45,   46,   47,\n       48,   49,   50,   51,   52,   53,   54,   55,   56,   57,\n        9,   58,    9,    1,   59,    1,   60,   61,   62,   63,\n\n       64,   65,   66,   67,   68,   69,   70,   71,   72,   73,\n       74,   75,   76,   77,   78,   79,   80,   81,   82,   83,\n       84,   85,   86,   87,   88,    1,    1,    1,    1,    1,\n        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,\n        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,\n        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,\n        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,\n        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,\n        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,\n        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,\n\n        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,\n        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,\n        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,\n        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,\n        1,    1,    1,    1,    1,    1,    1,    1,    1,    1,\n        1,    1,    1,    1,    1\n    } ;\n\nstatic const YY_CHAR yy_meta[89] =\n    {   0,\n        1,    2,    3,    4,    5,    1,    6,    1,    7,    1,\n        1,    8,    9,   10,    1,   11,   10,   10,   10,   12,\n       12,   12,   12,   12,   12,   12,   12,   12,   10,   13,\n        1,   14,   14,   14,   14,   14,   14,   14,   14,   14,\n       14,   14,   15,   16,   16,   16,   17,   16,   15,   16,\n       16,   16,   16,   16,   16,   16,   14,    9,   10,   16,\n       16,   16,   16,   16,   16,   16,   16,   16,   16,   16,\n       15,   16,   16,   16,   17,   16,   15,   16,   16,   16,\n       16,   16,   16,   16,   16,   18,   19,    1\n    } ;\n\nstatic const flex_int16_t yy_base[4209] =\n    {   0,\n        0,   81,  163,    0,    4,    8,   22,  250,   12,   50,\n       88,   93,   54,   99,  102,  257,  268,  274,  283,  293,\n       18,  289,11847,11844,11817,11810,  309,  315,  347,  369,\n      388,  407,  426,  437,  343,  446,  504,    0,  450,  456,\n      591,  597,  603,  609,  300,  328,  377,  410,  303,  431,\n    11811,11808,11800,11793,11792,11789,11714,11627,  591,  613,\n        0,    0,11527,11520,  608,  616,  646,  666,    0,    0,\n        0,    7,  618,  673,11549,13522,  419,13522,13522,13522,\n      334,13522,    3,    5,    8,    8,   56,   67,   93,  425,\n      628,   97,   98,  269,  133,13522,  387,13522,  422,  288,\n\n      297,  642,  664,  315,  428,  687,  326,  418,  412,  677,\n      685,  687,  703,  433,  565,  260,11536,   98,  770,  780,\n      786,13522,13522,13522,13522,  792,13522,13522,  615,13522,\n      818,  279,  766,13522,13522,13522,  350,  801,  644,  564,\n    11442,  756,  629,  805,  744,11435,  589,  817,  815,  832,\n      833,11434,  672,11431,  898,  901,  907,13522,  913,13522,\n    13522,  917,11404,11397,11396,  923,  933,  941,  948,  967,\n      977,11393,  692, 1007,11367, 1029,  783, 1039,  816,  927,\n      887,11360,  747, 1005,  942, 1022, 1008,  855,  750, 1057,\n    13522, 1068,13522,11414,  477,  263, 1034,  774, 1025,  918,\n\n      809, 1044,  877, 1043,  916,  957, 1051,  932, 1088,  941,\n      952, 1006,  320, 1129,13522,11411, 1133, 1138,  481,   89,\n     1152, 1158,  340, 1120,  489,  361, 1043, 1089,11348,  996,\n     1139, 1143, 1159,11341, 1016, 1161,13522,    0,    0,    0,\n    13522,13522, 1048, 1099, 1115, 1128, 1115, 1122,13522,  123,\n     1173,11340, 1118, 1178,13522,13522,  257, 1183,11337, 1119,\n    11329, 1199, 1179,13522,  641,    0,  706,11316, 1140, 1157,\n     1156, 1161, 1184, 1174, 1170, 1185, 1180, 1175, 1179, 1185,\n     1193, 1183,  491,11376,  883,  759, 1195, 1183, 1189, 1186,\n     1200, 1201, 1199, 1201, 1220, 1226,   13, 1212, 1229, 1231,\n\n     1225, 1218, 1223, 1240, 1233, 1235, 1230, 1250, 1240,  414,\n     1245, 1245, 1253, 1257, 1251,  864,11373,11196,  948, 1296,\n     1321, 1327,13522, 1331,13522, 1335,13522, 1339, 1279, 1273,\n     1284, 1301, 1275, 1309, 1305, 1317, 1291, 1306, 1307, 1317,\n     1334, 1324, 1329, 1355, 1326, 1340,  728,11007,  820, 1405,\n     1398, 1399,13522, 1411, 1415, 1402, 1419,11000,10999,  982,\n     1430, 1435, 1421, 1434, 1441, 1451, 1443,10996,10950, 1414,\n     1460, 1471, 1442, 1473, 1500, 1475, 1492, 1501,13522, 1509,\n     1042, 1517, 1521,10943, 1533,10993, 1538, 1558,   99, 1582,\n     1590, 1532,10939,10856, 1603, 1566, 1625, 1640, 1522, 1650,\n\n    13522, 1669, 1684, 1688, 1710,  239, 1729,13522,13522, 1742,\n     1750, 1546,10849,10848, 1048, 1629, 1655, 1559, 1593, 1723,\n     1665, 1541,10845, 1311, 1733, 1525, 1706, 1773, 1644, 1780,\n     1760, 1745, 1790,13522,10873, 1108,  873,13522, 1807,13522,\n    10866, 1466, 1341, 1393, 1539, 1559, 1618, 1626, 1672, 1708,\n     1751, 1715, 1768,10839, 1733, 1748, 1748, 1767, 1764, 1785,\n     1776, 1776, 1771, 1790, 1793, 1799, 1780, 1793, 1796, 1805,\n     1848, 1802, 1806, 1815, 1600,10862, 1873,13522,10854,13522,\n     1899, 1903, 1930, 1864,  353, 1936, 1379, 1883, 1719, 1909,\n    10847, 1942, 1948, 1957,  372, 1858, 1567, 1958,  600, 1964,\n\n     1965, 1625, 1970, 1971,10846, 1919,10788, 1432, 1969,13522,\n     1975, 1974,10656,10652, 1476, 1976, 1980,    0,    0,    0,\n     1848,  458, 1880, 1904,  691, 1932,13522,13522, 1982,10614,\n    10561, 1992, 1981, 1994,13522, 2007,10542,10523, 2019, 1983,\n     2037,10515, 1948, 1969, 1979, 1971, 1977, 1983, 1990,13522,\n     1980, 2010, 2011, 2015, 2018, 2064, 2015, 2012, 2057, 2058,\n     2011, 2027, 2037, 1437, 2036, 2035, 1589, 2048, 2045, 2046,\n    13522, 2059, 2051,10442, 2054, 2074, 2071, 2068, 2076, 2101,\n     2102, 2087, 2075, 2087, 2089, 2116,13522, 2106, 2119, 2108,\n     2128, 1624, 2066, 2085,13522, 2120, 2114, 2110, 2128,13522,\n\n     2107, 2120, 2134,13522, 2119, 2126,13522,13522, 2134, 2129,\n     2121, 2136, 2126, 2145, 2141, 2141, 2142, 2145, 2158, 2171,\n     2165, 2151, 2201,10373,10394, 2215, 2229,10393, 2209,10362,\n    10330, 2233, 2240,10288, 2239,10253,10280, 2246, 2256, 2086,\n     2221, 2273, 2196, 2283,  261, 2304,10316, 2252,  614, 2314,\n    10198, 2335,10132,10088, 2347, 2377, 2378, 2250, 2408, 2409,\n     2438, 2439, 2469,10032, 2277, 2316, 2454, 2470, 2501, 2528,\n     9974, 2267, 9927, 9613, 2348, 2371, 2226, 2260, 9144, 9171,\n     2488, 2384, 2505,13522, 2242, 2254, 2265, 2270, 2281, 2289,\n     2327, 9199, 2319, 2349, 2368, 2362, 2457, 2452, 2527, 2443,\n\n     2466, 2452, 9198, 2458, 2462, 2488,13522, 2480, 2493, 2495,\n     2510, 2514, 2510, 2526, 2531, 9197, 2528, 2548, 2538, 2528,\n     2525, 2545, 2535, 2528, 2563, 2530, 2546, 2548, 2541, 2558,\n     2555, 2582, 2567, 2584, 9196, 9195, 2572, 2322, 2428, 2500,\n     2516, 2567, 2632, 2636, 2645, 2646, 9220, 2650, 2655,  908,\n     2662, 2663, 2668, 9219, 2669, 2675, 2676, 2596, 2412, 9135,\n     9158, 9157, 2677, 9128, 9155, 2633, 2626, 2629, 2636, 9154,\n     2679, 9125, 9152, 9151, 2681, 9122, 9149,   16, 2639, 2640,\n     2662, 2648, 2647,13522, 2648, 2670, 2660, 2668, 2671, 2653,\n     2676, 2676, 2708, 2705, 2691, 2672, 2687, 2720, 2710, 2713,\n\n     2714, 2714, 2724, 2719, 2733,13522, 2773, 2394, 9071, 2715,\n    13522, 2717, 9070,13522, 2739, 2737, 2727, 2742, 2748, 2749,\n     2757, 2752, 9069, 2744, 2751, 2757, 2768, 2753, 2760, 1987,\n     2772, 2770, 2759, 9066, 2761, 2769, 2800, 2768, 2780,13522,\n     2815, 2779, 2770, 2786, 2773, 2770, 2792, 2794, 2798, 2814,\n     2799,13522, 2819, 2810, 2818, 2810, 2817, 2818, 2820, 2824,\n     2818, 2818, 2826, 1653, 2857, 2891, 1709, 2865, 2895, 2861,\n     2888, 2902, 2906, 2922,  682, 2887, 1477, 9056, 2928,  797,\n      979, 9016, 1489, 9015,13522, 9046,13522, 2910, 2906, 2960,\n     2982, 2995, 1428, 3019, 2909, 2998, 9044, 2976, 3060, 3025,\n\n     3079, 1553, 3094, 3110, 3029, 1648, 3036,13522, 9005,13522,\n     1089, 1801, 3123, 3139, 2389, 2903, 2935, 2881, 2945, 2946,\n     2961, 2894, 2900, 2912, 2971, 2981, 2981, 3015, 3111,13522,\n     3028, 3040,13522, 8993, 3026, 3178, 3191, 3046, 3061, 3082,\n    13522, 3094, 3101, 3100, 3113,13522, 3114, 3118, 3120, 3101,\n     3112, 3110, 8955, 3114, 3122, 3129, 3140, 3152, 3162, 3147,\n     3194, 3157, 3171, 3190, 3183, 3178, 3195, 3175, 3187, 3197,\n     3188, 3180, 8935, 3190, 3187, 3194, 3208, 3199, 3203, 3197,\n     3202, 3209,13522, 8946, 3197, 2986, 3052, 3066, 3095, 3114,\n     3170, 3185, 3274, 3275, 3246, 3281, 8889, 3282, 3287, 3288,\n\n     3293, 3294, 3299, 3300, 3255, 3298, 3268, 3300, 3259, 3245,\n     3269, 2057, 3304, 3302, 3311, 3305, 8649, 8629,13522, 3267,\n     3266,13522, 3287, 3288, 3280, 3288, 3283, 3285, 3306, 3288,\n     3302, 3307, 3309, 3297, 3332, 3300, 3347, 3303, 3308, 3322,\n     3333, 3322, 3322, 3334, 3337, 3338, 3339, 3346, 3346, 3346,\n     3360, 3350, 3358, 3356, 3369, 3364, 3367,13522, 3394, 3370,\n     3389, 3413, 3384, 3391, 3386, 3395, 3407, 3411, 3412, 3400,\n     3396, 3410, 8591, 3415, 3417, 3403, 3405, 3410,13522, 3409,\n     3413, 3413, 3457, 3430, 3436,13522, 3442, 3437, 3439, 3444,\n     3458, 3461, 3443, 3443, 3454, 3456, 3467, 3453, 3460,13522,\n\n     3462, 3461, 3478, 3469, 3480, 3482, 3482, 3492, 3487, 3495,\n     3509, 3487, 8562, 8540, 8510, 8499, 8431, 3546, 3536, 1536,\n     8412, 8339, 3572, 3540, 3527, 3538, 1842, 3573, 3605, 3571,\n     3634, 3635, 3664, 3589, 3665, 8295, 8167, 3500, 8166, 3534,\n     8217, 3532, 3526,13522, 3521,13522, 3548, 3574, 3613, 3625,\n     3617, 3606, 8226, 3622, 3676, 3616, 3627, 3641, 3638, 3647,\n    13522, 3642,13522, 8207, 3662,13522, 3672, 3679, 8135,    0,\n     3672, 3660, 3680, 3681, 3682, 3669, 3680, 3704, 3696, 3684,\n     3701, 3695, 3696, 3712, 3717, 3715, 3710, 3718, 3717, 3720,\n    13522, 3721, 3714, 3719, 3714, 3720, 8112, 3725, 3723, 3732,\n\n     3734, 8010, 1040, 7990, 3558, 3604, 3797, 3647, 3771, 3798,\n     3788, 3804, 3805, 3810, 3811, 3816, 3722, 7817, 7843, 7809,\n     3751, 3752, 3768, 7821, 7792, 7746, 7639, 7600, 7606, 3770,\n     3780, 3787,13522, 3786, 3789, 3776,13522, 3782, 3788, 3778,\n     3791, 3793, 3787, 3791, 3788, 3792, 3794, 3806, 3787, 3808,\n     3809, 3801, 3802, 3797, 3810, 3803, 3821, 3828, 3825, 3840,\n     3833, 3828, 3834, 3846, 3833, 3831, 3835, 3851, 3855, 3854,\n     3843, 3859, 3856,13522, 3847, 3858, 3863, 3850, 3841, 3853,\n    13522, 3892, 3864, 3312, 3850, 3867, 3871, 7612, 3864, 3899,\n     3887, 3890, 3886, 7388, 3882, 3888, 3906, 3894, 7383, 3900,\n\n     7278, 3914, 3900, 3902, 3909, 3914, 3916, 3916, 7263, 3907,\n    13522, 3916, 3904, 3908, 3921, 3911, 3929, 3943, 3941, 3942,\n     3957, 3958, 3949, 3961,13522, 3944, 3961, 3966, 3943, 3955,\n     3950, 3956, 3968, 3972, 3568, 1860, 2245, 7067, 3986, 4031,\n     2627, 6786, 4027, 2950, 4046, 1619, 2329, 4062, 4015, 3973,\n     3965,13522, 3965, 4013, 4017, 4005, 4006, 4008, 4015, 4027,\n     4020,    0, 4091, 4009,13522, 4020, 4034, 4020, 4063, 4046,\n     4062, 4063, 4067, 4074, 4064, 6786, 4060, 6624, 6572, 6568,\n     6501, 6422, 4060, 4130, 4062, 6322, 6210, 4075, 4067, 4081,\n     4071, 4083, 4086, 4096, 4101, 4091, 4099,13522, 4129, 4111,\n\n     4111, 4133,13522, 4130, 4124, 4119, 4133, 4126, 4121, 1884,\n     6172, 2202,    0, 4004, 4119, 4172, 4124, 4173, 3587, 4146,\n     4136, 6147, 6053, 4146, 4137, 4182, 4135, 4143, 4141, 4140,\n     4152, 4158, 4152, 4168, 4159, 4170, 4161, 4187, 4176, 4175,\n     4182, 4180, 4168, 4188, 4176, 4178, 4190, 4218, 4194, 4179,\n     4193, 4202, 4195, 4191, 4208, 4201, 4237, 4217, 4232, 4219,\n     4242, 4236, 4246, 4233, 4248, 4234, 4228, 4241, 4241, 4250,\n     4245, 4250, 4253, 4254, 4271, 4270, 4272, 4270,13522, 6039,\n     6024, 5918, 4286, 4285, 4275, 4292, 4292, 4279, 4301, 5855,\n     5834, 4296, 4298, 4309, 4345, 4293, 4281, 4293, 4290, 4298,\n\n     4300, 4316, 4319, 4327, 4326, 4337, 4340, 4341, 4326, 4338,\n     4336, 4337, 4357, 4348, 4350, 4342, 4356, 4359, 4365, 4364,\n     4359, 4350, 4372,13522, 4352, 4362, 4369, 4359, 4393, 4423,\n     4438, 4372, 4392, 4400, 4401,13522, 4401, 4410, 4396, 4395,\n     4412, 4398, 4408, 4481, 2466, 5819, 4482, 4430, 5824, 5815,\n     4407, 4420, 4430, 4428, 4460, 4490, 4446, 4459,13522, 4449,\n     4451,13522, 4468,13522,13522,13522,13522, 5824, 4449, 4472,\n     4521, 5740, 4477, 4488, 4491, 4490, 4493, 4495, 4489, 4492,\n     4512, 4522, 4515, 4503, 4524, 4527, 4508, 4528, 4525, 4533,\n     4534, 4535, 4524, 5702, 3610, 5747,    0, 4256, 4535, 3614,\n\n     5684,  918, 4527, 4528, 4453,13522,13522, 4542, 4529, 4531,\n     4541, 4542, 4529, 4530, 4548, 4538, 4545, 4558, 4558, 4567,\n     4578, 4575, 4573, 4574, 4576, 4574, 4575, 4583, 4579, 4589,\n     4590, 4595, 4585, 4595, 4581, 4576, 4600, 4597, 4584, 4591,\n     4592, 4593, 4603, 4605, 4612, 4603, 4614, 4619, 4620, 4627,\n     4623, 4620, 4640, 4641, 4630, 4628, 4647, 4663, 4646, 4632,\n     4648,13522, 4641, 4642, 4630, 4641, 4637, 4640, 4658, 4642,\n     4645, 5656, 4651, 5643, 4660, 4660, 4684, 4674, 4678, 4676,\n     4691, 4734, 4050, 5637, 4693, 4697, 4685,13522, 4697, 4693,\n    13522, 4701, 4687,13522,13522,13522, 4685, 4693, 4709, 4710,\n\n    13522, 4702, 4722, 4715, 4727, 4726, 4741, 4732, 4731, 4732,\n     4748, 4750, 4748, 4746, 4752, 4741, 4758, 4784, 4747, 4750,\n     4752, 4755, 4770, 4787, 1988, 5496, 4792, 4779,13522, 4778,\n     4796, 4797, 4798, 4801, 4800, 4793, 5465, 4851, 5463, 4403,\n     5411, 4791,    0,13522, 5392, 4807, 4796,13522, 4859, 4798,\n     4806, 4811, 4810, 4840, 5336, 4828, 4845,13522, 5332, 4842,\n     4903, 4857, 4868, 4856, 4861, 4858, 4864, 4865, 4861, 4878,\n    13522, 4882, 4875, 4901, 4899, 4909, 4911, 4911, 4911, 4918,\n     4905, 4906, 4902, 4682, 4721, 5235, 5193, 5178, 4904, 4910,\n     4893,    0, 1031, 4908, 4914,13522, 4915, 4917, 4917, 4915,\n\n     4931, 4916, 4932, 4931, 4938, 4931, 4938, 4956, 4951, 4955,\n     4951, 4967, 4962, 4963, 4974, 4969, 4952, 4959, 4962, 4970,\n     4977, 4894, 4970, 4964, 4967, 4967, 4969, 4982, 4983, 4974,\n     4980, 4976, 4991, 4987, 4995, 5013, 5016, 5055, 5022, 5023,\n     5026, 5024, 5029, 5026,13522, 5022, 5019, 5052,13522, 5038,\n     5036, 5038, 5053, 5039, 5040, 5046, 5047, 5040, 5073, 5154,\n     5047,13522, 5045, 5066, 5055, 5065, 5079, 5068, 5069, 5088,\n     5073, 5081, 5086, 5083, 5088, 5076, 5078,13522, 5124, 5093,\n     5087, 5083,13522, 5091, 5099,13522,13522,13522,13522, 5104,\n     5137, 5089, 5087, 5111, 5111,13522, 5126, 5123, 5125, 5133,\n\n     5126, 5133,13522,13522, 5137, 5145,13522, 5142, 5136, 5138,\n     5144, 5138, 5143, 5152, 5189, 5182, 5160, 5162, 5183, 5168,\n     5166, 5177, 5184, 5194, 5178, 5186, 5259, 4891, 5221, 5222,\n     4872, 4867, 5223, 5198, 5206,13522, 5208, 5216, 5220, 5224,\n     5211, 5226,13522, 5232, 5229, 5250, 5247, 5306, 4810, 5248,\n     5240,13522, 5236, 5252, 5252, 5257, 5258, 5254, 5259, 5247,\n     5286, 5254, 5274, 5283, 5278, 5287, 5305, 5311, 5312, 5298,\n     5311, 5303, 5319, 5320, 5312, 1679, 4691, 5387, 4427, 5391,\n    13522, 5313, 4459, 5308, 5332, 5329, 5359, 5360, 5367, 5360,\n     5361, 5357, 5364, 5370, 5355, 5367, 5363, 4432, 5297, 5372,\n\n     5379, 5379, 5361, 5362, 5370, 5376,13522, 5379, 5387, 5384,\n     5375, 5449, 5381, 5397, 5384, 5420, 5419, 5417, 5422, 5423,\n     5415, 5422, 5431, 5430, 5426, 5422, 5423, 5417, 5468, 5419,\n     5428, 5434, 5436, 5441, 5443, 5430, 5435, 5450, 4825,13522,\n     5439, 5447, 5442, 5448, 5469, 5469, 5459, 5458, 5462, 5465,\n     5473, 5468, 5478, 5514, 5490, 5479, 5478, 5477, 5481, 5485,\n     5486, 5494, 5493, 5530, 5521, 5526, 5538, 5527, 5522, 5528,\n     5538, 5534, 5537, 5548, 5539, 5539, 5542, 5560, 5548, 5567,\n    13522, 4392, 5568, 5566, 5561, 5569, 4330,13522, 4254,13522,\n     5567, 5567, 5578, 5569, 5561, 5569, 5589, 5588, 5574,13522,\n\n    13522, 5577, 5588,  282, 1415, 5583, 5585, 5231, 5618, 5627,\n     5604, 5608, 5601, 5601, 5616, 5611, 5607, 5621, 5616, 5629,\n     5618,13522,13522, 5653, 5654, 5655,13522,13522, 5631, 5620,\n     5619, 5626, 5637, 5642, 5633, 5638, 5644, 5639, 5644, 5703,\n     5766, 5650, 5655, 5672, 5670, 5671, 5671, 5701,    0, 5700,\n     5706, 5687, 5710, 5701, 5714, 5715, 5701,13522, 5717, 5718,\n     5719, 5720, 5735, 5723, 5729, 5732, 5755, 5750, 5745, 5765,\n    13522, 5751, 5768, 5769, 5770, 5767, 4179, 4047, 5806, 2225,\n     5359, 5810, 5813, 5775,13522, 5779, 5764, 5771, 5782, 5870,\n     5781, 5779, 5783, 5780, 5792, 5788, 5803, 5796, 5793, 5795,\n\n     5531, 5838, 5817, 5820, 5808, 5811, 5817, 5816, 5816, 5819,\n     5818, 5825, 5880,    0, 5838, 5845, 5851, 5849, 5863, 5852,\n     5849, 5848, 5847, 5854, 5852,    0, 5870, 5872, 5878, 5862,\n     5935,    0, 2714, 5868, 5884, 5869, 5887, 5896, 5298, 5889,\n     5914, 5907,13522, 5920, 5908, 5501, 5666, 5910, 5909, 5905,\n     5921, 5927, 5911, 5928, 5915, 5921, 5920, 5918, 5936, 5929,\n     5935, 5927, 5936, 5934, 5943, 5944, 5954, 5941, 5937, 5960,\n    13522,13522,13522,13522, 5960, 5973, 5972, 5953, 5968, 5975,\n     5977, 5977, 5976, 5966, 4011, 5984, 5975, 5989, 5976, 5991,\n    13522,13522,13522,13522, 5988, 5976,13522, 5978, 4020,13522,\n\n    13522, 5992, 5985,13522, 5985, 5980, 5997, 5992, 6005, 6003,\n     6017,13522, 2274, 2455,13522, 2617,13522, 6016, 6019, 6026,\n     3960, 3959, 6052, 3731, 6053,13522, 6016, 6029, 6030, 6021,\n     6028, 6040, 6035, 6030, 6028, 6035, 3617, 3598, 6067, 3580,\n     6068, 6041, 6048, 6049, 6040, 6042, 6038, 6047, 6037,13522,\n     6066, 6050, 6060, 6117, 6065, 6069, 6083, 6078, 6078, 6078,\n     6099, 6096, 6093, 6101, 6112, 6100, 6116, 6103, 6107,    0,\n     6111, 6112, 6124,13522, 6129,13522,13522, 6109,13522, 6119,\n     6120, 6123, 3591, 6123, 6126, 6128, 6121, 6129, 6131, 6129,\n    13522,13522, 6126,13522, 6145, 3553, 6185, 3535, 6206, 6133,\n\n     6172,13522, 6169, 6165, 6211, 5698, 6174, 6179, 6188, 6185,\n     6171, 6167, 6174, 6178, 6181, 6177, 6192, 6178, 6181, 6193,\n     6191, 6203, 6239,    0, 2876, 6264, 6209, 6209, 6227, 6233,\n     6235, 6226, 6238, 6240,13522, 6275, 6230, 3564, 6233, 6238,\n     6246, 6248, 6238, 6249, 6246, 6247, 6254, 6240, 6256,    0,\n     6248, 6254, 6249, 6264, 3557, 6256, 6254, 6303, 6271, 6269,\n     6326, 6285, 6289, 6290, 6286, 6296,13522,13522, 6298, 6291,\n     3426, 6288, 3406, 6320, 6294,13522, 6294, 6301, 6290, 6300,\n     6295, 6304, 6316, 6297, 3385, 6303, 6311, 6307, 6313, 6310,\n     6317, 6331,13522, 6317, 6336, 6328, 3352, 6337, 6335, 6346,\n\n    13522, 6340, 6342, 6341, 6336, 6342, 6360, 6345, 6346, 6349,\n     6350, 6367,13522,13522, 6366, 6372, 6370,13522, 6368, 6373,\n     6375, 3320, 2968,13522, 6380, 6377, 3306, 3316, 3227, 6403,\n     3171, 6405, 6407, 6371, 6388, 6382, 6384, 6398, 6396, 6398,\n     6391,13522, 6389, 3158, 3056, 6421, 3066, 6434, 6435, 6403,\n     3046, 6399, 6407, 6415, 6403, 6405,13522, 6419, 6423, 6414,\n    13522, 6426, 6427, 6435, 6433, 6425, 6438, 6427, 6435, 6436,\n     6438, 6439, 6445, 6452, 6453, 6460, 6456, 6469, 6470, 6467,\n     6472, 6474, 6478, 6479, 3015, 6481, 2993, 6479, 6466, 6482,\n     6476, 6478, 6488, 6479, 6479, 2955, 6552,13522, 2941, 6556,\n\n    13522, 6491, 6493, 6501, 6509, 6558,    0, 3125, 6545, 6507,\n     6521, 6517, 6518, 6534, 6528, 6526, 6527, 6538, 6574, 6526,\n     6538,13522, 6548, 6532, 6549, 6555, 6541, 2970, 6584,    0,\n     4006, 6537, 6553, 6554, 6571, 6574, 6571,13522, 6570, 6618,\n     6567,13522, 6571, 6586, 6577, 6572, 6595,13522, 6580, 6589,\n     6601, 6634, 6606, 6609, 6597, 6608, 6598,13522, 6600, 6611,\n     6658, 6608, 6612, 2952, 6676,  409, 6621, 2873, 6617, 6632,\n     6638, 6625, 6631, 6641, 6646, 6651,13522, 6643, 6657, 6641,\n     6640, 6648, 6657, 6665, 6662, 6664, 6668, 6659, 6654, 6669,\n     6655, 6667, 6668, 6677, 2855, 2820, 6661, 6681, 6677, 6687,\n\n     6692, 6680, 6696, 6704, 6708,13522, 6706, 6707, 6698, 6693,\n     6697, 6701,13522, 6709, 6707, 6704,13522, 6710, 6710, 6720,\n     6715, 6715, 6725, 6750, 6751,13522, 6719, 6733, 6731, 6724,\n     6741, 6743, 6749,13522, 6768, 6775, 6752, 6740, 6744,13522,\n     6760, 6763, 6750, 6756, 6753, 6752, 6754, 6761, 6765, 6766,\n     6774, 6770, 6765, 6777, 6782, 6783, 6774,13522, 6791, 6792,\n     6799, 6800, 6786, 6807, 6810, 6796, 6799, 6819, 6814, 6822,\n     6811,13522, 6807, 6822, 6809, 6825, 6822, 6831,13522, 6835,\n     6824,13522, 2863, 6868, 2710, 6827, 6836, 6832, 6826, 6842,\n     6845, 6839, 6855, 6846, 6896,    0, 4120, 6853, 6859, 6851,\n\n     6874, 6874, 6859, 6879,13522, 2649, 6876, 6867, 6878, 6913,\n     6921,13522, 6873, 6867,    0, 6922, 6892, 6883, 6887, 6927,\n     6903, 6877, 6905, 6911, 6893, 6953, 6917, 6920, 6902, 6918,\n     6906, 6931, 6935, 6928, 6981,    0, 4463, 6929, 6924, 6933,\n      620, 2582, 2237, 6942, 6934, 6971, 6935, 2577, 6973, 6951,\n     6957, 6948, 6954, 6972, 6961,13522, 6957, 6973, 2573, 2564,\n     6964, 6974, 6968, 6974, 6976, 6999, 2511, 6984, 6985, 6969,\n     6986, 6980, 6975, 6982, 6993, 6980, 6990, 6990,13522, 6995,\n     6989, 7000, 7000, 7017, 7005, 7010, 7010, 7017, 7017, 7031,\n     7032, 7031, 7021, 7023, 7036, 7027, 7062, 7039, 7027, 7028,\n\n     7029, 7025, 2486, 7063, 7070, 2475, 2471, 7049,13522, 7055,\n     7046, 7049, 7050, 7062, 7067, 7069, 7061, 2440, 7077, 7072,\n    13522, 7081,13522, 7080,13522, 7081, 7074, 7085,13522, 7086,\n     7077, 7092, 7092, 7093, 7094, 7085, 7097, 7090, 7099, 7103,\n    13522,13522,13522, 7116, 7104, 7115,13522, 7110, 7113, 7126,\n     7111, 7123, 7113, 7135,13522, 7119, 2424, 7126, 7126, 7136,\n     7122, 7124, 7177, 7128,13522, 7135, 7142, 7143, 7188, 7202,\n    13522,13522, 7143, 7165, 7162,    0, 7176, 7176, 7166, 7162,\n     7173, 7168, 7185, 7173, 7217, 7183, 7219,    0, 4751, 7180,\n     7183, 7181, 7242, 7195, 7181, 7208, 7205, 2393, 7205, 7215,\n\n     7209, 2311, 2298, 2329, 7208, 7214,13522, 7240, 7214,13522,\n     7221, 7222, 7212, 7221, 7228, 7237, 2193, 7242, 7232, 7251,\n     7247, 7242, 7237, 7247, 7243, 7244,13522, 7251, 7245, 7242,\n     7263, 7250, 7254, 7259, 7270, 7263, 7291, 7274, 7306, 7280,\n    13522, 7275, 7278, 7283,13522, 7281, 2171, 7295, 7307, 7295,\n    13522, 7295, 7308, 7311, 7298, 7311, 2192, 7295, 7296, 7302,\n     7317,13522, 7296, 7321,13522, 2198, 7322, 7321, 7325, 2113,\n     7328, 2068, 7327, 2064, 7330, 7333, 7347, 7337,13522, 7346,\n     7330, 7336, 7352, 7347, 7341, 7342, 7346,13522, 7347, 7349,\n     7368, 7350,13522, 7370, 7352, 7369, 7359, 7357, 7414, 7354,\n\n     7379, 7379, 7374,13522, 7384, 7390, 7391, 7399, 7398, 7447,\n     7419, 7438,13522, 7418,    0, 7439, 7452,    0, 5081, 7406,\n     7407, 7407, 2016, 7420, 7427, 7420, 7419, 7432, 7440, 7444,\n     7440, 7442, 7451, 7494, 7460, 7447, 7466, 2002, 7460, 7463,\n     7453, 7485, 7458, 7467, 7473, 7475,13522, 7472, 7488, 7491,\n     3116, 7481, 7476,13522, 7494, 7485, 7500,13522, 7495, 7506,\n    13522, 7507, 7495, 7508, 7509, 7511, 7504, 7509, 1897, 7515,\n     7515, 7515, 7518, 7513, 1889, 7518, 7509, 7521, 7514,13522,\n     7527,13522, 7522,13522,13522, 7523,13522, 1877, 7565, 7537,\n    13522, 7545,13522, 7538, 7552, 7557, 7551, 7547, 7564, 7554,\n\n    13522, 7551, 7569, 7571, 7570, 7556, 7570, 7557, 7551, 7573,\n     7572, 7580, 7568, 1901, 7576, 7572, 7585,13522, 7571, 7576,\n     7600, 7609, 7605, 7606,13522,13522, 7614, 7618, 7603, 7603,\n     7489, 7619, 7621,13522, 7655, 7656, 7614, 7627, 7633, 7620,\n     7616, 7628, 7626, 7624, 7679, 7634, 7706, 7652, 1866, 7642,\n     7651, 7673,    0, 7647, 7656, 7673, 7665, 7672, 7675, 7685,\n     7677, 7679, 7688, 7733, 7734, 7697, 7703,13522, 7696, 7708,\n     7709,    0, 7760, 7696, 7703, 7729, 7766, 7715, 7773, 7717,\n     7737, 7743, 7723, 7764, 7730, 7734, 7734, 7730, 7730, 1729,\n     7736, 7751, 7753, 7746, 7754, 1725,13522, 1710, 7764, 7751,\n\n     7762, 7763, 7754,13522, 1638, 7750, 7770, 7771, 7789,13522,\n     7761,13522, 7764, 7786, 7785, 7782, 7788, 7799, 7795, 7801,\n     1658, 7791, 7790, 7807, 7796, 7808, 7812, 7807, 7795, 7815,\n     7816, 7810, 7820, 1672,13522, 7799,13522, 7824,13522, 7821,\n     7813, 7814, 7823, 7830,13522, 7830, 7886, 7887, 7841, 7883,\n     7894, 7891, 7886, 7903, 7888, 7889, 7890, 7899, 7904, 7900,\n     7900, 7932, 7901,13522, 7899, 7899, 7959, 7914,    0, 7930,\n     7913, 7924, 7953, 7938, 7949, 7957, 7954, 7959,13522, 7895,\n     7897, 7995, 7953, 7948, 7999, 7955, 7953, 7968, 8004, 8005,\n     8023,13522, 7957,13522, 7975,13522, 7973,13522, 7995, 7980,\n\n     1522, 7986, 7996, 7988, 8023, 7995, 7991, 8019, 8003, 8019,\n     8010, 8007, 8024, 8012, 8028, 8029, 8025, 8026, 8035, 8016,\n     8041, 8036, 8036,13522, 8031, 8037, 8039, 8034, 8040, 8073,\n     8050, 8053, 8057, 8075, 1527, 8072, 8075, 8076, 8079, 8083,\n     1513, 8060,13522, 8083,13522,13522,13522, 8086,13522, 8071,\n     8102, 8129, 8013, 8134, 1514, 8156,    0, 8109, 8122, 8124,\n     8114, 8128, 8138, 8135,13522, 8131, 8137,13522,13522, 8174,\n     8148, 8149, 8134, 8139, 8150, 8213, 8152, 8139, 8152, 8153,\n        0, 8130, 8217, 8218, 8188, 8193, 8228, 8191, 8181, 8189,\n     1512, 8232, 8238, 8254, 8183,13522,13522,13522, 8205, 8235,\n\n     8202, 8195, 8219,13522, 8220, 8241, 8249, 8254, 8235, 8252,\n     8254, 1439, 8242, 1336,13522, 8243,13522, 8257, 8258, 8250,\n     8250, 8254,13522, 1352, 8262, 8256, 3100, 8264, 8258, 8300,\n     8268, 8277, 8293, 8308,    0, 1321, 8294, 8296, 8311, 8313,\n     1302, 8313, 8301, 8245, 8338, 8359, 8386,13522, 1288, 8316,\n     8319, 8323, 8246, 8334, 8338, 8350, 8302, 8345, 8341, 8343,\n    13522, 8350, 8353, 8414, 8367, 8352, 8353, 8421, 8348, 1166,\n     8303,    0, 1122, 8349,    0, 8349, 8359, 5246, 8390, 8408,\n     8402, 8441, 8469, 8478,13522, 8411, 8396, 8410, 8405,13522,\n     8415, 1053, 8419, 8423, 8407, 8411, 8414, 8410, 8416, 8434,\n\n     8474, 8460, 8460, 8461, 8474, 8477, 8478,13522, 1083, 8477,\n     3245,13522, 3342, 8478, 8488, 8465, 1026, 8469, 8481,    0,\n        0, 8499,13522, 8484, 8498,13522,13522, 8547, 8546, 8555,\n    13522, 8504, 8304, 8511, 8583, 8553,    0, 8514, 8584, 8538,\n     8541, 8552, 8538, 8544, 8604, 8561, 8570,13522, 8631, 8580,\n     8569,  996,  973, 8577, 8595, 6524,  903, 8541, 8568, 8587,\n     8601, 8655, 8603, 8597, 8621, 8626,13522, 8628, 8628, 8634,\n     8619, 8621, 8633, 8634, 8645, 8637, 8641, 8642, 8673, 8675,\n     8643,13522, 8645,13522,  926, 3767,13522, 4514, 8667,13522,\n      897, 8653,    0, 8649,13522, 8657, 8733, 8737,    0,    0,\n\n        0,13522, 8657, 8595, 8667, 8734, 8719,    0,    0, 8723,\n        0, 8682, 8669, 8674, 8700, 8711, 8711, 8712, 8761, 8712,\n     8728,13522,13522, 8730, 8731, 8717, 8736,  849, 8543,  880,\n     8729, 8719, 8722, 8737, 8723, 8724, 8726, 8722, 8745, 8763,\n    13522, 8766, 8773, 8790, 8759,13522, 8758, 8762,13522,13522,\n     8773, 8796,13522, 4738,13522, 8764,13522, 8769, 8777,13522,\n      855, 8764, 8824,    0, 5128,    0, 8814,    0,  828, 8772,\n     8783, 8785, 8792, 8790, 8790, 8798, 8806, 8847, 8705, 8727,\n     8809, 8810, 8846, 8808, 8815,13522, 8822, 8823, 8826,13522,\n     8829, 8827, 8817, 8822, 8822,13522, 8821, 8828,  733,13522,\n\n    13522, 8837, 8829, 8844, 8848,13522, 8831,  772,    0, 8862,\n      713, 8877,13522, 8836, 8842,13522, 8845, 8858, 8855, 8862,\n     8857, 8908, 8877, 8916, 8917, 8910, 8927, 8882, 8887,13522,\n     8899, 8886, 8901,13522,  640, 8900, 8897, 8901, 8907, 8899,\n     8912,  605,  470, 8907, 8944,13522,  427, 8940,  418, 8908,\n     8905, 8911, 8908,13522, 8902, 8909,    0, 8954, 8914, 8981,\n        0, 8982,    0, 8988, 8989,13522, 8929,13522, 8928, 8941,\n     8955,13522, 8951, 8954, 8968, 8951, 8971, 8966,    0,  364,\n     9004, 8956, 8962, 9008, 8961, 8975, 9014,13522, 8981,  362,\n      297, 9032,    0, 9045,    0,13522, 8991, 8991, 8984, 8986,\n\n     8995, 8989, 9003, 8999, 8994, 8999, 9009,    0,    0,  145,\n     9055,    0, 9010, 9066, 9062, 9005, 9075, 9046,13522,13522,\n      135,  125, 9045, 9046, 9042,13522,13522, 9048,13522, 9069,\n     9062, 9066, 9068,    0,  116,13522, 9094, 9121, 9122, 9130,\n     9063,13522,13522, 9095, 9099, 9100,13522,   41, 9093, 9124,\n    13522,13522, 9147, 9159,13522,13522,13522, 9125,13522,13522,\n     9131, 9174, 9132, 9144, 9151, 9144,13522, 9156, 9156, 9168,\n    13522,13522, 9231, 9250, 9269, 9288, 9307, 9326, 9345, 9364,\n     9383, 9402, 9421, 9440, 9459, 9478, 9497, 9516, 9535, 9554,\n     9573, 9592, 9611, 9630, 9649, 9668, 9687, 9706, 9725, 9744,\n\n     9763, 9782, 9801, 9820, 9839, 9858, 9877, 9896, 9915, 9934,\n     9953, 9972, 9991,10010,10029,10048,10067,10086,10105,10124,\n    10143,10162,10181,10200,10219,10238,10257,10276,10295,10314,\n    10333,10351,10370,10389,10408,10427,10446,10464,10483,10502,\n    10521,10540,10559,10578,10597,10616,10635,10654,10673,10692,\n    10711,10730,10749,10768,10787,10806,10825,10844,10863,10882,\n    10901,10919,10938,10957,10976,10995,11014,11033,11052,11070,\n    11089,11108,11127,11146,11165,11184,11203,11222,11241,11260,\n    11279,11298,11317,11336,11355,11374,11393,11412,11430,11449,\n    11468,11487,11506,11525,11544,11562,11581,11600,11619,11638,\n\n    11657,11676,11695,11714,11733,11752,11771,11790,11809,11828,\n    11847,11866,11885,11903,11922,11941,11960,11979,11998,12017,\n    12036,12055,12074,12093,12105,12120,12139,12147,12164,12182,\n    12186,12203,12222,12237,12254,12273,12292,12311,12329,12346,\n    12365,12384,12403,12422,12440,12457,12476,12490,12507,12526,\n    12544,12557,12573,12590,12604,12620,12636,12649,12666,12683,\n    12700,12715,12731,12744,12761,12778,12795,12814,12829,12846,\n    12863,12877,12896,12914,12932,12950,12968,12986,12998,13015,\n    13033,13051,13064,13081,13100,13118,13137,13155,13174,13192,\n    13209,13227,13242,13259,13277,13296,13314,13333,13352,13370,\n\n    13388,13407,13420,13437,13455,13473,13485,13502\n    } ;\n\nstatic const flex_int16_t yy_def[4209] =\n    {   0,\n     3973, 3973, 3972,    3, 3974, 3974,    3,    3, 3975, 3975,\n     3975, 3975, 3976, 3976, 3977, 3977, 3978, 3978, 3979, 3979,\n     3980, 3980, 3974, 3974, 3974, 3974, 3981, 3981, 3982, 3982,\n     3982, 3982, 3983, 3983, 3984, 3984, 3972,   37,   37,   37,\n     3974, 3974, 3974, 3974, 3974, 3974, 3985, 3985, 3986, 3986,\n     3987, 3987, 3988, 3988, 3989, 3989, 3990, 3990, 3991, 3991,\n     3974, 3974, 3992, 3992, 3993, 3993, 3991, 3991, 3974, 3974,\n     3994, 3994, 3995, 3995, 3972, 3972, 3972, 3972, 3972, 3972,\n     3996, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972,  131, 3972, 3972, 3972, 3997, 3997, 3997, 3972,\n     3972, 3997, 3998, 3998, 3998, 3972, 3999, 3998, 4000, 4000,\n     4000, 3972, 4001, 3972, 4000, 4002, 4002, 3972, 4002, 3972,\n     3972, 4003, 3972, 3972, 3972, 4003, 4004, 4003, 4005, 4005,\n     4005, 3972, 4006, 4005, 3972, 4007, 3972, 4005, 4008, 4008,\n     4008, 3972, 4009, 4008, 4010, 4010, 4010, 3972, 3972, 4010,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 4011, 4011, 3972, 3972,\n     4011, 4012, 4012, 3972, 4013, 4012, 3972, 4014, 4015, 4016,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     4017, 3972, 4018, 4017, 3972, 3972, 3972, 4019, 3972, 4020,\n     3972, 4019, 3972, 3972, 3972, 4021, 4021, 4021, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 4022, 3972, 4022, 4022,\n     4022, 3972, 3972, 4022, 4022, 4022, 4023, 3972, 4024, 4023,\n     4023, 4023, 3972, 4023, 4023, 4023, 4025, 3972, 4026, 4025,\n     4025, 4025, 3972, 4025, 4025, 4025, 4027, 4027, 3972, 4027,\n     3972, 4027, 4028, 3972, 4028, 3972, 4029, 4030, 4031, 4030,\n     4028, 4032, 3972, 4033, 4032, 4032, 4032, 4032, 3972, 4032,\n\n     3972, 4034, 4035, 4036, 4035, 4037, 4035, 3972, 3972, 4032,\n     4032, 4038, 3972, 4039, 4038, 4038, 4038, 3972, 4038, 4038,\n     4038, 4040, 3972, 4040, 4040, 3972, 4040, 3972, 3972, 4040,\n     4040, 4040, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n\n     3972, 3972, 3972, 3972, 3972, 4041, 3972, 4041, 3972, 3972,\n     4041, 4042, 3972, 4043, 4042, 3972, 4042, 4044, 4045, 4046,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 4047, 3972,\n     4048, 4047, 3972, 4047, 3972, 4049, 3972, 4050, 4049, 3972,\n     4049, 4051, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 4052, 3972, 3972, 4052, 4052, 4053, 4054, 3972,\n     3972, 4054, 4054, 4055, 4056, 3972, 3972, 4056, 4056, 3972,\n     3972, 4057, 4058, 4057, 4059, 4060, 4061, 4061, 4061, 4060,\n     4062, 4063, 3972, 3972, 4064, 4065, 4064, 4066, 4064, 4067,\n     4068, 4068, 4068, 4069, 4069, 4069, 4070, 4068, 4063, 4063,\n     4071, 4072, 3972, 3972, 4072, 4072, 3972, 4073, 3972, 3972,\n     4073, 3972, 4073, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 4074, 3972,\n     3972, 4075, 4076, 3972, 3972, 3972, 3972, 3972, 3972, 4077,\n     4078, 3972, 3972, 4079, 4080, 3972, 3972, 4081, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 4082, 3972, 4082, 4083, 3972, 4083, 4084,\n     3972, 4084, 3972, 4085, 4086, 4086, 4086, 4087, 4085, 4087,\n     4087, 3972, 4088, 3972, 3972, 4088, 3972, 4063, 3972, 4089,\n     4089, 4089, 4090, 4091, 4090, 4090, 4092, 4093, 4089, 4094,\n\n     4091, 4092, 4091, 4091, 4063, 4095, 4063, 3972, 4095, 3972,\n     4095, 4095, 4096, 4063, 4097, 3972, 4097, 4098, 3972, 4098,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 4099, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n\n     3972, 3972, 3972, 3972, 4100, 3972, 4101, 3972, 3972, 3972,\n     3972, 3972, 4102, 3972, 4103, 3972, 4104, 4104, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 4105, 3972, 4106, 3972, 4107, 4108, 4109,\n     4110, 3972, 4089, 4111, 4111, 4111, 4092, 4089, 4091, 4092,\n     4091, 4112, 4091, 4113, 4114, 4115, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 4116, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 4099, 4117,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n\n     3972, 3972, 4118, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 4119, 3972,\n     3972, 3972, 3972, 4120, 3972, 4121, 3972, 4122, 4122, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 4108, 4109, 4108, 4109, 4111, 4091,\n     4111, 4092, 4111, 4092, 4123, 4092, 4092, 4091, 4113, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 4116, 4124, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 4125, 3972, 3972, 3972, 4117, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 4118,\n     3972, 4118, 4126, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 4122, 4122, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 4111, 4092,\n     4112, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 4124, 4127, 4116, 4124, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 4128, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 4118, 3972, 4126, 3972, 3972, 3972,\n\n     4122, 4129, 3972, 3972, 4130, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 4092, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 4116, 4124, 3972, 4127,\n     4116, 3972, 4131, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 4118, 3972, 4122, 4132, 4133, 3972, 3972,\n     4130, 4134, 4130, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 4135, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 4124, 3972, 4127, 4127,\n     3972, 4131, 4136, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 4137, 4132, 4132, 4133, 4133,\n     3972, 3972, 4134, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 4138, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 4139, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 4135, 4140, 4135,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 4136, 4141, 4136, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 4142, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 4143, 4144, 4132, 3972,\n     4132, 4133, 4133, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n\n     4145, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 4138, 4146, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 4147, 3972, 3972, 3972, 3972,\n     4139, 4148, 4139, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 4135, 4140, 3972, 4140, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 4136, 4141, 3972,\n     4141, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 4142,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 4143, 4149, 4144, 4150, 3972,\n\n     3972, 3972, 3972, 3972, 4151, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 4145, 4152, 4145, 4153, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 4146, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 4147,\n     3972, 3972, 3972, 3972, 4148, 3972, 3972, 3972, 3972, 3972,\n     4154, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 4140,\n     3972, 4135, 4140, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 4141, 3972, 4136, 4141, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 4143, 4149, 3972, 4144, 4150,\n\n     3972, 3972, 3972, 3972, 3972, 4151, 4155, 4151, 4156, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 4157, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 4152, 4153, 4158,\n     4153, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 4159,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     4160, 3972, 3972, 4154, 4154, 4161, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 4140, 4135, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 4141, 4136, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 4155, 4156, 4156, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 4157, 4162, 4157, 3972, 3972, 3972,\n\n     3972, 3972, 3972, 3972, 3972, 4158, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 4159, 4159, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 4163, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 4160, 4164, 4160, 3972, 3972, 3972,\n     4161, 3972, 4161, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 4140, 3972, 3972, 3972,\n\n     3972, 3972, 3972, 3972, 4141, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 4162, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 4165, 4166,\n     3972, 3972, 3972, 3972, 3972, 4167, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 4163, 4168, 4163, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 4164, 3972, 3972,\n\n     3972, 3972, 4161, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 4165, 4165, 4166, 4169, 4166, 3972,\n     3972, 3972, 4167, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 4168, 3972, 3972,\n     3972, 4170, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     4161, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 4171, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 4169, 3972,\n     3972, 3972, 4172, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 4170, 4170, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 4173, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 4172, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 4174,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 4175, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 4173, 4173, 4176, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     4174, 4174, 4177, 4178, 3972, 3972, 3972, 3972, 3972, 3972,\n     4175, 4175, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 4179, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 4176, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 4177,\n     4177, 4180, 4178, 4178, 4181, 3972, 3972, 4182, 3972, 3972,\n     3972, 4175, 4175, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 4179,\n     4183, 3972, 3972, 3972, 3972, 3972, 3972, 4184, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 4185, 3972, 4186, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 4180, 4181, 3972, 3972, 4182, 3972, 4182, 3972, 3972,\n     3972, 4175, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 4183, 3972, 3972, 3972, 4184, 4184, 4187, 4188,\n\n     4189, 3972, 3972, 4190, 3972, 3972, 3972, 4185, 4191, 4186,\n     4192, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 4182, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     4188, 3972, 4190, 4193, 4190, 4194, 4195, 4191, 4192, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 4182, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 4193, 4194, 4195,\n     3972, 4195, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 4196, 3972, 4197, 4198, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 4195, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 4196, 4196, 3972, 4197,\n     4199, 4198, 4200, 4201, 4202, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 4203, 3972,\n     4204, 4195, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 4199,\n     4200, 4201, 4205, 4202, 4206, 3972, 3972, 3972, 3972, 3972,\n\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 4203, 4207, 4204,\n     4204, 4208, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     4205, 4206, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 4207, 4208, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972,    0, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972\n    } ;\n\nstatic const flex_int16_t yy_nxt[13611] =\n    {   0,\n     3972,   77,   78,   79,   77,  118,   80,   81,  118,  118,\n     3972,  256,  118,  129,   98,   82,  129,  130,  256,  157,\n      158, 3972,  157,  119,  120,  121,  119,  122,  123,  257,\n      571,   83,  124,   84,   85,  269,  257,  125,   86,   87,\n       88,  571,  131,  271,   89,   90,   91, 1017,   92,   93,\n      270,  129,   98,   94,  129,  130,   98,   95,  272,   83,\n      135,   84,   85,  269, 1018,  136,   86,   87,   88,  132,\n     3959,  271,   89,   90,   91,  159,   92,   93,  270,  126,\n      131,   94,   77,   78,   79,   77,  272,   80,   81,  129,\n       98,  490,  129,  130,  129,   98,   82,  129,  130,  319,\n\n      273,   98,  319,  138,  139,  135,  138,  132,  127,   96,\n      136,  140,   83,  141,   84,   85,  274,  648,  133,   86,\n       87,   88, 3952,  133,  275,   89,   90,   91,  273,   92,\n       93, 3943,  280,  281,   94,  283,  284,  527,   95,  528,\n       83, 3942,   84,   85,  274,  132,  491,   86,   87,   88,\n      132, 3972,  275,   89,   90,   91,  649,   92,   93,  142,\n      280,  281,   94,   96,   97,   98,   96,   97,   96,   96,\n       96,   96,   96,   96,   96,   96,   96,   96,   96,   96,\n       96,   96,   96,   96,   96,   96,   96,   96,   96,   96,\n       96,   96,   96,   96,   99,   96,   96,  100,  101,  102,\n\n      103,  104,  105,   96,   96,   96,  106,   96,  107,  108,\n      109,  110,  111,  112,  113,   96,  114,  115,   96,   96,\n      116,   96,   99,   96,   96,  100,  101,  102,  103,  104,\n      105,   96,   96,   96,  106,   96,  107,  108,  109,  110,\n      111,  112,  113,   96,  114,  115,   96,   96,   96,   96,\n      117,  119,  120,  121,  119,  122,  123,  665,  138,  139,\n      124,  138,  316,  317,  442,  125,  140,  442,  141,  144,\n      145,  527,  144,  528,  146,  144,  145,  147,  144,  880,\n      146,  283,  284,  147,  150,  151, 2314,  150, 2315,  152,\n      157,  158,  153,  157,  150,  151,  666,  150,  154,  152,\n\n      282,  224,  153, 3920,  224,  233,  225,  126,  154,  234,\n      163,  164,  235,  163,  142,  165,  163,  164,  881,  163,\n      166,  165,  475,  476,  163,  148,  166,  167,  282,  224,\n      163,  148,  224,  167,  225,  267,  127,   96,  267,  289,\n      155,  290,  498,  499,  186,  187,  159,  188,  170,  171,\n      155,  170,  189,  172,  295,  490,  173,  226,  174,  348,\n      236,  348,  175,  504,  505,  176,  168,  289, 3919,  290,\n      170,  171,  168,  170,  746,  172,  177,  302,  173,  228,\n      174,  229,  295,  268,  175,  226,  230,  176,  285,  170,\n      171,  285,  170, 3909,  172,  163,  163,  173,  177,  174,\n\n      190,  163,  163,  175,  178,  302,  176,  349,  170,  171,\n      491,  170,  228,  172,  229, 2842,  173,  177,  174,  230,\n      263,  264,  175,  263, 3812,  176,  178,  180,  181,  747,\n      180,  587,  182,  233,  231,  183,  177,  234,  180,  181,\n      235,  180,  587,  182,  286,  178,  183,  186,  187,  303,\n      188,  214,  215,  216,  217,  189,  191,  214,  215,  216,\n      217,  276,  191,  304,  178,  191, 2843,  231,  314,  277,\n      287,  191,  296,  288,  297,  571,  265,  303,  439,  440,\n      441,  439,  488,  184, 3849,  488,  571,  489,  236,  276,\n      503,  304,  559,  503,  184,  559,  314,  277,  287, 3879,\n\n      296,  288,  297,  190,  191,  192,  193,  194,  192,  191,\n      195,  191,  191,  191,  191,  191,  191,  191,  191,  196,\n      191,  191,  191,  191,  191,  191,  191,  191,  191,  191,\n      191,  191,  191,  191,  191,  197,  198,  199,  200,  201,\n      191,  191,  191,  202,  191,  191,  203,  204,  205,  206,\n      207,  191,  208,  209,  210,  191,  211,  191,  212,  191,\n      191,  213,  191,  197,  198,  199,  200,  201,  191,  191,\n      191,  202,  191,  191,  203,  204,  205,  206,  207,  191,\n      208,  209,  210,  191,  211,  191,  212,  191,  191,  191,\n      191,  191,  218,  219,  220,  221,  242,  222,  218,  219,\n\n      220,  221,  753,  222,  218,  219,  220,  221,  315,  222,\n      218,  219,  220,  221,  252,  222,  328,  253,  242,  328,\n      391,  352,  252,  252,  259,  253, 3002,  260,  243,  261,\n      244,  252,  648,  259, 3878,  358,  315,  252,  359,  245,\n      246,  247,  248,  283,  284,  252,  360,  259,  223,  353,\n      243,  242,  244,  348,  223,  348,  243,  754,  244,  278,\n      223,  245,  246,  247,  248,  254,  223,  245,  246,  247,\n      248,  242,  265,  254,  353,  262,  279, 3003,  243,  259,\n      244,  291,  260,  243,  261,  244,  360,  278,  259,  245,\n      246,  247,  248,  292,  245,  246,  247,  248, 3871,  293,\n\n      876,  349,  259,  243,  279,  244,  294,  267,  587,  291,\n      267,  243,  305,  244,  245,  246,  247,  248,  298,  587,\n      307,  292,  245,  246,  247,  248,  309,  293,  306,  370,\n      262,  243,  299,  244,  294,  308,  300,  348,  301,  348,\n      305,  310,  245,  246,  247,  248,  298,  311,  307,  396,\n      358,  312,  313,  359,  309,  268,  306,  353,  354,  355,\n      299,  316,  317,  308,  300,  348,  301,  348,  878,  310,\n     3849,  320,  321,  322,  320,  311,  323,  401, 3846,  312,\n      313,  324,  321,  322,  324,  349,  325,  326,  322,  322,\n      326, 3840,  327,  324,  321,  322,  324,  408,  325,  409,\n\n      343,  360,  350,  344,  415,  350,  361,  429, 1120,  361,\n      348,  358,  348,  356,  359,  880,  447,  345,  346,  365,\n      366,  368,  413,  358,  369,  414,  359,  321,  343,  622,\n      368,  344,  401,  371, 3813,  401,  371,  321,  368,  368,\n      399,  369,  369,  322,  447,  345,  346,  368,  368,  321,\n      329,  330,  331,  332,  333,  334,  285,  335,  351,  285,\n      336, 3806,  362,  453,  337,  593,  338,  339,  593,  340,\n      341,  342,  370,  415,  364,  475,  476,  623,  329,  330,\n      331,  332,  333,  334,  285,  335, 3658,  285,  336,  372,\n      370,  453,  337,  413,  338,  339,  414,  340,  341,  342,\n\n      375,  376,  378,  379,  368,  378, 3730,  369,  378,  379,\n      996,  378,  428,  368,  378,  381,  382,  378,  384,  384,\n     1788,  384,  456,  384,  384,  384, 3757,  384,  416,  384,\n     3753,  416,  384,  413,  384,  389,  414,  384,  384,  384,\n      286,  387,  384,  384,  415,  384,  423,  384,  389,  319,\n      456,  423,  319,  451,  393,  374,  384,  394,  380,  395,\n     3730,  460,  383,  393,  380,  997,  452,  466,  397,  471,\n      380,  397,  472,  393,  385,  266,  394,  393,  395, 3723,\n      385,  451,  393,  393,  417,  391,  394,  473,  395,  460,\n      390,  628,  393,  461,  452,  466,  393,  880,  391,  424,\n\n      472,  462, 3722,  384,  384,  396,  393,  420,  421,  384,\n      384,  413,  423,  393,  414,  473,  394,  423,  395,  384,\n      389,  461,  393,  425,  398,  402,  426,  384,  384,  462,\n      392,  423, 3972,  392,  396,  393,  393, 3972,  404,  629,\n      405,  410,  411,  640,  406,  393,  640,  507,  394,  474,\n      395, 1411,  507,  509,  393, 3690,  448,  671,  393,  430,\n      431,  423,  419,  449,  396,  424,  423,  443,  393,  433,\n      434,  435,  433,  515,  457,  450,  444,  474,  454,  427,\n      445,  510,  463,  436,  448,  446,  407, 3684,  455,  464,\n      521,  449,  458,  507,  459,  443,  400, 1412,  507,  465,\n\n      508,  510,  457,  450,  444,  672,  454,  665,  445,  442,\n      463, 3668,  442,  446,  432,  392,  455,  464,  521,  467,\n      458,  500,  459,  468,  500,  437,  501,  465, 3972,  469,\n      477,  478,  479,  477,  481,  478,  479,  482,  470,  483,\n      484,  485,  483,  507,  486,  522,  508,  467,  507,  513,\n      523,  468,  514,  483,  484,  485,  492,  469,  486,  493,\n      494,  495,  493,  524,  496,  513,  470,  513,  514,  525,\n      514,  526, 3972,  522,  662,  532,  539,  502,  523,  530,\n      263,  264,  531,  263,  530,  543,  437,  531,  530,  537,\n      437,  524,  538,  530,  537,  487,  511,  525,  537,  526,\n\n      515,  544,  530,  535,  535,  537,  545,  530,  538,  487,\n      537,  546,  537,  543,  537,  497,  515,  547,  517,  548,\n      549,  550,  551,  552,  553,  554,  556,  555,  537,  544,\n      532,  558,  561,  562,  545,  534,  265,  563,  564,  546,\n      539,  557,  565,  566,  567,  547,  568,  548,  549,  550,\n      551,  552,  553,  554,  556,  555,  541,  569,  570,  558,\n      561,  562,  572,  573,  574,  563,  564,  575,  576,  557,\n      565,  566,  567,  577,  568,  578,  579,  582,  583,  584,\n      580,  585,  581,  586,  588,  569,  570,  589,  590,  591,\n      572,  573,  574,  592, 3631,  575,  576,  320,  321,  322,\n\n      320,  577,  323,  578,  579,  582,  583,  584,  580,  585,\n      581,  586,  588, 2561,  596,  589,  590,  591,  597,  598,\n      677,  592,  324,  321,  322,  324,  601,  325,  326,  322,\n      322,  326,  324,  327,  609,  324,  326,  325,  610,  326,\n      328,  327,  596,  328,  602,  599,  597,  598,  600,  605,\n     3621,  606,  607,  321,  601,  611, 3608,  613,  603,  604,\n      612,  614,  609,  617,  618,  615,  610,  608,  678,  616,\n      620,  621,  602,  599,  685,  616,  600,  605,  321,  606,\n      607,  498,  499,  611,  322,  613,  603,  604,  612,  614,\n      619,  617,  618,  615, 3601,  608,  265,  616,  620,  621,\n\n      354,  355,  685,  616,  603,  604,  350,  622,  624,  350,\n      356,  348,  626,  348,  348,  626,  348,  627,  619, 2316,\n      348, 2317,  348,  634,  348,  358,  348,  364,  359,  368,\n      630,  361,  603,  604,  361,  686,  358,  365,  366,  359,\n      358,  758,  632,  359,  628,  632,  895,  358,  374,  368,\n      359,  636,  369,  633,  811,  623,  625,  358,  368,  356,\n      359,  371,  351,  686,  371,  811,  368,  442,  349,  369,\n      442,  635,  349,  375,  376,  368,  360,  639,  631,  368,\n      634,  368,  369,  391,  369,  762,  368,  362,  368,  759,\n      368,  364,  629,  378,  379,  876,  378, 3599,  360,  637,\n\n      370,  638,  378,  379,  638,  378,  368,  648,  360,  369,\n      378,  381,  382,  378,  897,  368, 3582,  372,  378,  641,\n     3972,  378,  384,  384, 2561,  384,  285,  384,  635,  285,\n      374,  653,  370,  763,  384,  384,  384,  384,  393,  384,\n      643,  394,  384,  395,  384,  423,  649,  393,  384,  380,\n      423,  400,  413,  643,  880,  414, 3535,  370,  380,  384,\n      389,  393,  384,  878,  384,  419,  380,  383,  673,  749,\n      750, 1127,  393,  389,  380,  651,  646,  395,  385,  654,\n     3500,  393,  428,  384,  389,  687,  384,  383,  383,  396,\n      391,  384,  384,  688,  384,  644,  384,  389,  424,  413,\n\n      646,  738,  414,  415,  738,  384,  814,  384,  384,  393,\n     1130,  383,  394,  687,  395,  390,  674,  814,  393,  384,\n      384,  688, 1338,  652,  645,  643,  397,  504,  505,  397,\n      416,  393,  393,  416,  394,  413,  395, 1127,  414,  650,\n      393,  840,  410,  411,  384,  389,  393,  391,  432,  651,\n      419,  395,  840,  679,  393,  393,  393,  420,  421,  394,\n      396,  395, 1112,  689,  671,  393,  665,  676,  384,  389,\n      392,  413,  690,  392,  414,  393,  384,  384,  656,  393,\n      657, 2178,  398, 2561,  658,  392,  417, 3430,  392,  400,\n      393,  689,  400,  404,  400,  405, 3415,  652,  393,  406,\n\n      690,  680,  661,  691,  894,  666,  663,  400,  430,  431,\n      623,  392,  672,  393,  392,  677,  393,  400, 1114,  404,\n      740,  405,  415,  740,  675,  406,  659,  675,  661,  413,\n      392,  691,  414,  392,  425,  393,  266,  426,  667,  393,\n      405,  407,  423,  669,  406,  407,  669,  661,  393,  423,\n      692,  394,  670,  395,  423,  660,  393,  393,  392,  394,\n      696,  395,  683,  678,  423,  393,  629,  407, 3409,  423,\n      392,  393,  700,  664,  400,  316,  317,  432,  692,  393,\n      415,  681,  679, 3408,  682,  701,  668, 3402,  696,  423,\n      427,  433,  434,  435,  433,  693,  392,  694,  702,  396,\n\n      700,  695,  432,  697,  703,  436,  704,  396,  439,  440,\n      441,  439,  707,  701,  698,  392,  705,  424,  708,  665,\n      709,  711,  710,  693,  717,  694,  702,  706,  712,  695,\n      680,  697,  703,  714,  704,  720,  721,  424,  713,  735,\n      707,  715,  698,  718,  705,  719,  708,  437,  709,  711,\n      710,  716,  717, 1344,  736,  706,  712,  737, 1134,  748,\n     1127,  714,  748,  720,  721,  488,  713,  735,  488,  715,\n      489,  718, 3364,  719,  477,  478,  479,  477,  880,  716,\n      722,  723,  736,  724,  488,  737,  725,  488,  726,  489,\n      727,  728,  729,  766,  730, 1594,  731,  732,  733,  734,\n\n      481,  478,  479,  481,  481,  478,  479,  482,  722,  723,\n      741,  724, 2561,  741,  725,  742,  726,  881,  727,  728,\n      729,  766,  730,  507,  731,  732,  733,  734,  507,  767,\n      437,  483,  484,  485,  483, 3309,  486,  493,  494,  495,\n      493, 1595,  496,  483,  484,  485,  492, 3301,  486,  493,\n      494,  495,  493,  768,  496, 3295,  437,  767,  744,  751,\n      437,  744,  751,  745,  752,  500,  503,  769,  500,  503,\n      501,  503,  755,  511,  503,  755,  508,  756,  760,  507,\n      513,  768,  517,  514,  507,  764,  513,  487,  530,  514,\n      772,  531,  776,  497,  541,  769,  779,  530,  530,  487,\n\n      530,  770,  780,  531, 1079,  497, 1127,  530, 3268,  530,\n      534,  530,  541,  537,  781, 1079,  538,  782,  537,  783,\n     3253,  502,  537,  530,  779,  537,  761,  784,  774,  785,\n      780,  515,  511,  765,  537,  786,  537,  517,  773,  532,\n      777,  787,  781,  537,  788,  782,  538,  783,  537,  771,\n      789,  534,  537,  790,  805,  784,  806,  785,  559,  807,\n      808,  559,  807,  786,  539,  809,  537,  593,  810,  787,\n      593,  812,  788,  894, 1086, 2561,  775,  813,  789, 2561,\n      815,  790,  805,  816,  806, 1086,  841,  640,  808,  841,\n      640,  817,  818,  809,  541,  791,  810,  792,  793,  812,\n\n      819,  794,  795,  796,  821,  813,  822,  797,  815,  823,\n      798,  816,  799,  800,  801,  802,  824,  803,  804,  817,\n      818,  825,  830,  791, 2561,  792,  793,  831,  819,  794,\n      795,  796,  821,  826,  822,  797,  832,  823,  798,  833,\n      799,  800,  801,  802,  824,  803,  804,  828,  829,  825,\n      830,  834,  827,  835,  836,  831,  837,  842,  843,  838,\n      844,  826,  845,  846,  832,  847,  848,  833,  849,  850,\n      851,  852,  853,  854,  855,  828,  829,  839,  856,  834,\n      827,  835,  836,  857,  837,  842,  843,  838,  844,  858,\n      845,  846,  859,  847,  848,  860,  849,  850,  851,  852,\n\n      853,  854,  855,  861,  862,  839,  856,  863,  352, 1936,\n      348,  857,  348, 1594,  876,  358,  626,  858,  359,  626,\n      859, 3201,  873,  860,  348,  873,  348, 2180, 2180, 3192,\n      866,  861,  862,  866,  632,  863,  356,  632,  348,  358,\n      348,  869,  359, 3002,  869,  368,  358,  638,  369,  359,\n      638, 3162,  368,  877,  368,  369,  885,  872,  864, 1412,\n      872,  368,  368,  876,  423,  369,  867,  886,  895,  423,\n      648,  368,  349,  413,  384,  643,  414,  384, 2523,  384,\n     2524,  908,  878,  429,  384,  643,  349,  384,  643,  383,\n      360,  874,  909,  922, 2843,  665,  870,  360,  643,  923,\n\n      924,  874,  383,  370, 3151,  384,  389,  896,  882,  925,\n      384,  432,  383,  370,  926,  384,  389,  918,  384,  883,\n      384,  922,  646,  738,  915,  911,  738,  923,  924,  389,\n      644,  878,  646,  383,  665, 2843,  897,  925,  887,  927,\n      879,  393,  926,  383,  394,  400,  395, 1127,  392,  675,\n      393,  392,  675,  393,  413, 2843,  656,  414,  657,  645,\n      643,  390,  658,  910,  393,  890,  928,  927, 3004,  645,\n      643,  650,  917,  912,  930,  917,  393,  413,  400,  392,\n      414,  400,  392,  400,  393,  593, 1530,  656,  593,  657,\n      884,  389,  888,  658,  928,  892,  890,  931, 1136, 3147,\n\n      384,  389,  930,  932,  659,  415,  400,  393,  933,  392,\n      392, 1058,  392,  392,  393,  393,  507,  898,  900,  657,\n      901,  507, 1058,  658,  902,  931,  890,  903,  415,  986,\n     3104,  932,  986,  660,  659,  659,  933,  392,  393,  392,\n      392,  429,  905,  392,  393,  393,  672,  404,  404,  405,\n      405, 2561, 1059,  906,  406,  400,  661,  661,  400, 2314,\n      400, 2315,  893,  894,  660,  899,  904,  393,  393, 1005,\n      392,  392,  663,  905,  392,  393,  393, 1739,  404,  404,\n      405,  405, 3065,  400,  906,  406, 1936,  661,  661,  681,\n      934,  935,  682,  938,  660,  407,  662,  423,  393,  393,\n\n      939,  740,  669,  940,  740,  669,  920,  393,  942,  921,\n      394,  407,  395,  943,  423, 3062,  393,  741,  934,  935,\n      741,  938,  742, 1740,  907,  392,  662,  913,  939,  914,\n      393,  940,  914,  944,  393,  945,  942,  394,  936,  395,\n      400,  943,  946,  393,  947,  424,  937,  937,  937,  937,\n      937,  937,  937,  937,  937,  907,  392,  393,  396,  948,\n      949,  944,  424,  945,  950,  951,  952,  954,  987, 3028,\n      946,  987,  947,  960,  961,  962,  963,  967,  964,  970,\n      965,  971,  973,  955,  966,  396,  974,  948,  949,  975,\n      976,  972,  950,  951,  952,  954,  956,  957,  968,  958,\n\n      959,  960,  961,  962,  963,  967,  964,  970,  965,  971,\n      973,  955,  966,  969,  974,  979,  985,  975,  976,  972,\n      977, 2316, 3020, 2317,  956,  957,  968,  958,  959,  978,\n      980, 3019,  981,  988,  982, 3009,  988,  744,  989, 3004,\n      744,  969,  745,  979,  985,  895,  990,  991,  977,  990,\n      991,  748,  992,  509,  748, 2965,  994,  978,  980,  994,\n      981,  995,  982,  751,  998, 1009,  751,  998,  752,  999,\n      755, 1010,  999,  755, 1000,  756, 1002, 1003, 1011, 1002,\n     1003,  511, 1004,  513, 1012,  530,  514,  537,  531, 1019,\n      538, 1020,  537, 1009,  530, 1021,  537, 1022, 1023, 1010,\n\n     1024, 1025, 1026, 1027, 1028, 1029, 1011, 1033,  530, 1030,\n      537, 3972, 1012,  897, 1034, 3972, 1044, 1019, 1045, 1020,\n     3972, 1035, 1042, 1021, 1031, 1022, 1023, 1032, 1024, 1025,\n     1026, 1027, 1028, 1029, 1007, 1033, 1013, 1030, 1015, 1036,\n     1039, 1043, 1034, 1037, 1044, 1048, 1045, 1038, 1050, 1035,\n     1042, 1046, 1031, 1047, 1040, 1032, 1041, 1052, 1053, 1055,\n     1054, 1049, 1056, 1051, 1057, 1061, 1062, 1036, 1039, 1043,\n     1064, 1037, 1065, 1048,  807, 1038, 1050,  807, 1066, 1046,\n     1067, 1047, 1040, 1068, 1041, 1052, 1053, 1055, 1054, 1049,\n     1056, 1051, 1057, 1061, 1062, 1069, 1070, 1071, 1064, 1073,\n\n     1065, 1074, 1075, 1076, 1077, 1078, 1066, 1080, 1067, 1081,\n     1082, 1068, 1084, 1085, 1088, 1089,  841, 1086, 1090,  841,\n     1091, 1092, 1093, 1069, 1070, 1071, 1094, 1073, 1086, 1074,\n     1075, 1076, 1077, 1078, 1095, 1080, 1096, 1081, 1082, 1087,\n     1084, 1085, 1088, 1089, 1097, 1098, 1090, 1099, 1091, 1092,\n     1093, 1100, 1101, 1102, 1094, 1104, 1105, 1106, 1107, 1108,\n     1109, 1103, 1095, 1110, 1096, 1111, 1113, 1087,  356, 2947,\n     1116,  364, 1097, 1098, 1115, 1099,  368, 3972, 2872, 1100,\n     1101, 1102, 3972, 1104, 1105, 1106, 1107, 1108, 1109, 1103,\n     1138, 1110,  866, 1111,  374,  866,  869, 1117, 1119,  869,\n\n      348,  358,  348,  872,  359,  876,  872,  873,  368,  419,\n      873,  369, 1137, 2871,  625, 1122,  393,  368,  635, 1121,\n     1124,  395,  631,  384,  643,  393,  384,  895,  384,  384,\n      643, 2845,  384, 1118,  384,  400,  917,  643,  678,  917,\n      874,  413, 1140,  643,  414,  637,  874,  920,  349,  432,\n      921,  383,  360, 1141, 1139,  423, 1142,  383, 3972,  370,\n      674,  392,  841,  654,  392,  841,  393,  652, 1127,  656,\n     1140, 1123, 2523,  878, 2524,  658, 2805,  400,  890,  644,\n      400, 1141,  400,  392, 1142,  879,  392,  986,  393,  393,\n      986,  656,  415,  657,  892,  897,  392,  658, 2399,  392,\n\n      890,  393,  680,  424,  656,  400, 1123, 1125,  645,  643,\n      658,  393, 2397,  890,  645,  643,  895,  659,  429, 2770,\n      392, 1143, 1144,  392,  393,  393,  400,  400,  900,  400,\n      901,  400, 1145,  659,  902,  393, 1342,  903,  394,  891,\n      395, 2768,  393, 1129,  393,  394,  660,  395,  393, 1143,\n     1144,  393,  891,  987,  400, 1126,  987, 2726,  393, 1146,\n     1145,  392,  894, 1151,  392,  393,  393,  988,  660,  656,\n      988,  657,  989, 1152, 1154,  658,  894, 2549,  890, 1156,\n      392,  660,  904,  392,  897,  393,  396, 1146,  900,  393,\n      901, 1151, 1157,  396,  902,  392, 1205,  903,  392, 1205,\n\n      393, 1152, 1154,  900, 3611, 1131, 3612, 1156,  393,  902,\n      897,  392,  903, 2547,  392,  990,  393, 1128,  990, 1132,\n     1157,  901, 3002,  393,  392,  902, 3972,  392,  903,  393,\n     1158, 3972, 1135, 1159,  405, 1160,  904, 1161,  406,  392,\n      914,  661, 1147,  914, 1162,  393,  660, 1148,  394, 1163,\n      395,  904,  392, 1164,  393, 1165, 1166, 1149, 1158, 1150,\n     1167, 1159, 1168, 1160, 1171, 1161, 1172, 1133,  393, 2126,\n     1147,  991, 1162, 3003,  991, 1148,  992, 1163, 1173, 1174,\n      668, 1164, 2533, 1165, 1166, 1149, 1206, 1150, 1167, 1206,\n     1168, 1175, 1171, 1176, 1172, 1177,  396, 1155, 1155, 1155,\n\n     1155, 1155, 1155, 1155, 1155, 1155, 1173, 1174, 1180,  392,\n      937,  937,  937,  937,  937,  937,  937,  937,  937, 1175,\n     1181, 1176, 1178, 1177, 1182, 1179, 1183, 1184, 1185, 1186,\n     1187, 1188, 1189, 1190, 1192, 1194, 1180, 1195, 1193, 1197,\n     1196, 1198, 1199, 1200, 1201, 1202, 1204, 1209, 1181, 3611,\n     1209, 3612, 1182, 1179, 1183, 1184, 1185, 1186, 1187, 1188,\n     1189, 1190, 1192, 1194, 1217, 1195, 1193, 1197, 1196, 1198,\n     1199, 1200, 1201, 1202, 1204, 1207,  994, 1219, 1207,  994,\n     1208,  995, 1210,  998, 2531, 1210,  998, 1211,  999, 1213,\n     1221,  999, 1213, 1000, 1214, 1002, 1222, 1214, 1002, 1215,\n\n     1003, 1216,  511, 1003, 1216, 1004,  517, 1218, 1223, 1220,\n      530, 1225,  759, 1224, 1227, 1230, 1231,  537, 1221,  530,\n     1226, 1232,  537, 1233, 1222,  763,  537, 2110, 1234, 1479,\n     1235,  534, 1236, 2723,  541, 1237, 1223, 1238, 1239, 1240,\n     1479, 1241, 1242, 1230, 1231, 1243, 3686, 2720, 3687, 1232,\n     1248, 1233, 1251, 1252, 1253,  761, 1234,  765, 1235,  773,\n     1236,  771,  777, 1237, 1254, 1238, 1239, 1240,  775, 1241,\n     1242, 1255, 1256, 1243, 1244, 1245, 1246, 1247, 1248, 1249,\n     1251, 1252, 1253, 1250, 1257, 1258, 1259, 1260, 1264, 1261,\n     1265, 1267, 1254, 1262, 1266, 1263, 1269, 1270, 1271, 1255,\n\n     1256, 1272, 1244, 1245, 1246, 1247, 1273, 1249, 1268, 1274,\n     2699, 1250, 1257, 1258, 1259, 1260, 1264, 1261, 1265, 1267,\n     1279, 1262, 1266, 1263, 1269, 1270, 1271, 1275, 1280, 1272,\n     1281, 1276, 1283, 1284, 1273, 1285, 1268, 1274, 1277, 1286,\n     1278, 1281, 1287, 2688, 1288, 1289, 1290, 1291, 1279, 1292,\n     1294, 1295, 1296, 1297, 1298, 1275, 1280, 1299, 1300, 1276,\n     1283, 1284, 1301, 1285, 2676, 1309, 1277, 1286, 1278, 1310,\n     1287, 1282, 1288, 1289, 1290, 1291, 1311, 1292, 1294, 1295,\n     1296, 1297, 1298, 1312, 2674, 1299, 1300, 1313, 1314, 1315,\n     1301, 1302, 1303, 1309, 1316, 1304, 1317, 1310, 1318, 1319,\n\n     1305, 1320, 1321, 1322, 1311, 1323, 1306, 1324, 1325, 1326,\n     1307, 1312, 1308, 1327, 1328, 1313, 1314, 1315, 1329, 1302,\n     1303, 1330, 1316, 1304, 1317, 1331, 1318, 1319, 1305, 1320,\n     1321, 1322, 1332, 1323, 1306, 1324, 1325, 1326, 1307, 1333,\n     1308, 1327, 1328, 1334,  352,  895, 1329,  384,  643, 1330,\n      384, 1337,  384, 1331,  876, 1341,  895,  429,  895, 1205,\n     1332, 1335, 1205, 2658,  874, 1350, 1352, 1333, 1353, 1354,\n     2642, 1334,  356,  392,  392,  383,  392,  392,  393,  393,\n     1346,  656, 1345,  657,  657,  432,  876, 1339,  658, 1127,\n      890,  890, 2399, 1350, 1352, 1343, 1353, 1354, 1349, 1355,\n\n      400,  393,  392,  644, 1479, 1206,  392,  665, 1206,  392,\n     2397,  393,  891,  897,  900, 1479, 1131, 2586,  400, 1356,\n      902, 1784, 1338,  903,  897,  877, 1342, 1355, 1347,  659,\n      899, 1688, 1336,  643,  393,  392,  400, 2547,  392,  400,\n      393,  400, 1688,  900, 1357,  901,  912, 1356, 1414,  902,\n     1360, 1414,  903, 1129,  878, 2126, 1361, 1364, 1340,  660,\n     1358, 1366,  894,  393,  400,  392,  400, 1412,  392,  400,\n      393,  400, 1357,  900, 2544,  901, 1359, 1367, 1360,  902,\n     1368, 1369,  903,  663, 1361, 1364, 1370, 1365, 1358, 1366,\n     1371,  904,  904,  393,  400, 1155, 1155, 1155, 1155, 1155,\n\n     1155, 1155, 1155, 1155, 1359, 1367, 1373, 1374, 1368, 1369,\n     1375, 1377, 1378, 1379, 1370, 1380, 1381, 1382, 1371, 1383,\n     1340, 1348,  407, 1384, 1384, 1384, 1384, 1384, 1384, 1384,\n     1384, 1384, 1385, 1386, 1373, 1374, 1387, 1388, 1375, 1377,\n     1378, 1379, 1389, 1380, 1381, 1382, 1390, 1383, 1391, 1392,\n     1393,  400, 1394, 1395, 1396, 1397, 1398, 1399, 1400, 1401,\n     1385, 1386, 1402, 1404, 1387, 1388, 1405, 1406, 1407, 1408,\n     1389, 3686, 1209, 3687, 1390, 1209, 1391, 1392, 1393,  509,\n     1394, 1395, 1396, 1397, 1398, 1399, 1400, 1401, 2531, 1415,\n     1402, 1404, 1415, 1419, 1405, 1406, 1407, 1408, 1207, 1210,\n\n     1420, 1207, 1210, 1208, 1211, 1416, 1213,  511, 1416, 1213,\n     1417, 1214, 1418, 1421, 1214, 1418, 1215, 1216, 1424, 1425,\n     1216, 1419, 1426, 1427, 1428, 1429, 1430, 1431, 1420, 1432,\n     1433, 1434, 1435, 1436, 1437, 1440, 1438, 1441, 1442, 1443,\n     1444, 1421, 1439, 1445, 1446, 1447, 1424, 1425, 1448, 1449,\n     1426, 1427, 1428, 1429, 1430, 1431, 1450, 1432, 1433, 1434,\n     1435, 1436, 1437, 1440, 1438, 1441, 1442, 1443, 1444, 1451,\n     1439, 1445, 1446, 1447, 1452, 1453, 1448, 1449, 1454, 1455,\n     1456, 1457, 1458, 1459, 1450, 1460, 1461, 1464, 1465, 1462,\n     1466, 1467, 1468, 1469, 1470, 1471, 1472, 1451, 1473, 1478,\n\n     1480, 1481, 1452, 1453, 1463, 1482, 1454, 1455, 1456, 1457,\n     1458, 1459, 1484, 1460, 1461, 1464, 1465, 1462, 1466, 1467,\n     1468, 1469, 1470, 1471, 1472, 1474, 1473, 1478, 1480, 1481,\n     1485, 1486, 1463, 1482, 1487, 1488, 1475, 1490, 1491, 1492,\n     1484, 1476, 1477, 1493, 1495, 1497, 1498, 1499, 1500, 1502,\n     1503, 1504, 1506, 1474, 1501, 1507, 1508, 1509, 1485, 1486,\n     1510, 1511, 1487, 1488, 1475, 1490, 1491, 1492, 1512, 1476,\n     1477, 1493, 1495, 1497, 1498, 1499, 1500, 1502, 1503, 1504,\n     1506, 1513, 1501, 1507, 1508, 1509, 1514, 1515, 1510, 1511,\n     1516, 1517, 1518, 1519, 1520, 1521, 1512, 1522, 1523, 1524,\n\n     1525, 1526, 1527, 1528,  895, 1414, 1532, 3972, 1414, 1513,\n     1535, 1533, 3972, 1534, 1514, 1515, 2110, 2528, 1516, 1517,\n     1518, 1519, 1520, 1521, 2513, 1522, 1523, 1524, 1525, 1526,\n     1527, 1528,  392,  665, 1532,  392, 1529,  393, 1535, 1533,\n      900, 1534,  901,  896, 3972,  895,  902,  400, 1536,  903,\n      400, 1537,  400, 1538, 1539, 1540,  400, 1541, 1542, 1543,\n      393, 1548, 1549,  392,  892, 1550,  392, 1878,  393, 2504,\n     1551, 1531,  897,  901, 1555,  400, 1536,  902, 1878, 1537,\n      903, 1538, 1539, 1540, 1126, 1541, 1542, 1543,  904, 1548,\n     1549,  392, 1545, 1550, 1552, 1545, 1553, 1545, 1551, 1554,\n\n      662, 1559, 1546,  659, 2399, 1557, 1545, 1560, 1561, 1563,\n     1569, 1558, 1570,  897, 1573, 1574, 1575, 1576, 1577, 1133,\n     1415, 3972, 1552, 1415, 1553, 1598, 3972, 1554, 1598, 1559,\n     1578, 1579,  894, 1557, 1580, 1560, 1561, 1563, 1569, 1558,\n     1570, 1581, 1573, 1574, 1575, 1576, 1577, 1582, 1547, 1384,\n     1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1578, 1579,\n     1583, 1584, 1580, 1585, 1586, 1587, 1588, 1590, 1591, 1581,\n     1592, 1593, 1589, 1416, 1418, 1582, 1416, 1418, 1417, 1599,\n     1600, 1603, 1604, 1605, 1606, 1607, 1605, 1608, 1583, 1584,\n     1609, 1585, 1586, 1587, 1588, 1590, 1591, 1610, 1592, 1593,\n\n     1589, 1611, 1612, 1613, 1614, 1615, 1616, 1599, 1600, 1603,\n     1604, 1620, 1606, 1607, 1621, 1608, 1622, 1623, 1609, 1624,\n     1625, 1626, 1617, 1627, 1628, 1610, 1633, 1634, 1635, 1611,\n     1612, 1613, 1614, 1615, 1616, 1618, 2397, 1636, 1637, 1620,\n     1619, 1638, 1621, 1639, 1622, 1623, 1640, 1624, 1625, 1626,\n     1617, 1627, 1628, 1629, 1633, 1634, 1635, 1598, 2301, 1630,\n     1598, 1631, 1647, 1618, 1632, 1636, 1637, 1648, 1619, 1638,\n     1649, 1639, 1641, 1650, 1640, 1651, 1642, 1652, 1653, 1654,\n     1655, 1629, 1656, 1643, 1657, 1644, 1645, 1630, 1646, 1631,\n     1647, 1658, 1632, 1659, 1660, 1648, 1661, 1662, 1649, 1663,\n\n     1641, 1650, 1664, 1651, 1642, 1652, 1653, 1654, 1655, 1665,\n     1656, 1643, 1657, 1644, 1645, 1666, 1646, 1667, 1671, 1658,\n     1672, 1659, 1660, 1673, 1661, 1662, 1674, 1663, 1675, 1676,\n     1664, 1683, 1677, 1684, 2300, 1690, 1691, 1665, 1692, 1678,\n     1685, 1693, 1694, 1666, 1695, 1667, 1671, 1679, 1672, 1696,\n     1697, 1673, 1680, 1686, 1674, 1687, 1675, 1676, 1698, 1683,\n     1677, 1684, 1688, 1690, 1691, 1699, 1692, 1678, 1685, 1693,\n     1694, 1700, 1695, 1688, 1701, 1679, 1702, 1696, 1697, 1703,\n     1680, 1686, 1704, 1687, 1689, 1705, 1698, 1707, 1708, 1709,\n     1706, 1710, 1711, 1699, 1712, 1713, 1714, 1715, 1716, 1700,\n\n     1717, 1720, 1701, 1722, 1702, 1718, 1721, 1703, 1723, 1724,\n     1704,  895, 1689, 1705, 1929, 1707, 1708, 1709, 1706, 1710,\n     1711, 1719, 1712, 1713, 1714, 1715, 1716, 1726, 1717, 1720,\n     1727, 1722, 1725, 1718, 1721, 1728, 1723, 1724, 1729,  400,\n     1730, 1127,  400, 1731,  400, 1732, 1733, 1734, 1735, 1719,\n     2295, 2200,  400, 1736, 1605, 1726, 1129, 1791, 1727, 1792,\n     1930, 1742, 1745, 1728, 3972, 2185, 1729,  400, 1730, 3972,\n     1746, 1731, 1747, 1732, 1733, 1734, 1735, 1748,  891,  897,\n     1347, 1736, 1545, 1545, 1980, 1545, 1545, 1545, 1545, 1742,\n     1745, 1753, 1737, 1737, 1754,  904, 1545, 1545, 1746, 1755,\n\n     1747, 1756, 1750, 1757, 1759, 1748, 1751, 1760, 1752, 1556,\n     1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 3754, 1753,\n     3755, 1763, 1754, 1764, 1765, 1766, 1767, 1755, 1768, 1756,\n     1750, 1757, 1759, 1769, 1751, 1760, 1752, 1770, 1738, 1547,\n     1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1763,\n     1771, 1764, 1765, 1766, 1767, 1772, 1768, 1773, 1774, 1775,\n     1776, 1769, 1777, 1778, 1779, 1770, 1780, 1781, 1782, 1783,\n     1785, 1789, 1790, 1794, 1795, 1796, 1797, 1798, 1771, 1800,\n     1801, 1802, 1803, 1772, 1799, 1773, 1774, 1775, 1776, 1804,\n     1777, 1778, 1779, 1805, 1780, 1781, 1782, 1783, 1785, 1789,\n\n     1790, 1794, 1795, 1796, 1797, 1798, 1806, 1800, 1801, 1802,\n     1803, 1807, 1799, 1808, 1809, 1810, 1811, 1804, 1812, 1813,\n     1814, 1805, 1815, 1816, 1817, 1818, 1819, 1820, 1821, 1822,\n     1823, 1824, 1825, 1826, 1806, 1827, 1828, 1829, 1830, 1807,\n     1831, 1808, 1809, 1810, 1811, 1832, 1812, 1813, 1814, 1833,\n     1815, 1816, 1817, 1818, 1819, 1820, 1821, 1822, 1823, 1824,\n     1825, 1826, 1834, 1827, 1828, 1829, 1830, 1835, 1831, 1836,\n     1837, 1838, 1839, 1832, 1840, 1841, 1842, 1833, 1843, 1844,\n     1845, 1847, 1848, 1849, 1850, 1851, 1852, 1853, 1854, 1855,\n     1834, 1845, 1856, 1594, 1857, 1835, 1858, 1836, 1837, 1838,\n\n     1839, 1860, 1840, 1841, 1842, 1862, 1843, 1844, 1863, 1847,\n     1848, 1849, 1850, 1851, 1852, 1853, 1854, 1855, 1864, 1865,\n     1856, 1846, 1857, 1866, 1858, 1867, 1868, 1880, 1881, 1860,\n     1882, 1883, 1884, 1862, 1885, 1886, 1863, 1869, 1878, 1595,\n     1887, 1888, 3754, 1889, 3755, 1890, 1864, 1865, 1978, 1878,\n     1891, 1866, 3972, 1867, 1868, 1880, 1881, 3972, 1882, 1883,\n     1884, 1892, 1885, 1886, 1893, 1869, 1870, 1871, 1887, 1888,\n     1872, 1889, 1873, 1890, 1894, 1895, 1874, 1875, 1891, 1896,\n     1876, 1897, 1898, 1899, 1900, 1877, 1901, 1902, 1903, 1892,\n     1904, 1905, 1893, 1906, 1870, 1871, 1909, 1911, 1872, 1910,\n\n     1873, 1912, 1894, 1895, 1874, 1875, 1913, 1896, 1876, 1897,\n     1898, 1899, 1900, 1877, 1901, 1902, 1903, 1907, 1904, 1905,\n     1914, 1906, 1915, 1917, 1909, 1911, 1918, 1910, 1919, 1912,\n     1908, 1920, 1921, 1922, 1913, 1925, 1923, 1926, 2149, 1931,\n     1934, 1935, 2243, 1937, 1938, 1907, 1939, 1940, 1914, 1924,\n     1915, 1917, 1545, 2243, 1918, 1545, 1919, 1545, 1908, 1920,\n     1921, 1922, 1927, 1925, 1923, 1926, 1545, 1931, 1934, 1935,\n     1936, 1937, 1938, 1944, 1939, 1940, 1945, 1924, 1749, 1749,\n     1749, 1749, 1749, 1749, 1749, 1749, 1749, 1941, 1946, 1942,\n     1949, 1950, 1951, 1947, 1605, 2012, 2123, 1791, 2012, 1792,\n\n     2122, 1944, 1930, 1952, 1945, 1953, 1954, 1955, 1547, 1956,\n     1957, 1958, 1959, 1960, 1961, 1941, 1946, 1942, 1949, 1950,\n     1951, 1947, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761,\n     1761, 1952, 1965, 1953, 1954, 1955, 1962, 1956, 1957, 1958,\n     1959, 1960, 1961, 1966, 1968, 1969, 1963, 1970, 1971, 1972,\n     1973, 1974, 1967, 1975, 1981, 1982, 1984, 1964, 1985, 1986,\n     1965, 1987, 1988, 1989, 1962, 1990, 1991, 1992, 1993, 1994,\n     1995, 1966, 1968, 1969, 1963, 1970, 1971, 1972, 1973, 1974,\n     1967, 1975, 1981, 1982, 1984, 1964, 1985, 1986, 1996, 1987,\n     1988, 1989, 1997, 1990, 1991, 1992, 1993, 1994, 1995, 1999,\n\n     2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 1998, 2008,\n     2009, 2010, 2011, 2013, 2014, 2015, 1996, 2016, 2017, 2018,\n     1997, 2019, 2020, 2021, 2022, 2023, 2024, 1999, 2000, 2001,\n     2002, 2003, 2004, 2005, 2006, 2007, 1998, 2008, 2009, 2010,\n     2011, 2013, 2014, 2015, 2025, 2016, 2017, 2018, 2026, 2019,\n     2020, 2021, 2022, 2023, 2024, 2027, 2029, 2030, 2031, 2029,\n     2032, 2028, 2033, 2035, 2036, 2037, 2038, 2034, 2039, 2040,\n     2042, 2043, 2025, 2044, 2047, 2048, 2026, 2049, 2050, 2051,\n     2040, 2055, 3972, 2027, 2056, 2030, 2031, 3972, 2032, 2028,\n     2033, 2035, 2036, 2037, 2038, 2034, 2039, 2045, 2042, 2043,\n\n     2057, 2044, 2047, 2048, 2058, 2049, 2050, 2051, 2052, 2055,\n     2041, 2046, 2056, 2059, 2060, 2053, 2061, 2062, 2065, 2063,\n     2066, 2067, 2068, 2069, 2070, 2045, 2071, 2077, 2057, 3972,\n     2078, 2079, 2058, 2064, 3972, 2080, 2052, 2081, 2082, 2084,\n     2085, 2059, 2060, 2053, 2061, 2062, 2065, 2063, 2066, 2067,\n     2068, 2069, 2070, 2086, 2071, 2077, 2072, 2073, 2078, 2079,\n     2087, 2064, 2074, 2080, 2088, 2081, 2082, 2084, 2085, 2089,\n     2075, 2090, 2091, 2076, 2092, 2093, 2094, 2095, 2100, 2096,\n     2101, 2086, 2102, 2097, 2072, 2073, 2103, 2104, 2087, 2105,\n     2074, 2106, 2088, 2109, 2098, 2083, 2099, 2089, 2075, 2090,\n\n     2091, 2076, 2092, 2093, 2094, 2095, 2100, 2096, 2101, 2111,\n     2102, 2097, 2054, 2112, 2103, 2104, 2115, 2105, 2113, 2106,\n     2116, 2095, 2098, 2096, 2099, 2114, 2117, 2097, 2118, 2119,\n     2120, 2121, 1739, 1739, 2125, 1980, 2127, 2111, 2098, 2110,\n     2107, 2112, 2321, 2128, 2115, 2129, 2113, 2130, 2116, 2095,\n     1978, 2096, 3657, 2114, 2117, 2097, 2118, 2119, 2120, 2121,\n     1545, 2133, 2134, 1545, 2127, 1545, 2098, 2131, 2107, 2132,\n     1737, 2128, 2135, 2129, 1545, 2130, 2136, 2137, 1740, 1930,\n     2126, 2138, 2139, 2150, 2151, 2152, 2153, 2154, 2322, 2133,\n     2134, 2155, 2156, 2157, 2158, 2131, 2159, 2132, 2201, 2461,\n\n     2135, 2201, 2461, 3658, 2136, 2137, 2162, 1976, 2163, 2138,\n     2139, 2150, 2151, 2152, 2153, 2154, 1738, 2140, 2164, 2155,\n     2156, 2157, 2158, 2165, 2159, 2141, 2141, 2141, 2141, 2141,\n     2141, 2141, 2141, 2141, 2162, 2160, 2163, 2142, 2166, 2143,\n     2144, 2145, 2161, 2167, 2168, 2146, 2164, 2170, 2171, 2172,\n     2147, 2165, 2173, 2174, 2175, 2169, 2176, 2184, 2186, 2148,\n     1948, 2180, 2181, 2160, 1943, 2142, 2166, 2143, 2144, 2145,\n     2161, 2167, 2168, 2146, 2187, 2170, 2171, 2172, 2147, 2188,\n     2173, 2174, 2175, 2169, 2176, 2184, 2186, 2148, 2179, 2180,\n     2181, 2179, 2182, 2180, 2183, 2182, 2189, 2190, 2191, 2192,\n\n     2193, 2194, 2187, 2195, 2196, 2197, 2198, 2188, 2199, 2202,\n     2203, 2204, 2205, 2206, 2207, 2208, 1978, 2209, 2210, 2211,\n     1933, 2212, 1547, 2215, 2189, 2190, 2191, 2192, 2193, 2194,\n     2216, 2195, 2196, 2197, 2198, 2217, 2199, 2202, 2203, 2204,\n     2205, 2206, 2207, 2208, 1978, 2209, 2210, 2211, 1980, 2212,\n     2012, 2215, 2218, 2012, 2219, 2214, 2220, 2221, 2216, 2222,\n     2223, 2224, 2225, 2217, 2226, 2227, 2228, 2229, 2230, 2029,\n     2234, 2235, 2231, 2236, 2232, 2237, 2238, 2239, 2240, 2241,\n     2218, 2242, 2219, 2244, 2220, 2221, 2245, 2222, 2223, 2224,\n     2225, 2246, 2226, 2227, 2228, 2229, 2230, 2247, 2234, 2235,\n\n     2248, 2236, 2249, 2237, 2238, 2239, 2240, 2241, 2250, 2242,\n     2251, 2244, 2252, 2253, 2245, 2254, 2255, 2256, 2467, 2246,\n     1928, 2269, 1741, 2270, 1916, 2247, 2271, 2272, 2248, 2467,\n     2249, 2273, 2201, 2274, 2275, 2423, 2250, 2424, 2251, 2276,\n     2252, 2253, 2277, 2254, 2255, 2256, 2257, 2258, 2259, 2269,\n     2260, 2270, 2261, 2262, 2271, 2272, 2263, 2264, 2265, 2273,\n     2266, 2274, 2275, 2267, 2278, 2268, 2279, 2276, 2280, 2281,\n     2277, 2282, 2283, 2284, 2257, 2258, 2259, 2285, 2260, 2286,\n     2261, 2262, 2287, 2288, 2263, 2264, 2265, 2289, 2266, 2290,\n     2291, 2267, 2278, 2268, 2279, 2292, 2280, 2281, 2293, 2282,\n\n     2283, 2284, 2294, 2296, 2297, 2285, 2298, 2286, 2299, 2302,\n     2287, 2288, 2303, 2304, 2305, 2289, 2306, 2290, 2291, 2307,\n     2308, 2309, 2310, 2292, 2311, 2312, 2293, 2313, 2318, 2324,\n     2294, 2296, 2297, 2319, 2298, 2320, 2299, 2302, 2321, 2326,\n     2303, 2304, 2305, 2327, 2306, 2328, 2329, 2307, 2308, 2309,\n     2310, 2330, 2311, 2312, 2331, 2313, 2318, 2332, 2333, 2334,\n     2335, 2319, 2336, 2320, 2337, 2340, 2337, 2326, 2342, 2343,\n     2344, 2327, 2345, 2328, 2329, 2325, 2346, 2347, 2348, 2330,\n     2349, 2350, 2331, 2468, 2110, 2332, 2333, 2334, 2335, 2351,\n     2336, 2352, 2362, 2353, 2468, 1879, 2342, 2343, 2344, 2609,\n\n     2345, 1861, 2609, 2363, 2346, 2347, 2348, 2364, 2349, 2350,\n     2338, 2341, 2126, 2365, 1859, 2367, 2368, 2351, 2366, 2352,\n     2362, 2353, 2354, 2354, 2354, 2354, 2354, 2354, 2354, 2354,\n     2354, 2363, 2369, 2371, 2355, 2364, 2356, 2357, 2358, 2372,\n     2373, 2365, 2359, 2367, 2368, 2374, 2366, 2360, 2375, 2376,\n     2377, 2378, 2379, 2380, 2381, 2382, 2361, 1786, 1412, 1596,\n     2369, 2371, 2355, 1762, 2356, 2357, 2358, 2372, 2373, 2383,\n     2359, 2384, 2385, 2374, 2386, 2360, 2375, 2376, 2377, 2378,\n     2379, 2380, 2381, 2382, 2361, 2141, 2141, 2141, 2141, 2141,\n     2141, 2141, 2141, 2141, 2387, 2388, 2389, 2383, 2390, 2384,\n\n     2385, 2391, 2386, 2392, 2393, 2394, 2395, 2179, 2180, 2181,\n     2179, 2182, 2180, 2183, 2182, 2180, 2183, 2400, 2401, 2402,\n     2403, 2404, 2387, 2388, 2389, 2413, 2390, 2414, 2415, 2391,\n     2416, 2392, 2393, 2394, 2395, 1758, 2417, 2418, 2419, 2426,\n     2420, 2421, 2426, 1744, 2422, 2400, 2401, 2402, 2403, 2404,\n     2428, 2429, 1743, 2413, 2430, 2414, 2415, 2431, 2416, 2432,\n     2433, 2434, 2435, 1978, 2417, 2418, 2419, 1980, 2420, 2421,\n     1980, 2405, 2422, 2436, 2405, 2437, 1741, 2439, 2428, 2429,\n     2427, 3972, 2430, 2440, 3972, 2431, 3972, 2432, 2433, 2434,\n     2435, 2406, 1682, 2441, 2442, 2443, 2444, 2445, 2446, 2447,\n\n     2448, 2436, 2449, 2437, 2407, 2439, 2408, 2451, 2427, 2452,\n     2453, 2440, 2454, 1681, 2456, 2457, 2409, 2458, 2410, 2411,\n     2412, 2441, 2442, 2443, 2444, 2445, 2446, 2447, 2448, 2459,\n     2449, 2460, 2407, 2462, 2408, 2451, 2029, 2452, 2453, 2231,\n     2454, 2232, 2456, 2457, 2409, 2458, 2410, 2411, 2412, 2463,\n     2464, 2465, 2466, 2469, 2470, 2471, 2472, 2459, 2473, 2460,\n     2474, 2462, 2476, 2477, 2478, 2479, 2480, 2481, 2482, 2475,\n     2483, 2484, 2485, 2486, 2487, 2488, 1670, 2463, 2464, 2465,\n     2466, 2469, 2470, 2471, 2472, 2491, 2473, 2492, 2474, 2489,\n     2476, 2477, 2478, 2479, 2480, 2481, 2482, 2493, 2483, 2484,\n\n     2485, 2486, 2487, 2488, 2490, 2494, 2495, 2496, 2497, 2498,\n     2499, 2500, 2501, 2491, 2502, 2492, 2503, 2489, 2505, 2506,\n     2507, 2508, 2509, 2510, 2511, 2493, 2512, 2514, 2515, 2516,\n     2517, 2518, 2490, 2494, 2495, 2496, 2497, 2498, 2499, 2500,\n     2501, 2519, 2502, 2520, 2503, 2521, 2505, 2506, 2507, 2508,\n     2509, 2510, 2511, 2522, 2512, 2514, 2515, 2516, 2517, 2518,\n     2525, 2526, 2527, 2529, 2532, 2534, 2535, 2536, 2537, 2519,\n     2538, 2520, 2539, 2521, 2540, 2541, 2542, 2543, 2545, 2548,\n     2550, 2522, 1669, 2551, 2552, 2553, 2554, 2555, 2525, 2526,\n     2527, 2556, 2557, 2534, 2535, 2536, 2537, 1668, 2538, 2558,\n\n     2539, 2559, 2540, 2541, 2542, 2543, 2560, 2562, 2550, 2530,\n     2533, 2551, 2552, 2553, 2554, 2555, 1602, 2563, 2564, 2556,\n     2557, 2565, 2567, 2568, 2546, 2549, 2566, 2558, 2561, 2559,\n     2569, 2570, 2571, 2572, 2560, 2562, 2354, 2354, 2354, 2354,\n     2354, 2354, 2354, 2354, 2354, 2563, 2564, 2573, 2574, 2565,\n     2567, 2568, 2575, 2576, 2566, 2577, 2578, 2579, 2569, 2570,\n     2571, 2572, 2580, 2581, 2582, 2583, 2584, 2585, 2587, 2588,\n     2589, 2590, 2591, 2592, 2593, 2573, 2574, 2594, 2595, 2619,\n     2575, 2576, 2619, 2577, 2578, 2579, 2597, 2598, 2601, 2597,\n     2580, 2581, 2582, 2583, 2584, 2585, 2587, 2588, 2589, 2590,\n\n     2591, 2592, 2593, 2602, 2603, 2594, 2595, 2600, 2598, 2605,\n     2600, 2604, 2405, 2610, 1601, 2606, 2601, 2607, 2611, 2613,\n     2615, 2616, 2617, 2618, 2612, 2620, 2621, 2622, 2623, 1596,\n     2624, 2602, 2603, 2625, 2626, 1572, 2614, 2605, 2627, 2604,\n     2201, 2610, 2397, 2423, 2632, 2424, 2611, 2613, 2615, 2616,\n     2617, 2618, 2612, 2620, 2621, 2622, 2623, 2396, 2624, 2633,\n     2634, 2625, 2626, 2399, 2614, 2426, 2627, 2635, 2629, 2636,\n     2630, 2637, 2632, 2638, 2639, 2641, 2640, 2643, 2398, 2640,\n     2644, 2645, 2646, 2647, 2648, 2649, 2650, 2633, 2634, 2651,\n     2652, 2653, 2654, 2655, 2656, 2635, 2657, 2636, 2659, 2637,\n\n     2660, 2638, 2639, 2641, 2661, 2643, 2662, 2661, 2644, 2645,\n     2646, 2647, 2648, 2649, 2650, 2663, 2667, 2651, 2652, 2653,\n     2654, 2655, 2656, 2668, 2657, 2669, 2659, 2665, 2660, 2670,\n     2665, 2671, 2666, 2672, 2662, 2673, 2675, 2677, 2679, 2680,\n     2681, 2682, 2683, 2663, 2667, 2684, 2685, 2686, 2677, 2687,\n     1571, 2668, 2689, 2669, 2690, 2691, 2692, 2670, 2693, 2671,\n     2694, 2672, 2695, 2673, 2675, 2696, 2679, 2680, 2681, 2682,\n     2683, 2697, 2698, 2684, 2685, 2686, 2700, 2687, 2678, 2701,\n     2689, 2702, 2690, 2691, 2692, 2703, 2693, 2704, 2694, 2705,\n     2695, 2706, 2707, 2696, 2708, 2709, 2710, 2711, 2712, 2697,\n\n     2698, 2713, 2714, 2715, 2700, 2716, 2717, 2701, 2718, 2702,\n     2719, 2721, 2722, 2703, 2724, 2704, 2321, 2705, 2529, 2706,\n     2707, 2726, 2708, 2709, 2710, 2711, 2712, 2727, 2728, 2713,\n     2714, 2715, 2735, 2716, 2717, 2729, 2718, 2730, 2719, 2721,\n     2722, 2731, 2732, 2733, 2734, 2337, 2545, 2737, 2738, 2726,\n     1568, 2739, 2740, 1936, 2741, 2727, 2728, 2742, 2743, 2744,\n     2533, 2745, 2725, 2729, 2533, 2730, 2746, 2747, 2748, 2731,\n     2732, 2733, 2734, 2749, 2750, 2737, 2738, 2751, 2549, 2739,\n     2740, 1936, 2741, 2752, 2753, 2742, 2743, 2744, 2754, 2745,\n     2755, 2736, 2549, 2756, 2746, 2747, 2748, 2757, 2758, 2759,\n\n     2760, 2749, 2750, 2761, 2762, 2751, 2763, 2764, 2765, 2766,\n     2767, 2752, 2753, 2769, 2771, 2772, 2754, 2773, 2755, 2774,\n     2775, 2756, 2776, 2777, 2778, 2757, 2758, 2759, 2760, 1567,\n     3728, 2761, 2762, 2779, 2763, 2764, 2765, 2766, 2767, 2780,\n     2781, 2769, 2771, 2772, 2782, 2773, 2609, 2774, 2775, 2784,\n     2776, 2777, 2778, 2597, 2598, 2786, 2597, 2600, 2598, 2405,\n     2600, 2779, 2606, 2787, 2607, 2788, 2789, 2780, 2781, 2790,\n     2791, 2792, 2782, 2793, 2794, 2619, 2798, 2799, 2795, 2800,\n     2796, 3729, 2801, 2786, 2802, 2426, 2803, 2804, 2629, 2807,\n     2630, 2787, 2808, 2788, 2789, 2809, 1566, 2790, 2791, 2792,\n\n     1565, 2793, 2794, 2810, 2798, 2799, 2811, 2800, 2812, 2397,\n     2801, 2817, 2802, 2399, 2803, 2804, 2813, 2807, 2814, 2816,\n     2808, 2818, 2816, 2809, 2396, 2819, 2820, 2821, 2398, 2822,\n     2823, 2810, 2824, 2825, 2811, 2826, 2812, 2827, 2826, 2817,\n     2829, 2830, 2831, 2832, 2813, 2833, 2814, 2834, 2840, 2818,\n     2838, 2839, 1564, 2819, 2820, 2821, 2828, 2822, 2823, 2661,\n     2824, 2825, 2835, 2844, 2836, 2827, 2846, 2847, 2829, 2830,\n     2831, 2832, 2848, 2833, 2849, 2834, 2840, 2665, 2838, 2839,\n     2665, 2850, 2666, 2851, 2828, 2852, 2853, 2854, 2855, 2856,\n     2857, 2844, 2858, 2859, 2846, 2847, 2860, 2861, 2862, 2863,\n\n     2848, 2864, 2849, 2865, 2866, 2867, 2868, 2869, 2870, 2850,\n     2873, 2851, 2874, 2852, 2853, 2854, 2855, 2856, 2857, 2875,\n     2858, 2859, 2876, 2877, 2860, 2861, 2862, 2863, 2878, 2864,\n     2879, 2865, 2866, 2867, 2868, 2869, 2870, 2880, 2873, 2881,\n     2874, 2882, 2883, 2884, 2885, 2886, 2887, 2875, 2888, 2889,\n     2876, 2877, 2890, 2891, 2892, 2893, 2878, 2894, 2879, 2895,\n     2896, 2529, 2897, 2898, 2899, 2880, 2900, 2881, 2901, 2882,\n     2883, 2884, 2885, 2886, 2887, 2902, 2888, 2889, 2903, 2545,\n     2890, 2891, 2892, 2893, 2904, 2894, 2905, 2895, 2896, 2906,\n     2907, 2898, 2899, 2908, 2900, 2909, 2901, 1562, 2910, 2911,\n\n     2912, 2913, 2914, 2902, 1127, 2915, 2903, 2530, 2110, 2916,\n     2917, 2918, 2904, 2919, 2920, 2921, 2922, 2906, 2907, 2923,\n     2924, 2908, 2925, 2909, 2926, 2546, 2910, 2911, 2912, 2913,\n     2914, 2927, 2126, 2915, 2928, 2929, 2930, 2916, 2917, 2918,\n     2931, 2919, 2920, 2921, 2922, 2932, 2933, 2923, 2924, 2934,\n     2925, 2935, 2926, 2936, 2937, 2938, 2939, 2940, 2941, 2927,\n     2942, 2943, 2928, 2929, 2930, 2944, 2945, 2946, 2931, 2609,\n     2948, 2949, 2784, 2932, 2933, 2950, 2951, 2934, 2952, 2935,\n     2953, 2936, 2937, 2938, 2939, 2940, 2941, 2954, 2942, 2943,\n     2955, 2956, 2958, 2944, 2945, 2946, 2959, 2619, 2948, 2949,\n\n     2795, 2960, 2796, 2950, 2951, 2961, 2952, 2962, 2953, 2963,\n     2964, 2966, 2967, 2968, 2969, 2954, 2971, 2969, 2955, 2956,\n     2958, 2972, 2970, 2816, 2959, 2970, 2816, 2973, 2974, 2960,\n     2975, 2976, 2983, 2961, 2978, 2962, 2984, 2963, 2964, 2966,\n     2967, 2968, 2979, 2980, 2971, 2981, 2985, 2982, 2986, 2972,\n     2990, 2991, 2992, 2993, 2826, 2973, 2974, 2987, 2975, 2988,\n     2983, 2994, 2978, 2977, 2984, 2995, 2996, 2997, 2999, 3000,\n     2979, 2980, 3001, 2981, 2985, 2982, 2986, 3005, 2990, 2991,\n     2992, 2993, 2661, 3006, 3008, 2835, 3011, 2836, 3007, 2994,\n     3010, 2977, 3012, 2995, 2996, 2997, 2999, 3000, 3013, 3007,\n\n     3001, 3010, 3014, 3015, 3016, 3005, 3017, 3018, 3021, 3023,\n     3024, 3006, 3008, 3025, 3011, 3026, 3027, 3029, 3030, 3031,\n     3012, 3032, 3022, 3033, 3034, 3035, 3013, 3027, 3036, 3037,\n     3014, 3015, 3016, 3038, 3017, 3018, 3021, 3023, 3024, 3039,\n     3040, 3025, 3041, 3026, 3042, 3029, 3030, 3031, 3043, 3032,\n     3044, 3033, 3034, 3035, 3045, 3046, 3036, 3037, 3047, 3048,\n     3049, 3038, 3050, 3051, 3052, 3053, 3054, 3039, 3040, 3055,\n     3041, 3056, 3042, 2529, 3057, 3058, 3043, 3059, 3044, 3060,\n     3061, 2545, 3045, 3046, 3066,  880, 3047, 3048, 3049, 3067,\n     3050, 3051, 3052, 3053, 3054, 3063, 3068, 3055, 3069, 3056,\n\n     3070, 3071, 3057, 3058, 3072, 3059, 3073, 3060, 3061, 3074,\n     3075, 3076, 3066, 3064, 3077, 3078, 3079, 3067, 3080, 2325,\n     3081, 3082, 3083, 3063, 3068, 3084, 3069, 2341, 3070, 3071,\n     3085, 3086, 3072, 3087, 3073, 3088, 3089, 3074, 3075, 3076,\n     3090, 3064, 3077, 3078, 3079, 3091, 3080, 3092, 3081, 3082,\n     3083, 3093, 3094, 3084, 3095, 3096, 3097, 3098, 3085, 3086,\n     3099, 3087, 3100, 3088, 3089, 3101, 3102, 3103, 3090, 3105,\n     3106, 3107, 3108, 3091, 3109, 3092, 3111, 3112, 3110, 3093,\n     3094, 3110, 3095, 3096, 3097, 3098, 3113, 3114, 3099, 3116,\n     3100, 3120, 3116, 3101, 3102, 3103, 3121, 3105, 3106, 3107,\n\n     3108, 3122, 3109, 2970, 3111, 3112, 3117, 3124, 3118, 3125,\n     3126, 3127, 3128, 3129, 3113, 3114, 3130, 3133, 3134, 3120,\n     2826, 3134, 3135, 2987, 3121, 2988, 3136, 3131, 3132, 3122,\n     3139, 3140, 3141, 3137, 3143, 3124, 3144, 3125, 3126, 3127,\n     3128, 3129, 3145, 3142, 3130, 3133, 3142, 3146, 3148, 3149,\n     3135, 3150, 3152, 3153, 3136, 3131, 3132, 3154, 3139, 3140,\n     3141, 3137, 3143, 3155, 3144, 3156, 3157, 3158, 3154, 3159,\n     3145, 3160, 3161, 3163, 3164, 3146, 3148, 3149, 3167, 3150,\n     3152, 3153, 3165, 3166, 3168, 3169, 3170, 3171, 3172, 3173,\n     3174, 3155, 3175, 3156, 3157, 3158, 3176, 3159, 3177, 3160,\n\n     3161, 3163, 3164, 3178, 3179, 3180, 3167, 3181, 3182, 3184,\n     3165, 3166, 3168, 3169, 3170, 3171, 3172, 3173, 3174, 3182,\n     3175, 1505, 3187, 3185, 3176, 3188, 3177, 3189, 3190, 3191,\n     3193, 3178, 3179, 3180, 3185, 3181, 1496, 3184, 3194, 3195,\n     3196, 3197, 3198, 3199, 3200, 3202, 3203, 3204, 3205, 3183,\n     3187, 3207, 3208, 3188, 3209, 3189, 3190, 3191, 3193, 3210,\n     3211, 3212, 3213, 3206, 3186, 3214, 3194, 3195, 3196, 3197,\n     3198, 3199, 3200, 3202, 3203, 3204, 3205, 3215, 3216, 3207,\n     3208, 3217, 3209, 3218, 3219, 3220, 3221, 3210, 3211, 3212,\n     3213, 3206, 3222, 3214, 3223, 3224, 3225, 3226, 3227, 3228,\n\n     3229, 3230, 3231, 3232, 3233, 3215, 3216, 3234, 3236, 3217,\n     3237, 3218, 3219, 3220, 3221, 3235, 3238, 3239, 3235, 3240,\n     3222, 3241, 3223, 3224, 3225, 3226, 3227, 3228, 3229, 3230,\n     3231, 3232, 3233, 3242, 3243, 3234, 3236, 3244, 3237, 3247,\n     3116, 1494, 3247, 3116, 3238, 3239, 1489, 3240, 3110, 3241,\n     3246, 3110, 3248, 2970, 3250, 3251, 3117, 3252, 3118, 3254,\n     3255, 3242, 3243, 3256, 3257, 3244, 3245, 3245, 3245, 3245,\n     3245, 3245, 3245, 3245, 3245, 3258, 3259, 3260, 3246, 3261,\n     3248, 3262, 3250, 3251, 3263, 3252, 3273, 3254, 3255, 3273,\n     3347, 3256, 3257, 3347, 3265, 3134, 3266, 3267, 3134, 3269,\n\n     3270, 3271, 3274, 3258, 3259, 3260, 3275, 3261, 3276, 3262,\n     3277, 3278, 3263, 3264, 3264, 3264, 3264, 3264, 3264, 3264,\n     3264, 3264, 3265, 3279, 3266, 3267, 3280, 3269, 3270, 3271,\n     3274, 3281, 3282, 3283, 3275, 3284, 3276, 3285, 3277, 3278,\n     3286, 3287, 3288, 3289, 3290, 3291, 3292, 3293, 3294, 3296,\n     3297, 3279, 3298, 3299, 3280, 3300, 3302, 3303, 3304, 3281,\n     3282, 3283, 3305, 3284, 3306, 3285, 3307, 3308, 3286, 3287,\n     3288, 3289, 3290, 3291, 3292, 3293, 3294, 3296, 3297, 3312,\n     3298, 3299, 3310, 3300, 3302, 3303, 3304, 3313, 3314, 3315,\n     3305, 3316, 3306, 3310, 3307, 3308, 3317, 3318, 3319, 3320,\n\n     3321, 3322, 3323, 3324, 3325, 3328, 3329, 3312, 3330, 3326,\n     3331, 3332, 3333, 3334, 3335, 3313, 3314, 3315, 3336, 3316,\n     3327, 3337, 3338, 3311, 3317, 3318, 3319, 3320, 3321, 3322,\n     3323, 3324, 3325, 3328, 3329, 3339, 3330, 3326, 3331, 3332,\n     3333, 3334, 3335, 3340, 3341, 3342, 3336, 3343, 3327, 3337,\n     3338, 3344, 3345, 3346, 3348, 3349, 3235, 3352, 3353, 3235,\n     3352, 3350, 3354, 3339, 3355, 3356, 3357, 3358, 3359, 3360,\n     1483, 3340, 3341, 3342, 3367, 3343, 1423, 3367, 1422, 3344,\n     3345, 3346, 3348, 3349, 3361, 3363, 3353, 3365, 3366, 3370,\n     3354, 3371, 3355, 3356, 3357, 3358, 3359, 3360, 3245, 3245,\n\n     3245, 3245, 3245, 3245, 3245, 3245, 3245, 3247, 3372, 3373,\n     3247, 3374, 3361, 3363, 3375, 3365, 3366, 3370, 3376, 3371,\n     3377, 3368, 3378, 3379,  541, 3362, 3362, 3362, 3362, 3362,\n     3362, 3362, 3362, 3362, 3381, 3380, 3372, 3373, 3380, 3374,\n     3382, 3383, 3375, 3384, 3385, 3386, 3376, 3387, 3377, 3368,\n     3378, 3379, 3264, 3264, 3264, 3264, 3264, 3264, 3264, 3264,\n     3264, 3273, 3381, 3388, 3273, 3390, 3392, 3389, 3382, 3383,\n     3389, 3384, 3385, 3386, 3391, 3387, 3393, 3391, 3394, 3395,\n     3397, 3396, 3398, 3399, 3400, 3401, 3403, 3404, 3405, 3406,\n     3407, 3388, 3396, 3390, 3392, 3410, 3411, 3412, 3413, 3414,\n\n     3416, 3417, 3418,  539, 3393, 3421, 3394, 3395, 3397, 3422,\n     3398, 3399, 3400, 3401, 3403, 3404, 3405, 3406, 3407, 3423,\n     3424, 3425, 3426, 3410, 3411, 3412, 3413, 3414, 3416, 3417,\n     3418, 3419, 3427, 3421, 3428, 3429, 3431, 3422, 3432, 3420,\n     3433, 3434, 3435, 3436, 3437, 3438, 3439, 3423, 3424, 3425,\n     3426, 3440, 3441, 3442, 3443, 3444, 3445, 3446, 3447, 3419,\n     3427, 3448, 3428, 3429, 3431, 3449, 3432, 3420, 3433, 3434,\n     3435, 3436, 3437, 3438, 3439, 3450, 3453,  534,  532, 3440,\n     3441, 3442, 3443, 3444, 3445, 3446, 3447, 3347, 3452, 3448,\n     3347, 3452, 3456, 3449,  517, 3456, 3482, 3457, 3483, 3482,\n\n      515, 3483,  511, 3450, 3453, 3451, 3451, 3451, 3451, 3451,\n     3451, 3451, 3451, 3451, 3454, 3454, 3454, 3454, 3454, 3454,\n     3454, 3454, 3454, 3454, 3454, 3351, 3351, 3351, 3351, 3351,\n     3351, 3351, 3351, 3351, 3351, 3351, 3458, 3459, 3460, 3454,\n     3461, 3462, 3463, 3464, 3465, 3466, 3467, 3468, 3469, 3471,\n     3351, 3362, 3362, 3362, 3362, 3362, 3362, 3362, 3362, 3362,\n     3367, 3472, 3473, 3367, 3458, 3459, 3460, 3474, 3461, 3462,\n     3463, 3464, 3465, 3466, 3467, 3468, 3469, 3471, 3470, 3470,\n     3470, 3470, 3470, 3470, 3470, 3470, 3470, 3475, 3476, 3472,\n     3473, 3477, 3478, 3479, 3480, 3474, 3484, 3485, 3486, 3484,\n\n     3487, 3488, 3489, 3487, 3490, 3492, 3493, 3495, 3492, 3493,\n     3496, 3497, 3498, 3499, 3547, 3475, 3476, 3547, 1413, 3477,\n     3478, 3479, 3480, 3498, 3391, 3485, 3486, 3391, 3501, 3488,\n     3489, 3502, 3490, 3503, 3505, 3495, 3506, 1409, 3496, 3497,\n     3504, 3499, 3494, 3494, 3494, 3494, 3494, 3494, 3494, 3494,\n     3494, 3504, 3510, 3511, 3512, 3513, 3501, 3507, 3514, 3502,\n     3515, 3503, 3505, 3516, 3506, 3508, 3509, 3517, 3518, 3519,\n     3520, 3521, 3522, 3523, 3524, 3525, 3526, 3527, 3528, 3529,\n     3510, 3511, 3512, 3513, 3531, 3507, 3514, 3530, 3515, 3530,\n     3532, 3516, 3533, 3508, 3509, 3517, 3518, 3519, 3520, 3521,\n\n     3522, 3523, 3524, 3525, 3526, 3527, 3528, 3529, 3534, 3536,\n     3537, 3538, 3531, 3539, 3540, 3541, 3542, 3543, 3532, 3544,\n     3533, 3451, 3451, 3451, 3451, 3451, 3451, 3451, 3451, 3451,\n     3452, 3482, 1403, 3452, 3482, 3545, 3534, 3536, 3537, 3538,\n     3548, 3539, 3540, 3541, 3542, 3543, 3972, 3544, 3546, 3546,\n     3546, 3546, 3546, 3546, 3546, 3546, 3546, 3456, 3550, 3530,\n     3456, 3551, 3457, 3552, 3553, 3454, 3454, 3454, 3454, 3454,\n     3454, 3454, 3454, 3454, 3454, 3454, 3554, 3555, 3556, 3557,\n     3558, 3559, 3560, 3561, 3562, 3563, 3550, 3566, 3567, 3551,\n     3454, 3552, 3553, 3470, 3470, 3470, 3470, 3470, 3470, 3470,\n\n     3470, 3470, 3568, 3569, 3554, 3555, 3556, 3557, 3558, 3559,\n     3560, 3561, 3562, 3563, 3564, 3566, 3567, 3564, 3571, 3574,\n     3576, 3571, 3574, 3572, 3575, 3577, 3579, 3580, 3581, 3487,\n     3568, 3569, 3487, 3492, 3578, 1372, 3583, 1363, 3585, 3493,\n     3586, 3589, 3493, 3590, 3565, 1351, 3628, 3635, 3576, 3628,\n     3635,  432,  419, 3577, 3579, 3580, 3581, 3584, 3584, 3584,\n     3584, 3584, 3584, 3584, 3584, 3584, 3585, 3591, 3586, 3589,\n     3592, 3590, 3565, 3494, 3494, 3494, 3494, 3494, 3494, 3494,\n     3494, 3494, 3587, 3593, 3594, 3595, 3596, 3597, 3588, 3598,\n     3600, 3602, 3603, 3604, 3605, 3591, 3606, 3607, 3592, 3609,\n\n     3610, 3613, 3614, 3639, 3571, 3704, 3639, 3571, 3704, 3572,\n     3587, 3593, 3594, 3595, 3596, 3597, 3588, 3598, 3600, 3602,\n     3603, 3604, 3605, 3616, 3606, 3607, 3617, 3609, 3610, 3613,\n     3614, 3615, 3615, 3615, 3615, 3615, 3615, 3615, 3615, 3615,\n     3615, 3615, 3618, 3619, 3622, 3623, 3624, 3625, 3626, 3627,\n     3574, 3616,  415, 3574, 3617, 3575, 3615, 3629, 3629, 3629,\n     3629, 3629, 3629, 3629, 3629, 3629, 3632, 3633, 3634, 3636,\n     3618, 3619, 3622, 3623, 3624, 3625, 3626, 3627, 3546, 3546,\n     3546, 3546, 3546, 3546, 3546, 3546, 3546, 3547, 3637, 3638,\n     3547, 3640, 3641, 3642, 3632, 3633, 3634, 3636, 3643, 3644,\n\n     3646, 3647, 3648, 3651, 3654, 3630, 3630, 3630, 3630, 3630,\n     3630, 3630, 3630, 3630, 3655, 3564, 3637, 3638, 3564, 3640,\n     3641, 3642, 3649, 3659,  400, 3649, 3643, 3644, 3646, 3647,\n     3648, 3651, 3654, 3645, 3645, 3645, 3645, 3645, 3645, 3645,\n     3645, 3645, 3655, 3660, 3661, 3582, 3663, 3664, 3665, 3666,\n     3667, 3659, 3650, 3669, 3670, 3671, 3672, 3673, 3674, 3675,\n     3662, 3662, 3662, 3662, 3662, 3662, 3662, 3662, 3662,  396,\n     3492, 3660, 3661, 3583, 3663, 3664, 3665, 3666, 3667, 3676,\n     3650, 3669, 3670, 3671, 3672, 3673, 3674, 3675, 3662, 3662,\n     3662, 3662, 3662, 3662, 3662, 3662, 3662, 3584, 3584, 3584,\n\n     3584, 3584, 3584, 3584, 3584, 3584, 3677, 3676, 3678, 3679,\n     3680, 3681, 3682, 3683, 3685, 3688,  374, 3689, 3691, 3615,\n     3615, 3615, 3615, 3615, 3615, 3615, 3615, 3615, 3615, 3615,\n     3692, 3694, 3695, 3696, 3677, 3703, 3678, 3679, 3680, 3681,\n     3682, 3683, 3685, 3688, 3615, 3689, 3691, 3728, 3698, 3783,\n     3699, 3698, 3702, 3700, 3707, 3705,  370, 3707, 3692, 3694,\n     3695, 3696, 3699, 3703, 3709, 3629, 3629, 3629, 3629, 3629,\n     3629, 3629, 3629, 3629, 3630, 3630, 3630, 3630, 3630, 3630,\n     3630, 3630, 3630, 3705, 3635, 3639, 3712, 3635, 3639, 3713,\n     3711, 3714, 3709, 3715, 3716,  364, 3704,  360, 3658, 3763,\n\n     3658, 3764, 3706, 3706, 3706, 3706, 3706, 3706, 3706, 3706,\n     3706, 3717, 3718, 3720, 3712, 3721, 3724, 3713, 3731, 3714,\n     3732, 3715, 3716, 3645, 3645, 3645, 3645, 3645, 3645, 3645,\n     3645, 3645, 3649, 3701, 3725, 3649, 3733, 3734, 3726, 3717,\n     3718, 3720, 3735, 3721, 3724, 3727, 3731,  356, 3732, 1293,\n     3719, 3719, 3719, 3719, 3719, 3719, 3719, 3719, 3719, 3582,\n     3736, 3737, 3725, 3738, 3733, 3734, 3726, 3739, 3740, 3741,\n     3735, 3742, 3743, 3727, 3662, 3662, 3662, 3662, 3662, 3662,\n     3662, 3662, 3662, 3744, 3745, 3746, 3747, 3748, 3736, 3737,\n     3749, 3738, 3750, 3751, 3752, 3739, 3740, 3741, 3756, 3742,\n\n     3743, 3749, 3758, 3750, 3759, 3760, 3824, 3762, 1229, 3824,\n     1228, 3744, 3745, 3746, 3747, 3748, 3766, 3770, 3771, 3772,\n     3707, 3751, 3752, 3707, 3972, 3767, 3756, 3972, 3825, 3972,\n     3758, 3825, 3759, 3760, 3699, 3762, 3699, 3699, 3698, 3972,\n     3699, 3698, 3773, 3700, 3766, 3770, 3771, 3772, 3699, 3774,\n     3775, 3776, 3699, 3706, 3706, 3706, 3706, 3706, 3706, 3706,\n     3706, 3706, 3777, 3778, 3779, 3780, 3781, 3782, 3784, 3785,\n     3773, 3786, 3787, 3788, 3789, 3790, 3791, 3774, 3775, 3776,\n     3719, 3719, 3719, 3719, 3719, 3719, 3719, 3719, 3719, 3792,\n     3777, 3778, 3779, 3780, 3781, 3782, 3784, 3785, 3793, 3786,\n\n     3787, 3788, 3789, 3790, 3791, 3794, 3795, 3796, 3797, 3798,\n     3799, 3800, 3802, 3801, 3803, 3807, 3804, 3792, 3796, 3701,\n     3811, 3814, 3815, 3701, 3801, 3704, 3793, 3805, 3763, 3816,\n     3764, 3817, 3818, 3794, 3795, 3819, 3797, 3798, 3799, 3800,\n     3802, 3820, 3803, 3807, 3804, 3821, 3826, 3827, 3822, 3814,\n     3815, 3822, 3728, 3828, 3829, 3805, 3830, 3816, 3831, 3817,\n     3818, 3832, 3833, 3819, 3834, 3835, 3836, 3837, 3847, 3820,\n     3838, 3812, 3839, 3821, 3826, 3827, 3841, 3842, 3843, 3844,\n     3845, 3828, 3829, 3847, 3830, 3850, 3831, 3851, 3852, 3832,\n     3833, 1212, 3834, 3835, 3836, 3837, 3823, 3853, 3838, 3854,\n\n     3839, 3855, 3856, 3729, 3841, 3842, 3843, 3844, 3845, 3858,\n     3859, 3864, 3858, 3850, 3864, 3851, 3852, 3824, 3825, 3848,\n     3824, 3825, 3861, 3863, 3823, 3853, 3866, 3854, 3865, 3855,\n     3856, 3865, 3867, 3868, 3812, 3869, 3870, 3872, 3859, 3873,\n     3874, 3875, 3876, 3877, 3880, 3881, 3882, 3883, 3881, 3884,\n     3885, 3886, 3887, 3888, 3866, 3858, 3889, 1203, 3858, 1191,\n     3867, 3868, 3847, 3869, 3870, 3872, 1170, 3873, 3874, 3875,\n     3876, 3877, 3880, 3896, 3897, 3883, 3898, 3884, 3885, 3886,\n     3887, 3888, 3972, 3972, 3889, 3972, 3972, 3972, 3972, 3864,\n     3865, 3899, 3864, 3865, 3893, 3895, 3900, 3812, 3901, 3902,\n\n     3903, 3896, 3897, 3904, 3898, 3911, 3905, 3913, 3911, 3914,\n     3912, 3915, 3914, 3848, 3916, 3917, 3918, 3906, 3917, 3899,\n     3907, 1153, 3923,  665, 3900, 3924, 3901, 3902, 3903, 3925,\n     3926, 3904, 3927, 3972, 3905, 3913, 3972, 3928, 3972, 3915,\n     3929, 3930, 3916, 3931, 3918, 3906, 3972, 3932, 3907, 3972,\n     3923, 3972, 3933, 3924, 3936, 3939, 3911, 3925, 3926, 3911,\n     3927, 3912, 1127, 3938,  648, 3928, 3938, 3914, 3929, 3930,\n     3914, 3931,  386,  386,  880, 3932, 3917, 3941, 3944, 3917,\n     3933, 3945, 3936, 3939, 3946, 3937, 3937, 3937, 3937, 3937,\n     3937, 3937, 3937, 3937, 3940, 3940, 3940, 3940, 3940, 3940,\n\n     3940, 3940, 3940, 3947, 3948, 3941, 3944, 3949, 3950, 3945,\n     3951, 3955, 3946, 3937, 3937, 3937, 3937, 3937, 3937, 3937,\n     3937, 3937, 3938, 3954, 1083, 3938, 3954, 1072, 1063, 1060,\n     3956, 3947, 3948, 3957, 3958, 3949, 3950, 3960, 3951, 3955,\n     3953, 3953, 3953, 3953, 3953, 3953, 3953, 3953, 3953, 3940,\n     3940, 3940, 3940, 3940, 3940, 3940, 3940, 3940, 3956, 3961,\n     3954, 3957, 3958, 3954, 3963, 3960, 3953, 3953, 3953, 3953,\n     3953, 3953, 3953, 3953, 3953, 3964, 3965, 3966, 3962, 3962,\n     3962, 3962, 3962, 3962, 3962, 3962, 3962, 3961, 3967, 3968,\n     3969, 3970, 3963, 3962, 3962, 3962, 3962, 3962, 3962, 3962,\n\n     3962, 3962, 3971, 3964, 3965, 3966, 1016,  541,  539, 1014,\n      534,  532, 1008,  517,  515, 1006, 3967, 3968, 3969, 3970,\n      511, 1001,  993,  984,  983,  953,  941,  929,  919,  432,\n     3971,   76,   76,   76,   76,   76,   76,   76,   76,   76,\n       76,   76,   76,   76,   76,   76,   76,   76,   76,   76,\n       98,   98,   98,   98,   98,   98,   98,   98,   98,   98,\n       98,   98,   98,   98,   98,   98,   98,   98,   98,  128,\n      128,  128,  128,  128,  128,  128,  128,  128,  128,  128,\n      128,  128,  128,  128,  128,  128,  128,  128,  134,  134,\n      134,  134,  134,  134,  134,  134,  134,  134,  134,  134,\n\n      134,  134,  134,  134,  134,  134,  134,  137,  137,  137,\n      137,  137,  137,  137,  137,  137,  137,  137,  137,  137,\n      137,  137,  137,  137,  137,  137,  143,  143,  143,  143,\n      143,  143,  143,  143,  143,  143,  143,  143,  143,  143,\n      143,  143,  143,  143,  143,  149,  149,  149,  149,  149,\n      149,  149,  149,  149,  149,  149,  149,  149,  149,  149,\n      149,  149,  149,  149,  156,  156,  156,  156,  156,  156,\n      156,  156,  156,  156,  156,  156,  156,  156,  156,  156,\n      156,  156,  156,  162,  162,  162,  162,  162,  162,  162,\n      162,  162,  162,  162,  162,  162,  162,  162,  162,  162,\n\n      162,  162,  169,  169,  169,  169,  169,  169,  169,  169,\n      169,  169,  169,  169,  169,  169,  169,  169,  169,  169,\n      169,  179,  179,  179,  179,  179,  179,  179,  179,  179,\n      179,  179,  179,  179,  179,  179,  179,  179,  179,  179,\n      185,  185,  185,  185,  185,  185,  185,  185,  185,  185,\n      185,  185,  185,  185,  185,  185,  185,  185,  185,  227,\n      227,  227,  227,  227,  227,  227,  227,  227,  227,  227,\n      227,  227,  227,  227,  227,  227,  227,  227,  232,  232,\n      232,  232,  232,  232,  232,  232,  232,  232,  232,  232,\n      232,  232,  232,  232,  232,  232,  232,  237,  237,  237,\n\n      237,  237,  237,  237,  237,  237,  237,  237,  237,  237,\n      237,  237,  237,  237,  237,  237,  238,  238,  238,  238,\n      238,  238,  238,  238,  238,  238,  238,  238,  238,  238,\n      238,  238,  238,  238,  238,  239,  239,  239,  239,  239,\n      239,  239,  239,  239,  239,  239,  239,  239,  239,  239,\n      239,  239,  239,  239,  240,  240,  240,  240,  240,  240,\n      240,  240,  240,  240,  240,  240,  240,  240,  240,  240,\n      240,  240,  240,  241,  241,  241,  241,  241,  241,  241,\n      241,  241,  241,  241,  241,  241,  241,  241,  241,  241,\n      241,  241,  249,  249,  249,  249,  249,  249,  249,  249,\n\n      249,  249,  249,  249,  249,  249,  249,  249,  249,  249,\n      249,  251,  251,  251,  251,  251,  251,  251,  251,  251,\n      251,  251,  251,  251,  251,  251,  251,  251,  251,  251,\n      255,  255,  255,  255,  255,  255,  255,  255,  255,  255,\n      255,  255,  255,  255,  255,  255,  255,  255,  255,  258,\n      258,  258,  258,  258,  258,  258,  258,  258,  258,  258,\n      258,  258,  258,  258,  258,  258,  258,  258,  266,  266,\n      916,  266,  266,  266,  266,  266,  266,  266,  266,  266,\n      266,  266,  266,  266,  266,  266,  266,  347,  347,  347,\n      347,  347,  347,  347,  347,  347,  347,  347,  347,  347,\n\n      347,  347,  347,  347,  347,  347,  357,  357,  357,  357,\n      357,  357,  357,  357,  357,  357,  357,  357,  357,  357,\n      357,  357,  357,  357,  357,  364,  364,  364,  364,  364,\n      364,  364,  364,  364,  364,  364,  364,  364,  364,  364,\n      364,  364,  364,  364,  367,  367,  367,  367,  367,  367,\n      367,  367,  367,  367,  367,  367,  367,  367,  367,  367,\n      367,  367,  367,  374,  374,  374,  374,  374,  374,  374,\n      374,  374,  374,  374,  374,  374,  374,  374,  374,  374,\n      374,  374,  377,  377,  377,  377,  377,  377,  377,  377,\n      377,  377,  377,  377,  377,  377,  377,  377,  377,  377,\n\n      377,  383,  383,  383,  383,  383,  383,  383,  383,  383,\n      383,  383,  383,  383,  383,  383,  383,  383,  383,  383,\n      388,  388,  388,  388,  388,  388,  388,  388,  388,  388,\n      388,  388,  388,  388,  388,  388,  388,  388,  388,  392,\n      392,  392,  392,  392,  392,  392,  392,  392,  392,  392,\n      392,  392,  392,  392,  392,  392,  392,  392,  400,  400,\n      400,  400,  400,  400,  400,  400,  400,  400,  400,  400,\n      400,  400,  400,  400,  400,  400,  400,  403,  403,  403,\n      403,  403,  403,  403,  403,  403,  403,  403,  403,  403,\n      403,  403,  403,  403,  403,  403,  412,  412,  412,  412,\n\n      412,  412,  412,  412,  412,  412,  412,  412,  412,  412,\n      412,  412,  412,  412,  412,  419,  419,  419,  419,  419,\n      419,  419,  419,  419,  419,  419,  419,  419,  419,  419,\n      419,  419,  419,  419,  422,  422,  422,  422,  422,  422,\n      422,  422,  422,  422,  422,  422,  422,  422,  422,  422,\n      422,  422,  422,  506,  506,  506,  506,  506,  506,  506,\n      506,  506,  506,  506,  506,  506,  506,  506,  506,  506,\n      506,  506,  512,  512,  512,  512,  512,  512,  512,  512,\n      512,  512,  512,  512,  512,  512,  512,  512,  512,  512,\n      512,  517,  517,  517,  517,  517,  517,  517,  517,  517,\n\n      517,  517,  517,  517,  517,  517,  517,  517,  517,  517,\n      518,  518,  419,  518,  518,  518,  518,  518,  518,  518,\n      518,  518,  518,  518,  518,  518,  518,  518,  518,  519,\n      519,  415,  519,  519,  519,  519,  519,  519,  519,  519,\n      519,  519,  519,  519,  519,  519,  519,  519,  520,  520,\n      665,  520,  520,  520,  520,  520,  520,  520,  520,  520,\n      520,  520,  520,  520,  520,  520,  520,  529,  529,  529,\n      529,  529,  529,  529,  529,  529,  529,  529,  529,  529,\n      529,  529,  529,  529,  529,  529,  534,  534,  534,  534,\n      534,  534,  534,  534,  534,  534,  534,  534,  534,  534,\n\n      534,  534,  534,  534,  534,  536,  536,  536,  536,  536,\n      536,  536,  536,  536,  536,  536,  536,  536,  536,  536,\n      536,  536,  536,  536,  541,  541,  541,  541,  541,  541,\n      541,  541,  541,  541,  541,  541,  541,  541,  541,  541,\n      541,  541,  541,  266,  266,  889,  266,  266,  266,  266,\n      266,  266,  266,  266,  266,  266,  266,  266,  266,  266,\n      266,  266,  347,  347,  347,  347,  347,  347,  347,  347,\n      347,  347,  347,  347,  347,  347,  347,  347,  347,  347,\n      347,  357,  357,  357,  357,  357,  357,  357,  357,  357,\n      357,  357,  357,  357,  357,  357,  357,  357,  357,  357,\n\n      364,  364,  364,  364,  364,  364,  364,  364,  364,  364,\n      364,  364,  364,  364,  364,  364,  364,  400,  364,  367,\n      367,  367,  367,  367,  367,  367,  367,  367,  367,  367,\n      367,  367,  367,  367,  367,  367,  367,  367,  374,  374,\n      374,  374,  374,  374,  374,  374,  374,  374,  374,  374,\n      374,  374,  374,  374,  374,  396,  374,  377,  377,  377,\n      377,  377,  377,  377,  377,  377,  377,  377,  377,  377,\n      377,  377,  377,  377,  377,  377,  383,  383,  383,  383,\n      383,  383,  383,  383,  383,  383,  383,  383,  383,  383,\n      383,  383,  383,  383,  383,  642,  642,  642,  642,  642,\n\n      642,  642,  642,  642,  642,  642,  642,  642,  642,  642,\n      642,  642,  642,  642,  388,  388,  388,  388,  388,  388,\n      388,  388,  388,  388,  388,  388,  388,  388,  388,  388,\n      388,  388,  388,  647,  648,  647,  647,  871,  374,  647,\n      647,  647,  647,  647,  647,  370,  647,  647,  647,  647,\n      647,  392,  392,  392,  392,  392,  392,  392,  392,  392,\n      392,  392,  392,  392,  392,  392,  392,  392,  392,  392,\n      400,  400,  400,  400,  400,  400,  400,  400,  400,  400,\n      400,  400,  400,  400,  400,  400,  400,  868,  400,  655,\n      655,  655,  655,  655,  655,  655,  655,  655,  655,  655,\n\n      655,  655,  655,  655,  655,  655,  655,  655,  403,  403,\n      403,  403,  403,  403,  403,  403,  403,  403,  403,  403,\n      403,  403,  403,  403,  403,  403,  403,  662,  662,  662,\n      662,  662,  662,  662,  662,  662,  662,  662,  662,  662,\n      662,  662,  662,  662,  662,  662,  664,  364,  664,  664,\n      360,  865,  664,  664,  664,  664,  664,  664,  356,  664,\n      664,  664,  664,  664,  412,  412,  412,  412,  412,  412,\n      412,  412,  412,  412,  412,  412,  412,  412,  412,  412,\n      412,  412,  412,  419,  419,  419,  419,  419,  419,  419,\n      419,  419,  419,  419,  419,  419,  419,  419,  419,  419,\n\n      820,  419,  422,  422,  422,  422,  422,  422,  422,  422,\n      422,  422,  422,  422,  422,  422,  422,  422,  422,  422,\n      422,  506,  506,  506,  506,  506,  506,  506,  506,  506,\n      506,  506,  506,  506,  506,  506,  506,  506,  506,  506,\n      512,  512,  512,  512,  512,  512,  512,  512,  512,  512,\n      512,  512,  512,  512,  512,  512,  512,  512,  512,  517,\n      517,  517,  517,  517,  517,  517,  517,  517,  517,  517,\n      517,  517,  517,  517,  517,  517,  778,  517,  518,  518,\n      539,  518,  518,  518,  518,  518,  518,  518,  518,  518,\n      518,  518,  518,  518,  518,  518,  518,  519,  519,  540,\n\n      519,  519,  519,  519,  519,  519,  519,  519,  519,  519,\n      519,  519,  519,  519,  519,  519,  520,  520,  532,  520,\n      520,  520,  520,  520,  520,  520,  520,  520,  520,  520,\n      520,  520,  520,  520,  520,  529,  529,  529,  529,  529,\n      529,  529,  529,  529,  529,  529,  529,  529,  529,  529,\n      529,  529,  529,  529,  534,  534,  534,  534,  534,  534,\n      534,  534,  534,  534,  534,  534,  534,  534,  534,  534,\n      534,  533,  534,  536,  536,  536,  536,  536,  536,  536,\n      536,  536,  536,  536,  536,  536,  536,  536,  536,  536,\n      536,  536,  541,  541,  541,  541,  541,  541,  541,  541,\n\n      541,  541,  541,  541,  541,  541,  541,  541,  541,  515,\n      541,  266,  266,  516,  266,  266,  266,  266,  266,  266,\n      266,  266,  266,  266,  266,  266,  266,  266,  266,  266,\n      347,  347,  347,  347,  347,  347,  347,  347,  347,  347,\n      347,  347,  347,  347,  347,  347,  347,  347,  347,  364,\n      364,  364,  364,  364,  364,  364,  364,  364,  364,  364,\n      364,  364,  364,  364,  364,  364,  364,  364,  357,  357,\n      357,  357,  357,  357,  357,  357,  357,  357,  357,  357,\n      357,  357,  357,  357,  357,  357,  357,  374,  374,  374,\n      374,  374,  374,  374,  374,  374,  374,  374,  374,  374,\n\n      374,  374,  374,  374,  374,  374,  367,  367,  367,  367,\n      367,  367,  367,  367,  367,  367,  367,  367,  367,  367,\n      367,  367,  367,  367,  367,  642,  642,  642,  642,  642,\n      642,  642,  642,  642,  642,  642,  642,  642,  642,  642,\n      642,  642,  642,  642,  875,  509,  875,  875,  757,  743,\n      875,  875,  875,  875,  875,  875,  480,  875,  875,  875,\n      875,  875,  875,  878,  739,  878,  878,  699,  684,  878,\n      878,  878,  878,  878,  878,  438,  878,  878,  878,  878,\n      878,  878,  388,  388,  388,  388,  388,  388,  388,  388,\n      388,  388,  388,  388,  388,  388,  388,  388,  388,  388,\n\n      388,  647,  429,  647,  647,  415,  418,  647,  647,  647,\n      647,  647,  647,  396,  647,  647,  647,  647,  647,  400,\n      400,  400,  400,  400,  400,  400,  400,  400,  400,  400,\n      400,  400,  400,  400,  400,  400,  400,  400,  392,  392,\n      392,  392,  392,  392,  392,  392,  392,  392,  392,  392,\n      392,  392,  392,  392,  392,  392,  392,  655,  655,  655,\n      655,  655,  655,  655,  655,  655,  655,  655,  655,  655,\n      655,  655,  655,  655,  655,  655,  891,  891,  891,  891,\n      891,  891,  891,  891,  891,  891,  891,  891,  891,  891,\n      891,  891,  891,  891,  891,  893,  399,  893,  893,  391,\n\n      386,  893,  893,  893,  893,  893,  893,  370,  893,  893,\n      893,  893,  893,  893,  660,  660,  660,  660,  660,  660,\n      660,  660,  660,  660,  660,  660,  660,  660,  660,  660,\n      660,  660,  660,  403,  403,  403,  403,  403,  403,  403,\n      403,  403,  403,  403,  403,  403,  403,  403,  403,  403,\n      403,  403,  664,  373,  664,  664,  360,  363,  664,  664,\n      664,  664,  664,  664,  352,  664,  664,  664,  664,  664,\n      662,  662,  662,  662,  662,  662,  662,  662,  662,  662,\n      662,  662,  662,  662,  662,  662,  662,  662,  662,  419,\n      419,  419,  419,  419,  419,  419,  419,  419,  419,  419,\n\n      419,  419,  419,  419,  419,  419,  419,  419,  412,  412,\n      412,  412,  412,  412,  412,  412,  412,  412,  412,  412,\n      412,  412,  412,  412,  412,  412,  412,  422,  422,  422,\n      422,  422,  422,  422,  422,  422,  422,  422,  422,  422,\n      422,  422,  422,  422,  422,  422,  506,  506,  506,  506,\n      506,  506,  506,  506,  506,  506,  506,  506,  506,  506,\n      506,  506,  506,  506,  506,  517,  517,  517,  517,  517,\n      517,  517,  517,  517,  517,  517,  517,  517,  517,  517,\n      517,  517,  517,  517,  512,  512,  512,  512,  512,  512,\n      512,  512,  512,  512,  512,  512,  512,  512,  512,  512,\n\n      512,  512,  512,  534,  534,  534,  534,  534,  534,  534,\n      534,  534,  534,  534,  534,  534,  534,  534,  534,  534,\n      534,  534,  529,  529,  529,  529,  529,  529,  529,  529,\n      529,  529,  529,  529,  529,  529,  529,  529,  529,  529,\n      529,  541,  541,  541,  541,  541,  541,  541,  541,  541,\n      541,  541,  541,  541,  541,  541,  541,  541,  541,  541,\n      536,  536,  536,  536,  536,  536,  536,  536,  536,  536,\n      536,  536,  536,  536,  536,  536,  536,  536,  536,  266,\n      266,  595,  266,  266,  266,  266,  266,  266,  266,  266,\n      266,  266,  266,  266,  266,  266,  266,  266,  347,  347,\n\n      347,  347,  347,  347,  347,  347,  347,  347,  347,  347,\n      347,  347,  347,  347,  347,  347,  347,  357,  357,  357,\n      357,  357,  357,  357,  357,  357,  357,  357,  357,  357,\n      357,  357,  357,  357,  357,  357,  367,  367,  367,  367,\n      367,  367,  367,  367,  367,  367,  367,  367,  367,  367,\n      367,  367,  367,  367,  367,  642,  642,  642,  642,  642,\n      642,  642,  642,  642,  642,  642,  642,  642,  642,  642,\n      642,  642,  642,  642,  875,  594,  875,  875,  560,  542,\n      875,  875,  875,  875,  875,  875,  540,  875,  875,  875,\n      875,  875,  875,  878,  540,  878,  878,  533,  516,  878,\n\n      878,  878,  878,  878,  878,  509,  878,  878,  878,  878,\n      878,  878,  647,  480,  647,  647,  438,  418,  647,  647,\n      647,  647,  647,  647,  399,  647,  647,  647,  647,  647,\n      655,  655,  655,  655,  655,  655,  655,  655,  655,  655,\n      655,  655,  655,  655,  655,  655,  655,  655,  655,  893,\n      399,  893,  893,  386,  386,  893,  893,  893,  893,  893,\n      893,  386,  893,  893,  893,  893,  893,  893,  660,  660,\n      660,  660,  660,  660,  660,  660,  660,  660,  660,  660,\n      660,  660,  660,  660,  660,  660,  660,  897,  373,  897,\n      897,  373,  363,  897,  897,  897,  897,  897,  897,  352,\n\n      897,  897,  897,  897,  897,  897,  891,  891,  891,  891,\n      891,  891,  891,  891,  891,  891,  891,  891,  891,  891,\n      891,  891,  891,  891,  891,  894,  894,  894,  894,  894,\n      894,  894,  894,  894,  894,  894,  894,  894,  894,  894,\n      894,  894,  894,  894,  664,  318,  664,  664, 3972,  250,\n      664,  664,  664,  664,  664,  664,  250,  664,  664,  664,\n      664,  664,  403,  403,  403,  403,  403,  403,  403,  403,\n      403,  403,  403,  403,  403,  403,  403,  403,  403,  403,\n      403,  412,  412,  412,  412,  412,  412,  412,  412,  412,\n      412,  412,  412,  412,  412,  412,  412,  412,  412,  412,\n\n      422,  422,  422,  422,  422,  422,  422,  422,  422,  422,\n      422,  422,  422,  422,  422,  422,  422,  422,  422, 1169,\n     1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169,   98,\n     1169, 1169, 1169, 1169, 1169, 1169, 1169, 1169,  506,  506,\n      506,  506,  506,  506,  506,  506,  506,  506,  506,  506,\n      506,  506,  506,  506,  506,  506,  506,  512,  512,  512,\n      512,  512,  512,  512,  512,  512,  512,  512,  512,  512,\n      512,  512,  512,  512,  512,  512,  529,  529,  529,  529,\n      529,  529,  529,  529,  529,  529,  529,  529,  529,  529,\n      529,  529,  529,  529,  529,  536,  536,  536,  536,  536,\n\n      536,  536,  536,  536,  536,  536,  536,  536,  536,  536,\n      536,  536,  536,  536,  266,  266,   98,  266,  266,  266,\n      266,  266,  266,  266,  266,  266,  266,  266,  266,  266,\n      266,  266,  266,  364,  364,  364,  364,  364,  364,  364,\n      364,  364,  364,  364,  364,  364,  364,  364,  364,  364,\n      364,  364,  374,  374,  374,  374,  374,  374,  374,  374,\n      374,  374,  374,  374,  374,  374,  374,  374,  374,  374,\n      374,  642,  642,  642,  642,  642,  642,  642,  642,  642,\n      642,  642,  642,  642,  642,  642,  642,  642,  642,  642,\n      875,   98,  875,  875,   98,   98,  875,  875,  875,  875,\n\n      875,  875,   98,  875,  875,  875,  875,  875,  875,  878,\n       98,  878,  878,   98,  161,  878,  878,  878,  878,  878,\n      878,  161,  878,  878,  878,  878,  878,  878,  400,  400,\n      400,  400,  400,  400,  400,  400,  400,  400,  400,  400,\n      400,  400,  400,  400,  400,  400,  400,  893,  160,  893,\n      893,  160, 3972,  893,  893,  893,  893,  893,  893, 3972,\n      893,  893,  893,  893,  893,  893,  894,  894,  894,  894,\n      894,  894,  894,  894,  894,  894,  894,  894,  894,  894,\n      894,  894,  894,  894,  894,  664, 3972,  664,  664, 3972,\n     3972,  664,  664,  664,  664,  664,  664,  664,  664,  664,\n\n      664,  664,  664,  662,  662,  662,  662,  662,  662,  662,\n      662,  662,  662,  662,  662,  662,  662,  662,  662,  662,\n      662,  662,  419,  419,  419,  419,  419,  419,  419,  419,\n      419,  419,  419,  419,  419,  419,  419,  419,  419,  419,\n      419, 1362, 3972, 1362, 1362, 3972, 3972, 1362, 1362, 1362,\n     1362, 3972, 1362, 1362, 1362, 1362, 1362, 1362, 1362, 1362,\n     1376, 1376, 1376, 1376, 1376, 1376, 1376, 3972, 1376, 1376,\n     3972, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1376, 1410,\n     1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410,\n     1410, 1410, 1410, 1410, 1410, 1410, 1410, 1410,  517,  517,\n\n      517,  517,  517,  517,  517,  517,  517,  517,  517,  517,\n      517,  517,  517,  517,  517,  517,  517,  534,  534,  534,\n      534,  534,  534,  534,  534,  534,  534,  534,  534,  534,\n      534,  534,  534,  534,  534,  534,  541,  541,  541,  541,\n      541,  541,  541,  541,  541,  541,  541,  541,  541,  541,\n      541,  541,  541,  541,  541,  266,  266, 3972,  266,  266,\n      266,  266,  266,  266,  266,  266,  266,  266,  266,  266,\n      266,  266,  266,  266,  891,  891,  891,  891,  891,  891,\n      891,  891,  891,  891,  891,  891,  891,  891,  891,  891,\n      891,  891,  891, 1544, 1544, 1544, 1544, 1544, 1544, 1544,\n\n     1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544, 1544,\n     1544, 1544, 1556, 3972, 3972, 3972, 1556, 3972, 3972, 1556,\n     1597, 3972, 3972, 3972, 3972, 3972, 1597, 1597, 1597, 1597,\n     3972, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1597, 1545,\n     1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545,\n     1545, 1545, 1545, 1545, 1545, 1545, 1545, 1545, 1749, 3972,\n     3972, 1749, 3972, 1749, 1787, 1787, 1787, 1787, 1787, 1787,\n     1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787, 1787,\n     1787, 1787, 1787, 1793, 3972, 3972, 1793, 1793, 3972, 3972,\n     1793, 1793, 3972, 1793, 3972, 1793, 1793, 1793, 1793, 1932,\n\n     1932, 1932, 1932, 1977, 1977, 3972, 1977, 1977, 1977, 1977,\n     1977, 1977, 1977, 1977, 1977, 1977, 1977, 1977, 1977, 1977,\n     1977, 1977, 1979, 1979, 3972, 1979, 1979, 1979, 1979, 1979,\n     1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979, 1979,\n     1979, 1983, 3972, 3972, 3972, 1983, 1983, 3972, 1983, 3972,\n     1983, 1983, 1983, 1983, 2108, 2108, 2108, 2108, 2108, 2108,\n     2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108, 2108,\n     2108, 2108, 2108, 2124, 2124, 2124, 2124, 2124, 2124, 2124,\n     2124, 2124, 2124, 2124, 2124, 2124, 2124, 2124, 2124, 2124,\n     2124, 2124, 2177, 2177, 2177, 2177, 2177, 2177, 2177, 2177,\n\n     2177, 2177, 2177, 2177, 2177, 2177, 2177, 2177, 2177, 2177,\n     2177, 2213, 2213, 3972, 3972, 2213, 2213, 2213, 2213, 2213,\n     2213, 3972, 2213, 2213, 2213, 2213, 2213, 2213, 2213, 2213,\n     2233, 3972, 3972, 2233, 2233, 3972, 3972, 2233, 2233, 3972,\n     2233, 3972, 2233, 2233, 2233, 2233, 2323, 2323, 2323, 2323,\n     2323, 2323, 2323, 2323, 2323, 2323, 2323, 2323, 2323, 2323,\n     2323, 2323, 2323, 2323, 2323, 2339, 2339, 2339, 2339, 2339,\n     2339, 2339, 2339, 2339, 2339, 2339, 2339, 2339, 2339, 2339,\n     2339, 2339, 2339, 2339, 2370, 3972, 3972, 3972, 3972, 3972,\n     2370, 2370, 2370, 2370, 3972, 2370, 2370, 2370, 2370, 2370,\n\n     2370, 2370, 2370, 2396, 2396, 3972, 2396, 2396, 2396, 2396,\n     2396, 2396, 2396, 2396, 2396, 2396, 2396, 2396, 2396, 2396,\n     2396, 2396, 2398, 2398, 3972, 2398, 2398, 2398, 2398, 2398,\n     2398, 2398, 2398, 2398, 2398, 2398, 2398, 2398, 2398, 2398,\n     2398, 2425, 3972, 3972, 2425, 2425, 3972, 3972, 2425, 2425,\n     3972, 2425, 3972, 2425, 2425, 2425, 2425, 2438, 3972, 3972,\n     3972, 3972, 3972, 2438, 2438, 2438, 2438, 3972, 2438, 2438,\n     2438, 2438, 2438, 2438, 2438, 2438, 2450, 2450, 3972, 2450,\n     2450, 3972, 2450, 2450, 2450, 2450, 2450, 2450, 2450, 2450,\n     2450, 2450, 2450, 2450, 2455, 3972, 3972, 3972, 2455, 2455,\n\n     3972, 2455, 3972, 2455, 2455, 2455, 2455, 2596, 2596, 2596,\n     2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596, 2596,\n     2596, 2596, 2596, 2596, 2596, 2596, 2599, 2599, 2599, 2599,\n     2599, 2599, 2599, 2599, 2599, 2599, 2599, 2599, 2599, 2599,\n     2599, 2599, 2599, 2599, 2599, 2608, 3972, 3972, 2608, 2608,\n     3972, 3972, 2608, 2608, 3972, 2608, 3972, 2608, 2608, 2608,\n     2608, 2628, 3972, 3972, 3972, 2628, 2628, 3972, 2628, 3972,\n     2628, 2628, 2628, 2628, 2631, 3972, 3972, 2631, 2631, 3972,\n     3972, 2631, 2631, 3972, 2631, 3972, 2631, 2631, 2631, 2631,\n     2664, 2664, 3972, 2664, 2664, 2664, 2664, 2664, 2664, 2664,\n\n     2664, 2664, 2664, 2664, 2664, 2664, 2664, 2664, 2783, 3972,\n     3972, 3972, 2783, 2783, 3972, 2783, 3972, 2783, 2783, 2783,\n     2783, 2785, 3972, 3972, 2785, 3972, 3972, 3972, 2785, 2785,\n     3972, 2785, 3972, 2785, 2785, 2785, 2785, 2797, 3972, 3972,\n     2797, 2797, 3972, 3972, 2797, 2797, 3972, 2797, 3972, 2797,\n     2797, 2797, 2797, 2806, 3972, 3972, 3972, 2806, 2806, 3972,\n     2806, 3972, 2806, 2806, 2806, 2806, 2815, 2815, 3972, 2815,\n     2815, 3972, 2815, 2815, 2815, 2815, 2815, 2815, 2815, 2815,\n     2815, 2815, 2815, 2815, 2837, 3972, 3972, 2837, 2837, 3972,\n     3972, 2837, 2837, 3972, 2837, 3972, 2837, 2837, 2837, 2837,\n\n     2841, 2841, 2841, 2841, 2841, 2841, 2841, 2841, 2841, 2841,\n     2841, 2841, 2841, 2841, 2841, 2841, 2841, 2841, 2841, 2957,\n     3972, 3972, 3972, 2957, 2957, 3972, 2957, 3972, 2957, 2957,\n     2957, 2957, 2989, 3972, 3972, 2989, 2989, 3972, 3972, 2989,\n     2989, 3972, 2989, 3972, 2989, 2989, 2989, 2989, 2998, 3972,\n     3972, 3972, 2998, 2998, 3972, 2998, 3972, 2998, 2998, 2998,\n     2998, 3115, 3115, 3972, 3115, 3115, 3972, 3115, 3115, 3115,\n     3115, 3115, 3115, 3115, 3115, 3115, 3115, 3115, 3115, 3119,\n     3972, 3972, 3119, 3119, 3972, 3972, 3119, 3119, 3972, 3119,\n     3972, 3119, 3119, 3119, 3119, 3123, 3123, 3123, 3123, 3972,\n\n     3123, 3123, 3123, 3123, 3123, 3123, 3123, 3123, 3123, 3123,\n     3123, 3123, 3123, 3123, 3138, 3972, 3972, 3972, 3972, 3972,\n     3138, 3138, 3138, 3138, 3972, 3138, 3138, 3138, 3138, 3138,\n     3138, 3138, 3138, 3249, 3972, 3972, 3972, 3249, 3249, 3972,\n     3249, 3972, 3249, 3249, 3249, 3249, 3272, 3272, 3972, 3272,\n     3272, 3972, 3272, 3272, 3272, 3272, 3272, 3272, 3272, 3272,\n     3272, 3272, 3272, 3272, 3351, 3972, 3972, 3351, 3351, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3351, 3369, 3369, 3972,\n     3972, 3972, 3369, 3369, 3369, 3369, 3369, 3369, 3369, 3369,\n     3369, 3369, 3369, 3369, 3369, 3369, 3455, 3455, 3972, 3455,\n\n     3455, 3455, 3455, 3455, 3455, 3455, 3455, 3455, 3455, 3455,\n     3455, 3455, 3455, 3455, 3481, 3481, 3972, 3481, 3481, 3972,\n     3481, 3481, 3481, 3481, 3481, 3481, 3481, 3481, 3481, 3481,\n     3481, 3481, 3491, 3491, 3972, 3491, 3491, 3972, 3491, 3491,\n     3491, 3491, 3491, 3491, 3491, 3491, 3491, 3491, 3491, 3491,\n     3549, 3549, 3972, 3549, 3549, 3972, 3549, 3549, 3549, 3549,\n     3549, 3549, 3549, 3549, 3549, 3549, 3549, 3549, 3570, 3570,\n     3972, 3570, 3570, 3570, 3570, 3570, 3570, 3570, 3570, 3570,\n     3570, 3570, 3570, 3570, 3570, 3570, 3573, 3573, 3972, 3573,\n     3573, 3573, 3573, 3573, 3573, 3573, 3573, 3573, 3573, 3573,\n\n     3573, 3573, 3573, 3573, 3620, 3972, 3972, 3620, 3972, 3620,\n     3972, 3620, 3620, 3620, 3620, 3652, 3652, 3972, 3652, 3652,\n     3972, 3652, 3652, 3652, 3652, 3652, 3652, 3652, 3652, 3652,\n     3652, 3652, 3652, 3653, 3653, 3972, 3653, 3653, 3972, 3653,\n     3653, 3653, 3653, 3653, 3653, 3653, 3653, 3653, 3653, 3653,\n     3653, 3656, 3656, 3656, 3656, 3656, 3656, 3656, 3656, 3656,\n     3656, 3656, 3656, 3656, 3656, 3656, 3656, 3656, 3656, 3656,\n     3693, 3972, 3972, 3693, 3972, 3693, 3972, 3693, 3693, 3693,\n     3693, 3697, 3697, 3972, 3697, 3697, 3697, 3697, 3697, 3697,\n     3697, 3697, 3697, 3697, 3697, 3697, 3697, 3697, 3697, 3697,\n\n     3708, 3708, 3972, 3708, 3708, 3972, 3708, 3708, 3708, 3708,\n     3708, 3708, 3708, 3708, 3708, 3708, 3708, 3708, 3710, 3710,\n     3972, 3972, 3710, 3710, 3710, 3710, 3710, 3710, 3972, 3710,\n     3710, 3710, 3710, 3710, 3710, 3710, 3710, 3699, 3699, 3972,\n     3699, 3699, 3972, 3699, 3699, 3699, 3699, 3699, 3699, 3699,\n     3699, 3699, 3699, 3699, 3699, 3761, 3972, 3972, 3972, 3972,\n     3972, 3761, 3761, 3761, 3761, 3972, 3761, 3761, 3761, 3761,\n     3761, 3761, 3761, 3761, 3701, 3972, 3972, 3972, 3972, 3972,\n     3701, 3701, 3701, 3701, 3972, 3701, 3701, 3701, 3701, 3701,\n     3701, 3701, 3701, 3765, 3972, 3972, 3765, 3765, 3972, 3972,\n\n     3765, 3765, 3972, 3765, 3972, 3765, 3765, 3765, 3765, 3768,\n     3768, 3972, 3768, 3768, 3972, 3768, 3768, 3768, 3768, 3768,\n     3768, 3768, 3768, 3768, 3768, 3768, 3768, 3769, 3972, 3972,\n     3972, 3972, 3972, 3769, 3769, 3769, 3769, 3972, 3769, 3769,\n     3769, 3769, 3769, 3769, 3769, 3769, 3808, 3972, 3972, 3972,\n     3808, 3808, 3972, 3808, 3972, 3808, 3808, 3808, 3808, 3809,\n     3809, 3972, 3809, 3809, 3972, 3809, 3809, 3809, 3809, 3809,\n     3809, 3809, 3809, 3809, 3809, 3809, 3809, 3810, 3810, 3810,\n     3810, 3810, 3810, 3810, 3810, 3810, 3810, 3810, 3810, 3810,\n     3810, 3810, 3810, 3810, 3810, 3810, 3857, 3857, 3972, 3857,\n\n     3857, 3972, 3857, 3857, 3857, 3857, 3857, 3857, 3857, 3857,\n     3857, 3857, 3857, 3857, 3860, 3860, 3972, 3972, 3860, 3860,\n     3860, 3860, 3860, 3860, 3972, 3860, 3860, 3860, 3860, 3860,\n     3860, 3860, 3860, 3862, 3862, 3972, 3972, 3862, 3862, 3862,\n     3862, 3862, 3862, 3972, 3862, 3862, 3862, 3862, 3862, 3862,\n     3862, 3862, 3890, 3890, 3972, 3890, 3890, 3972, 3890, 3890,\n     3890, 3890, 3890, 3890, 3890, 3890, 3890, 3890, 3890, 3890,\n     3891, 3891, 3972, 3891, 3891, 3972, 3891, 3891, 3891, 3891,\n     3891, 3891, 3891, 3891, 3891, 3891, 3891, 3891, 3892, 3892,\n     3972, 3972, 3892, 3892, 3892, 3892, 3892, 3892, 3972, 3892,\n\n     3892, 3892, 3892, 3892, 3892, 3892, 3892, 3894, 3894, 3972,\n     3972, 3894, 3894, 3894, 3894, 3894, 3894, 3972, 3894, 3894,\n     3894, 3894, 3894, 3894, 3894, 3894, 3908, 3972, 3972, 3908,\n     3972, 3908, 3972, 3908, 3908, 3908, 3908, 3910, 3910, 3972,\n     3910, 3910, 3910, 3910, 3910, 3910, 3910, 3910, 3910, 3910,\n     3910, 3910, 3910, 3910, 3910, 3921, 3921, 3972, 3921, 3921,\n     3972, 3921, 3921, 3921, 3921, 3921, 3921, 3921, 3921, 3921,\n     3921, 3921, 3921, 3922, 3922, 3972, 3922, 3922, 3972, 3922,\n     3922, 3922, 3922, 3922, 3922, 3922, 3922, 3922, 3922, 3922,\n     3922, 3934, 3972, 3972, 3934, 3972, 3934, 3972, 3934, 3934,\n\n     3934, 3934, 3935, 3972, 3972, 3972, 3972, 3972, 3935, 3935,\n     3935, 3935, 3972, 3935, 3935, 3935, 3935, 3935, 3935, 3935,\n     3935,   75, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972\n    } ;\n\nstatic const flex_int16_t yy_chk[13611] =\n    {   0,\n        0,    1,    1,    1,    1,    5,    1,    1,    5,    6,\n        0,   71,    6,    9,    9,    1,    9,    9,   72,   21,\n       21,    0,   21,    7,    7,    7,    7,    7,    7,   71,\n      297,    1,    7,    1,    1,   83,   72,    7,    1,    1,\n        1,  297,    9,   85,    1,    1,    1,  778,    1,    1,\n       84,   10,   10,    1,   10,   10,   13,    1,   86,    1,\n       13,    1,    1,   83,  778,   13,    1,    1,    1,    9,\n     3948,   85,    1,    1,    1,   21,    1,    1,   84,    7,\n       10,    1,    2,    2,    2,    2,   86,    2,    2,   11,\n       11,  220,   11,   11,   12,   12,    2,   12,   12,  118,\n\n       87,   14,  118,   15,   15,   14,   15,   10,    7,    7,\n       14,   15,    2,   15,    2,    2,   88,  389,   11,    2,\n        2,    2, 3935,   12,   89,    2,    2,    2,   87,    2,\n        2, 3922,   92,   93,    2,   95,   95,  250,    2,  250,\n        2, 3921,    2,    2,   88,   11,  220,    2,    2,    2,\n       12, 3910,   89,    2,    2,    2,  389,    2,    2,   15,\n       92,   93,    2,    3,    3,    3,    3,    3,    3,    3,\n        3,    3,    3,    3,    3,    3,    3,    3,    3,    3,\n        3,    3,    3,    3,    3,    3,    3,    3,    3,    3,\n        3,    3,    3,    3,    3,    3,    3,    3,    3,    3,\n\n        3,    3,    3,    3,    3,    3,    3,    3,    3,    3,\n        3,    3,    3,    3,    3,    3,    3,    3,    3,    3,\n        3,    3,    3,    3,    3,    3,    3,    3,    3,    3,\n        3,    3,    3,    3,    3,    3,    3,    3,    3,    3,\n        3,    3,    3,    3,    3,    3,    3,    3,    3,    3,\n        3,    8,    8,    8,    8,    8,    8,  406,   16,   16,\n        8,   16,  116,  116,  196,    8,   16,  196,   16,   17,\n       17,  257,   17,  257,   17,   18,   18,   17,   18,  645,\n       18,  132,  132,   18,   19,   19, 2104,   19, 2104,   19,\n       22,   22,   19,   22,   20,   20,  406,   20,   19,   20,\n\n       94,   45,   20, 3891,   45,   49,   45,    8,   20,   49,\n       27,   27,   49,   27,   16,   27,   28,   28,  645,   28,\n       27,   28,  213,  213,   27,   17,   28,   27,   94,   46,\n       28,   18,   46,   28,   46,   81,    8,    8,   81,  100,\n       19,  101,  223,  223,   35,   35,   22,   35,   29,   29,\n       20,   29,   35,   29,  104,  485,   29,   45,   29,  137,\n       49,  137,   29,  226,  226,   29,   27,  100, 3890,  101,\n       30,   30,   28,   30,  495,   30,   29,  107,   30,   47,\n       30,   47,  104,   81,   30,   46,   47,   30,   97,   31,\n       31,   97,   31, 3880,   31,   27,   27,   31,   30,   31,\n\n       35,   28,   28,   31,   29,  107,   31,  137,   32,   32,\n      485,   32,   48,   32,   48, 2666,   32,   31,   32,   48,\n       77,   77,   32,   77, 3849,   32,   30,   33,   33,  495,\n       33,  310,   33,   50,   47,   33,   32,   50,   34,   34,\n       50,   34,  310,   34,   97,   31,   34,   36,   36,  108,\n       36,   39,   39,   39,   39,   36,   39,   40,   40,   40,\n       40,   90,   40,  109,   32,   39, 2666,   48,  114,   90,\n       99,   40,  105,   99,  105,  522,   77,  108,  195,  195,\n      195,  195,  219,   33, 3847,  219,  522,  219,   50,   90,\n      225,  109,  283,  225,   34,  283,  114,   90,   99, 3843,\n\n      105,   99,  105,   36,   37,   37,   37,   37,   37,   37,\n       37,   37,   37,   37,   37,   37,   37,   37,   37,   37,\n       37,   37,   37,   37,   37,   37,   37,   37,   37,   37,\n       37,   37,   37,   37,   37,   37,   37,   37,   37,   37,\n       37,   37,   37,   37,   37,   37,   37,   37,   37,   37,\n       37,   37,   37,   37,   37,   37,   37,   37,   37,   37,\n       37,   37,   37,   37,   37,   37,   37,   37,   37,   37,\n       37,   37,   37,   37,   37,   37,   37,   37,   37,   37,\n       37,   37,   37,   37,   37,   37,   37,   37,   37,   37,\n       37,   37,   41,   41,   41,   41,   59,   41,   42,   42,\n\n       42,   42,  499,   42,   43,   43,   43,   43,  115,   43,\n       44,   44,   44,   44,   65,   44,  129,   65,   60,  129,\n      649,  140,   66,   65,   73,   66, 2841,   73,   59,   73,\n       59,   66,  649,   73, 3842,  143,  115,   65,  143,   59,\n       59,   59,   59,  265,  265,   66,  147,   73,   41,  140,\n       60,   67,   60,  139,   42,  139,   59,  499,   59,   91,\n       43,   60,   60,   60,   60,   65,   44,   59,   59,   59,\n       59,   68,  129,   66,  147,   73,   91, 2841,   60,   74,\n       60,  102,   74,   67,   74,   67,  143,   91,   74,   60,\n       60,   60,   60,  102,   67,   67,   67,   67, 3835,  103,\n\n      875,  139,   74,   68,   91,   68,  103,  267,  525,  102,\n      267,   67,  110,   67,   68,   68,   68,   68,  106,  525,\n      111,  102,   67,   67,   67,   67,  112,  103,  110,  153,\n       74,   68,  106,   68,  103,  111,  106,  347,  106,  347,\n      110,  112,   68,   68,   68,   68,  106,  113,  111,  173,\n      145,  113,  113,  145,  112,  267,  110,  153,  142,  142,\n      106,  286,  286,  111,  106,  142,  106,  142,  875,  112,\n     3811,  119,  119,  119,  119,  113,  119,  173, 3808,  113,\n      113,  120,  120,  120,  120,  347,  120,  121,  121,  121,\n      121, 3799,  121,  126,  126,  126,  126,  177,  126,  177,\n\n      133,  145,  138,  133,  183,  138,  144,  189,  880,  144,\n      138,  144,  138,  142,  144,  880,  198,  133,  133,  148,\n      148,  149,  179,  148,  149,  179,  148,  119,  133,  349,\n      149,  133,  183,  150, 3769,  189,  150,  120,  150,  151,\n      177,  150,  151,  121,  198,  133,  133,  150,  151,  126,\n      131,  131,  131,  131,  131,  131,  188,  131,  138,  188,\n      131, 3761,  144,  201,  131,  316,  131,  131,  316,  131,\n      131,  131,  149,  179,  148,  437,  437,  349,  131,  131,\n      131,  131,  131,  131,  285,  131, 3730,  285,  131,  150,\n      151,  201,  131,  181,  131,  131,  181,  131,  131,  131,\n\n      155,  155,  156,  156,  155,  156, 3728,  155,  157,  157,\n      750,  157,  188,  155,  159,  159,  159,  159,  162,  162,\n     1602,  162,  203,  162,  166,  166, 3691,  166,  180,  166,\n     3685,  180,  162,  180,  167,  167,  180,  167,  166,  167,\n      285,  166,  168,  168,  181,  168,  185,  168,  167,  319,\n      203,  185,  319,  200,  169,  155,  168,  169,  156,  169,\n     3657,  205,  167,  169,  157,  750,  200,  208,  170,  210,\n      159,  170,  210,  170,  162, 1602,  170,  169,  170, 3653,\n      166,  200,  170,  171,  180,  881,  171,  211,  171,  205,\n      167,  360,  171,  206,  200,  208,  170,  881,  168,  185,\n\n      210,  206, 3652,  162,  162,  169,  171,  184,  184,  166,\n      166,  184,  187,  174,  184,  211,  174,  187,  174,  167,\n      167,  206,  174,  186,  170,  174,  186,  168,  168,  206,\n      176,  186, 1793,  176,  171,  176,  174, 1793,  176,  360,\n      176,  178,  178,  381,  176,  178,  381,  227,  178,  212,\n      178, 1203,  227,  230,  178, 3617,  199,  415,  176,  190,\n      190,  190,  184,  199,  174,  187,  190,  197,  178,  192,\n      192,  192,  192,  235,  204,  199,  197,  212,  202,  186,\n      197,  230,  207,  192,  199,  197,  176, 3609,  202,  207,\n      243,  199,  204,  228,  204,  197,  178, 1203,  228,  207,\n\n      227,  235,  204,  199,  197,  415,  202,  911,  197,  436,\n      207, 3592,  436,  197,  190,  176,  202,  207,  243,  209,\n      204,  224,  204,  209,  224,  192,  224,  207, 3573,  209,\n      214,  214,  214,  214,  217,  217,  217,  217,  209,  218,\n      218,  218,  218,  231,  218,  244,  228,  209,  231,  232,\n      245,  209,  232,  221,  221,  221,  221,  209,  221,  222,\n      222,  222,  222,  246,  222,  233,  209,  236,  233,  247,\n      236,  248, 3570,  244,  911,  253,  260,  224,  245,  251,\n      263,  263,  251,  263,  254,  269,  214,  254,  251,  258,\n      217,  246,  258,  254,  258,  218,  231,  247,  258,  248,\n\n      232,  270,  251,  253,  260,  262,  271,  254,  262,  221,\n      262,  272,  258,  269,  262,  222,  233,  273,  236,  274,\n      275,  276,  277,  278,  279,  280,  281,  280,  262,  270,\n      251,  282,  287,  288,  271,  254,  263,  289,  290,  272,\n      258,  281,  291,  292,  293,  273,  294,  274,  275,  276,\n      277,  278,  279,  280,  281,  280,  262,  295,  296,  282,\n      287,  288,  298,  299,  300,  289,  290,  301,  302,  281,\n      291,  292,  293,  303,  294,  304,  305,  306,  307,  307,\n      305,  308,  305,  309,  311,  295,  296,  312,  313,  314,\n      298,  299,  300,  315, 3549,  301,  302,  320,  320,  320,\n\n      320,  303,  320,  304,  305,  306,  307,  307,  305,  308,\n      305,  309,  311, 3541,  329,  312,  313,  314,  330,  331,\n      424,  315,  321,  321,  321,  321,  333,  321,  322,  322,\n      322,  322,  324,  322,  337,  324,  326,  324,  338,  326,\n      328,  326,  329,  328,  334,  332,  330,  331,  332,  335,\n     3536,  335,  336,  320,  333,  338, 3524,  339,  334,  334,\n      338,  340,  337,  342,  343,  341,  338,  336,  424,  341,\n      345,  346,  334,  332,  443,  346,  332,  335,  321,  335,\n      336,  487,  487,  338,  322,  339,  334,  334,  338,  340,\n      344,  342,  343,  341, 3514,  336,  328,  341,  345,  346,\n\n      351,  351,  443,  346,  344,  344,  350,  351,  352,  350,\n      352,  356,  354,  356,  350,  354,  350,  355,  344, 2105,\n      354, 2105,  354,  370,  355,  357,  355,  363,  357,  370,\n      363,  361,  344,  344,  361,  444,  361,  362,  362,  361,\n      364,  508,  365,  364,  362,  365,  893,  365,  373,  367,\n      365,  373,  367,  366,  564,  351,  352,  366,  367,  356,\n      366,  371,  350,  444,  371,  564,  371,  442,  354,  371,\n      442,  370,  355,  372,  372,  371,  357,  376,  363,  374,\n      372,  376,  374,  877,  376,  515,  372,  361,  374,  508,\n      376,  364,  362,  377,  377,  877,  377, 3512,  365,  373,\n\n      367,  375,  378,  378,  375,  378,  375,  883,  366,  375,\n      380,  380,  380,  380,  893,  375, 3491,  371,  382,  382,\n     3455,  382,  383,  383, 3441,  383,  426,  383,  372,  426,\n      374,  399,  376,  515,  385,  385,  383,  385,  392,  387,\n      387,  392,  387,  392,  387,  422,  883,  392,  385,  377,\n      422,  399,  412,  387, 1120,  412, 3435,  375,  378,  388,\n      388,  392,  388,  877,  388,  418,  380,  387,  418,  497,\n      497,  902,  396,  388,  382,  396,  388,  396,  383,  399,\n     3401,  396,  426,  390,  390,  445,  390,  388,  390,  392,\n      385,  391,  391,  446,  391,  387,  391,  390,  422,  419,\n\n      390,  475,  419,  412,  475,  391,  567,  383,  383,  395,\n      902,  390,  395,  445,  395,  388,  418,  567,  395,  385,\n      385,  446, 1120,  396,  387,  387,  397,  502,  502,  397,\n      416,  397,  395,  416,  397,  416,  397, 1346,  416,  390,\n      397,  592,  398,  398,  388,  388,  398,  391,  429,  398,\n      419,  398,  592,  429,  397,  398,  400,  417,  417,  400,\n      395,  400,  864,  447,  417,  400,  906,  421,  390,  390,\n      402,  421,  448,  402,  421,  402,  391,  391,  402,  400,\n      402, 1976,  397, 3334,  402,  403,  416, 3321,  403,  404,\n      403,  447,  404,  403,  404,  403, 3305,  398,  402,  403,\n\n      448,  429,  403,  449, 1346,  906,  404,  400,  427,  427,\n      864,  405,  417,  403,  405,  427,  405,  404,  867,  405,\n      489,  405,  421,  489,  420,  405,  402,  420,  405,  420,\n      407,  449,  420,  407,  425,  407, 1976,  425,  407,  405,\n      407,  403,  425,  410,  407,  404,  410,  407,  410,  432,\n      450,  410,  411,  410,  432,  402,  411,  410,  407,  411,\n      452,  411,  431,  427,  431,  411,  867,  405, 3298,  431,\n      403,  410,  455,  404,  404,  428,  428,  428,  450,  411,\n      420,  430,  428, 3296,  430,  456,  407, 3290,  452,  430,\n      425,  433,  433,  433,  433,  451,  405,  451,  457,  410,\n\n      455,  451,  432,  453,  458,  433,  459,  411,  439,  439,\n      439,  439,  461,  456,  453,  407,  460,  431,  462,  912,\n      463,  464,  463,  451,  467,  451,  457,  460,  465,  451,\n      428,  453,  458,  466,  459,  469,  470,  430,  465,  472,\n      461,  466,  453,  468,  460,  468,  462,  433,  463,  464,\n      463,  466,  467, 1127,  473,  460,  465,  474,  912,  496,\n     1127,  466,  496,  469,  470,  484,  465,  472,  484,  466,\n      484,  468, 3249,  468,  477,  477,  477,  477, 1336,  466,\n      471,  471,  473,  471,  488,  474,  471,  488,  471,  488,\n      471,  471,  471,  521,  471, 1410,  471,  471,  471,  471,\n\n      481,  481,  481,  481,  482,  482,  482,  482,  471,  471,\n      490,  471, 3214,  490,  471,  490,  471, 1336,  471,  471,\n      471,  521,  471,  506,  471,  471,  471,  471,  506,  523,\n      477,  483,  483,  483,  483, 3188,  483,  486,  486,  486,\n      486, 1410,  486,  492,  492,  492,  492, 3175,  492,  493,\n      493,  493,  493,  524,  493, 3169,  481,  523,  494,  498,\n      482,  494,  498,  494,  498,  500,  501,  526,  500,  501,\n      500,  503,  504,  509,  503,  504,  506,  504,  509,  511,\n      512,  524,  516,  512,  511,  516,  517,  483,  529,  517,\n      533,  529,  540,  486,  540,  526,  543,  529,  532,  492,\n\n      534,  532,  544,  534,  830,  493, 1725,  532, 3138,  534,\n      533,  529,  540,  536,  545,  830,  536,  546,  536,  547,\n     3123,  500,  536,  534,  543,  539,  509,  548,  539,  549,\n      544,  512,  511,  516,  539,  551,  536,  517,  533,  529,\n      540,  552,  545,  541,  553,  546,  541,  547,  541,  532,\n      554,  534,  541,  555,  557,  548,  558,  549,  559,  560,\n      561,  559,  560,  551,  536,  562,  541,  593,  563,  552,\n      593,  565,  553, 1725, 1012, 3074,  539,  566,  554, 3072,\n      568,  555,  557,  569,  558, 1012,  594,  640,  561,  594,\n      640,  570,  572,  562,  541,  556,  563,  556,  556,  565,\n\n      573,  556,  556,  556,  575,  566,  576,  556,  568,  577,\n      556,  569,  556,  556,  556,  556,  578,  556,  556,  570,\n      572,  579,  582,  556, 3070,  556,  556,  583,  573,  556,\n      556,  556,  575,  580,  576,  556,  584,  577,  556,  585,\n      556,  556,  556,  556,  578,  556,  556,  581,  581,  579,\n      582,  586,  580,  588,  589,  583,  590,  596,  597,  591,\n      598,  580,  599,  601,  584,  602,  603,  585,  605,  606,\n      609,  610,  611,  612,  613,  581,  581,  591,  614,  586,\n      580,  588,  589,  615,  590,  596,  597,  591,  598,  616,\n      599,  601,  617,  602,  603,  618,  605,  606,  609,  610,\n\n      611,  612,  613,  619,  620,  591,  614,  621,  622, 3066,\n      623,  615,  623, 1412,  643,  629,  626,  616,  629,  626,\n      617, 3057,  641,  618,  626,  641,  626, 2180, 2180, 3047,\n      627,  619,  620,  627,  632,  621,  622,  632,  627,  632,\n      627,  633,  632, 2843,  633,  635,  633,  638,  635,  633,\n      638, 3017,  638,  643,  635,  638,  648,  639,  623, 1412,\n      639,  638,  639, 1337,  678,  639,  629,  648,  658,  678,\n      648,  639,  626,  672,  642,  642,  672,  642, 2313,  642,\n     2313,  665,  643,  677,  644,  644,  627,  644,  642,  644,\n      632,  642,  665,  685, 2843,  665,  635,  633,  644,  686,\n\n      687,  644,  642,  638, 3003,  646,  646,  658,  646,  688,\n      646,  677,  644,  639,  689,  650,  650,  678,  650,  646,\n      650,  685,  646,  738,  672,  666,  738,  686,  687,  650,\n      642, 1337,  650,  646,  666, 3004,  658,  688,  648,  690,\n      644,  652,  689,  650,  652,  666,  652, 1347,  655,  675,\n      652,  655,  675,  655,  675, 3003,  655,  675,  655,  642,\n      642,  646,  655,  665,  652,  655,  691,  690, 3002,  644,\n      644,  650,  676,  666,  693,  676,  655,  676,  656,  657,\n      676,  656,  657,  656,  657,  682, 1347,  657,  682,  657,\n      646,  646,  652,  657,  691,  656,  657,  694,  915, 2998,\n\n      650,  650,  693,  695,  655,  675,  656,  657,  696,  659,\n      660,  808,  659,  660,  659,  660,  759,  659,  660,  659,\n      660,  759,  808,  659,  660,  694,  659,  660,  676,  739,\n     2957,  695,  739,  655,  656,  657,  696,  659,  660,  661,\n      662,  682,  661,  662,  661,  662,  915,  661,  662,  661,\n      662, 2918,  808,  661,  662,  667,  661,  662,  667, 2314,\n      667, 2314,  656,  656,  657,  659,  660,  661,  662,  759,\n      663,  668,  667,  663,  668,  663,  668, 1545,  663,  668,\n      663,  668, 2907,  667,  663,  668, 2906,  663,  668,  681,\n      697,  698,  681,  700,  659,  661,  662,  681,  663,  668,\n\n      701,  740,  669,  702,  740,  669,  683,  669,  704,  683,\n      669,  667,  669,  705,  683, 2903,  669,  741,  697,  698,\n      741,  700,  741, 1545,  661,  662,  663,  668,  701,  670,\n      669,  702,  670,  706,  670,  708,  704,  670,  699,  670,\n      667,  705,  709,  670,  710,  681,  699,  699,  699,  699,\n      699,  699,  699,  699,  699,  663,  668,  670,  669,  711,\n      712,  706,  683,  708,  713,  714,  715,  717,  742, 2867,\n      709,  742,  710,  719,  720,  721,  722,  724,  723,  726,\n      723,  727,  728,  718,  723,  670,  729,  711,  712,  730,\n      731,  727,  713,  714,  715,  717,  718,  718,  725,  718,\n\n      718,  719,  720,  721,  722,  724,  723,  726,  723,  727,\n      728,  718,  723,  725,  729,  733,  737,  730,  731,  727,\n      732, 2316, 2860, 2316,  718,  718,  725,  718,  718,  732,\n      734, 2859,  734,  743,  734, 2848,  743,  744,  743, 2842,\n      744,  725,  744,  733,  737, 1341,  745,  746,  732,  745,\n      746,  748,  746,  758,  748, 2806,  749,  732,  734,  749,\n      734,  749,  734,  751,  752,  766,  751,  752,  751,  753,\n      755,  767,  753,  755,  753,  755,  756,  757,  768,  756,\n      757,  758,  757,  763,  769,  771,  763,  775,  771,  779,\n      775,  780,  775,  766,  771,  781,  775,  782,  783,  767,\n\n      785,  786,  787,  788,  789,  790,  768,  792,  771,  791,\n      775, 2785,  769, 1341,  792, 2233,  796,  779,  797,  780,\n     2233,  792,  795,  781,  791,  782,  783,  791,  785,  786,\n      787,  788,  789,  790,  763,  792,  771,  791,  775,  793,\n      794,  795,  792,  793,  796,  799,  797,  793,  800,  792,\n      795,  798,  791,  798,  794,  791,  794,  801,  802,  803,\n      802,  799,  804,  800,  805,  810,  812,  793,  794,  795,\n      815,  793,  816,  799,  807,  793,  800,  807,  817,  798,\n      818,  798,  794,  819,  794,  801,  802,  803,  802,  799,\n      804,  800,  805,  810,  812,  820,  821,  822,  815,  824,\n\n      816,  825,  826,  827,  828,  829,  817,  831,  818,  832,\n      833,  819,  835,  836,  838,  839,  841,  837,  842,  841,\n      843,  844,  845,  820,  821,  822,  846,  824,  837,  825,\n      826,  827,  828,  829,  847,  831,  848,  832,  833,  837,\n      835,  836,  838,  839,  849,  850,  842,  851,  843,  844,\n      845,  853,  854,  855,  846,  856,  857,  858,  859,  860,\n      861,  855,  847,  862,  848,  863,  865,  837,  865, 2783,\n      870,  868,  849,  850,  868,  851,  870, 2425, 2696,  853,\n      854,  855, 2425,  856,  857,  858,  859,  860,  861,  855,\n      918,  862,  866,  863,  871,  866,  869,  871,  876,  869,\n\n      866,  869,  866,  872,  869,  876,  872,  873,  872,  916,\n      873,  872,  916, 2695,  865,  889,  888,  872,  870,  888,\n      895,  888,  868,  874,  874,  888,  874,  895,  874,  879,\n      879, 2668,  879,  874,  879,  889,  917,  874,  918,  917,\n      874,  917,  922,  879,  917,  871,  879,  920,  866,  919,\n      920,  874,  869,  923,  919,  920,  924,  879, 2664,  872,\n      916,  890,  921,  889,  890,  921,  890,  888, 1344,  890,\n      922,  890, 2523,  876, 2523,  890, 2628,  898,  890,  874,\n      898,  923,  898,  891,  924,  879,  891,  986,  891,  890,\n      986,  891,  917,  891,  898,  895,  892,  891, 2599,  892,\n\n      891,  892,  919,  920,  892,  898,  892,  896,  874,  874,\n      892,  891, 2596,  892,  879,  879,  896,  890,  921, 2587,\n      894,  925,  926,  894,  892,  894,  900,  896,  894,  900,\n      894,  900,  927,  898,  894,  905, 1344,  894,  905,  891,\n      905, 2585,  907,  900,  905,  907,  890,  907,  894,  925,\n      926,  907,  892,  987,  900,  896,  987, 2551,  905,  928,\n      927,  899,  898,  931,  899,  907,  899,  988,  891,  899,\n      988,  899,  988,  932,  935,  899,  894, 2547,  899,  938,\n      901,  892,  900,  901,  896,  901,  905,  928,  901,  899,\n      901,  931,  939,  907,  901,  903,  989,  901,  903,  989,\n\n      903,  932,  935,  903, 3527,  903, 3527,  938,  901,  903,\n      900,  904,  903, 2545,  904,  990,  904,  899,  990,  904,\n      939,  904, 3151,  903,  913,  904, 2608,  913,  904,  913,\n      940, 2608,  913,  942,  913,  943,  901,  944,  913,  904,\n      914,  913,  929,  914,  945,  914,  899,  929,  914,  947,\n      914,  903,  913,  948,  914,  949,  950,  929,  940,  929,\n      951,  942,  952,  943,  954,  944,  955,  904,  914, 2544,\n      929,  991,  945, 3151,  991,  929,  991,  947,  956,  957,\n      913,  948, 2531,  949,  950,  929,  992,  929,  951,  992,\n      952,  958,  954,  959,  955,  960,  914,  936,  936,  936,\n\n      936,  936,  936,  936,  936,  936,  956,  957,  962,  913,\n      937,  937,  937,  937,  937,  937,  937,  937,  937,  958,\n      963,  959,  961,  960,  964,  961,  965,  966,  967,  968,\n      969,  970,  971,  972,  974,  975,  962,  976,  974,  977,\n      976,  978,  979,  980,  981,  982,  985,  995,  963, 3611,\n      995, 3611,  964,  961,  965,  966,  967,  968,  969,  970,\n      971,  972,  974,  975, 1005,  976,  974,  977,  976,  978,\n      979,  980,  981,  982,  985,  993,  994, 1007,  993,  994,\n      993,  994,  996,  998, 2529,  996,  998,  996,  999, 1000,\n     1009,  999, 1000,  999, 1001, 1002, 1010, 1001, 1002, 1001,\n\n     1003, 1004, 1006, 1003, 1004, 1003, 1008, 1006, 1011, 1008,\n     1013, 1014, 1005, 1013, 1016, 1020, 1021, 1015, 1009, 1013,\n     1015, 1023, 1015, 1024, 1010, 1007, 1015, 2528, 1025, 1284,\n     1026, 1014, 1027, 2527, 1016, 1028, 1011, 1029, 1030, 1031,\n     1284, 1032, 1033, 1020, 1021, 1034, 3613, 2522, 3613, 1023,\n     1036, 1024, 1038, 1039, 1040, 1006, 1025, 1008, 1026, 1014,\n     1027, 1013, 1016, 1028, 1041, 1029, 1030, 1031, 1015, 1032,\n     1033, 1042, 1043, 1034, 1035, 1035, 1035, 1035, 1036, 1037,\n     1038, 1039, 1040, 1037, 1044, 1045, 1046, 1047, 1049, 1048,\n     1050, 1051, 1041, 1048, 1050, 1048, 1052, 1053, 1054, 1042,\n\n     1043, 1055, 1035, 1035, 1035, 1035, 1056, 1037, 1051, 1057,\n     2497, 1037, 1044, 1045, 1046, 1047, 1049, 1048, 1050, 1051,\n     1060, 1048, 1050, 1048, 1052, 1053, 1054, 1059, 1061, 1055,\n     1062, 1059, 1063, 1064, 1056, 1065, 1051, 1057, 1059, 1066,\n     1059, 1062, 1067, 2485, 1068, 1069, 1070, 1071, 1060, 1072,\n     1074, 1075, 1076, 1077, 1078, 1059, 1061, 1080, 1081, 1059,\n     1063, 1064, 1082, 1065, 2473, 1084, 1059, 1066, 1059, 1085,\n     1067, 1062, 1068, 1069, 1070, 1071, 1087, 1072, 1074, 1075,\n     1076, 1077, 1078, 1088, 2471, 1080, 1081, 1089, 1090, 1091,\n     1082, 1083, 1083, 1084, 1092, 1083, 1093, 1085, 1094, 1095,\n\n     1083, 1096, 1097, 1098, 1087, 1099, 1083, 1101, 1102, 1103,\n     1083, 1088, 1083, 1104, 1105, 1089, 1090, 1091, 1106, 1083,\n     1083, 1107, 1092, 1083, 1093, 1108, 1094, 1095, 1083, 1096,\n     1097, 1098, 1109, 1099, 1083, 1101, 1102, 1103, 1083, 1110,\n     1083, 1104, 1105, 1111, 1112, 1125, 1106, 1118, 1118, 1107,\n     1118, 1119, 1118, 1108, 1119, 1124, 1126, 1138, 1124, 1205,\n     1109, 1118, 1205, 2455, 1118, 1140, 1142, 1110, 1143, 1145,\n     2438, 1111, 1112, 1123, 1128, 1118, 1123, 1128, 1123, 1128,\n     1130, 1123, 1128, 1123, 1128, 1138, 1335, 1123, 1128, 1130,\n     1123, 1128, 2398, 1140, 1142, 1126, 1143, 1145, 1134, 1147,\n\n     1130, 1123, 1128, 1118, 1419, 1206, 1129, 1134, 1206, 1129,\n     2396, 1129, 1125, 1125, 1129, 1419, 1129, 2383, 1134, 1148,\n     1129, 1595, 1119, 1129, 1126, 1335, 1124, 1147, 1130, 1123,\n     1128, 1600, 1118, 1118, 1129, 1131, 1132, 2340, 1131, 1132,\n     1131, 1132, 1600, 1131, 1149, 1131, 1134, 1148, 1208, 1131,\n     1151, 1208, 1131, 1132, 1335, 2338, 1152, 1154, 1123, 1128,\n     1150, 1156, 1129, 1131, 1132, 1133, 1135, 1595, 1133, 1135,\n     1133, 1135, 1149, 1133, 2337, 1133, 1150, 1157, 1151, 1133,\n     1158, 1159, 1133, 1135, 1152, 1154, 1160, 1155, 1150, 1156,\n     1162, 1131, 1132, 1133, 1135, 1155, 1155, 1155, 1155, 1155,\n\n     1155, 1155, 1155, 1155, 1150, 1157, 1165, 1167, 1158, 1159,\n     1168, 1171, 1172, 1173, 1160, 1174, 1175, 1176, 1162, 1177,\n     1131, 1133, 1135, 1178, 1178, 1178, 1178, 1178, 1178, 1178,\n     1178, 1178, 1179, 1180, 1165, 1167, 1181, 1182, 1168, 1171,\n     1172, 1173, 1183, 1174, 1175, 1176, 1184, 1177, 1185, 1186,\n     1186, 1135, 1187, 1188, 1189, 1190, 1192, 1193, 1194, 1195,\n     1179, 1180, 1196, 1198, 1181, 1182, 1199, 1200, 1201, 1201,\n     1183, 3686, 1209, 3686, 1184, 1209, 1185, 1186, 1186, 1217,\n     1187, 1188, 1189, 1190, 1192, 1193, 1194, 1195, 2324, 1211,\n     1196, 1198, 1211, 1221, 1199, 1200, 1201, 1201, 1207, 1210,\n\n     1222, 1207, 1210, 1207, 1210, 1212, 1213, 1217, 1212, 1213,\n     1212, 1214, 1215, 1223, 1214, 1215, 1214, 1216, 1230, 1231,\n     1216, 1221, 1232, 1234, 1235, 1236, 1238, 1239, 1222, 1240,\n     1241, 1242, 1243, 1244, 1245, 1247, 1246, 1248, 1249, 1250,\n     1251, 1223, 1246, 1252, 1253, 1254, 1230, 1231, 1255, 1256,\n     1232, 1234, 1235, 1236, 1238, 1239, 1257, 1240, 1241, 1242,\n     1243, 1244, 1245, 1247, 1246, 1248, 1249, 1250, 1251, 1258,\n     1246, 1252, 1253, 1254, 1259, 1260, 1255, 1256, 1261, 1262,\n     1263, 1264, 1265, 1266, 1257, 1267, 1268, 1270, 1271, 1269,\n     1272, 1273, 1275, 1276, 1277, 1278, 1279, 1258, 1280, 1283,\n\n     1285, 1286, 1259, 1260, 1269, 1287, 1261, 1262, 1263, 1264,\n     1265, 1266, 1289, 1267, 1268, 1270, 1271, 1269, 1272, 1273,\n     1275, 1276, 1277, 1278, 1279, 1282, 1280, 1283, 1285, 1286,\n     1290, 1291, 1269, 1287, 1292, 1293, 1282, 1295, 1296, 1297,\n     1289, 1282, 1282, 1298, 1300, 1302, 1303, 1304, 1305, 1306,\n     1307, 1308, 1310, 1282, 1305, 1312, 1313, 1314, 1290, 1291,\n     1315, 1316, 1292, 1293, 1282, 1295, 1296, 1297, 1317, 1282,\n     1282, 1298, 1300, 1302, 1303, 1304, 1305, 1306, 1307, 1308,\n     1310, 1318, 1305, 1312, 1313, 1314, 1319, 1320, 1315, 1316,\n     1321, 1322, 1323, 1324, 1326, 1327, 1317, 1328, 1329, 1330,\n\n     1331, 1332, 1333, 1334, 1339, 1414, 1350, 2631, 1414, 1318,\n     1353, 1351, 2631, 1351, 1319, 1320, 2322, 2321, 1321, 1322,\n     1323, 1324, 1326, 1327, 2299, 1328, 1329, 1330, 1331, 1332,\n     1333, 1334, 1340, 1349, 1350, 1340, 1343, 1340, 1353, 1351,\n     1340, 1351, 1340, 1339, 1349, 1343, 1340, 1345, 1354, 1340,\n     1345, 1355, 1345, 1356, 1357, 1358, 1343, 1359, 1360, 1361,\n     1340, 1364, 1366, 1348, 1345, 1367, 1348, 1683, 1348, 2285,\n     1368, 1348, 1339, 1348, 1372, 1345, 1354, 1348, 1683, 1355,\n     1348, 1356, 1357, 1358, 1343, 1359, 1360, 1361, 1340, 1364,\n     1366, 1348, 1363, 1367, 1369, 1363, 1370, 1363, 1368, 1371,\n\n     1349, 1373, 1363, 1345, 2178, 1372, 1363, 1374, 1375, 1377,\n     1383, 1372, 1385, 1343, 1388, 1389, 1390, 1391, 1392, 1348,\n     1415, 2797, 1369, 1415, 1370, 1417, 2797, 1371, 1417, 1373,\n     1393, 1394, 1345, 1372, 1395, 1374, 1375, 1377, 1383, 1372,\n     1385, 1396, 1388, 1389, 1390, 1391, 1392, 1397, 1363, 1384,\n     1384, 1384, 1384, 1384, 1384, 1384, 1384, 1384, 1393, 1394,\n     1399, 1400, 1395, 1401, 1402, 1404, 1405, 1406, 1407, 1396,\n     1408, 1409, 1405, 1416, 1418, 1397, 1416, 1418, 1416, 1420,\n     1421, 1424, 1425, 1426, 1427, 1428, 1426, 1429, 1399, 1400,\n     1430, 1401, 1402, 1404, 1405, 1406, 1407, 1431, 1408, 1409,\n\n     1405, 1432, 1433, 1434, 1435, 1436, 1437, 1420, 1421, 1424,\n     1425, 1439, 1427, 1428, 1440, 1429, 1441, 1442, 1430, 1443,\n     1444, 1445, 1438, 1446, 1447, 1431, 1449, 1450, 1451, 1432,\n     1433, 1434, 1435, 1436, 1437, 1438, 2177, 1452, 1453, 1439,\n     1438, 1454, 1440, 1455, 1441, 1442, 1456, 1443, 1444, 1445,\n     1438, 1446, 1447, 1448, 1449, 1450, 1451, 1598, 2089, 1448,\n     1598, 1448, 1458, 1438, 1448, 1452, 1453, 1459, 1438, 1454,\n     1460, 1455, 1457, 1461, 1456, 1462, 1457, 1463, 1464, 1465,\n     1466, 1448, 1467, 1457, 1468, 1457, 1457, 1448, 1457, 1448,\n     1458, 1469, 1448, 1470, 1471, 1459, 1472, 1473, 1460, 1474,\n\n     1457, 1461, 1475, 1462, 1457, 1463, 1464, 1465, 1466, 1476,\n     1467, 1457, 1468, 1457, 1457, 1477, 1457, 1478, 1483, 1469,\n     1484, 1470, 1471, 1485, 1472, 1473, 1486, 1474, 1487, 1488,\n     1475, 1492, 1489, 1493, 2087, 1496, 1497, 1476, 1498, 1489,\n     1494, 1499, 1500, 1477, 1501, 1478, 1483, 1489, 1484, 1502,\n     1503, 1485, 1489, 1494, 1486, 1494, 1487, 1488, 1504, 1492,\n     1489, 1493, 1495, 1496, 1497, 1505, 1498, 1489, 1494, 1499,\n     1500, 1506, 1501, 1495, 1507, 1489, 1508, 1502, 1503, 1509,\n     1489, 1494, 1510, 1494, 1495, 1511, 1504, 1512, 1513, 1514,\n     1511, 1515, 1516, 1505, 1517, 1518, 1519, 1520, 1521, 1506,\n\n     1522, 1525, 1507, 1526, 1508, 1523, 1525, 1509, 1527, 1528,\n     1510, 1529, 1495, 1511, 1740, 1512, 1513, 1514, 1511, 1515,\n     1516, 1523, 1517, 1518, 1519, 1520, 1521, 1532, 1522, 1525,\n     1533, 1526, 1530, 1523, 1525, 1534, 1527, 1528, 1535, 1531,\n     1537, 1530, 1531, 1538, 1531, 1539, 1540, 1541, 1542, 1523,\n     2082, 1998, 1530, 1543, 1605, 1532, 1531, 1605, 1533, 1605,\n     1740, 1548, 1551, 1534, 2837, 1983, 1535, 1531, 1537, 2837,\n     1552, 1538, 1553, 1539, 1540, 1541, 1542, 1554, 1529, 1529,\n     1530, 1543, 1544, 1547, 1979, 1544, 1547, 1544, 1547, 1548,\n     1551, 1557, 1544, 1547, 1558, 1531, 1544, 1547, 1552, 1560,\n\n     1553, 1561, 1555, 1563, 1569, 1554, 1555, 1570, 1555, 1556,\n     1556, 1556, 1556, 1556, 1556, 1556, 1556, 1556, 3688, 1557,\n     3688, 1573, 1558, 1574, 1575, 1576, 1577, 1560, 1578, 1561,\n     1555, 1563, 1569, 1579, 1555, 1570, 1555, 1580, 1544, 1547,\n     1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1573,\n     1581, 1574, 1575, 1576, 1577, 1582, 1578, 1583, 1584, 1585,\n     1586, 1579, 1587, 1588, 1589, 1580, 1590, 1591, 1592, 1593,\n     1599, 1603, 1604, 1608, 1609, 1610, 1611, 1612, 1581, 1613,\n     1614, 1615, 1616, 1582, 1612, 1583, 1584, 1585, 1586, 1617,\n     1587, 1588, 1589, 1618, 1590, 1591, 1592, 1593, 1599, 1603,\n\n     1604, 1608, 1609, 1610, 1611, 1612, 1619, 1613, 1614, 1615,\n     1616, 1620, 1612, 1621, 1622, 1623, 1624, 1617, 1625, 1626,\n     1627, 1618, 1628, 1629, 1630, 1631, 1632, 1633, 1634, 1635,\n     1636, 1637, 1638, 1639, 1619, 1640, 1641, 1642, 1643, 1620,\n     1644, 1621, 1622, 1623, 1624, 1645, 1625, 1626, 1627, 1646,\n     1628, 1629, 1630, 1631, 1632, 1633, 1634, 1635, 1636, 1637,\n     1638, 1639, 1647, 1640, 1641, 1642, 1643, 1648, 1644, 1649,\n     1650, 1651, 1652, 1645, 1653, 1654, 1655, 1646, 1656, 1657,\n     1658, 1659, 1660, 1661, 1663, 1664, 1665, 1666, 1667, 1668,\n     1647, 1658, 1669, 1784, 1670, 1648, 1671, 1649, 1650, 1651,\n\n     1652, 1673, 1653, 1654, 1655, 1675, 1656, 1657, 1676, 1659,\n     1660, 1661, 1663, 1664, 1665, 1666, 1667, 1668, 1677, 1678,\n     1669, 1658, 1670, 1679, 1671, 1680, 1681, 1685, 1686, 1673,\n     1687, 1689, 1690, 1675, 1692, 1693, 1676, 1681, 1785, 1784,\n     1697, 1698, 3754, 1699, 3754, 1700, 1677, 1678, 1977, 1785,\n     1702, 1679, 2989, 1680, 1681, 1685, 1686, 2989, 1687, 1689,\n     1690, 1703, 1692, 1693, 1704, 1681, 1682, 1682, 1697, 1698,\n     1682, 1699, 1682, 1700, 1705, 1706, 1682, 1682, 1702, 1707,\n     1682, 1708, 1709, 1710, 1711, 1682, 1712, 1713, 1714, 1703,\n     1715, 1716, 1704, 1717, 1682, 1682, 1719, 1720, 1682, 1719,\n\n     1682, 1721, 1705, 1706, 1682, 1682, 1722, 1707, 1682, 1708,\n     1709, 1710, 1711, 1682, 1712, 1713, 1714, 1718, 1715, 1716,\n     1723, 1717, 1724, 1727, 1719, 1720, 1728, 1719, 1730, 1721,\n     1718, 1731, 1732, 1733, 1722, 1735, 1734, 1736, 1949, 1742,\n     1746, 1747, 2039, 1750, 1751, 1718, 1752, 1753, 1723, 1734,\n     1724, 1727, 1738, 2039, 1728, 1738, 1730, 1738, 1718, 1731,\n     1732, 1733, 1738, 1735, 1734, 1736, 1738, 1742, 1746, 1747,\n     1749, 1750, 1751, 1756, 1752, 1753, 1757, 1734, 1749, 1749,\n     1749, 1749, 1749, 1749, 1749, 1749, 1749, 1754, 1757, 1754,\n     1760, 1762, 1762, 1757, 1791, 1822, 1932, 1791, 1822, 1791,\n\n     1931, 1756, 1928, 1763, 1757, 1764, 1765, 1766, 1738, 1767,\n     1768, 1769, 1770, 1772, 1773, 1754, 1757, 1754, 1760, 1762,\n     1762, 1757, 1761, 1761, 1761, 1761, 1761, 1761, 1761, 1761,\n     1761, 1763, 1775, 1764, 1765, 1766, 1774, 1767, 1768, 1769,\n     1770, 1772, 1773, 1775, 1776, 1777, 1774, 1778, 1779, 1780,\n     1781, 1782, 1775, 1783, 1789, 1790, 1794, 1774, 1795, 1797,\n     1775, 1798, 1799, 1800, 1774, 1801, 1802, 1803, 1804, 1805,\n     1806, 1775, 1776, 1777, 1774, 1778, 1779, 1780, 1781, 1782,\n     1775, 1783, 1789, 1790, 1794, 1774, 1795, 1797, 1807, 1798,\n     1799, 1800, 1808, 1801, 1802, 1803, 1804, 1805, 1806, 1809,\n\n     1810, 1811, 1812, 1813, 1814, 1815, 1816, 1817, 1808, 1818,\n     1819, 1820, 1821, 1823, 1824, 1825, 1807, 1826, 1827, 1828,\n     1808, 1829, 1830, 1831, 1832, 1833, 1834, 1809, 1810, 1811,\n     1812, 1813, 1814, 1815, 1816, 1817, 1808, 1818, 1819, 1820,\n     1821, 1823, 1824, 1825, 1835, 1826, 1827, 1828, 1836, 1829,\n     1830, 1831, 1832, 1833, 1834, 1837, 1838, 1839, 1840, 1838,\n     1841, 1837, 1841, 1842, 1843, 1844, 1846, 1841, 1847, 1848,\n     1850, 1851, 1835, 1852, 1854, 1855, 1836, 1856, 1857, 1858,\n     1848, 1861, 3119, 1837, 1863, 1839, 1840, 3119, 1841, 1837,\n     1841, 1842, 1843, 1844, 1846, 1841, 1847, 1853, 1850, 1851,\n\n     1864, 1852, 1854, 1855, 1865, 1856, 1857, 1858, 1859, 1861,\n     1848, 1853, 1863, 1866, 1867, 1859, 1868, 1869, 1871, 1870,\n     1872, 1873, 1874, 1875, 1876, 1853, 1877, 1880, 1864, 3765,\n     1881, 1882, 1865, 1870, 3765, 1884, 1859, 1885, 1890, 1892,\n     1893, 1866, 1867, 1859, 1868, 1869, 1871, 1870, 1872, 1873,\n     1874, 1875, 1876, 1894, 1877, 1880, 1879, 1879, 1881, 1882,\n     1895, 1870, 1879, 1884, 1897, 1885, 1890, 1892, 1893, 1898,\n     1879, 1899, 1900, 1879, 1901, 1902, 1905, 1906, 1908, 1906,\n     1909, 1894, 1910, 1906, 1879, 1879, 1911, 1912, 1895, 1913,\n     1879, 1914, 1897, 1916, 1906, 1891, 1906, 1898, 1879, 1899,\n\n     1900, 1879, 1901, 1902, 1905, 1906, 1908, 1906, 1909, 1917,\n     1910, 1906, 1860, 1918, 1911, 1912, 1920, 1913, 1919, 1914,\n     1921, 1915, 1906, 1915, 1906, 1919, 1922, 1915, 1923, 1924,\n     1925, 1926, 1929, 1930, 1933, 1788, 1934, 1917, 1915, 1916,\n     1915, 1918, 2108, 1935, 1920, 1937, 1919, 1938, 1921, 1915,\n     1787, 1915, 3578, 1919, 1922, 1915, 1923, 1924, 1925, 1926,\n     1927, 1940, 1941, 1927, 1934, 1927, 1915, 1939, 1915, 1939,\n     1927, 1935, 1942, 1937, 1927, 1938, 1944, 1945, 1929, 1930,\n     1933, 1946, 1947, 1950, 1951, 1953, 1954, 1955, 2108, 1940,\n     1941, 1956, 1957, 1958, 1959, 1939, 1960, 1939, 1999, 2239,\n\n     1942, 1999, 2239, 3578, 1944, 1945, 1962, 1786, 1963, 1946,\n     1947, 1950, 1951, 1953, 1954, 1955, 1927, 1948, 1964, 1956,\n     1957, 1958, 1959, 1965, 1960, 1948, 1948, 1948, 1948, 1948,\n     1948, 1948, 1948, 1948, 1962, 1961, 1963, 1948, 1966, 1948,\n     1948, 1948, 1961, 1967, 1968, 1948, 1964, 1969, 1970, 1971,\n     1948, 1965, 1972, 1973, 1974, 1968, 1975, 1982, 1984, 1948,\n     1759, 2181, 2181, 1961, 1755, 1948, 1966, 1948, 1948, 1948,\n     1961, 1967, 1968, 1948, 1985, 1969, 1970, 1971, 1948, 1986,\n     1972, 1973, 1974, 1968, 1975, 1982, 1984, 1948, 1978, 1978,\n     1978, 1978, 1980, 1980, 1980, 1980, 1987, 1988, 1989, 1990,\n\n     1991, 1992, 1985, 1993, 1994, 1995, 1996, 1986, 1997, 2000,\n     2001, 2002, 2003, 2004, 2005, 2006, 2181, 2008, 2009, 2010,\n     1745, 2011, 1741, 2013, 1987, 1988, 1989, 1990, 1991, 1992,\n     2014, 1993, 1994, 1995, 1996, 2015, 1997, 2000, 2001, 2002,\n     2003, 2004, 2005, 2006, 1978, 2008, 2009, 2010, 1980, 2011,\n     2012, 2013, 2016, 2012, 2017, 2012, 2018, 2019, 2014, 2020,\n     2021, 2022, 2023, 2015, 2024, 2025, 2026, 2027, 2028, 2029,\n     2030, 2031, 2029, 2032, 2029, 2033, 2034, 2035, 2036, 2037,\n     2016, 2038, 2017, 2041, 2018, 2019, 2042, 2020, 2021, 2022,\n     2023, 2043, 2024, 2025, 2026, 2027, 2028, 2044, 2030, 2031,\n\n     2045, 2032, 2046, 2033, 2034, 2035, 2036, 2037, 2047, 2038,\n     2048, 2041, 2049, 2050, 2042, 2051, 2052, 2053, 2246, 2043,\n     1739, 2055, 1737, 2056, 1726, 2044, 2057, 2058, 2045, 2246,\n     2046, 2059, 2201, 2060, 2061, 2201, 2047, 2201, 2048, 2062,\n     2049, 2050, 2063, 2051, 2052, 2053, 2054, 2054, 2054, 2055,\n     2054, 2056, 2054, 2054, 2057, 2058, 2054, 2054, 2054, 2059,\n     2054, 2060, 2061, 2054, 2064, 2054, 2065, 2062, 2066, 2067,\n     2063, 2068, 2069, 2070, 2054, 2054, 2054, 2071, 2054, 2072,\n     2054, 2054, 2073, 2074, 2054, 2054, 2054, 2075, 2054, 2076,\n     2077, 2054, 2064, 2054, 2065, 2078, 2066, 2067, 2079, 2068,\n\n     2069, 2070, 2080, 2083, 2084, 2071, 2085, 2072, 2086, 2091,\n     2073, 2074, 2092, 2093, 2094, 2075, 2095, 2076, 2077, 2096,\n     2097, 2098, 2099, 2078, 2099, 2102, 2079, 2103, 2106, 2109,\n     2080, 2083, 2084, 2107, 2085, 2107, 2086, 2091, 2110, 2111,\n     2092, 2093, 2094, 2112, 2095, 2113, 2114, 2096, 2097, 2098,\n     2099, 2115, 2099, 2102, 2116, 2103, 2106, 2117, 2118, 2119,\n     2120, 2107, 2121, 2107, 2124, 2125, 2126, 2111, 2129, 2130,\n     2131, 2112, 2132, 2113, 2114, 2109, 2133, 2134, 2135, 2115,\n     2136, 2137, 2116, 2247, 2110, 2117, 2118, 2119, 2120, 2138,\n     2121, 2139, 2142, 2139, 2247, 1684, 2129, 2130, 2131, 2406,\n\n     2132, 1674, 2406, 2143, 2133, 2134, 2135, 2144, 2136, 2137,\n     2124, 2125, 2126, 2145, 1672, 2146, 2147, 2138, 2145, 2139,\n     2142, 2139, 2140, 2140, 2140, 2140, 2140, 2140, 2140, 2140,\n     2140, 2143, 2148, 2150, 2140, 2144, 2140, 2140, 2140, 2151,\n     2152, 2145, 2140, 2146, 2147, 2153, 2145, 2140, 2154, 2155,\n     2156, 2157, 2159, 2160, 2161, 2162, 2140, 1601, 1596, 1594,\n     2148, 2150, 2140, 1572, 2140, 2140, 2140, 2151, 2152, 2163,\n     2140, 2164, 2165, 2153, 2166, 2140, 2154, 2155, 2156, 2157,\n     2159, 2160, 2161, 2162, 2140, 2141, 2141, 2141, 2141, 2141,\n     2141, 2141, 2141, 2141, 2167, 2168, 2169, 2163, 2170, 2164,\n\n     2165, 2172, 2166, 2173, 2174, 2175, 2176, 2179, 2179, 2179,\n     2179, 2182, 2182, 2182, 2182, 2183, 2183, 2184, 2186, 2187,\n     2188, 2189, 2167, 2168, 2169, 2191, 2170, 2192, 2193, 2172,\n     2194, 2173, 2174, 2175, 2176, 1568, 2195, 2196, 2197, 2202,\n     2198, 2199, 2202, 1550, 2200, 2184, 2186, 2187, 2188, 2189,\n     2203, 2204, 1549, 2191, 2205, 2192, 2193, 2206, 2194, 2207,\n     2208, 2209, 2210, 2179, 2195, 2196, 2197, 2182, 2198, 2199,\n     2183, 2190, 2200, 2211, 2190, 2212, 1546, 2215, 2203, 2204,\n     2202, 2213, 2205, 2216, 2213, 2206, 2213, 2207, 2208, 2209,\n     2210, 2190, 1491, 2217, 2218, 2219, 2220, 2221, 2222, 2223,\n\n     2224, 2211, 2225, 2212, 2190, 2215, 2190, 2227, 2202, 2228,\n     2229, 2216, 2230, 1490, 2234, 2235, 2190, 2236, 2190, 2190,\n     2190, 2217, 2218, 2219, 2220, 2221, 2222, 2223, 2224, 2237,\n     2225, 2238, 2190, 2240, 2190, 2227, 2231, 2228, 2229, 2231,\n     2230, 2231, 2234, 2235, 2190, 2236, 2190, 2190, 2190, 2241,\n     2242, 2244, 2245, 2248, 2249, 2250, 2251, 2237, 2252, 2238,\n     2253, 2240, 2254, 2255, 2256, 2257, 2258, 2259, 2260, 2253,\n     2261, 2262, 2263, 2264, 2265, 2266, 1482, 2241, 2242, 2244,\n     2245, 2248, 2249, 2250, 2251, 2268, 2252, 2269, 2253, 2267,\n     2254, 2255, 2256, 2257, 2258, 2259, 2260, 2270, 2261, 2262,\n\n     2263, 2264, 2265, 2266, 2267, 2275, 2276, 2277, 2278, 2279,\n     2280, 2281, 2282, 2268, 2283, 2269, 2284, 2267, 2286, 2287,\n     2288, 2289, 2290, 2295, 2296, 2270, 2298, 2302, 2303, 2305,\n     2306, 2307, 2267, 2275, 2276, 2277, 2278, 2279, 2280, 2281,\n     2282, 2308, 2283, 2309, 2284, 2310, 2286, 2287, 2288, 2289,\n     2290, 2295, 2296, 2311, 2298, 2302, 2303, 2305, 2306, 2307,\n     2318, 2319, 2320, 2323, 2325, 2327, 2328, 2329, 2330, 2308,\n     2331, 2309, 2332, 2310, 2333, 2334, 2335, 2336, 2339, 2341,\n     2342, 2311, 1481, 2343, 2344, 2345, 2346, 2347, 2318, 2319,\n     2320, 2348, 2349, 2327, 2328, 2329, 2330, 1480, 2331, 2351,\n\n     2332, 2352, 2333, 2334, 2335, 2336, 2353, 2355, 2342, 2323,\n     2325, 2343, 2344, 2345, 2346, 2347, 1423, 2356, 2357, 2348,\n     2349, 2358, 2359, 2360, 2339, 2341, 2358, 2351, 2354, 2352,\n     2361, 2362, 2363, 2364, 2353, 2355, 2354, 2354, 2354, 2354,\n     2354, 2354, 2354, 2354, 2354, 2356, 2357, 2365, 2366, 2358,\n     2359, 2360, 2367, 2368, 2358, 2369, 2371, 2372, 2361, 2362,\n     2363, 2364, 2373, 2375, 2378, 2380, 2381, 2382, 2384, 2385,\n     2386, 2387, 2388, 2389, 2390, 2365, 2366, 2393, 2395, 2414,\n     2367, 2368, 2414, 2369, 2371, 2372, 2397, 2397, 2400, 2397,\n     2373, 2375, 2378, 2380, 2381, 2382, 2384, 2385, 2386, 2387,\n\n     2388, 2389, 2390, 2401, 2403, 2393, 2395, 2399, 2399, 2404,\n     2399, 2403, 2405, 2407, 1422, 2405, 2400, 2405, 2408, 2409,\n     2410, 2411, 2412, 2413, 2408, 2415, 2416, 2417, 2418, 1411,\n     2419, 2401, 2403, 2420, 2421, 1387, 2409, 2404, 2422, 2403,\n     2423, 2407, 2397, 2423, 2427, 2423, 2408, 2409, 2410, 2411,\n     2412, 2413, 2408, 2415, 2416, 2417, 2418, 2397, 2419, 2428,\n     2429, 2420, 2421, 2399, 2409, 2426, 2422, 2430, 2426, 2431,\n     2426, 2432, 2427, 2433, 2434, 2437, 2436, 2439, 2399, 2436,\n     2440, 2441, 2442, 2443, 2444, 2445, 2446, 2428, 2429, 2447,\n     2448, 2449, 2451, 2452, 2453, 2430, 2454, 2431, 2456, 2432,\n\n     2457, 2433, 2434, 2437, 2458, 2439, 2459, 2458, 2440, 2441,\n     2442, 2443, 2444, 2445, 2446, 2460, 2462, 2447, 2448, 2449,\n     2451, 2452, 2453, 2463, 2454, 2464, 2456, 2461, 2457, 2465,\n     2461, 2466, 2461, 2469, 2459, 2470, 2472, 2474, 2475, 2477,\n     2478, 2479, 2480, 2460, 2462, 2481, 2482, 2483, 2474, 2484,\n     1386, 2463, 2486, 2464, 2487, 2488, 2489, 2465, 2490, 2466,\n     2491, 2469, 2492, 2470, 2472, 2494, 2475, 2477, 2478, 2479,\n     2480, 2495, 2496, 2481, 2482, 2483, 2498, 2484, 2474, 2499,\n     2486, 2500, 2487, 2488, 2489, 2502, 2490, 2503, 2491, 2504,\n     2492, 2505, 2506, 2494, 2507, 2508, 2509, 2510, 2511, 2495,\n\n     2496, 2512, 2515, 2516, 2498, 2517, 2519, 2499, 2520, 2500,\n     2521, 2525, 2526, 2502, 2530, 2503, 2532, 2504, 2533, 2505,\n     2506, 2534, 2507, 2508, 2509, 2510, 2511, 2535, 2536, 2512,\n     2515, 2516, 2546, 2517, 2519, 2537, 2520, 2538, 2521, 2525,\n     2526, 2539, 2540, 2541, 2543, 2548, 2549, 2550, 2552, 2534,\n     1382, 2553, 2554, 2555, 2556, 2535, 2536, 2558, 2559, 2560,\n     2530, 2562, 2532, 2537, 2533, 2538, 2563, 2564, 2565, 2539,\n     2540, 2541, 2543, 2566, 2567, 2550, 2552, 2568, 2546, 2553,\n     2554, 2555, 2556, 2569, 2570, 2558, 2559, 2560, 2571, 2562,\n     2572, 2548, 2549, 2573, 2563, 2564, 2565, 2574, 2575, 2576,\n\n     2577, 2566, 2567, 2578, 2579, 2568, 2580, 2581, 2582, 2583,\n     2584, 2569, 2570, 2586, 2588, 2589, 2571, 2590, 2572, 2591,\n     2592, 2573, 2593, 2594, 2595, 2574, 2575, 2576, 2577, 1381,\n     3656, 2578, 2579, 2602, 2580, 2581, 2582, 2583, 2584, 2603,\n     2604, 2586, 2588, 2589, 2605, 2590, 2609, 2591, 2592, 2609,\n     2593, 2594, 2595, 2597, 2597, 2610, 2597, 2600, 2600, 2606,\n     2600, 2602, 2606, 2611, 2606, 2612, 2613, 2603, 2604, 2614,\n     2615, 2616, 2605, 2617, 2618, 2619, 2620, 2621, 2619, 2623,\n     2619, 3656, 2624, 2610, 2625, 2629, 2626, 2627, 2629, 2632,\n     2629, 2611, 2633, 2612, 2613, 2634, 1380, 2614, 2615, 2616,\n\n     1379, 2617, 2618, 2635, 2620, 2621, 2636, 2623, 2637, 2597,\n     2624, 2641, 2625, 2600, 2626, 2627, 2639, 2632, 2639, 2640,\n     2633, 2643, 2640, 2634, 2597, 2644, 2645, 2646, 2600, 2647,\n     2649, 2635, 2650, 2651, 2636, 2652, 2637, 2653, 2652, 2641,\n     2654, 2655, 2656, 2657, 2639, 2659, 2639, 2660, 2663, 2643,\n     2662, 2662, 1378, 2644, 2645, 2646, 2653, 2647, 2649, 2661,\n     2650, 2651, 2661, 2667, 2661, 2653, 2669, 2670, 2654, 2655,\n     2656, 2657, 2671, 2659, 2672, 2660, 2663, 2665, 2662, 2662,\n     2665, 2673, 2665, 2674, 2653, 2675, 2676, 2678, 2679, 2680,\n     2681, 2667, 2682, 2683, 2669, 2670, 2684, 2685, 2686, 2687,\n\n     2671, 2688, 2672, 2689, 2690, 2691, 2692, 2693, 2694, 2673,\n     2697, 2674, 2698, 2675, 2676, 2678, 2679, 2680, 2681, 2699,\n     2682, 2683, 2700, 2701, 2684, 2685, 2686, 2687, 2702, 2688,\n     2703, 2689, 2690, 2691, 2692, 2693, 2694, 2704, 2697, 2705,\n     2698, 2707, 2708, 2709, 2710, 2711, 2712, 2699, 2714, 2715,\n     2700, 2701, 2716, 2718, 2719, 2720, 2702, 2721, 2703, 2722,\n     2723, 2724, 2725, 2727, 2728, 2704, 2729, 2705, 2730, 2707,\n     2708, 2709, 2710, 2711, 2712, 2731, 2714, 2715, 2732, 2735,\n     2716, 2718, 2719, 2720, 2733, 2721, 2736, 2722, 2723, 2737,\n     2738, 2727, 2728, 2739, 2729, 2741, 2730, 1376, 2742, 2743,\n\n     2744, 2745, 2746, 2731, 1342, 2747, 2732, 2724, 2725, 2748,\n     2749, 2750, 2733, 2751, 2752, 2753, 2754, 2737, 2738, 2755,\n     2756, 2739, 2757, 2741, 2759, 2735, 2742, 2743, 2744, 2745,\n     2746, 2760, 2736, 2747, 2761, 2762, 2763, 2748, 2749, 2750,\n     2764, 2751, 2752, 2753, 2754, 2765, 2766, 2755, 2756, 2767,\n     2757, 2768, 2759, 2769, 2770, 2771, 2773, 2774, 2775, 2760,\n     2776, 2777, 2761, 2762, 2763, 2778, 2780, 2781, 2764, 2784,\n     2786, 2787, 2784, 2765, 2766, 2788, 2789, 2767, 2790, 2768,\n     2791, 2769, 2770, 2771, 2773, 2774, 2775, 2792, 2776, 2777,\n     2793, 2794, 2798, 2778, 2780, 2781, 2799, 2795, 2786, 2787,\n\n     2795, 2800, 2795, 2788, 2789, 2801, 2790, 2802, 2791, 2803,\n     2804, 2807, 2808, 2809, 2810, 2792, 2813, 2810, 2793, 2794,\n     2798, 2814, 2811, 2816, 2799, 2811, 2816, 2817, 2818, 2800,\n     2819, 2820, 2822, 2801, 2821, 2802, 2823, 2803, 2804, 2807,\n     2808, 2809, 2821, 2821, 2813, 2821, 2824, 2821, 2825, 2814,\n     2827, 2828, 2829, 2830, 2826, 2817, 2818, 2826, 2819, 2826,\n     2822, 2831, 2821, 2820, 2823, 2832, 2833, 2834, 2838, 2839,\n     2821, 2821, 2840, 2821, 2824, 2821, 2825, 2844, 2827, 2828,\n     2829, 2830, 2835, 2845, 2847, 2835, 2850, 2835, 2846, 2831,\n     2849, 2820, 2851, 2832, 2833, 2834, 2838, 2839, 2852, 2846,\n\n     2840, 2849, 2853, 2854, 2855, 2844, 2857, 2858, 2861, 2862,\n     2863, 2845, 2847, 2864, 2850, 2865, 2866, 2868, 2869, 2870,\n     2851, 2871, 2861, 2872, 2873, 2874, 2852, 2866, 2875, 2876,\n     2853, 2854, 2855, 2877, 2857, 2858, 2861, 2862, 2863, 2878,\n     2880, 2864, 2881, 2865, 2882, 2868, 2869, 2870, 2883, 2871,\n     2884, 2872, 2873, 2874, 2885, 2886, 2875, 2876, 2887, 2888,\n     2889, 2877, 2890, 2891, 2892, 2893, 2894, 2878, 2880, 2895,\n     2881, 2896, 2882, 2897, 2898, 2899, 2883, 2900, 2884, 2901,\n     2902, 2905, 2885, 2886, 2908, 1338, 2887, 2888, 2889, 2910,\n     2890, 2891, 2892, 2893, 2894, 2904, 2911, 2895, 2912, 2896,\n\n     2913, 2914, 2898, 2899, 2915, 2900, 2916, 2901, 2902, 2917,\n     2919, 2920, 2908, 2904, 2922, 2924, 2926, 2910, 2927, 2897,\n     2928, 2930, 2931, 2904, 2911, 2932, 2912, 2905, 2913, 2914,\n     2933, 2934, 2915, 2935, 2916, 2936, 2937, 2917, 2919, 2920,\n     2938, 2904, 2922, 2924, 2926, 2939, 2927, 2940, 2928, 2930,\n     2931, 2944, 2945, 2932, 2946, 2948, 2949, 2950, 2933, 2934,\n     2951, 2935, 2952, 2936, 2937, 2953, 2954, 2956, 2938, 2958,\n     2959, 2960, 2961, 2939, 2962, 2940, 2964, 2966, 2963, 2944,\n     2945, 2963, 2946, 2948, 2949, 2950, 2967, 2968, 2951, 2969,\n     2952, 2973, 2969, 2953, 2954, 2956, 2974, 2958, 2959, 2960,\n\n     2961, 2975, 2962, 2970, 2964, 2966, 2970, 2977, 2970, 2978,\n     2979, 2980, 2981, 2982, 2967, 2968, 2983, 2984, 2985, 2973,\n     2987, 2985, 2986, 2987, 2974, 2987, 2986, 2983, 2983, 2975,\n     2990, 2991, 2992, 2986, 2994, 2977, 2995, 2978, 2979, 2980,\n     2981, 2982, 2996, 2993, 2983, 2984, 2993, 2997, 2999, 3000,\n     2986, 3001, 3005, 3006, 2986, 2983, 2983, 3008, 2990, 2991,\n     2992, 2986, 2994, 3009, 2995, 3011, 3012, 3013, 3008, 3014,\n     2996, 3015, 3016, 3018, 3019, 2997, 2999, 3000, 3021, 3001,\n     3005, 3006, 3020, 3020, 3022, 3023, 3024, 3025, 3026, 3028,\n     3029, 3009, 3030, 3011, 3012, 3013, 3031, 3014, 3032, 3015,\n\n     3016, 3018, 3019, 3033, 3034, 3035, 3021, 3036, 3037, 3038,\n     3020, 3020, 3022, 3023, 3024, 3025, 3026, 3028, 3029, 3037,\n     3030, 1309, 3040, 3039, 3031, 3042, 3032, 3043, 3044, 3046,\n     3048, 3033, 3034, 3035, 3039, 3036, 1301, 3038, 3049, 3050,\n     3052, 3053, 3054, 3055, 3056, 3058, 3059, 3060, 3061, 3037,\n     3040, 3063, 3064, 3042, 3067, 3043, 3044, 3046, 3048, 3068,\n     3069, 3071, 3073, 3061, 3039, 3075, 3049, 3050, 3052, 3053,\n     3054, 3055, 3056, 3058, 3059, 3060, 3061, 3076, 3077, 3063,\n     3064, 3078, 3067, 3080, 3081, 3082, 3083, 3068, 3069, 3071,\n     3073, 3061, 3084, 3075, 3085, 3086, 3087, 3089, 3090, 3091,\n\n     3092, 3094, 3095, 3096, 3097, 3076, 3077, 3098, 3100, 3078,\n     3101, 3080, 3081, 3082, 3083, 3099, 3102, 3103, 3099, 3105,\n     3084, 3106, 3085, 3086, 3087, 3089, 3090, 3091, 3092, 3094,\n     3095, 3096, 3097, 3107, 3108, 3098, 3100, 3109, 3101, 3112,\n     3116, 1299, 3112, 3116, 3102, 3103, 1294, 3105, 3110, 3106,\n     3111, 3110, 3114, 3117, 3120, 3121, 3117, 3122, 3117, 3124,\n     3125, 3107, 3108, 3126, 3127, 3109, 3110, 3110, 3110, 3110,\n     3110, 3110, 3110, 3110, 3110, 3128, 3129, 3130, 3111, 3131,\n     3114, 3132, 3120, 3121, 3133, 3122, 3142, 3124, 3125, 3142,\n     3231, 3126, 3127, 3231, 3135, 3134, 3136, 3137, 3134, 3139,\n\n     3140, 3141, 3143, 3128, 3129, 3130, 3144, 3131, 3145, 3132,\n     3146, 3148, 3133, 3134, 3134, 3134, 3134, 3134, 3134, 3134,\n     3134, 3134, 3135, 3149, 3136, 3137, 3150, 3139, 3140, 3141,\n     3143, 3152, 3153, 3155, 3144, 3156, 3145, 3157, 3146, 3148,\n     3159, 3160, 3162, 3163, 3164, 3165, 3166, 3167, 3168, 3170,\n     3171, 3149, 3172, 3173, 3150, 3174, 3176, 3177, 3178, 3152,\n     3153, 3155, 3179, 3156, 3181, 3157, 3183, 3186, 3159, 3160,\n     3162, 3163, 3164, 3165, 3166, 3167, 3168, 3170, 3171, 3190,\n     3172, 3173, 3189, 3174, 3176, 3177, 3178, 3192, 3194, 3195,\n     3179, 3196, 3181, 3189, 3183, 3186, 3197, 3198, 3199, 3200,\n\n     3202, 3203, 3204, 3205, 3206, 3208, 3209, 3190, 3210, 3207,\n     3211, 3212, 3213, 3215, 3216, 3192, 3194, 3195, 3217, 3196,\n     3207, 3219, 3220, 3189, 3197, 3198, 3199, 3200, 3202, 3203,\n     3204, 3205, 3206, 3208, 3209, 3221, 3210, 3207, 3211, 3212,\n     3213, 3215, 3216, 3222, 3223, 3224, 3217, 3227, 3207, 3219,\n     3220, 3228, 3229, 3230, 3232, 3233, 3235, 3236, 3237, 3235,\n     3236, 3235, 3238, 3221, 3239, 3240, 3241, 3242, 3243, 3244,\n     1288, 3222, 3223, 3224, 3252, 3227, 1229, 3252, 1228, 3228,\n     3229, 3230, 3232, 3233, 3246, 3248, 3237, 3250, 3251, 3254,\n     3238, 3255, 3239, 3240, 3241, 3242, 3243, 3244, 3245, 3245,\n\n     3245, 3245, 3245, 3245, 3245, 3245, 3245, 3247, 3256, 3257,\n     3247, 3258, 3246, 3248, 3259, 3250, 3251, 3254, 3260, 3255,\n     3261, 3252, 3262, 3263, 1227, 3247, 3247, 3247, 3247, 3247,\n     3247, 3247, 3247, 3247, 3266, 3265, 3256, 3257, 3265, 3258,\n     3267, 3269, 3259, 3270, 3271, 3274, 3260, 3275, 3261, 3252,\n     3262, 3263, 3264, 3264, 3264, 3264, 3264, 3264, 3264, 3264,\n     3264, 3273, 3266, 3276, 3273, 3278, 3280, 3277, 3267, 3269,\n     3277, 3270, 3271, 3274, 3279, 3275, 3281, 3279, 3282, 3283,\n     3285, 3284, 3286, 3287, 3288, 3289, 3291, 3292, 3293, 3294,\n     3295, 3276, 3284, 3278, 3280, 3299, 3300, 3301, 3302, 3303,\n\n     3306, 3307, 3308, 1226, 3281, 3311, 3282, 3283, 3285, 3313,\n     3286, 3287, 3288, 3289, 3291, 3292, 3293, 3294, 3295, 3314,\n     3315, 3316, 3317, 3299, 3300, 3301, 3302, 3303, 3306, 3307,\n     3308, 3309, 3318, 3311, 3319, 3320, 3322, 3313, 3323, 3309,\n     3324, 3325, 3326, 3327, 3328, 3329, 3330, 3314, 3315, 3316,\n     3317, 3331, 3332, 3333, 3336, 3338, 3340, 3341, 3342, 3309,\n     3318, 3343, 3319, 3320, 3322, 3344, 3323, 3309, 3324, 3325,\n     3326, 3327, 3328, 3329, 3330, 3346, 3349, 1225, 1224, 3331,\n     3332, 3333, 3336, 3338, 3340, 3341, 3342, 3347, 3348, 3343,\n     3347, 3348, 3352, 3344, 1220, 3352, 3380, 3352, 3381, 3380,\n\n     1219, 3381, 1218, 3346, 3349, 3347, 3347, 3347, 3347, 3347,\n     3347, 3347, 3347, 3347, 3350, 3350, 3350, 3350, 3350, 3350,\n     3350, 3350, 3350, 3350, 3350, 3351, 3351, 3351, 3351, 3351,\n     3351, 3351, 3351, 3351, 3351, 3351, 3353, 3354, 3355, 3350,\n     3356, 3357, 3358, 3359, 3360, 3361, 3363, 3365, 3366, 3368,\n     3351, 3362, 3362, 3362, 3362, 3362, 3362, 3362, 3362, 3362,\n     3367, 3370, 3371, 3367, 3353, 3354, 3355, 3372, 3356, 3357,\n     3358, 3359, 3360, 3361, 3363, 3365, 3366, 3368, 3367, 3367,\n     3367, 3367, 3367, 3367, 3367, 3367, 3367, 3373, 3374, 3370,\n     3371, 3375, 3376, 3377, 3378, 3372, 3382, 3383, 3384, 3382,\n\n     3385, 3386, 3387, 3385, 3388, 3389, 3390, 3393, 3389, 3390,\n     3395, 3397, 3399, 3400, 3453, 3373, 3374, 3453, 1204, 3375,\n     3376, 3377, 3378, 3399, 3391, 3383, 3384, 3391, 3402, 3386,\n     3387, 3403, 3388, 3404, 3406, 3393, 3407, 1202, 3395, 3397,\n     3405, 3400, 3391, 3391, 3391, 3391, 3391, 3391, 3391, 3391,\n     3391, 3405, 3409, 3410, 3411, 3412, 3402, 3408, 3413, 3403,\n     3414, 3404, 3406, 3415, 3407, 3408, 3408, 3416, 3417, 3418,\n     3419, 3420, 3421, 3422, 3423, 3425, 3426, 3427, 3428, 3429,\n     3409, 3410, 3411, 3412, 3431, 3408, 3413, 3430, 3414, 3430,\n     3432, 3415, 3433, 3408, 3408, 3416, 3417, 3418, 3419, 3420,\n\n     3421, 3422, 3423, 3425, 3426, 3427, 3428, 3429, 3434, 3436,\n     3437, 3438, 3431, 3439, 3440, 3442, 3444, 3448, 3432, 3450,\n     3433, 3451, 3451, 3451, 3451, 3451, 3451, 3451, 3451, 3451,\n     3452, 3482, 1197, 3452, 3482, 3452, 3434, 3436, 3437, 3438,\n     3454, 3439, 3440, 3442, 3444, 3448, 1169, 3450, 3452, 3452,\n     3452, 3452, 3452, 3452, 3452, 3452, 3452, 3456, 3458, 3430,\n     3456, 3459, 3456, 3460, 3461, 3454, 3454, 3454, 3454, 3454,\n     3454, 3454, 3454, 3454, 3454, 3454, 3462, 3463, 3464, 3466,\n     3467, 3471, 3472, 3473, 3474, 3475, 3458, 3477, 3478, 3459,\n     3454, 3460, 3461, 3470, 3470, 3470, 3470, 3470, 3470, 3470,\n\n     3470, 3470, 3479, 3480, 3462, 3463, 3464, 3466, 3467, 3471,\n     3472, 3473, 3474, 3475, 3476, 3477, 3478, 3476, 3483, 3484,\n     3485, 3483, 3484, 3483, 3484, 3486, 3488, 3489, 3490, 3487,\n     3479, 3480, 3487, 3492, 3487, 1164, 3492, 1153, 3495, 3493,\n     3499, 3501, 3493, 3502, 3476, 1141, 3544, 3553, 3485, 3544,\n     3553, 1139, 1137, 3486, 3488, 3489, 3490, 3493, 3493, 3493,\n     3493, 3493, 3493, 3493, 3493, 3493, 3495, 3503, 3499, 3501,\n     3505, 3502, 3476, 3494, 3494, 3494, 3494, 3494, 3494, 3494,\n     3494, 3494, 3500, 3506, 3507, 3508, 3509, 3510, 3500, 3511,\n     3513, 3516, 3518, 3519, 3520, 3503, 3521, 3522, 3505, 3525,\n\n     3526, 3528, 3529, 3557, 3571, 3633, 3557, 3571, 3633, 3571,\n     3500, 3506, 3507, 3508, 3509, 3510, 3500, 3511, 3513, 3516,\n     3518, 3519, 3520, 3531, 3521, 3522, 3532, 3525, 3526, 3528,\n     3529, 3530, 3530, 3530, 3530, 3530, 3530, 3530, 3530, 3530,\n     3530, 3530, 3533, 3534, 3537, 3538, 3539, 3540, 3542, 3543,\n     3574, 3531, 1136, 3574, 3532, 3574, 3530, 3545, 3545, 3545,\n     3545, 3545, 3545, 3545, 3545, 3545, 3550, 3551, 3552, 3554,\n     3533, 3534, 3537, 3538, 3539, 3540, 3542, 3543, 3546, 3546,\n     3546, 3546, 3546, 3546, 3546, 3546, 3546, 3547, 3555, 3556,\n     3547, 3558, 3559, 3560, 3550, 3551, 3552, 3554, 3562, 3563,\n\n     3565, 3566, 3567, 3569, 3576, 3547, 3547, 3547, 3547, 3547,\n     3547, 3547, 3547, 3547, 3577, 3564, 3555, 3556, 3564, 3558,\n     3559, 3560, 3568, 3579, 1122, 3568, 3562, 3563, 3565, 3566,\n     3567, 3569, 3576, 3564, 3564, 3564, 3564, 3564, 3564, 3564,\n     3564, 3564, 3577, 3580, 3581, 3582, 3586, 3587, 3588, 3589,\n     3591, 3579, 3568, 3593, 3594, 3595, 3596, 3597, 3598, 3599,\n     3582, 3582, 3582, 3582, 3582, 3582, 3582, 3582, 3582, 1121,\n     3583, 3580, 3581, 3583, 3586, 3587, 3588, 3589, 3591, 3600,\n     3568, 3593, 3594, 3595, 3596, 3597, 3598, 3599, 3583, 3583,\n     3583, 3583, 3583, 3583, 3583, 3583, 3583, 3584, 3584, 3584,\n\n     3584, 3584, 3584, 3584, 3584, 3584, 3601, 3600, 3602, 3603,\n     3604, 3605, 3606, 3607, 3610, 3614, 1117, 3616, 3618, 3615,\n     3615, 3615, 3615, 3615, 3615, 3615, 3615, 3615, 3615, 3615,\n     3619, 3622, 3624, 3625, 3601, 3632, 3602, 3603, 3604, 3605,\n     3606, 3607, 3610, 3614, 3615, 3616, 3618, 3658, 3628, 3729,\n     3628, 3628, 3629, 3628, 3636, 3634, 1116, 3636, 3619, 3622,\n     3624, 3625, 3628, 3632, 3638, 3629, 3629, 3629, 3629, 3629,\n     3629, 3629, 3629, 3629, 3630, 3630, 3630, 3630, 3630, 3630,\n     3630, 3630, 3630, 3634, 3635, 3639, 3640, 3635, 3639, 3641,\n     3639, 3642, 3638, 3643, 3644, 1115, 3704, 1114, 3658, 3704,\n\n     3729, 3704, 3635, 3635, 3635, 3635, 3635, 3635, 3635, 3635,\n     3635, 3646, 3647, 3650, 3640, 3651, 3654, 3641, 3659, 3642,\n     3660, 3643, 3644, 3645, 3645, 3645, 3645, 3645, 3645, 3645,\n     3645, 3645, 3649, 3628, 3655, 3649, 3661, 3663, 3655, 3646,\n     3647, 3650, 3664, 3651, 3654, 3655, 3659, 1113, 3660, 1073,\n     3649, 3649, 3649, 3649, 3649, 3649, 3649, 3649, 3649, 3662,\n     3665, 3666, 3655, 3668, 3661, 3663, 3655, 3669, 3670, 3671,\n     3664, 3672, 3673, 3655, 3662, 3662, 3662, 3662, 3662, 3662,\n     3662, 3662, 3662, 3674, 3675, 3676, 3677, 3678, 3665, 3666,\n     3679, 3668, 3680, 3681, 3683, 3669, 3670, 3671, 3689, 3672,\n\n     3673, 3679, 3692, 3680, 3694, 3696, 3779, 3703, 1018, 3779,\n     1017, 3674, 3675, 3676, 3677, 3678, 3705, 3712, 3713, 3714,\n     3707, 3681, 3683, 3707, 3710, 3707, 3689, 3710, 3780, 3710,\n     3692, 3780, 3694, 3696, 3697, 3703, 3697, 3697, 3698, 3697,\n     3698, 3698, 3715, 3698, 3705, 3712, 3713, 3714, 3697, 3716,\n     3717, 3718, 3698, 3706, 3706, 3706, 3706, 3706, 3706, 3706,\n     3706, 3706, 3720, 3721, 3724, 3725, 3726, 3727, 3731, 3732,\n     3715, 3733, 3734, 3735, 3736, 3737, 3738, 3716, 3717, 3718,\n     3719, 3719, 3719, 3719, 3719, 3719, 3719, 3719, 3719, 3739,\n     3720, 3721, 3724, 3725, 3726, 3727, 3731, 3732, 3740, 3733,\n\n     3734, 3735, 3736, 3737, 3738, 3742, 3743, 3744, 3745, 3747,\n     3748, 3751, 3756, 3752, 3758, 3762, 3759, 3739, 3744, 3697,\n     3767, 3770, 3771, 3698, 3752, 3763, 3740, 3759, 3763, 3772,\n     3763, 3773, 3774, 3742, 3743, 3775, 3745, 3747, 3748, 3751,\n     3756, 3776, 3758, 3762, 3759, 3777, 3781, 3782, 3778, 3770,\n     3771, 3778, 3783, 3784, 3785, 3759, 3787, 3772, 3788, 3773,\n     3774, 3789, 3791, 3775, 3792, 3793, 3794, 3795, 3810, 3776,\n     3797, 3767, 3798, 3777, 3781, 3782, 3802, 3803, 3804, 3805,\n     3807, 3784, 3785, 3812, 3787, 3814, 3788, 3815, 3817, 3789,\n     3791,  997, 3792, 3793, 3794, 3795, 3778, 3818, 3797, 3819,\n\n     3798, 3820, 3821, 3783, 3802, 3803, 3804, 3805, 3807, 3822,\n     3823, 3826, 3822, 3814, 3826, 3815, 3817, 3824, 3825, 3810,\n     3824, 3825, 3824, 3825, 3778, 3818, 3828, 3819, 3827, 3820,\n     3821, 3827, 3829, 3831, 3812, 3832, 3833, 3836, 3823, 3837,\n     3838, 3839, 3840, 3841, 3844, 3845, 3848, 3850, 3845, 3851,\n     3852, 3853, 3855, 3856, 3828, 3858, 3859,  984, 3858,  973,\n     3829, 3831, 3882, 3832, 3833, 3836,  953, 3837, 3838, 3839,\n     3840, 3841, 3844, 3867, 3869, 3850, 3870, 3851, 3852, 3853,\n     3855, 3856, 3860, 3862, 3859, 3860, 3862, 3860, 3862, 3864,\n     3865, 3871, 3864, 3865, 3864, 3865, 3873, 3848, 3874, 3875,\n\n     3876, 3867, 3869, 3877, 3870, 3881, 3878, 3883, 3881, 3884,\n     3881, 3885, 3884, 3882, 3886, 3887, 3889, 3878, 3887, 3871,\n     3878,  934, 3897,  909, 3873, 3898, 3874, 3875, 3876, 3899,\n     3900, 3877, 3901, 3892, 3878, 3883, 3892, 3902, 3892, 3885,\n     3903, 3904, 3886, 3905, 3889, 3878, 3894, 3906, 3878, 3894,\n     3897, 3894, 3907, 3898, 3913, 3916, 3911, 3899, 3900, 3911,\n     3901, 3911,  897, 3915,  886, 3902, 3915, 3914, 3903, 3904,\n     3914, 3905,  884,  882,  878, 3906, 3917, 3918, 3923, 3917,\n     3907, 3924, 3913, 3916, 3925, 3914, 3914, 3914, 3914, 3914,\n     3914, 3914, 3914, 3914, 3917, 3917, 3917, 3917, 3917, 3917,\n\n     3917, 3917, 3917, 3928, 3930, 3918, 3923, 3931, 3932, 3924,\n     3933, 3941, 3925, 3937, 3937, 3937, 3937, 3937, 3937, 3937,\n     3937, 3937, 3938, 3939,  834, 3938, 3939,  823,  813,  809,\n     3944, 3928, 3930, 3945, 3946, 3931, 3932, 3949, 3933, 3941,\n     3938, 3938, 3938, 3938, 3938, 3938, 3938, 3938, 3938, 3940,\n     3940, 3940, 3940, 3940, 3940, 3940, 3940, 3940, 3944, 3950,\n     3954, 3945, 3946, 3954, 3958, 3949, 3953, 3953, 3953, 3953,\n     3953, 3953, 3953, 3953, 3953, 3961, 3963, 3964, 3954, 3954,\n     3954, 3954, 3954, 3954, 3954, 3954, 3954, 3950, 3965, 3966,\n     3968, 3969, 3958, 3962, 3962, 3962, 3962, 3962, 3962, 3962,\n\n     3962, 3962, 3970, 3961, 3963, 3964,  777,  776,  774,  773,\n      772,  770,  765,  764,  762,  761, 3965, 3966, 3968, 3969,\n      760,  754,  747,  736,  735,  716,  703,  692,  680,  679,\n     3970, 3973, 3973, 3973, 3973, 3973, 3973, 3973, 3973, 3973,\n     3973, 3973, 3973, 3973, 3973, 3973, 3973, 3973, 3973, 3973,\n     3974, 3974, 3974, 3974, 3974, 3974, 3974, 3974, 3974, 3974,\n     3974, 3974, 3974, 3974, 3974, 3974, 3974, 3974, 3974, 3975,\n     3975, 3975, 3975, 3975, 3975, 3975, 3975, 3975, 3975, 3975,\n     3975, 3975, 3975, 3975, 3975, 3975, 3975, 3975, 3976, 3976,\n     3976, 3976, 3976, 3976, 3976, 3976, 3976, 3976, 3976, 3976,\n\n     3976, 3976, 3976, 3976, 3976, 3976, 3976, 3977, 3977, 3977,\n     3977, 3977, 3977, 3977, 3977, 3977, 3977, 3977, 3977, 3977,\n     3977, 3977, 3977, 3977, 3977, 3977, 3978, 3978, 3978, 3978,\n     3978, 3978, 3978, 3978, 3978, 3978, 3978, 3978, 3978, 3978,\n     3978, 3978, 3978, 3978, 3978, 3979, 3979, 3979, 3979, 3979,\n     3979, 3979, 3979, 3979, 3979, 3979, 3979, 3979, 3979, 3979,\n     3979, 3979, 3979, 3979, 3980, 3980, 3980, 3980, 3980, 3980,\n     3980, 3980, 3980, 3980, 3980, 3980, 3980, 3980, 3980, 3980,\n     3980, 3980, 3980, 3981, 3981, 3981, 3981, 3981, 3981, 3981,\n     3981, 3981, 3981, 3981, 3981, 3981, 3981, 3981, 3981, 3981,\n\n     3981, 3981, 3982, 3982, 3982, 3982, 3982, 3982, 3982, 3982,\n     3982, 3982, 3982, 3982, 3982, 3982, 3982, 3982, 3982, 3982,\n     3982, 3983, 3983, 3983, 3983, 3983, 3983, 3983, 3983, 3983,\n     3983, 3983, 3983, 3983, 3983, 3983, 3983, 3983, 3983, 3983,\n     3984, 3984, 3984, 3984, 3984, 3984, 3984, 3984, 3984, 3984,\n     3984, 3984, 3984, 3984, 3984, 3984, 3984, 3984, 3984, 3985,\n     3985, 3985, 3985, 3985, 3985, 3985, 3985, 3985, 3985, 3985,\n     3985, 3985, 3985, 3985, 3985, 3985, 3985, 3985, 3986, 3986,\n     3986, 3986, 3986, 3986, 3986, 3986, 3986, 3986, 3986, 3986,\n     3986, 3986, 3986, 3986, 3986, 3986, 3986, 3987, 3987, 3987,\n\n     3987, 3987, 3987, 3987, 3987, 3987, 3987, 3987, 3987, 3987,\n     3987, 3987, 3987, 3987, 3987, 3987, 3988, 3988, 3988, 3988,\n     3988, 3988, 3988, 3988, 3988, 3988, 3988, 3988, 3988, 3988,\n     3988, 3988, 3988, 3988, 3988, 3989, 3989, 3989, 3989, 3989,\n     3989, 3989, 3989, 3989, 3989, 3989, 3989, 3989, 3989, 3989,\n     3989, 3989, 3989, 3989, 3990, 3990, 3990, 3990, 3990, 3990,\n     3990, 3990, 3990, 3990, 3990, 3990, 3990, 3990, 3990, 3990,\n     3990, 3990, 3990, 3991, 3991, 3991, 3991, 3991, 3991, 3991,\n     3991, 3991, 3991, 3991, 3991, 3991, 3991, 3991, 3991, 3991,\n     3991, 3991, 3992, 3992, 3992, 3992, 3992, 3992, 3992, 3992,\n\n     3992, 3992, 3992, 3992, 3992, 3992, 3992, 3992, 3992, 3992,\n     3992, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993,\n     3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993, 3993,\n     3994, 3994, 3994, 3994, 3994, 3994, 3994, 3994, 3994, 3994,\n     3994, 3994, 3994, 3994, 3994, 3994, 3994, 3994, 3994, 3995,\n     3995, 3995, 3995, 3995, 3995, 3995, 3995, 3995, 3995, 3995,\n     3995, 3995, 3995, 3995, 3995, 3995, 3995, 3995, 3996, 3996,\n      674, 3996, 3996, 3996, 3996, 3996, 3996, 3996, 3996, 3996,\n     3996, 3996, 3996, 3996, 3996, 3996, 3996, 3997, 3997, 3997,\n     3997, 3997, 3997, 3997, 3997, 3997, 3997, 3997, 3997, 3997,\n\n     3997, 3997, 3997, 3997, 3997, 3997, 3998, 3998, 3998, 3998,\n     3998, 3998, 3998, 3998, 3998, 3998, 3998, 3998, 3998, 3998,\n     3998, 3998, 3998, 3998, 3998, 3999, 3999, 3999, 3999, 3999,\n     3999, 3999, 3999, 3999, 3999, 3999, 3999, 3999, 3999, 3999,\n     3999, 3999, 3999, 3999, 4000, 4000, 4000, 4000, 4000, 4000,\n     4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000, 4000,\n     4000, 4000, 4000, 4001, 4001, 4001, 4001, 4001, 4001, 4001,\n     4001, 4001, 4001, 4001, 4001, 4001, 4001, 4001, 4001, 4001,\n     4001, 4001, 4002, 4002, 4002, 4002, 4002, 4002, 4002, 4002,\n     4002, 4002, 4002, 4002, 4002, 4002, 4002, 4002, 4002, 4002,\n\n     4002, 4003, 4003, 4003, 4003, 4003, 4003, 4003, 4003, 4003,\n     4003, 4003, 4003, 4003, 4003, 4003, 4003, 4003, 4003, 4003,\n     4004, 4004, 4004, 4004, 4004, 4004, 4004, 4004, 4004, 4004,\n     4004, 4004, 4004, 4004, 4004, 4004, 4004, 4004, 4004, 4005,\n     4005, 4005, 4005, 4005, 4005, 4005, 4005, 4005, 4005, 4005,\n     4005, 4005, 4005, 4005, 4005, 4005, 4005, 4005, 4006, 4006,\n     4006, 4006, 4006, 4006, 4006, 4006, 4006, 4006, 4006, 4006,\n     4006, 4006, 4006, 4006, 4006, 4006, 4006, 4007, 4007, 4007,\n     4007, 4007, 4007, 4007, 4007, 4007, 4007, 4007, 4007, 4007,\n     4007, 4007, 4007, 4007, 4007, 4007, 4008, 4008, 4008, 4008,\n\n     4008, 4008, 4008, 4008, 4008, 4008, 4008, 4008, 4008, 4008,\n     4008, 4008, 4008, 4008, 4008, 4009, 4009, 4009, 4009, 4009,\n     4009, 4009, 4009, 4009, 4009, 4009, 4009, 4009, 4009, 4009,\n     4009, 4009, 4009, 4009, 4010, 4010, 4010, 4010, 4010, 4010,\n     4010, 4010, 4010, 4010, 4010, 4010, 4010, 4010, 4010, 4010,\n     4010, 4010, 4010, 4011, 4011, 4011, 4011, 4011, 4011, 4011,\n     4011, 4011, 4011, 4011, 4011, 4011, 4011, 4011, 4011, 4011,\n     4011, 4011, 4012, 4012, 4012, 4012, 4012, 4012, 4012, 4012,\n     4012, 4012, 4012, 4012, 4012, 4012, 4012, 4012, 4012, 4012,\n     4012, 4013, 4013, 4013, 4013, 4013, 4013, 4013, 4013, 4013,\n\n     4013, 4013, 4013, 4013, 4013, 4013, 4013, 4013, 4013, 4013,\n     4014, 4014,  673, 4014, 4014, 4014, 4014, 4014, 4014, 4014,\n     4014, 4014, 4014, 4014, 4014, 4014, 4014, 4014, 4014, 4015,\n     4015,  671, 4015, 4015, 4015, 4015, 4015, 4015, 4015, 4015,\n     4015, 4015, 4015, 4015, 4015, 4015, 4015, 4015, 4016, 4016,\n      664, 4016, 4016, 4016, 4016, 4016, 4016, 4016, 4016, 4016,\n     4016, 4016, 4016, 4016, 4016, 4016, 4016, 4017, 4017, 4017,\n     4017, 4017, 4017, 4017, 4017, 4017, 4017, 4017, 4017, 4017,\n     4017, 4017, 4017, 4017, 4017, 4017, 4018, 4018, 4018, 4018,\n     4018, 4018, 4018, 4018, 4018, 4018, 4018, 4018, 4018, 4018,\n\n     4018, 4018, 4018, 4018, 4018, 4019, 4019, 4019, 4019, 4019,\n     4019, 4019, 4019, 4019, 4019, 4019, 4019, 4019, 4019, 4019,\n     4019, 4019, 4019, 4019, 4020, 4020, 4020, 4020, 4020, 4020,\n     4020, 4020, 4020, 4020, 4020, 4020, 4020, 4020, 4020, 4020,\n     4020, 4020, 4020, 4021, 4021,  654, 4021, 4021, 4021, 4021,\n     4021, 4021, 4021, 4021, 4021, 4021, 4021, 4021, 4021, 4021,\n     4021, 4021, 4022, 4022, 4022, 4022, 4022, 4022, 4022, 4022,\n     4022, 4022, 4022, 4022, 4022, 4022, 4022, 4022, 4022, 4022,\n     4022, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023,\n     4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023,\n\n     4024, 4024, 4024, 4024, 4024, 4024, 4024, 4024, 4024, 4024,\n     4024, 4024, 4024, 4024, 4024, 4024, 4024,  653, 4024, 4025,\n     4025, 4025, 4025, 4025, 4025, 4025, 4025, 4025, 4025, 4025,\n     4025, 4025, 4025, 4025, 4025, 4025, 4025, 4025, 4026, 4026,\n     4026, 4026, 4026, 4026, 4026, 4026, 4026, 4026, 4026, 4026,\n     4026, 4026, 4026, 4026, 4026,  651, 4026, 4027, 4027, 4027,\n     4027, 4027, 4027, 4027, 4027, 4027, 4027, 4027, 4027, 4027,\n     4027, 4027, 4027, 4027, 4027, 4027, 4028, 4028, 4028, 4028,\n     4028, 4028, 4028, 4028, 4028, 4028, 4028, 4028, 4028, 4028,\n     4028, 4028, 4028, 4028, 4028, 4029, 4029, 4029, 4029, 4029,\n\n     4029, 4029, 4029, 4029, 4029, 4029, 4029, 4029, 4029, 4029,\n     4029, 4029, 4029, 4029, 4030, 4030, 4030, 4030, 4030, 4030,\n     4030, 4030, 4030, 4030, 4030, 4030, 4030, 4030, 4030, 4030,\n     4030, 4030, 4030, 4031,  647, 4031, 4031,  637,  636, 4031,\n     4031, 4031, 4031, 4031, 4031,  634, 4031, 4031, 4031, 4031,\n     4031, 4032, 4032, 4032, 4032, 4032, 4032, 4032, 4032, 4032,\n     4032, 4032, 4032, 4032, 4032, 4032, 4032, 4032, 4032, 4032,\n     4033, 4033, 4033, 4033, 4033, 4033, 4033, 4033, 4033, 4033,\n     4033, 4033, 4033, 4033, 4033, 4033, 4033,  631, 4033, 4034,\n     4034, 4034, 4034, 4034, 4034, 4034, 4034, 4034, 4034, 4034,\n\n     4034, 4034, 4034, 4034, 4034, 4034, 4034, 4034, 4035, 4035,\n     4035, 4035, 4035, 4035, 4035, 4035, 4035, 4035, 4035, 4035,\n     4035, 4035, 4035, 4035, 4035, 4035, 4035, 4036, 4036, 4036,\n     4036, 4036, 4036, 4036, 4036, 4036, 4036, 4036, 4036, 4036,\n     4036, 4036, 4036, 4036, 4036, 4036, 4037,  630, 4037, 4037,\n      628,  625, 4037, 4037, 4037, 4037, 4037, 4037,  624, 4037,\n     4037, 4037, 4037, 4037, 4038, 4038, 4038, 4038, 4038, 4038,\n     4038, 4038, 4038, 4038, 4038, 4038, 4038, 4038, 4038, 4038,\n     4038, 4038, 4038, 4039, 4039, 4039, 4039, 4039, 4039, 4039,\n     4039, 4039, 4039, 4039, 4039, 4039, 4039, 4039, 4039, 4039,\n\n      574, 4039, 4040, 4040, 4040, 4040, 4040, 4040, 4040, 4040,\n     4040, 4040, 4040, 4040, 4040, 4040, 4040, 4040, 4040, 4040,\n     4040, 4041, 4041, 4041, 4041, 4041, 4041, 4041, 4041, 4041,\n     4041, 4041, 4041, 4041, 4041, 4041, 4041, 4041, 4041, 4041,\n     4042, 4042, 4042, 4042, 4042, 4042, 4042, 4042, 4042, 4042,\n     4042, 4042, 4042, 4042, 4042, 4042, 4042, 4042, 4042, 4043,\n     4043, 4043, 4043, 4043, 4043, 4043, 4043, 4043, 4043, 4043,\n     4043, 4043, 4043, 4043, 4043, 4043,  542, 4043, 4044, 4044,\n      538, 4044, 4044, 4044, 4044, 4044, 4044, 4044, 4044, 4044,\n     4044, 4044, 4044, 4044, 4044, 4044, 4044, 4045, 4045,  537,\n\n     4045, 4045, 4045, 4045, 4045, 4045, 4045, 4045, 4045, 4045,\n     4045, 4045, 4045, 4045, 4045, 4045, 4046, 4046,  531, 4046,\n     4046, 4046, 4046, 4046, 4046, 4046, 4046, 4046, 4046, 4046,\n     4046, 4046, 4046, 4046, 4046, 4047, 4047, 4047, 4047, 4047,\n     4047, 4047, 4047, 4047, 4047, 4047, 4047, 4047, 4047, 4047,\n     4047, 4047, 4047, 4047, 4048, 4048, 4048, 4048, 4048, 4048,\n     4048, 4048, 4048, 4048, 4048, 4048, 4048, 4048, 4048, 4048,\n     4048,  530, 4048, 4049, 4049, 4049, 4049, 4049, 4049, 4049,\n     4049, 4049, 4049, 4049, 4049, 4049, 4049, 4049, 4049, 4049,\n     4049, 4049, 4050, 4050, 4050, 4050, 4050, 4050, 4050, 4050,\n\n     4050, 4050, 4050, 4050, 4050, 4050, 4050, 4050, 4050,  514,\n     4050, 4051, 4051,  513, 4051, 4051, 4051, 4051, 4051, 4051,\n     4051, 4051, 4051, 4051, 4051, 4051, 4051, 4051, 4051, 4051,\n     4052, 4052, 4052, 4052, 4052, 4052, 4052, 4052, 4052, 4052,\n     4052, 4052, 4052, 4052, 4052, 4052, 4052, 4052, 4052, 4053,\n     4053, 4053, 4053, 4053, 4053, 4053, 4053, 4053, 4053, 4053,\n     4053, 4053, 4053, 4053, 4053, 4053, 4053, 4053, 4054, 4054,\n     4054, 4054, 4054, 4054, 4054, 4054, 4054, 4054, 4054, 4054,\n     4054, 4054, 4054, 4054, 4054, 4054, 4054, 4055, 4055, 4055,\n     4055, 4055, 4055, 4055, 4055, 4055, 4055, 4055, 4055, 4055,\n\n     4055, 4055, 4055, 4055, 4055, 4055, 4056, 4056, 4056, 4056,\n     4056, 4056, 4056, 4056, 4056, 4056, 4056, 4056, 4056, 4056,\n     4056, 4056, 4056, 4056, 4056, 4057, 4057, 4057, 4057, 4057,\n     4057, 4057, 4057, 4057, 4057, 4057, 4057, 4057, 4057, 4057,\n     4057, 4057, 4057, 4057, 4058,  507, 4058, 4058,  505,  491,\n     4058, 4058, 4058, 4058, 4058, 4058,  479, 4058, 4058, 4058,\n     4058, 4058, 4058, 4059,  476, 4059, 4059,  454,  441, 4059,\n     4059, 4059, 4059, 4059, 4059,  435, 4059, 4059, 4059, 4059,\n     4059, 4059, 4060, 4060, 4060, 4060, 4060, 4060, 4060, 4060,\n     4060, 4060, 4060, 4060, 4060, 4060, 4060, 4060, 4060, 4060,\n\n     4060, 4061,  423, 4061, 4061,  414,  413, 4061, 4061, 4061,\n     4061, 4061, 4061,  394, 4061, 4061, 4061, 4061, 4061, 4062,\n     4062, 4062, 4062, 4062, 4062, 4062, 4062, 4062, 4062, 4062,\n     4062, 4062, 4062, 4062, 4062, 4062, 4062, 4062, 4063, 4063,\n     4063, 4063, 4063, 4063, 4063, 4063, 4063, 4063, 4063, 4063,\n     4063, 4063, 4063, 4063, 4063, 4063, 4063, 4064, 4064, 4064,\n     4064, 4064, 4064, 4064, 4064, 4064, 4064, 4064, 4064, 4064,\n     4064, 4064, 4064, 4064, 4064, 4064, 4065, 4065, 4065, 4065,\n     4065, 4065, 4065, 4065, 4065, 4065, 4065, 4065, 4065, 4065,\n     4065, 4065, 4065, 4065, 4065, 4066,  393, 4066, 4066,  386,\n\n      384, 4066, 4066, 4066, 4066, 4066, 4066,  369, 4066, 4066,\n     4066, 4066, 4066, 4066, 4067, 4067, 4067, 4067, 4067, 4067,\n     4067, 4067, 4067, 4067, 4067, 4067, 4067, 4067, 4067, 4067,\n     4067, 4067, 4067, 4068, 4068, 4068, 4068, 4068, 4068, 4068,\n     4068, 4068, 4068, 4068, 4068, 4068, 4068, 4068, 4068, 4068,\n     4068, 4068, 4069,  368, 4069, 4069,  359,  358, 4069, 4069,\n     4069, 4069, 4069, 4069,  348, 4069, 4069, 4069, 4069, 4069,\n     4070, 4070, 4070, 4070, 4070, 4070, 4070, 4070, 4070, 4070,\n     4070, 4070, 4070, 4070, 4070, 4070, 4070, 4070, 4070, 4071,\n     4071, 4071, 4071, 4071, 4071, 4071, 4071, 4071, 4071, 4071,\n\n     4071, 4071, 4071, 4071, 4071, 4071, 4071, 4071, 4072, 4072,\n     4072, 4072, 4072, 4072, 4072, 4072, 4072, 4072, 4072, 4072,\n     4072, 4072, 4072, 4072, 4072, 4072, 4072, 4073, 4073, 4073,\n     4073, 4073, 4073, 4073, 4073, 4073, 4073, 4073, 4073, 4073,\n     4073, 4073, 4073, 4073, 4073, 4073, 4074, 4074, 4074, 4074,\n     4074, 4074, 4074, 4074, 4074, 4074, 4074, 4074, 4074, 4074,\n     4074, 4074, 4074, 4074, 4074, 4075, 4075, 4075, 4075, 4075,\n     4075, 4075, 4075, 4075, 4075, 4075, 4075, 4075, 4075, 4075,\n     4075, 4075, 4075, 4075, 4076, 4076, 4076, 4076, 4076, 4076,\n     4076, 4076, 4076, 4076, 4076, 4076, 4076, 4076, 4076, 4076,\n\n     4076, 4076, 4076, 4077, 4077, 4077, 4077, 4077, 4077, 4077,\n     4077, 4077, 4077, 4077, 4077, 4077, 4077, 4077, 4077, 4077,\n     4077, 4077, 4078, 4078, 4078, 4078, 4078, 4078, 4078, 4078,\n     4078, 4078, 4078, 4078, 4078, 4078, 4078, 4078, 4078, 4078,\n     4078, 4079, 4079, 4079, 4079, 4079, 4079, 4079, 4079, 4079,\n     4079, 4079, 4079, 4079, 4079, 4079, 4079, 4079, 4079, 4079,\n     4080, 4080, 4080, 4080, 4080, 4080, 4080, 4080, 4080, 4080,\n     4080, 4080, 4080, 4080, 4080, 4080, 4080, 4080, 4080, 4081,\n     4081,  318, 4081, 4081, 4081, 4081, 4081, 4081, 4081, 4081,\n     4081, 4081, 4081, 4081, 4081, 4081, 4081, 4081, 4082, 4082,\n\n     4082, 4082, 4082, 4082, 4082, 4082, 4082, 4082, 4082, 4082,\n     4082, 4082, 4082, 4082, 4082, 4082, 4082, 4083, 4083, 4083,\n     4083, 4083, 4083, 4083, 4083, 4083, 4083, 4083, 4083, 4083,\n     4083, 4083, 4083, 4083, 4083, 4083, 4084, 4084, 4084, 4084,\n     4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084, 4084,\n     4084, 4084, 4084, 4084, 4084, 4085, 4085, 4085, 4085, 4085,\n     4085, 4085, 4085, 4085, 4085, 4085, 4085, 4085, 4085, 4085,\n     4085, 4085, 4085, 4085, 4086,  317, 4086, 4086,  284,  268,\n     4086, 4086, 4086, 4086, 4086, 4086,  261, 4086, 4086, 4086,\n     4086, 4086, 4086, 4087,  259, 4087, 4087,  252,  234, 4087,\n\n     4087, 4087, 4087, 4087, 4087,  229, 4087, 4087, 4087, 4087,\n     4087, 4087, 4088,  216, 4088, 4088,  194,  182, 4088, 4088,\n     4088, 4088, 4088, 4088,  175, 4088, 4088, 4088, 4088, 4088,\n     4089, 4089, 4089, 4089, 4089, 4089, 4089, 4089, 4089, 4089,\n     4089, 4089, 4089, 4089, 4089, 4089, 4089, 4089, 4089, 4090,\n      172, 4090, 4090,  165,  164, 4090, 4090, 4090, 4090, 4090,\n     4090,  163, 4090, 4090, 4090, 4090, 4090, 4090, 4091, 4091,\n     4091, 4091, 4091, 4091, 4091, 4091, 4091, 4091, 4091, 4091,\n     4091, 4091, 4091, 4091, 4091, 4091, 4091, 4092,  154, 4092,\n     4092,  152,  146, 4092, 4092, 4092, 4092, 4092, 4092,  141,\n\n     4092, 4092, 4092, 4092, 4092, 4092, 4093, 4093, 4093, 4093,\n     4093, 4093, 4093, 4093, 4093, 4093, 4093, 4093, 4093, 4093,\n     4093, 4093, 4093, 4093, 4093, 4094, 4094, 4094, 4094, 4094,\n     4094, 4094, 4094, 4094, 4094, 4094, 4094, 4094, 4094, 4094,\n     4094, 4094, 4094, 4094, 4095,  117, 4095, 4095,   75,   64,\n     4095, 4095, 4095, 4095, 4095, 4095,   63, 4095, 4095, 4095,\n     4095, 4095, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096,\n     4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096,\n     4096, 4097, 4097, 4097, 4097, 4097, 4097, 4097, 4097, 4097,\n     4097, 4097, 4097, 4097, 4097, 4097, 4097, 4097, 4097, 4097,\n\n     4098, 4098, 4098, 4098, 4098, 4098, 4098, 4098, 4098, 4098,\n     4098, 4098, 4098, 4098, 4098, 4098, 4098, 4098, 4098, 4099,\n     4099, 4099, 4099, 4099, 4099, 4099, 4099, 4099, 4099,   58,\n     4099, 4099, 4099, 4099, 4099, 4099, 4099, 4099, 4100, 4100,\n     4100, 4100, 4100, 4100, 4100, 4100, 4100, 4100, 4100, 4100,\n     4100, 4100, 4100, 4100, 4100, 4100, 4100, 4101, 4101, 4101,\n     4101, 4101, 4101, 4101, 4101, 4101, 4101, 4101, 4101, 4101,\n     4101, 4101, 4101, 4101, 4101, 4101, 4102, 4102, 4102, 4102,\n     4102, 4102, 4102, 4102, 4102, 4102, 4102, 4102, 4102, 4102,\n     4102, 4102, 4102, 4102, 4102, 4103, 4103, 4103, 4103, 4103,\n\n     4103, 4103, 4103, 4103, 4103, 4103, 4103, 4103, 4103, 4103,\n     4103, 4103, 4103, 4103, 4104, 4104,   57, 4104, 4104, 4104,\n     4104, 4104, 4104, 4104, 4104, 4104, 4104, 4104, 4104, 4104,\n     4104, 4104, 4104, 4105, 4105, 4105, 4105, 4105, 4105, 4105,\n     4105, 4105, 4105, 4105, 4105, 4105, 4105, 4105, 4105, 4105,\n     4105, 4105, 4106, 4106, 4106, 4106, 4106, 4106, 4106, 4106,\n     4106, 4106, 4106, 4106, 4106, 4106, 4106, 4106, 4106, 4106,\n     4106, 4107, 4107, 4107, 4107, 4107, 4107, 4107, 4107, 4107,\n     4107, 4107, 4107, 4107, 4107, 4107, 4107, 4107, 4107, 4107,\n     4108,   56, 4108, 4108,   55,   54, 4108, 4108, 4108, 4108,\n\n     4108, 4108,   53, 4108, 4108, 4108, 4108, 4108, 4108, 4109,\n       52, 4109, 4109,   51,   26, 4109, 4109, 4109, 4109, 4109,\n     4109,   25, 4109, 4109, 4109, 4109, 4109, 4109, 4110, 4110,\n     4110, 4110, 4110, 4110, 4110, 4110, 4110, 4110, 4110, 4110,\n     4110, 4110, 4110, 4110, 4110, 4110, 4110, 4111,   24, 4111,\n     4111,   23,    0, 4111, 4111, 4111, 4111, 4111, 4111,    0,\n     4111, 4111, 4111, 4111, 4111, 4111, 4112, 4112, 4112, 4112,\n     4112, 4112, 4112, 4112, 4112, 4112, 4112, 4112, 4112, 4112,\n     4112, 4112, 4112, 4112, 4112, 4113,    0, 4113, 4113,    0,\n        0, 4113, 4113, 4113, 4113, 4113, 4113, 4113, 4113, 4113,\n\n     4113, 4113, 4113, 4114, 4114, 4114, 4114, 4114, 4114, 4114,\n     4114, 4114, 4114, 4114, 4114, 4114, 4114, 4114, 4114, 4114,\n     4114, 4114, 4115, 4115, 4115, 4115, 4115, 4115, 4115, 4115,\n     4115, 4115, 4115, 4115, 4115, 4115, 4115, 4115, 4115, 4115,\n     4115, 4116,    0, 4116, 4116,    0,    0, 4116, 4116, 4116,\n     4116,    0, 4116, 4116, 4116, 4116, 4116, 4116, 4116, 4116,\n     4117, 4117, 4117, 4117, 4117, 4117, 4117,    0, 4117, 4117,\n        0, 4117, 4117, 4117, 4117, 4117, 4117, 4117, 4117, 4118,\n     4118, 4118, 4118, 4118, 4118, 4118, 4118, 4118, 4118, 4118,\n     4118, 4118, 4118, 4118, 4118, 4118, 4118, 4118, 4119, 4119,\n\n     4119, 4119, 4119, 4119, 4119, 4119, 4119, 4119, 4119, 4119,\n     4119, 4119, 4119, 4119, 4119, 4119, 4119, 4120, 4120, 4120,\n     4120, 4120, 4120, 4120, 4120, 4120, 4120, 4120, 4120, 4120,\n     4120, 4120, 4120, 4120, 4120, 4120, 4121, 4121, 4121, 4121,\n     4121, 4121, 4121, 4121, 4121, 4121, 4121, 4121, 4121, 4121,\n     4121, 4121, 4121, 4121, 4121, 4122, 4122,    0, 4122, 4122,\n     4122, 4122, 4122, 4122, 4122, 4122, 4122, 4122, 4122, 4122,\n     4122, 4122, 4122, 4122, 4123, 4123, 4123, 4123, 4123, 4123,\n     4123, 4123, 4123, 4123, 4123, 4123, 4123, 4123, 4123, 4123,\n     4123, 4123, 4123, 4124, 4124, 4124, 4124, 4124, 4124, 4124,\n\n     4124, 4124, 4124, 4124, 4124, 4124, 4124, 4124, 4124, 4124,\n     4124, 4124, 4125,    0,    0,    0, 4125,    0,    0, 4125,\n     4126,    0,    0,    0,    0,    0, 4126, 4126, 4126, 4126,\n        0, 4126, 4126, 4126, 4126, 4126, 4126, 4126, 4126, 4127,\n     4127, 4127, 4127, 4127, 4127, 4127, 4127, 4127, 4127, 4127,\n     4127, 4127, 4127, 4127, 4127, 4127, 4127, 4127, 4128,    0,\n        0, 4128,    0, 4128, 4129, 4129, 4129, 4129, 4129, 4129,\n     4129, 4129, 4129, 4129, 4129, 4129, 4129, 4129, 4129, 4129,\n     4129, 4129, 4129, 4130,    0,    0, 4130, 4130,    0,    0,\n     4130, 4130,    0, 4130,    0, 4130, 4130, 4130, 4130, 4131,\n\n     4131, 4131, 4131, 4132, 4132,    0, 4132, 4132, 4132, 4132,\n     4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132, 4132,\n     4132, 4132, 4133, 4133,    0, 4133, 4133, 4133, 4133, 4133,\n     4133, 4133, 4133, 4133, 4133, 4133, 4133, 4133, 4133, 4133,\n     4133, 4134,    0,    0,    0, 4134, 4134,    0, 4134,    0,\n     4134, 4134, 4134, 4134, 4135, 4135, 4135, 4135, 4135, 4135,\n     4135, 4135, 4135, 4135, 4135, 4135, 4135, 4135, 4135, 4135,\n     4135, 4135, 4135, 4136, 4136, 4136, 4136, 4136, 4136, 4136,\n     4136, 4136, 4136, 4136, 4136, 4136, 4136, 4136, 4136, 4136,\n     4136, 4136, 4137, 4137, 4137, 4137, 4137, 4137, 4137, 4137,\n\n     4137, 4137, 4137, 4137, 4137, 4137, 4137, 4137, 4137, 4137,\n     4137, 4138, 4138,    0,    0, 4138, 4138, 4138, 4138, 4138,\n     4138,    0, 4138, 4138, 4138, 4138, 4138, 4138, 4138, 4138,\n     4139,    0,    0, 4139, 4139,    0,    0, 4139, 4139,    0,\n     4139,    0, 4139, 4139, 4139, 4139, 4140, 4140, 4140, 4140,\n     4140, 4140, 4140, 4140, 4140, 4140, 4140, 4140, 4140, 4140,\n     4140, 4140, 4140, 4140, 4140, 4141, 4141, 4141, 4141, 4141,\n     4141, 4141, 4141, 4141, 4141, 4141, 4141, 4141, 4141, 4141,\n     4141, 4141, 4141, 4141, 4142,    0,    0,    0,    0,    0,\n     4142, 4142, 4142, 4142,    0, 4142, 4142, 4142, 4142, 4142,\n\n     4142, 4142, 4142, 4143, 4143,    0, 4143, 4143, 4143, 4143,\n     4143, 4143, 4143, 4143, 4143, 4143, 4143, 4143, 4143, 4143,\n     4143, 4143, 4144, 4144,    0, 4144, 4144, 4144, 4144, 4144,\n     4144, 4144, 4144, 4144, 4144, 4144, 4144, 4144, 4144, 4144,\n     4144, 4145,    0,    0, 4145, 4145,    0,    0, 4145, 4145,\n        0, 4145,    0, 4145, 4145, 4145, 4145, 4146,    0,    0,\n        0,    0,    0, 4146, 4146, 4146, 4146,    0, 4146, 4146,\n     4146, 4146, 4146, 4146, 4146, 4146, 4147, 4147,    0, 4147,\n     4147,    0, 4147, 4147, 4147, 4147, 4147, 4147, 4147, 4147,\n     4147, 4147, 4147, 4147, 4148,    0,    0,    0, 4148, 4148,\n\n        0, 4148,    0, 4148, 4148, 4148, 4148, 4149, 4149, 4149,\n     4149, 4149, 4149, 4149, 4149, 4149, 4149, 4149, 4149, 4149,\n     4149, 4149, 4149, 4149, 4149, 4149, 4150, 4150, 4150, 4150,\n     4150, 4150, 4150, 4150, 4150, 4150, 4150, 4150, 4150, 4150,\n     4150, 4150, 4150, 4150, 4150, 4151,    0,    0, 4151, 4151,\n        0,    0, 4151, 4151,    0, 4151,    0, 4151, 4151, 4151,\n     4151, 4152,    0,    0,    0, 4152, 4152,    0, 4152,    0,\n     4152, 4152, 4152, 4152, 4153,    0,    0, 4153, 4153,    0,\n        0, 4153, 4153,    0, 4153,    0, 4153, 4153, 4153, 4153,\n     4154, 4154,    0, 4154, 4154, 4154, 4154, 4154, 4154, 4154,\n\n     4154, 4154, 4154, 4154, 4154, 4154, 4154, 4154, 4155,    0,\n        0,    0, 4155, 4155,    0, 4155,    0, 4155, 4155, 4155,\n     4155, 4156,    0,    0, 4156,    0,    0,    0, 4156, 4156,\n        0, 4156,    0, 4156, 4156, 4156, 4156, 4157,    0,    0,\n     4157, 4157,    0,    0, 4157, 4157,    0, 4157,    0, 4157,\n     4157, 4157, 4157, 4158,    0,    0,    0, 4158, 4158,    0,\n     4158,    0, 4158, 4158, 4158, 4158, 4159, 4159,    0, 4159,\n     4159,    0, 4159, 4159, 4159, 4159, 4159, 4159, 4159, 4159,\n     4159, 4159, 4159, 4159, 4160,    0,    0, 4160, 4160,    0,\n        0, 4160, 4160,    0, 4160,    0, 4160, 4160, 4160, 4160,\n\n     4161, 4161, 4161, 4161, 4161, 4161, 4161, 4161, 4161, 4161,\n     4161, 4161, 4161, 4161, 4161, 4161, 4161, 4161, 4161, 4162,\n        0,    0,    0, 4162, 4162,    0, 4162,    0, 4162, 4162,\n     4162, 4162, 4163,    0,    0, 4163, 4163,    0,    0, 4163,\n     4163,    0, 4163,    0, 4163, 4163, 4163, 4163, 4164,    0,\n        0,    0, 4164, 4164,    0, 4164,    0, 4164, 4164, 4164,\n     4164, 4165, 4165,    0, 4165, 4165,    0, 4165, 4165, 4165,\n     4165, 4165, 4165, 4165, 4165, 4165, 4165, 4165, 4165, 4166,\n        0,    0, 4166, 4166,    0,    0, 4166, 4166,    0, 4166,\n        0, 4166, 4166, 4166, 4166, 4167, 4167, 4167, 4167,    0,\n\n     4167, 4167, 4167, 4167, 4167, 4167, 4167, 4167, 4167, 4167,\n     4167, 4167, 4167, 4167, 4168,    0,    0,    0,    0,    0,\n     4168, 4168, 4168, 4168,    0, 4168, 4168, 4168, 4168, 4168,\n     4168, 4168, 4168, 4169,    0,    0,    0, 4169, 4169,    0,\n     4169,    0, 4169, 4169, 4169, 4169, 4170, 4170,    0, 4170,\n     4170,    0, 4170, 4170, 4170, 4170, 4170, 4170, 4170, 4170,\n     4170, 4170, 4170, 4170, 4171,    0,    0, 4171, 4171,    0,\n        0,    0,    0,    0,    0,    0, 4171, 4172, 4172,    0,\n        0,    0, 4172, 4172, 4172, 4172, 4172, 4172, 4172, 4172,\n     4172, 4172, 4172, 4172, 4172, 4172, 4173, 4173,    0, 4173,\n\n     4173, 4173, 4173, 4173, 4173, 4173, 4173, 4173, 4173, 4173,\n     4173, 4173, 4173, 4173, 4174, 4174,    0, 4174, 4174,    0,\n     4174, 4174, 4174, 4174, 4174, 4174, 4174, 4174, 4174, 4174,\n     4174, 4174, 4175, 4175,    0, 4175, 4175,    0, 4175, 4175,\n     4175, 4175, 4175, 4175, 4175, 4175, 4175, 4175, 4175, 4175,\n     4176, 4176,    0, 4176, 4176,    0, 4176, 4176, 4176, 4176,\n     4176, 4176, 4176, 4176, 4176, 4176, 4176, 4176, 4177, 4177,\n        0, 4177, 4177, 4177, 4177, 4177, 4177, 4177, 4177, 4177,\n     4177, 4177, 4177, 4177, 4177, 4177, 4178, 4178,    0, 4178,\n     4178, 4178, 4178, 4178, 4178, 4178, 4178, 4178, 4178, 4178,\n\n     4178, 4178, 4178, 4178, 4179,    0,    0, 4179,    0, 4179,\n        0, 4179, 4179, 4179, 4179, 4180, 4180,    0, 4180, 4180,\n        0, 4180, 4180, 4180, 4180, 4180, 4180, 4180, 4180, 4180,\n     4180, 4180, 4180, 4181, 4181,    0, 4181, 4181,    0, 4181,\n     4181, 4181, 4181, 4181, 4181, 4181, 4181, 4181, 4181, 4181,\n     4181, 4182, 4182, 4182, 4182, 4182, 4182, 4182, 4182, 4182,\n     4182, 4182, 4182, 4182, 4182, 4182, 4182, 4182, 4182, 4182,\n     4183,    0,    0, 4183,    0, 4183,    0, 4183, 4183, 4183,\n     4183, 4184, 4184,    0, 4184, 4184, 4184, 4184, 4184, 4184,\n     4184, 4184, 4184, 4184, 4184, 4184, 4184, 4184, 4184, 4184,\n\n     4185, 4185,    0, 4185, 4185,    0, 4185, 4185, 4185, 4185,\n     4185, 4185, 4185, 4185, 4185, 4185, 4185, 4185, 4186, 4186,\n        0,    0, 4186, 4186, 4186, 4186, 4186, 4186,    0, 4186,\n     4186, 4186, 4186, 4186, 4186, 4186, 4186, 4187, 4187,    0,\n     4187, 4187,    0, 4187, 4187, 4187, 4187, 4187, 4187, 4187,\n     4187, 4187, 4187, 4187, 4187, 4188,    0,    0,    0,    0,\n        0, 4188, 4188, 4188, 4188,    0, 4188, 4188, 4188, 4188,\n     4188, 4188, 4188, 4188, 4189,    0,    0,    0,    0,    0,\n     4189, 4189, 4189, 4189,    0, 4189, 4189, 4189, 4189, 4189,\n     4189, 4189, 4189, 4190,    0,    0, 4190, 4190,    0,    0,\n\n     4190, 4190,    0, 4190,    0, 4190, 4190, 4190, 4190, 4191,\n     4191,    0, 4191, 4191,    0, 4191, 4191, 4191, 4191, 4191,\n     4191, 4191, 4191, 4191, 4191, 4191, 4191, 4192,    0,    0,\n        0,    0,    0, 4192, 4192, 4192, 4192,    0, 4192, 4192,\n     4192, 4192, 4192, 4192, 4192, 4192, 4193,    0,    0,    0,\n     4193, 4193,    0, 4193,    0, 4193, 4193, 4193, 4193, 4194,\n     4194,    0, 4194, 4194,    0, 4194, 4194, 4194, 4194, 4194,\n     4194, 4194, 4194, 4194, 4194, 4194, 4194, 4195, 4195, 4195,\n     4195, 4195, 4195, 4195, 4195, 4195, 4195, 4195, 4195, 4195,\n     4195, 4195, 4195, 4195, 4195, 4195, 4196, 4196,    0, 4196,\n\n     4196,    0, 4196, 4196, 4196, 4196, 4196, 4196, 4196, 4196,\n     4196, 4196, 4196, 4196, 4197, 4197,    0,    0, 4197, 4197,\n     4197, 4197, 4197, 4197,    0, 4197, 4197, 4197, 4197, 4197,\n     4197, 4197, 4197, 4198, 4198,    0,    0, 4198, 4198, 4198,\n     4198, 4198, 4198,    0, 4198, 4198, 4198, 4198, 4198, 4198,\n     4198, 4198, 4199, 4199,    0, 4199, 4199,    0, 4199, 4199,\n     4199, 4199, 4199, 4199, 4199, 4199, 4199, 4199, 4199, 4199,\n     4200, 4200,    0, 4200, 4200,    0, 4200, 4200, 4200, 4200,\n     4200, 4200, 4200, 4200, 4200, 4200, 4200, 4200, 4201, 4201,\n        0,    0, 4201, 4201, 4201, 4201, 4201, 4201,    0, 4201,\n\n     4201, 4201, 4201, 4201, 4201, 4201, 4201, 4202, 4202,    0,\n        0, 4202, 4202, 4202, 4202, 4202, 4202,    0, 4202, 4202,\n     4202, 4202, 4202, 4202, 4202, 4202, 4203,    0,    0, 4203,\n        0, 4203,    0, 4203, 4203, 4203, 4203, 4204, 4204,    0,\n     4204, 4204, 4204, 4204, 4204, 4204, 4204, 4204, 4204, 4204,\n     4204, 4204, 4204, 4204, 4204, 4205, 4205,    0, 4205, 4205,\n        0, 4205, 4205, 4205, 4205, 4205, 4205, 4205, 4205, 4205,\n     4205, 4205, 4205, 4206, 4206,    0, 4206, 4206,    0, 4206,\n     4206, 4206, 4206, 4206, 4206, 4206, 4206, 4206, 4206, 4206,\n     4206, 4207,    0,    0, 4207,    0, 4207,    0, 4207, 4207,\n\n     4207, 4207, 4208,    0,    0,    0,    0,    0, 4208, 4208,\n     4208, 4208,    0, 4208, 4208, 4208, 4208, 4208, 4208, 4208,\n     4208, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972,\n\n     3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972, 3972\n    } ;\n\nstatic yy_state_type yy_last_accepting_state;\nstatic char *yy_last_accepting_cpos;\n\nextern int yy_flex_debug;\nint yy_flex_debug = 1;\n\nstatic const flex_int16_t yy_rule_linenum[549] =\n    {   0,\n      511,  512,  513,  514,  515,  516,  517,  518,  519,  520,\n      521,  522,  523,  524,  525,  526,  527,  528,  529,  530,\n      531,  532,  534,  535,  536,  537,  538,  539,  540,  541,\n      542,  543,  544,  545,  546,  547,  548,  549,  550,  551,\n      552,  553,  554,  555,  556,  557,  558,  559,  560,  561,\n      562,  563,  564,  565,  567,  568,  571,  572,  573,  574,\n      575,  576,  577,  579,  580,  581,  582,  583,  584,  585,\n      586,  587,  588,  589,  590,  591,  592,  593,  594,  595,\n      596,  597,  598,  599,  600,  601,  602,  603,  604,  605,\n      606,  607,  608,  609,  610,  611,  612,  613,  614,  615,\n\n      617,  618,  619,  620,  621,  622,  623,  627,  632,  633,\n      638,  639,  640,  645,  646,  647,  652,  657,  658,  659,\n      664,  665,  669,  670,  671,  675,  676,  680,  681,  685,\n      686,  687,  691,  692,  696,  697,  702,  703,  704,  708,\n      712,  713,  721,  726,  727,  732,  733,  734,  743,  746,\n      747,  748,  749,  750,  751,  752,  753,  754,  755,  756,\n      757,  758,  759,  760,  761,  762,  763,  764,  765,  766,\n      767,  768,  769,  770,  771,  774,  775,  776,  777,  778,\n      779,  780,  781,  782,  784,  785,  786,  787,  788,  789,\n      790,  791,  792,  793,  794,  795,  796,  797,  798,  799,\n\n      800,  801,  802,  803,  804,  805,  806,  807,  808,  809,\n      810,  811,  812,  813,  814,  815,  816,  817,  818,  819,\n      820,  821,  822,  823,  824,  825,  826,  827,  828,  829,\n      830,  831,  832,  833,  834,  835,  836,  837,  838,  839,\n      840,  841,  842,  843,  844,  845,  846,  847,  848,  849,\n      850,  851,  852,  853,  854,  855,  856,  857,  858,  859,\n      860,  861,  863,  864,  865,  867,  868,  869,  870,  871,\n      872,  873,  874,  875,  876,  879,  883,  884,  885,  886,\n      887,  891,  892,  893,  894,  895,  896,  900,  901,  902,\n      903,  908,  909,  910,  911,  912,  913,  914,  915,  916,\n\n      917,  918,  919,  920,  921,  922,  923,  924,  925,  926,\n      927,  928,  929,  930,  931,  932,  933,  934,  935,  936,\n      937,  938,  939,  940,  941,  942,  943,  944,  945,  946,\n      947,  948,  949,  950,  951,  952,  953,  954,  955,  956,\n      957,  958,  959,  960,  961,  962,  963,  964,  965,  966,\n      967,  968,  969,  970,  971,  972,  973,  974,  975,  976,\n      977,  978,  979,  980,  981,  982,  983,  984,  985,  986,\n      987,  988,  989,  990,  991,  992,  993,  994,  995,  996,\n      997,  998,  999, 1000, 1001, 1002, 1003, 1004, 1005, 1006,\n     1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016,\n\n     1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026,\n     1027, 1028, 1029, 1030, 1031, 1032, 1035, 1036, 1037, 1038,\n     1039, 1040, 1041, 1042, 1043, 1047, 1048, 1049, 1050, 1051,\n     1052, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065,\n     1067, 1068, 1069, 1070, 1071, 1076, 1077, 1078, 1079, 1080,\n     1081, 1083, 1084, 1086, 1087, 1093, 1094, 1095, 1096, 1097,\n     1098, 1101, 1102, 1103, 1104, 1105, 1106, 1110, 1111, 1112,\n     1113, 1114, 1115, 1116, 1117, 1118, 1119, 1120, 1121, 1122,\n     1123, 1124, 1125, 1126, 1127, 1128, 1129, 1130, 1131, 1132,\n     1133, 1134, 1135, 1136, 1137, 1138, 1139, 1140, 1142, 1143,\n\n     1148, 1152, 1156, 1157, 1161, 1162, 1165, 1166, 1170, 1171,\n     1175, 1176, 1180, 1181, 1186, 1188, 1189, 1190, 1191, 1193,\n     1194, 1195, 1196, 1198, 1199, 1200, 1201, 1203, 1205, 1206,\n     1208, 1209, 1210, 1211, 1213, 1218, 1219, 1220, 1224, 1225,\n     1226, 1231, 1233, 1234, 1235, 1254, 1283, 1313\n    } ;\n\n/* The intent behind this definition is that it'll catch\n * any uses of REJECT which flex missed.\n */\n#define REJECT reject_used_but_not_detected\n#define yymore() yymore_used_but_not_detected\n#define YY_MORE_ADJ 0\n#define YY_RESTORE_YY_MORE_OFFSET\nchar *yytext;\n#line 1 \"seclang-scanner.ll\"\n#line 2 \"seclang-scanner.ll\"\n#include <cerrno>\n#include <climits>\n#include <cstdlib>\n#include <string>\n\n#include \"src/parser/driver.h\"\n#include \"src/parser/seclang-parser.hh\"\n#include \"src/utils/https_client.h\"\n#include \"src/utils/string.h\"\n\nusing modsecurity::Parser::Driver;\nusing modsecurity::Utils::HttpsClient;\nusing modsecurity::utils::string::parserSanitizer;\n\ntypedef yy::seclang_parser p;\nstatic int state_variable_from = 0;\nstatic std::stack<int> YY_PREVIOUS_STATE;\n\n// Work around an incompatibility in flex (at least versions\n// 2.5.31 through 2.5.33): it generates code that does\n// not conform to C89.  See Debian bug 333231\n// <http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=333231>.\n# undef yywrap\n# define yywrap() 1\n\n#define BEGINX(z) { \\\n    YY_PREVIOUS_STATE.push(YY_START); \\\n    BEGIN(z); \\\n}\n\n#define BEGINX_() { \\\n    YY_PREVIOUS_STATE.push(YY_START); \\\n    if (YY_START == SETVAR_ACTION_NONQUOTED) { \\\n        BEGIN(EXPECTING_VAR_PARAMETER_OR_MACRO_NONQUOTED); \\\n    } else if (YY_START == SETVAR_ACTION_QUOTED) { \\\n        BEGIN(EXPECTING_VAR_PARAMETER_OR_MACRO_QUOTED); \\\n    } else { \\\n        BEGIN(EXPECTING_VAR_PARAMETER); \\\n    } \\\n}\n\n#define BEGIN_PARAMETER() { if (YY_START == EXPECTING_OPERATOR_ENDS_WITH_SPACE) { BEGIN(TRANSITION_FROM_OP_TO_EXPECTING_PARAMETER_ENDS_WITH_SPACE); } else { BEGIN(TRANSITION_FROM_OP_TO_EXPECTING_PARAMETER_ENDS_WITH_QUOTE); } }\n#define BEGIN_NO_OP_INFORMED() { if (YY_START == EXPECTING_OPERATOR_ENDS_WITH_SPACE) { BEGIN(NO_OP_INFORMED_ENDS_WITH_SPACE); } else { BEGIN(NO_OP_INFORMED_ENDS_WITH_QUOTE); } }\n\n#define BEGIN_ACTION_OPERATION() { \\\n    if (YY_START == SETVAR_ACTION_NONQUOTED) { \\\n        BEGIN(SETVAR_ACTION_NONQUOTED_WAITING_OPERATION); \\\n    } else if (YY_START == SETVAR_ACTION_QUOTED) { \\\n        BEGIN(SETVAR_ACTION_QUOTED_WAITING_OPERATION); \\\n    } else if (YY_START == SETVAR_ACTION_NONQUOTED_WAITING_COLLECTION_ELEM) { \\\n        BEGIN(SETVAR_ACTION_NONQUOTED_WAITING_OPERATION); \\\n    } else if (YY_START == SETVAR_ACTION_QUOTED_WAITING_COLLECTION_ELEM) { \\\n        BEGIN(SETVAR_ACTION_QUOTED_WAITING_OPERATION); \\\n    }\\\n}\n\n\n#define BEGIN_ACTION_WAITING_CONTENT() { \\\n    if (YY_START == SETVAR_ACTION_NONQUOTED_WAITING_OPERATION) { \\\n        BEGIN(SETVAR_ACTION_NONQUOTED_WAITING_CONTENT); \\\n    } else if (YY_START == SETVAR_ACTION_QUOTED_WAITING_OPERATION) { \\\n        BEGIN(SETVAR_ACTION_QUOTED_WAITING_CONTENT); \\\n    } else if (YY_START == EXPECTING_VAR_PARAMETER_OR_MACRO_QUOTED) { \\\n        BEGIN(SETVAR_ACTION_QUOTED_WAITING_CONTENT); \\\n    } else if (YY_START == EXPECTING_VAR_PARAMETER_OR_MACRO_NONQUOTED) { \\\n        BEGIN(SETVAR_ACTION_NONQUOTED_WAITING_CONTENT); \\\n    } \\\n}\n\n\n#define BEGIN_PREVIOUS() { BEGIN(YY_PREVIOUS_STATE.top()); YY_PREVIOUS_STATE.pop(); }\n\n// The location of the current token.\n#line 5021 \"seclang-scanner.cc\"\n#define YY_NO_INPUT 1\n#define YY_NO_UNISTD_H 1\n\n#line 498 \"seclang-scanner.ll\"\n  // Code run each time a pattern is matched.\n  # define YY_USER_ACTION  driver.loc.back()->columns (yyleng);\n\n#line 5029 \"seclang-scanner.cc\"\n#line 5030 \"seclang-scanner.cc\"\n\n#define INITIAL 0\n#define EXPECTING_ACTION_PREDICATE_VARIABLE 1\n#define TRANSACTION_TO_VARIABLE 2\n#define EXPECTING_VARIABLE 3\n#define EXPECTING_OPERATOR_ENDS_WITH_SPACE 4\n#define EXPECTING_OPERATOR_ENDS_WITH_QUOTE 5\n#define EXPECTING_ACTION_PREDICATE 6\n#define ACTION_PREDICATE_ENDS_WITH_QUOTE 7\n#define ACTION_PREDICATE_ENDS_WITH_DOUBLE_QUOTE 8\n#define ACTION_PREDICATE_ENDS_WITH_COMMA_OR_DOUBLE_QUOTE 9\n#define COMMENT 10\n#define TRANSITION_FROM_OP_TO_EXPECTING_PARAMETER_ENDS_WITH_QUOTE 11\n#define TRANSITION_FROM_OP_TO_EXPECTING_PARAMETER_ENDS_WITH_SPACE 12\n#define EXPECTING_VAR_PARAMETER 13\n#define EXPECTING_VAR_PARAMETER_OR_MACRO_NONQUOTED 14\n#define EXPECTING_VAR_PARAMETER_OR_MACRO_QUOTED 15\n#define EXPECTING_PARAMETER_ENDS_WITH_QUOTE 16\n#define EXPECTING_PARAMETER_ENDS_WITH_SPACE 17\n#define EXPECTING_ACTIONS_ENDS_WITH_DOUBLE_QUOTE 18\n#define EXPECTING_ACTIONS_ONLY_ONE 19\n#define TRANSACTION_FROM_OPERATOR_TO_ACTIONS 20\n#define TRANSACTION_FROM_OPERATOR_PARAMETERS_TO_ACTIONS 21\n#define TRANSACTION_FROM_DIRECTIVE_TO_ACTIONS 22\n#define NO_OP_INFORMED_ENDS_WITH_SPACE 23\n#define NO_OP_INFORMED_ENDS_WITH_QUOTE 24\n#define FINISH_ACTIONS 25\n#define LEXING_ERROR 26\n#define LEXING_ERROR_ACTION 27\n#define LEXING_ERROR_VARIABLE 28\n#define SETVAR_ACTION_NONQUOTED 29\n#define SETVAR_ACTION_NONQUOTED_WAITING_COLLECTION_ELEM 30\n#define SETVAR_ACTION_NONQUOTED_WAITING_OPERATION 31\n#define SETVAR_ACTION_NONQUOTED_WAITING_CONTENT 32\n#define SETVAR_ACTION_QUOTED 33\n#define SETVAR_ACTION_QUOTED_WAITING_COLLECTION_ELEM 34\n#define SETVAR_ACTION_QUOTED_WAITING_OPERATION 35\n#define SETVAR_ACTION_QUOTED_WAITING_CONTENT 36\n\n#ifndef YY_NO_UNISTD_H\n/* Special case for \"unistd.h\", since it is non-ANSI. We include it way\n * down here because we want the user's section 1 to have been scanned first.\n * The user has a chance to override it with an option.\n */\n/* %if-c-only */\n#include <unistd.h>\n/* %endif */\n/* %if-c++-only */\n/* %endif */\n#endif\n\n#ifndef YY_EXTRA_TYPE\n#define YY_EXTRA_TYPE void *\n#endif\n\n/* %if-c-only Reentrant structure and macros (non-C++). */\n/* %if-reentrant */\n/* %if-c-only */\n\nstatic int yy_init_globals ( void );\n\n/* %endif */\n/* %if-reentrant */\n/* %endif */\n/* %endif End reentrant structures and macros. */\n\n/* Accessor methods to globals.\n   These are made visible to non-reentrant scanners for convenience. */\n\nint yylex_destroy ( void );\n\nint yyget_debug ( void );\n\nvoid yyset_debug ( int debug_flag  );\n\nYY_EXTRA_TYPE yyget_extra ( void );\n\nvoid yyset_extra ( YY_EXTRA_TYPE user_defined  );\n\nFILE *yyget_in ( void );\n\nvoid yyset_in  ( FILE * _in_str  );\n\nFILE *yyget_out ( void );\n\nvoid yyset_out  ( FILE * _out_str  );\n\n\t\t\tyy_size_t yyget_leng ( void );\n\nchar *yyget_text ( void );\n\nint yyget_lineno ( void );\n\nvoid yyset_lineno ( int _line_number  );\n\n/* %if-bison-bridge */\n/* %endif */\n\n/* Macros after this point can all be overridden by user definitions in\n * section 1.\n */\n\n#ifndef YY_SKIP_YYWRAP\n#ifdef __cplusplus\nextern \"C\" int yywrap ( void );\n#else\nextern int yywrap ( void );\n#endif\n#endif\n\n/* %not-for-header */\n#ifndef YY_NO_UNPUT\n    \n#endif\n/* %ok-for-header */\n\n/* %endif */\n\n#ifndef yytext_ptr\nstatic void yy_flex_strncpy ( char *, const char *, int );\n#endif\n\n#ifdef YY_NEED_STRLEN\nstatic int yy_flex_strlen ( const char * );\n#endif\n\n#ifndef YY_NO_INPUT\n/* %if-c-only Standard (non-C++) definition */\n/* %not-for-header */\n#ifdef __cplusplus\nstatic int yyinput ( void );\n#else\nstatic int input ( void );\n#endif\n/* %ok-for-header */\n\n/* %endif */\n#endif\n\n/* %if-c-only */\n\n/* %endif */\n\n/* Amount of stuff to slurp up with each read. */\n#ifndef YY_READ_BUF_SIZE\n#ifdef __ia64__\n/* On IA-64, the buffer size is 16k, not 8k */\n#define YY_READ_BUF_SIZE 16384\n#else\n#define YY_READ_BUF_SIZE 8192\n#endif /* __ia64__ */\n#endif\n\n/* Copy whatever the last rule matched to the standard output. */\n#ifndef ECHO\n/* %if-c-only Standard (non-C++) definition */\n/* This used to be an fputs(), but since the string might contain NUL's,\n * we now use fwrite().\n */\n#define ECHO do { if (fwrite( yytext, (size_t) yyleng, 1, yyout )) {} } while (0)\n/* %endif */\n/* %if-c++-only C++ definition */\n/* %endif */\n#endif\n\n/* Gets input and stuffs it into \"buf\".  number of characters read, or YY_NULL,\n * is returned in \"result\".\n */\n#ifndef YY_INPUT\n#define YY_INPUT(buf,result,max_size) \\\n/* %% [5.0] fread()/read() definition of YY_INPUT goes here unless we're doing C++ \\ */\\\n\tif ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \\\n\t\t{ \\\n\t\tint c = '*'; \\\n\t\tyy_size_t n; \\\n\t\tfor ( n = 0; n < max_size && \\\n\t\t\t     (c = getc( yyin )) != EOF && c != '\\n'; ++n ) \\\n\t\t\tbuf[n] = (char) c; \\\n\t\tif ( c == '\\n' ) \\\n\t\t\tbuf[n++] = (char) c; \\\n\t\tif ( c == EOF && ferror( yyin ) ) \\\n\t\t\tYY_FATAL_ERROR( \"input in flex scanner failed\" ); \\\n\t\tresult = n; \\\n\t\t} \\\n\telse \\\n\t\t{ \\\n\t\terrno=0; \\\n\t\twhile ( (result = (int) fread(buf, 1, (yy_size_t) max_size, yyin)) == 0 && ferror(yyin)) \\\n\t\t\t{ \\\n\t\t\tif( errno != EINTR) \\\n\t\t\t\t{ \\\n\t\t\t\tYY_FATAL_ERROR( \"input in flex scanner failed\" ); \\\n\t\t\t\tbreak; \\\n\t\t\t\t} \\\n\t\t\terrno=0; \\\n\t\t\tclearerr(yyin); \\\n\t\t\t} \\\n\t\t}\\\n\\\n/* %if-c++-only C++ definition \\ */\\\n/* %endif */\n\n#endif\n\n/* No semi-colon after return; correct usage is to write \"yyterminate();\" -\n * we don't want an extra ';' after the \"return\" because that will cause\n * some compilers to complain about unreachable statements.\n */\n#ifndef yyterminate\n#define yyterminate() return YY_NULL\n#endif\n\n/* Number of entries by which start-condition stack grows. */\n#ifndef YY_START_STACK_INCR\n#define YY_START_STACK_INCR 25\n#endif\n\n/* Report a fatal error. */\n#ifndef YY_FATAL_ERROR\n/* %if-c-only */\n#define YY_FATAL_ERROR(msg) yy_fatal_error( msg )\n/* %endif */\n/* %if-c++-only */\n/* %endif */\n#endif\n\n/* %if-tables-serialization structures and prototypes */\n/* %not-for-header */\n/* %ok-for-header */\n\n/* %not-for-header */\n/* %tables-yydmap generated elements */\n/* %endif */\n/* end tables serialization structures and prototypes */\n\n/* %ok-for-header */\n\n/* Default declaration of generated scanner - a define so the user can\n * easily add parameters.\n */\n#ifndef YY_DECL\n#define YY_DECL_IS_OURS 1\n/* %if-c-only Standard (non-C++) definition */\n\nextern int yylex (void);\n\n#define YY_DECL int yylex (void)\n/* %endif */\n/* %if-c++-only C++ definition */\n/* %endif */\n#endif /* !YY_DECL */\n\n/* Code executed at the beginning of each rule, after yytext and yyleng\n * have been set up.\n */\n#ifndef YY_USER_ACTION\n#define YY_USER_ACTION\n#endif\n\n/* Code executed at the end of each rule. */\n#ifndef YY_BREAK\n#define YY_BREAK /*LINTED*/break;\n#endif\n\n/* %% [6.0] YY_RULE_SETUP definition goes here */\n#define YY_RULE_SETUP \\\n\tYY_USER_ACTION\n\n/* %not-for-header */\n/** The main scanner function which does all the work.\n */\nYY_DECL\n{\n\tyy_state_type yy_current_state;\n\tchar *yy_cp, *yy_bp;\n\tint yy_act;\n    \n\tif ( !(yy_init) )\n\t\t{\n\t\t(yy_init) = 1;\n\n#ifdef YY_USER_INIT\n\t\tYY_USER_INIT;\n#endif\n\n\t\tif ( ! (yy_start) )\n\t\t\t(yy_start) = 1;\t/* first start state */\n\n\t\tif ( ! yyin )\n/* %if-c-only */\n\t\t\tyyin = stdin;\n/* %endif */\n/* %if-c++-only */\n/* %endif */\n\n\t\tif ( ! yyout )\n/* %if-c-only */\n\t\t\tyyout = stdout;\n/* %endif */\n/* %if-c++-only */\n/* %endif */\n\n\t\tif ( ! YY_CURRENT_BUFFER ) {\n\t\t\tyyensure_buffer_stack ();\n\t\t\tYY_CURRENT_BUFFER_LVALUE =\n\t\t\t\tyy_create_buffer( yyin, YY_BUF_SIZE );\n\t\t}\n\n\t\tyy_load_buffer_state(  );\n\t\t}\n\n\t{\n/* %% [7.0] user's declarations go here */\n#line 503 \"seclang-scanner.ll\"\n\n\n\n#line 507 \"seclang-scanner.ll\"\n  // Code run each time yylex is called.\n  driver.loc.back()->step();\n\n#line 5352 \"seclang-scanner.cc\"\n\n\twhile ( /*CONSTCOND*/1 )\t\t/* loops until end-of-file is reached */\n\t\t{\n/* %% [8.0] yymore()-related code goes here */\n\t\tyy_cp = (yy_c_buf_p);\n\n\t\t/* Support of yytext. */\n\t\t*yy_cp = (yy_hold_char);\n\n\t\t/* yy_bp points to the position in yy_ch_buf of the start of\n\t\t * the current run.\n\t\t */\n\t\tyy_bp = yy_cp;\n\n/* %% [9.0] code to set up and find next match goes here */\n\t\tyy_current_state = (yy_start);\nyy_match:\n\t\tdo\n\t\t\t{\n\t\t\tYY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)] ;\n\t\t\tif ( yy_accept[yy_current_state] )\n\t\t\t\t{\n\t\t\t\t(yy_last_accepting_state) = yy_current_state;\n\t\t\t\t(yy_last_accepting_cpos) = yy_cp;\n\t\t\t\t}\n\t\t\twhile ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )\n\t\t\t\t{\n\t\t\t\tyy_current_state = (int) yy_def[yy_current_state];\n\t\t\t\tif ( yy_current_state >= 3973 )\n\t\t\t\t\tyy_c = yy_meta[yy_c];\n\t\t\t\t}\n\t\t\tyy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c];\n\t\t\t++yy_cp;\n\t\t\t}\n\t\twhile ( yy_current_state != 3972 );\n\t\tyy_cp = (yy_last_accepting_cpos);\n\t\tyy_current_state = (yy_last_accepting_state);\n\nyy_find_action:\n/* %% [10.0] code to find the action number goes here */\n\t\tyy_act = yy_accept[yy_current_state];\n\n\t\tYY_DO_BEFORE_ACTION;\n\n/* %% [11.0] code for yylineno update goes here */\n\ndo_action:\t/* This label is used only to access EOF actions. */\n\n/* %% [12.0] debug code goes here */\n\t\tif ( yy_flex_debug )\n\t\t\t{\n\t\t\tif ( yy_act == 0 )\n\t\t\t\tfprintf( stderr, \"--scanner backing up\\n\" );\n\t\t\telse if ( yy_act < 549 )\n\t\t\t\tfprintf( stderr, \"--accepting rule at line %ld (\\\"%s\\\")\\n\",\n\t\t\t\t         (long)yy_rule_linenum[yy_act], yytext );\n\t\t\telse if ( yy_act == 549 )\n\t\t\t\tfprintf( stderr, \"--accepting default rule (\\\"%s\\\")\\n\",\n\t\t\t\t         yytext );\n\t\t\telse if ( yy_act == 550 )\n\t\t\t\tfprintf( stderr, \"--(end of buffer or a NUL)\\n\" );\n\t\t\telse\n\t\t\t\tfprintf( stderr, \"--EOF (start condition %d)\\n\", YY_START );\n\t\t\t}\n\n\t\tswitch ( yy_act )\n\t{ /* beginning of action switch */\n/* %% [13.0] actions go here */\n\t\t\tcase 0: /* must back up */\n\t\t\t/* undo the effects of YY_DO_BEFORE_ACTION */\n\t\t\t*yy_cp = (yy_hold_char);\n\t\t\tyy_cp = (yy_last_accepting_cpos);\n\t\t\tyy_current_state = (yy_last_accepting_state);\n\t\t\tgoto yy_find_action;\n\ncase 1:\nYY_RULE_SETUP\n#line 511 \"seclang-scanner.ll\"\n{ return p::make_ACTION_APPEND(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 2:\nYY_RULE_SETUP\n#line 512 \"seclang-scanner.ll\"\n{ return p::make_ACTION_BLOCK(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 3:\nYY_RULE_SETUP\n#line 513 \"seclang-scanner.ll\"\n{ return p::make_ACTION_CAPTURE(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 4:\nYY_RULE_SETUP\n#line 514 \"seclang-scanner.ll\"\n{ return p::make_ACTION_CHAIN(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 5:\nYY_RULE_SETUP\n#line 515 \"seclang-scanner.ll\"\n{ return p::make_ACTION_DENY(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 6:\nYY_RULE_SETUP\n#line 516 \"seclang-scanner.ll\"\n{ return p::make_ACTION_DEPRECATE_VAR(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 7:\nYY_RULE_SETUP\n#line 517 \"seclang-scanner.ll\"\n{ return p::make_ACTION_DROP(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 8:\nYY_RULE_SETUP\n#line 518 \"seclang-scanner.ll\"\n{ return p::make_ACTION_ID(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 9:\nYY_RULE_SETUP\n#line 519 \"seclang-scanner.ll\"\n{ return p::make_ACTION_LOG(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 10:\nYY_RULE_SETUP\n#line 520 \"seclang-scanner.ll\"\n{ return p::make_ACTION_MULTI_MATCH(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 11:\nYY_RULE_SETUP\n#line 521 \"seclang-scanner.ll\"\n{ return p::make_ACTION_NO_AUDIT_LOG(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 12:\nYY_RULE_SETUP\n#line 522 \"seclang-scanner.ll\"\n{ return p::make_ACTION_NO_LOG(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 13:\nYY_RULE_SETUP\n#line 523 \"seclang-scanner.ll\"\n{ return p::make_ACTION_PASS(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 14:\nYY_RULE_SETUP\n#line 524 \"seclang-scanner.ll\"\n{ return p::make_ACTION_PAUSE(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 15:\nYY_RULE_SETUP\n#line 525 \"seclang-scanner.ll\"\n{ return p::make_ACTION_PREPEND(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 16:\nYY_RULE_SETUP\n#line 526 \"seclang-scanner.ll\"\n{ return p::make_ACTION_PROXY(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 17:\nYY_RULE_SETUP\n#line 527 \"seclang-scanner.ll\"\n{ return p::make_ACTION_SANITISE_ARG(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 18:\nYY_RULE_SETUP\n#line 528 \"seclang-scanner.ll\"\n{ return p::make_ACTION_SANITISE_MATCHED(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 19:\nYY_RULE_SETUP\n#line 529 \"seclang-scanner.ll\"\n{ return p::make_ACTION_SANITISE_MATCHED_BYTES(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 20:\nYY_RULE_SETUP\n#line 530 \"seclang-scanner.ll\"\n{ return p::make_ACTION_SANITISE_REQUEST_HEADER(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 21:\nYY_RULE_SETUP\n#line 531 \"seclang-scanner.ll\"\n{ return p::make_ACTION_SANITISE_RESPONSE_HEADER(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 22:\nYY_RULE_SETUP\n#line 532 \"seclang-scanner.ll\"\n{ BEGIN(EXPECTING_ACTION_PREDICATE); return p::make_ACTION_SETRSC(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 23:\nYY_RULE_SETUP\n#line 534 \"seclang-scanner.ll\"\n{ return p::make_ACTION_STATUS(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 24:\n/* rule 24 can match eol */\nYY_RULE_SETUP\n#line 535 \"seclang-scanner.ll\"\n{ return p::make_ACTION_ACCURACY(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 25:\n/* rule 25 can match eol */\nYY_RULE_SETUP\n#line 536 \"seclang-scanner.ll\"\n{ return p::make_ACTION_ACCURACY(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 26:\nYY_RULE_SETUP\n#line 537 \"seclang-scanner.ll\"\n{ return p::make_ACTION_ALLOW(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 27:\nYY_RULE_SETUP\n#line 538 \"seclang-scanner.ll\"\n{ return p::make_ACTION_AUDIT_LOG(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 28:\nYY_RULE_SETUP\n#line 539 \"seclang-scanner.ll\"\n{ return p::make_ACTION_CTL_AUDIT_ENGINE(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 29:\nYY_RULE_SETUP\n#line 540 \"seclang-scanner.ll\"\n{ return p::make_ACTION_CTL_AUDIT_LOG_PARTS(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 30:\nYY_RULE_SETUP\n#line 541 \"seclang-scanner.ll\"\n{ return p::make_ACTION_CTL_BDY_JSON(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 31:\nYY_RULE_SETUP\n#line 542 \"seclang-scanner.ll\"\n{ return p::make_ACTION_CTL_BDY_XML(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 32:\nYY_RULE_SETUP\n#line 543 \"seclang-scanner.ll\"\n{ return p::make_ACTION_CTL_BDY_URLENCODED(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 33:\nYY_RULE_SETUP\n#line 544 \"seclang-scanner.ll\"\n{ return p::make_ACTION_CTL_FORCE_REQ_BODY_VAR(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 34:\nYY_RULE_SETUP\n#line 545 \"seclang-scanner.ll\"\n{ return p::make_ACTION_CTL_PARSE_XML_INTO_ARGS(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 35:\nYY_RULE_SETUP\n#line 546 \"seclang-scanner.ll\"\n{ return p::make_ACTION_CTL_REQUEST_BODY_ACCESS(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 36:\nYY_RULE_SETUP\n#line 547 \"seclang-scanner.ll\"\n{ return p::make_ACTION_CTL_RULE_ENGINE(*driver.loc.back()); }\n\tYY_BREAK\ncase 37:\nYY_RULE_SETUP\n#line 548 \"seclang-scanner.ll\"\n{ return p::make_ACTION_CTL_RULE_REMOVE_BY_ID(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 38:\nYY_RULE_SETUP\n#line 549 \"seclang-scanner.ll\"\n{ return p::make_ACTION_CTL_RULE_REMOVE_BY_TAG(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 39:\nYY_RULE_SETUP\n#line 550 \"seclang-scanner.ll\"\n{ return p::make_ACTION_CTL_RULE_REMOVE_TARGET_BY_ID(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 40:\nYY_RULE_SETUP\n#line 551 \"seclang-scanner.ll\"\n{ return p::make_ACTION_CTL_RULE_REMOVE_TARGET_BY_TAG(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 41:\n/* rule 41 can match eol */\nYY_RULE_SETUP\n#line 552 \"seclang-scanner.ll\"\n{ return p::make_ACTION_EXEC(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 42:\n/* rule 42 can match eol */\nYY_RULE_SETUP\n#line 553 \"seclang-scanner.ll\"\n{ return p::make_ACTION_EXEC(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 43:\nYY_RULE_SETUP\n#line 554 \"seclang-scanner.ll\"\n{ BEGIN(EXPECTING_ACTION_PREDICATE); return p::make_ACTION_EXPIRE_VAR(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 44:\nYY_RULE_SETUP\n#line 555 \"seclang-scanner.ll\"\n{ BEGIN(EXPECTING_ACTION_PREDICATE); return p::make_ACTION_INITCOL(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 45:\n/* rule 45 can match eol */\nYY_RULE_SETUP\n#line 556 \"seclang-scanner.ll\"\n{ return p::make_ACTION_MATURITY(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 46:\n/* rule 46 can match eol */\nYY_RULE_SETUP\n#line 557 \"seclang-scanner.ll\"\n{ return p::make_ACTION_MATURITY(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 47:\nYY_RULE_SETUP\n#line 558 \"seclang-scanner.ll\"\n{ BEGIN(EXPECTING_ACTION_PREDICATE); return p::make_ACTION_MSG(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 48:\nYY_RULE_SETUP\n#line 559 \"seclang-scanner.ll\"\n{ return p::make_ACTION_PHASE(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 49:\nYY_RULE_SETUP\n#line 560 \"seclang-scanner.ll\"\n{ BEGIN(EXPECTING_ACTION_PREDICATE); return p::make_ACTION_REDIRECT(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 50:\n/* rule 50 can match eol */\nYY_RULE_SETUP\n#line 561 \"seclang-scanner.ll\"\n{ return p::make_ACTION_REV(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 51:\n/* rule 51 can match eol */\nYY_RULE_SETUP\n#line 562 \"seclang-scanner.ll\"\n{ return p::make_ACTION_REV(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 52:\nYY_RULE_SETUP\n#line 563 \"seclang-scanner.ll\"\n{ BEGIN(EXPECTING_ACTION_PREDICATE); return p::make_ACTION_SETENV(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 53:\nYY_RULE_SETUP\n#line 564 \"seclang-scanner.ll\"\n{ BEGIN(EXPECTING_ACTION_PREDICATE); return p::make_ACTION_SETSID(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 54:\nYY_RULE_SETUP\n#line 565 \"seclang-scanner.ll\"\n{ BEGIN(EXPECTING_ACTION_PREDICATE); return p::make_ACTION_SETUID(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 55:\nYY_RULE_SETUP\n#line 567 \"seclang-scanner.ll\"\n{ BEGIN(SETVAR_ACTION_QUOTED); return p::make_ACTION_SETVAR(*driver.loc.back()); }\n\tYY_BREAK\ncase 56:\nYY_RULE_SETUP\n#line 568 \"seclang-scanner.ll\"\n{ BEGIN(SETVAR_ACTION_NONQUOTED); return p::make_ACTION_SETVAR(*driver.loc.back()); }\n\tYY_BREAK\ncase 57:\nYY_RULE_SETUP\n#line 571 \"seclang-scanner.ll\"\n{ return p::make_ACTION_SEVERITY(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 58:\nYY_RULE_SETUP\n#line 572 \"seclang-scanner.ll\"\n{ return p::make_ACTION_SEVERITY(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 59:\nYY_RULE_SETUP\n#line 573 \"seclang-scanner.ll\"\n{ return p::make_ACTION_SKIP_AFTER(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 60:\nYY_RULE_SETUP\n#line 574 \"seclang-scanner.ll\"\n{ return p::make_ACTION_SKIP(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 61:\nYY_RULE_SETUP\n#line 575 \"seclang-scanner.ll\"\n{ BEGIN(EXPECTING_ACTION_PREDICATE); return p::make_ACTION_TAG(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 62:\n/* rule 62 can match eol */\nYY_RULE_SETUP\n#line 576 \"seclang-scanner.ll\"\n{ return p::make_ACTION_VER(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 63:\nYY_RULE_SETUP\n#line 577 \"seclang-scanner.ll\"\n{ return p::make_ACTION_XMLNS(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 64:\nYY_RULE_SETUP\n#line 579 \"seclang-scanner.ll\"\n{ return p::make_ACTION_TRANSFORMATION_PARITY_ZERO_7_BIT(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 65:\nYY_RULE_SETUP\n#line 580 \"seclang-scanner.ll\"\n{ return p::make_ACTION_TRANSFORMATION_PARITY_ODD_7_BIT(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 66:\nYY_RULE_SETUP\n#line 581 \"seclang-scanner.ll\"\n{ return p::make_ACTION_TRANSFORMATION_PARITY_EVEN_7_BIT(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 67:\nYY_RULE_SETUP\n#line 582 \"seclang-scanner.ll\"\n{ return p::make_ACTION_TRANSFORMATION_SQL_HEX_DECODE(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 68:\nYY_RULE_SETUP\n#line 583 \"seclang-scanner.ll\"\n{ return p::make_ACTION_TRANSFORMATION_BASE_64_ENCODE(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 69:\nYY_RULE_SETUP\n#line 584 \"seclang-scanner.ll\"\n{ return p::make_ACTION_TRANSFORMATION_BASE_64_DECODE(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 70:\nYY_RULE_SETUP\n#line 585 \"seclang-scanner.ll\"\n{ return p::make_ACTION_TRANSFORMATION_BASE_64_DECODE_EXT(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 71:\nYY_RULE_SETUP\n#line 586 \"seclang-scanner.ll\"\n{ return p::make_ACTION_TRANSFORMATION_CMD_LINE(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 72:\nYY_RULE_SETUP\n#line 587 \"seclang-scanner.ll\"\n{ return p::make_ACTION_TRANSFORMATION_SHA1(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 73:\nYY_RULE_SETUP\n#line 588 \"seclang-scanner.ll\"\n{ return p::make_ACTION_TRANSFORMATION_MD5(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 74:\nYY_RULE_SETUP\n#line 589 \"seclang-scanner.ll\"\n{ return p::make_ACTION_TRANSFORMATION_ESCAPE_SEQ_DECODE(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 75:\nYY_RULE_SETUP\n#line 590 \"seclang-scanner.ll\"\n{ return p::make_ACTION_TRANSFORMATION_HEX_ENCODE(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 76:\nYY_RULE_SETUP\n#line 591 \"seclang-scanner.ll\"\n{ return p::make_ACTION_TRANSFORMATION_HEX_DECODE(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 77:\nYY_RULE_SETUP\n#line 592 \"seclang-scanner.ll\"\n{ return p::make_ACTION_TRANSFORMATION_LOWERCASE(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 78:\nYY_RULE_SETUP\n#line 593 \"seclang-scanner.ll\"\n{ return p::make_ACTION_TRANSFORMATION_UPPERCASE(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 79:\nYY_RULE_SETUP\n#line 594 \"seclang-scanner.ll\"\n{ return p::make_ACTION_TRANSFORMATION_URL_ENCODE(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 80:\nYY_RULE_SETUP\n#line 595 \"seclang-scanner.ll\"\n{ return p::make_ACTION_TRANSFORMATION_URL_DECODE_UNI(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 81:\nYY_RULE_SETUP\n#line 596 \"seclang-scanner.ll\"\n{ return p::make_ACTION_TRANSFORMATION_URL_DECODE(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 82:\nYY_RULE_SETUP\n#line 597 \"seclang-scanner.ll\"\n{ return p::make_ACTION_TRANSFORMATION_NONE(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 83:\nYY_RULE_SETUP\n#line 598 \"seclang-scanner.ll\"\n{ return p::make_ACTION_TRANSFORMATION_COMPRESS_WHITESPACE(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 84:\nYY_RULE_SETUP\n#line 599 \"seclang-scanner.ll\"\n{ return p::make_ACTION_TRANSFORMATION_REMOVE_WHITESPACE(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 85:\nYY_RULE_SETUP\n#line 600 \"seclang-scanner.ll\"\n{ return p::make_ACTION_TRANSFORMATION_REPLACE_NULLS(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 86:\nYY_RULE_SETUP\n#line 601 \"seclang-scanner.ll\"\n{ return p::make_ACTION_TRANSFORMATION_REMOVE_NULLS(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 87:\nYY_RULE_SETUP\n#line 602 \"seclang-scanner.ll\"\n{ return p::make_ACTION_TRANSFORMATION_HTML_ENTITY_DECODE(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 88:\nYY_RULE_SETUP\n#line 603 \"seclang-scanner.ll\"\n{ return p::make_ACTION_TRANSFORMATION_JS_DECODE(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 89:\nYY_RULE_SETUP\n#line 604 \"seclang-scanner.ll\"\n{ return p::make_ACTION_TRANSFORMATION_CSS_DECODE(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 90:\nYY_RULE_SETUP\n#line 605 \"seclang-scanner.ll\"\n{ return p::make_ACTION_TRANSFORMATION_TRIM(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 91:\nYY_RULE_SETUP\n#line 606 \"seclang-scanner.ll\"\n{ return p::make_ACTION_TRANSFORMATION_TRIM_LEFT(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 92:\nYY_RULE_SETUP\n#line 607 \"seclang-scanner.ll\"\n{ return p::make_ACTION_TRANSFORMATION_TRIM_RIGHT(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 93:\nYY_RULE_SETUP\n#line 608 \"seclang-scanner.ll\"\n{ return p::make_ACTION_TRANSFORMATION_NORMALISE_PATH_WIN(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 94:\nYY_RULE_SETUP\n#line 609 \"seclang-scanner.ll\"\n{ return p::make_ACTION_TRANSFORMATION_NORMALISE_PATH(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 95:\nYY_RULE_SETUP\n#line 610 \"seclang-scanner.ll\"\n{ return p::make_ACTION_TRANSFORMATION_LENGTH(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 96:\nYY_RULE_SETUP\n#line 611 \"seclang-scanner.ll\"\n{ return p::make_ACTION_TRANSFORMATION_UTF8_TO_UNICODE(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 97:\nYY_RULE_SETUP\n#line 612 \"seclang-scanner.ll\"\n{ return p::make_ACTION_TRANSFORMATION_REMOVE_COMMENTS_CHAR(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 98:\nYY_RULE_SETUP\n#line 613 \"seclang-scanner.ll\"\n{ return p::make_ACTION_TRANSFORMATION_REMOVE_COMMENTS(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 99:\nYY_RULE_SETUP\n#line 614 \"seclang-scanner.ll\"\n{ return p::make_ACTION_TRANSFORMATION_REPLACE_COMMENTS(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 100:\nYY_RULE_SETUP\n#line 615 \"seclang-scanner.ll\"\n{ BEGIN(EXPECTING_ACTION_PREDICATE); return p::make_ACTION_LOG_DATA(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 101:\nYY_RULE_SETUP\n#line 617 \"seclang-scanner.ll\"\n{ return p::make_CONFIG_VALUE_DETC(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 102:\nYY_RULE_SETUP\n#line 618 \"seclang-scanner.ll\"\n{ return p::make_CONFIG_VALUE_ONLYARGS(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 103:\nYY_RULE_SETUP\n#line 619 \"seclang-scanner.ll\"\n{ return p::make_CONFIG_VALUE_OFF(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 104:\nYY_RULE_SETUP\n#line 620 \"seclang-scanner.ll\"\n{ return p::make_CONFIG_VALUE_ON(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 105:\nYY_RULE_SETUP\n#line 621 \"seclang-scanner.ll\"\n{ return p::make_CONFIG_VALUE_RELEVANT_ONLY(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 106:\n/* rule 106 can match eol */\nYY_RULE_SETUP\n#line 622 \"seclang-scanner.ll\"\n{ driver.loc.back()->lines(1); driver.loc.back()->step(); }\n\tYY_BREAK\ncase 107:\n/* rule 107 can match eol */\nYY_RULE_SETUP\n#line 623 \"seclang-scanner.ll\"\n{ driver.loc.back()->lines(1); driver.loc.back()->step(); }\n\tYY_BREAK\n\n\ncase 108:\nYY_RULE_SETUP\n#line 627 \"seclang-scanner.ll\"\n{ return p::make_COMMA(*driver.loc.back()); }\n\tYY_BREAK\n\n\ncase 109:\n/* rule 109 can match eol */\nYY_RULE_SETUP\n#line 632 \"seclang-scanner.ll\"\n{ BEGIN(INITIAL); yyless(yyleng); driver.loc.back()->lines(1); driver.loc.back()->step(); }\n\tYY_BREAK\ncase 110:\n/* rule 110 can match eol */\nYY_RULE_SETUP\n#line 633 \"seclang-scanner.ll\"\n{ BEGIN(INITIAL); yyless(yyleng); driver.loc.back()->lines(1); driver.loc.back()->step(); }\n\tYY_BREAK\n\n\ncase 111:\nYY_RULE_SETUP\n#line 638 \"seclang-scanner.ll\"\n{ BEGIN(INITIAL); yyless(yyleng); }\n\tYY_BREAK\ncase 112:\n/* rule 112 can match eol */\nYY_RULE_SETUP\n#line 639 \"seclang-scanner.ll\"\n{ BEGIN(INITIAL); yyless(1); }\n\tYY_BREAK\ncase 113:\n/* rule 113 can match eol */\nYY_RULE_SETUP\n#line 640 \"seclang-scanner.ll\"\n{ BEGIN(INITIAL); driver.loc.back()->lines(1); driver.loc.back()->step(); }\n\tYY_BREAK\n\n\ncase 114:\nYY_RULE_SETUP\n#line 645 \"seclang-scanner.ll\"\n{ BEGIN(INITIAL); yyless(yyleng); p::make_NEW_LINE(*driver.loc.back()); }\n\tYY_BREAK\ncase 115:\n/* rule 115 can match eol */\nYY_RULE_SETUP\n#line 646 \"seclang-scanner.ll\"\n{ BEGIN(INITIAL); yyless(1); }\n\tYY_BREAK\ncase 116:\n/* rule 116 can match eol */\nYY_RULE_SETUP\n#line 647 \"seclang-scanner.ll\"\n{ BEGIN(INITIAL); driver.loc.back()->lines(1); driver.loc.back()->step(); }\n\tYY_BREAK\n\n\ncase 117:\nYY_RULE_SETUP\n#line 652 \"seclang-scanner.ll\"\n{ BEGIN(LEXING_ERROR_ACTION); yyless(0); }\n\tYY_BREAK\n\n\ncase 118:\nYY_RULE_SETUP\n#line 657 \"seclang-scanner.ll\"\n{ BEGIN(ACTION_PREDICATE_ENDS_WITH_QUOTE); }\n\tYY_BREAK\ncase 119:\nYY_RULE_SETUP\n#line 658 \"seclang-scanner.ll\"\n{ BEGIN(ACTION_PREDICATE_ENDS_WITH_DOUBLE_QUOTE); }\n\tYY_BREAK\ncase 120:\nYY_RULE_SETUP\n#line 659 \"seclang-scanner.ll\"\n{ BEGIN(ACTION_PREDICATE_ENDS_WITH_COMMA_OR_DOUBLE_QUOTE); yyless(0); }\n\tYY_BREAK\n\n\ncase 121:\n/* rule 121 can match eol */\nYY_RULE_SETUP\n#line 664 \"seclang-scanner.ll\"\n{ driver.loc.back()->lines(1); driver.loc.back()->step(); }\n\tYY_BREAK\ncase 122:\n/* rule 122 can match eol */\nYY_RULE_SETUP\n#line 665 \"seclang-scanner.ll\"\n{ driver.loc.back()->lines(1); driver.loc.back()->step(); }\n\tYY_BREAK\n\n\ncase 123:\nYY_RULE_SETUP\n#line 669 \"seclang-scanner.ll\"\n{ yyless(1); BEGIN_PREVIOUS(); }\n\tYY_BREAK\ncase 124:\nYY_RULE_SETUP\n#line 670 \"seclang-scanner.ll\"\n{ BEGIN_PREVIOUS(); }\n\tYY_BREAK\ncase 125:\nYY_RULE_SETUP\n#line 671 \"seclang-scanner.ll\"\n{ BEGIN_PREVIOUS(); }\n\tYY_BREAK\n\n\ncase 126:\nYY_RULE_SETUP\n#line 675 \"seclang-scanner.ll\"\n{ BEGIN(EXPECTING_ACTIONS_ENDS_WITH_DOUBLE_QUOTE); yyless(yyleng); }\n\tYY_BREAK\ncase 127:\n/* rule 127 can match eol */\nYY_RULE_SETUP\n#line 676 \"seclang-scanner.ll\"\n{ return p::make_FREE_TEXT_QUOTE_MACRO_EXPANSION(yytext, *driver.loc.back()); }\n\tYY_BREAK\n\n\ncase 128:\nYY_RULE_SETUP\n#line 680 \"seclang-scanner.ll\"\n{ BEGIN(EXPECTING_ACTIONS_ENDS_WITH_DOUBLE_QUOTE); yyless(yyleng); }\n\tYY_BREAK\ncase 129:\n/* rule 129 can match eol */\nYY_RULE_SETUP\n#line 681 \"seclang-scanner.ll\"\n{ return p::make_FREE_TEXT_QUOTE_MACRO_EXPANSION(yytext, *driver.loc.back()); }\n\tYY_BREAK\n\n\ncase 130:\nYY_RULE_SETUP\n#line 685 \"seclang-scanner.ll\"\n{ yyless(0); BEGIN(EXPECTING_ACTIONS_ENDS_WITH_DOUBLE_QUOTE); }\n\tYY_BREAK\ncase 131:\nYY_RULE_SETUP\n#line 686 \"seclang-scanner.ll\"\n{ yyless(0); BEGIN(EXPECTING_ACTIONS_ENDS_WITH_DOUBLE_QUOTE);}\n\tYY_BREAK\ncase 132:\n/* rule 132 can match eol */\nYY_RULE_SETUP\n#line 687 \"seclang-scanner.ll\"\n{ return p::make_FREE_TEXT_QUOTE_MACRO_EXPANSION(yytext, *driver.loc.back()); }\n\tYY_BREAK\n\n\ncase 133:\nYY_RULE_SETUP\n#line 691 \"seclang-scanner.ll\"\n{ BEGINX(EXPECTING_ACTION_PREDICATE_VARIABLE); }\n\tYY_BREAK\ncase 134:\nYY_RULE_SETUP\n#line 692 \"seclang-scanner.ll\"\n{ BEGIN(LEXING_ERROR_VARIABLE); yyless(0); }\n\tYY_BREAK\n\n\ncase 135:\nYY_RULE_SETUP\n#line 696 \"seclang-scanner.ll\"\n{ return p::make_NOT(*driver.loc.back()); }\n\tYY_BREAK\ncase 136:\n/* rule 136 can match eol */\nYY_RULE_SETUP\n#line 697 \"seclang-scanner.ll\"\n{ BEGIN_ACTION_OPERATION(); yyless(0); }\n\tYY_BREAK\n\n\ncase 137:\nYY_RULE_SETUP\n#line 702 \"seclang-scanner.ll\"\n{ BEGIN_ACTION_WAITING_CONTENT(); return p::make_SETVAR_OPERATION_EQUALS_PLUS(*driver.loc.back()); }\n\tYY_BREAK\ncase 138:\nYY_RULE_SETUP\n#line 703 \"seclang-scanner.ll\"\n{ BEGIN_ACTION_WAITING_CONTENT(); return p::make_SETVAR_OPERATION_EQUALS_MINUS(*driver.loc.back()); }\n\tYY_BREAK\ncase 139:\nYY_RULE_SETUP\n#line 704 \"seclang-scanner.ll\"\n{ BEGIN_ACTION_WAITING_CONTENT(); return p::make_SETVAR_OPERATION_EQUALS(*driver.loc.back()); }\n\tYY_BREAK\n\n\ncase 140:\n/* rule 140 can match eol */\nYY_RULE_SETUP\n#line 708 \"seclang-scanner.ll\"\n{ BEGIN(EXPECTING_ACTIONS_ENDS_WITH_DOUBLE_QUOTE); yyless(0);}\n\tYY_BREAK\n\n\ncase 141:\nYY_RULE_SETUP\n#line 712 \"seclang-scanner.ll\"\n{ BEGIN(EXPECTING_ACTIONS_ENDS_WITH_DOUBLE_QUOTE); }\n\tYY_BREAK\ncase 142:\n/* rule 142 can match eol */\nYY_RULE_SETUP\n#line 713 \"seclang-scanner.ll\"\n{ BEGIN(LEXING_ERROR_ACTION); yyless(0); }\n\tYY_BREAK\n\n\ncase 143:\nYY_RULE_SETUP\n#line 721 \"seclang-scanner.ll\"\n{ BEGINX(EXPECTING_ACTION_PREDICATE_VARIABLE); }\n\tYY_BREAK\n\n\ncase 144:\n/* rule 144 can match eol */\nYY_RULE_SETUP\n#line 726 \"seclang-scanner.ll\"\n{ return p::make_FREE_TEXT_QUOTE_MACRO_EXPANSION(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 145:\n/* rule 145 can match eol */\nYY_RULE_SETUP\n#line 727 \"seclang-scanner.ll\"\n{ BEGIN(EXPECTING_ACTIONS_ENDS_WITH_DOUBLE_QUOTE); yyless(0); }\n\tYY_BREAK\n\n\ncase 146:\nYY_RULE_SETUP\n#line 732 \"seclang-scanner.ll\"\n{ BEGIN(EXPECTING_ACTIONS_ENDS_WITH_DOUBLE_QUOTE); }\n\tYY_BREAK\ncase 147:\n/* rule 147 can match eol */\nYY_RULE_SETUP\n#line 733 \"seclang-scanner.ll\"\n{ return p::make_FREE_TEXT_QUOTE_MACRO_EXPANSION(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 148:\n/* rule 148 can match eol */\nYY_RULE_SETUP\n#line 734 \"seclang-scanner.ll\"\n{ BEGIN(EXPECTING_ACTIONS_ENDS_WITH_DOUBLE_QUOTE); yyless(0); }\n\tYY_BREAK\n\n\ncase YY_STATE_EOF(FINISH_ACTIONS):\n#line 742 \"seclang-scanner.ll\"\n{ BEGIN(INITIAL); yyless(0); p::make_NEW_LINE(*driver.loc.back()); }\n\tYY_BREAK\ncase 149:\nYY_RULE_SETUP\n#line 743 \"seclang-scanner.ll\"\n{ BEGIN(INITIAL); }\n\tYY_BREAK\n\ncase 150:\n/* rule 150 can match eol */\nYY_RULE_SETUP\n#line 746 \"seclang-scanner.ll\"\n{ return p::make_CONFIG_COMPONENT_SIG(strchr(yytext, ' ') + 2, *driver.loc.back()); }\n\tYY_BREAK\ncase 151:\n/* rule 151 can match eol */\nYY_RULE_SETUP\n#line 747 \"seclang-scanner.ll\"\n{ return p::make_CONFIG_SEC_SERVER_SIG(strchr(yytext, ' ') + 2, *driver.loc.back()); }\n\tYY_BREAK\ncase 152:\n/* rule 152 can match eol */\nYY_RULE_SETUP\n#line 748 \"seclang-scanner.ll\"\n{ return p::make_CONFIG_SEC_WEB_APP_ID(parserSanitizer(strchr(yytext, ' ') + 2), *driver.loc.back()); }\n\tYY_BREAK\ncase 153:\nYY_RULE_SETUP\n#line 749 \"seclang-scanner.ll\"\n{ return p::make_CONFIG_SEC_WEB_APP_ID(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); }\n\tYY_BREAK\ncase 154:\nYY_RULE_SETUP\n#line 750 \"seclang-scanner.ll\"\n{ return p::make_CONFIG_CONTENT_INJECTION(*driver.loc.back()); }\n\tYY_BREAK\ncase 155:\nYY_RULE_SETUP\n#line 751 \"seclang-scanner.ll\"\n{ return p::make_CONFIG_DIR_AUDIT_DIR_MOD(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); }\n\tYY_BREAK\ncase 156:\nYY_RULE_SETUP\n#line 752 \"seclang-scanner.ll\"\n{ return p::make_CONFIG_DIR_AUDIT_DIR_MOD(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); }\n\tYY_BREAK\ncase 157:\nYY_RULE_SETUP\n#line 753 \"seclang-scanner.ll\"\n{ return p::make_CONFIG_DIR_AUDIT_DIR(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); }\n\tYY_BREAK\ncase 158:\nYY_RULE_SETUP\n#line 754 \"seclang-scanner.ll\"\n{ return p::make_CONFIG_DIR_AUDIT_DIR(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); }\n\tYY_BREAK\ncase 159:\nYY_RULE_SETUP\n#line 755 \"seclang-scanner.ll\"\n{ return p::make_CONFIG_SEC_ARGUMENT_SEPARATOR(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); }\n\tYY_BREAK\ncase 160:\nYY_RULE_SETUP\n#line 756 \"seclang-scanner.ll\"\n{ return p::make_CONFIG_SEC_ARGUMENT_SEPARATOR(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); }\n\tYY_BREAK\ncase 161:\nYY_RULE_SETUP\n#line 757 \"seclang-scanner.ll\"\n{ return p::make_CONFIG_DIR_AUDIT_ENG(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 162:\nYY_RULE_SETUP\n#line 758 \"seclang-scanner.ll\"\n{ return p::make_CONFIG_DIR_AUDIT_FLE_MOD(strchr(yytext, ' ') + 1, *driver.loc.back()); }\n\tYY_BREAK\ncase 163:\nYY_RULE_SETUP\n#line 759 \"seclang-scanner.ll\"\n{ return p::make_CONFIG_DIR_AUDIT_LOG2(strchr(yytext, ' ') + 1, *driver.loc.back()); }\n\tYY_BREAK\ncase 164:\nYY_RULE_SETUP\n#line 760 \"seclang-scanner.ll\"\n{ return p::make_CONFIG_DIR_AUDIT_LOG_P(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); }\n\tYY_BREAK\ncase 165:\nYY_RULE_SETUP\n#line 761 \"seclang-scanner.ll\"\n{ return p::make_CONFIG_DIR_AUDIT_LOG_P(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); }\n\tYY_BREAK\ncase 166:\nYY_RULE_SETUP\n#line 762 \"seclang-scanner.ll\"\n{ return p::make_CONFIG_DIR_AUDIT_LOG(strchr(yytext, ' ') + 1, *driver.loc.back()); }\n\tYY_BREAK\ncase 167:\nYY_RULE_SETUP\n#line 763 \"seclang-scanner.ll\"\n{ return p::make_CONFIG_DIR_AUDIT_LOG_FMT(*driver.loc.back()); }\n\tYY_BREAK\ncase 168:\nYY_RULE_SETUP\n#line 764 \"seclang-scanner.ll\"\n{ return p::make_JSON(*driver.loc.back()); }\n\tYY_BREAK\ncase 169:\nYY_RULE_SETUP\n#line 765 \"seclang-scanner.ll\"\n{ return p::make_NATIVE(*driver.loc.back()); }\n\tYY_BREAK\ncase 170:\nYY_RULE_SETUP\n#line 766 \"seclang-scanner.ll\"\n{ return p::make_CONFIG_DIR_AUDIT_LOG(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); }\n\tYY_BREAK\ncase 171:\nYY_RULE_SETUP\n#line 767 \"seclang-scanner.ll\"\n{ return p::make_CONFIG_DIR_AUDIT_STS(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); }\n\tYY_BREAK\ncase 172:\nYY_RULE_SETUP\n#line 768 \"seclang-scanner.ll\"\n{ return p::make_CONFIG_DIR_AUDIT_STS(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); }\n\tYY_BREAK\ncase 173:\nYY_RULE_SETUP\n#line 769 \"seclang-scanner.ll\"\n{ return p::make_CONFIG_DIR_AUDIT_PREFIX(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); }\n\tYY_BREAK\ncase 174:\nYY_RULE_SETUP\n#line 770 \"seclang-scanner.ll\"\n{ return p::make_CONFIG_DIR_AUDIT_PREFIX(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); }\n\tYY_BREAK\ncase 175:\nYY_RULE_SETUP\n#line 771 \"seclang-scanner.ll\"\n{ return p::make_CONFIG_DIR_AUDIT_TPE(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 176:\nYY_RULE_SETUP\n#line 774 \"seclang-scanner.ll\"\n{ return p::make_CONFIG_DIR_DEBUG_LOG(strchr(yytext, ' ') + 1, *driver.loc.back()); }\n\tYY_BREAK\ncase 177:\nYY_RULE_SETUP\n#line 775 \"seclang-scanner.ll\"\n{ return p::make_CONFIG_DIR_DEBUG_LOG(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); }\n\tYY_BREAK\ncase 178:\nYY_RULE_SETUP\n#line 776 \"seclang-scanner.ll\"\n{ return p::make_CONFIG_DIR_DEBUG_LVL(strchr(yytext, ' ') + 1, *driver.loc.back()); }\n\tYY_BREAK\ncase 179:\nYY_RULE_SETUP\n#line 777 \"seclang-scanner.ll\"\n{ return p::make_CONFIG_DIR_GEO_DB(strchr(yytext, ' ') + 1, *driver.loc.back()); }\n\tYY_BREAK\ncase 180:\nYY_RULE_SETUP\n#line 778 \"seclang-scanner.ll\"\n{ return p::make_CONFIG_DIR_PCRE_MATCH_LIMIT_RECURSION(strchr(yytext, ' ') + 1, *driver.loc.back()); }\n\tYY_BREAK\ncase 181:\nYY_RULE_SETUP\n#line 779 \"seclang-scanner.ll\"\n{ return p::make_CONFIG_DIR_PCRE_MATCH_LIMIT(strchr(yytext, ' ') + 1, *driver.loc.back()); }\n\tYY_BREAK\ncase 182:\nYY_RULE_SETUP\n#line 780 \"seclang-scanner.ll\"\n{ return p::make_CONFIG_DIR_ARGS_LIMIT(strchr(yytext, ' ') + 1, *driver.loc.back()); }\n\tYY_BREAK\ncase 183:\nYY_RULE_SETUP\n#line 781 \"seclang-scanner.ll\"\n{ return p::make_CONFIG_DIR_REQ_BODY_JSON_DEPTH_LIMIT(strchr(yytext, ' ') + 1, *driver.loc.back()); }\n\tYY_BREAK\ncase 184:\nYY_RULE_SETUP\n#line 782 \"seclang-scanner.ll\"\n{ return p::make_CONFIG_DIR_REQ_BODY_IN_MEMORY_LIMIT(strchr(yytext, ' ') + 1, *driver.loc.back()); }\n\tYY_BREAK\ncase 185:\nYY_RULE_SETUP\n#line 784 \"seclang-scanner.ll\"\n{ return p::make_CONFIG_DIR_REQ_BODY_LIMIT_ACTION(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 186:\nYY_RULE_SETUP\n#line 785 \"seclang-scanner.ll\"\n{ return p::make_CONFIG_DIR_REQ_BODY_LIMIT(strchr(yytext, ' ') + 1, *driver.loc.back()); }\n\tYY_BREAK\ncase 187:\nYY_RULE_SETUP\n#line 786 \"seclang-scanner.ll\"\n{ return p::make_CONFIG_DIR_REQ_BODY_NO_FILES_LIMIT(strchr(yytext, ' ') + 1, *driver.loc.back()); }\n\tYY_BREAK\ncase 188:\nYY_RULE_SETUP\n#line 787 \"seclang-scanner.ll\"\n{ return p::make_CONFIG_DIR_REQ_BODY(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 189:\nYY_RULE_SETUP\n#line 788 \"seclang-scanner.ll\"\n{ return p::make_CONFIG_DIR_RES_BODY_LIMIT_ACTION(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 190:\nYY_RULE_SETUP\n#line 789 \"seclang-scanner.ll\"\n{ return p::make_CONFIG_DIR_RES_BODY_LIMIT(strchr(yytext, ' ') + 1, *driver.loc.back()); }\n\tYY_BREAK\ncase 191:\nYY_RULE_SETUP\n#line 790 \"seclang-scanner.ll\"\n{ return p::make_CONFIG_DIR_RES_BODY(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 192:\nYY_RULE_SETUP\n#line 791 \"seclang-scanner.ll\"\n{ return p::make_CONFIG_DIR_RULE_ENG(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 193:\nYY_RULE_SETUP\n#line 792 \"seclang-scanner.ll\"\n{ return p::make_CONFIG_DIR_SEC_MARKER(strchr(yytext, ' ') + 1, *driver.loc.back()); }\n\tYY_BREAK\ncase 194:\nYY_RULE_SETUP\n#line 793 \"seclang-scanner.ll\"\n{ return p::make_CONFIG_DIR_SEC_MARKER(strchr(yytext, ' ') + 1, *driver.loc.back()); }\n\tYY_BREAK\ncase 195:\nYY_RULE_SETUP\n#line 794 \"seclang-scanner.ll\"\n{ return p::make_CONFIG_DIR_UNICODE_MAP_FILE(strchr(yytext, ' ') + 1, *driver.loc.back()); }\n\tYY_BREAK\ncase 196:\nYY_RULE_SETUP\n#line 795 \"seclang-scanner.ll\"\n{ return p::make_CONFIG_SEC_RULE_REMOVE_BY_ID(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); }\n\tYY_BREAK\ncase 197:\nYY_RULE_SETUP\n#line 796 \"seclang-scanner.ll\"\n{ return p::make_CONFIG_SEC_RULE_REMOVE_BY_MSG(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); }\n\tYY_BREAK\ncase 198:\nYY_RULE_SETUP\n#line 797 \"seclang-scanner.ll\"\n{ return p::make_CONFIG_SEC_RULE_REMOVE_BY_MSG(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); }\n\tYY_BREAK\ncase 199:\nYY_RULE_SETUP\n#line 798 \"seclang-scanner.ll\"\n{ return p::make_CONFIG_SEC_RULE_REMOVE_BY_TAG(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); }\n\tYY_BREAK\ncase 200:\nYY_RULE_SETUP\n#line 799 \"seclang-scanner.ll\"\n{ return p::make_CONFIG_SEC_RULE_REMOVE_BY_TAG(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); }\n\tYY_BREAK\ncase 201:\nYY_RULE_SETUP\n#line 800 \"seclang-scanner.ll\"\n{ state_variable_from = 1; BEGIN(TRANSACTION_TO_VARIABLE); return p::make_CONFIG_SEC_RULE_UPDATE_TARGET_BY_TAG(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); }\n\tYY_BREAK\ncase 202:\nYY_RULE_SETUP\n#line 801 \"seclang-scanner.ll\"\n{ state_variable_from = 1; BEGIN(TRANSACTION_TO_VARIABLE); return p::make_CONFIG_SEC_RULE_UPDATE_TARGET_BY_TAG(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); }\n\tYY_BREAK\ncase 203:\nYY_RULE_SETUP\n#line 802 \"seclang-scanner.ll\"\n{ state_variable_from = 1; BEGIN(TRANSACTION_TO_VARIABLE); return p::make_CONFIG_SEC_RULE_UPDATE_TARGET_BY_MSG(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); }\n\tYY_BREAK\ncase 204:\nYY_RULE_SETUP\n#line 803 \"seclang-scanner.ll\"\n{ state_variable_from = 1; BEGIN(TRANSACTION_TO_VARIABLE); return p::make_CONFIG_SEC_RULE_UPDATE_TARGET_BY_MSG(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); }\n\tYY_BREAK\ncase 205:\nYY_RULE_SETUP\n#line 804 \"seclang-scanner.ll\"\n{ state_variable_from = 1; BEGIN(TRANSACTION_TO_VARIABLE); return p::make_CONFIG_SEC_RULE_UPDATE_TARGET_BY_ID(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); }\n\tYY_BREAK\ncase 206:\nYY_RULE_SETUP\n#line 805 \"seclang-scanner.ll\"\n{ state_variable_from = 1; BEGIN(TRANSACTION_TO_VARIABLE); return p::make_CONFIG_SEC_RULE_UPDATE_TARGET_BY_ID(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); }\n\tYY_BREAK\ncase 207:\nYY_RULE_SETUP\n#line 806 \"seclang-scanner.ll\"\n{ BEGIN(TRANSACTION_FROM_OPERATOR_TO_ACTIONS); return p::make_CONFIG_SEC_RULE_UPDATE_ACTION_BY_ID(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); }\n\tYY_BREAK\ncase 208:\nYY_RULE_SETUP\n#line 807 \"seclang-scanner.ll\"\n{ BEGIN(TRANSACTION_FROM_OPERATOR_TO_ACTIONS); return p::make_CONFIG_SEC_RULE_UPDATE_ACTION_BY_ID(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); }\n\tYY_BREAK\ncase 209:\nYY_RULE_SETUP\n#line 808 \"seclang-scanner.ll\"\n{ return p::make_CONFIG_UPDLOAD_KEEP_FILES(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 210:\nYY_RULE_SETUP\n#line 809 \"seclang-scanner.ll\"\n{ return p::make_CONFIG_UPDLOAD_SAVE_TMP_FILES(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 211:\nYY_RULE_SETUP\n#line 810 \"seclang-scanner.ll\"\n{ return p::make_CONFIG_UPLOAD_DIR(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); }\n\tYY_BREAK\ncase 212:\nYY_RULE_SETUP\n#line 811 \"seclang-scanner.ll\"\n{ return p::make_CONFIG_UPLOAD_DIR(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); }\n\tYY_BREAK\ncase 213:\nYY_RULE_SETUP\n#line 812 \"seclang-scanner.ll\"\n{ return p::make_CONFIG_UPLOAD_FILE_LIMIT(strchr(yytext, ' ') + 1, *driver.loc.back()); }\n\tYY_BREAK\ncase 214:\nYY_RULE_SETUP\n#line 813 \"seclang-scanner.ll\"\n{ return p::make_CONFIG_UPLOAD_FILE_MODE(strchr(yytext, ' ') + 1, *driver.loc.back()); }\n\tYY_BREAK\ncase 215:\nYY_RULE_SETUP\n#line 814 \"seclang-scanner.ll\"\n{ return p::make_CONFIG_VALUE_ABORT(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 216:\nYY_RULE_SETUP\n#line 815 \"seclang-scanner.ll\"\n{ return p::make_CONFIG_VALUE_DETC(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 217:\nYY_RULE_SETUP\n#line 816 \"seclang-scanner.ll\"\n{ return p::make_CONFIG_VALUE_HTTPS(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 218:\nYY_RULE_SETUP\n#line 817 \"seclang-scanner.ll\"\n{ return p::make_CONFIG_VALUE_ONLYARGS(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 219:\nYY_RULE_SETUP\n#line 818 \"seclang-scanner.ll\"\n{ return p::make_CONFIG_VALUE_OFF(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 220:\nYY_RULE_SETUP\n#line 819 \"seclang-scanner.ll\"\n{ return p::make_CONFIG_VALUE_ON(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 221:\nYY_RULE_SETUP\n#line 820 \"seclang-scanner.ll\"\n{ return p::make_CONFIG_VALUE_PARALLEL(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 222:\nYY_RULE_SETUP\n#line 821 \"seclang-scanner.ll\"\n{ return p::make_CONFIG_VALUE_PROCESS_PARTIAL(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 223:\nYY_RULE_SETUP\n#line 822 \"seclang-scanner.ll\"\n{ return p::make_CONFIG_VALUE_REJECT(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 224:\nYY_RULE_SETUP\n#line 823 \"seclang-scanner.ll\"\n{ return p::make_CONFIG_VALUE_RELEVANT_ONLY(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 225:\nYY_RULE_SETUP\n#line 824 \"seclang-scanner.ll\"\n{ return p::make_CONFIG_VALUE_SERIAL(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 226:\nYY_RULE_SETUP\n#line 825 \"seclang-scanner.ll\"\n{ return p::make_CONFIG_VALUE_WARN(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 227:\nYY_RULE_SETUP\n#line 826 \"seclang-scanner.ll\"\n{ return p::make_CONFIG_XML_EXTERNAL_ENTITY(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 228:\nYY_RULE_SETUP\n#line 827 \"seclang-scanner.ll\"\n{ return p::make_CONFIG_XML_PARSE_XML_INTO_ARGS(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 229:\nYY_RULE_SETUP\n#line 828 \"seclang-scanner.ll\"\n{ return p::make_CONGIG_DIR_RESPONSE_BODY_MP(strchr(yytext, ' ') + 1, *driver.loc.back()); }\n\tYY_BREAK\ncase 230:\nYY_RULE_SETUP\n#line 829 \"seclang-scanner.ll\"\n{ return p::make_CONGIG_DIR_RESPONSE_BODY_MP_CLEAR(*driver.loc.back()); }\n\tYY_BREAK\ncase 231:\nYY_RULE_SETUP\n#line 830 \"seclang-scanner.ll\"\n{ return p::make_CONGIG_DIR_SEC_ARG_SEP(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 232:\nYY_RULE_SETUP\n#line 831 \"seclang-scanner.ll\"\n{ return p::make_CONGIG_DIR_SEC_COOKIE_FORMAT(strchr(yytext, ' ') + 1, *driver.loc.back()); }\n\tYY_BREAK\ncase 233:\nYY_RULE_SETUP\n#line 832 \"seclang-scanner.ll\"\n{ return p::make_CONFIG_SEC_COOKIEV0_SEPARATOR(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); }\n\tYY_BREAK\ncase 234:\nYY_RULE_SETUP\n#line 833 \"seclang-scanner.ll\"\n{ return p::make_CONFIG_SEC_COOKIEV0_SEPARATOR(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); }\n\tYY_BREAK\ncase 235:\nYY_RULE_SETUP\n#line 834 \"seclang-scanner.ll\"\n{ return p::make_CONGIG_DIR_SEC_DATA_DIR(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); }\n\tYY_BREAK\ncase 236:\nYY_RULE_SETUP\n#line 835 \"seclang-scanner.ll\"\n{ return p::make_CONGIG_DIR_SEC_DATA_DIR(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); }\n\tYY_BREAK\ncase 237:\nYY_RULE_SETUP\n#line 836 \"seclang-scanner.ll\"\n{ return p::make_CONGIG_DIR_SEC_STATUS_ENGINE(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 238:\nYY_RULE_SETUP\n#line 837 \"seclang-scanner.ll\"\n{ return p::make_CONGIG_DIR_SEC_TMP_DIR(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); }\n\tYY_BREAK\ncase 239:\nYY_RULE_SETUP\n#line 838 \"seclang-scanner.ll\"\n{ return p::make_CONGIG_DIR_SEC_TMP_DIR(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); }\n\tYY_BREAK\ncase 240:\nYY_RULE_SETUP\n#line 839 \"seclang-scanner.ll\"\n{ BEGIN(TRANSACTION_FROM_DIRECTIVE_TO_ACTIONS); return p::make_DIRECTIVE_SECRULESCRIPT(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); }\n\tYY_BREAK\ncase 241:\nYY_RULE_SETUP\n#line 840 \"seclang-scanner.ll\"\n{ BEGIN(TRANSACTION_FROM_DIRECTIVE_TO_ACTIONS); return p::make_DIRECTIVE_SECRULESCRIPT(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); }\n\tYY_BREAK\ncase 242:\nYY_RULE_SETUP\n#line 841 \"seclang-scanner.ll\"\n{ return p::make_CONFIG_SEC_CACHE_TRANSFORMATIONS(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 243:\nYY_RULE_SETUP\n#line 842 \"seclang-scanner.ll\"\n{ return p::make_CONFIG_SEC_CHROOT_DIR(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); }\n\tYY_BREAK\ncase 244:\nYY_RULE_SETUP\n#line 843 \"seclang-scanner.ll\"\n{ return p::make_CONFIG_SEC_CHROOT_DIR(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); }\n\tYY_BREAK\ncase 245:\nYY_RULE_SETUP\n#line 844 \"seclang-scanner.ll\"\n{ return p::make_CONFIG_CONN_ENGINE(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 246:\nYY_RULE_SETUP\n#line 845 \"seclang-scanner.ll\"\n{ return p::make_CONFIG_SEC_HASH_ENGINE(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 247:\nYY_RULE_SETUP\n#line 846 \"seclang-scanner.ll\"\n{ return p::make_CONFIG_SEC_HASH_KEY(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 248:\nYY_RULE_SETUP\n#line 847 \"seclang-scanner.ll\"\n{ return p::make_CONFIG_SEC_HASH_PARAM(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 249:\nYY_RULE_SETUP\n#line 848 \"seclang-scanner.ll\"\n{ return p::make_CONFIG_SEC_HASH_METHOD_RX(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 250:\nYY_RULE_SETUP\n#line 849 \"seclang-scanner.ll\"\n{ return p::make_CONFIG_SEC_HASH_METHOD_PM(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 251:\nYY_RULE_SETUP\n#line 850 \"seclang-scanner.ll\"\n{ return p::make_CONFIG_DIR_GSB_DB(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); }\n\tYY_BREAK\ncase 252:\nYY_RULE_SETUP\n#line 851 \"seclang-scanner.ll\"\n{ return p::make_CONFIG_DIR_GSB_DB(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); }\n\tYY_BREAK\ncase 253:\nYY_RULE_SETUP\n#line 852 \"seclang-scanner.ll\"\n{ return p::make_CONFIG_SEC_GUARDIAN_LOG(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 254:\nYY_RULE_SETUP\n#line 853 \"seclang-scanner.ll\"\n{ return p::make_CONFIG_SEC_INTERCEPT_ON_ERROR(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 255:\nYY_RULE_SETUP\n#line 854 \"seclang-scanner.ll\"\n{ return p::make_CONFIG_SEC_CONN_R_STATE_LIMIT(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 256:\nYY_RULE_SETUP\n#line 855 \"seclang-scanner.ll\"\n{ return p::make_CONFIG_SEC_CONN_W_STATE_LIMIT(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 257:\nYY_RULE_SETUP\n#line 856 \"seclang-scanner.ll\"\n{ return p::make_CONFIG_SEC_SENSOR_ID(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 258:\nYY_RULE_SETUP\n#line 857 \"seclang-scanner.ll\"\n{ return p::make_CONFIG_SEC_RULE_INHERITANCE(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 259:\nYY_RULE_SETUP\n#line 858 \"seclang-scanner.ll\"\n{ return p::make_CONFIG_SEC_RULE_PERF_TIME(strchr(yytext, ' ') + 1, *driver.loc.back()); }\n\tYY_BREAK\ncase 260:\nYY_RULE_SETUP\n#line 859 \"seclang-scanner.ll\"\n{ return p::make_CONFIG_SEC_STREAM_IN_BODY_INSPECTION(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 261:\nYY_RULE_SETUP\n#line 860 \"seclang-scanner.ll\"\n{ return p::make_CONFIG_SEC_STREAM_OUT_BODY_INSPECTION(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 262:\nYY_RULE_SETUP\n#line 861 \"seclang-scanner.ll\"\n{ return p::make_CONFIG_SEC_DISABLE_BACKEND_COMPRESS(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 263:\nYY_RULE_SETUP\n#line 863 \"seclang-scanner.ll\"\n{ BEGIN(TRANSACTION_TO_VARIABLE); return p::make_DIRECTIVE(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 264:\nYY_RULE_SETUP\n#line 864 \"seclang-scanner.ll\"\n{ BEGIN(TRANSACTION_FROM_DIRECTIVE_TO_ACTIONS); return p::make_CONFIG_DIR_SEC_DEFAULT_ACTION(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 265:\nYY_RULE_SETUP\n#line 865 \"seclang-scanner.ll\"\n{ BEGIN(TRANSACTION_FROM_DIRECTIVE_TO_ACTIONS); return p::make_CONFIG_DIR_SEC_ACTION(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 266:\nYY_RULE_SETUP\n#line 867 \"seclang-scanner.ll\"\n{ return p::make_CONFIG_SEC_REMOTE_RULES_FAIL_ACTION(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 267:\nYY_RULE_SETUP\n#line 868 \"seclang-scanner.ll\"\n{ return p::make_CONFIG_SEC_COLLECTION_TIMEOUT(strchr(yytext, ' ') + 1, *driver.loc.back()); }\n\tYY_BREAK\ncase 268:\nYY_RULE_SETUP\n#line 869 \"seclang-scanner.ll\"\n{ return p::make_CONFIG_SEC_HTTP_BLKEY(strchr(yytext, ' ') + 1, *driver.loc.back()); }\n\tYY_BREAK\ncase 269:\n/* rule 269 can match eol */\nYY_RULE_SETUP\n#line 870 \"seclang-scanner.ll\"\n{ driver.loc.back()->lines(1); driver.loc.back()->step(); }\n\tYY_BREAK\ncase 270:\n/* rule 270 can match eol */\nYY_RULE_SETUP\n#line 871 \"seclang-scanner.ll\"\n{ driver.loc.back()->lines(1); driver.loc.back()->step(); BEGIN(COMMENT); }\n\tYY_BREAK\ncase 271:\n/* rule 271 can match eol */\nYY_RULE_SETUP\n#line 872 \"seclang-scanner.ll\"\n{ driver.loc.back()->lines(1); driver.loc.back()->step(); BEGIN(COMMENT);  }\n\tYY_BREAK\ncase 272:\nYY_RULE_SETUP\n#line 873 \"seclang-scanner.ll\"\n{ driver.loc.back()->step(); /* comment, just ignore. */ }\n\tYY_BREAK\ncase 273:\nYY_RULE_SETUP\n#line 874 \"seclang-scanner.ll\"\n{ driver.loc.back()->step(); /* carriage return, just ignore. */}\n\tYY_BREAK\ncase 274:\nYY_RULE_SETUP\n#line 875 \"seclang-scanner.ll\"\n{ return p::make_QUOTATION_MARK(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 275:\nYY_RULE_SETUP\n#line 876 \"seclang-scanner.ll\"\n{ return p::make_COMMA(*driver.loc.back()); }\n\tYY_BREAK\n\ncase 276:\nYY_RULE_SETUP\n#line 879 \"seclang-scanner.ll\"\n{ BEGIN(EXPECTING_VARIABLE); }\n\tYY_BREAK\n\n\ncase 277:\nYY_RULE_SETUP\n#line 883 \"seclang-scanner.ll\"\n{ return p::make_PIPE(*driver.loc.back()); }\n\tYY_BREAK\ncase 278:\nYY_RULE_SETUP\n#line 884 \"seclang-scanner.ll\"\n{ return p::make_PIPE(*driver.loc.back()); }\n\tYY_BREAK\ncase 279:\nYY_RULE_SETUP\n#line 885 \"seclang-scanner.ll\"\n{ return p::make_QUOTATION_MARK(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 280:\nYY_RULE_SETUP\n#line 886 \"seclang-scanner.ll\"\n{ return p::make_VAR_EXCLUSION(*driver.loc.back()); }\n\tYY_BREAK\ncase 281:\nYY_RULE_SETUP\n#line 887 \"seclang-scanner.ll\"\n{ return p::make_VAR_COUNT(*driver.loc.back()); }\n\tYY_BREAK\n\n\ncase 282:\nYY_RULE_SETUP\n#line 891 \"seclang-scanner.ll\"\n{ if (state_variable_from == 0) { BEGIN(EXPECTING_OPERATOR_ENDS_WITH_SPACE); } else { state_variable_from = 0; BEGIN(INITIAL);} }\n\tYY_BREAK\ncase 283:\nYY_RULE_SETUP\n#line 892 \"seclang-scanner.ll\"\n{ if (state_variable_from == 0) { BEGIN(EXPECTING_OPERATOR_ENDS_WITH_QUOTE); } else { state_variable_from = 0; BEGIN(INITIAL);} }\n\tYY_BREAK\ncase 284:\n/* rule 284 can match eol */\nYY_RULE_SETUP\n#line 893 \"seclang-scanner.ll\"\n{ if (state_variable_from == 0) { BEGIN(EXPECTING_OPERATOR_ENDS_WITH_SPACE); } else { state_variable_from = 0; BEGIN(INITIAL);} }\n\tYY_BREAK\ncase 285:\n/* rule 285 can match eol */\nYY_RULE_SETUP\n#line 894 \"seclang-scanner.ll\"\n{ if (state_variable_from == 0) { BEGIN(EXPECTING_OPERATOR_ENDS_WITH_QUOTE); } else { state_variable_from = 0; BEGIN(INITIAL);} }\n\tYY_BREAK\ncase 286:\n/* rule 286 can match eol */\nYY_RULE_SETUP\n#line 895 \"seclang-scanner.ll\"\n{ if (state_variable_from == 0) { BEGIN(EXPECTING_OPERATOR_ENDS_WITH_SPACE); } else { state_variable_from = 0; BEGIN(INITIAL);} }\n\tYY_BREAK\ncase 287:\n/* rule 287 can match eol */\nYY_RULE_SETUP\n#line 896 \"seclang-scanner.ll\"\n{ if (state_variable_from == 0) { BEGIN(EXPECTING_OPERATOR_ENDS_WITH_QUOTE); } else { state_variable_from = 0; BEGIN(INITIAL);} }\n\tYY_BREAK\n\n\ncase 288:\nYY_RULE_SETUP\n#line 900 \"seclang-scanner.ll\"\n{  }\n\tYY_BREAK\ncase 289:\nYY_RULE_SETUP\n#line 901 \"seclang-scanner.ll\"\n{ BEGIN(EXPECTING_ACTIONS_ENDS_WITH_DOUBLE_QUOTE); }\n\tYY_BREAK\ncase 290:\n/* rule 290 can match eol */\nYY_RULE_SETUP\n#line 902 \"seclang-scanner.ll\"\n{ BEGIN(EXPECTING_ACTIONS_ENDS_WITH_DOUBLE_QUOTE); }\n\tYY_BREAK\ncase 291:\n/* rule 291 can match eol */\nYY_RULE_SETUP\n#line 903 \"seclang-scanner.ll\"\n{ BEGIN(EXPECTING_ACTIONS_ENDS_WITH_DOUBLE_QUOTE); }\n\tYY_BREAK\n\n\ncase 292:\nYY_RULE_SETUP\n#line 908 \"seclang-scanner.ll\"\n{ BEGIN(LEXING_ERROR_VARIABLE); yyless(0); }\n\tYY_BREAK\ncase 293:\nYY_RULE_SETUP\n#line 909 \"seclang-scanner.ll\"\n{ return p::make_VARIABLE_ARGS_COMBINED_SIZE(*driver.loc.back()); }\n\tYY_BREAK\ncase 294:\nYY_RULE_SETUP\n#line 910 \"seclang-scanner.ll\"\n{ return p::make_VARIABLE_ARGS_GET_NAMES(*driver.loc.back()); }\n\tYY_BREAK\ncase 295:\nYY_RULE_SETUP\n#line 911 \"seclang-scanner.ll\"\n{ BEGINX(EXPECTING_VAR_PARAMETER); return p::make_VARIABLE_ARGS_GET_NAMES(*driver.loc.back()); }\n\tYY_BREAK\ncase 296:\nYY_RULE_SETUP\n#line 912 \"seclang-scanner.ll\"\n{ return p::make_VARIABLE_ARGS_NAMES(*driver.loc.back()); }\n\tYY_BREAK\ncase 297:\nYY_RULE_SETUP\n#line 913 \"seclang-scanner.ll\"\n{ BEGINX(EXPECTING_VAR_PARAMETER); return p::make_VARIABLE_ARGS_NAMES(*driver.loc.back()); }\n\tYY_BREAK\ncase 298:\nYY_RULE_SETUP\n#line 914 \"seclang-scanner.ll\"\n{ return p::make_VARIABLE_ARGS_POST_NAMES(*driver.loc.back()); }\n\tYY_BREAK\ncase 299:\nYY_RULE_SETUP\n#line 915 \"seclang-scanner.ll\"\n{ BEGINX(EXPECTING_VAR_PARAMETER); return p::make_VARIABLE_ARGS_POST_NAMES(*driver.loc.back()); }\n\tYY_BREAK\ncase 300:\nYY_RULE_SETUP\n#line 916 \"seclang-scanner.ll\"\n{ return p::make_VARIABLE_AUTH_TYPE(*driver.loc.back()); }\n\tYY_BREAK\ncase 301:\nYY_RULE_SETUP\n#line 917 \"seclang-scanner.ll\"\n{ return p::make_VARIABLE_FILES_COMBINED_SIZE(*driver.loc.back()); }\n\tYY_BREAK\ncase 302:\nYY_RULE_SETUP\n#line 918 \"seclang-scanner.ll\"\n{ return p::make_VARIABLE_FULL_REQUEST_LENGTH(*driver.loc.back()); }\n\tYY_BREAK\ncase 303:\nYY_RULE_SETUP\n#line 919 \"seclang-scanner.ll\"\n{ return p::make_VARIABLE_FULL_REQUEST(*driver.loc.back()); }\n\tYY_BREAK\ncase 304:\nYY_RULE_SETUP\n#line 920 \"seclang-scanner.ll\"\n{ return p::make_VARIABLE_INBOUND_DATA_ERROR(*driver.loc.back()); }\n\tYY_BREAK\ncase 305:\nYY_RULE_SETUP\n#line 921 \"seclang-scanner.ll\"\n{ return p::make_VARIABLE_MATCHED_VAR_NAME(*driver.loc.back()); }\n\tYY_BREAK\ncase 306:\nYY_RULE_SETUP\n#line 922 \"seclang-scanner.ll\"\n{ return p::make_VARIABLE_MATCHED_VAR(*driver.loc.back()); }\n\tYY_BREAK\ncase 307:\nYY_RULE_SETUP\n#line 923 \"seclang-scanner.ll\"\n{ return p::make_VARIABLE_MSC_PCRE_ERROR(*driver.loc.back()); }\n\tYY_BREAK\ncase 308:\nYY_RULE_SETUP\n#line 924 \"seclang-scanner.ll\"\n{ return p::make_VARIABLE_MSC_PCRE_LIMITS_EXCEEDED(*driver.loc.back()); }\n\tYY_BREAK\ncase 309:\nYY_RULE_SETUP\n#line 925 \"seclang-scanner.ll\"\n{ return p::make_VARIABLE_MULTIPART_BOUNDARY_QUOTED(*driver.loc.back()); }\n\tYY_BREAK\ncase 310:\nYY_RULE_SETUP\n#line 926 \"seclang-scanner.ll\"\n{ return p::make_VARIABLE_MULTIPART_BOUNDARY_WHITESPACE(*driver.loc.back()); }\n\tYY_BREAK\ncase 311:\nYY_RULE_SETUP\n#line 927 \"seclang-scanner.ll\"\n{ return p::make_VARIABLE_MULTIPART_CRLF_LF_LINES(*driver.loc.back()); }\n\tYY_BREAK\ncase 312:\nYY_RULE_SETUP\n#line 928 \"seclang-scanner.ll\"\n{ return p::make_VARIABLE_MULTIPART_DATA_AFTER(*driver.loc.back()); }\n\tYY_BREAK\ncase 313:\nYY_RULE_SETUP\n#line 929 \"seclang-scanner.ll\"\n{ return p::make_VARIABLE_MULTIPART_DATA_BEFORE(*driver.loc.back()); }\n\tYY_BREAK\ncase 314:\nYY_RULE_SETUP\n#line 930 \"seclang-scanner.ll\"\n{ return p::make_VARIABLE_MULTIPART_FILE_LIMIT_EXCEEDED(*driver.loc.back()); }\n\tYY_BREAK\ncase 315:\nYY_RULE_SETUP\n#line 931 \"seclang-scanner.ll\"\n{ BEGINX(EXPECTING_VAR_PARAMETER); return p::make_VARIABLE_MULTIPART_FILENAME(*driver.loc.back()); }\n\tYY_BREAK\ncase 316:\nYY_RULE_SETUP\n#line 932 \"seclang-scanner.ll\"\n{ return p::make_VARIABLE_MULTIPART_FILENAME(*driver.loc.back()); }\n\tYY_BREAK\ncase 317:\nYY_RULE_SETUP\n#line 933 \"seclang-scanner.ll\"\n{ return p::make_VARIABLE_MULTIPART_HEADER_FOLDING(*driver.loc.back()); }\n\tYY_BREAK\ncase 318:\nYY_RULE_SETUP\n#line 934 \"seclang-scanner.ll\"\n{ return p::make_VARIABLE_MULTIPART_HEADER_FOLDING(*driver.loc.back()); }\n\tYY_BREAK\ncase 319:\nYY_RULE_SETUP\n#line 935 \"seclang-scanner.ll\"\n{ return p::make_VARIABLE_MULTIPART_INVALID_HEADER_FOLDING(*driver.loc.back()); }\n\tYY_BREAK\ncase 320:\nYY_RULE_SETUP\n#line 936 \"seclang-scanner.ll\"\n{ return p::make_VARIABLE_MULTIPART_INVALID_PART(*driver.loc.back()); }\n\tYY_BREAK\ncase 321:\nYY_RULE_SETUP\n#line 937 \"seclang-scanner.ll\"\n{ return p::make_VARIABLE_MULTIPART_INVALID_QUOTING(*driver.loc.back()); }\n\tYY_BREAK\ncase 322:\nYY_RULE_SETUP\n#line 938 \"seclang-scanner.ll\"\n{ return p::make_VARIABLE_MULTIPART_LF_LINE(*driver.loc.back()); }\n\tYY_BREAK\ncase 323:\nYY_RULE_SETUP\n#line 939 \"seclang-scanner.ll\"\n{ return p::make_VARIABLE_MULTIPART_MISSING_SEMICOLON(*driver.loc.back()); }\n\tYY_BREAK\ncase 324:\nYY_RULE_SETUP\n#line 940 \"seclang-scanner.ll\"\n{ return p::make_VARIABLE_MULTIPART_SEMICOLON_MISSING(*driver.loc.back()); }\n\tYY_BREAK\ncase 325:\nYY_RULE_SETUP\n#line 941 \"seclang-scanner.ll\"\n{ BEGINX(EXPECTING_VAR_PARAMETER); return p::make_VARIABLE_MULTIPART_NAME(*driver.loc.back()); }\n\tYY_BREAK\ncase 326:\nYY_RULE_SETUP\n#line 942 \"seclang-scanner.ll\"\n{ return p::make_VARIABLE_MULTIPART_NAME(*driver.loc.back()); }\n\tYY_BREAK\ncase 327:\nYY_RULE_SETUP\n#line 943 \"seclang-scanner.ll\"\n{ return p::make_VARIABLE_MULTIPART_STRICT_ERROR(*driver.loc.back()); }\n\tYY_BREAK\ncase 328:\nYY_RULE_SETUP\n#line 944 \"seclang-scanner.ll\"\n{ return p::make_VARIABLE_MULTIPART_UNMATCHED_BOUNDARY(*driver.loc.back()); }\n\tYY_BREAK\ncase 329:\nYY_RULE_SETUP\n#line 945 \"seclang-scanner.ll\"\n{ return p::make_VARIABLE_OUTBOUND_DATA_ERROR(*driver.loc.back()); }\n\tYY_BREAK\ncase 330:\nYY_RULE_SETUP\n#line 946 \"seclang-scanner.ll\"\n{ return p::make_VARIABLE_PATH_INFO(*driver.loc.back()); }\n\tYY_BREAK\ncase 331:\nYY_RULE_SETUP\n#line 947 \"seclang-scanner.ll\"\n{ return p::make_VARIABLE_QUERY_STRING(*driver.loc.back()); }\n\tYY_BREAK\ncase 332:\nYY_RULE_SETUP\n#line 948 \"seclang-scanner.ll\"\n{ return p::make_VARIABLE_REMOTE_ADDR(*driver.loc.back()); }\n\tYY_BREAK\ncase 333:\nYY_RULE_SETUP\n#line 949 \"seclang-scanner.ll\"\n{ return p::make_VARIABLE_REMOTE_HOST(*driver.loc.back()); }\n\tYY_BREAK\ncase 334:\nYY_RULE_SETUP\n#line 950 \"seclang-scanner.ll\"\n{ return p::make_VARIABLE_REMOTE_PORT(*driver.loc.back()); }\n\tYY_BREAK\ncase 335:\nYY_RULE_SETUP\n#line 951 \"seclang-scanner.ll\"\n{ return p::make_VARIABLE_REQBODY_ERROR_MSG(*driver.loc.back()); }\n\tYY_BREAK\ncase 336:\nYY_RULE_SETUP\n#line 952 \"seclang-scanner.ll\"\n{ return p::make_VARIABLE_REQBODY_ERROR(*driver.loc.back()); }\n\tYY_BREAK\ncase 337:\nYY_RULE_SETUP\n#line 953 \"seclang-scanner.ll\"\n{ return p::make_VARIABLE_REQBODY_PROCESSOR_ERROR_MSG(*driver.loc.back()); }\n\tYY_BREAK\ncase 338:\nYY_RULE_SETUP\n#line 954 \"seclang-scanner.ll\"\n{ return p::make_VARIABLE_REQBODY_PROCESSOR_ERROR(*driver.loc.back()); }\n\tYY_BREAK\ncase 339:\nYY_RULE_SETUP\n#line 955 \"seclang-scanner.ll\"\n{ return p::make_VARIABLE_REQBODY_PROCESSOR(*driver.loc.back()); }\n\tYY_BREAK\ncase 340:\nYY_RULE_SETUP\n#line 956 \"seclang-scanner.ll\"\n{ return p::make_VARIABLE_REQUEST_BASENAME(*driver.loc.back()); }\n\tYY_BREAK\ncase 341:\nYY_RULE_SETUP\n#line 957 \"seclang-scanner.ll\"\n{ return p::make_VARIABLE_REQUEST_BODY_LENGTH(*driver.loc.back()); }\n\tYY_BREAK\ncase 342:\nYY_RULE_SETUP\n#line 958 \"seclang-scanner.ll\"\n{ return p::make_VARIABLE_REQUEST_BODY(*driver.loc.back()); }\n\tYY_BREAK\ncase 343:\nYY_RULE_SETUP\n#line 959 \"seclang-scanner.ll\"\n{ return p::make_VARIABLE_REQUEST_FILE_NAME(*driver.loc.back()); }\n\tYY_BREAK\ncase 344:\nYY_RULE_SETUP\n#line 960 \"seclang-scanner.ll\"\n{ return p::make_VARIABLE_REQUEST_HEADERS_NAMES(*driver.loc.back()); }\n\tYY_BREAK\ncase 345:\nYY_RULE_SETUP\n#line 961 \"seclang-scanner.ll\"\n{ BEGINX(EXPECTING_VAR_PARAMETER); return p::make_VARIABLE_REQUEST_HEADERS_NAMES(*driver.loc.back()); }\n\tYY_BREAK\ncase 346:\nYY_RULE_SETUP\n#line 962 \"seclang-scanner.ll\"\n{ return p::make_VARIABLE_REQUEST_LINE(*driver.loc.back()); }\n\tYY_BREAK\ncase 347:\nYY_RULE_SETUP\n#line 963 \"seclang-scanner.ll\"\n{ return p::make_VARIABLE_REQUEST_METHOD(*driver.loc.back()); }\n\tYY_BREAK\ncase 348:\nYY_RULE_SETUP\n#line 964 \"seclang-scanner.ll\"\n{ return p::make_VARIABLE_REQUEST_PROTOCOL(*driver.loc.back()); }\n\tYY_BREAK\ncase 349:\nYY_RULE_SETUP\n#line 965 \"seclang-scanner.ll\"\n{ return p::make_VARIABLE_REQUEST_URI_RAW(*driver.loc.back()); }\n\tYY_BREAK\ncase 350:\nYY_RULE_SETUP\n#line 966 \"seclang-scanner.ll\"\n{ return p::make_VARIABLE_REQUEST_URI(*driver.loc.back()); }\n\tYY_BREAK\ncase 351:\nYY_RULE_SETUP\n#line 967 \"seclang-scanner.ll\"\n{ return p::make_VARIABLE_RESPONSE_BODY(*driver.loc.back()); }\n\tYY_BREAK\ncase 352:\nYY_RULE_SETUP\n#line 968 \"seclang-scanner.ll\"\n{ return p::make_VARIABLE_RESPONSE_CONTENT_LENGTH(*driver.loc.back()); }\n\tYY_BREAK\ncase 353:\nYY_RULE_SETUP\n#line 969 \"seclang-scanner.ll\"\n{ return p::make_VARIABLE_RESPONSE_CONTENT_TYPE(*driver.loc.back()); }\n\tYY_BREAK\ncase 354:\nYY_RULE_SETUP\n#line 970 \"seclang-scanner.ll\"\n{ return p::make_VARIABLE_RESPONSE_HEADERS_NAMES(*driver.loc.back()); }\n\tYY_BREAK\ncase 355:\nYY_RULE_SETUP\n#line 971 \"seclang-scanner.ll\"\n{ BEGINX(EXPECTING_VAR_PARAMETER); return p::make_VARIABLE_RESPONSE_HEADERS_NAMES(*driver.loc.back()); }\n\tYY_BREAK\ncase 356:\nYY_RULE_SETUP\n#line 972 \"seclang-scanner.ll\"\n{ return p::make_VARIABLE_RESPONSE_PROTOCOL(*driver.loc.back()); }\n\tYY_BREAK\ncase 357:\nYY_RULE_SETUP\n#line 973 \"seclang-scanner.ll\"\n{ return p::make_VARIABLE_RESPONSE_STATUS(*driver.loc.back()); }\n\tYY_BREAK\ncase 358:\nYY_RULE_SETUP\n#line 974 \"seclang-scanner.ll\"\n{ return p::make_VARIABLE_SERVER_ADDR(*driver.loc.back()); }\n\tYY_BREAK\ncase 359:\nYY_RULE_SETUP\n#line 975 \"seclang-scanner.ll\"\n{ return p::make_VARIABLE_SERVER_NAME(*driver.loc.back()); }\n\tYY_BREAK\ncase 360:\nYY_RULE_SETUP\n#line 976 \"seclang-scanner.ll\"\n{ return p::make_VARIABLE_SERVER_PORT(*driver.loc.back()); }\n\tYY_BREAK\ncase 361:\nYY_RULE_SETUP\n#line 977 \"seclang-scanner.ll\"\n{ return p::make_VARIABLE_SESSION_ID(*driver.loc.back()); }\n\tYY_BREAK\ncase 362:\nYY_RULE_SETUP\n#line 978 \"seclang-scanner.ll\"\n{ return p::make_VARIABLE_UNIQUE_ID(*driver.loc.back()); }\n\tYY_BREAK\ncase 363:\nYY_RULE_SETUP\n#line 979 \"seclang-scanner.ll\"\n{ return p::make_VARIABLE_URL_ENCODED_ERROR(*driver.loc.back()); }\n\tYY_BREAK\ncase 364:\nYY_RULE_SETUP\n#line 980 \"seclang-scanner.ll\"\n{ return p::make_VARIABLE_USER_ID(*driver.loc.back()); }\n\tYY_BREAK\ncase 365:\nYY_RULE_SETUP\n#line 981 \"seclang-scanner.ll\"\n{ return p::make_VARIABLE_WEB_APP_ID(*driver.loc.back()); }\n\tYY_BREAK\ncase 366:\nYY_RULE_SETUP\n#line 982 \"seclang-scanner.ll\"\n{ return p::make_VARIABLE_ARGS(*driver.loc.back()); }\n\tYY_BREAK\ncase 367:\nYY_RULE_SETUP\n#line 983 \"seclang-scanner.ll\"\n{ BEGINX(EXPECTING_VAR_PARAMETER); return p::make_VARIABLE_ARGS(*driver.loc.back()); }\n\tYY_BREAK\ncase 368:\nYY_RULE_SETUP\n#line 984 \"seclang-scanner.ll\"\n{ return p::make_VARIABLE_ARGS_GET(*driver.loc.back()); }\n\tYY_BREAK\ncase 369:\nYY_RULE_SETUP\n#line 985 \"seclang-scanner.ll\"\n{ BEGINX(EXPECTING_VAR_PARAMETER); return p::make_VARIABLE_ARGS_GET(*driver.loc.back()); }\n\tYY_BREAK\ncase 370:\nYY_RULE_SETUP\n#line 986 \"seclang-scanner.ll\"\n{ return p::make_VARIABLE_ARGS_POST(*driver.loc.back()); }\n\tYY_BREAK\ncase 371:\nYY_RULE_SETUP\n#line 987 \"seclang-scanner.ll\"\n{ BEGINX(EXPECTING_VAR_PARAMETER); return p::make_VARIABLE_ARGS_POST(*driver.loc.back()); }\n\tYY_BREAK\ncase 372:\nYY_RULE_SETUP\n#line 988 \"seclang-scanner.ll\"\n{ return p::make_VARIABLE_FILES_SIZES(*driver.loc.back()); }\n\tYY_BREAK\ncase 373:\nYY_RULE_SETUP\n#line 989 \"seclang-scanner.ll\"\n{ BEGINX(EXPECTING_VAR_PARAMETER); return p::make_VARIABLE_FILES_SIZES(*driver.loc.back()); }\n\tYY_BREAK\ncase 374:\nYY_RULE_SETUP\n#line 990 \"seclang-scanner.ll\"\n{ return p::make_VARIABLE_FILES_NAMES(*driver.loc.back()); }\n\tYY_BREAK\ncase 375:\nYY_RULE_SETUP\n#line 991 \"seclang-scanner.ll\"\n{ BEGINX(EXPECTING_VAR_PARAMETER); return p::make_VARIABLE_FILES_NAMES(*driver.loc.back()); }\n\tYY_BREAK\ncase 376:\nYY_RULE_SETUP\n#line 992 \"seclang-scanner.ll\"\n{ return p::make_VARIABLE_FILES_TMP_CONTENT(*driver.loc.back()); }\n\tYY_BREAK\ncase 377:\nYY_RULE_SETUP\n#line 993 \"seclang-scanner.ll\"\n{ BEGINX(EXPECTING_VAR_PARAMETER); return p::make_VARIABLE_FILES_TMP_CONTENT(*driver.loc.back()); }\n\tYY_BREAK\ncase 378:\nYY_RULE_SETUP\n#line 994 \"seclang-scanner.ll\"\n{ return p::make_VARIABLE_MATCHED_VARS_NAMES(*driver.loc.back()); }\n\tYY_BREAK\ncase 379:\nYY_RULE_SETUP\n#line 995 \"seclang-scanner.ll\"\n{ BEGINX(EXPECTING_VAR_PARAMETER); return p::make_VARIABLE_MATCHED_VARS_NAMES(*driver.loc.back()); }\n\tYY_BREAK\ncase 380:\nYY_RULE_SETUP\n#line 996 \"seclang-scanner.ll\"\n{ return p::make_VARIABLE_MATCHED_VARS(*driver.loc.back()); }\n\tYY_BREAK\ncase 381:\nYY_RULE_SETUP\n#line 997 \"seclang-scanner.ll\"\n{ BEGINX(EXPECTING_VAR_PARAMETER); return p::make_VARIABLE_MATCHED_VARS(*driver.loc.back()); }\n\tYY_BREAK\ncase 382:\nYY_RULE_SETUP\n#line 998 \"seclang-scanner.ll\"\n{ return p::make_VARIABLE_FILES(*driver.loc.back()); }\n\tYY_BREAK\ncase 383:\nYY_RULE_SETUP\n#line 999 \"seclang-scanner.ll\"\n{ BEGINX(EXPECTING_VAR_PARAMETER); return p::make_VARIABLE_FILES(*driver.loc.back()); }\n\tYY_BREAK\ncase 384:\nYY_RULE_SETUP\n#line 1000 \"seclang-scanner.ll\"\n{ return p::make_VARIABLE_REQUEST_COOKIES(*driver.loc.back()); }\n\tYY_BREAK\ncase 385:\nYY_RULE_SETUP\n#line 1001 \"seclang-scanner.ll\"\n{ BEGINX(EXPECTING_VAR_PARAMETER); return p::make_VARIABLE_REQUEST_COOKIES(*driver.loc.back()); }\n\tYY_BREAK\ncase 386:\nYY_RULE_SETUP\n#line 1002 \"seclang-scanner.ll\"\n{ return p::make_VARIABLE_REQUEST_HEADERS(*driver.loc.back()); }\n\tYY_BREAK\ncase 387:\nYY_RULE_SETUP\n#line 1003 \"seclang-scanner.ll\"\n{ BEGINX(EXPECTING_VAR_PARAMETER); return p::make_VARIABLE_REQUEST_HEADERS(*driver.loc.back()); }\n\tYY_BREAK\ncase 388:\nYY_RULE_SETUP\n#line 1004 \"seclang-scanner.ll\"\n{ return p::make_VARIABLE_RESPONSE_HEADERS(*driver.loc.back()); }\n\tYY_BREAK\ncase 389:\nYY_RULE_SETUP\n#line 1005 \"seclang-scanner.ll\"\n{ BEGINX(EXPECTING_VAR_PARAMETER); return p::make_VARIABLE_RESPONSE_HEADERS(*driver.loc.back()); }\n\tYY_BREAK\ncase 390:\nYY_RULE_SETUP\n#line 1006 \"seclang-scanner.ll\"\n{ return p::make_VARIABLE_GEO(*driver.loc.back()); }\n\tYY_BREAK\ncase 391:\nYY_RULE_SETUP\n#line 1007 \"seclang-scanner.ll\"\n{ BEGINX(EXPECTING_VAR_PARAMETER); return p::make_VARIABLE_GEO(*driver.loc.back()); }\n\tYY_BREAK\ncase 392:\nYY_RULE_SETUP\n#line 1008 \"seclang-scanner.ll\"\n{ return p::make_VARIABLE_REQUEST_COOKIES_NAMES(*driver.loc.back()); }\n\tYY_BREAK\ncase 393:\nYY_RULE_SETUP\n#line 1009 \"seclang-scanner.ll\"\n{ BEGINX(EXPECTING_VAR_PARAMETER); return p::make_VARIABLE_REQUEST_COOKIES_NAMES(*driver.loc.back()); }\n\tYY_BREAK\ncase 394:\nYY_RULE_SETUP\n#line 1010 \"seclang-scanner.ll\"\n{ return p::make_VARIABLE_MULTIPART_PART_HEADERS(*driver.loc.back()); }\n\tYY_BREAK\ncase 395:\nYY_RULE_SETUP\n#line 1011 \"seclang-scanner.ll\"\n{ BEGINX(EXPECTING_VAR_PARAMETER); return p::make_VARIABLE_MULTIPART_PART_HEADERS(*driver.loc.back()); }\n\tYY_BREAK\ncase 396:\nYY_RULE_SETUP\n#line 1012 \"seclang-scanner.ll\"\n{ return p::make_VARIABLE_RULE(*driver.loc.back()); }\n\tYY_BREAK\ncase 397:\nYY_RULE_SETUP\n#line 1013 \"seclang-scanner.ll\"\n{ BEGINX(EXPECTING_VAR_PARAMETER); return p::make_VARIABLE_RULE(*driver.loc.back()); }\n\tYY_BREAK\ncase 398:\nYY_RULE_SETUP\n#line 1014 \"seclang-scanner.ll\"\n{ return p::make_VARIABLE_FILES_TMP_NAMES(*driver.loc.back()); }\n\tYY_BREAK\ncase 399:\nYY_RULE_SETUP\n#line 1015 \"seclang-scanner.ll\"\n{ BEGINX(EXPECTING_VAR_PARAMETER); return p::make_VARIABLE_FILES_TMP_NAMES(*driver.loc.back()); }\n\tYY_BREAK\ncase 400:\nYY_RULE_SETUP\n#line 1016 \"seclang-scanner.ll\"\n{ return p::make_RUN_TIME_VAR_XML(*driver.loc.back()); }\n\tYY_BREAK\ncase 401:\nYY_RULE_SETUP\n#line 1017 \"seclang-scanner.ll\"\n{ BEGINX(EXPECTING_VAR_PARAMETER); return p::make_RUN_TIME_VAR_XML(*driver.loc.back()); }\n\tYY_BREAK\ncase 402:\nYY_RULE_SETUP\n#line 1018 \"seclang-scanner.ll\"\n{ return p::make_RUN_TIME_VAR_ENV(*driver.loc.back()); }\n\tYY_BREAK\ncase 403:\nYY_RULE_SETUP\n#line 1019 \"seclang-scanner.ll\"\n{ BEGINX(EXPECTING_VAR_PARAMETER); return p::make_RUN_TIME_VAR_ENV(*driver.loc.back()); }\n\tYY_BREAK\ncase 404:\nYY_RULE_SETUP\n#line 1020 \"seclang-scanner.ll\"\n{ return p::make_RUN_TIME_VAR_BLD(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 405:\nYY_RULE_SETUP\n#line 1021 \"seclang-scanner.ll\"\n{ return p::make_RUN_TIME_VAR_DUR(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 406:\nYY_RULE_SETUP\n#line 1022 \"seclang-scanner.ll\"\n{ return p::make_RUN_TIME_VAR_HSV(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 407:\nYY_RULE_SETUP\n#line 1023 \"seclang-scanner.ll\"\n{ return p::make_RUN_TIME_VAR_REMOTE_USER(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 408:\nYY_RULE_SETUP\n#line 1024 \"seclang-scanner.ll\"\n{ return p::make_RUN_TIME_VAR_TIME_DAY(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 409:\nYY_RULE_SETUP\n#line 1025 \"seclang-scanner.ll\"\n{ return p::make_RUN_TIME_VAR_TIME_EPOCH(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 410:\nYY_RULE_SETUP\n#line 1026 \"seclang-scanner.ll\"\n{ return p::make_RUN_TIME_VAR_TIME_HOUR(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 411:\nYY_RULE_SETUP\n#line 1027 \"seclang-scanner.ll\"\n{ return p::make_RUN_TIME_VAR_TIME_MIN(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 412:\nYY_RULE_SETUP\n#line 1028 \"seclang-scanner.ll\"\n{ return p::make_RUN_TIME_VAR_TIME_MON(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 413:\nYY_RULE_SETUP\n#line 1029 \"seclang-scanner.ll\"\n{ return p::make_RUN_TIME_VAR_TIME_SEC(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 414:\nYY_RULE_SETUP\n#line 1030 \"seclang-scanner.ll\"\n{ return p::make_RUN_TIME_VAR_TIME_YEAR(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 415:\nYY_RULE_SETUP\n#line 1031 \"seclang-scanner.ll\"\n{ return p::make_RUN_TIME_VAR_TIME(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 416:\nYY_RULE_SETUP\n#line 1032 \"seclang-scanner.ll\"\n{ return p::make_RUN_TIME_VAR_TIME_WDAY(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 417:\nYY_RULE_SETUP\n#line 1035 \"seclang-scanner.ll\"\n{ driver.error (*driver.loc.back(), \"Variable VARIABLE_WEBSERVER_ERROR_LOG is not supported by libModSecurity\", \"\"); throw p::syntax_error(*driver.loc.back(), \"\");}\n\tYY_BREAK\ncase 418:\nYY_RULE_SETUP\n#line 1036 \"seclang-scanner.ll\"\n{ return p::make_VARIABLE_GLOBAL(*driver.loc.back()); }\n\tYY_BREAK\ncase 419:\nYY_RULE_SETUP\n#line 1037 \"seclang-scanner.ll\"\n{ return p::make_VARIABLE_IP(*driver.loc.back()); }\n\tYY_BREAK\ncase 420:\nYY_RULE_SETUP\n#line 1038 \"seclang-scanner.ll\"\n{ return p::make_VARIABLE_RESOURCE(*driver.loc.back()); }\n\tYY_BREAK\ncase 421:\nYY_RULE_SETUP\n#line 1039 \"seclang-scanner.ll\"\n{ return p::make_VARIABLE_SESSION(*driver.loc.back()); }\n\tYY_BREAK\ncase 422:\nYY_RULE_SETUP\n#line 1040 \"seclang-scanner.ll\"\n{ return p::make_VARIABLE_STATUS(*driver.loc.back()); }\n\tYY_BREAK\ncase 423:\nYY_RULE_SETUP\n#line 1041 \"seclang-scanner.ll\"\n{ return p::make_VARIABLE_STATUS_LINE(*driver.loc.back()); }\n\tYY_BREAK\ncase 424:\nYY_RULE_SETUP\n#line 1042 \"seclang-scanner.ll\"\n{ return p::make_VARIABLE_TX(*driver.loc.back()); }\n\tYY_BREAK\ncase 425:\nYY_RULE_SETUP\n#line 1043 \"seclang-scanner.ll\"\n{ return p::make_VARIABLE_USER(*driver.loc.back()); }\n\tYY_BREAK\n\n\ncase 426:\nYY_RULE_SETUP\n#line 1047 \"seclang-scanner.ll\"\n{ BEGINX_(); return p::make_VARIABLE_GLOBAL(*driver.loc.back()); }\n\tYY_BREAK\ncase 427:\nYY_RULE_SETUP\n#line 1048 \"seclang-scanner.ll\"\n{ BEGINX_(); return p::make_VARIABLE_IP(*driver.loc.back()); }\n\tYY_BREAK\ncase 428:\nYY_RULE_SETUP\n#line 1049 \"seclang-scanner.ll\"\n{ BEGINX_(); return p::make_VARIABLE_RESOURCE(*driver.loc.back()); }\n\tYY_BREAK\ncase 429:\nYY_RULE_SETUP\n#line 1050 \"seclang-scanner.ll\"\n{ BEGINX_(); return p::make_VARIABLE_SESSION(*driver.loc.back()); }\n\tYY_BREAK\ncase 430:\nYY_RULE_SETUP\n#line 1051 \"seclang-scanner.ll\"\n{ BEGINX_(); return p::make_VARIABLE_TX(*driver.loc.back()); }\n\tYY_BREAK\ncase 431:\nYY_RULE_SETUP\n#line 1052 \"seclang-scanner.ll\"\n{ BEGINX_(); return p::make_VARIABLE_USER(*driver.loc.back()); }\n\tYY_BREAK\n\n\ncase 432:\nYY_RULE_SETUP\n#line 1057 \"seclang-scanner.ll\"\n{ BEGIN_ACTION_WAITING_CONTENT(); return p::make_SETVAR_OPERATION_EQUALS_PLUS(*driver.loc.back()); }\n\tYY_BREAK\ncase 433:\nYY_RULE_SETUP\n#line 1058 \"seclang-scanner.ll\"\n{ BEGIN_ACTION_WAITING_CONTENT(); return p::make_SETVAR_OPERATION_EQUALS_MINUS(*driver.loc.back()); }\n\tYY_BREAK\ncase 434:\nYY_RULE_SETUP\n#line 1059 \"seclang-scanner.ll\"\n{ BEGIN_ACTION_WAITING_CONTENT(); return p::make_SETVAR_OPERATION_EQUALS(*driver.loc.back()); }\n\tYY_BREAK\ncase 435:\n/* rule 435 can match eol */\nYY_RULE_SETUP\n#line 1060 \"seclang-scanner.ll\"\n{ BEGIN_PREVIOUS(); yyless(yyleng - 1); return p::make_DICT_ELEMENT_REGEXP(std::string(yytext, 1, yyleng-2), *driver.loc.back()); }\n\tYY_BREAK\ncase 436:\n/* rule 436 can match eol */\nYY_RULE_SETUP\n#line 1061 \"seclang-scanner.ll\"\n{ BEGIN_PREVIOUS(); yyless(yyleng - 1); return p::make_DICT_ELEMENT_REGEXP(std::string(yytext, 1, yyleng-2), *driver.loc.back()); }\n\tYY_BREAK\ncase 437:\n/* rule 437 can match eol */\nYY_RULE_SETUP\n#line 1062 \"seclang-scanner.ll\"\n{ BEGIN_PREVIOUS(); yyless(yyleng - 0); return p::make_DICT_ELEMENT_REGEXP(std::string(yytext, 2, yyleng-4), *driver.loc.back()); }\n\tYY_BREAK\ncase 438:\n/* rule 438 can match eol */\nYY_RULE_SETUP\n#line 1063 \"seclang-scanner.ll\"\n{ BEGIN_PREVIOUS(); yyless(yyleng - 1); return p::make_DICT_ELEMENT_REGEXP(std::string(yytext, 2, yyleng-4), *driver.loc.back()); }\n\tYY_BREAK\ncase 439:\n/* rule 439 can match eol */\nYY_RULE_SETUP\n#line 1064 \"seclang-scanner.ll\"\n{ yyless(yyleng - 1); BEGIN_PREVIOUS(); return p::make_FREE_TEXT_QUOTE_MACRO_EXPANSION(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 440:\n/* rule 440 can match eol */\nYY_RULE_SETUP\n#line 1065 \"seclang-scanner.ll\"\n{ return p::make_FREE_TEXT_QUOTE_MACRO_EXPANSION(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 441:\n/* rule 441 can match eol */\nYY_RULE_SETUP\n#line 1067 \"seclang-scanner.ll\"\n{ BEGIN_PREVIOUS(); yyless(yyleng - 1); return p::make_DICT_ELEMENT_REGEXP(std::string(yytext, 1, yyleng-2), *driver.loc.back()); }\n\tYY_BREAK\ncase 442:\n/* rule 442 can match eol */\nYY_RULE_SETUP\n#line 1068 \"seclang-scanner.ll\"\n{ BEGIN_PREVIOUS(); yyless(yyleng - 1); return p::make_DICT_ELEMENT_REGEXP(std::string(yytext, 2, yyleng-4), *driver.loc.back()); }\n\tYY_BREAK\ncase 443:\nYY_RULE_SETUP\n#line 1069 \"seclang-scanner.ll\"\n{ BEGIN_PREVIOUS(); yyless(0); }\n\tYY_BREAK\ncase 444:\nYY_RULE_SETUP\n#line 1070 \"seclang-scanner.ll\"\n{ BEGIN_PREVIOUS(); yyless(0); }\n\tYY_BREAK\ncase 445:\nYY_RULE_SETUP\n#line 1071 \"seclang-scanner.ll\"\n{ BEGINX(LEXING_ERROR_ACTION); yyless(0); }\n\tYY_BREAK\n\n\ncase 446:\n/* rule 446 can match eol */\nYY_RULE_SETUP\n#line 1076 \"seclang-scanner.ll\"\n{ BEGIN_PREVIOUS(); yyless(yyleng); return p::make_DICT_ELEMENT_REGEXP(std::string(yytext, 1, yyleng-2), *driver.loc.back()); }\n\tYY_BREAK\ncase 447:\n/* rule 447 can match eol */\nYY_RULE_SETUP\n#line 1077 \"seclang-scanner.ll\"\n{ BEGIN_PREVIOUS(); yyless(yyleng - 1); return p::make_DICT_ELEMENT_REGEXP(std::string(yytext, 1, yyleng-2), *driver.loc.back()); }\n\tYY_BREAK\ncase 448:\n/* rule 448 can match eol */\nYY_RULE_SETUP\n#line 1078 \"seclang-scanner.ll\"\n{ BEGIN_PREVIOUS(); yyless(yyleng - 1); return p::make_DICT_ELEMENT_REGEXP(std::string(yytext, 1, yyleng-2), *driver.loc.back()); }\n\tYY_BREAK\ncase 449:\n/* rule 449 can match eol */\nYY_RULE_SETUP\n#line 1079 \"seclang-scanner.ll\"\n{ BEGIN_PREVIOUS(); yyless(yyleng - 0); return p::make_DICT_ELEMENT_REGEXP(std::string(yytext, 2, yyleng-4), *driver.loc.back()); }\n\tYY_BREAK\ncase 450:\n/* rule 450 can match eol */\nYY_RULE_SETUP\n#line 1080 \"seclang-scanner.ll\"\n{ BEGIN_PREVIOUS(); yyless(yyleng - 1); return p::make_DICT_ELEMENT_REGEXP(std::string(yytext, 2, yyleng-4), *driver.loc.back()); }\n\tYY_BREAK\ncase 451:\n/* rule 451 can match eol */\nYY_RULE_SETUP\n#line 1081 \"seclang-scanner.ll\"\n{ BEGIN_PREVIOUS(); return p::make_DICT_ELEMENT(yytext, *driver.loc.back()); }\n\tYY_BREAK\ncase 452:\n/* rule 452 can match eol */\nYY_RULE_SETUP\n#line 1083 \"seclang-scanner.ll\"\n{ BEGIN_PREVIOUS(); yyless(yyleng - 1); return p::make_DICT_ELEMENT_REGEXP(std::string(yytext, 1, yyleng-2), *driver.loc.back()); }\n\tYY_BREAK\ncase 453:\n/* rule 453 can match eol */\nYY_RULE_SETUP\n#line 1084 \"seclang-scanner.ll\"\n{ BEGIN_PREVIOUS(); yyless(yyleng - 1); return p::make_DICT_ELEMENT_REGEXP(std::string(yytext, 2, yyleng-4), *driver.loc.back()); }\n\tYY_BREAK\ncase 454:\nYY_RULE_SETUP\n#line 1086 \"seclang-scanner.ll\"\n{ BEGINX(LEXING_ERROR_ACTION); yyless(0); }\n\tYY_BREAK\ncase 455:\nYY_RULE_SETUP\n#line 1087 \"seclang-scanner.ll\"\n{ return p::make_QUOTATION_MARK(yytext, *driver.loc.back()); }\n\tYY_BREAK\n\n\ncase 456:\nYY_RULE_SETUP\n#line 1093 \"seclang-scanner.ll\"\n{ BEGIN(TRANSACTION_FROM_OPERATOR_TO_ACTIONS); return p::make_OPERATOR_GEOLOOKUP(*driver.loc.back()); }\n\tYY_BREAK\ncase 457:\nYY_RULE_SETUP\n#line 1094 \"seclang-scanner.ll\"\n{ BEGIN(TRANSACTION_FROM_OPERATOR_TO_ACTIONS); return p::make_OPERATOR_UNCONDITIONAL_MATCH(*driver.loc.back()); }\n\tYY_BREAK\ncase 458:\nYY_RULE_SETUP\n#line 1095 \"seclang-scanner.ll\"\n{ BEGIN(TRANSACTION_FROM_OPERATOR_TO_ACTIONS); return p::make_OPERATOR_DETECT_SQLI(*driver.loc.back()); }\n\tYY_BREAK\ncase 459:\nYY_RULE_SETUP\n#line 1096 \"seclang-scanner.ll\"\n{ BEGIN(TRANSACTION_FROM_OPERATOR_TO_ACTIONS); return p::make_OPERATOR_DETECT_XSS(*driver.loc.back()); }\n\tYY_BREAK\ncase 460:\nYY_RULE_SETUP\n#line 1097 \"seclang-scanner.ll\"\n{ BEGIN(TRANSACTION_FROM_OPERATOR_TO_ACTIONS); return p::make_OPERATOR_VALIDATE_URL_ENCODING(*driver.loc.back()); }\n\tYY_BREAK\ncase 461:\nYY_RULE_SETUP\n#line 1098 \"seclang-scanner.ll\"\n{ BEGIN(TRANSACTION_FROM_OPERATOR_TO_ACTIONS); return p::make_OPERATOR_VALIDATE_UTF8_ENCODING(*driver.loc.back()); }\n\tYY_BREAK\n\n\ncase 462:\nYY_RULE_SETUP\n#line 1101 \"seclang-scanner.ll\"\n{ BEGIN(TRANSACTION_FROM_OPERATOR_TO_ACTIONS); return p::make_OPERATOR_GEOLOOKUP(*driver.loc.back()); }\n\tYY_BREAK\ncase 463:\nYY_RULE_SETUP\n#line 1102 \"seclang-scanner.ll\"\n{ BEGIN(TRANSACTION_FROM_OPERATOR_TO_ACTIONS); return p::make_OPERATOR_UNCONDITIONAL_MATCH(*driver.loc.back()); }\n\tYY_BREAK\ncase 464:\nYY_RULE_SETUP\n#line 1103 \"seclang-scanner.ll\"\n{ BEGIN(TRANSACTION_FROM_OPERATOR_TO_ACTIONS); return p::make_OPERATOR_DETECT_SQLI(*driver.loc.back()); }\n\tYY_BREAK\ncase 465:\nYY_RULE_SETUP\n#line 1104 \"seclang-scanner.ll\"\n{ BEGIN(TRANSACTION_FROM_OPERATOR_TO_ACTIONS); return p::make_OPERATOR_DETECT_XSS(*driver.loc.back()); }\n\tYY_BREAK\ncase 466:\nYY_RULE_SETUP\n#line 1105 \"seclang-scanner.ll\"\n{ BEGIN(TRANSACTION_FROM_OPERATOR_TO_ACTIONS); return p::make_OPERATOR_VALIDATE_URL_ENCODING(*driver.loc.back()); }\n\tYY_BREAK\ncase 467:\nYY_RULE_SETUP\n#line 1106 \"seclang-scanner.ll\"\n{ BEGIN(TRANSACTION_FROM_OPERATOR_TO_ACTIONS); return p::make_OPERATOR_VALIDATE_UTF8_ENCODING(*driver.loc.back()); }\n\tYY_BREAK\n\n\ncase 468:\nYY_RULE_SETUP\n#line 1110 \"seclang-scanner.ll\"\n{ BEGIN_PARAMETER(); return p::make_OPERATOR_WITHIN(*driver.loc.back()); }\n\tYY_BREAK\ncase 469:\nYY_RULE_SETUP\n#line 1111 \"seclang-scanner.ll\"\n{ BEGIN_PARAMETER(); return p::make_OPERATOR_CONTAINS_WORD(*driver.loc.back()); }\n\tYY_BREAK\ncase 470:\nYY_RULE_SETUP\n#line 1112 \"seclang-scanner.ll\"\n{ BEGIN_PARAMETER(); return p::make_OPERATOR_CONTAINS(*driver.loc.back()); }\n\tYY_BREAK\ncase 471:\nYY_RULE_SETUP\n#line 1113 \"seclang-scanner.ll\"\n{ BEGIN_PARAMETER(); return p::make_OPERATOR_ENDS_WITH(*driver.loc.back()); }\n\tYY_BREAK\ncase 472:\nYY_RULE_SETUP\n#line 1114 \"seclang-scanner.ll\"\n{ BEGIN_PARAMETER(); return p::make_OPERATOR_EQ(*driver.loc.back()); }\n\tYY_BREAK\ncase 473:\nYY_RULE_SETUP\n#line 1115 \"seclang-scanner.ll\"\n{ BEGIN_PARAMETER(); return p::make_OPERATOR_GE(*driver.loc.back()); }\n\tYY_BREAK\ncase 474:\nYY_RULE_SETUP\n#line 1116 \"seclang-scanner.ll\"\n{ BEGIN_PARAMETER(); return p::make_OPERATOR_GT(*driver.loc.back()); }\n\tYY_BREAK\ncase 475:\nYY_RULE_SETUP\n#line 1117 \"seclang-scanner.ll\"\n{ BEGIN_PARAMETER(); return p::make_OPERATOR_IP_MATCH_FROM_FILE(*driver.loc.back()); }\n\tYY_BREAK\ncase 476:\nYY_RULE_SETUP\n#line 1118 \"seclang-scanner.ll\"\n{ BEGIN_PARAMETER(); return p::make_OPERATOR_IP_MATCH(*driver.loc.back()); }\n\tYY_BREAK\ncase 477:\nYY_RULE_SETUP\n#line 1119 \"seclang-scanner.ll\"\n{ BEGIN_PARAMETER(); return p::make_OPERATOR_LE(*driver.loc.back()); }\n\tYY_BREAK\ncase 478:\nYY_RULE_SETUP\n#line 1120 \"seclang-scanner.ll\"\n{ BEGIN_PARAMETER(); return p::make_OPERATOR_LT(*driver.loc.back()); }\n\tYY_BREAK\ncase 479:\nYY_RULE_SETUP\n#line 1121 \"seclang-scanner.ll\"\n{ BEGIN_PARAMETER(); return p::make_OPERATOR_PM_FROM_FILE(*driver.loc.back()); }\n\tYY_BREAK\ncase 480:\nYY_RULE_SETUP\n#line 1122 \"seclang-scanner.ll\"\n{ BEGIN_PARAMETER(); return p::make_OPERATOR_PM(*driver.loc.back()); }\n\tYY_BREAK\ncase 481:\nYY_RULE_SETUP\n#line 1123 \"seclang-scanner.ll\"\n{ BEGIN_PARAMETER(); return p::make_OPERATOR_RBL( *driver.loc.back()); }\n\tYY_BREAK\ncase 482:\nYY_RULE_SETUP\n#line 1124 \"seclang-scanner.ll\"\n{ BEGIN_PARAMETER(); return p::make_OPERATOR_RX(*driver.loc.back()); }\n\tYY_BREAK\ncase 483:\nYY_RULE_SETUP\n#line 1125 \"seclang-scanner.ll\"\n{ BEGIN_PARAMETER(); return p::make_OPERATOR_RX_GLOBAL(*driver.loc.back()); }\n\tYY_BREAK\ncase 484:\nYY_RULE_SETUP\n#line 1126 \"seclang-scanner.ll\"\n{ BEGIN_PARAMETER(); return p::make_OPERATOR_STR_EQ(*driver.loc.back()); }\n\tYY_BREAK\ncase 485:\nYY_RULE_SETUP\n#line 1127 \"seclang-scanner.ll\"\n{ BEGIN_PARAMETER(); return p::make_OPERATOR_STR_MATCH(*driver.loc.back()); }\n\tYY_BREAK\ncase 486:\nYY_RULE_SETUP\n#line 1128 \"seclang-scanner.ll\"\n{ BEGIN_PARAMETER(); return p::make_OPERATOR_BEGINS_WITH(*driver.loc.back()); }\n\tYY_BREAK\ncase 487:\nYY_RULE_SETUP\n#line 1129 \"seclang-scanner.ll\"\n{ BEGIN_PARAMETER(); return p::make_OPERATOR_INSPECT_FILE(*driver.loc.back()); }\n\tYY_BREAK\ncase 488:\nYY_RULE_SETUP\n#line 1130 \"seclang-scanner.ll\"\n{ BEGIN_PARAMETER(); return p::make_OPERATOR_FUZZY_HASH(*driver.loc.back()); }\n\tYY_BREAK\ncase 489:\nYY_RULE_SETUP\n#line 1131 \"seclang-scanner.ll\"\n{ BEGIN_PARAMETER(); return p::make_OPERATOR_VALIDATE_BYTE_RANGE(*driver.loc.back()); }\n\tYY_BREAK\ncase 490:\nYY_RULE_SETUP\n#line 1132 \"seclang-scanner.ll\"\n{ BEGIN_PARAMETER(); return p::make_OPERATOR_VALIDATE_DTD(*driver.loc.back()); }\n\tYY_BREAK\ncase 491:\nYY_RULE_SETUP\n#line 1133 \"seclang-scanner.ll\"\n{ BEGIN_PARAMETER(); return p::make_OPERATOR_VALIDATE_HASH(*driver.loc.back()); }\n\tYY_BREAK\ncase 492:\nYY_RULE_SETUP\n#line 1134 \"seclang-scanner.ll\"\n{ BEGIN_PARAMETER(); return p::make_OPERATOR_VALIDATE_SCHEMA(*driver.loc.back()); }\n\tYY_BREAK\ncase 493:\nYY_RULE_SETUP\n#line 1135 \"seclang-scanner.ll\"\n{ BEGIN_PARAMETER(); return p::make_OPERATOR_VERIFY_CC(*driver.loc.back()); }\n\tYY_BREAK\ncase 494:\nYY_RULE_SETUP\n#line 1136 \"seclang-scanner.ll\"\n{ BEGIN_PARAMETER(); return p::make_OPERATOR_VERIFY_CPF(*driver.loc.back()); }\n\tYY_BREAK\ncase 495:\nYY_RULE_SETUP\n#line 1137 \"seclang-scanner.ll\"\n{ BEGIN_PARAMETER(); return p::make_OPERATOR_VERIFY_SSN(*driver.loc.back()); }\n\tYY_BREAK\ncase 496:\nYY_RULE_SETUP\n#line 1138 \"seclang-scanner.ll\"\n{ BEGIN_PARAMETER(); return p::make_OPERATOR_VERIFY_SVNR(*driver.loc.back()); }\n\tYY_BREAK\ncase 497:\nYY_RULE_SETUP\n#line 1139 \"seclang-scanner.ll\"\n{ BEGIN_PARAMETER(); return p::make_OPERATOR_GSB_LOOKUP(*driver.loc.back()); }\n\tYY_BREAK\ncase 498:\nYY_RULE_SETUP\n#line 1140 \"seclang-scanner.ll\"\n{ BEGIN_PARAMETER(); return p::make_OPERATOR_RSUB(*driver.loc.back()); }\n\tYY_BREAK\ncase 499:\nYY_RULE_SETUP\n#line 1142 \"seclang-scanner.ll\"\n{ return p::make_NOT(*driver.loc.back()); }\n\tYY_BREAK\ncase 500:\nYY_RULE_SETUP\n#line 1143 \"seclang-scanner.ll\"\n{ BEGIN_NO_OP_INFORMED(); yyless(0); }\n\tYY_BREAK\n\n\ncase 501:\nYY_RULE_SETUP\n#line 1148 \"seclang-scanner.ll\"\n{ BEGIN(EXPECTING_PARAMETER_ENDS_WITH_SPACE); }\n\tYY_BREAK\n\n\ncase 502:\nYY_RULE_SETUP\n#line 1152 \"seclang-scanner.ll\"\n{ BEGIN(EXPECTING_PARAMETER_ENDS_WITH_QUOTE); }\n\tYY_BREAK\n\n\ncase 503:\nYY_RULE_SETUP\n#line 1156 \"seclang-scanner.ll\"\n{ BEGIN(TRANSACTION_FROM_OPERATOR_PARAMETERS_TO_ACTIONS); }\n\tYY_BREAK\ncase 504:\n/* rule 504 can match eol */\nYY_RULE_SETUP\n#line 1157 \"seclang-scanner.ll\"\n{ return p::make_FREE_TEXT_QUOTE_MACRO_EXPANSION(yytext, *driver.loc.back()); }\n\tYY_BREAK\n\n\ncase 505:\nYY_RULE_SETUP\n#line 1161 \"seclang-scanner.ll\"\n{ BEGIN(TRANSACTION_FROM_OPERATOR_PARAMETERS_TO_ACTIONS); }\n\tYY_BREAK\ncase 506:\n/* rule 506 can match eol */\nYY_RULE_SETUP\n#line 1162 \"seclang-scanner.ll\"\n{ return p::make_FREE_TEXT_QUOTE_MACRO_EXPANSION(yytext, *driver.loc.back()); }\n\tYY_BREAK\n\n\ncase 507:\nYY_RULE_SETUP\n#line 1165 \"seclang-scanner.ll\"\n{ BEGINX(EXPECTING_ACTION_PREDICATE_VARIABLE); }\n\tYY_BREAK\ncase 508:\nYY_RULE_SETUP\n#line 1166 \"seclang-scanner.ll\"\n{ BEGIN(LEXING_ERROR); yyless(0); }\n\tYY_BREAK\n\n\ncase 509:\nYY_RULE_SETUP\n#line 1170 \"seclang-scanner.ll\"\n{ BEGIN(TRANSACTION_FROM_OPERATOR_PARAMETERS_TO_ACTIONS); }\n\tYY_BREAK\ncase 510:\n/* rule 510 can match eol */\nYY_RULE_SETUP\n#line 1171 \"seclang-scanner.ll\"\n{ return p::make_FREE_TEXT_QUOTE_MACRO_EXPANSION(yytext, *driver.loc.back()); }\n\tYY_BREAK\n\n\ncase 511:\nYY_RULE_SETUP\n#line 1175 \"seclang-scanner.ll\"\n{ BEGIN(TRANSACTION_FROM_OPERATOR_PARAMETERS_TO_ACTIONS); }\n\tYY_BREAK\ncase 512:\n/* rule 512 can match eol */\nYY_RULE_SETUP\n#line 1176 \"seclang-scanner.ll\"\n{ return p::make_FREE_TEXT_QUOTE_MACRO_EXPANSION(yytext, *driver.loc.back()); }\n\tYY_BREAK\n\n\ncase 513:\nYY_RULE_SETUP\n#line 1180 \"seclang-scanner.ll\"\n{ BEGINX(EXPECTING_ACTION_PREDICATE_VARIABLE); }\n\tYY_BREAK\ncase 514:\nYY_RULE_SETUP\n#line 1181 \"seclang-scanner.ll\"\n{ BEGIN(LEXING_ERROR_VARIABLE); yyless(0); }\n\tYY_BREAK\n\n\ncase 515:\nYY_RULE_SETUP\n#line 1186 \"seclang-scanner.ll\"\n{ BEGIN(EXPECTING_ACTIONS_ONLY_ONE); }\n\tYY_BREAK\ncase 516:\n/* rule 516 can match eol */\nYY_RULE_SETUP\n#line 1188 \"seclang-scanner.ll\"\n{ driver.loc.back()->lines(1); driver.loc.back()->step(); BEGIN(EXPECTING_ACTIONS_ENDS_WITH_DOUBLE_QUOTE); }\n\tYY_BREAK\ncase 517:\n/* rule 517 can match eol */\nYY_RULE_SETUP\n#line 1189 \"seclang-scanner.ll\"\n{ driver.loc.back()->lines(1); driver.loc.back()->step(); BEGIN(EXPECTING_ACTIONS_ENDS_WITH_DOUBLE_QUOTE); }\n\tYY_BREAK\ncase 518:\n/* rule 518 can match eol */\nYY_RULE_SETUP\n#line 1190 \"seclang-scanner.ll\"\n{ driver.loc.back()->lines(1); driver.loc.back()->step(); BEGIN(EXPECTING_ACTIONS_ONLY_ONE); }\n\tYY_BREAK\ncase 519:\n/* rule 519 can match eol */\nYY_RULE_SETUP\n#line 1191 \"seclang-scanner.ll\"\n{ driver.loc.back()->lines(1); driver.loc.back()->step(); BEGIN(EXPECTING_ACTIONS_ONLY_ONE); }\n\tYY_BREAK\ncase 520:\n/* rule 520 can match eol */\nYY_RULE_SETUP\n#line 1193 \"seclang-scanner.ll\"\n{ driver.loc.back()->lines(1); driver.loc.back()->step(); BEGIN(EXPECTING_ACTIONS_ENDS_WITH_DOUBLE_QUOTE); }\n\tYY_BREAK\ncase 521:\n/* rule 521 can match eol */\nYY_RULE_SETUP\n#line 1194 \"seclang-scanner.ll\"\n{ driver.loc.back()->lines(1); driver.loc.back()->step(); BEGIN(EXPECTING_ACTIONS_ENDS_WITH_DOUBLE_QUOTE); }\n\tYY_BREAK\ncase 522:\n/* rule 522 can match eol */\nYY_RULE_SETUP\n#line 1195 \"seclang-scanner.ll\"\n{ driver.loc.back()->lines(1); driver.loc.back()->step(); BEGIN(EXPECTING_ACTIONS_ENDS_WITH_DOUBLE_QUOTE); }\n\tYY_BREAK\ncase 523:\n/* rule 523 can match eol */\nYY_RULE_SETUP\n#line 1196 \"seclang-scanner.ll\"\n{ driver.loc.back()->lines(1); driver.loc.back()->step(); BEGIN(EXPECTING_ACTIONS_ENDS_WITH_DOUBLE_QUOTE); }\n\tYY_BREAK\ncase 524:\n/* rule 524 can match eol */\nYY_RULE_SETUP\n#line 1198 \"seclang-scanner.ll\"\n{ driver.loc.back()->lines(1); driver.loc.back()->step(); BEGIN(EXPECTING_ACTIONS_ONLY_ONE); }\n\tYY_BREAK\ncase 525:\n/* rule 525 can match eol */\nYY_RULE_SETUP\n#line 1199 \"seclang-scanner.ll\"\n{ driver.loc.back()->lines(1); driver.loc.back()->step(); BEGIN(EXPECTING_ACTIONS_ONLY_ONE); }\n\tYY_BREAK\ncase 526:\n/* rule 526 can match eol */\nYY_RULE_SETUP\n#line 1200 \"seclang-scanner.ll\"\n{ driver.loc.back()->lines(1); driver.loc.back()->step(); BEGIN(EXPECTING_ACTIONS_ONLY_ONE); }\n\tYY_BREAK\ncase 527:\n/* rule 527 can match eol */\nYY_RULE_SETUP\n#line 1201 \"seclang-scanner.ll\"\n{ driver.loc.back()->lines(1); driver.loc.back()->step(); BEGIN(EXPECTING_ACTIONS_ONLY_ONE); }\n\tYY_BREAK\ncase 528:\nYY_RULE_SETUP\n#line 1203 \"seclang-scanner.ll\"\n{ BEGIN(EXPECTING_ACTIONS_ENDS_WITH_DOUBLE_QUOTE); }\n\tYY_BREAK\ncase 529:\n/* rule 529 can match eol */\nYY_RULE_SETUP\n#line 1205 \"seclang-scanner.ll\"\n{ driver.loc.back()->lines(1); driver.loc.back()->step(); BEGIN(EXPECTING_ACTIONS_ENDS_WITH_DOUBLE_QUOTE); }\n\tYY_BREAK\ncase 530:\n/* rule 530 can match eol */\nYY_RULE_SETUP\n#line 1206 \"seclang-scanner.ll\"\n{ driver.loc.back()->lines(1); driver.loc.back()->step(); BEGIN(EXPECTING_ACTIONS_ENDS_WITH_DOUBLE_QUOTE); }\n\tYY_BREAK\ncase 531:\n/* rule 531 can match eol */\nYY_RULE_SETUP\n#line 1208 \"seclang-scanner.ll\"\n{ driver.loc.back()->lines(1); driver.loc.back()->step(); BEGIN(EXPECTING_ACTIONS_ENDS_WITH_DOUBLE_QUOTE); }\n\tYY_BREAK\ncase 532:\n/* rule 532 can match eol */\nYY_RULE_SETUP\n#line 1209 \"seclang-scanner.ll\"\n{ driver.loc.back()->lines(1); driver.loc.back()->step(); BEGIN(EXPECTING_ACTIONS_ENDS_WITH_DOUBLE_QUOTE); }\n\tYY_BREAK\ncase 533:\n/* rule 533 can match eol */\nYY_RULE_SETUP\n#line 1210 \"seclang-scanner.ll\"\n{ driver.loc.back()->lines(1); driver.loc.back()->step(); BEGIN(EXPECTING_ACTIONS_ENDS_WITH_DOUBLE_QUOTE); }\n\tYY_BREAK\ncase 534:\n/* rule 534 can match eol */\nYY_RULE_SETUP\n#line 1211 \"seclang-scanner.ll\"\n{ driver.loc.back()->lines(1); driver.loc.back()->step(); BEGIN(EXPECTING_ACTIONS_ENDS_WITH_DOUBLE_QUOTE); }\n\tYY_BREAK\ncase 535:\nYY_RULE_SETUP\n#line 1213 \"seclang-scanner.ll\"\n{ BEGIN(EXPECTING_ACTIONS_ENDS_WITH_DOUBLE_QUOTE); }\n\tYY_BREAK\n\n\ncase 536:\nYY_RULE_SETUP\n#line 1218 \"seclang-scanner.ll\"\n{  }\n\tYY_BREAK\ncase 537:\n/* rule 537 can match eol */\nYY_RULE_SETUP\n#line 1219 \"seclang-scanner.ll\"\n{ driver.loc.back()->lines(1); driver.loc.back()->step(); }\n\tYY_BREAK\ncase 538:\n/* rule 538 can match eol */\nYY_RULE_SETUP\n#line 1220 \"seclang-scanner.ll\"\n{ driver.loc.back()->lines(1); driver.loc.back()->step(); }\n\tYY_BREAK\n\n\ncase 539:\n/* rule 539 can match eol */\nYY_RULE_SETUP\n#line 1224 \"seclang-scanner.ll\"\n{ driver.loc.back()->lines(1); driver.loc.back()->step(); }\n\tYY_BREAK\ncase 540:\n/* rule 540 can match eol */\nYY_RULE_SETUP\n#line 1225 \"seclang-scanner.ll\"\n{ driver.loc.back()->lines(1); driver.loc.back()->step(); }\n\tYY_BREAK\ncase 541:\n/* rule 541 can match eol */\nYY_RULE_SETUP\n#line 1226 \"seclang-scanner.ll\"\n{ BEGIN(INITIAL); driver.loc.back()->lines(1); driver.loc.back()->step(); }\n\tYY_BREAK\n\ncase 542:\nYY_RULE_SETUP\n#line 1231 \"seclang-scanner.ll\"\n{ BEGIN(LEXING_ERROR); yyless(0); }\n\tYY_BREAK\ncase 543:\nYY_RULE_SETUP\n#line 1233 \"seclang-scanner.ll\"\n{ driver.error (*driver.loc.back(), \"Invalid input: \", yytext); throw p::syntax_error(*driver.loc.back(), \"\"); }\n\tYY_BREAK\ncase 544:\nYY_RULE_SETUP\n#line 1234 \"seclang-scanner.ll\"\n{ driver.error (*driver.loc.back(), \"Expecting an action, got: \", yytext); throw p::syntax_error(*driver.loc.back(), \"\"); }\n\tYY_BREAK\ncase 545:\nYY_RULE_SETUP\n#line 1235 \"seclang-scanner.ll\"\n{ driver.error (*driver.loc.back(), \"Expecting a variable, got:  : \", yytext); throw p::syntax_error(*driver.loc.back(), \"\"); }\n\tYY_BREAK\ncase YY_STATE_EOF(INITIAL):\ncase YY_STATE_EOF(EXPECTING_ACTION_PREDICATE_VARIABLE):\ncase YY_STATE_EOF(TRANSACTION_TO_VARIABLE):\ncase YY_STATE_EOF(EXPECTING_VARIABLE):\ncase YY_STATE_EOF(EXPECTING_OPERATOR_ENDS_WITH_SPACE):\ncase YY_STATE_EOF(EXPECTING_OPERATOR_ENDS_WITH_QUOTE):\ncase YY_STATE_EOF(EXPECTING_ACTION_PREDICATE):\ncase YY_STATE_EOF(ACTION_PREDICATE_ENDS_WITH_QUOTE):\ncase YY_STATE_EOF(ACTION_PREDICATE_ENDS_WITH_DOUBLE_QUOTE):\ncase YY_STATE_EOF(ACTION_PREDICATE_ENDS_WITH_COMMA_OR_DOUBLE_QUOTE):\ncase YY_STATE_EOF(COMMENT):\ncase YY_STATE_EOF(TRANSITION_FROM_OP_TO_EXPECTING_PARAMETER_ENDS_WITH_QUOTE):\ncase YY_STATE_EOF(TRANSITION_FROM_OP_TO_EXPECTING_PARAMETER_ENDS_WITH_SPACE):\ncase YY_STATE_EOF(EXPECTING_VAR_PARAMETER):\ncase YY_STATE_EOF(EXPECTING_VAR_PARAMETER_OR_MACRO_NONQUOTED):\ncase YY_STATE_EOF(EXPECTING_VAR_PARAMETER_OR_MACRO_QUOTED):\ncase YY_STATE_EOF(EXPECTING_PARAMETER_ENDS_WITH_QUOTE):\ncase YY_STATE_EOF(EXPECTING_PARAMETER_ENDS_WITH_SPACE):\ncase YY_STATE_EOF(EXPECTING_ACTIONS_ENDS_WITH_DOUBLE_QUOTE):\ncase YY_STATE_EOF(EXPECTING_ACTIONS_ONLY_ONE):\ncase YY_STATE_EOF(TRANSACTION_FROM_OPERATOR_TO_ACTIONS):\ncase YY_STATE_EOF(TRANSACTION_FROM_OPERATOR_PARAMETERS_TO_ACTIONS):\ncase YY_STATE_EOF(TRANSACTION_FROM_DIRECTIVE_TO_ACTIONS):\ncase YY_STATE_EOF(NO_OP_INFORMED_ENDS_WITH_SPACE):\ncase YY_STATE_EOF(NO_OP_INFORMED_ENDS_WITH_QUOTE):\ncase YY_STATE_EOF(LEXING_ERROR):\ncase YY_STATE_EOF(LEXING_ERROR_ACTION):\ncase YY_STATE_EOF(LEXING_ERROR_VARIABLE):\ncase YY_STATE_EOF(SETVAR_ACTION_NONQUOTED):\ncase YY_STATE_EOF(SETVAR_ACTION_NONQUOTED_WAITING_COLLECTION_ELEM):\ncase YY_STATE_EOF(SETVAR_ACTION_NONQUOTED_WAITING_OPERATION):\ncase YY_STATE_EOF(SETVAR_ACTION_NONQUOTED_WAITING_CONTENT):\ncase YY_STATE_EOF(SETVAR_ACTION_QUOTED):\ncase YY_STATE_EOF(SETVAR_ACTION_QUOTED_WAITING_COLLECTION_ELEM):\ncase YY_STATE_EOF(SETVAR_ACTION_QUOTED_WAITING_OPERATION):\ncase YY_STATE_EOF(SETVAR_ACTION_QUOTED_WAITING_CONTENT):\n#line 1238 \"seclang-scanner.ll\"\n{\n    if (yyin) {\n        fclose(yyin);\n    }\n\n    yypop_buffer_state();\n    if (!YY_CURRENT_BUFFER) {\n        return p::make_END(*driver.loc.back());\n    }\n\n    yy::location *l = driver.loc.back();\n    driver.loc.pop_back();\n    delete l;\n}\n\tYY_BREAK\ncase 546:\nYY_RULE_SETUP\n#line 1254 \"seclang-scanner.ll\"\n{\n    std::string err;\n    const char *tmpStr = yytext + strlen(\"include\");\n    const char *file   = tmpStr + strspn( tmpStr, \" \\t\");\n    std::string fi = modsecurity::utils::find_resource(file, *driver.loc.back()->end.filename, &err);\n    if (fi.empty() == true) {\n        BEGIN(INITIAL);\n        driver.error (*driver.loc.back(), \"\", file + std::string(\": Not able to open file. \") + err);\n        throw p::syntax_error(*driver.loc.back(), \"\");\n    }\n    std::list<std::string> files = modsecurity::utils::expandEnv(fi, 0);\n    files.reverse();\n    for (auto& s: files) {\n        std::string err;\n        std::string f = modsecurity::utils::find_resource(s, *driver.loc.back()->end.filename, &err);\n        driver.loc.push_back(new yy::location());\n        driver.m_filenames.push_back(f);\n        driver.loc.back()->begin.filename = driver.loc.back()->end.filename = &(driver.m_filenames.back());\n        yyin = fopen(f.c_str(), \"r\" );\n        if (!yyin) {\n            BEGIN(INITIAL);\n            driver.loc.pop_back();\n            driver.error (*driver.loc.back(), \"\", s + std::string(\": Not able to open file. \") + err);\n            throw p::syntax_error(*driver.loc.back(), \"\");\n        }\n        yypush_buffer_state(yy_create_buffer( yyin, YY_BUF_SIZE ));\n    }\n}\n\tYY_BREAK\ncase 547:\nYY_RULE_SETUP\n#line 1283 \"seclang-scanner.ll\"\n{\n    std::string err;\n    const char *tmpStr = yytext + strlen(\"include\");\n    const char *afterWhitespace   = tmpStr + strspn( tmpStr, \" \\t\");\n    std::string file(afterWhitespace+1, strlen(afterWhitespace)-2);\n    std::string fi = modsecurity::utils::find_resource(file, *driver.loc.back()->end.filename, &err);\n    if (fi.empty() == true) {\n        BEGIN(INITIAL);\n        driver.error (*driver.loc.back(), \"\", file + std::string(\": Not able to open file. \") + err);\n        throw p::syntax_error(*driver.loc.back(), \"\");\n    }\n    std::list<std::string> files = modsecurity::utils::expandEnv(fi, 0);\n    files.reverse();\n    for (auto& s: files) {\n        std::string f = modsecurity::utils::find_resource(s, *driver.loc.back()->end.filename, &err);\n        driver.loc.push_back(new yy::location());\n        driver.m_filenames.push_back(f);\n        driver.loc.back()->begin.filename = driver.loc.back()->end.filename = &(driver.m_filenames.back());\n\n        yyin = fopen(f.c_str(), \"r\" );\n        if (!yyin) {\n            BEGIN(INITIAL);\n            driver.loc.pop_back();\n            driver.error (*driver.loc.back(), \"\", s + std::string(\": Not able to open file. \") + err);\n            throw p::syntax_error(*driver.loc.back(), \"\");\n        }\n        yypush_buffer_state(yy_create_buffer( yyin, YY_BUF_SIZE ));\n    }\n}\n\tYY_BREAK\ncase 548:\n/* rule 548 can match eol */\nYY_RULE_SETUP\n#line 1313 \"seclang-scanner.ll\"\n{\n    HttpsClient c;\n    std::string key;\n    std::string url;\n\n    std::vector<std::string> conf = modsecurity::utils::string::split(yytext, ' ');\n    if (conf.size() < 2) {\n        driver.error (*driver.loc.back(), \"\", \"SecRemoteRules demands a key and a URI\");\n        throw p::syntax_error(*driver.loc.back(), \"\");\n    }\n    key = conf[1];\n    url = conf[2];\n    c.setKey(key);\n\n    driver.loc.push_back(new yy::location());\n    driver.m_filenames.push_back(url);\n    driver.loc.back()->begin.filename = driver.loc.back()->end.filename = &(driver.m_filenames.back());\n    YY_BUFFER_STATE temp = YY_CURRENT_BUFFER;\n    yypush_buffer_state(temp);\n\n    bool ret = c.download(url);\n\n    if (ret == false) {\n        BEGIN(INITIAL);\n        if (driver.m_remoteRulesActionOnFailed == RulesSet::OnFailedRemoteRulesAction::WarnOnFailedRemoteRulesAction) {\n            /** TODO: Implement the server logging mechanism. */\n        }\n        if (driver.m_remoteRulesActionOnFailed == RulesSet::OnFailedRemoteRulesAction::AbortOnFailedRemoteRulesAction) {\n            driver.error (*driver.loc.back(), \"\", yytext + std::string(\" - Failed to download: \") + c.error);\n            throw p::syntax_error(*driver.loc.back(), \"\");\n        }\n    }\n\n    yy_scan_string(c.content.c_str());\n}\n\tYY_BREAK\ncase 549:\nYY_RULE_SETUP\n#line 1350 \"seclang-scanner.ll\"\nECHO;\n\tYY_BREAK\n#line 8488 \"seclang-scanner.cc\"\n\n\tcase YY_END_OF_BUFFER:\n\t\t{\n\t\t/* Amount of text matched not including the EOB char. */\n\t\tint yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1;\n\n\t\t/* Undo the effects of YY_DO_BEFORE_ACTION. */\n\t\t*yy_cp = (yy_hold_char);\n\t\tYY_RESTORE_YY_MORE_OFFSET\n\n\t\tif ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW )\n\t\t\t{\n\t\t\t/* We're scanning a new file or input source.  It's\n\t\t\t * possible that this happened because the user\n\t\t\t * just pointed yyin at a new source and called\n\t\t\t * yylex().  If so, then we have to assure\n\t\t\t * consistency between YY_CURRENT_BUFFER and our\n\t\t\t * globals.  Here is the right place to do so, because\n\t\t\t * this is the first action (other than possibly a\n\t\t\t * back-up) that will match for the new input source.\n\t\t\t */\n\t\t\t(yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;\n/* %if-c-only */\n\t\t\tYY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin;\n/* %endif */\n/* %if-c++-only */\n/* %endif */\n\t\t\tYY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL;\n\t\t\t}\n\n\t\t/* Note that here we test for yy_c_buf_p \"<=\" to the position\n\t\t * of the first EOB in the buffer, since yy_c_buf_p will\n\t\t * already have been incremented past the NUL character\n\t\t * (since all states make transitions on EOB to the\n\t\t * end-of-buffer state).  Contrast this with the test\n\t\t * in input().\n\t\t */\n\t\tif ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] )\n\t\t\t{ /* This was really a NUL. */\n\t\t\tyy_state_type yy_next_state;\n\n\t\t\t(yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text;\n\n\t\t\tyy_current_state = yy_get_previous_state(  );\n\n\t\t\t/* Okay, we're now positioned to make the NUL\n\t\t\t * transition.  We couldn't have\n\t\t\t * yy_get_previous_state() go ahead and do it\n\t\t\t * for us because it doesn't know how to deal\n\t\t\t * with the possibility of jamming (and we don't\n\t\t\t * want to build jamming into it because then it\n\t\t\t * will run more slowly).\n\t\t\t */\n\n\t\t\tyy_next_state = yy_try_NUL_trans( yy_current_state );\n\n\t\t\tyy_bp = (yytext_ptr) + YY_MORE_ADJ;\n\n\t\t\tif ( yy_next_state )\n\t\t\t\t{\n\t\t\t\t/* Consume the NUL. */\n\t\t\t\tyy_cp = ++(yy_c_buf_p);\n\t\t\t\tyy_current_state = yy_next_state;\n\t\t\t\tgoto yy_match;\n\t\t\t\t}\n\n\t\t\telse\n\t\t\t\t{\n/* %% [14.0] code to do back-up for compressed tables and set up yy_cp goes here */\n\t\t\t\tyy_cp = (yy_last_accepting_cpos);\n\t\t\t\tyy_current_state = (yy_last_accepting_state);\n\t\t\t\tgoto yy_find_action;\n\t\t\t\t}\n\t\t\t}\n\n\t\telse switch ( yy_get_next_buffer(  ) )\n\t\t\t{\n\t\t\tcase EOB_ACT_END_OF_FILE:\n\t\t\t\t{\n\t\t\t\t(yy_did_buffer_switch_on_eof) = 0;\n\n\t\t\t\tif ( yywrap(  ) )\n\t\t\t\t\t{\n\t\t\t\t\t/* Note: because we've taken care in\n\t\t\t\t\t * yy_get_next_buffer() to have set up\n\t\t\t\t\t * yytext, we can now set up\n\t\t\t\t\t * yy_c_buf_p so that if some total\n\t\t\t\t\t * hoser (like flex itself) wants to\n\t\t\t\t\t * call the scanner after we return the\n\t\t\t\t\t * YY_NULL, it'll still work - another\n\t\t\t\t\t * YY_NULL will get returned.\n\t\t\t\t\t */\n\t\t\t\t\t(yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ;\n\n\t\t\t\t\tyy_act = YY_STATE_EOF(YY_START);\n\t\t\t\t\tgoto do_action;\n\t\t\t\t\t}\n\n\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\tif ( ! (yy_did_buffer_switch_on_eof) )\n\t\t\t\t\t\tYY_NEW_FILE;\n\t\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\tcase EOB_ACT_CONTINUE_SCAN:\n\t\t\t\t(yy_c_buf_p) =\n\t\t\t\t\t(yytext_ptr) + yy_amount_of_matched_text;\n\n\t\t\t\tyy_current_state = yy_get_previous_state(  );\n\n\t\t\t\tyy_cp = (yy_c_buf_p);\n\t\t\t\tyy_bp = (yytext_ptr) + YY_MORE_ADJ;\n\t\t\t\tgoto yy_match;\n\n\t\t\tcase EOB_ACT_LAST_MATCH:\n\t\t\t\t(yy_c_buf_p) =\n\t\t\t\t&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)];\n\n\t\t\t\tyy_current_state = yy_get_previous_state(  );\n\n\t\t\t\tyy_cp = (yy_c_buf_p);\n\t\t\t\tyy_bp = (yytext_ptr) + YY_MORE_ADJ;\n\t\t\t\tgoto yy_find_action;\n\t\t\t}\n\t\tbreak;\n\t\t}\n\n\tdefault:\n\t\tYY_FATAL_ERROR(\n\t\t\t\"fatal flex scanner internal error--no action found\" );\n\t} /* end of action switch */\n\t\t} /* end of scanning one token */\n\t} /* end of user's declarations */\n} /* end of yylex */\n/* %ok-for-header */\n\n/* %if-c++-only */\n/* %not-for-header */\n/* %ok-for-header */\n\n/* %endif */\n\n/* yy_get_next_buffer - try to read in a new buffer\n *\n * Returns a code representing an action:\n *\tEOB_ACT_LAST_MATCH -\n *\tEOB_ACT_CONTINUE_SCAN - continue scanning from current position\n *\tEOB_ACT_END_OF_FILE - end of file\n */\n/* %if-c-only */\nstatic int yy_get_next_buffer (void)\n/* %endif */\n/* %if-c++-only */\n/* %endif */\n{\n    \tchar *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf;\n\tchar *source = (yytext_ptr);\n\tint number_to_move, i;\n\tint ret_val;\n\n\tif ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] )\n\t\tYY_FATAL_ERROR(\n\t\t\"fatal flex scanner internal error--end of buffer missed\" );\n\n\tif ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 )\n\t\t{ /* Don't try to fill the buffer, so this is an EOF. */\n\t\tif ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 )\n\t\t\t{\n\t\t\t/* We matched a single character, the EOB, so\n\t\t\t * treat this as a final EOF.\n\t\t\t */\n\t\t\treturn EOB_ACT_END_OF_FILE;\n\t\t\t}\n\n\t\telse\n\t\t\t{\n\t\t\t/* We matched some text prior to the EOB, first\n\t\t\t * process it.\n\t\t\t */\n\t\t\treturn EOB_ACT_LAST_MATCH;\n\t\t\t}\n\t\t}\n\n\t/* Try to read more data. */\n\n\t/* First move last chars to start of buffer. */\n\tnumber_to_move = (int) ((yy_c_buf_p) - (yytext_ptr) - 1);\n\n\tfor ( i = 0; i < number_to_move; ++i )\n\t\t*(dest++) = *(source++);\n\n\tif ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING )\n\t\t/* don't do the read, it's not guaranteed to return an EOF,\n\t\t * just force an EOF\n\t\t */\n\t\tYY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0;\n\n\telse\n\t\t{\n\t\t\tyy_size_t num_to_read =\n\t\t\tYY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1;\n\n\t\twhile ( num_to_read <= 0 )\n\t\t\t{ /* Not enough room in the buffer - grow it. */\n\n\t\t\t/* just a shorter name for the current buffer */\n\t\t\tYY_BUFFER_STATE b = YY_CURRENT_BUFFER_LVALUE;\n\n\t\t\tint yy_c_buf_p_offset =\n\t\t\t\t(int) ((yy_c_buf_p) - b->yy_ch_buf);\n\n\t\t\tif ( b->yy_is_our_buffer )\n\t\t\t\t{\n\t\t\t\tyy_size_t new_size = b->yy_buf_size * 2;\n\n\t\t\t\tif ( new_size <= 0 )\n\t\t\t\t\tb->yy_buf_size += b->yy_buf_size / 8;\n\t\t\t\telse\n\t\t\t\t\tb->yy_buf_size *= 2;\n\n\t\t\t\tb->yy_ch_buf = (char *)\n\t\t\t\t\t/* Include room in for 2 EOB chars. */\n\t\t\t\t\tyyrealloc( (void *) b->yy_ch_buf,\n\t\t\t\t\t\t\t (yy_size_t) (b->yy_buf_size + 2)  );\n\t\t\t\t}\n\t\t\telse\n\t\t\t\t/* Can't grow it, we don't own it. */\n\t\t\t\tb->yy_ch_buf = NULL;\n\n\t\t\tif ( ! b->yy_ch_buf )\n\t\t\t\tYY_FATAL_ERROR(\n\t\t\t\t\"fatal error - scanner input buffer overflow\" );\n\n\t\t\t(yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset];\n\n\t\t\tnum_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size -\n\t\t\t\t\t\tnumber_to_move - 1;\n\n\t\t\t}\n\n\t\tif ( num_to_read > YY_READ_BUF_SIZE )\n\t\t\tnum_to_read = YY_READ_BUF_SIZE;\n\n\t\t/* Read in more data. */\n\t\tYY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]),\n\t\t\t(yy_n_chars), num_to_read );\n\n\t\tYY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);\n\t\t}\n\n\tif ( (yy_n_chars) == 0 )\n\t\t{\n\t\tif ( number_to_move == YY_MORE_ADJ )\n\t\t\t{\n\t\t\tret_val = EOB_ACT_END_OF_FILE;\n\t\t\tyyrestart( yyin  );\n\t\t\t}\n\n\t\telse\n\t\t\t{\n\t\t\tret_val = EOB_ACT_LAST_MATCH;\n\t\t\tYY_CURRENT_BUFFER_LVALUE->yy_buffer_status =\n\t\t\t\tYY_BUFFER_EOF_PENDING;\n\t\t\t}\n\t\t}\n\n\telse\n\t\tret_val = EOB_ACT_CONTINUE_SCAN;\n\n\tif (((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) {\n\t\t/* Extend the array by 50%, plus the number we really need. */\n\t\tyy_size_t new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1);\n\t\tYY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc(\n\t\t\t(void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf, (yy_size_t) new_size  );\n\t\tif ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )\n\t\t\tYY_FATAL_ERROR( \"out of dynamic memory in yy_get_next_buffer()\" );\n\t\t/* \"- 2\" to take care of EOB's */\n\t\tYY_CURRENT_BUFFER_LVALUE->yy_buf_size = (int) (new_size - 2);\n\t}\n\n\t(yy_n_chars) += number_to_move;\n\tYY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR;\n\tYY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR;\n\n\t(yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0];\n\n\treturn ret_val;\n}\n\n/* yy_get_previous_state - get the state just before the EOB char was reached */\n\n/* %if-c-only */\n/* %not-for-header */\n    static yy_state_type yy_get_previous_state (void)\n/* %endif */\n/* %if-c++-only */\n/* %endif */\n{\n\tyy_state_type yy_current_state;\n\tchar *yy_cp;\n    \n/* %% [15.0] code to get the start state into yy_current_state goes here */\n\tyy_current_state = (yy_start);\n\n\tfor ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp )\n\t\t{\n/* %% [16.0] code to find the next state goes here */\n\t\tYY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1);\n\t\tif ( yy_accept[yy_current_state] )\n\t\t\t{\n\t\t\t(yy_last_accepting_state) = yy_current_state;\n\t\t\t(yy_last_accepting_cpos) = yy_cp;\n\t\t\t}\n\t\twhile ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )\n\t\t\t{\n\t\t\tyy_current_state = (int) yy_def[yy_current_state];\n\t\t\tif ( yy_current_state >= 3973 )\n\t\t\t\tyy_c = yy_meta[yy_c];\n\t\t\t}\n\t\tyy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c];\n\t\t}\n\n\treturn yy_current_state;\n}\n\n/* yy_try_NUL_trans - try to make a transition on the NUL character\n *\n * synopsis\n *\tnext_state = yy_try_NUL_trans( current_state );\n */\n/* %if-c-only */\n    static yy_state_type yy_try_NUL_trans  (yy_state_type yy_current_state )\n/* %endif */\n/* %if-c++-only */\n/* %endif */\n{\n\tint yy_is_jam;\n    /* %% [17.0] code to find the next state, and perhaps do backing up, goes here */\n\tchar *yy_cp = (yy_c_buf_p);\n\n\tYY_CHAR yy_c = 1;\n\tif ( yy_accept[yy_current_state] )\n\t\t{\n\t\t(yy_last_accepting_state) = yy_current_state;\n\t\t(yy_last_accepting_cpos) = yy_cp;\n\t\t}\n\twhile ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )\n\t\t{\n\t\tyy_current_state = (int) yy_def[yy_current_state];\n\t\tif ( yy_current_state >= 3973 )\n\t\t\tyy_c = yy_meta[yy_c];\n\t\t}\n\tyy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c];\n\tyy_is_jam = (yy_current_state == 3972);\n\n\t\treturn yy_is_jam ? 0 : yy_current_state;\n}\n\n#ifndef YY_NO_UNPUT\n/* %if-c-only */\n\n/* %endif */\n#endif\n\n/* %if-c-only */\n#ifndef YY_NO_INPUT\n#ifdef __cplusplus\n    static int yyinput (void)\n#else\n    static int input  (void)\n#endif\n\n/* %endif */\n/* %if-c++-only */\n/* %endif */\n{\n\tint c;\n    \n\t*(yy_c_buf_p) = (yy_hold_char);\n\n\tif ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR )\n\t\t{\n\t\t/* yy_c_buf_p now points to the character we want to return.\n\t\t * If this occurs *before* the EOB characters, then it's a\n\t\t * valid NUL; if not, then we've hit the end of the buffer.\n\t\t */\n\t\tif ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] )\n\t\t\t/* This was really a NUL. */\n\t\t\t*(yy_c_buf_p) = '\\0';\n\n\t\telse\n\t\t\t{ /* need more input */\n\t\t\tyy_size_t offset = (yy_c_buf_p) - (yytext_ptr);\n\t\t\t++(yy_c_buf_p);\n\n\t\t\tswitch ( yy_get_next_buffer(  ) )\n\t\t\t\t{\n\t\t\t\tcase EOB_ACT_LAST_MATCH:\n\t\t\t\t\t/* This happens because yy_g_n_b()\n\t\t\t\t\t * sees that we've accumulated a\n\t\t\t\t\t * token and flags that we need to\n\t\t\t\t\t * try matching the token before\n\t\t\t\t\t * proceeding.  But for input(),\n\t\t\t\t\t * there's no matching to consider.\n\t\t\t\t\t * So convert the EOB_ACT_LAST_MATCH\n\t\t\t\t\t * to EOB_ACT_END_OF_FILE.\n\t\t\t\t\t */\n\n\t\t\t\t\t/* Reset buffer status. */\n\t\t\t\t\tyyrestart( yyin );\n\n\t\t\t\t\t/*FALLTHROUGH*/\n\n\t\t\t\tcase EOB_ACT_END_OF_FILE:\n\t\t\t\t\t{\n\t\t\t\t\tif ( yywrap(  ) )\n\t\t\t\t\t\treturn 0;\n\n\t\t\t\t\tif ( ! (yy_did_buffer_switch_on_eof) )\n\t\t\t\t\t\tYY_NEW_FILE;\n#ifdef __cplusplus\n\t\t\t\t\treturn yyinput();\n#else\n\t\t\t\t\treturn input();\n#endif\n\t\t\t\t\t}\n\n\t\t\t\tcase EOB_ACT_CONTINUE_SCAN:\n\t\t\t\t\t(yy_c_buf_p) = (yytext_ptr) + offset;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\tc = *(unsigned char *) (yy_c_buf_p);\t/* cast for 8-bit char's */\n\t*(yy_c_buf_p) = '\\0';\t/* preserve yytext */\n\t(yy_hold_char) = *++(yy_c_buf_p);\n\n/* %% [19.0] update BOL and yylineno */\n\n\treturn c;\n}\n/* %if-c-only */\n#endif\t/* ifndef YY_NO_INPUT */\n/* %endif */\n\n/** Immediately switch to a different input stream.\n * @param input_file A readable stream.\n * \n * @note This function does not reset the start condition to @c INITIAL .\n */\n/* %if-c-only */\n    void yyrestart  (FILE * input_file )\n/* %endif */\n/* %if-c++-only */\n/* %endif */\n{\n    \n\tif ( ! YY_CURRENT_BUFFER ){\n        yyensure_buffer_stack ();\n\t\tYY_CURRENT_BUFFER_LVALUE =\n            yy_create_buffer( yyin, YY_BUF_SIZE );\n\t}\n\n\tyy_init_buffer( YY_CURRENT_BUFFER, input_file );\n\tyy_load_buffer_state(  );\n}\n\n/* %if-c++-only */\n/* %endif */\n\n/** Switch to a different input buffer.\n * @param new_buffer The new input buffer.\n * \n */\n/* %if-c-only */\n    void yy_switch_to_buffer  (YY_BUFFER_STATE  new_buffer )\n/* %endif */\n/* %if-c++-only */\n/* %endif */\n{\n    \n\t/* TODO. We should be able to replace this entire function body\n\t * with\n\t *\t\tyypop_buffer_state();\n\t *\t\tyypush_buffer_state(new_buffer);\n     */\n\tyyensure_buffer_stack ();\n\tif ( YY_CURRENT_BUFFER == new_buffer )\n\t\treturn;\n\n\tif ( YY_CURRENT_BUFFER )\n\t\t{\n\t\t/* Flush out information for old buffer. */\n\t\t*(yy_c_buf_p) = (yy_hold_char);\n\t\tYY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p);\n\t\tYY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);\n\t\t}\n\n\tYY_CURRENT_BUFFER_LVALUE = new_buffer;\n\tyy_load_buffer_state(  );\n\n\t/* We don't actually know whether we did this switch during\n\t * EOF (yywrap()) processing, but the only time this flag\n\t * is looked at is after yywrap() is called, so it's safe\n\t * to go ahead and always set it.\n\t */\n\t(yy_did_buffer_switch_on_eof) = 1;\n}\n\n/* %if-c-only */\nstatic void yy_load_buffer_state  (void)\n/* %endif */\n/* %if-c++-only */\n/* %endif */\n{\n    \t(yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;\n\t(yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos;\n/* %if-c-only */\n\tyyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file;\n/* %endif */\n/* %if-c++-only */\n/* %endif */\n\t(yy_hold_char) = *(yy_c_buf_p);\n}\n\n/** Allocate and initialize an input buffer state.\n * @param file A readable stream.\n * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE.\n * \n * @return the allocated buffer state.\n */\n/* %if-c-only */\n    YY_BUFFER_STATE yy_create_buffer  (FILE * file, int  size )\n/* %endif */\n/* %if-c++-only */\n/* %endif */\n{\n\tYY_BUFFER_STATE b;\n    \n\tb = (YY_BUFFER_STATE) yyalloc( sizeof( struct yy_buffer_state )  );\n\tif ( ! b )\n\t\tYY_FATAL_ERROR( \"out of dynamic memory in yy_create_buffer()\" );\n\n\tb->yy_buf_size = size;\n\n\t/* yy_ch_buf has to be 2 characters longer than the size given because\n\t * we need to put in 2 end-of-buffer characters.\n\t */\n\tb->yy_ch_buf = (char *) yyalloc( (yy_size_t) (b->yy_buf_size + 2)  );\n\tif ( ! b->yy_ch_buf )\n\t\tYY_FATAL_ERROR( \"out of dynamic memory in yy_create_buffer()\" );\n\n\tb->yy_is_our_buffer = 1;\n\n\tyy_init_buffer( b, file );\n\n\treturn b;\n}\n\n/* %if-c++-only */\n/* %endif */\n\n/** Destroy the buffer.\n * @param b a buffer created with yy_create_buffer()\n * \n */\n/* %if-c-only */\n    void yy_delete_buffer (YY_BUFFER_STATE  b )\n/* %endif */\n/* %if-c++-only */\n/* %endif */\n{\n    \n\tif ( ! b )\n\t\treturn;\n\n\tif ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */\n\t\tYY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0;\n\n\tif ( b->yy_is_our_buffer )\n\t\tyyfree( (void *) b->yy_ch_buf  );\n\n\tyyfree( (void *) b  );\n}\n\n/* Initializes or reinitializes a buffer.\n * This function is sometimes called more than once on the same buffer,\n * such as during a yyrestart() or at EOF.\n */\n/* %if-c-only */\n    static void yy_init_buffer  (YY_BUFFER_STATE  b, FILE * file )\n/* %endif */\n/* %if-c++-only */\n/* %endif */\n\n{\n\tint oerrno = errno;\n    \n\tyy_flush_buffer( b );\n\n/* %if-c-only */\n\tb->yy_input_file = file;\n/* %endif */\n/* %if-c++-only */\n/* %endif */\n\tb->yy_fill_buffer = 1;\n\n    /* If b is the current buffer, then yy_init_buffer was _probably_\n     * called from yyrestart() or through yy_get_next_buffer.\n     * In that case, we don't want to reset the lineno or column.\n     */\n    if (b != YY_CURRENT_BUFFER){\n        b->yy_bs_lineno = 1;\n        b->yy_bs_column = 0;\n    }\n\n/* %if-c-only */\n\n        b->yy_is_interactive = 0;\n    \n/* %endif */\n/* %if-c++-only */\n/* %endif */\n\terrno = oerrno;\n}\n\n/** Discard all buffered characters. On the next scan, YY_INPUT will be called.\n * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER.\n * \n */\n/* %if-c-only */\n    void yy_flush_buffer (YY_BUFFER_STATE  b )\n/* %endif */\n/* %if-c++-only */\n/* %endif */\n{\n    \tif ( ! b )\n\t\treturn;\n\n\tb->yy_n_chars = 0;\n\n\t/* We always need two end-of-buffer characters.  The first causes\n\t * a transition to the end-of-buffer state.  The second causes\n\t * a jam in that state.\n\t */\n\tb->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR;\n\tb->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR;\n\n\tb->yy_buf_pos = &b->yy_ch_buf[0];\n\n\tb->yy_at_bol = 1;\n\tb->yy_buffer_status = YY_BUFFER_NEW;\n\n\tif ( b == YY_CURRENT_BUFFER )\n\t\tyy_load_buffer_state(  );\n}\n\n/* %if-c-or-c++ */\n/** Pushes the new state onto the stack. The new state becomes\n *  the current state. This function will allocate the stack\n *  if necessary.\n *  @param new_buffer The new state.\n *  \n */\n/* %if-c-only */\nvoid yypush_buffer_state (YY_BUFFER_STATE new_buffer )\n/* %endif */\n/* %if-c++-only */\n/* %endif */\n{\n    \tif (new_buffer == NULL)\n\t\treturn;\n\n\tyyensure_buffer_stack();\n\n\t/* This block is copied from yy_switch_to_buffer. */\n\tif ( YY_CURRENT_BUFFER )\n\t\t{\n\t\t/* Flush out information for old buffer. */\n\t\t*(yy_c_buf_p) = (yy_hold_char);\n\t\tYY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p);\n\t\tYY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);\n\t\t}\n\n\t/* Only push if top exists. Otherwise, replace top. */\n\tif (YY_CURRENT_BUFFER)\n\t\t(yy_buffer_stack_top)++;\n\tYY_CURRENT_BUFFER_LVALUE = new_buffer;\n\n\t/* copied from yy_switch_to_buffer. */\n\tyy_load_buffer_state(  );\n\t(yy_did_buffer_switch_on_eof) = 1;\n}\n/* %endif */\n\n/* %if-c-or-c++ */\n/** Removes and deletes the top of the stack, if present.\n *  The next element becomes the new top.\n *  \n */\n/* %if-c-only */\nvoid yypop_buffer_state (void)\n/* %endif */\n/* %if-c++-only */\n/* %endif */\n{\n    \tif (!YY_CURRENT_BUFFER)\n\t\treturn;\n\n\tyy_delete_buffer(YY_CURRENT_BUFFER );\n\tYY_CURRENT_BUFFER_LVALUE = NULL;\n\tif ((yy_buffer_stack_top) > 0)\n\t\t--(yy_buffer_stack_top);\n\n\tif (YY_CURRENT_BUFFER) {\n\t\tyy_load_buffer_state(  );\n\t\t(yy_did_buffer_switch_on_eof) = 1;\n\t}\n}\n/* %endif */\n\n/* %if-c-or-c++ */\n/* Allocates the stack if it does not exist.\n *  Guarantees space for at least one push.\n */\n/* %if-c-only */\nstatic void yyensure_buffer_stack (void)\n/* %endif */\n/* %if-c++-only */\n/* %endif */\n{\n\tyy_size_t num_to_alloc;\n    \n\tif (!(yy_buffer_stack)) {\n\n\t\t/* First allocation is just for 2 elements, since we don't know if this\n\t\t * scanner will even need a stack. We use 2 instead of 1 to avoid an\n\t\t * immediate realloc on the next call.\n         */\n      num_to_alloc = 1; /* After all that talk, this was set to 1 anyways... */\n\t\t(yy_buffer_stack) = (struct yy_buffer_state**)yyalloc\n\t\t\t\t\t\t\t\t(num_to_alloc * sizeof(struct yy_buffer_state*)\n\t\t\t\t\t\t\t\t);\n\t\tif ( ! (yy_buffer_stack) )\n\t\t\tYY_FATAL_ERROR( \"out of dynamic memory in yyensure_buffer_stack()\" );\n\n\t\tmemset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*));\n\n\t\t(yy_buffer_stack_max) = num_to_alloc;\n\t\t(yy_buffer_stack_top) = 0;\n\t\treturn;\n\t}\n\n\tif ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){\n\n\t\t/* Increase the buffer to prepare for a possible push. */\n\t\tyy_size_t grow_size = 8 /* arbitrary grow size */;\n\n\t\tnum_to_alloc = (yy_buffer_stack_max) + grow_size;\n\t\t(yy_buffer_stack) = (struct yy_buffer_state**)yyrealloc\n\t\t\t\t\t\t\t\t((yy_buffer_stack),\n\t\t\t\t\t\t\t\tnum_to_alloc * sizeof(struct yy_buffer_state*)\n\t\t\t\t\t\t\t\t);\n\t\tif ( ! (yy_buffer_stack) )\n\t\t\tYY_FATAL_ERROR( \"out of dynamic memory in yyensure_buffer_stack()\" );\n\n\t\t/* zero only the new slots.*/\n\t\tmemset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*));\n\t\t(yy_buffer_stack_max) = num_to_alloc;\n\t}\n}\n/* %endif */\n\n/* %if-c-only */\n/** Setup the input buffer state to scan directly from a user-specified character buffer.\n * @param base the character buffer\n * @param size the size in bytes of the character buffer\n * \n * @return the newly allocated buffer state object.\n */\nYY_BUFFER_STATE yy_scan_buffer  (char * base, yy_size_t  size )\n{\n\tYY_BUFFER_STATE b;\n    \n\tif ( size < 2 ||\n\t     base[size-2] != YY_END_OF_BUFFER_CHAR ||\n\t     base[size-1] != YY_END_OF_BUFFER_CHAR )\n\t\t/* They forgot to leave room for the EOB's. */\n\t\treturn NULL;\n\n\tb = (YY_BUFFER_STATE) yyalloc( sizeof( struct yy_buffer_state )  );\n\tif ( ! b )\n\t\tYY_FATAL_ERROR( \"out of dynamic memory in yy_scan_buffer()\" );\n\n\tb->yy_buf_size = (int) (size - 2);\t/* \"- 2\" to take care of EOB's */\n\tb->yy_buf_pos = b->yy_ch_buf = base;\n\tb->yy_is_our_buffer = 0;\n\tb->yy_input_file = NULL;\n\tb->yy_n_chars = b->yy_buf_size;\n\tb->yy_is_interactive = 0;\n\tb->yy_at_bol = 1;\n\tb->yy_fill_buffer = 0;\n\tb->yy_buffer_status = YY_BUFFER_NEW;\n\n\tyy_switch_to_buffer( b  );\n\n\treturn b;\n}\n/* %endif */\n\n/* %if-c-only */\n/** Setup the input buffer state to scan a string. The next call to yylex() will\n * scan from a @e copy of @a str.\n * @param yystr a NUL-terminated string to scan\n * \n * @return the newly allocated buffer state object.\n * @note If you want to scan bytes that may contain NUL values, then use\n *       yy_scan_bytes() instead.\n */\nYY_BUFFER_STATE yy_scan_string (const char * yystr )\n{\n    \n\treturn yy_scan_bytes( yystr, (int) strlen(yystr) );\n}\n/* %endif */\n\n/* %if-c-only */\n/** Setup the input buffer state to scan the given bytes. The next call to yylex() will\n * scan from a @e copy of @a bytes.\n * @param yybytes the byte buffer to scan\n * @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes.\n * \n * @return the newly allocated buffer state object.\n */\nYY_BUFFER_STATE yy_scan_bytes  (const char * yybytes, yy_size_t  _yybytes_len )\n{\n\tYY_BUFFER_STATE b;\n\tchar *buf;\n\tyy_size_t n;\n\tyy_size_t i;\n    \n\t/* Get memory for full buffer, including space for trailing EOB's. */\n\tn = (yy_size_t) (_yybytes_len + 2);\n\tbuf = (char *) yyalloc( n  );\n\tif ( ! buf )\n\t\tYY_FATAL_ERROR( \"out of dynamic memory in yy_scan_bytes()\" );\n\n\tfor ( i = 0; i < _yybytes_len; ++i )\n\t\tbuf[i] = yybytes[i];\n\n\tbuf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR;\n\n\tb = yy_scan_buffer( buf, n );\n\tif ( ! b )\n\t\tYY_FATAL_ERROR( \"bad buffer in yy_scan_bytes()\" );\n\n\t/* It's okay to grow etc. this buffer, and we should throw it\n\t * away when we're done.\n\t */\n\tb->yy_is_our_buffer = 1;\n\n\treturn b;\n}\n/* %endif */\n\n#ifndef YY_EXIT_FAILURE\n#define YY_EXIT_FAILURE 2\n#endif\n\n/* %if-c-only */\nstatic void yynoreturn yy_fatal_error (const char* msg )\n{\n\t\t\tfprintf( stderr, \"%s\\n\", msg );\n\texit( YY_EXIT_FAILURE );\n}\n/* %endif */\n/* %if-c++-only */\n/* %endif */\n\n/* Redefine yyless() so it works in section 3 code. */\n\n#undef yyless\n#define yyless(n) \\\n\tdo \\\n\t\t{ \\\n\t\t/* Undo effects of setting up yytext. */ \\\n        yy_size_t yyless_macro_arg = (n); \\\n        YY_LESS_LINENO(yyless_macro_arg);\\\n\t\tyytext[yyleng] = (yy_hold_char); \\\n\t\t(yy_c_buf_p) = yytext + yyless_macro_arg; \\\n\t\t(yy_hold_char) = *(yy_c_buf_p); \\\n\t\t*(yy_c_buf_p) = '\\0'; \\\n\t\tyyleng = yyless_macro_arg; \\\n\t\t} \\\n\twhile ( 0 )\n\n/* Accessor  methods (get/set functions) to struct members. */\n\n/* %if-c-only */\n/* %if-reentrant */\n/* %endif */\n\n/** Get the current line number.\n * \n */\nint yyget_lineno  (void)\n{\n    \n    return yylineno;\n}\n\n/** Get the input stream.\n * \n */\nFILE *yyget_in  (void)\n{\n        return yyin;\n}\n\n/** Get the output stream.\n * \n */\nFILE *yyget_out  (void)\n{\n        return yyout;\n}\n\n/** Get the length of the current token.\n * \n */\nyy_size_t yyget_leng  (void)\n{\n        return yyleng;\n}\n\n/** Get the current token.\n * \n */\n\nchar *yyget_text  (void)\n{\n        return yytext;\n}\n\n/* %if-reentrant */\n/* %endif */\n\n/** Set the current line number.\n * @param _line_number line number\n * \n */\nvoid yyset_lineno (int  _line_number )\n{\n    \n    yylineno = _line_number;\n}\n\n/** Set the input stream. This does not discard the current\n * input buffer.\n * @param _in_str A readable stream.\n * \n * @see yy_switch_to_buffer\n */\nvoid yyset_in (FILE *  _in_str )\n{\n        yyin = _in_str ;\n}\n\nvoid yyset_out (FILE *  _out_str )\n{\n        yyout = _out_str ;\n}\n\nint yyget_debug  (void)\n{\n        return yy_flex_debug;\n}\n\nvoid yyset_debug (int  _bdebug )\n{\n        yy_flex_debug = _bdebug ;\n}\n\n/* %endif */\n\n/* %if-reentrant */\n/* %if-bison-bridge */\n/* %endif */\n/* %endif if-c-only */\n\n/* %if-c-only */\nstatic int yy_init_globals (void)\n{\n        /* Initialization is the same as for the non-reentrant scanner.\n     * This function is called from yylex_destroy(), so don't allocate here.\n     */\n\n    (yy_buffer_stack) = NULL;\n    (yy_buffer_stack_top) = 0;\n    (yy_buffer_stack_max) = 0;\n    (yy_c_buf_p) = NULL;\n    (yy_init) = 0;\n    (yy_start) = 0;\n\n/* Defined in main.c */\n#ifdef YY_STDINIT\n    yyin = stdin;\n    yyout = stdout;\n#else\n    yyin = NULL;\n    yyout = NULL;\n#endif\n\n    /* For future reference: Set errno on error, since we are called by\n     * yylex_init()\n     */\n    return 0;\n}\n/* %endif */\n\n/* %if-c-only SNIP! this currently causes conflicts with the c++ scanner */\n/* yylex_destroy is for both reentrant and non-reentrant scanners. */\nint yylex_destroy  (void)\n{\n    \n    /* Pop the buffer stack, destroying each element. */\n\twhile(YY_CURRENT_BUFFER){\n\t\tyy_delete_buffer( YY_CURRENT_BUFFER  );\n\t\tYY_CURRENT_BUFFER_LVALUE = NULL;\n\t\tyypop_buffer_state();\n\t}\n\n\t/* Destroy the stack itself. */\n\tyyfree((yy_buffer_stack) );\n\t(yy_buffer_stack) = NULL;\n\n    /* Reset the globals. This is important in a non-reentrant scanner so the next time\n     * yylex() is called, initialization will occur. */\n    yy_init_globals( );\n\n/* %if-reentrant */\n/* %endif */\n    return 0;\n}\n/* %endif */\n\n/*\n * Internal utility routines.\n */\n\n#ifndef yytext_ptr\nstatic void yy_flex_strncpy (char* s1, const char * s2, int n )\n{\n\t\t\n\tint i;\n\tfor ( i = 0; i < n; ++i )\n\t\ts1[i] = s2[i];\n}\n#endif\n\n#ifdef YY_NEED_STRLEN\nstatic int yy_flex_strlen (const char * s )\n{\n\tint n;\n\tfor ( n = 0; s[n]; ++n )\n\t\t;\n\n\treturn n;\n}\n#endif\n\nvoid *yyalloc (yy_size_t  size )\n{\n\t\t\treturn malloc(size);\n}\n\nvoid *yyrealloc  (void * ptr, yy_size_t  size )\n{\n\t\t\n\t/* The cast to (char *) in the following accommodates both\n\t * implementations that use char* generic pointers, and those\n\t * that use void* generic pointers.  It works with the latter\n\t * because both ANSI C and C++ allow castless assignment from\n\t * any pointer type to void*, and deal with argument conversions\n\t * as though doing an assignment.\n\t */\n\treturn realloc(ptr, size);\n}\n\nvoid yyfree (void * ptr )\n{\n\t\t\tfree( (char *) ptr );\t/* see yyrealloc() for (char *) cast */\n}\n\n/* %if-tables-serialization definitions */\n/* %define-yytables   The name for this specific scanner's tables. */\n#define YYTABLES_NAME \"yytables\"\n/* %endif */\n\n/* %ok-for-header */\n\n#line 1350 \"seclang-scanner.ll\"\n\n\nnamespace modsecurity {\n\nbool Driver::scan_begin () {\n    yy_flex_debug = trace_scanning;\n\n    if (buffer.empty() == false) {\n        yy_scan_string(buffer.c_str());\n        return true;\n    }\n    return false;\n}\n\nvoid Driver::scan_end () {\n    yylex_destroy();\n    BEGIN(INITIAL);\n}\n\n}\n\n\n"
  },
  {
    "path": "src/parser/seclang-scanner.ll",
    "content": "%{ /* -*- C++ -*- */\n#include <cerrno>\n#include <climits>\n#include <cstdlib>\n#include <string>\n\n#include \"src/parser/driver.h\"\n#include \"src/parser/seclang-parser.hh\"\n#include \"src/utils/https_client.h\"\n#include \"src/utils/string.h\"\n\nusing modsecurity::Parser::Driver;\nusing modsecurity::Utils::HttpsClient;\nusing modsecurity::utils::string::parserSanitizer;\n\ntypedef yy::seclang_parser p;\nstatic int state_variable_from = 0;\nstatic std::stack<int> YY_PREVIOUS_STATE;\n\n// Work around an incompatibility in flex (at least versions\n// 2.5.31 through 2.5.33): it generates code that does\n// not conform to C89.  See Debian bug 333231\n// <http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=333231>.\n# undef yywrap\n# define yywrap() 1\n\n#define BEGINX(z) { \\\n    YY_PREVIOUS_STATE.push(YY_START); \\\n    BEGIN(z); \\\n}\n\n#define BEGINX_() { \\\n    YY_PREVIOUS_STATE.push(YY_START); \\\n    if (YY_START == SETVAR_ACTION_NONQUOTED) { \\\n        BEGIN(EXPECTING_VAR_PARAMETER_OR_MACRO_NONQUOTED); \\\n    } else if (YY_START == SETVAR_ACTION_QUOTED) { \\\n        BEGIN(EXPECTING_VAR_PARAMETER_OR_MACRO_QUOTED); \\\n    } else { \\\n        BEGIN(EXPECTING_VAR_PARAMETER); \\\n    } \\\n}\n\n#define BEGIN_PARAMETER() { if (YY_START == EXPECTING_OPERATOR_ENDS_WITH_SPACE) { BEGIN(TRANSITION_FROM_OP_TO_EXPECTING_PARAMETER_ENDS_WITH_SPACE); } else { BEGIN(TRANSITION_FROM_OP_TO_EXPECTING_PARAMETER_ENDS_WITH_QUOTE); } }\n#define BEGIN_NO_OP_INFORMED() { if (YY_START == EXPECTING_OPERATOR_ENDS_WITH_SPACE) { BEGIN(NO_OP_INFORMED_ENDS_WITH_SPACE); } else { BEGIN(NO_OP_INFORMED_ENDS_WITH_QUOTE); } }\n\n#define BEGIN_ACTION_OPERATION() { \\\n    if (YY_START == SETVAR_ACTION_NONQUOTED) { \\\n        BEGIN(SETVAR_ACTION_NONQUOTED_WAITING_OPERATION); \\\n    } else if (YY_START == SETVAR_ACTION_QUOTED) { \\\n        BEGIN(SETVAR_ACTION_QUOTED_WAITING_OPERATION); \\\n    } else if (YY_START == SETVAR_ACTION_NONQUOTED_WAITING_COLLECTION_ELEM) { \\\n        BEGIN(SETVAR_ACTION_NONQUOTED_WAITING_OPERATION); \\\n    } else if (YY_START == SETVAR_ACTION_QUOTED_WAITING_COLLECTION_ELEM) { \\\n        BEGIN(SETVAR_ACTION_QUOTED_WAITING_OPERATION); \\\n    }\\\n}\n\n\n#define BEGIN_ACTION_WAITING_CONTENT() { \\\n    if (YY_START == SETVAR_ACTION_NONQUOTED_WAITING_OPERATION) { \\\n        BEGIN(SETVAR_ACTION_NONQUOTED_WAITING_CONTENT); \\\n    } else if (YY_START == SETVAR_ACTION_QUOTED_WAITING_OPERATION) { \\\n        BEGIN(SETVAR_ACTION_QUOTED_WAITING_CONTENT); \\\n    } else if (YY_START == EXPECTING_VAR_PARAMETER_OR_MACRO_QUOTED) { \\\n        BEGIN(SETVAR_ACTION_QUOTED_WAITING_CONTENT); \\\n    } else if (YY_START == EXPECTING_VAR_PARAMETER_OR_MACRO_NONQUOTED) { \\\n        BEGIN(SETVAR_ACTION_NONQUOTED_WAITING_CONTENT); \\\n    } \\\n}\n\n\n#define BEGIN_PREVIOUS() { BEGIN(YY_PREVIOUS_STATE.top()); YY_PREVIOUS_STATE.pop(); }\n\n// The location of the current token.\n%}\n%option noyywrap nounput batch debug noinput nounistd never-interactive\n\n\n\nACTION_ACCURACY                                 (?i:accuracy)\nACTION_ALLOW                                    ((?i:allow:(?i:REQUEST|PHASE))|(?i:phase:'(?i:REQUEST|PHASE)')|(?i:allow))\nACTION_APPEND                                   (?i:append)\nACTION_AUDIT_LOG                                (?i:auditlog)\nACTION_BLOCK                                    (?i:block)\nACTION_CAPTURE                                  (?i:capture)\nACTION_CHAIN                                    (?i:chain)\nACTION_CTL_AUDIT_ENGINE                         (?i:ctl:auditEngine)\nACTION_CTL_AUDIT_LOG_PARTS                      (?i:ctl:auditLogParts)\nACTION_CTL_BDY_JSON                             (?i:ctl:requestBodyProcessor=JSON)\nACTION_CTL_BDY_XML                              (?i:ctl:requestBodyProcessor=XML)\nACTION_CTL_BDY_URLENCODED                       (?i:ctl:requestBodyProcessor=URLENCODED)\nACTION_CTL_FORCE_REQ_BODY_VAR                   (?i:ctl:forceRequestBodyVariable)\nACTION_CTL_PARSE_XML_INTO_ARGS                  (?i:ctl:parseXmlIntoArgs)\nACTION_CTL_REQUEST_BODY_ACCESS                  (?i:ctl:requestBodyAccess)\nACTION_CTL_RULE_ENGINE                          (?i:ctl:ruleEngine)\nACTION_CTL_RULE_REMOVE_BY_TAG                   (?i:ctl:ruleRemoveByTag)\nACTION_CTL_RULE_REMOVE_BY_ID                    (?i:ctl:ruleRemoveById)\nACTION_CTL_RULE_REMOVE_TARGET_BY_ID             (?i:ctl:ruleRemoveTargetById)\nACTION_CTL_RULE_REMOVE_TARGET_BY_TAG            (?i:ctl:ruleRemoveTargetByTag)\nACTION_DENY                                     (?i:deny)\nACTION_DEPRECATE_VAR                            (?i:deprecatevar)\nACTION_DROP                                     (?i:drop)\nACTION_EXEC                                     (?i:exec)\nACTION_EXPIRE_VAR                               (?i:expirevar)\nACTION_ID                                       (?i:id:[0-9]+|id:'[0-9]+')\nACTION_INITCOL                                  (?i:initcol)\nACTION_LOG_DATA                                 (?i:logdata)\nACTION_LOG                                      (?i:log)\nACTION_MATURITY                                 (?i:maturity)\nACTION_MSG                                      (?i:msg)\nACTION_MULTI_MATCH                              (?i:multiMatch)\nACTION_NO_AUDIT_LOG                             (?i:noauditlog)\nACTION_NO_LOG                                   (?i:nolog)\nACTION_PASS                                     (?i:pass)\nACTION_PAUSE                                    (?i:pause)\nACTION_PHASE                                    ((?i:phase:(?i:REQUEST|RESPONSE|LOGGING|[0-9]+))|(?i:phase:'(?i:REQUEST|RESPONSE|LOGGING|[0-9]+)'))\nACTION_PREPEND                                  (?i:prepend)\nACTION_PROXY                                    (?i:proxy)\nACTION_REDIRECT                                 (?i:redirect)\nACTION_REV                                      (?i:rev)\nACTION_SANITISE_ARG                             (?i:sanitiseArg)\nACTION_SANITISE_MATCHED_BYTES                   (?i:sanitiseMatchedBytes)\nACTION_SANITISE_MATCHED                         (?i:sanitiseMatched)\nACTION_SANITISE_REQUEST_HEADER                  (?i:sanitiseRequestHeader)\nACTION_SANITISE_RESPONSE_HEADER                 (?i:sanitiseResponseHeader)\nACTION_SETENV                                   (?i:setenv)\nACTION_SETRSC                                   (?i:setrsc)\nACTION_SETSID                                   (?i:setsid)\nACTION_SETUID                                   (?i:setuid)\nACTION_SETVAR                                   (?i:setvar)\nACTION_SEVERITY                                 (?i:severity)\nACTION_SEVERITY_VALUE                           (?i:(EMERGENCY|ALERT|CRITICAL|ERROR|WARNING|NOTICE|INFO|DEBUG)|[0-9]+)\nACTION_SKIP_AFTER                               (?i:skipAfter)\nACTION_SKIP                                     (?i:skip)\nACTION_STATUS                                   (?i:status:[0-9]+)\nACTION_TAG                                      (?i:tag)\nACTION_VER                                      (?i:ver)\nACTION_XMLNS                                    (?i:xmlns)            \nACTION_TRANSFORMATION_BASE_64_ENCODE            (?i:t:base64Encode)\nACTION_TRANSFORMATION_BASE_64_DECODE            (?i:t:base64Decode)\nACTION_TRANSFORMATION_BASE_64_DECODE_EXT        (?i:t:base64DecodeExt)\nACTION_TRANSFORMATION_CMD_LINE                  (?i:t:cmdLine)\nACTION_TRANSFORMATION_COMPRESS_WHITESPACE       (?i:t:compressWhitespace)\nACTION_TRANSFORMATION_ESCAPE_SEQ_DECODE         (?i:t:escapeSeqDecode)\nACTION_TRANSFORMATION_CSS_DECODE                (?i:t:cssDecode)\nACTION_TRANSFORMATION_HEX_ENCODE                (?i:t:hexEncode)\nACTION_TRANSFORMATION_HEX_DECODE                (?i:t:hexDecode)\nACTION_TRANSFORMATION_HTML_ENTITY_DECODE        (?i:t:htmlEntityDecode)\nACTION_TRANSFORMATION_JS_DECODE                 (?i:t:jsDecode)\nACTION_TRANSFORMATION_LENGTH                    (?i:t:length)\nACTION_TRANSFORMATION_LOWERCASE                 (?i:t:lowercase)\nACTION_TRANSFORMATION_MD5                       (?i:t:md5)\nACTION_TRANSFORMATION_NONE                      (?i:t:none)\nACTION_TRANSFORMATION_NORMALISE_PATH            (?i:t:(normalisePath|normalizePath))\nACTION_TRANSFORMATION_NORMALISE_PATH_WIN        (?i:t:(normalisePathWin|normalizePathWin))\nACTION_TRANSFORMATION_PARITY_EVEN_7_BIT         (?i:t:parityEven7bit)\nACTION_TRANSFORMATION_PARITY_ODD_7_BIT          (?i:t:parityOdd7bit)\nACTION_TRANSFORMATION_PARITY_ZERO_7_BIT         (?i:t:parityZero7bit)\nACTION_TRANSFORMATION_REMOVE_COMMENTS           (?i:t:removeComments)\nACTION_TRANSFORMATION_REMOVE_COMMENTS_CHAR      (?i:t:removeCommentsChar)\nACTION_TRANSFORMATION_REMOVE_NULLS              (?i:t:removeNulls)\nACTION_TRANSFORMATION_REMOVE_WHITESPACE         (?i:t:removeWhitespace)\nACTION_TRANSFORMATION_REPLACE_COMMENTS          (?i:t:replaceComments)\nACTION_TRANSFORMATION_REPLACE_NULLS             (?i:t:replaceNulls)\nACTION_TRANSFORMATION_SHA1                      (?i:t:sha1)\nACTION_TRANSFORMATION_SQL_HEX_DECODE            (?i:t:sqlHexDecode)\nACTION_TRANSFORMATION_TRIM                      (?i:t:trim)\nACTION_TRANSFORMATION_TRIM_LEFT                 (?i:t:trimLeft)\nACTION_TRANSFORMATION_TRIM_RIGHT                (?i:t:trimRight)\nACTION_TRANSFORMATION_UPPERCASE                 (?i:t:uppercase)\nACTION_TRANSFORMATION_URL_ENCODE                (?i:t:urlEncode)\nACTION_TRANSFORMATION_URL_DECODE                (?i:t:urlDecode)\nACTION_TRANSFORMATION_URL_DECODE_UNI            (?i:t:urlDecodeUni)\nACTION_TRANSFORMATION_UTF8_TO_UNICODE           (?i:t:utf8toUnicode)\n\n\nVARIABLE_ARGS_COMBINED_SIZE               (?i:ARGS_COMBINED_SIZE)\nVARIABLE_ARGS_GET_NAMES                   (?i:ARGS_GET_NAMES)\nVARIABLE_ARGS_NAMES                       (?i:ARGS_NAMES)\nVARIABLE_ARGS_POST_NAMES                  (?i:ARGS_POST_NAMES)\nVARIABLE_AUTH_TYPE                        (?i:AUTH_TYPE)\nVARIABLE_FILES_COMBINED_SIZE              (?i:FILES_COMBINED_SIZE)\nVARIABLE_FILES_TMP_NAMES                  (?i:FILES_TMPNAMES)\nVARIABLE_FULL_REQUEST                     (?i:FULL_REQUEST)\nVARIABLE_FULL_REQUEST_LENGTH              (?i:FULL_REQUEST_LENGTH)\nVARIABLE_GLOBAL                           (?i:GLOBAL)\nVARIABLE_INBOUND_DATA_ERROR               (?i:INBOUND_DATA_ERROR)\nVARIABLE_MATCHED_VAR                      (?i:MATCHED_VAR)\nVARIABLE_MATCHED_VAR_NAME                 (?i:MATCHED_VAR_NAME)\nVARIABLE_MSC_PCRE_ERROR                   (?i:MSC_PCRE_ERROR)\nVARIABLE_MSC_PCRE_LIMITS_EXCEEDED         (?i:MSC_PCRE_LIMITS_EXCEEDED)\nVARIABLE_MULTIPART_BOUNDARY_QUOTED        (?i:MULTIPART_BOUNDARY_QUOTED)\nVARIABLE_MULTIPART_BOUNDARY_WHITESPACE    (?i:MULTIPART_BOUNDARY_WHITESPACE)\nVARIABLE_MULTIPART_CRLF_LF_LINES          (?i:MULTIPART_CRLF_LF_LINES)\nVARIABLE_MULTIPART_DATA_AFTER             (?i:MULTIPART_DATA_AFTER)\nVARIABLE_MULTIPART_DATA_BEFORE            (?i:MULTIPART_DATA_BEFORE)\nVARIABLE_MULTIPART_FILE_LIMIT_EXCEEDED    (?i:MULTIPART_FILE_LIMIT_EXCEEDED)\nVARIABLE_MULTIPART_FILENAME               (?i:MULTIPART_FILENAME)\nVARIABLE_MULTIPART_HEADER_FOLDING         (?i:MULTIPART_HEADER_FOLDING)\nVARIABLE_MULTIPART_INVALID_HEADER_FOLDING (?i:MULTIPART_INVALID_HEADER_FOLDING)\nVARIABLE_MULTIPART_INVALID_PART           (?i:MULTIPART_INVALID_PART)\nVARIABLE_MULTIPART_INVALID_QUOTING        (?i:MULTIPART_INVALID_QUOTING)\nVARIABLE_MULTIPART_LF_LINE                (?i:MULTIPART_LF_LINE)\nVARIABLE_MULTIPART_MISSING_SEMICOLON      (?i:MULTIPART_MISSING_SEMICOLON)\nVARIABLE_MULTIPART_SEMICOLON_MISSING      (?i:MULTIPART_SEMICOLON_MISSING)\nVARIABLE_MULTIPART_NAME                   (?i:MULTIPART_NAME)\nVARIABLE_MULTIPART_STRICT_ERROR           (?i:MULTIPART_STRICT_ERROR)\nVARIABLE_MULTIPART_UNMATCHED_BOUNDARY     (?i:MULTIPART_UNMATCHED_BOUNDARY)\nVARIABLE_OUTBOUND_DATA_ERROR              (?i:OUTBOUND_DATA_ERROR)\nVARIABLE_PATH_INFO                        (?i:PATH_INFO)\nVARIABLE_QUERY_STRING                     (?i:QUERY_STRING)\nVARIABLE_REMOTE_ADDR                      (?i:REMOTE_ADDR)\nVARIABLE_REMOTE_HOST                      (?i:REMOTE_HOST)\nVARIABLE_REMOTE_PORT                      (?i:REMOTE_PORT)\nVARIABLE_REQBODY_ERROR                    (?i:REQBODY_ERROR)\nVARIABLE_REQBODY_ERROR_MSG                (?i:REQBODY_ERROR_MSG)\nVARIABLE_REQBODY_PROCESSOR_ERROR          (?i:REQBODY_PROCESSOR_ERROR)\nVARIABLE_REQBODY_PROCESSOR_ERROR_MSG      (?i:REQBODY_PROCESSOR_ERROR_MSG)\nVARIABLE_REQBODY_PROCESSOR                (?i:REQBODY_PROCESSOR)\nVARIABLE_REQUEST_BASENAME                 (?i:REQUEST_BASENAME)\nVARIABLE_REQUEST_BODY                     (?i:REQUEST_BODY)\nVARIABLE_REQUEST_BODY_LENGTH              (?i:REQUEST_BODY_LENGTH)\nVARIABLE_REQUEST_FILE_NAME                (?i:REQUEST_FILENAME)\nVARIABLE_REQUEST_HEADERS_NAMES            (?i:REQUEST_HEADERS_NAMES)\nVARIABLE_REQUEST_LINE                     (?i:REQUEST_LINE)\nVARIABLE_REQUEST_METHOD                   (?i:REQUEST_METHOD)\nVARIABLE_REQUEST_PROTOCOL                 (?i:REQUEST_PROTOCOL)\nVARIABLE_REQUEST_URI                      (?i:REQUEST_URI)\nVARIABLE_REQUEST_URI_RAW                  (?i:REQUEST_URI_RAW)\nVARIABLE_RESOURCE                         (?i:RESOURCE)\nVARIABLE_RESPONSE_BODY                    (?i:RESPONSE_BODY)\nVARIABLE_RESPONSE_CONTENT_LENGTH          (?i:RESPONSE_CONTENT_LENGTH)\nVARIABLE_RESPONSE_CONTENT_TYPE            (?i:RESPONSE_CONTENT_TYPE)\nVARIABLE_RESPONSE_HEADERS_NAMES           (?i:RESPONSE_HEADERS_NAMES)\nVARIABLE_RESPONSE_PROTOCOL                (?i:RESPONSE_PROTOCOL)\nVARIABLE_RESPONSE_STATUS                  (?i:RESPONSE_STATUS)\nVARIABLE_SERVER_ADDR                      (?i:SERVER_ADDR)\nVARIABLE_SERVER_NAME                      (?i:SERVER_NAME)\nVARIABLE_SERVER_PORT                      (?i:SERVER_PORT)\nVARIABLE_SESSION_ID                       (?i:SESSIONID)\nVARIABLE_UNIQUE_ID                        (?i:UNIQUE_ID)\nVARIABLE_URL_ENCODED_ERROR                (?i:URLENCODED_ERROR)\nVARIABLE_USER_ID                          (?i:USERID)\nVARIABLE_WEBSERVER_ERROR_LOG              (?i:WEBSERVER_ERROR_LOG)\nVARIABLE_ARGS                             (?i:ARGS)\nVARIABLE_ARGS_POST                        (?i:ARGS_POST)\nVARIABLE_ARGS_GET                         (?i:ARGS_GET)\nVARIABLE_FILES_SIZES                      (?i:FILES_SIZES)\nVARIABLE_FILES_NAMES                      (?i:FILES_NAMES)\nVARIABLE_FILES_TMP_CONTENT                (?i:FILES_TMP_CONTENT)\nVARIABLE_MATCHED_VARS_NAMES               (?i:MATCHED_VARS_NAMES)\nVARIABLE_MATCHED_VARS                     (?i:MATCHED_VARS)\nVARIABLE_FILES                            (?i:FILES)\nVARIABLE_REQUEST_COOKIES                  (?i:REQUEST_COOKIES)\nVARIABLE_REQUEST_HEADERS                  (?i:REQUEST_HEADERS)\nVARIABLE_RESPONSE_HEADERS                 (?i:RESPONSE_HEADERS)\nVARIABLE_GEO                              (?i:GEO)\nVARIABLE_REQUEST_COOKIES_NAMES            (?i:REQUEST_COOKIES_NAMES)\nVARIABLE_MULTIPART_PART_HEADERS           (?i:MULTIPART_PART_HEADERS)\nVARIABLE_RULE                             (?i:RULE)\nVARIABLE_SESSION                          (?i:(SESSION))\nVARIABLE_IP                               (?i:(IP))\nVARIABLE_USER                             (?i:(USER))\nVARIABLE_STATUS                           (?i:(STATUS))\nVARIABLE_STATUS_LINE                      (?i:(STATUS_LINE))\nVARIABLE_TX                               (?i:TX)\nVARIABLE_WEB_APP_ID                       (?i:WEBAPPID)\nRUN_TIME_VAR_BLD                          (?i:MODSEC_BUILD)\nRUN_TIME_VAR_DUR                          (?i:DURATION)\nRUN_TIME_VAR_ENV                          (?i:ENV)\nRUN_TIME_VAR_HSV                          (?i:HIGHEST_SEVERITY)\nRUN_TIME_VAR_REMOTE_USER                  (?i:REMOTE_USER)\nRUN_TIME_VAR_TIME                         (?i:TIME)\nRUN_TIME_VAR_TIME_DAY                     (?i:TIME_DAY)\nRUN_TIME_VAR_TIME_EPOCH                   (?i:TIME_EPOCH)\nRUN_TIME_VAR_TIME_HOUR                    (?i:TIME_HOUR)\nRUN_TIME_VAR_TIME_MIN                     (?i:TIME_MIN)\nRUN_TIME_VAR_TIME_MON                     (?i:TIME_MON)\nRUN_TIME_VAR_TIME_SEC                     (?i:TIME_SEC)\nRUN_TIME_VAR_TIME_WDAY                    (?i:TIME_WDAY)\nRUN_TIME_VAR_TIME_YEAR                    (?i:TIME_YEAR)\nRUN_TIME_VAR_XML                          (?i:XML)\nVAR_EXCLUSION                             !\nVAR_COUNT                                 &\n\n\nOPERATOR_BEGINS_WITH                    (?i:@beginsWith)\nOPERATOR_CONTAINS                       (?i:@contains)\nOPERATOR_CONTAINS_WORD                  (?i:@containsWord)\nOPERATOR_DETECT_SQLI                    (?i:@detectSQLi)\nOPERATOR_DETECT_XSS                     (?i:@detectXSS)\nOPERATOR_ENDS_WITH                      (?i:@endsWith)\nOPERATOR_EQ                             (?i:@eq)\nOPERATOR_FUZZY_HASH                     (?i:@fuzzyHash)\nOPERATOR_GE                             (?i:@ge)\nOPERATOR_GEOLOOKUP                      (?i:@geoLookup)\nOPERATOR_GSB_LOOKUP                     (?i:@gsbLookup)\nOPERATOR_GT                             (?i:@gt)\nOPERATOR_INSPECT_FILE                   (?i:@inspectFile)\nOPERATOR_IP_MATCH_FROM_FILE             (?i:(@ipMatchF|@ipMatchFromFile))\nOPERATOR_IP_MATCH                       (?i:@ipMatch)\nOPERATOR_LE                             (?i:@le)\nOPERATOR_LT                             (?i:@lt)\nOPERATOR_PM_FROM_FILE                   (?i:(@pmf|@pmFromFile))\nOPERATOR_PM                             (?i:@pm)\nOPERATOR_RBL                            (?i:@rbl)\nOPERATOR_RSUB                           (?i:@rsub)\nOPERATOR_RX                             (?i:@rx)\nOPERATOR_RX_GLOBAL                      (?i:@rxGlobal)\nOPERATOR_STR_EQ                         (?i:@streq)\nOPERATOR_STR_MATCH                      (?i:@strmatch)\nOPERATOR_UNCONDITIONAL_MATCH            (?i:@unconditionalMatch)\nOPERATOR_VALIDATE_BYTE_RANGE            (?i:@validateByteRange)\nOPERATOR_VALIDATE_DTD                   (?i:@validateDTD)\nOPERATOR_VALIDATE_HASH                  (?i:@validateHash)\nOPERATOR_VALIDATE_SCHEMA                (?i:@validateSchema)\nOPERATOR_VALIDATE_URL_ENCODING          (?i:@validateUrlEncoding)\nOPERATOR_VALIDATE_UTF8_ENCODING         (?i:@validateUtf8Encoding)\nOPERATOR_VERIFY_CC                      (?i:@verifyCC)\nOPERATOR_VERIFY_CPF                     (?i:@verifyCPF)\nOPERATOR_VERIFY_SSN                     (?i:@verifySSN)\nOPERATOR_VERIFY_SVNR                    (?i:@verifySVNR)\nOPERATOR_WITHIN                         (?i:@within)\n\n\nAUDIT_PARTS                             [ABCDEFGHJKIZ]+\nCOL_FREE_TEXT_SPACE_COMMA               ([^,\"])+\nCOL_NAME                                [A-Za-z]+\nCONFIG_COMPONENT_SIG                    (?i:SecComponentSignature)\nCONFIG_SEC_SERVER_SIG                   (?i:SecServerSignature)\nCONFIG_SEC_WEB_APP_ID                   (?i:SecWebAppId)\nCONFIG_SEC_CACHE_TRANSFORMATIONS        (?i:SecCacheTransformations)\nCONFIG_SEC_CHROOT_DIR                   (?i:SecChrootDir)\nCONFIG_CONN_ENGINE                      (?i:SecConnEngine)\nCONFIG_SEC_HASH_ENGINE                  (?i:SecHashEngine)\nCONFIG_SEC_HASH_KEY                     (?i:SecHashKey)\nCONFIG_SEC_HASH_PARAM                   (?i:SecHashParam)\nCONFIG_SEC_HASH_METHOD_RX               (?i:SecHashMethodRx)\nCONFIG_SEC_HASH_METHOD_PM               (?i:SecHashMethodPm)\nCONFIG_CONTENT_INJECTION                (?i:SecContentInjection)\nCONFIG_SEC_ARGUMENT_SEPARATOR           (?i:SecArgumentSeparator)\nCONFIG_DIR_AUDIT_DIR                    (?i:SecAuditLogStorageDir)\nCONFIG_DIR_AUDIT_DIR_MOD                (?i:SecAuditLogDirMode)\nCONFIG_DIR_AUDIT_ENG                    (?i:SecAuditEngine)\nCONFIG_DIR_AUDIT_FLE_MOD                (?i:SecAuditLogFileMode)\nCONFIG_DIR_AUDIT_LOG2                   (?i:SecAuditLog2)\nCONFIG_DIR_AUDIT_LOG                    (?i:SecAuditLog)\nCONFIG_DIR_AUDIT_LOG_FMT                (?i:SecAuditLogFormat)\nCONFIG_DIR_AUDIT_PREFIX                 (?i:SecAuditLogPrefix)\nCONFIG_DIR_AUDIT_LOG_P                  (?i:SecAuditLogParts)\nCONFIG_DIR_AUDIT_STS                    (?i:SecAuditLogRelevantStatus)\nCONFIG_DIR_AUDIT_TPE                    (?i:SecAuditLogType)\nCONFIG_DIR_DEBUG_LOG                    (?i:SecDebugLog)\nCONFIG_DIR_DEBUG_LVL                    (?i:SecDebugLogLevel)\nCONFIG_DIR_GEO_DB                       (?i:SecGeoLookupDb)\nCONFIG_DIR_GSB_DB                       (?i:SecGsbLookupDb)\nCONFIG_SEC_GUARDIAN_LOG                 (?i:SecGuardianLog)\nCONFIG_SEC_INTERCEPT_ON_ERROR           (?i:SecInterceptOnError)\nCONFIG_SEC_CONN_R_STATE_LIMIT           (?i:SecConnReadStateLimit)\nCONFIG_SEC_CONN_W_STATE_LIMIT           (?i:SecConnWriteStateLimit)\nCONFIG_SEC_SENSOR_ID                    (?i:SecSensorId)\nCONFIG_SEC_RULE_INHERITANCE             (?i:SecRuleInheritance)\nCONFIG_SEC_RULE_PERF_TIME               (?i:SecRulePerfTime)\nCONFIG_SEC_STREAM_IN_BODY_INSPECTION    (?i:SecStreamInBodyInspection)\nCONFIG_SEC_STREAM_OUT_BODY_INSPECTION   (?i:SecStreamOutBodyInspection)\nCONFIG_DIR_PCRE_MATCH_LIMIT             (?i:SecPcreMatchLimit)\nCONFIG_DIR_PCRE_MATCH_LIMIT_RECURSION   (?i:SecPcreMatchLimitRecursion)\nCONFIG_DIR_ARGS_LIMIT                   (?i:SecArgumentsLimit)\nCONFIG_DIR_REQ_BODY_JSON_DEPTH_LIMIT    (?i:SecRequestBodyJsonDepthLimit)\nCONFIG_DIR_REQ_BODY                     (?i:SecRequestBodyAccess)\nCONFIG_DIR_REQ_BODY_IN_MEMORY_LIMIT     (?i:SecRequestBodyInMemoryLimit)\nCONFIG_DIR_REQ_BODY_LIMIT               (?i:SecRequestBodyLimit)\nCONFIG_DIR_REQ_BODY_LIMIT_ACTION        (?i:SecRequestBodyLimitAction)\nCONFIG_DIR_REQ_BODY_NO_FILES_LIMIT      (?i:SecRequestBodyNoFilesLimit)\nCONFIG_DIR_RES_BODY                     (?i:SecResponseBodyAccess)\nCONFIG_DIR_RES_BODY_LIMIT               (?i:SecResponseBodyLimit)\nCONFIG_DIR_RES_BODY_LIMIT_ACTION        (?i:SecResponseBodyLimitAction)\nCONFIG_DIR_RULE_ENG                     (?i:SecRuleEngine)\nCONFIG_DIR_SEC_ACTION                   (?i:SecAction)\nCONFIG_DIR_SEC_DEFAULT_ACTION           (?i:SecDefaultAction)\nCONFIG_SEC_DISABLE_BACKEND_COMPRESS     (?i:SecDisableBackendCompression)\nCONFIG_DIR_SEC_MARKER                   (?i:SecMarker)\nCONFIG_DIR_UNICODE_MAP_FILE             (?i:SecUnicodeMapFile)\nCONFIG_INCLUDE                          (?i:Include)\nCONFIG_SEC_COLLECTION_TIMEOUT           (?i:SecCollectionTimeout)\nCONFIG_SEC_HTTP_BLKEY                   (?i:SecHttpBlKey)\nCONFIG_SEC_REMOTE_RULES                 (?i:SecRemoteRules)\nCONFIG_SEC_REMOTE_RULES_FAIL_ACTION     (?i:SecRemoteRulesFailAction)\nCONFIG_SEC_REMOVE_RULES_BY_ID           (?i:SecRuleRemoveById)\nCONFIG_SEC_REMOVE_RULES_BY_MSG          (?i:SecRuleRemoveByMsg)\nCONFIG_SEC_REMOVE_RULES_BY_TAG          (?i:SecRuleRemoveByTag)\nCONFIG_SEC_UPDATE_TARGET_BY_TAG         (?i:SecRuleUpdateTargetByTag)\nCONFIG_SEC_UPDATE_TARGET_BY_MSG         (?i:SecRuleUpdateTargetByMsg)\nCONFIG_SEC_UPDATE_TARGET_BY_ID          (?i:SecRuleUpdateTargetById)\nCONFIG_SEC_UPDATE_ACTION_BY_ID          (?i:SecRuleUpdateActionById)\nCONFIG_UPDLOAD_KEEP_FILES               (?i:SecUploadKeepFiles)\nCONFIG_UPDLOAD_SAVE_TMP_FILES           (?i:SecTmpSaveUploadedFiles)\nCONFIG_UPLOAD_DIR                       (?i:SecUploadDir)\nCONFIG_UPLOAD_FILE_LIMIT                (?i:SecUploadFileLimit)\nCONFIG_UPLOAD_FILE_MODE                 (?i:SecUploadFileMode)\nCONFIG_VALUE_ABORT                      (?i:Abort)\nCONFIG_VALUE_DETC                       (?i:DetectionOnly)\nCONFIG_VALUE_HTTPS                      (?i:https)\nCONFIG_VALUE_NUMBER                     [0-9]+\nCONFIG_VALUE_ONLYARGS                   (?i:OnlyArgs)\nCONFIG_VALUE_OFF                        (?i:Off)\nCONFIG_VALUE_ON                         (?i:On)\nCONFIG_VALUE_PARALLEL                   (?i:Parallel|Concurrent)\nCONFIG_VALUE_PATH                       (?i:[0-9a-z_/.*: \\\\()-]+)\nCONFIG_VALUE_PROCESS_PARTIAL            (?i:ProcessPartial)\nCONFIG_VALUE_REJECT                     (?i:Reject)\nCONFIG_VALUE_RELEVANT_ONLY              (?i:RelevantOnly)\nCONFIG_VALUE_SERIAL                     (?i:Serial)\nCONFIG_VALUE_WARN                       (?i:Warn)\nCONFIG_XML_EXTERNAL_ENTITY              (?i:SecXmlExternalEntity)\nCONFIG_XML_PARSE_XML_INTO_ARGS          (?i:SecParseXmlIntoArgs)\nCONGIG_DIR_RESPONSE_BODY_MP             (?i:SecResponseBodyMimeType)\nCONGIG_DIR_RESPONSE_BODY_MP_CLEAR       (?i:SecResponseBodyMimeTypesClear)\nCONGIG_DIR_SEC_ARG_SEP                  (?i:SecArgumentSeparator)\nCONGIG_DIR_SEC_COOKIE_FORMAT            (?i:SecCookieFormat)\nCONFIG_SEC_COOKIEV0_SEPARATOR           (?i:SecCookieV0Separator)\nCONGIG_DIR_SEC_DATA_DIR                 (?i:SecDataDir)\nCONGIG_DIR_SEC_STATUS_ENGINE            (?i:SecStatusEngine)\nCONGIG_DIR_SEC_TMP_DIR                  (?i:SecTmpDir)\nDICT_ELEMENT                            ([^\\\"|,\\n \\t}=]|([^\\\\]\\\\\\\"))+\nDICT_ELEMENT_WITH_PIPE                  [^ =\\t\"]+\nDICT_ELEMENT_NO_PIPE                    [^ =\\|\\t\"]+\nDICT_ELEMENT_NO_MACRO                   ([^\\\"|,%{\\n \\t}=]|([^\\\\]\\\\\\\"))+\nDICT_ELEMENT_WITH_EQUALS                ([^\\\"|,\\n \\t}]|([^\\\\]\\\\\\\"))+\n\nDIRECTIVE                               (?i:SecRule)\nDIRECTIVE_SECRULESCRIPT                 (?i:SecRuleScript)\nFREE_TEXT_NEW_LINE                      [^\\\"|\\n]+\nFREE_TEXT_QUOTE                         ([^\\']|([^\\\\]\\\\\\'))+\nQUOTE_BUT_SCAPED                        (')\nDOUBLE_QUOTE_BUT_SCAPED                 (\")\nCOMMA_BUT_SCAPED                        (,)\nFREE_TEXT_QUOTE_MACRO_EXPANSION                 (([^%'])|([^\\\\][\\\\][%][{])|([^\\\\]([\\\\][\\\\])+[\\\\][%][{])|[^\\\\][\\\\][']|[^\\\\]([\\\\][\\\\])+[\\\\]['])+\nFREE_TEXT_DOUBLE_QUOTE_MACRO_EXPANSION          ((([^\"%])|([%][^{]))|([^\\\\][\\\\][%][{])|([^\\\\]([\\\\][\\\\])+[\\\\][%][{])|[^\\\\][\\\\][\"]|[^\\\\]([\\\\][\\\\])+[\\\\][\"])+\nFREE_TEXT_EQUALS_MACRO_EXPANSION                ((([^\",=%])|([%][^{]))|([^\\\\][\\\\][%][{])|([^\\\\]([\\\\][\\\\])+[\\\\][%][{])|[^\\\\][\\\\][=]|[^\\\\]([\\\\][\\\\])+[\\\\][=])+\nFREE_TEXT_EQUALS_QUOTE_MACRO_EXPANSION          ((([^'\",=%])|([%][^{]))|([^\\\\][\\\\][%][{])|([^\\\\]([\\\\][\\\\])+[\\\\][%][{])|[^\\\\][\\\\][=]|[^\\\\][\\\\][']|[^\\\\]([\\\\][\\\\])+[\\\\][=])+\nFREE_TEXT_COMMA_MACRO_EXPANSION                 (([^%,])|([^\\\\][\\\\][%][{])|([^\\\\]([\\\\][\\\\])+[\\\\][%][{])|[^\\\\][\\\\][,]|[^\\\\]([\\\\][\\\\])+[\\\\][,])+\nFREE_TEXT_COMMA_DOUBLE_QUOTE_MACRO_EXPANSION    ((([^,\"%])|([%][^{]))|([^\\\\][\\\\][%][{])|([^\\\\]([\\\\][\\\\])+[\\\\][%][{])|[^\\\\][\\\\][\"]|[^\\\\]([\\\\][\\\\])+[\\\\][\"])+\n\nFREE_TEXT_SPACE_MACRO_EXPANSION         (([^% ])|([^\\\\][\\\\][%][{])|([^\\\\]([\\\\][\\\\])+[\\\\][%][{])|[^\\\\][\\\\][ ]|[^\\\\]([\\\\][\\\\])+[\\\\][ ])+\nSTART_MACRO_VARIABLE                    (\\%\\{)\nFREE_TEXT_QUOTE_COMMA                   [^,\\']+\nFREE_TEXT_SPACE                         [^ \\t]+\nFREE_TEXT_SPACE_COMMA                   [^, \\t]+\nFREE_TEXT_SPACE_COMMA_QUOTE             [^, \\t\\\"\\n\\r]+\nFREE_TEXT_COMMA_QUOTE                   [^,\\\"\\\\n\\\\r]+\nNEW_LINE_FREE_TEXT                      [^, \\t\\\"\\n\\r]+\nNOT !\nFREE_TEXT                               ([^\\\"]|([^\\\\]\\\\\\\"))+\nREMOVE_RULE_BY                          [0-9A-Za-z_\\/\\.\\-\\*\\:\\;\\]\\[\\$]+\n\nVAR_FREE_TEXT_QUOTE                     ([^\\']|([^\\\\]\\\\\\'))+\nVAR_FREE_TEXT_SPACE                     [^ \\t\\\"]+\nVAR_FREE_TEXT_SPACE_COMMA               [^, \\t\\\"]+\n\nJSON                                    (?i:JSON)\nNATIVE                                  (?i:NATIVE)\n\nNEW_LINE                                [\\n\\r]+\n\nEQUALS                                  (?i:=)\nEQUALS_PLUS                             (?i:=\\+)\nEQUALS_MINUS                            (?i:=\\-)\n\n%x EXPECTING_ACTION_PREDICATE_VARIABLE\n%x TRANSACTION_TO_VARIABLE\n%x EXPECTING_VARIABLE\n%x EXPECTING_OPERATOR_ENDS_WITH_SPACE EXPECTING_OPERATOR_ENDS_WITH_QUOTE\n%x EXPECTING_ACTION_PREDICATE ACTION_PREDICATE_ENDS_WITH_QUOTE ACTION_PREDICATE_ENDS_WITH_DOUBLE_QUOTE ACTION_PREDICATE_ENDS_WITH_COMMA_OR_DOUBLE_QUOTE\n%x COMMENT\n%x TRANSITION_FROM_OP_TO_EXPECTING_PARAMETER_ENDS_WITH_QUOTE TRANSITION_FROM_OP_TO_EXPECTING_PARAMETER_ENDS_WITH_SPACE\n%x EXPECTING_VAR_PARAMETER EXPECTING_VAR_PARAMETER_OR_MACRO_NONQUOTED EXPECTING_VAR_PARAMETER_OR_MACRO_QUOTED\n%x EXPECTING_PARAMETER_ENDS_WITH_QUOTE EXPECTING_PARAMETER_ENDS_WITH_SPACE\n%x EXPECTING_ACTIONS_ENDS_WITH_DOUBLE_QUOTE EXPECTING_ACTIONS_ONLY_ONE\n%x TRANSACTION_FROM_OPERATOR_TO_ACTIONS\n%x TRANSACTION_FROM_OPERATOR_PARAMETERS_TO_ACTIONS\n%x TRANSACTION_FROM_DIRECTIVE_TO_ACTIONS\n%x NO_OP_INFORMED_ENDS_WITH_SPACE NO_OP_INFORMED_ENDS_WITH_QUOTE\n%x FINISH_ACTIONS\n%x LEXING_ERROR\n%x LEXING_ERROR_ACTION\n%x LEXING_ERROR_VARIABLE\n%x SETVAR_ACTION_NONQUOTED\n%x SETVAR_ACTION_NONQUOTED_WAITING_COLLECTION_ELEM\n%x SETVAR_ACTION_NONQUOTED_WAITING_OPERATION\n%x SETVAR_ACTION_NONQUOTED_WAITING_CONTENT\n%x SETVAR_ACTION_QUOTED\n%x SETVAR_ACTION_QUOTED_WAITING_COLLECTION_ELEM\n%x SETVAR_ACTION_QUOTED_WAITING_OPERATION\n%x SETVAR_ACTION_QUOTED_WAITING_CONTENT\n\n%{\n  // Code run each time a pattern is matched.\n  # define YY_USER_ACTION  driver.loc.back()->columns (yyleng);\n\n%}\n\n%%\n\n%{\n  // Code run each time yylex is called.\n  driver.loc.back()->step();\n%}\n<EXPECTING_ACTIONS_ENDS_WITH_DOUBLE_QUOTE,EXPECTING_ACTIONS_ONLY_ONE>{\n{ACTION_APPEND}                                                         { return p::make_ACTION_APPEND(yytext, *driver.loc.back()); }\n{ACTION_BLOCK}                                                          { return p::make_ACTION_BLOCK(yytext, *driver.loc.back()); }\n{ACTION_CAPTURE}                                                        { return p::make_ACTION_CAPTURE(yytext, *driver.loc.back()); }\n{ACTION_CHAIN}                                                          { return p::make_ACTION_CHAIN(yytext, *driver.loc.back()); }\n{ACTION_DENY}                                                           { return p::make_ACTION_DENY(yytext, *driver.loc.back()); }\n{ACTION_DEPRECATE_VAR}                                                  { return p::make_ACTION_DEPRECATE_VAR(yytext, *driver.loc.back()); }\n{ACTION_DROP}                                                           { return p::make_ACTION_DROP(yytext, *driver.loc.back()); }\n{ACTION_ID}                                                             { return p::make_ACTION_ID(yytext, *driver.loc.back()); }\n{ACTION_LOG}                                                            { return p::make_ACTION_LOG(yytext, *driver.loc.back()); }\n{ACTION_MULTI_MATCH}                                                    { return p::make_ACTION_MULTI_MATCH(yytext, *driver.loc.back()); }\n{ACTION_NO_AUDIT_LOG}                                                   { return p::make_ACTION_NO_AUDIT_LOG(yytext, *driver.loc.back()); }\n{ACTION_NO_LOG}                                                         { return p::make_ACTION_NO_LOG(yytext, *driver.loc.back()); }\n{ACTION_PASS}                                                           { return p::make_ACTION_PASS(yytext, *driver.loc.back()); }\n{ACTION_PAUSE}                                                          { return p::make_ACTION_PAUSE(yytext, *driver.loc.back()); }\n{ACTION_PREPEND}                                                        { return p::make_ACTION_PREPEND(yytext, *driver.loc.back()); }\n{ACTION_PROXY}                                                          { return p::make_ACTION_PROXY(yytext, *driver.loc.back()); }\n{ACTION_SANITISE_ARG}                                                   { return p::make_ACTION_SANITISE_ARG(yytext, *driver.loc.back()); }\n{ACTION_SANITISE_MATCHED}                                               { return p::make_ACTION_SANITISE_MATCHED(yytext, *driver.loc.back()); }\n{ACTION_SANITISE_MATCHED_BYTES}                                         { return p::make_ACTION_SANITISE_MATCHED_BYTES(yytext, *driver.loc.back()); }\n{ACTION_SANITISE_REQUEST_HEADER}                                        { return p::make_ACTION_SANITISE_REQUEST_HEADER(yytext, *driver.loc.back()); }\n{ACTION_SANITISE_RESPONSE_HEADER}                                       { return p::make_ACTION_SANITISE_RESPONSE_HEADER(yytext, *driver.loc.back()); }\n{ACTION_SETRSC}:                                                        { BEGIN(EXPECTING_ACTION_PREDICATE); return p::make_ACTION_SETRSC(yytext, *driver.loc.back()); }\n\n{ACTION_STATUS}                                                         { return p::make_ACTION_STATUS(yytext, *driver.loc.back()); }\n{ACTION_ACCURACY}:'{FREE_TEXT_QUOTE}'                                   { return p::make_ACTION_ACCURACY(yytext, *driver.loc.back()); }\n{ACTION_ACCURACY}:{FREE_TEXT_QUOTE}                                     { return p::make_ACTION_ACCURACY(yytext, *driver.loc.back()); }\n{ACTION_ALLOW}                                                          { return p::make_ACTION_ALLOW(yytext, *driver.loc.back()); }\n{ACTION_AUDIT_LOG}                                                      { return p::make_ACTION_AUDIT_LOG(yytext, *driver.loc.back()); }\n{ACTION_CTL_AUDIT_ENGINE}=                                              { return p::make_ACTION_CTL_AUDIT_ENGINE(yytext, *driver.loc.back()); }\n{ACTION_CTL_AUDIT_LOG_PARTS}=[+|-]{AUDIT_PARTS}                         { return p::make_ACTION_CTL_AUDIT_LOG_PARTS(yytext, *driver.loc.back()); }\n{ACTION_CTL_BDY_JSON}                                                   { return p::make_ACTION_CTL_BDY_JSON(yytext, *driver.loc.back()); }\n{ACTION_CTL_BDY_XML}                                                    { return p::make_ACTION_CTL_BDY_XML(yytext, *driver.loc.back()); }\n{ACTION_CTL_BDY_URLENCODED}                                             { return p::make_ACTION_CTL_BDY_URLENCODED(yytext, *driver.loc.back()); }\n{ACTION_CTL_FORCE_REQ_BODY_VAR}=                                        { return p::make_ACTION_CTL_FORCE_REQ_BODY_VAR(yytext, *driver.loc.back()); }\n{ACTION_CTL_PARSE_XML_INTO_ARGS}=                                       { return p::make_ACTION_CTL_PARSE_XML_INTO_ARGS(yytext, *driver.loc.back()); }\n{ACTION_CTL_REQUEST_BODY_ACCESS}=                                       { return p::make_ACTION_CTL_REQUEST_BODY_ACCESS(yytext, *driver.loc.back()); }\n{ACTION_CTL_RULE_ENGINE}=                                               { return p::make_ACTION_CTL_RULE_ENGINE(*driver.loc.back()); }\n{ACTION_CTL_RULE_REMOVE_BY_ID}[=]{REMOVE_RULE_BY}                       { return p::make_ACTION_CTL_RULE_REMOVE_BY_ID(yytext, *driver.loc.back()); }\n{ACTION_CTL_RULE_REMOVE_BY_TAG}[=]{REMOVE_RULE_BY}                      { return p::make_ACTION_CTL_RULE_REMOVE_BY_TAG(yytext, *driver.loc.back()); }\n{ACTION_CTL_RULE_REMOVE_TARGET_BY_ID}[=]{REMOVE_RULE_BY}                { return p::make_ACTION_CTL_RULE_REMOVE_TARGET_BY_ID(yytext, *driver.loc.back()); }\n{ACTION_CTL_RULE_REMOVE_TARGET_BY_TAG}[=]{REMOVE_RULE_BY}               { return p::make_ACTION_CTL_RULE_REMOVE_TARGET_BY_TAG(yytext, *driver.loc.back()); }\n{ACTION_EXEC}:'{VAR_FREE_TEXT_QUOTE}'                                   { return p::make_ACTION_EXEC(yytext, *driver.loc.back()); }\n{ACTION_EXEC}:{VAR_FREE_TEXT_SPACE_COMMA}                               { return p::make_ACTION_EXEC(yytext, *driver.loc.back()); }\n{ACTION_EXPIRE_VAR}:                                                    { BEGIN(EXPECTING_ACTION_PREDICATE); return p::make_ACTION_EXPIRE_VAR(yytext, *driver.loc.back()); }\n{ACTION_INITCOL}:{COL_NAME}=                                            { BEGIN(EXPECTING_ACTION_PREDICATE); return p::make_ACTION_INITCOL(yytext, *driver.loc.back()); }\n{ACTION_MATURITY}:'{FREE_TEXT_QUOTE}'                                   { return p::make_ACTION_MATURITY(yytext, *driver.loc.back()); }\n{ACTION_MATURITY}:{FREE_TEXT_QUOTE}                                     { return p::make_ACTION_MATURITY(yytext, *driver.loc.back()); }\n{ACTION_MSG}:                                                           { BEGIN(EXPECTING_ACTION_PREDICATE); return p::make_ACTION_MSG(yytext, *driver.loc.back()); }\n{ACTION_PHASE}                                                          { return p::make_ACTION_PHASE(yytext, *driver.loc.back()); }\n{ACTION_REDIRECT}:                                                      { BEGIN(EXPECTING_ACTION_PREDICATE); return p::make_ACTION_REDIRECT(yytext, *driver.loc.back()); }\n{ACTION_REV}:'{FREE_TEXT_QUOTE_COMMA}'                                  { return p::make_ACTION_REV(yytext, *driver.loc.back()); }\n{ACTION_REV}:{FREE_TEXT_QUOTE_COMMA}                                    { return p::make_ACTION_REV(yytext, *driver.loc.back()); }\n{ACTION_SETENV}:                                                         { BEGIN(EXPECTING_ACTION_PREDICATE); return p::make_ACTION_SETENV(yytext, *driver.loc.back()); }\n{ACTION_SETSID}:                                                        { BEGIN(EXPECTING_ACTION_PREDICATE); return p::make_ACTION_SETSID(yytext, *driver.loc.back()); }\n{ACTION_SETUID}:                                                        { BEGIN(EXPECTING_ACTION_PREDICATE); return p::make_ACTION_SETUID(yytext, *driver.loc.back()); }\n\n{ACTION_SETVAR}:'                                                       { BEGIN(SETVAR_ACTION_QUOTED); return p::make_ACTION_SETVAR(*driver.loc.back()); }\n{ACTION_SETVAR}:                                                        { BEGIN(SETVAR_ACTION_NONQUOTED); return p::make_ACTION_SETVAR(*driver.loc.back()); }\n\n\n{ACTION_SEVERITY}:'{ACTION_SEVERITY_VALUE}'                             { return p::make_ACTION_SEVERITY(yytext, *driver.loc.back()); }\n{ACTION_SEVERITY}:{ACTION_SEVERITY_VALUE}                               { return p::make_ACTION_SEVERITY(yytext, *driver.loc.back()); }\n{ACTION_SKIP_AFTER}:{FREE_TEXT_SPACE_COMMA_QUOTE}                       { return p::make_ACTION_SKIP_AFTER(yytext, *driver.loc.back()); }\n{ACTION_SKIP}:{CONFIG_VALUE_NUMBER}                                     { return p::make_ACTION_SKIP(yytext, *driver.loc.back()); }\n{ACTION_TAG}:                                                           { BEGIN(EXPECTING_ACTION_PREDICATE); return p::make_ACTION_TAG(yytext, *driver.loc.back()); }\n{ACTION_VER}:'{FREE_TEXT_QUOTE}'                                        { return p::make_ACTION_VER(yytext, *driver.loc.back()); }\n{ACTION_XMLNS}:{FREE_TEXT_SPACE_COMMA_QUOTE}                            { return p::make_ACTION_XMLNS(yytext, *driver.loc.back()); }\n\n{ACTION_TRANSFORMATION_PARITY_ZERO_7_BIT}                               { return p::make_ACTION_TRANSFORMATION_PARITY_ZERO_7_BIT(yytext, *driver.loc.back()); }\n{ACTION_TRANSFORMATION_PARITY_ODD_7_BIT}                                { return p::make_ACTION_TRANSFORMATION_PARITY_ODD_7_BIT(yytext, *driver.loc.back()); }\n{ACTION_TRANSFORMATION_PARITY_EVEN_7_BIT}                               { return p::make_ACTION_TRANSFORMATION_PARITY_EVEN_7_BIT(yytext, *driver.loc.back()); }\n{ACTION_TRANSFORMATION_SQL_HEX_DECODE}                                  { return p::make_ACTION_TRANSFORMATION_SQL_HEX_DECODE(yytext, *driver.loc.back()); }\n{ACTION_TRANSFORMATION_BASE_64_ENCODE}                                  { return p::make_ACTION_TRANSFORMATION_BASE_64_ENCODE(yytext, *driver.loc.back()); }\n{ACTION_TRANSFORMATION_BASE_64_DECODE}                                  { return p::make_ACTION_TRANSFORMATION_BASE_64_DECODE(yytext, *driver.loc.back()); }\n{ACTION_TRANSFORMATION_BASE_64_DECODE_EXT}                              { return p::make_ACTION_TRANSFORMATION_BASE_64_DECODE_EXT(yytext, *driver.loc.back()); }\n{ACTION_TRANSFORMATION_CMD_LINE}                                        { return p::make_ACTION_TRANSFORMATION_CMD_LINE(yytext, *driver.loc.back()); }\n{ACTION_TRANSFORMATION_SHA1}                                            { return p::make_ACTION_TRANSFORMATION_SHA1(yytext, *driver.loc.back()); }\n{ACTION_TRANSFORMATION_MD5}                                             { return p::make_ACTION_TRANSFORMATION_MD5(yytext, *driver.loc.back()); }\n{ACTION_TRANSFORMATION_ESCAPE_SEQ_DECODE}                               { return p::make_ACTION_TRANSFORMATION_ESCAPE_SEQ_DECODE(yytext, *driver.loc.back()); }\n{ACTION_TRANSFORMATION_HEX_ENCODE}                                      { return p::make_ACTION_TRANSFORMATION_HEX_ENCODE(yytext, *driver.loc.back()); }\n{ACTION_TRANSFORMATION_HEX_DECODE}                                      { return p::make_ACTION_TRANSFORMATION_HEX_DECODE(yytext, *driver.loc.back()); }\n{ACTION_TRANSFORMATION_LOWERCASE}                                       { return p::make_ACTION_TRANSFORMATION_LOWERCASE(yytext, *driver.loc.back()); }\n{ACTION_TRANSFORMATION_UPPERCASE}                                       { return p::make_ACTION_TRANSFORMATION_UPPERCASE(yytext, *driver.loc.back()); }\n{ACTION_TRANSFORMATION_URL_ENCODE}                                      { return p::make_ACTION_TRANSFORMATION_URL_ENCODE(yytext, *driver.loc.back()); }\n{ACTION_TRANSFORMATION_URL_DECODE_UNI}                                  { return p::make_ACTION_TRANSFORMATION_URL_DECODE_UNI(yytext, *driver.loc.back()); }\n{ACTION_TRANSFORMATION_URL_DECODE}                                      { return p::make_ACTION_TRANSFORMATION_URL_DECODE(yytext, *driver.loc.back()); }\n{ACTION_TRANSFORMATION_NONE}                                            { return p::make_ACTION_TRANSFORMATION_NONE(yytext, *driver.loc.back()); }\n{ACTION_TRANSFORMATION_COMPRESS_WHITESPACE}                             { return p::make_ACTION_TRANSFORMATION_COMPRESS_WHITESPACE(yytext, *driver.loc.back()); }\n{ACTION_TRANSFORMATION_REMOVE_WHITESPACE}                               { return p::make_ACTION_TRANSFORMATION_REMOVE_WHITESPACE(yytext, *driver.loc.back()); }\n{ACTION_TRANSFORMATION_REPLACE_NULLS}                                   { return p::make_ACTION_TRANSFORMATION_REPLACE_NULLS(yytext, *driver.loc.back()); }\n{ACTION_TRANSFORMATION_REMOVE_NULLS}                                    { return p::make_ACTION_TRANSFORMATION_REMOVE_NULLS(yytext, *driver.loc.back()); }\n{ACTION_TRANSFORMATION_HTML_ENTITY_DECODE}                              { return p::make_ACTION_TRANSFORMATION_HTML_ENTITY_DECODE(yytext, *driver.loc.back()); }\n{ACTION_TRANSFORMATION_JS_DECODE}                                       { return p::make_ACTION_TRANSFORMATION_JS_DECODE(yytext, *driver.loc.back()); }\n{ACTION_TRANSFORMATION_CSS_DECODE}                                      { return p::make_ACTION_TRANSFORMATION_CSS_DECODE(yytext, *driver.loc.back()); }\n{ACTION_TRANSFORMATION_TRIM}                                            { return p::make_ACTION_TRANSFORMATION_TRIM(yytext, *driver.loc.back()); }\n{ACTION_TRANSFORMATION_TRIM_LEFT}                                       { return p::make_ACTION_TRANSFORMATION_TRIM_LEFT(yytext, *driver.loc.back()); }\n{ACTION_TRANSFORMATION_TRIM_RIGHT}                                      { return p::make_ACTION_TRANSFORMATION_TRIM_RIGHT(yytext, *driver.loc.back()); }\n{ACTION_TRANSFORMATION_NORMALISE_PATH_WIN}                              { return p::make_ACTION_TRANSFORMATION_NORMALISE_PATH_WIN(yytext, *driver.loc.back()); }\n{ACTION_TRANSFORMATION_NORMALISE_PATH}                                  { return p::make_ACTION_TRANSFORMATION_NORMALISE_PATH(yytext, *driver.loc.back()); }\n{ACTION_TRANSFORMATION_LENGTH}                                          { return p::make_ACTION_TRANSFORMATION_LENGTH(yytext, *driver.loc.back()); }\n{ACTION_TRANSFORMATION_UTF8_TO_UNICODE}                                 { return p::make_ACTION_TRANSFORMATION_UTF8_TO_UNICODE(yytext, *driver.loc.back()); }\n{ACTION_TRANSFORMATION_REMOVE_COMMENTS_CHAR}                            { return p::make_ACTION_TRANSFORMATION_REMOVE_COMMENTS_CHAR(yytext, *driver.loc.back()); }\n{ACTION_TRANSFORMATION_REMOVE_COMMENTS}                                 { return p::make_ACTION_TRANSFORMATION_REMOVE_COMMENTS(yytext, *driver.loc.back()); }\n{ACTION_TRANSFORMATION_REPLACE_COMMENTS}                                { return p::make_ACTION_TRANSFORMATION_REPLACE_COMMENTS(yytext, *driver.loc.back()); }\n{ACTION_LOG_DATA}:                                                      { BEGIN(EXPECTING_ACTION_PREDICATE); return p::make_ACTION_LOG_DATA(yytext, *driver.loc.back()); }\n\n{CONFIG_VALUE_DETC}                                                     { return p::make_CONFIG_VALUE_DETC(yytext, *driver.loc.back()); }\n{CONFIG_VALUE_ONLYARGS}                                                 { return p::make_CONFIG_VALUE_ONLYARGS(yytext, *driver.loc.back()); }\n{CONFIG_VALUE_OFF}                                                      { return p::make_CONFIG_VALUE_OFF(yytext, *driver.loc.back()); }\n{CONFIG_VALUE_ON}                                                       { return p::make_CONFIG_VALUE_ON(yytext, *driver.loc.back()); }\n{CONFIG_VALUE_RELEVANT_ONLY}                                            { return p::make_CONFIG_VALUE_RELEVANT_ONLY(yytext, *driver.loc.back()); }\n[ \\t]*\\\\\\n[ \\t]*                                                        { driver.loc.back()->lines(1); driver.loc.back()->step(); }\n[ \\t]*\\\\\\r\\n[ \\t]*                                                      { driver.loc.back()->lines(1); driver.loc.back()->step(); }\n}\n\n<EXPECTING_ACTIONS_ENDS_WITH_DOUBLE_QUOTE>{\n[ \\t]*[,][ \\t]*                                                         { return p::make_COMMA(*driver.loc.back()); }\n}\n\n\n<EXPECTING_ACTIONS_ENDS_WITH_DOUBLE_QUOTE>{\n[ \\t]*\\n                                                                { BEGIN(INITIAL); yyless(yyleng); driver.loc.back()->lines(1); driver.loc.back()->step(); }\n[ \\t]*\\r\\n                                                              { BEGIN(INITIAL); yyless(yyleng); driver.loc.back()->lines(1); driver.loc.back()->step(); }\n}\n\n\n<EXPECTING_ACTIONS_ONLY_ONE>{\n[ ][ \\t]*                                                               { BEGIN(INITIAL); yyless(yyleng); }\n[ ]*[ \\t]*\\n                                                            { BEGIN(INITIAL); yyless(1); }\n[ ]*[ \\t]*\\r\\n                                                          { BEGIN(INITIAL); driver.loc.back()->lines(1); driver.loc.back()->step(); }\n}\n\n\n<EXPECTING_ACTIONS_ENDS_WITH_DOUBLE_QUOTE>{\n[\"][ \\t]*                                                               { BEGIN(INITIAL); yyless(yyleng); p::make_NEW_LINE(*driver.loc.back()); }\n[\"][ \\t]*\\n                                                             { BEGIN(INITIAL); yyless(1); }\n[\"][ \\t]*\\r\\n                                                           { BEGIN(INITIAL); driver.loc.back()->lines(1); driver.loc.back()->step(); }\n}\n\n\n<EXPECTING_ACTIONS_ENDS_WITH_DOUBLE_QUOTE,EXPECTING_ACTIONS_ONLY_ONE>{\n.                                                   { BEGIN(LEXING_ERROR_ACTION); yyless(0); }\n}\n\n\n<EXPECTING_ACTION_PREDICATE>{\n[']                                                 { BEGIN(ACTION_PREDICATE_ENDS_WITH_QUOTE); }\n[\"]                                                 { BEGIN(ACTION_PREDICATE_ENDS_WITH_DOUBLE_QUOTE); }\n.                                                   { BEGIN(ACTION_PREDICATE_ENDS_WITH_COMMA_OR_DOUBLE_QUOTE); yyless(0); }\n}\n\n\n<EXPECTING_ACTION_PREDICATE_VARIABLE,ACTION_PREDICATE_ENDS_WITH_QUOTE,ACTION_PREDICATE_ENDS_WITH_DOUBLE_QUOTE,ACTION_PREDICATE_ENDS_WITH_COMMA_OR_DOUBLE_QUOTE,EXPECTING_PARAMETER_ENDS_WITH_QUOTE,EXPECTING_PARAMETER_ENDS_WITH_SPACE>{\n[ \\t]*\\\\\\n[ \\t]*                                    { driver.loc.back()->lines(1); driver.loc.back()->step(); }\n[ \\t]*\\\\\\r\\n[ \\t]*                                  { driver.loc.back()->lines(1); driver.loc.back()->step(); }\n}\n\n<EXPECTING_ACTION_PREDICATE_VARIABLE>{\n[}][%][{] { yyless(1); BEGIN_PREVIOUS(); }\n[}][%]    { BEGIN_PREVIOUS(); }\n[}]       { BEGIN_PREVIOUS(); }\n}\n\n<ACTION_PREDICATE_ENDS_WITH_QUOTE>{\n[']                                                  { BEGIN(EXPECTING_ACTIONS_ENDS_WITH_DOUBLE_QUOTE); yyless(yyleng); }\n{FREE_TEXT_QUOTE_MACRO_EXPANSION}                    { return p::make_FREE_TEXT_QUOTE_MACRO_EXPANSION(yytext, *driver.loc.back()); }\n}\n\n<ACTION_PREDICATE_ENDS_WITH_DOUBLE_QUOTE>{\n[\"]                                                  { BEGIN(EXPECTING_ACTIONS_ENDS_WITH_DOUBLE_QUOTE); yyless(yyleng); }\n{FREE_TEXT_DOUBLE_QUOTE_MACRO_EXPANSION}             { return p::make_FREE_TEXT_QUOTE_MACRO_EXPANSION(yytext, *driver.loc.back()); }\n}\n\n<ACTION_PREDICATE_ENDS_WITH_COMMA_OR_DOUBLE_QUOTE>{\n[,]                                                  { yyless(0); BEGIN(EXPECTING_ACTIONS_ENDS_WITH_DOUBLE_QUOTE); }\n[\"]                                                  { yyless(0); BEGIN(EXPECTING_ACTIONS_ENDS_WITH_DOUBLE_QUOTE);}\n{FREE_TEXT_COMMA_DOUBLE_QUOTE_MACRO_EXPANSION}       { return p::make_FREE_TEXT_QUOTE_MACRO_EXPANSION(yytext, *driver.loc.back()); }\n}\n\n<ACTION_PREDICATE_ENDS_WITH_QUOTE,ACTION_PREDICATE_ENDS_WITH_DOUBLE_QUOTE,ACTION_PREDICATE_ENDS_WITH_COMMA_OR_DOUBLE_QUOTE>{\n{START_MACRO_VARIABLE}                               { BEGINX(EXPECTING_ACTION_PREDICATE_VARIABLE); }\n.                                                    { BEGIN(LEXING_ERROR_VARIABLE); yyless(0); }\n}\n\n<SETVAR_ACTION_NONQUOTED,SETVAR_ACTION_QUOTED>{\n{NOT}                                                { return p::make_NOT(*driver.loc.back()); }\n.|\\n                                                 { BEGIN_ACTION_OPERATION(); yyless(0); }\n}\n\n\n<SETVAR_ACTION_NONQUOTED_WAITING_OPERATION,SETVAR_ACTION_QUOTED_WAITING_OPERATION>{\n{EQUALS_PLUS}                                       { BEGIN_ACTION_WAITING_CONTENT(); return p::make_SETVAR_OPERATION_EQUALS_PLUS(*driver.loc.back()); }\n{EQUALS_MINUS}                                      { BEGIN_ACTION_WAITING_CONTENT(); return p::make_SETVAR_OPERATION_EQUALS_MINUS(*driver.loc.back()); }\n{EQUALS}                                            { BEGIN_ACTION_WAITING_CONTENT(); return p::make_SETVAR_OPERATION_EQUALS(*driver.loc.back()); }\n}\n\n<SETVAR_ACTION_NONQUOTED_WAITING_OPERATION>{\n.|\\n                                                { BEGIN(EXPECTING_ACTIONS_ENDS_WITH_DOUBLE_QUOTE); yyless(0);}\n}\n\n<SETVAR_ACTION_QUOTED_WAITING_OPERATION>{\n\\'                                                  { BEGIN(EXPECTING_ACTIONS_ENDS_WITH_DOUBLE_QUOTE); }\n.|\\n                                                { BEGIN(LEXING_ERROR_ACTION); yyless(0); }\n}\n\n\n\n\n\n<SETVAR_ACTION_NONQUOTED_WAITING_CONTENT,SETVAR_ACTION_QUOTED_WAITING_CONTENT>{\n{START_MACRO_VARIABLE}                              { BEGINX(EXPECTING_ACTION_PREDICATE_VARIABLE); }\n}\n\n\n<SETVAR_ACTION_NONQUOTED_WAITING_CONTENT>{\n{FREE_TEXT_EQUALS_MACRO_EXPANSION}                  { return p::make_FREE_TEXT_QUOTE_MACRO_EXPANSION(yytext, *driver.loc.back()); }\n.|\\n                                                { BEGIN(EXPECTING_ACTIONS_ENDS_WITH_DOUBLE_QUOTE); yyless(0); }\n}\n\n\n<SETVAR_ACTION_QUOTED_WAITING_CONTENT>{\n\\'                                                  { BEGIN(EXPECTING_ACTIONS_ENDS_WITH_DOUBLE_QUOTE); }\n{FREE_TEXT_EQUALS_QUOTE_MACRO_EXPANSION}            { return p::make_FREE_TEXT_QUOTE_MACRO_EXPANSION(yytext, *driver.loc.back()); }\n.|\\n                                                { BEGIN(EXPECTING_ACTIONS_ENDS_WITH_DOUBLE_QUOTE); yyless(0); }\n}\n\n\n\n\n\n<FINISH_ACTIONS>{\n<<EOF>> { BEGIN(INITIAL); yyless(0); p::make_NEW_LINE(*driver.loc.back()); }\n. { BEGIN(INITIAL); }\n}\n\n{CONFIG_COMPONENT_SIG}[ \\t]+[\"]{FREE_TEXT}[\"]                           { return p::make_CONFIG_COMPONENT_SIG(strchr(yytext, ' ') + 2, *driver.loc.back()); }\n{CONFIG_SEC_SERVER_SIG}[ \\t]+[\"]{FREE_TEXT}[\"]                          { return p::make_CONFIG_SEC_SERVER_SIG(strchr(yytext, ' ') + 2, *driver.loc.back()); }\n{CONFIG_SEC_WEB_APP_ID}[ \\t]+[\"]{FREE_TEXT}[\"]                          { return p::make_CONFIG_SEC_WEB_APP_ID(parserSanitizer(strchr(yytext, ' ') + 2), *driver.loc.back()); }\n{CONFIG_SEC_WEB_APP_ID}[ \\t]+{FREE_TEXT_NEW_LINE}                       { return p::make_CONFIG_SEC_WEB_APP_ID(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); }\n{CONFIG_CONTENT_INJECTION}                                              { return p::make_CONFIG_CONTENT_INJECTION(*driver.loc.back()); }\n{CONFIG_DIR_AUDIT_DIR_MOD}[ \\t]+{CONFIG_VALUE_NUMBER}                   { return p::make_CONFIG_DIR_AUDIT_DIR_MOD(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); }\n{CONFIG_DIR_AUDIT_DIR_MOD}[ \\t]+[\"]{CONFIG_VALUE_NUMBER}[\"]             { return p::make_CONFIG_DIR_AUDIT_DIR_MOD(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); }\n{CONFIG_DIR_AUDIT_DIR}[ \\t]+{CONFIG_VALUE_PATH}                         { return p::make_CONFIG_DIR_AUDIT_DIR(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); }\n{CONFIG_DIR_AUDIT_DIR}[ \\t]+[\"]{CONFIG_VALUE_PATH}[\"]                   { return p::make_CONFIG_DIR_AUDIT_DIR(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); }\n{CONFIG_SEC_ARGUMENT_SEPARATOR}[ \\t]+[\"]{NEW_LINE_FREE_TEXT}[\"]         { return p::make_CONFIG_SEC_ARGUMENT_SEPARATOR(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); }\n{CONFIG_SEC_ARGUMENT_SEPARATOR}[ \\t]+{NEW_LINE_FREE_TEXT}               { return p::make_CONFIG_SEC_ARGUMENT_SEPARATOR(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); }\n{CONFIG_DIR_AUDIT_ENG}                                                  { return p::make_CONFIG_DIR_AUDIT_ENG(yytext, *driver.loc.back()); }\n{CONFIG_DIR_AUDIT_FLE_MOD}[ \\t]+{CONFIG_VALUE_NUMBER}                   { return p::make_CONFIG_DIR_AUDIT_FLE_MOD(strchr(yytext, ' ') + 1, *driver.loc.back()); }\n{CONFIG_DIR_AUDIT_LOG2}[ \\t]+{CONFIG_VALUE_PATH}                        { return p::make_CONFIG_DIR_AUDIT_LOG2(strchr(yytext, ' ') + 1, *driver.loc.back()); }\n{CONFIG_DIR_AUDIT_LOG_P}[ \\t]+{AUDIT_PARTS}                             { return p::make_CONFIG_DIR_AUDIT_LOG_P(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); }\n{CONFIG_DIR_AUDIT_LOG_P}[ \\t]+[\"]{AUDIT_PARTS}[\"]                       { return p::make_CONFIG_DIR_AUDIT_LOG_P(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); }\n{CONFIG_DIR_AUDIT_LOG}[ \\t]+{CONFIG_VALUE_PATH}                         { return p::make_CONFIG_DIR_AUDIT_LOG(strchr(yytext, ' ') + 1, *driver.loc.back()); }\n{CONFIG_DIR_AUDIT_LOG_FMT}                                              { return p::make_CONFIG_DIR_AUDIT_LOG_FMT(*driver.loc.back()); }\n{JSON}                                                                  { return p::make_JSON(*driver.loc.back()); }\n{NATIVE}                                                                { return p::make_NATIVE(*driver.loc.back()); }\n{CONFIG_DIR_AUDIT_LOG}[ \\t]+[\"]{CONFIG_VALUE_PATH}[\"]                   { return p::make_CONFIG_DIR_AUDIT_LOG(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); }\n{CONFIG_DIR_AUDIT_STS}[ \\t]+{FREE_TEXT_NEW_LINE}                        { return p::make_CONFIG_DIR_AUDIT_STS(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); }\n{CONFIG_DIR_AUDIT_STS}[ \\t]+[\"]{NEW_LINE_FREE_TEXT}[\"]                  { return p::make_CONFIG_DIR_AUDIT_STS(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); }\n{CONFIG_DIR_AUDIT_PREFIX}[ \\t]+{FREE_TEXT_NEW_LINE}                     { return p::make_CONFIG_DIR_AUDIT_PREFIX(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); }\n{CONFIG_DIR_AUDIT_PREFIX}[ \\t]+[\"]{FREE_TEXT_NEW_LINE}[\"]               { return p::make_CONFIG_DIR_AUDIT_PREFIX(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); }\n{CONFIG_DIR_AUDIT_TPE}                                                  { return p::make_CONFIG_DIR_AUDIT_TPE(yytext, *driver.loc.back()); }\n\n\n{CONFIG_DIR_DEBUG_LOG}[ \\t]+{CONFIG_VALUE_PATH}                         { return p::make_CONFIG_DIR_DEBUG_LOG(strchr(yytext, ' ') + 1, *driver.loc.back()); }\n{CONFIG_DIR_DEBUG_LOG}[ \\t]+[\"]{CONFIG_VALUE_PATH}[\"]                   { return p::make_CONFIG_DIR_DEBUG_LOG(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); }\n{CONFIG_DIR_DEBUG_LVL}[ \\t]+{CONFIG_VALUE_NUMBER}                       { return p::make_CONFIG_DIR_DEBUG_LVL(strchr(yytext, ' ') + 1, *driver.loc.back()); }\n{CONFIG_DIR_GEO_DB}[ \\t]+{FREE_TEXT_NEW_LINE}                           { return p::make_CONFIG_DIR_GEO_DB(strchr(yytext, ' ') + 1, *driver.loc.back()); }\n{CONFIG_DIR_PCRE_MATCH_LIMIT_RECURSION}[ \\t]+{CONFIG_VALUE_NUMBER}      { return p::make_CONFIG_DIR_PCRE_MATCH_LIMIT_RECURSION(strchr(yytext, ' ') + 1, *driver.loc.back()); }\n{CONFIG_DIR_PCRE_MATCH_LIMIT}[ \\t]+{CONFIG_VALUE_NUMBER}                { return p::make_CONFIG_DIR_PCRE_MATCH_LIMIT(strchr(yytext, ' ') + 1, *driver.loc.back()); }\n{CONFIG_DIR_ARGS_LIMIT}[ \\t]+{CONFIG_VALUE_NUMBER}                      { return p::make_CONFIG_DIR_ARGS_LIMIT(strchr(yytext, ' ') + 1, *driver.loc.back()); }\n{CONFIG_DIR_REQ_BODY_JSON_DEPTH_LIMIT}[ \\t]+{CONFIG_VALUE_NUMBER}       { return p::make_CONFIG_DIR_REQ_BODY_JSON_DEPTH_LIMIT(strchr(yytext, ' ') + 1, *driver.loc.back()); }\n{CONFIG_DIR_REQ_BODY_IN_MEMORY_LIMIT}[ \\t]+{CONFIG_VALUE_NUMBER}        { return p::make_CONFIG_DIR_REQ_BODY_IN_MEMORY_LIMIT(strchr(yytext, ' ') + 1, *driver.loc.back()); }\n\n{CONFIG_DIR_REQ_BODY_LIMIT_ACTION}                                      { return p::make_CONFIG_DIR_REQ_BODY_LIMIT_ACTION(yytext, *driver.loc.back()); }\n{CONFIG_DIR_REQ_BODY_LIMIT}[ \\t]+{CONFIG_VALUE_NUMBER}                  { return p::make_CONFIG_DIR_REQ_BODY_LIMIT(strchr(yytext, ' ') + 1, *driver.loc.back()); }\n{CONFIG_DIR_REQ_BODY_NO_FILES_LIMIT}[ \\t]+{CONFIG_VALUE_NUMBER}         { return p::make_CONFIG_DIR_REQ_BODY_NO_FILES_LIMIT(strchr(yytext, ' ') + 1, *driver.loc.back()); }\n{CONFIG_DIR_REQ_BODY}                                                   { return p::make_CONFIG_DIR_REQ_BODY(yytext, *driver.loc.back()); }\n{CONFIG_DIR_RES_BODY_LIMIT_ACTION}                                      { return p::make_CONFIG_DIR_RES_BODY_LIMIT_ACTION(yytext, *driver.loc.back()); }\n{CONFIG_DIR_RES_BODY_LIMIT}[ \\t]+{CONFIG_VALUE_NUMBER}                  { return p::make_CONFIG_DIR_RES_BODY_LIMIT(strchr(yytext, ' ') + 1, *driver.loc.back()); }\n{CONFIG_DIR_RES_BODY}                                                   { return p::make_CONFIG_DIR_RES_BODY(yytext, *driver.loc.back()); }\n{CONFIG_DIR_RULE_ENG}                                                   { return p::make_CONFIG_DIR_RULE_ENG(yytext, *driver.loc.back()); }\n{CONFIG_DIR_SEC_MARKER}[ \\t]+[\"]{NEW_LINE_FREE_TEXT}[\"]                 { return p::make_CONFIG_DIR_SEC_MARKER(strchr(yytext, ' ') + 1, *driver.loc.back()); }\n{CONFIG_DIR_SEC_MARKER}[ \\t]+{NEW_LINE_FREE_TEXT}                       { return p::make_CONFIG_DIR_SEC_MARKER(strchr(yytext, ' ') + 1, *driver.loc.back()); }\n{CONFIG_DIR_UNICODE_MAP_FILE}[ \\t]+{FREE_TEXT_NEW_LINE}[ ]+{CONFIG_VALUE_NUMBER}                    { return p::make_CONFIG_DIR_UNICODE_MAP_FILE(strchr(yytext, ' ') + 1, *driver.loc.back()); }\n{CONFIG_SEC_REMOVE_RULES_BY_ID}[ \\t]+{FREE_TEXT_NEW_LINE}               { return p::make_CONFIG_SEC_RULE_REMOVE_BY_ID(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); }\n{CONFIG_SEC_REMOVE_RULES_BY_MSG}[ \\t]+{FREE_TEXT_NEW_LINE}              { return p::make_CONFIG_SEC_RULE_REMOVE_BY_MSG(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); }\n{CONFIG_SEC_REMOVE_RULES_BY_MSG}[ \\t]+[\"]{FREE_TEXT_NEW_LINE}[\"]        { return p::make_CONFIG_SEC_RULE_REMOVE_BY_MSG(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); }\n{CONFIG_SEC_REMOVE_RULES_BY_TAG}[ \\t]+{FREE_TEXT_NEW_LINE}              { return p::make_CONFIG_SEC_RULE_REMOVE_BY_TAG(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); }\n{CONFIG_SEC_REMOVE_RULES_BY_TAG}[ \\t]+[\"]{FREE_TEXT_NEW_LINE}[\"]        { return p::make_CONFIG_SEC_RULE_REMOVE_BY_TAG(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); }\n{CONFIG_SEC_UPDATE_TARGET_BY_TAG}[ \\t]+[\"]{FREE_TEXT_NEW_LINE}[\"]       { state_variable_from = 1; BEGIN(TRANSACTION_TO_VARIABLE); return p::make_CONFIG_SEC_RULE_UPDATE_TARGET_BY_TAG(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); }\n{CONFIG_SEC_UPDATE_TARGET_BY_TAG}[ \\t]+{FREE_TEXT_SPACE_COMMA_QUOTE}    { state_variable_from = 1; BEGIN(TRANSACTION_TO_VARIABLE); return p::make_CONFIG_SEC_RULE_UPDATE_TARGET_BY_TAG(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); }\n{CONFIG_SEC_UPDATE_TARGET_BY_MSG}[ \\t]+[\"]{FREE_TEXT_NEW_LINE}[\"]       { state_variable_from = 1; BEGIN(TRANSACTION_TO_VARIABLE); return p::make_CONFIG_SEC_RULE_UPDATE_TARGET_BY_MSG(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); }\n{CONFIG_SEC_UPDATE_TARGET_BY_MSG}[ \\t]+{FREE_TEXT_SPACE_COMMA_QUOTE}    { state_variable_from = 1; BEGIN(TRANSACTION_TO_VARIABLE); return p::make_CONFIG_SEC_RULE_UPDATE_TARGET_BY_MSG(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); }\n{CONFIG_SEC_UPDATE_TARGET_BY_ID}[ \\t]+[\"]{FREE_TEXT_NEW_LINE}[\"]        { state_variable_from = 1; BEGIN(TRANSACTION_TO_VARIABLE); return p::make_CONFIG_SEC_RULE_UPDATE_TARGET_BY_ID(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); }\n{CONFIG_SEC_UPDATE_TARGET_BY_ID}[ \\t]+{FREE_TEXT_SPACE_COMMA_QUOTE}     { state_variable_from = 1; BEGIN(TRANSACTION_TO_VARIABLE); return p::make_CONFIG_SEC_RULE_UPDATE_TARGET_BY_ID(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); }\n{CONFIG_SEC_UPDATE_ACTION_BY_ID}[ \\t]+[\"]{FREE_TEXT_NEW_LINE}[\"]        { BEGIN(TRANSACTION_FROM_OPERATOR_TO_ACTIONS); return p::make_CONFIG_SEC_RULE_UPDATE_ACTION_BY_ID(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); }\n{CONFIG_SEC_UPDATE_ACTION_BY_ID}[ \\t]+{FREE_TEXT_SPACE_COMMA_QUOTE}     { BEGIN(TRANSACTION_FROM_OPERATOR_TO_ACTIONS); return p::make_CONFIG_SEC_RULE_UPDATE_ACTION_BY_ID(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); }\n{CONFIG_UPDLOAD_KEEP_FILES}                                             { return p::make_CONFIG_UPDLOAD_KEEP_FILES(yytext, *driver.loc.back()); }\n{CONFIG_UPDLOAD_SAVE_TMP_FILES}                                         { return p::make_CONFIG_UPDLOAD_SAVE_TMP_FILES(yytext, *driver.loc.back()); }\n{CONFIG_UPLOAD_DIR}[ \\t]+{CONFIG_VALUE_PATH}                            { return p::make_CONFIG_UPLOAD_DIR(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); }\n{CONFIG_UPLOAD_DIR}[ \\t]+[\"]{CONFIG_VALUE_PATH}[\"]                      { return p::make_CONFIG_UPLOAD_DIR(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); }\n{CONFIG_UPLOAD_FILE_LIMIT}[ \\t]+{CONFIG_VALUE_NUMBER}                   { return p::make_CONFIG_UPLOAD_FILE_LIMIT(strchr(yytext, ' ') + 1, *driver.loc.back()); }\n{CONFIG_UPLOAD_FILE_MODE}[ \\t]+{CONFIG_VALUE_NUMBER}                    { return p::make_CONFIG_UPLOAD_FILE_MODE(strchr(yytext, ' ') + 1, *driver.loc.back()); }\n{CONFIG_VALUE_ABORT}                                                    { return p::make_CONFIG_VALUE_ABORT(yytext, *driver.loc.back()); }\n{CONFIG_VALUE_DETC}                                                     { return p::make_CONFIG_VALUE_DETC(yytext, *driver.loc.back()); }\n{CONFIG_VALUE_HTTPS}                                                    { return p::make_CONFIG_VALUE_HTTPS(yytext, *driver.loc.back()); }\n{CONFIG_VALUE_ONLYARGS}                                                 { return p::make_CONFIG_VALUE_ONLYARGS(yytext, *driver.loc.back()); }\n{CONFIG_VALUE_OFF}                                                      { return p::make_CONFIG_VALUE_OFF(yytext, *driver.loc.back()); }\n{CONFIG_VALUE_ON}                                                       { return p::make_CONFIG_VALUE_ON(yytext, *driver.loc.back()); }\n{CONFIG_VALUE_PARALLEL}                                                 { return p::make_CONFIG_VALUE_PARALLEL(yytext, *driver.loc.back()); }\n{CONFIG_VALUE_PROCESS_PARTIAL}                                          { return p::make_CONFIG_VALUE_PROCESS_PARTIAL(yytext, *driver.loc.back()); }\n{CONFIG_VALUE_REJECT}                                                   { return p::make_CONFIG_VALUE_REJECT(yytext, *driver.loc.back()); }\n{CONFIG_VALUE_RELEVANT_ONLY}                                            { return p::make_CONFIG_VALUE_RELEVANT_ONLY(yytext, *driver.loc.back()); }\n{CONFIG_VALUE_SERIAL}                                                   { return p::make_CONFIG_VALUE_SERIAL(yytext, *driver.loc.back()); }\n{CONFIG_VALUE_WARN}                                                     { return p::make_CONFIG_VALUE_WARN(yytext, *driver.loc.back()); }\n{CONFIG_XML_EXTERNAL_ENTITY}                                            { return p::make_CONFIG_XML_EXTERNAL_ENTITY(yytext, *driver.loc.back()); }\n{CONFIG_XML_PARSE_XML_INTO_ARGS}                                        { return p::make_CONFIG_XML_PARSE_XML_INTO_ARGS(yytext, *driver.loc.back()); }\n{CONGIG_DIR_RESPONSE_BODY_MP}[ \\t]+{FREE_TEXT_NEW_LINE}                 { return p::make_CONGIG_DIR_RESPONSE_BODY_MP(strchr(yytext, ' ') + 1, *driver.loc.back()); }\n{CONGIG_DIR_RESPONSE_BODY_MP_CLEAR}                                     { return p::make_CONGIG_DIR_RESPONSE_BODY_MP_CLEAR(*driver.loc.back()); }\n{CONGIG_DIR_SEC_ARG_SEP}[ \\t]+{FREE_TEXT_NEW_LINE}                      { return p::make_CONGIG_DIR_SEC_ARG_SEP(yytext, *driver.loc.back()); }\n{CONGIG_DIR_SEC_COOKIE_FORMAT}[ \\t]+{CONFIG_VALUE_NUMBER}               { return p::make_CONGIG_DIR_SEC_COOKIE_FORMAT(strchr(yytext, ' ') + 1, *driver.loc.back()); }\n{CONFIG_SEC_COOKIEV0_SEPARATOR}[ \\t]+[\"]{NEW_LINE_FREE_TEXT}[\"]         { return p::make_CONFIG_SEC_COOKIEV0_SEPARATOR(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); }\n{CONFIG_SEC_COOKIEV0_SEPARATOR}[ \\t]+{NEW_LINE_FREE_TEXT}               { return p::make_CONFIG_SEC_COOKIEV0_SEPARATOR(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); }\n{CONGIG_DIR_SEC_DATA_DIR}[ \\t]+{CONFIG_VALUE_PATH}                      { return p::make_CONGIG_DIR_SEC_DATA_DIR(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); }\n{CONGIG_DIR_SEC_DATA_DIR}[ \\t]+[\"]{CONFIG_VALUE_PATH}[\"]                { return p::make_CONGIG_DIR_SEC_DATA_DIR(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); }\n{CONGIG_DIR_SEC_STATUS_ENGINE}[ \\t]+{FREE_TEXT_NEW_LINE}                { return p::make_CONGIG_DIR_SEC_STATUS_ENGINE(yytext, *driver.loc.back()); }\n{CONGIG_DIR_SEC_TMP_DIR}[ \\t]+{CONFIG_VALUE_PATH}                       { return p::make_CONGIG_DIR_SEC_TMP_DIR(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); }\n{CONGIG_DIR_SEC_TMP_DIR}[ \\t]+[\"]{CONFIG_VALUE_PATH}[\"]                 { return p::make_CONGIG_DIR_SEC_TMP_DIR(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); }\n{DIRECTIVE_SECRULESCRIPT}[ \\t]+{CONFIG_VALUE_PATH}                      { BEGIN(TRANSACTION_FROM_DIRECTIVE_TO_ACTIONS); return p::make_DIRECTIVE_SECRULESCRIPT(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); }\n{DIRECTIVE_SECRULESCRIPT}[ \\t]+[\"]{FREE_TEXT_SPACE_COMMA_QUOTE}[\"]      { BEGIN(TRANSACTION_FROM_DIRECTIVE_TO_ACTIONS); return p::make_DIRECTIVE_SECRULESCRIPT(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); }\n{CONFIG_SEC_CACHE_TRANSFORMATIONS}{FREE_TEXT_NEW_LINE}                  { return p::make_CONFIG_SEC_CACHE_TRANSFORMATIONS(yytext, *driver.loc.back()); }\n{CONFIG_SEC_CHROOT_DIR}[ \\t]+{CONFIG_VALUE_PATH}                        { return p::make_CONFIG_SEC_CHROOT_DIR(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); }\n{CONFIG_SEC_CHROOT_DIR}[ \\t]+[\"]{CONFIG_VALUE_PATH}[\"]                  { return p::make_CONFIG_SEC_CHROOT_DIR(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); }\n{CONFIG_CONN_ENGINE}                                                    { return p::make_CONFIG_CONN_ENGINE(yytext, *driver.loc.back()); }\n{CONFIG_SEC_HASH_ENGINE}                                                { return p::make_CONFIG_SEC_HASH_ENGINE(yytext, *driver.loc.back()); }\n{CONFIG_SEC_HASH_KEY}                                                   { return p::make_CONFIG_SEC_HASH_KEY(yytext, *driver.loc.back()); }\n{CONFIG_SEC_HASH_PARAM}                                                 { return p::make_CONFIG_SEC_HASH_PARAM(yytext, *driver.loc.back()); }\n{CONFIG_SEC_HASH_METHOD_RX}                                             { return p::make_CONFIG_SEC_HASH_METHOD_RX(yytext, *driver.loc.back()); }\n{CONFIG_SEC_HASH_METHOD_PM}                                             { return p::make_CONFIG_SEC_HASH_METHOD_PM(yytext, *driver.loc.back()); }\n{CONFIG_DIR_GSB_DB}[ \\t]+{CONFIG_VALUE_PATH}                            { return p::make_CONFIG_DIR_GSB_DB(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); }\n{CONFIG_DIR_GSB_DB}[ \\t]+[\"]{CONFIG_VALUE_PATH}[\"]                      { return p::make_CONFIG_DIR_GSB_DB(parserSanitizer(strchr(yytext, ' ') + 1), *driver.loc.back()); }\n{CONFIG_SEC_GUARDIAN_LOG}                                               { return p::make_CONFIG_SEC_GUARDIAN_LOG(yytext, *driver.loc.back()); }\n{CONFIG_SEC_INTERCEPT_ON_ERROR}                                         { return p::make_CONFIG_SEC_INTERCEPT_ON_ERROR(yytext, *driver.loc.back()); }\n{CONFIG_SEC_CONN_R_STATE_LIMIT}{FREE_TEXT_NEW_LINE}                     { return p::make_CONFIG_SEC_CONN_R_STATE_LIMIT(yytext, *driver.loc.back()); }\n{CONFIG_SEC_CONN_W_STATE_LIMIT}{FREE_TEXT_NEW_LINE}                     { return p::make_CONFIG_SEC_CONN_W_STATE_LIMIT(yytext, *driver.loc.back()); }\n{CONFIG_SEC_SENSOR_ID}{FREE_TEXT_NEW_LINE}                              { return p::make_CONFIG_SEC_SENSOR_ID(yytext, *driver.loc.back()); }\n{CONFIG_SEC_RULE_INHERITANCE}                                           { return p::make_CONFIG_SEC_RULE_INHERITANCE(yytext, *driver.loc.back()); }\n{CONFIG_SEC_RULE_PERF_TIME}[ \\t]+{CONFIG_VALUE_NUMBER}                  { return p::make_CONFIG_SEC_RULE_PERF_TIME(strchr(yytext, ' ') + 1, *driver.loc.back()); }\n{CONFIG_SEC_STREAM_IN_BODY_INSPECTION}                                  { return p::make_CONFIG_SEC_STREAM_IN_BODY_INSPECTION(yytext, *driver.loc.back()); }\n{CONFIG_SEC_STREAM_OUT_BODY_INSPECTION}                                 { return p::make_CONFIG_SEC_STREAM_OUT_BODY_INSPECTION(yytext, *driver.loc.back()); }\n{CONFIG_SEC_DISABLE_BACKEND_COMPRESS}                                   { return p::make_CONFIG_SEC_DISABLE_BACKEND_COMPRESS(yytext, *driver.loc.back()); }\n\n{DIRECTIVE}                                                             { BEGIN(TRANSACTION_TO_VARIABLE); return p::make_DIRECTIVE(yytext, *driver.loc.back()); }\n{CONFIG_DIR_SEC_DEFAULT_ACTION}                                         { BEGIN(TRANSACTION_FROM_DIRECTIVE_TO_ACTIONS); return p::make_CONFIG_DIR_SEC_DEFAULT_ACTION(yytext, *driver.loc.back()); }\n{CONFIG_DIR_SEC_ACTION}                                                 { BEGIN(TRANSACTION_FROM_DIRECTIVE_TO_ACTIONS); return p::make_CONFIG_DIR_SEC_ACTION(yytext, *driver.loc.back()); }\n\n{CONFIG_SEC_REMOTE_RULES_FAIL_ACTION}                                   { return p::make_CONFIG_SEC_REMOTE_RULES_FAIL_ACTION(yytext, *driver.loc.back()); }\n{CONFIG_SEC_COLLECTION_TIMEOUT}[ \\t]+{CONFIG_VALUE_NUMBER}              { return p::make_CONFIG_SEC_COLLECTION_TIMEOUT(strchr(yytext, ' ') + 1, *driver.loc.back()); }\n{CONFIG_SEC_HTTP_BLKEY}[ \\t]+{FREE_TEXT_NEW_LINE}                       { return p::make_CONFIG_SEC_HTTP_BLKEY(strchr(yytext, ' ') + 1, *driver.loc.back()); }\n[ \\t]*[\\n]                                                              { driver.loc.back()->lines(1); driver.loc.back()->step(); }\n#[ \\t]*SecRule[^\\\\].*\\\\[ \\t]*[\\r\\n]*                                    { driver.loc.back()->lines(1); driver.loc.back()->step(); BEGIN(COMMENT); }\n#[ \\t]*SecAction[^\\\\].*\\\\[ \\t]*[^\\\\n]                                   { driver.loc.back()->lines(1); driver.loc.back()->step(); BEGIN(COMMENT);  }\n#.*                                                                     { driver.loc.back()->step(); /* comment, just ignore. */ }\n\\r                                                                      { driver.loc.back()->step(); /* carriage return, just ignore. */}\n[\"]                                                                     { return p::make_QUOTATION_MARK(yytext, *driver.loc.back()); }\n[,]                                                                     { return p::make_COMMA(*driver.loc.back()); }\n\n<TRANSACTION_TO_VARIABLE>{\n[ \\t]*                        { BEGIN(EXPECTING_VARIABLE); }\n}\n\n<EXPECTING_VARIABLE>{\n[|]                                         { return p::make_PIPE(*driver.loc.back()); }\n[,]                                         { return p::make_PIPE(*driver.loc.back()); }\n[\"]                                         { return p::make_QUOTATION_MARK(yytext, *driver.loc.back()); }\n{VAR_EXCLUSION}                             { return p::make_VAR_EXCLUSION(*driver.loc.back()); }\n{VAR_COUNT}                                 { return p::make_VAR_COUNT(*driver.loc.back()); }\n}\n\n<EXPECTING_VARIABLE>{\n[ \\t]+                                      { if (state_variable_from == 0) { BEGIN(EXPECTING_OPERATOR_ENDS_WITH_SPACE); } else { state_variable_from = 0; BEGIN(INITIAL);} }\n[ \\t]*\\\"                                    { if (state_variable_from == 0) { BEGIN(EXPECTING_OPERATOR_ENDS_WITH_QUOTE); } else { state_variable_from = 0; BEGIN(INITIAL);} }\n[ \\t]*[\\\\\\n]*[ \\t]*                         { if (state_variable_from == 0) { BEGIN(EXPECTING_OPERATOR_ENDS_WITH_SPACE); } else { state_variable_from = 0; BEGIN(INITIAL);} }\n[ \\t]*[\\\\\\n]*[ \\t]*\\\"                       { if (state_variable_from == 0) { BEGIN(EXPECTING_OPERATOR_ENDS_WITH_QUOTE); } else { state_variable_from = 0; BEGIN(INITIAL);} }\n[ \\t]*[\\\\\\r\\n]*[ \\t]*                       { if (state_variable_from == 0) { BEGIN(EXPECTING_OPERATOR_ENDS_WITH_SPACE); } else { state_variable_from = 0; BEGIN(INITIAL);} }\n[ \\t]*[\\\\\\r\\n]*[ \\t]*\\\"                     { if (state_variable_from == 0) { BEGIN(EXPECTING_OPERATOR_ENDS_WITH_QUOTE); } else { state_variable_from = 0; BEGIN(INITIAL);} }\n}\n\n<TRANSACTION_FROM_DIRECTIVE_TO_ACTIONS>{\n[ \\t]* {  }\n[ \\t]*\\\"[ \\t]*                { BEGIN(EXPECTING_ACTIONS_ENDS_WITH_DOUBLE_QUOTE); }\n[ \\t]*\\\\\\n[ \\t]*\\\"[ \\t]*      { BEGIN(EXPECTING_ACTIONS_ENDS_WITH_DOUBLE_QUOTE); }\n[ \\t]*\\\\\\r\\n[ \\t]*\\\"[ \\t]*    { BEGIN(EXPECTING_ACTIONS_ENDS_WITH_DOUBLE_QUOTE); }\n}\n\n\n<EXPECTING_VARIABLE,EXPECTING_ACTION_PREDICATE_VARIABLE>{\n.                                           { BEGIN(LEXING_ERROR_VARIABLE); yyless(0); }\n{VARIABLE_ARGS_COMBINED_SIZE}               { return p::make_VARIABLE_ARGS_COMBINED_SIZE(*driver.loc.back()); }\n{VARIABLE_ARGS_GET_NAMES}                   { return p::make_VARIABLE_ARGS_GET_NAMES(*driver.loc.back()); }\n{VARIABLE_ARGS_GET_NAMES}[:.]               { BEGINX(EXPECTING_VAR_PARAMETER); return p::make_VARIABLE_ARGS_GET_NAMES(*driver.loc.back()); }\n{VARIABLE_ARGS_NAMES}                       { return p::make_VARIABLE_ARGS_NAMES(*driver.loc.back()); }\n{VARIABLE_ARGS_NAMES}[:.]                   { BEGINX(EXPECTING_VAR_PARAMETER); return p::make_VARIABLE_ARGS_NAMES(*driver.loc.back()); }\n{VARIABLE_ARGS_POST_NAMES}                  { return p::make_VARIABLE_ARGS_POST_NAMES(*driver.loc.back()); }\n{VARIABLE_ARGS_POST_NAMES}[:.]              { BEGINX(EXPECTING_VAR_PARAMETER); return p::make_VARIABLE_ARGS_POST_NAMES(*driver.loc.back()); }\n{VARIABLE_AUTH_TYPE}                        { return p::make_VARIABLE_AUTH_TYPE(*driver.loc.back()); }\n{VARIABLE_FILES_COMBINED_SIZE}              { return p::make_VARIABLE_FILES_COMBINED_SIZE(*driver.loc.back()); }\n{VARIABLE_FULL_REQUEST_LENGTH}              { return p::make_VARIABLE_FULL_REQUEST_LENGTH(*driver.loc.back()); }\n{VARIABLE_FULL_REQUEST}                     { return p::make_VARIABLE_FULL_REQUEST(*driver.loc.back()); }\n{VARIABLE_INBOUND_DATA_ERROR}               { return p::make_VARIABLE_INBOUND_DATA_ERROR(*driver.loc.back()); }\n{VARIABLE_MATCHED_VAR_NAME}                 { return p::make_VARIABLE_MATCHED_VAR_NAME(*driver.loc.back()); }\n{VARIABLE_MATCHED_VAR}                      { return p::make_VARIABLE_MATCHED_VAR(*driver.loc.back()); }\n{VARIABLE_MSC_PCRE_ERROR}                   { return p::make_VARIABLE_MSC_PCRE_ERROR(*driver.loc.back()); }\n{VARIABLE_MSC_PCRE_LIMITS_EXCEEDED}         { return p::make_VARIABLE_MSC_PCRE_LIMITS_EXCEEDED(*driver.loc.back()); }\n{VARIABLE_MULTIPART_BOUNDARY_QUOTED}        { return p::make_VARIABLE_MULTIPART_BOUNDARY_QUOTED(*driver.loc.back()); }\n{VARIABLE_MULTIPART_BOUNDARY_WHITESPACE}    { return p::make_VARIABLE_MULTIPART_BOUNDARY_WHITESPACE(*driver.loc.back()); }\n{VARIABLE_MULTIPART_CRLF_LF_LINES}          { return p::make_VARIABLE_MULTIPART_CRLF_LF_LINES(*driver.loc.back()); }\n{VARIABLE_MULTIPART_DATA_AFTER}             { return p::make_VARIABLE_MULTIPART_DATA_AFTER(*driver.loc.back()); }\n{VARIABLE_MULTIPART_DATA_BEFORE}            { return p::make_VARIABLE_MULTIPART_DATA_BEFORE(*driver.loc.back()); }\n{VARIABLE_MULTIPART_FILE_LIMIT_EXCEEDED}    { return p::make_VARIABLE_MULTIPART_FILE_LIMIT_EXCEEDED(*driver.loc.back()); }\n{VARIABLE_MULTIPART_FILENAME}[:.]           { BEGINX(EXPECTING_VAR_PARAMETER); return p::make_VARIABLE_MULTIPART_FILENAME(*driver.loc.back()); }\n{VARIABLE_MULTIPART_FILENAME}               { return p::make_VARIABLE_MULTIPART_FILENAME(*driver.loc.back()); }\n{VARIABLE_MULTIPART_HEADER_FOLDING}         { return p::make_VARIABLE_MULTIPART_HEADER_FOLDING(*driver.loc.back()); }\n{VARIABLE_MULTIPART_HEADER_FOLDING}         { return p::make_VARIABLE_MULTIPART_HEADER_FOLDING(*driver.loc.back()); }\n{VARIABLE_MULTIPART_INVALID_HEADER_FOLDING} { return p::make_VARIABLE_MULTIPART_INVALID_HEADER_FOLDING(*driver.loc.back()); }\n{VARIABLE_MULTIPART_INVALID_PART}           { return p::make_VARIABLE_MULTIPART_INVALID_PART(*driver.loc.back()); }\n{VARIABLE_MULTIPART_INVALID_QUOTING}        { return p::make_VARIABLE_MULTIPART_INVALID_QUOTING(*driver.loc.back()); }\n{VARIABLE_MULTIPART_LF_LINE}                { return p::make_VARIABLE_MULTIPART_LF_LINE(*driver.loc.back()); }\n{VARIABLE_MULTIPART_MISSING_SEMICOLON}      { return p::make_VARIABLE_MULTIPART_MISSING_SEMICOLON(*driver.loc.back()); }\n{VARIABLE_MULTIPART_SEMICOLON_MISSING}      { return p::make_VARIABLE_MULTIPART_SEMICOLON_MISSING(*driver.loc.back()); }\n{VARIABLE_MULTIPART_NAME}[:.]               { BEGINX(EXPECTING_VAR_PARAMETER); return p::make_VARIABLE_MULTIPART_NAME(*driver.loc.back()); }\n{VARIABLE_MULTIPART_NAME}                   { return p::make_VARIABLE_MULTIPART_NAME(*driver.loc.back()); }\n{VARIABLE_MULTIPART_STRICT_ERROR}           { return p::make_VARIABLE_MULTIPART_STRICT_ERROR(*driver.loc.back()); }\n{VARIABLE_MULTIPART_UNMATCHED_BOUNDARY}     { return p::make_VARIABLE_MULTIPART_UNMATCHED_BOUNDARY(*driver.loc.back()); }\n{VARIABLE_OUTBOUND_DATA_ERROR}              { return p::make_VARIABLE_OUTBOUND_DATA_ERROR(*driver.loc.back()); }\n{VARIABLE_PATH_INFO}                        { return p::make_VARIABLE_PATH_INFO(*driver.loc.back()); }\n{VARIABLE_QUERY_STRING}                     { return p::make_VARIABLE_QUERY_STRING(*driver.loc.back()); }\n{VARIABLE_REMOTE_ADDR}                      { return p::make_VARIABLE_REMOTE_ADDR(*driver.loc.back()); }\n{VARIABLE_REMOTE_HOST}                      { return p::make_VARIABLE_REMOTE_HOST(*driver.loc.back()); }\n{VARIABLE_REMOTE_PORT}                      { return p::make_VARIABLE_REMOTE_PORT(*driver.loc.back()); }\n{VARIABLE_REQBODY_ERROR_MSG}                { return p::make_VARIABLE_REQBODY_ERROR_MSG(*driver.loc.back()); }\n{VARIABLE_REQBODY_ERROR}                    { return p::make_VARIABLE_REQBODY_ERROR(*driver.loc.back()); }\n{VARIABLE_REQBODY_PROCESSOR_ERROR_MSG}      { return p::make_VARIABLE_REQBODY_PROCESSOR_ERROR_MSG(*driver.loc.back()); }\n{VARIABLE_REQBODY_PROCESSOR_ERROR}          { return p::make_VARIABLE_REQBODY_PROCESSOR_ERROR(*driver.loc.back()); }\n{VARIABLE_REQBODY_PROCESSOR}                { return p::make_VARIABLE_REQBODY_PROCESSOR(*driver.loc.back()); }\n{VARIABLE_REQUEST_BASENAME}                 { return p::make_VARIABLE_REQUEST_BASENAME(*driver.loc.back()); }\n{VARIABLE_REQUEST_BODY_LENGTH}              { return p::make_VARIABLE_REQUEST_BODY_LENGTH(*driver.loc.back()); }\n{VARIABLE_REQUEST_BODY}                     { return p::make_VARIABLE_REQUEST_BODY(*driver.loc.back()); }\n{VARIABLE_REQUEST_FILE_NAME}                { return p::make_VARIABLE_REQUEST_FILE_NAME(*driver.loc.back()); }\n{VARIABLE_REQUEST_HEADERS_NAMES}            { return p::make_VARIABLE_REQUEST_HEADERS_NAMES(*driver.loc.back()); }\n{VARIABLE_REQUEST_HEADERS_NAMES}[:.]        { BEGINX(EXPECTING_VAR_PARAMETER); return p::make_VARIABLE_REQUEST_HEADERS_NAMES(*driver.loc.back()); }\n{VARIABLE_REQUEST_LINE}                     { return p::make_VARIABLE_REQUEST_LINE(*driver.loc.back()); }\n{VARIABLE_REQUEST_METHOD}                   { return p::make_VARIABLE_REQUEST_METHOD(*driver.loc.back()); }\n{VARIABLE_REQUEST_PROTOCOL}                 { return p::make_VARIABLE_REQUEST_PROTOCOL(*driver.loc.back()); }\n{VARIABLE_REQUEST_URI_RAW}                  { return p::make_VARIABLE_REQUEST_URI_RAW(*driver.loc.back()); }\n{VARIABLE_REQUEST_URI}                      { return p::make_VARIABLE_REQUEST_URI(*driver.loc.back()); }\n{VARIABLE_RESPONSE_BODY}                    { return p::make_VARIABLE_RESPONSE_BODY(*driver.loc.back()); }\n{VARIABLE_RESPONSE_CONTENT_LENGTH}          { return p::make_VARIABLE_RESPONSE_CONTENT_LENGTH(*driver.loc.back()); }\n{VARIABLE_RESPONSE_CONTENT_TYPE}            { return p::make_VARIABLE_RESPONSE_CONTENT_TYPE(*driver.loc.back()); }\n{VARIABLE_RESPONSE_HEADERS_NAMES}           { return p::make_VARIABLE_RESPONSE_HEADERS_NAMES(*driver.loc.back()); }\n{VARIABLE_RESPONSE_HEADERS_NAMES}[:.]       { BEGINX(EXPECTING_VAR_PARAMETER); return p::make_VARIABLE_RESPONSE_HEADERS_NAMES(*driver.loc.back()); }\n{VARIABLE_RESPONSE_PROTOCOL}                { return p::make_VARIABLE_RESPONSE_PROTOCOL(*driver.loc.back()); }\n{VARIABLE_RESPONSE_STATUS}                  { return p::make_VARIABLE_RESPONSE_STATUS(*driver.loc.back()); }\n{VARIABLE_SERVER_ADDR}                      { return p::make_VARIABLE_SERVER_ADDR(*driver.loc.back()); }\n{VARIABLE_SERVER_NAME}                      { return p::make_VARIABLE_SERVER_NAME(*driver.loc.back()); }\n{VARIABLE_SERVER_PORT}                      { return p::make_VARIABLE_SERVER_PORT(*driver.loc.back()); }\n{VARIABLE_SESSION_ID}                       { return p::make_VARIABLE_SESSION_ID(*driver.loc.back()); }\n{VARIABLE_UNIQUE_ID}                        { return p::make_VARIABLE_UNIQUE_ID(*driver.loc.back()); }\n{VARIABLE_URL_ENCODED_ERROR}                { return p::make_VARIABLE_URL_ENCODED_ERROR(*driver.loc.back()); }\n{VARIABLE_USER_ID}                          { return p::make_VARIABLE_USER_ID(*driver.loc.back()); }\n{VARIABLE_WEB_APP_ID}                       { return p::make_VARIABLE_WEB_APP_ID(*driver.loc.back()); }\n{VARIABLE_ARGS}                             { return p::make_VARIABLE_ARGS(*driver.loc.back()); }\n{VARIABLE_ARGS}[:.]                         { BEGINX(EXPECTING_VAR_PARAMETER); return p::make_VARIABLE_ARGS(*driver.loc.back()); }\n{VARIABLE_ARGS_GET}                         { return p::make_VARIABLE_ARGS_GET(*driver.loc.back()); }\n{VARIABLE_ARGS_GET}[:.]                     { BEGINX(EXPECTING_VAR_PARAMETER); return p::make_VARIABLE_ARGS_GET(*driver.loc.back()); }\n{VARIABLE_ARGS_POST}                        { return p::make_VARIABLE_ARGS_POST(*driver.loc.back()); }\n{VARIABLE_ARGS_POST}[:.]                    { BEGINX(EXPECTING_VAR_PARAMETER); return p::make_VARIABLE_ARGS_POST(*driver.loc.back()); }\n{VARIABLE_FILES_SIZES}                      { return p::make_VARIABLE_FILES_SIZES(*driver.loc.back()); }\n{VARIABLE_FILES_SIZES}[:.]                  { BEGINX(EXPECTING_VAR_PARAMETER); return p::make_VARIABLE_FILES_SIZES(*driver.loc.back()); }\n{VARIABLE_FILES_NAMES}                      { return p::make_VARIABLE_FILES_NAMES(*driver.loc.back()); }\n{VARIABLE_FILES_NAMES}[:.]                  { BEGINX(EXPECTING_VAR_PARAMETER); return p::make_VARIABLE_FILES_NAMES(*driver.loc.back()); }\n{VARIABLE_FILES_TMP_CONTENT}                { return p::make_VARIABLE_FILES_TMP_CONTENT(*driver.loc.back()); }\n{VARIABLE_FILES_TMP_CONTENT}[:.]            { BEGINX(EXPECTING_VAR_PARAMETER); return p::make_VARIABLE_FILES_TMP_CONTENT(*driver.loc.back()); }\n{VARIABLE_MATCHED_VARS_NAMES}               { return p::make_VARIABLE_MATCHED_VARS_NAMES(*driver.loc.back()); }\n{VARIABLE_MATCHED_VARS_NAMES}[:.]           { BEGINX(EXPECTING_VAR_PARAMETER); return p::make_VARIABLE_MATCHED_VARS_NAMES(*driver.loc.back()); }\n{VARIABLE_MATCHED_VARS}                     { return p::make_VARIABLE_MATCHED_VARS(*driver.loc.back()); }\n{VARIABLE_MATCHED_VARS}[:.]                 { BEGINX(EXPECTING_VAR_PARAMETER); return p::make_VARIABLE_MATCHED_VARS(*driver.loc.back()); }\n{VARIABLE_FILES}                            { return p::make_VARIABLE_FILES(*driver.loc.back()); }\n{VARIABLE_FILES}[:.]                        { BEGINX(EXPECTING_VAR_PARAMETER); return p::make_VARIABLE_FILES(*driver.loc.back()); }\n{VARIABLE_REQUEST_COOKIES}                  { return p::make_VARIABLE_REQUEST_COOKIES(*driver.loc.back()); }\n{VARIABLE_REQUEST_COOKIES}[:.]              { BEGINX(EXPECTING_VAR_PARAMETER); return p::make_VARIABLE_REQUEST_COOKIES(*driver.loc.back()); }\n{VARIABLE_REQUEST_HEADERS}                  { return p::make_VARIABLE_REQUEST_HEADERS(*driver.loc.back()); }\n{VARIABLE_REQUEST_HEADERS}[:.]              { BEGINX(EXPECTING_VAR_PARAMETER); return p::make_VARIABLE_REQUEST_HEADERS(*driver.loc.back()); }\n{VARIABLE_RESPONSE_HEADERS}                 { return p::make_VARIABLE_RESPONSE_HEADERS(*driver.loc.back()); }\n{VARIABLE_RESPONSE_HEADERS}[:.]             { BEGINX(EXPECTING_VAR_PARAMETER); return p::make_VARIABLE_RESPONSE_HEADERS(*driver.loc.back()); }\n{VARIABLE_GEO}                              { return p::make_VARIABLE_GEO(*driver.loc.back()); }\n{VARIABLE_GEO}[:.]                          { BEGINX(EXPECTING_VAR_PARAMETER); return p::make_VARIABLE_GEO(*driver.loc.back()); }\n{VARIABLE_REQUEST_COOKIES_NAMES}            { return p::make_VARIABLE_REQUEST_COOKIES_NAMES(*driver.loc.back()); }\n{VARIABLE_REQUEST_COOKIES_NAMES}[:.]        { BEGINX(EXPECTING_VAR_PARAMETER); return p::make_VARIABLE_REQUEST_COOKIES_NAMES(*driver.loc.back()); }\n{VARIABLE_MULTIPART_PART_HEADERS}           { return p::make_VARIABLE_MULTIPART_PART_HEADERS(*driver.loc.back()); }\n{VARIABLE_MULTIPART_PART_HEADERS}[:.]       { BEGINX(EXPECTING_VAR_PARAMETER); return p::make_VARIABLE_MULTIPART_PART_HEADERS(*driver.loc.back()); }\n{VARIABLE_RULE}                             { return p::make_VARIABLE_RULE(*driver.loc.back()); }\n{VARIABLE_RULE}[:.]                         { BEGINX(EXPECTING_VAR_PARAMETER); return p::make_VARIABLE_RULE(*driver.loc.back()); }\n{VARIABLE_FILES_TMP_NAMES}                  { return p::make_VARIABLE_FILES_TMP_NAMES(*driver.loc.back()); }\n{VARIABLE_FILES_TMP_NAMES}[:.]              { BEGINX(EXPECTING_VAR_PARAMETER); return p::make_VARIABLE_FILES_TMP_NAMES(*driver.loc.back()); }\n{RUN_TIME_VAR_XML}                          { return p::make_RUN_TIME_VAR_XML(*driver.loc.back()); }\n{RUN_TIME_VAR_XML}[:.]                      { BEGINX(EXPECTING_VAR_PARAMETER); return p::make_RUN_TIME_VAR_XML(*driver.loc.back()); }\n{RUN_TIME_VAR_ENV}                          { return p::make_RUN_TIME_VAR_ENV(*driver.loc.back()); }\n{RUN_TIME_VAR_ENV}[:.]                      { BEGINX(EXPECTING_VAR_PARAMETER); return p::make_RUN_TIME_VAR_ENV(*driver.loc.back()); }\n{RUN_TIME_VAR_BLD}                          { return p::make_RUN_TIME_VAR_BLD(yytext, *driver.loc.back()); }\n{RUN_TIME_VAR_DUR}                          { return p::make_RUN_TIME_VAR_DUR(yytext, *driver.loc.back()); }\n{RUN_TIME_VAR_HSV}                          { return p::make_RUN_TIME_VAR_HSV(yytext, *driver.loc.back()); }\n{RUN_TIME_VAR_REMOTE_USER}                  { return p::make_RUN_TIME_VAR_REMOTE_USER(yytext, *driver.loc.back()); }\n{RUN_TIME_VAR_TIME_DAY}                     { return p::make_RUN_TIME_VAR_TIME_DAY(yytext, *driver.loc.back()); }\n{RUN_TIME_VAR_TIME_EPOCH}                   { return p::make_RUN_TIME_VAR_TIME_EPOCH(yytext, *driver.loc.back()); }\n{RUN_TIME_VAR_TIME_HOUR}                    { return p::make_RUN_TIME_VAR_TIME_HOUR(yytext, *driver.loc.back()); }\n{RUN_TIME_VAR_TIME_MIN}                     { return p::make_RUN_TIME_VAR_TIME_MIN(yytext, *driver.loc.back()); }\n{RUN_TIME_VAR_TIME_MON}                     { return p::make_RUN_TIME_VAR_TIME_MON(yytext, *driver.loc.back()); }\n{RUN_TIME_VAR_TIME_SEC}                     { return p::make_RUN_TIME_VAR_TIME_SEC(yytext, *driver.loc.back()); }\n{RUN_TIME_VAR_TIME_YEAR}                    { return p::make_RUN_TIME_VAR_TIME_YEAR(yytext, *driver.loc.back()); }\n{RUN_TIME_VAR_TIME}                         { return p::make_RUN_TIME_VAR_TIME(yytext, *driver.loc.back()); }\n{RUN_TIME_VAR_TIME_WDAY}                    { return p::make_RUN_TIME_VAR_TIME_WDAY(yytext, *driver.loc.back()); }\n\n\n{VARIABLE_WEBSERVER_ERROR_LOG}              { driver.error (*driver.loc.back(), \"Variable VARIABLE_WEBSERVER_ERROR_LOG is not supported by libModSecurity\", \"\"); throw p::syntax_error(*driver.loc.back(), \"\");}\n{VARIABLE_GLOBAL}                           { return p::make_VARIABLE_GLOBAL(*driver.loc.back()); }\n{VARIABLE_IP}                               { return p::make_VARIABLE_IP(*driver.loc.back()); }\n{VARIABLE_RESOURCE}                         { return p::make_VARIABLE_RESOURCE(*driver.loc.back()); }\n{VARIABLE_SESSION}                          { return p::make_VARIABLE_SESSION(*driver.loc.back()); }\n{VARIABLE_STATUS}                           { return p::make_VARIABLE_STATUS(*driver.loc.back()); }\n{VARIABLE_STATUS_LINE}                      { return p::make_VARIABLE_STATUS_LINE(*driver.loc.back()); }\n{VARIABLE_TX}                               { return p::make_VARIABLE_TX(*driver.loc.back()); }\n{VARIABLE_USER}                             { return p::make_VARIABLE_USER(*driver.loc.back()); }\n}\n\n<EXPECTING_VARIABLE,EXPECTING_ACTION_PREDICATE_VARIABLE,SETVAR_ACTION_NONQUOTED,SETVAR_ACTION_QUOTED>{\n{VARIABLE_GLOBAL}[:.]                       { BEGINX_(); return p::make_VARIABLE_GLOBAL(*driver.loc.back()); }\n{VARIABLE_IP}[:.]                           { BEGINX_(); return p::make_VARIABLE_IP(*driver.loc.back()); }\n{VARIABLE_RESOURCE}[:.]                     { BEGINX_(); return p::make_VARIABLE_RESOURCE(*driver.loc.back()); }\n{VARIABLE_SESSION}[:.]                      { BEGINX_(); return p::make_VARIABLE_SESSION(*driver.loc.back()); }\n{VARIABLE_TX}[:.]                           { BEGINX_(); return p::make_VARIABLE_TX(*driver.loc.back()); }\n{VARIABLE_USER}[:.]                         { BEGINX_(); return p::make_VARIABLE_USER(*driver.loc.back()); }\n}\n\n\n<EXPECTING_VAR_PARAMETER_OR_MACRO_QUOTED,EXPECTING_VAR_PARAMETER_OR_MACRO_NONQUOTED>{\n{EQUALS_PLUS}                             { BEGIN_ACTION_WAITING_CONTENT(); return p::make_SETVAR_OPERATION_EQUALS_PLUS(*driver.loc.back()); }\n{EQUALS_MINUS}                            { BEGIN_ACTION_WAITING_CONTENT(); return p::make_SETVAR_OPERATION_EQUALS_MINUS(*driver.loc.back()); }\n{EQUALS}                                  { BEGIN_ACTION_WAITING_CONTENT(); return p::make_SETVAR_OPERATION_EQUALS(*driver.loc.back()); }\n[\\/]{DICT_ELEMENT_NO_PIPE}[\\/][ ]         { BEGIN_PREVIOUS(); yyless(yyleng - 1); return p::make_DICT_ELEMENT_REGEXP(std::string(yytext, 1, yyleng-2), *driver.loc.back()); }\n[\\/]{DICT_ELEMENT_NO_PIPE}[\\/][|]         { BEGIN_PREVIOUS(); yyless(yyleng - 1); return p::make_DICT_ELEMENT_REGEXP(std::string(yytext, 1, yyleng-2), *driver.loc.back()); }\n['][\\/]{DICT_ELEMENT_WITH_PIPE}[\\/][']    { BEGIN_PREVIOUS(); yyless(yyleng - 0); return p::make_DICT_ELEMENT_REGEXP(std::string(yytext, 2, yyleng-4), *driver.loc.back()); }\n['][\\/]{DICT_ELEMENT_WITH_PIPE}[\\/]['][|] { BEGIN_PREVIOUS(); yyless(yyleng - 1); return p::make_DICT_ELEMENT_REGEXP(std::string(yytext, 2, yyleng-4), *driver.loc.back()); }\n{FREE_TEXT_EQUALS_MACRO_EXPANSION}[']     { yyless(yyleng - 1); BEGIN_PREVIOUS(); return p::make_FREE_TEXT_QUOTE_MACRO_EXPANSION(yytext, *driver.loc.back()); }\n{FREE_TEXT_EQUALS_MACRO_EXPANSION}        { return p::make_FREE_TEXT_QUOTE_MACRO_EXPANSION(yytext, *driver.loc.back()); }\n\n[\\/]{DICT_ELEMENT_NO_PIPE}[\\/][,]         { BEGIN_PREVIOUS(); yyless(yyleng - 1); return p::make_DICT_ELEMENT_REGEXP(std::string(yytext, 1, yyleng-2), *driver.loc.back()); }\n['][\\/]{DICT_ELEMENT_NO_PIPE}[\\/]['][,]   { BEGIN_PREVIOUS(); yyless(yyleng - 1); return p::make_DICT_ELEMENT_REGEXP(std::string(yytext, 2, yyleng-4), *driver.loc.back()); }\n[\"]                                       { BEGIN_PREVIOUS(); yyless(0); }\n[,]                                       { BEGIN_PREVIOUS(); yyless(0); }\n.                                         { BEGINX(LEXING_ERROR_ACTION); yyless(0); }\n}\n\n\n<EXPECTING_VAR_PARAMETER>{\n[\\/]{DICT_ELEMENT_NO_PIPE}[\\/]            { BEGIN_PREVIOUS(); yyless(yyleng); return p::make_DICT_ELEMENT_REGEXP(std::string(yytext, 1, yyleng-2), *driver.loc.back()); }\n[\\/]{DICT_ELEMENT_NO_PIPE}[\\/][ ]         { BEGIN_PREVIOUS(); yyless(yyleng - 1); return p::make_DICT_ELEMENT_REGEXP(std::string(yytext, 1, yyleng-2), *driver.loc.back()); }\n[\\/]{DICT_ELEMENT_NO_PIPE}[\\/][|]         { BEGIN_PREVIOUS(); yyless(yyleng - 1); return p::make_DICT_ELEMENT_REGEXP(std::string(yytext, 1, yyleng-2), *driver.loc.back()); }\n['][\\/]{DICT_ELEMENT_WITH_PIPE}[\\/][']    { BEGIN_PREVIOUS(); yyless(yyleng - 0); return p::make_DICT_ELEMENT_REGEXP(std::string(yytext, 2, yyleng-4), *driver.loc.back()); }\n['][\\/]{DICT_ELEMENT_WITH_PIPE}[\\/]['][|] { BEGIN_PREVIOUS(); yyless(yyleng - 1); return p::make_DICT_ELEMENT_REGEXP(std::string(yytext, 2, yyleng-4), *driver.loc.back()); }\n{DICT_ELEMENT_WITH_EQUALS}                { BEGIN_PREVIOUS(); return p::make_DICT_ELEMENT(yytext, *driver.loc.back()); }\n\n[\\/]{DICT_ELEMENT_NO_PIPE}[\\/][,]         { BEGIN_PREVIOUS(); yyless(yyleng - 1); return p::make_DICT_ELEMENT_REGEXP(std::string(yytext, 1, yyleng-2), *driver.loc.back()); }\n['][\\/]{DICT_ELEMENT_NO_PIPE}[\\/]['][,]   { BEGIN_PREVIOUS(); yyless(yyleng - 1); return p::make_DICT_ELEMENT_REGEXP(std::string(yytext, 2, yyleng-4), *driver.loc.back()); }\n\n.                                         { BEGINX(LEXING_ERROR_ACTION); yyless(0); }\n[\"]                                       { return p::make_QUOTATION_MARK(yytext, *driver.loc.back()); }\n}\n\n\n\n<EXPECTING_OPERATOR_ENDS_WITH_SPACE>{\n{OPERATOR_GEOLOOKUP}[ ]                   { BEGIN(TRANSACTION_FROM_OPERATOR_TO_ACTIONS); return p::make_OPERATOR_GEOLOOKUP(*driver.loc.back()); }\n{OPERATOR_UNCONDITIONAL_MATCH}[ ]         { BEGIN(TRANSACTION_FROM_OPERATOR_TO_ACTIONS); return p::make_OPERATOR_UNCONDITIONAL_MATCH(*driver.loc.back()); }\n{OPERATOR_DETECT_SQLI}[ ]                 { BEGIN(TRANSACTION_FROM_OPERATOR_TO_ACTIONS); return p::make_OPERATOR_DETECT_SQLI(*driver.loc.back()); }\n{OPERATOR_DETECT_XSS}[ ]                  { BEGIN(TRANSACTION_FROM_OPERATOR_TO_ACTIONS); return p::make_OPERATOR_DETECT_XSS(*driver.loc.back()); }\n{OPERATOR_VALIDATE_URL_ENCODING}[ ]       { BEGIN(TRANSACTION_FROM_OPERATOR_TO_ACTIONS); return p::make_OPERATOR_VALIDATE_URL_ENCODING(*driver.loc.back()); }\n{OPERATOR_VALIDATE_UTF8_ENCODING}[ ]      { BEGIN(TRANSACTION_FROM_OPERATOR_TO_ACTIONS); return p::make_OPERATOR_VALIDATE_UTF8_ENCODING(*driver.loc.back()); }\n}\n<EXPECTING_OPERATOR_ENDS_WITH_QUOTE>{\n{OPERATOR_GEOLOOKUP}[ ]*[\"]               { BEGIN(TRANSACTION_FROM_OPERATOR_TO_ACTIONS); return p::make_OPERATOR_GEOLOOKUP(*driver.loc.back()); }\n{OPERATOR_UNCONDITIONAL_MATCH}[ ]*[\"]     { BEGIN(TRANSACTION_FROM_OPERATOR_TO_ACTIONS); return p::make_OPERATOR_UNCONDITIONAL_MATCH(*driver.loc.back()); }\n{OPERATOR_DETECT_SQLI}[ ]*[\"]             { BEGIN(TRANSACTION_FROM_OPERATOR_TO_ACTIONS); return p::make_OPERATOR_DETECT_SQLI(*driver.loc.back()); }\n{OPERATOR_DETECT_XSS}[ ]*[\"]              { BEGIN(TRANSACTION_FROM_OPERATOR_TO_ACTIONS); return p::make_OPERATOR_DETECT_XSS(*driver.loc.back()); }\n{OPERATOR_VALIDATE_URL_ENCODING}[ ]*[\"]   { BEGIN(TRANSACTION_FROM_OPERATOR_TO_ACTIONS); return p::make_OPERATOR_VALIDATE_URL_ENCODING(*driver.loc.back()); }\n{OPERATOR_VALIDATE_UTF8_ENCODING}[ ]*[\"]  { BEGIN(TRANSACTION_FROM_OPERATOR_TO_ACTIONS); return p::make_OPERATOR_VALIDATE_UTF8_ENCODING(*driver.loc.back()); }\n}\n\n<EXPECTING_OPERATOR_ENDS_WITH_SPACE,EXPECTING_OPERATOR_ENDS_WITH_QUOTE>{\n{OPERATOR_WITHIN}                       { BEGIN_PARAMETER(); return p::make_OPERATOR_WITHIN(*driver.loc.back()); }\n{OPERATOR_CONTAINS_WORD}                { BEGIN_PARAMETER(); return p::make_OPERATOR_CONTAINS_WORD(*driver.loc.back()); }\n{OPERATOR_CONTAINS}                     { BEGIN_PARAMETER(); return p::make_OPERATOR_CONTAINS(*driver.loc.back()); }\n{OPERATOR_ENDS_WITH}                    { BEGIN_PARAMETER(); return p::make_OPERATOR_ENDS_WITH(*driver.loc.back()); }\n{OPERATOR_EQ}                           { BEGIN_PARAMETER(); return p::make_OPERATOR_EQ(*driver.loc.back()); }\n{OPERATOR_GE}                           { BEGIN_PARAMETER(); return p::make_OPERATOR_GE(*driver.loc.back()); }\n{OPERATOR_GT}                           { BEGIN_PARAMETER(); return p::make_OPERATOR_GT(*driver.loc.back()); }\n{OPERATOR_IP_MATCH_FROM_FILE}           { BEGIN_PARAMETER(); return p::make_OPERATOR_IP_MATCH_FROM_FILE(*driver.loc.back()); }\n{OPERATOR_IP_MATCH}                     { BEGIN_PARAMETER(); return p::make_OPERATOR_IP_MATCH(*driver.loc.back()); }\n{OPERATOR_LE}                           { BEGIN_PARAMETER(); return p::make_OPERATOR_LE(*driver.loc.back()); }\n{OPERATOR_LT}                           { BEGIN_PARAMETER(); return p::make_OPERATOR_LT(*driver.loc.back()); }\n{OPERATOR_PM_FROM_FILE}                 { BEGIN_PARAMETER(); return p::make_OPERATOR_PM_FROM_FILE(*driver.loc.back()); }\n{OPERATOR_PM}                           { BEGIN_PARAMETER(); return p::make_OPERATOR_PM(*driver.loc.back()); }\n{OPERATOR_RBL}                          { BEGIN_PARAMETER(); return p::make_OPERATOR_RBL( *driver.loc.back()); }\n{OPERATOR_RX}                           { BEGIN_PARAMETER(); return p::make_OPERATOR_RX(*driver.loc.back()); }\n{OPERATOR_RX_GLOBAL}                    { BEGIN_PARAMETER(); return p::make_OPERATOR_RX_GLOBAL(*driver.loc.back()); }\n{OPERATOR_STR_EQ}                       { BEGIN_PARAMETER(); return p::make_OPERATOR_STR_EQ(*driver.loc.back()); }\n{OPERATOR_STR_MATCH}                    { BEGIN_PARAMETER(); return p::make_OPERATOR_STR_MATCH(*driver.loc.back()); }\n{OPERATOR_BEGINS_WITH}                  { BEGIN_PARAMETER(); return p::make_OPERATOR_BEGINS_WITH(*driver.loc.back()); }\n{OPERATOR_INSPECT_FILE}                 { BEGIN_PARAMETER(); return p::make_OPERATOR_INSPECT_FILE(*driver.loc.back()); }\n{OPERATOR_FUZZY_HASH}                   { BEGIN_PARAMETER(); return p::make_OPERATOR_FUZZY_HASH(*driver.loc.back()); }\n{OPERATOR_VALIDATE_BYTE_RANGE}          { BEGIN_PARAMETER(); return p::make_OPERATOR_VALIDATE_BYTE_RANGE(*driver.loc.back()); }\n{OPERATOR_VALIDATE_DTD}                 { BEGIN_PARAMETER(); return p::make_OPERATOR_VALIDATE_DTD(*driver.loc.back()); }\n{OPERATOR_VALIDATE_HASH}                { BEGIN_PARAMETER(); return p::make_OPERATOR_VALIDATE_HASH(*driver.loc.back()); }\n{OPERATOR_VALIDATE_SCHEMA}              { BEGIN_PARAMETER(); return p::make_OPERATOR_VALIDATE_SCHEMA(*driver.loc.back()); }\n{OPERATOR_VERIFY_CC}                    { BEGIN_PARAMETER(); return p::make_OPERATOR_VERIFY_CC(*driver.loc.back()); }\n{OPERATOR_VERIFY_CPF}                   { BEGIN_PARAMETER(); return p::make_OPERATOR_VERIFY_CPF(*driver.loc.back()); }\n{OPERATOR_VERIFY_SSN}                   { BEGIN_PARAMETER(); return p::make_OPERATOR_VERIFY_SSN(*driver.loc.back()); }\n{OPERATOR_VERIFY_SVNR}                   { BEGIN_PARAMETER(); return p::make_OPERATOR_VERIFY_SVNR(*driver.loc.back()); }\n{OPERATOR_GSB_LOOKUP}                   { BEGIN_PARAMETER(); return p::make_OPERATOR_GSB_LOOKUP(*driver.loc.back()); }\n{OPERATOR_RSUB}                         { BEGIN_PARAMETER(); return p::make_OPERATOR_RSUB(*driver.loc.back()); }\n\n{NOT}                                   { return p::make_NOT(*driver.loc.back()); }\n.                                       { BEGIN_NO_OP_INFORMED(); yyless(0); }\n}\n\n\n<TRANSITION_FROM_OP_TO_EXPECTING_PARAMETER_ENDS_WITH_SPACE>{\n[ ]    { BEGIN(EXPECTING_PARAMETER_ENDS_WITH_SPACE); }\n}\n\n<TRANSITION_FROM_OP_TO_EXPECTING_PARAMETER_ENDS_WITH_QUOTE>{\n[ ]    { BEGIN(EXPECTING_PARAMETER_ENDS_WITH_QUOTE); }\n}\n\n<NO_OP_INFORMED_ENDS_WITH_QUOTE>{\n[\"]                                             { BEGIN(TRANSACTION_FROM_OPERATOR_PARAMETERS_TO_ACTIONS); }\n{FREE_TEXT_DOUBLE_QUOTE_MACRO_EXPANSION}        { return p::make_FREE_TEXT_QUOTE_MACRO_EXPANSION(yytext, *driver.loc.back()); }\n}\n\n<NO_OP_INFORMED_ENDS_WITH_SPACE>{\n[ ]                                             { BEGIN(TRANSACTION_FROM_OPERATOR_PARAMETERS_TO_ACTIONS); }\n{FREE_TEXT_SPACE_MACRO_EXPANSION}               { return p::make_FREE_TEXT_QUOTE_MACRO_EXPANSION(yytext, *driver.loc.back()); }\n}\n<NO_OP_INFORMED_ENDS_WITH_QUOTE,NO_OP_INFORMED_ENDS_WITH_SPACE>{\n{START_MACRO_VARIABLE}                          { BEGINX(EXPECTING_ACTION_PREDICATE_VARIABLE); }\n.                                               { BEGIN(LEXING_ERROR); yyless(0); }\n}\n\n<EXPECTING_PARAMETER_ENDS_WITH_QUOTE>{\n[\"]                                             { BEGIN(TRANSACTION_FROM_OPERATOR_PARAMETERS_TO_ACTIONS); }\n{FREE_TEXT_DOUBLE_QUOTE_MACRO_EXPANSION}        { return p::make_FREE_TEXT_QUOTE_MACRO_EXPANSION(yytext, *driver.loc.back()); }\n}\n\n<EXPECTING_PARAMETER_ENDS_WITH_SPACE>{\n[ ]                                             { BEGIN(TRANSACTION_FROM_OPERATOR_PARAMETERS_TO_ACTIONS); }\n{FREE_TEXT_SPACE_MACRO_EXPANSION}               { return p::make_FREE_TEXT_QUOTE_MACRO_EXPANSION(yytext, *driver.loc.back()); }\n}\n\n<EXPECTING_PARAMETER_ENDS_WITH_QUOTE,EXPECTING_PARAMETER_ENDS_WITH_SPACE,EXPECTING_VAR_PARAMETER_OR_MACRO_QUOTED,EXPECTING_VAR_PARAMETER_OR_MACRO_NONQUOTED>{\n{START_MACRO_VARIABLE}                          { BEGINX(EXPECTING_ACTION_PREDICATE_VARIABLE); }\n.                                               { BEGIN(LEXING_ERROR_VARIABLE); yyless(0); }\n}\n\n\n<TRANSACTION_FROM_OPERATOR_TO_ACTIONS,TRANSACTION_FROM_OPERATOR_PARAMETERS_TO_ACTIONS>{\n[ ]+                                  { BEGIN(EXPECTING_ACTIONS_ONLY_ONE); }\n\n[ \\t]*\\\\\\n[ \\t]*\\\"[ \\t]*              { driver.loc.back()->lines(1); driver.loc.back()->step(); BEGIN(EXPECTING_ACTIONS_ENDS_WITH_DOUBLE_QUOTE); }\n[ \\t]*\\n[ \\t]*\\\"[ \\t]*                { driver.loc.back()->lines(1); driver.loc.back()->step(); BEGIN(EXPECTING_ACTIONS_ENDS_WITH_DOUBLE_QUOTE); }\n[ \\t]*\\\\\\n[ \\t]*                      { driver.loc.back()->lines(1); driver.loc.back()->step(); BEGIN(EXPECTING_ACTIONS_ONLY_ONE); }\n[ \\t]*\\n[ \\t]*                        { driver.loc.back()->lines(1); driver.loc.back()->step(); BEGIN(EXPECTING_ACTIONS_ONLY_ONE); }\n\n[ \\t]*\\\\\\r\\\\\\n[ \\t]*\\\"[ \\t]*          { driver.loc.back()->lines(1); driver.loc.back()->step(); BEGIN(EXPECTING_ACTIONS_ENDS_WITH_DOUBLE_QUOTE); }\n[ \\t]*\\\\\\r\\n[ \\t]*\\\"[ \\t]*            { driver.loc.back()->lines(1); driver.loc.back()->step(); BEGIN(EXPECTING_ACTIONS_ENDS_WITH_DOUBLE_QUOTE); }\n[ \\t]*\\r\\\\\\n[ \\t]*\\\"[ \\t]*            { driver.loc.back()->lines(1); driver.loc.back()->step(); BEGIN(EXPECTING_ACTIONS_ENDS_WITH_DOUBLE_QUOTE); }\n[ \\t]*\\r\\n[ \\t]*\\\"[ \\t]*              { driver.loc.back()->lines(1); driver.loc.back()->step(); BEGIN(EXPECTING_ACTIONS_ENDS_WITH_DOUBLE_QUOTE); }\n\n[ \\t]*\\\\\\r\\\\\\n[ \\t]*                  { driver.loc.back()->lines(1); driver.loc.back()->step(); BEGIN(EXPECTING_ACTIONS_ONLY_ONE); }\n[ \\t]*\\\\\\r\\n[ \\t]*                    { driver.loc.back()->lines(1); driver.loc.back()->step(); BEGIN(EXPECTING_ACTIONS_ONLY_ONE); }\n[ \\t]*\\r\\\\\\n[ \\t]*                    { driver.loc.back()->lines(1); driver.loc.back()->step(); BEGIN(EXPECTING_ACTIONS_ONLY_ONE); }\n[ \\t]*\\r\\n[ \\t]*                      { driver.loc.back()->lines(1); driver.loc.back()->step(); BEGIN(EXPECTING_ACTIONS_ONLY_ONE); }\n\n[ \\t]*\\\"[ \\t]*                        { BEGIN(EXPECTING_ACTIONS_ENDS_WITH_DOUBLE_QUOTE); }\n\n[ \\t]*\\\"[ \\t]*\\\\\\n[ \\t]*\\\"[ \\t]*      { driver.loc.back()->lines(1); driver.loc.back()->step(); BEGIN(EXPECTING_ACTIONS_ENDS_WITH_DOUBLE_QUOTE); }\n[ \\t]*\\\"[ \\t]*\\n[ \\t]*\\\"[ \\t]*        { driver.loc.back()->lines(1); driver.loc.back()->step(); BEGIN(EXPECTING_ACTIONS_ENDS_WITH_DOUBLE_QUOTE); }\n\n[ \\t]*\\\"[ \\t]*\\\\\\r\\n[ \\t]*\\\"[ \\t]*    { driver.loc.back()->lines(1); driver.loc.back()->step(); BEGIN(EXPECTING_ACTIONS_ENDS_WITH_DOUBLE_QUOTE); }\n[ \\t]*\\\"[ \\t]*\\\\\\r\\\\\\n[ \\t]*\\\"[ \\t]*  { driver.loc.back()->lines(1); driver.loc.back()->step(); BEGIN(EXPECTING_ACTIONS_ENDS_WITH_DOUBLE_QUOTE); }\n[ \\t]*\\\"[ \\t]*\\r\\n[ \\t]*\\\"[ \\t]*      { driver.loc.back()->lines(1); driver.loc.back()->step(); BEGIN(EXPECTING_ACTIONS_ENDS_WITH_DOUBLE_QUOTE); }\n[ \\t]*\\\"[ \\t]*\\r\\\\\\n[ \\t]*\\\"[ \\t]*    { driver.loc.back()->lines(1); driver.loc.back()->step(); BEGIN(EXPECTING_ACTIONS_ENDS_WITH_DOUBLE_QUOTE); }\n\n[ \\t]*\\\"[ \\t]*\\\"[ \\t]*                { BEGIN(EXPECTING_ACTIONS_ENDS_WITH_DOUBLE_QUOTE); }\n}\n\n\n<INITIAL,EXPECTING_OPERATOR_ENDS_WITH_SPACE,EXPECTING_OPERATOR_ENDS_WITH_QUOTE,EXPECTING_VAR_PARAMETER_OR_MACRO_QUOTED,EXPECTING_VAR_PARAMETER_OR_MACRO_NONQUOTED>{\n[ \\t]+                                {  }\n[ \\t]*\\\\\\n[ \\t]*                      { driver.loc.back()->lines(1); driver.loc.back()->step(); }\n[ \\t]*\\\\\\r\\n[ \\t]*                    { driver.loc.back()->lines(1); driver.loc.back()->step(); }\n}\n\n<COMMENT>{\n.*[ \\t]*\\\\\\n[ \\t]*                    { driver.loc.back()->lines(1); driver.loc.back()->step(); }\n.*[ \\t]*\\\\\\r\\n[ \\t]*                  { driver.loc.back()->lines(1); driver.loc.back()->step(); }\n.*[^\\\\]                               { BEGIN(INITIAL); driver.loc.back()->lines(1); driver.loc.back()->step(); }\n}\n\n\n\n.                                     { BEGIN(LEXING_ERROR); yyless(0); }\n\n<LEXING_ERROR>.+  { driver.error (*driver.loc.back(), \"Invalid input: \", yytext); throw p::syntax_error(*driver.loc.back(), \"\"); }\n<LEXING_ERROR_ACTION>.+  { driver.error (*driver.loc.back(), \"Expecting an action, got: \", yytext); throw p::syntax_error(*driver.loc.back(), \"\"); }\n<LEXING_ERROR_VARIABLE>.+  { driver.error (*driver.loc.back(), \"Expecting a variable, got:  : \", yytext); throw p::syntax_error(*driver.loc.back(), \"\"); }\n\n\n<<EOF>> {\n    if (yyin) {\n        fclose(yyin);\n    }\n\n    yypop_buffer_state();\n    if (!YY_CURRENT_BUFFER) {\n        return p::make_END(*driver.loc.back());\n    }\n\n    yy::location *l = driver.loc.back();\n    driver.loc.pop_back();\n    delete l;\n}\n\n\n{CONFIG_INCLUDE}[ \\t]+{CONFIG_VALUE_PATH} {\n    std::string err;\n    const char *tmpStr = yytext + strlen(\"include\");\n    const char *file   = tmpStr + strspn( tmpStr, \" \\t\");\n    std::string fi = modsecurity::utils::find_resource(file, *driver.loc.back()->end.filename, &err);\n    if (fi.empty() == true) {\n        BEGIN(INITIAL);\n        driver.error (*driver.loc.back(), \"\", file + std::string(\": Not able to open file. \") + err);\n        throw p::syntax_error(*driver.loc.back(), \"\");\n    }\n    std::list<std::string> files = modsecurity::utils::expandEnv(fi, 0);\n    files.reverse();\n    for (auto& s: files) {\n        std::string err;\n        std::string f = modsecurity::utils::find_resource(s, *driver.loc.back()->end.filename, &err);\n        driver.loc.push_back(new yy::location());\n        driver.m_filenames.push_back(f);\n        driver.loc.back()->begin.filename = driver.loc.back()->end.filename = &(driver.m_filenames.back());\n        yyin = fopen(f.c_str(), \"r\" );\n        if (!yyin) {\n            BEGIN(INITIAL);\n            driver.loc.pop_back();\n            driver.error (*driver.loc.back(), \"\", s + std::string(\": Not able to open file. \") + err);\n            throw p::syntax_error(*driver.loc.back(), \"\");\n        }\n        yypush_buffer_state(yy_create_buffer( yyin, YY_BUF_SIZE ));\n    }\n}\n\n{CONFIG_INCLUDE}[ \\t]+[\"]{CONFIG_VALUE_PATH}[\"] {\n    std::string err;\n    const char *tmpStr = yytext + strlen(\"include\");\n    const char *afterWhitespace   = tmpStr + strspn( tmpStr, \" \\t\");\n    std::string file(afterWhitespace+1, strlen(afterWhitespace)-2);\n    std::string fi = modsecurity::utils::find_resource(file, *driver.loc.back()->end.filename, &err);\n    if (fi.empty() == true) {\n        BEGIN(INITIAL);\n        driver.error (*driver.loc.back(), \"\", file + std::string(\": Not able to open file. \") + err);\n        throw p::syntax_error(*driver.loc.back(), \"\");\n    }\n    std::list<std::string> files = modsecurity::utils::expandEnv(fi, 0);\n    files.reverse();\n    for (auto& s: files) {\n        std::string f = modsecurity::utils::find_resource(s, *driver.loc.back()->end.filename, &err);\n        driver.loc.push_back(new yy::location());\n        driver.m_filenames.push_back(f);\n        driver.loc.back()->begin.filename = driver.loc.back()->end.filename = &(driver.m_filenames.back());\n\n        yyin = fopen(f.c_str(), \"r\" );\n        if (!yyin) {\n            BEGIN(INITIAL);\n            driver.loc.pop_back();\n            driver.error (*driver.loc.back(), \"\", s + std::string(\": Not able to open file. \") + err);\n            throw p::syntax_error(*driver.loc.back(), \"\");\n        }\n        yypush_buffer_state(yy_create_buffer( yyin, YY_BUF_SIZE ));\n    }\n}\n\n{CONFIG_SEC_REMOTE_RULES}[ ][^ ]+[ ][^\\n\\r ]+ {\n    HttpsClient c;\n    std::string key;\n    std::string url;\n\n    std::vector<std::string> conf = modsecurity::utils::string::split(yytext, ' ');\n    if (conf.size() < 2) {\n        driver.error (*driver.loc.back(), \"\", \"SecRemoteRules demands a key and a URI\");\n        throw p::syntax_error(*driver.loc.back(), \"\");\n    }\n    key = conf[1];\n    url = conf[2];\n    c.setKey(key);\n\n    driver.loc.push_back(new yy::location());\n    driver.m_filenames.push_back(url);\n    driver.loc.back()->begin.filename = driver.loc.back()->end.filename = &(driver.m_filenames.back());\n    YY_BUFFER_STATE temp = YY_CURRENT_BUFFER;\n    yypush_buffer_state(temp);\n\n    bool ret = c.download(url);\n\n    if (ret == false) {\n        BEGIN(INITIAL);\n        if (driver.m_remoteRulesActionOnFailed == RulesSet::OnFailedRemoteRulesAction::WarnOnFailedRemoteRulesAction) {\n            /** TODO: Implement the server logging mechanism. */\n        }\n        if (driver.m_remoteRulesActionOnFailed == RulesSet::OnFailedRemoteRulesAction::AbortOnFailedRemoteRulesAction) {\n            driver.error (*driver.loc.back(), \"\", yytext + std::string(\" - Failed to download: \") + c.error);\n            throw p::syntax_error(*driver.loc.back(), \"\");\n        }\n    }\n\n    yy_scan_string(c.content.c_str());\n}\n\n\n%%\n\nnamespace modsecurity {\n\nbool Driver::scan_begin () {\n    yy_flex_debug = trace_scanning;\n\n    if (buffer.empty() == false) {\n        yy_scan_string(buffer.c_str());\n        return true;\n    }\n    return false;\n}\n\nvoid Driver::scan_end () {\n    yylex_destroy();\n    BEGIN(INITIAL);\n}\n\n}\n\n"
  },
  {
    "path": "src/parser/stack.hh",
    "content": "// A Bison parser, made by GNU Bison 3.8.2.\n\n// Starting with Bison 3.2, this file is useless: the structure it\n// used to define is now defined with the parser itself.\n//\n// To get rid of this file:\n// 1. add '%require \"3.2\"' (or newer) to your grammar file\n// 2. remove references to this file from your build system.\n"
  },
  {
    "path": "src/request_body_processor/json.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n\n#ifdef WITH_YAJL\n\n#include \"src/request_body_processor/json.h\"\n\n#include <list>\n#include <iostream>\n#include <string>\n\n\nnamespace modsecurity {\nnamespace RequestBodyProcessor {\n\nstatic const double json_depth_limit_default = 10000.0;\nstatic const char* json_depth_limit_exceeded_msg = \". Parsing depth limit exceeded\";\n\nJSON::JSON(Transaction *transaction) : m_transaction(transaction),\n    m_handle(NULL),\n    m_current_key(\"\"),\n    m_max_depth(json_depth_limit_default),\n    m_current_depth(0),\n    m_depth_limit_exceeded(false) {\n    /**\n     * yajl callback functions\n     * For more information on the function signatures and order, check\n     * http://lloyd.github.com/yajl/yajl-1.0.12/structyajl__callbacks.html\n     */\n\n    /**\n     * yajl configuration and callbacks\n     */\n    static yajl_callbacks callbacks = {\n        yajl_null,\n        yajl_boolean,\n        NULL /* yajl_integer  */,\n        NULL /* yajl_double */,\n        yajl_number,\n        yajl_string,\n        yajl_start_map,\n        yajl_map_key,\n        yajl_end_map,\n        yajl_start_array,\n        yajl_end_array\n    };\n\n\n    /**\n     * yajl initialization\n     *\n     * yajl_parser_config definition:\n     * http://lloyd.github.io/yajl/yajl-2.0.1/yajl__parse_8h.html#aec816c5518264d2ac41c05469a0f986c\n     *\n     * TODO: make UTF8 validation optional, as it depends on Content-Encoding\n     */\n    m_handle = yajl_alloc(&callbacks, NULL, this);\n\n    yajl_config(m_handle, yajl_allow_partial_values, 0);\n}\n\n\nJSON::~JSON() {\n    while (m_containers.size() > 0) {\n        JSONContainer *a = m_containers.back();\n        m_containers.pop_back();\n        delete a;\n    }\n    yajl_free(m_handle);\n}\n\n\nbool JSON::init() {\n    return true;\n}\n\n\nbool JSON::processChunk(const char *buf, unsigned int size, std::string *err) {\n    /* Feed our parser and catch any errors */\n    m_status = yajl_parse(m_handle,\n        (const unsigned char *)buf, size);\n    if (m_status != yajl_status_ok) {\n        unsigned char *e = yajl_get_error(m_handle, 0,\n            (const unsigned char *)buf, size);\n        /* We need to free the yajl error message later, how to do this? */\n        err->assign((const char *)e);\n        if (m_depth_limit_exceeded) {\n            err->append(json_depth_limit_exceeded_msg);\n\t}\n        yajl_free_error(m_handle, e);\n        return false;\n    }\n\n    return true;\n}\n\n\nbool JSON::complete(std::string *err) {\n    /* Wrap up the parsing process */\n    m_status = yajl_complete_parse(m_handle);\n    if (m_status  != yajl_status_ok) {\n        unsigned char *e = yajl_get_error(m_handle, 0, NULL, 0);\n        /* We need to free the yajl error message later, how to do this? */\n        err->assign((const char *)e);\n        if (m_depth_limit_exceeded) {\n            err->append(json_depth_limit_exceeded_msg);\n\t}\n        yajl_free_error(m_handle, e);\n        return false;\n    }\n\n    return true;\n}\n\n\nint JSON::addArgument(const std::string& value) {\n    std::string data(\"\");\n    std::string path;\n\n    for (size_t i =  0; i < m_containers.size(); i++) {\n        const JSONContainerArray *a = dynamic_cast<JSONContainerArray *>(\n            m_containers[i]);\n        path = path + m_containers[i]->m_name;\n        if (a != NULL) {\n            path = path + \".array_\" + std::to_string(a->m_elementCounter);\n        } else {\n            path = path + \".\";\n        }\n    }\n\n    if (m_containers.size() > 0) {\n        JSONContainerArray *a = dynamic_cast<JSONContainerArray *>(\n            m_containers.back());\n        if (a) {\n            a->m_elementCounter++;\n        } else {\n            data = getCurrentKey();\n        }\n    } else {\n        data = getCurrentKey();\n    }\n\n\n    if (!m_transaction->addArgument(\"JSON\", path + data, value, 0)) {\n        // cancel parsing by returning false\n        return 0;\n    }\n\n    return 1;\n}\n\n\n/**\n * Callback for hash key values; we use those to define the variable names\n * under ARGS. Whenever we reach a new key, we update the current key value.\n */\nint JSON::yajl_map_key(void *ctx, const unsigned char *key, size_t length) {\n    JSON *tthis = reinterpret_cast<JSON *>(ctx);\n    std::string safe_key;\n\n    /**\n     * yajl does not provide us with null-terminated strings, but\n     * rather expects us to copy the data from the key up to the\n     * length informed; we create a standalone null-termined copy\n     * in safe_key\n     */\n    safe_key.assign((const char *)key, length);\n\n    tthis->m_current_key = safe_key;\n\n    return 1;\n}\n\n\n/**\n * Callback for null values\n *\n */\nint JSON::yajl_null(void *ctx) {\n    JSON *tthis = reinterpret_cast<JSON *>(ctx);\n    return tthis->addArgument(\"\");\n}\n\n\n/**\n * Callback for boolean values\n */\nint JSON::yajl_boolean(void *ctx, int value) {\n    JSON *tthis =  reinterpret_cast<JSON *>(ctx);\n    if (value) {\n        return tthis->addArgument(\"true\");\n    }\n    return tthis->addArgument(\"false\");\n}\n\n\n/**\n * Callback for string values\n */\nint JSON::yajl_string(void *ctx, const unsigned char *value, size_t length) {\n    JSON *tthis = reinterpret_cast<JSON *>(ctx);\n    std::string v = std::string((const char*)value, length);\n    return tthis->addArgument(v);\n}\n\n\n/**\n * Callback for numbers; YAJL can use separate callbacks for integers/longs and\n * float/double values, but since we are not interested in using the numeric\n * values here, we use a generic handler which uses numeric strings\n */\nint JSON::yajl_number(void *ctx, const char *value, size_t length) {\n    JSON *tthis = reinterpret_cast<JSON *>(ctx);\n    std::string v = std::string((const char*)value, length);\n    return tthis->addArgument(v);\n}\n\n\n/**\n * Callback for a new hash, which indicates a new subtree, labeled as the\n * current argument name, is being created\n */\nint JSON::yajl_start_array(void *ctx) {\n    JSON *tthis = reinterpret_cast<JSON *>(ctx);\n    std::string name = tthis->getCurrentKey();\n    tthis->m_containers.push_back(\n        reinterpret_cast<JSONContainer *>(new JSONContainerArray(name)));\n    tthis->m_current_depth++;\n    if (tthis->m_current_depth > tthis->m_max_depth) {\n        tthis->m_depth_limit_exceeded = true;\n        return 0;\n    }\n    return 1;\n}\n\n\nint JSON::yajl_end_array(void *ctx) {\n    JSON *tthis = reinterpret_cast<JSON *>(ctx);\n    if (tthis->m_containers.empty()) {\n        tthis->m_current_depth--;\n        return 1;\n    }\n\n    JSONContainer *a = tthis->m_containers.back();\n    tthis->m_containers.pop_back();\n    delete a;\n    if (tthis->m_containers.size() > 0) {\n        JSONContainerArray *ja = dynamic_cast<JSONContainerArray *>(\n            tthis->m_containers.back());\n        if (ja) {\n            ja->m_elementCounter++;\n        }\n    }\n    tthis->m_current_depth--;\n\n    return 1;\n}\n\n\nint JSON::yajl_start_map(void *ctx) {\n    JSON *tthis = reinterpret_cast<JSON *>(ctx);\n    std::string name(tthis->getCurrentKey());\n    tthis->m_containers.push_back(\n        reinterpret_cast<JSONContainer *>(new JSONContainerMap(name)));\n    tthis->m_current_depth++;\n    if (tthis->m_current_depth > tthis->m_max_depth) {\n        tthis->m_depth_limit_exceeded = true;\n        return 0;\n    }\n    return 1;\n}\n\n\n/**\n * Callback for end hash, meaning the current subtree is being closed, and that\n * we should go back to the parent variable label\n */\nint JSON::yajl_end_map(void *ctx) {\n    JSON *tthis = reinterpret_cast<JSON *>(ctx);\n    if (tthis->m_containers.empty()) {\n        tthis->m_current_depth--;\n        return 1;\n    }\n\n    JSONContainer *a = tthis->m_containers.back();\n    tthis->m_containers.pop_back();\n    delete a;\n\n    if (tthis->m_containers.size() > 0) {\n        JSONContainerArray *ja = dynamic_cast<JSONContainerArray *>(\n            tthis->m_containers.back());\n        if (ja) {\n            ja->m_elementCounter++;\n        }\n    }\n\n    tthis->m_current_depth--;\n    return 1;\n}\n\n\n}  // namespace RequestBodyProcessor\n}  // namespace modsecurity\n\n\n#endif  // WITH_YAJL\n\n"
  },
  {
    "path": "src/request_body_processor/json.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#ifndef SRC_REQUEST_BODY_PROCESSOR_JSON_H_\n#define SRC_REQUEST_BODY_PROCESSOR_JSON_H_\n\n\n#ifdef WITH_YAJL\n\n#include <yajl/yajl_parse.h>\n\n#include <string>\n#include <iostream>\n#include <deque>\n\n#include \"modsecurity/transaction.h\"\n#include \"modsecurity/rules_set.h\"\n\n\nnamespace modsecurity {\nnamespace RequestBodyProcessor {\n\n\nclass JSONContainer {\n public:\n    explicit JSONContainer(const std::string &name) : m_name(name) { }\n    virtual ~JSONContainer() { }\n    std::string m_name;\n};\n\n\nclass JSONContainerArray : public JSONContainer {\n public:\n    explicit JSONContainerArray(const std::string &name) : JSONContainer(name),\n        m_elementCounter(0) { }\n    size_t m_elementCounter;\n};\n\n\nclass JSONContainerMap : public JSONContainer {\n public:\n     explicit JSONContainerMap(const std::string &name) : JSONContainer(name) { }\n};\n\n\nclass JSON {\n public:\n    explicit JSON(Transaction *transaction);\n    ~JSON();\n\n    static bool init();\n    bool processChunk(const char *buf, unsigned int size, std::string *err);\n    bool complete(std::string *err);\n\n    int addArgument(const std::string& value);\n\n    static int yajl_number(void *ctx, const char *value, size_t length);\n    static int yajl_string(void *ctx, const unsigned char *value,\n        size_t length);\n    static int yajl_boolean(void *ctx, int value);\n    static int yajl_null(void *ctx);\n    static int yajl_map_key(void *ctx, const unsigned char *key,\n        size_t length);\n    static int yajl_end_map(void *ctx);\n    static int yajl_start_map(void *ctx);\n    static int yajl_start_array(void *ctx);\n    static int yajl_end_array(void *ctx);\n\n    bool isPreviousArray() const {\n        const JSONContainerArray *prev = NULL;\n        if (m_containers.size() < 1) {\n            return false;\n        }\n        prev = dynamic_cast<JSONContainerArray *>(\n            m_containers[m_containers.size() - 1]);\n        return prev != NULL;\n    }\n\n    std::string getCurrentKey(bool emptyIsNull = false) {\n        std::string ret(m_current_key);\n        if (m_containers.size() == 0) {\n            return \"json\";\n        }\n        if (m_current_key.empty() == true) {\n            if (isPreviousArray() || emptyIsNull == true) {\n                return \"\";\n            }\n            return \"empty-key\";\n        }\n        m_current_key = \"\";\n        return ret;\n    }\n\n    void setMaxDepth(double max_depth) {\n        m_max_depth = max_depth;\n    }\n\n private:\n    std::deque<JSONContainer *> m_containers;\n    Transaction *m_transaction;\n    yajl_handle m_handle;\n    yajl_status m_status;\n    std::string m_current_key;\n    double m_max_depth;\n    int64_t m_current_depth;\n    bool m_depth_limit_exceeded;\n};\n\n\n}  // namespace RequestBodyProcessor\n}  // namespace modsecurity\n\n#endif  // WITH_YAJL\n\n#endif  // SRC_REQUEST_BODY_PROCESSOR_JSON_H_\n\n"
  },
  {
    "path": "src/request_body_processor/multipart.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"src/request_body_processor/multipart.h\"\n\n#include <time.h>\n#include <stdio.h>\n#include <string.h>\n#include <sys/types.h>\n#include <sys/stat.h>\n#include <fcntl.h>\n#ifndef WIN32\n#include <unistd.h>\n#else\n#include <io.h>\n#include \"src/compat/msvc.h\"\n#endif\n#include <list>\n#include <iostream>\n#include <string>\n#include <utility>\n\n#include \"modsecurity/rules_set.h\"\n#include \"modsecurity/collection/collections.h\"\n#include \"src/utils/string.h\"\n\n\nnamespace modsecurity {\nnamespace RequestBodyProcessor {\n\nstatic const char* mime_charset_special = \"!#$%&+-^_`{}~\";\nstatic const char* attr_char_special = \"!#$&+-.^_`~\";\n\nMultipartPartTmpFile::~MultipartPartTmpFile() {\n    if (!m_tmp_file_name.empty() && m_delete) {\n        /* make sure it is closed first */\n        if (m_tmp_file_fd > 0) {\n            Close();\n        }\n\n        const int unlink_rc = unlink(m_tmp_file_name.c_str());\n        if (unlink_rc < 0) {\n            ms_dbg_a(m_transaction, 1, \"Multipart: Failed to delete file (part) \\\"\" \\\n                + m_tmp_file_name + \"\\\" because \" \\\n                + std::to_string(errno) +  \"(\" \\\n                + strerror(errno) + \")\");\n        } else {\n                ms_dbg_a(m_transaction, 4, \"Multipart: file deleted successfully (part) \\\"\" \\\n                            + m_tmp_file_name + \"\\\"\");\n        }\n\n    }\n}\n\nvoid MultipartPartTmpFile::Open() {\n    time_t tt = time(nullptr);\n\n    struct tm timeinfo;\n    localtime_r(&tt, &timeinfo);\n\n    char tstr[std::size(\"/yyyymmdd-hhmmss\")];\n    strftime(tstr, std::size(tstr), \"/%Y%m%d-%H%M%S\", &timeinfo);\n\n    std::string path = m_transaction->m_rules->m_uploadDirectory.m_value;\n    path = path + tstr + \"-\" + m_transaction->m_id;\n    path += \"-file-XXXXXX\";\n\n#ifndef WIN32\n    m_tmp_file_fd = mkstemp(path.data());\n#else\n    _mktemp_s(path.data(), path.length()+1);\n    m_tmp_file_fd = _open(path.c_str(), _O_CREAT | _O_EXCL | _O_RDWR);\n#endif\n    m_tmp_file_name = path;\n    ms_dbg_a(m_transaction, 4, \"MultipartPartTmpFile: Create filename= \" + m_tmp_file_name);\n\n    int mode = m_transaction->m_rules->m_uploadFileMode.m_value;\n    if ((m_tmp_file_fd != -1) && (mode != 0)) {\n#ifndef WIN32\n        if (fchmod(m_tmp_file_fd, mode) == -1) {\n#else\n        if (_chmod(m_tmp_file_name.c_str(), mode) == -1) {\n#endif\n            m_tmp_file_fd = -1;\n        }\n    }\n}\n\nvoid MultipartPartTmpFile::Close() {\n    close(m_tmp_file_fd);\n    m_tmp_file_fd = -1;\n}\n\n\nMultipart::Multipart(const std::string &header, Transaction *transaction)\n    : m_reqbody_no_files_length(0),\n    m_nfiles(0),\n    m_boundary_count(0),\n    m_buf{0},\n    m_buf_contains_line(0),\n    m_bufptr(NULL),\n    m_bufleft(0),\n    m_buf_offset(0),\n    m_crlf_state(0),\n    m_crlf_state_buf_end(0),\n    m_mpp(NULL),\n    m_mpp_state(0),\n    m_mpp_substate_part_data_read(0),\n    m_reserve{0},\n    m_seen_data(0),\n    m_is_complete(0),\n    m_flag_error(0),\n    m_flag_data_before(0),\n    m_flag_data_after(0),\n    m_flag_header_folding(0),\n    m_flag_boundary_quoted(0),\n    m_flag_lf_line(0),\n    m_flag_crlf_line(0),\n    m_flag_unmatched_boundary(0),\n    m_flag_boundary_whitespace(0),\n    m_flag_missing_semicolon(0),\n    m_flag_invalid_quoting(0),\n    m_flag_invalid_part(0),\n    m_flag_invalid_header_folding(0),\n    m_flag_file_limit_exceeded(0),\n    m_header(header),\n    m_transaction(transaction) { }\n\n\nMultipart::~Multipart() {\n    ms_dbg_a(m_transaction, 4,\n        \"Multipart: Cleanup started (keep files set to \" \\\n        + RulesSetProperties::configBooleanString(\n            m_transaction->m_rules->m_uploadKeepFiles) \\\n        + \")\");\n\n    if (m_transaction->m_rules->m_uploadKeepFiles\n        != RulesSetProperties::TrueConfigBoolean) {\n        for (MultipartPart *m : m_parts) {\n            if ((m->m_type == MULTIPART_FILE) && (m->m_tmp_file)) {\n                // only mark for deletion for now; the file should stay on disk until\n                // the transaction is complete\n                ms_dbg_a(m_transaction, 9, \"Multipart: Marking temporary file for deletion: \" \\\n                    + m->m_tmp_file->getFilename());\n                m->m_tmp_file->setDelete();\n            }\n\n        }\n    }\n\n    while (m_parts.empty() == false) {\n        auto *a = m_parts.back();\n        m_parts.pop_back();\n        delete a;\n    }\n\n    if (m_mpp != NULL) {\n        delete m_mpp;\n        m_mpp = NULL;\n    }\n}\n\n\nint Multipart::is_token_char(unsigned char c) {\n    /* ENH Is the performance important at all? We could use a table instead. */\n\n    /* CTLs not allowed */\n    if ((c <= 32) || (c >= 127)) {\n        return 0;\n    }\n\n    switch (c) {\n        case '(' :\n        case ')' :\n        case '<' :\n        case '>' :\n        case '@' :\n        case ',' :\n        case ';' :\n        case ':' :\n        case '\\\\' :\n        case '\"' :\n        case '/' :\n        case '[' :\n        case ']' :\n        case '?' :\n        case '=' :\n            return 0;\n    }\n\n    return 1;\n}\n\n\nint Multipart::boundary_characters_valid(const char *boundary) {\n    const unsigned char *p = (unsigned char *)boundary;\n    unsigned char c;\n\n    if (p == NULL) {\n        return -1;\n    }\n\n    while ((c = *p) != '\\0') {\n        // Check against allowed list defined in RFC2046 page 22\n        if (!(\n            ('0' <= c && c <= '9')\n            || ('A' <= c && c <= 'Z')\n            || ('a' <= c && c <= 'z')\n            || (c == ' ' && *(p + 1) != '\\0') // space allowed, but not as last character\n            || c == '\\''\n            || c == '('\n            || c == ')'\n            || c == '+'\n            || c == '_'\n            || c == ','\n            || c == '-'\n            || c == '.'\n            || c == '/'\n            || c == ':'\n            || c == '='\n            || c == '?'\n            )) {\n            return 0;\n        }\n        p++;\n    }\n\n    return 1;\n}\n\n\nvoid Multipart::validate_quotes(const char *data, char quote)  {\n    int len;\n\n    if (data == NULL)\n        return;\n\n    // if the value was enclosed in double quotes, then we don't care about\n    // a single quote character within the name.\n    if (quote == '\"') {\n        return;\n    }\n\n    len = strlen(data);\n\n    for (int i = 0;i < len;i++)   {\n        if (data[i] == '\\'') {\n            ms_dbg_a(m_transaction, 9,\n                \"Multipart: Invalid quoting detected: \" \\\n                + std::string(data) + \" length \" \\\n                + std::to_string(len) + \" bytes\");\n            m_flag_invalid_quoting = 1;\n        }\n    }\n}\n\n\nint Multipart::parse_content_disposition(const char *c_d_value, int offset) {\n    const char *p = NULL;\n    std::string filenameStar;\n\n    /* accept only what we understand */\n    if (strncmp(c_d_value, \"form-data\", 9) != 0) {\n        return -1;\n    }\n\n    /* see if there are any other parts to parse */\n\n    p = c_d_value + 9;\n    while ((*p == '\\t') || (*p == ' ')) p++;\n    if (*p == '\\0') {\n        return 1; /* this is OK */\n    }\n\n    if (*p != ';') {\n        return -2;\n    }\n    p++;\n\n    /* parse the appended parts */\n\n    while (*p != '\\0') {\n        const char *start = NULL;\n        std::string name;\n        std::string value;\n\n        /* go over the whitespace */\n        while ((*p == '\\t') || (*p == ' ')) {\n            p++;\n        }\n\n        if (*p == '\\0') {\n            return -3;\n        }\n\n        start = p;\n        while ((*p != '\\0') && (*p != '=') && (*p != '\\t') && (*p != ' ')) {\n            p++;\n        }\n\n        if (*p == '\\0') {\n            return -4;\n        }\n\n        name = std::string(start, (p - start));\n\n        while ((*p == '\\t') || (*p == ' ')) {\n            p++;\n        }\n\n        if (*p == '\\0') {\n            return -5;\n        }\n\n        if (*p != '=') {\n            return -13;\n        }\n\n        p++;\n\n        while ((*p == '\\t') || (*p == ' ')) {\n            p++;\n        }\n\n        if (*p == '\\0') {\n            return -6;\n        }\n\n        char quote = '\\0';\n        if (name == \"filename*\") {\n            /* filename*=charset'[optional-language]'filename */\n            /* Read beyond the charset and the optional language*/\n            const char* start_of_charset = p;\n            while ((*p != '\\0') && (isalnum(*p) || (strchr(mime_charset_special, *p)))) {\n                p++;\n            }\n            if ((*p != '\\'') || (p == start_of_charset)) {\n                return -16; // Must be at least one legit char before ' for start of language\n            }\n            p++;\n            while ((*p != '\\0') && (*p != '\\'')) {\n                p++;\n            }\n            if (*p != '\\'') {\n                return -17; // Single quote for end-of-language not found\n            }\n            p++;\n\n            /* Now read what should be the actual filename */\n            const char* start_of_filename = p;\n            while ((*p != '\\0') && (*p != ';')) {\n                if (*p == '%') {\n                    if ((*(p+1) == '\\0') || (!isxdigit(*(p+1))) || (!isxdigit(*(p+2)))) {\n                        return -18;\n                    }\n                    p += 3;\n                } else if (isalnum(*p) || strchr(attr_char_special, *p)) {\n                    p++;\n                } else {\n                    return -19;\n                }\n            }\n            value.assign(start_of_filename, p - start_of_filename);\n        } else if ((*p == '\"') || (*p == '\\'')) {\n            /* Accept both quotes as some backends will accept them, but\n             * technically \"'\" is invalid and so flag_invalid_quoting is\n             * set so the user can deal with it in the rules if they so wish.\n             */\n            quote = *p; // remember which quote character was used for the value\n\n            if (quote == '\\'') {\n                m_flag_invalid_quoting = 1;\n            }\n\n            p++;\n            if (*p == '\\0') {\n                return -7;\n            }\n\n            while (*p != '\\0') {\n                if (*p == '\\\\') {\n                    if (*(p + 1) == '\\0') {\n                        /* improper escaping */\n                        return -8;\n                    }\n                    /* only quote and \\ can be escaped */\n                    if ((*(p + 1) == quote) || (*(p + 1) == '\\\\')) {\n                        p++;\n                    } else {\n                        /* improper escaping */\n\n                        /* We allow for now because IE sends\n                         * improperly escaped content and there's\n                         * nothing we can do about it.\n                         *\n                         * return -9;\n                         */\n                    }\n                } else if (*p == quote) {\n                    break;\n                }\n\n                value.append((p++), 1);\n            }\n\n            p++; /* go over the quote at the end */\n\n        } else {\n            /* not quoted */\n\n            start = p;\n            while ((*p != '\\0') && (is_token_char(*p))) {\n                p++;\n            }\n            value.assign(start, p - start);\n        }\n\n        /* evaluate part */\n        if (name == \"name\") {\n            validate_quotes(value.c_str(), quote);\n\n            m_transaction->m_variableMultipartName.set(value, value,\n                offset + ((p - c_d_value) - value.size()));\n\n            if (!m_mpp->m_name.empty()) {\n                ms_dbg_a(m_transaction, 4,\n                    \"Multipart: Warning: Duplicate Content-Disposition \" \\\n                    \"name: \" + value + \". Previously: \" + m_mpp->m_name + \"\");\n                return -14;\n            }\n            m_mpp->m_name.assign(value);\n            m_mpp->m_nameOffset = offset + ((p - c_d_value) - value.size());\n            ms_dbg_a(m_transaction, 9,\n                \"Multipart: Content-Disposition name: \" + value + \".\");\n        } else if (name == \"filename\") {\n            validate_quotes(value.c_str(), quote);\n            m_transaction->m_variableMultipartFileName.set(value, value, \\\n                offset + ((p - c_d_value) - value.size()));\n\n            if (!m_mpp->m_filename.empty()) {\n                ms_dbg_a(m_transaction, 4,\n                    \"Multipart: Warning: Duplicate Content-Disposition \" \\\n                    \"filename: \" + value + \".\");\n                return -15;\n            }\n            m_mpp->m_filename.assign(value);\n            m_mpp->m_filenameOffset = offset + ((p - c_d_value) - value.size());\n\n            ms_dbg_a(m_transaction, 9,\n                \"Multipart: Content-Disposition filename: \" + value + \".\");\n        } else if (name == \"filename*\") {\n            if (!filenameStar.empty()) {\n                ms_dbg_a(m_transaction, 4,\n                    \"Multipart: Warning: Duplicate Content-Disposition \" \\\n                    \"filename*: \" + value + \".\");\n                return -20;\n            }\n            filenameStar.assign(value);\n            ms_dbg_a(m_transaction, 9,\n                \"Multipart: Content-Disposition filename*: \" + value + \".\");\n        } else {\n            return -11;\n        }\n\n        if (*p != '\\0') {\n            while ((*p == '\\t') || (*p == ' ')) {\n                p++;\n            }\n\n            /* the next character must be a zero or a semi-colon */\n            if (*p == '\\0') {\n                // Just let the 'while' condition end the loop\n            } else {\n                if (*p != ';') {\n                    p--;\n                    if (*p == '\\'' || *p == '\\\"') {\n                        ms_dbg_a(m_transaction, 9,\n                            \"Multipart: Invalid quoting detected: \" \\\n                            + std::string(p) + \" length \" \\\n                            + std::to_string(strlen(p)) + \" bytes\");\n                        m_flag_invalid_quoting = 1;\n                    }\n                    /* p++; */\n                    return -12;\n                }\n                p++; /* move over the semi-colon */\n            }\n        }\n\n        /* loop will stop when (*p == '\\0') */\n    }\n\n    if (!filenameStar.empty() && m_mpp->m_filename.empty()) {\n        ms_dbg_a(m_transaction, 4,\n            \"Multipart: Warning: no filename= but filename*:\" \\\n            + filenameStar + \".\");\n        return -21;\n    }\n\n    return 1;\n}\n\n\nint Multipart::process_part_data(std::string *error, size_t offset) {\n    char *p = m_buf + (MULTIPART_BUF_SIZE - m_bufleft);\n    char localreserve[2] = { '\\0', '\\0' }; /* initialized to quiet warning */\n    int bytes_reserved = 0;\n\n    m_mpp_substate_part_data_read = 1;\n\n    /* Preserve some bytes for later. */\n    if (((MULTIPART_BUF_SIZE - m_bufleft) >= 1) && (*(p - 1) == '\\n')) {\n        if (((MULTIPART_BUF_SIZE - m_bufleft) >= 2) && (*(p - 2) == '\\r')) {\n            /* Two bytes. */\n            bytes_reserved = 2;\n            localreserve[0] = *(p - 2);\n            localreserve[1] = *(p - 1);\n            m_bufleft += 2;\n            *(p - 2) = 0;\n        } else {\n            /* Only one byte. */\n            bytes_reserved = 1;\n            localreserve[0] = *(p - 1);\n            localreserve[1] = 0;\n            m_bufleft += 1;\n            *(p - 1) = 0;\n        }\n    }\n\n    /* add data to the part we are building */\n    if (m_mpp->m_type == MULTIPART_FILE) {\n        bool extract = m_transaction->m_rules->m_uploadKeepFiles \\\n            == RulesSetProperties::TrueConfigBoolean \\\n            || m_transaction->m_rules->m_tmpSaveUploadedFiles \\\n            == RulesSetProperties::TrueConfigBoolean;\n\n        /* remember where we started */\n        if (m_mpp->m_length == 0) {\n            m_mpp->m_offset = m_buf_offset;\n        }\n\n        /* check if the file limit has been reached */\n        if (extract && m_transaction->m_rules->m_uploadFileLimit.m_value\n            && (m_nfiles >=\n                m_transaction->m_rules->m_uploadFileLimit.m_value)) {\n            if (m_flag_file_limit_exceeded == 0) {\n                ms_dbg_a(m_transaction, 1,\n                    \"Multipart: Upload file limit exceeded \" \\\n                    + std::to_string(\n                        m_transaction->m_rules->m_uploadFileLimit.m_value) \\\n                    + \". Use SecUploadFileLimit to change the limit.\");\n               error->assign(\"Multipart: Upload file limit exceeded \" \\\n                + std::to_string(\n                    m_transaction->m_rules->m_uploadFileLimit.m_value) \\\n                + \". Use SecUploadFileLimit to change the limit.\");\n                m_flag_file_limit_exceeded = 1;\n            }\n            extract = 0;\n        }\n        /* only store individual files on disk if we are going\n         * to keep them or if we need to have them approved later\n         */\n        if (extract) {\n            /* first create a temporary file if we don't have it already */\n            if (!m_mpp->m_tmp_file || !m_mpp->m_tmp_file->isValid()) {\n                m_mpp->m_tmp_file = std::make_shared<RequestBodyProcessor::MultipartPartTmpFile>(m_transaction);\n                m_transaction->m_multipartPartTmpFiles.push_back(m_mpp->m_tmp_file);\n                m_mpp->m_tmp_file->Open();\n\n                /* do we have an opened file? */\n                if (m_mpp->m_tmp_file->getFd() < 0) {\n                    ms_dbg_a(m_transaction, 1,\n                        \"Multipart: Failed to create file: \" \\\n                        + m_mpp->m_tmp_file->getFilename());\n                    error->assign(\"Multipart: Failed to create file: \" \\\n                        + m_mpp->m_tmp_file->getFilename());\n                    return -1;\n                }\n                /* keep track of the files count */\n\n                m_nfiles++;\n\n                ms_dbg_a(m_transaction, 4,\n                    \"Multipart: Created temporary file \" \\\n                    + std::to_string(m_nfiles) + \" (mode o\" + std::to_string(m_transaction->m_rules->m_uploadFileMode.m_value) + \"): \" \\\n                    + m_mpp->m_tmp_file->getFilename());\n            }\n\n            /* write the reserve first */\n            if (m_reserve[0] != 0) {\n                if (write(m_mpp->m_tmp_file->getFd(), &m_reserve[1], m_reserve[0])\n                    != m_reserve[0]) {\n                    ms_dbg_a(m_transaction, 1,\n                        \"Multipart: writing to \\\"\" \\\n                        + m_mpp->m_tmp_file->getFilename() + \"\\\" failed\");\n                    error->assign(\"Multipart: writing to \\\"\" \\\n                        + m_mpp->m_tmp_file->getFilename() + \"\\\" failed\");\n                    return -1;\n                }\n\n                m_mpp->m_tmp_file_size.first += m_reserve[0];\n                if (m_mpp->m_tmp_file_size.second == 0) {\n                    m_mpp->m_tmp_file_size.second = offset \\\n                        - m_mpp->m_tmp_file_size.first;\n                }\n                m_mpp->m_length += m_reserve[0];\n            }\n\n            /* write data to the file */\n\n            if (write(m_mpp->m_tmp_file->getFd(), m_buf,\n                MULTIPART_BUF_SIZE - m_bufleft)\n                != (MULTIPART_BUF_SIZE - m_bufleft)) {\n                ms_dbg_a(m_transaction, 1,\n                    \"Multipart: writing to \\\"\" \\\n                    + m_mpp->m_tmp_file->getFilename() + \"\\\" failed\");\n                error->assign(\"Multipart: writing to \\\"\" \\\n                    + m_mpp->m_tmp_file->getFilename() + \"\\\" failed\");\n                return -1;\n            }\n\n            m_mpp->m_value.append(std::string(m_buf,\n                    MULTIPART_BUF_SIZE - m_bufleft));\n            m_mpp->m_valueOffset = offset - (MULTIPART_BUF_SIZE - m_bufleft);\n\n            m_mpp->m_tmp_file_size.first += (MULTIPART_BUF_SIZE - m_bufleft);\n            if (m_mpp->m_tmp_file_size.second == 0) {\n                m_mpp->m_tmp_file_size.second = offset \\\n                    - m_mpp->m_tmp_file_size.first;\n            }\n\n            m_mpp->m_length += (MULTIPART_BUF_SIZE - m_bufleft);\n        } else {\n            /* just keep track of the file size */\n            m_mpp->m_tmp_file_size.first += (MULTIPART_BUF_SIZE - m_bufleft) \\\n                + m_reserve[0];\n            if (m_mpp->m_tmp_file_size.second == 0) {\n                m_mpp->m_tmp_file_size.second = offset \\\n                    - m_mpp->m_tmp_file_size.first;\n            }\n\n            m_mpp->m_length += (MULTIPART_BUF_SIZE - m_bufleft) + m_reserve[0];\n        }\n    } else if (m_mpp->m_type == MULTIPART_FORMDATA) {\n        std::string d;\n\n        /* The buffer contains data so increase the data length counter. */\n        m_reqbody_no_files_length += (MULTIPART_BUF_SIZE - m_bufleft) \\\n            + m_reserve[0];\n\n        /* add this part to the list of parts */\n\n        /* remember where we started */\n        if (m_mpp->m_length == 0) {\n            m_mpp->m_offset = m_buf_offset;\n        }\n\n        if (m_reserve[0] != 0) {\n            d.assign(&(m_reserve[1]), m_reserve[0]);\n            d.assign(m_buf, MULTIPART_BUF_SIZE - m_bufleft);\n\n            m_mpp->m_length += d.size();\n        } else {\n            d.assign(m_buf, MULTIPART_BUF_SIZE - m_bufleft);\n            m_mpp->m_length += d.size();\n        }\n\n        m_mpp->m_value_parts.push_back(std::make_pair(d, m_buf_offset));\n\n        ms_dbg_a(m_transaction, 9,\n            \"Multipart: Added data to variable: \" + d);\n    } else {\n        ms_dbg_a(m_transaction, 1,\n            \"Multipart: unknown part type: \" \\\n            + std::to_string(m_mpp->m_type));\n\n        error->assign(\"Multipart: unknown part type: \" \\\n            + std::to_string(m_mpp->m_type));\n        return false;\n    }\n\n    /* store the reserved bytes to the multipart\n     * context so that they don't get lost\n     */\n    if (bytes_reserved) {\n        m_reserve[0] = bytes_reserved;\n        m_reserve[1] = localreserve[0];\n        m_reserve[2] = localreserve[1];\n        m_buf_offset += bytes_reserved;\n    } else {\n        m_buf_offset -= m_reserve[0];\n        m_reserve[0] = 0;\n    }\n\n    return true;\n}\n\n\nint Multipart::process_part_header(std::string *error, int offset) {\n    int i, len;\n\n    /* Check for nul bytes. */\n    len = MULTIPART_BUF_SIZE - m_bufleft;\n    int len_without_termination = len - 1;\n    for (i = 0; i < len; i++) {\n        if (m_buf[i] == '\\0') {\n            ms_dbg_a(m_transaction, 1,\n                \"Multipart: Nul byte in part headers.\");\n\n            error->assign(\"Multipart: Nul byte in part headers.\");\n            return false;\n        }\n    }\n\n    i = 0;\n    /* The buffer is data so increase the data length counter. */\n    m_reqbody_no_files_length += (MULTIPART_BUF_SIZE - m_bufleft);\n\n    if (len > 1) {\n        if (m_buf[len - 2] == '\\r') {\n            m_flag_crlf_line = 1;\n            len_without_termination--;\n        } else {\n            m_flag_lf_line = 1;\n        }\n    } else {\n        m_flag_lf_line = 1;\n    }\n\n    /* Is this an empty line? */\n    if (((m_buf[0] == '\\r') && (m_buf[1] == '\\n') && (m_buf[2] == '\\0'))\n        || ((m_buf[0] == '\\n') && (m_buf[1] == '\\0'))) { /* Empty line. */\n        std::string header_value(\"\");\n        int rc;\n\n        /* record the previous completed header */\n        if (!m_mpp->m_last_header_line.empty()) {\n            m_mpp->m_header_lines.push_back(std::make_pair(\n                offset-m_mpp->m_last_header_line.length(), m_mpp->m_last_header_line));\n            m_mpp->m_last_header_line.assign(\"\");\n        }\n\n        if (m_mpp->m_headers.count(\"Content-Disposition\") == 0) {\n            ms_dbg_a(m_transaction, 1,\n                \"Multipart: Part missing Content-Disposition header.\");\n\n            error->assign(\"Multipart: Part missing \" \\\n                \"Content-Disposition header.\");\n            return false;\n        }\n        header_value = m_mpp->m_headers.at(\"Content-Disposition\").second;\n\n        try {\n            rc = parse_content_disposition(header_value.c_str(),\n                m_mpp->m_headers.at(\"Content-Disposition\").first);\n        } catch (...) {\n            ms_dbg_a(m_transaction, 1,\n                \"Multipart: Unexpected error parsing Content-Disposition header.\");\n            rc = -99;\n        }\n        if (rc < 0) {\n            ms_dbg_a(m_transaction, 1,\n                \"Multipart: Invalid Content-Disposition header (\"\n                + std::to_string(rc) + \"): \" + header_value);\n\n            error->assign(\"Multipart: Invalid Content-Disposition header (\"\n                + std::to_string(rc) + \"): \" + header_value);\n            return false;\n        }\n\n        if (m_mpp->m_name.empty()) {\n            ms_dbg_a(m_transaction, 1,\n                \"Multipart: Content-Disposition header missing \" \\\n                \"name field.\");\n\n            error->assign(\"Multipart: Content-Disposition header missing \" \\\n                \"name field.\");\n\n            return false;\n        }\n\n        if (!m_mpp->m_filename.empty()) {\n            /* Some parsers use crude methods to extract the name and filename\n             * values from the C-D header. We need to check for the case where they\n             * didn't understand C-D but we did.\n             */\n            if (strstr(header_value.c_str(), \"filename=\") == NULL) {\n                ms_dbg_a(m_transaction, 1,\n                    \"Multipart: Invalid Content-Disposition \" \\\n                    \"header (filename).\");\n\n                error->assign(\"Multipart: Invalid Content-Disposition \" \\\n                    \"header (filename).\");\n                return false;\n            }\n\n            m_mpp->m_type = MULTIPART_FILE;\n        } else {\n            m_mpp->m_type = MULTIPART_FORMDATA;\n        }\n\n        m_mpp_state = 1;\n        m_mpp_substate_part_data_read = 0;\n        m_mpp->m_last_header_name.assign(\"\");\n    } else {  /* Header line. */\n        if (isspace(m_buf[0])) {\n            std::string header_value;\n            char *data;\n            std::string new_value;\n\n            /* header folding, add data to the header we are building */\n            m_flag_header_folding = 1;\n\n            /* RFC-2557 states header folding is SP / HTAB, but PHP and\n             * perhaps others will take any whitespace.  So, we accept,\n             * but with a flag set.\n             */\n            if ((m_buf[0] != '\\t') && (m_buf[0] != ' ')) {\n                m_flag_invalid_header_folding = 1;\n            }\n\n            if (m_mpp->m_last_header_name.empty()) {\n                /* we are not building a header at this moment */\n                ms_dbg_a(m_transaction, 1,\n                    \"Multipart: Invalid part header (folding error).\");\n\n                error->assign(\"Multipart: Invalid part header \" \\\n                    \"(folding error).\");\n                return false;\n            }\n\n            /* locate the beginning of data */\n            data = m_buf;\n            while (isspace(*data)) {\n                /* Flag invalid header folding if an invalid RFC-2557\n                 * character is used anywhere in the folding prefix.\n                 */\n                if ((*data != '\\t') && (*data != ' ')) {\n                    m_flag_invalid_header_folding = 1;\n                }\n                data++;\n                i++;\n            }\n\n            new_value = std::string(data);\n            utils::string::chomp(new_value);\n\n            /* update the header value in the table */\n            header_value = m_mpp->m_headers.at(\n                m_mpp->m_last_header_name).second;\n            new_value = header_value + \" \" +  new_value;\n            m_mpp->m_headers.at(m_mpp->m_last_header_name).second = new_value;\n\n            ms_dbg_a(m_transaction, 9,\n                \"Multipart: Continued folder header \\\"\" \\\n                + m_mpp->m_last_header_name + \"\\\" with \\\"\" \\\n                + std::string(data) + \"\\\"\");\n\n            if (new_value.size() > MULTIPART_BUF_SIZE) {\n                ms_dbg_a(m_transaction, 1, \"Multipart: Part header too long.\");\n\n                error->assign(\"Multipart: Part header too long.\");\n                return false;\n            }\n\n            m_mpp->m_last_header_line = m_mpp->m_last_header_name + \": \" + new_value;\n        } else {\n            char *data;\n            std::string header_value;\n            std::string header_name;\n            /* new header */\n\n            /* record the previous completed header */\n            if (!m_mpp->m_last_header_line.empty()) {\n                m_mpp->m_header_lines.push_back(std::make_pair(\n                    offset-m_mpp->m_last_header_line.length(), m_mpp->m_last_header_line));\n                m_mpp->m_last_header_line.assign(\"\");\n            }\n\n            data = m_buf;\n            while ((*data != ':') && (*data != '\\0')) {\n                data++;\n                i++;\n            }\n            if (*data == '\\0') {\n                ms_dbg_a(m_transaction, 1,\n                    \"Multipart: Invalid part header (colon missing): \" \\\n                    + std::string(m_buf));\n\n                error->assign(\"Multipart: Invalid part header \" \\\n                    \"(colon missing): \" + std::string(m_buf));\n                return false;\n            }\n\n            /* extract header name */\n            header_name = std::string(m_buf, data - m_buf);\n            if (data == m_buf) {\n                ms_dbg_a(m_transaction, 1,\n                    \"Multipart: Invalid part header \" \\\n                    \"(header name missing).\");\n\n                error->assign(\"Multipart: Invalid part header \" \\\n                    \"(header name missing).\");\n                 return false;\n            }\n\n            /* check if multipart header contains any invalid characters */\n            for (const auto& ch : header_name) {\n                if (ch < 33 || ch > 126) {\n                    ms_dbg_a(m_transaction, 1,\n                        \"Multipart: Invalid part header \" \\\n                        \"(contains invalid character).\");\n                    error->assign(\"Multipart: Invalid part header \"\\\n                        \"(contains invalid character).\");\n                    return false;\n                }\n            }\n\n            /* extract the value value */\n            data++;\n            i++;\n            while ((*data == '\\t') || (*data == ' ')) {\n                data++;\n                i++;\n            }\n            header_value = std::string(data);\n            utils::string::chomp(header_value);\n\n            /* error if the name already exists */\n            if (m_mpp->m_headers.count(header_name) > 0) {\n                ms_dbg_a(m_transaction, 1,\n                    \"Multipart: Duplicate part header: \" \\\n                    + header_name + \".\");\n\n                return false;\n            }\n\n            m_mpp->m_last_header_name.assign(header_name);\n\n\n            m_mpp->m_headers.emplace(\n                std::string(header_name), std::make_pair(offset - len + i,\n                    std::string(header_value)));\n\n            ms_dbg_a(m_transaction, 9,\n                \"Multipart: Added part header \\\"\" + header_name \\\n                + \"\\\" \\\"\" + header_value + \"\\\".\");\n            if (len_without_termination > 0) {\n                m_mpp->m_last_header_line.assign(m_buf, len_without_termination);\n            } else {\n                m_mpp->m_last_header_line.assign(\"\");\n            }\n        }\n    }\n\n    return true;\n}\n\n\nint Multipart::process_boundary(int last_part) {\n    /* if there was a part being built finish it */\n    if (m_mpp != NULL) {\n        /* record all the part header lines from the part into the transaction collection */\n        for (const auto& header_line : m_mpp->m_header_lines) {\n            m_transaction->m_variableMultipartPartHeaders.set(m_mpp->m_name,\n                header_line.second, header_line.first);\n            ms_dbg_a(m_transaction, 9, \"Multipart: Added part header line:\" + header_line.second );\n        }\n\n        /* close the temp file */\n        if ((m_mpp->m_type == MULTIPART_FILE) && (m_mpp->m_tmp_file)\n            && (m_mpp->m_tmp_file->isValid())) {\n            m_mpp->m_tmp_file->Close();\n        }\n\n        if (m_mpp->m_type != MULTIPART_FILE) {\n            /* now construct a single string out of the parts */\n            for (const auto &i : m_mpp->m_value_parts) {\n                if (m_mpp->m_valueOffset == 0) {\n                    m_mpp->m_valueOffset = i.second;\n                }\n                m_mpp->m_value.append(i.first);\n            }\n        }\n\n        if (m_mpp->m_name.empty() == false) {\n            /* add the part to the list of parts */\n            m_parts.push_back(m_mpp);\n\n            if (m_mpp->m_type == MULTIPART_FILE) {\n                ms_dbg_a(m_transaction, 9,\n                    \"Multipart: Added file part to the list: name \\\"\" \\\n                    + m_mpp->m_name + \"\\\" \"\n                    \"file name \\\"\" + m_mpp->m_filename + \"\\\" (offset \" \\\n                    + std::to_string(m_mpp->m_offset) +\n                    \", length \" + std::to_string(m_mpp->m_length) + \")\");\n            } else {\n                ms_dbg_a(m_transaction, 9,\n                    \"Multipart: Added part to the list: name \\\"\" \\\n                    + m_mpp->m_name + \"\\\" \"\n                    \"(offset \" + std::to_string(m_mpp->m_offset) \\\n                    + \", length \" + std::to_string(m_mpp->m_length) + \")\");\n            }\n        } else {\n            m_flag_invalid_part = true;\n            ms_dbg_a(m_transaction, 3,\n                \"Multipart: Skipping invalid part (part name missing): \"\n                \"(offset \" + std::to_string(m_mpp->m_offset) + \", length \"\n                + std::to_string(m_mpp->m_length) + \")\");\n\n            delete m_mpp;\n        }\n\n        m_mpp = NULL;\n    }\n\n    if (last_part == 0) {\n        /* start building a new part */\n        m_mpp = new MultipartPart();\n\n        m_mpp_state = 0;\n        m_mpp_substate_part_data_read = 0;\n\n        m_reserve[0] = 0;\n        m_reserve[1] = 0;\n        m_reserve[2] = 0;\n        m_reserve[3] = 0;\n    }\n\n    return 1;\n}\n\n\n/**\n * Finalize multipart processing. This method is invoked at the end, when it\n * is clear that there is no more data to be processed.\n */\nint Multipart::multipart_complete(std::string *error) {\n    m_transaction->m_variableMultipartUnmatchedBoundary.set(\n        std::to_string(m_flag_unmatched_boundary),\n        m_transaction->m_variableOffset);\n\n    m_transaction->m_variableMultipartDataBefore.set(\n        std::to_string(m_flag_data_before),\n        m_transaction->m_variableOffset);\n    if (m_flag_data_before) {\n        ms_dbg_a(m_transaction, 4,\n            \"Multipart: Warning: seen data before first boundary.\");\n    }\n\n    m_transaction->m_variableMultipartDataAfter.set(\n        std::to_string(m_flag_data_after),\n        m_transaction->m_variableOffset);\n    if (m_flag_data_after) {\n        ms_dbg_a(m_transaction, 4,\n            \"Multipart: Warning: seen data after last boundary.\");\n    }\n\n    m_transaction->m_variableMultipartBoundaryQuoted.set(\n        std::to_string(m_flag_boundary_quoted),\n        m_transaction->m_variableOffset);\n    if (m_flag_boundary_quoted) {\n        ms_dbg_a(m_transaction, 4,\n            \"Multipart: Warning: boundary was quoted.\");\n    }\n\n    m_transaction->m_variableMultipartBoundaryWhiteSpace.set(\n        std::to_string(m_flag_boundary_whitespace),\n        m_transaction->m_variableOffset);\n    if (m_flag_boundary_whitespace) {\n        ms_dbg_a(m_transaction, 4,\n            \"Multipart: Warning: boundary whitespace in C-T header.\");\n    }\n\n    m_transaction->m_variableMultipartHeaderFolding.set(\n        std::to_string(m_flag_header_folding),\n        m_transaction->m_variableOffset);\n    if (m_flag_header_folding) {\n        ms_dbg_a(m_transaction, 4,\n            \"Multipart: Warning: header folding used.\");\n    }\n    m_transaction->m_variableMultipartLFLine.set(\n        std::to_string(m_flag_lf_line),\n        m_transaction->m_variableOffset);\n    m_transaction->m_variableMultipartCrlfLFLines.set(\n        std::to_string(m_flag_crlf_line && m_flag_lf_line),\n        m_transaction->m_variableOffset);\n    if (m_flag_crlf_line && m_flag_lf_line) {\n        ms_dbg_a(m_transaction, 4,\n            \"Multipart: Warning: mixed line endings used (CRLF/LF).\");\n    } else if (m_flag_lf_line) {\n        ms_dbg_a(m_transaction, 4,\n            \"Multipart: Warning: incorrect line endings used (LF).\");\n    }\n    m_transaction->m_variableMultipartMissingSemicolon.set(\n        std::to_string(m_flag_missing_semicolon),\n        m_transaction->m_variableOffset);\n    if (m_flag_missing_semicolon) {\n        ms_dbg_a(m_transaction, 4,\n            \"Multipart: Warning: missing semicolon in C-T header.\");\n    }\n\n    m_transaction->m_variableMultipartInvalidQuoting.set(\n        std::to_string(m_flag_invalid_quoting),\n        m_transaction->m_variableOffset);\n    if (m_flag_invalid_quoting) {\n        ms_dbg_a(m_transaction, 4,\n            \"Multipart: Warning: invalid quoting used.\");\n    }\n    m_transaction->m_variableMultipartInvalidPart.set(\n        std::to_string(m_flag_invalid_part),\n        m_transaction->m_variableOffset);\n    if (m_flag_invalid_part) {\n        ms_dbg_a(m_transaction, 4,\n            \"Multipart: Warning: invalid part parsing.\");\n    }\n\n    m_transaction->m_variableMultipartInvalidHeaderFolding.set(\n        std::to_string(m_flag_invalid_header_folding),\n        m_transaction->m_variableOffset);\n    if (m_flag_invalid_header_folding) {\n        ms_dbg_a(m_transaction, 4,\n            \"Multipart: Warning: invalid header folding used.\");\n    }\n\n    m_transaction->m_variableMultipartStrictError.set(\n        std::to_string(m_flag_error || m_flag_boundary_quoted != 0\n        || m_flag_boundary_whitespace != 0 || m_flag_data_before != 0\n        || m_flag_data_after != 0 || m_flag_header_folding != 0\n        || m_flag_lf_line != 0 || m_flag_missing_semicolon != 0\n        || m_flag_invalid_quoting != 0 || m_flag_invalid_part != 0\n        || m_flag_invalid_header_folding != 0\n        || m_flag_file_limit_exceeded != 0), m_transaction->m_variableOffset);\n\n\n    if ((m_seen_data != 0) && (m_is_complete == 0)) {\n        if (m_boundary_count > 0) {\n            /* Check if we have the final boundary (that we haven't\n             * processed yet) in the buffer.\n             */\n            if (m_buf_contains_line) {\n                if (((unsigned int)(MULTIPART_BUF_SIZE - m_bufleft)\n                        == (4 + m_boundary.size()))\n                    && (*(m_buf) == '-')\n                    && (*(m_buf + 1) == '-')\n                    && (strncmp(m_buf + 2, m_boundary.c_str(),\n                        m_boundary.size()) == 0)\n                    && (*(m_buf + 2 + m_boundary.size()) == '-')\n                    && (*(m_buf + 2 + m_boundary.size() + 1) == '-')) {\n                    // these next two checks may result in repeating work from earlier in this fn\n                    // ignore the duplication for now to minimize refactoring\n                    if ((m_crlf_state_buf_end == 2) && (m_flag_lf_line != 1)) {\n                        m_flag_lf_line = 1;\n                        m_transaction->m_variableMultipartLFLine.set(std::to_string(m_flag_lf_line),\n                            m_transaction->m_variableOffset);\n                        m_transaction->m_variableMultipartCrlfLFLines.set(std::to_string(m_flag_crlf_line && m_flag_lf_line),\n                            m_transaction->m_variableOffset);\n                        if (m_flag_crlf_line && m_flag_lf_line) {\n                            ms_dbg_a(m_transaction, 4, \"Multipart: Warning: mixed line endings used (CRLF/LF).\");\n                        } else if (m_flag_lf_line) {\n                            ms_dbg_a(m_transaction, 4, \"Multipart: Warning: incorrect line endings used (LF).\");\n                        }\n                        m_transaction->m_variableMultipartStrictError.set(\n                            std::to_string(m_flag_lf_line) , m_transaction->m_variableOffset);\n\t\t    }\n                    if ((m_mpp_substate_part_data_read == 0) && (m_flag_invalid_part != 1)) {\n                        // it looks like the final boundary, but it's where part data should begin\n                        m_flag_invalid_part = 1;\n                        ms_dbg_a(m_transaction, 3, \"Multipart: Invalid part (data contains final boundary)\");\n                        m_transaction->m_variableMultipartStrictError.set(\n                            std::to_string(m_flag_invalid_part) , m_transaction->m_variableOffset);\n                        m_transaction->m_variableMultipartInvalidPart.set(std::to_string(m_flag_invalid_part),\n                            m_transaction->m_variableOffset);\n                        ms_dbg_a(m_transaction, 4, \"Multipart: Warning: invalid part parsing.\");\n                    }\n\n                    /* Looks like the final boundary - process it. */\n                    if (process_boundary(1 /* final */) < 0) {\n                        m_flag_error = 1;\n                        return -1;\n                    }\n\n                    /* The payload is complete after all. */\n                    m_is_complete = 1;\n                }\n            }\n\n            if (m_is_complete == 0) {\n                ms_dbg_a(m_transaction, 1,\n                    \"Multipart: Final boundary missing.\");\n                error->assign(\"Multipart: Final boundary missing.\");\n                return false;\n            }\n        } else {\n            ms_dbg_a(m_transaction, 1,\n                \"Multipart: No boundaries found in payload.\");\n            error->assign(\"Multipart: No boundaries found in payload.\");\n            return false;\n        }\n    }\n\n    int file_combined_size = 0;\n    for (MultipartPart *m : m_parts) {\n        // FIXME: duplicate code, see transaction.\n        //        we need a helper function for this.\n        if (m->m_name.empty()) {\n            continue;\n        }\n        size_t offset = m_transaction->m_variableOffset + 1;\n\n        if (m->m_type == MULTIPART_FILE) {\n            if (m->m_tmp_file && !m->m_tmp_file->getFilename().empty()) {\n                m_transaction->m_variableFilesTmpNames.set(m->m_tmp_file->getFilename(),\n                    m->m_tmp_file->getFilename(), m->m_filenameOffset);\n            }\n\n            m_transaction->m_variableFiles.set(m->m_name,\n                m->m_filename, m->m_filenameOffset);\n\n            m_transaction->m_variableFilesNames.set(m->m_name,\n                m->m_name, m->m_nameOffset);\n\n            m_transaction->m_variableFilesSizes.set(m->m_name,\n                std::to_string(m->m_tmp_file_size.first),\n                m->m_tmp_file_size.second,\n                m->m_tmp_file_size.first);\n\n            m_transaction->m_variableFilesTmpContent.set(m->m_name,\n               m->m_value, m->m_valueOffset);\n\n            file_combined_size = file_combined_size + m->m_tmp_file_size.first;\n\n            m_transaction->m_variableFilesCombinedSize.set(\n               std::to_string(file_combined_size),\n               m->m_tmp_file_size.second, m->m_tmp_file_size.first);\n        } else {\n            ms_dbg_a(m_transaction, 4,\n                \"Adding request argument (BODY): name \\\"\" +\n                m->m_name + \"\\\", value \\\"\" + m->m_value + \"\\\"\");\n            m_transaction->m_variableArgs.set(m->m_name, m->m_value,\n                offset + m->m_valueOffset);\n            m_transaction->m_variableArgsPost.set(m->m_name, m->m_value,\n               offset + m->m_valueOffset);\n        }\n#if 0\n        if (m_transaction->m_namesArgs->empty()) {\n            m_transaction->m_namesArgs->assign(key);\n        } else {\n            m_transaction->m_namesArgs->assign(*m_namesArgs + \" \" + key);\n        }\n        if (m_transaction->m_namesArgsPost->empty()) {\n            m_transaction->m_namesArgsPost->assign(key);\n        } else {\n            m_transaction->m_namesArgsPost->assign(\n                *m_namesArgsPost + \" \" + key);\n        }\n\n        m_transaction->m_ARGScombinedSize = \\\n            m_transaction->m_ARGScombinedSize + \\\n            m->m_name.length() + m->m_value.length();\n        m_transaction->m_ARGScombinedSizeStr->assign(\n            std::to_string(m_transaction->->m_ARGScombinedSize));\n#endif\n    }\n\n\n    return true;\n}\n\n\nint Multipart::count_boundary_params(const std::string& str_header_value) {\n    int count = 0;\n\n    const auto lower = utils::string::tolower(str_header_value);\n    const char *s = lower.c_str();\n    while ((s = strstr(s, \"boundary\")) != NULL) {\n        s += 8;\n\n        if (strchr(s, '=') != NULL) {\n            count++;\n        }\n    }\n\n    return count;\n}\n\n\nbool Multipart::init(std::string *error) {\n    m_bufleft = MULTIPART_BUF_SIZE;\n    m_bufptr = m_buf;\n    m_buf_contains_line = true;\n    m_mpp = NULL;\n    const char *m_boundary_tmp = NULL;\n\n    if (m_header.empty()) {\n        m_flag_error = true;\n        ms_dbg_a(m_transaction, 4,\n            \"Multipart: Content-Type header not available.\");\n        error->assign(\"Multipart: Content-Type header not available.\");\n        return false;\n    }\n\n    if (m_header.size() > 1024) {\n        m_flag_error = 1;\n        ms_dbg_a(m_transaction, 4,\n            \"Multipart: Invalid boundary in C-T (length).\");\n        error->assign(\"Multipart: Invalid boundary in C-T (length).\");\n        return false;\n    }\n\n    if (strncasecmp(m_header.c_str(), \"multipart/form-data\", 19) != 0) {\n        m_flag_error = 1;\n        ms_dbg_a(m_transaction, 4, \"Multipart: Invalid MIME type.\");\n        error->assign(\"Multipart: Invalid MIME type.\");\n        return false;\n    }\n\n    /* Count how many times the word \"boundary\" appears in the C-T header. */\n    if (count_boundary_params(m_header) > 1) {\n        m_flag_error = 1;\n        ms_dbg_a(m_transaction, 4,\n            \"Multipart: Multiple boundary parameters in C-T.\");\n        error->assign(\"Multipart: Multiple boundary parameters in C-T.\");\n        return false;\n    }\n\n    m_boundary_tmp = strstr(m_header.c_str(), \"boundary\");\n    if (m_boundary_tmp) {\n        m_boundary = std::string(m_boundary_tmp);\n        const char *p = NULL;\n        const char *b = NULL;\n        int seen_semicolon = 0;\n        int len = 0;\n\n        /* Check for extra characters before the boundary. */\n        for (p = m_header.c_str() + 19;\n            p < m_boundary_tmp; p++) {\n            if (!isspace(*p)) {\n                if ((seen_semicolon == 0) && (*p == ';')) {\n                    seen_semicolon = 1; /* It is OK to have one semicolon. */\n                } else {\n                    m_flag_error = 1;\n                    ms_dbg_a(m_transaction, 4,\n                        \"Multipart: Invalid boundary in C-T \" \\\n                        \"(malformed).\");\n                    error->assign(\"Multipart: Invalid boundary in C-T \" \\\n                        \"(malformed).\");\n                    return false;\n                }\n            }\n        }\n\n        /* Have we seen the semicolon in the header? */\n        if (seen_semicolon == 0) {\n            m_flag_missing_semicolon = 1;\n        }\n\n        b = strchr(m_boundary_tmp + 8, '=');\n        if (b == NULL) {\n            m_flag_error = 1;\n            ms_dbg_a(m_transaction, 4,\n                \"Multipart: Invalid boundary in C-T (malformed).\");\n            error->assign(\"Multipart: Invalid boundary in C-T (malformed).\");\n            return false;\n        }\n\n        /* Check parameter name ends well. */\n        if (b != (m_boundary.c_str() + 8)) {\n            /* Check all characters between the end of the boundary\n             * and the = character.\n             */\n            for (p = m_boundary_tmp + 8; p < b; p++) {\n                if (isspace(*p)) {\n                    /* Flag for whitespace after parameter name. */\n                    m_flag_boundary_whitespace = 1;\n                } else {\n                    m_flag_error = 1;\n                    ms_dbg_a(m_transaction, 4,\n                        \"Multipart: Invalid boundary in C-T \" \\\n                        \"(parameter name).\");\n                    error->assign(\"Multipart: Invalid boundary in C-T \" \\\n                        \"(parameter name).\");\n                    return false;\n                }\n            }\n        }\n\n        b++; /* Go over the = character. */\n        len = strlen(b);\n\n        /* Flag for whitespace before parameter value. */\n        if (isspace(*b)) {\n            m_flag_boundary_whitespace = 1;\n        }\n\n        /* Is the boundary quoted? */\n        if ((len >= 2) && (*b == '\"') && (*(b + len - 1) == '\"')) {\n            /* Quoted. */\n            m_boundary.assign(std::string(b + 1, len - 2));\n            if (m_boundary.empty()) {\n                return false;\n            }\n            m_flag_boundary_quoted = 1;\n        } else {\n            /* Not quoted. */\n\n            /* Test for partial quoting. */\n            if ((*b == '\"')\n                || ((len >= 2) && (*(b + len - 1) == '\"'))) {\n                m_flag_error = 1;\n                ms_dbg_a(m_transaction, 4,\n                    \"Multipart: Invalid boundary in C-T (quote).\");\n                error->assign(\"Multipart: Invalid boundary in C-T (quote).\");\n                return false;\n            }\n\n            m_boundary.assign(b);\n            if (m_boundary.empty()) {\n                return false;\n            }\n\n            m_flag_boundary_quoted = 0;\n        }\n\n        /* Case-insensitive test for the string \"boundary\" in the boundary. */\n        if (count_boundary_params(m_boundary) != 0) {\n            m_flag_error = 1;\n            ms_dbg_a(m_transaction, 4,\n                \"Multipart: Invalid boundary in C-T (content).\");\n            error->assign(\"Multipart: Invalid boundary in C-T (content).\");\n            return false;\n        }\n\n        /* Some frameworks are known to incorrectly include a charset= parameter */\n        /* after the boundary. Doing so is not RFC-compliant, but we will tolerate it.*/\n        if (boundary_characters_valid(m_boundary.c_str()) != 1) {\n            size_t semicolon_after_boundary = m_boundary.find(';');\n            if (semicolon_after_boundary != std::string::npos) {\n                ms_dbg_a(m_transaction, 3,\n                    \"Multipart: Invalid parameter after boundary in C-T (tolerated).\");\n                m_boundary = m_boundary.substr(0, semicolon_after_boundary);\n            }\n        }\n        /* Validate the characters used in the boundary. */\n        if (boundary_characters_valid(m_boundary.c_str()) != 1) {\n            m_flag_error = 1;\n            ms_dbg_a(m_transaction, 4,\n                \"Multipart: Invalid boundary in C-T (characters).\");\n            error->assign(\"Multipart: Invalid boundary in C-T (characters).\");\n            return false;\n        }\n\n        ms_dbg_a(m_transaction, 9, \"Multipart: Boundary\" +\n            (m_flag_boundary_quoted ?\n                std::string(\" (quoted)\") : std::string(\"\")) +\n            std::string(\": \") + m_boundary);\n\n        if (m_boundary.size() == 0) {\n            m_flag_error = 1;\n            ms_dbg_a(m_transaction, 4,\n                \"Multipart: Invalid boundary in C-T (empty).\");\n            error->assign(\"Multipart: Invalid boundary in C-T (empty).\");\n            return false;\n        }\n    } else { /* Could not find boundary in the C-T header. */\n        m_flag_error = 1;\n\n        /* Test for case-insensitive boundary. Allowed by the RFC but\n         * highly unusual. */\n        if (count_boundary_params(m_header) > 0) {\n            ms_dbg_a(m_transaction, 4,\n                \"Multipart: Invalid boundary in C-T (case sensitivity).\");\n            error->assign(\"Multipart: Invalid boundary in C-T \" \\\n                \"(case sensitivity).\");\n            return false;\n        }\n\n        ms_dbg_a(m_transaction, 4, \"Multipart: Boundary not found in C-T.\");\n        error->assign(\"Multipart: Boundary not found in C-T.\");\n        return false;\n    }\n\n    return 1;\n}\n\n\n/*\n * Assuming that all data is on data. We are not processing chunks.\n *\n */\nbool Multipart::process(const std::string& data, std::string *error,\n    int offset) {\n    const char *inptr = data.c_str();\n    unsigned int inleft = data.size();\n    size_t z = 0;\n\n    if (data.size() == 0) return true;\n    m_seen_data = true;\n\n    if (m_is_complete) {\n        m_flag_data_before = true;\n\n        ms_dbg_a(m_transaction, 4,\n            \"Multipart: Ignoring data after last boundary (received \" \\\n            + std::to_string(data.size()) + \" bytes)\");\n\n        return true;\n    }\n\n    if (m_bufleft == 0) {\n        m_flag_error = 1;\n        ms_dbg_a(m_transaction, 4,\n            \"Multipart: Internal error in process_chunk: no space left \" \\\n            \"in the buffer\");\n        return false;\n    }\n\n    /* here we loop through the available data, one byte at a time */\n    while (inleft > 0) {\n        char c = *inptr;\n        int process_buffer = 0;\n\n        z++;\n\n        if ((c == '\\r') && (m_bufleft == 1)) {\n            /* we don't want to take \\r as the last byte in the buffer */\n            process_buffer = 1;\n        } else {\n            inptr++;\n            inleft = inleft - 1;\n\n            *(m_bufptr) = c;\n            m_bufptr++;\n            m_bufleft--;\n        }\n\n        /* until we either reach the end of the line\n         * or the end of our internal buffer\n         */\n        if ((c == '\\n') || (m_bufleft == 0) || (process_buffer)) {\n            int processed_as_boundary = 0;\n\n            *(m_bufptr) = 0;\n\n            /* Do we have something that looks like a boundary? */\n            if (m_buf_contains_line && (strlen(m_buf) > 3) && (*(m_buf) == '-')\n                && (*(m_buf + 1) == '-')) {\n                /* Does it match our boundary? */\n                if ((strlen(m_buf) >= m_boundary.size() + 2)\n                    && (strncmp(m_buf + 2, m_boundary.c_str(),\n                        m_boundary.size()) == 0)) {\n                    if (m_crlf_state_buf_end == 2) {\n                        m_flag_lf_line = 1;\n\t\t    }\n                    if ((m_mpp_substate_part_data_read == 0) && (m_boundary_count > 0)) {\n                        /* string matches our boundary, but it's where part data should begin */\n                        m_flag_invalid_part = 1;\n                        ms_dbg_a(m_transaction, 3, \"Multipart: Invalid part (data contains boundary)\");\n\n                    } else {\n                        char *boundary_end = m_buf + 2 + m_boundary.size();\n                        /* if it match, AND there was a matched boundary at least,\n                           set the m_flag_unmatched_boundary flag to 2\n                           this indicates that there were an opened boundary, which\n                           matches the reference, and here is the final boundary.\n                           The flag will differ from 0, so the previous rules (\"!@eq 0\")\n                           will catch all \"errors\", without any modification, but we can\n                           use the new, permission mode with \"@eq 1\"\n                        */\n                        if (m_boundary_count > 0) {\n                            m_flag_unmatched_boundary = 2;\n                        }\n                        int is_final = 0;\n\n                        /* Is this the final boundary? */\n                        if ((*boundary_end == '-')\n                            && (*(boundary_end + 1)== '-')) {\n                            is_final = 1;\n                            boundary_end += 2;\n\n                            if (m_is_complete != 0) {\n                                m_flag_error = 1;\n                                ms_dbg_a(m_transaction, 4,\n                                    \"Multipart: Invalid boundary \" \\\n                                    \"(final duplicate).\");\n\n                                error->assign(\"Multipart: Invalid boundary \" \\\n                                    \"(final duplicate).\");\n                                return false;\n                            }\n                        }\n\n                        /* Allow for CRLF and LF line endings. */\n                        if (((*boundary_end == '\\r')\n                            && (*(boundary_end + 1) == '\\n')\n                            && (*(boundary_end + 2) == '\\0'))\n                            || ((*boundary_end == '\\n')\n                            && (*(boundary_end + 1) == '\\0'))) {\n                            if (*boundary_end == '\\n') {\n                                m_flag_lf_line = 1;\n                            } else {\n                                m_flag_crlf_line = 1;\n                            }\n\n                            if (process_boundary((is_final ? 1 : 0)) < 0) {\n                                m_flag_error = true;\n                                return false;\n                            }\n\n                            if (is_final) {\n                                m_is_complete = 1;\n                            }\n\n                            processed_as_boundary = 1;\n                            m_boundary_count++;\n                        } else {\n                            /* error */\n                            m_flag_error = 1;\n                            ms_dbg_a(m_transaction, 4,\n                                \"Multipart: Invalid boundary: \" \\\n                                + std::string(m_buf));\n                            error->assign(\"Multipart: Invalid boundary: \" \\\n                                + std::string(m_buf));\n                            return false;\n                        }\n                    }\n                } else { /* It looks like a boundary but */\n                         /* we couldn't match it. */\n                    const char *p = NULL;\n\n                    /* Check if an attempt to use quotes around the\n                     * boundary was made. */\n                    if ((m_flag_boundary_quoted)\n                        && (strlen(m_buf) >= m_boundary.size() + 3)\n                        && (*(m_buf + 2) == '\"')\n                        && (strncmp(m_buf + 3, m_boundary.c_str(),\n                            m_boundary.size()) == 0)) {\n                        m_flag_error = 1;\n                        ms_dbg_a(m_transaction, 4,\n                            \"Multipart: Invalid boundary (quotes).\");\n                        error->assign(\"Multipart: Invalid boundary (quotes).\");\n                        return false;\n                    }\n\n                    /* Check the beginning of the boundary for whitespace. */\n                    p = m_buf + 2;\n                    while (isspace(*p)) {\n                        p++;\n                    }\n\n                    if ((p != m_buf + 2)\n                        && (strncmp(p, m_boundary.c_str(),\n                            m_boundary.size()) == 0)) {\n                        /* Found whitespace in front of a boundary. */\n                        m_flag_error = 1;\n                        ms_dbg_a(m_transaction, 4,\n                            \"Multipart: Invalid boundary (whitespace).\");\n                        error->assign(\"Multipart: Invalid boundary \" \\\n                            \"(whitespace).\");\n                        return false;\n                    }\n\n                    m_flag_unmatched_boundary = 1;\n                }\n            } else { /* We do not think the buffer contains a boundary. */\n                /* Look into the buffer to see if there's anything\n                 * there that resembles a boundary.\n                 */\n                if (m_buf_contains_line) {\n                    int i, len = (MULTIPART_BUF_SIZE - m_bufleft);\n                    char *p = m_buf;\n\n                    for (i = 0; i < len; i++) {\n                        if ((p[i] == '-') && (i + 1 < len)\n                            && (p[i + 1] == '-')) {\n                            if (strncmp(p + i + 2, m_boundary.c_str(),\n                                m_boundary.size()) == 0) {\n                                m_flag_unmatched_boundary = 1;\n                                break;\n                            }\n                        }\n                    }\n                }\n            }\n\n            /* Process as data if it was not a boundary. */\n            if (processed_as_boundary == 0) {\n                if (m_mpp == NULL) {\n                    m_flag_data_before = 1;\n                    ms_dbg_a(m_transaction, 4,\n                        \"Multipart: Ignoring data before first \" \\\n                        \"boundary.\");\n                } else {\n                    if (m_mpp_state == 0) {\n                        if ((m_bufleft == 0) || (process_buffer)) {\n                            /* part header lines must be shorter than\n                             * MULTIPART_BUF_SIZE bytes\n                             */\n                            m_flag_error = 1;\n                            ms_dbg_a(m_transaction, 4,\n                                \"Multipart: Part header line over \" \\\n                                + std::to_string(MULTIPART_BUF_SIZE) \\\n                                + \" bytes long\");\n                            error->assign(\"Multipart: Part header line over \" \\\n                                + std::to_string(MULTIPART_BUF_SIZE) \\\n                                + \" bytes long\");\n                            return false;\n                        }\n\n                        if (process_part_header(error, offset + z) < 0) {\n                            m_flag_error = 1;\n                            return false;\n                        }\n\n                    } else {\n                        if (process_part_data(error, offset + z) < 0) {\n                            m_flag_error = 1;\n                            return false;\n                        }\n                    }\n                }\n            }\n\n            /* Update the offset of the data we are about\n             * to process. This is to allow us to know the\n             * offsets of individual files and variables.\n             */\n            m_buf_offset += (MULTIPART_BUF_SIZE - m_bufleft);\n\n            /* reset the pointer to the beginning of the buffer\n             * and continue to accept input data\n             */\n            m_bufptr = m_buf;\n            m_bufleft = MULTIPART_BUF_SIZE;\n            m_buf_contains_line = (c == 0x0a) ? 1 : 0;\n\n            if (c == 0x0a) {\n                if (m_crlf_state == 1) {\n                    m_crlf_state = 3;\n                } else {\n                    m_crlf_state = 2;\n                }\n            }\n            m_crlf_state_buf_end = m_crlf_state;\n\n        }\n\n        if (c == 0x0d) {\n            m_crlf_state = 1;\n        } else if (c != 0x0a) {\n            m_crlf_state = 0;\n        }\n\n\n        if ((m_is_complete) && (inleft != 0)) {\n            m_flag_data_after = 1;\n            ms_dbg_a(m_transaction, 4,\n                \"Multipart: Ignoring data after last boundary (\" \\\n                + std::to_string(inleft) + \"bytes left)\");\n            return true;\n        }\n    }\n\n    return true;\n}\n\n\n}  // namespace RequestBodyProcessor\n}  // namespace modsecurity\n"
  },
  {
    "path": "src/request_body_processor/multipart.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <string>\n#include <iostream>\n#include <list>\n#include <unordered_map>\n#include <utility>\n\n#ifndef SRC_REQUEST_BODY_PROCESSOR_MULTIPART_H_\n#define SRC_REQUEST_BODY_PROCESSOR_MULTIPART_H_\n\n#include \"modsecurity/transaction.h\"\n\nnamespace modsecurity {\nnamespace RequestBodyProcessor {\n\n#define MULTIPART_BUF_SIZE 4096\n#define MULTIPART_FORMDATA 1\n#define MULTIPART_FILE 2\n\n\nstruct MyHash {\n    size_t operator()(const std::string& Keyval) const {\n        size_t h = 0;\n        std::for_each(Keyval.begin(), Keyval.end(), [&](char c) {\n            h += tolower(c);\n        });\n        return h;\n    }\n};\n\n\nstruct MyEqual {\n    bool operator()(const std::string& Left, const std::string& Right) const {\n        return Left.size() == Right.size()\n             && std::equal(Left.begin(), Left.end(), Right.begin(),\n            [](char a, char b) {\n                return tolower(a) == tolower(b);\n            });\n    }\n};\n\n\nclass MultipartPartTmpFile {\n public:\n     explicit MultipartPartTmpFile(Transaction *transaction)\n        : m_transaction(transaction),\n        m_tmp_file_fd(0),\n        m_delete(false)\n    { }\n\n    ~MultipartPartTmpFile();\n\n    // forbid copying\n    MultipartPartTmpFile(const MultipartPartTmpFile&) = delete;\n    MultipartPartTmpFile& operator=(const MultipartPartTmpFile&) = delete;\n\n    int getFd() const {return m_tmp_file_fd;}\n    void setFd(int fd) {m_tmp_file_fd = fd;}\n    const std::string& getFilename() const {return m_tmp_file_name;}\n    void setDelete() {m_delete = true;}\n\n    bool isValid() const {return ((m_tmp_file_fd != 0) && (!m_tmp_file_name.empty()));}\n\n    void Open();\n    void Close();\n\n private:\n    Transaction *m_transaction;\n    int m_tmp_file_fd;\n    std::string m_tmp_file_name;\n    bool m_delete; // whether to delete when transaction is done\n};\n\n\nclass MultipartPart {\n public:\n    MultipartPart()\n     : m_type(MULTIPART_FORMDATA),\n     m_name(\"\"),\n     m_nameOffset(0),\n     m_value(\"\"),\n     m_valueOffset(0),\n     m_value_parts(),\n     m_tmp_file_size(),\n     m_filename(\"\"),\n     m_filenameOffset(0),\n     m_last_header_name(\"\"),\n     m_headers(),\n     m_offset(0),\n     m_length(0) {\n         m_tmp_file_size.first = 0;\n         m_tmp_file_size.second = 0;\n    }\n\n    ~MultipartPart() {\n        m_headers.clear();\n        m_value_parts.clear();\n    }\n\n    /* part type, can be MULTIPART_FORMDATA or MULTIPART_FILE */\n    int m_type;\n\n    /* the name */\n    std::string m_name;\n    size_t m_nameOffset;\n\n    /* variables only, variable value */\n    std::string m_value;\n    size_t m_valueOffset;\n\n    std::list<std::pair<std::string, int>> m_value_parts;\n\n    /* files only, the content type (where available) */\n    /* std::string m_content_type; */\n\n    /* files only, the name of the temporary file holding data */\n    std::shared_ptr<RequestBodyProcessor::MultipartPartTmpFile> m_tmp_file;\n    std::pair<size_t, size_t> m_tmp_file_size;\n\n    /* files only, filename as supplied by the browser */\n    std::string m_filename;\n    size_t m_filenameOffset;\n\n    std::string m_last_header_name;\n    std::unordered_map<std::string, std::pair<size_t, std::string>,\n        MyHash, MyEqual> m_headers;\n    std::string m_last_header_line;\n    std::vector<std::pair<size_t, std::string>> m_header_lines;\n\n\n    unsigned int m_offset;\n    unsigned int m_length;\n};\n\n\nclass Multipart {\n public:\n    Multipart(const std::string &header, Transaction *transaction);\n\n    Multipart(const Multipart&) = delete;\n    Multipart& operator=(const Multipart&) = delete;\n\n    ~Multipart();\n\n    bool init(std::string *err);\n\n    static int boundary_characters_valid(const char *boundary);\n    static int count_boundary_params(const std::string& str_header_value);\n    static int is_token_char(unsigned char c);\n    int multipart_complete(std::string *err);\n\n    int parse_content_disposition(const char *c_d_value, int offset);\n    bool process(const std::string& data, std::string *err, int offset);\n    int process_boundary(int last_part);\n    int process_part_header(std::string *error, int offset);\n    int process_part_data(std::string *error, size_t offset);\n\n    void validate_quotes(const char *data, char quote);\n\n    size_t m_reqbody_no_files_length;\n    std::list<MultipartPart *> m_parts;\n\n    /* Number of parts that are files */\n    int m_nfiles;\n\n    /* mime boundary used to detect when\n     * parts end and begin\n     */\n    std::string m_boundary;\n    int  m_boundary_count;\n\n    /* internal buffer and other variables\n     * used while parsing\n     */\n    char m_buf[MULTIPART_BUF_SIZE + 2];\n    int m_buf_contains_line;\n    char *m_bufptr;\n    int m_bufleft;\n\n    unsigned int m_buf_offset;\n\n    /* line ending status seen immediately before current position.\n     * 0 = neither LF nor CR; 1 = prev char CR; 2 = prev char LF alone;\n     * 3 = prev two chars were CRLF\n     */\n    int                      m_crlf_state;\n\n    /* crlf_state at end of previous buffer */\n    int                      m_crlf_state_buf_end;\n\n    /* pointer that keeps track of a part while\n     * it is being built\n     */\n    MultipartPart *m_mpp;\n\n\n    /* part parsing state; 0 means we are reading\n     * headers, 1 means we are collecting data\n     */\n    int m_mpp_state;\n\n    /* part parsing substate;  if mpp_state is 1 (collecting\n     * data), then for this variable:\n     * 0 means we have not yet read any data between the\n     * post-headers blank line and the next boundary\n     * 1 means we have read at some data after that blank line\n     */\n    int m_mpp_substate_part_data_read;\n\n    /* because of the way this parsing algorithm\n     * works we hold back the last two bytes of\n     * each data chunk so that we can discard it\n     * later if the next data chunk proves to be\n     * a boundary; the first byte is an indicator\n     * 0 - no content, 1 - two data bytes available\n     */\n    char m_reserve[4];\n\n    int m_seen_data;\n    int m_is_complete;\n\n    int m_flag_error;\n    int m_flag_data_before;\n    int m_flag_data_after;\n    int m_flag_header_folding;\n    int m_flag_boundary_quoted;\n    int m_flag_lf_line;\n    int m_flag_crlf_line;\n    int m_flag_unmatched_boundary;\n    int m_flag_boundary_whitespace;\n    int m_flag_missing_semicolon;\n    int m_flag_invalid_quoting;\n    int m_flag_invalid_part;\n    int m_flag_invalid_header_folding;\n    int m_flag_file_limit_exceeded;\n\n private:\n    std::string m_header;\n    Transaction *m_transaction;\n};\n\n\n}  // namespace RequestBodyProcessor\n}  // namespace modsecurity\n\n#endif  // SRC_REQUEST_BODY_PROCESSOR_MULTIPART_H_\n"
  },
  {
    "path": "src/request_body_processor/xml.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"src/request_body_processor/xml.h\"\n\n#include <list>\n#include <iostream>\n#include <string>\n\n\nnamespace modsecurity {\nnamespace RequestBodyProcessor {\n\n#ifdef WITH_LIBXML2\n\n/*\n* NodeData for parsing XML into args\n*/\nNodeData::NodeData() {\n    has_child = false;\n}\n\nNodeData::~NodeData() {};\n\n/*\n* XMLNodes for parsing XML into args\n*/\nXMLNodes::XMLNodes(Transaction *transaction) \n    : nodes{},\n    node_depth(0),\n    currpath(\"\"),\n    currval(\"\"),\n    currval_is_set(false),\n    m_transaction(transaction)\n    {}\n\nXMLNodes::~XMLNodes() {};\n\n/*\n* SAX handler for parsing XML into args\n*/\nclass MSCSAXHandler {\n    public:\n        void onStartElement(void * ctx, const xmlChar *localname) {\n\n            std::string name = reinterpret_cast<const char*>(localname);\n\n            XMLNodes* xml_data = static_cast<XMLNodes*>(ctx);\n            xml_data->nodes.push_back(std::make_shared<NodeData>());\n            xml_data->node_depth++;\n            // FIXME - later if we want to check the depth of XML tree\n            /* if (max_depth > 0 && max_depth > xml_data->node_depth) {\n                std::cout << \"Depth of XML tree reached the given maximum value \" << xml_data->node_depth << std::endl;\n                exit(1);\n            } */\n            // if it's not the first (root) item, then append a '.'\n            // note, the condition should always be true because there is always a pseudo root element: 'xml'\n            if (xml_data->nodes.size() > 1) {\n                xml_data->currpath.append(\".\");\n                xml_data->nodes[xml_data->nodes.size()-2]->has_child = true;\n            }\n            xml_data->currpath.append(name);\n            // set the current value empty\n            // this is necessary because if there is any text between the tags (new line, etc)\n            // it will be added to the current value\n            xml_data->currval = \"\";\n            xml_data->currval_is_set = false;\n        }\n\n        void onEndElement(void * ctx, const xmlChar *localname) {\n            std::string name = reinterpret_cast<const char*>(localname);\n            XMLNodes* xml_data = static_cast<XMLNodes*>(ctx);\n            const std::shared_ptr<NodeData>& nd = xml_data->nodes[xml_data->nodes.size()-1];\n            if (nd->has_child == false) {\n                // check the return value\n                // if false, then stop parsing\n                // this means the number of arguments reached the limit\n                if (xml_data->m_transaction->addArgument(\"XML\", xml_data->currpath, xml_data->currval, 0) == false) {\n                    xmlStopParser(xml_data->parsing_ctx_arg);\n                }\n            }\n            if (xml_data->currpath.length() > 0) {\n                // set an offset to store whether this is the first item, in order to know whether to remove the '.'\n                int offset = (xml_data->nodes.size() > 1) ? 1 : 0;\n                xml_data->currpath.erase(xml_data->currpath.length() - (name.length()+offset));\n            }\n            xml_data->nodes.pop_back();\n            xml_data->node_depth--;\n            xml_data->currval = \"\";\n            xml_data->currval_is_set = false;\n        }\n\n        void onCharacters(void *ctx, const xmlChar *ch, int len) {\n            XMLNodes* xml_data = static_cast<XMLNodes*>(ctx);\n            std::string content(reinterpret_cast<const char *>(ch), len);\n\n            // libxml2 SAX parser will call this function multiple times\n            // during the parsing of a single node, if the value has multibyte\n            // characters, so we need to concatenate the values\n            if (xml_data->currval_is_set == false) {\n                xml_data->currval = content;\n                xml_data->currval_is_set = true;\n            } else {\n                xml_data->currval += content;\n            }\n        }\n};\n\nextern \"C\" {\n    void MSC_startElement(void *userData,\n        const xmlChar *name,\n        const xmlChar *prefix,\n        const xmlChar *URI,\n        int nb_namespaces,\n        const xmlChar **namespaces,\n        int nb_attributes,\n        int nb_defaulted,\n        const xmlChar **attributes) {\n\n            MSCSAXHandler* handler = static_cast<MSCSAXHandler*>(userData);\n            handler->onStartElement(userData, name);\n    }\n\n    void MSC_endElement(\n        void *userData,\n        const xmlChar *name,\n        const xmlChar* prefix,\n        const xmlChar* URI) {\n\n            MSCSAXHandler* handler = static_cast<MSCSAXHandler*>(userData);\n            handler->onEndElement(userData, name);\n    }\n\n    void MSC_xmlcharacters(void *userData, const xmlChar *ch, int len) {\n        MSCSAXHandler* handler = static_cast<MSCSAXHandler*>(userData);\n        handler->onCharacters(userData, ch, len);\n    }\n}\n\nXML::XML(Transaction *transaction)\n    : m_transaction(transaction) {\n    m_data.doc = NULL;\n    m_data.parsing_ctx = NULL;\n    m_data.sax_handler = NULL;\n    m_data.xml_error = \"\";\n    m_data.parsing_ctx_arg = NULL;\n    m_data.xml_parser_state = NULL;\n}\n\n\nXML::~XML() {\n    if (m_data.parsing_ctx != NULL) {\n        xmlFreeParserCtxt(m_data.parsing_ctx);\n        m_data.parsing_ctx = NULL;\n    }\n    if (m_data.doc != NULL) {\n        xmlFreeDoc(m_data.doc);\n        m_data.doc = NULL;\n    }\n}\n\nbool XML::init() {\n    //xmlParserInputBufferCreateFilenameFunc entity;\n    if (m_transaction->m_rules->m_secXMLExternalEntity\n        == RulesSetProperties::TrueConfigBoolean) {\n        /*entity = */xmlParserInputBufferCreateFilenameDefault(\n            __xmlParserInputBufferCreateFilename);\n    } else {\n        /*entity = */xmlParserInputBufferCreateFilenameDefault(\n            this->unloadExternalEntity);\n    }\n    if (m_transaction->m_secXMLParseXmlIntoArgs\n        == RulesSetProperties::TrueConfigXMLParseXmlIntoArgs ||\n        m_transaction->m_secXMLParseXmlIntoArgs\n        == RulesSetProperties::OnlyArgsConfigXMLParseXmlIntoArgs) {\n        ms_dbg_a(m_transaction, 9,\n                \"XML: SecParseXmlIntoArgs is set to \" \\\n                + RulesSetProperties::configXMLParseXmlIntoArgsString(static_cast<RulesSetProperties::ConfigXMLParseXmlIntoArgs>(m_transaction->m_secXMLParseXmlIntoArgs)));\n        m_data.sax_handler = std::make_unique<xmlSAXHandler>();\n        memset(m_data.sax_handler.get(), 0, sizeof(xmlSAXHandler));\n\n        m_data.sax_handler->initialized = XML_SAX2_MAGIC;\n        m_data.sax_handler->startElementNs = &MSC_startElement;\n        m_data.sax_handler->endElementNs = &MSC_endElement;\n        m_data.sax_handler->characters = &MSC_xmlcharacters;\n\n        // set the parser state struct\n        m_data.xml_parser_state                  = std::make_unique<XMLNodes>(m_transaction);\n        m_data.xml_parser_state->node_depth      = 0;\n        m_data.xml_parser_state->currval         = \"\";\n        // the XML will contain at least one node, which is the pseudo root node 'xml'\n        m_data.xml_parser_state->currpath        = \"xml.\";\n    }\n\n    return true;\n}\n\n\nxmlParserInputBufferPtr XML::unloadExternalEntity(const char *URI,\n    xmlCharEncoding enc) {\n    return NULL;\n}\n\n\nbool XML::processChunk(const char *buf, unsigned int size,\n    std::string *error) {\n    /* We want to initialise our parsing context here, to\n     * enable us to pass it the first chunk of data so that\n     * it can attempt to auto-detect the encoding.\n     */\n    if (m_data.parsing_ctx == NULL && m_data.parsing_ctx_arg == NULL) {\n        /* First invocation. */\n\n        ms_dbg_a(m_transaction, 4, \"XML: Initialising parser.\");\n\n        /* NOTE When Sax interface is used libxml will not\n         *      create the document object, but we need it.\n\n        msr->xml->sax_handler = (xmlSAXHandler *)apr_pcalloc(msr->mp,\n            sizeof(xmlSAXHandler));\n        if (msr->xml->sax_handler == NULL) return -1;\n        msr->xml->sax_handler->error = xml_receive_sax_error;\n        msr->xml->sax_handler->warning = xml_receive_sax_error;\n        msr->xml->parsing_ctx = xmlCreatePushParserCtxt(msr->xml->sax_handler,\n            msr, buf, size, \"body.xml\");\n\n        */\n\n        if (m_transaction->m_secXMLParseXmlIntoArgs\n            != RulesSetProperties::OnlyArgsConfigXMLParseXmlIntoArgs) {\n            m_data.parsing_ctx = xmlCreatePushParserCtxt(NULL, NULL,\n                buf, size, \"body.xml\");\n\n            if (m_data.parsing_ctx == NULL) {\n                ms_dbg_a(m_transaction, 4,\n                    \"XML: Failed to create parsing context.\");\n                error->assign(\"XML: Failed to create parsing context.\");\n                return false;\n            }\n            // disable parser errors being printed to stderr\n            m_data.parsing_ctx->options |= XML_PARSE_NOWARNING | XML_PARSE_NOERROR;\n        }\n\n        if (m_transaction->m_secXMLParseXmlIntoArgs\n            == RulesSetProperties::OnlyArgsConfigXMLParseXmlIntoArgs ||\n            m_transaction->m_secXMLParseXmlIntoArgs\n            == RulesSetProperties::TrueConfigXMLParseXmlIntoArgs) {\n            m_data.parsing_ctx_arg = xmlCreatePushParserCtxt(\n                m_data.sax_handler.get(),\n                m_data.xml_parser_state.get(),\n                buf,\n                size,\n                NULL);\n            if (m_data.parsing_ctx_arg == NULL) {\n                error->assign(\"XML: Failed to create parsing context for ARGS.\");\n                return false;\n            }\n            // disable parser errors being printed to stderr\n            m_data.parsing_ctx_arg->options |= XML_PARSE_NOWARNING | XML_PARSE_NOERROR;\n        }\n\n        return true;\n    }\n\n    /* Not a first invocation. */\n    if (m_data.parsing_ctx != NULL &&\n        m_transaction->m_secXMLParseXmlIntoArgs\n        != RulesSetProperties::OnlyArgsConfigXMLParseXmlIntoArgs) {\n        xmlParseChunk(m_data.parsing_ctx, buf, size, 0);\n        m_data.xml_parser_state->parsing_ctx_arg = m_data.parsing_ctx_arg;\n        if (m_data.parsing_ctx->wellFormed != 1) {\n            error->assign(\"XML: Failed to parse document.\");\n            ms_dbg_a(m_transaction, 4, \"XML: Failed to parse document.\");\n            return false;\n        }\n    }\n\n    if (m_data.parsing_ctx_arg != NULL &&\n        (\n            m_transaction->m_secXMLParseXmlIntoArgs\n              == RulesSetProperties::OnlyArgsConfigXMLParseXmlIntoArgs\n            ||\n            m_transaction->m_secXMLParseXmlIntoArgs\n              == RulesSetProperties::TrueConfigXMLParseXmlIntoArgs)\n        ) {\n        xmlParseChunk(m_data.parsing_ctx_arg, buf, size, 0);\n        if (m_data.parsing_ctx_arg->wellFormed != 1) {\n            error->assign(\"XML: Failed to parse document for ARGS.\");\n            ms_dbg_a(m_transaction, 4, \"XML: Failed to parse document for ARGS.\");\n            return false;\n        }\n    }\n\n    return true;\n}\n\n\nbool XML::complete(std::string *error) {\n    /* Only if we have a context, meaning we've done some work. */\n    if (m_data.parsing_ctx != NULL || m_data.parsing_ctx_arg != NULL) {\n        if (m_data.parsing_ctx != NULL &&\n            m_transaction->m_secXMLParseXmlIntoArgs\n            != RulesSetProperties::OnlyArgsConfigXMLParseXmlIntoArgs) {\n            /* This is how we signal the end of parsing to libxml. */\n            xmlParseChunk(m_data.parsing_ctx, NULL, 0, 1);\n\n            /* Preserve the results for our reference. */\n            m_data.well_formed = m_data.parsing_ctx->wellFormed;\n            m_data.doc = m_data.parsing_ctx->myDoc;\n\n            /* Clean up everything else. */\n            xmlFreeParserCtxt(m_data.parsing_ctx);\n            m_data.parsing_ctx = NULL;\n            ms_dbg_a(m_transaction, 4, \"XML: Parsing complete (well_formed \" \\\n                + std::to_string(m_data.well_formed) + \").\");\n\n            if (m_data.well_formed != 1) {\n                error->assign(\"XML: Failed to parse document.\");\n                ms_dbg_a(m_transaction, 4, \"XML: Failed to parse document.\");\n                return false;\n            }\n        }\n        if (m_data.parsing_ctx_arg != NULL &&\n            (\n                m_transaction->m_secXMLParseXmlIntoArgs\n                  == RulesSetProperties::OnlyArgsConfigXMLParseXmlIntoArgs\n                  ||\n                m_transaction->m_secXMLParseXmlIntoArgs\n                  == RulesSetProperties::TrueConfigXMLParseXmlIntoArgs)\n            ) {\n            /* This is how we signale the end of parsing to libxml. */\n            if (xmlParseChunk(m_data.parsing_ctx_arg, NULL, 0, 1) != 0) {\n                if (m_data.xml_error != \"\") {\n                    error->assign(m_data.xml_error);\n                }\n                else {\n                    error->assign(\"XML: Failed to parse document for ARGS.\");\n                }\n                xmlFreeParserCtxt(m_data.parsing_ctx_arg);\n                m_data.parsing_ctx_arg = NULL;\n                return false;\n            }\n            xmlFreeParserCtxt(m_data.parsing_ctx_arg);\n            m_data.parsing_ctx_arg = NULL;\n        }\n    }\n\n    return true;\n}\n\n#endif\n\n}  // namespace RequestBodyProcessor\n}  // namespace modsecurity\n"
  },
  {
    "path": "src/request_body_processor/xml.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#ifdef WITH_LIBXML2\n#include <libxml/xmlschemas.h>\n#include <libxml/xpath.h>\n#include <libxml/SAX2.h>\n#endif\n\n#include <string>\n#include <iostream>\n\n#include \"modsecurity/transaction.h\"\n#include \"modsecurity/rules_set.h\"\n\n#ifndef SRC_REQUEST_BODY_PROCESSOR_XML_H_\n#define SRC_REQUEST_BODY_PROCESSOR_XML_H_\n\n\nnamespace modsecurity {\nnamespace RequestBodyProcessor {\n\n#ifdef WITH_LIBXML2\n\n/*\n* NodeData for parsing XML into args\n*/\nclass NodeData {\n    public:\n        explicit NodeData();\n        ~NodeData();\n\n        bool has_child;\n};\n\n/*\n* XMLNodes for parsing XML into args\n*/\nclass XMLNodes {\n    public:\n        std::vector<std::shared_ptr<NodeData>> nodes;\n        unsigned long int node_depth;\n        std::string       currpath;\n        std::string       currval;\n        bool              currval_is_set;\n        Transaction      *m_transaction;\n        // need to store context - this is the same as in xml_data\n        // need to stop parsing if the number of arguments reached the limit\n        xmlParserCtxtPtr  parsing_ctx_arg;\n\n        explicit XMLNodes (Transaction *);\n        ~XMLNodes();\n};\n\nstruct xml_data {\n    std::unique_ptr<xmlSAXHandler> sax_handler;\n    xmlParserCtxtPtr parsing_ctx;\n    xmlDocPtr doc;\n\n    unsigned int well_formed;\n\n    /* error reporting and XML array flag */\n    std::string               xml_error;\n\n    /* additional parser context for arguments */\n    xmlParserCtxtPtr          parsing_ctx_arg;\n\n    /* parser state for SAX parser */\n    std::unique_ptr<XMLNodes> xml_parser_state;\n};\n\ntypedef struct xml_data xml_data;\n\nclass XML {\n public:\n    explicit XML(Transaction *transaction);\n    ~XML();\n    bool init();\n    bool processChunk(const char *buf, unsigned int size, std::string *err);\n    bool complete(std::string *err);\n    static xmlParserInputBufferPtr unloadExternalEntity(const char *URI,\n        xmlCharEncoding enc);\n\n    xml_data m_data;\n\n private:\n    Transaction *m_transaction;\n    std::string m_header;\n};\n\n#endif\n\n}  // namespace RequestBodyProcessor\n}  // namespace modsecurity\n\n#endif  // SRC_REQUEST_BODY_PROCESSOR_XML_H_\n"
  },
  {
    "path": "src/rule.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"modsecurity/rule.h\"\n\n#include <stdio.h>\n\n#include <algorithm>\n#include <iostream>\n#include <string>\n#include <cstring>\n#include <list>\n#include <utility>\n#include <memory>\n\n#include \"modsecurity/rules_set.h\"\n#include \"src/operators/operator.h\"\n#include \"modsecurity/actions/action.h\"\n#include \"modsecurity/modsecurity.h\"\n#include \"src/actions/transformations/none.h\"\n#include \"src/actions/tag.h\"\n#include \"src/utils/string.h\"\n#include \"modsecurity/rule_message.h\"\n#include \"src/actions/msg.h\"\n#include \"src/actions/log_data.h\"\n#include \"src/actions/severity.h\"\n#include \"src/actions/capture.h\"\n#include \"src/actions/multi_match.h\"\n#include \"src/actions/set_var.h\"\n#include \"src/actions/block.h\"\n#include \"src/variables/variable.h\"\n"
  },
  {
    "path": "src/rule_message.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2023 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"modsecurity/rule_message.h\"\n\n#include \"modsecurity/rules_set.h\"\n#include \"modsecurity/modsecurity.h\"\n#include \"modsecurity/transaction.h\"\n#include \"src/utils/string.h\"\n\nnamespace modsecurity {\n\n\nstd::string RuleMessage::_details(const RuleMessage &rm) {\n    std::string msg;\n\n    msg.append(\" [file \\\"\" + rm.m_rule.getFileName() + \"\\\"]\");\n    msg.append(\" [line \\\"\" + std::to_string(rm.m_rule.getLineNumber()) + \"\\\"]\");\n    msg.append(\" [id \\\"\" + std::to_string(rm.m_rule.m_ruleId) + \"\\\"]\");\n    msg.append(\" [rev \\\"\" + utils::string::toHexIfNeeded(rm.m_rule.m_rev, true) + \"\\\"]\");\n    msg.append(\" [msg \\\"\" + rm.m_message + \"\\\"]\");\n    msg.append(\" [data \\\"\" + utils::string::toHexIfNeeded(utils::string::limitTo(200, rm.m_data), true) + \"\\\"]\");\n    msg.append(\" [severity \\\"\" +\n        std::to_string(rm.m_severity) + \"\\\"]\");\n    msg.append(\" [ver \\\"\" + utils::string::toHexIfNeeded(rm.m_rule.m_ver, true) + \"\\\"]\");\n    msg.append(\" [maturity \\\"\" + std::to_string(rm.m_rule.m_maturity) + \"\\\"]\");\n    msg.append(\" [accuracy \\\"\" + std::to_string(rm.m_rule.m_accuracy) + \"\\\"]\");\n\n    for (const auto &a : rm.m_tags) {\n        msg.append(\" [tag \\\"\" + utils::string::toHexIfNeeded(a, true) + \"\\\"]\");\n    }\n\n    msg.append(\" [hostname \\\"\" + rm.m_transaction.m_requestHostName \\\n        + \"\\\"]\");\n    msg.append(\" [uri \\\"\" + utils::string::limitTo(200, rm.m_transaction.m_uri_no_query_string_decoded) + \"\\\"]\");\n    msg.append(\" [unique_id \\\"\" + rm.m_transaction.m_id + \"\\\"]\");\n    msg.append(\" [ref \\\"\" + utils::string::limitTo(200, rm.m_reference) + \"\\\"]\");\n\n    return msg;\n}\n\n\nstd::string RuleMessage::_errorLogTail(const RuleMessage &rm) {\n    std::string msg;\n\n    msg.append(\"[hostname \\\"\" + rm.m_transaction.m_serverIpAddress + \"\\\"]\");\n    msg.append(\" [uri \\\"\" + utils::string::limitTo(200, rm.m_transaction.m_uri_no_query_string_decoded) + \"\\\"]\");\n    msg.append(\" [unique_id \\\"\" + rm.m_transaction.m_id + \"\\\"]\");\n\n    return msg;\n}\n\n\nstd::string RuleMessage::log(const RuleMessage &rm, int props, int code) {\n    std::string msg(\"\");\n    msg.reserve(2048);\n\n    if (props & ClientLogMessageInfo) {\n        msg.append(\"[client \" + rm.m_transaction.m_clientIpAddress + \"] \");\n    }\n\n    if (rm.m_isDisruptive) {\n        msg.append(\"ModSecurity: Access denied with code \");\n        if (code == -1) {\n            msg.append(\"%d\");\n        } else {\n            msg.append(std::to_string(code));\n        }\n        msg.append(\" (phase \");\n        msg.append(std::to_string(rm.getPhase()) + \"). \");\n    } else {\n        msg.append(\"ModSecurity: Warning. \");\n    }\n\n    msg.append(rm.m_match);\n    msg.append(_details(rm));\n\n    if (props & ErrorLogTailLogMessageInfo) {\n        msg.append(\" \" + _errorLogTail(rm));\n    }\n\n    return modsecurity::utils::string::toHexIfNeeded(msg);\n}\n\n\n}  // namespace modsecurity\n"
  },
  {
    "path": "src/rule_script.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"src/rule_script.h\"\n\n\nnamespace modsecurity {\n\nbool RuleScript::init(std::string *err) {\n    return m_lua.load(m_name, err);\n}\n\nbool RuleScript::evaluate(Transaction *trans,\n    RuleMessage &ruleMessage) {\n\n    ms_dbg_a(trans, 4, \" Executing script: \" + m_name + \".\");\n\n    bool containsDisruptive = false;\n\n    executeActionsIndependentOfChainedRuleResult(trans,\n        &containsDisruptive, ruleMessage);\n\n    bool ret = m_lua.run(trans);\n\n    if (ret) {\n        executeActionsAfterFullMatch(trans, containsDisruptive, ruleMessage);\n    }\n\n    return ret;\n}\n\n}  // namespace modsecurity\n"
  },
  {
    "path": "src/rule_script.h",
    "content": "\n/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#ifndef SRC_RULE_SCRIPT_H_\n#define SRC_RULE_SCRIPT_H_\n\n#include <string>\n#include <memory>\n#include <vector>\n\n#include \"modsecurity/rules_set.h\"\n#include \"modsecurity/rule.h\"\n#include \"src/engine/lua.h\"\n#include \"src/operators/operator.h\"\n#include \"modsecurity/actions/action.h\"\n#include \"modsecurity/modsecurity.h\"\n#include \"src/actions/transformations/none.h\"\n#include \"src/actions/tag.h\"\n#include \"src/utils/string.h\"\n#include \"modsecurity/rule_message.h\"\n#include \"src/actions/msg.h\"\n#include \"src/actions/log_data.h\"\n#include \"src/actions/severity.h\"\n#include \"src/variables/variable.h\"\n\n\nnamespace modsecurity {\n\nusing actions::Action;\n\n/** @ingroup ModSecurity_CPP_API */\nclass RuleScript : public RuleWithActions {\n public:\n    RuleScript(const std::string &name,\n        std::vector<Action *> *actions,\n        Transformations *t,\n        const std::string &fileName,\n        int lineNumber)\n            : RuleWithActions(actions, t, fileName, lineNumber),\n        m_name(name),\n        m_lua() { }\n\n    RuleScript(const RuleScript& r) = delete;\n\n    RuleScript &operator=(const RuleScript &r) = delete;\n\n    bool init(std::string *err);\n\n    bool evaluate(Transaction *trans, RuleMessage &ruleMessage) override;\n\n    std::string m_name;\n    engine::Lua m_lua;\n};\n\n}  // namespace modsecurity\n\n#endif  // SRC_RULE_SCRIPT_H_\n\n"
  },
  {
    "path": "src/rule_unconditional.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"modsecurity/rule_unconditional.h\"\n\n\nnamespace modsecurity {\n\n\nbool RuleUnconditional::evaluate(Transaction *trans,\n    RuleMessage &ruleMessage) {\n    RuleWithActions::evaluate(trans, ruleMessage);\n\n    // FIXME: This needs to be romeved on the runtime exeption review.\n    bool containsBlock = false;\n\n    ms_dbg_a(trans, 4, \"(Rule: \" + std::to_string(m_ruleId) \\\n        + \") Executing unconditional rule...\");\n\n    executeActionsIndependentOfChainedRuleResult(trans,\n        &containsBlock, ruleMessage);\n\n    executeActionsAfterFullMatch(trans, containsBlock, ruleMessage);\n\n    performLogging(trans, ruleMessage);\n\n    return true;\n}\n\n}  // namespace modsecurity\n"
  },
  {
    "path": "src/rule_with_actions.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"modsecurity/rule.h\"\n\n#include <stdio.h>\n\n#include <cassert>\n#include <algorithm>\n#include <iostream>\n#include <string>\n#include <cstring>\n#include <list>\n#include <utility>\n#include <memory>\n#include <cassert>\n\n#include \"modsecurity/rules_set.h\"\n#include \"src/operators/operator.h\"\n#include \"modsecurity/actions/action.h\"\n#include \"modsecurity/modsecurity.h\"\n#include \"src/actions/transformations/none.h\"\n#include \"src/actions/tag.h\"\n#include \"src/utils/string.h\"\n#include \"modsecurity/rule_message.h\"\n#include \"modsecurity/rule_with_actions.h\"\n#include \"src/actions/msg.h\"\n#include \"src/actions/log_data.h\"\n#include \"src/actions/severity.h\"\n#include \"src/actions/capture.h\"\n#include \"src/actions/multi_match.h\"\n#include \"src/actions/set_var.h\"\n#include \"src/actions/block.h\"\n#include \"src/variables/variable.h\"\n\n\nnamespace modsecurity {\n\nusing operators::Operator;\nusing actions::Action;\nusing variables::Variable;\nusing actions::transformations::None;\nusing actions::transformations::Transformation;\n\n\n\nRuleWithActions::RuleWithActions(\n    Actions *actions,\n    Transformations *transformations,\n    const std::string &fileName,\n    int lineNumber)\n    : Rule(fileName, lineNumber),\n    m_rev(\"\"),\n    m_ver(\"\"),\n    m_accuracy(0),\n    m_maturity(0),\n    m_ruleId(0),\n    m_chainedRuleChild(nullptr),\n    m_chainedRuleParent(nullptr),\n    m_disruptiveAction(nullptr),\n    m_logData(nullptr),\n    m_msg(nullptr),\n    m_severity(nullptr),\n    m_actionsRuntimePos(),\n    m_actionsSetVar(),\n    m_actionsTag(),\n    m_transformations(transformations != NULL ? *transformations : Transformations()),\n    m_containsCaptureAction(false),\n    m_containsMultiMatchAction(false),\n    m_containsStaticBlockAction(false),\n    m_isChained(false) {\n\n    if (transformations != NULL) {\n        delete transformations;\n    }\n\n    if (actions) {\n        for (Action *a : *actions) {\n            switch (a->action_kind) {\n                case Action::Kind::ConfigurationKind:\n                    a->evaluate(this, NULL);\n                    delete a;\n                    break;\n                case Action::Kind::RunTimeOnlyIfMatchKind:\n                    if (dynamic_cast<actions::Capture *>(a)) {\n                        m_containsCaptureAction = true;\n                        delete a;\n                    } else if (dynamic_cast<actions::MultiMatch *>(a)) {\n                        m_containsMultiMatchAction = true;\n                        delete a;\n                    } else if (auto sa = dynamic_cast<actions::Severity *>(a)) {\n                        m_severity = sa;\n                    } else if (auto lda = dynamic_cast<actions::LogData *>(a)) { // cppcheck-suppress unreadVariable ; false positive\n                        m_logData = lda;\n                    } else if (auto ma = dynamic_cast<actions::Msg *>(a)) { // cppcheck-suppress unreadVariable ; false positive\n                        m_msg = ma;\n                    } else if (auto sva = dynamic_cast<actions::SetVar *>(a)) {\n                        m_actionsSetVar.push_back(sva);\n                    } else if (auto ta = dynamic_cast<actions::Tag *>(a)) {\n                        m_actionsTag.push_back(ta);\n                    } else if (dynamic_cast<actions::Block *>(a)) {\n                        m_actionsRuntimePos.push_back(a);\n                        m_containsStaticBlockAction = true;\n                    } else if (a->isDisruptive() == true) {\n                        if (m_disruptiveAction != nullptr) {\n                            delete m_disruptiveAction;\n                            m_disruptiveAction = nullptr;\n                        }\n                        m_disruptiveAction = a;\n                    } else {\n                        m_actionsRuntimePos.push_back(a);\n                    }\n                    break;\n                default:\n                    std::cout << \"General failure, action: \" << a->m_name;\n                    std::cout << \" has an unknown type.\" << std::endl;\n                    delete a;\n                    #ifdef NDEBUG\n                    break;\n                    #else\n                    assert(false);\n                    #endif\n            }\n        }\n        delete actions;\n    }\n}\n\nRuleWithActions::~RuleWithActions() {\n    if (m_severity) {\n        delete m_severity;\n        m_severity = nullptr;\n    }\n    if (m_logData) {\n        delete m_logData;\n        m_logData = nullptr;\n    }\n    if (m_msg) {\n        delete m_msg;\n        m_msg = nullptr;\n    }\n    while (m_transformations.empty() == false) {\n        auto *a = m_transformations.back();\n        m_transformations.pop_back();\n        delete a;\n    }\n    while (m_actionsRuntimePos.empty() == false) {\n        auto *a = m_actionsRuntimePos.back();\n        m_actionsRuntimePos.pop_back();\n        delete a;\n    }\n    while (m_actionsSetVar.empty() == false) {\n        auto *a = m_actionsSetVar.back();\n        m_actionsSetVar.pop_back();\n        delete a;\n    }\n    while (m_actionsTag.empty() == false) {\n        auto *a = m_actionsTag.back();\n        m_actionsTag.pop_back();\n        delete a;\n    }\n    if (m_disruptiveAction != nullptr) {\n        delete m_disruptiveAction;\n        m_disruptiveAction = nullptr;\n    }\n}\n\n\nbool RuleWithActions::evaluate(Transaction *transaction) {\n    RuleMessage rm(*this, *transaction);\n    return evaluate(transaction, rm);\n}\n\n\nbool RuleWithActions::evaluate(Transaction *transaction,\n    RuleMessage &ruleMessage) {\n\n    /* Rule evaluate is pure virtual.\n     *\n     * Rule::evaluate(transaction, ruleMessage);\n     */\n\n    /* Matched vars needs to be clear at every new rule execution */\n    transaction->m_matched.clear();\n\n    return true;\n}\n\n\nvoid RuleWithActions::executeActionsIndependentOfChainedRuleResult(Transaction *trans,\n    bool *containsBlock, RuleMessage &ruleMessage) {\n\n    for (actions::SetVar *a : m_actionsSetVar) {\n        ms_dbg_a(trans, 4, \"Running [independent] (non-disruptive) \" \\\n            \"action: \" + *a->m_name.get());\n\n        a->evaluate(this, trans);\n    }\n\n    for (auto &b :\n        trans->m_rules->m_exceptions.m_action_pre_update_target_by_id) {\n        if (m_ruleId != b.first) {\n            continue;\n        }\n        actions::Action *a = b.second.get();\n        if (a->isDisruptive() == true && *a->m_name.get() == \"block\") {\n            ms_dbg_a(trans, 9, \"Rule contains a `block' action\");\n                *containsBlock = true;\n        } else if (*a->m_name.get() == \"setvar\") {\n            ms_dbg_a(trans, 4, \"Running [independent] (non-disruptive) \" \\\n                \"action: \" + *a->m_name.get());\n            a->evaluate(this, trans, ruleMessage);\n        }\n    }\n\n    if (m_containsMultiMatchAction && m_chainedRuleParent == nullptr) {\n        if (m_severity) {\n            m_severity->evaluate(this, trans, ruleMessage);\n        }\n        if (m_logData) {\n            m_logData->evaluate(this, trans, ruleMessage);\n        }\n        if (m_msg) {\n            m_msg->evaluate(this, trans, ruleMessage);\n        }\n        for (actions::Tag *a : m_actionsTag) {\n            a->evaluate(this, trans, ruleMessage);\n        }\n    }\n\n}\n\n\nvoid RuleWithActions::executeActionsAfterFullMatch(Transaction *trans,\n    bool containsBlock, RuleMessage &ruleMessage) {\n    bool disruptiveAlreadyExecuted = false;\n\n    for (const auto &a : trans->m_rules->m_defaultActions[getPhase()]) { // cppcheck-suppress ctunullpointer\n        if (a.get()->action_kind != actions::Action::Kind::RunTimeOnlyIfMatchKind) {\n            continue;\n        }\n        if (!a.get()->isDisruptive()) {\n            executeAction(trans, containsBlock, ruleMessage, a.get(), true);\n        }\n    }\n\n    for (actions::Tag *a : this->m_actionsTag) {\n        ms_dbg_a(trans, 4, \"Running (non-disruptive) action: \" \\\n            + *a->m_name.get());\n        a->evaluate(this, trans, ruleMessage);\n    }\n\n    for (auto &b :\n        trans->m_rules->m_exceptions.m_action_pos_update_target_by_id) {\n        if (m_ruleId != b.first) {\n            continue;\n        }\n        actions::Action *a = b.second.get();\n        executeAction(trans, containsBlock, ruleMessage, a, false);\n        disruptiveAlreadyExecuted = true;\n    }\n    if (m_severity) {\n        m_severity->evaluate(this, trans, ruleMessage);\n    }\n\n    if (m_logData) {\n        m_logData->evaluate(this, trans, ruleMessage);\n    }\n\n    if (m_msg) {\n        m_msg->evaluate(this, trans, ruleMessage);\n    }\n    for (Action *a : this->m_actionsRuntimePos) {\n        if (!a->isDisruptive()\n                && !(disruptiveAlreadyExecuted\n                && dynamic_cast<actions::Block *>(a))) {\n            executeAction(trans, containsBlock, ruleMessage, a, false);\n        }\n    }\n    if (!disruptiveAlreadyExecuted && m_disruptiveAction != nullptr) {\n        executeAction(trans, containsBlock, ruleMessage,\n            m_disruptiveAction, false);\n    }\n}\n\n\nvoid RuleWithActions::executeAction(Transaction *trans,\n    bool containsBlock, RuleMessage &ruleMessage,\n    Action *a, bool defaultContext) {\n    if (a->isDisruptive() == false && *a->m_name.get() != \"block\") {\n        ms_dbg_a(trans, 9, \"Running \" \\\n            \"action: \" + *a->m_name.get());\n        a->evaluate(this, trans, ruleMessage);\n        return;\n    }\n\n    if (defaultContext && !containsBlock) {\n        ms_dbg_a(trans, 4, \"Ignoring action: \" + *a->m_name.get() + \\\n            \" (rule does not cotains block)\");\n        return;\n    }\n\n    if (trans->getRuleEngineState() == RulesSet::EnabledRuleEngine) {\n        ms_dbg_a(trans, 4, \"Running (disruptive)     action: \" + *a->m_name.get() + \\\n            \".\");\n        a->evaluate(this, trans, ruleMessage);\n        return;\n    }\n\n    ms_dbg_a(trans, 4, \"Not running any disruptive action (or block): \" \\\n        + *a->m_name.get() + \". SecRuleEngine is not On.\");\n}\n\n\ninline void RuleWithActions::executeTransformation(\n    const actions::transformations::Transformation &a,\n    std::string &value,\n    const Transaction *trans,\n    TransformationResults &ret,\n    std::string &path,\n    int &nth) const {\n\n    if (a.transform(value, trans) &&\n        m_containsMultiMatchAction) {\n        ret.emplace_back(value, a.m_name);\n        nth++;\n    }\n\n    if (path.empty()) {\n        path.append(*a.m_name.get());\n    } else {\n        path.append(\",\" + *a.m_name.get());\n    }\n\n    ms_dbg_a(trans, 9, \" T (\" + \\\n        std::to_string(nth) + \") \" + \\\n        *a.m_name.get() + \": \\\"\" + \\\n        utils::string::limitTo(80, value) +\"\\\"\");\n}\n\nvoid RuleWithActions::executeTransformations(\n    const Transaction *trans, const std::string &in, TransformationResults &ret) {\n    int none = 0;\n    int transformations = 0;\n    std::string path;\n    auto value = in;\n\n    if (m_containsMultiMatchAction == true) {\n        /* keep the original value */\n        ret.emplace_back(value,\n                       std::make_shared<std::string>(path));\n    }\n\n    for (const Action *a : m_transformations) {\n        if (a->m_isNone) {\n            none++;\n        }\n    }\n\n    // Check for transformations on the SecDefaultAction\n    // Notice that first we make sure that won't be a t:none\n    // on the target rule.\n    if (none == 0) {\n        for (auto &a : trans->m_rules->m_defaultActions[getPhase()]) {\n            if (a->action_kind \\\n                != actions::Action::Kind::RunTimeBeforeMatchAttemptKind) {\n                continue;\n            }\n\n            // FIXME: here the object needs to be a transformation already.\n            auto t = dynamic_cast<const Transformation*>(a.get());\n            assert(t != nullptr);\n            executeTransformation(*t, value, trans, ret, path,\n                transformations);\n        }\n    }\n\n    for (const Transformation *a : m_transformations) {\n        assert(a != nullptr);\n        if (none == 0) {\n            executeTransformation(*a, value, trans, ret, path,\n                transformations);\n        }\n        if (a->m_isNone) {\n            none--;\n        }\n    }\n\n    // FIXME: It can't be something different from transformation. Sort this\n    //        on rules compile time.\n    for (auto &b :\n        trans->m_rules->m_exceptions.m_action_pre_update_target_by_id) {\n        if (m_ruleId != b.first) {\n            continue;\n        }\n        auto a = dynamic_cast<const Transformation*>(b.second.get());\n        assert(a != nullptr);\n        if (a->m_isNone) {\n            none++;\n        }\n    }\n\n    for (auto &b :\n        trans->m_rules->m_exceptions.m_action_pre_update_target_by_id) {\n        if (m_ruleId != b.first) {\n            continue;\n        }\n        auto a = dynamic_cast<const Transformation*>(b.second.get());\n        assert(a != nullptr);\n        if (none == 0) {\n            executeTransformation(*a, value, trans, ret, path,\n                transformations);\n        }\n        if (a->m_isNone) {\n            none--;\n        }\n    }\n\n    if (m_containsMultiMatchAction == true) {\n        ms_dbg_a(trans, 9, \"multiMatch is enabled. \" \\\n            + std::to_string(ret.size()) + \\\n            \" values to be tested.\");\n    }\n\n    if (!m_containsMultiMatchAction) {\n        ret.emplace_back(value,\n                       std::make_shared<std::string>(path));\n    }\n}\n\n\nbool RuleWithActions::containsTag(const std::string& name, Transaction *t) {\n    for (auto &tag : m_actionsTag) {\n        if (tag != NULL && tag->getName(t) == name) {\n            return true;\n        }\n    }\n    return false;\n}\n\n\nbool RuleWithActions::containsMsg(const std::string& name, Transaction *t) {\n    return m_msg && m_msg->data(t) == name;\n}\n\n\nstd::vector<actions::Action *> RuleWithActions::getActionsByName(const std::string& name,\n    const Transaction *trans) {\n    std::vector<actions::Action *> ret;\n    for (auto &z : m_actionsRuntimePos) {\n        if (*z->m_name.get() == name) {\n            ret.push_back(z);\n        }\n    }\n    for (auto &z : m_transformations) {\n        if (*z->m_name.get() == name) {\n            ret.push_back(z);\n        }\n    }\n    for (auto &b :\n        trans->m_rules->m_exceptions.m_action_pre_update_target_by_id) {\n        if (m_ruleId != b.first) {\n            continue;\n        }\n        actions::Action *z = b.second.get();\n        if (*z->m_name.get() == name) {\n            ret.push_back(z);\n        }\n    }\n    for (auto &b :\n        trans->m_rules->m_exceptions.m_action_pos_update_target_by_id) {\n        if (m_ruleId != b.first) {\n            continue;\n        }\n        actions::Action *z = b.second.get();\n        if (*z->m_name.get() == name) {\n            ret.push_back(z);\n        }\n    }\n    return ret;\n}\n\nvoid RuleWithActions::performLogging(Transaction *trans,\n    RuleMessage &ruleMessage,\n    bool lastLog,\n    bool chainedParentNull) const {\n\n    /* last rule in the chain. */\n    bool isItToBeLogged = ruleMessage.m_saveMessage;\n\n    /**\n    *\n    * RuleMessage is stacked allocated for the rule execution,\n    * anything beyond this may lead to invalid pointer access.\n    *\n    * In case of a warning, o set of messages is saved to be read\n    * at audit log generation. Therefore demands a copy here.\n    *\n    * FIXME: Study an way to avoid the copy.\n    *\n    **/\n    if (lastLog) {\n        if (chainedParentNull) {\n            isItToBeLogged = (ruleMessage.m_saveMessage && (m_chainedRuleParent == nullptr));\n            if (isItToBeLogged && !hasMultimatch()) {\n                /* warn */\n                trans->m_rulesMessages.push_back(ruleMessage);\n\n                /* error */\n                if (!ruleMessage.m_isDisruptive) {\n                    trans->serverLog(ruleMessage);\n                }\n            }\n        } else if (hasBlockAction() && !hasMultimatch()) {\n            /* warn */\n            trans->m_rulesMessages.push_back(ruleMessage);\n            /* error */\n            if (!ruleMessage.m_isDisruptive) {\n                trans->serverLog(ruleMessage);\n            }\n        } else {\n            if (isItToBeLogged && !hasMultimatch()\n                && !ruleMessage.m_message.empty()) {\n                /* warn */\n                trans->m_rulesMessages.push_back(ruleMessage);\n\n                /* error */\n                if (!ruleMessage.m_isDisruptive) {\n                    trans->serverLog(ruleMessage);\n                }\n            }\n        }\n    } else {\n        if (hasMultimatch() && isItToBeLogged) {\n            /* warn */\n            trans->m_rulesMessages.push_back(ruleMessage);\n\n            /* error */\n            if (!ruleMessage.m_isDisruptive) {\n                trans->serverLog(ruleMessage);\n            }\n\n            ruleMessage.reset(false);\n        }\n    }\n}\n\nstd::string RuleWithActions::logData(Transaction *t) { return m_logData->data(t); }\nstd::string RuleWithActions::msg(Transaction *t) { return m_msg->data(t); }\nint RuleWithActions::severity() const { return m_severity->m_severity; }\n\n\n}  // namespace modsecurity\n"
  },
  {
    "path": "src/rule_with_operator.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2023 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"modsecurity/rule_with_operator.h\"\n\n#include <stdio.h>\n\n#include <algorithm>\n#include <iostream>\n#include <string>\n#include <cstring>\n#include <list>\n#include <utility>\n#include <memory>\n\n#include \"modsecurity/rules_set.h\"\n#include \"src/operators/operator.h\"\n#include \"modsecurity/actions/action.h\"\n#include \"modsecurity/modsecurity.h\"\n#include \"src/actions/transformations/none.h\"\n#include \"src/actions/tag.h\"\n#include \"src/utils/string.h\"\n#include \"modsecurity/rule_message.h\"\n#include \"src/actions/msg.h\"\n#include \"src/actions/log_data.h\"\n#include \"src/actions/severity.h\"\n#include \"src/actions/capture.h\"\n#include \"src/actions/multi_match.h\"\n#include \"src/actions/set_var.h\"\n#include \"src/actions/block.h\"\n#include \"src/variables/variable.h\"\n\n\nnamespace modsecurity {\n\nusing operators::Operator;\nusing actions::Action;\nusing variables::Variable;\nusing actions::transformations::None;\n\n\nRuleWithOperator::RuleWithOperator(Operator *op,\n    variables::Variables *_variables,\n    std::vector<Action *> *actions,\n    Transformations *transformations,\n    const std::string &fileName,\n    int lineNumber)\n    : RuleWithActions(actions, transformations, fileName, lineNumber),\n    m_variables(_variables),\n    m_operator(op) { /* */ }\n\n\nRuleWithOperator::~RuleWithOperator() {\n    if (m_operator != NULL) {\n        delete m_operator;\n    }\n\n    while (m_variables != NULL && m_variables->empty() == false) {\n        auto *a = m_variables->back();\n        m_variables->pop_back();\n        delete a;\n    }\n\n    if (m_variables != NULL) {\n        delete m_variables;\n    }\n}\n\n\nvoid RuleWithOperator::updateMatchedVars(Transaction *trans, const std::string &key,\n    const std::string &value) {\n    ms_dbg_a(trans, 9, \"Matched vars updated.\");\n    trans->m_variableMatchedVar.set(value, trans->m_variableOffset);\n    trans->m_variableMatchedVarName.set(key, trans->m_variableOffset);\n\n    trans->m_variableMatchedVars.set(key, value, trans->m_variableOffset);\n    trans->m_variableMatchedVarsNames.set(key, key, trans->m_variableOffset);\n}\n\n\nbool RuleWithOperator::executeOperatorAt(Transaction *trans, const std::string &key,\n    const std::string &value, RuleMessage &ruleMessage) {\n#if MSC_EXEC_CLOCK_ENABLED\n    clock_t begin = clock();\n    clock_t end;\n    double elapsed_s = 0;\n#endif\n    bool ret;\n\n    ms_dbg_a(trans, 9, \"Target value: \\\"\" + utils::string::limitTo(80,\n        utils::string::toHexIfNeeded(value)) \\\n        + \"\\\" (Variable: \" + key + \")\");\n\n    ret = this->m_operator->evaluateInternal(trans, this, value, ruleMessage);\n\n    if (ret == false) {\n        return false;\n    }\n\n#if MSC_EXEC_CLOCK_ENABLED\n    end = clock();\n    elapsed_s = static_cast<double>(end - begin) / CLOCKS_PER_SEC;\n\n    ms_dbg_a(trans, 5, \"Operator completed in \" + \\\n        std::to_string(elapsed_s) + \" seconds\");\n#endif\n    return ret;\n}\n\n\ntemplate<typename MapType, typename Operation>\nvoid getVariablesExceptionsHelper(\n    variables::Variables *exclusion, variables::Variables *addition,\n    const MapType &map, Operation op) {\n    for (const auto &[x, v] : map) {\n        if (op(x)) {\n            auto b = v.get();\n            if (auto vme = dynamic_cast<variables::VariableModificatorExclusion*>(b)) {\n                exclusion->push_back(vme->m_base.get());\n            } else {\n                addition->push_back(b);\n            }\n        }\n    }\n}\n\n\nvoid RuleWithOperator::getVariablesExceptions(Transaction &t,\n    variables::Variables *exclusion, variables::Variables *addition) {\n    getVariablesExceptionsHelper(exclusion, addition,\n        t.m_rules->m_exceptions.m_variable_update_target_by_tag, \n        [this, &t](const auto &tag) { return containsTag(*tag.get(), &t); });\n\n    getVariablesExceptionsHelper(exclusion, addition,\n        t.m_rules->m_exceptions.m_variable_update_target_by_msg,\n        [this, &t](const auto &msg) { return containsMsg(*msg.get(), &t); });\n\n    getVariablesExceptionsHelper(exclusion, addition,\n        t.m_rules->m_exceptions.m_variable_update_target_by_id,\n        [this](const auto &id) { return m_ruleId == id; });\n}\n\n\ninline void RuleWithOperator::getFinalVars(variables::Variables *vars,\n    variables::Variables *exclusion, Transaction *trans) {\n    variables::Variables addition;\n    getVariablesExceptions(*trans, exclusion, &addition); // cppcheck-suppress ctunullpointer\n\n    for (std::size_t i = 0; i < m_variables->size(); i++) {\n        Variable *variable = m_variables->at(i);\n        if (exclusion->contains(variable)) {\n            continue;\n        }\n        if (std::find_if(trans->m_ruleRemoveTargetById.begin(),\n                trans->m_ruleRemoveTargetById.end(),\n                [&, variable, this](const auto &m) -> bool {\n                    const auto& str1 = m.second;\n                    const auto& str2 = *variable->m_fullName.get();\n                    return m.first == m_ruleId &&\n                           str1.size() == str2.size() &&\n                           std::equal(str1.begin(), str1.end(), str2.begin(),\n                                      [](char a, char b) {\n                                          return std::tolower(static_cast<unsigned char>(a)) ==\n                                                 std::tolower(static_cast<unsigned char>(b));\n                                      }); // end-of std::equal\n                }) != trans->m_ruleRemoveTargetById.end()) {\n            continue;\n        }\n        if (std::find_if(trans->m_ruleRemoveTargetByTag.begin(),\n                    trans->m_ruleRemoveTargetByTag.end(),\n                    [&, variable, trans, this](\n                        const auto &m) -> bool {\n                        return containsTag(m.first, trans)\n                            && m.second == *variable->m_fullName.get();\n                    }) != trans->m_ruleRemoveTargetByTag.end()) {\n            continue;\n        }\n        vars->push_back(variable);\n    }\n\n    for (auto *variable : addition) {\n        vars->push_back(variable);\n    }\n}\n\n\nbool RuleWithOperator::evaluate(Transaction *trans,\n    RuleMessage &ruleMessage) {\n    bool globalRet = false;\n    bool recursiveGlobalRet;\n    bool containsBlock = hasBlockAction();\n    std::string eparam;\n    variables::Variables vars;\n    vars.reserve(4);\n    variables::Variables exclusion;\n\n    RuleWithActions::evaluate(trans, ruleMessage);\n\n\n    // FIXME: Make a class runTimeException to handle this cases.\n    for (const auto &i : trans->m_ruleRemoveById) {\n        if (m_ruleId != i) {\n            continue;\n        }\n        ms_dbg_a(trans, 9, \"Rule id: \" + std::to_string(m_ruleId) +\n            \" was skipped due to a ruleRemoveById action...\");\n        return true;\n    }\n    for (const auto &i : trans->m_ruleRemoveByIdRange) {\n        if (!(i.first <= m_ruleId && i.second >= m_ruleId)) {\n            continue;\n        }\n        ms_dbg_a(trans, 9, \"Rule id: \" + std::to_string(m_ruleId) +\n            \" was skipped due to a ruleRemoveById action...\");\n        return true;\n    }\n\n    if (m_operator->m_string) {\n        eparam = m_operator->m_string->evaluate(trans);\n\n        if (m_operator->m_string->containsMacro()) {\n            eparam = \"\\\"\" + eparam + \"\\\" Was: \\\"\" \\\n                + m_operator->m_string->evaluate(NULL) + \"\\\"\";\n        } else {\n            eparam = \"\\\"\" + eparam + \"\\\"\";\n        }\n    ms_dbg_a(trans, 4, \"(Rule: \" + std::to_string(m_ruleId) \\\n        + \") Executing operator \\\"\" + getOperatorName() \\\n        + \"\\\" with param \" \\\n        + eparam \\\n        + \" against \" \\\n        + m_variables + \".\");\n    } else {\n        ms_dbg_a(trans, 4, \"(Rule: \" + std::to_string(m_ruleId) \\\n            + \") Executing operator \\\"\" + getOperatorName() \\\n            + \" against \" \\\n            + m_variables + \".\");\n    }\n\n\n    getFinalVars(&vars, &exclusion, trans);\n\n    for (auto &var : vars) {\n        std::vector<const VariableValue *> e;\n        if (!var) {\n            continue;\n        }\n        var->evaluate(trans, this, &e);\n        for (const VariableValue *v : e) {\n            const std::string &value = v->getValue();\n            const std::string &key = v->getKeyWithCollection();\n\n            if (exclusion.contains(v) ||\n                std::find_if(trans->m_ruleRemoveTargetById.begin(),\n                    trans->m_ruleRemoveTargetById.end(),\n                    [&, v, this](const auto &m) -> bool {\n                        return m.first == m_ruleId && m.second == v->getKeyWithCollection();\n                    }) != trans->m_ruleRemoveTargetById.end()\n            ) {\n                delete v;\n                v = nullptr;\n                continue;\n            }\n            if (exclusion.contains(v) ||\n                std::find_if(trans->m_ruleRemoveTargetByTag.begin(),\n                    trans->m_ruleRemoveTargetByTag.end(),\n                    [&, v, trans, this](const auto &m) -> bool {\n                        return containsTag(m.first, trans) && m.second == v->getKeyWithCollection();\n                    }) != trans->m_ruleRemoveTargetByTag.end()\n            ) {\n                delete v;\n                v = nullptr;\n                continue;\n            }\n\n            TransformationResults values;\n\n            executeTransformations(trans, value, values);\n\n            for (const auto &valueTemp : values) {\n                const auto &valueAfterTrans = valueTemp.first;\n\n                const bool ret = executeOperatorAt(trans, key, valueAfterTrans, ruleMessage);\n\n                if (ret == true) {\n                    ruleMessage.m_match = m_operator->resolveMatchMessage(trans,\n                        key, value);\n                    for (const auto &i : v->getOrigin()) {\n                        ruleMessage.m_reference.append(i.toText());\n                    }\n\n                    ruleMessage.m_reference.append(*valueTemp.second);\n                    updateMatchedVars(trans, key, valueAfterTrans);\n                    executeActionsIndependentOfChainedRuleResult(trans,\n                        &containsBlock, ruleMessage);\n\n                    performLogging(trans, ruleMessage, false);\n\n                    globalRet = true;\n                }\n            }\n            delete v;\n            v = NULL;\n        }\n        e.clear();\n        e.reserve(4);\n    }\n\n    if (globalRet == false) {\n        ms_dbg_a(trans, 4, \"Rule returned 0.\");\n        goto end_clean;\n    }\n    ms_dbg_a(trans, 4, \"Rule returned 1.\");\n\n    if (this->isChained() == false) {\n        goto end_exec;\n    }\n\n    /* FIXME: this check should happens on the parser. */\n    if (this->m_chainedRuleChild == nullptr) {\n        ms_dbg_a(trans, 4, \"Rule is marked as chained but there \" \\\n            \"isn't a subsequent rule.\");\n        goto end_clean;\n    }\n\n    ms_dbg_a(trans, 4, \"Executing chained rule.\");\n    recursiveGlobalRet = m_chainedRuleChild->evaluate(trans, ruleMessage);\n\n    if (recursiveGlobalRet == true) {\n        goto end_exec;\n    }\n\nend_clean:\n    return false;\n\nend_exec:\n    executeActionsAfterFullMatch(trans, containsBlock, ruleMessage);\n\n    /* last rule in the chain. */\n    performLogging(trans, ruleMessage, true, true);\n    return true;\n}\n\n\nconst std::string& RuleWithOperator::getOperatorName() const { return m_operator->m_op; }\n\n\n}  // namespace modsecurity\n"
  },
  {
    "path": "src/rules_exceptions.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2023 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"modsecurity/rules_exceptions.h\"\n\n#include <string>\n\n#include \"src/utils/string.h\"\n#include \"src/variables/variable.h\"\n\nnamespace modsecurity {\n\n\nRulesExceptions::RulesExceptions() {\n}\n\n\nRulesExceptions::~RulesExceptions() {\n}\n\n\nbool RulesExceptions::loadUpdateActionById(double id,\n    std::unique_ptr<std::vector<std::unique_ptr<actions::Action> > > actions,\n    std::string *error) {\n\n    for (auto &a : *actions) {\n        if (a->action_kind == actions::Action::Kind::ConfigurationKind) {\n            std::cout << \"General failure, action: \" << a->m_name;\n            std::cout << \" has not expected to be used with UpdateActionByID.\";\n            std::cout << std::endl;\n        } else if (a->action_kind\n            == actions::Action::Kind::RunTimeBeforeMatchAttemptKind) {\n            m_action_pre_update_target_by_id.emplace(std::pair<double,\n                std::unique_ptr<actions::Action>>(id , std::move(a)));\n        } else if (a->action_kind == actions::Action::Kind::RunTimeOnlyIfMatchKind) {\n            m_action_pos_update_target_by_id.emplace(std::pair<double,\n                std::unique_ptr<actions::Action>>(id , std::move(a)));\n        } else {\n            std::cout << \"General failure, action: \" << a->m_name;\n            std::cout << \" has an unknown type.\" << std::endl;\n        }\n    }\n\n    return true;\n}\n\n\nbool RulesExceptions::loadRemoveRuleByMsg(const std::string &msg,\n    const std::string *error) {\n    m_remove_rule_by_msg.push_back(msg);\n\n    return true;\n}\n\n\nbool RulesExceptions::loadRemoveRuleByTag(const std::string &msg,\n    const std::string *error) {\n    m_remove_rule_by_tag.push_back(msg);\n\n    return true;\n}\n\n\nbool RulesExceptions::loadUpdateTargetByMsg(const std::string &msg,\n    std::unique_ptr<std::vector<std::unique_ptr<variables::Variable> > > var,\n    std::string *error) {\n    for (auto &i : *var) {\n        m_variable_update_target_by_msg.emplace(\n            std::pair<std::shared_ptr<std::string>,\n            std::unique_ptr<variables::Variable>>(\n                std::make_shared<std::string>(msg),\n                std::move(i)));\n    }\n\n    return true;\n}\n\n\nbool RulesExceptions::loadUpdateTargetByTag(const std::string &tag,\n    std::unique_ptr<std::vector<std::unique_ptr<variables::Variable> > > var,\n    std::string *error) {\n\n    for (auto &i : *var) {\n        m_variable_update_target_by_tag.emplace(\n            std::pair<std::shared_ptr<std::string>,\n                std::unique_ptr<variables::Variable>>(\n                    std::make_shared<std::string>(tag),\n                    std::move(i)));\n    }\n\n    return true;\n}\n\n\nbool RulesExceptions::loadUpdateTargetById(double id,\n    std::unique_ptr<std::vector<std::unique_ptr<variables::Variable> > > var,\n    std::string *error) {\n\n    for (auto &i : *var) {\n        m_variable_update_target_by_id.emplace(\n            std::pair<double,\n                std::unique_ptr<variables::Variable>>(id,\n                std::move(i)));\n    }\n\n    return true;\n}\n\n\nbool RulesExceptions::load(const std::string &a, std::string *error) {\n    bool added = false;\n    std::vector<std::string> toRemove = utils::string::ssplit(a, ' ');\n    for (const std::string &r : toRemove) {\n        std::string b = modsecurity::utils::string::parserSanitizer(r);\n        if (b.size() == 0) {\n            continue;\n        }\n\n        size_t dash = b.find('-');\n        if (dash != std::string::npos) {\n            std::string n1s = std::string(b, 0, dash);\n            std::string n2s = std::string(b, dash + 1, b.size() - (dash + 1));\n            int n1n = 0;\n            int n2n = 0;\n            try {\n                n1n = std::stoi(n1s);\n                added = true;\n            } catch (...) {\n                error->assign(\"Not a number: \" + n1s);\n                return false;\n            }\n            try {\n                n2n = std::stoi(n2s);\n                added = true;\n            } catch (...) {\n                error->assign(\"Not a number: \" + n2s);\n                return false;\n            }\n\n            if (n1s > n2s) {\n                error->assign(\"Invalid range: \" + b);\n                return false;\n            }\n            addRange(n1n, n2n);\n            added = true;\n        } else {\n            try {\n                int num = std::stoi(b);\n                addNumber(num);\n                added = true;\n            } catch (...) {\n                error->assign(\"Not a number or range: \" + b);\n                return false;\n            }\n        }\n    }\n\n    if (added) {\n        return true;\n    }\n\n    error->assign(\"Not a number or range: \" + a);\n    return false;\n}\n\n\nbool RulesExceptions::addNumber(int a) {\n    m_numbers.push_back(a);\n    return true;\n}\n\n\nbool RulesExceptions::addRange(int a, int b) {\n    m_ranges.push_back(std::make_pair(a, b));\n    return true;\n}\n\n\nbool RulesExceptions::contains(int a) {\n    for (int z : m_numbers) {\n        if (a == z) {\n            return true;\n        }\n    }\n\n    for (auto z : m_ranges) {\n        if (z.first <= a && z.second >= a) {\n            return true;\n        }\n    }\n\n    return false;\n}\n\n\nbool RulesExceptions::merge(RulesExceptions *from) {\n    for (int a : from->m_numbers) {\n        bool ret = addNumber(a);\n        if (ret == false) {\n            return ret;\n        }\n    }\n    for (auto b : from->m_ranges) {\n        bool ret = addRange(b.first, b.second);\n        if (ret == false) {\n            return ret;\n        }\n    }\n\n    for (auto &p : from->m_variable_update_target_by_tag) {\n        m_variable_update_target_by_tag.emplace(\n            std::pair<std::shared_ptr<std::string>,\n            std::shared_ptr<variables::Variable>>(p.first,\n                p.second));\n    }\n\n    for (auto &p : from->m_variable_update_target_by_msg) {\n        m_variable_update_target_by_msg.emplace(\n            std::pair<std::shared_ptr<std::string>,\n            std::shared_ptr<variables::Variable>>(p.first,\n                p.second));\n    }\n\n    for (auto &p : from->m_variable_update_target_by_id) {\n        m_variable_update_target_by_id.emplace(\n            std::pair<double,\n                std::shared_ptr<variables::Variable>>(p.first,\n                    p.second));\n    }\n\n    for (auto &p : from->m_action_pos_update_target_by_id) {\n        m_action_pos_update_target_by_id.emplace(\n            std::pair<double,\n                std::shared_ptr<actions::Action>>(p.first,\n                    p.second));\n    }\n\n    for (auto &p : from->m_action_pre_update_target_by_id) {\n        m_action_pre_update_target_by_id.emplace(\n            std::pair<double,\n                std::shared_ptr<actions::Action>>(p.first,\n                    p.second));\n    }\n\n    for (const auto &p : from->m_remove_rule_by_msg) {\n        m_remove_rule_by_msg.push_back(p);\n    }\n\n    for (const auto &p : from->m_remove_rule_by_tag) {\n        m_remove_rule_by_tag.push_back(p);\n    }\n\n    return true;\n}\n\n}  // namespace modsecurity\n\n"
  },
  {
    "path": "src/rules_set.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2023 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <ctime>\n#include <iostream>\n#include <fstream>\n#include <string>\n#include <vector>\n\n#include \"modsecurity/rules_set.h\"\n#include \"modsecurity/modsecurity.h\"\n#include \"modsecurity/transaction.h\"\n#include \"src/parser/driver.h\"\n#include \"src/utils/https_client.h\"\n#include \"modsecurity/rules.h\"\n\nusing modsecurity::Parser::Driver;\nusing modsecurity::Utils::HttpsClient;\n\nnamespace modsecurity {\n\n\n/**\n * @name    loadFromUri\n * @brief   load rules from a give uri\n * @ingroup ModSecCore\n *\n * Load the rules from a given uri into memory in\n * the format expected by ModSecurity core.\n *\n * @param uri Full path to the rules file.\n *\n * @return Number of rules loaded, -1 if failed.\n * @retval true  Rules where loaded successfully.\n * @retval false Problem loading the rules.\n *\n */\nint RulesSet::loadFromUri(const char *uri) {\n    Driver *driver = new Driver();\n\n    if (driver->parseFile(uri) == 0) {\n        m_parserError << driver->m_parserError.str();\n        delete driver;\n        return -1;\n    }\n\n    int rules = this->merge(driver);\n    delete driver;\n\n    return rules;\n}\n\n\nint RulesSet::load(const char *file, const std::string &ref) {\n    Driver *driver = new Driver();\n\n    if (driver->parse(file, ref) == 0) {\n        m_parserError << driver->m_parserError.str();\n        delete driver;\n        return -1;\n    }\n    int rules = this->merge(driver);\n    if (rules == -1) {\n        m_parserError << driver->m_parserError.str();\n        delete driver;\n        return -1;\n    }\n    delete driver;\n\n    return rules;\n}\n\n\nint RulesSet::loadRemote(const char *key, const char *uri) {\n    HttpsClient client;\n    client.setKey(key);\n    bool ret = client.download(uri);\n\n    if (ret) {\n        return this->load(client.content.c_str(), uri);\n    }\n\n    return -1;\n}\n\n\nint RulesSet::load(const char *plainRules) {\n    return this->load(plainRules, \"\");\n}\n\n\nstd::string RulesSet::getParserError() const {\n    return this->m_parserError.str();\n}\n\nstd::string RulesSet::getParserError() {\n    return static_cast<const RulesSet&>(*this).getParserError();\n}\n\nvoid RulesSet::cleanMatchedVars(Transaction *trans) {\n    ms_dbg_a(trans, 9, \"Matched vars cleaned.\");\n    // cppcheck-suppress ctunullpointer\n    trans->m_variableMatchedVar.unset();\n    trans->m_variableMatchedVars.unset();\n    trans->m_variableMatchedVarName.unset();\n    trans->m_variableMatchedVarsNames.unset();\n}\n\nint RulesSet::evaluate(int phase, Transaction *t) {\n    if (phase >= modsecurity::Phases::NUMBER_OF_PHASES) {\n       return 0;\n    }\n\n    const Rules *rules = m_rulesSetPhases[phase];\n\n    ms_dbg_a(t, 9, \"This phase consists of \" \\\n        + std::to_string(rules->size()) + \" rule(s).\");\n\n    if (t->m_allowType == actions::disruptive::FromNowOnAllowType\n        && phase != modsecurity::Phases::LoggingPhase) {\n        ms_dbg_a(t, 9, \"Skipping all rules evaluation on this phase as request \" \\\n            \"through the utilization of an `allow' action.\");\n        return true;\n    }\n    if (t->m_allowType == actions::disruptive::RequestAllowType\n        && phase <= modsecurity::Phases::RequestBodyPhase) {\n        ms_dbg_a(t, 9, \"Skipping all rules evaluation on this phase as request \" \\\n            \"through the utilization of an `allow' action.\");\n        return true;\n    }\n    //if (t->m_allowType != actions::disruptive::NoneAllowType) {\n    t->m_allowType = actions::disruptive::NoneAllowType;\n    //}\n\n    for (int i = 0; i < rules->size(); i++) {\n        // FIXME: This is not meant to be here. At the end of this refactoring,\n        //        the shared pointer won't be used.\n        auto rule = rules->at(i);\n        if (t->isInsideAMarker() && !rule->isMarker()) {\n            ms_dbg_a(t, 9, \"Skipped rule id '\" + rule->getReference() \\\n                + \"' due to a SecMarker: \" + *t->getCurrentMarker());\n\n        } else if (rule->isMarker()) {\n            rule->evaluate(t);\n        } else if (t->m_skip_next > 0) {\n            t->m_skip_next--;\n            ms_dbg_a(t, 9, \"Skipped rule id '\" + rule->getReference() \\\n                + \"' due to a `skip' action. Still \" + \\\n                std::to_string(t->m_skip_next) + \" to be skipped.\");\n        } else if (t->m_allowType\n            != actions::disruptive::NoneAllowType) {\n            ms_dbg_a(t, 9, \"Skipped rule id '\" + rule->getReference() \\\n                + \"' as request trough the utilization of an `allow' action.\");\n        } else {\n            Rule *base = rule.get();\n            RuleWithActions *ruleWithActions = dynamic_cast<RuleWithActions *>(base);\n            // FIXME: Those should be treated inside the rule itself\n            if (ruleWithActions && m_exceptions.contains(ruleWithActions->m_ruleId)) {\n                ms_dbg_a(t, 9, \"Skipped rule id '\" + rule->getReference() \\\n                    + \"'. Removed by an SecRuleRemove directive.\");\n                continue;\n            }\n            bool remove_rule = false;\n            if (ruleWithActions && m_exceptions.m_remove_rule_by_msg.empty() == false) {\n                for (const auto &z : m_exceptions.m_remove_rule_by_msg) {\n                    if (ruleWithActions->containsMsg(z, t) == true) {\n                        ms_dbg_a(t, 9, \"Skipped rule id '\" \\\n                            + ruleWithActions->getReference() \\\n                            + \"'. Removed by a SecRuleRemoveByMsg directive.\");\n                        remove_rule = true;\n                        break;\n                    }\n                }\n                if (remove_rule) {\n                    continue;\n                }\n            }\n\n            if (ruleWithActions && m_exceptions.m_remove_rule_by_tag.empty() == false) {\n                for (const auto &z : m_exceptions.m_remove_rule_by_tag) {\n                    if (ruleWithActions->containsTag(z, t) == true) {\n                        ms_dbg_a(t, 9, \"Skipped rule id '\" \\\n                            + ruleWithActions->getReference() \\\n                            + \"'. Removed by a SecRuleRemoveByTag directive.\");\n                        remove_rule = true;\n                        break;\n                    }\n                }\n                if (remove_rule) {\n                    continue;\n                }\n            }\n\n\n            if (ruleWithActions) {\n                for (const auto &z : t->m_ruleRemoveByTag) {\n                    if (ruleWithActions->containsTag(z, t) == true) {\n                        ms_dbg_a(t, 9, \"Skipped rule id '\" \\\n                            + ruleWithActions->getReference() \\\n                            + \"'. Skipped due to a ruleRemoveByTag action.\");\n                        remove_rule = true;\n                        break;\n                    }\n                }\n                if (remove_rule) {\n                    continue;\n                }\n            }\n\n            rule->evaluate(t);\n            cleanMatchedVars(t);\n            if (t->m_it.disruptive > 0) {\n\n                ms_dbg_a(t, 8, \"Skipping this phase as this \" \\\n                    \"request was already intercepted.\");\n                break;\n            }\n        }\n    }\n    return 1;\n}\n\n\nint RulesSet::merge(Driver *from) {\n    int amount_of_rules = 0;\n\n    amount_of_rules = m_rulesSetPhases.append(&from->m_rulesSetPhases,\n        &m_parserError);\n    mergeProperties(\n        dynamic_cast<RulesSetProperties *>(from),\n        dynamic_cast<RulesSetProperties *>(this),\n        &m_parserError);\n\n    return amount_of_rules;\n}\n\n\nint RulesSet::merge(RulesSet *from) {\n    int amount_of_rules = 0;\n\n    amount_of_rules = m_rulesSetPhases.append(&from->m_rulesSetPhases,\n        &m_parserError);\n    mergeProperties(\n        dynamic_cast<RulesSetProperties *>(from),\n        dynamic_cast<RulesSetProperties *>(this),\n        &m_parserError);\n\n    return amount_of_rules;\n}\n\n\nvoid RulesSet::debug(int level, const std::string &id,\n    const std::string &uri, const std::string &msg) {\n    if (m_debugLog != NULL) {\n        m_debugLog->write(level, id, uri, msg);\n    }\n}\n\n\nvoid RulesSet::dump() const {\n    m_rulesSetPhases.dump();\n}\n\n\nextern \"C\" RulesSet *msc_create_rules_set(void) {\n    return new RulesSet();\n}\n\n\nextern \"C\" void msc_rules_dump(const RulesSet *rules) {\n    rules->dump();\n}\n\n\nextern \"C\" int msc_rules_merge(RulesSet *rules_dst,\n    RulesSet *rules_from, const char **error) {\n    int ret = rules_dst->merge(rules_from);\n    if (ret < 0) {\n        *error = strdup(rules_dst->getParserError().c_str());\n    }\n    return ret;\n}\n\n\nextern \"C\" int msc_rules_add_remote(RulesSet *rules,\n    const char *key, const char *uri, const char **error) {\n    int ret = rules->loadRemote(key, uri);\n    if (ret < 0) {\n        *error = strdup(rules->getParserError().c_str());\n    }\n    return ret;\n}\n\n\nextern \"C\" int msc_rules_add_file(RulesSet *rules, const char *file,\n    const char **error) {\n    int ret = rules->loadFromUri(file);\n    if (ret < 0) {\n        *error = strdup(rules->getParserError().c_str());\n    }\n    return ret;\n}\n\n\nextern \"C\" int msc_rules_add(RulesSet *rules, const char *plain_rules,\n    const char **error) {\n    int ret = rules->load(plain_rules);\n    if (ret < 0) {\n        *error = strdup(rules->getParserError().c_str());\n    }\n    return ret;\n}\n\n\n/**\n * @name    msc_rules_error_cleanup\n * @brief   Deallocates an error message buffer returned by a msc_rules_xxx function.\n *\n * This is a helper function to free the error message buffer allocated\n * by a msc_rules_xxx function.\n *\n * @param error Error message pointer.\n *\n */\nextern \"C\" void msc_rules_error_cleanup(const char *error) {\n    free((void*) error);\n}\n\n\nextern \"C\" int msc_rules_cleanup(RulesSet *rules) {\n    delete rules;\n    return true;\n}\n\n\n}  // namespace modsecurity\n\n"
  },
  {
    "path": "src/rules_set_phases.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <ctime>\n#include <iostream>\n#include <fstream>\n#include <string>\n#include <vector>\n\n#include \"modsecurity/rules_set_phases.h\"\n#include \"modsecurity/rule.h\"\n#include \"modsecurity/rules.h\"\n#include \"modsecurity/modsecurity.h\"\n\n\n\nnamespace modsecurity {\n\n\nbool RulesSetPhases::insert(std::shared_ptr<Rule> rule) {\n    if (rule->getPhase() >= modsecurity::Phases::NUMBER_OF_PHASES) {\n        return false;\n    }\n    m_rulesAtPhase[rule->getPhase()].insert(rule);\n\n    return true;\n}\n\n\nint RulesSetPhases::append(RulesSetPhases *from, std::ostringstream *err) {\n    int amount_of_rules = 0;\n    std::vector<int64_t> v;\n\n    for (int i = 0; i < modsecurity::Phases::NUMBER_OF_PHASES; i++) {\n        v.reserve(m_rulesAtPhase[i].size());\n        for (const auto &r : m_rulesAtPhase[i].m_rules) {\n            const auto *rule_ckc = dynamic_cast<const RuleWithOperator *>(r.get());\n            if (!rule_ckc) {\n                continue;\n            }\n            v.push_back(rule_ckc->m_ruleId);\n        }\n    }\n    std::sort (v.begin(), v.end());\n\n    for (int phase = 0; phase < modsecurity::Phases::NUMBER_OF_PHASES; phase++) {\n        int res = m_rulesAtPhase[phase].append(from->at(phase), v, err);\n        if (res < 0) {\n            return res;\n        }\n        amount_of_rules = amount_of_rules + res;\n    }\n\n    return amount_of_rules;\n}\n\nvoid RulesSetPhases::dump() const {\n    for (int i = 0; i <= modsecurity::Phases::NUMBER_OF_PHASES; i++) {\n        std::cout << \"Phase: \" << std::to_string(i);\n        std::cout << \" (\" << std::to_string(m_rulesAtPhase[i].size());\n        std::cout << \" rules)\" << std::endl;\n        m_rulesAtPhase[i].dump();\n    }\n}\n\n\n}  // namespace modsecurity\n\n"
  },
  {
    "path": "src/rules_set_properties.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <string>\n\n#include \"modsecurity/rules_set_properties.h\"\n#include \"src/utils/string.h\"\n#include \"src/variables/variable.h\"\n\n#ifdef WIN32\n#include \"src/compat/msvc.h\"\n#endif\n\nnamespace modsecurity {\n\n\nvoid ConfigUnicodeMap::loadConfig(std::string f, double configCodePage,\n    RulesSetProperties *driver, std::string *errg) {\n    char *buf = NULL;\n    char *hmap = NULL;\n    const char *p = NULL;\n    char *savedptr = NULL;\n    int found = 0;\n    int length = 0;\n    int processing = 0;\n\n    driver->m_unicodeMapTable.m_set = true;\n    driver->m_unicodeMapTable.m_unicodeCodePage = configCodePage;\n\n    driver->m_unicodeMapTable.m_unicodeMapTable.reset(new modsecurity::UnicodeMapHolder());\n\n    /* Setting some unicode values - http://tools.ietf.org/html/rfc3490#section-3.1 */\n    /* Set 0x3002 -> 0x2e */\n    driver->m_unicodeMapTable.m_unicodeMapTable->change(0x3002, 0x2e);\n    /* Set 0xFF61 -> 0x2e */\n    driver->m_unicodeMapTable.m_unicodeMapTable->change(0xff61, 0x2e);\n    /* Set 0xFF0E -> 0x2e */\n    driver->m_unicodeMapTable.m_unicodeMapTable->change(0xff0e, 0x2e);\n    /* Set 0x002E -> 0x2e */\n    driver->m_unicodeMapTable.m_unicodeMapTable->change(0x002e, 0x2e);\n\n\n    std::ifstream file_stream(f, std::ios::in | std::ios::binary);\n    if (file_stream) {\n        file_stream.seekg (0, file_stream.end);\n        length = file_stream.tellg();\n        file_stream.seekg (0, file_stream.beg);\n    } else {\n        std::stringstream ss;\n        ss << \"Failed to open the unicode map file from: \" << f << \" \";\n        errg->assign(ss.str());\n        return;\n    }\n\n    if (length <= 0) {\n        std::stringstream ss;\n        ss << \"Failed to open the unicode map file from: \" << f << \" \";\n        errg->assign(ss.str());\n        return;\n    }\n\n    buf = new char[length+1];\n    if (!buf) {\n        std::stringstream ss;\n        ss << \"Failed to open the unicode map file from: \" << f << \" \";\n        errg->assign(ss.str());\n        return;\n    }\n\n    memset(buf, '\\0', (sizeof(char)*(length+1)));\n\n    file_stream.read(buf, length);\n    file_stream.close();\n\n    p = strtok_r(buf, CODEPAGE_SEPARATORS, &savedptr);\n\n    while (p != NULL) {\n        unsigned int codepage = atol(p);\n\n        if (codepage == configCodePage) {\n            found = 1;\n        }\n\n        if (found == 1 && (strchr(p,':') != NULL))   {\n            char *mapping = strdup(p);\n            processing = 1;\n\n            if (mapping != NULL) {\n                const char *ucode = strtok_r(mapping, \":\", &hmap);\n                int code = strtol(ucode, nullptr, 16);\n                int map = strtol(hmap, nullptr, 16);\n                if (code >= 0 && code <= 65535)    {\n                    driver->m_unicodeMapTable.m_unicodeMapTable->change(code, map);\n                }\n\n                free(mapping);\n                mapping = NULL;\n            }\n        }\n\n        if (processing == 1 && (strchr(p,':') == NULL)) {\n            break;\n        }\n\n        if (!savedptr) {\n            break;\n        }\n\n        p = strtok_r(NULL, CODEPAGE_SEPARATORS, &savedptr);\n    }\n\n    delete[] buf;\n}\n\n\n}  // namespace modsecurity\n\n"
  },
  {
    "path": "src/run_time_string.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n\n#include <memory>\n\n#include \"src/run_time_string.h\"\n\n#include \"modsecurity/variable_value.h\"\n#include \"modsecurity/transaction.h\"\n#include \"src/variables/rule.h\"\n#include \"src/variables/tx.h\"\n#include \"src/variables/highest_severity.h\"\n#include \"src/utils/string.h\"\n#include \"src/variables/variable.h\"\n\n\nnamespace modsecurity {\n\n\nvoid RunTimeString::appendText(const std::string &text) {\n    auto r = std::make_unique<RunTimeElementHolder>();\n    r->m_string = text;\n    m_elements.push_back(std::move(r));\n}\n\n\nvoid RunTimeString::appendVar(\n    std::unique_ptr<modsecurity::variables::Variable> var) {\n    auto r = std::make_unique<RunTimeElementHolder>();\n    r->m_var = std::move(var);\n    m_elements.push_back(std::move(r));\n    m_containsMacro = true;\n}\n\n\nstd::string RunTimeString::evaluate(Transaction *t) {\n    return evaluate(t, NULL);\n}\n\n\nstd::string RunTimeString::evaluate(Transaction *t, Rule *r) {\n    std::string s;\n    for (auto &z : m_elements) {\n        if (z->m_string.size() > 0) {\n            s.append(z->m_string);\n        } else if (z->m_var != NULL && t != NULL) {\n            std::vector<const VariableValue *> l;\n            // FIXME: This cast should be removed.\n            RuleWithOperator *rr = dynamic_cast<RuleWithOperator *>(r);\n            z->m_var->evaluate(t, rr, &l);\n            if (l.size() > 0) {\n                s.append(l[0]->getValue());\n            }\n            for (auto &i : l) {\n                delete i;\n            }\n        }\n    }\n    return s;\n}\n\n}  // namespace modsecurity\n"
  },
  {
    "path": "src/run_time_string.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n\n#include <ctime>\n#include <iostream>\n#include <string>\n#include <vector>\n#include <memory>\n#include <list>\n#include <utility>\n\n#include \"modsecurity/modsecurity.h\"\n#include \"modsecurity/transaction.h\"\n#include \"src/variables/variable.h\"\n\n\n#ifndef SRC_RUN_TIME_STRING_H_\n#define SRC_RUN_TIME_STRING_H_\n\nnamespace modsecurity {\n\nclass RunTimeElementHolder {\n public:\n    RunTimeElementHolder() :\n        m_string(\"\") {\n            m_var.reset(NULL);\n        }\n    std::unique_ptr<modsecurity::variables::Variable> m_var;\n    std::string m_string;\n};\n\nclass RunTimeString {\n public:\n    RunTimeString() :\n        m_containsMacro(false) { }\n    void appendText(const std::string &text);\n    void appendVar(std::unique_ptr<modsecurity::variables::Variable> var);\n    std::string evaluate(Transaction *t);\n    std::string evaluate(Transaction *t, Rule *r);\n    std::string evaluate() {\n        return evaluate(NULL);\n    }\n    inline bool containsMacro() const { return m_containsMacro; }\n    bool m_containsMacro;\n\n protected:\n    std::list<std::unique_ptr<RunTimeElementHolder>> m_elements;\n};\n\n\n}  // namespace modsecurity\n\n\n\n#endif  // SRC_RUN_TIME_STRING_H_\n"
  },
  {
    "path": "src/transaction.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2023 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"modsecurity/transaction.h\"\n\n#ifdef WITH_YAJL\n#include <yajl/yajl_tree.h>\n#include <yajl/yajl_gen.h>\n#endif\n\n#include <stdio.h>\n#include <string.h>\n\n#include <cstdio>\n#include <ctime>\n#include <fstream>\n#include <iomanip>\n#include <iostream>\n#include <set>\n#include <unordered_map>\n#include <vector>\n\n#include \"modsecurity/actions/action.h\"\n#include \"src/actions/disruptive/deny.h\"\n#include \"modsecurity/intervention.h\"\n#include \"modsecurity/modsecurity.h\"\n#include \"src/request_body_processor/multipart.h\"\n#include \"src/request_body_processor/xml.h\"\n#ifdef WITH_YAJL\n#include \"src/request_body_processor/json.h\"\n#endif\n#include \"modsecurity/audit_log.h\"\n#include \"src/unique_id.h\"\n#include \"src/utils/string.h\"\n#include \"src/utils/system.h\"\n#include \"src/utils/decode.h\"\n#include \"src/utils/random.h\"\n#include \"modsecurity/rule.h\"\n#include \"modsecurity/rule_message.h\"\n#include \"modsecurity/rules_set_properties.h\"\n#include \"src/actions/disruptive/allow.h\"\n#include \"src/variables/remote_user.h\"\n\n#ifdef WIN32\n#include \"src/compat/msvc.h\"\n#endif\n\n\nusing modsecurity::actions::Action;\nusing modsecurity::RequestBodyProcessor::Multipart;\nusing modsecurity::RequestBodyProcessor::XML;\n\nnamespace modsecurity {\n\n/**\n * @name    Transaction\n * @brief   Represents the inspection on an entire request.\n *\n * An instance of the Transaction class represents an entire request, on its\n * different phases.\n *\n * @param ms ModSecurity core instance.\n * @param rules Rules instance.\n *\n * Example Usage:\n * @code\n *\n * using ModSecurity::ModSecurity;\n * using ModSecurity::Rules;\n * using ModSecurity::Transaction;\n *\n * ModSecurity *modsec;\n * ModSecurity::Rules *rules;\n *\n * modsec = new ModSecurity();\n * rules = new Rules();\n * rules->loadFromUri(rules_file);\n *\n * Transaction *modsecTransaction = new Transaction(modsec, rules);\n * modsecTransaction->processConnection(\"127.0.0.1\", 33333, \"127.0.0.1\", 8080);\n *\n * if (modsecTransaction->intervention()) {\n *     std::cout << \"There is an intervention\" << std::endl;\n * }\n *\n * ...\n *\n * delete modsecTransaction;\n *\n * @endcode\n *\n */\n\nstatic std::string get_id(const char *id, const time_t timestamp) {\n    return (id == nullptr) ?\n        std::to_string(timestamp) +\n            std::to_string(modsecurity::utils::generate_transaction_unique_id())\n        : id;\n}\n\nTransaction::Transaction(ModSecurity *ms, RulesSet *rules, void *logCbData)\n    : Transaction(ms, rules, nullptr, logCbData) { }\n\nTransaction::Transaction(ModSecurity *ms, RulesSet *rules, const char *id, void *logCbData)\n    : Transaction(ms, rules, id, logCbData, std::time(nullptr)) { }\n\nTransaction::Transaction(ModSecurity *ms, RulesSet *rules, const char *id,\n    void *logCbData, const time_t timestamp)\n    : m_creationTimeStamp(utils::cpu_seconds()),\n    m_ARGScombinedSizeDouble(0),\n    m_clientPort(0),\n    m_highestSeverityAction(255),\n    m_httpCodeReturned(200),\n    m_serverPort(0),\n    m_ms(ms),\n    m_requestBodyType(UnknownFormat),\n    m_requestBodyProcessor(UnknownFormat),\n    m_rules(rules),\n    m_requestBodyAccess(RulesSet::PropertyNotSetConfigBoolean),\n    m_ctlAuditEngine(AuditLog::AuditLogStatus::NotSetLogStatus),\n    m_id(get_id(id, timestamp)),\n    m_skip_next(0),\n    m_allowType(modsecurity::actions::disruptive::NoneAllowType),\n    m_timeStamp(timestamp),\n    m_collections(ms->m_global_collection, ms->m_ip_collection,\n        ms->m_session_collection, ms->m_user_collection,\n        ms->m_resource_collection),\n#ifdef WITH_LIBXML2\n    m_xml(new RequestBodyProcessor::XML(this)),\n#else\n    m_xml(nullptr),\n#endif\n#ifdef WITH_YAJL\n    m_json(new RequestBodyProcessor::JSON(this)),\n#else\n    m_json(nullptr),\n#endif\n    m_secRuleEngine(RulesSetProperties::PropertyNotSetRuleEngine),\n    m_secXMLParseXmlIntoArgs(rules->m_secXMLParseXmlIntoArgs),\n    m_logCbData(logCbData),\n    TransactionAnchoredVariables(this) {\n    m_variableUrlEncodedError.set(\"0\", 0);\n    m_variableMscPcreError.set(\"0\", 0);\n    m_variableMscPcreLimitsExceeded.set(\"0\", 0);\n\n    ms_dbg(4, \"Initializing transaction\");\n\n    intervention::clean(&m_it);\n}\n\n\nTransaction::~Transaction() {\n    m_responseBody.str(std::string());\n    m_responseBody.clear();\n\n    m_requestBody.str(std::string());\n    m_requestBody.clear();\n\n    m_rulesMessages.clear();\n\n    intervention::free(&m_it);\n    intervention::clean(&m_it);\n\n#ifdef WITH_YAJL\n    delete m_json;\n#endif\n#ifdef WITH_LIBXML2\n    delete m_xml;\n#endif\n}\n\n\n/**\n * @name    debug\n * @brief   Prints a message on the debug logs.\n *\n * Debug logs are important during the rules creation phase, this method can be\n * used to print message on this debug log.\n *\n * @param level Debug level, current supported from 0 to 9.\n * @param message Message to be logged.\n *\n */\n#ifndef NO_LOGS\nvoid Transaction::debug(int level, const std::string& message) const {\n    if (m_rules == NULL) {\n        return;\n    }\n\n    m_rules->debug(level, m_id, m_uri, message);\n}\n#endif\n\n/**\n * @name    processConnection\n * @brief   Perform the analysis on the connection.\n *\n * This method should be called at very beginning of a request process, it is\n * expected to be executed prior to the virtual host resolution, when the\n * connection arrives on the server.\n *\n * @note Remember to check for a possible intervention.\n *\n * @param transaction ModSecurity Transaction.\n * @param client Client's IP address in text format.\n * @param cPort Client's port\n * @param server Server's IP address in text format.\n * @param sPort Server's port\n *\n * @returns If the operation was successful or not.\n * @retval true Operation was successful.\n * @retval false Operation failed.\n *\n */\nint Transaction::processConnection(const char *client, int cPort,\n    const char *server, int sPort) {\n    m_clientIpAddress = client;\n    m_serverIpAddress = server;\n    if (m_requestHostName.empty() == true) {\n        m_requestHostName = server;\n    }\n    this->m_clientPort = cPort;\n    this->m_serverPort = sPort;\n    ms_dbg(4, \"Transaction context created.\");\n    ms_dbg(4, \"Starting phase CONNECTION. (SecRules 0)\");\n\n\n    m_variableRemoteHost.set(m_clientIpAddress, m_variableOffset);\n    m_variableUniqueID.set(m_id, m_variableOffset);\n    m_variableRemoteAddr.set(m_clientIpAddress, m_variableOffset);\n    m_variableServerAddr.set(m_serverIpAddress, m_variableOffset);\n    m_variableServerPort.set(std::to_string(this->m_serverPort),\n        m_variableOffset);\n    m_variableRemotePort.set(std::to_string(this->m_clientPort),\n        m_variableOffset);\n\n    this->m_rules->evaluate(modsecurity::ConnectionPhase, this);\n    return true;\n}\n\n\nbool Transaction::extractArguments(const std::string &orig,\n    const std::string& buf, size_t offset) {\n    char sep1 = '&';\n    if (m_rules->m_secArgumentSeparator.m_set) {\n        sep1 = m_rules->m_secArgumentSeparator.m_value.at(0);\n    }\n    const auto key_value_sets = utils::string::ssplit(buf, sep1);\n\n    for (const auto &t : key_value_sets) {\n        const auto sep2 = '=';\n        auto [key, value] = utils::string::ssplit_pair(t, sep2);\n\n        int invalid_count;\n        utils::urldecode_nonstrict_inplace(key, invalid_count);\n        utils::urldecode_nonstrict_inplace(value, invalid_count);\n\n        if (invalid_count > 0) {\n            m_variableUrlEncodedError.set(\"1\", m_variableOffset);\n        }\n\n        addArgument(orig, key, value, offset);\n        offset = offset + t.size() + 1;\n    }\n\n    return true;\n}\n\n\nbool Transaction::addArgument(const std::string& orig, const std::string& key,\n    const std::string& value, size_t offset) {\n    ms_dbg(4, \"Adding request argument (\" + orig + \"): name \\\"\" + \\\n                key + \"\\\", value \\\"\" + value + \"\\\"\");\n\n    if (m_rules->m_argumentsLimit.m_set\n            && m_variableArgs.size() >= m_rules->m_argumentsLimit.m_value) {\n        ms_dbg(4, \"Skipping request argument, over limit (\" + std::to_string(m_rules->m_argumentsLimit.m_value) + \")\")\n        return false;\n    }\n\n    offset = offset + key.size() + 1;\n    m_variableArgs.set(key, value, offset);\n\n    if (orig == \"GET\") {\n        m_variableArgsGet.set(key, value, offset);\n    } else if (orig == \"POST\") {\n        m_variableArgsPost.set(key, value, offset);\n    }\n\n    m_ARGScombinedSizeDouble = m_ARGScombinedSizeDouble + \\\n        key.length() + value.length();\n\n    m_variableARGScombinedSize.set(std::to_string(m_ARGScombinedSizeDouble),\n        offset - key.size() - 1, key.size());\n    m_variableARGScombinedSize.set(std::to_string(m_ARGScombinedSizeDouble),\n        offset, value.length());\n\n    return true;\n}\n\n\n/**\n * @name    processURI\n * @brief   Perform the analysis on the URI and all the query string variables.\n *\n * This method should be called at very beginning of a request process, it is\n * expected to be executed prior to the virtual host resolution, when the\n * connection arrives on the server.\n *\n * @note There is no direct connection between this function and any phase of\n *       the SecLanguage's phases. It is something that may occur between the\n *       SecLanguage phase 1 and 2.\n * @note Remember to check for a possible intervention.\n *\n * @param transaction ModSecurity transaction.\n * @param uri   Uri.\n * @param method   Method (GET, POST, PUT).\n * @param http_version   Http version (1.0, 1.1, 2.0).\n *\n * @returns If the operation was successful or not.\n * @retval true Operation was successful.\n * @retval false Operation failed.\n *\n */\nint Transaction::processURI(const char *uri, const char *method,\n    const char *http_version) {\n\n    ms_dbg(4, \"Starting phase URI. (SecRules 0 + 1/2)\");\n\n    m_httpVersion = http_version;\n    m_uri = uri;\n    std::string uri_s(uri);\n\n    // any uri-fragment that was received should only be retained in\n    // - m_uri\n    // - m_variableRequestURIRaw\n    // - m_variableRequestLine\n    size_t pos_raw_fragment = uri_s.find(\"#\");\n    if (pos_raw_fragment != std::string::npos) {\n        uri_s = uri_s.substr(0, pos_raw_fragment);\n    }\n\n    size_t pos_raw_query = uri_s.find(\"?\");\n\n    std::string path_info_raw;\n    if (pos_raw_query == std::string::npos) {\n        path_info_raw = std::string(uri_s, 0);\n    } else {\n        path_info_raw = std::string(uri_s, 0, pos_raw_query);\n    }\n    std::string path_info = utils::uri_decode(path_info_raw);\n\n    m_uri_decoded = utils::uri_decode(uri_s);\n\n    size_t var_size = pos_raw_query;\n\n    m_variableRequestMethod.set(method, 0);\n\n\n    std::string requestLine(std::string(method) + \" \" + std::string(uri));\n    m_variableRequestLine.set(requestLine \\\n        + \" HTTP/\" + std::string(http_version), m_variableOffset);\n\n    m_variableRequestProtocol.set(\"HTTP/\" + std::string(http_version),\n        m_variableOffset + requestLine.size() + 1);\n\n    m_uri_no_query_string_decoded = path_info;\n\n    if (pos_raw_query != std::string::npos) {\n        std::string qry = std::string(uri_s, pos_raw_query + 1,\n            uri_s.length() - (pos_raw_query + 1));\n        m_variableQueryString.set(qry, pos_raw_query + 1\n            + std::string(method).size() + 1);\n    }\n\n\n    if (var_size == std::string::npos) {\n        var_size = uri_s.size();\n    }\n\n    m_variablePathInfo.set(path_info, m_variableOffset + strlen(method) +\n        1, var_size);\n    m_variableRequestFilename.set(path_info,  m_variableOffset +\n        strlen(method) + 1, var_size);\n\n\n    size_t offset = path_info.find_last_of(\"/\\\\\");\n    if (offset != std::string::npos && path_info.length() > offset + 1) {\n        std::string basename = std::string(path_info, offset + 1,\n            path_info.length() - (offset + 1));\n        m_variableRequestBasename.set(basename, m_variableOffset +\n            strlen(method) + 1 + offset + 1);\n    }\n\n    m_variableOffset = m_variableRequestLine.m_value.size();\n\n    std::string parsedURI = m_uri_decoded;\n    // The more popular case is without domain\n    if (!m_uri_decoded.empty() && m_uri_decoded[0] != '/') {\n        bool fullDomain = true;\n        size_t scheme = m_uri_decoded.find(\":\")+1;\n        if (scheme == std::string::npos) {\n            fullDomain = false;\n        }\n        // Searching with a pos of -1 is undefined we also shortcut\n        if (scheme != std::string::npos && fullDomain == true) {\n            // Assuming we found a colon make sure its followed\n            size_t netloc = m_uri_decoded.find(\"//\", scheme) + 2;\n            if (netloc == std::string::npos || (netloc != scheme + 2)) {\n                fullDomain = false;\n            }\n            if (netloc != std::string::npos && fullDomain == true) {\n                size_t path = m_uri_decoded.find(\"/\", netloc);\n                if (path != std::string::npos) {\n                    parsedURI = m_uri_decoded.substr(path);\n                }\n            }\n        }\n    }\n\n    m_variableRequestURI.set(parsedURI, std::string(method).size() + 1,\n        uri_s.size());\n    m_variableRequestURIRaw.set(uri, std::string(method).size() + 1);\n\n    if (m_variableQueryString.m_value.empty() == false) {\n        extractArguments(\"GET\", m_variableQueryString.m_value,\n            m_variableQueryString.m_offset);\n    }\n\n    m_variableOffset = m_variableOffset + 1;\n    return true;\n}\n\n\n/**\n * @name    processRequestHeaders\n * @brief   Perform the analysis on the request readers.\n *\n * This method perform the analysis on the request headers, notice however\n * that the headers should be added prior to the execution of this function.\n *\n * @note Remember to check for a possible intervention.\n *\n * @returns If the operation was successful or not.\n * @retval true Operation was successful.\n * @retval false Operation failed.\n *\n */\nint Transaction::processRequestHeaders() {\n    ms_dbg(4, \"Starting phase REQUEST_HEADERS.  (SecRules 1)\");\n\n    if (getRuleEngineState() == RulesSet::DisabledRuleEngine) {\n        ms_dbg(4, \"Rule engine disabled, returning...\");\n        return true;\n    }\n\n    this->m_rules->evaluate(modsecurity::RequestHeadersPhase, this);\n\n    return true;\n}\n\n\n/**\n * @name    addRequestHeader\n * @brief   Adds a request header\n *\n * With this method it is possible to feed ModSecurity with a request header.\n *\n * @note This function expects a NULL terminated string, for both: key and\n *       value.\n *\n * @param key   header name.\n * @param value header value.\n *\n * @returns If the operation was successful or not.\n * @retval true Operation was successful.\n * @retval false Operation failed.\n *\n */\nint Transaction::addRequestHeader(const std::string& key,\n    const std::string& value) {\n    m_variableRequestHeadersNames.set(key, key, m_variableOffset);\n\n    m_variableOffset = m_variableOffset + key.size() + 2;\n    m_variableRequestHeaders.set(key, value, m_variableOffset);\n\n\n    std::string keyl = utils::string::tolower(key);\n    if (keyl == \"authorization\") {\n        std::vector<std::string> type = utils::string::split(value, ' ');\n        m_variableAuthType.set(type[0], m_variableOffset);\n    }\n\n    if (keyl == \"cookie\") {\n        size_t localOffset = m_variableOffset;\n        size_t pos;\n\n        std::vector<std::string> cookies = utils::string::ssplit(value, ';');\n\n        if (!cookies.empty()) {\n            // Get rid of any optional whitespace after the cookie-string\n            // (i.e. after the end of the final cookie-pair)\n            std::string& final_cookie_pair = cookies.back();\n            while (!final_cookie_pair.empty() && isspace(final_cookie_pair.back())) {\n                final_cookie_pair.pop_back();\n            }\n        }\n\n        for (const std::string &c : cookies) {\n            // skip empty substring, eg \"Cookie: ;;foo=bar\"\n            if (c.empty() == true) {\n                localOffset++; // add length of ';'\n                continue;\n            }\n\n            // find the first '='\n            pos = c.find_first_of(\"=\", 0);\n            std::string ckey;\n            std::string cval = \"\";\n\n            // if the cookie doesn't contains '=', its just a key\n            if (pos == std::string::npos) {\n                ckey = c;\n            }\n            // else split to two substrings by first =\n            else {\n                ckey = c.substr(0, pos);\n                // value will contains the next '=' chars if exists\n                // eg. foo=bar=baz -> key: foo, value: bar=baz\n                cval = c.substr(pos+1);\n            }\n\n            // ltrim the key - following the modsec v2 way\n            while (ckey.empty() == false && isspace(ckey[0])) {\n                ckey.erase(0, 1);\n                localOffset++;\n            }\n\n            // if the key is empty (eg: \"Cookie:   =bar;\") skip it\n            if (ckey.empty() == true) {\n                localOffset = localOffset + c.length() + 1;\n                continue;\n            }\n            else {\n                // handle cookie only if the key is not empty\n                // set cookie name\n                m_variableRequestCookiesNames.set(ckey,\n                        ckey, localOffset);\n                localOffset = localOffset + ckey.size() + 1;\n                // set cookie value\n                m_variableRequestCookies.set(ckey, cval,\n                        localOffset);\n                localOffset = localOffset + cval.size() + 1;\n            }\n        }\n    }\n    /**\n     * Simple check to decide the request body content. This is not the right\n     * place, the \"body processor\" should be able to tell what he is capable\n     * to deal with.\n     *\n     */\n\n    if (keyl == \"content-type\") {\n        std::string multipart(\"multipart/form-data\");\n        std::string urlencoded(\"application/x-www-form-urlencoded\");\n        std::string l = utils::string::tolower(value);\n        if (l.compare(0, multipart.length(), multipart) == 0) {\n            this->m_requestBodyType = MultiPartRequestBody;\n            m_variableReqbodyProcessor.set(\"MULTIPART\", m_variableOffset);\n        }\n\n        if (l.compare(0, urlencoded.length(), urlencoded) == 0) {\n            this->m_requestBodyType = WWWFormUrlEncoded;\n            m_variableReqbodyProcessor.set(\"URLENCODED\", m_variableOffset);\n        }\n    }\n\n    if (keyl == \"host\") {\n        std::vector<std::string> host = utils::string::split(value, ':');\n        m_variableServerName.set(host[0], m_variableOffset);\n    }\n    m_variableOffset = m_variableOffset + value.size() + 1;\n\n    return 1;\n}\n\n\n/**\n * @name    addRequestHeader\n * @brief   Adds a request header\n *\n * With this method it is possible to feed ModSecurity with a request header.\n *\n * @note This function expects a NULL terminated string, for both: key and\n *       value.\n *\n * @param key   header name.\n * @param value header value.\n *\n * @returns If the operation was successful or not.\n * @retval true Operation was successful.\n * @retval false Operation failed.\n *\n */\nint Transaction::addRequestHeader(const unsigned char *key,\n    const unsigned char *value) {\n    return this->addRequestHeader(key,\n        strlen(reinterpret_cast<const char *>(key)),\n        value,\n        strlen(reinterpret_cast<const char *>(value)));\n}\n\n\n/**\n * @name    addRequestHeader\n * @brief   Adds a request header\n *\n * Do not expect a NULL terminated string, instead it expect the string and the\n * string size, for the value and key.\n *\n * @param transaction   ModSecurity transaction.\n * @param key     header name.\n * @param key_n   header name size.\n * @param value   header value.\n * @param value_n header value size.\n *\n * @returns If the operation was successful or not.\n * @retval 1 Operation was successful.\n * @retval 0 Operation failed.\n *\n */\nint Transaction::addRequestHeader(const unsigned char *key, size_t key_n,\n    const unsigned char *value, size_t value_n) {\n    std::string keys;\n    std::string values;\n\n    keys.assign(reinterpret_cast<const char *>(key), key_n);\n    values.assign(reinterpret_cast<const char *>(value), value_n);\n\n    return this->addRequestHeader(keys, values);\n}\n\n\n/**\n * @name    processRequestBody\n * @brief   Perform the request body (if any)\n *\n * This method perform the analysis on the request body. It is optional to\n * call that function. If this API consumer already know that there isn't a\n * body for inspect it is recommended to skip this step.\n *\n * @note It is necessary to \"append\" the request body prior to the execution\n *       of this function.\n * @note Remember to check for a possible intervention.\n *\n * @returns If the operation was successful or not.\n * @retval true Operation was successful.\n * @retval false Operation failed.\n *\n */\nint Transaction::processRequestBody() {\n    ms_dbg(4, \"Starting phase REQUEST_BODY. (SecRules 2)\");\n\n    if (getRuleEngineState() == RulesSetProperties::DisabledRuleEngine) {\n        ms_dbg(4, \"Rule engine disabled, returning...\");\n        return true;\n    }\n\n    if (m_variableInboundDataError.m_value.empty() == true) {\n        m_variableInboundDataError.set(\"0\", 0);\n    }\n\n    /*\n     * Process the request body even if there is nothing to be done.\n     *\n     * if (m_requestBody.tellp() <= 0) {\n     *     return true;\n     * }\n     *\n     */\n    std::unique_ptr<std::string> a = m_variableRequestHeaders.resolveFirst(\n        \"Content-Type\");\n\n    bool requestBodyNoFilesLimitExceeded = false;\n    if ((m_requestBodyType == WWWFormUrlEncoded) ||\n        (m_requestBodyProcessor == JSONRequestBody) ||\n        (m_requestBodyProcessor == XMLRequestBody)) {\n        if ((m_rules->m_requestBodyNoFilesLimit.m_set)\n            && (m_requestBody.str().size() > m_rules->m_requestBodyNoFilesLimit.m_value)) {\n            m_variableReqbodyError.set(\"1\", 0);\n            m_variableReqbodyErrorMsg.set(\"Request body excluding files is bigger than the maximum expected.\", 0);\n            m_variableInboundDataError.set(\"1\", m_variableOffset);\n            ms_dbg(5, \"Request body excluding files is bigger than the maximum expected. Limit: \" \\\n                + std::to_string(m_rules->m_requestBodyNoFilesLimit.m_value));\n            requestBodyNoFilesLimitExceeded = true;\n\t}\n    }\n\n#ifdef WITH_LIBXML2\n    if (m_requestBodyProcessor == XMLRequestBody) {\n        // large size might cause issues in the parsing itself; omit if exceeded\n        if (!requestBodyNoFilesLimitExceeded) {\n            std::string error;\n            if (m_xml->init() == true) {\n                m_xml->processChunk(m_requestBody.str().c_str(),\n                    m_requestBody.str().size(),\n                    &error);\n                m_xml->complete(&error);\n            }\n            if (error.empty() == false) {\n                m_variableReqbodyError.set(\"1\", m_variableOffset);\n                m_variableReqbodyErrorMsg.set(\"XML parsing error: \" + error,\n                    m_variableOffset);\n                m_variableReqbodyProcessorErrorMsg.set(\"XML parsing error: \" \\\n                    + error, m_variableOffset);\n                m_variableReqbodyProcessorError.set(\"1\", m_variableOffset);\n            } else {\n                m_variableReqbodyError.set(\"0\", m_variableOffset);\n                m_variableReqbodyProcessorError.set(\"0\", m_variableOffset);\n            }\n        }\n#endif\n#if WITH_YAJL\n#ifdef WITH_LIBXML2\n    } else if (m_requestBodyProcessor == JSONRequestBody) {\n#else\n    if (m_requestBodyProcessor == JSONRequestBody) {\n#endif\n        // large size might cause issues in the parsing itself; omit if exceeded\n        if (!requestBodyNoFilesLimitExceeded) {\n            std::string error;\n            if (m_rules->m_requestBodyJsonDepthLimit.m_set) {\n                m_json->setMaxDepth(m_rules->m_requestBodyJsonDepthLimit.m_value);\n            }\n            if (m_json->init() == true) {\n                m_json->processChunk(m_requestBody.str().c_str(),\n                    m_requestBody.str().size(),\n                    &error);\n                m_json->complete(&error);\n            }\n            if (error.empty() == false && m_requestBody.str().size() > 0) {\n                m_variableReqbodyError.set(\"1\", m_variableOffset);\n                m_variableReqbodyProcessorError.set(\"1\", m_variableOffset);\n                m_variableReqbodyErrorMsg.set(\"JSON parsing error: \" + error,\n                    m_variableOffset);\n                m_variableReqbodyProcessorErrorMsg.set(\"JSON parsing error: \" \\\n                    + error, m_variableOffset);\n            } else {\n                m_variableReqbodyError.set(\"0\", m_variableOffset);\n                m_variableReqbodyProcessorError.set(\"0\", m_variableOffset);\n            }\n        }\n#endif\n#if defined(WITH_LIBXML2) or defined(WITH_YAJL)\n    } else if (m_requestBodyType == MultiPartRequestBody) {\n#else\n    if (m_requestBodyType == MultiPartRequestBody) {\n#endif\n        std::string error;\n        int reqbodyNoFilesLength = 0;\n        if (a != NULL) {\n            Multipart m(*a, this);\n            if (m.init(&error) == true) {\n                m.process(m_requestBody.str(), &error, m_variableOffset);\n            }\n            reqbodyNoFilesLength = m.m_reqbody_no_files_length;\n            m.multipart_complete(&error);\n        }\n        if (error.empty() == false) {\n            m_variableReqbodyError.set(\"1\", m_variableOffset);\n            m_variableReqbodyProcessorError.set(\"1\", m_variableOffset);\n            m_variableReqbodyErrorMsg.set(\"Multipart parsing error: \" + error,\n                m_variableOffset);\n            m_variableReqbodyProcessorErrorMsg.set(\"Multipart parsing \" \\\n                \"error: \" + error, m_variableOffset);\n        } else if (((m_rules->m_requestBodyNoFilesLimit.m_set)\n                   && (reqbodyNoFilesLength > m_rules->m_requestBodyNoFilesLimit.m_value))) {\n            m_variableReqbodyError.set(\"1\", 0);\n            m_variableReqbodyErrorMsg.set(\"Request body excluding files is bigger than the maximum expected.\", 0);\n            m_variableInboundDataError.set(\"1\", m_variableOffset);\n            ms_dbg(5, \"Request body excluding files is bigger than the maximum expected. Limit: \" \\\n                + std::to_string(m_rules->m_requestBodyNoFilesLimit.m_value));\n        } else {\n            m_variableReqbodyError.set(\"0\", m_variableOffset);\n            m_variableReqbodyProcessorError.set(\"0\", m_variableOffset);\n        }\n    } else if (m_requestBodyType == WWWFormUrlEncoded) {\n        m_variableOffset++;\n        // large size might cause issues in the parsing itself; omit if exceeded\n        if (!requestBodyNoFilesLimitExceeded) {\n            extractArguments(\"POST\", m_requestBody.str(), m_variableOffset);\n\t}\n    } else if (m_requestBodyType != UnknownFormat) {\n        /**\n         * FIXME: double check to see if that is a valid scenario...\n         *\n         */\n        std::string error;\n        if (a != NULL && a->empty() == false) {\n            error.assign(*a);\n        }\n\n        m_variableReqbodyError.set(\"1\", m_variableOffset);\n        m_variableReqbodyProcessorError.set(\"1\", m_variableOffset);\n        m_variableReqbodyErrorMsg.set(\"Unknown request body processor: \" \\\n            + error, m_variableOffset);\n        m_variableReqbodyProcessorErrorMsg.set(\"Unknown request body \" \\\n            \"processor: \" + error, m_variableOffset);\n    } else {\n        m_variableReqbodyError.set(\"0\", m_variableOffset);\n        m_variableReqbodyProcessorError.set(\"0\", m_variableOffset);\n    }\n\n    if (m_rules->m_secRequestBodyAccess == RulesSetProperties::FalseConfigBoolean) {\n        if (m_requestBodyAccess != RulesSetProperties::TrueConfigBoolean) {\n            ms_dbg(4, \"Request body processing is disabled\");\n            return true;\n        } else {\n            ms_dbg(4, \"Request body processing is disabled, but \" \\\n                \"enabled to this transaction due to ctl:requestBodyAccess \" \\\n                \"action\");\n        }\n    } else {\n        if (m_requestBodyAccess == RulesSetProperties::FalseConfigBoolean) {\n            ms_dbg(4, \"Request body processing is enabled, but \" \\\n                \"disabled to this transaction due to ctl:requestBodyAccess \" \\\n                \"action\");\n            return true;\n        }\n    }\n\n    /**\n     * FIXME: This variable should be calculated on demand, it is\n     * computationally intensive.\n     */\n    std::string fullRequest;\n    std::vector<const VariableValue *> l;\n    m_variableRequestHeaders.resolve(&l);\n    for (auto &h : l) {\n        fullRequest = fullRequest + h->getKey() + \": \" + h->getValue() + \"\\n\";\n        delete h;\n    }\n\n    fullRequest = fullRequest + \"\\n\\n\";\n    fullRequest = fullRequest + m_requestBody.str();\n    m_variableFullRequest.set(fullRequest, m_variableOffset);\n    m_variableFullRequestLength.set(std::to_string(fullRequest.size()),\n        m_variableOffset);\n\n    if (m_requestBody.tellp() > 0) {\n        m_variableRequestBody.set(m_requestBody.str(), m_variableOffset);\n        m_variableRequestBodyLength.set(std::to_string(\n            m_requestBody.str().size()),\n            m_variableOffset, m_requestBody.str().size());\n    }\n\n    this->m_rules->evaluate(modsecurity::RequestBodyPhase, this);\n    return true;\n}\n\n\n/**\n * @name    appendRequestBody\n * @brief   Adds request body to be inspected.\n *\n * With this method it is possible to feed ModSecurity with data for\n * inspection regarding the request body. There are two possibilities here:\n *\n * 1 - Adds the buffer in a row;\n * 2 - Adds it in chunks;\n *\n * A third option should be developed which is share your application buffer.\n * In any case, remember that the utilization of this function may reduce your\n * server throughput, as this buffer creations is computationally expensive.\n *\n * @note While feeding ModSecurity remember to keep checking if there is an\n *       intervention, Sec Language has the capability to set the maximum\n *       inspection size which may be reached, and the decision on what to do\n *       in this case is upon the rules.\n *\n * @returns If the operation was successful or not.\n * @retval true Operation was successful.\n * @retval false Operation failed.\n *\n */\nint Transaction::requestBodyFromFile(const char *path) {\n    std::ifstream request_body(path);\n    std::string str;\n\n    if (request_body.is_open() == false) {\n        ms_dbg(3, \"Failed to open request body at: \" + std::string(path));\n        return false;\n    }\n\n    request_body.seekg(0, std::ios::end);\n    try {\n        str.reserve(request_body.tellg());\n    } catch (...) {\n        ms_dbg(3, \"Failed to allocate memory to load request body.\");\n        return false;\n    }\n    request_body.seekg(0, std::ios::beg);\n    str.assign((std::istreambuf_iterator<char>(request_body)),\n            std::istreambuf_iterator<char>());\n\n    const char *buf = str.c_str();\n    int len = request_body.tellg();\n\n    ms_dbg(9, \"Adding request body: \" + std::to_string(len) + \" bytes. \" \\\n        \"Limit set to: \"\n        + std::to_string(this->m_rules->m_requestBodyLimit.m_value));\n\n    return appendRequestBody(reinterpret_cast<const unsigned char*>(buf), len);\n}\n\nint Transaction::appendRequestBody(const unsigned char *buf, size_t len) {\n    int current_size = this->m_requestBody.tellp();\n\n    ms_dbg(9, \"Appending request body: \" + std::to_string(len) + \" bytes. \" \\\n        \"Limit set to: \"\n        + std::to_string(this->m_rules->m_requestBodyLimit.m_value));\n\n    if (this->m_rules->m_requestBodyLimit.m_value > 0\n        && this->m_rules->m_requestBodyLimit.m_value < len + current_size) {\n        m_variableInboundDataError.set(\"1\", m_variableOffset);\n        ms_dbg(5, \"Request body is bigger than the maximum expected.\");\n\n        if (this->m_rules->m_requestBodyLimitAction ==\n            RulesSet::BodyLimitAction::ProcessPartialBodyLimitAction) {\n            size_t spaceLeft = this->m_rules->m_requestBodyLimit.m_value\n                - current_size;\n            this->m_requestBody.write(reinterpret_cast<const char*>(buf),\n                spaceLeft);\n            ms_dbg(5, \"Request body limit is marked to process partial\");\n            return false;\n        } else {\n            if (this->m_rules->m_requestBodyLimitAction ==\n                RulesSet::BodyLimitAction::RejectBodyLimitAction) {\n                ms_dbg(5, \"Request body limit is marked to reject the \" \\\n                    \"request\");\n                if (getRuleEngineState() == RulesSet::EnabledRuleEngine) {\n                    intervention::free(&m_it);\n                    m_it.log = strdup(\"Request body limit is marked to \" \\\n                            \"reject the request\");\n                    m_it.status = 403;\n                    m_it.disruptive = true;\n                } else {\n                    ms_dbg(5, \"Not rejecting the request as the engine is \" \\\n                        \"not Enabled\");\n                }\n            }\n            return true;\n        }\n    }\n\n    this->m_requestBody.write(reinterpret_cast<const char*>(buf), len);\n\n    return true;\n}\n\n\n/**\n * @name    processResponseHeaders\n * @brief   Perform the analysis on the response readers.\n *\n * This method perform the analysis on the response headers, notice however\n * that the headers should be added prior to the execution of this function.\n *\n * @note Remember to check for a possible intervention.\n *\n * @param code The returned http code.\n * @param proto Protocol used on the response.\n *\n * @returns If the operation was successful or not.\n * @retval true Operation was successful.\n * @retval false Operation failed.\n *\n */\nint Transaction::processResponseHeaders(int code, const std::string& proto) {\n    ms_dbg(4, \"Starting phase RESPONSE_HEADERS. (SecRules 3)\");\n\n    this->m_httpCodeReturned = code;\n    m_variableResponseStatus.set(std::to_string(code), m_variableOffset);\n    m_variableResponseProtocol.set(proto, m_variableOffset);\n\n    if (getRuleEngineState() == RulesSet::DisabledRuleEngine) {\n        ms_dbg(4, \"Rule engine disabled, returning...\");\n        return true;\n    }\n\n    this->m_rules->evaluate(modsecurity::ResponseHeadersPhase, this);\n    return true;\n}\n\n\n/**\n * @name    addResponseHeader\n * @brief   Adds a response header\n *\n * With this method it is possible to feed ModSecurity with a response\n * header.\n *\n * @note This method expects a NULL terminated string, for both: key and\n *       value.\n *\n * @param key     header name.\n * @param value   header value.\n *\n * @returns If the operation was successful or not.\n * @retval true Operation was successful.\n * @retval false Operation failed.\n *\n */\nint Transaction::addResponseHeader(const std::string& key,\n    const std::string& value) {\n    m_variableResponseHeadersNames.set(key, key, m_variableOffset);\n    m_variableResponseHeaders.set(key, value, m_variableOffset);\n\n    if (utils::string::tolower(key) == \"content-type\") {\n        // Removes the charset=...\n        // Content-Type: text/html; charset=UTF-8\n        std::vector<std::string> val = utils::string::split(value, ';');\n        if (val.size() > 0) {\n            m_variableResponseContentType.set(val[0], 0);\n        }\n    }\n    return 1;\n}\n\n\n/**\n * @name    addResponseHeader\n * @brief   Adds a response header\n *\n * With this method it is possible to feed ModSecurity with a response\n * header.\n *\n * @note This method expects a NULL terminated string, for both: key and\n *       value.\n *\n * @param key     header name.\n * @param value   header value.\n *\n * @returns If the operation was successful or not.\n * @retval true Operation was successful.\n * @retval false Operation failed.\n *\n */\nint Transaction::addResponseHeader(const unsigned char *key,\n    const unsigned char *value) {\n    return this->addResponseHeader(key,\n        strlen(reinterpret_cast<const char *>(key)),\n        value,\n        strlen(reinterpret_cast<const char *>(value)));\n}\n\n\n/**\n * @name    msc_add_n_response_header\n * @brief   Adds a response header\n *\n * Do not expect a NULL terminated string, instead it expect the string and the\n * string size, for the value and key.\n *\n * @param key     header name.\n * @param key_n   header name size.\n * @param value   header value.\n * @param value_n header value size.\n *\n * @returns If the operation was successful or not.\n * @retval true Operation was successful.\n * @retval false Operation failed.\n *\n */\nint Transaction::addResponseHeader(const unsigned char *key, size_t key_n,\n    const unsigned char *value, size_t value_n) {\n    std::string keys;\n    std::string values;\n\n    keys.assign(reinterpret_cast<const char *>(key), key_n);\n    values.assign(reinterpret_cast<const char *>(value), value_n);\n\n    return this->addResponseHeader(keys, values);\n}\n\n\n/**\n * @name    processResponseBody\n * @brief   Perform the request body (if any)\n *\n * This method perform the analysis on the request body. It is optional to\n * call that method. If this API consumer already know that there isn't a\n * body for inspect it is recommended to skip this step.\n *\n * @note It is necessary to \"append\" the request body prior to the execution\n *       of this method.\n * @note Remember to check for a possible intervention.\n *\n * @returns If the operation was successful or not.\n * @retval true Operation was successful.\n * @retval false Operation failed.\n *\n */\nint Transaction::processResponseBody() {\n    ms_dbg(4, \"Starting phase RESPONSE_BODY. (SecRules 4)\");\n\n    if (getRuleEngineState() == RulesSet::DisabledRuleEngine) {\n        ms_dbg(4, \"Rule engine disabled, returning...\");\n        return true;\n    }\n\n    if (m_rules->m_secResponseBodyAccess != RulesSetProperties::TrueConfigBoolean) {\n        ms_dbg(4, \"Response body is disabled, returning... \" + std::to_string(m_rules->m_secResponseBodyAccess));\n        return true;\n    }\n\n    const std::set<std::string> &bi = \\\n        m_rules->m_responseBodyTypeToBeInspected.m_value;\n    auto t = bi.find(m_variableResponseContentType.m_value);\n    if (t == bi.end()\n        && m_rules->m_responseBodyTypeToBeInspected.m_set == true) {\n        ms_dbg(5, \"Response Content-Type is \" \\\n            + m_variableResponseContentType.m_value \\\n            + \". It is not marked to be inspected.\");\n        std::string validContetTypes(\"\");\n        for (std::set<std::string>::iterator i = bi.begin();\n             i != bi.end(); ++i) {\n            validContetTypes.append(*i + \" \");\n        }\n        ms_dbg(8, \"Content-Type(s) marked to be inspected: \" \\\n            + validContetTypes);\n        return true;\n    }\n    if (m_variableOutboundDataError.m_value.empty() == true) {\n        m_variableOutboundDataError.set(\"0\", m_variableOffset);\n    }\n\n    m_variableResponseBody.set(m_responseBody.str(), m_variableOffset);\n    m_variableResponseContentLength.set(std::to_string(\n        m_responseBody.str().size()), m_variableOffset);\n\n    m_rules->evaluate(modsecurity::ResponseBodyPhase, this);\n    return true;\n}\n\n\n/**\n * @name    appendResponseBody\n * @brief   Adds reponse body to be inspected.\n *\n * With this method it is possible to feed ModSecurity with data for\n * inspection regarding the response body. ModSecurity can also update the\n * contents of the response body, this is not quite ready yet on this version\n * of the API.\n *\n * @note If the content is updated, the client cannot receive the content\n *       length header filled, at least not with the old values. Otherwise\n *       unexpected behavior may happens.\n *\n * @returns If the operation was successful or not.\n * @retval true Operation was successful.\n * @retval false Operation failed, process partial demanded.\n *\n */\nint Transaction::appendResponseBody(const unsigned char *buf, size_t len) {\n    int current_size = this->m_responseBody.tellp();\n\n    const std::set<std::string> &bi = \\\n        this->m_rules->m_responseBodyTypeToBeInspected.m_value;\n    auto t = bi.find(m_variableResponseContentType.m_value);\n    if (t == bi.end() && bi.empty() == false) {\n        ms_dbg(4, \"Not appending response body. \" \\\n            \"Response Content-Type is \" \\\n            + m_variableResponseContentType.m_value \\\n            + \". It is not marked to be inspected.\");\n        return true;\n    }\n\n    ms_dbg(9, \"Appending response body: \" + std::to_string(len + current_size)\n        + \" bytes. Limit set to: \" +\n        std::to_string(this->m_rules->m_responseBodyLimit.m_value));\n\n    if (this->m_rules->m_responseBodyLimit.m_value > 0\n        && this->m_rules->m_responseBodyLimit.m_value < len + current_size) {\n        m_variableOutboundDataError.set(\"1\", m_variableOffset);\n        ms_dbg(5, \"Response body is bigger than the maximum expected.\");\n        if (this->m_rules->m_responseBodyLimitAction ==\n            RulesSet::BodyLimitAction::ProcessPartialBodyLimitAction) {\n            size_t spaceLeft = this->m_rules->m_responseBodyLimit.m_value \\\n                - current_size;\n            this->m_responseBody.write(reinterpret_cast<const char*>(buf),\n                spaceLeft);\n            ms_dbg(5, \"Response body limit is marked to process partial\");\n            return false;\n        } else {\n            if (this->m_rules->m_responseBodyLimitAction ==\n                RulesSet::BodyLimitAction::RejectBodyLimitAction) {\n                ms_dbg(5, \"Response body limit is marked to reject the \" \\\n                    \"request\");\n                if (getRuleEngineState() == RulesSet::EnabledRuleEngine) {\n                    intervention::free(&m_it);\n                    m_it.log = strdup(\"Response body limit is marked to reject \" \\\n                        \"the request\");\n                    m_it.status = 403;\n                    m_it.disruptive = true;\n                } else {\n                    ms_dbg(5, \"Not rejecting the request as the engine is \" \\\n                        \"not Enabled\");\n                }\n            }\n            return true;\n        }\n    }\n\n    this->m_responseBody.write(reinterpret_cast<const char*>(buf), len);\n\n    return true;\n}\n\n\n/**\n * @name    getResponseBody\n * @brief   Retrieve a buffer with the updated response body.\n *\n * This method is needed to be called whenever ModSecurity update the\n * contents of the response body, otherwise there is no need to call this\n * method.\n *\n * WARN: This is a skeleton that it is not in use yet.\n *\n * @return It returns a buffer (const char *)\n *\n */\nconst char *Transaction::getResponseBody() const {\n    return strdup(this->m_responseBody.str().c_str());\n}\n\n\n/**\n * @name    getResponseBodyLength\n * @brief   Retrieve the length of the response body.\n *\n * This method returns the size of the response body buffer.\n *\n *\n * @return Size of the update response body.\n *\n */\nsize_t Transaction::getResponseBodyLength() {\n    size_t size = 0;\n    m_responseBody.seekp(0, std::ios::end);\n    size = m_responseBody.tellp();\n\n    return size;\n}\n\n/**\n * @name    getRequestBodyLength\n * @brief   Retrieve the length of the request body.\n *\n * This method returns the size of the request body buffer, notice\n * however, that most likely there isn't an update. Thus, this method will\n * return 0.\n *\n *\n * @return Size of the request body.\n *\n */\nsize_t Transaction::getRequestBodyLength() {\n    size_t size = 0;\n\n    m_requestBody.seekp(0, std::ios::end);\n    size = m_requestBody.tellp();\n\n    return size;\n}\n\n\n/**\n * @name    processLogging\n * @brief   Logging all information relative to this transaction.\n *\n * At this point there is not need to hold the connection, the response can be\n * delivered prior to the execution of this method.\n *\n * @returns If the operation was successful or not.\n * @retval true Operation was successful.\n * @retval false Operation failed.\n *\n */\nint Transaction::processLogging() {\n    ms_dbg(4, \"Starting phase LOGGING. (SecRules 5)\");\n\n    if (getRuleEngineState() == RulesSet::DisabledRuleEngine) {\n        ms_dbg(4, \"Rule engine disabled, returning...\");\n        return true;\n    }\n\n    this->m_rules->evaluate(modsecurity::LoggingPhase, this);\n\n    /* If relevant, save this transaction information at the audit_logs */\n    if (m_rules->m_auditLog != NULL) {\n        int parts = this->m_rules->m_auditLog->getParts();\n        ms_dbg(8, \"Checking if this request is suitable to be \" \\\n            \"saved as an audit log.\");\n\n        if (!this->m_auditLogModifier.empty()) {\n            ms_dbg(4, \"There was an audit log modifier for this transaction.\");\n            std::list<std::pair<int, std::string>>::iterator it;\n            ms_dbg(7, \"AuditLog parts before modification(s): \" +\n                std::to_string(parts) + \".\");\n            for (it = m_auditLogModifier.begin();\n                it != m_auditLogModifier.end(); ++it) {\n                std::pair <int, std::string> p = *it;\n                if (p.first == 0) {  // Add\n                    parts = this->m_rules->m_auditLog->addParts(parts,\n                        p.second);\n                } else {  // Remove\n                    parts = this->m_rules->m_auditLog->removeParts(parts,\n                        p.second);\n                }\n            }\n        }\n        ms_dbg(8, \"Checking if this request is relevant to be \" \\\n            \"part of the audit logs.\");\n        bool saved = this->m_rules->m_auditLog->saveIfRelevant(this, parts);\n        if (saved) {\n            ms_dbg(8, \"Request was relevant to be saved. Parts: \" +\n                std::to_string(parts));\n        }\n    }\n\n    return true;\n}\n\n\n/**\n * @name    intervention\n * @brief   Check if ModSecurity has anything to ask to the server.\n *\n * Intervention can generate a log event and/or perform a disruptive action.\n *\n * If the return value is true, all fields in the ModSecurityIntervention\n * parameter have been initialized and are safe to access.\n * If the return value is false, no changes to the ModSecurityIntervention\n * parameter have been made.\n *\n * @param it Pointer to ModSecurityIntervention structure\n * @retval true  A intervention should be made.\n * @retval false Nothing to be done.\n *\n */\nbool Transaction::intervention(ModSecurityIntervention *it) {\n    const auto disruptive = m_it.disruptive;\n    if (m_it.disruptive) {\n        if (m_it.url) {\n            it->url = strdup(m_it.url);\n        } else {\n            it->url = NULL;\n        }\n        it->disruptive = m_it.disruptive;\n        it->status = m_it.status;\n\n        if (m_it.log != NULL) {\n            std::string log(m_it.log);\n            utils::string::replaceAll(log, \"%d\",\n                std::to_string(it->status));\n            it->log = strdup(log.c_str());\n        } else {\n            it->log = NULL;\n        }\n        intervention::reset(&m_it);\n    }\n\n    return disruptive;\n}\n\n\nstd::string Transaction::toOldAuditLogFormatIndex(const std::string &filename,\n    double size, const std::string &md5) {\n    std::stringstream ss;\n\n    struct tm timeinfo;\n    localtime_r(&this->m_timeStamp, &timeinfo);\n\n    char tstr[std::size(\"[dd/Mmm/yyyy:hh:mm:ss shhmm]\")];\n    strftime(tstr, std::size(tstr), \"[%d/%b/%Y:%H:%M:%S %z]\", &timeinfo);\n\n    ss << utils::string::dash_if_empty(\n       m_variableRequestHeaders.resolveFirst(\"Host\").get())\n        << \" \";\n    ss << utils::string::dash_if_empty(&this->m_clientIpAddress) << \" \";\n    /** TODO: Check variable */\n    variables::RemoteUser *r = new variables::RemoteUser(\"REMOTE_USER\");\n    std::vector<const VariableValue *> l;\n    r->evaluate(this, NULL, &l);\n    for (auto &a : l) {\n        delete a;\n    }\n    delete r;\n\n    ss << utils::string::dash_if_empty(\n        &m_variableRemoteUser);\n    ss << \" \";\n    /** TODO: Check variable */\n    //ss << utils::string::dash_if_empty(\n    //    this->m_collections.resolveFirst(\"LOCAL_USER\").get());\n    //ss << \" \";\n    ss << tstr << \" \";\n\n    ss << \"\\\"\";\n    ss << utils::string::dash_if_empty(m_variableRequestMethod.evaluate());\n    ss << \" \";\n    ss << this->m_uri.c_str() << \" \";\n    ss << \"HTTP/\" << m_httpVersion.c_str();\n    ss << \"\\\" \";\n\n    ss << this->m_httpCodeReturned << \" \";\n    ss << this->m_responseBody.tellp() << \" \";\n    /** TODO: Check variable */\n    ss << utils::string::dash_if_empty(\n        m_variableRequestHeaders.resolveFirst(\"REFERER\").get()) << \" \";\n    ss << \"\\\"\";\n    ss << utils::string::dash_if_empty(\n        m_variableRequestHeaders.resolveFirst(\"User-Agent\").get());\n    ss << \"\\\" \";\n    ss << m_id << \" \";\n    /** TODO: Check variable */\n    ss << utils::string::dash_if_empty(\n        m_variableRequestHeaders.resolveFirst(\"REFERER\").get()) << \" \";\n\n    ss << filename << \" \";\n    ss << \"0\" << \" \";\n    ss << std::to_string(size) << \" \";\n    ss << \"md5:\" << md5 << std::endl;\n\n    return ss.str();\n}\n\n\nstd::string Transaction::toOldAuditLogFormat(int parts,\n    const std::string &trailer, const std::string &prefix) {\n    std::stringstream audit_log;\n\n    struct tm timeinfo;\n    localtime_r(&this->m_timeStamp, &timeinfo);\n\n    char tstr[std::size(\"[dd/Mmm/yyyy:hh:mm:ss shhmm]\")];\n    strftime(tstr, std::size(tstr), \"[%d/%b/%Y:%H:%M:%S %z]\", &timeinfo);\n\n    audit_log << prefix << \"--\" << trailer << \"-\" << \"A--\" << std::endl;\n    audit_log << prefix;\n    audit_log << tstr;\n    audit_log << \" \" << m_id;\n    audit_log << \" \" << this->m_clientIpAddress;\n    audit_log << \" \" << this->m_clientPort;\n    audit_log << \" \" << m_serverIpAddress;\n    audit_log << \" \" << this->m_serverPort;\n    audit_log << std::endl;\n\n    if (parts & audit_log::AuditLog::BAuditLogPart) {\n        std::vector<const VariableValue *> l;\n        audit_log << prefix << \"--\" << trailer << \"-\" << \"B--\" << std::endl;\n        audit_log << prefix;\n        audit_log << utils::string::dash_if_empty(\n            m_variableRequestMethod.evaluate());\n        audit_log << \" \" << this->m_uri.c_str() << \" \" << \"HTTP/\";\n        audit_log << this->m_httpVersion.c_str() << std::endl;\n\n        m_variableRequestHeaders.resolve(&l);\n        for (auto &h : l) {\n            size_t pos = strlen(\"REQUEST_HEADERS:\");\n            audit_log << prefix;\n            audit_log << h->getKeyWithCollection().c_str() + pos << \": \";\n            audit_log << h->getValue().c_str() << std::endl;\n            delete h;\n        }\n        audit_log << prefix << std::endl;\n    }\n    if (parts & audit_log::AuditLog::CAuditLogPart\n        &&  m_requestBody.tellp() > 0) {\n        std::string body =  m_requestBody.str();\n        audit_log << prefix << \"--\" << trailer << \"-\" << \"C--\" << std::endl;\n        if (body.size() > 0) {\n            audit_log << prefix << body << std::endl;\n        }\n        audit_log << prefix << std::endl;\n    }\n    if (parts & audit_log::AuditLog::DAuditLogPart) {\n        audit_log << prefix << \"--\" << trailer << \"-\" << \"D--\" << std::endl;\n        audit_log << prefix << std::endl;\n        /** TODO: write audit_log D part. */\n    }\n    if (parts & audit_log::AuditLog::EAuditLogPart\n        && m_responseBody.tellp() > 0) {\n        std::string body = utils::string::toHexIfNeeded(m_responseBody.str());\n        audit_log << prefix << \"--\" << trailer << \"-\" << \"E--\" << std::endl;\n        if (body.size() > 0) {\n            audit_log << prefix << body << std::endl;\n        }\n        audit_log << prefix << std::endl;\n    }\n    if (parts & audit_log::AuditLog::FAuditLogPart) {\n        std::vector<const VariableValue *> l;\n\n        audit_log << prefix << \"--\" << trailer << \"-\" << \"F--\" << std::endl;\n        audit_log << prefix << \"HTTP/\" << m_httpVersion.c_str()  << \" \";\n        audit_log << this->m_httpCodeReturned << std::endl;\n        m_variableResponseHeaders.resolve(&l);\n        for (auto &h : l) {\n            audit_log << prefix;\n            audit_log << h->getKey().c_str() << \": \";\n            audit_log << h->getValue().c_str() << std::endl;\n            delete h;\n        }\n    }\n    audit_log << prefix << std::endl;\n\n    if (parts & audit_log::AuditLog::GAuditLogPart) {\n        audit_log << prefix << \"--\" << trailer << \"-\" << \"G--\" << std::endl;\n        audit_log << std::endl;\n        /** TODO: write audit_log G part. */\n    }\n    if (parts & audit_log::AuditLog::HAuditLogPart) {\n        audit_log << prefix << \"--\" << trailer << \"-\" << \"H--\" << std::endl;\n        for (const auto &a : m_rulesMessages) {\n            audit_log << prefix << a.log(0, m_httpCodeReturned) << std::endl;\n        }\n        audit_log << prefix << std::endl;\n        /** TODO: write audit_log H part. */\n    }\n    if (parts & audit_log::AuditLog::IAuditLogPart) {\n        audit_log << prefix << \"--\" << trailer << \"-\" << \"I--\" << std::endl;\n        audit_log << prefix << std::endl;\n        /** TODO: write audit_log I part. */\n    }\n    if (parts & audit_log::AuditLog::JAuditLogPart) {\n        audit_log << prefix << \"--\" << trailer << \"-\" << \"J--\" << std::endl;\n        audit_log << prefix << std::endl;\n        /** TODO: write audit_log J part. */\n    }\n    if (parts & audit_log::AuditLog::KAuditLogPart) {\n        audit_log << prefix << \"--\" << trailer << \"-\" << \"K--\" << std::endl;\n        audit_log << prefix << std::endl;\n        /** TODO: write audit_log K part. */\n    }\n    audit_log << prefix << \"--\" << trailer << \"-\" << \"Z--\" << std::endl << std::endl;\n\n    return audit_log.str();\n}\n\n\nstd::string Transaction::toJSON(int parts) {\n#ifdef WITH_YAJL\n    const unsigned char *buf;\n    size_t len;\n    yajl_gen g;\n    std::string log;\n    std::string ts = utils::string::ascTime(&m_timeStamp);\n    std::string uniqueId = UniqueId::uniqueId();\n\n    g = yajl_gen_alloc(NULL);\n    if (g == NULL) {\n      return \"\";\n    }\n    yajl_gen_config(g, yajl_gen_beautify, 0);\n\n    /* main */\n    yajl_gen_map_open(g);\n\n    /* trasaction */\n    yajl_gen_string(g, reinterpret_cast<const unsigned char*>(\"transaction\"),\n        strlen(\"transaction\"));\n\n    yajl_gen_map_open(g);\n    /* Part: A (header mandatory) */\n    LOGFY_ADD(\"client_ip\", m_clientIpAddress);\n    LOGFY_ADD(\"time_stamp\", ts);\n    LOGFY_ADD(\"server_id\", uniqueId);\n    LOGFY_ADD_NUM(\"client_port\", m_clientPort);\n    LOGFY_ADD(\"host_ip\", m_serverIpAddress);\n    LOGFY_ADD_NUM(\"host_port\", m_serverPort);\n    LOGFY_ADD(\"unique_id\", m_id);\n\n    /* request */\n    yajl_gen_string(g, reinterpret_cast<const unsigned char*>(\"request\"),\n        strlen(\"request\"));\n    yajl_gen_map_open(g);\n\n    LOGFY_ADD(\"method\",\n        utils::string::dash_if_empty(\n            m_variableRequestMethod.evaluate()));\n\n    LOGFY_ADD(\"http_version\", m_httpVersion);\n    LOGFY_ADD(\"hostname\", m_requestHostName);\n    LOGFY_ADD(\"uri\", this->m_uri);\n\n    if (parts & audit_log::AuditLog::CAuditLogPart) {\n        // FIXME: check for the binary content size.\n        LOGFY_ADD(\"body\", utils::string::toHexIfNeeded(this->m_requestBody.str()));\n    }\n\n    /* request headers */\n    if (parts & audit_log::AuditLog::BAuditLogPart) {\n        std::vector<const VariableValue *> l;\n        yajl_gen_string(g, reinterpret_cast<const unsigned char*>(\"headers\"),\n            strlen(\"headers\"));\n        yajl_gen_map_open(g);\n\n        m_variableRequestHeaders.resolve(&l);\n        for (auto &h : l) {\n            LOGFY_ADD(utils::string::toHexIfNeeded(h->getKey().c_str()).c_str(), utils::string::toHexIfNeeded(h->getValue()));\n            delete h;\n        }\n\n        /* end: request headers */\n        yajl_gen_map_close(g);\n    }\n\n    /* end: request */\n    yajl_gen_map_close(g);\n\n    /* response */\n    yajl_gen_string(g, reinterpret_cast<const unsigned char*>(\"response\"),\n        strlen(\"response\"));\n    yajl_gen_map_open(g);\n\n    if (parts & audit_log::AuditLog::EAuditLogPart) {\n        LOGFY_ADD(\"body\", this->m_responseBody.str());\n    }\n    LOGFY_ADD_NUM(\"http_code\", m_httpCodeReturned);\n\n    /* response headers */\n    if (parts & audit_log::AuditLog::FAuditLogPart) {\n        std::vector<const VariableValue *> l;\n        yajl_gen_string(g, reinterpret_cast<const unsigned char*>(\"headers\"),\n            strlen(\"headers\"));\n        yajl_gen_map_open(g);\n\n        m_variableResponseHeaders.resolve(&l);\n        for (auto &h : l) {\n            LOGFY_ADD(h->getKey().c_str(), h->getValue());\n            delete h;\n        }\n\n        /* end: response headers */\n        yajl_gen_map_close(g);\n    }\n    /* end: response */\n    yajl_gen_map_close(g);\n\n    /* producer */\n    if (parts & audit_log::AuditLog::HAuditLogPart) {\n        yajl_gen_string(g, reinterpret_cast<const unsigned char*>(\"producer\"),\n            strlen(\"producer\"));\n        yajl_gen_map_open(g);\n\n        /* producer > libmodsecurity */\n        LOGFY_ADD(\"modsecurity\", m_ms->whoAmI());\n\n        /* producer > connector */\n        LOGFY_ADD(\"connector\", m_ms->getConnectorInformation());\n\n        /* producer > engine state */\n        LOGFY_ADD(\"secrules_engine\",\n            RulesSet::ruleEngineStateString(\n            (RulesSetProperties::RuleEngine) getRuleEngineState()));\n\n        /* producer > components */\n        yajl_gen_string(g,\n            reinterpret_cast<const unsigned char*>(\"components\"),\n            strlen(\"components\"));\n\n        yajl_gen_array_open(g);\n        for (const auto &a : m_rules->m_components) {\n            yajl_gen_string(g,\n                reinterpret_cast<const unsigned char*>\n                    (a.data()), a.length());\n        }\n        yajl_gen_array_close(g);\n\n        /* end: producer */\n        yajl_gen_map_close(g);\n\n        /* messages */\n        yajl_gen_string(g,\n            reinterpret_cast<const unsigned char*>(\"messages\"),\n            strlen(\"messages\"));\n        yajl_gen_array_open(g);\n        for (auto a : m_rulesMessages) {\n            yajl_gen_map_open(g);\n            LOGFY_ADD(\"message\", a.m_message);\n            yajl_gen_string(g,\n                reinterpret_cast<const unsigned char*>(\"details\"),\n                strlen(\"details\"));\n            yajl_gen_map_open(g);\n            LOGFY_ADD(\"match\", a.m_match);\n            LOGFY_ADD(\"reference\", a.m_reference);\n            LOGFY_ADD(\"ruleId\", std::to_string(a.m_rule.m_ruleId));\n            LOGFY_ADD(\"file\", a.m_rule.getFileName());\n            LOGFY_ADD(\"lineNumber\", std::to_string(a.m_rule.getLineNumber()));\n            LOGFY_ADD(\"data\", utils::string::toHexIfNeeded(a.m_data));\n            LOGFY_ADD(\"severity\", std::to_string(a.m_severity));\n            LOGFY_ADD(\"ver\", a.m_rule.m_ver);\n            LOGFY_ADD(\"rev\", a.m_rule.m_rev);\n\n            yajl_gen_string(g,\n                reinterpret_cast<const unsigned char*>(\"tags\"),\n                strlen(\"tags\"));\n            yajl_gen_array_open(g);\n            for (auto b : a.m_tags) {\n                yajl_gen_string(g,\n                    reinterpret_cast<const unsigned char*>(b.data()),\n                    b.length());\n            }\n            yajl_gen_array_close(g);\n\n            LOGFY_ADD(\"maturity\", std::to_string(a.m_rule.m_maturity));\n            LOGFY_ADD(\"accuracy\", std::to_string(a.m_rule.m_accuracy));\n            yajl_gen_map_close(g);\n            yajl_gen_map_close(g);\n        }\n        yajl_gen_array_close(g);\n        /* end: messages */\n    }\n\n    /* end: transaction */\n    yajl_gen_map_close(g);\n\n    /* end: main */\n    yajl_gen_map_close(g);\n\n    yajl_gen_get_buf(g, &buf, &len);\n\n    log.assign(reinterpret_cast<const char*>(buf), len);\n    log.append(\"\\n\");\n\n    yajl_gen_free(g);\n\n    return log;\n#else\n    return std::string(\"{\\\"error\\\":\\\"ModSecurity was \" \\\n        \"not compiled with JSON support.\\\"}\");\n#endif\n}\n\n\nvoid Transaction::serverLog(const RuleMessage &rm) {\n    m_ms->serverLog(m_logCbData, rm);\n}\n\n\nint Transaction::getRuleEngineState() const {\n    if (m_secRuleEngine == RulesSetProperties::PropertyNotSetRuleEngine) {\n        return m_rules->m_secRuleEngine;\n    }\n\n    return m_secRuleEngine;\n}\n\n\n/**\n * @name    updateStatusCode\n * @brief   Updates response status code.\n *\n * Called after processResponseHeaders to inform a new response code.\n * Not mandatory.\n *\n *\n * @param status The returned http code.\n *\n * @returns If the operation was successful or not.\n * @retval true Operation was successful.\n * @retval false Operation failed.\n *\n */\nint Transaction::updateStatusCode(int code) {\n    this->m_httpCodeReturned = code;\n    m_variableResponseStatus.set(std::to_string(code), m_variableOffset);\n\n    return true;\n}\n\n\n/**\n * @name    msc_new_transaction\n * @brief   Create a new transaction for a given configuration and ModSecurity core.\n *\n * The transaction is the unit that will be used the inspect every request. It holds\n * all the information for a given request.\n *\n * @note Remember to cleanup the transaction when the transaction is complete.\n *\n * @param ms ModSecurity core pointer.\n * @param rules Rules pointer.\n *\n * @return Pointer to Transaction structure\n * @retval >0   Transaction structure was initialized correctly\n * @retval NULL Transaction cannot be initialized, either by problems with the rules,\n *              problems with the ModSecurity core or missing memory to\n *              allocate the resources needed by the transaction.\n *\n */\nextern \"C\" Transaction *msc_new_transaction(ModSecurity *ms,\n    RulesSet *rules, void *logCbData) {\n    return new Transaction(ms, rules, logCbData);\n}\nextern \"C\" Transaction *msc_new_transaction_with_id(ModSecurity *ms,\n    RulesSet *rules, const char *id, void *logCbData) {\n    return new Transaction(ms, rules, id, logCbData);\n}\n\n/**\n * @name    msc_process_connection\n * @brief   Perform the analysis on the connection.\n *\n * This function should be called at very beginning of a request process, it is\n * expected to be executed prior to the virtual host resolution, when the\n * connection arrives on the server.\n *\n * @note Remember to check for a possible intervention.\n *\n * @param transaction ModSecurity transaction.\n * @param client Client's IP address in text format.\n * @param cPort Client's port\n * @param server Server's IP address in text format.\n * @param sPort Server's port\n *\n * @returns If the operation was successful or not.\n * @retval 1 Operation was successful.\n * @retval 0 Operation failed.\n *\n */\nextern \"C\" int msc_process_connection(Transaction *transaction,\n    const char *client, int cPort, const char *server, int sPort) {\n    return transaction->processConnection(client, cPort, server, sPort);\n}\n\n\n/**\n * @name    msc_process_uri\n * @brief   Perform the analysis on the URI and all the query string variables.\n *\n * This function should be called at very beginning of a request process, it is\n * expected to be executed prior to the virtual host resolution, when the\n * connection arrives on the server.\n *\n * @note There is no direct connection between this function and any phase of\n *       the SecLanguage's phases. It is something that may occur between the\n *       SecLanguage phase 1 and 2.\n * @note Remember to check for a possible intervention.\n *\n * @param transaction ModSecurity transaction.\n * @param uri   Uri.\n * @param protocol   Protocol (GET, POST, PUT).\n * @param http_version   Http version (1.0, 1.2, 2.0).\n *\n * @returns If the operation was successful or not.\n * @retval 1 Operation was successful.\n * @retval 0 Operation failed.\n *\n */\nextern \"C\" int msc_process_uri(Transaction *transaction, const char *uri,\n    const char *protocol, const char *http_version) {\n    return transaction->processURI(uri, protocol, http_version);\n}\n\n\n/**\n * @name    msc_process_request_headers\n * @brief   Perform the analysis on the request readers.\n *\n * This function perform the analysis on the request headers, notice however\n * that the headers should be added prior to the execution of this function.\n *\n * @note Remember to check for a possible intervention.\n *\n * @param transaction ModSecurity transaction.\n *\n * @returns If the operation was successful or not.\n * @retval 1 Operation was successful.\n * @retval 0 Operation failed.\n *\n */\nextern \"C\" int msc_process_request_headers(Transaction *transaction) {\n    return transaction->processRequestHeaders();\n}\n\n\n/**\n * @name    msc_process_request_body\n * @brief   Perform the analysis on the request body (if any)\n *\n * This function perform the analysis on the request body. It is optional to\n * call that function. If this API consumer already know that there isn't a\n * body for inspect it is recommended to skip this step.\n *\n * @note It is necessary to \"append\" the request body prior to the execution\n *       of this function.\n * @note Remember to check for a possible intervention.\n *\n * @param transaction ModSecurity transaction.\n *\n * @returns If the operation was successful or not.\n * @retval 1 Operation was successful.\n * @retval 0 Operation failed.\n *\n */\nextern \"C\" int msc_process_request_body(Transaction *transaction) {\n    return transaction->processRequestBody();\n}\n\n\n/**\n * @name    msc_append_request_body\n * @brief   Adds request body to be inspected.\n *\n * With this function it is possible to feed ModSecurity with data for\n * inspection regarding the request body. There are two possibilities here:\n *\n * 1 - Adds the buffer in a row;\n * 2 - Adds it in chunks;\n *\n * A third option should be developed which is share your application buffer.\n * In any case, remember that the utilization of this function may reduce your\n * server throughput, as this buffer creations is computationally expensive.\n *\n * @note While feeding ModSecurity remember to keep checking if there is an\n *       intervention, Sec Language has the capability to set the maximum\n *       inspection size which may be reached, and the decision on what to do\n *       in this case is upon the rules.\n *\n * @param transaction ModSecurity transaction.\n *\n * @returns If the operation was successful or not.\n * @retval 1 Operation was successful.\n * @retval 0 Operation failed.\n *\n */\nextern \"C\" int msc_append_request_body(Transaction *transaction,\n    const unsigned char *buf, size_t len) {\n    return transaction->appendRequestBody(buf, len);\n}\n\n\nextern \"C\" int msc_request_body_from_file(Transaction *transaction,\n    const char *path) {\n    return transaction->requestBodyFromFile(path);\n}\n\n\n/**\n * @name    msc_process_response_headers\n * @brief   Perform the analysis on the response headers.\n *\n * This function perform the analysis on the response headers, notice however\n * that the headers should be added prior to the execution of this function.\n *\n * @note Remember to check for a possible intervention.\n *\n * @param transaction ModSecurity transaction.\n *\n * @returns If the operation was successful or not.\n * @retval 1 Operation was successful.\n * @retval 0 Operation failed.\n *\n */\nextern \"C\" int msc_process_response_headers(Transaction *transaction,\n    int code, const char* protocol) {\n    return transaction->processResponseHeaders(code, protocol);\n}\n\n\n/**\n * @name    msc_process_response_body\n * @brief   Perform the analysis on the response body (if any)\n *\n * This function perform the analysis on the response body. It is optional to\n * call that function. If this API consumer already know that there isn't a\n * body for inspect it is recommended to skip this step.\n *\n * @note It is necessary to \"append\" the response body prior to the execution\n *       of this function.\n * @note Remember to check for a possible intervention.\n *\n * @param transaction ModSecurity transaction.\n *\n * @returns If the operation was successful or not.\n * @retval 1 Operation was successful.\n * @retval 0 Operation failed.\n *\n */\nextern \"C\" int msc_process_response_body(Transaction *transaction) {\n    return transaction->processResponseBody();\n}\n\n\n/**\n * @name    msc_append_response_body\n * @brief   Adds reponse body to be inspected.\n *\n * With this function it is possible to feed ModSecurity with data for\n * inspection regarding the response body. ModSecurity can also update the\n * contents of the response body, this is not quite ready yet on this version\n * of the API.\n *\n * @note If the content is updated, the client cannot receive the content\n *       length header filled, at least not with the old values. Otherwise\n *       unexpected behavior may happens.\n *\n * @param transaction ModSecurity transaction.\n *\n * @returns If the operation was successful or not.\n * @retval 1 Operation was successful.\n * @retval 0 Operation failed.\n *\n */\nextern \"C\" int msc_append_response_body(Transaction *transaction,\n    const unsigned char *buf, size_t len) {\n    return transaction->appendResponseBody(buf, len);\n}\n\n\n/**\n * @name    msc_add_request_header\n * @brief   Adds a request header\n *\n * With this function it is possible to feed ModSecurity with a request header.\n *\n * @note This function expects a NULL terminated string, for both: key and\n *       value.\n *\n * @param transaction ModSecurity transaction.\n * @param key   header name.\n * @param value header value.\n *\n * @returns If the operation was successful or not.\n * @retval 1 Operation was successful.\n * @retval 0 Operation failed.\n *\n */\nextern \"C\" int msc_add_request_header(Transaction *transaction,\n    const unsigned char *key,\n    const unsigned char *value) {\n    return transaction->addRequestHeader(key, value);\n}\n\n\n/**\n * @name    msc_add_n_request_header\n * @brief   Adds a request header\n *\n * Same as msc_add_request_header, do not expect a NULL terminated string,\n * instead it expect the string and the string size, for the value and key.\n *\n * @param transaction   ModSecurity transaction.\n * @param key     header name.\n * @param key_len header name size.\n * @param value   header value.\n * @param val_len header value size.\n *\n * @returns If the operation was successful or not.\n * @retval 1 Operation was successful.\n * @retval 0 Operation failed.\n *\n */\nextern \"C\" int msc_add_n_request_header(Transaction *transaction,\n    const unsigned char *key,\n    size_t key_len, const unsigned char *value, size_t value_len) {\n    return transaction->addRequestHeader(key, key_len, value, value_len);\n}\n\n\n/**\n * @name    msc_add_response_header\n * @brief   Adds a response header\n *\n * With this function it is possible to feed ModSecurity with a response\n * header.\n *\n * @note This function expects a NULL terminated string, for both: key and\n *       value.\n *\n * @param transaction   ModSecurity transaction.\n * @param key     header name.\n * @param value   header value.\n *\n * @returns If the operation was successful or not.\n * @retval 1 Operation was successful.\n * @retval 0 Operation failed.\n *\n */\nextern \"C\" int msc_add_response_header(Transaction *transaction,\n    const unsigned char *key,\n    const unsigned char *value) {\n    return transaction->addResponseHeader(key, value);\n}\n\n\n/**\n * @name    msc_add_n_response_header\n * @brief   Adds a response header\n *\n * Same as msc_add_response_header, do not expect a NULL terminated string,\n * instead it expect the string and the string size, for the value and key.\n *\n * @param transaction   ModSecurity transaction.\n * @param key     header name.\n * @param key_len header name size.\n * @param value   header value.\n * @param val_len header value size.\n *\n * @returns If the operation was successful or not.\n * @retval 1 Operation was successful.\n * @retval 0 Operation failed.\n *\n */\nextern \"C\" int msc_add_n_response_header(Transaction *transaction,\n    const unsigned char *key, size_t key_len, const unsigned char *value,\n    size_t value_len) {\n    return transaction->addResponseHeader(key, key_len, value, value_len);\n}\n\n\n/**\n * @name    msc_transaction_cleanup\n * @brief   Removes all the resources allocated by a given Transaction.\n *\n * It is mandatory to call this function after every request being finished,\n * otherwise it may end up in a huge memory leak.\n *\n * @param transaction ModSecurity transaction.\n *\n */\nextern \"C\" void msc_transaction_cleanup(Transaction *transaction) {\n    delete transaction;\n}\n\n\n/**\n * @name    msc_intervention\n * @brief   Check if ModSecurity has anything to ask to the server.\n *\n * Intervention can generate a log event and/or perform a disruptive action.\n *\n * If the return value is not zero, all fields in the ModSecurityIntervention\n * parameter have been initialized and are safe to access.\n * If the return value is zero, no changes to the ModSecurityIntervention\n * parameter have been made.\n *\n * @param transaction ModSecurity transaction.\n * @param it Pointer to ModSecurityIntervention structure\n * @returns If an intervention should be made\n * @retval >0 A intervention should be made.\n * @retval 0  Nothing to be done.\n *\n */\nextern \"C\" int msc_intervention(Transaction *transaction,\n    ModSecurityIntervention *it) {\n    return transaction->intervention(it);\n}\n\n\n/**\n * @name    msc_intervention_cleanup\n * @brief   Removes all the resources allocated by a given Intervention.\n *\n * This is a helper function to free any allocated buffers owned by the\n * intervention.\n *\n * @param it ModSecurity intervention.\n *\n */\nextern \"C\" void msc_intervention_cleanup(ModSecurityIntervention *it) {\n    intervention::free(it);\n    intervention::clean(it);\n}\n\n\n/**\n * @name    msc_get_response_body\n * @brief   Retrieve a buffer with the updated response body.\n *\n * This function is needed to be called whenever ModSecurity update the\n * contents of the response body, otherwise there is no need to call this\n * function.\n *\n * @param transaction ModSecurity transaction.\n *\n * @return It returns a buffer (const char *)\n * @retval >0   body was update and available.\n * @retval NULL Nothing was updated.\n *\n */\nextern \"C\" const char *msc_get_response_body(const Transaction *transaction) {\n    return transaction->getResponseBody();\n}\n\n\n/**\n * @name    msc_get_response_body_length\n * @brief   Retrieve the length of the response body.\n *\n * This function returns the size of the response body buffer.\n *\n * @param transaction ModSecurity transaction.\n *\n * @return Size of the response body.\n *\n */\nextern \"C\" size_t msc_get_response_body_length(Transaction *transaction) {\n    return transaction->getResponseBodyLength();\n}\n\n/**\n * @name    msc_get_request_body_length\n * @brief   Retrieve the length of the request body.\n *\n * This function returns the size of the request body buffer.\n *\n * @param transaction ModSecurity transaction.\n *\n * @return Size of the request body.\n *\n */\nextern \"C\" size_t msc_get_request_body_length(Transaction *transaction) {\n    return transaction->getRequestBodyLength();\n}\n\n/**\n * @name    msc_process_logging\n * @brief   Logging all information relative to this transaction.\n *\n * At this point there is not need to hold the connection, the response can be\n * delivered prior to the execution of this function.\n *\n * @param transaction ModSecurity transaction.\n *\n * @returns If the operation was successful or not.\n * @retval 1 Operation was successful.\n * @retval 0 Operation failed.\n *\n */\nextern \"C\" int msc_process_logging(Transaction *transaction) {\n    return transaction->processLogging();\n}\n\n\n/**\n * @name    msc_update_status_code\n * @brief   Updates response status code.\n *\n * Called after msc_process_response_headers to inform a new response code.\n * Not mandatory.\n *\n * @param transaction ModSecurity transaction.\n *\n * @returns If the operation was successful or not.\n * @retval 1 Operation was successful.\n * @retval 0 Operation failed.\n *\n */\nextern \"C\" int msc_update_status_code(Transaction *transaction, int status) {\n    return transaction->updateStatusCode(status);\n}\n\n\n/**\n * @name    setRequestHostName\n * @brief   Set request's host name\n *\n * With this method it is possible to set the request's hostname.\n *\n * @note This function expects a NULL terminated string.\n *\n * @param hostname hostname.\n *\n * @returns If the operation was successful or not.\n * @retval true Operation was successful.\n * @retval false Operation failed.\n *\n */\nint Transaction::setRequestHostName(const std::string& hostname) {\n\n    if (hostname != \"\") {\n        m_requestHostName = hostname;\n    }\n\n    return true;\n}\n\n\n/**\n * @name    msc_set_request_hostname\n * @brief   Set request's host name\n *\n * With this method it is possible to set request's hostname.\n *\n * @note This function expects a NULL terminated string.\n *\n * @param transaction ModSecurity transaction.\n * @param hostname hostname.\n *\n * @returns If the operation was successful or not.\n * @retval 1 Operation was successful.\n * @retval 0 Operation failed.\n *\n */\nextern \"C\" int msc_set_request_hostname(Transaction *transaction,\n    const unsigned char *hostname) {\n    return transaction->setRequestHostName(reinterpret_cast<const char *>(hostname));\n}\n\n\n}  // namespace modsecurity\n\n"
  },
  {
    "path": "src/unique_id.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"src/unique_id.h\"\n#include \"src/config.h\"\n\n#ifdef WIN32\n#include \"src/compat/msvc.h\"\n#include <WinSock2.h>\n#include <iphlpapi.h>\n#endif\n\n#if (defined(__linux__) || defined(__gnu_linux__)) || DARWIN\n#include <sys/socket.h>\n#include <arpa/inet.h>\n#include <netinet/in.h>\n#endif\n\n#ifdef DARWIN\n#include <ifaddrs.h>\n#include <net/if.h>\n#include <net/if_dl.h>\n#include <sys/types.h>\n#ifndef IFT_ETHER\n#define IFT_ETHER 0x6 /* Ethernet CSMACD */\n#endif\n#endif\n\n#if (defined(__linux__) || defined(__gnu_linux__))\n#include <linux/if.h>\n#include <linux/sockios.h>\n#include <sys/ioctl.h>\n#endif\n\n#ifdef HAVE_SYS_UTSNAME_H\n#include <sys/utsname.h>\n#endif\n\n#include <stdio.h>\n#ifndef WIN32\n#include <unistd.h>\n#else\n#include <io.h>\n#endif\n#include <string.h>\n\n#include \"src/utils/sha1.h\"\n\nnamespace modsecurity {\n\nstd::once_flag UniqueId::onceFlag;\n\nvoid UniqueId::fillUniqueId() {\n    std::string macAddress;\n    std::string name;\n    std::string data;\n\n    macAddress = ethernetMacAddress();\n    name = machineName();\n\n    data = macAddress + name;\n\n    this->uniqueId_str = Utils::Sha1::hexdigest(data);\n}\n\n// Based on:\n// http://stackoverflow.com/questions/16858782/how-to-obtain-almost-unique-system-identifier-in-a-cross-platform-way\nstd::string UniqueId::machineName() {\n    char machine_name[MAX_MACHINE_NAME_SIZE];\n    size_t len = MAX_MACHINE_NAME_SIZE;\n#ifdef WIN32\n    DWORD lenComputerName = len;\n#endif\n\n    memset(machine_name, '\\0', sizeof(char) * len);\n\n#ifdef WIN32\n    if (GetComputerName(machine_name, &lenComputerName) == 0) {\n        goto failed;\n    }\n#endif\n\n#ifdef HAVE_SYS_UTSNAME_H\n    static struct utsname u;\n\n    if (uname(&u) < 0) {\n        goto failed;\n    }\n\n    snprintf(machine_name, len-1, \"%s\", u.nodename);\n#endif\n\n    return std::string(machine_name);\n\n#if defined(HAVE_SYS_UTSNAME_H) || defined(WIN32)\nfailed:\n    return std::string(\"\");\n#endif\n}\n\nstd::string UniqueId::ethernetMacAddress() {\n    char mac[MAC_ADDRESS_SIZE];\n    memset(mac, '\\0', sizeof(char)*(MAC_ADDRESS_SIZE));\n#ifdef DARWIN\n    struct ifaddrs* ifaphead;\n    struct ifaddrs* ifap;\n    int i = 0;\n\n    if (getifaddrs(&ifaphead) != 0) {\n        goto failed;\n    }\n\n    // iterate over the net interfaces\n    for (ifap = ifaphead; ifap; ifap = ifap->ifa_next) {\n        struct sockaddr_dl* sdl = (struct sockaddr_dl*)ifap->ifa_addr;\n        if (sdl && (sdl->sdl_family == AF_LINK) && (sdl->sdl_type == IFT_ETHER)\n                && mac[0] && mac[1] && mac[2] && i < 6) {\n            snprintf(mac, MAC_ADDRESS_SIZE, \"%02x:%02x:%02x:%02x:%02x:%02x\",\n                (unsigned char)LLADDR(sdl)[0],\n                (unsigned char)LLADDR(sdl)[1],\n                (unsigned char)LLADDR(sdl)[2],\n                (unsigned char)LLADDR(sdl)[3],\n                (unsigned char)LLADDR(sdl)[4],\n                (unsigned char)LLADDR(sdl)[5]);\n            break;\n        }\n    }\n\n    freeifaddrs(ifaphead);\n#endif\n\n#if (defined(__linux__) || defined(__gnu_linux__))\n    struct ifconf conf;\n    int sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);\n    struct ifreq* ifr;\n    if ( sock < 0 ) {\n        goto failed;\n    }\n\n    char ifconfbuf[128 * sizeof(struct ifreq)];\n    memset(ifconfbuf, 0, sizeof(ifconfbuf));\n    conf.ifc_buf = ifconfbuf;\n    conf.ifc_len = sizeof(ifconfbuf);\n    if (ioctl(sock, SIOCGIFCONF, &conf)) {\n        close(sock);\n        goto failed;\n    }\n\n    for (ifr = conf.ifc_req; ifr < conf.ifc_req + conf.ifc_len; ifr++) {\n        if (ioctl(sock, SIOCGIFFLAGS, ifr)) {\n            continue;  // failed to get flags, skip it\n        }\n\n        if (ioctl(sock, SIOCGIFHWADDR, ifr) == 0) {\n            if (!ifr->ifr_addr.sa_data[0] && !ifr->ifr_addr.sa_data[1]\n                && !ifr->ifr_addr.sa_data[2]) {\n                continue;\n            }\n\n            snprintf(mac, MAC_ADDRESS_SIZE, \"%02x:%02x:%02x:%02x:%02x:%02x\",\n                (unsigned char)ifr->ifr_addr.sa_data[0],\n                (unsigned char)ifr->ifr_addr.sa_data[1],\n                (unsigned char)ifr->ifr_addr.sa_data[2],\n                (unsigned char)ifr->ifr_addr.sa_data[3],\n                (unsigned char)ifr->ifr_addr.sa_data[4],\n                (unsigned char)ifr->ifr_addr.sa_data[5]);\n\n            break;\n        }\n    }\n    close(sock);\n#endif\n\n#if WIN32\n    PIP_ADAPTER_INFO pAdapterInfo;\n    PIP_ADAPTER_INFO pAdapter = NULL;\n    DWORD dwRetVal = 0;\n\n    ULONG ulOutBufLen = sizeof (IP_ADAPTER_INFO);\n    pAdapterInfo = reinterpret_cast<IP_ADAPTER_INFO *>(malloc( \\\n        sizeof (IP_ADAPTER_INFO)));\n    if (!pAdapterInfo) {\n        goto failed;\n    }\n\n    if (GetAdaptersInfo(pAdapterInfo, &ulOutBufLen) == ERROR_BUFFER_OVERFLOW) {\n        free(pAdapterInfo);\n        pAdapterInfo = reinterpret_cast<IP_ADAPTER_INFO *>(malloc(ulOutBufLen));\n        if (!pAdapterInfo) {\n            goto failed;\n        }\n    }\n\n    dwRetVal = GetAdaptersInfo(pAdapterInfo, &ulOutBufLen);\n    if (dwRetVal != NO_ERROR) {\n        free(pAdapterInfo);\n        goto failed;\n    }\n\n    pAdapter = pAdapterInfo;\n    while (pAdapter && !mac[0] && !mac[1] && !mac[2]) {\n        if (pAdapter->AddressLength > 4) {\n            snprintf(mac, MAC_ADDRESS_SIZE, \"%02x:%02x:%02x:%02x:%02x:%02x\",\n                (unsigned char)pAdapter->Address[0],\n                (unsigned char)pAdapter->Address[1],\n                (unsigned char)pAdapter->Address[2],\n                (unsigned char)pAdapter->Address[3],\n                (unsigned char)pAdapter->Address[4],\n                (unsigned char)pAdapter->Address[5]);\n            break;\n        }\n        pAdapter = pAdapter->Next;\n    }\n\n    free(pAdapterInfo);\n#endif\n\n    return std::string(reinterpret_cast<const char *>(mac));\n#if defined(__linux__) || defined(__gnu_linux__) || defined(DARWIN) || defined(WIN32)\nfailed:  // cppcheck-suppress unusedLabelConfiguration\n    return std::string(\"\");\n#endif\n}\n\n\n}  // namespace modsecurity\n"
  },
  {
    "path": "src/unique_id.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#ifdef __cplusplus\n#include <string>\n#include <mutex>\n#endif\n\n#ifndef SRC_UNIQUE_ID_H_\n#define SRC_UNIQUE_ID_H_\n\n\n#ifdef __cplusplus\n\nnamespace modsecurity {\n\n#define MAC_ADDRESS_SIZE 19\n#define MAX_MACHINE_NAME_SIZE 256\n\n/** @ingroup ModSecurity_CPP_API */\nclass UniqueId {\n public:\n    static UniqueId& getInstance() {\n        static UniqueId instance;\n        return instance;\n    }\n\n    static std::string uniqueId() {\n        std::call_once(UniqueId::onceFlag,[]() {\n            UniqueId::getInstance().fillUniqueId();\n        });\n\n        return UniqueId::getInstance().uniqueId_str;\n    }\n\n    void fillUniqueId();\n    static std::string machineName();\n    static std::string ethernetMacAddress();\n\n    std::string uniqueId_str;\n\n private:\n    UniqueId() {}\n    // C++ 03\n    UniqueId(UniqueId const&);\n    // void operator=(UniqueId const&);\n\n    // C++ 11\n    // UniqueId(UniqueId const&) = delete;\n    // void operator=(UniqueId const&) = delete;\n\n    static std::once_flag onceFlag;\n};\n\n}  // namespace modsecurity\n#endif\n\n#endif  // SRC_UNIQUE_ID_H_\n"
  },
  {
    "path": "src/utils/acmp.cc",
    "content": "/*\n* ModSecurity for Apache 2.x, http://www.modsecurity.org/\n* Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n*\n* You may not use this file except in compliance with\n* the License.  You may obtain a copy of the License at\n*\n*     http://www.apache.org/licenses/LICENSE-2.0\n*\n* If any of the files related to licensing are missing or if you have any\n* other questions related to licensing please contact Trustwave Holdings, Inc.\n* directly using the email address security@modsecurity.org.\n*/\n\n/* Aho-Corasick Matching  */\n\n#include \"src/utils/acmp.h\"\n\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n#include <cstddef>\n#include <stdio.h>\n#include <ctype.h>\n\n#include <iostream>\n#include <string>\n#include <vector>\n\n\n/**\n * TODO: This code comes from ModSecurity 2.9.0 there are two memory leaks here\n *       that should be mitigated. This ACMP parser should be re-written to\n *       consume less memory.\n */\n\nextern \"C\" {\n\n/*\n *******************************************************************************\n *******************************************************************************\n * Functions for UTF-8 support\n */\n\n\n/*\n *******************************************************************************\n *******************************************************************************\n * Code for local / static utility functions\n */\n\n/**\n * Returns length of given string for parser's encoding\n */\nstatic size_t acmp_strlen(ACMP *parser, const char *str) {\n    return strlen(str);\n}\n\n/**\n * Turns string to array of ucs values, depending on parser's encoding\n *       str - string to convert, doesn't have to be NULL-terminated\n * ucs_chars - where to write ucs values\n *       len - length of input string\n */\nstatic void acmp_strtoucs(ACMP *parser, const char *str, long *ucs_chars, int len) {\n    const char *c = str;\n\n    for (int i = 0;i < len;i++) {\n        *(ucs_chars++) = *(c++);\n    }\n}\n\n/**\n * Returns node with given letter, or null if not found\n */\nstatic acmp_node_t *acmp_child_for_code(acmp_node_t *parent_node, long ucs_code) {\n    acmp_node_t *node = parent_node->child;\n    if (node == NULL) return NULL;\n    for (;;) {\n        if (node->letter == ucs_code) return node;\n        node = node->sibling;\n        if (node == NULL) return NULL;\n    }\n}\n\n/**\n * Adds node to parent node, if it is not already there\n */\nstatic void acmp_add_node_to_parent(acmp_node_t *parent, acmp_node_t *child) {\n    acmp_node_t *node = NULL;\n\n    child->parent = parent;\n    if (parent->child == NULL) {\n        parent->child = child;\n        return;\n    }\n\n    node = parent->child;\n    for (;;) {\n        if (node == child) return;\n        if (node->sibling == NULL) {\n            node->sibling = child;\n            return;\n        }\n        node = node->sibling;\n    }\n}\n\n/**\n * Copies values from one node to another, without child/sibling/fail pointers\n * and without state variables.\n */\nstatic void acmp_clone_node_no_state(acmp_node_t *from, acmp_node_t *to) {\n    memcpy(to, from, sizeof(acmp_node_t));\n    to->child = NULL;\n    to->sibling = NULL;\n    to->fail = NULL;\n    to->hit_count = 0;\n}\n\nstatic inline acmp_node_t *acmp_btree_find(acmp_node_t *node, long letter) {\n    acmp_btree_node_t *bnode = node->btree;\n    for (;;) {\n        if (bnode == NULL) return NULL;\n        if (bnode->letter == letter) return bnode->node;\n        if (bnode->letter > letter) {\n            bnode = bnode->left;\n        } else {\n            bnode = bnode->right;\n        }\n    }\n}\n\n/**\n *\n */\nstatic inline acmp_node_t *acmp_goto(acmp_node_t *node, long letter) {\n    return acmp_btree_find(node, letter);\n}\n\n/**\n * Connects each node with its first fail node that is end of a phrase.\n */\nstatic void acmp_connect_other_matches(ACMP *parser, acmp_node_t *node) {\n    acmp_node_t *child, *om;\n\n    for (child = node->child; child != NULL; child = child->sibling) {\n        if (child->fail == NULL) continue;\n        for (om = child->fail; om != parser->root_node; om = om->fail) {\n            if (om->is_last) {\n                child->o_match = om;\n                break;\n            }\n        }\n    }\n\n    /* Go recursively through children of this node that have a child node */\n    for(child = node->child; child != NULL; child = child->sibling) {\n        if (child->child != NULL) acmp_connect_other_matches(parser, child);\n    }\n}\n\n/**\n * Adds leaves to binary tree, working from sorted array of keyword tree nodes\n */\nstatic void acmp_add_btree_leaves(acmp_btree_node_t *node, acmp_node_t *nodes[],\n        int pos, int lb, int rb) {\n\n    int left = 0, right = 0;\n    if ((pos - lb) > 1) {\n        left = lb + (pos - lb) / 2;\n        node->left = reinterpret_cast<acmp_btree_node_t *>(calloc(1, sizeof(acmp_btree_node_t)));\n        node->left->node = NULL;\n        node->left->right = NULL;\n        node->left->left = NULL;\n        node->left->letter = 0;\n        /* ENH: Check alloc succeded */\n        node->left->node = nodes[left];\n        node->left->letter = nodes[left]->letter;\n#ifdef DEBUG_ACMP\n        fprintf(stderr, \"%lc ->left %lc\\n\", (wint_t)node->node->letter, (wint_t)node->left->node->letter);\n#endif\n    }\n    if ((rb - pos) > 1) {\n        right = pos + (rb - pos) / 2;\n        node->right = reinterpret_cast<acmp_btree_node_t *>(calloc(1, sizeof(acmp_btree_node_t)));\n        node->right->node = NULL;\n        node->right->right = NULL;\n        node->right->left = NULL;\n        node->right->letter = 0;\n        /* ENH: Check alloc succeded */\n        node->right->node = nodes[right];\n        node->right->letter = nodes[right]->letter;\n#ifdef DEBUG_ACMP\n        fprintf(stderr, \"%lc ->right %lc\\n\", (wint_t)node->node->letter, (wint_t)node->right->node->letter);\n#endif\n    }\n    if (node->right != NULL) {\n        acmp_add_btree_leaves(node->right, nodes, right, pos, rb);\n    }\n    if (node->left != NULL) {\n        acmp_add_btree_leaves(node->left, nodes, left, lb, pos);\n    }\n}\n\n/**\n * Builds balanced binary tree from children nodes of given node.\n */\nstatic void acmp_build_binary_tree(ACMP *parser, acmp_node_t *node) {\n    size_t count, i, j;\n    acmp_node_t *child = node->child;\n    acmp_node_t **nodes;\n    size_t pos;\n\n    /* Build an array big enough */\n    for (count = 0; child != NULL; child = child->sibling) count++;\n    nodes = (acmp_node_t **)calloc(1, count * sizeof(acmp_node_t *));\n    /* ENH: Check alloc succeded */\n\n    /* ENH: Combine this in the loop below - we do not need two loops */\n    child = node->child;\n    for (i = 0; i < count; i++) {\n        nodes[i] = child;\n        child = child->sibling;\n    };\n\n    /* We have array with all children of the node and number of those children\n     */\n    for (i = 0; i < count - 1; i++) {\n        for (j = i + 1; j < count; j++) {\n            acmp_node_t *tmp;\n\n            if (nodes[i]->letter < nodes[j]->letter) continue;\n\n            tmp = nodes[i];\n            nodes[i] = nodes[j];\n            nodes[j] = tmp;\n        }\n    }       \n    if (node->btree != NULL) {\n        free(node->btree);\n        node->btree = NULL;\n    }\n    node->btree = reinterpret_cast<acmp_btree_node_t *>(calloc(1, sizeof(acmp_btree_node_t)));\n\n    /* ENH: Check alloc succeded */\n    pos = count / 2;\n    node->btree->node = nodes[pos];\n    node->btree->letter = nodes[pos]->letter;\n    acmp_add_btree_leaves(node->btree, nodes, pos, -1, count);\n    for (i = 0; i < count; i++) {\n        if (nodes[i]->child != NULL) acmp_build_binary_tree(parser, nodes[i]);\n    }\n    if (nodes != NULL) {\n        free(nodes);\n    }\n}\n\n/**\n * Constructs fail paths on keyword trie\n */\nstatic int acmp_connect_fail_branches(ACMP *parser) {\n    /* Already connected ? */\n    acmp_node_t *child, *node, *goto_node;\n\n    if (parser->is_failtree_done != 0) return 1;\n\n    std::vector<acmp_node_t *> arr;\n    std::vector<acmp_node_t *> arr2;\n    std::vector<acmp_node_t *> tmp;\n\n    parser->root_node->text = (char *)\"\";\n\n    parser->root_node->fail = parser->root_node;\n\n    /* All first-level children will fail back to root node */\n    for (child = parser->root_node->child; child != NULL; child = child->sibling) {\n        child->fail = parser->root_node;\n        arr.push_back(child);\n    }\n\n    for (;;) {\n        while (arr.empty() == false) {\n            node = arr.back();\n            arr.pop_back();\n            node->fail = parser->root_node;\n            if (node->parent != parser->root_node) {\n                goto_node = acmp_child_for_code(node->parent->fail, node->letter);\n                node->fail = (goto_node != NULL) ? goto_node : parser->root_node;\n            }\n#ifdef DEBUG_ACMP\n            fprintf(stderr, \"fail direction: *%s* => *%s*\\n\", node->text, node->fail->text);\n#endif\n            child = node->child;\n            while (child != NULL) {\n                arr2.push_back(child);\n                child = child->sibling;\n            }\n        }\n        if (arr2.empty() == true) break;\n\n        tmp = arr;\n        arr = arr2;\n        arr2 = tmp;\n    }\n\n    acmp_connect_other_matches(parser, parser->root_node);\n    if (parser->root_node->child != NULL) acmp_build_binary_tree(parser, parser->root_node);\n    parser->is_failtree_done = 1;\n\n    return 1;\n}\n\n/*\n *******************************************************************************\n *******************************************************************************\n * Code for functions from header file\n */\n\n\n/**\n * flags - OR-ed values of ACMP_FLAG constants\n */\nACMP *acmp_create(int flags) {\n    ACMP *parser;\n\n    parser = reinterpret_cast<ACMP *>(calloc(1, sizeof(ACMP)));\n    /* ENH: Check alloc succeded */\n    parser->is_case_sensitive = (flags & ACMP_FLAG_CASE_SENSITIVE) == 0 ? 0 : 1;\n    parser->root_node = reinterpret_cast<acmp_node_t *>(calloc(1, sizeof(acmp_node_t)));\n    /* ENH: Check alloc succeded */\n    return parser;\n}\n\n/**\n * Creates fail tree and initializes buffer\n */\nint acmp_prepare(ACMP *parser) {\n    int st;\n\n    if (parser->bp_buff_len < parser->longest_entry) {\n        parser->bp_buff_len = parser->longest_entry * 2;\n        //parser->bp_buffer = (size_t *)calloc(1, sizeof(size_t) * parser->bp_buff_len);\n        /* ENH: Check alloc succeded */\n    }\n\n    st = acmp_connect_fail_branches(parser);\n    parser->active_node = parser->root_node;\n    if (st != 1) return st;\n    parser->is_active = 1;\n    return 1;\n}\n\n/**\n * Adds pattern to parser\n * parser - ACMP parser\n * pattern - string nwith pattern to match\n * callback - Optional, pointer to an acmp_callback_t function\n * data - pointer to data that will be passed to callback function, only used if callback\n *   is supplied\n * len - Length of pattern in characters, if zero string length is used.\n */\nint acmp_add_pattern(ACMP *parser, const char *pattern,\n        acmp_callback_t callback, void *data, size_t len)\n{\n    size_t length, i, j;\n    long *ucs_chars;\n    acmp_node_t *parent, *child;\n\nif (parser->is_active != 0) return -1;\n    length = (len == 0) ? acmp_strlen(parser, pattern) : len;\n    ucs_chars = (long *)calloc(1, length * sizeof(long));\n    /* ENH: Check alloc succeded */\n\n    parent = parser->root_node;\n    acmp_strtoucs(parser, pattern, ucs_chars, length);\n\n    for (i = 0; i < length; i++) {\n        long letter = ucs_chars[i];\n        if (parser->is_case_sensitive == 0) {\n            letter = tolower(letter);\n        }\n        child = acmp_child_for_code(parent, letter);\n        if (child == NULL) {\n            child = reinterpret_cast<acmp_node_t *>(calloc(1, sizeof(acmp_node_t)));\n            /* ENH: Check alloc succeded */\n            child->pattern = (char *)\"\";\n            child->letter = letter;\n            child->depth = i;\n            child->text = (char *)calloc(1, strlen(pattern) + 2);\n            /* ENH: Check alloc succeded */\n            for (j = 0; j <= i; j++) child->text[j] = pattern[j];\n        }\n        if (i == length - 1) {\n            if (child->is_last == 0) {\n                parser->dict_count++;\n                child->is_last = 1;\n                child->pattern = (char *)calloc(1, strlen(pattern) + 2);\n                /* ENH: Check alloc succeded */\n                strcpy(child->pattern, pattern);\n            }\n            child->callback = callback;\n            child->callback_data = data;\n        }\n        acmp_add_node_to_parent(parent, child);\n        parent = child;\n    }\n    if (length > parser->longest_entry) parser->longest_entry = length;\n    parser->is_failtree_done = 0;\n    free(ucs_chars);\n    return 1;\n}\n\n/**\n * Process the data using ACMPT to keep state, and ACMPT's parser to keep the tree\n */\nint acmp_process_quick(ACMPT *acmpt, const char **match, const char *data, size_t len) {\n    ACMP *parser;\n    acmp_node_t *node, *go_to;\n    const char *end;\n    int offset = 0;\n\n    /*\n    if (acmpt->parser->is_failtree_done == 0) {\n        acmp_prepare(acmpt->parser);\n    };\n    */\n\n    parser = acmpt->parser;\n    if (acmpt->ptr == NULL) acmpt->ptr = parser->root_node;\n    node = reinterpret_cast<acmp_node_t *>(acmpt->ptr);\n    end = data + len;\n\n    while (data < end) {\n        long letter = (unsigned char)*data++;\n\n        if (parser->is_case_sensitive == 0) letter = tolower(letter);\n\n        go_to = NULL;\n        while (go_to == NULL) {\n            go_to = acmp_goto(node, letter);\n            if (go_to != NULL) {\n                if (go_to->is_last) {\n                    *match = go_to->text;\n                    return offset;\n                }\n            }\n            if (node == parser->root_node) break;\n            if (go_to == NULL) node = node->fail;\n        }\n        if (go_to != NULL) node = go_to;\n\n        /* If node has o_match, then we found a pattern */\n        if (node->o_match != NULL) {\n            *match = node->text;\n            return offset;\n        }\n        offset++;\n    }\n    acmpt->ptr = node;\n    return -1;\n}\n\n}\n"
  },
  {
    "path": "src/utils/acmp.h",
    "content": "/*\n* ModSecurity for Apache 2.x, http://www.modsecurity.org/\n* Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n*\n* You may not use this file except in compliance with\n* the License.  You may obtain a copy of the License at\n*\n*     http://www.apache.org/licenses/LICENSE-2.0\n*\n* If any of the files related to licensing are missing or if you have any\n* other questions related to licensing please contact Trustwave Holdings, Inc.\n* directly using the email address security@modsecurity.org.\n*/\n\n#ifndef ACMP_H_\n#define ACMP_H_\n\n#define ACMP_FLAG_BYTE               0\n#define ACMP_FLAG_CASE_SENSITIVE     1\n#define ACMP_FLAG_CASE_INSENSITIVE   0\n#ifdef ACMP_USE_UTF8\n#define ACMP_FLAG_UTF8               0x100\n#endif\n\n#include <cstddef>\n#include <string>\n\n\nextern \"C\" {\n/**\n * Opaque struct with parser data\n */\ntypedef struct ACMP ACMP;\n\n/**\n * Used to separate state from the trie for acmp_process_quick function\n */\ntypedef struct {\n    ACMP *parser;\n    void *ptr;\n} ACMPT;\n\n/*\n *******************************************************************************\n *******************************************************************************\n * Data structures for acmp parser\n */\n\n/**\n * Callback function. Arguments are:\n * ACMP * - acmp parser that initiated callback\n * void * - custom data you supplied when adding callback\n * size_t - position in bytes where pattern was found\n * size_t - position in chars where pattern was found, for multibyte strings\n */\ntypedef void (*acmp_callback_t)(ACMP *, void *, size_t, size_t);\n\n\n/**\n * One node in trie\n */\ntypedef struct acmp_node_t acmp_node_t;\ntypedef struct acmp_btree_node_t acmp_btree_node_t;\nstruct acmp_node_t {\n    long letter;\n    int  is_last;\n    acmp_callback_t callback;\n    void *callback_data;\n    int depth;\n\n    acmp_node_t *child;\n    acmp_node_t *sibling;\n    acmp_node_t *fail;\n    acmp_node_t *parent;\n    acmp_node_t *o_match;\n\n    acmp_btree_node_t *btree;\n\n    size_t hit_count;\n\n    char *text;\n    char *pattern;\n};\n\nstruct acmp_btree_node_t {\n    long letter;\n    acmp_btree_node_t *left;\n    acmp_btree_node_t *right;\n    acmp_node_t *node;\n};\n\n/**\n * Data related to parser, not to individual nodes\n */\nstruct ACMP {\n\n    int is_case_sensitive;\n\n    int dict_count;\n    size_t longest_entry;\n\n    acmp_node_t *root_node;\n\n    const char *data_start;\n    const char *data_end;\n    const char *data_pos;\n    size_t data_len;\n\n    size_t *bp_buffer;\n    size_t bp_buff_len;\n\n    acmp_node_t *active_node;\n    char u8_buff[6];\n    size_t  u8buff_len;\n    size_t  hit_count;\n    int  is_failtree_done;\n    int  is_active;\n    size_t  byte_pos;\n    size_t  char_pos;\n};\n\n\n//static long utf8_lcase(long ucs_code);\n\n/**\n * flags - OR-ed values of ACMP_FLAG constants\n */\nACMP *acmp_create(int flags);\n\n/**\n * Destroys previously created parser\n */\nvoid acmp_destroy(ACMP *parser);\n\n/**\n * Creates parser with same options and same patterns\n * parser - ACMP parser to duplicate\n */\nACMP *acmp_duplicate(ACMP *parser);\n\n/**\n * Adds pattern to parser. Cannot be done after starting the search.\n * parser - ACMP parser\n * pattern - string with pattern to match\n * callback - Optional, pointer to an acmp_callback_t function\n * data - pointer to data that will be passed to callback function, only used if callback\n *   is supplied\n * len - Length of pattern in characters, if zero string length is used.\n */\nint acmp_add_pattern(ACMP *parser, const char *pattern,\n    acmp_callback_t callback, void *data, size_t len);\n\n/**\n * Called to process incoming data stream. You must call acmp_done after sending\n *   last data packet\n *\n * data - ptr to incoming data\n * len  - size of data in bytes\n */\nint acmp_process(ACMP *parser, const char *data, size_t len);\n\n/**\n * Returns number of matches on all patterns combined\n */\nsize_t acmp_match_count_total(ACMP *parser);\n\n/**\n * Returns number of matches for given pattern\n */\nsize_t acmp_match_count(ACMP *parser, const char *pattern);\n\n/**\n * Resets the state of parser so you can start using it with new set of data,\n * or add new patterns.\n */\nvoid acmp_reset(ACMP *parser);\n\n/**\n * Creates an ACMPT struct that will use parser's tree, without duplicating its data\n */\nACMPT *acmp_duplicate_quick(ACMP *parser);\n\n/**\n * Process the data using ACMPT to keep state, and ACMPT's parser to keep the tree\n */\nint acmp_process_quick(ACMPT *acmpt, const char **match, const char *data, size_t len);\n\n/**\n * Prepares parser for searching\n */\nint acmp_prepare(ACMP *parser);\n\n}\n\n#endif /*ACMP_H_*/\n"
  },
  {
    "path": "src/utils/base64.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"src/utils/base64.h\"\n\n#include <string.h>\n\n#include <string>\n#include <fstream>\n#include <iostream>\n\n#include \"mbedtls/base64.h\"\n\ntemplate<typename Operation>\ninline std::string base64Helper(const char *data, const unsigned int len, Operation op) { // cppcheck-suppress syntaxError ; false positive\n    size_t out_len = 0;\n\n    op(nullptr, 0, &out_len,\n        reinterpret_cast<const unsigned char *>(data), len);\n\n    std::string ret(out_len, {});\n    if(out_len > 0) {\n        op(reinterpret_cast<unsigned char *>(ret.data()), ret.size(), &out_len,\n            reinterpret_cast<const unsigned char *>(data), len);\n\n        ret.resize(out_len);\n    }\n\n    return ret;\n}\n\nnamespace modsecurity {\nnamespace Utils {\n\n\nstd::string Base64::encode(const std::string& data) {\n    return base64Helper(data.c_str(), data.size(), mbedtls_base64_encode);\n}\n\n\nstd::string Base64::decode(const std::string& data, bool forgiven) {\n    if (forgiven) {\n        return decode_forgiven(data);\n    }\n\n    return decode(data);\n}\n\n\nstd::string Base64::decode(const std::string& data) {\n    return base64Helper(data.c_str(), strlen(data.c_str()), mbedtls_base64_decode);\n}\n\n\nstd::string Base64::decode_forgiven(const std::string& data) {\n    return base64Helper(data.c_str(), data.size(), decode_forgiven_engine);\n}\n\n\nvoid Base64::decode_forgiven_engine(unsigned char *plain_text,\n        size_t plain_text_size, size_t *aiming_size,\n        const unsigned char *encoded, size_t input_len) {\n    int i = 0, j = 0, k = 0;\n    int ch = 0;\n    static const char b64_pad = '=';\n    static const int b64_reverse_t[256] = {\n        -2, -2, -2, -2, -2, -2, -2, -2, -2, -1, -1, -2, -2, -1, -2, -2,\n        -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,\n        -1, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, 62, -2, -2, -2, 63,\n        52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -2, -2, -2, -2, -2, -2,\n        -2, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,\n        15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -2, -2, -2, -2, -2,\n        -2, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,\n        41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -2, -2, -2, -2, -2,\n        -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,\n        -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,\n        -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,\n        -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,\n        -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,\n        -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,\n        -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2,\n        -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2\n    };\n\n\n    while (/*ch = *encoded++ != '\\0' && */input_len-- > 0) {\n        ch = *encoded++;\n        if (ch == b64_pad) {\n            if (*encoded != '=' && (i % 4) == 1) {\n                *aiming_size = 0;\n                return;\n            }\n            continue;\n        }\n\n        ch = b64_reverse_t[ch];\n        if (ch < 0) {\n            continue;\n        /*} else if (ch == -2) {\n            *aiming_size = 0;\n            return;*/\n        }\n        switch (i % 4) {\n            case 0:\n                if (plain_text_size != 0) {\n                    plain_text[j] = ch << 2;\n                }\n                break;\n            case 1:\n                if (plain_text_size == 0) {\n                    j++;\n                } else {\n                    plain_text[j++] |= ch >> 4;\n                    plain_text[j] = (ch & 0x0f) << 4;\n                }\n                break;\n            case 2:\n                if (plain_text_size == 0) {\n                    j++;\n                } else {\n                    plain_text[j++] |= ch >>2;\n                    plain_text[j] = (ch & 0x03) << 6;\n                }\n                break;\n            case 3:\n                if (plain_text_size == 0) {\n                    j++;\n                } else {\n                    plain_text[j++] |= ch;\n                }\n                break;\n        }\n        i++;\n    }\n    k = j;\n\n    if (ch == b64_pad) {\n        switch (i % 4) {\n            case 1:\n                *aiming_size = 0;\n                return;\n            case 2:\n                k++;\n            case 3:\n                if (plain_text_size != 0) {\n                    plain_text[k] = 0;\n                }\n        }\n    }\n\n    if (plain_text_size != 0) {\n        plain_text[j] = '\\0';\n    }\n\n    if (plain_text_size == 0) {\n        *aiming_size = k + 1;\n    } else {\n        *aiming_size = j;\n    }\n}\n\n}  // namespace Utils\n}  // namespace modsecurity\n"
  },
  {
    "path": "src/utils/base64.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n\n#ifndef SRC_UTILS_BASE64_H_\n#define SRC_UTILS_BASE64_H_\n\n#include <string>\n\nnamespace modsecurity {\nnamespace Utils {\n\nclass Base64 {\n public:\n    Base64() { }\n\n    static std::string encode(const std::string& data);\n\n    static std::string decode(const std::string& data, bool forgiven);\n    static std::string decode(const std::string& data);\n    static std::string decode_forgiven(const std::string& data);\n\n    static void decode_forgiven_engine(unsigned char *plain_text,\n        size_t plain_text_size, size_t *aiming_size,\n        const unsigned char *encoded,\n        size_t input_len);\n};\n\n\n}  // namespace Utils\n}  // namespace modsecurity\n\n#endif  // SRC_UTILS_BASE64_H_\n\n"
  },
  {
    "path": "src/utils/decode.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"src/utils/decode.h\"\n#include \"modsecurity/modsecurity.h\"\n#include \"src/utils/string.h\"\n\nusing namespace modsecurity::utils::string;\n\nnamespace modsecurity::utils {\n\n\nbool urldecode_nonstrict_inplace(std::string &val,\n    int &invalid_count) {\n    unsigned char *d = (unsigned char *)val.data();\n    unsigned char *s = d;\n    const unsigned char *e = s + val.size();\n\n    invalid_count = 0;\n    bool changed = false;\n\n    while (s != e) {\n        if (*s == '%') {\n            /* Character is a percent sign. */\n\n            /* Are there enough bytes available? */\n            if (s + 2 < e) {\n                const auto c1 = *(s + 1);\n                const auto c2 = *(s + 2);\n                if (VALID_HEX(c1) && VALID_HEX(c2)) {\n                    const auto uni = string::x2c(s + 1);\n\n                    *d++ = uni;\n                    s += 3;\n                    changed = true;\n                } else {\n                    /* Not a valid encoding, skip this % */\n                    *d++ = *s++;\n                    invalid_count++;\n                }\n            } else {\n                /* Not enough bytes available, copy the raw bytes. */\n                *d++ = *s++;\n                invalid_count++;\n            }\n        } else {\n            /* Character is not a percent sign. */\n            if (*s == '+') {\n                *d++ = ' ';\n                changed = true;\n            } else {\n                *d++ = *s;\n            }\n            s++;\n        }\n    }\n\n    if (changed)\n        val.resize((char*) d - val.c_str());\n\n    return changed;\n}\n\n\nstd::string uri_decode(const std::string & sSrc) {\n    // Note from RFC1630: \"Sequences which start with a percent\n    // sign but are not followed by two hexadecimal characters\n    // (0-9, A-F) are reserved for future extension\"\n\n    const unsigned char * pSrc = (const unsigned char *)sSrc.c_str();\n    const int SRC_LEN = sSrc.length();\n    const unsigned char * const SRC_END = pSrc + SRC_LEN;\n    // last decodable '%'\n    const unsigned char * const SRC_LAST_DEC = SRC_END - 2;\n\n    char * const pStart = new char[SRC_LEN];\n    char * pEnd = pStart;\n\n    while (pSrc < SRC_LAST_DEC) {\n        if (*pSrc == '%') {\n            char dec1, dec2;\n            if ((char)-1 != (dec1 = string::HEX2DEC[*(pSrc + 1)])\n                && (char)-1 != (dec2 = string::HEX2DEC[*(pSrc + 2)])) {\n                *pEnd++ = (dec1 << 4) + dec2;\n                pSrc += 3;\n                continue;\n            }\n        }\n        *pEnd++ = *pSrc++;\n    }\n\n    // the last 2- chars\n    while (pSrc < SRC_END) {\n        *pEnd++ = *pSrc++;\n    }\n\n    std::string sResult(pStart, pEnd);\n    delete [] pStart;\n    return sResult;\n}\n\n\n}  // namespace modsecurity::utils\n"
  },
  {
    "path": "src/utils/decode.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <ctime>\n#include <iostream>\n#include <string>\n#include <vector>\n\n#include \"modsecurity/modsecurity.h\"\n#include \"src/utils/string.h\"\n\n#ifndef SRC_UTILS_DECODE_H_\n#define SRC_UTILS_DECODE_H_\n\n\nnamespace modsecurity {\nnamespace utils {\n\n\nbool urldecode_nonstrict_inplace(std::string &val,\n    int &invalid_count);\nstd::string uri_decode(const std::string & sSrc);\n\n\n}  // namespace utils\n}  // namespace modsecurity\n\n#endif  // SRC_UTILS_DECODE_H_\n"
  },
  {
    "path": "src/utils/geo_lookup.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#ifndef WIN32\n#include <sys/socket.h>\n#include <netinet/in.h>\n#include <arpa/inet.h>\n#else\n#include <WinSock2.h>\n#endif\n#include <string>\n\n#include <fstream>\n#include <iostream>\n\n#include \"src/utils/geo_lookup.h\"\n#if WITH_MAXMIND\n#include <maxminddb.h>\n#elif WITH_GEOIP\n#include <GeoIPCity.h>\n#endif\n\nnamespace modsecurity {\nnamespace Utils {\n\n\nGeoLookup::~GeoLookup() {\n    cleanUp();\n}\n\n\nvoid GeoLookup::cleanUp() {\n#ifdef WITH_MAXMIND\n    if (m_version == VERSION_MAXMIND) {\n        MMDB_close(&mmdb);\n    }\n#endif\n#ifdef WITH_GEOIP\n    if (m_version == VERSION_GEOIP && m_gi != NULL) {\n        GeoIP_delete(m_gi);\n        m_gi = NULL;\n    }\n#endif\n    m_version = NOT_LOADED;\n}\n\n\nbool GeoLookup::setDataBase(const std::string& filePath,\n    std::string *err) {\n#ifdef WITH_MAXMIND\n    std::string intMax;\n#endif\n#ifdef WITH_GEOIP\n    std::string intGeo;\n#endif\n\n#ifdef WITH_MAXMIND\n    int status = MMDB_open(filePath.c_str(), MMDB_MODE_MMAP, &mmdb);\n    if (status != MMDB_SUCCESS) {\n        intMax.assign(\"libMaxMind: Can't open: \" + std::string(MMDB_strerror(status)) + \".\");\n    } else {\n        m_version = VERSION_MAXMIND;\n    }\n#endif\n\n#ifdef WITH_GEOIP\n    if (m_version == NOT_LOADED) {\n        m_gi = GeoIP_open(filePath.c_str(), GEOIP_MEMORY_CACHE);\n        if (m_gi == NULL) {\n            intGeo.append(\"GeoIP: Can't open: \" + filePath + \".\");\n        } else {\n            m_version = VERSION_GEOIP;\n        }\n    }\n#endif\n\n    if (m_version == NOT_LOADED) {\n        err->assign(\"Can't open:  \" + filePath + \". \");\n        err->append(\"Support enabled for:\");\n#ifdef WITH_MAXMIND\n        err->append(\" libMaxMind\");\n#endif\n#ifdef WITH_GEOIP\n        err->append(\" GeoIP\");\n#endif\n        err->append(\".\");\n\n#ifdef WITH_MAXMIND\n        if (!intMax.empty()) {\n            err->append(\" \" + intMax);\n        }\n#endif\n#ifdef WITH_GEOIP\n        if (!intGeo.empty()) {\n            err->append(\" \" + intGeo);\n        }\n#endif\n\n        return false;\n    }\n\n    return true;\n}\n\n\nbool GeoLookup::lookup(const std::string& target, Transaction *trans,\n    std::function<bool(int, const std::string &)> debug) const {\n\n    if (m_version == NOT_LOADED) {\n        if (debug) {\n            debug(4, \"Database is not open. \" \\\n                \"Use: SecGeoLookupDb directive.\");\n        }\n        return false;\n    }\n\n#ifdef WITH_MAXMIND\n    if (m_version == VERSION_MAXMIND) {\n        int gai_error, mmdb_error;\n        MMDB_lookup_result_s r;\n\n        r = MMDB_lookup_string(&mmdb, target.c_str(), &gai_error, &mmdb_error);\n\n        if (gai_error) {\n            if (debug) {\n                debug(4, \"MaxMind: Error from getaddrinfo for: \" +\n                    target + \". \" + gai_strerror(gai_error));\n            }\n            return false;\n        }\n\n        if (mmdb_error != MMDB_SUCCESS) {\n            if (debug) {\n                debug(4, \"MaxMind: Got an error from libmaxminddb: \" +\n                    std::string(MMDB_strerror(mmdb_error)));\n            }\n            return false;\n        }\n\n        if (!r.found_entry) {\n            return false;\n        } else {\n            MMDB_entry_data_s entry_data;\n\n            int status = MMDB_get_value(&r.entry, &entry_data,\n                \"country\", \"iso_code\", NULL);\n            if (status == MMDB_SUCCESS && entry_data.has_data) {\n                trans->m_variableGeo.set(\"COUNTRY_CODE\",\n                    std::string(entry_data.utf8_string,\n                        entry_data.data_size), 0);\n            }\n\n            status = MMDB_get_value(&r.entry, &entry_data,\n                \"country\", \"names\", \"en\", NULL);\n            if (status == MMDB_SUCCESS && entry_data.has_data) {\n                trans->m_variableGeo.set(\"COUNTRY_NAME\",\n                    std::string(entry_data.utf8_string,\n                        entry_data.data_size), 0);\n            }\n\n            status = MMDB_get_value(&r.entry, &entry_data,\n                \"continent\", \"names\", \"en\", NULL);\n            if (status == MMDB_SUCCESS && entry_data.has_data) {\n                trans->m_variableGeo.set(\"COUNTRY_CONTINENT\",\n                    std::string(entry_data.utf8_string,\n                        entry_data.data_size), 0);\n            }\n\n            status = MMDB_get_value(&r.entry, &entry_data,\n                \"city\", \"names\", \"en\", NULL);\n            if (status == MMDB_SUCCESS && entry_data.has_data) {\n                trans->m_variableGeo.set(\"CITY\",\n                    std::string(entry_data.utf8_string,\n                        entry_data.data_size), 0);\n            }\n\n            status = MMDB_get_value(&r.entry, &entry_data,\n                \"postal\", \"code\", NULL);\n            if (status == MMDB_SUCCESS && entry_data.has_data) {\n                trans->m_variableGeo.set(\"POSTAL_CODE\",\n                    std::string(entry_data.utf8_string,\n                        entry_data.data_size), 0);\n            }\n\n            status = MMDB_get_value(&r.entry, &entry_data,\n                \"location\", \"latitude\", NULL);\n            if (status == MMDB_SUCCESS && entry_data.has_data) {\n                trans->m_variableGeo.set(\"LATITUDE\",\n                    std::to_string(entry_data.double_value), 0);\n            }\n\n            status = MMDB_get_value(&r.entry, &entry_data,\n                \"location\", \"longitude\", NULL);\n            if (status == MMDB_SUCCESS && entry_data.has_data) {\n                trans->m_variableGeo.set(\"LONGITUDE\",\n                    std::to_string(entry_data.double_value), 0);\n            }\n\n            /*\n            status = MMDB_get_value(&r.entry, &entry_data,\n                NULL);\n            if (status == MMDB_SUCCESS && entry_data.has_data) {\n                trans->m_variableGeo.set(\"COUNTRY_CODE3\",\n                    std::string(entry_data.utf8_string), 0);\n            }\n\n            status = MMDB_get_value(&r.entry, &entry_data,\n                NULL);\n            if (status == MMDB_SUCCESS && entry_data.has_data) {\n                trans->m_variableGeo.set(\"REGION\",\n                    std::string(entry_data.utf8_string), 0);\n            }\n\n            status = MMDB_get_value(&r.entry, &entry_data,\n                NULL);\n            if (status == MMDB_SUCCESS && entry_data.has_data) {\n                trans->m_variableGeo.set(\"DMA_CODE\",\n                    std::string(entry_data.utf8_string), 0);\n            }\n\n            status = MMDB_get_value(&r.entry, &entry_data,\n                NULL);\n            if (status == MMDB_SUCCESS && entry_data.has_data) {\n                trans->m_variableGeo.set(\"AREA_CODE\",\n                    std::string(entry_data.utf8_string), 0);\n            }\n            */\n        }\n    }\n#endif\n\n#ifdef WITH_GEOIP\n    if (m_version == VERSION_GEOIP) {\n        GeoIPRecord *gir;\n        gir = GeoIP_record_by_name(m_gi, target.c_str());\n        if (gir == NULL) {\n            return false;\n        }\n\n        if (trans) {\n            if (gir->country_code) {\n                trans->m_variableGeo.set(\"COUNTRY_CODE\",\n                    std::string(gir->country_code), 0);\n            }\n            if (gir->country_code3) {\n                trans->m_variableGeo.set(\"COUNTRY_CODE3\",\n                    std::string(gir->country_code3), 0);\n            }\n            if (gir->country_name) {\n                trans->m_variableGeo.set(\"COUNTRY_NAME\",\n                    std::string(gir->country_name), 0);\n            }\n            if (gir->continent_code) {\n                trans->m_variableGeo.set(\"COUNTRY_CONTINENT\",\n                    std::string(gir->continent_code), 0);\n            }\n            if (gir->country_code && gir->region) {\n                trans->m_variableGeo.set(\"REGION\",\n                    std::string(GeoIP_region_name_by_code(gir->country_code,\n                        gir->region)), 0);\n            }\n            if (gir->city) {\n                trans->m_variableGeo.set(\"CITY\", std::string(gir->city), 0);\n            }\n            if (gir->postal_code) {\n                trans->m_variableGeo.set(\"POSTAL_CODE\",\n                    std::string(gir->postal_code), 0);\n            }\n            if (gir->latitude) {\n                trans->m_variableGeo.set(\"LATITUDE\",\n                    std::to_string(gir->latitude), 0);\n            }\n            if (gir->longitude) {\n                trans->m_variableGeo.set(\"LONGITUDE\",\n                    std::to_string(gir->longitude), 0);\n            }\n            if (gir->metro_code) {\n                trans->m_variableGeo.set(\"DMA_CODE\",\n                    std::to_string(gir->metro_code), 0);\n            }\n            if (gir->area_code) {\n                trans->m_variableGeo.set(\"AREA_CODE\",\n                    std::to_string(gir->area_code), 0);\n            }\n        }\n\n        GeoIPRecord_delete(gir);\n    }\n#endif\n\n    return true;\n}\n\n\n\n}  // namespace Utils\n}  // namespace modsecurity\n\n"
  },
  {
    "path": "src/utils/geo_lookup.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <iostream>\n#include <fstream>\n#include <string>\n#include <functional>\n\n#if WITH_MAXMIND\n#include <maxminddb.h>\n#endif\n#if WITH_GEOIP\n#include <GeoIPCity.h>\n#endif\n\n#ifndef SRC_UTILS_GEO_LOOKUP_H_\n#define SRC_UTILS_GEO_LOOKUP_H_\n\n#include \"modsecurity/transaction.h\"\n\nnamespace modsecurity {\nnamespace Utils {\n\nenum GeoLookupVersion {\n    NOT_LOADED,\n    VERSION_MAXMIND,\n    VERSION_GEOIP,\n};\n\nclass GeoLookup {\n public:\n    static GeoLookup& getInstance() {\n        static GeoLookup instance;\n        return instance;\n    }\n\n    bool setDataBase(const std::string& filePath, std::string *err);\n    void cleanUp();\n\n    bool lookup(const std::string& target, Transaction *transaction,\n        std::function<bool(int, const std::string &)> debug) const;\n\n private:\n    GeoLookup() :\n        m_version(NOT_LOADED)\n#if WITH_GEOIP\n        ,m_gi(NULL)\n#endif\n        { }\n    ~GeoLookup();\n    GeoLookup(GeoLookup const&);\n    void operator=(GeoLookup const&);\n\n    GeoLookupVersion m_version;\n#if WITH_MAXMIND\n    MMDB_s mmdb;\n#endif\n#if WITH_GEOIP\n    GeoIP *m_gi;\n#endif\n\n};\n\n\n}  // namespace Utils\n}  // namespace modsecurity\n\n#endif  // SRC_UTILS_GEO_LOOKUP_H_\n"
  },
  {
    "path": "src/utils/https_client.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"src/utils/https_client.h\"\n#include \"src/config.h\"\n\n#ifdef MSC_WITH_CURL\n#include <curl/curl.h>\n#endif\n\n#ifndef WIN32\n#include <sys/socket.h>\n#include <sys/types.h>\n#include <netinet/in.h>\n#include <arpa/inet.h>\n#else\n#include <WinSock2.h>\n#endif\n#include <string>\n\n#include <fstream>\n#include <iostream>\n\n#include \"modsecurity/modsecurity.h\"\n#include \"src/unique_id.h\"\n\nnamespace modsecurity {\nnamespace Utils {\n\n\nsize_t HttpsClient::handle(char * data, size_t size, size_t nmemb, void * p) {\n    return static_cast<HttpsClient*>(p)->handle_impl(data, size, nmemb);\n}\n\n\nsize_t HttpsClient::handle_impl(char* data, size_t size, size_t nmemb) {\n    content.append(data, size * nmemb);\n    return size * nmemb;\n}\n\nvoid HttpsClient::setKey(const std::string& key) {\n    m_key = \"ModSec-key: \" + key;\n}\n\nvoid HttpsClient::setRequestBody(const std::string& requestBody) {\n    m_requestBody = requestBody;\n}\n\nvoid HttpsClient::setRequestType(const std::string& requestType) {\n    m_requestType = requestType;\n}\n\n\n#ifdef MSC_WITH_CURL\nbool HttpsClient::download(const std::string &uri) {\n    CURL *curl;\n    CURLcode res;\n    std::string uniqueId = \"ModSec-unique-id: \" + UniqueId::uniqueId();\n    std::string status = \"ModSec-status: \" + std::to_string(MODSECURITY_VERSION_NUM);\n\n    curl = curl_easy_init();\n    if (!curl) {\n        error = \"Not able to initialize libcurl\";\n        return false;\n    }\n\n    struct curl_slist *headers_chunk = NULL;\n    curl_easy_setopt(curl, CURLOPT_URL, uri.c_str());\n\n    headers_chunk = curl_slist_append(headers_chunk, uniqueId.c_str());\n    headers_chunk = curl_slist_append(headers_chunk, status.c_str());\n\n    if (m_requestType.empty() == false) {\n        std::string hdr = \"Content-Type: \" + m_requestType;\n        headers_chunk = curl_slist_append(headers_chunk, hdr.c_str());\n    }\n\n    if (m_key.empty() == false) {\n        headers_chunk = curl_slist_append(headers_chunk, m_key.c_str());\n    }\n\n    /* Make it TLS 1.2 at least. */\n    curl_easy_setopt(curl, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1_2);\n\n    /* those are the default options, but lets make sure */\n    curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 1);\n    curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 1);\n\n#ifdef WIN32\n    /* use the operating system's native CA store for certificate verification.*/\n    curl_easy_setopt(curl, CURLOPT_SSL_OPTIONS, (long)CURLSSLOPT_NATIVE_CA);\n#endif\n\n    /* send all data to this function  */\n    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &HttpsClient::handle);\n\n    /* we pass our 'chunk' struct to the callback function */\n    curl_easy_setopt(curl, CURLOPT_WRITEDATA, this);\n\n    curl_easy_setopt(curl, CURLOPT_USERAGENT, \"ModSecurity3\");\n\n    /* We want Curl to return error in case there is an HTTP error code */\n    curl_easy_setopt(curl, CURLOPT_FAILONERROR, 1);\n\n    if (m_requestBody.empty() == false) {\n        curl_easy_setopt(curl, CURLOPT_POSTFIELDS, m_requestBody.c_str());\n        headers_chunk = curl_slist_append(headers_chunk, \"Expect:\"); // Disable Expect: 100-continue\n    }\n\n    /* set HTTP headers for request */\n    curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers_chunk);\n\n    res = curl_easy_perform(curl);\n\n    curl_slist_free_all(headers_chunk);\n\n    if (res != CURLE_OK) {\n        error = curl_easy_strerror(res);\n    }\n\n    curl_easy_cleanup(curl);\n\n    return res == CURLE_OK;\n}\n#else\nbool HttpsClient::download(const std::string &uri) {\n    error = \"Not compiled with libcurl support\";\n    return false;\n}\n#endif\n\n}  // namespace Utils\n}  // namespace modsecurity\n\n"
  },
  {
    "path": "src/utils/https_client.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#ifdef MSC_WITH_CURL\n#include <curl/curl.h>\n#endif\n\n#include <iostream>\n#include <fstream>\n#include <string>\n#include <functional>\n\n#ifndef SRC_UTILS_HTTPS_CLIENT_H_\n#define SRC_UTILS_HTTPS_CLIENT_H_\n\n#include \"modsecurity/transaction.h\"\n\nnamespace modsecurity {\nnamespace Utils {\n\n\nclass HttpsClient {\n public:\n    HttpsClient()\n        : content(\"\"),\n        error(\"\"),\n        m_key(\"\"),\n        m_requestBody(\"\"),\n        m_requestType(\"\") { }\n\n    bool download(const std::string &uri);\n    std::string content;\n\n    static size_t handle(char * data, size_t size, size_t nmemb, void * p);\n    size_t handle_impl(char * data, size_t size, size_t nmemb);\n    void setKey(const std::string& key);\n    void setRequestType(const std::string& requestType);\n    void setRequestBody(const std::string& requestBody);\n\n    std::string error;\n private:\n    std::string m_key;\n    std::string m_requestBody;\n    std::string m_requestType;\n};\n\n\n}  // namespace Utils\n}  // namespace modsecurity\n\n#endif  // SRC_UTILS_HTTPS_CLIENT_H_\n"
  },
  {
    "path": "src/utils/ip_tree.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2022 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"src/utils/ip_tree.h\"\n\n#ifndef WIN32\n#include <sys/socket.h>\n#include <sys/types.h>\n#include <netinet/in.h>\n#include <arpa/inet.h>\n#else\n#include <WinSock2.h>\n#endif\n#include <string>\n\n#include <fstream>\n#include <iostream>\n\n#include \"src/utils/geo_lookup.h\"\n#include \"src/utils/https_client.h\"\n\nnamespace modsecurity {\nnamespace Utils {\n\nvoid IpTree::postOrderTraversal(TreeNode *node) {\n    if (node == NULL) {\n        return;\n    }\n\n    postOrderTraversal(node->left);\n    postOrderTraversal(node->right);\n\n    if (node->netmasks) {\n        free(node->netmasks);\n        node->netmasks = NULL;\n    }\n    if (node->prefix) {\n        if (node->prefix->buffer) {\n            free(node->prefix->buffer);\n            node->prefix->buffer = NULL;\n        }\n        if (node->prefix->prefix_data) {\n            free(node->prefix->prefix_data);\n            node->prefix->prefix_data = NULL;\n        }\n        free(node->prefix);\n        node->prefix = NULL;\n    }\n    free(node);\n}\n\n\nIpTree::IpTree() {\n    // FIXME: deal with possible error.\n    char *error;\n    create_radix_tree(&m_tree, &error);\n}\n\n\nIpTree::~IpTree() {\n    if (m_tree != NULL) {\n        if (m_tree->ipv4_tree != NULL) {\n            // Tree_traversal: Post-order to delete all the items.\n            postOrderTraversal(m_tree->ipv4_tree->head);\n            free(m_tree->ipv4_tree);\n            m_tree->ipv4_tree = NULL;\n        }\n        if (m_tree->ipv6_tree != NULL) {\n            // Tree_traversal: Post-order to delete all the items.\n            postOrderTraversal(m_tree->ipv6_tree->head);\n            free(m_tree->ipv6_tree);\n            m_tree->ipv6_tree = NULL;\n        }\n\n        free(m_tree);\n        m_tree = NULL;\n    }\n}\n\nbool IpTree::addFromBuffer(std::istream *ss, std::string *error) {\n    char *error_msg = NULL;\n    for (std::string line; std::getline(*ss, line); ) {\n        size_t comment_start = line.find('#');\n        if (comment_start != std::string::npos) {\n            line = line.substr(0, comment_start);\n        }\n        int res = add_ip_from_param(line.c_str(), &m_tree, &error_msg);\n        if (res != 0) {\n            if (error_msg != NULL) {\n                error->assign(error_msg);\n            }\n            return false;\n        }\n    }\n\n    return true;\n}\n\n\nbool IpTree::addFromBuffer(const std::string& buffer, std::string *error) {\n    std::stringstream ss;\n    ss << buffer;\n    return addFromBuffer(&ss, error);\n}\n\n\nbool IpTree::addFromFile(const std::string& file, std::string *error) {\n    std::ifstream myfile(file, std::ios::in);\n\n    if (myfile.is_open() == false) {\n        error->assign(\"Failed to open file: \" + file);\n        return false;\n    }\n\n    return addFromBuffer(&myfile, error);\n}\n\n\nbool IpTree::addFromUrl(const std::string& url, std::string *error) {\n    HttpsClient c;\n    bool ret = c.download(url);\n\n    if (ret == false) {\n        error->assign(c.error);\n    } else {\n        ret = addFromBuffer(c.content, error);\n    }\n\n    return ret;\n}\n\n\nbool IpTree::contains(const std::string& ip) {\n    int res = 0;\n    char *error_msg = NULL;\n\n    res = tree_contains_ip(m_tree, ip.c_str(), &error_msg);\n\n    if (res < 0) {\n        return false;\n    }\n\n    if (res > 0) {\n        return true;\n    }\n\n    return false;\n}\n\n\n}  // namespace Utils\n}  // namespace modsecurity\n"
  },
  {
    "path": "src/utils/ip_tree.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <iostream>\n#include <fstream>\n#include <string>\n#include <functional>\n\n#ifndef SRC_UTILS_IP_TREE_H_\n#define SRC_UTILS_IP_TREE_H_\n\n#include \"modsecurity/transaction.h\"\n#include \"src/utils/msc_tree.h\"\n\nnamespace modsecurity {\nnamespace Utils {\n\n\nclass IpTree {\n public:\n    IpTree();\n    IpTree(const IpTree&) = delete;\n    IpTree& operator=(const IpTree&) = delete;\n    ~IpTree();\n\n    bool contains(const std::string &ip);\n    void postOrderTraversal(TreeNode *node);\n    bool addFromBuffer(std::istream *ss, std::string *error);\n    bool addFromBuffer(const std::string& buffer, std::string *error);\n    bool addFromFile(const std::string& file, std::string *error);\n    bool addFromUrl(const std::string& url, std::string *error);\n private:\n    TreeRoot *m_tree;\n};\n\n\n}  // namespace Utils\n}  // namespace modsecurity\n\n#endif  // SRC_UTILS_IP_TREE_H_\n"
  },
  {
    "path": "src/utils/md5.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#ifndef SRC_UTILS_MD5_H_\n#define SRC_UTILS_MD5_H_\n\n#include \"src/utils/sha1.h\"\n#include \"mbedtls/md5.h\"\n#include <string>\n\nnamespace modsecurity::Utils {\n\n\nclass Md5 : public DigestImpl<&mbedtls_md5, 16> {\n};\n\n\n}  // namespace modsecurity::Utils\n\n#endif  // SRC_UTILS_MD5_H_"
  },
  {
    "path": "src/utils/msc_tree.cc",
    "content": "/*\n * ModSecurity for Apache 2.x, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2023 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n */\n\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n#ifndef WIN32\n#include <sys/socket.h>\n#include <netinet/in.h>\n#include <arpa/inet.h>\n#else\n#include \"src/compat/msvc.h\"\n#include <WinSock2.h>\n#include <WS2tcpip.h>\n#endif\n\n#include \"src/utils/msc_tree.h\"\n\nextern \"C\" {\n\nCPTTree *CPTCreateRadixTree()   {\n    CPTTree *tree;\n\n    tree = reinterpret_cast<CPTTree *>(malloc(sizeof(CPTTree)));\n\n    if(tree == NULL)\n        return NULL;\n\n    memset(tree, 0, sizeof(CPTTree));\n\n    return tree;\n}\n\nvoid ConvertIPNetmask(unsigned char *buffer, unsigned char netmask, unsigned int ip_bitmask) {\n    int aux = 0, bytes = 0;\n    int mask = 0;\n\n    bytes = ip_bitmask/8;\n\n    while(aux < bytes)    {\n        int mask_bit  = ((1+aux) * 8);\n\n        if (mask_bit > netmask) {\n            mask = 0;\n            if ((mask_bit - netmask) < 8)   mask = SHIFT_LEFT_MASK(mask_bit - netmask);\n        }   else    {\n            mask = -1;\n        }\n\n        buffer[aux] &= mask;\n        aux++;\n    }\n\n    return;\n}\n\nTreeNode *CPTCreateNode()   {\n    TreeNode *node;\n\n    node = reinterpret_cast<TreeNode *>(malloc(sizeof(TreeNode)));\n\n    if(node == NULL)\n        return NULL;\n\n    memset(node, 0, sizeof(TreeNode));\n    return node;\n}\n\nCPTData *CPTCreateCPTData(unsigned char netmask) {\n\n    CPTData *prefix_data = reinterpret_cast<CPTData *>(malloc(sizeof(CPTData)));\n\n    if (prefix_data == NULL) {\n        return NULL;\n    }\n\n    memset(prefix_data, 0, sizeof(CPTData));\n\n    prefix_data->netmask = netmask;\n\n    return prefix_data;\n}\n\nTreePrefix *InsertDataPrefix(TreePrefix *prefix, unsigned char *ipdata, unsigned int ip_bitmask,\n        unsigned char netmask)  {\n\n    if(prefix == NULL)\n        return NULL;\n\n    memcpy(prefix->buffer, ipdata, ip_bitmask/8);\n    prefix->bitlen = ip_bitmask;\n\n    prefix->prefix_data = CPTCreateCPTData(netmask);\n\n    if(prefix->prefix_data == NULL)\n        return NULL;\n\n    return prefix;\n}\n\nTreePrefix *CPTCreatePrefix(unsigned char *ipdata, unsigned int ip_bitmask,\n        unsigned char netmask)  {\n\n    TreePrefix *prefix = NULL;\n    int bytes = ip_bitmask;\n\n    if ((ip_bitmask % 8 != 0) || (ipdata == NULL)) {\n        return NULL;\n    }\n\n    prefix = reinterpret_cast<TreePrefix *>(malloc(sizeof(TreePrefix)));\n    if (prefix == NULL)\n        return NULL;\n\n    memset(prefix, 0, sizeof(TreePrefix));\n\n    prefix->buffer = reinterpret_cast<unsigned char *>(malloc(bytes));\n\n    if (prefix->buffer == NULL) {\n        free(prefix);\n        return NULL;\n    }\n\n    memset(prefix->buffer, 0, bytes);\n\n    return InsertDataPrefix(prefix, ipdata, ip_bitmask, netmask);\n}\n\nvoid CPTAppendToCPTDataList(CPTData *n, CPTData **list)  {\n    CPTData *temp = NULL, *prev = NULL;\n\n    if (n == NULL) {\n        return;\n    }\n\n    if (list == NULL) {\n        return;\n    }\n\n    prev = *list;\n    temp = *list;\n\n    while (temp != NULL) {\n        if (n->netmask > temp->netmask)\n            break;\n        prev = temp;\n        temp = temp->next;\n    }\n\n    if (temp == *list) {\n        n->next = *list;\n        *list = n;\n    } else {\n        n->next = prev->next;\n        prev->next = n;\n    }\n\n    return;\n}\n\nint TreePrefixContainNetmask(TreePrefix *prefix, unsigned char netmask)   {\n    CPTData *prefix_data = NULL;\n\n    if (prefix == NULL) {\n        return 0;\n    }\n\n    prefix_data = prefix->prefix_data;\n\n    while (prefix_data != NULL) {\n        if (prefix_data->netmask == netmask)\n            return 1;\n        prefix_data = prefix_data->next;\n    }\n\n    return 0;\n}\n\nint CheckBitmask(unsigned char netmask, unsigned int ip_bitmask)   {\n\n    switch(netmask) {\n\n        case 0xff:\n            return 1;\n        case 0x20:\n            if(ip_bitmask == 0x20)\n                return 1;\n            break;\n        case 0x80:\n            if(ip_bitmask == 0x80)\n                return 1;\n            break;\n    }\n\n    return 0;\n}\n\nTreeNode *CPTCreateHead(TreePrefix *prefix, TreeNode *node, CPTTree *tree, unsigned char netmask, unsigned int ip_bitmask)    {\n\n    if(tree == NULL)\n        return NULL;\n\n    if(prefix == NULL)\n        return NULL;\n\n    if (node != NULL)   {\n\n        node->prefix = prefix;\n        node->bit = prefix->bitlen;\n        tree->head = node;\n\n        if(CheckBitmask(netmask, ip_bitmask))\n            return node;\n\n        node->count++;\n        node->netmasks = reinterpret_cast<unsigned char *>(malloc(node->count *  sizeof(unsigned char)));\n\n        if(node->netmasks)\n            node->netmasks[0] = netmask;\n\n        return node;\n\n    } else {\n        return NULL;\n    }\n\n    return NULL;\n}\n\nTreeNode *SetParentNode(TreeNode *node, TreeNode *new_node, CPTTree *tree)  {\n\n    if (node->parent == NULL)\n        tree->head = new_node;\n    else if (node->parent->right == node)\n        node->parent->right = new_node;\n    else\n        node->parent->left = new_node;\n\n    return new_node;\n}\n\nint InsertNetmask(TreeNode *node, TreeNode *parent, TreeNode *new_node,\n        CPTTree *tree, unsigned char netmask, unsigned char bitlen) {\n    if (netmask != NETMASK_256-1 && netmask != NETMASK_128) {\n        if (netmask != NETMASK_32 || bitlen != NETMASK_32) {\n            int i;\n            node = new_node;\n            parent = new_node->parent;\n\n            while (parent != NULL && netmask < (parent->bit + 1)) {\n                node = parent;\n                parent = parent->parent;\n            }\n\n            node->count++;\n\n            node->netmasks = reinterpret_cast<unsigned char *>(malloc(node->count * sizeof(unsigned char)));\n            if(node->netmasks == NULL) {\n                return 0;\n            }\n            memset(node->netmasks, 0, (node->count *  sizeof(unsigned char)));\n\n            if ((node->count-1) == 0) {\n                node->netmasks[0] = netmask;\n                return 1;\n            }\n\n            node->netmasks[node->count - 1] = netmask;\n\n            i = node->count - 2;\n            while (i >= 0) {\n                if (netmask < node->netmasks[i]) {\n                    node->netmasks[i + 1] = netmask;\n                    break;\n                }\n\n                node->netmasks[i + 1] = node->netmasks[i];\n                node->netmasks[i] = netmask;\n                i--;\n            }\n        }\n    }\n\n    return 0;\n}\n\nTreeNode *CPTAddElement(unsigned char *ipdata, unsigned int ip_bitmask, CPTTree *tree, unsigned char netmask)   {\n    unsigned char *buffer = NULL;\n    unsigned char bitlen = 0;\n    int bit_validation = 0, test_bit = 0;\n    size_t i = 0;\n    unsigned int x, y;\n    TreeNode *node = NULL, *new_node = NULL;\n    TreeNode *parent = NULL, *i_node = NULL;\n    TreeNode *bottom_node = NULL;\n    TreePrefix *prefix = NULL;\n\n    if (tree == NULL) {\n        return NULL;\n    }\n\n    ConvertIPNetmask(ipdata, netmask, ip_bitmask);\n\n    prefix = CPTCreatePrefix(ipdata, ip_bitmask, netmask);\n\n    if (prefix == NULL) {\n        return NULL;\n    }\n\n    if (tree->head == NULL) {\n        node = CPTCreateNode();\n        return CPTCreateHead(prefix, node, tree, netmask, ip_bitmask);\n    }\n\n    node = tree->head;\n    buffer = prefix->buffer;\n    bitlen = prefix->bitlen;\n\n    while (node->bit < bitlen || node->prefix == NULL) {\n\n        if (bitlen < node->bit) {\n            if (node->right == NULL)\n                break;\n            else\n                node = node->right;\n        } else {\n            x = SHIFT_RIGHT_MASK(node->bit, 3); y = SHIFT_RIGHT_MASK(NETMASK_128, (node->bit % 8));\n\n            if (TREE_CHECK(buffer[x],y)) {\n                if (node->right == NULL)\n                    break;\n                node = node->right;\n            } else {\n                if (node->left == NULL)\n                    break;\n                else\n                    node = node->left;\n            }\n        }\n    }\n\n    bottom_node = node;\n\n    if(node->bit < bitlen)\n        bit_validation = node->bit;\n    else\n        bit_validation = bitlen;\n\n    for (i = 0; (i * NETMASK_8) < bit_validation; i++) {\n        int net = 0, div = 0;\n        int cnt = 0;\n        int temp;\n\n        if ((temp = (buffer[i] ^ bottom_node->prefix->buffer[i])) == 0) {\n            test_bit = (i + 1) * NETMASK_8;\n            continue;\n        }\n\n        temp += temp;\n\n        for(cnt = 0, net = NETMASK_256, div = 2; net >= NETMASK_2; net = NETMASK_256/div,\n                div += div, cnt++)      {\n            if(temp >= net)   {\n                test_bit = (i * NETMASK_8) + cnt;\n                break;\n            }\n        }\n        break;\n    }\n\n    if (bit_validation < test_bit)\n        test_bit = bit_validation;\n\n    parent = node->parent;\n\n    while (parent && test_bit <= parent->bit) {\n        node = parent;\n        parent = node->parent;\n    }\n\n    if (test_bit == bitlen && node->bit == bitlen) {\n        if (node->prefix != NULL) {\n            int found = 0;\n            CPTData *prefix_data;\n\n            prefix_data = node->prefix->prefix_data;\n\n            while(prefix_data != NULL)  {\n                if (prefix_data->netmask == netmask)\n                    ++found;\n                prefix_data = prefix_data->next;\n            }\n\n            if (found != 0) {\n\n                CPTData *prefix_data = CPTCreateCPTData(netmask);\n                CPTAppendToCPTDataList(prefix_data, &prefix->prefix_data);\n\n                if(CheckBitmask(netmask, ip_bitmask))\n                    return node;\n\n                parent = node->parent;\n                while (parent != NULL && netmask < (parent->bit + 1)) {\n                    node = parent;\n                    parent = parent->parent;\n                }\n\n                node->count++;\n                new_node = node;\n                node->netmasks = reinterpret_cast<unsigned char *>(malloc(node->count *  sizeof(unsigned char)));\n                memset(node->netmasks, 0, (node->count *  sizeof(unsigned char)));\n\n                if ((node->count -1) == 0) {\n                    node->netmasks[0] = netmask;\n                    return new_node;\n                }\n\n                node->netmasks[node->count - 1] = netmask;\n\n                int index = node->count - 2;\n                while (index >= 0) {\n                    if (netmask < node->netmasks[index]) {\n                        node->netmasks[index + 1] = netmask;\n                        break;\n                    }\n\n                    node->netmasks[index + 1] = node->netmasks[index];\n                    node->netmasks[index] = netmask;\n                    index--;\n                }\n            }\n        } else {\n            node->prefix = CPTCreatePrefix(prefix->buffer, prefix->bitlen,\n                    NETMASK_256-1);\n        }\n        return node;\n    }\n\n    new_node = CPTCreateNode();\n\n    if(new_node == NULL)\n        return NULL;\n\n    new_node->prefix = prefix;\n    new_node->bit = prefix->bitlen;\n\n    if (test_bit == bitlen) {\n\n        x = SHIFT_RIGHT_MASK(test_bit, 3); y = SHIFT_RIGHT_MASK(NETMASK_128, (test_bit % 8));\n\n        if (TREE_CHECK(bottom_node->prefix->buffer[x],y)) {\n            new_node->right = node;\n        } else {\n            new_node->left = node;\n        }\n\n        new_node->parent = node->parent;\n        node->parent = SetParentNode(node, new_node, tree);\n\n    } else {\n        i_node = CPTCreateNode();\n\n        if (i_node == NULL) {\n            free(new_node->prefix);\n            free(new_node);\n            return NULL;\n        }\n\n        //i_node->prefix = NULL;\n        i_node->bit = test_bit;\n        i_node->parent = node->parent;\n\n        if (node->netmasks != NULL) {\n            i = 0;\n            int j;\n            while(i < node->count) {\n                if (node->netmasks[i] < test_bit + 1)\n                    break;\n                i++;\n            }\n\n            i_node->netmasks = reinterpret_cast<unsigned char *>(malloc((node->count - i) * sizeof(unsigned char)));\n            memset(i_node->netmasks, 0, ((node->count - i) * sizeof(unsigned char)));\n\n            if(i_node->netmasks == NULL) {\n                free(new_node->prefix);\n                free(new_node);\n                free(i_node);\n                return NULL;\n            }\n\n            j = 0;\n            while (j < (node->count - i))   {\n                i_node->netmasks[j] = node->netmasks[i + j];\n                j++;\n            }\n\n            i_node->count = (node->count - i);\n            node->count = i;\n\n            if (node->count == 0) {\n                node->netmasks = NULL;\n            }\n        }\n\n        x = SHIFT_RIGHT_MASK(test_bit, 3); y = SHIFT_RIGHT_MASK(NETMASK_128, (test_bit % 8));\n\n        if (TREE_CHECK(buffer[x],y)) {\n            i_node->left = node;\n            i_node->right = new_node;\n        } else {\n            i_node->left = new_node;\n            i_node->right = node;\n        }\n\n        new_node->parent = i_node;\n        node->parent = SetParentNode(node, i_node, tree);\n    }\n\n    if (InsertNetmask(node, parent, new_node, tree, netmask, bitlen))\n        return new_node;\n\n    return new_node;\n}\n\nint TreeCheckData(TreePrefix *prefix, CPTData *prefix_data, unsigned int netmask)   {\n\n    while(prefix_data != NULL)  {\n        if (prefix_data->netmask == netmask) {\n            return 1;\n        }\n        prefix_data = prefix_data->next;\n    }\n\n    return 0;\n}\n\nint TreePrefixNetmask(TreePrefix *prefix, unsigned int netmask, int flag)   {\n    CPTData *prefix_data = NULL;\n    int ret = 0;\n\n    if (prefix == NULL) {\n        //if (msr && msr->txcfg->debuglog_level >= 9) {\n        //    msr_log(msr, 9, \"TreePrefixNetmask: prefix is NULL.\");\n        //}\n        return 0;\n    }\n\n    prefix_data = prefix->prefix_data;\n\n    if (flag == 1) {\n\n        if(prefix_data == NULL) return 0;\n\n        if (prefix_data->netmask != netmask) {\n            //if (msr && msr->txcfg->debuglog_level >= 9) {\n            //    msr_log(msr, 9, \"TreePrefixNetmask: Cannot find a prefix with correct netmask.\");\n            //}\n            return 0;\n        } else {\n            //if (msr && msr->txcfg->debuglog_level >= 9) {\n            //    msr_log(msr, 9, \"TreePrefixNetmask: Found a prefix with correct netmask.\");\n            //}\n            return 1;\n        }\n    }\n\n    //if (msr && msr->txcfg->debuglog_level >= 9) {\n    //    msr_log(msr, 9, \"TreePrefixNetmask: Check if a prefix has a the correct netmask\");\n    //}\n\n    ret = TreeCheckData(prefix, prefix_data, netmask);\n\n    return ret;\n}\n\nTreeNode *CPTRetriveNode(unsigned char *buffer, unsigned int ip_bitmask, TreeNode *node)  {\n\n    if(node == NULL)    {\n        //if (msr && msr->txcfg->debuglog_level >= 9) {\n        //    msr_log(msr, 9, \"CPTRetriveNode: Node tree is NULL.\");\n        //}\n        return NULL;\n    }\n\n    if(buffer == NULL)  {\n        //if (msr && msr->txcfg->debuglog_level >= 9) {\n        //    msr_log(msr, 9, \"CPTRetriveNode: Empty ip address. Nothing to search for.\");\n        //}\n        return NULL;\n    }\n\n    while (node->bit < ip_bitmask) {\n        unsigned int x = SHIFT_RIGHT_MASK(node->bit, 3);\n        unsigned int y = SHIFT_RIGHT_MASK(NETMASK_128, (node->bit % 8));\n\n        if (TREE_CHECK(buffer[x], y)) {\n            node = node->right;\n            if (node == NULL)   return NULL;\n        } else {\n            node = node->left;\n            if (node == NULL)   return NULL;\n        }\n    }\n\n    //if (msr && msr->txcfg->debuglog_level >= 9) {\n    //    msr_log(msr, 9, \"CPTRetriveNode: Found the node for provided ip address.\");\n    //}\n\n\n    return node;\n}\n\nTreeNode *CPTRetriveParentNode(TreeNode *node)  {\n\n    while (node != NULL && node->netmasks == NULL)\n        node = node->parent;\n\n    return node;\n}\n\nTreeNode *CPTFindElementIPNetblock(unsigned char *ipdata, unsigned char ip_bitmask, TreeNode *node) {\n    TreeNode *netmask_node = NULL;\n    int mask = 0;\n    int i = 0, j = 0;\n    int mask_bits = 0;\n\n    node = CPTRetriveParentNode(node);\n\n    if (node == NULL)   {\n        //if (msr && msr->txcfg->debuglog_level >= 9) {\n        //    msr_log(msr, 9, \"CPTFindElementIPNetblock: Node tree is NULL.\");\n        //}\n        return NULL;\n    }\n\n    netmask_node = node;\n\n    while(j < netmask_node->count)    {\n        int bytes = ip_bitmask / 8;\n\n        while( i < bytes )  {\n\n            mask = -1;\n            mask_bits = ((i + 1) * 8);\n\n            if (mask_bits > netmask_node->netmasks[j]) {\n                if ((mask_bits - netmask_node->netmasks[j]) < 8)\n                    mask = SHIFT_LEFT_MASK(mask_bits - netmask_node->netmasks[j]);\n                else\n                    mask = 0;\n            }\n\n            ipdata[i] &= mask;\n            i++;\n        }\n\n        node = CPTRetriveNode(ipdata, ip_bitmask, node);\n\n        if(node == NULL)    {\n            //if (msr && msr->txcfg->debuglog_level >= 9) {\n            //    msr_log(msr, 9, \"CPTFindElement: Node tree is NULL.\");\n            //}\n            return node;\n        }\n\n        if (node->bit != ip_bitmask)    {\n            //if (msr && msr->txcfg->debuglog_level >= 9) {\n            //    msr_log(msr, 9, \"CPTFindElementIPNetblock: Found a tree node but netmask is different.\");\n            //}\n            return NULL;\n        }\n\n        if (node->prefix == NULL)   {\n            //if (msr && msr->txcfg->debuglog_level >= 9) {\n            //    msr_log(msr, 9, \"CPTFindElementIPNetblock: Found a tree node but prefix is NULL.\");\n            //}\n            return NULL;\n        }\n\n        if (memcmp(node->prefix->buffer, ipdata, bytes) == 0) {\n            mask = SHIFT_LEFT_MASK(8 - ip_bitmask % 8);\n\n            if ((ip_bitmask % 8) == 0) {\n                if (TreePrefixNetmask(node->prefix, netmask_node->netmasks[j], FALSE)) {\n                    //if (msr && msr->txcfg->debuglog_level >= 9) {\n                    //    msr_log(msr, 9, \"CPTFindElementIPNetblock: Node found for provided ip address\");\n                    //}\n                    return node;\n                }\n            }\n\n            if ((node->prefix->buffer[bytes] & mask) == (ipdata[bytes] & mask)) {\n                if (TreePrefixNetmask(node->prefix, netmask_node->netmasks[j], FALSE)) {\n                    //if (msr && msr->txcfg->debuglog_level >= 9) {\n                    //    msr_log(msr, 9, \"CPTFindElementIPNetblock: Node found for provided ip address\");\n                    //}\n                    return node;\n                }\n            }\n        }\n\n        j++;\n    }\n\n    return CPTFindElementIPNetblock(ipdata, ip_bitmask, netmask_node->parent);\n}\n\nTreeNode *CPTFindElement(unsigned char *ipdata, unsigned int ip_bitmask, CPTTree *tree)   {\n    TreeNode *node = NULL;\n    int mask = 0, bytes = 0;\n    unsigned char temp_data[NETMASK_256-1];\n\n    if (tree == NULL)   {\n        //if (msr && msr->txcfg->debuglog_level >= 9) {\n        //    msr_log(msr, 9, \"CPTFindElement: Tree is NULL. Cannot proceed searching the ip.\");\n        //}\n        return node;\n    }\n\n    if (tree->head == NULL) {\n        //if (msr && msr->txcfg->debuglog_level >= 9) {\n        //    msr_log(msr, 9, \"CPTFindElement: Tree head is NULL. Cannot proceed searching the ip.\");\n        //}\n        return node;\n    }\n\n    node = tree->head;\n\n    if (ip_bitmask > (NETMASK_256-1))   {\n        //if (msr && msr->txcfg->debuglog_level >= 9) {\n        //    msr_log(msr, 9, \"CPTFindElement: Netmask cannot be greater than 255\");\n        //}\n        return NULL;\n    }\n\n    bytes = ip_bitmask/8;\n\n    memset(temp_data, 0, NETMASK_256-1);\n    memcpy(temp_data, ipdata, bytes);\n\n    node = CPTRetriveNode(temp_data, ip_bitmask, node);\n\n    if(node == NULL)    {\n        //if (msr && msr->txcfg->debuglog_level >= 9) {\n        //    msr_log(msr, 9, \"CPTFindElement: Node tree is NULL.\");\n        //}\n        return node;\n    }\n\n    if (node->bit != ip_bitmask) {\n        //if (msr && msr->txcfg->debuglog_level >= 9) {\n        //    msr_log(msr, 9, \"CPTFindElement: Found a tree node but netmask is different.\");\n        //}\n        return NULL;\n    }\n\n    if(node->prefix == NULL)    {\n        //if (msr && msr->txcfg->debuglog_level >= 9) {\n        //    msr_log(msr, 9, \"CPTFindElement: Found a tree node but prefix is NULL.\");\n        //}\n        return node;\n    }\n\n    if ((node->netmasks == NULL) && memcmp(node->prefix->buffer, temp_data, bytes) == 0) {\n        mask = SHIFT_LEFT_MASK(8 - ip_bitmask % 8);\n\n        if ((ip_bitmask % 8) == 0) {\n            if (TreePrefixNetmask(node->prefix, ip_bitmask, TRUE)) {\n                //if (msr && msr->txcfg->debuglog_level >= 9) {\n                    //msr_log(msr, 9, \"CPTFindElement: Node found for provided ip address\");\n                //}\n                return node;\n            }\n        }\n        if ((node->prefix->buffer[bytes] & mask) == (temp_data[bytes] & mask)) {\n            if (TreePrefixNetmask(node->prefix, ip_bitmask, TRUE)) {\n                //if (msr && msr->txcfg->debuglog_level >= 9) {\n                    //msr_log(msr, 9, \"CPTFindElement: Node found for provided ip address\");\n                //}\n                return node;\n            }\n        }\n    }\n\n    return CPTFindElementIPNetblock(temp_data, ip_bitmask, node);\n}\n\nTreeNode *CPTIpMatch(unsigned char *ipdata, CPTTree *tree, int type)   {\n\n    if(tree == NULL)  {\n        //if (msr && msr->txcfg->debuglog_level >= 9) {\n            //msr_log(msr, 9, \"CPTIpMatch: Tree is NULL. Cannot proceed searching the ip.\");\n        //}\n        return NULL;\n    }\n\n    if(ipdata == NULL)  {\n        //if (msr && msr->txcfg->debuglog_level >= 9) {\n            //msr_log(msr, 9, \"CPTIpMatch: Empty ip address. Nothing to search for.\");\n        //}\n        return NULL;\n    }\n\n    switch(type)    {\n        case IPV4_TREE:\n            //if (msr && msr->txcfg->debuglog_level >= 9) {\n                //msr_log(msr, 9, \"CPTIpMatch: Searching ip type 0x%x\", type);\n            //}\n            return CPTFindElement(ipdata, NETMASK_32, tree);\n        case IPV6_TREE:\n            //if (msr && msr->txcfg->debuglog_level >= 9) {\n                //msr_log(msr, 9, \"CPTIpMatch: Searching ip type 0x%x\", type);\n            //}\n            return CPTFindElement(ipdata, NETMASK_128, tree);\n        default:\n            //if (msr && msr->txcfg->debuglog_level >= 9) {\n                //msr_log(msr, 9, \"CPTIpMatch: Unknown ip type 0x%x\", type);\n            //}\n            return NULL;\n    }\n}\n\nTreeNode *TreeAddIP(const char *buffer, CPTTree *tree, int type) {\n    unsigned long ip;\n    int ret;\n    unsigned char netmask_v4 = NETMASK_32, netmask_v6 = NETMASK_128;\n    char ip_strv4[NETMASK_32], ip_strv6[NETMASK_128];\n    struct in_addr addr4;\n    struct in6_addr addr6;\n    int pos = 0;\n    char *ptr = NULL;\n\n    if(tree == NULL)\n        return NULL;\n\n    pos = strchr(buffer, '/') - buffer;\n\n    switch(type)    {\n\n        case IPV4_TREE:\n            memset(&(addr4.s_addr), 0, sizeof(addr4.s_addr));\n            memset(ip_strv4, 0x0, NETMASK_32);\n\n            strncpy(ip_strv4, buffer, sizeof(ip_strv4));\n            *(ip_strv4 + (sizeof(ip_strv4) - 1)) = '\\0';\n\n            ptr = strdup(ip_strv4);\n            netmask_v4 = is_netmask_v4(ptr);\n\n            if (netmask_v4 > NETMASK_32) {\n                free(ptr);\n                ptr = NULL;\n                return NULL;\n            }\n            if (ptr != NULL) {\n                free(ptr);\n                ptr = NULL;\n            }\n            if (netmask_v4 == 0) {\n                return NULL;\n            }\n            else if (pos < strlen(ip_strv4)) {\n                ip_strv4[pos] = '\\0';\n            }\n\n            ret = inet_pton(AF_INET, ip_strv4, &(addr4.s_addr));\n\n            if (ret <= 0) {\n                return NULL;\n            }\n\n            tree->count++;\n            return CPTAddElement((unsigned char *)&(addr4.s_addr), NETMASK_32, tree, netmask_v4);\n\n        case IPV6_TREE:\n            memset(&(addr6.s6_addr), 0, sizeof(addr6.s6_addr));\n            memset(ip_strv6, 0x0, NETMASK_128);\n\n            strncpy(ip_strv6, buffer, sizeof(ip_strv6));\n            *(ip_strv6 + sizeof(ip_strv6) - 1) = '\\0';\n\n            ptr = strdup(ip_strv6);\n            netmask_v6 = is_netmask_v6(ptr);\n\n            if (netmask_v6 > NETMASK_128) {\n                free(ptr);\n                ptr = NULL;\n                return NULL;\n            }\n\n            if(ptr != NULL) {\n                free(ptr);\n                ptr = NULL;\n            }\n\n            if(netmask_v6 == 0) {\n                return NULL;\n            }\n            else if (netmask_v6 != NETMASK_128 && pos < strlen(ip_strv6)) {\n                ip_strv6[pos] = '\\0';\n            }\n\n            ret = inet_pton(AF_INET6, ip_strv6, &(addr6.s6_addr));\n\n            if (ret <= 0)\n            {\n                return NULL;\n            }\n\n            tree->count++;\n\n            return CPTAddElement((unsigned char *)&(addr6.s6_addr), NETMASK_128, tree, netmask_v6);\n        default:\n            return NULL;\n    }\n\n    return NULL;\n}\n\n\n\n\n\n\n\n\n\n\nint tree_contains_ip(TreeRoot *rtree,\n    const char *value, char **error_msg)\n{\n    struct in_addr in;\n    struct in6_addr in6;\n\n    if (rtree == NULL)\n    {\n        return 0;\n    }\n\n    if (strchr(value, ':') == NULL) {\n        if (inet_pton(AF_INET, value, &(in.s_addr)) <= 0) {\n            //*error_msg = apr_psprintf(mp, \"IPmatch: bad IPv4 \" \\\n            //    \"specification \\\"%s\\\".\", value);\n            return -1;\n        }\n\n        if (CPTIpMatch((unsigned char *)&(in.s_addr), rtree->ipv4_tree,\n            IPV4_TREE) != NULL) {\n            return 1;\n        }\n    }\n    else {\n        if (inet_pton(AF_INET6, value, &(in6.s6_addr)) <= 0) {\n            //*error_msg = apr_psprintf(mp, \"IPmatch: bad IPv6 \" \\\n             //   \"specification \\\"%s\\\".\", value);\n            return -1;\n        }\n\n        if (CPTIpMatch((unsigned char *)&(in6.s6_addr), rtree->ipv6_tree,\n            IPV6_TREE) != NULL) {\n            return 1;\n        }\n    }\n\n\n    return 0;\n}\n\n\n\nint add_ip_from_param(\n    const char *param, TreeRoot **rtree, char **error_msg)\n{\n    char *param_copy = strdup(param);\n    char *saved = NULL;\n    char *str;\n    TreeNode *tnode = NULL;\n\n    str = strtok_r(param_copy, \",\", &saved);\n    while (str != NULL)\n    {\n        if (strchr(str, ':') == NULL)\n        {\n            tnode = TreeAddIP(str, (*rtree)->ipv4_tree, IPV4_TREE);\n        }\n        else\n        {\n            tnode = TreeAddIP(str, (*rtree)->ipv6_tree, IPV6_TREE);\n        }\n\n        if (tnode == NULL)\n        {\n            //*error_msg = apr_psprintf(\"Could not add entry \" \\\n            //    \"\\\"%s\\\" from: %s.\", str, param);\n            free(param_copy);\n            return -1;\n        }\n\n        str = strtok_r(NULL, \",\", &saved);\n    }\n    free(param_copy);\n\n    return 0;\n}\n\n\nint ip_tree_from_param(\n    const char *param, TreeRoot **rtree, char **error_msg)\n{\n    char *param_copy = strdup(param);\n    char *saved = NULL;\n    char *str = NULL;\n    TreeNode *tnode = NULL;\n\n    if (create_radix_tree(rtree, error_msg))\n    {\n        free(param_copy);\n        return -1;\n    }\n\n    str = strtok_r(param_copy, \",\", &saved);\n    while (str != NULL)\n    {\n        if (strchr(str, ':') == NULL)\n        {\n            tnode = TreeAddIP(str, (*rtree)->ipv4_tree, IPV4_TREE);\n        }\n        else\n        {\n            tnode = TreeAddIP(str, (*rtree)->ipv6_tree, IPV6_TREE);\n        }\n\n        if (tnode == NULL)\n        {\n            //*error_msg = apr_psprintf(\"Could not add entry \" \\\n            //    \"\\\"%s\\\" from: %s.\", str, param);\n            free(param_copy);\n            return -1;\n        }\n\n        str = strtok_r(NULL, \",\", &saved);\n    }\n    free(param_copy);\n\n    return 0;\n}\n\n\n/** \\brief Validate IPv4 Netmask\n *\n * \\param ip_strv6 Pointer to ipv6 address\n *\n * \\retval netmask_v4 On Success\n */\nunsigned char is_netmask_v4(char *ip_strv4) {\n    unsigned char netmask_v4 = 32;\n    char *mask_str = NULL;\n\n    if(ip_strv4 == NULL)\n        return netmask_v4;\n\n    if ((mask_str = strchr(ip_strv4, '/'))) {\n        int cidr;\n        *(mask_str++) = '\\0';\n\n        if (strchr(mask_str, '.') != NULL) {\n            return 0;\n        }\n\n        cidr = atoi(mask_str);\n        if (cidr == 32) {\n            return 32;\n        }\n        if ((cidr < 0) || (cidr > 32)) {\n            return 0;\n        }\n\n        netmask_v4 = (unsigned char)cidr;\n    }\n\n    return netmask_v4;\n}\n\n/** \\brief Validate IPv6 Netmask\n *\n * \\param ip_strv6 Pointer to ipv6 address\n *\n * \\retval netmask_v6 On Success\n */\nunsigned char is_netmask_v6(char *ip_strv6) {\n    unsigned char netmask_v6 = 128;\n    char *mask_str = NULL;\n\n    if(ip_strv6 == NULL)\n        return netmask_v6;\n\n    if ((mask_str = strchr(ip_strv6, '/'))) {\n        int cidr;\n        *(mask_str++) = '\\0';\n\n        if (strchr(mask_str, ':') != NULL) {\n            return 0;\n        }\n\n        cidr = atoi(mask_str);\n        if ((cidr < 0) || (cidr > 128)) {\n            return 0;\n        }\n        netmask_v6 = (unsigned char)cidr;\n    }\n\n    return netmask_v6;\n}\n\n\nint create_radix_tree(TreeRoot **rtree, char **error_msg)\n{\n    *rtree = reinterpret_cast<TreeRoot *>(malloc(sizeof(TreeRoot)));\n    if (*rtree == NULL)\n    {\n        //*error_msg = apr_psprintf(mp, \"Failed allocating \" \\\n        //    \"memory to TreeRoot.\");\n        goto root_node_failed;\n    }\n    memset(*rtree, 0, sizeof(TreeRoot));\n\n    (*rtree)->ipv4_tree = CPTCreateRadixTree();\n    if ((*rtree)->ipv4_tree == NULL)\n    {\n        //*error_msg = apr_psprintf(mp, \"IPmatch: Tree initialization \" \\\n        //    \"failed.\");\n        goto ipv4_tree_failed;\n    }\n\n    (*rtree)->ipv6_tree = CPTCreateRadixTree();\n    if ((*rtree)->ipv6_tree == NULL)\n    {\n        //*error_msg = apr_psprintf(mp, \"IPmatch: Tree initialization \" \\\n        //    \"failed.\");\n        goto ipv6_tree_failed;\n    }\n\n    return 0;\n\nipv6_tree_failed:\nipv4_tree_failed:\nroot_node_failed:\n    return -1;\n}\n\n}\n"
  },
  {
    "path": "src/utils/msc_tree.h",
    "content": "/*\n* ModSecurity for Apache 2.x, http://www.modsecurity.org/\n* Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n*\n* You may not use this file except in compliance with\n* the License.  You may obtain a copy of the License at\n*\n*     http://www.apache.org/licenses/LICENSE-2.0\n*\n* If any of the files related to licensing are missing or if you have any\n* other questions related to licensing please contact Trustwave Holdings, Inc.\n* directly using the email address security@modsecurity.org.\n*/\n\n\n/*\n *\n * TODO: This is an improved copy of the ModSecurity 2.9 file, this may need\n * some other enhancements and/or fixes.\n *\n */\n\n#ifndef SRC_UTILS_MSC_TREE_H_\n#define SRC_UTILS_MSC_TREE_H_\n\n\ntypedef struct CPTData CPTData;\ntypedef struct TreePrefix TreePrefix;\ntypedef struct TreeNode TreeNode;\ntypedef struct CPTTree CPTTree;\ntypedef struct TreeRoot TreeRoot;\n\n#define IPV4_TREE 0x1\n#define IPV6_TREE 0x2\n\n#define IPV4_LEN 0x20\n#define IPV6_LEN 0x80\n\n#define TREE_CHECK(x, y) ((x) & (y))\n#define MASK_BITS(x) ((x + 1) * 8)\n#define SHIFT_LEFT_MASK(x) ((-1) << (x))\n#define SHIFT_RIGHT_MASK(x,y) ((x) >> (y))\n\n#define NETMASK_256 0x100\n#define NETMASK_128 0x80\n#define NETMASK_64  0x40\n#define NETMASK_32 0x20\n#define NETMASK_16 0x10\n#define NETMASK_8  0x8\n#define NETMASK_4  0x4\n#define NETMASK_2  0x2\n\n#define FALSE 0\n#define TRUE 1\n\nextern \"C\" {\n\nstruct CPTData {\n    unsigned char netmask;\n    struct CPTData *next;\n};\n\nstruct TreePrefix {\n    unsigned char *buffer;\n    unsigned int bitlen;\n    CPTData *prefix_data;\n};\n\nstruct TreeNode {\n    unsigned int bit;\n    int count;\n    unsigned char *netmasks;\n    TreePrefix *prefix;\n    struct TreeNode *left, *right;\n    struct TreeNode *parent;\n};\n\nstruct CPTTree {\n    int count;\n    TreeNode *head;\n};\n\nstruct TreeRoot {\n    CPTTree *ipv4_tree;\n    CPTTree *ipv6_tree;\n};\n\nCPTTree *CPTCreateRadixTree();\nTreeNode *CPTIpMatch(unsigned char *ipdata, CPTTree *tree, int type);\nTreeNode *TreeAddIP(const char *buffer, CPTTree *tree, int type);\n\nunsigned char is_netmask_v4(char *ip_strv4);\n\nunsigned char is_netmask_v6(char *ip_strv6);\n\n/** @ingroup ModSecurity_Legacy */\nint tree_contains_ip(TreeRoot *rtree,\n    const char *value, char **error_msg);\n\nint add_ip_from_param(const char *param, TreeRoot **rtree, char **error_msg);\nint ip_tree_from_param(const char *param, TreeRoot **rtree, char **error_msg);\nint create_radix_tree(TreeRoot **rtree, char **error_msg);\n}\n\n#endif  // SRC_UTILS_MSC_TREE_H_\n"
  },
  {
    "path": "src/utils/phase.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <ctime>\n#include <iostream>\n#include <string>\n#include <vector>\n\n#ifndef SRC_UTILS_PHASE_H_\n#define SRC_UTILS_PHASE_H_\n\n#include \"modsecurity/modsecurity.h\"\n\nnamespace modsecurity {\nnamespace utils {\n\nstd::string phase_name(int x) {\n    switch (x) {\n        case modsecurity::Phases::ConnectionPhase:\n            return \"Connection Phase\";\n            break;\n        case modsecurity::Phases::UriPhase:\n            return \"URI Phase\";\n            break;\n        case modsecurity::Phases::RequestHeadersPhase:\n            return \"Request Headers\";\n            break;\n        case modsecurity::Phases::RequestBodyPhase:\n            return \"Request Body\";\n            break;\n        case modsecurity::Phases::ResponseHeadersPhase:\n            return \"Response Headers\";\n            break;\n        case modsecurity::Phases::ResponseBodyPhase:\n            return \"Reponse Body\";\n            break;\n        case modsecurity::Phases::LoggingPhase:\n            return \"Logging\";\n            break;\n    }\n    return \"Phase '\" + std::to_string(x) + \"' is not known.\";\n}\n\n}  // namespace utils\n}  // namespace modsecurity\n\n#endif  // SRC_UTILS_PHASE_H_\n"
  },
  {
    "path": "src/utils/random.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n\n#include <algorithm>\n#include <random>\n#include <memory>\n#include <functional>\n#include <string>\n\n#include \"modsecurity/modsecurity.h\"\n\nnamespace modsecurity {\nnamespace utils {\n\n\ndouble random_number(const double from, const double to) {\n    std::random_device rd;\n    std::mt19937 mt(rd());\n    return std::bind(\n        std::uniform_real_distribution<>{from, to},\n        std::default_random_engine{ mt() })();\n}\n\n\ndouble generate_transaction_unique_id() {\n    return random_number(0, 100);\n}\n\n\n}  // namespace utils\n}  // namespace modsecurity\n\n"
  },
  {
    "path": "src/utils/random.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <ctime>\n#include <iostream>\n#include <string>\n#include <vector>\n\n#include \"modsecurity/modsecurity.h\"\n\n#ifndef SRC_UTILS_RANDOM_H_\n#define SRC_UTILS_RANDOM_H_\n\n\nnamespace modsecurity {\nnamespace utils {\n\n\n    double random_number(const double from, const double to);\n    double generate_transaction_unique_id();\n\n\n}  // namespace utils\n}  // namespace modsecurity\n\n\n#endif  // SRC_UTILS_RANDOM_H_\n"
  },
  {
    "path": "src/utils/regex.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"src/utils/regex.h\"\n\n#include <string>\n#include <list>\n\n#include <fstream>\n#include <iostream>\n\n#include \"src/utils/geo_lookup.h\"\n\n#ifdef WITH_PCRE\n#if PCRE_HAVE_JIT\n// NOTE: Add PCRE_STUDY_EXTRA_NEEDED so studying always yields a pcre_extra strucure\n// and we can selectively override match limits using a copy of that structure at runtime.\n#define pcre_study_opt PCRE_STUDY_JIT_COMPILE | PCRE_STUDY_EXTRA_NEEDED\n#else\n// NOTE: Add PCRE_STUDY_EXTRA_NEEDED so studying always yields a pcre_extra strucure\n// and we can selectively override match limits using a copy of that structure at runtime.\n#define pcre_study_opt PCRE_STUDY_EXTRA_NEEDED\n#endif\n#endif\n\n#ifndef WITH_PCRE\nclass Pcre2MatchContextPtr {\n public:\n    Pcre2MatchContextPtr()\n        : m_match_context(pcre2_match_context_create(nullptr)) {}\n\n\t\tPcre2MatchContextPtr(const Pcre2MatchContextPtr&) = delete;\n\t\tPcre2MatchContextPtr& operator=(const Pcre2MatchContextPtr&) = delete;\n\n    ~Pcre2MatchContextPtr() {\n        pcre2_match_context_free(m_match_context);\n    }\n\n    explicit operator pcre2_match_context*() const {\n        return m_match_context;\n    }\n\n private:\n    pcre2_match_context *m_match_context;\n};\n#endif\n\nnamespace modsecurity {\nnamespace Utils {\n\n// Helper function to tell us if the current config indicates CRLF is a valid newline sequence\nbool crlfIsNewline() {\n#ifndef WITH_PCRE\n    uint32_t newline = 0;\n    pcre2_config(PCRE2_CONFIG_NEWLINE, &newline);\n    bool crlf_is_newline =\n        newline == PCRE2_NEWLINE_ANY ||\n        newline == PCRE2_NEWLINE_CRLF ||\n        newline == PCRE2_NEWLINE_ANYCRLF;\n#else\n    int d = 0;\n    pcre_config(PCRE_CONFIG_NEWLINE, &d);\n\n    unsigned int option_bits = (d == 13)? PCRE_NEWLINE_CR :\n        (d == 10)? PCRE_NEWLINE_LF :\n        (d == (13<<8 | 10))? PCRE_NEWLINE_CRLF :\n        (d == -2)? PCRE_NEWLINE_ANYCRLF :\n        (d == -1)? PCRE_NEWLINE_ANY : 0;\n\n    bool crlf_is_newline =\n        option_bits == PCRE_NEWLINE_ANY ||\n        option_bits == PCRE_NEWLINE_CRLF ||\n        option_bits == PCRE_NEWLINE_ANYCRLF;\n#endif\n    return crlf_is_newline;\n}\n\nRegex::Regex(const std::string& pattern_, bool ignoreCase)\n    : pattern(pattern_.empty() ? \".*\" : pattern_) {\n#ifndef WITH_PCRE\n    PCRE2_SPTR pcre2_pattern = reinterpret_cast<PCRE2_SPTR>(pattern.c_str());\n    uint32_t pcre2_options = (PCRE2_DOTALL|PCRE2_MULTILINE);\n    if (ignoreCase) {\n        pcre2_options |= PCRE2_CASELESS;\n    }\n    int errornumber = 0;\n    PCRE2_SIZE erroroffset = 0;\n    m_pc = pcre2_compile(pcre2_pattern, PCRE2_ZERO_TERMINATED,\n        pcre2_options, &errornumber, &erroroffset, nullptr);\n    m_pcje = pcre2_jit_compile(m_pc, PCRE2_JIT_COMPLETE);\n#else\n    const char *errptr = nullptr;\n    int erroffset;\n    int flags = (PCRE_DOTALL|PCRE_MULTILINE);\n\n    if (ignoreCase == true) {\n        flags |= PCRE_CASELESS;\n    }\n    m_pc = pcre_compile(pattern.c_str(), flags,\n        &errptr, &erroffset, nullptr);\n\n    m_pce = pcre_study(m_pc, pcre_study_opt, &errptr);\n#endif\n}\n\n\nRegex::~Regex() {\n#ifndef WITH_PCRE\n    pcre2_code_free(m_pc);\n#else\n    if (m_pc != nullptr) {\n        pcre_free(m_pc);\n        m_pc = nullptr;\n    }\n    if (m_pce != nullptr) {\n#if PCRE_HAVE_JIT\n        pcre_free_study(m_pce);\n#else\n        pcre_free(m_pce);\n#endif\n        m_pce = nullptr;\n    }\n#endif\n}\n\n\nstd::list<SMatch> Regex::searchAll(const std::string& s) const {\n    std::list<SMatch> retList;\n    int rc = 0;\n#ifndef WITH_PCRE\n    PCRE2_SPTR pcre2_s = reinterpret_cast<PCRE2_SPTR>(s.c_str());\n    PCRE2_SIZE offset = 0;\n\n    pcre2_match_data *match_data = pcre2_match_data_create_from_pattern(m_pc, nullptr);\n    do {\n        if (m_pcje == 0) {\n            rc = pcre2_jit_match(m_pc, pcre2_s, s.length(),\n                            offset, 0, match_data, nullptr);\n        } \n        \n        if (m_pcje != 0 || rc == PCRE2_ERROR_JIT_STACKLIMIT) {\n            rc = pcre2_match(m_pc, pcre2_s, s.length(),\n                            offset, PCRE2_NO_JIT, match_data, nullptr);\n        }\n        const PCRE2_SIZE *ovector = pcre2_get_ovector_pointer(match_data);\n#else\n    const char *subject = s.c_str();\n    int ovector[OVECCOUNT];\n    int offset = 0;\n\n    do {\n        rc = pcre_exec(m_pc, m_pce, subject,\n            s.size(), offset, 0, ovector, OVECCOUNT);\n#endif\n        for (int i = 0; i < rc; i++) {\n            size_t start = ovector[2*i];\n            size_t end = ovector[2*i+1];\n            size_t len = end - start;\n            if (end > s.size()) {\n                rc = -1;\n                break;\n            }\n            std::string match = std::string(s, start, len);\n            offset = start + len;\n            retList.push_front(SMatch(match, start));\n\n            if (len == 0) {\n                rc = 0;\n                break;\n            }\n        }\n    } while (rc > 0);\n\n#ifndef WITH_PCRE\n    pcre2_match_data_free(match_data);\n#endif\n    return retList;\n}\n\nRegexResult Regex::searchOneMatch(const std::string& s, std::vector<SMatchCapture>& captures, unsigned long match_limit) const {\n#ifndef WITH_PCRE\n    Pcre2MatchContextPtr match_context;\n    if (match_limit > 0) {\n        // TODO: What if setting the match limit fails?\n        pcre2_set_match_limit(static_cast<pcre2_match_context*>(match_context), match_limit);\n    }\n\n    PCRE2_SPTR pcre2_s = reinterpret_cast<PCRE2_SPTR>(s.c_str());\n    pcre2_match_data *match_data = pcre2_match_data_create_from_pattern(m_pc, nullptr);\n    int rc = 0;\n    if (m_pcje == 0) {\n        rc = pcre2_jit_match(m_pc, pcre2_s, s.length(), 0, 0, match_data, static_cast<pcre2_match_context*>(match_context));\n    } \n    \n    if (m_pcje != 0 || rc == PCRE2_ERROR_JIT_STACKLIMIT) {\n        rc = pcre2_match(m_pc, pcre2_s, s.length(), 0, PCRE2_NO_JIT, match_data, static_cast<pcre2_match_context*>(match_context));\n    }\n    const PCRE2_SIZE *ovector = pcre2_get_ovector_pointer(match_data);\n#else\n    const char *subject = s.c_str();\n    int ovector[OVECCOUNT];\n    pcre_extra local_pce;\n    pcre_extra *pce = m_pce;\n\n    if (m_pce != nullptr && match_limit > 0) {\n        local_pce = *m_pce;\n        local_pce.match_limit = match_limit;\n        local_pce.flags |= PCRE_EXTRA_MATCH_LIMIT;\n        pce = &local_pce;\n    }\n\n    int rc = pcre_exec(m_pc, pce, subject, s.size(), 0, 0, ovector, OVECCOUNT);\n#endif\n\n    for (int i = 0; i < rc; i++) {\n        size_t start = ovector[2*i];\n        size_t end = ovector[2*i+1];\n        size_t len = end - start;\n        if (end > s.size()) {\n            continue;\n        }\n        SMatchCapture capture(i, start, len);\n        captures.push_back(capture);\n    }\n\n#ifndef WITH_PCRE\n    pcre2_match_data_free(match_data);\n#endif\n    return to_regex_result(rc);\n}\n\nRegexResult Regex::searchGlobal(const std::string& s, std::vector<SMatchCapture>& captures, unsigned long match_limit) const {\n    bool prev_match_zero_length = false;\n#ifndef WITH_PCRE\n    Pcre2MatchContextPtr match_context;\n    if (match_limit > 0) {\n        // TODO: What if setting the match limit fails?\n        pcre2_set_match_limit(static_cast<pcre2_match_context*>(match_context), match_limit);\n    }\n\n    PCRE2_SPTR pcre2_s = reinterpret_cast<PCRE2_SPTR>(s.c_str());\n    PCRE2_SIZE startOffset = 0;\n\n    pcre2_match_data *match_data = pcre2_match_data_create_from_pattern(m_pc, nullptr);\n    while (startOffset <= s.length()) {\n        uint32_t pcre2_options = 0;\n        if (prev_match_zero_length) {\n            pcre2_options = PCRE2_NOTEMPTY_ATSTART | PCRE2_ANCHORED;\n        }\n        int rc = pcre2_match(m_pc, pcre2_s, s.length(),\n                            startOffset, pcre2_options, match_data, static_cast<pcre2_match_context*>(match_context));\n        const PCRE2_SIZE *ovector = pcre2_get_ovector_pointer(match_data);\n\n#else\n    const char *subject = s.c_str();\n    pcre_extra local_pce;\n    pcre_extra *pce = m_pce;\n\n    if (m_pce != nullptr && match_limit > 0) {\n        local_pce = *m_pce;\n        local_pce.match_limit = match_limit;\n        local_pce.flags |= PCRE_EXTRA_MATCH_LIMIT;\n        pce = &local_pce;\n    }\n\n    int startOffset = 0;\n\n    while (startOffset <= s.length()) {\n        int ovector[OVECCOUNT];\n        int pcre_options = 0;\n        if (prev_match_zero_length) {\n            pcre_options = PCRE_NOTEMPTY_ATSTART | PCRE_ANCHORED;\n        }\n        int rc = pcre_exec(m_pc, pce, subject, s.length(), startOffset, pcre_options, ovector, OVECCOUNT);\n\n        RegexResult regex_result = to_regex_result(rc);\n        if (regex_result != RegexResult::Ok) {\n            return regex_result;\n        }\n\n#endif\n        if (rc > 0) {\n            size_t firstGroupForThisFullMatch = captures.size();\n            for (int i = 0; i < rc; i++) {\n                size_t start = ovector[2*i];\n                size_t end = ovector[2*i+1];\n                size_t len = end - start;\n                if (end > s.length()) {\n                    continue;\n                }\n                SMatchCapture capture(firstGroupForThisFullMatch + i, start, len);\n                captures.push_back(capture);\n\n                if (i == 0) {\n                    if (len > 0) {\n                        // normal case; next call to pcre_exec should start after the end of the last full match string\n                        startOffset = end;\n                        prev_match_zero_length = false;\n                    } else {\n                        if ( startOffset == s.length()) {\n                            // zero-length match at end of string; force end of while-loop\n                            startOffset++;\n                        } else {\n                            // zero-length match mid-string; adjust next match attempt\n                            prev_match_zero_length = true;\n                        }\n                    }\n                }\n            }\n        } else {\n            if (prev_match_zero_length) {\n                // The n-1 search found a zero-length match, so we did a subsequent search\n                // with the special flags. That subsequent exec did not find a match, so now advance\n                // by one character (unless CRLF, then advance by two)\n                startOffset++;\n                if (crlfIsNewline() && (startOffset < s.length()) && (s[startOffset-1] == '\\r')\n                    && (s[startOffset] == '\\n')) {\n                    startOffset++;\n                }\n                prev_match_zero_length = false;\n            } else {\n                // normal case; no match on most recent scan (with options=0).  We are done.\n                break;\n            }\n        }\n    }\n\n#ifndef WITH_PCRE\n    pcre2_match_data_free(match_data);\n#endif\n    return RegexResult::Ok;\n}\n\nint Regex::search(const std::string& s, SMatch *match) const {\n#ifndef WITH_PCRE\n    PCRE2_SPTR pcre2_s = reinterpret_cast<PCRE2_SPTR>(s.c_str());\n    pcre2_match_data *match_data = pcre2_match_data_create_from_pattern(m_pc, nullptr);\n    int ret = 0;\n    if (m_pcje == 0) {\n        ret = pcre2_match(m_pc, pcre2_s, s.length(),\n            0, 0, match_data, nullptr) > 0;\n    } \n    \n    if (m_pcje != 0 || ret == PCRE2_ERROR_JIT_STACKLIMIT) {\n        ret = pcre2_match(m_pc, pcre2_s, s.length(),\n            0, PCRE2_NO_JIT, match_data, nullptr) > 0;\n    }\n    if (ret > 0) { // match\n        PCRE2_SIZE *ovector = pcre2_get_ovector_pointer(match_data);\n#else\n    int ovector[OVECCOUNT];\n    int ret = pcre_exec(m_pc, m_pce, s.c_str(),\n        s.size(), 0, 0, ovector, OVECCOUNT) > 0;\n\n    if (ret > 0) {\n#endif\n        *match = SMatch(\n            std::string(s, ovector[ret-1], ovector[ret] - ovector[ret-1]),\n            0);\n    }\n\n#ifndef WITH_PCRE\n    pcre2_match_data_free(match_data);\n#endif\n    return ret;\n}\n\nint Regex::search(const std::string& s) const {\n#ifndef WITH_PCRE\n    PCRE2_SPTR pcre2_s = reinterpret_cast<PCRE2_SPTR>(s.c_str());\n    pcre2_match_data *match_data = pcre2_match_data_create_from_pattern(m_pc, nullptr);\n    int rc = 0;\n    if (m_pcje == 0) {\n        rc = pcre2_jit_match(m_pc, pcre2_s, s.length(), 0, 0, match_data, nullptr);\n    }\n\n    if (m_pcje != 0 || rc == PCRE2_ERROR_JIT_STACKLIMIT) {\n        rc = pcre2_match(m_pc, pcre2_s, s.length(), 0, PCRE2_NO_JIT, match_data, nullptr);\n    }\n    pcre2_match_data_free(match_data);\n    if (rc > 0) {\n        return 1; // match\n    } else {\n        return 0; // no match\n    }\n#else\n    int ovector[OVECCOUNT];\n    return pcre_exec(m_pc, m_pce, s.c_str(),\n        s.size(), 0, 0, ovector, OVECCOUNT) > 0;\n#endif\n}\n\nRegexResult Regex::to_regex_result(int pcre_exec_result) const {\n    if (\n        pcre_exec_result > 0 ||\n#ifndef WITH_PCRE\n        pcre_exec_result == PCRE2_ERROR_NOMATCH\n#else\n        pcre_exec_result == PCRE_ERROR_NOMATCH\n#endif\n    ) {\n        return RegexResult::Ok;\n    } else if(\n#ifndef WITH_PCRE\n        pcre_exec_result == PCRE2_ERROR_MATCHLIMIT\n#else\n        pcre_exec_result == PCRE_ERROR_MATCHLIMIT\n#endif\n    ) {\n        return RegexResult::ErrorMatchLimit;\n    } else {\n        // Note that this can include the case where the PCRE result was zero.\n        // Zero is returned if the offset vector is not large enough and can be considered an error.\n        return RegexResult::ErrorOther;\n    }\n}\n\n}  // namespace Utils\n}  // namespace modsecurity\n"
  },
  {
    "path": "src/utils/regex.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n#ifndef WITH_PCRE\n#define PCRE2_CODE_UNIT_WIDTH 8\n#include <pcre2.h>\n#else\n#include <pcre.h>\n#endif\n\n#include <iostream>\n#include <fstream>\n#include <string>\n#include <list>\n#include <vector>\n\n#ifndef SRC_UTILS_REGEX_H_\n#define SRC_UTILS_REGEX_H_\n\n\nnamespace modsecurity {\nnamespace Utils {\n\n#define OVECCOUNT 900\n\nenum class RegexResult {\n    Ok,\n    ErrorMatchLimit,\n    ErrorOther,\n};\n\nclass SMatch {\n public:\n    SMatch() :\n\tm_match(),\n\tm_offset(0) { }\n\n    SMatch(const std::string &match, size_t offset) :\n\tm_match(match),\n\tm_offset(offset) { }\n\n    const std::string& str() const { return m_match; }\n    size_t offset() const { return m_offset; }\n\n private:\n    std::string m_match;\n    size_t m_offset;\n};\n\nstruct SMatchCapture {\n    SMatchCapture(size_t group, size_t offset, size_t length) :\n\tm_group(group),\n\tm_offset(offset),\n\tm_length(length) { }\n\n    size_t m_group; // E.g. 0 = full match; 6 = capture group 6\n    size_t m_offset; // offset of match within the analyzed string\n    size_t m_length;\n};\n\nclass Regex {\n public:\n    explicit Regex(const std::string& pattern_, bool ignoreCase = false);\n    ~Regex();\n\n    // m_pc and m_pce can't be easily copied\n    Regex(const Regex&) = delete;\n    Regex& operator=(const Regex&) = delete;\n\n    bool hasError() const {\n        return (m_pc == nullptr);\n    }\n    std::list<SMatch> searchAll(const std::string& s) const;\n    RegexResult searchOneMatch(const std::string& s, std::vector<SMatchCapture>& captures, unsigned long match_limit = 0) const;\n    RegexResult searchGlobal(const std::string& s, std::vector<SMatchCapture>& captures, unsigned long match_limit = 0) const;\n    int search(const std::string &s, SMatch *match) const;\n    int search(const std::string &s) const;\n\n    const std::string pattern;\n private:\n    RegexResult to_regex_result(int pcre_exec_result) const;\n\n#ifndef WITH_PCRE\n    pcre2_code *m_pc;\n    int m_pcje;\n#else\n    pcre *m_pc = nullptr;\n    pcre_extra *m_pce = nullptr;\n#endif\n};\n\n\nstatic inline int regex_search(const std::string& s, SMatch *match, const Regex& regex) {\n    return regex.search(s, match);\n}\n\n\nstatic inline int regex_search(const std::string& s, const Regex& regex) {\n    return regex.search(s);\n}\n\n\n}  // namespace Utils\n}  // namespace modsecurity\n\n#endif  // SRC_UTILS_REGEX_H_\n"
  },
  {
    "path": "src/utils/sha1.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#ifndef SRC_UTILS_SHA1_H_\n#define SRC_UTILS_SHA1_H_\n\n#include <string>\n#include <cassert>\n\n#include \"src/utils/string.h\"\n#include \"mbedtls/sha1.h\"\n\nnamespace modsecurity::Utils {\n\n\nusing DigestOp = int (*)(const unsigned char *, size_t, unsigned char []);\n\n\ntemplate<DigestOp digestOp, int DigestSize>\nclass DigestImpl {\n public:\n\n    static std::string digest(const std::string& input) {\n        return digestHelper(input, [](const auto digest) { \n            return std::string(digest);\n        });\n    }\n\n    static void digestReplace(std::string& value) {\n        digestHelper(value, [&value](const auto digest) mutable { \n            value = digest;\n        });\n    }\n\n    static std::string hexdigest(const std::string &input) {\n        return digestHelper(input, [](const auto digest) { \n            return utils::string::string_to_hex(digest);\n        });\n    }\n\nprivate:\n\n    template<typename ConvertOp>\n    static auto digestHelper(const std::string &input,\n        ConvertOp convertOp) -> auto {\n        char digest[DigestSize];\n\n        const auto ret = (*digestOp)(reinterpret_cast<const unsigned char *>(input.c_str()),\n                 input.size(), reinterpret_cast<unsigned char *>(digest));\n        assert(ret == 0);\n\n        return convertOp(std::string_view(digest, DigestSize));\n    }\n};\n\n\nclass Sha1 : public DigestImpl<&mbedtls_sha1, 20> {\n};\n\n\n}  // namespace modsecurity::Utils\n\n#endif  // SRC_UTILS_SHA1_H_\n"
  },
  {
    "path": "src/utils/shared_files.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"src/utils/shared_files.h\"\n\n#include <fcntl.h>\n#ifdef WIN32\n#include <algorithm>\n#endif\n\n\nnamespace modsecurity {\nnamespace utils {\n\n\nSharedFiles::handlers_map::iterator SharedFiles::add_new_handler(\n    const std::string &fileName, std::string *error) {\n    FILE *fp = fopen(fileName.c_str(), \"a\");\n    if (fp == 0) {\n        error->assign(\"Failed to open file: \" + fileName);\n        return m_handlers.end();\n    }\n\n#ifdef WIN32\n    // replace invalid characters for a Win32 named object\n    auto tmp = fileName;\n    std::replace(tmp.begin(), tmp.end(), '\\\\', '_');\n    std::replace(tmp.begin(), tmp.end(), '/', '_');\n\n    // use named mutex for multi-process locking support\n    const auto mutexName = \"Global\\\\ModSecurity_\" + tmp;\n\n    HANDLE hMutex = CreateMutex(NULL, FALSE, mutexName.c_str());\n    if (hMutex == NULL) {\n        error->assign(\"Failed to create mutex for shared file: \" + fileName);\n        fclose(fp);\n        return m_handlers.end();\n    }\n#endif\n\n    auto handler = handler_info {\n        fp,\n#ifdef WIN32\n        hMutex,\n#endif\n        0\n    };\n    // cppcheck-suppress resourceLeak ; false positive, fp is closed in SharedFiles::close\n    return m_handlers.insert({ fileName, handler }).first;\n}\n\n\nbool SharedFiles::open(const std::string& fileName, std::string *error) {\n    auto it = m_handlers.find(fileName);\n    if (it == m_handlers.end()) {\n        it = add_new_handler(fileName, error);\n        if (error->size() > 0)\n            return false;\n    }\n\n    if (it == m_handlers.end()) {\n        error->assign(\"Not able to open: \" + fileName);\n        return false;\n    }\n\n    it->second.cnt++;\n\n    return true;\n}\n\n\nvoid SharedFiles::close(const std::string& fileName) {\n    if (fileName.empty())\n        return;\n\n    auto it = m_handlers.find(fileName);\n    if (it == m_handlers.end())\n        return;\n\n    it->second.cnt--;\n    if (it->second.cnt == 0)\n    {\n        fclose(it->second.fp);\n#ifdef WIN32\n        CloseHandle(it->second.hMutex);\n#endif\n\n        m_handlers.erase(it);\n    }\n}\n\n\nbool SharedFiles::write(const std::string& fileName,\n    const std::string &msg, std::string *error) {\n    bool ret = true;\n\n    auto it = m_handlers.find(fileName);\n    if (it == m_handlers.end()) {\n        error->assign(\"file is not open: \" + fileName);\n        return false;\n    }\n\n    //Exclusively lock whole file\n#ifndef WIN32\n    struct flock lock {};\n    lock.l_start = lock.l_len = lock.l_whence = 0;\n    lock.l_type = F_WRLCK;\n    fcntl(fileno(it->second.fp), F_SETLKW, &lock);\n#else\n    DWORD dwWaitResult = WaitForSingleObject(it->second.hMutex, INFINITE);\n    if (dwWaitResult != WAIT_OBJECT_0) {\n        error->assign(\"couldn't lock shared file: \" + fileName);\n        return false;\n    }\n#endif\n\n    auto wrote = fwrite(msg.c_str(), 1, msg.size(), it->second.fp);\n    if (wrote < msg.size()) {\n        error->assign(\"failed to write: \" + fileName);\n        ret = false;\n    }\n    fflush(it->second.fp);\n\n    //Remove exclusive lock\n#ifndef WIN32\n    lock.l_type = F_UNLCK;\n    fcntl(fileno(it->second.fp), F_SETLKW, &lock);\n#else\n    ::ReleaseMutex(it->second.hMutex);\n#endif\n\n    return ret;\n}\n\n\n}  // namespace utils\n}  // namespace modsecurity\n"
  },
  {
    "path": "src/utils/shared_files.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#ifndef SRC_UTILS_SHARED_FILES_H_\n#define SRC_UTILS_SHARED_FILES_H_\n\n\n#include <stdio.h>\n#ifdef WIN32\n#include <Windows.h>\n#endif\n\n#include <unordered_map>\n#include <string>\n\n\nnamespace modsecurity {\nnamespace utils {\n\n\nclass SharedFiles {\npublic:\n    bool open(const std::string& fileName, std::string *error);\n    void close(const std::string& fileName);\n    bool write(const std::string& fileName, const std::string &msg,\n        std::string *error);\n\n    static SharedFiles& getInstance() {\n        static SharedFiles instance;\n        return instance;\n    }\n\nprivate:\n    SharedFiles() = default;\n    ~SharedFiles() = default;\n\n    // C++ 03\n    // ========\n    // Dont forget to declare these two. You want to make sure they\n    // are unacceptable otherwise you may accidentally get copies of\n    // your singleton appearing.\n    SharedFiles(SharedFiles const&) = delete;\n    void operator=(SharedFiles const&) = delete;\n\n     struct handler_info {\n         FILE* fp;\n#ifdef WIN32\n         HANDLE hMutex;\n#endif\n         unsigned int cnt;\n     };\n\n    using handlers_map = std::unordered_map<std::string, handler_info>;\n    handlers_map m_handlers;\n\n    handlers_map::iterator add_new_handler(\n        const std::string &fileName, std::string *error);\n};\n\n\n}  // namespace utils\n}  // namespace modsecurity\n\n#endif  // SRC_UTILS_SHARED_FILES_H_\n"
  },
  {
    "path": "src/utils/string.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2023 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#ifndef SRC_UTILS_STRING_H_\n#define SRC_UTILS_STRING_H_\n\n#include <ctime>\n#include <string>\n#include <cstring>\n#include <vector>\n#include <algorithm>\n#include <utility>\n#include <sstream>\n#include <iomanip>\n#include <time.h>\n\n#ifdef WIN32\n#include \"src/compat/msvc.h\"\n#endif\n\nnamespace modsecurity::utils::string {\n\ntemplate<typename CharT>\nconstexpr bool VALID_HEX(CharT X) {\n    return ((X >= '0') && (X <= '9')) \n        || ((X >= 'a') && (X <= 'f'))\n        || ((X >= 'A') && (X <= 'F'));\n}\n\ntemplate<typename CharT>\nconstexpr bool ISODIGIT(CharT X) {\n    return (X >= '0') && (X <= '7');\n}\n\nconstexpr unsigned char NBSP = 160;\n\nconst char HEX2DEC[256] = {\n    /*       0  1  2  3   4  5  6  7   8  9  A  B   C  D  E  F */\n    /* 0 */ (char)-1, (char)-1, (char)-1, (char)-1,  (char)-1, (char)-1, (char)-1, (char)-1,  (char)-1, (char)-1, (char)-1, (char)-1,  (char)-1, (char)-1, (char)-1, (char)-1,\n    /* 1 */ (char)-1, (char)-1, (char)-1, (char)-1,  (char)-1, (char)-1, (char)-1, (char)-1,  (char)-1, (char)-1, (char)-1, (char)-1,  (char)-1, (char)-1, (char)-1, (char)-1,\n    /* 2 */ (char)-1, (char)-1, (char)-1, (char)-1,  (char)-1, (char)-1, (char)-1, (char)-1,  (char)-1, (char)-1, (char)-1, (char)-1,  (char)-1, (char)-1, (char)-1, (char)-1,\n    /* 3 */  0,  1,  2,  3,   4,  5,  6,  7,   8,  9, (char)-1, (char)-1,  (char)-1, (char)-1, (char)-1, (char)-1,\n\n    /* 4 */ (char)-1, 10, 11, 12,  13, 14, 15, (char)-1,  (char)-1, (char)-1, (char)-1, (char)-1,  (char)-1, (char)-1, (char)-1, (char)-1,\n    /* 5 */ (char)-1, (char)-1, (char)-1, (char)-1,  (char)-1, (char)-1, (char)-1, (char)-1,  (char)-1, (char)-1, (char)-1, (char)-1,  (char)-1, (char)-1, (char)-1, (char)-1,\n    /* 6 */ (char)-1, 10, 11, 12,  13, 14, 15, (char)-1,  (char)-1, (char)-1, (char)-1, (char)-1,  (char)-1, (char)-1, (char)-1, (char)-1,\n    /* 7 */ (char)-1, (char)-1, (char)-1, (char)-1,  (char)-1, (char)-1, (char)-1, (char)-1,  (char)-1, (char)-1, (char)-1, (char)-1,  (char)-1, (char)-1, (char)-1, (char)-1,\n\n    /* 8 */ (char)-1, (char)-1, (char)-1, (char)-1,  (char)-1, (char)-1, (char)-1, (char)-1,  (char)-1, (char)-1, (char)-1, (char)-1,  (char)-1, (char)-1, (char)-1, (char)-1,\n    /* 9 */ (char)-1, (char)-1, (char)-1, (char)-1,  (char)-1, (char)-1, (char)-1, (char)-1,  (char)-1, (char)-1, (char)-1, (char)-1,  (char)-1, (char)-1, (char)-1, (char)-1,\n    /* A */ (char)-1, (char)-1, (char)-1, (char)-1,  (char)-1, (char)-1, (char)-1, (char)-1,  (char)-1, (char)-1, (char)-1, (char)-1,  (char)-1, (char)-1, (char)-1, (char)-1,\n    /* B */ (char)-1, (char)-1, (char)-1, (char)-1,  (char)-1, (char)-1, (char)-1, (char)-1,  (char)-1, (char)-1, (char)-1, (char)-1,  (char)-1, (char)-1, (char)-1, (char)-1,\n\n    /* C */ (char)-1, (char)-1, (char)-1, (char)-1,  (char)-1, (char)-1, (char)-1, (char)-1,  (char)-1, (char)-1, (char)-1, (char)-1,  (char)-1, (char)-1, (char)-1, (char)-1,\n    /* D */ (char)-1, (char)-1, (char)-1, (char)-1,  (char)-1, (char)-1, (char)-1, (char)-1,  (char)-1, (char)-1, (char)-1, (char)-1,  (char)-1, (char)-1, (char)-1, (char)-1,\n    /* E */ (char)-1, (char)-1, (char)-1, (char)-1,  (char)-1, (char)-1, (char)-1, (char)-1,  (char)-1, (char)-1, (char)-1, (char)-1,  (char)-1, (char)-1, (char)-1, (char)-1,\n    /* F */ (char)-1, (char)-1, (char)-1, (char)-1,  (char)-1, (char)-1, (char)-1, (char)-1,  (char)-1, (char)-1, (char)-1, (char)-1,  (char)-1, (char)-1, (char)-1, (char)-1\n};\n\n\ninline std::string ascTime(const time_t *t) {\n    struct tm timeinfo;\n    localtime_r(t, &timeinfo);\n    char tstr[std::size(\"Www Mmm dd hh:mm:ss yyyy\")];\n    strftime(tstr, std::size(tstr), \"%c\", &timeinfo);\n    return tstr;\n}\n\n\ninline std::string dash_if_empty(const std::string *str) {\n    if (str == nullptr || str->empty()) {\n        return \"-\";\n    }\n\n    return *str;\n}\n\n\ninline std::string limitTo(int amount, const std::string &str) {\n    std::string ret;\n\n    if (str.length() > amount) {\n        ret.assign(str, 0, amount);\n        ret = ret + \" (\" + std::to_string(str.length() - amount) + \" \" \\\n            \"characters omitted)\";\n        return ret;\n    }\n\n    return str;\n}\n\n\ninline std::string toHexIfNeeded(const std::string &str, bool escape_spec = false) {\n    // escape_spec: escape special chars or not\n    // spec chars: '\"' (quotation mark, ascii 34), '\\' (backslash, ascii 92)\n    std::stringstream res;\n\n    for (const auto ch : str) {\n        int c = (unsigned char)ch;\n        if (c < 32 || c > 126 || (escape_spec == true && (c == 34 || c == 92))) {\n            res << \"\\\\x\" << std::setw(2) << std::setfill('0') << std::hex << c;\n        } else {\n            res << ch;\n        }\n    }\n\n    return res.str();\n}\n\n\ninline std::vector<std::string> ssplit(const std::string &str, char delimiter) {\n    std::vector<std::string> internal;\n    std::stringstream ss(str);  // Turn the string into a stream.\n    std::string tok;\n\n    while (getline(ss, tok, delimiter)) {\n        internal.push_back(tok);\n    }\n\n    return internal;\n}\n\n\ninline std::pair<std::string, std::string> ssplit_pair(const std::string& str, char delimiter) {\n    std::stringstream ss(str);  // Turn the string into a stream.\n    std::string key;\n    std::string value;\n\n    getline(ss, key, delimiter);\n    if (key.length() < str.length()) {\n        value = str.substr(key.length()+1);\n    }\n\n    return std::make_pair(key, value);\n}\n\n\ninline std::vector<std::string> split(const std::string &str, char delimiter) {\n    std::vector<std::string> internal = ssplit(str, delimiter);\n\n    if (internal.empty()) {\n        internal.push_back(str);\n    }\n\n    return internal;\n}\n\n\ninline void chomp(std::string &str) {\n    std::string::size_type pos = str.find_last_not_of(\"\\n\\r\");\n    if (pos != std::string::npos) {\n        str.erase(pos+1, str.length()-pos-1);\n    }\n}\n\n\ninline void replaceAll(std::string &str, std::string_view from,\n    std::string_view to) {\n    size_t start_pos = 0;\n    while ((start_pos = str.find(from, start_pos)) != std::string::npos) {\n        str.replace(start_pos, from.length(), to);\n        start_pos += to.length();\n    }\n}\n\n\ninline std::string removeWhiteSpacesIfNeeded(std::string a) {\n    while (a.size() > 1 && a.front() == ' ') {\n        a.erase(0, 1);\n    }\n    while (a.size() > 1 && a.back() == ' ') {\n        a.pop_back();\n    }\n    return a;\n}\n\n\ninline std::string removeBracketsIfNeeded(std::string a) {\n    if (a.length() > 1 && a.front() == '\"' && a.back() == '\"') {\n        a.pop_back();\n        a.erase(0, 1);\n    }\n    if (a.length() > 1 && a.front() == '\\'' && a.back() == '\\'') {\n        a.pop_back();\n        a.erase(0, 1);\n    }\n    return a;\n}\n\n\ninline std::string parserSanitizer(std::string a) {\n    a = removeWhiteSpacesIfNeeded(a);\n    a = removeBracketsIfNeeded(a);\n    return a;\n}\n\n\n/**\n * Converts a single hexadecimal digit into a decimal value.\n */\ninline unsigned char xsingle2c(const unsigned char *what) {\n    unsigned char digit;\n\n    digit = (what[0] >= 'A' ? ((what[0] & 0xdf) - 'A') + 10 : (what[0] - '0'));\n\n    return digit;\n}\n\n\ninline unsigned char x2c(const unsigned char *what) {\n    unsigned char digit;\n\n    digit = xsingle2c(what);\n    digit *= 16;\n    digit += xsingle2c(what+1);\n\n    return digit;\n}\n\n\ninline unsigned char *c2x(unsigned what, unsigned char *where) {\n    static const char c2x_table[] = \"0123456789abcdef\";\n\n    what = what & 0xff;\n    *where++ = c2x_table[what >> 4];\n    *where++ = c2x_table[what & 0x0f];\n\n    return where;\n}\n\n\ninline std::string string_to_hex(std::string_view input) {\n    static const char* const lut = \"0123456789abcdef\";\n\n    std::string a(input.size()*2, 0);\n    char *d = a.data();\n\n    for (const unsigned char c : input) {\n        *d++ = lut[c >> 4];\n        *d++ = lut[c & 15];\n    }\n\n    return a;\n}\n\n\ntemplate<typename Operation>\ninline std::string toCaseHelper(std::string str, Operation op) { // cppcheck-suppress syntaxError ; false positive\n    std::transform(str.begin(),\n            str.end(),\n            str.begin(),\n            op);\n\n    return str;\n}\n\n\ninline std::string tolower(std::string str) { // cppcheck-suppress passedByValue ; copied value is used for in-place transformation\n    return toCaseHelper(str, ::tolower);\n}\n\n\ninline std::string toupper(std::string str) { // cppcheck-suppress passedByValue ; copied value is used for in-place transformation\n    return toCaseHelper(str, ::toupper);\n}\n\n\n}  // namespace modsecurity::utils::string\n\n#endif  // SRC_UTILS_STRING_H_\n"
  },
  {
    "path": "src/utils/system.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2023 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <stdio.h>\n#include <stdlib.h>\n#include <stddef.h>\n#include <string.h>\n#ifdef __OpenBSD__\n#include <glob.h>\n#elif defined(WIN32)\n#include \"Poco/Glob.h\"\n#include <algorithm>\n#else\n#include <wordexp.h>\n#endif\n#include <stdint.h>\n#include <inttypes.h>\n\n#include <ctime>\n#include <iostream>\n#include <string>\n#include <vector>\n\n#if defined _MSC_VER\n#include \"src/compat/msvc.h\"\n#include <direct.h>\n#elif defined __GNUC__\n#include <sys/types.h>\n#include <sys/stat.h>\n#endif\n\n#include \"src/utils/system.h\"\n#include \"src/config.h\"\n\n#ifdef WIN32\n\n// Public domain code from mingw-w64's winpthreads\n// https://sourceforge.net/p/mingw-w64/code/HEAD/tree/trunk/mingw-w64-libraries/winpthreads/src/clock.c\n// \n\n#define CLOCK_PROCESS_CPUTIME_ID    2\n#define POW10_7                 10000000\n\n// NOTE: includes only CLOCK_PROCESS_CPUTIME_ID implementation, ignores clock_id argument\nstatic int clock_gettime(int clock_id, struct timespec *tp)\n{\n    unsigned __int64 t;\n    LARGE_INTEGER pf, pc;\n    union {\n        unsigned __int64 u64;\n        FILETIME ft;\n    }  ct, et, kt, ut;\n\n    if(0 == GetProcessTimes(GetCurrentProcess(), &ct.ft, &et.ft, &kt.ft, &ut.ft))\n        return -1;\n    t = kt.u64 + ut.u64;\n    tp->tv_sec = t / POW10_7;\n    tp->tv_nsec = ((int) (t % POW10_7)) * 100;\n\n    return 0;\n}\n\n#endif\n\nnamespace modsecurity {\nnamespace utils {\n\n\ndouble cpu_seconds(void) {\n    /*\n     * FIXME: Temporary hack to fix build on MacOS X.  Very issuficient way, but\n     *      works.  Worth reimplementing using mach_absolute_time().\n     */\n#ifndef MACOSX\n    struct timespec t;\n    if (!clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &t))\n        return static_cast<double>(t.tv_sec)\n            + static_cast<double>(t.tv_nsec / 1000000000.0);\n    else\n        return static_cast<double>(clock()) /\n            static_cast<double>(CLOCKS_PER_SEC);\n#endif\n        return 0;\n}\n\n\nstd::string find_resource(const std::string& resource,\n    const std::string& config, std::string *err) {\n\n    err->assign(\"Looking at: \");\n    // Trying absolute or relative to the current dir.\n    auto iss = std::ifstream(resource, std::ios::in);\n    if (iss.is_open()) {\n        return resource;\n    } else {\n        err->append(\"'\" + resource + \"', \");\n    }\n\n    // What about `*' ?\n    if (utils::expandEnv(resource, 0).size() > 0) {\n        return resource;\n    } else {\n        err->append(\"'\" + resource + \"', \");\n    }\n\n    // Trying the same path of the configuration file.\n    std::string f = get_path(config) + \"/\" + resource;\n    iss = std::ifstream(f, std::ios::in);\n    if (iss.is_open()) {\n        return f;\n    } else {\n        err->append(\"'\" + f + \"', \");\n    }\n\n    // What about `*' ?\n    if (utils::expandEnv(f, 0).size() > 0) {\n        return f;\n    } else {\n        err->append(\"'\" + f + \"'.\");\n    }\n\n    return std::string(\"\");\n}\n\n\nstd::string get_path(const std::string& file) {\n    size_t found;\n\n    found = file.find_last_of(\"/\\\\\");\n    if (found > 0) {\n        return file.substr(0, found);\n    }\n\n    return std::string(\"\");\n}\n\n\nstd::list<std::string> expandEnv(const std::string& var, int flags) {\n    std::list<std::string> vars;\n#ifdef WIN32\n    // NOTE: align scopes with if & if in other versions\n    {\n        {\n            std::set<std::string> files;\n            Poco::Glob::glob(var, files);\n            for(auto file : files) {\n                std::replace(file.begin(), file.end(), '\\\\', '/');  // preserve unix-like paths\n                const char* exp[] = { file.c_str() };\n#elif defined(__OpenBSD__)\n    glob_t p;\n    if (glob(var.c_str(), flags, NULL, &p) == false) {\n        if (p.gl_pathc) {\n            for (char** exp = p.gl_pathv; *exp; ++exp) {\n#else\n    wordexp_t p;\n    flags = flags | WRDE_NOCMD;\n    if (wordexp(var.c_str(), &p, flags) == false) {\n        if (p.we_wordc) {\n            for (char** exp = p.we_wordv; *exp; ++exp) {\n#endif\n                auto iss = std::ifstream(exp[0], std::ios::in);\n                if (iss.is_open())\n                    vars.push_back(exp[0]);\n            }\n        }\n#ifdef WIN32\n#elif defined(__OpenBSD__)\n        globfree(&p);\n#else\n        wordfree(&p);\n#endif\n    }\n    return vars;\n}\n\nbool createDir(const std::string& dir, int mode, std::string *error) {\n#ifndef WIN32\n    int ret = mkdir(dir.data(), mode);\n#else\n    if (dir == \".\")\n        return true;\n    int ret = _mkdir(dir.c_str());\n#endif\n    if (ret != 0 && errno != EEXIST) {\n        error->assign(\"Not able to create directory: \" + dir + \": \" \\\n            + strerror(errno) + \".\");\n        return false;\n    }\n\n    return true;\n}\n\n\nbool isFile(const std::string& f) {\n    struct stat fileInfo;\n    FILE *fp = fopen(f.c_str(), \"r\");\n    if (fp == NULL) {\n        return false;\n    }\n    fstat(fileno(fp), &fileInfo);\n    if (!S_ISREG(fileInfo.st_mode)) { // cppcheck-suppress syntaxError ; false positive\n        fclose(fp);\n        return false;\n    }\n    fclose(fp);\n\n    return true;\n}\n\n\n}  // namespace utils\n}  // namespace modsecurity\n"
  },
  {
    "path": "src/utils/system.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <string>\n#include <list>\n\n#include \"modsecurity/modsecurity.h\"\n\n#ifndef SRC_UTILS_SYSTEM_H_\n#define SRC_UTILS_SYSTEM_H_\n\n\nnamespace modsecurity {\nnamespace utils {\n\n\ndouble cpu_seconds(void);\nstd::string find_resource(const std::string& file, const std::string& config,\n    std::string *err);\nstd::string get_path(const std::string& file);\nstd::list<std::string> expandEnv(const std::string& var, int flags);\nbool createDir(const std::string& dir, int mode, std::string *error);\nbool isFile(const std::string& f);\n\n}  // namespace utils\n}  // namespace modsecurity\n\n#endif  // SRC_UTILS_SYSTEM_H_\n"
  },
  {
    "path": "src/variables/args.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <iostream>\n#include <string>\n#include <vector>\n#include <list>\n#include <utility>\n\n#ifndef SRC_VARIABLES_ARGS_H_\n#define SRC_VARIABLES_ARGS_H_\n\n#include \"src/variables/variable.h\"\n\nnamespace modsecurity {\n\nclass Transaction;\nnamespace variables {\n\nDEFINE_VARIABLE_DICT(Args, ARGS, m_variableArgs)\n\n\n}  // namespace variables\n}  // namespace modsecurity\n\n#endif  // SRC_VARIABLES_ARGS_H_\n\n"
  },
  {
    "path": "src/variables/args_combined_size.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <iostream>\n#include <string>\n#include <vector>\n#include <list>\n#include <utility>\n\n#ifndef SRC_VARIABLES_ARGS_COMBINED_SIZE_H_\n#define SRC_VARIABLES_ARGS_COMBINED_SIZE_H_\n\n#include \"src/variables/variable.h\"\n\nnamespace modsecurity {\n\nclass Transaction;\nnamespace variables {\n\n\nDEFINE_VARIABLE(ArgsCombinedSize, ARGS_COMBINED_SIZE,\n    m_variableARGScombinedSize)\n\n\n}  // namespace variables\n}  // namespace modsecurity\n\n#endif  // SRC_VARIABLES_ARGS_COMBINED_SIZE_H_\n"
  },
  {
    "path": "src/variables/args_get.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <iostream>\n#include <string>\n#include <vector>\n#include <list>\n#include <utility>\n\n#ifndef SRC_VARIABLES_ARGS_GET_H_\n#define SRC_VARIABLES_ARGS_GET_H_\n\n#include \"src/variables/variable.h\"\n\nnamespace modsecurity {\n\nclass Transaction;\nnamespace variables {\n\n\nDEFINE_VARIABLE_DICT(ArgsGet, ARGS_GET, m_variableArgsGet)\n\n\n}  // namespace variables\n}  // namespace modsecurity\n\n#endif  // SRC_VARIABLES_ARGS_GET_H_\n\n"
  },
  {
    "path": "src/variables/args_get_names.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <iostream>\n#include <string>\n#include <vector>\n#include <list>\n#include <utility>\n\n#ifndef SRC_VARIABLES_ARGS_GET_NAMES_H_\n#define SRC_VARIABLES_ARGS_GET_NAMES_H_\n\n#include \"src/variables/variable.h\"\n\nnamespace modsecurity {\n\nclass Transaction;\nnamespace variables {\n\n\nDEFINE_VARIABLE_DICT(ArgsGetNames, ARGS_GET_NAMES, m_variableArgsGetNames)\n\n\n}  // namespace variables\n}  // namespace modsecurity\n\n#endif  // SRC_VARIABLES_ARGS_GET_NAMES_H_\n"
  },
  {
    "path": "src/variables/args_names.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <iostream>\n#include <string>\n#include <vector>\n#include <list>\n#include <utility>\n\n#ifndef SRC_VARIABLES_ARGS_NAMES_H_\n#define SRC_VARIABLES_ARGS_NAMES_H_\n\n#include \"src/variables/variable.h\"\n\nnamespace modsecurity {\n\nclass Transaction;\nnamespace variables {\n\n\nDEFINE_VARIABLE_DICT(ArgsNames, ARGS_NAMES, m_variableArgsNames)\n\n\n}  // namespace variables\n}  // namespace modsecurity\n\n#endif  // SRC_VARIABLES_ARGS_NAMES_H_\n"
  },
  {
    "path": "src/variables/args_post.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <iostream>\n#include <string>\n#include <vector>\n#include <list>\n#include <utility>\n\n#ifndef SRC_VARIABLES_ARGS_POST_H_\n#define SRC_VARIABLES_ARGS_POST_H_\n\n#include \"src/variables/variable.h\"\n\nnamespace modsecurity {\n\nclass Transaction;\nnamespace variables {\n\n\nDEFINE_VARIABLE_DICT(ArgsPost, ARGS_POST, m_variableArgsPost)\n\n\n}  // namespace variables\n}  // namespace modsecurity\n\n#endif  // SRC_VARIABLES_ARGS_POST_H_\n\n"
  },
  {
    "path": "src/variables/args_post_names.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <iostream>\n#include <string>\n#include <vector>\n#include <list>\n#include <utility>\n\n#ifndef SRC_VARIABLES_ARGS_POST_NAMES_H_\n#define SRC_VARIABLES_ARGS_POST_NAMES_H_\n\n#include \"src/variables/variable.h\"\n\nnamespace modsecurity {\n\nclass Transaction;\nnamespace variables {\n\n\nDEFINE_VARIABLE_DICT(ArgsPostNames, ARGS_POST_NAMES, m_variableArgsPostNames)\n\n\n}  // namespace variables\n}  // namespace modsecurity\n\n#endif  // SRC_VARIABLES_ARGS_POST_NAMES_H_\n"
  },
  {
    "path": "src/variables/auth_type.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <iostream>\n#include <string>\n#include <vector>\n#include <list>\n#include <utility>\n\n#ifndef SRC_VARIABLES_AUTH_TYPE_H_\n#define SRC_VARIABLES_AUTH_TYPE_H_\n\n#include \"src/variables/variable.h\"\n\nnamespace modsecurity {\n\nclass Transaction;\nnamespace variables {\n\n\nDEFINE_VARIABLE(AuthType, AUTH_TYPE, m_variableAuthType)\n\n\n}  // namespace variables\n}  // namespace modsecurity\n\n#endif  // SRC_VARIABLES_AUTH_TYPE_H_\n"
  },
  {
    "path": "src/variables/duration.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"src/variables/duration.h\"\n\n#include <iostream>\n#include <string>\n#include <vector>\n#include <list>\n#include <utility>\n\n#include \"modsecurity/transaction.h\"\n#include \"src/utils/system.h\"\n\nnamespace modsecurity {\nnamespace variables {\n\nvoid Duration::evaluate(Transaction *transaction,\n    RuleWithActions *rule,\n    std::vector<const VariableValue *> *l) {\n    double e = utils::cpu_seconds() - transaction->m_creationTimeStamp;\n\n    transaction->m_variableDuration.assign(std::to_string(e));\n\n    l->push_back(new VariableValue(&m_retName,\n        &transaction->m_variableDuration));\n}\n\n\n}  // namespace variables\n}  // namespace modsecurity\n"
  },
  {
    "path": "src/variables/duration.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <vector>\n#include <string>\n#include <list>\n#include <utility>\n\n#ifndef SRC_VARIABLES_DURATION_H_\n#define SRC_VARIABLES_DURATION_H_\n\n#include \"src/variables/variable.h\"\n\nnamespace modsecurity {\n\nclass Transaction;\nnamespace variables {\n\nclass Duration : public Variable {\n public:\n    explicit Duration(const std::string &_name)\n        : Variable(_name),\n        m_retName(\"DURATION\") { }\n\n    void evaluate(Transaction *transaction,\n        RuleWithActions *rule,\n        std::vector<const VariableValue *> *l) override;\n    std::string m_retName;\n};\n\n\n}  // namespace variables\n}  // namespace modsecurity\n\n#endif  // SRC_VARIABLES_DURATION_H_\n"
  },
  {
    "path": "src/variables/env.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"src/variables/env.h\"\n\n#include <stdlib.h>\n#include <stdio.h>\n\n#include <iostream>\n#include <string>\n#include <vector>\n#include <list>\n#include <utility>\n#include <map>\n\n#ifdef WIN32\n#include \"src/compat/msvc.h\"\n#endif\n\n#include \"modsecurity/transaction.h\"\n\n#ifndef WIN32\nextern char **environ;\n#endif\n\nnamespace modsecurity {\nnamespace variables {\n\nvoid Env::evaluate(Transaction *transaction,\n    RuleWithActions *rule,\n    std::vector<const VariableValue *> *l) {\n    for (char **current = environ; *current; current++) {\n        std::string env = std::string(*current);\n        size_t pos = env.find_first_of(\"=\");\n        if (pos == std::string::npos) {\n            continue;\n        }\n        std::string key = std::string(env, 0, pos);\n        std::string value = std::string(env, pos+1, env.length() - (pos + 1));\n        std::pair<std::string, std::string> a(key, value);\n        transaction->m_variableEnvs.insert(a);\n    }\n\n    const auto hasName = m_name.length() > 0;\n    for (const auto& x : transaction->m_variableEnvs) {\n#ifndef WIN32\n        if (hasName && x.first != m_name) {\n#else\n        if (hasName && strcasecmp(x.first.c_str(), m_name.c_str()) != 0) {\n#endif\n            continue;\n        }\n        // (Windows) we need to keep the case from the rule in case that from\n        // the environment differs.\n        const auto &key = hasName ? m_name : x.first;\n        if (!m_keyExclusion.toOmit(key)) {\n            l->push_back(new VariableValue(&m_collectionName, &key,\n                &x.second));\n        }\n    }\n}\n\n\n}  // namespace variables\n}  // namespace modsecurity\n"
  },
  {
    "path": "src/variables/env.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <vector>\n#include <string>\n#include <list>\n#include <utility>\n\n#ifndef SRC_VARIABLES_ENV_H_\n#define SRC_VARIABLES_ENV_H_\n\n#include \"src/variables/variable.h\"\n\nnamespace modsecurity {\n\nclass Transaction;\nnamespace variables {\n\nclass Env : public Variable {\n public:\n    explicit Env(const std::string &_name)\n        : Variable(_name) { }\n\n    void evaluate(Transaction *transaction,\n        RuleWithActions *rule,\n        std::vector<const VariableValue *> *l) override;\n};\n\n}  // namespace variables\n}  // namespace modsecurity\n\n#endif  // SRC_VARIABLES_ENV_H_\n"
  },
  {
    "path": "src/variables/files.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <iostream>\n#include <string>\n#include <vector>\n#include <list>\n#include <utility>\n\n#ifndef SRC_VARIABLES_FILES_H_\n#define SRC_VARIABLES_FILES_H_\n\n#include \"src/variables/variable.h\"\n\nnamespace modsecurity {\n\nclass Transaction;\nnamespace variables {\n\n\nDEFINE_VARIABLE_DICT(Files, FILES, m_variableFiles)\n\n\n}  // namespace variables\n}  // namespace modsecurity\n\n#endif  // SRC_VARIABLES_FILES_H_\n\n"
  },
  {
    "path": "src/variables/files_combined_size.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <iostream>\n#include <string>\n#include <vector>\n#include <list>\n#include <utility>\n\n#ifndef SRC_VARIABLES_FILES_COMBINED_SIZE_H_\n#define SRC_VARIABLES_FILES_COMBINED_SIZE_H_\n\n#include \"src/variables/variable.h\"\n\nnamespace modsecurity {\n\nclass Transaction;\nnamespace variables {\n\n\nDEFINE_VARIABLE(FilesCombinedSize, FILES_COMBINED_SIZE,\n    m_variableFilesCombinedSize)\n\n\n}  // namespace variables\n}  // namespace modsecurity\n\n#endif  // SRC_VARIABLES_FILES_COMBINED_SIZE_H_\n"
  },
  {
    "path": "src/variables/files_names.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <iostream>\n#include <string>\n#include <vector>\n#include <list>\n#include <utility>\n\n#ifndef SRC_VARIABLES_FILES_NAMES_H_\n#define SRC_VARIABLES_FILES_NAMES_H_\n\n#include \"src/variables/variable.h\"\n\nnamespace modsecurity {\n\nclass Transaction;\nnamespace variables {\n\n\nDEFINE_VARIABLE_DICT(FilesNames, FILES_NAMES, m_variableFilesNames)\n\n\n}  // namespace variables\n}  // namespace modsecurity\n\n#endif  // SRC_VARIABLES_FILES_NAMES_H_\n\n"
  },
  {
    "path": "src/variables/files_sizes.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <iostream>\n#include <string>\n#include <vector>\n#include <list>\n#include <utility>\n\n#ifndef SRC_VARIABLES_FILES_SIZES_H_\n#define SRC_VARIABLES_FILES_SIZES_H_\n\n#include \"src/variables/variable.h\"\n\nnamespace modsecurity {\n\nclass Transaction;\nnamespace variables {\n\n\nDEFINE_VARIABLE_DICT(FilesSizes, FILES_SIZES, m_variableFilesSizes)\n\n\n}  // namespace variables\n}  // namespace modsecurity\n\n#endif  // SRC_VARIABLES_FILES_SIZES_H_\n\n"
  },
  {
    "path": "src/variables/files_tmp_content.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <iostream>\n#include <string>\n#include <vector>\n#include <list>\n#include <utility>\n\n#ifndef SRC_VARIABLES_FILES_TMP_CONTENT_H_\n#define SRC_VARIABLES_FILES_TMP_CONTENT_H_\n\n#include \"src/variables/variable.h\"\n\nnamespace modsecurity {\n\nclass Transaction;\nnamespace variables {\n\n\nDEFINE_VARIABLE_DICT(FilesTmpContent, FILES_TMP_CONTENT,\n    m_variableFilesTmpContent)\n\n\n}  // namespace variables\n}  // namespace modsecurity\n\n#endif  // SRC_VARIABLES_FILES_TMP_CONTENT_H_\n\n"
  },
  {
    "path": "src/variables/files_tmp_names.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <iostream>\n#include <string>\n#include <vector>\n#include <list>\n#include <utility>\n\n#ifndef SRC_VARIABLES_FILES_TMP_NAMES_H_\n#define SRC_VARIABLES_FILES_TMP_NAMES_H_\n\n#include \"src/variables/variable.h\"\n\nnamespace modsecurity {\n\nclass Transaction;\nnamespace variables {\n\n\nDEFINE_VARIABLE_DICT(FilesTmpNames, FILES_TMPNAMES, m_variableFilesTmpNames)\n\n\n}  // namespace variables\n}  // namespace modsecurity\n\n#endif  // SRC_VARIABLES_FILES_TMP_NAMES_H_\n"
  },
  {
    "path": "src/variables/full_request.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <iostream>\n#include <string>\n#include <vector>\n#include <list>\n#include <utility>\n\n#ifndef SRC_VARIABLES_FULL_REQUEST_H_\n#define SRC_VARIABLES_FULL_REQUEST_H_\n\n#include \"src/variables/variable.h\"\n\nnamespace modsecurity {\n\nclass Transaction;\nnamespace variables {\n\n\nDEFINE_VARIABLE(FullRequest, FULL_REQUEST, m_variableFullRequest)\n\n\n}  // namespace variables\n}  // namespace modsecurity\n\n#endif  // SRC_VARIABLES_FULL_REQUEST_H_\n"
  },
  {
    "path": "src/variables/full_request_length.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <iostream>\n#include <string>\n#include <vector>\n#include <list>\n#include <utility>\n\n#ifndef SRC_VARIABLES_FULL_REQUEST_LENGTH_H_\n#define SRC_VARIABLES_FULL_REQUEST_LENGTH_H_\n\n#include \"src/variables/variable.h\"\n\nnamespace modsecurity {\n\nclass Transaction;\nnamespace variables {\n\n\nDEFINE_VARIABLE(FullRequestLength, FULL_REQUEST_LENGTH,\n    m_variableFullRequestLength)\n\n\n}  // namespace variables\n}  // namespace modsecurity\n\n#endif  // SRC_VARIABLES_FULL_REQUEST_LENGTH_H_\n"
  },
  {
    "path": "src/variables/geo.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <iostream>\n#include <string>\n#include <vector>\n#include <list>\n#include <utility>\n\n#ifndef SRC_VARIABLES_GEO_H_\n#define SRC_VARIABLES_GEO_H_\n\n#include \"src/variables/variable.h\"\n\nnamespace modsecurity {\n\nclass Transaction;\nnamespace variables {\n\n\nDEFINE_VARIABLE_DICT(Geo, GEO, m_variableGeo)\n\n\n}  // namespace variables\n}  // namespace modsecurity\n\n#endif  // SRC_VARIABLES_GEO_H_\n\n"
  },
  {
    "path": "src/variables/global.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2023 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <list>\n#include <memory>\n#include <string>\n#include <utility>\n#include <vector>\n\n#ifndef SRC_VARIABLES_GLOBAL_H_\n#define SRC_VARIABLES_GLOBAL_H_\n\n#include \"src/variables/variable.h\"\n#include \"src/run_time_string.h\"\n\nnamespace modsecurity {\n\nclass Transaction;\nnamespace variables {\n\n\nclass Global_DictElement : public Variable {\n public:\n    explicit Global_DictElement(const std::string &dictElement)\n        : Variable(\"GLOBAL:\" + dictElement),\n        m_dictElement(\"GLOBAL:\" + dictElement) { }\n\n    void evaluate(Transaction *t,\n        RuleWithActions *rule,\n        std::vector<const VariableValue *> *l) override {\n        t->m_collections.m_global_collection->resolveMultiMatches(\n            m_name, t->m_collections.m_global_collection_key,\n            t->m_rules->m_secWebAppId.m_value, l, m_keyExclusion);\n    }\n\n    std::string m_dictElement;\n};\n\n\nclass Global_NoDictElement : public Variable {\n public:\n    Global_NoDictElement()\n        : Variable(\"GLOBAL\") { }\n\n    void evaluate(Transaction *t,\n        RuleWithActions *rule,\n        std::vector<const VariableValue *> *l) override {\n        t->m_collections.m_global_collection->resolveMultiMatches(\"\",\n            t->m_collections.m_global_collection_key,\n            t->m_rules->m_secWebAppId.m_value, l, m_keyExclusion);\n    }\n};\n\n\nclass Global_DictElementRegexp : public VariableRegex {\n public:\n    explicit Global_DictElementRegexp(const std::string &dictElement)\n        : VariableRegex(\"GLOBAL\", dictElement),\n        m_dictElement(dictElement) { }\n\n    void evaluate(Transaction *t,\n        RuleWithActions *rule,\n        std::vector<const VariableValue *> *l) override {\n        t->m_collections.m_global_collection->resolveRegularExpression(\n            m_dictElement,\n            t->m_collections.m_global_collection_key,\n            t->m_rules->m_secWebAppId.m_value, l, m_keyExclusion);\n    }\n\n    std::string m_dictElement;\n};\n\n\nclass Global_DynamicElement : public Variable {\n public:\n    explicit Global_DynamicElement(std::unique_ptr<RunTimeString> dictElement)\n        : Variable(\"GLOBAL:dynamic\"),\n        m_string(std::move(dictElement)) { }\n\n    void evaluate(Transaction *t,\n        RuleWithActions *rule,\n        std::vector<const VariableValue *> *l) override {\n        std::string string = m_string->evaluate(t);\n        t->m_collections.m_global_collection->resolveMultiMatches(\n            string,\n            t->m_collections.m_global_collection_key,\n            t->m_rules->m_secWebAppId.m_value, l, m_keyExclusion);\n    }\n\n    static void del(Transaction *t, const std::string &k) {\n        t->m_collections.m_global_collection->del(k,\n            t->m_collections.m_global_collection_key,\n            t->m_rules->m_secWebAppId.m_value);\n    }\n\n    static void setExpiry(Transaction *t, const std::string &k, int32_t expiry_seconds) {\n        t->m_collections.m_global_collection->setExpiry(k,\n            t->m_collections.m_global_collection_key,\n            t->m_rules->m_secWebAppId.m_value, expiry_seconds);\n    }\n\n    static void storeOrUpdateFirst(Transaction *t, const std::string &var,\n        const std::string &value) {\n        t->m_collections.m_global_collection->storeOrUpdateFirst(\n            var, t->m_collections.m_global_collection_key,\n            t->m_rules->m_secWebAppId.m_value,\n            value);\n    }\n\n    std::unique_ptr<RunTimeString> m_string;\n};\n\n\n}  // namespace variables\n}  // namespace modsecurity\n\n#endif  // SRC_VARIABLES_GLOBAL_H_\n"
  },
  {
    "path": "src/variables/highest_severity.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"src/variables/highest_severity.h\"\n\n#include <iostream>\n#include <string>\n#include <vector>\n#include <list>\n#include <utility>\n\n#include \"modsecurity/transaction.h\"\n\nnamespace modsecurity {\nnamespace variables {\n\nvoid HighestSeverity::evaluate(Transaction *transaction,\n    RuleWithActions *rule,\n    std::vector<const VariableValue *> *l) {\n    transaction->m_variableHighestSeverityAction.assign(\n        std::to_string(transaction->m_highestSeverityAction));\n    l->push_back(new VariableValue(m_fullName.get(),\n       &transaction->m_variableHighestSeverityAction));\n}\n\n\n}  // namespace variables\n}  // namespace modsecurity\n"
  },
  {
    "path": "src/variables/highest_severity.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <vector>\n#include <string>\n#include <list>\n#include <utility>\n\n#ifndef SRC_VARIABLES_HIGHEST_SEVERITY_H_\n#define SRC_VARIABLES_HIGHEST_SEVERITY_H_\n\n#include \"src/variables/variable.h\"\n\nnamespace modsecurity {\n\nclass Transaction;\nnamespace variables {\n\nclass HighestSeverity : public Variable {\n public:\n    explicit HighestSeverity(const std::string &_name)\n        : Variable(_name)\n    { }\n\n    void evaluate(Transaction *transaction,\n        RuleWithActions *rule,\n        std::vector<const VariableValue *> *l) override;\n};\n\n\n}  // namespace variables\n}  // namespace modsecurity\n\n#endif  // SRC_VARIABLES_HIGHEST_SEVERITY_H_\n"
  },
  {
    "path": "src/variables/inbound_data_error.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <iostream>\n#include <string>\n#include <vector>\n#include <list>\n#include <utility>\n\n#ifndef SRC_VARIABLES_INBOUND_DATA_ERROR_H_\n#define SRC_VARIABLES_INBOUND_DATA_ERROR_H_\n\n#include \"src/variables/variable.h\"\n\nnamespace modsecurity {\n\nclass Transaction;\nnamespace variables {\n\n\nDEFINE_VARIABLE(InboundDataError, INBOUND_DATA_ERROR,\n    m_variableInboundDataError)\n\n\n}  // namespace variables\n}  // namespace modsecurity\n\n#endif  // SRC_VARIABLES_INBOUND_DATA_ERROR_H_\n"
  },
  {
    "path": "src/variables/ip.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2023 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <list>\n#include <memory>\n#include <string>\n#include <utility>\n#include <vector>\n\n#ifndef SRC_VARIABLES_IP_H_\n#define SRC_VARIABLES_IP_H_\n\n#include \"src/variables/variable.h\"\n#include \"src/run_time_string.h\"\n\nnamespace modsecurity {\n\nclass Transaction;\nnamespace variables {\n\n\nclass Ip_DictElement : public Variable {\n public:\n    explicit Ip_DictElement(const std::string &dictElement)\n        : Variable(\"IP:\" + dictElement),\n        m_dictElement(\"IP:\" + dictElement) { }\n\n    void evaluate(Transaction *t,\n        RuleWithActions *rule,\n        std::vector<const VariableValue *> *l) override {\n        t->m_collections.m_ip_collection->resolveMultiMatches(\n            m_name, t->m_collections.m_ip_collection_key,\n            t->m_rules->m_secWebAppId.m_value, l, m_keyExclusion);\n    }\n\n    std::string m_dictElement;\n};\n\n\nclass Ip_NoDictElement : public Variable {\n public:\n    Ip_NoDictElement()\n        : Variable(\"IP\") { }\n\n    void evaluate(Transaction *t,\n        RuleWithActions *rule,\n        std::vector<const VariableValue *> *l) override {\n        t->m_collections.m_ip_collection->resolveMultiMatches(\"\",\n            t->m_collections.m_ip_collection_key,\n            t->m_rules->m_secWebAppId.m_value, l, m_keyExclusion);\n    }\n};\n\n\nclass Ip_DictElementRegexp : public VariableRegex {\n public:\n    explicit Ip_DictElementRegexp(const std::string &dictElement)\n        : VariableRegex(\"IP\", dictElement),\n        m_dictElement(dictElement) { }\n\n    void evaluate(Transaction *t,\n        RuleWithActions *rule,\n        std::vector<const VariableValue *> *l) override {\n        t->m_collections.m_ip_collection->resolveRegularExpression(\n            m_dictElement, t->m_collections.m_ip_collection_key,\n            t->m_rules->m_secWebAppId.m_value, l, m_keyExclusion);\n    }\n\n    std::string m_dictElement;\n};\n\n\nclass Ip_DynamicElement : public Variable {\n public:\n    explicit Ip_DynamicElement(std::unique_ptr<RunTimeString> dictElement)\n        : Variable(\"IP:dynamic\"),\n        m_string(std::move(dictElement)) { }\n\n    void evaluate(Transaction *t,\n        RuleWithActions *rule,\n        std::vector<const VariableValue *> *l) override {\n        std::string string = m_string->evaluate(t);\n        t->m_collections.m_ip_collection->resolveMultiMatches(\n            string,\n            t->m_collections.m_ip_collection_key,\n            t->m_rules->m_secWebAppId.m_value, l, m_keyExclusion);\n    }\n\n    static void del(Transaction *t, const std::string &k) {\n        t->m_collections.m_ip_collection->del(k,\n            t->m_collections.m_ip_collection_key,\n            t->m_rules->m_secWebAppId.m_value);\n    }\n\n    static void setExpiry(Transaction *t, const std::string &k, int32_t expiry_seconds) {\n        t->m_collections.m_ip_collection->setExpiry(k,\n            t->m_collections.m_ip_collection_key,\n            t->m_rules->m_secWebAppId.m_value, expiry_seconds);\n    }\n\n    static void storeOrUpdateFirst(Transaction *t, const std::string &var,\n        const std::string &value) {\n        t->m_collections.m_ip_collection->storeOrUpdateFirst(\n            var, t->m_collections.m_ip_collection_key,\n            t->m_rules->m_secWebAppId.m_value,\n            value);\n    }\n\n    std::unique_ptr<RunTimeString> m_string;\n};\n\n\n}  // namespace variables\n}  // namespace modsecurity\n\n#endif  // SRC_VARIABLES_IP_H_\n"
  },
  {
    "path": "src/variables/matched_var.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <iostream>\n#include <string>\n#include <vector>\n#include <list>\n#include <utility>\n\n#ifndef SRC_VARIABLES_MATCHED_VAR_H_\n#define SRC_VARIABLES_MATCHED_VAR_H_\n\n#include \"src/variables/variable.h\"\n\nnamespace modsecurity {\n\nclass Transaction;\nnamespace variables {\n\n\nDEFINE_VARIABLE(MatchedVar, MATCHED_VAR, m_variableMatchedVar)\n\n\n}  // namespace variables\n}  // namespace modsecurity\n\n#endif  // SRC_VARIABLES_MATCHED_VAR_H_\n"
  },
  {
    "path": "src/variables/matched_var_name.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <iostream>\n#include <string>\n#include <vector>\n#include <list>\n#include <utility>\n\n#ifndef SRC_VARIABLES_MATCHED_VAR_NAME_H_\n#define SRC_VARIABLES_MATCHED_VAR_NAME_H_\n\n#include \"src/variables/variable.h\"\n\nnamespace modsecurity {\n\nclass Transaction;\nnamespace variables {\n\n\nDEFINE_VARIABLE(MatchedVarName, MATCHED_VAR_NAME, m_variableMatchedVarName)\n\n\n}  // namespace variables\n}  // namespace modsecurity\n\n#endif  // SRC_VARIABLES_MATCHED_VAR_NAME_H_\n"
  },
  {
    "path": "src/variables/matched_vars.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <iostream>\n#include <string>\n#include <vector>\n#include <list>\n#include <utility>\n\n#ifndef SRC_VARIABLES_MATCHED_VARS_H_\n#define SRC_VARIABLES_MATCHED_VARS_H_\n\n#include \"src/variables/variable.h\"\n\nnamespace modsecurity {\n\nclass Transaction;\nnamespace variables {\n\n\nDEFINE_VARIABLE_DICT(MatchedVars, MATCHED_VARS, m_variableMatchedVars)\n\n\n}  // namespace variables\n}  // namespace modsecurity\n\n#endif  // SRC_VARIABLES_MATCHED_VARS_H_\n\n"
  },
  {
    "path": "src/variables/matched_vars_names.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <iostream>\n#include <string>\n#include <vector>\n#include <list>\n#include <utility>\n\n#ifndef SRC_VARIABLES_MATCHED_VARS_NAMES_H_\n#define SRC_VARIABLES_MATCHED_VARS_NAMES_H_\n\n#include \"src/variables/variable.h\"\n\nnamespace modsecurity {\n\nclass Transaction;\nnamespace variables {\n\n\nDEFINE_VARIABLE_DICT(MatchedVarsNames, MATCHED_VARS_NAMES,\n   m_variableMatchedVarsNames)\n\n\n}  // namespace variables\n}  // namespace modsecurity\n\n#endif  // SRC_VARIABLES_MATCHED_VARS_NAMES_H_\n\n"
  },
  {
    "path": "src/variables/modsec_build.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"src/variables/modsec_build.h\"\n\n#include <vector>\n#include <list>\n#include <utility>\n\n#include \"modsecurity/transaction.h\"\n\nnamespace modsecurity {\nnamespace variables {\n\nvoid ModsecBuild::evaluate(Transaction *transaction,\n    RuleWithActions *rule,\n    std::vector<const VariableValue *> *l) {\n\n    l->push_back(new VariableValue(&m_retName, &m_build));\n}\n\n\n}  // namespace variables\n}  // namespace modsecurity\n"
  },
  {
    "path": "src/variables/modsec_build.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <vector>\n#include <string>\n#include <list>\n#include <utility>\n#include <iostream>\n\n#ifndef SRC_VARIABLES_MODSEC_BUILD_H_\n#define SRC_VARIABLES_MODSEC_BUILD_H_\n\n#include \"src/variables/variable.h\"\n#include \"modsecurity/modsecurity.h\"\n\nnamespace modsecurity {\n\nclass Transaction;\nnamespace variables {\n\nclass ModsecBuild : public Variable {\n public:\n    explicit ModsecBuild(const std::string &_name)\n        : Variable(_name),\n        m_retName(\"MODSEC_BUILD\") {\n        std::ostringstream ss;\n        ss << std::setw(2) << std::setfill('0') << MODSECURITY_MAJOR;\n        ss << std::setw(2) << std::setfill('0') << MODSECURITY_MINOR;\n        ss << std::setw(2) << std::setfill('0') << MODSECURITY_PATCHLEVEL;\n        ss << std::setw(2) << std::setfill('0') << MODSECURITY_TAG_NUM;\n        m_build = ss.str();\n    }\n\n    void evaluate(Transaction *transaction,\n        RuleWithActions *rule,\n        std::vector<const VariableValue *> *l) override;\n\n    std::string m_build;\n    std::string m_retName;\n};\n\n\n}  // namespace variables\n}  // namespace modsecurity\n\n#endif  // SRC_VARIABLES_MODSEC_BUILD_H_\n"
  },
  {
    "path": "src/variables/msc_pcre_error.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2022 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <iostream>\n#include <string>\n#include <vector>\n#include <list>\n#include <utility>\n\n#ifndef SRC_VARIABLES_MSC_PCRE_ERROR_H_\n#define SRC_VARIABLES_MSC_PCRE_ERROR_H_\n\n#include \"src/variables/variable.h\"\n\nnamespace modsecurity {\n\nclass Transaction;\nnamespace variables {\n\n\nDEFINE_VARIABLE(MscPcreError, MSC_PCRE_ERROR, m_variableMscPcreError)\n\n\n}  // namespace variables\n}  // namespace modsecurity\n\n#endif  // SRC_VARIABLES_MSC_PCRE_ERROR_H_\n"
  },
  {
    "path": "src/variables/msc_pcre_limits_exceeded.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2022 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <iostream>\n#include <string>\n#include <vector>\n#include <list>\n#include <utility>\n\n#ifndef SRC_VARIABLES_MSC_PCRE_LIMITS_EXCEEDED_H_\n#define SRC_VARIABLES_MSC_PCRE_LIMITS_EXCEEDED_H_\n\n#include \"src/variables/variable.h\"\n\nnamespace modsecurity {\n\nclass Transaction;\nnamespace variables {\n\n\nDEFINE_VARIABLE(MscPcreLimitsExceeded, MSC_PCRE_LIMITS_EXCEEDED, m_variableMscPcreLimitsExceeded)\n\n\n}  // namespace variables\n}  // namespace modsecurity\n\n#endif  // SRC_VARIABLES_MSC_PCRE_LIMITS_EXCEEDED_H_\n"
  },
  {
    "path": "src/variables/multipart_boundary_quoted.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <iostream>\n#include <string>\n#include <vector>\n#include <list>\n#include <utility>\n\n#ifndef SRC_VARIABLES_MULTIPART_BOUNDARY_QUOTED_H_\n#define SRC_VARIABLES_MULTIPART_BOUNDARY_QUOTED_H_\n\n#include \"src/variables/variable.h\"\n\nnamespace modsecurity {\n\nclass Transaction;\nnamespace variables {\n\n\nDEFINE_VARIABLE(MultipartBoundaryQuoted, MULTIPART_BOUNDARY_QUOTED,\n    m_variableMultipartBoundaryQuoted)\n\n\n}  // namespace variables\n}  // namespace modsecurity\n\n#endif  // SRC_VARIABLES_MULTIPART_BOUNDARY_QUOTED_H_\n"
  },
  {
    "path": "src/variables/multipart_boundary_whitespace.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <iostream>\n#include <string>\n#include <vector>\n#include <list>\n#include <utility>\n\n#ifndef SRC_VARIABLES_MULTIPART_BOUNDARY_WHITESPACE_H_\n#define SRC_VARIABLES_MULTIPART_BOUNDARY_WHITESPACE_H_\n\n#include \"src/variables/variable.h\"\n\nnamespace modsecurity {\n\nclass Transaction;\nnamespace variables {\n\n\nDEFINE_VARIABLE(MultipartBoundaryWhiteSpace, MULTIPART_BOUNDARY_WHITESPACE,\n    m_variableMultipartBoundaryWhiteSpace)\n\n\n}  // namespace variables\n}  // namespace modsecurity\n\n#endif  // SRC_VARIABLES_MULTIPART_BOUNDARY_WHITESPACE_H_\n"
  },
  {
    "path": "src/variables/multipart_crlf_lf_lines.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <iostream>\n#include <string>\n#include <vector>\n#include <list>\n#include <utility>\n\n#ifndef SRC_VARIABLES_MULTIPART_CRLF_LF_LINES_H_\n#define SRC_VARIABLES_MULTIPART_CRLF_LF_LINES_H_\n\n#include \"src/variables/variable.h\"\n\nnamespace modsecurity {\n\nclass Transaction;\nnamespace variables {\n\n\nDEFINE_VARIABLE(MultipartCrlfLFLines, MULTIPART_CRLF_LF_LINES,\n    m_variableMultipartCrlfLFLines)\n\n\n}  // namespace variables\n}  // namespace modsecurity\n\n#endif  // SRC_VARIABLES_MULTIPART_CRLF_LF_LINES_H_\n"
  },
  {
    "path": "src/variables/multipart_data_after.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <iostream>\n#include <string>\n#include <vector>\n#include <list>\n#include <utility>\n\n#ifndef SRC_VARIABLES_MULTIPART_DATA_AFTER_H_\n#define SRC_VARIABLES_MULTIPART_DATA_AFTER_H_\n\n#include \"src/variables/variable.h\"\n\nnamespace modsecurity {\n\nclass Transaction;\nnamespace variables {\n\n\nDEFINE_VARIABLE(MultipartDateAfter, MULTIPART_DATA_AFTER,\n    m_variableMultipartDataAfter)\n\n\n}  // namespace variables\n}  // namespace modsecurity\n\n#endif  // SRC_VARIABLES_MULTIPART_DATA_AFTER_H_\n"
  },
  {
    "path": "src/variables/multipart_data_before.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <iostream>\n#include <string>\n#include <vector>\n#include <list>\n#include <utility>\n\n#ifndef SRC_VARIABLES_MULTIPART_DATA_BEFORE_H_\n#define SRC_VARIABLES_MULTIPART_DATA_BEFORE_H_\n\n#include \"src/variables/variable.h\"\n\nnamespace modsecurity {\n\nclass Transaction;\nnamespace variables {\n\n\nDEFINE_VARIABLE(MultipartDateBefore, MULTIPART_DATA_BEFORE,\n    m_variableMultipartDataBefore)\n\n\n}  // namespace variables\n}  // namespace modsecurity\n\n#endif  // SRC_VARIABLES_MULTIPART_DATA_BEFORE_H_\n"
  },
  {
    "path": "src/variables/multipart_file_limit_exceeded.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <iostream>\n#include <string>\n#include <vector>\n#include <list>\n#include <utility>\n\n#ifndef SRC_VARIABLES_MULTIPART_FILE_LIMIT_EXCEEDED_H_\n#define SRC_VARIABLES_MULTIPART_FILE_LIMIT_EXCEEDED_H_\n\n#include \"src/variables/variable.h\"\n\nnamespace modsecurity {\n\nclass Transaction;\nnamespace variables {\n\n\nDEFINE_VARIABLE(MultipartFileLimitExceeded, MULTIPART_FILE_LIMIT_EXCEEDED,\n    m_variableMultipartFileLimitExceeded)\n\n\n}  // namespace variables\n}  // namespace modsecurity\n\n#endif  // SRC_VARIABLES_MULTIPART_FILE_LIMIT_EXCEEDED_H_\n"
  },
  {
    "path": "src/variables/multipart_file_name.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <iostream>\n#include <string>\n#include <vector>\n#include <list>\n#include <utility>\n\n#ifndef SRC_VARIABLES_MULTIPART_FILE_NAME_H_\n#define SRC_VARIABLES_MULTIPART_FILE_NAME_H_\n\n#include \"src/variables/variable.h\"\n\nnamespace modsecurity {\n\nclass Transaction;\nnamespace variables {\n\n\nDEFINE_VARIABLE_DICT(MultiPartFileName, MULTIPART_FILENAME,\n    m_variableMultipartFileName)\n\n\n}  // namespace variables\n}  // namespace modsecurity\n\n#endif  // SRC_VARIABLES_MULTIPART_FILE_NAME_H_\n\n"
  },
  {
    "path": "src/variables/multipart_header_folding.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <iostream>\n#include <string>\n#include <vector>\n#include <list>\n#include <utility>\n\n#ifndef SRC_VARIABLES_MULTIPART_HEADER_FOLDING_H_\n#define SRC_VARIABLES_MULTIPART_HEADER_FOLDING_H_\n\n#include \"src/variables/variable.h\"\n\nnamespace modsecurity {\n\nclass Transaction;\nnamespace variables {\n\n\nDEFINE_VARIABLE(MultipartHeaderFolding, MULTIPART_HEADER_FOLDING,\n    m_variableMultipartHeaderFolding)\n\n\n}  // namespace variables\n}  // namespace modsecurity\n\n#endif  // SRC_VARIABLES_MULTIPART_HEADER_FOLDING_H_\n"
  },
  {
    "path": "src/variables/multipart_invalid_header_folding.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <iostream>\n#include <string>\n#include <vector>\n#include <list>\n#include <utility>\n\n#ifndef SRC_VARIABLES_MULTIPART_INVALID_HEADER_FOLDING_H_\n#define SRC_VARIABLES_MULTIPART_INVALID_HEADER_FOLDING_H_\n\n#include \"src/variables/variable.h\"\n\nnamespace modsecurity {\n\nclass Transaction;\nnamespace variables {\n\n\nDEFINE_VARIABLE(MultipartInvalidHeaderFolding, MULTIPART_INVALID_HEADER_FOLDING, m_variableMultipartInvalidHeaderFolding)\n\n\n}  // namespace variables\n}  // namespace modsecurity\n\n#endif  // SRC_VARIABLES_MULTIPART_INVALID_HEADER_FOLDING_H_\n"
  },
  {
    "path": "src/variables/multipart_invalid_part.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <iostream>\n#include <string>\n#include <vector>\n#include <list>\n#include <utility>\n\n#ifndef SRC_VARIABLES_MULTIPART_INVALID_PART_H_\n#define SRC_VARIABLES_MULTIPART_INVALID_PART_H_\n\n#include \"src/variables/variable.h\"\n\nnamespace modsecurity {\n\nclass Transaction;\nnamespace variables {\n\n\nDEFINE_VARIABLE(MultipartInvalidPart, MULTIPART_INVALID_PART,\n    m_variableMultipartInvalidPart)\n\n\n}  // namespace variables\n}  // namespace modsecurity\n\n#endif  // SRC_VARIABLES_MULTIPART_INVALID_PART_H_\n"
  },
  {
    "path": "src/variables/multipart_invalid_quoting.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <iostream>\n#include <string>\n#include <vector>\n#include <list>\n#include <utility>\n\n#ifndef SRC_VARIABLES_MULTIPART_INVALID_QUOTING_H_\n#define SRC_VARIABLES_MULTIPART_INVALID_QUOTING_H_\n\n#include \"src/variables/variable.h\"\n\nnamespace modsecurity {\n\nclass Transaction;\nnamespace variables {\n\n\nDEFINE_VARIABLE(MultipartInvalidQuoting, MULTIPART_INVALID_QUOTING,\n    m_variableMultipartInvalidQuoting)\n\n\n}  // namespace variables\n}  // namespace modsecurity\n\n#endif  // SRC_VARIABLES_MULTIPART_INVALID_QUOTING_H_\n"
  },
  {
    "path": "src/variables/multipart_lf_line.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <iostream>\n#include <string>\n#include <vector>\n#include <list>\n#include <utility>\n\n#ifndef SRC_VARIABLES_MULTIPART_LF_LINE_H_\n#define SRC_VARIABLES_MULTIPART_LF_LINE_H_\n\n#include \"src/variables/variable.h\"\n\nnamespace modsecurity {\n\nclass Transaction;\nnamespace variables {\n\n\nDEFINE_VARIABLE(MultipartLFLine, MULTIPART_LF_LINE, m_variableMultipartLFLine)\n\n\n}  // namespace variables\n}  // namespace modsecurity\n\n#endif  // SRC_VARIABLES_MULTIPART_LF_LINE_H_\n"
  },
  {
    "path": "src/variables/multipart_missing_semicolon.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <iostream>\n#include <string>\n#include <vector>\n#include <list>\n#include <utility>\n\n#ifndef SRC_VARIABLES_MULTIPART_MISSING_SEMICOLON_H_\n#define SRC_VARIABLES_MULTIPART_MISSING_SEMICOLON_H_\n\n#include \"src/variables/variable.h\"\n\nnamespace modsecurity {\n\nclass Transaction;\nnamespace variables {\n\n\nDEFINE_VARIABLE(MultipartMissingSemicolon, MULTIPART_MISSING_SEMICOLON,\n    m_variableMultipartMissingSemicolon)\n\n\n}  // namespace variables\n}  // namespace modsecurity\n\n#endif  // SRC_VARIABLES_MULTIPART_MISSING_SEMICOLON_H_\n"
  },
  {
    "path": "src/variables/multipart_name.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <iostream>\n#include <string>\n#include <vector>\n#include <list>\n#include <utility>\n\n#ifndef SRC_VARIABLES_MULTIPART_NAME_H_\n#define SRC_VARIABLES_MULTIPART_NAME_H_\n\n#include \"src/variables/variable.h\"\n\nnamespace modsecurity {\n\nclass Transaction;\nnamespace variables {\n\n\nDEFINE_VARIABLE_DICT(MultiPartName, MULTIPART_NAME, m_variableMultipartName)\n\n\n}  // namespace variables\n}  // namespace modsecurity\n\n#endif  // SRC_VARIABLES_MULTIPART_NAME_H_\n\n"
  },
  {
    "path": "src/variables/multipart_part_headers.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2022 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <iostream>\n#include <string>\n#include <vector>\n#include <list>\n#include <utility>\n\n#ifndef SRC_VARIABLES_MULTIPART_PART_HEADERS_H_\n#define SRC_VARIABLES_MULTIPART_PART_HEADERS_H_\n\n#include \"src/variables/variable.h\"\n\nnamespace modsecurity {\n\nclass Transaction;\nnamespace variables {\n\n\nDEFINE_VARIABLE_DICT(MultipartPartHeaders, MULTIPART_PART_HEADERS,\n    m_variableMultipartPartHeaders)\n\n\n}  // namespace variables\n}  // namespace modsecurity\n\n#endif  // SRC_VARIABLES_MULTIPART_PART_HEADERS_H_\n\n"
  },
  {
    "path": "src/variables/multipart_strict_error.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <iostream>\n#include <string>\n#include <vector>\n#include <list>\n#include <utility>\n\n#ifndef SRC_VARIABLES_MULTIPART_STRICT_ERROR_H_\n#define SRC_VARIABLES_MULTIPART_STRICT_ERROR_H_\n\n#include \"src/variables/variable.h\"\n\nnamespace modsecurity {\n\nclass Transaction;\nnamespace variables {\n\n\nDEFINE_VARIABLE(MultipartStrictError, MULTIPART_STRICT_ERROR,\n    m_variableMultipartStrictError)\n\n\n}  // namespace variables\n}  // namespace modsecurity\n\n#endif  // SRC_VARIABLES_MULTIPART_STRICT_ERROR_H_\n"
  },
  {
    "path": "src/variables/multipart_unmatched_boundary.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <iostream>\n#include <string>\n#include <vector>\n#include <list>\n#include <utility>\n\n#ifndef SRC_VARIABLES_MULTIPART_UNMATCHED_BOUNDARY_H_\n#define SRC_VARIABLES_MULTIPART_UNMATCHED_BOUNDARY_H_\n\n#include \"src/variables/variable.h\"\n\nnamespace modsecurity {\n\nclass Transaction;\nnamespace variables {\n\n\nDEFINE_VARIABLE(MultipartUnmatchedBoundary, MULTIPART_UNMATCHED_BOUNDARY,\n    m_variableMultipartUnmatchedBoundary)\n\n\n}  // namespace variables\n}  // namespace modsecurity\n\n#endif  // SRC_VARIABLES_MULTIPART_UNMATCHED_BOUNDARY_H_\n"
  },
  {
    "path": "src/variables/outbound_data_error.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <iostream>\n#include <string>\n#include <vector>\n#include <list>\n#include <utility>\n\n#ifndef SRC_VARIABLES_OUTBOUND_DATA_ERROR_H_\n#define SRC_VARIABLES_OUTBOUND_DATA_ERROR_H_\n\n#include \"src/variables/variable.h\"\n\nnamespace modsecurity {\n\nclass Transaction;\nnamespace variables {\n\n\nDEFINE_VARIABLE(OutboundDataError, OUTBOUND_DATA_ERROR,\n    m_variableOutboundDataError)\n\n\n}  // namespace variables\n}  // namespace modsecurity\n\n#endif  // SRC_VARIABLES_OUTBOUND_DATA_ERROR_H_\n"
  },
  {
    "path": "src/variables/path_info.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <iostream>\n#include <string>\n#include <vector>\n#include <list>\n#include <utility>\n\n#ifndef SRC_VARIABLES_PATH_INFO_H_\n#define SRC_VARIABLES_PATH_INFO_H_\n\n#include \"src/variables/variable.h\"\n\nnamespace modsecurity {\n\nclass Transaction;\nnamespace variables {\n\n\nDEFINE_VARIABLE(PathInfo, PATH_INFO, m_variablePathInfo)\n\n\n}  // namespace variables\n}  // namespace modsecurity\n\n#endif  // SRC_VARIABLES_PATH_INFO_H_\n"
  },
  {
    "path": "src/variables/query_string.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <iostream>\n#include <string>\n#include <vector>\n#include <list>\n#include <utility>\n\n#ifndef SRC_VARIABLES_QUERY_STRING_H_\n#define SRC_VARIABLES_QUERY_STRING_H_\n\n#include \"src/variables/variable.h\"\n\nnamespace modsecurity {\n\nclass Transaction;\nnamespace variables {\n\n\nDEFINE_VARIABLE(QueryString, QUERY_STRING, m_variableQueryString)\n\n\n}  // namespace variables\n}  // namespace modsecurity\n\n#endif  // SRC_VARIABLES_QUERY_STRING_H_\n"
  },
  {
    "path": "src/variables/remote_addr.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <iostream>\n#include <string>\n#include <vector>\n#include <list>\n#include <utility>\n\n#ifndef SRC_VARIABLES_REMOTE_ADDR_H_\n#define SRC_VARIABLES_REMOTE_ADDR_H_\n\n#include \"src/variables/variable.h\"\n\nnamespace modsecurity {\n\nclass Transaction;\nnamespace variables {\n\n\nDEFINE_VARIABLE(RemoteAddr, REMOTE_ADDR, m_variableRemoteAddr)\n\n\n}  // namespace variables\n}  // namespace modsecurity\n\n#endif  // SRC_VARIABLES_REMOTE_ADDR_H_\n"
  },
  {
    "path": "src/variables/remote_host.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <iostream>\n#include <string>\n#include <vector>\n#include <list>\n#include <utility>\n\n#ifndef SRC_VARIABLES_REMOTE_HOST_H_\n#define SRC_VARIABLES_REMOTE_HOST_H_\n\n#include \"src/variables/variable.h\"\n\nnamespace modsecurity {\n\nclass Transaction;\nnamespace variables {\n\n\nDEFINE_VARIABLE(RemoteHost, REMOTE_HOST, m_variableRemoteHost)\n\n\n}  // namespace variables\n}  // namespace modsecurity\n\n#endif  // SRC_VARIABLES_REMOTE_HOST_H_\n"
  },
  {
    "path": "src/variables/remote_port.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <iostream>\n#include <string>\n#include <vector>\n#include <list>\n#include <utility>\n\n#ifndef SRC_VARIABLES_REMOTE_PORT_H_\n#define SRC_VARIABLES_REMOTE_PORT_H_\n\n#include \"src/variables/variable.h\"\n\nnamespace modsecurity {\n\nclass Transaction;\nnamespace variables {\n\n\nDEFINE_VARIABLE(RemotePort, REMOTE_PORT, m_variableRemotePort)\n\n\n}  // namespace variables\n}  // namespace modsecurity\n\n#endif  // SRC_VARIABLES_REMOTE_PORT_H_\n"
  },
  {
    "path": "src/variables/remote_user.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2023 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"src/variables/remote_user.h\"\n\n#include <time.h>\n#include <stdio.h>\n#include <string.h>\n#include <sys/types.h>\n#include <sys/stat.h>\n#include <fcntl.h>\n\n#include <iostream>\n#include <string>\n#include <vector>\n#include <list>\n#include <utility>\n#include <memory>\n\n#include \"modsecurity/transaction.h\"\n#include \"src/utils/base64.h\"\n\nnamespace modsecurity {\nnamespace variables {\n\n\nvoid RemoteUser::evaluate(Transaction *transaction,\n    RuleWithActions *rule,\n    std::vector<const VariableValue *> *l) {\n    std::vector<const VariableValue *> l2;\n\n    transaction->m_variableRequestHeaders.resolve(\"authorization\", &l2);\n\n    if (!l2.empty()) {\n        const auto *v = l2[0];\n\n        const auto &header = v->getValue();\n\n        std::string base64;\n\n        if (header.compare(0, 6, \"Basic \") == 0) {\n            base64 = std::string(header, 6, header.length());\n        }\n\n        base64 = Utils::Base64::decode(base64);\n\n        if (const auto pos{base64.find(\":\")}; pos != std::string::npos) {\n            transaction->m_variableRemoteUser.assign(std::string(base64, 0, pos));\n\n            auto var = std::make_unique<VariableValue>(&v->getKeyWithCollection(),\n                &transaction->m_variableRemoteUser);\n\n            var->reserveOrigin(v->getOrigin().size());\n            for (const auto &i : v->getOrigin()) {\n                var->addOrigin(i);\n            }\n            l->push_back(var.release());\n        }\n\n        for (auto &a : l2) {\n            delete a;\n        }\n    }\n}\n\n\n}  // namespace variables\n}  // namespace modsecurity\n"
  },
  {
    "path": "src/variables/remote_user.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <iostream>\n#include <string>\n#include <vector>\n#include <list>\n#include <utility>\n\n#ifndef SRC_VARIABLES_REMOTE_USER_H_\n#define SRC_VARIABLES_REMOTE_USER_H_\n\n#include \"src/variables/variable.h\"\n\nnamespace modsecurity {\n\nclass Transaction;\nnamespace variables {\n\n\nclass RemoteUser : public Variable {\n public:\n    explicit RemoteUser(const std::string &_name)\n        : Variable(_name),\n        m_retName(\"REMOTE_USER\") { }\n\n    void evaluate(Transaction *transaction,\n        RuleWithActions *rule,\n        std::vector<const VariableValue *> *l) override;\n    std::string m_retName;\n};\n\n\n}  // namespace variables\n}  // namespace modsecurity\n\n#endif  // SRC_VARIABLES_REMOTE_USER_H_\n\n"
  },
  {
    "path": "src/variables/reqbody_error.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <iostream>\n#include <string>\n#include <vector>\n#include <list>\n#include <utility>\n\n#ifndef SRC_VARIABLES_REQBODY_ERROR_H_\n#define SRC_VARIABLES_REQBODY_ERROR_H_\n\n#include \"src/variables/variable.h\"\n\nnamespace modsecurity {\n\nclass Transaction;\nnamespace variables {\n\n\nDEFINE_VARIABLE(ReqbodyError, REQBODY_ERROR, m_variableReqbodyError)\n\n\n}  // namespace variables\n}  // namespace modsecurity\n\n#endif  // SRC_VARIABLES_REQBODY_ERROR_H_\n"
  },
  {
    "path": "src/variables/reqbody_error_msg.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <iostream>\n#include <string>\n#include <vector>\n#include <list>\n#include <utility>\n\n#ifndef SRC_VARIABLES_REQBODY_ERROR_MSG_H_\n#define SRC_VARIABLES_REQBODY_ERROR_MSG_H_\n\n#include \"src/variables/variable.h\"\n\nnamespace modsecurity {\n\nclass Transaction;\nnamespace variables {\n\n\nDEFINE_VARIABLE(ReqbodyErrorMsg, REQBODY_ERROR_MSG, m_variableReqbodyErrorMsg)\n\n\n}  // namespace variables\n}  // namespace modsecurity\n\n#endif  // SRC_VARIABLES_REQBODY_ERROR_MSG_H_\n"
  },
  {
    "path": "src/variables/reqbody_processor.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <iostream>\n#include <string>\n#include <vector>\n#include <list>\n#include <utility>\n\n#ifndef SRC_VARIABLES_REQBODY_PROCESSOR_H_\n#define SRC_VARIABLES_REQBODY_PROCESSOR_H_\n\n#include \"src/variables/variable.h\"\n\nnamespace modsecurity {\n\nclass Transaction;\nnamespace variables {\n\n\nDEFINE_VARIABLE(ReqbodyProcessor, REQBODY_PROCESSOR, m_variableReqbodyProcessor)\n\n\n}  // namespace variables\n}  // namespace modsecurity\n\n#endif  // SRC_VARIABLES_REQBODY_PROCESSOR_H_\n"
  },
  {
    "path": "src/variables/reqbody_processor_error.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <iostream>\n#include <string>\n#include <vector>\n#include <list>\n#include <utility>\n\n#ifndef SRC_VARIABLES_REQBODY_PROCESSOR_ERROR_H_\n#define SRC_VARIABLES_REQBODY_PROCESSOR_ERROR_H_\n\n#include \"src/variables/variable.h\"\n\nnamespace modsecurity {\n\nclass Transaction;\nnamespace variables {\n\n\nDEFINE_VARIABLE(ReqbodyProcessorError, REQBODY_PROCESSOR_ERROR,\n    m_variableReqbodyProcessorError)\n\n\n}  // namespace variables\n}  // namespace modsecurity\n\n#endif  // SRC_VARIABLES_REQBODY_PROCESSOR_ERROR_H_\n"
  },
  {
    "path": "src/variables/reqbody_processor_error_msg.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <iostream>\n#include <string>\n#include <vector>\n#include <list>\n#include <utility>\n\n#ifndef SRC_VARIABLES_REQBODY_PROCESSOR_ERROR_MSG_H_\n#define SRC_VARIABLES_REQBODY_PROCESSOR_ERROR_MSG_H_\n\n#include \"src/variables/variable.h\"\n\nnamespace modsecurity {\n\nclass Transaction;\nnamespace variables {\n\n\nDEFINE_VARIABLE(ReqbodyProcessorErrorMsg, PROCESSOR_ERROR_MSG,\n    m_variableReqbodyProcessorErrorMsg)\n\n\n}  // namespace variables\n}  // namespace modsecurity\n\n#endif  // SRC_VARIABLES_REQBODY_PROCESSOR_ERROR_MSG_H_\n"
  },
  {
    "path": "src/variables/request_base_name.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <iostream>\n#include <string>\n#include <vector>\n#include <list>\n#include <utility>\n\n#ifndef SRC_VARIABLES_REQUEST_BASE_NAME_H_\n#define SRC_VARIABLES_REQUEST_BASE_NAME_H_\n\n#include \"src/variables/variable.h\"\n\nnamespace modsecurity {\n\nclass Transaction;\nnamespace variables {\n\n\nDEFINE_VARIABLE(RequestBasename, REQUEST_BASENAME, m_variableRequestBasename)\n\n\n}  // namespace variables\n}  // namespace modsecurity\n\n#endif  // SRC_VARIABLES_REQUEST_BASE_NAME_H_\n"
  },
  {
    "path": "src/variables/request_body.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <iostream>\n#include <string>\n#include <vector>\n#include <list>\n#include <utility>\n\n#ifndef SRC_VARIABLES_REQUEST_BODY_H_\n#define SRC_VARIABLES_REQUEST_BODY_H_\n\n#include \"src/variables/variable.h\"\n\nnamespace modsecurity {\n\nclass Transaction;\nnamespace variables {\n\n\nDEFINE_VARIABLE(RequestBody, REQUEST_BODY, m_variableRequestBody)\n\n\n}  // namespace variables\n}  // namespace modsecurity\n\n#endif  // SRC_VARIABLES_REQUEST_BODY_H_\n"
  },
  {
    "path": "src/variables/request_body_length.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <iostream>\n#include <string>\n#include <vector>\n#include <list>\n#include <utility>\n\n#ifndef SRC_VARIABLES_REQUEST_BODY_LENGTH_H_\n#define SRC_VARIABLES_REQUEST_BODY_LENGTH_H_\n\n#include \"src/variables/variable.h\"\n\nnamespace modsecurity {\n\nclass Transaction;\nnamespace variables {\n\n\nDEFINE_VARIABLE(RequestBodyLength, REQUEST_BODY_LENGTH,\n    m_variableRequestBodyLength)\n\n\n}  // namespace variables\n}  // namespace modsecurity\n\n#endif  // SRC_VARIABLES_REQUEST_BODY_LENGTH_H_\n"
  },
  {
    "path": "src/variables/request_cookies.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <iostream>\n#include <string>\n#include <vector>\n#include <list>\n#include <utility>\n\n#ifndef SRC_VARIABLES_REQUEST_COOKIES_H_\n#define SRC_VARIABLES_REQUEST_COOKIES_H_\n\n#include \"src/variables/variable.h\"\n\nnamespace modsecurity {\n\nclass Transaction;\nnamespace variables {\n\n\nDEFINE_VARIABLE_DICT(RequestCookies, REQUEST_COOKIES, m_variableRequestCookies)\n\n\n}  // namespace variables\n}  // namespace modsecurity\n\n#endif  // SRC_VARIABLES_REQUEST_COOKIES_H_\n\n"
  },
  {
    "path": "src/variables/request_cookies_names.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <iostream>\n#include <string>\n#include <vector>\n#include <list>\n#include <utility>\n\n#ifndef SRC_VARIABLES_REQUEST_COOKIES_NAMES_H_\n#define SRC_VARIABLES_REQUEST_COOKIES_NAMES_H_\n\n#include \"src/variables/variable.h\"\n\nnamespace modsecurity {\n\nclass Transaction;\nnamespace variables {\n\n\nDEFINE_VARIABLE_DICT(RequestCookiesNames, REQUEST_COOKIES_NAMES,\n    m_variableRequestCookiesNames)\n\n\n}  // namespace variables\n}  // namespace modsecurity\n\n#endif  // SRC_VARIABLES_REQUEST_COOKIES_NAMES_H_\n\n"
  },
  {
    "path": "src/variables/request_file_name.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <iostream>\n#include <string>\n#include <vector>\n#include <list>\n#include <utility>\n\n#ifndef SRC_VARIABLES_REQUEST_FILE_NAME_H_\n#define SRC_VARIABLES_REQUEST_FILE_NAME_H_\n\n#include \"src/variables/variable.h\"\n\nnamespace modsecurity {\n\nclass Transaction;\nnamespace variables {\n\n\nDEFINE_VARIABLE(RequestFilename, REQUEST_FILENAME, m_variableRequestFilename)\n\n\n}  // namespace variables\n}  // namespace modsecurity\n\n#endif  // SRC_VARIABLES_REQUEST_FILE_NAME_H_\n"
  },
  {
    "path": "src/variables/request_headers.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <iostream>\n#include <string>\n#include <vector>\n#include <list>\n#include <utility>\n\n#ifndef SRC_VARIABLES_REQUEST_HEADERS_H_\n#define SRC_VARIABLES_REQUEST_HEADERS_H_\n\n#include \"src/variables/variable.h\"\n\nnamespace modsecurity {\n\nclass Transaction;\nnamespace variables {\n\n\nDEFINE_VARIABLE_DICT(RequestHeaders, REQUEST_HEADERS, m_variableRequestHeaders)\n\n\n}  // namespace variables\n}  // namespace modsecurity\n\n#endif  // SRC_VARIABLES_REQUEST_HEADERS_H_\n\n"
  },
  {
    "path": "src/variables/request_headers_names.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <iostream>\n#include <string>\n#include <vector>\n#include <list>\n#include <utility>\n\n#ifndef SRC_VARIABLES_REQUEST_HEADERS_NAMES_H_\n#define SRC_VARIABLES_REQUEST_HEADERS_NAMES_H_\n\n#include \"src/variables/variable.h\"\n\nnamespace modsecurity {\n\nclass Transaction;\nnamespace variables {\n\n\nDEFINE_VARIABLE_DICT(RequestHeadersNames, REQUEST_HEADERS_NAMES,\n    m_variableRequestHeadersNames)\n\n\n}  // namespace variables\n}  // namespace modsecurity\n\n#endif  // SRC_VARIABLES_REQUEST_HEADERS_NAMES_H_\n"
  },
  {
    "path": "src/variables/request_line.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <iostream>\n#include <string>\n#include <vector>\n#include <list>\n#include <utility>\n\n#ifndef SRC_VARIABLES_REQUEST_LINE_H_\n#define SRC_VARIABLES_REQUEST_LINE_H_\n\n#include \"src/variables/variable.h\"\n\nnamespace modsecurity {\n\nclass Transaction;\nnamespace variables {\n\n\nDEFINE_VARIABLE(RequestLine, REQUEST_LINE, m_variableRequestLine)\n\n\n}  // namespace variables\n}  // namespace modsecurity\n\n#endif  // SRC_VARIABLES_REQUEST_LINE_H_\n"
  },
  {
    "path": "src/variables/request_method.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <iostream>\n#include <string>\n#include <vector>\n#include <list>\n#include <utility>\n\n#ifndef SRC_VARIABLES_REQUEST_METHOD_H_\n#define SRC_VARIABLES_REQUEST_METHOD_H_\n\n#include \"src/variables/variable.h\"\n\nnamespace modsecurity {\n\nclass Transaction;\nnamespace variables {\n\n\nDEFINE_VARIABLE(RequestMethod, REQUEST_METHOD, m_variableRequestMethod)\n\n\n}  // namespace variables\n}  // namespace modsecurity\n\n#endif  // SRC_VARIABLES_REQUEST_METHOD_H_\n"
  },
  {
    "path": "src/variables/request_protocol.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <iostream>\n#include <string>\n#include <vector>\n#include <list>\n#include <utility>\n\n#ifndef SRC_VARIABLES_REQUEST_PROTOCOL_H_\n#define SRC_VARIABLES_REQUEST_PROTOCOL_H_\n\n#include \"src/variables/variable.h\"\n\nnamespace modsecurity {\n\nclass Transaction;\nnamespace variables {\n\n\nDEFINE_VARIABLE(RequestProtocol, REQUEST_PROTOCOL, m_variableRequestProtocol)\n\n\n}  // namespace variables\n}  // namespace modsecurity\n\n#endif  // SRC_VARIABLES_REQUEST_PROTOCOL_H_\n"
  },
  {
    "path": "src/variables/request_uri.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <iostream>\n#include <string>\n#include <vector>\n#include <list>\n#include <utility>\n\n#ifndef SRC_VARIABLES_REQUEST_URI_H_\n#define SRC_VARIABLES_REQUEST_URI_H_\n\n#include \"src/variables/variable.h\"\n\nnamespace modsecurity {\n\nclass Transaction;\nnamespace variables {\n\n\nDEFINE_VARIABLE(RequestURI, REQUEST_URI, m_variableRequestURI)\n\n\n}  // namespace variables\n}  // namespace modsecurity\n\n#endif  // SRC_VARIABLES_REQUEST_URI_H_\n"
  },
  {
    "path": "src/variables/request_uri_raw.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <iostream>\n#include <string>\n#include <vector>\n#include <list>\n#include <utility>\n\n#ifndef SRC_VARIABLES_REQUEST_URI_RAW_H_\n#define SRC_VARIABLES_REQUEST_URI_RAW_H_\n\n#include \"src/variables/variable.h\"\n\nnamespace modsecurity {\n\nclass Transaction;\nnamespace variables {\n\n\nDEFINE_VARIABLE(RequestURIRaw, REQUEST_URI_RAW, m_variableRequestURIRaw)\n\n\n}  // namespace variables\n}  // namespace modsecurity\n\n#endif  // SRC_VARIABLES_REQUEST_URI_RAW_H_\n"
  },
  {
    "path": "src/variables/resource.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2023 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <list>\n#include <memory>\n#include <string>\n#include <utility>\n#include <vector>\n\n#ifndef SRC_VARIABLES_RESOURCE_H_\n#define SRC_VARIABLES_RESOURCE_H_\n\n#include \"src/variables/variable.h\"\n#include \"src/run_time_string.h\"\n\nnamespace modsecurity {\n\nclass Transaction;\nnamespace variables {\n\n\nclass Resource_DictElement : public Variable {\n public:\n    explicit Resource_DictElement(const std::string &dictElement)\n        : Variable(\"RESOURCE:\" + dictElement),\n        m_dictElement(\"RESOURCE:\" + dictElement) { }\n\n    void evaluate(Transaction *t,\n        RuleWithActions *rule,\n        std::vector<const VariableValue *> *l) override {\n        t->m_collections.m_resource_collection->resolveMultiMatches(\n            m_name, t->m_collections.m_resource_collection_key,\n            t->m_rules->m_secWebAppId.m_value, l, m_keyExclusion);\n    }\n\n    std::string m_dictElement;\n};\n\n\nclass Resource_NoDictElement : public Variable {\n public:\n    Resource_NoDictElement()\n        : Variable(\"RESOURCE\") { }\n\n    void evaluate(Transaction *t,\n        RuleWithActions *rule,\n        std::vector<const VariableValue *> *l) override {\n        t->m_collections.m_resource_collection->resolveMultiMatches(m_name,\n            t->m_collections.m_resource_collection_key,\n            t->m_rules->m_secWebAppId.m_value, l, m_keyExclusion);\n    }\n};\n\n\nclass Resource_DictElementRegexp : public VariableRegex {\n public:\n    explicit Resource_DictElementRegexp(const std::string &dictElement)\n        : VariableRegex(\"RESOURCE:\", dictElement),\n        m_dictElement(dictElement) { }\n\n    void evaluate(Transaction *t,\n        RuleWithActions *rule,\n        std::vector<const VariableValue *> *l) override {\n        t->m_collections.m_resource_collection->resolveRegularExpression(\n            m_dictElement, t->m_collections.m_resource_collection_key,\n            t->m_rules->m_secWebAppId.m_value, l, m_keyExclusion);\n    }\n\n    std::string m_dictElement;\n};\n\n\nclass Resource_DynamicElement : public Variable {\n public:\n    explicit Resource_DynamicElement(std::unique_ptr<RunTimeString> dictElement)\n        : Variable(\"RESOURCE:dynamic\"),\n        m_string(std::move(dictElement)) { }\n\n    void evaluate(Transaction *t,\n        RuleWithActions *rule,\n        std::vector<const VariableValue *> *l) override {\n        std::string string = m_string->evaluate(t);\n        t->m_collections.m_resource_collection->resolveMultiMatches(\n            string,\n            t->m_collections.m_resource_collection_key,\n            t->m_rules->m_secWebAppId.m_value, l, m_keyExclusion);\n    }\n\n    static void del(Transaction *t, const std::string &k) {\n        t->m_collections.m_resource_collection->del(k,\n            t->m_collections.m_resource_collection_key,\n            t->m_rules->m_secWebAppId.m_value);\n    }\n\n    static void setExpiry(Transaction *t, const std::string &k, int32_t expiry_seconds) {\n        t->m_collections.m_resource_collection->setExpiry(k,\n            t->m_collections.m_resource_collection_key,\n            t->m_rules->m_secWebAppId.m_value, expiry_seconds);\n    }\n\n\n    static void storeOrUpdateFirst(Transaction *t, const std::string &var,\n        const std::string &value) {\n        t->m_collections.m_resource_collection->storeOrUpdateFirst(\n            var, t->m_collections.m_resource_collection_key,\n            t->m_rules->m_secWebAppId.m_value, value);\n    }\n\n    std::unique_ptr<RunTimeString> m_string;\n};\n\n\n}  // namespace variables\n}  // namespace modsecurity\n\n#endif  // SRC_VARIABLES_RESOURCE_H_\n"
  },
  {
    "path": "src/variables/response_body.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <iostream>\n#include <string>\n#include <vector>\n#include <list>\n#include <utility>\n\n#ifndef SRC_VARIABLES_RESPONSE_BODY_H_\n#define SRC_VARIABLES_RESPONSE_BODY_H_\n\n#include \"src/variables/variable.h\"\n\nnamespace modsecurity {\n\nclass Transaction;\nnamespace variables {\n\n\nDEFINE_VARIABLE(ResponseBody, RESPONSE_BODY, m_variableResponseBody)\n\n\n}  // namespace variables\n}  // namespace modsecurity\n\n#endif  // SRC_VARIABLES_RESPONSE_BODY_H_\n"
  },
  {
    "path": "src/variables/response_content_length.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <iostream>\n#include <string>\n#include <vector>\n#include <list>\n#include <utility>\n\n#ifndef SRC_VARIABLES_RESPONSE_CONTENT_LENGTH_H_\n#define SRC_VARIABLES_RESPONSE_CONTENT_LENGTH_H_\n\n#include \"src/variables/variable.h\"\n\nnamespace modsecurity {\n\nclass Transaction;\nnamespace variables {\n\n\nDEFINE_VARIABLE(ResponseContentLength, RESPONSE_CONTENT_LENGTH,\n    m_variableResponseContentLength)\n\n\n}  // namespace variables\n}  // namespace modsecurity\n\n#endif  // SRC_VARIABLES_RESPONSE_CONTENT_LENGTH_H_\n"
  },
  {
    "path": "src/variables/response_content_type.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <iostream>\n#include <string>\n#include <vector>\n#include <list>\n#include <utility>\n\n#ifndef SRC_VARIABLES_RESPONSE_CONTENT_TYPE_H_\n#define SRC_VARIABLES_RESPONSE_CONTENT_TYPE_H_\n\n#include \"src/variables/variable.h\"\n\nnamespace modsecurity {\n\nclass Transaction;\nnamespace variables {\n\n\nDEFINE_VARIABLE(ResponseContentType, RESPONSE_CONTENT_TYPE,\n    m_variableResponseContentType)\n\n\n}  // namespace variables\n}  // namespace modsecurity\n\n#endif  // SRC_VARIABLES_RESPONSE_CONTENT_TYPE_H_\n"
  },
  {
    "path": "src/variables/response_headers.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <iostream>\n#include <string>\n#include <vector>\n#include <list>\n#include <utility>\n\n#ifndef SRC_VARIABLES_RESPONSE_HEADERS_H_\n#define SRC_VARIABLES_RESPONSE_HEADERS_H_\n\n#include \"src/variables/variable.h\"\n\nnamespace modsecurity {\n\nclass Transaction;\nnamespace variables {\n\n\nDEFINE_VARIABLE_DICT(ResponseHeaders, RESPONSE_HEADERS,\n    m_variableResponseHeaders)\n\n\n}  // namespace variables\n}  // namespace modsecurity\n\n#endif  // SRC_VARIABLES_RESPONSE_HEADERS_H_\n\n"
  },
  {
    "path": "src/variables/response_headers_names.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <iostream>\n#include <string>\n#include <vector>\n#include <list>\n#include <utility>\n\n#ifndef SRC_VARIABLES_RESPONSE_HEADERS_NAMES_H_\n#define SRC_VARIABLES_RESPONSE_HEADERS_NAMES_H_\n\n#include \"src/variables/variable.h\"\n\nnamespace modsecurity {\n\nclass Transaction;\nnamespace variables {\n\n\nDEFINE_VARIABLE_DICT(ResponseHeadersNames, RESPONSE_HEADERS_NAMES,\n    m_variableResponseHeadersNames)\n\n\n}  // namespace variables\n}  // namespace modsecurity\n\n#endif  // SRC_VARIABLES_RESPONSE_HEADERS_NAMES_H_\n"
  },
  {
    "path": "src/variables/response_protocol.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <iostream>\n#include <string>\n#include <vector>\n#include <list>\n#include <utility>\n\n#ifndef SRC_VARIABLES_RESPONSE_PROTOCOL_H_\n#define SRC_VARIABLES_RESPONSE_PROTOCOL_H_\n\n#include \"src/variables/variable.h\"\n\nnamespace modsecurity {\n\nclass Transaction;\nnamespace variables {\n\n\nDEFINE_VARIABLE(ResponseProtocol, RESPONSE_PROTOCOL, m_variableResponseProtocol)\n\n\n}  // namespace variables\n}  // namespace modsecurity\n\n#endif  // SRC_VARIABLES_RESPONSE_PROTOCOL_H_\n"
  },
  {
    "path": "src/variables/response_status.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <iostream>\n#include <string>\n#include <vector>\n#include <list>\n#include <utility>\n\n#ifndef SRC_VARIABLES_RESPONSE_STATUS_H_\n#define SRC_VARIABLES_RESPONSE_STATUS_H_\n\n#include \"src/variables/variable.h\"\n\nnamespace modsecurity {\n\nclass Transaction;\nnamespace variables {\n\n\nDEFINE_VARIABLE(ResponseStatus, RESPONSE_STATUS, m_variableResponseStatus)\n\n\n}  // namespace variables\n}  // namespace modsecurity\n\n#endif  // SRC_VARIABLES_RESPONSE_STATUS_H_\n"
  },
  {
    "path": "src/variables/rule.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"src/variables/rule.h\"\n\n\nnamespace modsecurity {\nnamespace variables {\n\n\nconst std::string Rule_DictElement::m_rule(\"RULE\");\nconst std::string Rule_DictElement::m_rule_id(\"id\");\nconst std::string Rule_DictElement::m_rule_rev(\"rev\");\nconst std::string Rule_DictElement::m_rule_severity(\"severity\");\nconst std::string Rule_DictElement::m_rule_logdata(\"logdata\");\nconst std::string Rule_DictElement::m_rule_msg(\"msg\");\n\n\n}  // namespace variables\n}  // namespace modsecurity\n"
  },
  {
    "path": "src/variables/rule.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <string>\n#include <vector>\n#include <list>\n\n#ifndef SRC_VARIABLES_RULE_H_\n#define SRC_VARIABLES_RULE_H_\n\n#include \"src/variables/variable.h\"\n#include \"src/actions/severity.h\"\n#include \"src/actions/log_data.h\"\n#include \"src/actions/msg.h\"\n\n\nnamespace modsecurity {\n\nclass Transaction;\nnamespace variables {\n\n\nclass Rule_DictElement : public VariableDictElement { \\\n public:\n    explicit Rule_DictElement(const std::string &dictElement)\n        : VariableDictElement(m_rule, dictElement) { }\n\n    static void id(Transaction *t,\n        const RuleWithActions *rule,\n        std::vector<const VariableValue *> *l) {\n        const RuleWithActions *r = rule;\n\n        while (r && r->m_ruleId == 0) {\n            r = r->m_chainedRuleParent;\n        }\n\n        if (!r || r->m_ruleId == 0) {\n            return;\n        }\n\n        addVariableOrigin(m_rule_id, std::to_string(r->m_ruleId), l);\n    }\n\n\n    static void rev(Transaction *t,\n        RuleWithActions *rule,\n        std::vector<const VariableValue *> *l) {\n        RuleWithActions *r = rule;\n\n        while (r && r->m_rev.empty()) {\n            r = r->m_chainedRuleParent;\n        }\n\n        if (!r) {\n            return;\n        }\n\n        addVariableOrigin(m_rule_rev, r->m_rev, l);\n    }\n\n\n    static void severity(Transaction *t,\n        const RuleWithActions *rule,\n        std::vector<const VariableValue *> *l) {\n        const RuleWithActions *r = rule;\n\n        while (r && !r->hasSeverity()) {\n            r = r->m_chainedRuleParent;\n        }\n\n        if (r && r->hasSeverity()) {\n            addVariableOrigin(m_rule_severity, std::to_string(r->severity()), l);\n        }\n    }\n\n\n    static void logData(Transaction *t,\n        RuleWithActions *rule,\n        std::vector<const VariableValue *> *l) {\n        RuleWithActions *r = rule;\n\n        while (r && !r->hasLogData()) {\n            r = r->m_chainedRuleParent;\n        }\n\n        if (r && r->hasLogData()) {\n            addVariableOrigin(m_rule_logdata, r->logData(t), l);\n        }\n    }\n\n    static void msg(Transaction *t,\n        RuleWithActions *rule,\n        std::vector<const VariableValue *> *l) {\n        RuleWithActions *r = rule;\n\n        while (r && !r->hasMsg()) {\n            r = r->m_chainedRuleParent;\n        }\n\n        if (r && r->hasMsg()) {\n            addVariableOrigin(m_rule_msg, r->msg(t), l);\n        }\n    }\n\n    void evaluate(Transaction *t,\n        RuleWithActions *rule,\n        std::vector<const VariableValue *> *l) override {\n        if (m_dictElement == m_rule_id) {\n            id(t, rule, l);\n            return;\n        }\n        if (rule && m_dictElement == m_rule_rev) {\n            rev(t, rule, l);\n            return;\n        }\n        if (rule && m_dictElement == m_rule_severity) {\n            severity(t, rule, l);\n            return;\n        }\n        if (m_dictElement == m_rule_logdata) {\n            logData(t, rule, l);\n            return;\n        }\n        if (m_dictElement == m_rule_msg) {\n            msg(t, rule, l);\n            return;\n        }\n    }\n\n    static const std::string m_rule;\n    static const std::string m_rule_id;\n    static const std::string m_rule_rev;\n    static const std::string m_rule_severity;\n    static const std::string m_rule_logdata;\n    static const std::string m_rule_msg;\n\nprivate:\n\n    static inline void addVariableOrigin(const std::string &key,\n        const std::string &value,\n        std::vector<const VariableValue *> *l) {\n        auto var = new VariableValue(&m_rule, &key,\n            &value\n        );\n        var->addOrigin();\n        l->push_back(var);\n    }\n};\n\n\nclass Rule_DictElementRegexp : public VariableRegex {\n public:\n    explicit Rule_DictElementRegexp(const std::string &regex)\n        : VariableRegex(\"RULE\", regex) { }\n\n    void evaluate(Transaction *t,\n        RuleWithActions *rule,\n        std::vector<const VariableValue *> *l) override {\n        if (Utils::regex_search(\"id\", m_r) > 0) {\n            Rule_DictElement::id(t, rule, l);\n            return;\n        }\n        if (Utils::regex_search(\"rev\", m_r) > 0) {\n            Rule_DictElement::rev(t, rule, l);\n            return;\n        }\n        if (Utils::regex_search(\"severity\", m_r) > 0) {\n            Rule_DictElement::severity(t, rule, l);\n            return;\n        }\n        if (Utils::regex_search(\"logdata\", m_r) > 0) {\n            Rule_DictElement::logData(t, rule, l);\n            return;\n        }\n        if (Utils::regex_search(\"msg\", m_r) > 0) {\n            Rule_DictElement::msg(t, rule, l);\n            return;\n        }\n    }\n};\n\n\nclass Rule_NoDictElement : public Variable {\n public:\n    explicit Rule_NoDictElement()\n        : Variable(\"RULE\") { }\n\n    void evaluate(Transaction *t,\n        RuleWithActions *rule,\n        std::vector<const VariableValue *> *l) override {\n        Rule_DictElement::id(t, rule, l);\n        Rule_DictElement::rev(t, rule, l);\n        Rule_DictElement::severity(t, rule, l);\n        Rule_DictElement::logData(t, rule, l);\n        Rule_DictElement::msg(t, rule, l);\n    }\n};\n\n// DEFINE_VARIABLE_DICT(Rule, RULE, m_variableRule)\n\n\n}  // namespace variables\n}  // namespace modsecurity\n\n#endif  // SRC_VARIABLES_RULE_H_\n"
  },
  {
    "path": "src/variables/server_addr.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <iostream>\n#include <string>\n#include <vector>\n#include <list>\n#include <utility>\n\n#ifndef SRC_VARIABLES_SERVER_ADDR_H_\n#define SRC_VARIABLES_SERVER_ADDR_H_\n\n#include \"src/variables/variable.h\"\n\nnamespace modsecurity {\n\nclass Transaction;\nnamespace variables {\n\n\nDEFINE_VARIABLE(ServerAddr, SERVER_ADDR, m_variableServerAddr)\n\n\n}  // namespace variables\n}  // namespace modsecurity\n\n#endif  // SRC_VARIABLES_SERVER_ADDR_H_\n"
  },
  {
    "path": "src/variables/server_name.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <iostream>\n#include <string>\n#include <vector>\n#include <list>\n#include <utility>\n\n#ifndef SRC_VARIABLES_SERVER_NAME_H_\n#define SRC_VARIABLES_SERVER_NAME_H_\n\n#include \"src/variables/variable.h\"\n\nnamespace modsecurity {\n\nclass Transaction;\nnamespace variables {\n\n\nDEFINE_VARIABLE(ServerName, SERVER_NAME, m_variableServerName)\n\n\n}  // namespace variables\n}  // namespace modsecurity\n\n#endif  // SRC_VARIABLES_SERVER_NAME_H_\n"
  },
  {
    "path": "src/variables/server_port.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <iostream>\n#include <string>\n#include <vector>\n#include <list>\n#include <utility>\n\n#ifndef SRC_VARIABLES_SERVER_PORT_H_\n#define SRC_VARIABLES_SERVER_PORT_H_\n\n#include \"src/variables/variable.h\"\n\nnamespace modsecurity {\n\nclass Transaction;\nnamespace variables {\n\n\nDEFINE_VARIABLE(ServerPort, SERVER_PORT, m_variableServerPort)\n\n\n}  // namespace variables\n}  // namespace modsecurity\n\n#endif  // SRC_VARIABLES_SERVER_PORT_H_\n"
  },
  {
    "path": "src/variables/session.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2023 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <list>\n#include <memory>\n#include <string>\n#include <utility>\n#include <vector>\n\n#ifndef SRC_VARIABLES_SESSION_H_\n#define SRC_VARIABLES_SESSION_H_\n\n#include \"src/variables/variable.h\"\n#include \"src/run_time_string.h\"\n\nnamespace modsecurity {\n\nclass Transaction;\nnamespace variables {\n\n\nclass Session_DictElement : public Variable {\n public:\n    explicit Session_DictElement(const std::string &dictElement)\n        : Variable(\"SESSION:\" + dictElement),\n        m_dictElement(\"SESSION:\" + dictElement) { }\n\n    void evaluate(Transaction *t,\n        RuleWithActions *rule,\n        std::vector<const VariableValue *> *l) override {\n        t->m_collections.m_session_collection->resolveMultiMatches(\n            m_name, t->m_collections.m_session_collection_key,\n            t->m_rules->m_secWebAppId.m_value, l, m_keyExclusion);\n    }\n\n    std::string m_dictElement;\n};\n\n\nclass Session_NoDictElement : public Variable {\n public:\n    Session_NoDictElement()\n        : Variable(\"SESSION\") { }\n\n    void evaluate(Transaction *t,\n        RuleWithActions *rule,\n        std::vector<const VariableValue *> *l) override {\n        t->m_collections.m_session_collection->resolveMultiMatches(\"\",\n            t->m_collections.m_session_collection_key,\n            t->m_rules->m_secWebAppId.m_value, l, m_keyExclusion);\n    }\n};\n\n\nclass Session_DictElementRegexp : public VariableRegex {\n public:\n    explicit Session_DictElementRegexp(const std::string &dictElement)\n        : VariableRegex(\"SESSION\", dictElement),\n        m_dictElement(dictElement) { }\n\n    void evaluate(Transaction *t,\n        RuleWithActions *rule,\n        std::vector<const VariableValue *> *l) override {\n        t->m_collections.m_session_collection->resolveRegularExpression(\n            m_dictElement, t->m_collections.m_session_collection_key,\n            t->m_rules->m_secWebAppId.m_value, l, m_keyExclusion);\n    }\n\n    std::string m_dictElement;\n};\n\n\nclass Session_DynamicElement : public Variable {\n public:\n    explicit Session_DynamicElement(std::unique_ptr<RunTimeString> dictElement)\n        : Variable(\"SESSION:dynamic\"),\n        m_string(std::move(dictElement)) { }\n\n    void evaluate(Transaction *t,\n        RuleWithActions *rule,\n        std::vector<const VariableValue *> *l) override {\n        std::string string = m_string->evaluate(t);\n        t->m_collections.m_session_collection->resolveMultiMatches(\n            string,\n            t->m_collections.m_session_collection_key,\n            t->m_rules->m_secWebAppId.m_value, l, m_keyExclusion);\n    }\n\n    static void del(Transaction *t, const std::string &k) {\n        t->m_collections.m_session_collection->del(k,\n            t->m_collections.m_session_collection_key,\n            t->m_collections.m_ip_collection_key);\n    }\n\n    static void setExpiry(Transaction *t, const std::string &k, int32_t expiry_seconds) {\n        t->m_collections.m_session_collection->setExpiry(k,\n            t->m_collections.m_session_collection_key,\n            t->m_rules->m_secWebAppId.m_value, expiry_seconds);\n    }\n\n    static void storeOrUpdateFirst(Transaction *t, const std::string &var,\n        const std::string &value) {\n        t->m_collections.m_session_collection->storeOrUpdateFirst(\n            var, t->m_collections.m_session_collection_key,\n            t->m_rules->m_secWebAppId.m_value,\n            value);\n    }\n\n    std::unique_ptr<RunTimeString> m_string;\n};\n\n\n}  // namespace variables\n}  // namespace modsecurity\n\n#endif  // SRC_VARIABLES_SESSION_H_\n"
  },
  {
    "path": "src/variables/session_id.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <iostream>\n#include <string>\n#include <vector>\n#include <list>\n#include <utility>\n\n#ifndef SRC_VARIABLES_SESSION_ID_H_\n#define SRC_VARIABLES_SESSION_ID_H_\n\n#include \"src/variables/variable.h\"\n\nnamespace modsecurity {\n\nclass Transaction;\nnamespace variables {\n\nDEFINE_VARIABLE(SessionID, SESSIONID, m_variableSessionID)\n\n\n}  // namespace variables\n}  // namespace modsecurity\n\n#endif  // SRC_VARIABLES_SESSION_ID_H_\n"
  },
  {
    "path": "src/variables/status.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <iostream>\n#include <string>\n#include <vector>\n#include <list>\n#include <utility>\n\n#ifndef SRC_VARIABLES_STATUS_H_\n#define SRC_VARIABLES_STATUS_H_\n\n#include \"src/variables/variable.h\"\n\nnamespace modsecurity {\n\nclass Transaction;\nnamespace variables {\n\n\nDEFINE_VARIABLE(Status, STATUS, m_variableResponseStatus)\n\n\n}  // namespace variables\n}  // namespace modsecurity\n\n#endif  // SRC_VARIABLES_STATUS_H_\n"
  },
  {
    "path": "src/variables/time.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"src/variables/time.h\"\n\n#include <time.h>\n#include <stdio.h>\n#include <string.h>\n#include <sys/types.h>\n#include <sys/stat.h>\n#include <fcntl.h>\n\n#include <iostream>\n#include <string>\n#include <vector>\n#include <list>\n#include <utility>\n\n#include \"modsecurity/transaction.h\"\n\n#ifdef WIN32\n#include \"src/compat/msvc.h\"\n#endif\n\nnamespace modsecurity {\nnamespace variables {\n\nvoid Time::evaluate(Transaction *transaction,\n    RuleWithActions *rule,\n    std::vector<const VariableValue *> *l) {\n    time_t timer;\n    time(&timer);\n\n    struct tm timeinfo;\n    localtime_r(&timer, &timeinfo);\n\n    char tstr[std::size(\"hh:mm:ss\")];\n    strftime(tstr, 200, \"%H:%M:%S\", &timeinfo);\n\n    transaction->m_variableTime.assign(tstr);\n    l->push_back(new VariableValue(&m_retName,\n        &transaction->m_variableTime));\n}\n\n\n}  // namespace variables\n}  // namespace modsecurity\n"
  },
  {
    "path": "src/variables/time.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <iostream>\n#include <string>\n#include <vector>\n#include <list>\n#include <utility>\n\n#ifndef SRC_VARIABLES_TIME_H_\n#define SRC_VARIABLES_TIME_H_\n\n#include \"src/variables/variable.h\"\n\nnamespace modsecurity {\n\nclass Transaction;\nnamespace variables {\n\nclass Time : public Variable {\n public:\n    explicit Time(const std::string &_name)\n        : Variable(_name),\n        m_retName(\"TIME\") { }\n\n    void evaluate(Transaction *transaction,\n        RuleWithActions *rule,\n        std::vector<const VariableValue *> *l) override;\n    std::string m_retName;\n};\n\n}  // namespace variables\n}  // namespace modsecurity\n\n#endif  // SRC_VARIABLES_TIME_H_\n"
  },
  {
    "path": "src/variables/time_day.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"src/variables/time_day.h\"\n\n#include <time.h>\n#include <stdio.h>\n#include <string.h>\n#include <sys/types.h>\n#include <sys/stat.h>\n#include <fcntl.h>\n\n#include <iostream>\n#include <string>\n#include <vector>\n#include <list>\n#include <utility>\n\n#include \"modsecurity/transaction.h\"\n\n#ifdef WIN32\n#include \"src/compat/msvc.h\"\n#endif\n\nnamespace modsecurity {\nnamespace variables {\n\nvoid TimeDay::evaluate(Transaction *transaction,\n    RuleWithActions *rule,\n    std::vector<const VariableValue *> *l) {\n    time_t timer;\n    time(&timer);\n\n    struct tm timeinfo;\n    localtime_r(&timer, &timeinfo);\n\n    char tstr[std::size(\"dd\")];\n    strftime(tstr, std::size(tstr), \"%d\", &timeinfo);\n\n    transaction->m_variableTimeDay.assign(tstr);\n\n    l->push_back(new VariableValue(&m_retName,\n        &transaction->m_variableTimeDay));\n}\n\n\n}  // namespace variables\n}  // namespace modsecurity\n"
  },
  {
    "path": "src/variables/time_day.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <vector>\n#include <string>\n#include <list>\n#include <utility>\n\n#ifndef SRC_VARIABLES_TIME_DAY_H_\n#define SRC_VARIABLES_TIME_DAY_H_\n\n#include \"src/variables/variable.h\"\n\nnamespace modsecurity {\n\nclass Transaction;\nnamespace variables {\n\nclass TimeDay : public Variable {\n public:\n    explicit TimeDay(const std::string &_name)\n        : Variable(_name),\n        m_retName(\"TIME_DAY\") { }\n\n    void evaluate(Transaction *transaction,\n        RuleWithActions *rule,\n        std::vector<const VariableValue *> *l) override;\n    std::string m_retName;\n};\n\n}  // namespace variables\n}  // namespace modsecurity\n\n#endif  // SRC_VARIABLES_TIME_DAY_H_\n"
  },
  {
    "path": "src/variables/time_epoch.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"src/variables/time_epoch.h\"\n\n#include <time.h>\n#include <stdio.h>\n#include <string.h>\n#include <sys/types.h>\n#include <sys/stat.h>\n#include <fcntl.h>\n\n#include <iostream>\n#include <string>\n#include <vector>\n#include <list>\n#include <utility>\n\n#include \"modsecurity/transaction.h\"\n\nnamespace modsecurity {\nnamespace variables {\n\nvoid TimeEpoch::evaluate(Transaction *transaction,\n    RuleWithActions *rule,\n    std::vector<const VariableValue *> *l) {\n    transaction->m_variableTimeEpoch.assign(\n        std::to_string(std::time(nullptr)));\n    l->push_back(new VariableValue(&m_retName,\n        &transaction->m_variableTimeEpoch));\n}\n\n\n}  // namespace variables\n}  // namespace modsecurity\n"
  },
  {
    "path": "src/variables/time_epoch.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <vector>\n#include <string>\n#include <list>\n#include <utility>\n\n#ifndef SRC_VARIABLES_TIME_EPOCH_H_\n#define SRC_VARIABLES_TIME_EPOCH_H_\n\n#include \"src/variables/variable.h\"\n\nnamespace modsecurity {\n\nclass Transaction;\nnamespace variables {\n\nclass TimeEpoch : public Variable {\n public:\n    explicit TimeEpoch(const std::string &_name)\n        : Variable(_name),\n        m_retName(\"TIME_EPOCH\") { }\n\n    void evaluate(Transaction *transaction,\n        RuleWithActions *rule,\n        std::vector<const VariableValue *> *l) override;\n    std::string m_retName;\n};\n\n}  // namespace variables\n}  // namespace modsecurity\n\n#endif  // SRC_VARIABLES_TIME_EPOCH_H_\n"
  },
  {
    "path": "src/variables/time_hour.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"src/variables/time_hour.h\"\n\n#include <time.h>\n#include <stdio.h>\n#include <string.h>\n#include <sys/types.h>\n#include <sys/stat.h>\n#include <fcntl.h>\n\n#include <iostream>\n#include <string>\n#include <vector>\n#include <list>\n#include <utility>\n\n#include \"modsecurity/transaction.h\"\n\n#ifdef WIN32\n#include \"src/compat/msvc.h\"\n#endif\n\nnamespace modsecurity {\nnamespace variables {\n\nvoid TimeHour::evaluate(Transaction *transaction,\n    RuleWithActions *rule,\n    std::vector<const VariableValue *> *l) {\n    time_t timer;\n    time(&timer);\n\n    struct tm timeinfo;\n    localtime_r(&timer, &timeinfo);\n\n    char tstr[std::size(\"hh\")];\n    strftime(tstr, std::size(tstr), \"%H\", &timeinfo);\n\n    transaction->m_variableTimeHour.assign(tstr);\n\n    l->push_back(new VariableValue(&m_retName,\n        &transaction->m_variableTimeHour));\n}\n\n\n}  // namespace variables\n}  // namespace modsecurity\n"
  },
  {
    "path": "src/variables/time_hour.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <vector>\n#include <string>\n#include <list>\n#include <utility>\n\n#ifndef SRC_VARIABLES_TIME_HOUR_H_\n#define SRC_VARIABLES_TIME_HOUR_H_\n\n#include \"src/variables/variable.h\"\n\nnamespace modsecurity {\n\nclass Transaction;\nnamespace variables {\n\nclass TimeHour : public Variable {\n public:\n    explicit TimeHour(const std::string &_name)\n        : Variable(_name),\n        m_retName(\"TIME_HOUR\") { }\n\n    void evaluate(Transaction *transaction,\n        RuleWithActions *rule,\n        std::vector<const VariableValue *> *l) override;\n    std::string m_retName;\n};\n\n}  // namespace variables\n}  // namespace modsecurity\n\n#endif  // SRC_VARIABLES_TIME_HOUR_H_\n"
  },
  {
    "path": "src/variables/time_min.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"src/variables/time_min.h\"\n\n#include <time.h>\n#include <stdio.h>\n#include <string.h>\n#include <sys/types.h>\n#include <sys/stat.h>\n#include <fcntl.h>\n\n#include <iostream>\n#include <string>\n#include <vector>\n#include <list>\n#include <utility>\n\n#include \"modsecurity/transaction.h\"\n\n#ifdef WIN32\n#include \"src/compat/msvc.h\"\n#endif\n\nnamespace modsecurity {\nnamespace variables {\n\nvoid TimeMin::evaluate(Transaction *transaction,\n    RuleWithActions *rule,\n    std::vector<const VariableValue *> *l) {\n    time_t timer;\n    time(&timer);\n\n    struct tm timeinfo;\n    localtime_r(&timer, &timeinfo);\n\n    char tstr[std::size(\"mm\")];\n    strftime(tstr, std::size(tstr), \"%M\", &timeinfo);\n\n    transaction->m_variableTimeMin.assign(tstr);\n\n    l->push_back(new VariableValue(&m_retName,\n        &transaction->m_variableTimeMin));\n}\n\n\n}  // namespace variables\n}  // namespace modsecurity\n"
  },
  {
    "path": "src/variables/time_min.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <vector>\n#include <string>\n#include <list>\n#include <utility>\n\n#ifndef SRC_VARIABLES_TIME_MIN_H_\n#define SRC_VARIABLES_TIME_MIN_H_\n\n#include \"src/variables/variable.h\"\n\nnamespace modsecurity {\n\nclass Transaction;\nnamespace variables {\n\nclass TimeMin : public Variable {\n public:\n    explicit TimeMin(const std::string &_name)\n        : Variable(_name),\n        m_retName(\"TIME_MIN\") { }\n\n    void evaluate(Transaction *transaction,\n        RuleWithActions *rule,\n        std::vector<const VariableValue *> *l) override;\n    std::string m_retName;\n};\n\n}  // namespace variables\n}  // namespace modsecurity\n\n#endif  // SRC_VARIABLES_TIME_MIN_H_\n"
  },
  {
    "path": "src/variables/time_mon.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"src/variables/time_mon.h\"\n\n#include <time.h>\n#include <stdio.h>\n#include <string.h>\n#include <sys/types.h>\n#include <sys/stat.h>\n#include <fcntl.h>\n\n#include <iostream>\n#include <string>\n#include <vector>\n#include <list>\n#include <utility>\n\n#include \"modsecurity/transaction.h\"\n\n#ifdef WIN32\n#include \"src/compat/msvc.h\"\n#endif\n\nnamespace modsecurity {\nnamespace variables {\n\nvoid TimeMon::evaluate(Transaction *transaction,\n    RuleWithActions *rule,\n    std::vector<const VariableValue *> *l) {\n    time_t timer;\n    time(&timer);\n\n    struct tm timeinfo;\n    localtime_r(&timer, &timeinfo);\n\n    transaction->m_variableTimeMin.assign(std::to_string(timeinfo.tm_mon + 1));\n\n    l->push_back(new VariableValue(&m_retName,\n        &transaction->m_variableTimeMin));\n}\n\n\n}  // namespace variables\n}  // namespace modsecurity\n"
  },
  {
    "path": "src/variables/time_mon.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <vector>\n#include <string>\n#include <list>\n#include <utility>\n\n#ifndef SRC_VARIABLES_TIME_MON_H_\n#define SRC_VARIABLES_TIME_MON_H_\n\n#include \"src/variables/variable.h\"\n\nnamespace modsecurity {\n\nclass Transaction;\nnamespace variables {\n\nclass TimeMon : public Variable {\n public:\n    explicit TimeMon(const std::string &_name)\n        : Variable(_name),\n        m_retName(\"TIME_MON\") { }\n\n    void evaluate(Transaction *transaction,\n        RuleWithActions *rule,\n        std::vector<const VariableValue *> *l) override;\n    std::string m_retName;\n};\n\n}  // namespace variables\n}  // namespace modsecurity\n\n#endif  // SRC_VARIABLES_TIME_MON_H_\n"
  },
  {
    "path": "src/variables/time_sec.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"src/variables/time_sec.h\"\n\n#include <time.h>\n#include <stdio.h>\n#include <string.h>\n#include <sys/types.h>\n#include <sys/stat.h>\n#include <fcntl.h>\n\n#include <iostream>\n#include <string>\n#include <vector>\n#include <list>\n#include <utility>\n\n#include \"modsecurity/transaction.h\"\n\n#ifdef WIN32\n#include \"src/compat/msvc.h\"\n#endif\n\nnamespace modsecurity {\nnamespace variables {\n\nvoid TimeSec::evaluate(Transaction *transaction,\n    RuleWithActions *rule,\n    std::vector<const VariableValue *> *l) {\n    time_t timer;\n    time(&timer);\n\n    struct tm timeinfo;\n    localtime_r(&timer, &timeinfo);\n\n    char tstr[std::size(\"ss\")];\n    strftime(tstr, std::size(tstr), \"%S\", &timeinfo);\n\n    transaction->m_variableTimeSec.assign(tstr);\n\n    l->push_back(new VariableValue(&m_retName,\n        &transaction->m_variableTimeSec));\n}\n\n\n}  // namespace variables\n}  // namespace modsecurity\n"
  },
  {
    "path": "src/variables/time_sec.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <vector>\n#include <string>\n#include <list>\n#include <utility>\n\n#ifndef SRC_VARIABLES_TIME_SEC_H_\n#define SRC_VARIABLES_TIME_SEC_H_\n\n#include \"src/variables/variable.h\"\n\nnamespace modsecurity {\n\nclass Transaction;\nnamespace variables {\n\nclass TimeSec : public Variable {\n public:\n    explicit TimeSec(const std::string &_name)\n        : Variable(_name),\n        m_retName(\"TIME_SEC\") { }\n\n    void evaluate(Transaction *transaction,\n        RuleWithActions *rule,\n        std::vector<const VariableValue *> *l) override;\n    std::string m_retName;\n};\n\n}  // namespace variables\n}  // namespace modsecurity\n\n#endif  // SRC_VARIABLES_TIME_SEC_H_\n"
  },
  {
    "path": "src/variables/time_wday.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"src/variables/time_wday.h\"\n\n#include <time.h>\n#include <stdio.h>\n#include <string.h>\n#include <sys/types.h>\n#include <sys/stat.h>\n#include <fcntl.h>\n\n#include <iostream>\n#include <string>\n#include <vector>\n#include <list>\n#include <utility>\n\n#include \"modsecurity/transaction.h\"\n\n#ifdef WIN32\n#include \"src/compat/msvc.h\"\n#endif\n\nnamespace modsecurity {\nnamespace variables {\n\nvoid TimeWDay::evaluate(Transaction *transaction,\n    RuleWithActions *rule,\n    std::vector<const VariableValue *> *l) {\n    time_t timer;\n    time(&timer);\n\n    struct tm timeinfo;\n    localtime_r(&timer, &timeinfo);\n\n    char tstr[std::size(\"d\")];\n    strftime(tstr, std::size(tstr), \"%u\", &timeinfo);\n\n    transaction->m_variableTimeWDay.assign(tstr);\n\n    l->push_back(new VariableValue(&m_retName,\n        &transaction->m_variableTimeWDay));\n}\n\n\n}  // namespace variables\n}  // namespace modsecurity\n"
  },
  {
    "path": "src/variables/time_wday.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <vector>\n#include <string>\n#include <list>\n#include <utility>\n\n#ifndef SRC_VARIABLES_TIME_WDAY_H_\n#define SRC_VARIABLES_TIME_WDAY_H_\n\n#include \"src/variables/variable.h\"\n\nnamespace modsecurity {\n\nclass Transaction;\nnamespace variables {\n\nclass TimeWDay : public Variable {\n public:\n    explicit TimeWDay(const std::string &_name)\n        : Variable(_name),\n        m_retName(\"TIME_WDAY\") { }\n\n    void evaluate(Transaction *transaction,\n        RuleWithActions *rule,\n        std::vector<const VariableValue *> *l) override;\n    std::string m_retName;\n};\n\n}  // namespace variables\n}  // namespace modsecurity\n\n#endif  // SRC_VARIABLES_TIME_WDAY_H_\n"
  },
  {
    "path": "src/variables/time_year.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"src/variables/time_year.h\"\n\n#include <time.h>\n#include <stdio.h>\n#include <string.h>\n#include <sys/types.h>\n#include <sys/stat.h>\n#include <fcntl.h>\n\n#include <iostream>\n#include <string>\n#include <vector>\n#include <list>\n#include <utility>\n\n#include \"modsecurity/transaction.h\"\n\n#ifdef WIN32\n#include \"src/compat/msvc.h\"\n#endif\n\nnamespace modsecurity {\nnamespace variables {\n\nvoid TimeYear::evaluate(Transaction *transaction,\n    RuleWithActions *rule,\n    std::vector<const VariableValue *> *l) {\n    time_t timer;\n    time(&timer);\n\n    struct tm timeinfo;\n    localtime_r(&timer, &timeinfo);\n\n    char tstr[std::size(\"yyyy\")];\n    strftime(tstr, std::size(tstr), \"%Y\", &timeinfo);\n\n    transaction->m_variableTimeYear.assign(tstr);\n\n    l->push_back(new VariableValue(&m_retName,\n        &transaction->m_variableTimeYear));\n}\n\n\n}  // namespace variables\n}  // namespace modsecurity\n"
  },
  {
    "path": "src/variables/time_year.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <vector>\n#include <string>\n#include <list>\n#include <utility>\n\n#ifndef SRC_VARIABLES_TIME_YEAR_H_\n#define SRC_VARIABLES_TIME_YEAR_H_\n\n#include \"src/variables/variable.h\"\n\nnamespace modsecurity {\n\nclass Transaction;\nnamespace variables {\n\nclass TimeYear : public Variable {\n public:\n    explicit TimeYear(const std::string &_name)\n        : Variable(_name),\n        m_retName(\"TIME_YEAR\") { }\n\n    void evaluate(Transaction *transaction,\n        RuleWithActions *rule,\n        std::vector<const VariableValue *> *l) override;\n    std::string m_retName;\n};\n\n}  // namespace variables\n}  // namespace modsecurity\n\n#endif  // SRC_VARIABLES_TIME_YEAR_H_\n"
  },
  {
    "path": "src/variables/tx.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"src/variables/tx.h\"\n\n#include <time.h>\n#include <stdio.h>\n#include <string.h>\n#include <sys/types.h>\n#include <sys/stat.h>\n#include <fcntl.h>\n\n#include <iostream>\n#include <string>\n#include <vector>\n#include <list>\n#include <utility>\n\n#include \"modsecurity/transaction.h\"\n\nnamespace modsecurity {\nnamespace variables {\n\n\n\n}  // namespace variables\n}  // namespace modsecurity\n"
  },
  {
    "path": "src/variables/tx.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <iostream>\n#include <string>\n#include <vector>\n#include <list>\n#include <utility>\n#include <memory>\n\n#ifndef SRC_VARIABLES_TX_H_\n#define SRC_VARIABLES_TX_H_\n\n#include \"src/variables/variable.h\"\n#include \"src/run_time_string.h\"\n\nnamespace modsecurity {\n\nclass Transaction;\nnamespace variables {\n\n\nclass Tx_DictElement : public Variable {\n public:\n    explicit Tx_DictElement(const std::string &dictElement)\n        : Variable(\"TX:\" + dictElement),\n        m_dictElement(\"TX:\" + dictElement) { }\n\n    void evaluate(Transaction *t,\n        RuleWithActions *rule,\n        std::vector<const VariableValue *> *l) override {\n        t->m_collections.m_tx_collection->resolveMultiMatches(\n            m_name, l, m_keyExclusion);\n    }\n\n    std::string m_dictElement;\n};\n\n\nclass Tx_NoDictElement : public Variable {\n public:\n    Tx_NoDictElement()\n        : Variable(\"TX\") { }\n\n    void evaluate(Transaction *t,\n        RuleWithActions *rule,\n        std::vector<const VariableValue *> *l) override {\n        t->m_collections.m_tx_collection->resolveMultiMatches(\"\", l,\n            m_keyExclusion);\n    }\n};\n\n\nclass Tx_DictElementRegexp : public VariableRegex {\n public:\n    explicit Tx_DictElementRegexp(const std::string &dictElement)\n        : VariableRegex(\"TX\", dictElement),\n        m_dictElement(dictElement) { }\n\n    void evaluate(Transaction *t,\n        RuleWithActions *rule,\n        std::vector<const VariableValue *> *l) override {\n        t->m_collections.m_tx_collection->resolveRegularExpression(\n            m_dictElement, l, m_keyExclusion);\n    }\n\n    std::string m_dictElement;\n};\n\n\nclass Tx_DynamicElement : public Variable {\n public:\n    explicit Tx_DynamicElement(std::unique_ptr<RunTimeString> dictElement)\n        : Variable(\"TX:dynamic\"),\n        m_string(std::move(dictElement)) { }\n\n    void evaluate(Transaction *t,\n        RuleWithActions *rule,\n        std::vector<const VariableValue *> *l) override {\n        std::string string = m_string->evaluate(t);\n        t->m_collections.m_tx_collection->resolveMultiMatches(string, l,\n            m_keyExclusion);\n    }\n\n    static void del(Transaction *t, const std::string &k) {\n        t->m_collections.m_tx_collection->del(k);\n    }\n\n    static void storeOrUpdateFirst(Transaction *t, const std::string &var,\n        const std::string &value) {\n        t->m_collections.m_tx_collection->storeOrUpdateFirst(var, value);\n    }\n\n    std::unique_ptr<RunTimeString> m_string;\n};\n\n\n}  // namespace variables\n}  // namespace modsecurity\n\n#endif  // SRC_VARIABLES_TX_H_\n"
  },
  {
    "path": "src/variables/unique_id.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <iostream>\n#include <string>\n#include <vector>\n#include <list>\n#include <utility>\n\n#ifndef SRC_VARIABLES_UNIQUE_ID_H_\n#define SRC_VARIABLES_UNIQUE_ID_H_\n\n#include \"src/variables/variable.h\"\n\nnamespace modsecurity {\n\nclass Transaction;\nnamespace variables {\n\n\nDEFINE_VARIABLE(UniqueID, UNIQUEID, m_variableUniqueID)\n\n\n}  // namespace variables\n}  // namespace modsecurity\n\n#endif  // SRC_VARIABLES_UNIQUE_ID_H_\n"
  },
  {
    "path": "src/variables/url_encoded_error.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <iostream>\n#include <string>\n#include <vector>\n#include <list>\n#include <utility>\n\n#ifndef SRC_VARIABLES_URL_ENCODED_ERROR_H_\n#define SRC_VARIABLES_URL_ENCODED_ERROR_H_\n\n#include \"src/variables/variable.h\"\n\nnamespace modsecurity {\n\nclass Transaction;\nnamespace variables {\n\n\nDEFINE_VARIABLE(UrlEncodedError, URLENCODED_ERROR, m_variableUrlEncodedError)\n\n\n}  // namespace variables\n}  // namespace modsecurity\n\n#endif  // SRC_VARIABLES_URL_ENCODED_ERROR_H_\n"
  },
  {
    "path": "src/variables/user.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2023 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <list>\n#include <memory>\n#include <string>\n#include <utility>\n#include <vector>\n\n#ifndef SRC_VARIABLES_USER_H_\n#define SRC_VARIABLES_USER_H_\n\n#include \"src/variables/variable.h\"\n#include \"src/run_time_string.h\"\n\nnamespace modsecurity {\n\nclass Transaction;\nnamespace variables {\n\n\nclass User_DictElement : public Variable {\n public:\n    explicit User_DictElement(const std::string &dictElement)\n        : Variable(\"USER:\" + dictElement),\n        m_dictElement(\"USER:\" + dictElement) { }\n\n    void evaluate(Transaction *t,\n        RuleWithActions *rule,\n        std::vector<const VariableValue *> *l) override {\n        t->m_collections.m_user_collection->resolveMultiMatches(\n            m_name, t->m_collections.m_user_collection_key,\n            t->m_rules->m_secWebAppId.m_value, l, m_keyExclusion);\n    }\n\n    std::string m_dictElement;\n};\n\n\nclass User_NoDictElement : public Variable {\n public:\n    User_NoDictElement()\n        : Variable(\"USER\") { }\n\n    void evaluate(Transaction *t,\n        RuleWithActions *rule,\n        std::vector<const VariableValue *> *l) override {\n        t->m_collections.m_user_collection->resolveMultiMatches(m_name,\n            t->m_collections.m_user_collection_key,\n            t->m_rules->m_secWebAppId.m_value, l, m_keyExclusion);\n    }\n};\n\n\nclass User_DictElementRegexp : public VariableRegex {\n public:\n    explicit User_DictElementRegexp(const std::string &dictElement)\n        : VariableRegex(\"USER\", dictElement),\n        m_dictElement(dictElement) { }\n\n    void evaluate(Transaction *t,\n        RuleWithActions *rule,\n        std::vector<const VariableValue *> *l) override {\n        t->m_collections.m_user_collection->resolveRegularExpression(\n            m_dictElement, t->m_collections.m_user_collection_key,\n            t->m_rules->m_secWebAppId.m_value, l, m_keyExclusion);\n    }\n\n    std::string m_dictElement;\n};\n\n\nclass User_DynamicElement : public Variable {\n public:\n    explicit User_DynamicElement(std::unique_ptr<RunTimeString> dictElement)\n        : Variable(\"USER:dynamic\"),\n        m_string(std::move(dictElement)) { }\n\n    void evaluate(Transaction *t,\n        RuleWithActions *rule,\n        std::vector<const VariableValue *> *l) override {\n        std::string string = m_string->evaluate(t);\n        t->m_collections.m_user_collection->resolveMultiMatches(\n            string,\n            t->m_collections.m_user_collection_key,\n            t->m_rules->m_secWebAppId.m_value, l, m_keyExclusion);\n    }\n\n    static void del(Transaction *t, const std::string &k) {\n        t->m_collections.m_user_collection->del(k,\n            t->m_collections.m_user_collection_key,\n            t->m_rules->m_secWebAppId.m_value);\n    }\n\n    static void setExpiry(Transaction *t, const std::string &k, int32_t expiry_seconds) {\n        t->m_collections.m_user_collection->setExpiry(k,\n            t->m_collections.m_user_collection_key,\n            t->m_rules->m_secWebAppId.m_value, expiry_seconds);\n    }\n\n    static void storeOrUpdateFirst(Transaction *t, const std::string &var,\n        const std::string &value) {\n        t->m_collections.m_user_collection->storeOrUpdateFirst(\n            var, t->m_collections.m_user_collection_key,\n            t->m_rules->m_secWebAppId.m_value,\n            value);\n    }\n\n    std::unique_ptr<RunTimeString> m_string;\n};\n\n\n}  // namespace variables\n}  // namespace modsecurity\n\n#endif  // SRC_VARIABLES_USER_H_\n"
  },
  {
    "path": "src/variables/user_id.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <iostream>\n#include <string>\n#include <vector>\n#include <list>\n#include <utility>\n\n#ifndef SRC_VARIABLES_USER_ID_H_\n#define SRC_VARIABLES_USER_ID_H_\n\n#include \"src/variables/variable.h\"\n\nnamespace modsecurity {\n\nclass Transaction;\nnamespace variables {\n\n\nDEFINE_VARIABLE(UserID, USERID, m_variableUserID)\n\n\n}  // namespace variables\n}  // namespace modsecurity\n\n#endif  // SRC_VARIABLES_USER_ID_H_\n"
  },
  {
    "path": "src/variables/variable.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2023 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"src/variables/variable.h\"\n\n#include <iostream>\n#include <string>\n#include <vector>\n#include <list>\n\n#include \"modsecurity/transaction.h\"\n#include \"src/utils/string.h\"\n\n\nnamespace modsecurity {\nnamespace variables {\n\n\nVariable::Variable(const std::string &name)\n    : m_name(name),\n    m_collectionName(\"\") {\n    size_t a = m_name.find(\":\");\n    if (a == std::string::npos) {\n        a = m_name.find(\".\");\n    }\n    if (a != std::string::npos) {\n        m_collectionName = utils::string::toupper(std::string(m_name, 0, a));\n        m_name = std::string(m_name, a + 1, m_name.size());\n        m_fullName = std::make_shared<std::string>(m_collectionName\n            + \":\" + m_name);\n    } else {\n        m_fullName = std::make_shared<std::string>(m_name);\n        m_collectionName = m_name;\n        m_name = \"\";\n    }\n}\n\n\nVariable::Variable(const Variable *var) :\n    m_name(var->m_name),\n    m_collectionName(var->m_collectionName),\n    m_fullName(var->m_fullName) { }\n\n\nvoid Variable::addsKeyExclusion(const Variable *v) {\n    std::unique_ptr<KeyExclusion> r;\n    const auto *ve = \\\n        dynamic_cast<const VariableModificatorExclusion *>(v);\n    const VariableRegex *vr;\n\n    if (!ve) {\n        return;\n    }\n\n    vr = dynamic_cast<const VariableRegex *>(ve->m_base.get());\n\n    if (vr == NULL) {\n        r.reset(new KeyExclusionString(v->m_name));\n    } else {\n        r.reset(new KeyExclusionRegex(vr->m_regex));\n    }\n\n    m_keyExclusion.push_back(std::move(r));\n}\n\n\nstd::string operator+(const std::string &a, const Variable *v) {\n    return a + *v->m_fullName.get();\n}\n\n\nstd::string operator+(const std::string &a, const Variables *v) {\n    std::string test;\n    for (const auto &b : *v) {\n        if (test.empty()) {\n            test = std::string(\"\") + b;\n        } else {\n            test = test + \"|\" + b;\n        }\n    }\n\n    return a + test;\n}\n\n\n}  // namespace variables\n}  // namespace modsecurity\n"
  },
  {
    "path": "src/variables/variable.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2023 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <exception>\n#include <list>\n#include <memory>\n#include <string>\n#include <utility>\n#include <vector>\n#include <deque>\n\n#include \"modsecurity/rules_set.h\"\n#include \"modsecurity/transaction.h\"\n#include \"modsecurity/rule.h\"\n#include \"src/utils/string.h\"\n#include \"src/utils/regex.h\"\n\n#ifndef SRC_VARIABLES_VARIABLE_H_\n#define SRC_VARIABLES_VARIABLE_H_\n\n#define DEFINE_VARIABLE(n, N, e) \\\n    VAR_DIRECT(n, N, e)\n\n#define DEFINE_VARIABLE_DICT(n, N, e) \\\n    VAR_WITH_DICT_ELEMENT(n, N, e) \\\n    \\\n    VAR_WITHOUT_DICT_ELEMENT(n, N, e) \\\n    \\\n    VAR_WITH_REGEX(n, N, e) \\\n\n\n\n#define VAR_WITH_REGEX(n, N, e) \\\nclass n ## _DictElementRegexp : public VariableRegex { \\\n public: \\\n    explicit n ## _DictElementRegexp(const std::string &regex) \\\n        : VariableRegex(#N, regex) { } \\\n\\\n    void evaluate(Transaction *transaction, \\\n        RuleWithActions *rule, \\\n        std::vector<const VariableValue *> *l) override { \\\n        transaction-> e .resolveRegularExpression(&m_r, l, \\\n            m_keyExclusion); \\\n    } \\\n};\n\n\n#define VAR_WITH_DICT_ELEMENT(n, N, e) \\\nclass n ## _DictElement : public VariableDictElement { \\\n public: \\\n    explicit n ## _DictElement(const std::string &dictElement) \\\n        : VariableDictElement(#N, dictElement) { } \\\n\\\n    void evaluate(Transaction *transaction, \\\n        RuleWithActions *rule, \\\n        std::vector<const VariableValue *> *l) override { \\\n        transaction-> e .resolve(m_dictElement, l); \\\n    } \\\n};\n\n\n#define VAR_WITHOUT_DICT_ELEMENT(n, N, e) \\\nclass n ## _NoDictElement : public Variable { \\\n public: \\\n    explicit n ## _NoDictElement() \\\n        : Variable(#N) { } \\\n\\\n    void evaluate(Transaction *transaction, \\\n        RuleWithActions *rule, \\\n        std::vector<const VariableValue *> *l) override { \\\n        transaction-> e .resolve(l, m_keyExclusion); \\\n    } \\\n};\n\n\n#define VAR_DIRECT(n, N, e) \\\nclass n : public Variable { \\\n public: \\\n    n() \\\n        : Variable(#N) { } \\\n    \\\n    void evaluate(Transaction *transaction, \\\n        RuleWithActions *rule, \\\n        std::vector<const VariableValue *> *l) override { \\\n        transaction-> e .evaluate(l); \\\n    } \\\n};\n\n\nnamespace modsecurity {\n\nclass Transaction;\nnamespace variables {\n\nclass KeyExclusion {\n public:\n    KeyExclusion() { }\n    virtual bool match(const std::string &a) = 0;\n    virtual ~KeyExclusion() { }\n};\n\n\n// FIXME: use pre built regex.\nclass KeyExclusionRegex : public KeyExclusion {\n public:\n    explicit KeyExclusionRegex(const Utils::Regex &re)\n        : m_re(re.pattern, true) { }\n    explicit KeyExclusionRegex(const std::string &re)\n        : m_re(re, true) { }\n\n    ~KeyExclusionRegex() override { }\n\n    bool match(const std::string &a) override {\n        return m_re.searchAll(a).size() > 0;\n    }\n\n    Utils::Regex m_re;\n};\n\n\nclass KeyExclusionString : public KeyExclusion {\n public:\n    explicit KeyExclusionString(const std::string &a)\n        : m_key(utils::string::toupper(a)) { }\n\n    ~KeyExclusionString() override { }\n\n    bool match(const std::string &a) override {\n        return a.size() == m_key.size() && std::equal(a.begin(), a.end(),\n            m_key.begin(),\n            [](char aa, char bb) {\n                return static_cast<char>(toupper(aa)) == static_cast<char>(bb);\n            });\n    }\n\n    std::string m_key;\n};\n\n\nclass KeyExclusions : public std::deque<std::unique_ptr<KeyExclusion>> {\n public:\n    KeyExclusions() {\n    }\n\n    bool toOmit(std::string a) const {\n        for (auto &z : *this) {\n            if (z->match(a)) {\n                return true;\n            }\n        }\n        return false;\n    }\n\n    bool toOmit(std::string a) { // cppcheck-suppress passedByValue\n        return static_cast<const KeyExclusions&>(*this).toOmit(a);\n    }\n};\n\n\nclass VariableMonkeyResolution {\n public:\n    VariableMonkeyResolution () { }\n    static inline bool comp(const std::string &a, const std::string &b) {\n        return a.size() == b.size()\n             && std::equal(a.begin(), a.end(), b.begin(),\n            [](char aa, char bb) {\n            return toupper(aa) == bb;\n        });\n    }\n\n    static void stringMatchResolveMulti(Transaction *t,\n        const std::string &variable,\n        std::vector<const VariableValue *> *l) {\n        size_t collection_delimiter_offset = variable.find(\".\");\n        if (collection_delimiter_offset == std::string::npos) {\n            collection_delimiter_offset = variable.find(\":\");\n        }\n        std::string col; // collection name excluding individual variable specification\n        std::string var; // variable within the collection\n        if (collection_delimiter_offset == std::string::npos) {\n            col = variable;\n        } else {\n            col = std::string(variable, 0, collection_delimiter_offset);\n            var = std::string(variable, collection_delimiter_offset + 1,\n                variable.length() - (collection_delimiter_offset + 1));\n\t}\n\n        // First check if the request is for a collection of type AnchoredSetVariable\n        AnchoredSetVariable* anchoredSetVariable = NULL;\n        if (comp(col, \"ARGS\")) {\n            anchoredSetVariable = &t->m_variableArgs;\n        } else if (comp(col, \"ARGS_GET\")) {\n            anchoredSetVariable = &t->m_variableArgsGet;\n        } else if (comp(col, \"ARGS_POST\")) {\n            anchoredSetVariable = &t->m_variableArgsPost;\n        } else if (comp(col, \"FILES_SIZES\")) {\n            anchoredSetVariable = &t->m_variableFilesSizes;\n        } else if (comp(col, \"FILES_NAMES\")) {\n            anchoredSetVariable = &t->m_variableFilesNames;\n        } else if (comp(col, \"FILES_TMP_CONTENT\")) {\n            anchoredSetVariable = &t->m_variableFilesTmpContent;\n        } else if (comp(col, \"MULTIPART_FILENAME\")) {\n            anchoredSetVariable = &t->m_variableMultipartFileName;\n        } else if (comp(col, \"MULTIPART_NAME\")) {\n            anchoredSetVariable = &t->m_variableMultipartName;\n        } else if (comp(col, \"MATCHED_VARS_NAMES\")) {\n            anchoredSetVariable = &t->m_variableMatchedVarsNames;\n        } else if (comp(col, \"MATCHED_VARS\")) {\n            anchoredSetVariable = &t->m_variableMatchedVars;\n        } else if (comp(col, \"FILES\")) {\n            anchoredSetVariable = &t->m_variableFiles;\n        } else if (comp(col, \"REQUEST_COOKIES\")) {\n            anchoredSetVariable = &t->m_variableRequestCookies;\n        } else if (comp(col, \"REQUEST_HEADERS\")) {\n            anchoredSetVariable = &t->m_variableRequestHeaders;\n        } else if (comp(variable, \"REQUEST_HEADERS_NAMES\")) {\n            anchoredSetVariable = &t->m_variableRequestHeadersNames;\n        } else if (comp(col, \"RESPONSE_HEADERS\")) {\n            anchoredSetVariable = &t->m_variableResponseHeaders;\n        } else if (comp(variable, \"RESPONSE_HEADERS_NAMES\")) {\n            anchoredSetVariable = &t->m_variableResponseHeadersNames;\n        } else if (comp(col, \"GEO\")) {\n            anchoredSetVariable = &t->m_variableGeo;\n        } else if (comp(col, \"REQUEST_COOKIES_NAMES\")) {\n            anchoredSetVariable = &t->m_variableRequestCookiesNames;\n        } else if (comp(col, \"MULTIPART_PART_HEADERS\")) {\n            anchoredSetVariable = &t->m_variableMultipartPartHeaders;\n        } else if (comp(col, \"FILES_TMPNAMES\")) {\n            anchoredSetVariable = &t->m_variableFilesTmpNames;\n        }\n        if (anchoredSetVariable != NULL) {\n            if (collection_delimiter_offset == std::string::npos) {\n                anchoredSetVariable->resolve(l);\n            } else {\n                anchoredSetVariable->resolve(var, l);\n            }\n            return;\n        }\n\n        // Next check for collection of type AnchoredSetVariableTranslationProxy\n        AnchoredSetVariableTranslationProxy* anchoredSetVariableTranslationProxy = NULL;\n        if (comp(col, \"ARGS_NAMES\")) {\n            anchoredSetVariableTranslationProxy = &t->m_variableArgsNames;\n        } else if (comp(col, \"ARGS_GET_NAMES\")) {\n            anchoredSetVariableTranslationProxy = &t->m_variableArgsGetNames;\n        } else if (comp(col, \"ARGS_POST_NAMES\")) {\n            anchoredSetVariableTranslationProxy = &t->m_variableArgsPostNames;\n        }\n        if (anchoredSetVariableTranslationProxy != NULL) {\n            if (collection_delimiter_offset == std::string::npos) {\n                anchoredSetVariableTranslationProxy->resolve(l);\n            } else {\n                anchoredSetVariableTranslationProxy->resolve(var, l);\n            }\n            return;\n        }\n\n\n        // It could still be a non-collection variable, but in that case\n        // there should not be a request for a variable-within-a-collection\n        if (collection_delimiter_offset != std::string::npos) {\n            throw std::invalid_argument(\"Variable not found.\");\n        }\n\n        if (comp(variable, \"RESPONSE_CONTENT_TYPE\")) {\n            t->m_variableResponseContentType.evaluate(l);\n        } else if (comp(variable, \"ARGS_COMBINED_SIZE\")) {\n            t->m_variableARGScombinedSize.evaluate(l);\n        } else if (comp(variable, \"AUTH_TYPE\")) {\n            t->m_variableAuthType.evaluate(l);\n        } else if (comp(variable, \"FILES_COMBINED_SIZE\")) {\n            t->m_variableFilesCombinedSize.evaluate(l);\n        } else if (comp(variable, \"FULL_REQUEST\")) {\n            t->m_variableFullRequest.evaluate(l);\n        } else if (comp(variable, \"FULL_REQUEST_LENGTH\")) {\n            t->m_variableFullRequestLength.evaluate(l);\n        } else if (comp(variable, \"INBOUND_DATA_ERROR\")) {\n            t->m_variableInboundDataError.evaluate(l);\n        } else if (comp(variable, \"MATCHED_VAR\")) {\n            t->m_variableMatchedVar.evaluate(l);\n        } else if (comp(variable, \"MATCHED_VAR_NAME\")) {\n            t->m_variableMatchedVarName.evaluate(l);\n        } else if (comp(variable, \"MSC_PCRE_ERROR\")) {\n            t->m_variableMscPcreError.evaluate(l);\n        } else if (comp(variable, \"MSC_PCRE_LIMITS_EXCEEDED\")) {\n            t->m_variableMscPcreLimitsExceeded.evaluate(l);\n        } else if (comp(variable, \"MULTIPART_CRLF_LF_LINES\")) {\n            t->m_variableMultipartCrlfLFLines.evaluate(l);\n        } else if (comp(variable, \"MULTIPART_DATA_AFTER\")) {\n            t->m_variableMultipartDataAfter.evaluate(l);\n        } else if (comp(variable, \"MULTIPART_FILE_LIMIT_EXCEEDED\")) {\n            t->m_variableMultipartFileLimitExceeded.evaluate(l);\n        } else if (comp(variable, \"MULTIPART_STRICT_ERROR\")) {\n            t->m_variableMultipartStrictError.evaluate(l);\n        } else if (comp(variable, \"MULTIPART_HEADER_FOLDING\")) {\n            t->m_variableMultipartHeaderFolding.evaluate(l);\n        } else if (comp(variable, \"MULTIPART_INVALID_QUOTING\")) {\n            t->m_variableMultipartInvalidQuoting.evaluate(l);\n        } else if (comp(variable, \"MULTIPART_INVALID_HEADER_FOLDING\")) {\n            t->m_variableMultipartInvalidHeaderFolding.evaluate(l);\n        } else if (comp(variable, \"MULTIPART_UNMATCHED_BOUNDARY\")) {\n            t->m_variableMultipartUnmatchedBoundary.evaluate(l);\n        } else if (comp(variable, \"OUTBOUND_DATA_ERROR\")) {\n            t->m_variableOutboundDataError.evaluate(l);\n        } else if (comp(variable, \"PATH_INFO\")) {\n            t->m_variablePathInfo.evaluate(l);\n        } else if (comp(variable, \"QUERY_STRING\")) {\n            t->m_variableQueryString.evaluate(l);\n        } else if (comp(variable, \"REMOTE_ADDR\")) {\n            t->m_variableRemoteAddr.evaluate(l);\n        } else if (comp(variable, \"REMOTE_HOST\")) {\n            t->m_variableRemoteHost.evaluate(l);\n        } else if (comp(variable, \"REMOTE_PORT\")) {\n            t->m_variableRemotePort.evaluate(l);\n        } else if (comp(variable, \"REQBODY_ERROR\")) {\n            t->m_variableReqbodyError.evaluate(l);\n        } else if (comp(variable, \"REQBODY_ERROR_MSG\")) {\n            t->m_variableReqbodyErrorMsg.evaluate(l);\n        } else if (comp(variable, \"REQBODY_PROCESSOR_ERROR_MSG\")) {\n            t->m_variableReqbodyProcessorErrorMsg.evaluate(l);\n        } else if (comp(variable, \"REQBODY_PROCESSOR_ERROR\")) {\n            t->m_variableReqbodyProcessorError.evaluate(l);\n        } else if (comp(variable, \"REQBODY_PROCESSOR\")) {\n            t->m_variableReqbodyProcessor.evaluate(l);\n        } else if (comp(variable, \"REQUEST_BASENAME\")) {\n            t->m_variableRequestBasename.evaluate(l);\n        } else if (comp(variable, \"REQUEST_BODY\")) {\n            t->m_variableRequestBody.evaluate(l);\n        } else if (comp(variable, \"REQUEST_BODY_LENGTH\")) {\n            t->m_variableRequestBodyLength.evaluate(l);\n        } else if (comp(variable, \"REQUEST_FILENAME\")) {\n            t->m_variableRequestFilename.evaluate(l);\n        } else if (comp(variable, \"REQUEST_LINE\")) {\n            t->m_variableRequestLine.evaluate(l);\n        } else if (comp(variable, \"REQUEST_METHOD\")) {\n            t->m_variableRequestMethod.evaluate(l);\n        } else if (comp(variable, \"REQUEST_PROTOCOL\")) {\n            t->m_variableRequestProtocol.evaluate(l);\n        } else if (comp(variable, \"REQUEST_URI\")) {\n            t->m_variableRequestURI.evaluate(l);\n        } else if (comp(variable, \"REQUEST_URI_RAW\")) {\n            t->m_variableRequestURIRaw.evaluate(l);\n        } else if (comp(variable, \"RESOURCE\")) {\n            t->m_variableResource.evaluate(l);\n        } else if (comp(variable, \"RESPONSE_BODY\")) {\n            t->m_variableResponseBody.evaluate(l);\n        } else if (comp(variable, \"RESPONSE_CONTENT_LENGTH\")) {\n            t->m_variableResponseContentLength.evaluate(l);\n        } else if (comp(variable, \"RESPONSE_PROTOCOL\")) {\n            t->m_variableResponseProtocol.evaluate(l);\n        } else if (comp(variable, \"RESPONSE_STATUS\")) {\n            t->m_variableResponseStatus.evaluate(l);\n        } else if (comp(variable, \"SERVER_ADDR\")) {\n            t->m_variableServerAddr.evaluate(l);\n        } else if (comp(variable, \"SERVER_NAME\")) {\n            t->m_variableServerName.evaluate(l);\n        } else if (comp(variable, \"SERVER_PORT\")) {\n            t->m_variableServerPort.evaluate(l);\n        } else if (comp(variable, \"SESSIONID\")) {\n            t->m_variableSessionID.evaluate(l);\n        } else if (comp(variable, \"UNIQUE_ID\")) {\n            t->m_variableUniqueID.evaluate(l);\n        } else if (comp(variable, \"URLENCODED_ERROR\")) {\n            t->m_variableUrlEncodedError.evaluate(l);\n        } else if (comp(variable, \"USERID\")) {\n            t->m_variableUserID.evaluate(l);\n        } else {\n            throw std::invalid_argument(\"Variable not found.\");\n        }\n    }\n\n    static std::string stringMatchResolve(Transaction *t,\n        const std::string &variable) {\n        std::unique_ptr<std::string> vv;\n        size_t collection = variable.find(\".\");\n        if (collection == std::string::npos) {\n            collection = variable.find(\":\");\n        }\n        if (collection == std::string::npos) {\n            if (comp(variable, \"RESPONSE_CONTENT_TYPE\")) {\n                vv = t->m_variableResponseContentType.resolveFirst();\n            } else if (comp(variable, \"ARGS_COMBINED_SIZE\")) {\n                vv = t->m_variableARGScombinedSize.resolveFirst();\n            } else if (comp(variable, \"AUTH_TYPE\")) {\n                vv = t->m_variableAuthType.resolveFirst();\n            } else if (comp(variable, \"FILES_COMBINED_SIZE\")) {\n                vv = t->m_variableFilesCombinedSize.resolveFirst();\n            } else if (comp(variable, \"FULL_REQUEST\")) {\n                vv = t->m_variableFullRequest.resolveFirst();\n            } else if (comp(variable, \"FULL_REQUEST_LENGTH\")) {\n                vv = t->m_variableFullRequestLength.resolveFirst();\n            } else if (comp(variable, \"INBOUND_DATA_ERROR\")) {\n                vv = t->m_variableInboundDataError.resolveFirst();\n            } else if (comp(variable, \"MATCHED_VAR\")) {\n                vv = t->m_variableMatchedVar.resolveFirst();\n            } else if (comp(variable, \"MATCHED_VAR_NAME\")) {\n                vv = t->m_variableMatchedVarName.resolveFirst();\n            } else if (comp(variable, \"MSC_PCRE_ERROR\")) {\n                vv = t->m_variableMscPcreError.resolveFirst();\n            } else if (comp(variable, \"MSC_PCRE_LIMITS_EXCEEDED\")) {\n                vv = t->m_variableMscPcreLimitsExceeded.resolveFirst();\n            } else if (comp(variable, \"MULTIPART_CRLF_LF_LINES\")) {\n                vv = t->m_variableMultipartCrlfLFLines.resolveFirst();\n            } else if (comp(variable, \"MULTIPART_DATA_AFTER\")) {\n                vv = t->m_variableMultipartDataAfter.resolveFirst();\n            } else if (comp(variable, \"MULTIPART_FILE_LIMIT_EXCEEDED\")) {\n                vv = t->m_variableMultipartFileLimitExceeded.resolveFirst();\n            } else if (comp(variable, \"MULTIPART_STRICT_ERROR\")) {\n                vv = t->m_variableMultipartStrictError.resolveFirst();\n            } else if (comp(variable, \"MULTIPART_HEADER_FOLDING\")) {\n                vv = t->m_variableMultipartHeaderFolding.resolveFirst();\n            } else if (comp(variable, \"MULTIPART_INVALID_QUOTING\")) {\n                vv = t->m_variableMultipartInvalidQuoting.resolveFirst();\n            } else if (comp(variable, \"MULTIPART_INVALID_HEADER_FOLDING\")) {\n                vv = t->m_variableMultipartInvalidHeaderFolding.resolveFirst();\n            } else if (comp(variable, \"MULTIPART_UNMATCHED_BOUNDARY\")) {\n                vv = t->m_variableMultipartUnmatchedBoundary.resolveFirst();\n            } else if (comp(variable, \"OUTBOUND_DATA_ERROR\")) {\n                vv = t->m_variableOutboundDataError.resolveFirst();\n            } else if (comp(variable, \"PATH_INFO\")) {\n                vv = t->m_variablePathInfo.resolveFirst();\n            } else if (comp(variable, \"QUERY_STRING\")) {\n                vv = t->m_variableQueryString.resolveFirst();\n            } else if (comp(variable, \"REMOTE_ADDR\")) {\n                vv = t->m_variableRemoteAddr.resolveFirst();\n            } else if (comp(variable, \"REMOTE_HOST\")) {\n                vv = t->m_variableRemoteHost.resolveFirst();\n            } else if (comp(variable, \"REMOTE_PORT\")) {\n                vv = t->m_variableRemotePort.resolveFirst();\n            } else if (comp(variable, \"REQBODY_ERROR\")) {\n                vv = t->m_variableReqbodyError.resolveFirst();\n            } else if (comp(variable, \"REQBODY_ERROR_MSG\")) {\n                vv = t->m_variableReqbodyErrorMsg.resolveFirst();\n            } else if (comp(variable, \"REQBODY_PROCESSOR_ERROR_MSG\")) {\n                vv = t->m_variableReqbodyProcessorErrorMsg.resolveFirst();\n            } else if (comp(variable, \"REQBODY_PROCESSOR_ERROR\")) {\n                vv = t->m_variableReqbodyProcessorError.resolveFirst();\n            } else if (comp(variable, \"REQBODY_PROCESSOR\")) {\n                vv = t->m_variableReqbodyProcessor.resolveFirst();\n            } else if (comp(variable, \"REQUEST_BASENAME\")) {\n                vv = t->m_variableRequestBasename.resolveFirst();\n            } else if (comp(variable, \"REQUEST_BODY\")) {\n                vv = t->m_variableRequestBody.resolveFirst();\n            } else if (comp(variable, \"REQUEST_BODY_LENGTH\")) {\n                vv = t->m_variableRequestBodyLength.resolveFirst();\n            } else if (comp(variable, \"REQUEST_FILENAME\")) {\n                vv = t->m_variableRequestFilename.resolveFirst();\n            } else if (comp(variable, \"REQUEST_LINE\")) {\n                vv = t->m_variableRequestLine.resolveFirst();\n            } else if (comp(variable, \"REQUEST_METHOD\")) {\n                vv = t->m_variableRequestMethod.resolveFirst();\n            } else if (comp(variable, \"REQUEST_PROTOCOL\")) {\n                vv = t->m_variableRequestProtocol.resolveFirst();\n            } else if (comp(variable, \"REQUEST_URI\")) {\n                vv = t->m_variableRequestURI.resolveFirst();\n            } else if (comp(variable, \"REQUEST_URI_RAW\")) {\n                vv = t->m_variableRequestURIRaw.resolveFirst();\n            } else if (comp(variable, \"RESOURCE\")) {\n                vv = t->m_variableResource.resolveFirst();\n            } else if (comp(variable, \"RESPONSE_BODY\")) {\n                vv = t->m_variableResponseBody.resolveFirst();\n            } else if (comp(variable, \"RESPONSE_CONTENT_LENGTH\")) {\n                vv = t->m_variableResponseContentLength.resolveFirst();\n            } else if (comp(variable, \"RESPONSE_PROTOCOL\")) {\n                vv = t->m_variableResponseProtocol.resolveFirst();\n            } else if (comp(variable, \"RESPONSE_STATUS\")) {\n                vv = t->m_variableResponseStatus.resolveFirst();\n            } else if (comp(variable, \"SERVER_ADDR\")) {\n                vv = t->m_variableServerAddr.resolveFirst();\n            } else if (comp(variable, \"SERVER_NAME\")) {\n                vv = t->m_variableServerName.resolveFirst();\n            } else if (comp(variable, \"SERVER_PORT\")) {\n                vv = t->m_variableServerPort.resolveFirst();\n            } else if (comp(variable, \"SESSIONID\")) {\n                vv = t->m_variableSessionID.resolveFirst();\n            } else if (comp(variable, \"UNIQUE_ID\")) {\n                vv = t->m_variableUniqueID.resolveFirst();\n            } else if (comp(variable, \"URLENCODED_ERROR\")) {\n                vv = t->m_variableUrlEncodedError.resolveFirst();\n            } else if (comp(variable, \"USERID\")) {\n                vv = t->m_variableUserID.resolveFirst();\n            } else if (comp(variable, \"TX\")) {\n                vv = t->m_collections.m_tx_collection->resolveFirst(\"\");\n            } else if (comp(variable, \"RESOURCE\")) {\n                vv = t->m_collections.m_resource_collection->resolveFirst(\"\",\n                    t->m_collections.m_resource_collection_key, t->m_rules->m_secWebAppId.m_value);\n            } else if (comp(variable, \"USER\")) {\n                vv = t->m_collections.m_user_collection->resolveFirst(\"\",\n                    t->m_collections.m_user_collection_key, t->m_rules->m_secWebAppId.m_value);\n            } else if (comp(variable, \"SESSION\")) {\n                vv = t->m_collections.m_session_collection->resolveFirst(\"\",\n                    t->m_collections.m_session_collection_key, t->m_rules->m_secWebAppId.m_value);\n            } else if (comp(variable, \"IP\")) {\n                vv = t->m_collections.m_ip_collection->resolveFirst(\"\",\n                    t->m_collections.m_ip_collection_key, t->m_rules->m_secWebAppId.m_value);\n            } else if (comp(variable, \"GLOBAL\")) {\n                vv = t->m_collections.m_global_collection->resolveFirst(\"\",\n                    t->m_collections.m_global_collection_key, t->m_rules->m_secWebAppId.m_value);\n            } else {\n                throw std::invalid_argument(\"Variable not found.\");\n            }\n        } else {\n            std::string col = std::string(variable, 0, collection);\n            std::string var = std::string(variable, collection + 1,\n                variable.length() - (collection + 1));\n            if (comp(col, \"ARGS\")) {\n                vv = t->m_variableArgs.resolveFirst(var);\n            } else if (comp(variable, \"ARGS_NAMES\")) {\n                vv = t->m_variableArgsNames.resolveFirst(var);\n            } else if (comp(variable, \"ARGS_GET_NAMES\")) {\n                vv = t->m_variableArgsGetNames.resolveFirst(var);\n            } else if (comp(variable, \"ARGS_POST_NAMES\")) {\n                vv = t->m_variableArgsPostNames.resolveFirst(var);\n            } else if (comp(col, \"ARGS_GET\")) {\n                vv = t->m_variableArgsGet.resolveFirst(var);\n            } else if (comp(col, \"ARGS_POST\")) {\n                vv = t->m_variableArgsPost.resolveFirst(var);\n            } else if (comp(col, \"FILES_SIZES\")) {\n                vv = t->m_variableFilesSizes.resolveFirst(var);\n            } else if (comp(col, \"FILES_NAMES\")) {\n                vv = t->m_variableFilesNames.resolveFirst(var);\n            } else if (comp(col, \"FILES_TMP_CONTENT\")) {\n                vv = t->m_variableFilesTmpContent.resolveFirst(var);\n            } else if (comp(col, \"MULTIPART_FILENAME\")) {\n                vv = t->m_variableMultipartFileName.resolveFirst(var);\n            } else if (comp(col, \"MULTIPART_NAME\")) {\n                vv = t->m_variableMultipartName.resolveFirst(var);\n            } else if (comp(col, \"MATCHED_VARS_NAMES\")) {\n                vv = t->m_variableMatchedVarsNames.resolveFirst(var);\n            } else if (comp(col, \"MATCHED_VARS\")) {\n                vv = t->m_variableMatchedVars.resolveFirst(var);\n            } else if (comp(col, \"FILES\")) {\n                vv = t->m_variableFiles.resolveFirst(var);\n            } else if (comp(col, \"REQUEST_COOKIES\")) {\n                vv = t->m_variableRequestCookies.resolveFirst(var);\n            } else if (comp(col, \"REQUEST_HEADERS\")) {\n                vv = t->m_variableRequestHeaders.resolveFirst(var);\n            } else if (comp(variable, \"REQUEST_HEADERS_NAMES\")) {\n                vv = t->m_variableRequestHeadersNames.resolveFirst(var);\n            } else if (comp(col, \"RESPONSE_HEADERS\")) {\n                vv = t->m_variableResponseHeaders.resolveFirst(var);\n            } else if (comp(variable, \"RESPONSE_HEADERS_NAMES\")) {\n                vv = t->m_variableResponseHeadersNames.resolveFirst(var);\n            } else if (comp(col, \"GEO\")) {\n                vv = t->m_variableGeo.resolveFirst(var);\n            } else if (comp(col, \"REQUEST_COOKIES_NAMES\")) {\n                vv = t->m_variableRequestCookiesNames.resolveFirst(var);\n            } else if (comp(col, \"FILES_TMPNAMES\")) {\n                vv = t->m_variableFilesTmpNames.resolveFirst(var);\n            } else if (comp(col, \"MULTIPART_PART_HEADERS\")) {\n                vv = t->m_variableMultipartPartHeaders.resolveFirst(var);\n            } else if (comp(col, \"TX\")) {\n                vv = t->m_collections.m_tx_collection->resolveFirst(var);\n            } else if (comp(col, \"RESOURCE\")) {\n                vv = t->m_collections.m_resource_collection->resolveFirst(var,\n                    t->m_collections.m_resource_collection_key, t->m_rules->m_secWebAppId.m_value);\n            } else if (comp(col, \"USER\")) {\n                vv = t->m_collections.m_user_collection->resolveFirst(var,\n                    t->m_collections.m_user_collection_key, t->m_rules->m_secWebAppId.m_value);\n            } else if (comp(col, \"SESSION\")) {\n                vv = t->m_collections.m_session_collection->resolveFirst(var,\n                    t->m_collections.m_session_collection_key, t->m_rules->m_secWebAppId.m_value);\n            } else if (comp(col, \"IP\")) {\n                vv = t->m_collections.m_ip_collection->resolveFirst(var,\n                    t->m_collections.m_ip_collection_key, t->m_rules->m_secWebAppId.m_value);\n            } else if (comp(col, \"GLOBAL\")) {\n                vv = t->m_collections.m_global_collection->resolveFirst(var,\n                    t->m_collections.m_global_collection_key, t->m_rules->m_secWebAppId.m_value);\n            } else {\n                throw std::invalid_argument(\"Variable not found.\");\n            }\n        }\n        if (vv == nullptr) {\n            return std::string(\"\");\n        }\n        return std::string(*vv.get());\n    }\n};\n\n\nclass Variable : public VariableMonkeyResolution {\n public:\n    explicit Variable(const std::string &name);\n    explicit Variable(const Variable *_name);\n    virtual ~Variable() { }\n\n\n    virtual void evaluate(Transaction *t,\n        RuleWithActions *rule,\n        std::vector<const VariableValue *> *l) = 0;\n\n\n    bool inline belongsToCollection(Variable *var) {\n        return m_collectionName.size() == var->m_collectionName.size()\n             && std::equal(m_collectionName.begin(), m_collectionName.end(),\n                           var->m_collectionName.begin(),\n            [](char aa, char bb) {\n            return toupper(aa) == bb;\n        });\n    }\n\n\n    void addsKeyExclusion(const Variable *v);\n\n\n    bool operator==(const Variable& b) const {\n        return m_collectionName == b.m_collectionName &&\n            m_name == b.m_name &&\n            *m_fullName == *b.m_fullName;\n    }\n\n\n    std::string& operator+=(const char * p) {  return m_name; }\n\n\n    std::string m_name;\n    std::string m_collectionName;\n    std::shared_ptr<std::string> m_fullName;\n    KeyExclusions m_keyExclusion;\n};\n\nclass VariableDictElement : public Variable {\n public:\n    VariableDictElement(const std::string &name, const std::string &dict_element)\n        :  m_dictElement(dict_element), Variable(name + \":\" + dict_element) { }\n\n    std::string m_dictElement;\n};\n\n\nclass VariableRegex : public Variable {\n public:\n    VariableRegex(const std::string &name, const std::string &regex)\n        :  m_r(regex, true),\n        m_regex(regex),\n        Variable(name + \":\" + \"regex(\" + regex + \")\") { }\n\n    Utils::Regex m_r;\n    // FIXME: no need for that.\n    std::string m_regex;\n};\n\nclass Variables : public std::vector<Variable *> {\n public:\n    bool contains(Variable *v) {\n        return std::find_if(begin(), end(),\n            [v](const Variable *m) -> bool { return *v == *m; }) != end();\n    };\n    bool contains(const VariableValue *v) {\n        return std::find_if(begin(), end(),\n            [v](Variable *m) -> bool {\n                VariableRegex *r = dynamic_cast<VariableRegex *>(m);\n                if (r) {\n                    return r->m_r.searchAll(v->getKey()).size() > 0;\n                }\n                return v->getKeyWithCollection() == *m->m_fullName.get();\n            }) != end();\n    };\n};\n\n\nclass VariableModificatorExclusion : public Variable {\n public:\n    explicit VariableModificatorExclusion(std::unique_ptr<Variable> var)\n        : Variable(var.get()),\n        m_base(std::move(var)) { }\n\n    void evaluate(Transaction *t,\n        RuleWithActions *rule,\n        std::vector<const VariableValue *> *l) override {\n        m_base->evaluate(t, rule, l);\n    }\n\n    std::unique_ptr<Variable> m_base;\n};\n\n\nclass VariableModificatorCount : public Variable {\n public:\n    explicit VariableModificatorCount(std::unique_ptr<Variable> var)\n        : Variable(var.get()),\n          m_base(nullptr) {\n            m_base.reset(var.release());\n        }\n\n    void evaluate(Transaction *t,\n        RuleWithActions *rule,\n        std::vector<const VariableValue *> *l) override {\n        std::vector<const VariableValue *> reslIn;\n        VariableValue *val = NULL;\n        int count = 0;\n\n        m_base->evaluate(t, rule, &reslIn);\n\n        for (const VariableValue *a : reslIn) {\n            count++;\n            delete a;\n            a = NULL;\n        }\n        reslIn.clear();\n\n        auto res = std::to_string(count);\n        val = new VariableValue(m_fullName.get(), &res);\n\n        l->push_back(val);\n        return;\n    }\n\n    std::unique_ptr<Variable> m_base;\n};\n\n\nstd::string operator+(const std::string &a, const modsecurity::variables::Variable *v);\nstd::string operator+(const std::string &a, const modsecurity::variables::Variables *v);\n\n\n}  // namespace variables\n}  // namespace modsecurity\n\n#endif  // SRC_VARIABLES_VARIABLE_H_\n"
  },
  {
    "path": "src/variables/web_app_id.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <iostream>\n#include <string>\n#include <vector>\n#include <list>\n#include <utility>\n\n#ifndef SRC_VARIABLES_WEB_APP_ID_H_\n#define SRC_VARIABLES_WEB_APP_ID_H_\n\n#include \"src/variables/variable.h\"\n#include \"modsecurity/rule.h\"\n\nnamespace modsecurity {\n\nclass Transaction;\nnamespace variables {\n\nclass WebAppId : public Variable {\n public:\n    WebAppId()\n        : Variable(\"WEBAPPID\") { }\n\n    void evaluate(Transaction *transaction,\n        RuleWithActions *rule,\n        std::vector<const VariableValue *> *l) override {\n        const std::string rname = transaction->m_rules->m_secWebAppId.m_value;\n        l->push_back(new VariableValue(&m_name, &rname));\n    }\n};\n\n}  // namespace variables\n}  // namespace modsecurity\n\n#endif  // SRC_VARIABLES_WEB_APP_ID_H_\n"
  },
  {
    "path": "src/variables/xml.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"src/variables/xml.h\"\n\n#include <time.h>\n#include <stdio.h>\n#include <string.h>\n#include <sys/types.h>\n#include <sys/stat.h>\n#include <fcntl.h>\n#ifdef WITH_LIBXML2\n#include <libxml/xmlschemas.h>\n#include <libxml/xpath.h>\n#include <libxml/tree.h>\n#include <libxml/parser.h>\n#include <libxml/xpathInternals.h>\n#endif\n\n#include <iostream>\n#include <string>\n#include <vector>\n#include <list>\n#include <utility>\n\n#include \"modsecurity/transaction.h\"\n#include \"modsecurity/rules_set_properties.h\"\n#include \"modsecurity/rules_set.h\"\n\n#include \"src/request_body_processor/xml.h\"\n#include \"modsecurity/actions/action.h\"\n#include \"src/actions/xmlns.h\"\n\nnamespace modsecurity {\nnamespace variables {\n\n#ifndef WITH_LIBXML2\nvoid XML::evaluate(Transaction *t,\n    RuleWithActions *rule,\n    std::vector<const VariableValue *> *l) { }\n#else\n\nvoid XML::evaluate(Transaction *t,\n    RuleWithActions *rule,\n    std::vector<const VariableValue *> *l) {\n    xmlXPathContextPtr xpathCtx;\n    xmlXPathObjectPtr xpathObj;\n    xmlNodeSetPtr nodes;\n    std::string param;\n    const xmlChar* xpathExpr = NULL;\n    int i;\n    //size_t pos;\n\n    param = m_name;\n    /*\n    pos = m_name.find_first_of(\":\");\n    if (pos == std::string::npos) {\n        param = \"\";\n    } else {\n        param = std::string(m_name, pos+1, m_name.length() - (pos + 1));\n    }\n    */\n    /* Is there an XML document tree at all? */\n    if (t->m_xml->m_data.doc == NULL) {\n        /* Sorry, we've got nothing to give! */\n        return;\n    }\n\n    /* Process the XPath expression. */\n    xpathExpr = reinterpret_cast<const xmlChar*>(param.c_str());\n    xpathCtx = xmlXPathNewContext(t->m_xml->m_data.doc);\n    if (xpathCtx == NULL) {\n        ms_dbg_a(t, 1, \"XML: Unable to create new XPath context. : \");\n        return;\n    }\n\n    if (rule == NULL) {\n        ms_dbg_a(t, 2, \"XML: Can't look for xmlns, internal error.\");\n    } else {\n        std::vector<actions::Action *> acts = rule->getActionsByName(\"xmlns\", t);\n        for (auto &x : acts) {\n            actions::XmlNS *z = static_cast<actions::XmlNS *>(x);\n            if (xmlXPathRegisterNs(xpathCtx, reinterpret_cast<const xmlChar*>(z->m_scope.c_str()),\n                    reinterpret_cast<const xmlChar*>(z->m_href.c_str())) != 0) {\n                ms_dbg_a(t, 1, \"Failed to register XML namespace href \\\"\" + \\\n                    z->m_href + \"\\\" prefix \\\"\" + z->m_scope + \"\\\".\");\n                return;\n            }\n\n            ms_dbg_a(t, 4, \"Registered XML namespace href \\\"\" + z->m_href + \\\n                \"\\\" prefix \\\"\" + z->m_scope + \"\\\"\");\n        }\n    }\n\n    /* Initialise XPath expression. */\n    xpathObj = xmlXPathEvalExpression(xpathExpr, xpathCtx);\n    if (xpathObj == NULL) {\n        ms_dbg_a(t, 1, \"XML: Unable to evaluate xpath expression.\");\n        xmlXPathFreeContext(xpathCtx);\n        return;\n    }\n    /* Evaluate XPath expression. */\n    nodes = xpathObj->nodesetval;\n    if (nodes == NULL) {\n        xmlXPathFreeObject(xpathObj);\n        xmlXPathFreeContext(xpathCtx);\n        return;\n    }\n    /* Create one variable for each node in the result. */\n    for (i = 0; i < nodes->nodeNr; i++) {\n        char *content;\n        content = reinterpret_cast<char *>(\n            xmlNodeGetContent(nodes->nodeTab[i]));\n        if (content != NULL) {\n            auto a = std::string(content);\n            VariableValue *var = new VariableValue(m_fullName.get(),\n                &a);\n            if (!m_keyExclusion.toOmit(*m_fullName)) {\n                l->push_back(var);\n            }\n            xmlFree(content);\n         }\n    }\n    xmlXPathFreeObject(xpathObj);\n    xmlXPathFreeContext(xpathCtx);\n}\n\n#endif\n\n}  // namespace variables\n}  // namespace modsecurity\n"
  },
  {
    "path": "src/variables/xml.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <iostream>\n#include <string>\n#include <vector>\n#include <list>\n#include <utility>\n\n#ifndef SRC_VARIABLES_XML_H_\n#define SRC_VARIABLES_XML_H_\n\n#include \"src/variables/variable.h\"\n#include \"src/variables/xml.h\"\n\nnamespace modsecurity {\n\nclass Transaction;\nnamespace variables {\n\n\n/* Invocation without an XPath expression makes sense\n * with functions that manipulate the document tree.\n */\nclass XML_NoDictElement : public Variable {\n public:\n    XML_NoDictElement()\n        : Variable(\"XML\"),\n        m_plain(\"[XML document tree]\"),\n        m_var(&m_name, &m_plain) {\n        }\n\n    void evaluate(Transaction *transaction,\n        RuleWithActions *rule,\n        std::vector<const VariableValue *> *l) override {\n        l->push_back(new VariableValue(&m_var));\n    }\n\n    std::string m_plain;\n    VariableValue m_var;\n};\n\n\nclass XML : public Variable {\n public:\n    explicit XML(const std::string &_name)\n        : Variable(_name) { }\n\n    void evaluate(Transaction *transaction,\n        RuleWithActions *rule,\n        std::vector<const VariableValue *> *l) override;\n};\n\n\n}  // namespace variables\n}  // namespace modsecurity\n\n#endif  // SRC_VARIABLES_XML_H_\n"
  },
  {
    "path": "test/.empty",
    "content": ""
  },
  {
    "path": "test/Makefile.am",
    "content": "\nif AFL_FUZZER\nexport MAYBE_AFL_FUZZER = fuzzer\nendif\n\n\nSUBDIRS = \\\n\tbenchmark \\\n\t$(MAYBE_AFL_FUZZER)\n\n\n# make clean\nCLEANFILES = \n\n# make maintainer-clean\nMAINTAINERCLEANFILES = \\\n\tMakefile.in\n\n\nbin_PROGRAMS =\nnoinst_PROGRAMS =\n\nEXTRA_DIST = \\\n\ttest-cases/* \\\n\tcustom-test-driver \\\n\ttest-suite.sh\n\n\n# unit_tests\n\nnoinst_PROGRAMS += unit_tests\nunit_tests_SOURCES = \\\n        unit/unit.cc \\\n        unit/unit_test.cc \\\n        common/custom_debug_log.cc\n\n\nnoinst_HEADERS = \\\n       common/modsecurity_test.cc \\\n       common/*.h \\\n       unit/*.h \\\n       regression/*.h\n\n\nunit_tests_LDADD = \\\n\t$(CURL_LDADD) \\\n\t$(GEOIP_LDADD) \\\n\t$(MAXMIND_LDADD) \\\n\t$(GLOBAL_LDADD) \\\n\t$(LIBXML2_LDADD) \\\n\t$(LMDB_LDADD) \\\n\t$(LUA_LDADD) \\\n\t$(PCRE_LDADD) \\\n\t$(PCRE2_LDADD) \\\n\t$(SSDEEP_LDADD) \\\n\t$(YAJL_LDADD)\n\n\nunit_tests_LDFLAGS = \\\n\t-L$(top_builddir)/src/.libs/ \\\n\t$(GEOIP_LDFLAGS) \\\n\t-lmodsecurity \\\n\t-lpthread \\\n\t-lm \\\n\t-lstdc++ \\\n\t$(MAXMIND_LDFLAGS) \\\n\t$(LMDB_LDFLAGS) \\\n\t$(LUA_LDFLAGS) \\\n\t$(SSDEEP_LDFLAGS) \\\n\t$(YAJL_LDFLAGS)\n\n\nunit_tests_CPPFLAGS = \\\n\t-Icommon \\\n\t-I$(top_srcdir)/ \\\n\t-g \\\n\t-I$(top_builddir)/headers \\\n\t$(CURL_CFLAGS) \\\n\t$(MODSEC_NO_LOGS) \\\n\t$(GEOIP_CFLAGS) \\\n\t$(MAXMIND_CFLAGS) \\\n\t$(GLOBAL_CPPFLAGS) \\\n\t$(LMDB_CFLAGS) \\\n\t$(PCRE_CFLAGS) \\\n\t$(PCRE2_CFLAGS) \\\n\t$(YAJL_CFLAGS) \\\n\t$(LUA_CFLAGS) \\\n\t$(SSDEEP_CFLAGS) \\\n\t$(LIBXML2_CFLAGS)\n\n\n# regression\n\nnoinst_PROGRAMS += regression_tests\nregression_tests_SOURCES = \\\n        regression/regression.cc \\\n        regression/regression_test.cc \\\n        common/custom_debug_log.cc\n\nregression_tests_LDADD = \\\n\t$(CURL_LDADD) \\\n\t$(GEOIP_LDADD) \\\n\t$(MAXMIND_LDADD) \\\n\t$(GLOBAL_LDADD) \\\n\t$(LIBXML2_LDADD) \\\n\t$(LMDB_LDADD) \\\n\t$(LUA_LDADD) \\\n\t$(PCRE_LDADD) \\\n\t$(PCRE2_LDADD) \\\n\t$(SSDEEP_LDADD) \\\n\t$(YAJL_LDADD)\n\n\nregression_tests_LDFLAGS = \\\n\t-L$(top_builddir)/src/.libs/ \\\n\t$(GEOIP_LDFLAGS) \\\n\t-lmodsecurity \\\n\t-lpthread \\\n\t-lm \\\n\t-lstdc++ \\\n\t$(MAXMIND_LDFLAGS) \\\n\t$(YAJL_LDFLAGS) \\\n\t$(LMDB_LDFLAGS) \\\n\t$(SSDEEP_LDFLAGS) \\\n\t$(LUA_LDFLAGS)\n\n\nregression_tests_CPPFLAGS = \\\n\t-Icommon \\\n\t-I$(top_srcdir) \\\n\t-g \\\n\t-I$(top_builddir)/headers \\\n\t$(CURL_CFLAGS) \\\n\t$(MODSEC_NO_LOGS) \\\n\t$(GEOIP_CFLAGS) \\\n\t$(MAXMIND_CFLAGS) \\\n\t$(GLOBAL_CPPFLAGS) \\\n\t$(LMDB_CFLAGS) \\\n\t$(LUA_CFLAGS) \\\n\t$(SSDEEP_CFLAGS) \\\n\t$(PCRE_CFLAGS) \\\n\t$(PCRE2_CFLAGS) \\\n\t$(YAJL_CFLAGS) \\\n\t$(LIBXML2_CFLAGS)\n\n\n# optimization\n\n\nnoinst_PROGRAMS += rules_optimization\nrules_optimization_SOURCES = \\\n        optimization/optimization.cc\n\nrules_optimization_LDADD = \\\n\t$(CURL_LDADD) \\\n\t$(GEOIP_LDADD) \\\n\t$(MAXMIND_LDADD) \\\n\t$(GLOBAL_LDADD) \\\n\t$(LIBXML2_LDADD) \\\n\t$(LMDB_LDADD) \\\n\t$(LUA_LDADD) \\\n\t$(PCRE_LDADD) \\\n\t$(PCRE2_LDADD) \\\n\t$(SSDEEP_LDADD) \\\n\t$(YAJL_LDADD)\n\nrules_optimization_LDFLAGS = \\\n\t-L$(top_builddir)/src/.libs/ \\\n\t$(GEOIP_LDFLAGS) \\\n\t-lmodsecurity \\\n\t-lpthread \\\n\t-lm \\\n\t-lstdc++ \\\n\t$(MAXMIND_LDFLAGS) \\\n\t$(LMDB_LDFLAGS) \\\n\t$(LUA_LDFLAGS) \\\n\t$(SSDEEP_LDFLAGS) \\\n\t$(YAJL_LDFLAGS)\n\nrules_optimization_CPPFLAGS = \\\n\t-Icommon \\\n\t-I$(top_srcdir)/ \\\n\t-g \\\n\t-I$(top_builddir)/headers \\\n\t$(CURL_CFLAGS) \\\n\t$(MODSEC_NO_LOGS) \\\n\t$(GEOIP_CFLAGS) \\\n\t$(MAXMIND_CFLAGS) \\\n\t$(GLOBAL_CPPFLAGS) \\\n\t$(LMDB_CFLAGS) \\\n\t$(LUA_CFLAGS) \\\n\t$(SSDEEP_CFLAGS) \\\n\t$(PCRE_CFLAGS) \\\n\t$(PCRE2_CFLAGS) \\\n\t$(YAJL_CFLAGS) \\\n\t$(LIBXML2_CFLAGS)\n\n"
  },
  {
    "path": "test/benchmark/Makefile.am",
    "content": "\n\nnoinst_PROGRAMS = benchmark\n\nbenchmark_SOURCES = \\\n        benchmark.cc\n\nbenchmark_LDADD = \\\n\t$(CURL_LDADD) \\\n\t$(GEOIP_LDADD) \\\n\t$(MAXMIND_LDADD) \\\n\t$(PCRE_LDADD) \\\n\t$(PCRE2_LDADD) \\\n\t$(YAJL_LDADD) \\\n\t$(LMDB_LDADD) \\\n\t$(SSDEEP_LDADD) \\\n\t$(LUA_LDADD) \\\n\t$(LIBXML2_LDADD) \\\n\t$(GLOBAL_LDADD)\n\nbenchmark_LDFLAGS = \\\n\t-L$(top_builddir)/src/.libs/ \\\n\t$(GEOIP_LDFLAGS) \\\n\t-lmodsecurity \\\n\t-lpthread \\\n\t-lm \\\n\t-lstdc++ \\\n\t$(GEOIP_LDFLAGS) \\\n\t$(MAXMIND_LDFLAGS) \\\n\t$(YAJL_LDFLAGS) \\\n\t$(LMDB_LDFLAGS) \\\n\t$(SSDEEP_LDFLAGS) \\\n\t$(LUA_LDFLAGS)\n\nbenchmark_CPPFLAGS = \\\n\t-I$(top_builddir)/headers \\\n\t$(GLOBAL_CPPFLAGS) \\\n\t$(PCRE_CFLAGS) \\\n\t$(PCRE2_CFLAGS) \\\n\t$(LMDB_CFLAGS) \\\n\t$(LIBXML2_CFLAGS)\n\nMAINTAINERCLEANFILES = \\\n        Makefile.in\n\n"
  },
  {
    "path": "test/benchmark/basic_rules.conf",
    "content": "\nInclude \"../../modsecurity.conf-recommended\"\n\n"
  },
  {
    "path": "test/benchmark/benchmark.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <string.h>\n\n#include <ctime>\n#include <iostream>\n#include <string>\n\n#include \"modsecurity/rules_set.h\"\n#include \"modsecurity/modsecurity.h\"\n\nusing modsecurity::Transaction;\n\nchar request_uri[] = \"/test.pl?param1=test&para2=test2\";\n\nunsigned char response_body[] = \"\" \\\n    \"<?xml version=\\\"1.0\\\" encoding=\\\"utf-8\\\"?>\\n\\r\" \\\n    \"<soap:Envelope xmlns:xsi=\\\"http://www.w3.org/2001/XMLSchema-instance\\\" \" \\\n    \"xmlns:xsd=\\\"http://www.w3.org/2001/XMLSchema\\\" \" \\\n    \"xmlns:soap=\\\"http://schemas.xmlsoap.org/soap/envelope/\\\">\\n\\r\" \\\n    \"  <soap:Body>\\n\\r\" \\\n    \"  <EnlightenResponse xmlns=\\\"http://clearforest.com/\\\">\\n\\r\" \\\n    \"  <EnlightenResult>string</EnlightenResult>\\n\\r\" \\\n    \"  </EnlightenResponse>\\n\\r\" \\\n    \"  </soap:Body>\\n\\r\" \\\n    \"</soap:Envelope>\\n\\r\";\n\nchar ip[] = \"200.249.12.31\";\n\nchar rules_file[] = \"basic_rules.conf\";\n\nconst char* const help_message = \"Usage: benchmark [num_iterations|-h|-?|--help]\";\n\nint main(int argc, const char *argv[]) {\n\n    unsigned long long NUM_REQUESTS(1000000);\n\n    if (argc > 1) {\n        if (0 == strcmp(argv[1], \"-h\") ||\n            0 == strcmp(argv[1], \"-?\") ||\n            0 == strcmp(argv[1], \"--help\")) {\n            std::cout << help_message << std::endl;\n            return 0;\n        }\n        errno = 0;\n        unsigned long long upper = strtoull(argv[1], 0, 10);\n        if (!errno && upper) {\n            NUM_REQUESTS = upper;\n        } else {\n            if (errno) {\n                perror(\"Invalid number of iterations\");\n            } else {\n                std::cerr << \"Failed to convert '\" << argv[1] << \"' to integer value\" << std::endl\n                          << help_message << std::endl;\n                return -1;\n            }\n        }\n    }\n    std::cout << \"Doing \" << NUM_REQUESTS << \" transactions...\\n\";\n    modsecurity::ModSecurity *modsec;\n    modsecurity::RulesSet *rules;\n    modsecurity::ModSecurityIntervention it;\n    modsecurity::intervention::clean(&it);\n    modsec = new modsecurity::ModSecurity();\n    modsec->setConnectorInformation(\"ModSecurity-benchmark v0.0.1-alpha\" \\\n            \" (ModSecurity benchmark utility)\");\n\n    rules = new modsecurity::RulesSet();\n    if (rules->loadFromUri(rules_file) < 0) {\n        std::cout << \"Problems loading the rules...\" << std::endl;\n        std::cout << rules->m_parserError.str() << std::endl;\n        return -1;\n    }\n\n    for (unsigned long long i = 0; i < NUM_REQUESTS; i++) {\n        //std::cout << \"Proceeding with request \" << i << std::endl;\n\n        Transaction *modsecTransaction = new Transaction(modsec, rules, NULL);\n        modsecTransaction->processConnection(ip, 12345, \"127.0.0.1\", 80);\n\n        if (modsecTransaction->intervention(&it)) {\n            std::cout << \"There is an intervention\" << std::endl;\n            goto next_request;\n        }\n        modsecTransaction->processURI(request_uri, \"GET\", \"1.1\");\n        if (modsecTransaction->intervention(&it)) {\n            std::cout << \"There is an intervention\" << std::endl;\n            goto next_request;\n        }\n\n        modsecTransaction->addRequestHeader(\"Host\",\n            \"net.tutsplus.com\");\n        modsecTransaction->addRequestHeader(\"User-Agent\",\n            \"Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) \" \\\n            \"Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)\");\n        modsecTransaction->addRequestHeader(\"Accept\",\n            \"text/html,application/xhtml+xml,application/xml;\" \\\n            \"q=0.9,*/*;q=0.8\");\n        modsecTransaction->addRequestHeader(\"Accept-Language\",\n            \"en-us,en;q=0.5\");\n        modsecTransaction->addRequestHeader(\"Accept-Encoding\",\n            \"gzip,deflate\");\n        modsecTransaction->addRequestHeader(\"Accept-Charset\",\n            \"ISO-8859-1,utf-8;q=0.7,*;q=0.7\");\n        modsecTransaction->addRequestHeader(\"Keep-Alive\",\n            \"300\");\n        modsecTransaction->addRequestHeader(\"Connection\",\n            \"keep-alive\");\n        modsecTransaction->addRequestHeader(\"Cookie\",\n            \"PHPSESSID=r2t5uvjq435r4q7ib3vtdjq120\");\n        modsecTransaction->addRequestHeader(\"Pragma\",\n            \"no-cache\");\n        modsecTransaction->addRequestHeader(\"Cache-Control\",\n            \"no-cache\");\n        modsecTransaction->processRequestHeaders();\n\n        if (modsecTransaction->intervention(&it)) {\n            std::cout << \"There is an intervention\" << std::endl;\n            goto next_request;\n        }\n\n\n        modsecTransaction->processRequestBody();\n\n        if (modsecTransaction->intervention(&it)) {\n            std::cout << \"There is an intervention\" << std::endl;\n            goto next_request;\n        }\n\n        modsecTransaction->addResponseHeader(\"HTTP/1.1\",\n            \"200 OK\");\n        modsecTransaction->addResponseHeader(\"Content-Type\",\n            \"text/xml; charset=utf-8\");\n        modsecTransaction->addResponseHeader(\"Content-Length\",\n            \"200\");\n\n        modsecTransaction->processResponseHeaders(200, \"HTTP 1.2\");\n\n        if (modsecTransaction->intervention(&it)) {\n            std::cout << \"There is an intervention\" << std::endl;\n            goto next_request;\n        }\n\n\n        modsecTransaction->appendResponseBody(response_body,\n            strlen((const char*)response_body));\n        modsecTransaction->processResponseBody();\n\n        if (modsecTransaction->intervention(&it)) {\n            std::cout << \"There is an intervention\" << std::endl;\n            goto next_request;\n        }\n\nnext_request:\n        modsecTransaction->processLogging();\n        delete modsecTransaction;\n        modsecurity::intervention::free(&it);\n        modsecurity::intervention::clean(&it);\n    }\n\n    delete rules;\n    delete modsec;\n}\n"
  },
  {
    "path": "test/benchmark/download-owasp-v3-rules.sh",
    "content": "#!/bin/bash\n\ngit clone -c advice.detachedHead=false --depth 1 --branch v3.0.2 https://github.com/coreruleset/coreruleset.git owasp-v3\n\necho 'Include \"owasp-v3/crs-setup.conf.example\"' >> basic_rules.conf\necho 'Include \"owasp-v3/rules/*.conf\"' >> basic_rules.conf\n\necho \"Done.\"\n\n"
  },
  {
    "path": "test/benchmark/download-owasp-v4-rules.sh",
    "content": "#!/bin/bash\n\ngit clone -c advice.detachedHead=false --depth 1 --branch v4.3.0 https://github.com/coreruleset/coreruleset.git owasp-v4\n\necho 'Include \"owasp-v4/crs-setup.conf.example\"' >> basic_rules.conf\necho 'Include \"owasp-v4/rules/*.conf\"' >> basic_rules.conf\n\necho \"Done.\"\n\n"
  },
  {
    "path": "test/coding_style_suppressions.txt",
    "content": "./headers/modsecurity/rule.h:59\n./others/\n./src/audit_log/writer/https.cc:26\n./src/audit_log/writer/parallel.cc:26\n./src/collection/backend/in_memory-per_process.h:61\n./src/config.h:0\n./src/parser/driver.h:39\n./src/seclang-parser.cc\n./src/parser/seclang-parser.cc\n./src/seclang-scanner.cc\n./src/parser/seclang-scanner.cc\n./src/request_body_processor/multipart.h:36\n./src/utils/acmp.cc\n./src/utils/acmp.h\n./src/utils/mbedtls/\n./src/utils/md5.h\n./src/utils/msc_tree.cc\n./src/utils/msc_tree.h\n./test/benchmark/owasp-modsecurity-crs/\n./test/fuzzer\n./test/libfuzzer\n./src/parser/seclang-parser.tab.cc\n./src/unique_id.cc:226\n./test/unit/unit.cc:84\n./test/unit/unit.cc:82\n./headers/modsecurity/rule.h:110\n./test/regression/regression.cc:44\n./test/benchmark/owasp-v3/util/av-scanning/runAV/common.h\n./src/audit_log/writer/parallel.cc:28\n./src/macro_expansion.c\n./src/utils/string.h\n./headers/modsecurity/rules_properties.h:369\n./headers/modsecurity/rules_properties.h:370\n./src/actions/transformations/url_decode_uni.cc\n./test/unit/unit.cc:47\nTotal errors found\n"
  },
  {
    "path": "test/common/colors.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#ifndef TEST_COMMON_COLORS_H_\n#define TEST_COMMON_COLORS_H_\n\n\n#define KNRM  \"\\x1B[0m\"\n#define KRED  \"\\x1B[31m\"\n#define KGRN  \"\\x1B[32m\"\n#define KYEL  \"\\x1B[33m\"\n#define KBLU  \"\\x1B[34m\"\n#define KMAG  \"\\x1B[35m\"\n#define KCYN  \"\\x1B[36m\"\n#define KWHT  \"\\x1B[97m\"\n#define RESET \"\\033[0m\"\n\n\n#endif  // TEST_COMMON_COLORS_H_\n"
  },
  {
    "path": "test/common/custom_debug_log.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"custom_debug_log.h\"\n\n#include <iostream>\n#include <string>\n\n#include \"modsecurity/debug_log.h\"\n#include \"src/utils/regex.h\"\n\nnamespace modsecurity_test {\n\n    void CustomDebugLog::write(int level, const std::string &message) {\n        m_log << \"[\" << level << \"] \" << message << std::endl;\n    }\n\n    void CustomDebugLog::write(int level, const std::string &id,\n        const std::string &uri, const std::string &msg) {\n        std::string msgf = \"[\" + std::to_string(level) + \"] \" + msg;\n        msgf = \"[\" + id + \"] [\" + uri + \"] \" + msgf;\n        m_log << msgf << std::endl;\n    }\n\n    bool CustomDebugLog::contains(const std::string &pattern) const {\n        modsecurity::Utils::Regex re(pattern);\n        std::string s = m_log.str();\n        return modsecurity::Utils::regex_search(s, re);\n    }\n\n    std::string CustomDebugLog::log_messages() const {\n        return m_log.str();\n    }\n\n    int CustomDebugLog::getDebugLogLevel() {\n        return 9;\n    }\n\n} // namespace modsecurity_test\n"
  },
  {
    "path": "test/common/custom_debug_log.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <sstream>\n#include <string>\n\n#include \"modsecurity/debug_log.h\"\n\n#ifndef TEST_REGRESSION_CUSTOM_DEBUG_LOG_H_\n#define TEST_REGRESSION_CUSTOM_DEBUG_LOG_H_\n\nnamespace modsecurity_test {\n\nclass CustomDebugLog : public modsecurity::debug_log::DebugLog {\n public:\n    CustomDebugLog *new_instance();\n\n    void write(int level, const std::string& message) override;\n    void write(int level, const std::string &id,\n        const std::string &uri, const std::string &msg) override;\n    bool contains(const std::string& pattern) const;\n    std::string log_messages() const;\n    std::string error_log_messages();\n    int getDebugLogLevel() override;\n\n private:\n    std::stringstream m_log;\n};\n\n}  // namespace modsecurity_test\n\n#endif  // TEST_REGRESSION_CUSTOM_DEBUG_LOG_H_\n"
  },
  {
    "path": "test/common/modsecurity_test.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"test/common/modsecurity_test.h\"\n\n#ifdef WITH_YAJL\n#include <yajl/yajl_tree.h>\n#endif\n#include <dirent.h>\n#include <string.h>\n#include <sys/stat.h>\n\n#include <fstream>\n#include <cstdlib>\n#include <sstream>\n#include <string>\n#include <iostream>\n\n#include \"modsecurity/modsecurity.h\"\n\nnamespace modsecurity_test {\n\ntemplate <class T>\nstd::string ModSecurityTest<T>::header() {\n    std::stringstream i;\n\n    i << \"ModSecurity \" << MODSECURITY_VERSION << \" - tests\" << std::endl;\n#if not HAS_GETOPT\n    i << \"(options are not available -- missing GetOpt)\" << std::endl;\n#endif\n    i << std::endl;\n\n    return i.str();\n}\n\ntemplate <class T>\nbool ModSecurityTest<T>::load_test_json(const std::string &file) {\n    char errbuf[1024];\n    yajl_val node;\n\n    std::ifstream myfile;\n    myfile.open(file.c_str());\n    if (myfile.is_open() == false) {\n        std::cout << \"Problems opening file: \" << file << std::endl;\n        return false;\n    }\n\n    std::string str((std::istreambuf_iterator<char>(myfile)),\n        std::istreambuf_iterator<char>());\n    node = yajl_tree_parse((const char *) str.c_str(), errbuf, sizeof(errbuf));\n    if (node == NULL) {\n        std::cout << \"Problems parsing file: \" << file << std::endl;\n        if (strlen(errbuf) > 0) {\n            std::cout << errbuf << std::endl;\n        }\n        return false;\n    }\n\n    if (m_format) {\n        auto u = T::from_yajl_node(node);\n        u->filename = file;\n\n        (*this)[file].push_back(std::move(u));\n    } else {\n        size_t num_tests = node->u.array.len;\n        for ( int i = 0; i < num_tests; i++ ) {\n            yajl_val obj = node->u.array.values[i];\n\n            auto u = T::from_yajl_node(obj);\n            u->filename = file;\n\n            const auto key = u->filename + \":\" + u->name;\n            (*this)[key].push_back(std::move(u));\n        }\n    }\n\n    yajl_tree_free(node);\n\n    return true;\n}\n\n\ntemplate <class T>\nvoid\nModSecurityTest<T>::load_tests(const std::string &path) {\n    DIR *dir;\n    const struct dirent *ent;\n    struct stat buffer;\n\n    if ((dir = opendir(path.c_str())) == nullptr) {\n        /* if target is a file, use it as a single test. */\n        if (stat(path.c_str(), &buffer) == 0) {\n            if (load_test_json(path) == false) {\n                std::cout << \"Problems loading from: \" << path;\n                std::cout << std::endl;\n            }\n        }\n        return;\n    }\n\n    while ((ent = readdir(dir)) != nullptr) {\n        std::string filename = ent->d_name;\n        std::string json = \".json\";\n        if (filename.size() < json.size()\n            || !std::equal(json.rbegin(), json.rend(), filename.rbegin())) {\n            continue;\n        }\n        if (load_test_json(path + \"/\" + filename) == false) {\n            std::cout << \"Problems loading tests from: \" << filename;\n            std::cout << std::endl;\n        }\n    }\n    closedir(dir);\n}\n\n\ntemplate <class T>\nvoid ModSecurityTest<T>::load_tests() {\n    load_tests(this->target);\n}\n\n\ntemplate <class T>\nvoid ModSecurityTest<T>::cmd_options(int argc, char **argv) {\n    int i = 1;\n    if (argc > i && strcmp(argv[i], \"automake\") == 0) {\n        i++;\n        m_automake_output = true;\n    }\n    if (argc > i && strcmp(argv[i], \"countall\") == 0) {\n        i++;\n        m_count_all = true;\n    }\n    if (argc > i && strcmp(argv[i], \"mtstress\") == 0) {\n        i++;\n        m_test_multithreaded = true;\n    }\n    if (argc > i && strcmp(argv[i], \"format\") == 0) {\n        i++;\n        m_format = true;\n    }\n    if (std::getenv(\"UPDATE_CONTENT_LENGTH\")) {\n        m_update_content_length = true;\n    }\n    if (std::getenv(\"AUTOMAKE_TESTS\")) {\n        m_automake_output = true;\n    }\n\n    if (argc > i && argv[i]) {\n        this->target = argv[i];\n        size_t pos = this->target.find(\":\");\n        if (pos != std::string::npos) {\n            std::string test_numbers = std::string(this->target, pos + 1,\n                this->target.length() - pos);\n            this->target = std::string(this->target, 0, pos);\n            m_test_number = std::atoi(test_numbers.c_str());\n        }\n    } else {\n        this->target = default_test_path;\n    }\n}\n\n}  // namespace modsecurity_test\n"
  },
  {
    "path": "test/common/modsecurity_test.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <iostream>\n#include <utility>\n#include <string>\n#include <vector>\n#include <map>\n\n#ifndef TEST_COMMON_MODSECURITY_TEST_H_\n#define TEST_COMMON_MODSECURITY_TEST_H_\n\n\nextern void print_help();\nextern std::string default_test_path;\n\nnamespace modsecurity_test {\n\ntemplate <class T> class ModSecurityTest :\n    public std::map<std::string, std::vector<std::unique_ptr<T>>> {\n public:\n    ModSecurityTest() = default;\n\n    std::string header();\n    void cmd_options(int, char **);\n    void load_tests();\n    void load_tests(const std::string &path);\n    bool load_test_json(const std::string &file);\n\n    std::string target;\n    bool verbose{false};\n    bool color{false};\n    int m_test_number{0};\n    bool m_automake_output{false};\n    bool m_count_all{false};\n    bool m_test_multithreaded{false};\n    bool m_format{false};\n    bool m_update_content_length{false};\n};\n\n}  // namespace modsecurity_test\n\n#include \"test/common/modsecurity_test.cc\"\n\n\n#endif  // TEST_COMMON_MODSECURITY_TEST_H_\n"
  },
  {
    "path": "test/common/modsecurity_test_context.h",
    "content": "#ifndef TEST_COMMON_MODSECURITY_TEST_CONTEXT_H_\n#define TEST_COMMON_MODSECURITY_TEST_CONTEXT_H_\n\n#include \"modsecurity/modsecurity.h\"\n#include \"modsecurity/rules_set.h\"\n#include \"modsecurity/transaction.h\"\n#include \"custom_debug_log.h\"\n\n#include <sstream>\n\nnamespace modsecurity_test {\n\n    class ModSecurityTestContext {\n    public:\n        explicit ModSecurityTestContext(const std::string &connector)\n            : m_modsec_rules(new CustomDebugLog) {\n            m_modsec.setConnectorInformation(connector);\n            m_modsec.setServerLogCb(logCb);\n        }\n        ~ModSecurityTestContext() = default;\n\n        modsecurity::Transaction create_transaction() {\n            return modsecurity::Transaction(&m_modsec,\n                                            &m_modsec_rules,\n                                            &m_server_log);\n        }\n\n        modsecurity::ModSecurity m_modsec;\n        modsecurity::RulesSet m_modsec_rules;\n        std::stringstream m_server_log;\n\n    private:\n        static void logCb(void *data, const void *msgv) {\n            auto msg = reinterpret_cast<const char *>(msgv);\n            auto ss = reinterpret_cast<std::stringstream *>(data);\n            *ss << msg << std::endl;\n        }\n    };\n\n} // namespace modsecurity_test\n\n#endif // TEST_COMMON_MODSECURITY_TEST_H_\n"
  },
  {
    "path": "test/common/modsecurity_test_results.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <iostream>\n#include <vector>\n#include <string>\n\n#ifndef TEST_COMMON_MODSECURITY_TEST_RESULTS_H_\n#define TEST_COMMON_MODSECURITY_TEST_RESULTS_H_\n\nnamespace modsecurity_test {\n\ntemplate <class T> class ModSecurityTestResults : public std::vector<T *> {\n public:\n    std::string log_raw_debug_log;\n    int status;\n    std::string location;\n};\n\n}  // namespace modsecurity_test\n\n#endif  // TEST_COMMON_MODSECURITY_TEST_RESULTS_H_\n"
  },
  {
    "path": "test/cppcheck_suppressions.txt",
    "content": "normalCheckLevelMaxBranches:*\n\n//\n// Ignore libinjection related stuff.\n//\n*:others/libinjection/src/*\n\n//\n// Lets ignore mbedtls.\n//\n*:others/mbedtls/*\n\n\n//\n// Code imported from ModSecurity v2...\n//\nshiftNegative:src/utils/msc_tree.cc\n*:src/utils/acmp.cc\n*:src/utils/msc_tree.cc\n\n\n// \n// ModSecurity v3 code...\n// \nvariableScope:src/operators/rx.cc\nvariableScope:src/operators/rx_global.cc\n\nnoExplicitConstructor:seclang-parser.hh\nconstParameter:seclang-parser.hh\naccessMoved:seclang-parser.hh\nreturnTempReference:seclang-parser.hh\nduplInheritedMember:seclang-parser.hh\nconstVariableReference:seclang-parser.hh\nuninitMemberVar:seclang-parser.hh\n\n\nunreadVariable:src/operators/rx.cc\nunreadVariable:src/operators/rx_global.cc\n\nnoExplicitConstructor:src/collection/backend/collection_data.h\nstlIfStrFind:src/collection/backend/collection_data.cc\n\nunusedFunction\nmissingIncludeSystem\nuseStlAlgorithm\npreprocessorErrorDirective\nfuncArgNamesDifferent\nmissingInclude\n\npurgedConfiguration\n\nnullPointerRedundantCheck\nknownConditionTrueFalse\ncstyleCast\nfunctionStatic\nshadowFunction\n\nstlcstrConstructor\nstlcstrStream\nuselessCallsSubstr\n\n// Examples\nmemleak:examples/using_bodies_in_chunks/simple_request.cc\n\n"
  },
  {
    "path": "test/custom-test-driver",
    "content": "#! /bin/sh\n# test-driver - basic testsuite driver script.\n\nscriptversion=2013-07-13.22-modsec; # UTC\n\n# Copyright (C) 2011-2014 Free Software Foundation, Inc.\n#\n# This program is free software; you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation; either version 2, or (at your option)\n# any later version.\n#\n# This program is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with this program.  If not, see <http://www.gnu.org/licenses/>.\n\n# As a special exception to the GNU General Public License, if you\n# distribute this file as part of a program that contains a\n# configuration script generated by Autoconf, you may include it under\n# the same distribution terms that you use for the rest of that program.\n\n# This file is maintained in Automake, please report\n# bugs to <bug-automake@gnu.org> or send patches to\n# <automake-patches@gnu.org>.\n\n# Make unconditional expansion of undefined variables an error.  This\n# helps a lot in preventing typo-related bugs.\nset -u\n\nusage_error ()\n{\n  echo \"$0: $*\" >&2\n  print_usage >&2\n  exit 2\n}\n\nprint_usage ()\n{\n  cat <<END\nUsage:\n  test-driver --test-name NAME --log-file PATH --trs-file PATH\n              [--expect-failure {yes|no}] [--color-tests {yes|no}]\n              [--enable-hard-errors {yes|no}] [--]\n              TEST-SCRIPT [TEST-SCRIPT-ARGUMENTS]\nThe '--test-name', '--log-file' and '--trs-file' options are mandatory.\nEND\n}\n\ntest_name= # Used for reporting.\nlog_file=  # Where to save the output of the test script.\ntrs_file=  # Where to save the metadata of the test run.\nexpect_failure=no\ncolor_tests=no\nenable_hard_errors=yes\nwhile test $# -gt 0; do\n  case $1 in\n  --help) print_usage; exit $?;;\n  --version) echo \"test-driver $scriptversion\"; exit $?;;\n  --test-name) test_name=$2; shift;;\n  --log-file) log_file=$2; shift;;\n  --trs-file) trs_file=$2; shift;;\n  --color-tests) color_tests=$2; shift;;\n  --expect-failure) expect_failure=$2; shift;;\n  --enable-hard-errors) enable_hard_errors=$2; shift;;\n  --) shift; break;;\n  -*) usage_error \"invalid option: '$1'\";;\n   *) break;;\n  esac\n  shift\ndone\n\nmissing_opts=\ntest x\"$test_name\" = x && missing_opts=\"$missing_opts --test-name\"\ntest x\"$log_file\"  = x && missing_opts=\"$missing_opts --log-file\"\ntest x\"$trs_file\"  = x && missing_opts=\"$missing_opts --trs-file\"\nif test x\"$missing_opts\" != x; then\n  usage_error \"the following mandatory options are missing:$missing_opts\"\nfi\n\nif test $# -eq 0; then\n  usage_error \"missing argument\"\nfi\n\nif test $color_tests = yes; then\n  # Keep this in sync with 'lib/am/check.am:$(am__tty_colors)'.\n  red='\u001b[0;31m' # Red.\n  grn='\u001b[0;32m' # Green.\n  lgn='\u001b[1;32m' # Light green.\n  blu='\u001b[1;34m' # Blue.\n  mgn='\u001b[0;35m' # Magenta.\n  wht='\u001b[1;40m' # White.\n  std='\u001b[m'     # No color.\nelse\n  red= grn= lgn= blu= mgn= std= wht=\nfi\n\ndo_exit='rm -f $log_file $trs_file; (exit $st); exit $st'\ntrap \"st=129; $do_exit\" 1\ntrap \"st=130; $do_exit\" 2\ntrap \"st=141; $do_exit\" 13\ntrap \"st=143; $do_exit\" 15\n\n# Test script is run here.\n\"$@\" >$log_file 2>&1 \nestatus=$?\ncat $log_file >> $trs_file\ntfail=`cat $log_file | egrep \"^:test-result: FAIL\" | wc -l`\ntfail=`printf \"%3d\" $tfail`\ntpass=`cat $log_file | egrep \"^:test-result: PASS\" | wc -l`\ntpass=`printf \"%4d\" $tpass`\nttotal=`cat $log_file | egrep \"^:test-result: \" | wc -l`\nttotal=`printf \"%4d\" $ttotal`\n\n# Report outcome to console.\nif test ${tfail} -eq 0; then\n    echo \"(${grn}${tpass}$std/${red}${tfail}$std/${wht}${ttotal}${std}): $test_name\"\nelse\n    echo \"(${grn}${tpass}$std/${red}${tfail}$std/${wht}${ttotal}${std}): ${red}$test_name${std}\"\nfi\n\n# Local Variables:\n# mode: shell-script\n# sh-indentation: 2\n# eval: (add-hook 'write-file-hooks 'time-stamp)\n# time-stamp-start: \"scriptversion=\"\n# time-stamp-format: \"%:y-%02m-%02d.%02H\"\n# time-stamp-time-zone: \"UTC\"\n# time-stamp-end: \"; # UTC\"\n# End:\n"
  },
  {
    "path": "test/fuzzer/Makefile.am",
    "content": "\n\n# make clean\nCLEANFILES = \n\n# make maintainer-clean\nMAINTAINERCLEANFILES = \\\n\tMakefile.in\n\n\nnoinst_PROGRAMS = afl_fuzzer\n\nafl_fuzzer_SOURCES = \\\n\tafl_fuzzer.cc\n\nafl_fuzzer_LDADD = \\\n\t$(GLOBAL_LDADD) \\\n\t$(CURL_LDADD) \\\n\t$(GEOIP_LDFLAGS) $(GEOIP_LDADD) \\\n\t$(PCRE_LDADD) \\\n\t$(PCRE2_LDADD) \\\n\t$(YAJL_LDFLAGS) $(YAJL_LDADD) \\\n\t$(LMDB_LDFLAGS) $(LMDB_LDADD) \\\n\t$(MAXMIND_LDFLAGS) $(MAXMIND_LDADD) \\\n\t$(SSDEEP_LDFLAGS) $(SSDEEP_LDADD) \\\n\t$(LUA_LDFLAGS) $(LUA_LDADD) \\\n\t$(LIBXML2_LDADD) \\\n\t$(top_builddir)/src/.libs/libmodsecurity.a \\\n\t$(top_builddir)/others/libinjection.la \\\n\t$(top_builddir)/others/libmbedtls.la\n\n\nafl_fuzzer_CPPFLAGS = \\\n\t-Icommon \\\n\t-I../ \\\n\t-I../../ \\\n\t-O0 \\\n\t-g \\\n\t-I$(top_builddir)/headers \\\n\t$(CURL_CFLAGS) \\\n\t$(GEOIP_CFLAGS) \\\n\t$(MAXMIND_CFLAGS) \\\n\t$(GLOBAL_CPPFLAGS) \\\n\t$(MODSEC_NO_LOGS) \\\n\t$(YAJL_CFLAGS) \\\n\t$(LMDB_CFLAGS) \\\n\t$(PCRE_CFLAGS) \\\n\t$(PCRE2_CFLAGS) \\\n\t$(LIBXML2_CFLAGS)\n"
  },
  {
    "path": "test/fuzzer/afl_fuzzer.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n\n#include <string.h>\n#include \"modsecurity/rules_set.h\"\n#include \"modsecurity/modsecurity.h\"\n#include \"src/actions/transformations/transformation.h\"\n\n/**\n * for i in $(ls -l src/actions/transformations/*.h | awk {'print $9'}); do echo \"#include \\\"$i\\\"\"; done;\n *\n */\n#include \"src/actions/transformations/base64_decode.h\"\n#include \"src/actions/transformations/base64_decode_ext.h\"\n#include \"src/actions/transformations/base64_encode.h\"\n#include \"src/actions/transformations/cmd_line.h\"\n#include \"src/actions/transformations/compress_whitespace.h\"\n#include \"src/actions/transformations/css_decode.h\"\n#include \"src/actions/transformations/escape_seq_decode.h\"\n#include \"src/actions/transformations/hex_decode.h\"\n#include \"src/actions/transformations/hex_encode.h\"\n#include \"src/actions/transformations/html_entity_decode.h\"\n#include \"src/actions/transformations/js_decode.h\"\n#include \"src/actions/transformations/length.h\"\n#include \"src/actions/transformations/lower_case.h\"\n#include \"src/actions/transformations/md5.h\"\n#include \"src/actions/transformations/none.h\"\n#include \"src/actions/transformations/normalise_path.h\"\n#include \"src/actions/transformations/normalise_path_win.h\"\n#include \"src/actions/transformations/parity_even_7bit.h\"\n#include \"src/actions/transformations/parity_odd_7bit.h\"\n#include \"src/actions/transformations/parity_zero_7bit.h\"\n#include \"src/actions/transformations/remove_comments.h\"\n#include \"src/actions/transformations/remove_comments_char.h\"\n#include \"src/actions/transformations/remove_nulls.h\"\n#include \"src/actions/transformations/remove_whitespace.h\"\n#include \"src/actions/transformations/replace_comments.h\"\n#include \"src/actions/transformations/replace_nulls.h\"\n#include \"src/actions/transformations/sha1.h\"\n#include \"src/actions/transformations/sql_hex_decode.h\"\n#include \"src/actions/transformations/transformation.h\"\n#include \"src/actions/transformations/trim.h\"\n#include \"src/actions/transformations/trim_left.h\"\n#include \"src/actions/transformations/trim_right.h\"\n#include \"src/actions/transformations/upper_case.h\"\n#include \"src/actions/transformations/url_decode.h\"\n#include \"src/actions/transformations/url_decode_uni.h\"\n#include \"src/actions/transformations/url_encode.h\"\n#include \"src/actions/transformations/utf8_to_unicode.h\"\n\n\n\n/**\n * for i in $(ls -l src/operators/*.h | awk {'print $9'}); do echo \"#include \\\"$i\\\"\"; done;\n *\n */\n#include \"src/operators/begins_with.h\"\n#include \"src/operators/contains.h\"\n#include \"src/operators/contains_word.h\"\n#include \"src/operators/detect_sqli.h\"\n#include \"src/operators/detect_xss.h\"\n#include \"src/operators/ends_with.h\"\n#include \"src/operators/eq.h\"\n#include \"src/operators/fuzzy_hash.h\"\n#include \"src/operators/ge.h\"\n#include \"src/operators/geo_lookup.h\"\n#include \"src/operators/gsblookup.h\"\n#include \"src/operators/gt.h\"\n#include \"src/operators/inspect_file.h\"\n#include \"src/operators/ip_match_f.h\"\n#include \"src/operators/ip_match_from_file.h\"\n#include \"src/operators/ip_match.h\"\n#include \"src/operators/le.h\"\n#include \"src/operators/lt.h\"\n#include \"src/operators/no_match.h\"\n#include \"src/operators/operator.h\"\n#include \"src/operators/pm_f.h\"\n#include \"src/operators/pm_from_file.h\"\n#include \"src/operators/pm.h\"\n#include \"src/operators/rbl.h\"\n#include \"src/operators/rsub.h\"\n#include \"src/operators/rx.h\"\n#include \"src/operators/str_eq.h\"\n#include \"src/operators/str_match.h\"\n#include \"src/operators/unconditional_match.h\"\n#include \"src/operators/validate_byte_range.h\"\n#include \"src/operators/validate_dtd.h\"\n#include \"src/operators/validate_hash.h\"\n#include \"src/operators/validate_schema.h\"\n#include \"src/operators/validate_url_encoding.h\"\n#include \"src/operators/validate_utf8_encoding.h\"\n#include \"src/operators/verify_cc.h\"\n#include \"src/operators/verify_cpf.h\"\n#include \"src/operators/verify_ssn.h\"\n#include \"src/operators/within.h\"\n\n\nusing namespace modsecurity::actions::transformations;\nusing namespace modsecurity::operators;\nusing namespace modsecurity;\n\n#include <stdio.h>\n#include <stdlib.h>\n#ifndef WIN32\n#include <unistd.h>\n#else\n#include <io.h>\n#endif\n#include <signal.h>\n#include <string.h>\n\ninline void op_test(const std::string &opName, const std::string &s) {\n    Operator *op = Operator::instantiate(opName, \"\");\n    op->init(\"\", nullptr);\n    op->evaluate(nullptr, nullptr, s, nullptr);\n    delete op;\n}\n\nint main(int argc, char** argv) {\n    uint8_t buf[128];\n\n#if 0\n    std::string lastString;\n#endif\n\n    while (__AFL_LOOP(1000)) {\n        ssize_t read_bytes;\n        // (re-) initialize the library and read new input\n        memset(buf, 0, 128);\n        read_bytes = read(STDIN_FILENO, buf, 128);\n\n        std::string currentString = std::string(read_bytes, 128);\n        const std::string& s = currentString;\n#if 0\n        std::string z = lastString;\n#endif\n\n        ModSecurity *ms = new ModSecurity();\n        RulesSet *rules = new RulesSet();\n        // Here it is possible to load a real transaction from a JSON.\n        // like we do on the regression tests.\n        Transaction *t = new Transaction(ms, rules, NULL);\n\n\n        /**\n        * Transformations, generated by:\n        *\n        * for i in $(grep \"class \" -Ri src/actions/transformations/* | grep \" :\" | grep -v \"InstantCache\" | awk {'print $2'}); do echo $i *$(echo $i | awk '{print tolower($0)}') = new $i\\(\\\"$i\\\"\\)\\; $(echo $i | awk '{print tolower($0)}')-\\>evaluate\\(s, NULL\\)\\; delete $(echo $i | awk '{print tolower($0)}')\\;; done;\n        *\n        */\nBase64Decode *base64decode = new Base64Decode(\"Base64Decode\"); base64decode->evaluate(s, NULL); delete base64decode;\nBase64DecodeExt *base64decodeext = new Base64DecodeExt(\"Base64DecodeExt\"); base64decodeext->evaluate(s, NULL); delete base64decodeext;\nBase64Encode *base64encode = new Base64Encode(\"Base64Encode\"); base64encode->evaluate(s, NULL); delete base64encode;\nCmdLine *cmdline = new CmdLine(\"CmdLine\"); cmdline->evaluate(s, NULL); delete cmdline;\nCompressWhitespace *compresswhitespace = new CompressWhitespace(\"CompressWhitespace\"); compresswhitespace->evaluate(s, NULL); delete compresswhitespace;\nCssDecode *cssdecode = new CssDecode(\"CssDecode\"); cssdecode->evaluate(s, NULL); delete cssdecode;\nEscapeSeqDecode *escapeseqdecode = new EscapeSeqDecode(\"EscapeSeqDecode\"); escapeseqdecode->evaluate(s, NULL); delete escapeseqdecode;\nHexDecode *hexdecode = new HexDecode(\"HexDecode\"); hexdecode->evaluate(s, NULL); delete hexdecode;\nHexEncode *hexencode = new HexEncode(\"HexEncode\"); hexencode->evaluate(s, NULL); delete hexencode;\nHtmlEntityDecode *htmlentitydecode = new HtmlEntityDecode(\"HtmlEntityDecode\"); htmlentitydecode->evaluate(s, NULL); delete htmlentitydecode;\nJsDecode *jsdecode = new JsDecode(\"JsDecode\"); jsdecode->evaluate(s, NULL); delete jsdecode;\nLength *length = new Length(\"Length\"); length->evaluate(s, NULL); delete length;\nLowerCase *lowercase = new LowerCase(\"LowerCase\"); lowercase->evaluate(s, NULL); delete lowercase;\nMd5 *md5 = new Md5(\"Md5\"); md5->evaluate(s, NULL); delete md5;\nNone *none = new None(\"None\"); none->evaluate(s, NULL); delete none;\nNormalisePath *normalisepath = new NormalisePath(\"NormalisePath\"); normalisepath->evaluate(s, NULL); delete normalisepath;\nNormalisePathWin *normalisepathwin = new NormalisePathWin(\"NormalisePathWin\"); normalisepathwin->evaluate(s, NULL); delete normalisepathwin;\nParityEven7bit *parityeven7bit = new ParityEven7bit(\"ParityEven7bit\"); parityeven7bit->evaluate(s, NULL); delete parityeven7bit;\nParityOdd7bit *parityodd7bit = new ParityOdd7bit(\"ParityOdd7bit\"); parityodd7bit->evaluate(s, NULL); delete parityodd7bit;\nParityZero7bit *parityzero7bit = new ParityZero7bit(\"ParityZero7bit\"); parityzero7bit->evaluate(s, NULL); delete parityzero7bit;\nRemoveComments *removecomments = new RemoveComments(\"RemoveComments\"); removecomments->evaluate(s, NULL); delete removecomments;\nRemoveCommentsChar *removecommentschar = new RemoveCommentsChar(\"RemoveCommentsChar\"); removecommentschar->evaluate(s, NULL); delete removecommentschar;\nRemoveNulls *removenulls = new RemoveNulls(\"RemoveNulls\"); removenulls->evaluate(s, NULL); delete removenulls;\nRemoveWhitespace *removewhitespace = new RemoveWhitespace(\"RemoveWhitespace\"); removewhitespace->evaluate(s, NULL); delete removewhitespace;\nReplaceComments *replacecomments = new ReplaceComments(\"ReplaceComments\"); replacecomments->evaluate(s, NULL); delete replacecomments;\nReplaceNulls *replacenulls = new ReplaceNulls(\"ReplaceNulls\"); replacenulls->evaluate(s, NULL); delete replacenulls;\nSha1 *sha1 = new Sha1(\"Sha1\"); sha1->evaluate(s, NULL); delete sha1;\nSqlHexDecode *sqlhexdecode = new SqlHexDecode(\"SqlHexDecode\"); sqlhexdecode->evaluate(s, NULL); delete sqlhexdecode;\nTransformation *transformation = new Transformation(\"Transformation\"); transformation->evaluate(s, NULL); delete transformation;\nTrim *trim = new Trim(\"Trim\"); trim->evaluate(s, NULL); delete trim;\nTrimLeft *trimleft = new TrimLeft(\"TrimLeft\"); trimleft->evaluate(s, NULL); delete trimleft;\nTrimRight *trimright = new TrimRight(\"TrimRight\"); trimright->evaluate(s, NULL); delete trimright;\nUpperCase *uppercase = new UpperCase(\"UpperCase\"); uppercase->evaluate(s, NULL); delete uppercase;\nUrlDecode *urldecode = new UrlDecode(\"UrlDecode\"); urldecode->evaluate(s, NULL); delete urldecode;\nUrlDecodeUni *urldecodeuni = new UrlDecodeUni(\"UrlDecodeUni\"); urldecodeuni->evaluate(s, NULL); delete urldecodeuni;\nUrlEncode *urlencode = new UrlEncode(\"UrlEncode\"); urlencode->evaluate(s, NULL); delete urlencode;\nUtf8ToUnicode *utf8tounicode = new Utf8ToUnicode(\"Utf8ToUnicode\"); utf8tounicode->evaluate(s, NULL); delete utf8tounicode;\n\n\n        /**\n        * Operators, generated by:\n        *\n        * for i in $(grep \"class \" -Ri src/operators/* | grep \" :\" | awk {'print $2'}); do echo $i *$(echo $i | awk '{print tolower($0)}') = new $i\\(\\\"$i\\\", z, false\\)\\; $(echo $i | awk '{print tolower($0)}')-\\>evaluate\\(t, s\\)\\; delete $(echo $i | awk '{print tolower($0)}')\\;; done;\n        *\n        */\nop_test(\"BeginsWith\", s);\nop_test(\"Contains\", s);\nop_test(\"ContainsWord\", s);\nop_test(\"DetectSQLi\", s);\nop_test(\"DetectXSS\", s);\nop_test(\"EndsWith\", s);\nop_test(\"Eq\", s);\n//op_test(\"FuzzyHash\", s);\nop_test(\"Ge\", s);\n//op_test(\"GeoLookup\", s);\n//op_test(\"GsbLookup\", s);\nop_test(\"Gt\", s);\n//op_test(\"InspectFile\", s);\n//op_test(\"IpMatchF\", s);\n//op_test(\"IpMatchFromFile\", s);\nop_test(\"IpMatch\", s);\nop_test(\"Le\", s);\nop_test(\"Lt\", s);\nop_test(\"NoMatch\", s);\n//op_test(\"PmF\", s);\n//op_test(\"PmFromFile\", s);\nop_test(\"Pm\", s);\nop_test(\"Rbl\", s);\nop_test(\"Rsub\", s);\nop_test(\"Rx\", s);\nop_test(\"StrEq\", s);\nop_test(\"StrMatch\", s);\nop_test(\"UnconditionalMatch\", s);\n//op_test(\"ValidateByteRange\", s);\n//op_test(\"ValidateDTD\", s);\n//op_test(\"ValidateHash\", s);\n//op_test(\"ValidateSchema\", s);\n//op_test(\"ValidateUrlEncoding\", s);\nop_test(\"ValidateUtf8Encoding\", s);\nop_test(\"VerifyCC\", s);\nop_test(\"VerifyCPF\", s);\nop_test(\"VerifySSN\", s);\nop_test(\"VerifySVNR\", s);\nop_test(\"Within\", s);\n\n\n        /**\n        * ModSec API\n        *\n        */\n#if 0\n    t->processConnection(s.c_str(), 123, s.c_str(), 123);\n    t->processURI(s.c_str(), z.c_str(), z.c_str());\n    t->addRequestHeader(s, z);\n    t->addRequestHeader(s, s);\n    t->addRequestHeader(z, z);\n    t->addRequestHeader(z, s);\n    t->processRequestHeaders();\n    t->appendRequestBody((const unsigned char *)s.c_str(), s.length());\n    t->processRequestBody();\n    t->addResponseHeader(s, z);\n    t->addResponseHeader(s, s);\n    t->addResponseHeader(z, z);\n    t->addResponseHeader(z, s);\n    t->processResponseHeaders();\n    t->appendResponseBody((const unsigned char *)s.c_str(), s.length());\n    t->processResponseBody();\n#endif\n\n\n        delete t;\n        delete rules;\n        delete ms;\n#if 0\n        lastString = currentString;\n#endif\n    }\n    return 0;\n}\n\n"
  },
  {
    "path": "test/modsecurity-regression-ip-list.txt",
    "content": "127.0.0.1\n8.8.4.4\n"
  },
  {
    "path": "test/modsecurity-regression-rules.txt",
    "content": "SecRule REQUEST_FILENAME \"@pmFromFile https://raw.githubusercontent.com/owasp-modsecurity/ModSecurity/refs/heads/v3/master/test/modsecurity-regression-ip-list.txt\" \"id:'123',phase:2,log,pass,t:none\"\n"
  },
  {
    "path": "test/optimization/optimization.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2023 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <string.h>\n\n#include <ctime>\n#include <iostream>\n#include <string>\n#include <list>\n\n#include \"modsecurity/rules_set_properties.h\"\n#include \"modsecurity/rules_set.h\"\n#include \"modsecurity/modsecurity.h\"\n#include \"src/utils/system.h\"\n#include \"src/parser/driver.h\"\n#include \"src/utils/https_client.h\"\n#include \"modsecurity/transaction.h\"\n#include \"modsecurity/rule_unconditional.h\"\n#include \"modsecurity/rule_with_operator.h\"\n\n\nvoid print_help() {\n    std::cout << \"Use ./optimization /path/to/files.something\" << std::endl;\n    std::cout << std::endl;\n    std::cout << std::endl;\n}\n\n\nint main(int argc, char **argv) {\n    modsecurity::RulesSet *modsecRules = new modsecurity::RulesSet();\n    std::list<std::string> files;\n    int total = 0;\n\n    int p = 1;\n    while (p < argc) {\n        std::list<std::string> tfiles = modsecurity::utils::expandEnv(\n            argv[p], 0);\n        for (const auto &file : tfiles) {\n            files.insert(files.begin(), file);\n        }\n        p++;\n    }\n\n\n    for (const auto &x : files) {\n        std::cout << \"Loading file: \" << x << std::endl;\n        if (modsecRules->loadFromUri(x.c_str()) < 0) {\n            std::cout << \"Not able to load the rules\" << std::endl;\n            std::cout << modsecRules->getParserError() << std::endl;\n            delete modsecRules;\n            return -1;\n        }\n    }\n\n    std::cout << std::endl;\n    std::cout << std::endl;\n    std::cout << \"Rules optimization\" << std::endl;\n    std::cout << std::endl;\n\n    int nphases = modsecurity::Phases::NUMBER_OF_PHASES;\n    for (int j = 0; j < nphases; j++) {\n        Rules *rules = modsecRules->m_rulesSetPhases[j];\n        if (rules->size() == 0) {\n            continue;\n        }\n        std::cout << \"Phase: \" << std::to_string(j);\n        std::cout << \" (\" << std::to_string(rules->size());\n        std::cout << \" rules)\" << std::endl;\n\n        std::unordered_map<std::string, int> operators;\n\n        for (int i = 0; i < rules->size(); i++) {\n            auto z = rules->at(i);\n            if (z == NULL) {\n                continue;\n            }\n\n            if (dynamic_cast<modsecurity::RuleUnconditional *>(z.get())) {\n                std::string op = \"Unconditional\";\n                if (operators.count(op) > 0) {\n                    operators[op] = 1 + operators[op];\n                } else {\n                    operators[op] = 1;\n                }\n            }\n\n            if (const auto *rwo = dynamic_cast<modsecurity::RuleWithOperator *>(z.get())) {\n                const auto &op = rwo->getOperatorName();\n                if (operators.count(op) > 0) {\n                    operators[op] = 1 + operators[op];\n                } else {\n                    operators[op] = 1;\n                }\n            }\n\n        }\n        if (operators.empty()) {\n            std::cout << \" ~ no SecRule found ~ \" << std::endl;\n            continue;\n        }\n\n        std::cout << \" Operators\" << std::endl;\n        for (const auto &z : operators) {\n            const auto &s = z.second;\n            std::cout << \"   \" << std::left << std::setw(20) << z.first;\n            std::cout << std::right << std::setw(4) << s;\n            std::cout << std::endl;\n        }\n\n        total += rules->size();\n    }\n    std::cout << std::endl;\n\n    std::cout << \"Total of: \" << std::to_string(total) << \" rules.\";\n    std::cout << std::endl;\n    std::cout << std::endl;\n    std::cout << std::endl;\n\n    delete modsecRules;\n\n    return 0;\n}\n"
  },
  {
    "path": "test/regression/regression.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2023 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <string.h>\n\n#ifndef WIN32\n#include <unistd.h>\n#else\n#include <io.h>\n#endif\n\n#include <ctime>\n#include <iostream>\n#include <string>\n#include <list>\n#include <algorithm>\n#include <cassert>\n\n#include \"modsecurity/rules_set.h\"\n#include \"modsecurity/modsecurity.h\"\n#include \"test/common/modsecurity_test.h\"\n#include \"test/common/colors.h\"\n#include \"test/regression/regression_test.h\"\n#include \"test/common/modsecurity_test_results.h\"\n#include \"test/common/modsecurity_test_context.h\"\n#include \"src/utils/regex.h\"\n\nusing modsecurity_test::CustomDebugLog;\nusing modsecurity_test::ModSecurityTest;\nusing modsecurity_test::ModSecurityTestResults;\nusing modsecurity_test::RegressionTest;\nusing modsecurity_test::RegressionTests;\nusing modsecurity_test::RegressionTestResult;\n\nusing modsecurity::Utils::regex_search;\nusing modsecurity::Utils::SMatch;\nusing modsecurity::Utils::Regex;\n\nstd::string default_test_path = \"test-cases/regression\";\nstd::list<std::string> resources;\n\nvoid print_help() {\n    std::cout << \"Use ./regression-tests /path/to/file\" << std::endl;\n    std::cout << std::endl;\n    std::cout << std::endl;\n}\n\nbool contains(const std::string &s, const std::string &pattern) {\n    bool ret;\n    modsecurity::Utils::Regex re(pattern);\n    ret = modsecurity::Utils::regex_search(s, re);\n    return ret;\n}\n\nvoid clearAuditLog(const std::string &filename) {\n    if (!filename.empty()) {\n        std::ofstream file{filename.c_str(), std::ofstream::out | std::ofstream::trunc};\n        if (!file.is_open() || file.fail()) {\n            std::cout << std::endl << \"Failed to clear previous contents of audit log: \" \\\n                << filename << std::endl;\n        }\n    }\n}\nstd::string getAuditLogContent(const std::string &filename) {\n    std::stringstream buffer;\n    if (!filename.empty()) {\n        try {\n           std::ifstream t(filename);\n           buffer << t.rdbuf();\n        } catch (...) {\n            std::cout << \"Failed to read file:\" << filename << std::endl;\n        }\n    }\n    return buffer.str();\n}\n\n\nvoid actions(ModSecurityTestResults<RegressionTest> *r,\n    modsecurity::Transaction *a, std::stringstream *serverLog) {\n    modsecurity::ModSecurityIntervention it;\n    memset(&it, '\\0', sizeof(modsecurity::ModSecurityIntervention));\n    it.status = 200;\n    if (a->intervention(&it) == true) {\n        if (it.pause != 0) {\n            // FIXME:\n        }\n        if (it.status != 0) {\n            r->status = it.status;\n        }\n        if (it.url != nullptr) {\n            r->location.append(it.url);\n\t    free(it.url);\n\t    it.url = nullptr;\n        }\n        if (it.log != nullptr) {\n            *serverLog << it.log;\n            free(it.log);\n            it.log = nullptr;\n        }\n    }\n}\n\nvoid perform_unit_test(const ModSecurityTest<RegressionTest> &test,\n    const std::vector<std::unique_ptr<RegressionTest>> &tests,\n    ModSecurityTestResults<RegressionTestResult> *res, int *count)\n{\n    for (auto &t : tests) {\n        ModSecurityTestResults<RegressionTest> r;\n        RegressionTestResult *testRes = new RegressionTestResult();\n\n        testRes->test = t.get();\n        r.status = 200;\n        (*count)++;\n\n        size_t offset = t->filename.find_last_of(\"/\\\\\");\n        std::string filename(\"\");\n        if (offset != std::string::npos) {\n            filename = std::string(t->filename, offset + 1,\n                t->filename.length() - offset - 1);\n        } else {\n            filename = t->filename;\n        }\n\n        if (!test.m_automake_output) {\n            std::cout << std::setw(3) << std::right <<\n                std::to_string(*count) << \" \";\n            std::cout << std::setw(50) << std::left << filename;\n            std::cout << std::setw(70) << std::left << t->name;\n        }\n\n        if (t->enabled == 0) {\n            if (test.m_automake_output) {\n                std::cout << \":test-result: SKIP\" << filename \\\n                    << \":\" << t->name << std::endl;\n            } else {\n                std::cout << KCYN << \"disabled\" << RESET << std::endl;\n            }\n            res->push_back(testRes);\n            testRes->disabled = true;\n            testRes->reason << \"JSON disabled\";\n            continue;\n        }\n\n#ifdef WITH_LMDB\n        // some tests (e.g. issue-1831.json)  don't like it when data persists between runs\n        unlink(\"./modsec-shared-collections\");\n        unlink(\"./modsec-shared-collections-lock\");\n#endif\n\n        modsecurity_test::ModSecurityTestContext context(\"ModSecurity-regression v0.0.1-alpha\" \\\n            \" (ModSecurity regression test utility)\");\n\n        bool found = true;\n        if (t->resource.empty() == false) {\n            found = (std::find(resources.begin(), resources.end(), t->resource)\n                != resources.end());\n        }\n\n        if (!found) {\n            testRes->passed = false;\n            testRes->skipped = true;\n            testRes->reason << KCYN << \"ModSecurity was not \" << std::endl;\n            testRes->reason << KCYN << \"compiled with support \" << std::endl;\n            testRes->reason << KCYN << \"to: \" << t->resource << std::endl;\n            testRes->reason << RESET << std::endl;\n            if (test.m_automake_output) {\n                std::cout << \":test-result: SKIP \" << filename \\\n                    << \":\" << t->name << std::endl;\n            } else {\n                std::cout << KCYN << \"skipped!\" << RESET << std::endl;\n            }\n            res->push_back(testRes);\n\n            continue;\n        }\n\n        context.m_modsec_rules.load(\"SecDebugLogLevel 9\");\n        if (context.m_modsec_rules.load(t->rules.c_str(), filename) < 0) {\n            /* Parser error */\n            if (t->parser_error.empty() == true) {\n                /*\n                 * Not expecting any error, thus return the error to\n                 * the user.\n                 */\n                if (test.m_automake_output) {\n                    std::cout << \":test-result: FAIL \" << filename \\\n                        << \":\" << t->name << \":\" << *count << std::endl;\n                } else {\n                    std::cout << KRED << \"failed!\" << RESET << std::endl;\n                }\n                testRes->reason << KRED << \"parse failed.\" << RESET \\\n                    << std::endl;\n                testRes->reason << context.m_modsec_rules.getParserError() \\\n                    << std::endl;\n                testRes->passed = false;\n                res->push_back(testRes);\n\n                continue;\n            }\n\n            Regex re(t->parser_error);\n            SMatch match;\n            const auto s = context.m_modsec_rules.getParserError();\n\n            if (regex_search(s, &match, re)) {\n                if (test.m_automake_output) {\n                    std::cout << \":test-result: PASS \" << filename \\\n                        << \":\" << t->name << std::endl;\n                } else {\n                    std::cout << KGRN << \"passed!\" << RESET << std::endl;\n                }\n                /* Parser error was expected, thus, the test passed. */\n                testRes->reason << KGRN << \"passed!\" << RESET << std::endl;\n                testRes->passed = true;\n                res->push_back(testRes);\n\n                continue;\n            } else {\n                /* Parser error was expected, but with a different content */\n                if (test.m_automake_output) {\n                    std::cout << \":test-result: FAIL \" << filename \\\n                        << \":\" << t->name << \":\" << *count << std::endl;\n                } else {\n                    std::cout << KRED << \"failed!\" << RESET << std::endl;\n                }\n\n                testRes->reason << KRED << \"failed!\" << RESET << std::endl;\n                testRes->reason << KWHT << \"Expected a parser error.\" \\\n                    << RESET << std::endl;\n                testRes->reason << KWHT << \"Expected: \" << RESET \\\n                    << t->parser_error << std::endl;\n                testRes->reason << KWHT << \"Produced: \" << RESET \\\n                    << s << std::endl;\n                testRes->passed = false;\n                res->push_back(testRes);\n\n                continue;\n            }\n        } else {\n            /* Parser error was expected but never happened */\n            if (t->parser_error.empty() == false) {\n                if (test.m_automake_output) {\n                    std::cout << \":test-result: FAIL \" << filename \\\n                        << \":\" << t->name << \":\" << *count << std::endl;\n                } else {\n                    std::cout << KRED << \"failed!\" << RESET << std::endl;\n                    std::cout << KWHT << \"Expected a parser error.\" \\\n                        << RESET << std::endl;\n                    std::cout << KWHT << \"Expected: \" << RESET \\\n                        << t->parser_error << std::endl;\n                }\n                testRes->passed = false;\n                res->push_back(testRes);\n\n                continue;\n            }\n        }\n\n        auto modsec_transaction = context.create_transaction();\n\n        if (t->hostname != \"\") {\n            modsec_transaction.setRequestHostName(t->hostname);\n        }\n\n        clearAuditLog(modsec_transaction.m_rules->m_auditLog->m_path1);\n\n        modsec_transaction.processConnection(t->clientIp.c_str(),\n            t->clientPort, t->serverIp.c_str(), t->serverPort);\n\n        actions(&r, &modsec_transaction, &context.m_server_log);\n\n        modsec_transaction.processURI(t->uri.c_str(), t->method.c_str(),\n            t->httpVersion.c_str());\n\n        actions(&r, &modsec_transaction, &context.m_server_log);\n\n        for (const auto &[name, value] : t->request_headers) {\n            modsec_transaction.addRequestHeader(name.c_str(),\n                value.c_str());\n        }\n\n        modsec_transaction.processRequestHeaders();\n        actions(&r, &modsec_transaction, &context.m_server_log);\n\n        modsec_transaction.appendRequestBody(\n            (unsigned char *)t->request_body.c_str(),\n            t->request_body.size());\n        modsec_transaction.processRequestBody();\n        actions(&r, &modsec_transaction, &context.m_server_log);\n\n        for (const auto &[name, value] : t->response_headers) {\n            modsec_transaction.addResponseHeader(name.c_str(),\n                value.c_str());\n        }\n\n        modsec_transaction.processResponseHeaders(r.status,\n            t->response_protocol);\n        actions(&r, &modsec_transaction, &context.m_server_log);\n\n        modsec_transaction.appendResponseBody(\n            (unsigned char *)t->response_body.c_str(),\n            t->response_body.size());\n        modsec_transaction.processResponseBody();\n        actions(&r, &modsec_transaction, &context.m_server_log);\n\n        modsec_transaction.processLogging();\n\n        const auto *d = static_cast<CustomDebugLog *>(context.m_modsec_rules.m_debugLog);\n\n        if (!d->contains(t->debug_log)) {\n            if (test.m_automake_output) {\n                std::cout << \":test-result: FAIL \" << filename \\\n                    << \":\" << t->name << \":\" << *count << std::endl;\n            } else {\n                std::cout << KRED << \"failed!\" << RESET << std::endl;\n            }\n            testRes->reason << \"Debug log was not matching the \" \\\n                << \"expected results.\" << std::endl;\n            testRes->reason << KWHT << \"Expecting: \" << RESET\n                << t->debug_log + \"\";\n            testRes->passed = false;\n        } else if (r.status != t->http_code) {\n            if (test.m_automake_output) {\n                std::cout << \":test-result: FAIL \" << filename \\\n                    << \":\" << t->name << \":\" << *count << std::endl;\n            } else {\n                std::cout << KRED << \"failed!\" << RESET << std::endl;\n            }\n            testRes->reason << \"HTTP code mismatch. expecting: \" +\n                std::to_string(t->http_code) +\n                \" got: \" + std::to_string(r.status) + \"\\n\";\n            testRes->passed = false;\n        } else if (!contains(context.m_server_log.str(), t->error_log)) {\n            if (test.m_automake_output) {\n                std::cout << \":test-result: FAIL \" << filename \\\n                    << \":\" << t->name << std::endl;\n            } else {\n                std::cout << KRED << \"failed!\" << RESET << std::endl;\n            }\n            testRes->reason << \"Error log was not matching the \" \\\n                << \"expected results.\" << std::endl;\n            testRes->reason << KWHT << \"Expecting: \" << RESET \\\n                << t->error_log + \"\";\n            testRes->passed = false;\n        } else if (!t->audit_log.empty() && !contains(getAuditLogContent(modsec_transaction.m_rules->m_auditLog->m_path1), t->audit_log)) {\n            if (test.m_automake_output) {\n                std::cout << \":test-result: FAIL \" << filename \\\n                    << \":\" << t->name << \":\" << *count << std::endl;\n            } else {\n                std::cout << KRED << \"failed!\" << RESET << std::endl;\n            }\n            testRes->reason << \"Audit log was not matching the \" \\\n                << \"expected results.\" << std::endl;\n            testRes->reason << KWHT << \"Expecting: \" << RESET \\\n                << t->audit_log + \"\";\n            testRes->passed = false;\n        } else {\n            if (test.m_automake_output) {\n                std::cout << \":test-result: PASS \" << filename \\\n                    << \":\" << t->name << std::endl;\n            } else  {\n                std::cout << KGRN << \"passed!\" << RESET << std::endl;\n            }\n            testRes->passed = true;\n        }\n\n        if (testRes->passed == false) {\n            testRes->reason << std::endl;\n            testRes->reason << KWHT << \"Debug log:\" << RESET << std::endl;\n            testRes->reason << d->log_messages() << std::endl;\n            testRes->reason << KWHT << \"Error log:\" << RESET << std::endl;\n            testRes->reason << context.m_server_log.str() << std::endl;\n            testRes->reason << KWHT << \"Audit log:\" << RESET << std::endl;\n            testRes->reason << getAuditLogContent(modsec_transaction.m_rules->m_auditLog->m_path1) << std::endl;\n        }\n\n        r.log_raw_debug_log = d->log_messages();\n\n        res->push_back(testRes);\n    }\n}\n\nint main(int argc, char **argv)\n{\n    ModSecurityTest<RegressionTest> test;\n\n    std::string ver(MODSECURITY_VERSION);\n    std::string envvar(\"ModSecurity \" + ver + \" regression tests\");\n\n#ifndef WIN32\n    setenv(\"MODSECURITY\", envvar.c_str(), 1);\n#else\n    _putenv_s(\"MODSECURITY\", envvar.c_str());\n#endif\n\n#ifndef NO_LOGS\n    int test_number = 0;\n#endif\n\n#if defined(WITH_GEOIP) or defined(WITH_MAXMIND)\n    resources.push_back(\"geoip-or-maxmind\");\n#endif\n#if defined(WITH_MAXMIND)\n    resources.push_back(\"maxmind\");\n#endif\n#if defined(WITH_GEOIP)\n    resources.push_back(\"geoip\");\n#endif\n#ifdef WITH_CURL\n    resources.push_back(\"curl\");\n#endif\n#ifdef WITH_SSDEEP\n    resources.push_back(\"ssdeep\");\n#endif\n#ifdef WITH_LUA\n    resources.push_back(\"lua\");\n#endif\n#ifdef WITH_LIBXML2\n    resources.push_back(\"libxml2\");\n#endif\n\n#ifdef NO_LOGS\n    std::cout << \"Test utility cannot work without logging support.\" \\\n        << std::endl;\n    return 0;\n#else\n    test.cmd_options(argc, argv);\n\n    if (test.m_format) {\n#ifdef WITH_YAJL\n        std::cout << \"start formatting test case JSON files\" << std::endl;\n        ModSecurityTest<RegressionTests> test2;\n        test2.cmd_options(argc, argv);\n        test2.load_tests();\n        for (const auto &[name, tests] : test2) {\n            std::ofstream ofs{name};\n            if (!ofs.is_open()) {\n                std::cerr << \"cannot open \" << name << \" for writing.\" << std::endl;\n                return 1;\n            }\n            if (test2.m_update_content_length) {\n                tests[0]->update_content_lengths();\n            }\n            ofs << tests[0]->toJSON();\n            ofs.close();\n            std::cout << \"written formatted JSON to \" << name << std::endl;\n        }\n        std::cout << \"finished formatting files.\" << std::endl;\n        return 0;\n#else\n        std::cout << \"Test utility cannot format test case JSON files without being built with YAJL.\" \\\n            << std::endl;\n        return 1;\n#endif\n    }\n\n    if (!test.m_automake_output && !test.m_count_all) {\n        std::cout << test.header();\n    }\n\n    test.load_tests();\n\n    if (!test.m_automake_output && !test.m_count_all) {\n        std::cout << std::setw(4) << std::right << \"# \";\n        std::cout << std::setw(50) << std::left << \"File Name\";\n        std::cout << std::setw(70) << std::left << \"Test Name\";\n        std::cout << std::setw(10) << std::left << \"Passed?\";\n        std::cout << std::endl;\n        std::cout << std::setw(4) << std::right << \"--- \";\n        std::cout << std::setw(50) << std::left << \"---------\";\n        std::cout << std::setw(70) << std::left << \"---------\";\n        std::cout << std::setw(10) << std::left << \"-------\";\n        std::cout << std::endl;\n    }\n    int counter = 0;\n\n    std::list<std::string> keyList;\n    for (const auto &[name, tests] : test) {\n        keyList.push_back(name);\n    }\n    keyList.sort();\n\n    if (test.m_count_all) {\n        std::cout << std::to_string(keyList.size()) << std::endl;\n        exit(0);\n    }\n\n    ModSecurityTestResults<RegressionTestResult> res;\n    for (const std::string &a : keyList) {\n        test_number++;\n        if ((test.m_test_number == 0)\n            || (test_number == test.m_test_number)) {\n            const auto &tests = test[a];\n            perform_unit_test(test, tests, &res, &counter);\n        }\n    }\n\n    std::cout << std::endl;\n\n    int passed = 0;\n    int failed = 0;\n    int disabled = 0;\n    int skipped = 0;\n\n    for (RegressionTestResult *r : res) {\n        if (r->skipped == true) {\n            skipped++;\n        }\n        if (r->disabled == true) {\n            disabled++;\n        }\n        if (r->passed == true) {\n            passed++;\n        }\n\n        if (!r->passed && !r->skipped && !r->disabled) {\n            if (!test.m_automake_output) {\n                std::cout << KRED << \"Test failed.\" << RESET << KWHT \\\n                    << \" From: \" \\\n                    << RESET << r->test->filename << \".\" << std::endl;\n                std::cout << KWHT << \"Test name: \" << RESET \\\n                    << r->test->name \\\n                    << \".\" << std::endl;\n                std::cout << KWHT << \"Reason: \" << RESET << std::endl;\n                std::cout << r->reason.str() << std::endl;\n            }\n            failed++;\n        }\n        delete r;\n    }\n\n    if (!test.m_automake_output) {\n        std::cout << \"Ran a total of: \" << std::to_string(failed + passed) \\\n            << \" regression tests - \";\n        if (failed == 0) {\n            std::cout << KGRN << \"All tests passed. \" << RESET;\n        } else {\n            std::cout << KRED << failed << \" failed. \" << RESET;\n        }\n\n        std::cout << KCYN << std::to_string(skipped) << \" \";\n        std::cout << \"skipped test(s). \" << std::to_string(disabled) << \" \";\n        std::cout << \"disabled test(s).\" << RESET << std::endl;\n    }\n\n    return failed;\n#endif\n}\n"
  },
  {
    "path": "test/regression/regression_test.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"test/regression/regression_test.h\"\n\n#include <string.h>\n\n#include <sstream>\n#include <unordered_map>\n#include <string>\n#include <algorithm>\n#include <memory>\n\n#ifdef WITH_YAJL\n#include <yajl/yajl_gen.h>\n#endif\n\nnamespace modsecurity_test {\n\nstd::string RegressionTest::print() {\n    std::stringstream i;\n\n#if 0\n    i << KRED << \"Test failed.\" << RESET << \" From: \" \\\n    i << this->filename << std::endl;\n    i << \"{\" << std::endl;\n    i << \"  \\\"ret\\\": \\\"\" << this->ret << \"\\\"\" << std::endl;\n    i << \"  \\\"type\\\": \\\"\" << this->type << \"\\\"\" << std::endl;\n    i << \"  \\\"name\\\": \\\"\" << this->name << \"\\\"\" << std::endl;\n    i << \"  \\\"input\\\": \\\"\" << this->input << \"\\\"\" << std::endl;\n    i << \"  \\\"param\\\": \\\"\" << this->param << \"\\\"\" << std::endl;\n    i << \"}\" << std::endl;\n    i << \"Expecting: \" << this->ret << \" - operator returned: \" << \\\n        this->obtained << std::endl;\n#endif\n    return i.str();\n}\n\n\ninline std::string RegressionTest::yajl_array_to_str(const yajl_val &node) {\n    std::stringstream i;\n    for (int z = 0; z < node->u.array.len; z++) {\n        yajl_val val3 = node->u.array.values[z];\n        const char *key = YAJL_GET_STRING(val3);\n        i << key;\n    }\n    return i.str();\n}\n\n\ninline std::vector<std::string> RegressionTest::yajl_array_to_vec_str(\n    const yajl_val &node) {\n    std::vector<std::string> vec;\n    for (int z = 0; z < node->u.array.len; z++) {\n        yajl_val val3 = node->u.array.values[z];\n        const char *key = YAJL_GET_STRING(val3);\n        vec.push_back(key);\n    }\n    return vec;\n}\n\n\ninline std::vector<std::pair<std::string, std::string>>\n    RegressionTest::yajl_array_to_map(const yajl_val &node) {\n    std::vector<std::pair<std::string, std::string>> vec;\n    for (int z = 0; z < node->u.object.len; z++) {\n        const char *key = node->u.object.keys[z];\n        yajl_val val3 = node->u.object.values[z];\n        const char *value = YAJL_GET_STRING(val3);\n        std::pair<std::string, std::string> a(key, value);\n        vec.push_back(a);\n    }\n    return vec;\n}\n\nstatic inline void set_int_from_yajl(int &dest, std::string_view want_key, std::string_view key, const yajl_val &val) {\n    if (key == want_key) {\n        dest = YAJL_GET_INTEGER(val);\n    }\n}\n\nstatic inline void set_opt_int_from_yajl(std::optional<int> &dest, std::string_view want_key, std::string_view key, const yajl_val &val) {\n    if (key == want_key) {\n        dest = YAJL_GET_INTEGER(val);\n    }\n}\n\nstatic inline void set_string_from_yajl(std::string &dest, std::string_view want_key, std::string_view key, const yajl_val &val) {\n    if (key == want_key) {\n        dest = YAJL_GET_STRING(val);\n    }\n}\n\nstd::unique_ptr<RegressionTest> RegressionTest::from_yajl_node(const yajl_val &node) {\n    size_t nelem = node->u.object.len;\n    auto u = std::make_unique<RegressionTest>();\n    u->http_code = 200;\n\n    for (int i = 0; i < nelem; i++) {\n        const char *key = node->u.object.keys[ i ];\n        yajl_val val = node->u.object.values[ i ];\n\n        set_int_from_yajl(u->enabled, \"enabled\", key, val);\n        set_int_from_yajl(u->version_min, \"version_min\", key, val);\n        set_opt_int_from_yajl(u->version_max, \"version_max\", key, val);\n        set_string_from_yajl(u->title, \"title\", key, val);\n        set_string_from_yajl(u->url, \"url\", key, val);\n        set_string_from_yajl(u->resource, \"resource\", key, val);\n        set_opt_int_from_yajl(u->github_issue, \"github_issue\", key, val);\n        if (strcmp(key, \"client\") == 0) {\n            u->update_client_from_yajl_node(val);\n        }\n        if (strcmp(key, \"server\") == 0) {\n            u->update_server_from_yajl_node(val);\n        }\n        if (strcmp(key, \"request\") == 0) {\n            u->update_request_from_yajl_node(val);\n        }\n        if (strcmp(key, \"response\") == 0) {\n            u->update_response_from_yajl_node(val);\n        }\n        if (strcmp(key, \"expected\") == 0) {\n            u->update_expected_from_yajl_node(val);\n        }\n        if (strcmp(key, \"rules\") == 0) {\n            u->update_rules_from_yajl_node(val);\n        }\n    }\n\n    u->name = u->title;\n\n    return u;\n}\n\nvoid RegressionTest::update_client_from_yajl_node(const yajl_val &val) {\n    for (int j = 0; j < val->u.object.len; j++) {\n        const char *key2 = val->u.object.keys[j];\n        yajl_val val2 = val->u.object.values[j];\n\n        set_string_from_yajl(clientIp, \"ip\", key2, val2);\n        set_int_from_yajl(clientPort, \"port\", key2, val2);\n    }\n}\n\nvoid RegressionTest::update_server_from_yajl_node(const yajl_val &val) {\n    for (int j = 0; j < val->u.object.len; j++) {\n        const char *key2 = val->u.object.keys[j];\n        yajl_val val2 = val->u.object.values[j];\n\n        set_string_from_yajl(serverIp, \"ip\", key2, val2);\n        set_int_from_yajl(serverPort, \"port\", key2, val2);\n        set_string_from_yajl(hostname, \"hostname\", key2, val2);\n    }\n}\n\nvoid RegressionTest::update_request_from_yajl_node(const yajl_val &val) {\n    for (int j = 0; j < val->u.object.len; j++) {\n        const char *key2 = val->u.object.keys[j];\n        yajl_val val2 = val->u.object.values[j];\n\n        set_string_from_yajl(uri, \"uri\", key2, val2);\n        set_string_from_yajl(method, \"method\", key2, val2);\n        if (strcmp(key2, \"http_version\") == 0) {\n            httpVersion = YAJL_GET_NUMBER(val2);\n        }\n        if (strcmp(key2, \"headers\") == 0) {\n            request_headers = yajl_array_to_map(val2);\n        }\n        if (strcmp(key2, \"body\") == 0) {\n            request_body = yajl_array_to_str(val2);\n            request_body_lines = yajl_array_to_vec_str(val2);\n        }\n    }\n}\n\nvoid RegressionTest::update_response_from_yajl_node(const yajl_val &val) {\n    for (int j = 0; j < val->u.object.len; j++) {\n        const char *key2 = val->u.object.keys[j];\n        yajl_val val2 = val->u.object.values[j];\n\n        if (strcmp(key2, \"headers\") == 0) {\n            response_headers = yajl_array_to_map(val2);\n        }\n        if (strcmp(key2, \"body\") == 0) {\n            response_body = yajl_array_to_str(val2);\n            response_body_lines = yajl_array_to_vec_str(val2);\n        }\n        set_string_from_yajl(response_protocol, \"protocol\", key2, val2);\n    }\n}\n\nvoid RegressionTest::update_expected_from_yajl_node(const yajl_val &val) {\n    for (int j = 0; j < val->u.object.len; j++) {\n        const char *key2 = val->u.object.keys[j];\n        yajl_val val2 = val->u.object.values[j];\n\n        set_string_from_yajl(audit_log, \"audit_log\", key2, val2);\n        set_string_from_yajl(debug_log, \"debug_log\", key2, val2);\n        set_string_from_yajl(error_log, \"error_log\", key2, val2);\n        set_int_from_yajl(http_code, \"http_code\", key2, val2);\n        set_string_from_yajl(redirect_url, \"redirect_url\", key2, val2);\n        set_string_from_yajl(parser_error, \"parser_error\", key2, val2);\n    }\n}\n\nvoid RegressionTest::update_rules_from_yajl_node(const yajl_val &val) {\n    std::stringstream si;\n    for (int j = 0; j < val->u.array.len; j++) {\n        yajl_val val2 = val->u.array.values[ j ];\n        const char *keyj = YAJL_GET_STRING(val2);\n        si << keyj << \"\\n\";\n    }\n    rules = si.str();\n    rules_lines = yajl_array_to_vec_str(val);\n}\n\n\nconstexpr char ascii_tolower(char c) {\n    return 'A' <= c && c <= 'Z' ? (c + ('a' - 'A')) : c;\n}\n\nbool iequals_ascii(std::string_view a, std::string_view b) {\n    return a.size() == b.size() &&\n        std::equal(a.begin(), a.end(), b.begin(), b.end(),\n            [](char x, char y) {\n                return ascii_tolower(x) == ascii_tolower(y);\n            });\n}\n\nstatic bool has_chunked_header(const std::vector<std::pair<std::string, std::string>> &headers) {\n    return std::any_of(std::begin(headers), std::end(headers),\n        [](const auto &header) {\n            const auto &[name, value]{header};\n            return iequals_ascii(name, \"Transfer-Encoding\") && iequals_ascii(value, \"chunked\");\n        });\n}\n\nstatic void update_content_length(std::vector<std::pair<std::string, std::string>> &headers, size_t length) {\n    if (has_chunked_header(headers)) {\n        return;\n    }\n\n    bool has_content_length = false;\n    for (auto &[name, value] : headers) {\n        if (iequals_ascii(name, \"Content-Length\")) {\n            value = std::to_string(length);\n            has_content_length = true;\n        }\n    }\n    if (!has_content_length) {\n        headers.emplace_back(std::pair{\"Content-Length\", std::to_string(length)});\n    }\n}\n\nvoid RegressionTest::update_content_lengths() {\n    update_content_length(request_headers, request_body.size());\n    update_content_length(response_headers, response_body.size());\n}\n\nstd::unique_ptr<RegressionTests> RegressionTests::from_yajl_node(const yajl_val &node) {\n    auto u = std::make_unique<RegressionTests>();\n    size_t num_tests = node->u.array.len;\n    for (int i = 0; i < num_tests; i++) {\n        yajl_val obj = node->u.array.values[i];\n        u->tests.emplace_back(std::move(RegressionTest::from_yajl_node(obj)));\n    }\n    return u;\n}\n\nvoid RegressionTests::update_content_lengths() {\n    for (auto & test : tests) {\n        test->update_content_lengths();\n    }\n}\n\n#ifdef WITH_YAJL\n\nstatic yajl_gen_status gen_string_view(yajl_gen g, std::string_view s) {\n    return yajl_gen_string(g, reinterpret_cast<const unsigned char *>(s.data()), s.length());\n}\n\nstatic yajl_gen_status gen_key_str(yajl_gen g, std::string_view key, std::string_view val) {\n    if (auto s{gen_string_view(g, key)}; s != yajl_gen_status_ok) {\n        return s;\n    }\n    return gen_string_view(g, val);\n}\n\nstatic yajl_gen_status gen_key_str_if_non_empty(yajl_gen g, std::string_view key, std::string_view val) {\n    if (val.empty()) {\n        return yajl_gen_status_ok;\n    }\n    return gen_key_str(g, key, val);\n}\n\nstatic yajl_gen_status gen_key_int(yajl_gen g, std::string_view key, int val) {\n    if (auto s{gen_string_view(g, key)}; s != yajl_gen_status_ok) {\n        return s;\n    }\n    return yajl_gen_integer(g, val);\n}\n\nstatic yajl_gen_status gen_key_opt_int(yajl_gen g, std::string_view key, std::optional<int> val) {\n    if (!val.has_value()) {\n        return yajl_gen_status_ok;\n    }\n    return gen_key_int(g, key, val.value());\n}\n\nstatic yajl_gen_status gen_key_int_if_non_zero(yajl_gen g, std::string_view key, int val) {\n    if (val == 0) {\n        return yajl_gen_status_ok;\n    }\n    return gen_key_int(g, key, val);\n}\n\nstatic yajl_gen_status gen_key_number(yajl_gen g, std::string_view key, std::string_view raw_val) {\n    if (auto s{gen_string_view(g, key)}; s != yajl_gen_status_ok) {\n        return s;\n    }\n    return yajl_gen_number(g, reinterpret_cast<const char *>(raw_val.data()), raw_val.length());\n}\n\nstatic yajl_gen_status gen_key_str_array(yajl_gen g, std::string_view key, const std::vector<std::string> &lines) {\n    if (auto s{gen_string_view(g, key)}; s != yajl_gen_status_ok) {\n        return s;\n    }\n    if (auto s{yajl_gen_array_open(g)}; s != yajl_gen_status_ok) {\n        return s;\n    }\n    for (const auto &line : lines) {\n        if (auto s{gen_string_view(g, line)}; s != yajl_gen_status_ok) {\n            return s;\n        }\n    }\n    return yajl_gen_array_close(g);\n}\n\nstatic yajl_gen_status gen_key_headers(yajl_gen g, std::string_view key, const std::vector<std::pair<std::string, std::string>> &headers) {\n    if (auto s{gen_string_view(g, key)}; s != yajl_gen_status_ok) {\n        return s;\n    }\n    if (auto s{yajl_gen_map_open(g)}; s != yajl_gen_status_ok) {\n        return s;\n    }\n    for (const auto &[name, value] : headers) {\n        if (auto s{gen_key_str(g, name, value)}; s != yajl_gen_status_ok) {\n            return s;\n        }\n    }\n    return yajl_gen_map_close(g);\n}\n\nstd::string RegressionTests::toJSON() const {\n    const unsigned char *buf;\n    size_t len;\n    yajl_gen g;\n\n    g = yajl_gen_alloc(NULL);\n    if (g == NULL) {\n        return \"\";\n    }\n    yajl_gen_config(g, yajl_gen_beautify, 1);\n    yajl_gen_config(g, yajl_gen_indent_string, \"  \");\n\n    yajl_gen_array_open(g);\n    for (const auto &t : tests) {\n        yajl_gen_map_open(g);\n        gen_key_int(g, \"enabled\", t->enabled);\n        gen_key_int(g, \"version_min\", t->version_min);\n        gen_key_opt_int(g, \"version_max\", t->version_max);\n        gen_key_str(g, \"title\", t->title);\n        gen_key_str_if_non_empty(g, \"url\", t->url);\n        gen_key_str_if_non_empty(g, \"resource\", t->resource);\n        gen_key_opt_int(g, \"github_issue\", t->github_issue);\n\n        gen_string_view(g, \"client\");\n        yajl_gen_map_open(g);\n        gen_key_str(g, \"ip\", t->clientIp);\n        gen_key_int(g, \"port\", t->clientPort);\n        yajl_gen_map_close(g);\n\n        gen_string_view(g, \"server\");\n        yajl_gen_map_open(g);\n        gen_key_str(g, \"ip\", t->serverIp);\n        gen_key_int(g, \"port\", t->serverPort);\n        yajl_gen_map_close(g);\n\n        gen_string_view(g, \"request\");\n        yajl_gen_map_open(g);\n        gen_key_headers(g, \"headers\", t->request_headers);\n        gen_key_str(g, \"uri\", t->uri);\n        gen_key_str(g, \"method\", t->method);\n        if (!t->httpVersion.empty()) {\n            gen_key_number(g, \"http_version\", t->httpVersion);\n        }\n\n        auto request_body_lines{t->request_body_lines};\n        if (request_body_lines.empty()) {\n            request_body_lines.emplace_back(\"\");\n        }\n        gen_key_str_array(g, \"body\", request_body_lines);\n\n        yajl_gen_map_close(g);\n\n        gen_string_view(g, \"response\");\n        yajl_gen_map_open(g);\n        gen_key_headers(g, \"headers\", t->response_headers);\n\n        auto response_body_lines{t->response_body_lines};\n        if (response_body_lines.empty()) {\n            response_body_lines.emplace_back(\"\");\n        }\n        gen_key_str_array(g, \"body\", response_body_lines);\n\n        gen_key_str_if_non_empty(g, \"protocol\", t->response_protocol);\n        yajl_gen_map_close(g);\n\n        gen_string_view(g, \"expected\");\n        yajl_gen_map_open(g);\n        gen_key_str_if_non_empty(g, \"audit_log\", t->audit_log);\n        gen_key_str_if_non_empty(g, \"debug_log\", t->debug_log);\n        gen_key_str_if_non_empty(g, \"error_log\", t->error_log);\n        gen_key_int(g, \"http_code\", t->http_code);\n        gen_key_str_if_non_empty(g, \"redirect_url\", t->redirect_url);\n        gen_key_str_if_non_empty(g, \"parser_error\", t->parser_error);\n        yajl_gen_map_close(g);\n\n        gen_key_str_array(g, \"rules\", t->rules_lines);\n\n        yajl_gen_map_close(g);\n    }\n    yajl_gen_array_close(g);\n\n    yajl_gen_get_buf(g, &buf, &len);\n    std::string s{reinterpret_cast<const char*>(buf), len};\n    yajl_gen_free(g);\n    return s;\n}\n\n#endif // WITH_YAJL\n\n}  // namespace modsecurity_test\n"
  },
  {
    "path": "test/regression/regression_test.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <yajl/yajl_tree.h>\n\n#include <iostream>\n#include <sstream>\n#include <map>\n#include <vector>\n#include <string>\n#include <utility>\n#include <optional>\n#include <memory>\n\n#ifndef TEST_REGRESSION_REGRESSION_TEST_H_\n#define TEST_REGRESSION_REGRESSION_TEST_H_\n\nnamespace modsecurity_test {\n\n\nclass RegressionTest {\n public:\n    static std::unique_ptr<RegressionTest> from_yajl_node(const yajl_val &);\n\n    static std::string print();\n    std::string filename;\n    std::string name;\n    std::string title;\n\n    std::string rules;\n\n    std::string url;\n    int enabled;\n    int version_min;\n    std::optional<int> version_max;\n    std::optional<int> github_issue;\n\n    std::vector<std::pair<std::string, std::string>> request_headers;\n    std::vector<std::pair<std::string, std::string>> response_headers;\n    std::string request_body;\n    std::string response_body;\n    std::string response_protocol;\n\n    std::string audit_log;\n    std::string debug_log;\n    std::string error_log;\n    std::string parser_error;\n\n    std::string clientIp;\n    std::string serverIp;\n    int clientPort;\n    int serverPort;\n    std::string hostname;\n\n    std::string method;\n    std::string httpVersion;\n    std::string uri;\n    std::string resource;\n\n    static inline std::string yajl_array_to_str(const yajl_val &node);\n    static inline std::vector<std::string> yajl_array_to_vec_str(\n        const yajl_val &node);\n    static inline std::vector<std::pair<std::string, std::string>>\n        yajl_array_to_map(const yajl_val &node);\n\n    int http_code;\n    std::string redirect_url;\n\n    // fields for formatting JSON\n\n    std::vector<std::string> request_body_lines;\n    std::vector<std::string> response_body_lines;\n    std::vector<std::string> rules_lines;\n    void update_content_lengths();\n\nprivate:\n   void update_client_from_yajl_node(const yajl_val &val);\n   void update_server_from_yajl_node(const yajl_val &val);\n   void update_request_from_yajl_node(const yajl_val &val);\n   void update_response_from_yajl_node(const yajl_val &val);\n   void update_expected_from_yajl_node(const yajl_val &val);\n   void update_rules_from_yajl_node(const yajl_val &val);\n};\n\nclass RegressionTests {\n public:\n    static std::unique_ptr<RegressionTests> from_yajl_node(const yajl_val &);\n    void update_content_lengths();\n    std::string toJSON() const;\n\n    std::string filename;\n    std::string name;\n\n    std::vector<std::unique_ptr<RegressionTest>> tests;\n};\n\nclass RegressionTestResult {\n public:\n    RegressionTestResult() :\n      passed(false),\n      skipped(false),\n      disabled(false),\n      test(NULL) { }\n\n    bool passed;\n    bool skipped;\n    bool disabled;\n    RegressionTest *test;\n    std::stringstream reason;\n};\n\n\n}  // namespace modsecurity_test\n\n#endif  // TEST_REGRESSION_REGRESSION_TEST_H_\n"
  },
  {
    "path": "test/regression-tests-valgrind.sh",
    "content": "#!/usr/bin/env bash\n\nvalgrind --tool=massif ./regression_tests $*\nvalgrind --leak-check=full --suppressions=./valgrind_suppressions.txt ./regression_tests $*\n"
  },
  {
    "path": "test/test-cases/data/GeoIP2-City-Test-source.json",
    "content": "[\n   {\n      \"::200.249.12.31/120\" : {\n         \"continent\" : {\n            \"code\" : \"SA\",\n            \"geoname_id\" : 123,\n            \"names\" : {\n               \"en\" : \"South America\",\n               \"pt-BR\" : \"America do Sul\"\n            }\n         },\n         \"country\" : {\n            \"geoname_id\" : 123,\n            \"iso_code\" : \"BR\",\n            \"names\" : {\n               \"en\" : \"Brazil\",\n               \"pt-BR\" : \"Brasil\"\n            }\n         },\n         \"location\" : {\n            \"accuracy_radius\" : 100,\n            \"latitude\" : \"-8.051502\",\n            \"longitude\" : \"-34.874919\"\n         },\n         \"registered_country\" : {\n            \"geoname_id\" : 123,\n            \"iso_code\" : \"BR\",\n            \"names\" : {\n               \"en\" : \"Brazil\",\n               \"pt-BR\" : \"Brasil\"\n            }\n         },\n         \"postal\": {\n            \"code\": \"50040090\"\n         },\n         \"city\": {\n            \"names\": {\n                \"en\": \"Recife\"\n            }\n         }\n      }\n   }\n]\n\n"
  },
  {
    "path": "test/test-cases/data/SoapEnvelope-bad.dtd",
    "content": "<!-- A stupid Soap DTD example -->\n<!ELEMENT Envelope (Header?,Body)>\n<!ELEMENT Header (#PCDATA)>\n<!ELEMENT Body (getInput)>\n\n<!ELEMENT getInput (id)>\n<!ELEMENT id (#PCDATA)>\n<!ATLIST id type CDATA #REQUIRED>\n"
  },
  {
    "path": "test/test-cases/data/SoapEnvelope-bad.xsd",
    "content": "<?xml version='1.0' encoding='UTF-8' ?>\n\n<!-- Schema for the SOAP/1.1 envelope\n\nPortions © 2001 DevelopMentor. \n© 2001 W3C (Massachusetts Institute of Technology, Institut National de Recherche en Informatique et en Automatique, Keio University). All Rights Reserved.  \n \nThis document is governed by the W3C Software License [1] as described in the FAQ [2].\n[1] http://www.w3.org/Consortium/Legal/copyright-software-19980720\n[2] http://www.w3.org/Consortium/Legal/IPR-FAQ-20000620.html#DTD \nBy obtaining, using and/or copying this work, you (the licensee) agree that you have read, understood, and will comply with the following terms and conditions:\n\nPermission to use, copy, modify, and distribute this software and its documentation, with or without modification,  for any purpose and without fee or royalty is hereby granted, provided that you include the following on ALL copies of the software and documentation or portions thereof, including modifications, that you make:\n\n1.  The full text of this NOTICE in a location viewable to users of the redistributed or derivative work. \n\n2.  Any pre-existing intellectual property disclaimers, notices, or terms and conditions. If none exist, a short notice of the following form (hypertext is preferred, text is permitted) should be used within the body of any redistributed or derivative code: \"Copyright © 2001 World Wide Web Consortium, (Massachusetts Institute of Technology, Institut National de Recherche en Informatique et en Automatique, Keio University). All Rights Reserved. http://www.w3.org/Consortium/Legal/\" \n\n3.  Notice of any changes or modifications to the W3C files, including the date changes were made. (We recommend you provide URIs to the location from which the code is derived.)   \n\nOriginal W3C files; http://www.w3.org/2001/06/soap-envelope\nChanges made: \n     - reverted namespace to http://schemas.xmlsoap.org/soap/envelope/\n     - reverted mustUnderstand to only allow 0 and 1 as lexical values\n\t - made encodingStyle a global attribute 20020825\n\t - removed default value from mustUnderstand attribute declaration\n\nTHIS SOFTWARE AND DOCUMENTATION IS PROVIDED \"AS IS,\" AND COPYRIGHT HOLDERS MAKE NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO, WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF THE SOFTWARE OR DOCUMENTATION WILL NOT INFRINGE ANY THIRD PARTY PATENTS, COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS.\n\nCOPYRIGHT HOLDERS WILL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF ANY USE OF THE SOFTWARE OR DOCUMENTATION.\n\nThe name and trademarks of copyright holders may NOT be used in advertising or publicity pertaining to the software without specific, written prior permission. Title to copyright in this software and any associated documentation will at all times remain with copyright holders.\n\n-->\n<xs:chema xmlns:xs=\"http://www.w3.org/2001/XMLSchema\"\n           xmlns:tns=\"http://schemas.xmlsoap.org/soap/envelope/\"\n           targetNamespace=\"http://schemas.xmlsoap.org/soap/envelope/\" >\n\n     \n  <!-- Envelope, header and body -->\n  <xs:element name=\"Envelope\" type=\"tns:Envelope\" />\n  <xs:complexType name=\"Envelope\" >\n    <xs:sequence>\n      <xs:element ref=\"tns:Header\" minOccurs=\"0\" />\n      <xs:element ref=\"tns:Body\" minOccurs=\"1\" />\n      <xs:any namespace=\"##other\" minOccurs=\"0\" maxOccurs=\"unbounded\" processContents=\"lax\" />\n    </xs:sequence>\n    <xs:anyAttribute namespace=\"##other\" processContents=\"lax\" />\n  </xs:complexType>\n\n  <xs:element name=\"Header\" type=\"tns:Header\" />\n  <xs:complexType name=\"Header\" >\n    <xs:sequence>\n      <xs:any namespace=\"##other\" minOccurs=\"0\" maxOccurs=\"unbounded\" processContents=\"lax\" />\n    </xs:sequence>\n    <xs:anyAttribute namespace=\"##other\" processContents=\"lax\" />\n  </xs:complexType>\n  \n  <xs:element name=\"Body\" type=\"tns:Body\" />\n  <xs:complexType name=\"Body\" >\n    <xs:sequence>\n      <xs:any namespace=\"##any\" minOccurs=\"0\" maxOccurs=\"unbounded\" processContents=\"lax\" />\n    </xs:sequence>\n    <xs:anyAttribute namespace=\"##any\" processContents=\"lax\" >\n\t  <xs:annotation>\n\t    <xs:documentation>\n\t\t  Prose in the spec does not specify that attributes are allowed on the Body element\n\t\t</xs:documentation>\n\t  </xs:annotation>\n\t</xs:anyAttribute>\n  </xs:complexType>\n\n       \n  <!-- Global Attributes.  The following attributes are intended to be usable via qualified attribute names on any complex type referencing them.  -->\n  <xs:attribute name=\"mustUnderstand\" >\t\n     <xs:simpleType>\n     <xs:restriction base='xs:boolean'>\n\t   <xs:pattern value='0|1' />\n\t </xs:restriction>\n   </xs:simpleType>\n  </xs:attribute>\n  <xs:attribute name=\"actor\" type=\"xs:anyURI\" />\n\n  <xs:simpleType name=\"encodingStyle\" >\n    <xs:annotation>\n\t  <xs:documentation>\n\t    'encodingStyle' indicates any canonicalization conventions followed in the contents of the containing element.  For example, the value 'http://schemas.xmlsoap.org/soap/encoding/' indicates the pattern described in SOAP specification\n\t  </xs:documentation>\n\t</xs:annotation>\n    <xs:list itemType=\"xs:anyURI\" />\n  </xs:simpleType>\n\n  <xs:attribute name=\"encodingStyle\" type=\"tns:encodingStyle\" />\n  <xs:attributeGroup name=\"encodingStyle\" >\n    <xs:attribute ref=\"tns:encodingStyle\" />\n  </xs:attributeGroup>\n\n  <xs:element name=\"Fault\" type=\"tns:Fault\" />\n  <xs:complexType name=\"Fault\" final=\"extension\" >\n    <xs:annotation>\n\t  <xs:documentation>\n\t    Fault reporting structure\n\t  </xs:documentation>\n\t</xs:annotation>\n    <xs:sequence>\n      <xs:element name=\"faultcode\" type=\"xs:QName\" />\n      <xs:element name=\"faultstring\" type=\"xs:string\" />\n      <xs:element name=\"faultactor\" type=\"xs:anyURI\" minOccurs=\"0\" />\n      <xs:element name=\"detail\" type=\"tns:detail\" minOccurs=\"0\" />      \n    </xs:sequence>\n  </xs:complexType>\n\n  <xs:complexType name=\"detail\">\n    <xs:sequence>\n      <xs:any namespace=\"##any\" minOccurs=\"0\" maxOccurs=\"unbounded\" processContents=\"lax\" />\n    </xs:sequence>\n    <xs:anyAttribute namespace=\"##any\" processContents=\"lax\" /> \n  </xs:complexType>\n\n</xs:schema>\n\n\n\n\n\n\n"
  },
  {
    "path": "test/test-cases/data/SoapEnvelope.dtd",
    "content": "<!-- A stupid Soap DTD example -->\n<!ELEMENT Envelope (Header?,Body)>\n<!ELEMENT Header (#PCDATA)>\n<!ELEMENT Body (getInput)>\n\n<!ELEMENT getInput (id)>\n<!ELEMENT id (#PCDATA)>\n<!ATTLIST id type CDATA #REQUIRED>\n"
  },
  {
    "path": "test/test-cases/data/SoapEnvelope.xsd",
    "content": "<?xml version='1.0' encoding='UTF-8' ?>\n\n<!-- Schema for the SOAP/1.1 envelope\n\nPortions © 2001 DevelopMentor. \n© 2001 W3C (Massachusetts Institute of Technology, Institut National de Recherche en Informatique et en Automatique, Keio University). All Rights Reserved.  \n \nThis document is governed by the W3C Software License [1] as described in the FAQ [2].\n[1] http://www.w3.org/Consortium/Legal/copyright-software-19980720\n[2] http://www.w3.org/Consortium/Legal/IPR-FAQ-20000620.html#DTD \nBy obtaining, using and/or copying this work, you (the licensee) agree that you have read, understood, and will comply with the following terms and conditions:\n\nPermission to use, copy, modify, and distribute this software and its documentation, with or without modification,  for any purpose and without fee or royalty is hereby granted, provided that you include the following on ALL copies of the software and documentation or portions thereof, including modifications, that you make:\n\n1.  The full text of this NOTICE in a location viewable to users of the redistributed or derivative work. \n\n2.  Any pre-existing intellectual property disclaimers, notices, or terms and conditions. If none exist, a short notice of the following form (hypertext is preferred, text is permitted) should be used within the body of any redistributed or derivative code: \"Copyright © 2001 World Wide Web Consortium, (Massachusetts Institute of Technology, Institut National de Recherche en Informatique et en Automatique, Keio University). All Rights Reserved. http://www.w3.org/Consortium/Legal/\" \n\n3.  Notice of any changes or modifications to the W3C files, including the date changes were made. (We recommend you provide URIs to the location from which the code is derived.)   \n\nOriginal W3C files; http://www.w3.org/2001/06/soap-envelope\nChanges made: \n     - reverted namespace to http://schemas.xmlsoap.org/soap/envelope/\n     - reverted mustUnderstand to only allow 0 and 1 as lexical values\n\t - made encodingStyle a global attribute 20020825\n\t - removed default value from mustUnderstand attribute declaration\n\nTHIS SOFTWARE AND DOCUMENTATION IS PROVIDED \"AS IS,\" AND COPYRIGHT HOLDERS MAKE NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO, WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF THE SOFTWARE OR DOCUMENTATION WILL NOT INFRINGE ANY THIRD PARTY PATENTS, COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS.\n\nCOPYRIGHT HOLDERS WILL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF ANY USE OF THE SOFTWARE OR DOCUMENTATION.\n\nThe name and trademarks of copyright holders may NOT be used in advertising or publicity pertaining to the software without specific, written prior permission. Title to copyright in this software and any associated documentation will at all times remain with copyright holders.\n\n-->\n<xs:schema xmlns:xs=\"http://www.w3.org/2001/XMLSchema\"\n           xmlns:tns=\"http://schemas.xmlsoap.org/soap/envelope/\"\n           targetNamespace=\"http://schemas.xmlsoap.org/soap/envelope/\" >\n\n     \n  <!-- Envelope, header and body -->\n  <xs:element name=\"Envelope\" type=\"tns:Envelope\" />\n  <xs:complexType name=\"Envelope\" >\n    <xs:sequence>\n      <xs:element ref=\"tns:Header\" minOccurs=\"0\" />\n      <xs:element ref=\"tns:Body\" minOccurs=\"1\" />\n      <xs:any namespace=\"##other\" minOccurs=\"0\" maxOccurs=\"unbounded\" processContents=\"lax\" />\n    </xs:sequence>\n    <xs:anyAttribute namespace=\"##other\" processContents=\"lax\" />\n  </xs:complexType>\n\n  <xs:element name=\"Header\" type=\"tns:Header\" />\n  <xs:complexType name=\"Header\" >\n    <xs:sequence>\n      <xs:any namespace=\"##other\" minOccurs=\"0\" maxOccurs=\"unbounded\" processContents=\"lax\" />\n    </xs:sequence>\n    <xs:anyAttribute namespace=\"##other\" processContents=\"lax\" />\n  </xs:complexType>\n  \n  <xs:element name=\"Body\" type=\"tns:Body\" />\n  <xs:complexType name=\"Body\" >\n    <xs:sequence>\n      <xs:any namespace=\"##any\" minOccurs=\"0\" maxOccurs=\"unbounded\" processContents=\"lax\" />\n    </xs:sequence>\n    <xs:anyAttribute namespace=\"##any\" processContents=\"lax\" >\n\t  <xs:annotation>\n\t    <xs:documentation>\n\t\t  Prose in the spec does not specify that attributes are allowed on the Body element\n\t\t</xs:documentation>\n\t  </xs:annotation>\n\t</xs:anyAttribute>\n  </xs:complexType>\n\n       \n  <!-- Global Attributes.  The following attributes are intended to be usable via qualified attribute names on any complex type referencing them.  -->\n  <xs:attribute name=\"mustUnderstand\" >\t\n     <xs:simpleType>\n     <xs:restriction base='xs:boolean'>\n\t   <xs:pattern value='0|1' />\n\t </xs:restriction>\n   </xs:simpleType>\n  </xs:attribute>\n  <xs:attribute name=\"actor\" type=\"xs:anyURI\" />\n\n  <xs:simpleType name=\"encodingStyle\" >\n    <xs:annotation>\n\t  <xs:documentation>\n\t    'encodingStyle' indicates any canonicalization conventions followed in the contents of the containing element.  For example, the value 'http://schemas.xmlsoap.org/soap/encoding/' indicates the pattern described in SOAP specification\n\t  </xs:documentation>\n\t</xs:annotation>\n    <xs:list itemType=\"xs:anyURI\" />\n  </xs:simpleType>\n\n  <xs:attribute name=\"encodingStyle\" type=\"tns:encodingStyle\" />\n  <xs:attributeGroup name=\"encodingStyle\" >\n    <xs:attribute ref=\"tns:encodingStyle\" />\n  </xs:attributeGroup>\n\n  <xs:element name=\"Fault\" type=\"tns:Fault\" />\n  <xs:complexType name=\"Fault\" final=\"extension\" >\n    <xs:annotation>\n\t  <xs:documentation>\n\t    Fault reporting structure\n\t  </xs:documentation>\n\t</xs:annotation>\n    <xs:sequence>\n      <xs:element name=\"faultcode\" type=\"xs:QName\" />\n      <xs:element name=\"faultstring\" type=\"xs:string\" />\n      <xs:element name=\"faultactor\" type=\"xs:anyURI\" minOccurs=\"0\" />\n      <xs:element name=\"detail\" type=\"tns:detail\" minOccurs=\"0\" />      \n    </xs:sequence>\n  </xs:complexType>\n\n  <xs:complexType name=\"detail\">\n    <xs:sequence>\n      <xs:any namespace=\"##any\" minOccurs=\"0\" maxOccurs=\"unbounded\" processContents=\"lax\" />\n    </xs:sequence>\n    <xs:anyAttribute namespace=\"##any\" processContents=\"lax\" /> \n  </xs:complexType>\n\n</xs:schema>\n\n\n\n\n\n\n"
  },
  {
    "path": "test/test-cases/data/SoapEnvelope2.xsd",
    "content": "<?xml version='1.0' encoding='UTF-8' ?>\n\n<!-- Schema for the SOAP/1.1 envelope\n\nPortions © 2001 DevelopMentor. \n© 2001 W3C (Massachusetts Institute of Technology, Institut National de Recherche en Informatique et en Automatique, Keio University). All Rights Reserved.  \n \nThis document is governed by the W3C Software License [1] as described in the FAQ [2].\n[1] http://www.w3.org/Consortium/Legal/copyright-software-19980720\n[2] http://www.w3.org/Consortium/Legal/IPR-FAQ-20000620.html#DTD \nBy obtaining, using and/or copying this work, you (the licensee) agree that you have read, understood, and will comply with the following terms and conditions:\n\nPermission to use, copy, modify, and distribute this software and its documentation, with or without modification,  for any purpose and without fee or royalty is hereby granted, provided that you include the following on ALL copies of the software and documentation or portions thereof, including modifications, that you make:\n\n1.  The full text of this NOTICE in a location viewable to users of the redistributed or derivative work. \n\n2.  Any pre-existing intellectual property disclaimers, notices, or terms and conditions. If none exist, a short notice of the following form (hypertext is preferred, text is permitted) should be used within the body of any redistributed or derivative code: \"Copyright © 2001 World Wide Web Consortium, (Massachusetts Institute of Technology, Institut National de Recherche en Informatique et en Automatique, Keio University). All Rights Reserved. http://www.w3.org/Consortium/Legal/\" \n\n3.  Notice of any changes or modifications to the W3C files, including the date changes were made. (We recommend you provide URIs to the location from which the code is derived.)   \n\nOriginal W3C files; http://www.w3.org/2001/06/soap-envelope\nChanges made: \n     - reverted namespace to http://schemas.xmlsoap.org/soap/envelope/\n     - reverted mustUnderstand to only allow 0 and 1 as lexical values\n\t - made encodingStyle a global attribute 20020825\n\t - removed default value from mustUnderstand attribute declaration\n\nTHIS SOFTWARE AND DOCUMENTATION IS PROVIDED \"AS IS,\" AND COPYRIGHT HOLDERS MAKE NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO, WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF THE SOFTWARE OR DOCUMENTATION WILL NOT INFRINGE ANY THIRD PARTY PATENTS, COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS.\n\nCOPYRIGHT HOLDERS WILL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF ANY USE OF THE SOFTWARE OR DOCUMENTATION.\n\nThe name and trademarks of copyright holders may NOT be used in advertising or publicity pertaining to the software without specific, written prior permission. Title to copyright in this software and any associated documentation will at all times remain with copyright holders.\n\n-->\n<xs:schema xmlns:xs=\"http://www.w3.org/2001/XMLSchema\"\n           xmlns:tns=\"http://schemas.xmlsoap.org/soap/envelope/\"\n           targetNamespace=\"http://schemas.xmlsoap.org/soap/envelope/\" >\n\n     \n  <!-- Envelope, header and body -->\n  <xs:element name=\"Envelope\" type=\"tns:Envelope\" />\n  <xs:complexType name=\"Envelope\" >\n    <xs:sequence>\n      <xs:element ref=\"tns:Header\" minOccurs=\"0\" />\n      <xs:element ref=\"tns:Body\" minOccurs=\"1\" />\n      <xs:any namespace=\"##other\" minOccurs=\"0\" maxOccurs=\"unbounded\" processContents=\"lax\" />\n    </xs:sequence>\n    <xs:anyAttribute namespace=\"##other\" processContents=\"lax\" />\n  </xs:complexType>\n\n  <xs:element name=\"Header\" type=\"tns:Header\" />\n  <xs:complexType name=\"Header\" >\n    <xs:sequence>\n      <xs:any namespace=\"##other\" minOccurs=\"0\" maxOccurs=\"unbounded\" processContents=\"lax\" />\n    </xs:sequence>\n    <xs:anyAttribute namespace=\"##other\" processContents=\"lax\" />\n  </xs:complexType>\n  \n  <xs:element name=\"Body\" type=\"tns:Body\" />\n  <xs:complexType name=\"Body\" >\n    <xs:sequence>\n      <xs:any namespace=\"##any\" minOccurs=\"0\" maxOccurs=\"unbounded\" processContents=\"lax\" />\n    </xs:sequence>\n    <xs:anyAttribute namespace=\"##any\" processContents=\"lax\" >\n\t  <xs:annotation>\n\t    <xs:documentation>\n\t\t  Prose in the spec does not specify that attributes are allowed on the Body element\n\t\t</xs:documentation>\n\t  </xs:annotation>\n\t</xs:anyAttribute>\n  </xs:complexType>\n\n       \n  <!-- Global Attributes.  The following attributes are intended to be usable via qualified attribute names on any complex type referencing them.  -->\n  <xs:attribute name=\"mustUnderstand\" >\t\n     <xs:simpleType>\n     <xs:restriction base='xs:boolean'>\n\t   <xs:pattern value='0|1' />\n\t </xs:restriction>\n   </xs:simpleType>\n  </xs:attribute>\n  <xs:attribute name=\"actor\" type=\"xs:anyURI\" />\n\n  <xs:simpleType name=\"encodingStyle\" >\n    <xs:annotation>\n\t  <xs:documentation>\n\t    'encodingStyle' indicates any canonicalization conventions followed in the contents of the containing element.  For example, the value 'http://schemas.xmlsoap.org/soap/encoding/' indicates the pattern described in SOAP specification\n\t  </xs:documentation>\n\t</xs:annotation>\n    <xs:list itemType=\"xs:anyURI\" />\n  </xs:simpleType>\n\n  <xs:attribute name=\"encodingStyle\" type=\"tns:encodingStyle\" />\n  <xs:attributeGroup name=\"encodingStyle\" >\n    <xs:attribute ref=\"tns:encodingStyle\" />\n  </xs:attributeGroup>\n\n  <xs:element name=\"Fault\" type=\"tns:Fault\" />\n  <xs:complexType name=\"Fault\" final=\"extension\" >\n    <xs:annotation>\n\t  <xs:documentation>\n\t    Fault reporting structure\n\t  </xs:documentation>\n\t</xs:annotation>\n    <xs:sequence>\n      <xs:element name=\"faultcode\" type=\"xs:QName\" />\n      <xs:element name=\"faultstring\" type=\"xs:string\" />\n      <xs:element name=\"faultactor\" type=\"xs:anyURI\" minOccurs=\"0\" />\n      <xs:element name=\"detail\" type=\"tns:detail\" minOccurs=\"0\" />      \n    </xs:sequence>\n  </xs:complexType>\n\n  <xs:complexType name=\"detail\">\n    <xs:sequence>\n      <xs:any namespace=\"##any\" minOccurs=\"0\" maxOccurs=\"unbounded\" processContents=\"lax\" />\n    </xs:sequence>\n    <xs:anyAttribute namespace=\"##any\" processContents=\"lax\" /> \n  </xs:complexType>\n\n</xs:schema>\n\n\n\n\n\n\n"
  },
  {
    "path": "test/test-cases/data/big-file.conf",
    "content": "# 1\n# 2\n# 3\n# 4\n# 5\n# 6\n# 7\n# 8\n\n# 10\n# 11\n# 12\n\n\n\nSecRule TX:PARANOIA_LEVEL \"@lt 1\" \"phase:1,id:930011,nolog,pass,skipAfter:END-REQUEST-930-APPLICATION-ATTACK-LFI\" \nSecRule TX:PARANOIA_LEVEL \"@lt 1\" \"phase:2,id:930012,nolog,pass,skipAfter:END-REQUEST-930-APPLICATION-ATTACK-LFI\"\n# 18\n# 19\n# 20\n\n# 22\n# 23\n# 24\n# 25\n# 26\n# 27\n# 28\nSecRule REQUEST_URI_RAW|REQUEST_BODY|REQUEST_HEADERS|!REQUEST_HEADERS:Referer|XML:/* \"(?i)(?:\\x5c|(?:%(?:c(?:0%(?:[2aq]f|5c|9v)|1%(?:[19p]c|8s|af))|2(?:5(?:c(?:0%25af|1%259c)|2f|5c)|%46|f)|(?:(?:f(?:8%8)?0%8|e)0%80%a|bg%q)f|%3(?:2(?:%(?:%6|4)6|F)|5%%63)|u(?:221[56]|002f|EFC8|F025)|1u|5c)|0x(?:2f|5c)|\\/))(?:%(?:(?:f(?:(?:c%80|8)%8)?0%8|e)0%80%ae|2(?:(?:5(?:c0%25a|2))?e|%45)|u(?:(?:002|ff0)e|2024)|%32(?:%(?:%6|4)5|E)|c0(?:%[256aef]e|\\.))|\\.(?:%0[01]|\\?)?|\\?\\.?|0x2e){2}(?:\\x5c|(?:%(?:c(?:0%(?:[2aq]f|5c|9v)|1%(?:[19p]c|8s|af))|2(?:5(?:c(?:0%25af|1%259c)|2f|5c)|%46|f)|(?:(?:f(?:8%8)?0%8|e)0%80%a|bg%q)f|%3(?:2(?:%(?:%6|4)6|F)|5%%63)|u(?:221[56]|002f|EFC8|F025)|1u|5c)|0x(?:2f|5c)|\\/))|test1\" \\\n\t\"phase:request,\\\n\tmsg:'Path Traversal Attack (/../)',\\\n\tid:930100,\\\n\tver:'OWASP_CRS/3.0.0',\\\n\trev:'3',\\\n\tmaturity:'9',\\\n\taccuracy:'7',\\\n\tt:none,\\\n\tblock,\\\n\tseverity:CRITICAL,\\\n\tlogdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\\\n\tcapture,\\\n\ttag:'application-multi',\\\n\ttag:'language-multi',\\\n\ttag:'platform-multi',\\\n\ttag:'attack-lfi',\\\n\ttag:'OWASP_CRS/WEB_ATTACK/DIR_TRAVERSAL',\\\n\tsetvar:'tx.msg=%{rule.msg}',\\\n\tsetvar:tx.anomaly_score=+%{tx.critical_anomaly_score},\\\n\tsetvar:tx.lfi_score=+%{tx.critical_anomaly_score},\\\n\tsetvar:'tx.%{rule.id}-OWASP_CRS/WEB_ATTACK/DIR_TRAVERSAL-%{matched_var_name}=%{matched_var}'\"\n\n# 52\n# 53\n# 54\nSecRule REQUEST_URI|REQUEST_BODY|REQUEST_HEADERS|!REQUEST_HEADERS:Referer|XML:/* \"@pm test2\" \\\n\t\"phase:request,\\\n        msg:'Path Traversal Attack (/../)',\\\n        id:930110,\\\n        ver:'OWASP_CRS/3.0.0',\\\n        rev:'1',\\\n        maturity:'9',\\\n\taccuracy:'7',\\\n\tmultiMatch,\\\n        t:none,t:utf8toUnicode,t:urlDecodeUni,t:removeNulls,t:cmdLine,\\\n        block,\\\n        severity:CRITICAL,\\\n        logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\\\n        capture,\\\n        tag:'application-multi',\\\n        tag:'language-multi',\\\n        tag:'platform-multi',\\\n        tag:'attack-lfi',\\\n        tag:'OWASP_CRS/WEB_ATTACK/DIR_TRAVERSAL',\\\n        setvar:'tx.msg=%{rule.msg}',\\\n        setvar:tx.anomaly_score=+%{tx.critical_anomaly_score},\\\n        setvar:tx.lfi_score=+%{tx.critical_anomaly_score},\\\n        setvar:'tx.%{rule.id}-OWASP_CRS/WEB_ATTACK/DIR_TRAVERSAL-%{matched_var_name}=%{matched_var}'\"\n\n# 79\n# 80\n# 81\n# 82\n# 83\nSecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|REQUEST_COOKIES_NAMES|ARGS_NAMES|ARGS|XML:/* \"@pm test3\" \\\n\t\"phase:request,\\\n\tmsg:'OS File Access Attempt',\\\n\trev:'4',\\\n\tver:'OWASP_CRS/3.0.0',\\\n\tmaturity:'9',\\\n\taccuracy:'9',\\\n\tcapture,\\\n\tt:none,t:utf8toUnicode,t:urlDecodeUni,t:normalizePathWin,t:lowercase,\\\n\tblock,\\\n\tid:930120,\\\n        tag:'application-multi',\\\n        tag:'language-multi',\\\n        tag:'platform-multi',\\\n        tag:'attack-lfi',\\\n\ttag:'OWASP_CRS/WEB_ATTACK/FILE_INJECTION',\\\n\ttag:'WASCTC/WASC-33',\\\n\ttag:'OWASP_TOP_10/A4',\\\n\ttag:'PCI/6.5.4',\\\n\tlogdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\\\n\tseverity:'CRITICAL',\\\n\tsetvar:'tx.msg=%{rule.msg}',\\\n\tsetvar:tx.lfi_score=+%{tx.critical_anomaly_score},\\\n\tsetvar:tx.anomaly_score=+%{tx.critical_anomaly_score},\\\n\tsetvar:tx.%{rule.id}-OWASP_CRS/WEB_ATTACK/FILE_INJECTION-%{matched_var_name}=%{tx.0}\"\n\n# 110\n# 111\n# 112\n# 113\n# 114\n# 115\nSecRule REQUEST_FILENAME|ARGS \"@pm test4\" \\\n\t\"phase:request,\\\n\tmsg:'Restricted File Access Attempt',\\\n\trev:'1',\\\n\tver:'OWASP_CRS/3.0.0',\\\n\tmaturity:'7',\\\n\taccuracy:'8',\\\n\tcapture,\\\n\tt:none,t:utf8toUnicode,t:urlDecodeUni,t:normalizePathWin,t:lowercase,\\\n\tblock,\\\n\tid:930130,\\\n\ttag:'application-multi',\\\n\ttag:'language-multi',\\\n\ttag:'platform-multi',\\\n\ttag:'attack-lfi',\\\n\ttag:'OWASP_CRS/WEB_ATTACK/FILE_INJECTION',\\\n\ttag:'WASCTC/WASC-33',\\\n\ttag:'OWASP_TOP_10/A4',\\\n\ttag:'PCI/6.5.4',\\\n\tlogdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\\\n\tseverity:'CRITICAL',\\\n\tsetvar:'tx.msg=%{rule.msg}',\\\n\tsetvar:tx.lfi_score=+%{tx.critical_anomaly_score},\\\n\tsetvar:tx.anomaly_score=+%{tx.critical_anomaly_score},\\\n\tsetvar:tx.%{rule.id}-OWASP_CRS/WEB_ATTACK/FILE_INJECTION-%{matched_var_name}=%{tx.0}\"\n\n\n\nSecRule TX:PARANOIA_LEVEL \"@lt 2\" \"phase:1,id:930013,nolog,pass,skipAfter:END-REQUEST-930-APPLICATION-ATTACK-LFI\"\nSecRule TX:PARANOIA_LEVEL \"@lt 2\" \"phase:2,id:930014,nolog,pass,skipAfter:END-REQUEST-930-APPLICATION-ATTACK-LFI\"\n# 146\n# 147\n# 148\n\n\n\nSecRule TX:PARANOIA_LEVEL \"@lt 3\" \"phase:1,id:930015,nolog,pass,skipAfter:END-REQUEST-930-APPLICATION-ATTACK-LFI\"\nSecRule TX:PARANOIA_LEVEL \"@lt 3\" \"phase:2,id:930016,nolog,pass,skipAfter:END-REQUEST-930-APPLICATION-ATTACK-LFI\"\n# 154\n# 155\n# 156\n\n\n\nSecRule TX:PARANOIA_LEVEL \"@lt 4\" \"phase:1,id:930017,nolog,pass,skipAfter:END-REQUEST-930-APPLICATION-ATTACK-LFI\"\nSecRule TX:PARANOIA_LEVEL \"@lt 4\" \"phase:2,id:930018,nolog,pass,skipAfter:END-REQUEST-930-APPLICATION-ATTACK-LFI\"\n# 162\n# 163\n# 164\n\n\n\n# 168\n# 169\n# 170\nSecMarker \"END-REQUEST-930-APPLICATION-ATTACK-LFI\"\n# 172\n\nSecRule REQUEST_FILENAME|ARGS \"@pm test5\" \\\n\t\"phase:request,\\\n\tmsg:'Restricted File Access Attempt',\\\n\trev:'1',\\\n\tver:'OWASP_CRS/3.0.0',\\\n\tmaturity:'7',\\\n\taccuracy:'8',\\\n\tcapture,\\\n\tt:none,t:utf8toUnicode,t:urlDecodeUni,t:normalizePathWin,t:lowercase,\\\n\tblock,\\\n\tid:9304130,\\\n\ttag:'application-multi',\\\n\ttag:'language-multi',\\\n\ttag:'platform-multi',\\\n\ttag:'attack-lfi',\\\n\ttag:'OWASP_CRS/WEB_ATTACK/FILE_INJECTION',\\\n\ttag:'WASCTC/WASC-33',\\\n\ttag:'OWASP_TOP_10/A4',\\\n\ttag:'PCI/6.5.4',\\\n\tlogdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}',\\\n\tseverity:'CRITICAL',\\\n\tsetvar:'tx.msg=%{rule.msg}',\\\n\tsetvar:tx.lfi_score=+%{tx.critical_anomaly_score},\\\n\tsetvar:tx.anomaly_score=+%{tx.critical_anomaly_score},\\\n\tsetvar:tx.%{rule.id}-OWASP_CRS/WEB_ATTACK/FILE_INJECTION-%{matched_var_name}=%{tx.0}\"\n"
  },
  {
    "path": "test/test-cases/data/config_example-bad-op-include.txt",
    "content": "SecRule ARGS \"@contains config_example\" \"id:10,pass,t:trim\"\nSecRule ARGS 123 \"@missingOperator config_example\" \"id:11,pass,t:trim\"\n"
  },
  {
    "path": "test/test-cases/data/config_example-ops-include.txt",
    "content": "Include test-cases/data/config_example-not-exist.txt"
  },
  {
    "path": "test/test-cases/data/config_example.txt",
    "content": "Include test-cases/data/config_example2.txt\nSecRule ARGS \"@contains config_example\" \"id:101,pass,t:trim\""
  },
  {
    "path": "test/test-cases/data/config_example2.txt",
    "content": "SecRule ARGS \"@contains config_example2\" \"id:40,pass,t:trim\""
  },
  {
    "path": "test/test-cases/data/config_example3.txt",
    "content": "Include test-cases/data/config_example2.txt\nSecRule ARGS \"@contains config_example\" ops \"id:1000,pass,t:trim\""
  },
  {
    "path": "test/test-cases/data/geo/README.txt",
    "content": "This data was download from:\n\nhttps://github.com/maxmind/geoip-api-php/tree/master/tests\n\n"
  },
  {
    "path": "test/test-cases/data/inspectFile-abcdef.lua",
    "content": "#!/usr/bin/lua\n\nfunction main(filename)\n    local file = io.open(filename, 'r')\n    local chunk = file:read(1024)\n    local ret = string.match(chunk, 'abcdef')\n    io.close(file)\n\n    return ret\nend\n"
  },
  {
    "path": "test/test-cases/data/ipMatchFromFile.txt",
    "content": "127.0.0.1\n\n# Comment line\n10.10.10.1\n::1\n200.249.12.31\n"
  },
  {
    "path": "test/test-cases/data/match-getvar-multi-transformations.lua",
    "content": "function main()\n    ret = nil\n    m.log(9, \"Lets rock.\");\n\n    var = m.getvar(\"tx.test\" , { \"lowercase\", \"uppercase\" });\n    if var == nil then\n        m.log(9, \"Don't know what to say...\");\n        return ret;\n    end\n\n    if var == \"FELIPE\" then\n        m.log(9, \"Whee. Working like a charm. That is what we have: \" .. var);\n    elseif var == \"felipe\" then\n        m.log(9, \"Oh boy. Got: \" .. var);\n        ret =\"ok\";\n    else\n        m.log(9, \"Really?\");\n    end\n\n    return \"whee\"\nend\n"
  },
  {
    "path": "test/test-cases/data/match-getvar-transformation.lua",
    "content": "function main()\n    ret = nil\n    m.log(9, \"Lets rock.\");\n\n    var = m.getvar(\"tx.test\" , \"lowercase\");\n    if var == nil then\n        m.log(9, \"Don't know what to say...\");\n        return ret;\n    end\n\n    if var == \"FELIPE\" then\n        m.log(9, \"Ops.\");\n    elseif var == \"felipe\" then\n        m.log(9, \"Just fine.\");\n        ret =\"ok\";\n    else\n        m.log(9, \"Really?\");\n    end\n\n    return \"whee\"\nend\n"
  },
  {
    "path": "test/test-cases/data/match-getvar-withTnfs.lua",
    "content": "function main()\n    ret = nil\n\n    var = m.getvar(\"tx.test\", \"lowercase\");\n\n    return ret\nend\n"
  },
  {
    "path": "test/test-cases/data/match-getvar.lua",
    "content": "function main()\n    ret = nil\n\n    num = m.getvar(\"tx.test\");\n    if num == nil then\n        m.log(9, \"Don't know what to say about this so called number.\");\n        return ret\n    end\n    num = tonumber(num)\n\n    if num > 1 then\n        m.log(9, \"Number is bigger than one.\");\n        ret = \"Whee :)\"\n    else\n        m.log(9, \"Really?\");\n    end\n\n    return ret\nend\n"
  },
  {
    "path": "test/test-cases/data/match-getvars-args.lua",
    "content": "function main()\n    local d = m.getvars(\"ARGS\");\n    local size = #d;\n    m.log(9,\"ARGS count read =\" .. tostring(size));\n\n    ret = nil\n\n    if ( #d == 2 ) then\n        return nil\n    end\n\n    return \"Unexpected result\"\nend\n"
  },
  {
    "path": "test/test-cases/data/match-getvars.lua",
    "content": "function dump(o)\n   if type(o) == 'table' then\n      local s = '{ '\n      for k,v in pairs(o) do\n         if type(k) ~= 'number' then k = '\"'..k..'\"' end\n         s = s .. '['..k..'] = ' .. dump(v) .. ','\n      end\n      return s .. '} '\n   else\n      return tostring(o)\n   end\nend\n\nfunction main()\n    ret = nil\n    m.log(9, \"Here I am\");\n    z = m.getvars(\"QUERY_STRING\");\n    m.log(9, \"Z: \" .. dump(z))\n\n    return ret\nend\n"
  },
  {
    "path": "test/test-cases/data/match-log.lua",
    "content": "function main()\n    m.log(9, \"echo 123\");\n    return \"Lua script matched.\";\nend\n"
  },
  {
    "path": "test/test-cases/data/match-set.lua",
    "content": "function main()\n    m.log(9, \"echo 123\");\n    m.setvar(\"tx.test\", \"whee\");\n    return \"Lua script matched.\";\nend\n"
  },
  {
    "path": "test/test-cases/data/match.lua",
    "content": "function main()\n    return \"Lua script matched.\";\nend\n"
  },
  {
    "path": "test/test-cases/data/not-so-big-file.conf",
    "content": "# 1\n# 2\n# 3\n# 4\n# 5\n# 6\n# 7\n# 8\n\n# 10\n# 11\n# 12\n\nInclude \"big-file.conf\"\n\n# 18\n# 19\n# 20\n\n# 22\n# 23\n# 24\n# 25\n# 26\n# 27\n# 28\n"
  },
  {
    "path": "test/test-cases/data/pattern-file1.data",
    "content": "# comment\npattern1"
  },
  {
    "path": "test/test-cases/data/pattern-file2.data",
    "content": "# comment\npattern2\n"
  },
  {
    "path": "test/test-cases/data/script.lua",
    "content": "-- Your script must define the main entry\n-- point, as below.\nfunction main()\n    -- Log something at level 1. Normally you shouldn't be\n    -- logging anything, especially not at level 1, but this is\n    -- just to show you can. Useful for debugging.\n    m.log(1, \"Hello world!\");\n\n    -- Retrieve one variable.\n    local var1 = m.getvar(\"REMOTE_ADDR\");\n\n    -- Retrieve one variable, applying one transformation function.\n    -- The second parameter is a string.\n    local var2 = m.getvar(\"ARGS\", \"lowercase\");\n\n    -- Retrieve one variable, applying several transformation functions.\n    -- The second parameter is now a list. You should note that m.getvar()\n    -- requires the use of comma to separate collection names from\n    -- variable names. This is because only one variable is returned.\n    local var3 = m.getvar(\"ARGS.p\", { \"lowercase\", \"compressWhitespace\" } );\n\n    -- If you want this rule to match return a string\n    -- containing the error message. The message must contain the name\n    -- of the variable where the problem is located.\n    -- return \"Variable ARGS:p looks suspicious!\"\n\n    -- Otherwise, simply return nil.\n    return nil;\nend"
  },
  {
    "path": "test/test-cases/data/setvar.lua",
    "content": "function main()\n\tvar = 2;\n\tm.setvar(\"TX.lua_set_var\", var);\n\tm.setvar(\"IP.lua_set_var\", var);\n\tm.setvar(\"GLOBAL.lua_set_var\", var);\n\tm.setvar(\"RESOURCE.lua_set_var\", var);\n\tm.setvar(\"SESSION.lua_set_var\", var);\n\tm.setvar(\"USER.lua_set_var\", var);\n\treturn nil;\nend\n"
  },
  {
    "path": "test/test-cases/data/ssdeep.txt",
    "content": "ssdeep,1.1--blocksize:hash:hash,filename\n96:MbQ1L0LDX8GPI8ov3D2D9zd6/gz2wZhFvV0O598La8Kqvfi0znNa8Xi5SM7XRWCK:KvL8Gg8rWIz2ZKqvfjzQ55RpRHjftQ++,\"modsecurity.conf-recommended\"\n192:b8B5UQvywcMIJuavpde/Yyz/U/vF+vGCoCvrQr/dw:afcnrvp8zqUvGrzr6,\"README_WINDOWS.TXT\"\n96:+qK8Z4gA165/hquKNMi68zuEyMM9qNB26x:+RG4z6c1LyZOB26x,\"README.TXT\"\n"
  },
  {
    "path": "test/test-cases/data/test.lua",
    "content": ""
  },
  {
    "path": "test/test-cases/data/unicode.mapping-reduced",
    "content": "1251 0434:64 043e:6f 0440:70\n"
  },
  {
    "path": "test/test-cases/regression/action-allow.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing allow action (1/3)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"User-Agent\": \"My sweet little browser\",\n        \"Cookie\": \"PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?key=value&key=other_value\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Skipped rule id 'action-allow.json:3' as request trough the utilization of an `allow' action\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecAction \\\"phase:1,allow,msg:'ALLOWED',id:500065\\\"\",\n      \"SecAction \\\"phase:1,deny,msg:'DENIED',id:500066\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing allow action (2/3)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"User-Agent\": \"My sweet little browser\",\n        \"Cookie\": \"PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?key=value&key=other_value\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"http_code\": 500\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecAction \\\"phase:1,allow:request,msg:'ALLOWED',id:500065\\\"\",\n      \"SecRule ARGS \\\"@contains value\\\" \\\"id:1,t:trim,status:500,deny,phase:3\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing allow action (3/3)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"User-Agent\": \"My sweet little browser\",\n        \"Cookie\": \"PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?key=value&key=other_value\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"http_code\": 500\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecAction \\\"phase:1,allow:phase,msg:'ALLOWED',id:500065\\\"\",\n      \"SecRule ARGS \\\"@contains value\\\" \\\"id:1,t:trim,status:500,deny,phase:3\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/action-block.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing 'block' action without desruptive action\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 12300\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"a.b.com\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"User-Agent\": \"My sweet little browser\",\n        \"Cookie\": \"PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/path1\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"http_code\": 200,\n      \"parser_error\": \"Line: 1. Column: 16. SecDefaultAction must specify a disruptive action.\"\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecDefaultAction \\\"phase:1,log,block,status:404\\\"\",\n      \"SecRule REQUEST_URI \\\"@contains path1\\\" \\\"phase:1,block,id:5\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing 'block' action with desruptive action\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 12300\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"a.b.com\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"User-Agent\": \"My sweet little browser\",\n        \"Cookie\": \"PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/path1\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"http_code\": 400\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecDefaultAction \\\"phase:1,log,block,deny,status:400\\\"\",\n      \"SecRule REQUEST_URI \\\"@contains path1\\\" \\\"phase:1,block,id:5\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/action-ctl_audit_engine.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"version_max\": 0,\n    \"title\": \"auditengine : Config=Off, ctl:auditEngine=on\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 2313\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"www.modsecurity.org\",\n        \"User-Agent\": \"Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)\",\n        \"Accept\": \"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\",\n        \"Accept-Language\": \"en-us,en;q=0.5\",\n        \"Accept-Encoding\": \"gzip,deflate\",\n        \"Accept-Charset\": \"ISO-8859-1,utf-8;q=0.7,*;q=0.7\",\n        \"Keep-Alive\": \"300\",\n        \"Connection\": \"keep-alive\",\n        \"Pragma\": \"no-cache\",\n        \"Cache-Control\": \"no-cache\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/test.pl?parm1=test1&parm2=test2\",\n      \"method\": \"GET\",\n      \"http_version\": 1.1,\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"audit_log\": \"--A--\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecDefaultAction \\\"phase:2,nolog,pass\\\"\",\n      \"SecAuditEngine Off\",\n      \"SecAuditLogParts ABCFHZ\",\n      \"SecAuditLog /tmp/modsec_test_ctl_auditengine_auditlog_1.log\",\n      \"SecAuditLogDirMode 0766\",\n      \"SecAuditLogFileMode 0666\",\n      \"SecAuditLogType Serial\",\n      \"SecAuditLogRelevantStatus \\\"^(?:5|4(?!04))\\\"\",\n      \"SecRule ARGS \\\"@contains test2\\\" \\\"id:1701,phase:2,pass,nolog,ctl:auditEngine=on\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/action-ctl_request_body_access.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing CtlRequestBodyAccess (1)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"523\",\n        \"Content-Type\": \"multipart/form-data; boundary=------------------------756b6d74fa1a8ee2\",\n        \"Expect\": \"100-continue\"\n      },\n      \"uri\": \"/test\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"--------------------------756b6d74fa1a8ee2\\r\\n\",\n        \"Content-Disposition: form-data; name=\\\"name\\\"\\r\\n\",\n        \"\\r\\n\",\n        \"test\\r\\n\",\n        \"--------------------------756b6d74fa1a8ee2\\r\\n\",\n        \"Content-Disposition: form-data; name=\\\"filedata\\\"; filename=\\\"small_text_file.txt\\\"\\r\\n\",\n        \"Content-Type: text/plain\\r\\n\",\n        \"\\r\\n\",\n        \"This is a very small test file..\\r\\n\",\n        \"--------------------------756b6d74fa1a8ee2\\r\\n\",\n        \"Content-Disposition: form-data; name=\\\"filedata\\\"; filename=\\\"small_text_file.txt\\\"\\r\\n\",\n        \"Content-Type: text/plain\\r\\n\",\n        \"\\r\\n\",\n        \"This is another very small test file..\\r\\n\",\n        \"--------------------------756b6d74fa1a8ee2--\\r\\n\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Request body processing is enabled, but disabled to this transaction due to ctl:requestBodyAccess action\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRequestBodyAccess On\",\n      \"SecRule REQUEST_URI \\\"@contains test\\\" \\\"id:1,phase:1,pass,t:trim,ctl:RequestBodyAccess=Off\\\"\",\n      \"SecRule REQUEST_BODY \\\"@contains very small test file\\\" \\\"id:2,log,phase:3\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing CtlRequestBodyAccess (2)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"523\",\n        \"Content-Type\": \"multipart/form-data; boundary=------------------------756b6d74fa1a8ee2\",\n        \"Expect\": \"100-continue\"\n      },\n      \"uri\": \"/test\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"--------------------------756b6d74fa1a8ee2\\r\\n\",\n        \"Content-Disposition: form-data; name=\\\"name\\\"\\r\\n\",\n        \"\\r\\n\",\n        \"test\\r\\n\",\n        \"--------------------------756b6d74fa1a8ee2\\r\\n\",\n        \"Content-Disposition: form-data; name=\\\"filedata\\\"; filename=\\\"small_text_file.txt\\\"\\r\\n\",\n        \"Content-Type: text/plain\\r\\n\",\n        \"\\r\\n\",\n        \"This is a very small test file..\\r\\n\",\n        \"--------------------------756b6d74fa1a8ee2\\r\\n\",\n        \"Content-Disposition: form-data; name=\\\"filedata\\\"; filename=\\\"small_text_file.txt\\\"\\r\\n\",\n        \"Content-Type: text/plain\\r\\n\",\n        \"\\r\\n\",\n        \"This is another very small test file..\\r\\n\",\n        \"--------------------------756b6d74fa1a8ee2--\\r\\n\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"--------------------------756b6d74fa1a8ee2\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRequestBodyAccess On\",\n      \"SecRule REQUEST_URI \\\"@contains test\\\" \\\"id:1,phase:1,pass,t:trim\\\"\",\n      \"SecRule REQUEST_BODY \\\"@contains very small test file\\\" \\\"id:2,log,phase:3\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing CtlRequestBodyAccess (3)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"523\",\n        \"Content-Type\": \"multipart/form-data; boundary=------------------------756b6d74fa1a8ee2\",\n        \"Expect\": \"100-continue\"\n      },\n      \"uri\": \"/test\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"--------------------------756b6d74fa1a8ee2\\r\\n\",\n        \"Content-Disposition: form-data; name=\\\"name\\\"\\r\\n\",\n        \"\\r\\n\",\n        \"test\\r\\n\",\n        \"--------------------------756b6d74fa1a8ee2\\r\\n\",\n        \"Content-Disposition: form-data; name=\\\"filedata\\\"; filename=\\\"small_text_file.txt\\\"\\r\\n\",\n        \"Content-Type: text/plain\\r\\n\",\n        \"\\r\\n\",\n        \"This is a very small test file..\\r\\n\",\n        \"--------------------------756b6d74fa1a8ee2\\r\\n\",\n        \"Content-Disposition: form-data; name=\\\"filedata\\\"; filename=\\\"small_text_file.txt\\\"\\r\\n\",\n        \"Content-Type: text/plain\\r\\n\",\n        \"\\r\\n\",\n        \"This is another very small test file..\\r\\n\",\n        \"--------------------------756b6d74fa1a8ee2--\\r\\n\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"--------------------------756b6d74fa1a8ee2\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRequestBodyAccess Off\",\n      \"SecRule REQUEST_URI \\\"@contains test\\\" \\\"id:1,phase:1,pass,t:trim,ctl:RequestBodyAccess=On\\\"\",\n      \"SecRule REQUEST_BODY \\\"@contains very small test file\\\" \\\"id:2,log,phase:3\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/action-ctl_request_body_processor.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing CtlRequestBodyProcessor=XML (1)\",\n    \"resource\": \"libxml2\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Cookie\": \"PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120\",\n        \"Content-Type\": \"text/xml\",\n        \"Content-Length\": \"732\"\n      },\n      \"uri\": \"/?key=value&key=other_value\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"<?xml version=\\\"1.0\\\" encoding=\\\"UTF-8\\\"?>\",\n        \"<bookstore>\",\n        \"<book category=\\\"COOKING\\\">\",\n        \"<title lang=\\\"en\\\">Everyday Italian</title>\",\n        \"<author>Giada De Laurentiis</author>\",\n        \"<year>2005</year>\",\n        \"<price>30.00</price>\",\n        \"</book>\",\n        \"<book category=\\\"CHILDREN\\\">\",\n        \"<title lang=\\\"en\\\">Harry Potter</title>\",\n        \"<author>J K. Rowling</author>\",\n        \"<year>2005</year>\",\n        \"<price>29.99</price>\",\n        \"</book>\",\n        \"<book category=\\\"WEB\\\">\",\n        \"<title lang=\\\"en\\\">XQuery Kick Start</title>\",\n        \"<author>James McGovern</author>\",\n        \"<author>Per Bothner</author>\",\n        \"<author>Kurt Cagle</author>\",\n        \"<author>James Linn</author>\",\n        \"<author>Vaidyanathan Nagarajan</author>\",\n        \"<year>2003</year>\",\n        \"<price>49.99</price>\",\n        \"</book>\",\n        \"<book category=\\\"WEB\\\">\",\n        \"<title lang=\\\"en\\\">Learning XML</title>\",\n        \"<author>Erik T. Ray</author>\",\n        \"<year>2003</year>\",\n        \"<price>39.95</price>\",\n        \"</book>\",\n        \"</bookstore>\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Registered XML namespace href \\\"http://schemas.xmlsoap.org/soap/envelope/\\\" prefix \\\"soap\\\"\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRequestBodyAccess On\",\n      \"SecRule REQUEST_HEADERS:Content-Type \\\"^text/xml$\\\" \\\"id:500005,phase:1,t:none,t:lowercase,nolog,pass,ctl:requestBodyProcessor=XML\\\"\",\n      \"SecRule XML:/bookstore/book/price[text()] \\\"Fred\\\" \\\"phase:3,id:123,xmlns:soap='http://schemas.xmlsoap.org/soap/envelope/'\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing CtlRequestBodyProcessor=XML (2)\",\n    \"resource\": \"libxml2\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Cookie\": \"PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120\",\n        \"Content-Type\": \"text/xml\",\n        \"Content-Length\": \"732\"\n      },\n      \"uri\": \"/?key=value&key=other_value\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"<?xml version=\\\"1.0\\\" encoding=\\\"UTF-8\\\"?>\",\n        \"<bookstore>\",\n        \"<book category=\\\"COOKING\\\">\",\n        \"<title lang=\\\"en\\\">Everyday Italian</title>\",\n        \"<author>Giada De Laurentiis</author>\",\n        \"<year>2005</year>\",\n        \"<price>30.00</price>\",\n        \"</book>\",\n        \"<book category=\\\"CHILDREN\\\">\",\n        \"<title lang=\\\"en\\\">Harry Potter</title>\",\n        \"<author>J K. Rowling</author>\",\n        \"<year>2005</year>\",\n        \"<price>29.99</price>\",\n        \"</book>\",\n        \"<book category=\\\"WEB\\\">\",\n        \"<title lang=\\\"en\\\">XQuery Kick Start</title>\",\n        \"<author>James McGovern</author>\",\n        \"<author>Per Bothner</author>\",\n        \"<author>Kurt Cagle</author>\",\n        \"<author>James Linn</author>\",\n        \"<author>Vaidyanathan Nagarajan</author>\",\n        \"<year>2003</year>\",\n        \"<price>49.99</price>\",\n        \"</book>\",\n        \"<book category=\\\"WEB\\\">\",\n        \"<title lang=\\\"en\\\">Learning XML</title>\",\n        \"<author>Erik T. Ray</author>\",\n        \"<year>2003</year>\",\n        \"<price>39.95</price>\",\n        \"</book>\",\n        \"</bookstore>\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Rule returned 0\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRequestBodyAccess On\",\n      \"SecRule XML:/bookstore/book/price[text()] \\\"Fred\\\" \\\"phase:3,id:123,xmlns:soap='http://schemas.xmlsoap.org/soap/envelope/'\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing CtlRequestBodyProcessor=XML (3)\",\n    \"resource\": \"libxml2\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Cookie\": \"PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120\",\n        \"Content-Type\": \"text/xml\",\n        \"Content-Length\": \"9\"\n      },\n      \"uri\": \"/?key=value&key=other_value\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"not a xml\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"XML: Failed to parse document.\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRequestBodyAccess On\",\n      \"SecRule REQUEST_HEADERS:Content-Type \\\"^text/xml$\\\" \\\"id:500005,phase:1,t:none,t:lowercase,nolog,pass,ctl:requestBodyProcessor=XML\\\"\",\n      \"SecRule XML:/bookstore/book/price[text()] \\\"Fred\\\" \\\"phase:3,id:123,xmlns:soap='http://schemas.xmlsoap.org/soap/envelope/'\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/action-ctl_request_body_processor_urlencoded.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"ctl:requestBodyProcessor=URLENCODED\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"14\",\n        \"Content-Type\": \"application/lhebs\",\n        \"Expect\": \"100-continue\"\n      },\n      \"uri\": \"/a=urlencoded\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"param1=value1\\r\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\\\\\"value1\",\n      \"http_code\": 403\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRequestBodyAccess On\",\n      \"SecRule REQUEST_HEADERS:Content-Type \\\"@contains lhebs\\\" \\\"phase:1,id:122,t:none,log,auditlog,pass,ctl:requestBodyProcessor=URLENCODED\\\"\",\n      \"SecRule ARGS_POST \\\"@contains value1\\\" \\\"phase:2,id:123,t:none,deny,log,auditlog\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"ctl:requestBodyProcessor=URLENCODED\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"14\",\n        \"Content-Type\": \"application/x-www-form-urlencoded\",\n        \"Expect\": \"100-continue\"\n      },\n      \"uri\": \"/a=urlencoded\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"param1=value1\\r\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\\\\\"value1\",\n      \"http_code\": 403\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRequestBodyAccess On\",\n      \"SecRule ARGS_POST \\\"@contains value1\\\" \\\"phase:2,id:123,t:none,deny,log,auditlog\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/action-ctl_rule_engine.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing CtlRuleEngine (1)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\",\n        \"Content-Type\": \"plain/text\",\n        \"Expect\": \"100-continue\"\n      },\n      \"uri\": \"/test?test=test\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Setting SecRuleEngine to Disabled as requested by a ctl:ruleEngine action\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRequestBodyAccess On\",\n      \"SecRule REQUEST_URI \\\"@contains test\\\" \\\"id:1,phase:1,pass,t:trim,ctl:RuleEngine=Off\\\"\",\n      \"SecRule ARGS \\\"@contains test\\\" \\\"id:2,log,phase:3,block,deny,status:302\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing CtlRuleEngine (2)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\",\n        \"Content-Type\": \"plain/text\",\n        \"Expect\": \"100-continue\"\n      },\n      \"uri\": \"/test?test=test\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Setting SecRuleEngine to DetectionOnly as requested by a ctl:ruleEngine action\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRequestBodyAccess On\",\n      \"SecRule REQUEST_URI \\\"@contains test\\\" \\\"id:1,phase:1,pass,t:trim,ctl:RuleEngine=DetectionOnly\\\"\",\n      \"SecRule ARGS \\\"@contains test\\\" \\\"id:2,log,phase:3,block,deny,status:302\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing CtlRuleEngine (3)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\",\n        \"Content-Type\": \"plain/text\",\n        \"Expect\": \"100-continue\"\n      },\n      \"uri\": \"/test?test=test\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Setting SecRuleEngine to Enabled as requested by a ctl:ruleEngine action\",\n      \"http_code\": 302\n    },\n    \"rules\": [\n      \"SecRuleEngine DetectionOnly\",\n      \"SecRule REQUEST_URI \\\"@contains test\\\" \\\"id:1,phase:1,pass,t:trim,ctl:RuleEngine=On\\\"\",\n      \"SecRule ARGS \\\"@contains test\\\" \\\"id:2,log,phase:3,block,deny,status:302\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing CtlRuleEngine (4)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\",\n        \"Content-Type\": \"plain/text\",\n        \"Expect\": \"100-continue\"\n      },\n      \"uri\": \"/test?test=test\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Setting SecRuleEngine to Enabled as requested by a ctl:ruleEngine action\",\n      \"http_code\": 302\n    },\n    \"rules\": [\n      \"SecRuleEngine DetectionOnly\",\n      \"SecRule REQUEST_URI \\\"@contains test\\\" \\\"id:1,phase:1,pass,t:trim,ctl:RuleEngine=On,log,phase:3,block,deny,status:302\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing CtlRuleEngine (5)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\",\n        \"Content-Type\": \"plain/text\",\n        \"Expect\": \"100-continue\"\n      },\n      \"uri\": \"/test?test=test\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Setting SecRuleEngine to Disabled as requested by a ctl:ruleEngine action\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine DetectionOnly\",\n      \"SecRule REQUEST_URI \\\"@contains test\\\" \\\"id:1,phase:1,pass,t:trim,ctl:RuleEngine=Off,log,phase:3,block,deny,status:302\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing CtlRuleEngine (6)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\",\n        \"Content-Type\": \"plain/text\",\n        \"Expect\": \"100-continue\"\n      },\n      \"uri\": \"/test?test=test\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Setting SecRuleEngine to DetectionOnly as requested by a ctl:ruleEngine action\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine DetectionOnly\",\n      \"SecRule REQUEST_URI \\\"@contains test\\\" \\\"id:1,phase:1,pass,t:trim,ctl:RuleEngine=DetectionOnly,log,phase:3,block,deny,status:302\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing CtlRuleEngine (7)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\",\n        \"Content-Type\": \"plain/text\",\n        \"Expect\": \"100-continue\"\n      },\n      \"uri\": \"/test?test=test\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Setting SecRuleEngine to DetectionOnly as requested by a ctl:ruleEngine action\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine DetectionOnly\",\n      \"SecRule REQUEST_URI \\\"@contains test\\\" \\\"id:1,phase:1,pass,t:trim,log,phase:3,block,deny,status:302,ctl:RuleEngine=DetectionOnly\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/action-ctl_rule_remove_by_id.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing CtlRuleRemoteById (1)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Cookie\": \"PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120\",\n        \"Content-Type\": \"text/xml\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/wp-login.php?whee=something&pwd=lhebs\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Rule id: 1 was skipped due to a ruleRemoveById action...\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRule REQUEST_FILENAME \\\"@endsWith /wp-login.php\\\" \\\"id:9002100,phase:2,t:none,nolog,pass,ctl:ruleRemoveById=1\\\"\",\n      \"SecRule ARGS_NAMES \\\"@contains whee\\\" \\\"id:1,phase:3,t:none,nolog,pass,tag:'CRS'\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing CtlRuleRemoteById (2)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Cookie\": \"PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120\",\n        \"Content-Type\": \"text/xml\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/wp-login.php?whee=something&pwd=lhebs\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: .*Variable: ARGS_NAMES:whee\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRule REQUEST_FILENAME \\\"@endsWith /wp-login.php\\\" \\\"id:9002100,phase:2,t:none,nolog,pass,ctl:ruleRemoveById=123\\\"\",\n      \"SecRule ARGS_NAMES \\\"@contains whee\\\" \\\"id:1,phase:3,t:none,nolog,pass,tag:'CRS2'\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/action-ctl_rule_remove_by_tag.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing ctl:ruleRemoveByTag (1/2)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?key=value&key=other_value\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Skipped rule id '2'. Skipped due to a ruleRemoveByTag action.\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRule ARGS:key \\\".\\\" \\\"id:4,ctl:ruleRemoveByTag=tag123\\\"\",\n      \"SecRule ARGS \\\"@contains test1\\\" \\\"id:1,pass,t:trim\\\"\",\n      \"SecRule ARGS \\\"@contains test2\\\" \\\"id:2,pass,t:trim,tag:tag123\\\"\",\n      \"SecRule ARGS \\\"@contains test3\\\" \\\"id:3,pass,t:trim\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing ctl:ruleRemoveByTag (2/2)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?key=value&key=other_value\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Skipped rule id '3'. Skipped due to a ruleRemoveByTag action.\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRule ARGS:key \\\".\\\" \\\"id:4,ctl:ruleRemoveByTag=whee\\\"\",\n      \"SecRule ARGS \\\"@contains test\\\" \\\"id:1,pass,t:trim\\\"\",\n      \"SecRule ARGS \\\"@contains test\\\" \\\"id:2,pass,t:trim\\\"\",\n      \"SecRule ARGS \\\"@contains test\\\" \\\"id:3,pass,t:trim,tag:whee\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/action-ctl_rule_remove_target_by_id.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing CtlRuleRemoveTargetById (1)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Cookie\": \"PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120\",\n        \"Content-Type\": \"text/xml\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/wp-login.php?whee&pwd=lhebs\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule REQUEST_FILENAME \\\"@endsWith /wp-login.php\\\" \\\"id:9002100,phase:2,t:none,nolog,pass,ctl:ruleRemoveTargetById=1;ARGS:pwd\\\"\",\n      \"SecRule ARGS \\\"@contains lhebs\\\" \\\"id:1,phase:3,t:none,status:202,block,deny,tag:'CRS'\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing CtlRuleRemoveTargetById (2)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Cookie\": \"PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120\",\n        \"Content-Type\": \"text/xml\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/wp-login.php?whee=something&pwd=lhebs\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: .*Variable: ARGS_NAMES:whee\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRule REQUEST_FILENAME \\\"@endsWith /wp-login.php\\\" \\\"id:9002100,phase:2,t:none,nolog,pass,ctl:ruleRemoveTargetById=123;ARGS:pwd\\\"\",\n      \"SecRule ARGS_NAMES \\\"@contains whee\\\" \\\"id:1,phase:3,t:none,nolog,pass,tag:'CRS2'\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing CtlRuleRemoveTargetById (3)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Cookie\": \"PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120\",\n        \"Content-Type\": \"text/xml\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/wp-login.php?whee=something&pwd=lhebs\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRule REQUEST_FILENAME \\\"@endsWith /wp-login.php\\\" \\\"id:9002100,phase:2,t:none,nolog,pass,ctl:ruleRemoveTargetById=1;ARGS\\\"\",\n      \"SecRule ARGS \\\"@contains lhebs\\\" \\\"id:1,phase:3,t:none,status:202,block,deny,tag:'CRS'\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing CtlRuleRemoveTargetById (4): uppercase `Referer` header\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Cookie\": \"PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120\",\n        \"Content-Type\": \"text/xml\",\n        \"Referer\": \"This is an attack\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/index.html\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule REQUEST_FILENAME \\\"@unconditionalMatch\\\" \\\"id:1,phase:1,pass,t:none,ctl:ruleRemoveTargetById=2;REQUEST_HEADERS:referer\\\"\",\n      \"SecRule REQUEST_HEADERS:Referer \\\"@contains attack\\\" \\\"id:2,phase:1,deny,t:none,log\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing CtlRuleRemoveTargetById (5): lowercase `Referer` header\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Cookie\": \"PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120\",\n        \"Content-Type\": \"text/xml\",\n        \"referer\": \"This is an attack\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/index.html\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule REQUEST_FILENAME \\\"@unconditionalMatch\\\" \\\"id:1,phase:1,pass,t:none,ctl:ruleRemoveTargetById=2;REQUEST_HEADERS:referer\\\"\",\n      \"SecRule REQUEST_HEADERS:Referer \\\"@contains attack\\\" \\\"id:2,phase:1,deny,t:none,log\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/action-ctl_rule_remove_target_by_tag.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing CtlRuleRemoteTargetByTag (1)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Cookie\": \"PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120\",\n        \"Content-Type\": \"text/xml\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/wp-login.php?whee&pwd=lhebs\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule REQUEST_FILENAME \\\"@endsWith /wp-login.php\\\" \\\"id:9002100,phase:2,t:none,nolog,pass,ctl:ruleRemoveTargetByTag=CRS;ARGS:pwd\\\"\",\n      \"SecRule ARGS \\\"@contains lhebs\\\" \\\"id:1,phase:3,t:none,nolog,pass,tag:'CRS',deny\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing CtlRuleRemoteTargetByTag (2)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Cookie\": \"PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120\",\n        \"Content-Type\": \"text/xml\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/wp-login.php?whee&pwd=lhebs\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: .*Variable: ARGS_NAMES:pwd\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRule REQUEST_FILENAME \\\"@endsWith /wp-login.php\\\" \\\"id:9002100,phase:2,t:none,nolog,pass,ctl:ruleRemoveTargetByTag=CRS;ARGS:pwd\\\"\",\n      \"SecRule ARGS_NAMES \\\"@contains pwd\\\" \\\"id:1,phase:3,t:none,nolog,pass,tag:'CRS2'\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing CtlRuleRemoteTargetByTag (3)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Cookie\": \"PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120\",\n        \"Content-Type\": \"text/xml\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/wp-login.php?whee=something&pwd=lhebs\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: .*Variable: ARGS_NAMES:whee\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRule REQUEST_FILENAME \\\"@endsWith /wp-login.php\\\" \\\"id:9002100,phase:2,t:none,nolog,pass,ctl:ruleRemoveTargetByTag=CRS;ARGS\\\"\",\n      \"SecRule ARGS_NAMES \\\"@contains whee\\\" \\\"id:1,phase:3,t:none,nolog,pass,tag:'CRS2'\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/action-disruptive.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Disruptive actions (1/n)\",\n    \"client\": {\n      \"ip\": \"\",\n      \"port\": 0\n    },\n    \"server\": {\n      \"ip\": \"\",\n      \"port\": 0\n    },\n    \"request\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"\",\n      \"method\": \"\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Running action deny\",\n      \"http_code\": 403\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecDefaultAction \\\"phase:2,deny,status:404\\\"\",\n      \"SecAction \\\"id:'900001',phase:request,nolog,status:403,t:none,block\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Disruptive actions (2/n)\",\n    \"client\": {\n      \"ip\": \"\",\n      \"port\": 0\n    },\n    \"server\": {\n      \"ip\": \"\",\n      \"port\": 0\n    },\n    \"request\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"\",\n      \"method\": \"\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Running action deny\",\n      \"http_code\": 404\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecDefaultAction \\\"phase:2,deny,status:404\\\"\",\n      \"SecAction \\\"id:'1',phase:request,nolog,t:none,block\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Disruptive actions (3/n)\",\n    \"client\": {\n      \"ip\": \"\",\n      \"port\": 0\n    },\n    \"server\": {\n      \"ip\": \"\",\n      \"port\": 0\n    },\n    \"request\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"\",\n      \"method\": \"\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"http_code\": 404\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecDefaultAction \\\"phase:2,deny,status:404\\\"\",\n      \"SecAction \\\"id:'1',phase:request,nolog,block,t:none\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Disruptive actions (4/n)\",\n    \"client\": {\n      \"ip\": \"\",\n      \"port\": 0\n    },\n    \"server\": {\n      \"ip\": \"\",\n      \"port\": 0\n    },\n    \"request\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"\",\n      \"method\": \"\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecAction \\\"id:'1',phase:request,nolog,t:none\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Disruptive actions (5/n)\",\n    \"client\": {\n      \"ip\": \"\",\n      \"port\": 0\n    },\n    \"server\": {\n      \"ip\": \"\",\n      \"port\": 0\n    },\n    \"request\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"\",\n      \"method\": \"\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecDefaultAction \\\"phase:2,deny,status:404\\\"\",\n      \"SecAction \\\"id:'1',phase:request,nolog,pass,t:none\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Disruptive actions (6/n)\",\n    \"client\": {\n      \"ip\": \"\",\n      \"port\": 0\n    },\n    \"server\": {\n      \"ip\": \"\",\n      \"port\": 0\n    },\n    \"request\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"\",\n      \"method\": \"\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"http_code\": 403\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecAction \\\"id:'1',phase:request,drop,nolog,t:none\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/action-exec.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"version_max\": 0,\n    \"title\": \"Testing action :: exec (1/3)\",\n    \"resource\": \"lua\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 2313\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"User-Agent\": \"Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)\",\n        \"Accept\": \"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\",\n        \"Accept-Language\": \"en-us,en;q=0.5\",\n        \"Accept-Encoding\": \"gzip,deflate\",\n        \"Accept-Charset\": \"ISO-8859-1,utf-8;q=0.7,*;q=0.7\",\n        \"Keep-Alive\": \"300\",\n        \"Connection\": \"keep-alive\",\n        \"Cookie\": \"PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120\",\n        \"Pragma\": \"no-cache\",\n        \"Cache-Control\": \"no-cache\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/test.pl?param1=   test   &param2=test2\",\n      \"method\": \"GET\",\n      \"http_version\": 1.1,\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Type\": \"text/xml; charset=utf-8\\n\\r\",\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Saving msg: This is a test, text/html,application\",\n      \"http_code\": 200,\n      \"parser_error\": \"exec: Expecting a Lua script: /bin/ech\"\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule REQUEST_HEADERS \\\"@contains PHPSESSID\\\" \\\"id:1,t:lowercase,t:none,exec:/bin/echo\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"version_max\": 0,\n    \"title\": \"Testing action :: exec (2/2)\",\n    \"resource\": \"lua\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 2313\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"User-Agent\": \"Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)\",\n        \"Accept\": \"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\",\n        \"Accept-Language\": \"en-us,en;q=0.5\",\n        \"Accept-Encoding\": \"gzip,deflate\",\n        \"Accept-Charset\": \"ISO-8859-1,utf-8;q=0.7,*;q=0.7\",\n        \"Keep-Alive\": \"300\",\n        \"Connection\": \"keep-alive\",\n        \"Cookie\": \"PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120\",\n        \"Pragma\": \"no-cache\",\n        \"Cache-Control\": \"no-cache\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/test.pl?param1=   test   &param2=test2\",\n      \"method\": \"GET\",\n      \"http_version\": 1.1,\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Type\": \"text/xml; charset=utf-8\\n\\r\",\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Running script... test-cases/data/test.lua\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule REQUEST_HEADERS:Cookie \\\"@contains PHPSESSID\\\" \\\"id:1,exec:test-cases/data/test.lua\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"version_max\": 0,\n    \"title\": \"Testing action :: exec (3/3)\",\n    \"resource\": \"lua\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 2313\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"User-Agent\": \"Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)\",\n        \"Accept\": \"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\",\n        \"Accept-Language\": \"en-us,en;q=0.5\",\n        \"Accept-Encoding\": \"gzip,deflate\",\n        \"Accept-Charset\": \"ISO-8859-1,utf-8;q=0.7,*;q=0.7\",\n        \"Keep-Alive\": \"300\",\n        \"Connection\": \"keep-alive\",\n        \"Cookie\": \"PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120\",\n        \"Pragma\": \"no-cache\",\n        \"Cache-Control\": \"no-cache\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/test.pl?param1=   test   &param2=test2\",\n      \"method\": \"GET\",\n      \"http_version\": 1.1,\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Type\": \"text/xml; charset=utf-8\\n\\r\",\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Running script... test-cases/data/match.lua\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule REQUEST_HEADERS:Cookie \\\"@contains PHPSESSID\\\" \\\"id:1,exec:test-cases/data/match.lua\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/action-expirevar.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing expirevar action (1/x) - ip, expire later\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?key=value\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Saving msg: mycount1 is 100\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecAction \\\"initcol:ip='127.0.0.1',id:5000,phase:1\\\"\",\n      \"SecRule ARGS \\\"@rx value\\\" \\\"id:'5001',phase:2,setvar:ip.mycount1=100,expirevar:ip.mycount1=60,pass\\\"\",\n      \"SecRule &IP:mycount1 \\\"@eq 1\\\" \\\"id:'5002',phase:2,pass,log,msg:'mycount1 is %{ip.mycount1}'\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing expirevar action (2/x) - ip, expire immediately\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?key=value\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Saving msg: mycount1 is \",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecAction \\\"initcol:ip='127.0.0.1',id:5010,phase:1\\\"\",\n      \"SecRule ARGS \\\"@rx value\\\" \\\"id:'5011',phase:2,setvar:ip.mycount1=100,expirevar:ip.mycount1=0,pass\\\"\",\n      \"SecRule &IP:mycount1 \\\"@eq 0\\\" \\\"id:'5012',phase:2,pass,log,msg:'mycount1 is %{ip.mycount1}'\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing expirevar action (3/x) session, expire later\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?key=value\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Saving msg: mycount1 is 12\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule ARGS \\\"@rx .\\\" \\\"id:5150,phase:2,pass,setsid:sess1234\\\"\",\n      \"SecRule ARGS \\\"@rx value\\\" \\\"id:5151,phase:2,pass,setvar:session.mycount1=12,expirevar:session.mycount1=30\\\"\",\n      \"SecRule &SESSION:mycount1 \\\"@eq 1\\\" \\\"id:'5152',phase:2,pass,log,msg:'mycount1 is %{session.mycount1}'\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing expirevar action (4/x) session, expire immediately\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?key=value\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Saving msg: mycount1 is\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule ARGS \\\"@rx .\\\" \\\"id:5150,phase:2,pass,setsid:sess1234\\\"\",\n      \"SecRule ARGS \\\"@rx value\\\" \\\"id:5151,phase:2,pass,setvar:session.mycount1=12,expirevar:session.mycount1=0\\\"\",\n      \"SecRule &SESSION:mycount1 \\\"@eq 0\\\" \\\"id:'5152',phase:2,pass,log,msg:'mycount1 is %{session.mycount1}'\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/action-id.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Action :: id (1/6)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"27\",\n        \"Content-Type\": \"application/x-www-form-urlencoded\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"param1=value1&param2=value2\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"http_code\": 200,\n      \"parser_error\": \"The input \\\"111111111111222222222222222222222222222333333333333333333333333333444444444444444444444444444444555555555555555555555555666666666666666666666666666666666666666666\\\" does not seems to be a valid rule id.\"\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule ARGS \\\"@rx (value1)\\\" \\\"id:111111111111222222222222222222222222222333333333333333333333333333444444444444444444444444444444555555555555555555555555666666666666666666666666666666666666666666,phase:2,pass,t:trim\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Action :: id (2/6)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"27\",\n        \"Content-Type\": \"application/x-www-form-urlencoded\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"param1=value1&param2=value2\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"http_code\": 200,\n      \"parser_error\": \"File: action-id.json. Line: 2. Column: 56. Expecting an action, got:  id:-1,phase:2,pass,t:trim\\\"\"\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule ARGS \\\"@rx (value1)\\\" \\\"id:-1,phase:2,pass,t:trim\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Action :: id (3/6)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"27\",\n        \"Content-Type\": \"application/x-www-form-urlencoded\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"param1=value1&param2=value2\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \" t:trim: \\\"value2\\\"\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule ARGS \\\"@rx (value1)\\\" \\\"id:1,phase:3,pass,t:trim\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Action :: id (4/6)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"27\",\n        \"Content-Type\": \"application/x-www-form-urlencoded\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"param1=value1&param2=value2\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \" t:trim: \\\"value2\\\"\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule ARGS \\\"@rx (value1)\\\" \\\"id:'1',phase:3,pass,t:trim\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Action :: id (5/6)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"27\",\n        \"Content-Type\": \"application/x-www-form-urlencoded\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"param1=value1&param2=value2\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"http_code\": 200,\n      \"parser_error\": \"action-id.json. Line: 2. Column: 56. Expecting an action, got:  id:'1,phase:2,pass,t:trim\\\"\"\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule ARGS \\\"@rx (value1)\\\" \\\"id:'1,phase:2,pass,t:trim\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Action :: id (6/6)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"27\",\n        \"Content-Type\": \"application/x-www-form-urlencoded\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"param1=value1&param2=value2\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"http_code\": 200,\n      \"parser_error\": \"action-id.json. Line: 2. Column: 56. Expecting an action, got:  ',phase:2,pass,t:trim\\\"\"\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule ARGS \\\"@rx (value1)\\\" \\\"id:1',phase:2,pass,t:trim\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/action-initcol.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing initcol action\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"User-Agent\": \"My sweet little browser\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?key=value&key=other_value\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Saving variable: IP:auth_attempt with value: \",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule REQUEST_HEADERS:User-Agent \\\"^(.*)$\\\" \\\"id:'900018',phase:1,t:none,t:sha1,t:hexEncode,setvar:tx.ua_hash=%{matched_var},nolog,pass\\\"\",\n      \"SecRule &TX:REAL_IP \\\"@eq 0\\\" \\\"id:'900021',phase:1,t:none,initcol:global=global,initcol:ip=%{remote_addr}_%{tx.ua_hash},setvar:tx.real_ip=%{remote_addr},nolog,pass\\\"\",\n      \"SecRule REQUEST_HEADERS:User-Agent \\\"^(.*)$\\\" \\\"id:'900019',phase:2,t:none,setvar:ip.auth_attempt=+1,nolog,pass\\\"\",\n      \"SecRule REQUEST_HEADERS:User-Agent \\\"^(.*)$\\\" \\\"id:'900020',phase:2,t:none,setvar:ip.auth_attempt=+1,nolog,pass\\\"\",\n      \"SecRule REQUEST_HEADERS:User-Agent \\\"^(.*)$\\\" \\\"id:'900022',phase:2,t:none,setvar:ip.auth_attempt=+1,nolog,pass\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/action-msg.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"version_max\": 0,\n    \"title\": \"Testing action :: msg (this test is not really testing it)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 2313\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"User-Agent\": \"Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)\",\n        \"Accept\": \"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\",\n        \"Accept-Language\": \"en-us,en;q=0.5\",\n        \"Accept-Encoding\": \"gzip,deflate\",\n        \"Accept-Charset\": \"ISO-8859-1,utf-8;q=0.7,*;q=0.7\",\n        \"Keep-Alive\": \"300\",\n        \"Connection\": \"keep-alive\",\n        \"Cookie\": \"PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120\",\n        \"Pragma\": \"no-cache\",\n        \"Cache-Control\": \"no-cache\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/test.pl?param1=   test   &param2=test2\",\n      \"method\": \"GET\",\n      \"http_version\": 1.1,\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Type\": \"text/xml; charset=utf-8\\n\\r\",\n        \"Content-Length\": \"384\"\n      },\n      \"body\": [\n        \"<?xml version=\\\"1.0\\\" encoding=\\\"utf-8\\\"?>\\n\\r\",\n        \"<soap:Envelope xmlns:xsi=\\\"http://www.w3.org/2001/XMLSchema-instance\\\" xmlns:xsd=\\\"http://www.w3.org/2001/XMLSchema\\\" xmlns:soap=\\\"http://schemas.xmlsoap.org/soap/envelope/\\\">\\n\\r\",\n        \"  <soap:Body>\\n\\r\",\n        \"  <EnlightenResponse xmlns=\\\"http://clearforest.com/\\\">\\n\\r\",\n        \"  <EnlightenResult>string</EnlightenResult>\\n\\r\",\n        \"  </EnlightenResponse>\\n\\r\",\n        \"  </soap:Body>\\n\\r\",\n        \"</soap:Envelope>\\n\\r\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Saving msg: This is a test, text/html,application\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule REQUEST_HEADERS \\\"@contains PHPSESSID\\\" \\\"id:1,t:lowercase,t:none,msg:'This is a test, %{REQUEST_HEADERS:Accept}%'\\\"\",\n      \"SecRule TX \\\"@contains to_test\\\" \\\"id:2,t:lowercase,t:none\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"version_max\": 0,\n    \"title\": \"Testing action :: msg - variable expansion\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 2313\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"User-Agent\": \"Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)\",\n        \"Accept\": \"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\",\n        \"Accept-Language\": \"en-us,en;q=0.5\",\n        \"Accept-Encoding\": \"gzip,deflate\",\n        \"Accept-Charset\": \"ISO-8859-1,utf-8;q=0.7,*;q=0.7\",\n        \"Keep-Alive\": \"300\",\n        \"Connection\": \"keep-alive\",\n        \"Cookie\": \"PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120\",\n        \"Pragma\": \"no-cache\",\n        \"Cache-Control\": \"no-cache\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/test.pl?param1=   test   &param2=test2\",\n      \"method\": \"GET\",\n      \"http_version\": 1.1,\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Type\": \"text/xml; charset=utf-8\\n\\r\",\n        \"Content-Length\": \"384\"\n      },\n      \"body\": [\n        \"<?xml version=\\\"1.0\\\" encoding=\\\"utf-8\\\"?>\\n\\r\",\n        \"<soap:Envelope xmlns:xsi=\\\"http://www.w3.org/2001/XMLSchema-instance\\\" xmlns:xsd=\\\"http://www.w3.org/2001/XMLSchema\\\" xmlns:soap=\\\"http://schemas.xmlsoap.org/soap/envelope/\\\">\\n\\r\",\n        \"  <soap:Body>\\n\\r\",\n        \"  <EnlightenResponse xmlns=\\\"http://clearforest.com/\\\">\\n\\r\",\n        \"  <EnlightenResult>string</EnlightenResult>\\n\\r\",\n        \"  </EnlightenResponse>\\n\\r\",\n        \"  </soap:Body>\\n\\r\",\n        \"</soap:Envelope>\\n\\r\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Saving msg: This is a test: PHPSESSID ops\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule REQUEST_HEADERS \\\"@rx PHPSESSID\\\" \\\"id:1,capture,t:lowercase,t:none,msg:'This is a test: %{TX.0}% ops'\\\"\",\n      \"SecRule TX \\\"@rx to_test\\\" \\\"id:2,t:lowercase,capture,t:none\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/action-setenv.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing setsid action (1/3)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"User-Agent\": \"My sweet little browser\",\n        \"Cookie\": \"PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?key=value&key=other_value\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Setting environment variable: variable to PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule REQUEST_HEADERS:Cookie \\\"^(.*)$\\\" \\\"id:'900018',phase:2,setenv:'variable=%{matched_var}',pass\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing setenv action (2/3)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"User-Agent\": \"My sweet little browser\",\n        \"Cookie\": \"PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?key=value&key=other_value\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Setting environment variable: variable to PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule REQUEST_HEADERS:Cookie \\\"^(.*)$\\\" \\\"id:'900018',phase:2,setenv:variable=%{matched_var},pass\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing setenv action (3/3)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"User-Agent\": \"My sweet little browser\",\n        \"Cookie\": \"PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?key=value&key=other_value\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Setting environment variable: variable to PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120==test=test\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule REQUEST_HEADERS:Cookie \\\"^(.*)$\\\" \\\"id:'900018',phase:2,setenv:variable=%{matched_var}==test=test,pass\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/action-setrsc.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing setrsc action\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"User-Agent\": \"My sweet little browser\",\n        \"Cookie\": \"PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?key=value&key=other_value\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Saving variable: RESOURCE:score with value: \",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule REQUEST_HEADERS:User-Agent \\\"^(.*)$\\\" \\\"id:'900018',phase:1,t:none,t:sha1,t:hexEncode,setrsc:'test',nolog,pass\\\"\",\n      \"SecRule REQUEST_HEADERS \\\".*\\\" \\\"id:'900021',phase:1,setvar:RESOURCE.score=+10\\\"\",\n      \"SecRule REQUEST_HEADERS:User-Agent \\\"^(.*)$\\\" \\\"id:'900068',phase:1,t:none,t:sha1,t:hexEncode,setrsc:%{REQUEST_COOKIES:PHPSESSID}2,nolog,pass\\\"\",\n      \"SecRule REQUEST_HEADERS \\\".*\\\" \\\"id:'900022',phase:1,setvar:RESOURCE.score=+5\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/action-setsid.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing setsid action\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"User-Agent\": \"My sweet little browser\",\n        \"Cookie\": \"PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?key=value&key=other_value\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Saving variable: SESSION:score with value: \",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule REQUEST_HEADERS:User-Agent \\\"^(.*)$\\\" \\\"id:'900018',phase:1,t:none,t:sha1,t:hexEncode,setsid:%{REQUEST_COOKIES:PHPSESSID}%,nolog,pass\\\"\",\n      \"SecRule REQUEST_HEADERS \\\".*\\\" \\\"id:'900021',phase:1,setvar:SESSION.score=+10\\\"\",\n      \"SecRule REQUEST_HEADERS:User-Agent \\\"^(.*)$\\\" \\\"id:'900068',phase:1,t:none,t:sha1,t:hexEncode,setsid:%{REQUEST_COOKIES:PHPSESSID}2,nolog,pass\\\"\",\n      \"SecRule REQUEST_HEADERS \\\".*\\\" \\\"id:'900022',phase:1,setvar:SESSION.score=+5\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/action-setuid.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing setuid action\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"User-Agent\": \"My sweet little browser\",\n        \"Cookie\": \"PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?key=value&key=other_value\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Saving variable: USER:score with value: \",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule REQUEST_HEADERS:User-Agent \\\"^(.*)$\\\" \\\"id:'900018',phase:1,t:none,t:sha1,t:hexEncode,setuid:%{REQUEST_COOKIES:USER}%,nolog,pass\\\"\",\n      \"SecRule REQUEST_HEADERS \\\".*\\\" \\\"id:'900021',phase:1,setvar:USER.score=+10\\\"\",\n      \"SecRule REQUEST_HEADERS:User-Agent \\\"^(.*)$\\\" \\\"id:'900068',phase:1,t:none,t:sha1,t:hexEncode,setsid:%{REQUEST_COOKIES:PHPSESSID}2,nolog,pass\\\"\",\n      \"SecRule REQUEST_HEADERS \\\".*\\\" \\\"id:'900022',phase:1,setvar:USER.score=+5\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/action-skip.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing skip action 1/3\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"User-Agent\": \"My sweet little browser\",\n        \"Cookie\": \"PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?key=value&key=other_value\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"\\\\[9\\\\] Skipped rule id \\\\'2\\\\' due to a \\\\`skip\\\\' action.\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule REQUEST_HEADERS:User-Agent \\\"^(.*)$\\\" \\\"id:'1',phase:1,skip:1\\\"\",\n      \"SecRule REQUEST_HEADERS \\\"should be skipped\\\" \\\"id:'2',phase:1,setvar:SESSION.score=+10\\\"\",\n      \"SecRule REQUEST_HEADERS:User-Agent \\\"^(.*)$\\\" \\\"id:'3',phase:1,t:none,nolog,pass\\\"\",\n      \"SecRule REQUEST_HEADERS \\\".*\\\" \\\"id:'4',phase:1,setvar:SESSION.score=+5\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing skip action 2/3\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"User-Agent\": \"My sweet little browser\",\n        \"Cookie\": \"PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?key=value&key=other_value\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"http_code\": 200,\n      \"parser_error\": \"Rules error. File: action-skip.json. Line: 2. Column: 71. Expecting an action, got:  skip:abc\"\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule REQUEST_HEADERS:User-Agent \\\"^(.*)$\\\" \\\"id:'1',phase:1,skip:abc\\\"\",\n      \"SecRule REQUEST_HEADERS \\\"should be skipped\\\" \\\"id:'2',phase:1,setvar:SESSION.score=+10\\\"\",\n      \"SecRule REQUEST_HEADERS:User-Agent \\\"^(.*)$\\\" \\\"id:'3',phase:1,t:none,nolog,pass\\\"\",\n      \"SecRule REQUEST_HEADERS \\\".*\\\" \\\"id:'4',phase:1,setvar:SESSION.score=+5\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing skip action 3/3\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"User-Agent\": \"My sweet little browser\",\n        \"Cookie\": \"PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?key=value&key=other_value\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"\\\\[9\\\\] Skipped rule id \\\\'3\\\\' due to a \\\\`skip\\\\' action.\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule REQUEST_HEADERS:User-Agent \\\"^(.*)$\\\" \\\"id:'1',phase:1,skip:2\\\"\",\n      \"SecRule REQUEST_HEADERS \\\"should be skipped\\\" \\\"id:'2',phase:1,setvar:SESSION.score=+10\\\"\",\n      \"SecRule REQUEST_HEADERS:User-Agent \\\"^(.*)$\\\" \\\"id:'3',phase:1,t:none,nolog,pass\\\"\",\n      \"SecRule REQUEST_HEADERS \\\".*\\\" \\\"id:'4',phase:1,setvar:SESSION.score=+5\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/action-tag.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"version_max\": 0,\n    \"title\": \"Testing action :: tag 1\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 2313\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"User-Agent\": \"Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)\",\n        \"Accept\": \"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\",\n        \"Accept-Language\": \"en-us,en;q=0.5\",\n        \"Accept-Encoding\": \"gzip,deflate\",\n        \"Accept-Charset\": \"ISO-8859-1,utf-8;q=0.7,*;q=0.7\",\n        \"Keep-Alive\": \"300\",\n        \"Connection\": \"keep-alive\",\n        \"Cookie\": \"PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120\",\n        \"Pragma\": \"no-cache\",\n        \"Cache-Control\": \"no-cache\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/test.pl?param1=   test   &param2=test2\",\n      \"method\": \"GET\",\n      \"http_version\": 1.1,\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Type\": \"text/xml; charset=utf-8\\n\\r\",\n        \"Content-Length\": \"384\"\n      },\n      \"body\": [\n        \"<?xml version=\\\"1.0\\\" encoding=\\\"utf-8\\\"?>\\n\\r\",\n        \"<soap:Envelope xmlns:xsi=\\\"http://www.w3.org/2001/XMLSchema-instance\\\" xmlns:xsd=\\\"http://www.w3.org/2001/XMLSchema\\\" xmlns:soap=\\\"http://schemas.xmlsoap.org/soap/envelope/\\\">\\n\\r\",\n        \"  <soap:Body>\\n\\r\",\n        \"  <EnlightenResponse xmlns=\\\"http://clearforest.com/\\\">\\n\\r\",\n        \"  <EnlightenResult>string</EnlightenResult>\\n\\r\",\n        \"  </EnlightenResponse>\\n\\r\",\n        \"  </soap:Body>\\n\\r\",\n        \"</soap:Envelope>\\n\\r\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Rule tag: teste\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule REQUEST_HEADERS \\\"@contains PHPSESSID\\\" \\\"id:1,tag:'teste',t:lowercase,t:none\\\"\",\n      \"SecRule TX \\\"@contains to_test\\\" \\\"id:2,t:lowercase,t:none\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"version_max\": 0,\n    \"title\": \"Testing action :: tag 2\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 2313\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"User-Agent\": \"Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)\",\n        \"Accept\": \"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\",\n        \"Accept-Language\": \"en-us,en;q=0.5\",\n        \"Accept-Encoding\": \"gzip,deflate\",\n        \"Accept-Charset\": \"ISO-8859-1,utf-8;q=0.7,*;q=0.7\",\n        \"Keep-Alive\": \"300\",\n        \"Connection\": \"keep-alive\",\n        \"Cookie\": \"PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120\",\n        \"Pragma\": \"no-cache\",\n        \"Cache-Control\": \"no-cache\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/test.pl?param1=   test   &param2=test2\",\n      \"method\": \"GET\",\n      \"http_version\": 1.1,\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Type\": \"text/xml; charset=utf-8\\n\\r\",\n        \"Content-Length\": \"384\"\n      },\n      \"body\": [\n        \"<?xml version=\\\"1.0\\\" encoding=\\\"utf-8\\\"?>\\n\\r\",\n        \"<soap:Envelope xmlns:xsi=\\\"http://www.w3.org/2001/XMLSchema-instance\\\" xmlns:xsd=\\\"http://www.w3.org/2001/XMLSchema\\\" xmlns:soap=\\\"http://schemas.xmlsoap.org/soap/envelope/\\\">\\n\\r\",\n        \"  <soap:Body>\\n\\r\",\n        \"  <EnlightenResponse xmlns=\\\"http://clearforest.com/\\\">\\n\\r\",\n        \"  <EnlightenResult>string</EnlightenResult>\\n\\r\",\n        \"  </EnlightenResponse>\\n\\r\",\n        \"  </soap:Body>\\n\\r\",\n        \"</soap:Envelope>\\n\\r\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Rule tag: teste no-cache\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule REQUEST_HEADERS \\\"@contains PHPSESSID\\\" \\\"id:1,tag:'teste %{REQUEST_HEADERS:Pragma}%',t:lowercase,t:none\\\"\",\n      \"SecRule TX \\\"@contains to_test\\\" \\\"id:2,t:lowercase,t:none\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/action-tnf-base64.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Transformatio :: base64 (1/2)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"27\",\n        \"Content-Type\": \"application/x-www-form-urlencoded\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"param1=value1&param2=value2\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"t:base64encode: \\\"dmFsdWUy\\\"\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule ARGS \\\"@rx .\\\" \\\"id:1,phase:2,t:base64encode,pass,t:trim\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Transformatio :: base64 (2/2)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"29\",\n        \"Content-Type\": \"application/x-www-form-urlencoded\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"param1=dmFsdWUy&param2=value2\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"t:base64decode: \\\"value2\\\"\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule ARGS \\\"@rx .\\\" \\\"id:1,phase:2,t:base64decode,pass,t:trim\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/action-xmlns.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing action :: XMLNS (parser error 1)\",\n    \"client\": {\n      \"ip\": \"\",\n      \"port\": 0\n    },\n    \"server\": {\n      \"ip\": \"\",\n      \"port\": 0\n    },\n    \"request\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"\",\n      \"method\": \"\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"http_code\": 200,\n      \"parser_error\": \"XMLS: Bad format, missing equals sign\"\n    },\n    \"rules\": [\n      \"SecRule REQUEST_HEADERS:Content-Type \\\"^text/xml$\\\" \\\"id:500008,phase:1,t:none,t:lowercase,nolog,pass,ctl:requestBodyProcessor=XML\\\"\",\n      \"SecRule REQUEST_HEADERS:User-Agent \\\"^(.*)$\\\" \\\"id:123,xmlns:soap'http://schemas.xmlsoap.org/soap/envelope/'\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing action :: XMLNS (parser error 2)\",\n    \"client\": {\n      \"ip\": \"\",\n      \"port\": 0\n    },\n    \"server\": {\n      \"ip\": \"\",\n      \"port\": 0\n    },\n    \"request\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"\",\n      \"method\": \"\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"http_code\": 200,\n      \"parser_error\": \"XMLS: XMLNS is invalid. Expecting a name=value format.\"\n    },\n    \"rules\": [\n      \"SecRule REQUEST_HEADERS:Content-Type \\\"^text/xml$\\\" \\\"id:500008,phase:1,t:none,t:lowercase,nolog,pass,ctl:requestBodyProcessor=XML\\\"\",\n      \"SecRule REQUEST_HEADERS:User-Agent \\\"^(.*)$\\\" \\\"id:123,xmlns:=\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing action :: XMLNS (parser error 3)\",\n    \"client\": {\n      \"ip\": \"\",\n      \"port\": 0\n    },\n    \"server\": {\n      \"ip\": \"\",\n      \"port\": 0\n    },\n    \"request\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"\",\n      \"method\": \"\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"http_code\": 200,\n      \"parser_error\": \"XMLS: Missing xmlns href for prefix: `schemas.xmlsoap.org/soap/envelope/'.\"\n    },\n    \"rules\": [\n      \"SecRule REQUEST_HEADERS:Content-Type \\\"^text/xml$\\\" \\\"id:500008,phase:1,t:none,t:lowercase,nolog,pass,ctl:requestBodyProcessor=XML\\\"\",\n      \"SecRule REQUEST_HEADERS:User-Agent \\\"^(.*)$\\\" \\\"id:123,xmlns:soap='schemas.xmlsoap.org/soap/envelope/'\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing XML request body parser (validate ok)\",\n    \"resource\": \"libxml2\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Cookie\": \"PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120\",\n        \"Content-Type\": \"text/xml\",\n        \"Content-Length\": \"732\"\n      },\n      \"uri\": \"/?key=value&key=other_value\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"<?xml version=\\\"1.0\\\" encoding=\\\"UTF-8\\\"?>\",\n        \"<bookstore>\",\n        \"<book category=\\\"COOKING\\\">\",\n        \"<title lang=\\\"en\\\">Everyday Italian</title>\",\n        \"<author>Giada De Laurentiis</author>\",\n        \"<year>2005</year>\",\n        \"<price>30.00</price>\",\n        \"</book>\",\n        \"<book category=\\\"CHILDREN\\\">\",\n        \"<title lang=\\\"en\\\">Harry Potter</title>\",\n        \"<author>J K. Rowling</author>\",\n        \"<year>2005</year>\",\n        \"<price>29.99</price>\",\n        \"</book>\",\n        \"<book category=\\\"WEB\\\">\",\n        \"<title lang=\\\"en\\\">XQuery Kick Start</title>\",\n        \"<author>James McGovern</author>\",\n        \"<author>Per Bothner</author>\",\n        \"<author>Kurt Cagle</author>\",\n        \"<author>James Linn</author>\",\n        \"<author>Vaidyanathan Nagarajan</author>\",\n        \"<year>2003</year>\",\n        \"<price>49.99</price>\",\n        \"</book>\",\n        \"<book category=\\\"WEB\\\">\",\n        \"<title lang=\\\"en\\\">Learning XML</title>\",\n        \"<author>Erik T. Ray</author>\",\n        \"<year>2003</year>\",\n        \"<price>39.95</price>\",\n        \"</book>\",\n        \"</bookstore>\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"39.95\\\" \\\\(Variable: XML:/bookstore/book/price\\\\[text\\\\(\\\\)\\\\]\\\\)\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRequestBodyAccess On\",\n      \"SecRule REQUEST_HEADERS:Content-Type \\\"^text/xml$\\\" \\\"id:500005,phase:1,t:none,t:lowercase,nolog,pass,ctl:requestBodyProcessor=XML\\\"\",\n      \"SecRule XML:/bookstore/book/price[text()] \\\"Fred\\\" \\\"phase:3,id:123,xmlns:soap='http://schemas.xmlsoap.org/soap/envelope/'\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/actions.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"version_max\": 0,\n    \"title\": \"actions :: trim,deny\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 2313\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"net.tutsplus.com\",\n        \"User-Agent\": \"Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)\",\n        \"Accept\": \"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\",\n        \"Accept-Language\": \"en-us,en;q=0.5\",\n        \"Accept-Encoding\": \"gzip,deflate\",\n        \"Accept-Charset\": \"ISO-8859-1,utf-8;q=0.7,*;q=0.7\",\n        \"Keep-Alive\": \"300\",\n        \"Connection\": \"keep-alive\",\n        \"Cookie\": \"PHPSESSID=r2t5uvjq435r4q7ib3vtdjq120\",\n        \"Pragma\": \"no-cache\",\n        \"Cache-Control\": \"no-cache\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/test.pl?param1=   test   &param2=test2\",\n      \"method\": \"GET\",\n      \"http_version\": 1.1,\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Type\": \"text/xml; charset=utf-8\\n\\r\",\n        \"Content-Length\": \"384\"\n      },\n      \"body\": [\n        \"<?xml version=\\\"1.0\\\" encoding=\\\"utf-8\\\"?>\\n\\r\",\n        \"<soap:Envelope xmlns:xsi=\\\"http://www.w3.org/2001/XMLSchema-instance\\\" xmlns:xsd=\\\"http://www.w3.org/2001/XMLSchema\\\" xmlns:soap=\\\"http://schemas.xmlsoap.org/soap/envelope/\\\">\\n\\r\",\n        \"  <soap:Body>\\n\\r\",\n        \"  <EnlightenResponse xmlns=\\\"http://clearforest.com/\\\">\\n\\r\",\n        \"  <EnlightenResult>string</EnlightenResult>\\n\\r\",\n        \"  </EnlightenResponse>\\n\\r\",\n        \"  </soap:Body>\\n\\r\",\n        \"</soap:Envelope>\\n\\r\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"\\\\[9\\\\]  T \\\\(0\\\\) t:trim: \\\"test\",\n      \"http_code\": 403\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecResponseBodyAccess On\",\n      \"SecRule ARGS \\\"@contains test\\\" \\\"id:1,t:trim,deny\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"version_max\": 0,\n    \"title\": \"actions :: trim,redirect:'http://www.google.com'\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 2313\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"net.tutsplus.com\",\n        \"User-Agent\": \"Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)\",\n        \"Accept\": \"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\",\n        \"Accept-Language\": \"en-us,en;q=0.5\",\n        \"Accept-Encoding\": \"gzip,deflate\",\n        \"Accept-Charset\": \"ISO-8859-1,utf-8;q=0.7,*;q=0.7\",\n        \"Keep-Alive\": \"300\",\n        \"Connection\": \"keep-alive\",\n        \"Cookie\": \"PHPSESSID=r2t5uvjq435r4q7ib3vtdjq120\",\n        \"Pragma\": \"no-cache\",\n        \"Cache-Control\": \"no-cache\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/test.pl?param1=   test   &param2=test2\",\n      \"method\": \"GET\",\n      \"http_version\": 1.1,\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Type\": \"text/xml; charset=utf-8\\n\\r\",\n        \"Content-Length\": \"384\"\n      },\n      \"body\": [\n        \"<?xml version=\\\"1.0\\\" encoding=\\\"utf-8\\\"?>\\n\\r\",\n        \"<soap:Envelope xmlns:xsi=\\\"http://www.w3.org/2001/XMLSchema-instance\\\" xmlns:xsd=\\\"http://www.w3.org/2001/XMLSchema\\\" xmlns:soap=\\\"http://schemas.xmlsoap.org/soap/envelope/\\\">\\n\\r\",\n        \"  <soap:Body>\\n\\r\",\n        \"  <EnlightenResponse xmlns=\\\"http://clearforest.com/\\\">\\n\\r\",\n        \"  <EnlightenResult>string</EnlightenResult>\\n\\r\",\n        \"  </EnlightenResponse>\\n\\r\",\n        \"  </soap:Body>\\n\\r\",\n        \"</soap:Envelope>\\n\\r\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"\\\\[9\\\\]  T \\\\(0\\\\) t:trim: \\\"test\",\n      \"http_code\": 302,\n      \"redirect_url\": \"http://www.google.com\"\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule ARGS \\\"@contains test\\\" \\\"id:1,t:trim,redirect:'http://www.google.com'\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"version_max\": 0,\n    \"title\": \"actions :: trim,status:306,redirect:http://www.google.com\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 2313\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"net.tutsplus.com\",\n        \"User-Agent\": \"Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)\",\n        \"Accept\": \"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\",\n        \"Accept-Language\": \"en-us,en;q=0.5\",\n        \"Accept-Encoding\": \"gzip,deflate\",\n        \"Accept-Charset\": \"ISO-8859-1,utf-8;q=0.7,*;q=0.7\",\n        \"Keep-Alive\": \"300\",\n        \"Connection\": \"keep-alive\",\n        \"Cookie\": \"PHPSESSID=r2t5uvjq435r4q7ib3vtdjq120\",\n        \"Pragma\": \"no-cache\",\n        \"Cache-Control\": \"no-cache\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/test.pl?param1=   test   &param2=test2\",\n      \"method\": \"GET\",\n      \"http_version\": 1.1,\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Type\": \"text/xml; charset=utf-8\\n\\r\",\n        \"Content-Length\": \"384\"\n      },\n      \"body\": [\n        \"<?xml version=\\\"1.0\\\" encoding=\\\"utf-8\\\"?>\\n\\r\",\n        \"<soap:Envelope xmlns:xsi=\\\"http://www.w3.org/2001/XMLSchema-instance\\\" xmlns:xsd=\\\"http://www.w3.org/2001/XMLSchema\\\" xmlns:soap=\\\"http://schemas.xmlsoap.org/soap/envelope/\\\">\\n\\r\",\n        \"  <soap:Body>\\n\\r\",\n        \"  <EnlightenResponse xmlns=\\\"http://clearforest.com/\\\">\\n\\r\",\n        \"  <EnlightenResult>string</EnlightenResult>\\n\\r\",\n        \"  </EnlightenResponse>\\n\\r\",\n        \"  </soap:Body>\\n\\r\",\n        \"</soap:Envelope>\\n\\r\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"\\\\[9\\\\]  T \\\\(0\\\\) t:trim: \\\"test\",\n      \"http_code\": 306,\n      \"redirect_url\": \"http://www.google.com\"\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule ARGS \\\"@contains test\\\" \\\"id:1,t:trim,status:306,redirect:'http://www.google.com'\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"version_max\": 0,\n    \"title\": \"actions :: trim,status:500\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 2313\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"net.tutsplus.com\",\n        \"User-Agent\": \"Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)\",\n        \"Accept\": \"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\",\n        \"Accept-Language\": \"en-us,en;q=0.5\",\n        \"Accept-Encoding\": \"gzip,deflate\",\n        \"Accept-Charset\": \"ISO-8859-1,utf-8;q=0.7,*;q=0.7\",\n        \"Keep-Alive\": \"300\",\n        \"Connection\": \"keep-alive\",\n        \"Cookie\": \"PHPSESSID=r2t5uvjq435r4q7ib3vtdjq120\",\n        \"Pragma\": \"no-cache\",\n        \"Cache-Control\": \"no-cache\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/test.pl?param1=   test   &param2=test2\",\n      \"method\": \"GET\",\n      \"http_version\": 1.1,\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Type\": \"text/xml; charset=utf-8\\n\\r\",\n        \"Content-Length\": \"384\"\n      },\n      \"body\": [\n        \"<?xml version=\\\"1.0\\\" encoding=\\\"utf-8\\\"?>\\n\\r\",\n        \"<soap:Envelope xmlns:xsi=\\\"http://www.w3.org/2001/XMLSchema-instance\\\" xmlns:xsd=\\\"http://www.w3.org/2001/XMLSchema\\\" xmlns:soap=\\\"http://schemas.xmlsoap.org/soap/envelope/\\\">\\n\\r\",\n        \"  <soap:Body>\\n\\r\",\n        \"  <EnlightenResponse xmlns=\\\"http://clearforest.com/\\\">\\n\\r\",\n        \"  <EnlightenResult>string</EnlightenResult>\\n\\r\",\n        \"  </EnlightenResponse>\\n\\r\",\n        \"  </soap:Body>\\n\\r\",\n        \"</soap:Envelope>\\n\\r\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"\\\\[9\\\\]  T \\\\(0\\\\) t:trim: \\\"test\",\n      \"http_code\": 500\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule ARGS \\\"@contains test\\\" \\\"id:1,t:trim,deny,status:500\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"version_max\": 0,\n    \"title\": \"actions :: phase:2,trim,status:500,deny\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 2313\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"net.tutsplus.com\",\n        \"User-Agent\": \"Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)\",\n        \"Accept\": \"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\",\n        \"Accept-Language\": \"en-us,en;q=0.5\",\n        \"Accept-Encoding\": \"gzip,deflate\",\n        \"Accept-Charset\": \"ISO-8859-1,utf-8;q=0.7,*;q=0.7\",\n        \"Keep-Alive\": \"300\",\n        \"Connection\": \"keep-alive\",\n        \"Cookie\": \"PHPSESSID=r2t5uvjq435r4q7ib3vtdjq120\",\n        \"Pragma\": \"no-cache\",\n        \"Cache-Control\": \"no-cache\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/test.pl?param1=   test   &param2=test2\",\n      \"method\": \"GET\",\n      \"http_version\": 1.1,\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Type\": \"text/xml; charset=utf-8\\n\\r\",\n        \"Content-Length\": \"384\"\n      },\n      \"body\": [\n        \"<?xml version=\\\"1.0\\\" encoding=\\\"utf-8\\\"?>\\n\\r\",\n        \"<soap:Envelope xmlns:xsi=\\\"http://www.w3.org/2001/XMLSchema-instance\\\" xmlns:xsd=\\\"http://www.w3.org/2001/XMLSchema\\\" xmlns:soap=\\\"http://schemas.xmlsoap.org/soap/envelope/\\\">\\n\\r\",\n        \"  <soap:Body>\\n\\r\",\n        \"  <EnlightenResponse xmlns=\\\"http://clearforest.com/\\\">\\n\\r\",\n        \"  <EnlightenResult>string</EnlightenResult>\\n\\r\",\n        \"  </EnlightenResponse>\\n\\r\",\n        \"  </soap:Body>\\n\\r\",\n        \"</soap:Envelope>\\n\\r\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"\\\\[9\\\\]  T \\\\(0\\\\) t:trim: \\\"test\",\n      \"http_code\": 500\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule ARGS \\\"@contains test\\\" \\\"id:1,phase:2,t:trim,status:500,deny\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"version_max\": 0,\n    \"title\": \"actions :: phase:4,trim,status:500,deny\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 2313\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"net.tutsplus.com\",\n        \"User-Agent\": \"Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)\",\n        \"Accept\": \"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\",\n        \"Accept-Language\": \"en-us,en;q=0.5\",\n        \"Accept-Encoding\": \"gzip,deflate\",\n        \"Accept-Charset\": \"ISO-8859-1,utf-8;q=0.7,*;q=0.7\",\n        \"Keep-Alive\": \"300\",\n        \"Connection\": \"keep-alive\",\n        \"Cookie\": \"PHPSESSID=r2t5uvjq435r4q7ib3vtdjq120\",\n        \"Pragma\": \"no-cache\",\n        \"Cache-Control\": \"no-cache\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/test.pl?param1=   test   &param2=test2\",\n      \"method\": \"GET\",\n      \"http_version\": 1.1,\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Type\": \"text/xml; charset=utf-8\\n\\r\",\n        \"Content-Length\": \"384\"\n      },\n      \"body\": [\n        \"<?xml version=\\\"1.0\\\" encoding=\\\"utf-8\\\"?>\\n\\r\",\n        \"<soap:Envelope xmlns:xsi=\\\"http://www.w3.org/2001/XMLSchema-instance\\\" xmlns:xsd=\\\"http://www.w3.org/2001/XMLSchema\\\" xmlns:soap=\\\"http://schemas.xmlsoap.org/soap/envelope/\\\">\\n\\r\",\n        \"  <soap:Body>\\n\\r\",\n        \"  <EnlightenResponse xmlns=\\\"http://clearforest.com/\\\">\\n\\r\",\n        \"  <EnlightenResult>string</EnlightenResult>\\n\\r\",\n        \"  </EnlightenResponse>\\n\\r\",\n        \"  </soap:Body>\\n\\r\",\n        \"</soap:Envelope>\\n\\r\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"\\\\[9\\\\]  T \\\\(0\\\\) t:trim: \\\"test\",\n      \"http_code\": 500\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecResponseBodyAccess On\",\n      \"SecRule ARGS \\\"@contains test\\\" \\\"id:1,phase:4,t:trim,status:500,deny\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/auditlog.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"version_max\": 0,\n    \"title\": \"auditlog : basic parser test - Parallel\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 2313\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"www.modsecurity.org\",\n        \"User-Agent\": \"Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)\",\n        \"Accept\": \"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\",\n        \"Accept-Language\": \"en-us,en;q=0.5\",\n        \"Accept-Encoding\": \"gzip,deflate\",\n        \"Accept-Charset\": \"ISO-8859-1,utf-8;q=0.7,*;q=0.7\",\n        \"Keep-Alive\": \"300\",\n        \"Connection\": \"keep-alive\",\n        \"Pragma\": \"no-cache\",\n        \"Cache-Control\": \"no-cache\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/test.pl?param1=   test   &param2=test2\",\n      \"method\": \"GET\",\n      \"http_version\": 1.1,\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Type\": \"plain/text\\n\\r\",\n        \"Content-Length\": \"4\"\n      },\n      \"body\": [\n        \"test\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"\\\\[9\\\\]  T \\\\(0\\\\) t:trim: \\\"test\",\n      \"http_code\": 403\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule ARGS \\\"@contains test\\\" \\\"id:1,t:trim,deny,auditlog\\\"\",\n      \"SecAuditEngine RelevantOnly\",\n      \"SecAuditLogParts ABCFHZ\",\n      \"SecAuditLogStorageDir /tmp/test\",\n      \"SecAuditLogDirMode 0766\",\n      \"SecAuditLogFileMode 0600\",\n      \"SecAuditLogType Parallel\",\n      \"SecAuditLogRelevantStatus \\\"^(?:5|4(?!04))\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"version_max\": 0,\n    \"title\": \"auditlog : basic parser test - Serial\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 2313\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"www.modsecurity.org\",\n        \"User-Agent\": \"Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)\",\n        \"Accept\": \"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\",\n        \"Accept-Language\": \"en-us,en;q=0.5\",\n        \"Accept-Encoding\": \"gzip,deflate\",\n        \"Accept-Charset\": \"ISO-8859-1,utf-8;q=0.7,*;q=0.7\",\n        \"Keep-Alive\": \"300\",\n        \"Connection\": \"keep-alive\",\n        \"Pragma\": \"no-cache\",\n        \"Cache-Control\": \"no-cache\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/test.pl?param1=   test   &param2=test2\",\n      \"method\": \"GET\",\n      \"http_version\": 1.1,\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Type\": \"plain/text\\n\\r\",\n        \"Content-Length\": \"4\"\n      },\n      \"body\": [\n        \"test\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"\\\\[9\\\\]  T \\\\(0\\\\) t:trim: \\\"test\",\n      \"http_code\": 403\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule ARGS \\\"@contains test\\\" \\\"id:1,t:trim,deny,auditlog\\\"\",\n      \"SecAuditEngine RelevantOnly\",\n      \"SecAuditLogParts ABCFHZ\",\n      \"SecAuditLogStorageDir /tmp/test\",\n      \"SecAuditLog /tmp/audit_test.log\",\n      \"SecAuditLogDirMode 0766\",\n      \"SecAuditLogFileMode 0600\",\n      \"SecAuditLogType Serial\",\n      \"SecAuditLogRelevantStatus \\\"^(?:5|4(?!04))\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"version_max\": 0,\n    \"title\": \"auditlog : basic parser test - Parallel\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 2313\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"www.modsecurity.org\",\n        \"User-Agent\": \"Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)\",\n        \"Accept\": \"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\",\n        \"Accept-Language\": \"en-us,en;q=0.5\",\n        \"Accept-Encoding\": \"gzip,deflate\",\n        \"Accept-Charset\": \"ISO-8859-1,utf-8;q=0.7,*;q=0.7\",\n        \"Keep-Alive\": \"300\",\n        \"Connection\": \"keep-alive\",\n        \"Pragma\": \"no-cache\",\n        \"Cache-Control\": \"no-cache\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/test.pl?param1=   test   &param2=test2\",\n      \"method\": \"GET\",\n      \"http_version\": 1.1,\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Type\": \"plain/text\\n\\r\",\n        \"Content-Length\": \"4\"\n      },\n      \"body\": [\n        \"test\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"\\\\[9\\\\]  T \\\\(0\\\\) t:trim: \\\"test\",\n      \"http_code\": 403\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule ARGS \\\"@contains test\\\" \\\"id:1,t:trim,deny,auditlog\\\"\",\n      \"SecAuditEngine RelevantOnly\",\n      \"SecAuditLogParts ABCFHZ\",\n      \"SecAuditLogStorageDir /tmp/test\",\n      \"SecAuditLog /tmp/audit_test_parallel.log\",\n      \"SecAuditLogDirMode 0766\",\n      \"SecAuditLogFileMode 0600\",\n      \"SecAuditLogType Parallel\",\n      \"SecAuditLogRelevantStatus \\\"^(?:5|4(?!04))\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"version_max\": 0,\n    \"title\": \"auditlog : basic parser test - JSON\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 2313\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"www.modsecurity.org\",\n        \"User-Agent\": \"Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)\",\n        \"Accept\": \"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\",\n        \"Accept-Language\": \"en-us,en;q=0.5\",\n        \"Accept-Encoding\": \"gzip,deflate\",\n        \"Accept-Charset\": \"ISO-8859-1,utf-8;q=0.7,*;q=0.7\",\n        \"Keep-Alive\": \"300\",\n        \"Connection\": \"keep-alive\",\n        \"Pragma\": \"no-cache\",\n        \"Cache-Control\": \"no-cache\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/test.pl?param1=   test   &param2=test2\",\n      \"method\": \"GET\",\n      \"http_version\": 1.1,\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Type\": \"plain/text\\n\\r\",\n        \"Content-Length\": \"4\"\n      },\n      \"body\": [\n        \"test\"\n      ]\n    },\n    \"expected\": {\n      \"audit_log\": \"{\\\"transaction\\\":{\\\"client_ip\\\":\\\"200.249.12.31\\\",\\\"time_stamp\\\":\\\"\\\\S{3} \\\\S{3} [ \\\\d]\\\\d \\\\d{2}:\\\\d{2}:\\\\d{2} \\\\d{4}\\\"\",\n      \"http_code\": 403\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule ARGS \\\"@contains test\\\" \\\"id:1,t:trim,deny,auditlog\\\"\",\n      \"SecAuditEngine RelevantOnly\",\n      \"SecAuditLogFormat JSON\",\n      \"SecAuditLogParts ABCFHZ\",\n      \"SecAuditLogStorageDir /tmp/test\",\n      \"SecAuditLog /tmp/audit_test_parallel.log\",\n      \"SecAuditLogDirMode 0766\",\n      \"SecAuditLogFileMode 0600\",\n      \"SecAuditLogType Serial\",\n      \"SecAuditLogRelevantStatus \\\"^(?:5|4(?!04))\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"version_max\": 0,\n    \"title\": \"auditlog : messages verification - nolog,auditlog\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 2313\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"www.modsecurity.org\",\n        \"User-Agent\": \"Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)\",\n        \"Accept\": \"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\",\n        \"Accept-Language\": \"en-us,en;q=0.5\",\n        \"Accept-Encoding\": \"gzip,deflate\",\n        \"Accept-Charset\": \"ISO-8859-1,utf-8;q=0.7,*;q=0.7\",\n        \"Keep-Alive\": \"300\",\n        \"Connection\": \"keep-alive\",\n        \"Pragma\": \"no-cache\",\n        \"Cache-Control\": \"no-cache\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/test.pl?param1=test&param2=test2\",\n      \"method\": \"GET\",\n      \"http_version\": 1.1,\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"audit_log\": \"id \\\"1556\",\n      \"http_code\": 403\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecDefaultAction \\\"phase:1,nolog,auditlog,deny,status:403\\\"\",\n      \"SecRule ARGS \\\"@contains test\\\" \\\"id:1556,phase:1,block,nolog,auditlog\\\"\",\n      \"SecAuditEngine RelevantOnly\",\n      \"SecAuditLogParts ABCFHZ\",\n      \"SecAuditLog /tmp/test/modsec_audit_auditlog_1.log\",\n      \"SecAuditLogDirMode 0766\",\n      \"SecAuditLogFileMode 0666\",\n      \"SecAuditLogType Serial\",\n      \"SecAuditLogRelevantStatus \\\"^(?:5|4(?!04))\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"version_max\": 0,\n    \"title\": \"auditlog : multiMatch data, match after last transform\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 2313\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"www.modsecurity.org\",\n        \"User-Agent\": \"Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)\",\n        \"Accept\": \"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\",\n        \"Accept-Language\": \"en-us,en;q=0.5\",\n        \"Accept-Encoding\": \"gzip,deflate\",\n        \"Accept-Charset\": \"ISO-8859-1,utf-8;q=0.7,*;q=0.7\",\n        \"Keep-Alive\": \"300\",\n        \"Connection\": \"keep-alive\",\n        \"Pragma\": \"no-cache\",\n        \"Cache-Control\": \"no-cache\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/test.pl?param1=test&param2=tEst2\",\n      \"method\": \"GET\",\n      \"http_version\": 1.1,\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"audit_log\": \"\\\\[msg \\\"testmsg\\\"\\\\] \\\\[data \\\"testdata\\\"\\\\] \\\\[severity \\\"7\\\"\\\\] \\\\[ver \\\"\\\"\\\\] \\\\[maturity \\\"0\\\"\\\\] \\\\[accuracy \\\"0\\\"\\\\] \\\\[tag \\\"testtag1\\\"\\\\] \\\\[tag \\\"testtag2\\\"\\\\]\",\n      \"http_code\": 403\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecDefaultAction \\\"phase:1,nolog,auditlog,deny,status:403\\\"\",\n      \"SecRule ARGS \\\"@contains test2\\\" \\\"id:1557,phase:1,multiMatch,block,log,t:none,t:urlDecode,t:lowercase,msg:'testmsg',logdata:'testdata',severity:'DEBUG',tag:'testtag1',tag:'testtag2'\\\"\",\n      \"SecAuditEngine RelevantOnly\",\n      \"SecAuditLogParts ABCFHZ\",\n      \"SecAuditLog /tmp/test/modsec_audit_multimatch_1.log\",\n      \"SecAuditLogDirMode 0766\",\n      \"SecAuditLogFileMode 0666\",\n      \"SecAuditLogType Serial\",\n      \"SecAuditLogRelevantStatus \\\"^(?:5|4(?!04))\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"version_max\": 0,\n    \"title\": \"auditlog : multiMatch data, match only after intermediate transform\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 2313\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"www.modsecurity.org\",\n        \"User-Agent\": \"Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)\",\n        \"Accept\": \"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\",\n        \"Accept-Language\": \"en-us,en;q=0.5\",\n        \"Accept-Encoding\": \"gzip,deflate\",\n        \"Accept-Charset\": \"ISO-8859-1,utf-8;q=0.7,*;q=0.7\",\n        \"Keep-Alive\": \"300\",\n        \"Connection\": \"keep-alive\",\n        \"Pragma\": \"no-cache\",\n        \"Cache-Control\": \"no-cache\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/test.pl?param1=test&param2=%20tEst2\",\n      \"method\": \"GET\",\n      \"http_version\": 1.1,\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"audit_log\": \"\\\\[msg \\\"testmsg\\\"\\\\] \\\\[data \\\"testdata\\\"\\\\] \\\\[severity \\\"7\\\"\\\\] \\\\[ver \\\"\\\"\\\\] \\\\[maturity \\\"0\\\"\\\\] \\\\[accuracy \\\"0\\\"\\\\] \\\\[tag \\\"testtag1\\\"\\\\] \\\\[tag \\\"testtag2\\\"\\\\]\",\n      \"http_code\": 403\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecDefaultAction \\\"phase:1,nolog,auditlog,deny,status:403\\\"\",\n      \"SecRule ARGS \\\"@streq tEst2\\\" \\\"id:1558,phase:1,multiMatch,block,log,t:none,t:trim,t:lowercase,msg:'testmsg',logdata:'testdata',severity:'DEBUG',tag:'testtag1',tag:'testtag2'\\\"\",\n      \"SecAuditEngine RelevantOnly\",\n      \"SecAuditLogParts ABCFHZ\",\n      \"SecAuditLog /tmp/test/modsec_audit_multimatch_2.log\",\n      \"SecAuditLogDirMode 0766\",\n      \"SecAuditLogFileMode 0666\",\n      \"SecAuditLogType Serial\",\n      \"SecAuditLogRelevantStatus \\\"^(?:5|4(?!04))\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"version_max\": 0,\n    \"title\": \"auditlog : rule chain, multiMatch data, match after last transform\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 2313\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"www.modsecurity.org\",\n        \"User-Agent\": \"Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)\",\n        \"Accept\": \"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\",\n        \"Accept-Language\": \"en-us,en;q=0.5\",\n        \"Accept-Encoding\": \"gzip,deflate\",\n        \"Accept-Charset\": \"ISO-8859-1,utf-8;q=0.7,*;q=0.7\",\n        \"Keep-Alive\": \"300\",\n        \"Connection\": \"keep-alive\",\n        \"Pragma\": \"no-cache\",\n        \"Cache-Control\": \"no-cache\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/test.pl?param1=test&param2=tEst2\",\n      \"method\": \"GET\",\n      \"http_version\": 1.1,\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"audit_log\": \"\\\\[msg \\\"testmsg\\\"\\\\] \\\\[data \\\"testdata\\\"\\\\] \\\\[severity \\\"7\\\"\\\\] \\\\[ver \\\"\\\"\\\\] \\\\[maturity \\\"0\\\"\\\\] \\\\[accuracy \\\"0\\\"\\\\] \\\\[tag \\\"testtag1\\\"\\\\] \\\\[tag \\\"testtag2\\\"\\\\]\",\n      \"http_code\": 403\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecDefaultAction \\\"phase:1,nolog,auditlog,deny,status:403\\\"\",\n      \"SecRule ARGS \\\"@contains test2\\\" \\\"id:1559,phase:1,multiMatch,block,log,t:none,t:urlDecode,t:lowercase,msg:'testmsg',logdata:'testdata',severity:'DEBUG',tag:'testtag1',tag:'testtag2',chain\\\"\",\n      \"SecRule REQUEST_METHOD \\\"@streq GET\\\" \\\"t:none\\\"\",\n      \"SecAuditEngine RelevantOnly\",\n      \"SecAuditLogParts ABCFHZ\",\n      \"SecAuditLog /tmp/test/modsec_audit_multimatch_3.log\",\n      \"SecAuditLogDirMode 0766\",\n      \"SecAuditLogFileMode 0666\",\n      \"SecAuditLogType Serial\",\n      \"SecAuditLogRelevantStatus \\\"^(?:5|4(?!04))\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"version_max\": 0,\n    \"title\": \"auditlog : rule chain, multiMatch data, match only after intermediate transform\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 2313\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"www.modsecurity.org\",\n        \"User-Agent\": \"Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)\",\n        \"Accept\": \"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\",\n        \"Accept-Language\": \"en-us,en;q=0.5\",\n        \"Accept-Encoding\": \"gzip,deflate\",\n        \"Accept-Charset\": \"ISO-8859-1,utf-8;q=0.7,*;q=0.7\",\n        \"Keep-Alive\": \"300\",\n        \"Connection\": \"keep-alive\",\n        \"Pragma\": \"no-cache\",\n        \"Cache-Control\": \"no-cache\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/test.pl?param1=test&param2=%20tEst2\",\n      \"method\": \"GET\",\n      \"http_version\": 1.1,\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"audit_log\": \"\\\\[msg \\\"testmsg\\\"\\\\] \\\\[data \\\"testdata\\\"\\\\] \\\\[severity \\\"7\\\"\\\\] \\\\[ver \\\"\\\"\\\\] \\\\[maturity \\\"0\\\"\\\\] \\\\[accuracy \\\"0\\\"\\\\] \\\\[tag \\\"testtag1\\\"\\\\] \\\\[tag \\\"testtag2\\\"\\\\]\",\n      \"http_code\": 403\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecDefaultAction \\\"phase:1,nolog,auditlog,deny,status:403\\\"\",\n      \"SecRule ARGS \\\"@streq tEst2\\\" \\\"id:1560,phase:1,multiMatch,block,log,t:none,t:trim,t:lowercase,msg:'testmsg',logdata:'testdata',severity:'DEBUG',tag:'testtag1',tag:'testtag2',chain\\\"\",\n      \"SecRule REQUEST_METHOD \\\"@streq GET\\\" \\\"t:none\\\"\",\n      \"SecAuditEngine RelevantOnly\",\n      \"SecAuditLogParts ABCFHZ\",\n      \"SecAuditLog /tmp/test/modsec_audit_multimatch_4.log\",\n      \"SecAuditLogDirMode 0766\",\n      \"SecAuditLogFileMode 0666\",\n      \"SecAuditLogType Serial\",\n      \"SecAuditLogRelevantStatus \\\"^(?:5|4(?!04))\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"version_max\": 0,\n    \"title\": \"auditlog : SecAuditLogPrefix\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 2313\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"www.modsecurity.org\",\n        \"User-Agent\": \"Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)\",\n        \"Accept\": \"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\",\n        \"Accept-Language\": \"en-us,en;q=0.5\",\n        \"Accept-Encoding\": \"gzip,deflate\",\n        \"Accept-Charset\": \"ISO-8859-1,utf-8;q=0.7,*;q=0.7\",\n        \"Keep-Alive\": \"300\",\n        \"Connection\": \"keep-alive\",\n        \"Pragma\": \"no-cache\",\n        \"Cache-Control\": \"no-cache\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/test.pl?param1=   test   &param2=test2\",\n      \"method\": \"GET\",\n      \"http_version\": 1.1,\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Type\": \"plain/text\\n\\r\",\n        \"Content-Length\": \"4\"\n      },\n      \"body\": [\n        \"test\"\n      ]\n    },\n    \"expected\": {\n      \"audit_log\": \"\\\\[audit\\\\.log]:\\\\ ---.*\\\\[audit\\\\.log]:\\\\ Keep-Alive\",\n      \"http_code\": 403\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule ARGS \\\"@contains test\\\" \\\"id:1,t:trim,deny,auditlog\\\"\",\n      \"SecAuditEngine RelevantOnly\",\n      \"SecAuditLogPrefix \\\"[audit.log]: \\\"\",\n      \"SecAuditLogParts ABCFHZ\",\n      \"SecAuditLogStorageDir /tmp/test\",\n      \"SecAuditLog /tmp/audit_test_prefix.log\",\n      \"SecAuditLogDirMode 0766\",\n      \"SecAuditLogFileMode 0600\",\n      \"SecAuditLogType Serial\",\n      \"SecAuditLogRelevantStatus \\\"^(?:5|4(?!04))\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"version_max\": 0,\n    \"title\": \"auditlog : Binary char from input, check message\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 2313\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"www.modsecurity.org\",\n        \"User-Agent\": \"Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)\",\n        \"Accept\": \"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\",\n        \"Accept-Language\": \"en-us,en;q=0.5\",\n        \"Accept-Encoding\": \"gzip,deflate\",\n        \"Accept-Charset\": \"ISO-8859-1,utf-8;q=0.7,*;q=0.7\",\n        \"Keep-Alive\": \"300\",\n        \"Connection\": \"keep-alive\",\n        \"Pragma\": \"no-cache\",\n        \"Cache-Control\": \"no-cache\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?%ADd+allow%3d1+%ADd+auto\",\n      \"method\": \"GET\",\n      \"http_version\": 1.1,\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Type\": \"plain/text\\n\\r\",\n        \"Content-Length\": \"4\"\n      },\n      \"body\": [\n        \"test\"\n      ]\n    },\n    \"expected\": {\n      \"audit_log\": \"\\\"match\\\":\\\"Matched \\\\\\\\\\\"Operator `ValidateUtf8Encoding' with parameter `' against variable `ARGS_NAMES:\\\\\\\\\\\\\\\\xadd allow=1 \\\\\\\\\\\\\\\\xadd auto' \\\\(Value: `\\\\\\\\\\\\\\\\xadd allow=1 \\\\\\\\\\\\\\\\xadd auto' \\\\)\\\"\",\n      \"http_code\": 403\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule REQUEST_FILENAME|ARGS|ARGS_NAMES \\\"@validateUtf8Encoding\\\" \\\"id:920250,phase:2,deny,t:none,msg:'UTF8 Encoding Abuse Attack Attempt',logdata:'%{MATCHED_VAR}'\",\n      \"SecAuditEngine RelevantOnly\",\n      \"SecAuditLogParts ABHJZ\",\n      \"SecAuditLogFormat JSON\",\n      \"SecAuditLogStorageDir /tmp/test\",\n      \"SecAuditLog /tmp/audit_test_prefix.log\",\n      \"SecAuditLogDirMode 0766\",\n      \"SecAuditLogFileMode 0600\",\n      \"SecAuditLogType Serial\",\n      \"SecAuditLogRelevantStatus \\\"^(?:5|4(?!04))\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"version_max\": 0,\n    \"title\": \"auditlog : Binary char from input, check body\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 2313\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"www.modsecurity.org\",\n        \"User-Agent\": \"Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)\",\n        \"Accept\": \"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\",\n        \"Accept-Language\": \"en-us,en;q=0.5\",\n        \"Accept-Encoding\": \"gzip,deflate\",\n        \"Accept-Charset\": \"ISO-8859-1,utf-8;q=0.7,*;q=0.7\",\n        \"Keep-Alive\": \"300\",\n        \"Connection\": \"keep-alive\",\n        \"Pragma\": \"no-cache\",\n        \"Cache-Control\": \"no-cache\",\n        \"Content-Type\": \"application/x-www-form-urlencoded\",\n        \"Content-Length\": \"5\"\n      },\n      \"uri\": \"/?attack=true\",\n      \"method\": \"POST\",\n      \"http_version\": 1.1,\n      \"body\": [\n        \"­=­\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Type\": \"plain/text\\n\\r\",\n        \"Content-Length\": \"4\"\n      },\n      \"body\": [\n        \"test\"\n      ]\n    },\n    \"expected\": {\n      \"audit_log\": \"\\\"body\\\":\\\"\\\\\\\\\\\\\\\\xc2\\\\\\\\\\\\\\\\xad=\\\\\\\\\\\\\\\\xc2\\\\\\\\\\\\\\\\xad\",\n      \"http_code\": 403\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule ARGS_NAMES \\\"@rx attack\\\" \\\"id:1,phase:2,deny,t:none\",\n      \"SecAuditEngine RelevantOnly\",\n      \"SecAuditLogParts ABCHJZ\",\n      \"SecAuditLogFormat JSON\",\n      \"SecAuditLogStorageDir /tmp/test\",\n      \"SecAuditLog /tmp/audit_test_prefix.log\",\n      \"SecAuditLogDirMode 0766\",\n      \"SecAuditLogFileMode 0600\",\n      \"SecAuditLogType Serial\",\n      \"SecAuditLogRelevantStatus \\\"^(?:5|4(?!04))\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"version_max\": 0,\n    \"title\": \"auditlog : Binary char from input, check header\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 2313\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"www.modsecurity.org\",\n        \"User-Agent\": \"Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)\",\n        \"Accept\": \"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\",\n        \"Accept-Language\": \"en-us,en;q=0.5\",\n        \"Accept-Encoding\": \"gzip,deflate\",\n        \"Accept-Charset\": \"ISO-8859-1,utf-8;q=0.7,*;q=0.7\",\n        \"Keep-Alive\": \"300\",\n        \"Connection\": \"keep-alive\",\n        \"Pragma\": \"no-cache\",\n        \"Cache-Control\": \"no-cache\",\n        \"Content-Type\": \"application/x-www-form-urlencoded\",\n        \"Content-Length\": \"5\",\n        \"X-­-custom\": \"Some ­ value\"\n      },\n      \"uri\": \"/?attack=true\",\n      \"method\": \"POST\",\n      \"http_version\": 1.1,\n      \"body\": [\n        \"­=­\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Type\": \"plain/text\\n\\r\",\n        \"Content-Length\": \"4\"\n      },\n      \"body\": [\n        \"test\"\n      ]\n    },\n    \"expected\": {\n      \"audit_log\": \"\\\"X-\\\\\\\\\\\\\\\\xc2\\\\\\\\\\\\\\\\xad-custom\\\":\\\"Some \\\\\\\\\\\\\\\\xc2\\\\\\\\\\\\\\\\xad value\\\"\",\n      \"http_code\": 403\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule ARGS|ARGS_NAMES \\\"@rx attack\\\" \\\"id:1,phase:2,deny,t:none\",\n      \"SecAuditEngine RelevantOnly\",\n      \"SecAuditLogParts ABHJZ\",\n      \"SecAuditLogFormat JSON\",\n      \"SecAuditLogStorageDir /tmp/test\",\n      \"SecAuditLog /tmp/audit_test_prefix.log\",\n      \"SecAuditLogDirMode 0766\",\n      \"SecAuditLogFileMode 0600\",\n      \"SecAuditLogType Serial\",\n      \"SecAuditLogRelevantStatus \\\"^(?:5|4(?!04))\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/collection-case-insensitive.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"version_max\": 0,\n    \"title\": \"Testing collection :: Case insensitive (1/1)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 2313\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"User-Agent\": \"Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)\",\n        \"Accept\": \"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\",\n        \"Accept-Language\": \"en-us,en;q=0.5\",\n        \"Accept-Encoding\": \"gzip,deflate\",\n        \"Accept-Charset\": \"ISO-8859-1,utf-8;q=0.7,*;q=0.7\",\n        \"Keep-Alive\": \"300\",\n        \"Connection\": \"keep-alive\",\n        \"Cookie\": \"PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120\",\n        \"Pragma\": \"no-cache\",\n        \"Cache-Control\": \"no-cache\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/test.pl?param1=   test   &param2=test2\",\n      \"method\": \"GET\",\n      \"http_version\": 1.1,\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Type\": \"text/xml; charset=utf-8\\n\\r\",\n        \"Content-Length\": \"384\"\n      },\n      \"body\": [\n        \"<?xml version=\\\"1.0\\\" encoding=\\\"utf-8\\\"?>\\n\\r\",\n        \"<soap:Envelope xmlns:xsi=\\\"http://www.w3.org/2001/XMLSchema-instance\\\" xmlns:xsd=\\\"http://www.w3.org/2001/XMLSchema\\\" xmlns:soap=\\\"http://schemas.xmlsoap.org/soap/envelope/\\\">\\n\\r\",\n        \"  <soap:Body>\\n\\r\",\n        \"  <EnlightenResponse xmlns=\\\"http://clearforest.com/\\\">\\n\\r\",\n        \"  <EnlightenResult>string</EnlightenResult>\\n\\r\",\n        \"  </EnlightenResponse>\\n\\r\",\n        \"  </soap:Body>\\n\\r\",\n        \"</soap:Envelope>\\n\\r\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"matched_var:PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120\\\" \\\\(Variable: TX:something\\\\)\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule REQUEST_headers \\\"@contains PHPSESSID\\\" \\\"id:1,t:lowercase,t:none,setvar:TX.something=matched_var:%{matched_var}%\\\"\",\n      \"SecRule TX \\\"@contains to_test\\\" \\\"id:2,t:lowercase,t:none\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/collection-lua.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing LUA :: m.set TX (1/7)\",\n    \"resource\": \"lua\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"My sweet little browser\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/whee?res=1\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"2\\\" \\\\(Variable: TX.lua_set_var\\\\)\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecAction \\\"id:1,pass,setvar:TX.lua_set_var=1\\\"\",\n      \"SecRuleScript test-cases/data/setvar.lua \\\"id:2,pass\\\"\",\n      \"SecRule TX.lua_set_var \\\"@contains 2\\\" \\\"id:3,t:none\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing LUA :: m.set IP (2/7)\",\n    \"resource\": \"lua\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"My sweet little browser\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/whee?res=1\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"2\\\" \\\\(Variable: IP:::::lua_set_var\\\\)\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecAction \\\"id:1,pass,setvar:IP.lua_set_var=1\\\"\",\n      \"SecRuleScript test-cases/data/setvar.lua \\\"id:2,pass\\\"\",\n      \"SecRule IP.lua_set_var \\\"@contains 2\\\" \\\"id:3,t:none\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing LUA :: m.set GLOBAL (3/7)\",\n    \"resource\": \"lua\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"My sweet little browser\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/whee?res=1\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"2\\\" \\\\(Variable: GLOBAL:::::lua_set_var\\\\)\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecAction \\\"id:1,pass,setvar:GLOBAL.lua_set_var=1\\\"\",\n      \"SecRuleScript test-cases/data/setvar.lua \\\"id:2,pass\\\"\",\n      \"SecRule GLOBAL.lua_set_var \\\"@contains 2\\\" \\\"id:3,t:none\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing LUA :: m.set RESOURCE (4/7)\",\n    \"resource\": \"lua\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"My sweet little browser\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/whee?res=1\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"2\\\" \\\\(Variable: RESOURCE:::::lua_set_var\\\\)\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecAction \\\"id:1,pass,setvar:RESOURCE.lua_set_var=1\\\"\",\n      \"SecRuleScript test-cases/data/setvar.lua \\\"id:2,pass\\\"\",\n      \"SecRule RESOURCE.lua_set_var \\\"@contains 2\\\" \\\"id:3,t:none\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing LUA :: m.set SESSION (5/7)\",\n    \"resource\": \"lua\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"My sweet little browser\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/whee?res=1\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"2\\\" \\\\(Variable: SESSION:::::lua_set_var\\\\)\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecAction \\\"id:1,pass,setvar:SESSION.lua_set_var=1\\\"\",\n      \"SecRuleScript test-cases/data/setvar.lua \\\"id:2,pass\\\"\",\n      \"SecRule SESSION.lua_set_var \\\"@contains 2\\\" \\\"id:3,t:none\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing LUA :: m.set USER (6/7)\",\n    \"resource\": \"lua\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"My sweet little browser\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/whee?res=1\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"2\\\" \\\\(Variable: USER:::::lua_set_var\\\\)\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecAction \\\"id:1,pass,setvar:USER.lua_set_var=1\\\"\",\n      \"SecRuleScript test-cases/data/setvar.lua \\\"id:2,pass\\\"\",\n      \"SecRule USER.lua_set_var \\\"@contains 2\\\" \\\"id:3,t:none\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing LUA :: m.getvars ARGS (8/8)\",\n    \"resource\": \"lua\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"My sweet little browser\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/whee?parm1=a&parm2=b\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRuleScript test-cases/data/match-getvars-args.lua \\\"id:2,phase:2,deny,status:403\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/collection-regular_expression_selection.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"version_max\": 0,\n    \"title\": \"Testing collection :: TX/regular expression (1/2)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 2313\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"User-Agent\": \"Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)\",\n        \"Accept\": \"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\",\n        \"Accept-Language\": \"en-us,en;q=0.5\",\n        \"Accept-Encoding\": \"gzip,deflate\",\n        \"Accept-Charset\": \"ISO-8859-1,utf-8;q=0.7,*;q=0.7\",\n        \"Keep-Alive\": \"300\",\n        \"Connection\": \"keep-alive\",\n        \"Cookie\": \"PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120\",\n        \"Pragma\": \"no-cache\",\n        \"Cache-Control\": \"no-cache\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/test.pl?id_a=test&nah=nops\",\n      \"method\": \"GET\",\n      \"http_version\": 1.1,\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Type\": \"text/xml; charset=utf-8\\n\\r\",\n        \"Content-Length\": \"384\"\n      },\n      \"body\": [\n        \"<?xml version=\\\"1.0\\\" encoding=\\\"utf-8\\\"?>\\n\\r\",\n        \"<soap:Envelope xmlns:xsi=\\\"http://www.w3.org/2001/XMLSchema-instance\\\" xmlns:xsd=\\\"http://www.w3.org/2001/XMLSchema\\\" xmlns:soap=\\\"http://schemas.xmlsoap.org/soap/envelope/\\\">\\n\\r\",\n        \"  <soap:Body>\\n\\r\",\n        \"  <EnlightenResponse xmlns=\\\"http://clearforest.com/\\\">\\n\\r\",\n        \"  <EnlightenResult>string</EnlightenResult>\\n\\r\",\n        \"  </EnlightenResponse>\\n\\r\",\n        \"  </soap:Body>\\n\\r\",\n        \"</soap:Envelope>\\n\\r\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Saving variable: IP:nah with value: nops\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule ARGS:/^id_/ \\\"@contains test\\\" \\\"id:1,phase:2,t:lowercase,initcol:ip=%{REMOTE_ADDR}\\\"\",\n      \"SecRule ARGS:/^id_/ \\\"@contains test\\\" \\\"id:2,phase:2,t:lowercase,setvar:IP.nah=nops\\\"\",\n      \"SecRule IP:/id_a$/ \\\"rx .\\\" \\\"id:3,phase:2,deny,status:403\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"version_max\": 0,\n    \"title\": \"Testing collection :: TX/regular expression (2/2)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 2313\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"User-Agent\": \"Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)\",\n        \"Accept\": \"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\",\n        \"Accept-Language\": \"en-us,en;q=0.5\",\n        \"Accept-Encoding\": \"gzip,deflate\",\n        \"Accept-Charset\": \"ISO-8859-1,utf-8;q=0.7,*;q=0.7\",\n        \"Keep-Alive\": \"300\",\n        \"Connection\": \"keep-alive\",\n        \"Cookie\": \"PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120\",\n        \"Pragma\": \"no-cache\",\n        \"Cache-Control\": \"no-cache\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/test.pl?id_a=test&nah=nops\",\n      \"method\": \"GET\",\n      \"http_version\": 1.1,\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Type\": \"text/xml; charset=utf-8\\n\\r\",\n        \"Content-Length\": \"384\"\n      },\n      \"body\": [\n        \"<?xml version=\\\"1.0\\\" encoding=\\\"utf-8\\\"?>\\n\\r\",\n        \"<soap:Envelope xmlns:xsi=\\\"http://www.w3.org/2001/XMLSchema-instance\\\" xmlns:xsd=\\\"http://www.w3.org/2001/XMLSchema\\\" xmlns:soap=\\\"http://schemas.xmlsoap.org/soap/envelope/\\\">\\n\\r\",\n        \"  <soap:Body>\\n\\r\",\n        \"  <EnlightenResponse xmlns=\\\"http://clearforest.com/\\\">\\n\\r\",\n        \"  <EnlightenResult>string</EnlightenResult>\\n\\r\",\n        \"  </EnlightenResponse>\\n\\r\",\n        \"  </soap:Body>\\n\\r\",\n        \"</soap:Envelope>\\n\\r\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Saving variable: IP:id_a with value: nops\",\n      \"http_code\": 403\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule ARGS:/^id_/ \\\"@contains test\\\" \\\"id:11,phase:2,t:lowercase,initcol:ip=%{REMOTE_ADDR}\\\"\",\n      \"SecRule ARGS:/^id_/ \\\"@contains test\\\" \\\"id:12,phase:2,t:lowercase,setvar:IP.id_a=nops\\\"\",\n      \"SecRule IP:/id_a$/ \\\"@contains nops\\\" \\\"id:13,phase:2,deny,status:403\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/collection-resource.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"version_max\": 0,\n    \"title\": \"Testing collection :: RESOURCE (1/2)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 2313\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"User-Agent\": \"Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)\",\n        \"Accept\": \"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\",\n        \"Accept-Language\": \"en-us,en;q=0.5\",\n        \"Accept-Encoding\": \"gzip,deflate\",\n        \"Accept-Charset\": \"ISO-8859-1,utf-8;q=0.7,*;q=0.7\",\n        \"Keep-Alive\": \"300\",\n        \"Connection\": \"keep-alive\",\n        \"Cookie\": \"PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120\",\n        \"Pragma\": \"no-cache\",\n        \"Cache-Control\": \"no-cache\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/test.pl?resource=whee\",\n      \"method\": \"GET\",\n      \"http_version\": 1.1,\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Type\": \"text/xml; charset=utf-8\\n\\r\",\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"123\\\" \\\\(Variable: RESOURCE:whee::::test\\\\)\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule ARGS:resource \\\"@unconditionalmatch \\\" \\\"phase:2,pass,initcol:resource=%{ARGS.resource},id:900003\\\"\",\n      \"SecRule ARGS:resource \\\"@unconditionalmatch \\\" \\\"phase:2,pass,setvar:resource.test=123,id:900000\\\"\",\n      \"SecRule ARGS:resource \\\"@unconditionalmatch \\\" \\\"phase:2,pass,expirevar:resource.timeout=3600,id:9000033\\\"\",\n      \"SecRule RESOURCE:test \\\"@unconditionalmatch \\\" \\\"phase:2,pass,expirevar:resource.timeout=3600,id:9000034\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"version_max\": 0,\n    \"title\": \"Testing collection :: RESOURCE (2/2)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 2313\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"User-Agent\": \"Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)\",\n        \"Accept\": \"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\",\n        \"Accept-Language\": \"en-us,en;q=0.5\",\n        \"Accept-Encoding\": \"gzip,deflate\",\n        \"Accept-Charset\": \"ISO-8859-1,utf-8;q=0.7,*;q=0.7\",\n        \"Keep-Alive\": \"300\",\n        \"Connection\": \"keep-alive\",\n        \"Cookie\": \"PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120\",\n        \"Pragma\": \"no-cache\",\n        \"Cache-Control\": \"no-cache\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/test.pl?resource=whee\",\n      \"method\": \"GET\",\n      \"http_version\": 1.1,\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Type\": \"text/xml; charset=utf-8\\n\\r\",\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"RESOURCE:whee::webappid::test\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecWebAppId webappid\",\n      \"SecRule ARGS:resource \\\"@unconditionalmatch \\\" \\\"phase:2,pass,initcol:resource=%{ARGS.resource},id:900003\\\"\",\n      \"SecRule ARGS:resource \\\"@unconditionalmatch \\\" \\\"phase:2,pass,setvar:resource.test=123,id:900000\\\"\",\n      \"SecRule ARGS:resource \\\"@unconditionalmatch \\\" \\\"phase:2,pass,expirevar:resource.timeout=3600,id:9000033\\\"\",\n      \"SecRule RESOURCE:test \\\"@unconditionalmatch \\\" \\\"phase:2,pass,expirevar:resource.timeout=3600,id:9000034\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/collection-tx-with-macro.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"version_max\": 0,\n    \"title\": \"Testing collection :: TX (with macro) (1/4)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 2313\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"User-Agent\": \"Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)\",\n        \"Accept\": \"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\",\n        \"Accept-Language\": \"en-us,en;q=0.5\",\n        \"Accept-Encoding\": \"gzip,deflate\",\n        \"Accept-Charset\": \"ISO-8859-1,utf-8;q=0.7,*;q=0.7\",\n        \"Keep-Alive\": \"300\",\n        \"Connection\": \"keep-alive\",\n        \"Cookie\": \"PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120\",\n        \"Pragma\": \"no-cache\",\n        \"Cache-Control\": \"no-cache\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/test.pl?param1=   test   &param2=test2\",\n      \"method\": \"GET\",\n      \"http_version\": 1.1,\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Type\": \"text/xml; charset=utf-8\\n\\r\",\n        \"Content-Length\": \"384\"\n      },\n      \"body\": [\n        \"<?xml version=\\\"1.0\\\" encoding=\\\"utf-8\\\"?>\\n\\r\",\n        \"<soap:Envelope xmlns:xsi=\\\"http://www.w3.org/2001/XMLSchema-instance\\\" xmlns:xsd=\\\"http://www.w3.org/2001/XMLSchema\\\" xmlns:soap=\\\"http://schemas.xmlsoap.org/soap/envelope/\\\">\\n\\r\",\n        \"  <soap:Body>\\n\\r\",\n        \"  <EnlightenResponse xmlns=\\\"http://clearforest.com/\\\">\\n\\r\",\n        \"  <EnlightenResult>string</EnlightenResult>\\n\\r\",\n        \"  </EnlightenResponse>\\n\\r\",\n        \"  </soap:Body>\\n\\r\",\n        \"</soap:Envelope>\\n\\r\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120\\\" \\\\(Variable: TX:something\\\\)\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule REQUEST_HEADERS \\\"@contains PHPSESSID\\\" \\\"id:1,t:lowercase,t:none,setvar:TX.something=%{REQUEST_HEADERS:Cookie}%\\\"\",\n      \"SecRule TX \\\"@contains to_test\\\" \\\"id:2,t:lowercase,t:none\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"version_max\": 0,\n    \"title\": \"Testing collection :: TX (with macro) (2/4)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 2313\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"User-Agent\": \"Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)\",\n        \"Accept\": \"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\",\n        \"Accept-Language\": \"en-us,en;q=0.5\",\n        \"Accept-Encoding\": \"gzip,deflate\",\n        \"Accept-Charset\": \"ISO-8859-1,utf-8;q=0.7,*;q=0.7\",\n        \"Keep-Alive\": \"300\",\n        \"Connection\": \"keep-alive\",\n        \"Cookie\": \"PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120\",\n        \"Pragma\": \"no-cache\",\n        \"Cache-Control\": \"no-cache\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/test.pl?param1=   test   &param2=test2\",\n      \"method\": \"GET\",\n      \"http_version\": 1.1,\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Type\": \"text/xml; charset=utf-8\\n\\r\",\n        \"Content-Length\": \"384\"\n      },\n      \"body\": [\n        \"<?xml version=\\\"1.0\\\" encoding=\\\"utf-8\\\"?>\\n\\r\",\n        \"<soap:Envelope xmlns:xsi=\\\"http://www.w3.org/2001/XMLSchema-instance\\\" xmlns:xsd=\\\"http://www.w3.org/2001/XMLSchema\\\" xmlns:soap=\\\"http://schemas.xmlsoap.org/soap/envelope/\\\">\\n\\r\",\n        \"  <soap:Body>\\n\\r\",\n        \"  <EnlightenResponse xmlns=\\\"http://clearforest.com/\\\">\\n\\r\",\n        \"  <EnlightenResult>string</EnlightenResult>\\n\\r\",\n        \"  </EnlightenResponse>\\n\\r\",\n        \"  </soap:Body>\\n\\r\",\n        \"</soap:Envelope>\\n\\r\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"1\\\" \\\\(Variable: TX:somethingPHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120\\\\)\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule REQUEST_HEADERS \\\"@contains PHPSESSID\\\" \\\"id:1,t:lowercase,t:none,setvar:TX.something%{REQUEST_HEADERS:Cookie}%\\\"\",\n      \"SecRule TX \\\"@contains to_test\\\" \\\"id:2,t:lowercase,t:none\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"version_max\": 0,\n    \"title\": \"Testing collection :: TX (with macro) (3/4)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 2313\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"User-Agent\": \"Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)\",\n        \"Accept\": \"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\",\n        \"Accept-Language\": \"en-us,en;q=0.5\",\n        \"Accept-Encoding\": \"gzip,deflate\",\n        \"Accept-Charset\": \"ISO-8859-1,utf-8;q=0.7,*;q=0.7\",\n        \"Keep-Alive\": \"300\",\n        \"Connection\": \"keep-alive\",\n        \"Cookie\": \"PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120\",\n        \"Pragma\": \"no-cache\",\n        \"Cache-Control\": \"no-cache\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/test.pl?param1=   test   &param2=test2\",\n      \"method\": \"GET\",\n      \"http_version\": 1.1,\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Type\": \"text/xml; charset=utf-8\\n\\r\",\n        \"Content-Length\": \"384\"\n      },\n      \"body\": [\n        \"<?xml version=\\\"1.0\\\" encoding=\\\"utf-8\\\"?>\\n\\r\",\n        \"<soap:Envelope xmlns:xsi=\\\"http://www.w3.org/2001/XMLSchema-instance\\\" xmlns:xsd=\\\"http://www.w3.org/2001/XMLSchema\\\" xmlns:soap=\\\"http://schemas.xmlsoap.org/soap/envelope/\\\">\\n\\r\",\n        \"  <soap:Body>\\n\\r\",\n        \"  <EnlightenResponse xmlns=\\\"http://clearforest.com/\\\">\\n\\r\",\n        \"  <EnlightenResult>string</EnlightenResult>\\n\\r\",\n        \"  </EnlightenResponse>\\n\\r\",\n        \"  </soap:Body>\\n\\r\",\n        \"</soap:Envelope>\\n\\r\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"310\\\" \\\\(Variable: TX:something\\\\)\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule REQUEST_HEADERS \\\"@contains PHPSESSID\\\" \\\"id:1,t:lowercase,t:none,setvar:TX.something=%{REQUEST_HEADERS:Keep-Alive}%\\\"\",\n      \"SecRule REQUEST_HEADERS \\\"@contains PHPSESSID\\\" \\\"id:2,t:lowercase,t:none,setvar:TX.something=+10\\\"\",\n      \"SecRule TX \\\"@contains to_test\\\" \\\"id:3,t:lowercase,t:none\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"version_max\": 0,\n    \"title\": \"Testing collection :: TX (with macro) (4/4)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 2313\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"User-Agent\": \"Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)\",\n        \"Accept\": \"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\",\n        \"Accept-Language\": \"en-us,en;q=0.5\",\n        \"Accept-Encoding\": \"gzip,deflate\",\n        \"Accept-Charset\": \"ISO-8859-1,utf-8;q=0.7,*;q=0.7\",\n        \"Keep-Alive\": \"300\",\n        \"Connection\": \"keep-alive\",\n        \"Cookie\": \"PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120\",\n        \"Pragma\": \"no-cache\",\n        \"Cache-Control\": \"no-cache\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/test.pl?param1=   test   &param2=test2\",\n      \"method\": \"GET\",\n      \"http_version\": 1.1,\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Type\": \"text/xml; charset=utf-8\\n\\r\",\n        \"Content-Length\": \"384\"\n      },\n      \"body\": [\n        \"<?xml version=\\\"1.0\\\" encoding=\\\"utf-8\\\"?>\\n\\r\",\n        \"<soap:Envelope xmlns:xsi=\\\"http://www.w3.org/2001/XMLSchema-instance\\\" xmlns:xsd=\\\"http://www.w3.org/2001/XMLSchema\\\" xmlns:soap=\\\"http://schemas.xmlsoap.org/soap/envelope/\\\">\\n\\r\",\n        \"  <soap:Body>\\n\\r\",\n        \"  <EnlightenResponse xmlns=\\\"http://clearforest.com/\\\">\\n\\r\",\n        \"  <EnlightenResult>string</EnlightenResult>\\n\\r\",\n        \"  </EnlightenResponse>\\n\\r\",\n        \"  </soap:Body>\\n\\r\",\n        \"</soap:Envelope>\\n\\r\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"5\\\" \\\\(Variable: TX:something_else\\\\)\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule REQUEST_HEADERS \\\"@contains PHPSESSID\\\" \\\"id:1,t:lowercase,t:none,setvar:TX.something=+10\\\"\",\n      \"SecRule REQUEST_HEADERS \\\"@contains PHPSESSID\\\" \\\"id:2,t:lowercase,t:none,setvar:TX.something_else=%{tx.something}%\\\"\",\n      \"SecRule REQUEST_HEADERS \\\"@contains PHPSESSID\\\" \\\"id:3,t:lowercase,t:none,setvar:TX.something_else=-5\\\"\",\n      \"SecRule TX:something_else \\\"@contains to_test\\\" \\\"id:4,t:lowercase,t:none\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/collection-tx.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"version_max\": 0,\n    \"title\": \"Collection :: TX full vs partial match\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 2313\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"User-Agent\": \"Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"GET\",\n      \"http_version\": 1.1,\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Type\": \"text/xml; charset=utf-8\\n\",\n        \"Content-Length\": \"39\"\n      },\n      \"body\": [\n        \"<?xml version=\\\"1.0\\\" encoding=\\\"utf-8\\\"?>\\n\"\n      ]\n    },\n    \"expected\": {\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule REMOTE_ADDR \\\"@unconditionalMatch\\\" \\\"id:1,deny,setvar:TX.partial_match=1,chain\\\"\",\n      \"SecRule TX.partial \\\"@gt 0\\\" \\\"id:2,t:lowercase,t:none,status:444\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"version_max\": 0,\n    \"title\": \"Testing collection :: TX (1/4)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 2313\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"User-Agent\": \"Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)\",\n        \"Accept\": \"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\",\n        \"Accept-Language\": \"en-us,en;q=0.5\",\n        \"Accept-Encoding\": \"gzip,deflate\",\n        \"Accept-Charset\": \"ISO-8859-1,utf-8;q=0.7,*;q=0.7\",\n        \"Keep-Alive\": \"300\",\n        \"Connection\": \"keep-alive\",\n        \"Cookie\": \"PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120\",\n        \"Pragma\": \"no-cache\",\n        \"Cache-Control\": \"no-cache\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/test.pl?param1=   test   &param2=test2\",\n      \"method\": \"GET\",\n      \"http_version\": 1.1,\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Type\": \"text/xml; charset=utf-8\\n\\r\",\n        \"Content-Length\": \"384\"\n      },\n      \"body\": [\n        \"<?xml version=\\\"1.0\\\" encoding=\\\"utf-8\\\"?>\\n\\r\",\n        \"<soap:Envelope xmlns:xsi=\\\"http://www.w3.org/2001/XMLSchema-instance\\\" xmlns:xsd=\\\"http://www.w3.org/2001/XMLSchema\\\" xmlns:soap=\\\"http://schemas.xmlsoap.org/soap/envelope/\\\">\\n\\r\",\n        \"  <soap:Body>\\n\\r\",\n        \"  <EnlightenResponse xmlns=\\\"http://clearforest.com/\\\">\\n\\r\",\n        \"  <EnlightenResult>string</EnlightenResult>\\n\\r\",\n        \"  </EnlightenResponse>\\n\\r\",\n        \"  </soap:Body>\\n\\r\",\n        \"</soap:Envelope>\\n\\r\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"to_test\\\" \\\\(Variable: TX:something\\\\)\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule REQUEST_HEADERS \\\"@contains PHPSESSID\\\" \\\"id:1,t:lowercase,t:none,setvar:TX.something=to_test\\\"\",\n      \"SecRule TX \\\"@contains to_test\\\" \\\"id:2,t:lowercase,t:none\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"version_max\": 0,\n    \"title\": \"Testing collection :: TX (2/4)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 2313\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"User-Agent\": \"Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)\",\n        \"Accept\": \"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\",\n        \"Accept-Language\": \"en-us,en;q=0.5\",\n        \"Accept-Encoding\": \"gzip,deflate\",\n        \"Accept-Charset\": \"ISO-8859-1,utf-8;q=0.7,*;q=0.7\",\n        \"Keep-Alive\": \"300\",\n        \"Connection\": \"keep-alive\",\n        \"Cookie\": \"PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120\",\n        \"Pragma\": \"no-cache\",\n        \"Cache-Control\": \"no-cache\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/test.pl?param1=   test   &param2=test2\",\n      \"method\": \"GET\",\n      \"http_version\": 1.1,\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Type\": \"text/xml; charset=utf-8\\n\\r\",\n        \"Content-Length\": \"384\"\n      },\n      \"body\": [\n        \"<?xml version=\\\"1.0\\\" encoding=\\\"utf-8\\\"?>\\n\\r\",\n        \"<soap:Envelope xmlns:xsi=\\\"http://www.w3.org/2001/XMLSchema-instance\\\" xmlns:xsd=\\\"http://www.w3.org/2001/XMLSchema\\\" xmlns:soap=\\\"http://schemas.xmlsoap.org/soap/envelope/\\\">\\n\\r\",\n        \"  <soap:Body>\\n\\r\",\n        \"  <EnlightenResponse xmlns=\\\"http://clearforest.com/\\\">\\n\\r\",\n        \"  <EnlightenResult>string</EnlightenResult>\\n\\r\",\n        \"  </EnlightenResponse>\\n\\r\",\n        \"  </soap:Body>\\n\\r\",\n        \"</soap:Envelope>\\n\\r\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"1\\\" \\\\(Variable: TX:something\\\\)\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule REQUEST_HEADERS \\\"@contains PHPSESSID\\\" \\\"id:1,t:lowercase,t:none,setvar:TX.something\\\"\",\n      \"SecRule TX \\\"@contains to_test\\\" \\\"id:2,t:lowercase,t:none\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"version_max\": 0,\n    \"title\": \"Testing collection :: TX (3/4)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 2313\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"User-Agent\": \"Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)\",\n        \"Accept\": \"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\",\n        \"Accept-Language\": \"en-us,en;q=0.5\",\n        \"Accept-Encoding\": \"gzip,deflate\",\n        \"Accept-Charset\": \"ISO-8859-1,utf-8;q=0.7,*;q=0.7\",\n        \"Keep-Alive\": \"300\",\n        \"Connection\": \"keep-alive\",\n        \"Cookie\": \"PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120\",\n        \"Pragma\": \"no-cache\",\n        \"Cache-Control\": \"no-cache\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/test.pl?param1=   test   &param2=test2\",\n      \"method\": \"GET\",\n      \"http_version\": 1.1,\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Type\": \"text/xml; charset=utf-8\\n\\r\",\n        \"Content-Length\": \"384\"\n      },\n      \"body\": [\n        \"<?xml version=\\\"1.0\\\" encoding=\\\"utf-8\\\"?>\\n\\r\",\n        \"<soap:Envelope xmlns:xsi=\\\"http://www.w3.org/2001/XMLSchema-instance\\\" xmlns:xsd=\\\"http://www.w3.org/2001/XMLSchema\\\" xmlns:soap=\\\"http://schemas.xmlsoap.org/soap/envelope/\\\">\\n\\r\",\n        \"  <soap:Body>\\n\\r\",\n        \"  <EnlightenResponse xmlns=\\\"http://clearforest.com/\\\">\\n\\r\",\n        \"  <EnlightenResult>string</EnlightenResult>\\n\\r\",\n        \"  </EnlightenResponse>\\n\\r\",\n        \"  </soap:Body>\\n\\r\",\n        \"</soap:Envelope>\\n\\r\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"20\\\" \\\\(Variable: TX:something\\\\)\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule REQUEST_HEADERS \\\"@contains PHPSESSID\\\" \\\"id:1,t:lowercase,t:none,setvar:TX.something=+10\\\"\",\n      \"SecRule REQUEST_HEADERS \\\"@contains PHPSESSID\\\" \\\"id:2,t:lowercase,t:none,setvar:TX.something=+10\\\"\",\n      \"SecRule TX \\\"@contains to_test\\\" \\\"id:3,t:lowercase,t:none\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"version_max\": 0,\n    \"title\": \"Testing collection :: TX (4/4)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 2313\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"User-Agent\": \"Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)\",\n        \"Accept\": \"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\",\n        \"Accept-Language\": \"en-us,en;q=0.5\",\n        \"Accept-Encoding\": \"gzip,deflate\",\n        \"Accept-Charset\": \"ISO-8859-1,utf-8;q=0.7,*;q=0.7\",\n        \"Keep-Alive\": \"300\",\n        \"Connection\": \"keep-alive\",\n        \"Cookie\": \"PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120\",\n        \"Pragma\": \"no-cache\",\n        \"Cache-Control\": \"no-cache\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/test.pl?param1=   test   &param2=test2\",\n      \"method\": \"GET\",\n      \"http_version\": 1.1,\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Type\": \"text/xml; charset=utf-8\\n\\r\",\n        \"Content-Length\": \"384\"\n      },\n      \"body\": [\n        \"<?xml version=\\\"1.0\\\" encoding=\\\"utf-8\\\"?>\\n\\r\",\n        \"<soap:Envelope xmlns:xsi=\\\"http://www.w3.org/2001/XMLSchema-instance\\\" xmlns:xsd=\\\"http://www.w3.org/2001/XMLSchema\\\" xmlns:soap=\\\"http://schemas.xmlsoap.org/soap/envelope/\\\">\\n\\r\",\n        \"  <soap:Body>\\n\\r\",\n        \"  <EnlightenResponse xmlns=\\\"http://clearforest.com/\\\">\\n\\r\",\n        \"  <EnlightenResult>string</EnlightenResult>\\n\\r\",\n        \"  </EnlightenResponse>\\n\\r\",\n        \"  </soap:Body>\\n\\r\",\n        \"</soap:Envelope>\\n\\r\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"15\\\" \\\\(Variable: TX:something\\\\)\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule REQUEST_HEADERS \\\"@contains PHPSESSID\\\" \\\"id:1,t:lowercase,t:none,setvar:TX.something=+10\\\"\",\n      \"SecRule REQUEST_HEADERS \\\"@contains PHPSESSID\\\" \\\"id:2,t:lowercase,t:none,setvar:TX.something=+10\\\"\",\n      \"SecRule REQUEST_HEADERS \\\"@contains PHPSESSID\\\" \\\"id:3,t:lowercase,t:none,setvar:TX.something=-5\\\"\",\n      \"SecRule TX \\\"@contains to_test\\\" \\\"id:4,t:lowercase,t:none\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"version_max\": 0,\n    \"title\": \"Testing collection :: TX (5/n)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 2313\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"User-Agent\": \"Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)\",\n        \"Accept\": \"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\",\n        \"Accept-Language\": \"en-us,en;q=0.5\",\n        \"Accept-Encoding\": \"gzip,deflate\",\n        \"Accept-Charset\": \"ISO-8859-1,utf-8;q=0.7,*;q=0.7\",\n        \"Keep-Alive\": \"300\",\n        \"Connection\": \"keep-alive\",\n        \"Cookie\": \"PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120 - cookie I\",\n        \"Cookie2\": \"PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120 - cookie II\",\n        \"Pragma\": \"no-cache\",\n        \"Cache-Control\": \"no-cache\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/test.pl?param1=   test   &param2=test2\",\n      \"method\": \"GET\",\n      \"http_version\": 1.1,\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Type\": \"text/xml; charset=utf-8\\n\\r\",\n        \"Content-Length\": \"384\"\n      },\n      \"body\": [\n        \"<?xml version=\\\"1.0\\\" encoding=\\\"utf-8\\\"?>\\n\\r\",\n        \"<soap:Envelope xmlns:xsi=\\\"http://www.w3.org/2001/XMLSchema-instance\\\" xmlns:xsd=\\\"http://www.w3.org/2001/XMLSchema\\\" xmlns:soap=\\\"http://schemas.xmlsoap.org/soap/envelope/\\\">\\n\\r\",\n        \"  <soap:Body>\\n\\r\",\n        \"  <EnlightenResponse xmlns=\\\"http://clearforest.com/\\\">\\n\\r\",\n        \"  <EnlightenResult>string</EnlightenResult>\\n\\r\",\n        \"  </EnlightenResponse>\\n\\r\",\n        \"  </soap:Body>\\n\\r\",\n        \"</soap:Envelope>\\n\\r\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"40\\\" \\\\(Variable: TX:anomaly_score\\\\)\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule REQUEST_HEADERS:Cookie \\\"@contains PHPSESSID\\\" \\\"id:1,setvar:tx.critical_anomaly_score=5\\\"\",\n      \"SecRule REQUEST_HEADERS:Cookie \\\"@contains PHPSESSID\\\" \\\"id:2,setvar:tx.anomaly_score=10\\\"\",\n      \"SecRule REQUEST_HEADERS:Cookie|REQUEST_HEADERS:Cookie2 \\\"@contains ookie\\\" \\\"id:4,t:lowercase,t:removewhitespace,multimatch,setvar:tx.anomaly_score=+%{tx.critical_anomaly_score}\\\"\",\n      \"SecRule TX \\\"@contains to_test\\\" \\\"id:100\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/config-body_limits.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"SecResponseBodyLimitAction Reject\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?key=value&key=other_value\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"http_code\": 403\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecResponseBodyLimitAction Reject\",\n      \"SecResponseBodyLimit 5\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"SecResponseBodyLimitAction ProcessPartial\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?key=value&key=other_value\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecResponseBodyLimitAction ProcessPartial\",\n      \"SecResponseBodyLimit 5\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"SecRequestBodyLimitAction Reject\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Type\": \"multipart/form-data; boundary=------------------------756b6d74fa1a8ee2\",\n        \"Content-Length\": \"523\"\n      },\n      \"uri\": \"/?key=value&key=other_value\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"--------------------------756b6d74fa1a8ee2\\r\\n\",\n        \"Content-Disposition: form-data; name=\\\"name\\\"\\r\\n\",\n        \"\\r\\n\",\n        \"test\\r\\n\",\n        \"--------------------------756b6d74fa1a8ee2\\r\\n\",\n        \"Content-Disposition: form-data; name=\\\"filedata\\\"; filename=\\\"small_text_file.txt\\\"\\r\\n\",\n        \"Content-Type: text/plain\\r\\n\",\n        \"\\r\\n\",\n        \"This is a very small test file..\\r\\n\",\n        \"--------------------------756b6d74fa1a8ee2\\r\\n\",\n        \"Content-Disposition: form-data; name=\\\"filedata\\\"; filename=\\\"small_text_file.txt\\\"\\r\\n\",\n        \"Content-Type: text/plain\\r\\n\",\n        \"\\r\\n\",\n        \"This is another very small test file..\\r\\n\",\n        \"--------------------------756b6d74fa1a8ee2--\\r\\n\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"http_code\": 403\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRequestBodyLimitAction Reject\",\n      \"SecRequestBodyLimit 5\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"SecRequestBodyLimitAction Reject - Engine Disabled\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Type\": \"multipart/form-data; boundary=------------------------756b6d74fa1a8ee2\",\n        \"Content-Length\": \"523\"\n      },\n      \"uri\": \"/?key=value&key=other_value\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"--------------------------756b6d74fa1a8ee2\\r\\n\",\n        \"Content-Disposition: form-data; name=\\\"name\\\"\\r\\n\",\n        \"\\r\\n\",\n        \"test\\r\\n\",\n        \"--------------------------756b6d74fa1a8ee2\\r\\n\",\n        \"Content-Disposition: form-data; name=\\\"filedata\\\"; filename=\\\"small_text_file.txt\\\"\\r\\n\",\n        \"Content-Type: text/plain\\r\\n\",\n        \"\\r\\n\",\n        \"This is a very small test file..\\r\\n\",\n        \"--------------------------756b6d74fa1a8ee2\\r\\n\",\n        \"Content-Disposition: form-data; name=\\\"filedata\\\"; filename=\\\"small_text_file.txt\\\"\\r\\n\",\n        \"Content-Type: text/plain\\r\\n\",\n        \"\\r\\n\",\n        \"This is another very small test file..\\r\\n\",\n        \"--------------------------756b6d74fa1a8ee2--\\r\\n\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine Off\",\n      \"SecRequestBodyLimitAction Reject\",\n      \"SecRequestBodyLimit 5\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"SecRequestBodyLimitAction Reject - Engine Detection Only\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Type\": \"multipart/form-data; boundary=------------------------756b6d74fa1a8ee2\",\n        \"Content-Length\": \"523\"\n      },\n      \"uri\": \"/?key=value&key=other_value\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"--------------------------756b6d74fa1a8ee2\\r\\n\",\n        \"Content-Disposition: form-data; name=\\\"name\\\"\\r\\n\",\n        \"\\r\\n\",\n        \"test\\r\\n\",\n        \"--------------------------756b6d74fa1a8ee2\\r\\n\",\n        \"Content-Disposition: form-data; name=\\\"filedata\\\"; filename=\\\"small_text_file.txt\\\"\\r\\n\",\n        \"Content-Type: text/plain\\r\\n\",\n        \"\\r\\n\",\n        \"This is a very small test file..\\r\\n\",\n        \"--------------------------756b6d74fa1a8ee2\\r\\n\",\n        \"Content-Disposition: form-data; name=\\\"filedata\\\"; filename=\\\"small_text_file.txt\\\"\\r\\n\",\n        \"Content-Type: text/plain\\r\\n\",\n        \"\\r\\n\",\n        \"This is another very small test file..\\r\\n\",\n        \"--------------------------756b6d74fa1a8ee2--\\r\\n\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine DetectionOnly\",\n      \"SecRequestBodyLimitAction Reject\",\n      \"SecRequestBodyLimit 5\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"SecRequestBodyLimitAction ProcessPartial\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Content-Type\": \"multipart/form-data; boundary=------------------------756b6d74fa1a8ee2\",\n        \"Content-Length\": \"523\"\n      },\n      \"uri\": \"/?key=value&key=other_value\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"--------------------------756b6d74fa1a8ee2\\r\\n\",\n        \"Content-Disposition: form-data; name=\\\"name\\\"\\r\\n\",\n        \"\\r\\n\",\n        \"test\\r\\n\",\n        \"--------------------------756b6d74fa1a8ee2\\r\\n\",\n        \"Content-Disposition: form-data; name=\\\"filedata\\\"; filename=\\\"small_text_file.txt\\\"\\r\\n\",\n        \"Content-Type: text/plain\\r\\n\",\n        \"\\r\\n\",\n        \"This is a very small test file..\\r\\n\",\n        \"--------------------------756b6d74fa1a8ee2\\r\\n\",\n        \"Content-Disposition: form-data; name=\\\"filedata\\\"; filename=\\\"small_text_file.txt\\\"\\r\\n\",\n        \"Content-Type: text/plain\\r\\n\",\n        \"\\r\\n\",\n        \"This is another very small test file..\\r\\n\",\n        \"--------------------------756b6d74fa1a8ee2--\\r\\n\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRequestBodyLimitAction ProcessPartial\",\n      \"SecRequestBodyLimit 5\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"SecResponseBodyLimitAction Reject - Engine Disabled\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?key=value&key=other_value\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine Off\",\n      \"SecResponseBodyLimitAction Reject\",\n      \"SecResponseBodyLimit 5\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"SecResponseBodyLimitAction Reject - Engine Detection Only\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?key=value&key=other_value\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine DetectionOnly\",\n      \"SecResponseBodyLimitAction Reject\",\n      \"SecResponseBodyLimit 5\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"SecRequestBodyNoFilesLimit - urlencoded, limit exceeded\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"41\",\n        \"Content-Type\": \"application/x-www-form-urlencoded\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"param1=value1&param2=value2&param3=value3\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Request body excluding files is bigger than the maximum expected.\",\n      \"http_code\": 400\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRequestBodyAccess On\",\n      \"SecRequestBodyNoFilesLimit 20\",\n      \"SecRule REQBODY_ERROR \\\"!@eq 0\\\" \\\"id:'200002', phase:2,t:none,log,deny,status:400,msg:'Failed to parse request body.',logdata:'%{reqbody_error_msg}',severity:2\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"SecRequestBodyNoFilesLimit - urlencoded, limit not exceeded\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"41\",\n        \"Content-Type\": \"application/x-www-form-urlencoded\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"param1=value1&param2=value2&param3=value3\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRequestBodyAccess On\",\n      \"SecRequestBodyNoFilesLimit 60\",\n      \"SecRule REQBODY_ERROR \\\"!@eq 0\\\" \\\"id:'200002', phase:2,t:none,log,deny,status:400,msg:'Failed to parse request body.',logdata:'%{reqbody_error_msg}',severity:2\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"SecRequestBodyNoFilesLimit - json, limit exceeded\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"48\",\n        \"Content-Type\": \"application/json\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"{\\\"param1\\\":{\\\"param2\\\":\\\"value2\\\",\\\"param3\\\":\\\"value3\\\"}}\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Request body excluding files is bigger than the maximum expected.\",\n      \"http_code\": 400\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRequestBodyAccess On\",\n      \"SecRequestBodyNoFilesLimit 20\",\n      \"SecRule REQUEST_HEADERS:Content-Type \\\"application/json\\\" \\\"id:'200001',phase:1,t:none,t:lowercase,pass,nolog,ctl:requestBodyProcessor=JSON\\\"\",\n      \"SecRule REQBODY_ERROR \\\"!@eq 0\\\" \\\"id:'200002', phase:2,t:none,log,deny,status:400,msg:'Failed to parse request body.',logdata:'%{reqbody_error_msg}',severity:2\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"SecRequestBodyNoFilesLimit - json, limit not exceeded\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"48\",\n        \"Content-Type\": \"application/json\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"{\\\"param1\\\":{\\\"param2\\\":\\\"value2\\\",\\\"param3\\\":\\\"value3\\\"}}\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRequestBodyAccess On\",\n      \"SecRequestBodyNoFilesLimit 80\",\n      \"SecRule REQUEST_HEADERS:Content-Type \\\"application/json\\\" \\\"id:'200001',phase:1,t:none,t:lowercase,pass,nolog,ctl:requestBodyProcessor=JSON\\\"\",\n      \"SecRule REQBODY_ERROR \\\"!@eq 0\\\" \\\"id:'200002', phase:2,t:none,log,deny,status:400,msg:'Failed to parse request body.',logdata:'%{reqbody_error_msg}',severity:2\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"SecRequestBodyNoFilesLimit - xml, limit exceeded\",\n    \"resource\": \"libxml2\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"77\",\n        \"Content-Type\": \"application/xml\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"<?xml version=\\\"1.0\\\" encoding=\\\"UTF-8\\\"?><aaa><bbb>ccc</bbb><ddd>eee</ddd></aaa>\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Request body excluding files is bigger than the maximum expected.\",\n      \"http_code\": 400\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRequestBodyAccess On\",\n      \"SecRequestBodyNoFilesLimit 20\",\n      \"SecRule REQUEST_HEADERS:Content-Type \\\"(?:application(?:/soap\\\\+|/)|text/)xml\\\" \\\"id:'200000',phase:1,t:none,t:lowercase,pass,nolog,ctl:requestBodyProcessor=XML\\\"\",\n      \"SecRule REQBODY_ERROR \\\"!@eq 0\\\" \\\"id:'200002', phase:2,t:none,log,deny,status:400,msg:'Failed to parse request body.',logdata:'%{reqbody_error_msg}',severity:2\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"SecRequestBodyNoFilesLimit - xml, limit not exceeded\",\n    \"resource\": \"libxml2\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"77\",\n        \"Content-Type\": \"application/xml\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"<?xml version=\\\"1.0\\\" encoding=\\\"UTF-8\\\"?><aaa><bbb>ccc</bbb><ddd>eee</ddd></aaa>\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRequestBodyAccess On\",\n      \"SecRequestBodyNoFilesLimit 90\",\n      \"SecRule REQUEST_HEADERS:Content-Type \\\"(?:application(?:/soap\\\\+|/)|text/)xml\\\" \\\"id:'200000',phase:1,t:none,t:lowercase,pass,nolog,ctl:requestBodyProcessor=XML\\\"\",\n      \"SecRule REQBODY_ERROR \\\"!@eq 0\\\" \\\"id:'200002', phase:2,t:none,log,deny,status:400,msg:'Failed to parse request body.',logdata:'%{reqbody_error_msg}',severity:2\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"SecRequestBodyNoFilesLimit - multipart, limit exceeded\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"198\",\n        \"Content-Type\": \"multipart/form-data; boundary=0000\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"--0000\\n\",\n        \"Content-Disposition: form-data; name=\\\"a\\\"\\n\",\n        \"\\n\",\n        \"1\\n\",\n        \"--0000\\n\",\n        \"Content-Disposition: form-data; name=\\\"b\\\"; filename=\\\"c.txt\\\"\\n\",\n        \"\\n\",\n        \"2222222222222222222222222222222222222222222222222222222222222222222222\\n\",\n        \"--0000--\\n\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Request body excluding files is bigger than the maximum expected.\",\n      \"http_code\": 400\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRequestBodyAccess On\",\n      \"SecRequestBodyNoFilesLimit 80\",\n      \"SecRule REQBODY_ERROR \\\"!@eq 0\\\" \\\"id:'200002', phase:2,t:none,log,deny,status:400,msg:'Failed to parse request body.',logdata:'%{reqbody_error_msg}',severity:2\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"SecRequestBodyNoFilesLimit - multipart, limit not exceeded\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"198\",\n        \"Content-Type\": \"multipart/form-data; boundary=0000\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"--0000\\n\",\n        \"Content-Disposition: form-data; name=\\\"a\\\"\\n\",\n        \"\\n\",\n        \"1\\n\",\n        \"--0000\\n\",\n        \"Content-Disposition: form-data; name=\\\"b\\\"; filename=\\\"c.txt\\\"\\n\",\n        \"\\n\",\n        \"2222222222222222222222222222222222222222222222222222222222222222222222\\n\",\n        \"--0000--\\n\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRequestBodyAccess On\",\n      \"SecRequestBodyNoFilesLimit 120\",\n      \"SecRule REQBODY_ERROR \\\"!@eq 0\\\" \\\"id:'200002', phase:2,t:none,log,deny,status:400,msg:'Failed to parse request body.',logdata:'%{reqbody_error_msg}',severity:2\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/config-calling_phases_by_name.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Config :: Phases by name (1/2)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?key=value&key=other_value\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"other_value\\\" \\\\(Variable: MATCHED_VAR\\\\)\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule ARGS:key \\\"@contains other_value\\\" \\\"id:1,phase:request,pass,chain\\\"\",\n      \"SecRule MATCHED_VAR \\\"@contains asdf\\\" \\\"\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Config :: Phases by name (2/2)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?key=value&key=other_value\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"other_value\\\" \\\\(Variable: MATCHED_VAR\\\\)\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule ARGS:key \\\"@contains other_value\\\" \\\"chain,pass,phase:response,id:28\\\"\",\n      \"SecRule MATCHED_VAR \\\"@contains Aasdf\\\" \\\"\\\"\",\n      \"SecResponseBodyAccess On\",\n      \"SecRule MATCHED_VAR \\\"@contains other_value\\\" \\\"id:29,phase:response,pass\\\"\",\n      \"SecRule MATCHED_VAR \\\"@contains other_value\\\" \\\"id:30,phase:response,pass\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/config-include-bad.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Include - bad rule\",\n    \"client\": {\n      \"ip\": \"\",\n      \"port\": 0\n    },\n    \"server\": {\n      \"ip\": \"\",\n      \"port\": 0\n    },\n    \"request\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"\",\n      \"method\": \"\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"http_code\": 200,\n      \"parser_error\": \"Rules error. File: test-cases/data/config_example3.txt. Line: 2. Column: 66. Expecting an action, got:  ops \\\"id:1000,pass,t:trim\\\"\"\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"Include test-cases/data/config_example3.txt\",\n      \"SecRule ARGS \\\"@missing_operator test\\\" \\\"id:19,pass,t:trim\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Include - missing file\",\n    \"client\": {\n      \"ip\": \"\",\n      \"port\": 0\n    },\n    \"server\": {\n      \"ip\": \"\",\n      \"port\": 0\n    },\n    \"request\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"\",\n      \"method\": \"\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"http_code\": 200,\n      \"parser_error\": \"Rules error. File: config-include-bad.json. Line: 2. Column: 46. test-cases/data/config_example-ops.txt: Not able to open file.\"\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"Include test-cases/data/config_example-ops.txt\",\n      \"SecRule ARGS \\\"@contains test\\\" \\\"id:19,pass,t:trim\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Include - missing at include\",\n    \"client\": {\n      \"ip\": \"\",\n      \"port\": 0\n    },\n    \"server\": {\n      \"ip\": \"\",\n      \"port\": 0\n    },\n    \"request\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"\",\n      \"method\": \"\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"http_code\": 200,\n      \"parser_error\": \"Rules error. File: test-cases/data/config_example-ops-include.txt. Line: 1. Column: 52. test-cases/data/config_example-not-exist.txt: Not able to open file.\"\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"Include test-cases/data/config_example-ops-include.txt\",\n      \"SecRule ARGS \\\"@contains test\\\" \\\"id:19,pass,t:trim\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Include - duplicate id\",\n    \"client\": {\n      \"ip\": \"\",\n      \"port\": 0\n    },\n    \"server\": {\n      \"ip\": \"\",\n      \"port\": 0\n    },\n    \"request\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"\",\n      \"method\": \"\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"http_code\": 200,\n      \"parser_error\": \"Rule id: 40 is duplicated\"\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"Include test-cases/data/config_example.txt\",\n      \"Include test-cases/data/config_example.txt\",\n      \"SecRule ARGS \\\"@missing_operator test\\\" \\\"id:19,pass,t:trim\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/config-include.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Include (1/8)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?key=value&key=other_value\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Executing operator \\\"Contains\\\" with param \\\"config_example2\\\" against ARGS.\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"Include test-cases/data/config_example2.txt\",\n      \"SecRule ARGS \\\"@contains test\\\" \\\"id:9,pass,t:trim\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Include (2/8)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?key=value&key=other_value\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Executing operator \\\"Contains\\\" with param \\\"config_example\\\" against ARGS.\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"Include test-cases/data/config_example.txt\",\n      \"SecRule ARGS \\\"@contains test\\\" \\\"id:9,pass,t:trim\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Include (3/8)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?key=value&key=other_value\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Executing operator \\\"Contains\\\" with param \\\"config_example2\\\" against ARGS.\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"Include test-cases/data/config_example2.txt\",\n      \"SecRule ARGS \\\"@contains test\\\" \\\"id:9,pass,t:trim\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Include (4/8)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?key=value&key=other_value\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Executing operator \\\"Contains\\\" with param \\\"test\\\" against ARGS.\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule ARGS \\\"@contains test\\\" \\\"id:9,pass,t:trim\\\"\",\n      \"Include test-cases/data/config_example2.txt\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Include (5/8)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?key=value&key=other_value\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Executing operator \\\"Contains\\\" with param \\\"config_example2\\\" against ARGS.\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule ARGS \\\"@contains test\\\" \\\"id:1,pass,t:trim\\\"\",\n      \"Include test-cases/data/config_example.txt\",\n      \"SecRule ARGS \\\"@contains test\\\" \\\"id:3,pass,t:trim\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Include (6/8)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?key=value&key=other_value\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Executing operator \\\"Contains\\\" with param \\\"test\\\" against ARGS.\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"Include test-cases/data/config_example2.txt\",\n      \"SecRule ARGS \\\"@contains test\\\" \\\"id:9,pass,t:trim\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Include (7/8)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?key=value&key=other_value\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"http_code\": 200,\n      \"parser_error\": \"Looking at: 'test-cases/data/conasdffig_example2.txt'\"\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"Include test-cases/data/conasdffig_example2.txt\",\n      \"SecRule ARGS \\\"@contains test\\\" \\\"id:9,pass,t:trim\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Include (8/8) -- quoted with wildcard\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?key=value&key=other_value\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Executing operator \\\"Contains\\\" with param \\\"config_example2\\\" against ARGS.\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"Include \\\"test-cases/data/config_ex*ple2.txt\\\"\",\n      \"SecRule ARGS \\\"@contains test\\\" \\\"id:9,pass,t:trim\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/config-remove_by_id.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"SecRuleRemoveById (1/3)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?key=value&key=other_value\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Skipped rule id '2'. Removed by an SecRuleRemove directive.\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleRemoveById 2\",\n      \"SecRule ARGS \\\"@contains test\\\" \\\"id:1,pass,t:trim\\\"\",\n      \"SecRule ARGS \\\"@contains test\\\" \\\"id:2,pass,t:trim\\\"\",\n      \"SecRule ARGS \\\"@contains test\\\" \\\"id:3,pass,t:trim\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"SecRuleRemoveById (2/3)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?key=value&key=other_value\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Skipped rule id '2'. Removed by an SecRuleRemove directive.\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleRemoveById 1-3\",\n      \"SecRule ARGS \\\"@contains test\\\" \\\"id:1,pass,t:trim\\\"\",\n      \"SecRule ARGS \\\"@contains test\\\" \\\"id:2,pass,t:trim\\\"\",\n      \"SecRule ARGS \\\"@contains test\\\" \\\"id:3,pass,t:trim\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"SecRuleRemoveById (3/3)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?key=value&key=other_value\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Skipped rule id '2'. Removed by an SecRuleRemove directive.\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleRemoveById 1 2-3\",\n      \"SecRule ARGS \\\"@contains test\\\" \\\"id:1,pass,t:trim\\\"\",\n      \"SecRule ARGS \\\"@contains test\\\" \\\"id:2,pass,t:trim\\\"\",\n      \"SecRule ARGS \\\"@contains test\\\" \\\"id:3,pass,t:trim\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/config-remove_by_msg.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"SecRuleRemoveByMsg (1/2)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?key=value&key=other_value\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Skipped rule id '2'. Removed by a SecRuleRemoveByMsg directive.\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleRemoveByMsg tag123\",\n      \"SecRule ARGS \\\"@contains test\\\" \\\"id:1,pass,t:trim\\\"\",\n      \"SecRule ARGS \\\"@contains test\\\" \\\"id:2,pass,t:trim,msg:'tag123'\\\"\",\n      \"SecRule ARGS \\\"@contains test\\\" \\\"id:3,pass,t:trim\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"SecRuleRemoveByMsg (2/2)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?key=value&key=other_value\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Skipped rule id '3'. Removed by a SecRuleRemoveByMsg directive.\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleRemoveByMsg whee\",\n      \"SecRule ARGS \\\"@contains test\\\" \\\"id:1,pass,t:trim\\\"\",\n      \"SecRule ARGS \\\"@contains test\\\" \\\"id:2,pass,t:trim\\\"\",\n      \"SecRule ARGS \\\"@contains test\\\" \\\"id:3,pass,t:trim,msg:'whee'\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/config-remove_by_tag.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"SecRuleRemoveByTag (1/2)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?key=value&key=other_value\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Skipped rule id '2'. Removed by a SecRuleRemoveByTag directive\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleRemoveByTag tag123\",\n      \"SecRule ARGS \\\"@contains test\\\" \\\"id:1,pass,t:trim\\\"\",\n      \"SecRule ARGS \\\"@contains test\\\" \\\"id:2,pass,t:trim,tag:tag123\\\"\",\n      \"SecRule ARGS \\\"@contains test\\\" \\\"id:3,pass,t:trim\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"SecRuleRemoveByTag (2/2)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?key=value&key=other_value\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Skipped rule id '3'. Removed by a SecRuleRemoveByTag directive.\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleRemoveByTag whee\",\n      \"SecRule ARGS \\\"@contains test\\\" \\\"id:1,pass,t:trim\\\"\",\n      \"SecRule ARGS \\\"@contains test\\\" \\\"id:2,pass,t:trim\\\"\",\n      \"SecRule ARGS \\\"@contains test\\\" \\\"id:3,pass,t:trim,tag:whee\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/config-response_type.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"SecResponseBodyMimeType (1/3)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?key=value&key=other_value\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"T \\\\(0\\\\) t:trim: \\\"no need.\\\"\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecResponseBodyAccess On\",\n      \"SecResponseBodyMimeType text/plain text/html text/xml\",\n      \"SecRule RESPONSE_BODY \\\"@contains RESPONSE_CONTENT_TYPE\\\" \\\"id:9,pass,t:trim,phase:4\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"SecResponseBodyMimeType (2/3)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?key=value&key=other_value\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Response Content-Type is text/html. It is not marked to be inspected.\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecResponseBodyAccess On\",\n      \"SecResponseBodyMimeType application/something\",\n      \"SecRule RESPONSE_BODY \\\"@contains RESPONSE_CONTENT_TYPE\\\" \\\"id:9,pass,t:trim,phase:4\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"SecResponseBodyMimeType (3/3)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?key=value&key=other_value\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Response Content-Type is text/html. It is not marked to be inspected.\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecResponseBodyAccess On\",\n      \"SecResponseBodyMimeType text/plain text/tml text/xml\",\n      \"SecResponseBodyMimeTypesClear\",\n      \"SecRule RESPONSE_BODY \\\"@contains RESPONSE_CONTENT_TYPE\\\" \\\"id:9,pass,t:trim,phase:4\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/config-secdefaultaction.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"version_max\": 0,\n    \"title\": \"Testing action :: SecDefaultAction: supporting transformation\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 2313\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"User-Agent\": \"Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)\",\n        \"Accept\": \"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\",\n        \"Accept-Language\": \"en-us,en;q=0.5\",\n        \"Accept-Encoding\": \"gzip,deflate\",\n        \"Accept-Charset\": \"ISO-8859-1,utf-8;q=0.7,*;q=0.7\",\n        \"Keep-Alive\": \"300\",\n        \"Connection\": \"keep-alive\",\n        \"Cookie\": \"PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120\",\n        \"Pragma\": \"no-cache\",\n        \"Cache-Control\": \"no-cache\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/test.pl?param1=   test   &param2=test2\",\n      \"method\": \"GET\",\n      \"http_version\": 1.1,\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Type\": \"text/xml; charset=utf-8\\n\\r\",\n        \"Content-Length\": \"384\"\n      },\n      \"body\": [\n        \"<?xml version=\\\"1.0\\\" encoding=\\\"utf-8\\\"?>\\n\\r\",\n        \"<soap:Envelope xmlns:xsi=\\\"http://www.w3.org/2001/XMLSchema-instance\\\" xmlns:xsd=\\\"http://www.w3.org/2001/XMLSchema\\\" xmlns:soap=\\\"http://schemas.xmlsoap.org/soap/envelope/\\\">\\n\\r\",\n        \"  <soap:Body>\\n\\r\",\n        \"  <EnlightenResponse xmlns=\\\"http://clearforest.com/\\\">\\n\\r\",\n        \"  <EnlightenResult>string</EnlightenResult>\\n\\r\",\n        \"  </EnlightenResponse>\\n\\r\",\n        \"  </soap:Body>\\n\\r\",\n        \"</soap:Envelope>\\n\\r\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"lowercase: \\\"300\\\"\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecDefaultAction \\\"phase:2,t:lowercase,pass\\\"\",\n      \"SecRule REQUEST_HEADERS \\\"@contains PHPSESSID\\\" \\\"phase:2,id:1,msg:'This is a test, %{REQUEST_HEADERS:Accept}%'\\\"\",\n      \"SecRule TX \\\"@contains to_test\\\" \\\"id:2,t:lowercase,t:none\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"version_max\": 0,\n    \"title\": \"Testing action :: SecDefaultAction: supporting transformation + t:none\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 2313\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"User-Agent\": \"Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)\",\n        \"Accept\": \"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\",\n        \"Accept-Language\": \"en-us,en;q=0.5\",\n        \"Accept-Encoding\": \"gzip,deflate\",\n        \"Accept-Charset\": \"ISO-8859-1,utf-8;q=0.7,*;q=0.7\",\n        \"Keep-Alive\": \"300\",\n        \"Connection\": \"keep-alive\",\n        \"Cookie\": \"PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120\",\n        \"Pragma\": \"no-cache\",\n        \"Cache-Control\": \"no-cache\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/test.pl?param1=   test   &param2=test2\",\n      \"method\": \"GET\",\n      \"http_version\": 1.1,\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Type\": \"text/xml; charset=utf-8\\n\\r\",\n        \"Content-Length\": \"384\"\n      },\n      \"body\": [\n        \"<?xml version=\\\"1.0\\\" encoding=\\\"utf-8\\\"?>\\n\\r\",\n        \"<soap:Envelope xmlns:xsi=\\\"http://www.w3.org/2001/XMLSchema-instance\\\" xmlns:xsd=\\\"http://www.w3.org/2001/XMLSchema\\\" xmlns:soap=\\\"http://schemas.xmlsoap.org/soap/envelope/\\\">\\n\\r\",\n        \"  <soap:Body>\\n\\r\",\n        \"  <EnlightenResponse xmlns=\\\"http://clearforest.com/\\\">\\n\\r\",\n        \"  <EnlightenResult>string</EnlightenResult>\\n\\r\",\n        \"  </EnlightenResponse>\\n\\r\",\n        \"  </soap:Body>\\n\\r\",\n        \"</soap:Envelope>\\n\\r\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \" Target value: \\\"PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120\\\" \",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecDefaultAction \\\"phase:2,t:lowercase,pass\\\"\",\n      \"SecRule REQUEST_HEADERS \\\"@contains PHPSESSID\\\" \\\"t:none,phase:2,id:1,msg:'This is a test, %{REQUEST_HEADERS:Accept}%'\\\"\",\n      \"SecRule TX \\\"@contains to_test\\\" \\\"id:2,t:lowercase,t:none\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"version_max\": 0,\n    \"title\": \"Testing action :: SecDefaultAction: t:none\",\n    \"client\": {\n      \"ip\": \"\",\n      \"port\": 0\n    },\n    \"server\": {\n      \"ip\": \"\",\n      \"port\": 0\n    },\n    \"request\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"\",\n      \"method\": \"\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"http_code\": 200,\n      \"parser_error\": \"The transformation none is not suitable to be part of the SecDefaultActions\"\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecDefaultAction \\\"phase:2,t:none\\\"\",\n      \"SecRule REQUEST_HEADERS \\\"@contains PHPSESSID\\\" \\\"t:none,phase:2,id:1,msg:'This is a test, %{REQUEST_HEADERS:Accept}%'\\\"\",\n      \"SecRule TX \\\"@contains to_test\\\" \\\"id:2,t:lowercase,t:none\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"version_max\": 0,\n    \"title\": \"Testing action :: SecDefaultAction: simple test\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 2313\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"User-Agent\": \"Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)\",\n        \"Accept\": \"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\",\n        \"Accept-Language\": \"en-us,en;q=0.5\",\n        \"Accept-Encoding\": \"gzip,deflate\",\n        \"Accept-Charset\": \"ISO-8859-1,utf-8;q=0.7,*;q=0.7\",\n        \"Keep-Alive\": \"300\",\n        \"Connection\": \"keep-alive\",\n        \"Cookie\": \"PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120\",\n        \"Pragma\": \"no-cache\",\n        \"Cache-Control\": \"no-cache\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/test.pl?param1=   test   &param2=test2\",\n      \"method\": \"GET\",\n      \"http_version\": 1.1,\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Type\": \"text/xml; charset=utf-8\\n\\r\",\n        \"Content-Length\": \"384\"\n      },\n      \"body\": [\n        \"<?xml version=\\\"1.0\\\" encoding=\\\"utf-8\\\"?>\\n\\r\",\n        \"<soap:Envelope xmlns:xsi=\\\"http://www.w3.org/2001/XMLSchema-instance\\\" xmlns:xsd=\\\"http://www.w3.org/2001/XMLSchema\\\" xmlns:soap=\\\"http://schemas.xmlsoap.org/soap/envelope/\\\">\\n\\r\",\n        \"  <soap:Body>\\n\\r\",\n        \"  <EnlightenResponse xmlns=\\\"http://clearforest.com/\\\">\\n\\r\",\n        \"  <EnlightenResult>string</EnlightenResult>\\n\\r\",\n        \"  </EnlightenResponse>\\n\\r\",\n        \"  </soap:Body>\\n\\r\",\n        \"</soap:Envelope>\\n\\r\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Saving msg: This is a test, text/html,application\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecDefaultAction \\\"phase:2,log,auditlog,pass\\\"\",\n      \"SecRule REQUEST_HEADERS \\\"@contains PHPSESSID\\\" \\\"id:1,t:lowercase,t:none,msg:'This is a test, %{REQUEST_HEADERS:Accept}%'\\\"\",\n      \"SecRule TX \\\"@contains to_test\\\" \\\"id:2,t:lowercase,t:none\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"version_max\": 0,\n    \"title\": \"Testing action :: SecDefaultAction: action not suitable\",\n    \"client\": {\n      \"ip\": \"\",\n      \"port\": 0\n    },\n    \"server\": {\n      \"ip\": \"\",\n      \"port\": 0\n    },\n    \"request\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"\",\n      \"method\": \"\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"http_code\": 200,\n      \"parser_error\": \"The action 'id' is not suitable to be part of the SecDefaultActions\"\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecDefaultAction \\\"phase:2,id:1,log,auditlog,pass,tag:'teste'\\\"\",\n      \"SecRule REQUEST_HEADERS \\\"@contains PHPSESSID\\\" \\\"id:1,tag:'teste',t:lowercase,t:none,msg:'This is a test, %{REQUEST_HEADERS:Accept}%'\\\"\",\n      \"SecRule TX \\\"@contains to_test\\\" \\\"id:2,t:lowercase,t:none\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"version_max\": 0,\n    \"title\": \"Testing action :: SecDefaultAction: twice\",\n    \"client\": {\n      \"ip\": \"\",\n      \"port\": 0\n    },\n    \"server\": {\n      \"ip\": \"\",\n      \"port\": 0\n    },\n    \"request\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"\",\n      \"method\": \"\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"http_code\": 200,\n      \"parser_error\": \"SecDefaultActions can only be placed once per phase and configuration context. Phase 2 was informed already.\"\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecDefaultAction \\\"phase:2,log,auditlog,pass,tag:'teste'\\\"\",\n      \"SecDefaultAction \\\"phase:2,log,auditlog,pass,tag:'teste'\\\"\",\n      \"SecRule REQUEST_HEADERS \\\"@contains PHPSESSID\\\" \\\"id:1,tag:'teste',t:lowercase,t:none,msg:'This is a test, %{REQUEST_HEADERS:Accept}%'\\\"\",\n      \"SecRule TX \\\"@contains to_test\\\" \\\"id:2,t:lowercase,t:none\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"version_max\": 0,\n    \"title\": \"Testing action :: SecDefaultAction: status + redirect\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 2313\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"User-Agent\": \"Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)\",\n        \"Accept\": \"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\",\n        \"Accept-Language\": \"en-us,en;q=0.5\",\n        \"Accept-Encoding\": \"gzip,deflate\",\n        \"Accept-Charset\": \"ISO-8859-1,utf-8;q=0.7,*;q=0.7\",\n        \"Keep-Alive\": \"300\",\n        \"Connection\": \"keep-alive\",\n        \"Cookie\": \"PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120\",\n        \"Pragma\": \"no-cache\",\n        \"Cache-Control\": \"no-cache\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/test.pl?param1=   test   &param2=test2\",\n      \"method\": \"GET\",\n      \"http_version\": 1.1,\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Type\": \"text/xml; charset=utf-8\\n\\r\",\n        \"Content-Length\": \"384\"\n      },\n      \"body\": [\n        \"<?xml version=\\\"1.0\\\" encoding=\\\"utf-8\\\"?>\\n\\r\",\n        \"<soap:Envelope xmlns:xsi=\\\"http://www.w3.org/2001/XMLSchema-instance\\\" xmlns:xsd=\\\"http://www.w3.org/2001/XMLSchema\\\" xmlns:soap=\\\"http://schemas.xmlsoap.org/soap/envelope/\\\">\\n\\r\",\n        \"  <soap:Body>\\n\\r\",\n        \"  <EnlightenResponse xmlns=\\\"http://clearforest.com/\\\">\\n\\r\",\n        \"  <EnlightenResult>string</EnlightenResult>\\n\\r\",\n        \"  </EnlightenResponse>\\n\\r\",\n        \"  </soap:Body>\\n\\r\",\n        \"</soap:Envelope>\\n\\r\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Request was relevant to be saved.\",\n      \"http_code\": 302\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecDefaultAction \\\"phase:2,log,auditlog,status:302,redirect:'http://www.google.com'\\\"\",\n      \"SecRule REQUEST_HEADERS \\\"@contains PHPSESSID\\\" \\\"phase:2,id:1,block\\\"\",\n      \"SecRule TX \\\"@contains to_test\\\" \\\"id:2,t:lowercase,t:none,block\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/config-secremoterules.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Include remote rules\",\n    \"resource\": \"curl\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?key=value&key=other_value\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Executing operator \\\"PmFromFile\\\" with param \\\".*\\\" against REQUEST_FILENAME\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRemoteRules key https://raw.githubusercontent.com/owasp-modsecurity/ModSecurity/refs/heads/v3/master/test/modsecurity-regression-rules.txt\",\n      \"SecRule ARGS \\\"@contains somethingelse\\\" \\\"id:9,pass,t:trim\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Include remote rules - failed download (Abort)\",\n    \"resource\": \"curl\",\n    \"client\": {\n      \"ip\": \"\",\n      \"port\": 0\n    },\n    \"server\": {\n      \"ip\": \"\",\n      \"port\": 0\n    },\n    \"request\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"\",\n      \"method\": \"\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"http_code\": 200,\n      \"parser_error\": \"Failed to download\"\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRemoteRulesFailAction Abort\",\n      \"SecRemoteRules key https://gist.githubusercontent.com/zimmerle/a4c1ec028999f7df71d0cc80f4f271ca/raw/4c74363bf4eae974180f1a82007196e58729dd16/modsecurity-regression-test-secremoterules-bonga.txt\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Include remote rules - failed download (Warn)\",\n    \"resource\": \"curl\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?key=value&key=other_value\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Executing operator \\\"Contains\\\" with param \\\"somethingelse\\\" against ARGS.\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRemoteRulesFailAction Warn\",\n      \"SecRemoteRules key https://gist.githubusercontent.com/zimmerle/a4c1ec028999f7df71d0cc80f4f271ca/raw/4c74363bf4eae974180f1a82007196e58729dd16/modsecurity-regression-test-secremoterules-bonga.txt\",\n      \"SecRule ARGS \\\"@contains somethingelse\\\" \\\"id:9,pass,t:trim\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/config-update-action-by-id.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"SecRuleUpdateActionById (1/n)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\",\n        \"Content-Type\": \"application/lhebs\",\n        \"Expect\": \"100-continue\"\n      },\n      \"uri\": \"/a=urlencoded?param1=value1\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Skipped rule id '200005'\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRuleUpdateActionById 200004 \\\"allow\\\"\",\n      \"SecRule ARGS \\\"@contains value1\\\" \\\"phase:3,id:200004,deny\\\"\",\n      \"SecRule ARGS \\\"@contains value1\\\" \\\"phase:3,id:200005,log\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"SecRuleUpdateActionById (2/n)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\",\n        \"Content-Type\": \"application/lhebs\",\n        \"Expect\": \"100-continue\"\n      },\n      \"uri\": \"/a=urlencoded?param1=value1\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"http_code\": 403\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule ARGS \\\"@contains value1\\\" \\\"phase:3,id:200004,deny\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"SecRuleUpdateActionById (3/n)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\",\n        \"Content-Type\": \"application/lhebs\",\n        \"Expect\": \"100-continue\"\n      },\n      \"uri\": \"/a=urlencoded?param1=value1\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Running action: log\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRuleUpdateActionById 200004 \\\"pass\\\"\",\n      \"SecRule ARGS \\\"@contains value1\\\" \\\"phase:3,id:200004,deny\\\"\",\n      \"SecRule ARGS \\\"@contains value1\\\" \\\"phase:3,id:200005,log\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"SecRuleUpdateActionById (4/n)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\",\n        \"Content-Type\": \"application/lhebs\",\n        \"Expect\": \"100-continue\"\n      },\n      \"uri\": \"/a=urlencoded?param1=value1\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Running action: log\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRuleUpdateActionById 200004 \\\"pass\\\"\",\n      \"SecDefaultAction \\\"phase:3,deny\\\"\",\n      \"SecRule ARGS \\\"@contains value1\\\" \\\"phase:3,id:200004,block\\\"\",\n      \"SecRule ARGS \\\"@contains value1\\\" \\\"phase:3,id:200005,log\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"SecRuleUpdateActionById (5/n)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\",\n        \"Content-Type\": \"application/lhebs\",\n        \"Expect\": \"100-continue\"\n      },\n      \"uri\": \"/a=urlencoded?param1=value1\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Dropping the evaluation of upcoming rules in favor of\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRuleUpdateActionById 200004 \\\"allow\\\"\",\n      \"SecDefaultAction \\\"phase:3,deny\\\"\",\n      \"SecRule ARGS \\\"@contains value1\\\" \\\"phase:3,id:200004,block\\\"\",\n      \"SecRule ARGS \\\"@contains value1\\\" \\\"phase:3,id:200005,log\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"SecRuleUpdateActionById (6/n)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\",\n        \"Content-Type\": \"application/lhebs\",\n        \"Expect\": \"100-continue\"\n      },\n      \"uri\": \"/a=urlencoded?param1=value1\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"error_log\": \"Access denied with code 302\",\n      \"http_code\": 302\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRuleUpdateActionById 200004 \\\"redirect:'https://%{request_headers.host}/'\\\"\",\n      \"SecRule ARGS \\\"@contains value1\\\" \\\"phase:3,id:200004,block,deny\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/config-update-target-by-id.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"SecRuleUpdateTargetById - exclude whole collection\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?key=value&key=other_value\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRuleUpdateTargetById 1 !ARGS\",\n      \"SecRule ARGS \\\"@contains value\\\" \\\"id:1,pass,t:trim,tag:'test',deny\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"SecRuleUpdateTargetById - exclude using regex\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?mixpanel=value&mixpanel=other_value\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRuleUpdateTargetById 1 !ARGS:/mixpanel$/\",\n      \"SecRule ARGS \\\"@contains value\\\" \\\"id:1,pass,t:trim,tag:'test',deny\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"SecRuleUpdateTargetById - exclude using full name\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?mixpanel=value\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRuleUpdateTargetById 1 !ARGS:mixpanel\",\n      \"SecRule ARGS \\\"@contains value\\\" \\\"id:1,t:trim,tag:'test',deny\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"SecRuleUpdateTargetById - exclude from ARGS_NAMES using regex (match)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?xxxyyy=value\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRuleUpdateTargetById 1 \\\"!ARGS:/xxx/\\\"\",\n      \"SecRule ARGS_NAMES \\\"@contains yyy\\\" \\\"id:1,phase:2,deny,status:403\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"SecRuleUpdateTargetById - exclude from ARGS_NAMES using regex (no match)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?xxyyy=value\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"http_code\": 403\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRuleUpdateTargetById 1 \\\"!ARGS:/xxx/\\\"\",\n      \"SecRule ARGS_NAMES \\\"@contains yyy\\\" \\\"id:1,phase:2,deny,status:403\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/config-update-target-by-msg.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"SecRuleUpdateTargetByTag\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?key=value&key=other_value\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRuleUpdateTargetByMsg test !ARGS\",\n      \"SecRule ARGS \\\"@contains value\\\" \\\"id:1,pass,t:trim,msg:'test',deny\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/config-update-target-by-tag.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"SecRuleUpdateTargetByTag (1/6)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?key=value&key=other_value\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRuleUpdateTargetByTag test !ARGS\",\n      \"SecRule ARGS \\\"@contains value\\\" \\\"id:1,pass,t:trim,tag:'test',deny\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"SecRuleUpdateTargetByTag (2/6)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?key=value&key=other_value\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRuleUpdateTargetByTag test !ARGS:'/.*y$/'\",\n      \"SecRule ARGS \\\"@contains value\\\" \\\"id:1,pass,t:trim,tag:'test',deny\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"SecRuleUpdateTargetByTag (3/6)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?key=value&key=other_value\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRuleUpdateTargetByTag test !ARGS:'/k.*/'\",\n      \"SecRule ARGS \\\"@contains value\\\" \\\"id:1,pass,t:trim,tag:'test',deny\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"SecRuleUpdateTargetByTag (4/6)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?key=value&key=other_value\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRuleUpdateTargetByTag test !ARGS:/ke/\",\n      \"SecRule ARGS \\\"@contains value\\\" \\\"id:1,pass,t:trim,tag:'test',deny\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"SecRuleUpdateTargetByTag Test (5/6) Regex with match anchored at beginning of Subject\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?key=value&ref=something\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRuleUpdateTargetByTag test !ARGS:'/(?!ref)/'\",\n      \"SecRule ARGS \\\"@contains value\\\" \\\"id:1,pass,t:trim,tag:'test',deny\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"SecRuleUpdateTargetByTag Test (6/6) Regex with match anchored at beginning of Subject\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?key=value&ref=something\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRuleUpdateTargetByTag test !ARGS:'/^ref/'\",\n      \"SecRule ARGS \\\"@contains something\\\" \\\"id:1,pass,t:trim,tag:'test',deny\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"SecRuleUpdateTargetByTag Test (7/6) Exclusion by full name\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?key=value&ref=something\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRuleUpdateTargetByTag test !ARGS:ref\",\n      \"SecRule ARGS \\\"@contains something\\\" \\\"id:1,pass,t:trim,tag:'test',deny\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/config-xml_external_entity.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing SecXMLExternalEntity/XXE 1\",\n    \"resource\": \"libxml2\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Cookie\": \"PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120\",\n        \"Content-Type\": \"text/xml\",\n        \"Content-Length\": \"162\"\n      },\n      \"uri\": \"/?key=value&key=other_value\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"<?xml version=\\\"1.0\\\" encoding=\\\"UTF-8\\\"?>\",\n        \"<!DOCTYPE author [\",\n        \"<!ELEMENT book (#PCDATA)>\",\n        \"<!ENTITY js \\\"Jo Smith\\\">\",\n        \"]>\",\n        \"<bookstore>\",\n        \"<book category=\\\"WEB\\\"> &js;</book>\",\n        \"</bookstore>\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\" jo smith\\\"\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRequestBodyAccess On\",\n      \"SecXMLExternalEntity Off\",\n      \"SecRule REQUEST_HEADERS:Content-Type \\\"^text/xml$\\\" \\\"id:500005,phase:1,t:none,t:lowercase,nolog,pass,ctl:requestBodyProcessor=XML\\\"\",\n      \"SecRule XML:/bookstore/book[text()] \\\".*\\\" \\\"id:500006,phase:3,t:none,t:lowercase,nolog,pass\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing SecXMLExternalEntity/XXE 2\",\n    \"resource\": \"libxml2\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Cookie\": \"PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120\",\n        \"Content-Type\": \"text/xml\",\n        \"Content-Length\": \"166\"\n      },\n      \"uri\": \"/?key=value&key=other_value\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"<?xml version=\\\"1.0\\\" encoding=\\\"UTF-8\\\"?>\",\n        \"<!DOCTYPE author [\",\n        \"<!ELEMENT book ANY>\",\n        \"<!ENTITY js SYSTEM \\\"/etc/passwd\\\">\",\n        \"]>\",\n        \"<bookstore>\",\n        \"<book category=\\\"WEB\\\"> &js;</book>\",\n        \"</bookstore>\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"XML: Failed to load DTD: test-cases/data/SoapEnvelope.dtd\",\n      \"http_code\": 403\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRequestBodyAccess On\",\n      \"SecXMLExternalEntity Off\",\n      \"SecRule REQUEST_HEADERS:Content-Type \\\"^text/xml$\\\" \\\"id:500005,phase:1,t:none,t:lowercase,nolog,pass,ctl:requestBodyProcessor=XML\\\"\",\n      \"SecRule XML:/bookstore/book \\\".*\\\" \\\"id:500006,phase:3,t:none,t:lowercase,nolog,pass,xmlns:soap='http://schemas.xmlsoap.org/soap/envelope/'\\\"\",\n      \"SecRule XML \\\"@validateDTD test-cases/data/SoapEnvelope.dtd\\\" \\\"id:500007,phase:3,deny\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing SecXMLExternalEntity/XXE 3\",\n    \"resource\": \"libxml2\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Cookie\": \"PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120\",\n        \"Content-Type\": \"text/xml\",\n        \"Content-Length\": \"166\"\n      },\n      \"uri\": \"/?key=value&key=other_value\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"<?xml version=\\\"1.0\\\" encoding=\\\"UTF-8\\\"?>\",\n        \"<!DOCTYPE author [\",\n        \"<!ELEMENT book ANY>\",\n        \"<!ENTITY js SYSTEM \\\"/etc/passwd\\\">\",\n        \"]>\",\n        \"<bookstore>\",\n        \"<book category=\\\"WEB\\\"> &js;</book>\",\n        \"</bookstore>\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"XML Error: No declaration for element bookstore\",\n      \"http_code\": 403\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRequestBodyAccess On\",\n      \"SecXMLExternalEntity On\",\n      \"SecRule REQUEST_HEADERS:Content-Type \\\"^text/xml$\\\" \\\"id:500005,phase:1,t:none,t:lowercase,nolog,pass,ctl:requestBodyProcessor=XML\\\"\",\n      \"SecRule XML:/bookstore/book \\\".*\\\" \\\"id:500006,phase:3,t:none,t:lowercase,nolog,pass,xmlns:soap='http://schemas.xmlsoap.org/soap/envelope/'\\\"\",\n      \"SecRule XML \\\"@validateDTD test-cases/data/SoapEnvelope.dtd\\\" \\\"id:500007,phase:3,deny\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/debug_log.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"version_max\": 0,\n    \"title\": \"Debug log\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 2313\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"net.tutsplus.com\",\n        \"User-Agent\": \"Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)\",\n        \"Accept\": \"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\",\n        \"Accept-Language\": \"en-us,en;q=0.5\",\n        \"Accept-Encoding\": \"gzip,deflate\",\n        \"Accept-Charset\": \"ISO-8859-1,utf-8;q=0.7,*;q=0.7\",\n        \"Keep-Alive\": \"300\",\n        \"Connection\": \"keep-alive\",\n        \"Cookie\": \"PHPSESSID=r2t5uvjq435r4q7ib3vtdjq120\",\n        \"Pragma\": \"no-cache\",\n        \"Cache-Control\": \"no-cache\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/test.pl?param1=test&para2=test2\",\n      \"method\": \"GET\",\n      \"http_version\": 1.1,\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Type\": \"text/xml; charset=utf-8\\n\\r\",\n        \"Content-Length\": \"384\"\n      },\n      \"body\": [\n        \"<?xml version=\\\"1.0\\\" encoding=\\\"utf-8\\\"?>\\n\\r\",\n        \"<soap:Envelope xmlns:xsi=\\\"http://www.w3.org/2001/XMLSchema-instance\\\" xmlns:xsd=\\\"http://www.w3.org/2001/XMLSchema\\\" xmlns:soap=\\\"http://schemas.xmlsoap.org/soap/envelope/\\\">\\n\\r\",\n        \"  <soap:Body>\\n\\r\",\n        \"  <EnlightenResponse xmlns=\\\"http://clearforest.com/\\\">\\n\\r\",\n        \"  <EnlightenResult>string</EnlightenResult>\\n\\r\",\n        \"  </EnlightenResponse>\\n\\r\",\n        \"  </soap:Body>\\n\\r\",\n        \"</soap:Envelope>\\n\\r\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \".*\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule ARGS \\\"@contains test\\\" \\\"id:3,pass\\\"\",\n      \"SecRule ARGS \\\"@contains /test.txt\\\" \\\"id:4,allow\\\"\",\n      \"SecRule ARGS:teste \\\"@contains /test.txt\\\" \\\" id:1,allow,deny\\\"\",\n      \"SecRule ARGS \\\"@contains /test.txt\\\" \\\"allow, allow,id:2,deny\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/directive-sec_rule_script.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"version_max\": 0,\n    \"title\": \"Testing action :: SecRuleScript (1/4)\",\n    \"resource\": \"lua\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 2313\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"User-Agent\": \"Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)\",\n        \"Accept\": \"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\",\n        \"Accept-Language\": \"en-us,en;q=0.5\",\n        \"Accept-Encoding\": \"gzip,deflate\",\n        \"Accept-Charset\": \"ISO-8859-1,utf-8;q=0.7,*;q=0.7\",\n        \"Keep-Alive\": \"300\",\n        \"Connection\": \"keep-alive\",\n        \"Cookie\": \"PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120\",\n        \"Pragma\": \"no-cache\",\n        \"Cache-Control\": \"no-cache\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/test.pl?param1=   test   &param2=test2\",\n      \"method\": \"GET\",\n      \"http_version\": 1.1,\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Type\": \"text/xml; charset=utf-8\\n\\r\",\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"http_code\": 200,\n      \"parser_error\": \"Failed to load script: Failed to compile script 'test-cases/data/match\"\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRuleScript test-cases/data/match-ops.lua \\\"id:1,t:lowercase,t:none\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"version_max\": 0,\n    \"title\": \"Testing action :: SecRuleScript (2/4)\",\n    \"resource\": \"lua\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 2313\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"User-Agent\": \"Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)\",\n        \"Accept\": \"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\",\n        \"Accept-Language\": \"en-us,en;q=0.5\",\n        \"Accept-Encoding\": \"gzip,deflate\",\n        \"Accept-Charset\": \"ISO-8859-1,utf-8;q=0.7,*;q=0.7\",\n        \"Keep-Alive\": \"300\",\n        \"Connection\": \"keep-alive\",\n        \"Cookie\": \"PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120\",\n        \"Pragma\": \"no-cache\",\n        \"Cache-Control\": \"no-cache\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/test.pl?param1=   test   &param2=test2\",\n      \"method\": \"GET\",\n      \"http_version\": 1.1,\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Type\": \"text/xml; charset=utf-8\\n\\r\",\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"http_code\": 200,\n      \"parser_error\": \"Failed to load script: Failed to compile script \"\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRuleScript /bin/echo \\\"id:1,t:lowercase,t:none\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"version_max\": 0,\n    \"title\": \"Testing action :: SecRuleScript (3/4)\",\n    \"resource\": \"lua\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 2313\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"User-Agent\": \"Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)\",\n        \"Accept\": \"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\",\n        \"Accept-Language\": \"en-us,en;q=0.5\",\n        \"Accept-Encoding\": \"gzip,deflate\",\n        \"Accept-Charset\": \"ISO-8859-1,utf-8;q=0.7,*;q=0.7\",\n        \"Keep-Alive\": \"300\",\n        \"Connection\": \"keep-alive\",\n        \"Cookie\": \"PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120\",\n        \"Pragma\": \"no-cache\",\n        \"Cache-Control\": \"no-cache\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/test.pl?param1=   test   &param2=test2\",\n      \"method\": \"GET\",\n      \"http_version\": 1.1,\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Type\": \"text/xml; charset=utf-8\\n\\r\",\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"echo 123\",\n      \"http_code\": 404\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRuleScript test-cases/data/match-log.lua \\\"id:1,t:lowercase,t:none,status:404,deny\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"version_max\": 0,\n    \"title\": \"Testing action :: SecRuleScript (4/4)\",\n    \"resource\": \"lua\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 2313\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"User-Agent\": \"Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)\",\n        \"Accept\": \"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\",\n        \"Accept-Language\": \"en-us,en;q=0.5\",\n        \"Accept-Encoding\": \"gzip,deflate\",\n        \"Accept-Charset\": \"ISO-8859-1,utf-8;q=0.7,*;q=0.7\",\n        \"Keep-Alive\": \"300\",\n        \"Connection\": \"keep-alive\",\n        \"Cookie\": \"PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120\",\n        \"Pragma\": \"no-cache\",\n        \"Cache-Control\": \"no-cache\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/test.pl?param1=   test   &param2=test2\",\n      \"method\": \"GET\",\n      \"http_version\": 1.1,\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Type\": \"text/xml; charset=utf-8\\n\\r\",\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Running \\\\(disruptive\\\\)     action: deny\",\n      \"http_code\": 404\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRuleScript test-cases/data/match.lua \\\"id:1,t:lowercase,t:none,status:404,deny\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/fn-setHostname.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing function :: setRequestHostName\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 0\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"www.modsecurity.org\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/foo?q=attack\",\n      \"method\": \"GET\",\n      \"http_version\": 1.1,\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/plain\",\n        \"Content-Length\": \"10\"\n      },\n      \"body\": [\n        \"denystring\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"[hostname: \\\"modsecurity.org\\\"]\",\n      \"http_code\": 403\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecResponseBodyAccess On\",\n      \"SecRule ARGS_GET \\\"@contains attack\\\" \\\"id:1,phase:2,deny\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/issue-1152.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 209000,\n    \"version_max\": -1,\n    \"title\": \"Should libmodsec pass action clear m_actions?\",\n    \"url\": \"https://github.com/SpiderLabs/ModSecurity/issues/1152\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 2313\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"net.tutsplus.com\",\n        \"User-Agent\": \"Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)\",\n        \"Accept\": \"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\",\n        \"Accept-Language\": \"en-us,en;q=0.5\",\n        \"Accept-Encoding\": \"gzip,deflate\",\n        \"Accept-Charset\": \"ISO-8859-1,utf-8;q=0.7,*;q=0.7\",\n        \"Keep-Alive\": \"300\",\n        \"Connection\": \"keep-alive\",\n        \"Cookie\": \"PHPSESSID=r2t5uvjq435r4q7ib3vtdjq120\",\n        \"Pragma\": \"no-cache\",\n        \"Cache-Control\": \"no-cache\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/test.pl?foo=bar\",\n      \"method\": \"GET\",\n      \"http_version\": 1.1,\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Type\": \"text/xml; charset=utf-8\\n\\r\",\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"http_code\": 403\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule ARGS:foo \\\"bar\\\" \\\"id:'900017',phase:1,t:none,deny,nolog,msg:'foo = bar'\\\"\",\n      \"SecRule &TX:REAL_IP \\\"@eq 0\\\" \\\"id:'900021',phase:1,t:none,initcol:global=global,initcol:ip=%{remote_addr}_%{tx.ua_hash},setvar:tx.real_ip=%{remote_addr},nolog,pass\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 209000,\n    \"version_max\": -1,\n    \"title\": \"Should libmodsec pass action clear m_actions?\",\n    \"url\": \"https://github.com/SpiderLabs/ModSecurity/issues/1152\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 2313\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"net.tutsplus.com\",\n        \"User-Agent\": \"Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)\",\n        \"Accept\": \"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\",\n        \"Accept-Language\": \"en-us,en;q=0.5\",\n        \"Accept-Encoding\": \"gzip,deflate\",\n        \"Accept-Charset\": \"ISO-8859-1,utf-8;q=0.7,*;q=0.7\",\n        \"Keep-Alive\": \"300\",\n        \"Connection\": \"keep-alive\",\n        \"Cookie\": \"PHPSESSID=r2t5uvjq435r4q7ib3vtdjq120\",\n        \"Pragma\": \"no-cache\",\n        \"Cache-Control\": \"no-cache\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/test.pl?foo=bar\",\n      \"method\": \"GET\",\n      \"http_version\": 1.1,\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Type\": \"text/xml; charset=utf-8\\n\\r\",\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"http_code\": 403\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule ARGS:foo \\\"bar\\\" \\\"id:'900017',phase:1,t:none,deny,nolog,msg:'foo = bar'\\\"\",\n      \"SecRule &TX:REAL_IP \\\"@eq 0\\\" \\\"id:'900021',phase:1,t:none,initcol:global=global,initcol:ip=%{remote_addr}_%{tx.ua_hash},setvar:tx.real_ip=%{remote_addr},nolog\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 209000,\n    \"version_max\": -1,\n    \"title\": \"Should libmodsec pass action clear m_actions?\",\n    \"url\": \"https://github.com/SpiderLabs/ModSecurity/issues/1152\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 2313\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"net.tutsplus.com\",\n        \"User-Agent\": \"Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)\",\n        \"Accept\": \"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\",\n        \"Accept-Language\": \"en-us,en;q=0.5\",\n        \"Accept-Encoding\": \"gzip,deflate\",\n        \"Accept-Charset\": \"ISO-8859-1,utf-8;q=0.7,*;q=0.7\",\n        \"Keep-Alive\": \"300\",\n        \"Connection\": \"keep-alive\",\n        \"Cookie\": \"PHPSESSID=r2t5uvjq435r4q7ib3vtdjq120\",\n        \"Pragma\": \"no-cache\",\n        \"Cache-Control\": \"no-cache\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/test.pl?foo=bar\",\n      \"method\": \"GET\",\n      \"http_version\": 1.1,\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Type\": \"text/xml; charset=utf-8\\n\\r\",\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule ARGS:foo \\\"bar\\\" \\\"id:'900017',phase:1,t:none,nolog,msg:'foo = bar'\\\"\",\n      \"SecRule &TX:REAL_IP \\\"@eq 0\\\" \\\"id:'900021',phase:1,t:none,initcol:global=global,initcol:ip=%{remote_addr}_%{tx.ua_hash},setvar:tx.real_ip=%{remote_addr},nolog,deny,pass\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 209000,\n    \"version_max\": -1,\n    \"title\": \"Should libmodsec pass action clear m_actions?\",\n    \"url\": \"https://github.com/SpiderLabs/ModSecurity/issues/1152\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 2313\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"net.tutsplus.com\",\n        \"User-Agent\": \"Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)\",\n        \"Accept\": \"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\",\n        \"Accept-Language\": \"en-us,en;q=0.5\",\n        \"Accept-Encoding\": \"gzip,deflate\",\n        \"Accept-Charset\": \"ISO-8859-1,utf-8;q=0.7,*;q=0.7\",\n        \"Keep-Alive\": \"300\",\n        \"Connection\": \"keep-alive\",\n        \"Cookie\": \"PHPSESSID=r2t5uvjq435r4q7ib3vtdjq120\",\n        \"Pragma\": \"no-cache\",\n        \"Cache-Control\": \"no-cache\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/test.pl?a=test&b=test&c=test&d=test\",\n      \"method\": \"GET\",\n      \"http_version\": 1.1,\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Type\": \"text/xml; charset=utf-8\\n\\r\",\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"4\\\" \\\\(Variable: TX:test\\\\)\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"# Set TX.test to zero\",\n      \"SecAction \\\"phase:2,nolog,pass,setvar:TX.test=0,id:123\\\"\",\n      \"# Increment TX.test for every request parameter\",\n      \"SecRule ARGS \\\"test\\\" \\\"phase:2,log,pass,setvar:TX.test=+1,id:124\\\"\",\n      \"SecRule TX:test \\\"test\\\" \\\"phase:2,log,pass,id:125\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/issue-1528.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 209000,\n    \"version_max\": -1,\n    \"title\": \"Macro expansion inside regex does not work\",\n    \"url\": \"https://github.com/SpiderLabs/ModSecurity/issues/1528\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 2313\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?param=attack\",\n      \"method\": \"GET\",\n      \"http_version\": 1.1,\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Rule returned 1\",\n      \"error_log\": \"Matched \\\"Operator `Rx' with parameter `\\\\^attack\\\\$'\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecAction \\\"id:1, nolog, setvar:tx.bad_value=attack\\\"\",\n      \"SecRule ARGS:param \\\"@rx ^%{tx.bad_value}$\\\" \\\"id:2,block\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/issue-1565.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 209000,\n    \"version_max\": -1,\n    \"title\": \"Problem with OWASP CRS rule 920160 when msc_process_request_headers called (1/2)\",\n    \"url\": \"https://github.com/SpiderLabs/ModSecurity/issues/1565\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 2313\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"\",\n      \"method\": \"GET\",\n      \"http_version\": 1.1,\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Rule returned 0.\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule REQUEST_HEADERS:Content-Length \\\"!^\\\\d+$\\\" \\\"id:1,log\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 209000,\n    \"version_max\": -1,\n    \"title\": \"Problem with OWASP CRS rule 920160 when msc_process_request_headers called (2/2)\",\n    \"url\": \"https://github.com/SpiderLabs/ModSecurity/issues/1565\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 2313\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"\",\n      \"method\": \"GET\",\n      \"http_version\": 1.1,\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Rule returned 1\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule REQUEST_HEADERS:Content-Length \\\"^\\\\d+$\\\" \\\"id:1,log\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/issue-1576.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 209000,\n    \"version_max\": -1,\n    \"title\": \"JSON array should be handled even without a key (1)\",\n    \"url\": \"https://github.com/SpiderLabs/ModSecurity/issues/1576\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Cookie\": \"PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120\",\n        \"Content-Type\": \"application/json\",\n        \"Content-Length\": \"158\"\n      },\n      \"uri\": \"/?key=value&key=other_value\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"{\",\n        \"   \\\"foo\\\":\\\"bar\\\",\",\n        \"   \\\"mod\\\":\\\"sec\\\",\",\n        \"   \\\"ops\\\": [\",\n        \"       [\\\"um\\\", \\\"um e meio\\\"], \",\n        \"       \\\"dois\\\",\",\n        \"       \\\"tres\\\",\",\n        \"       { \\\"eins\\\": [\\\"zwei\\\", \\\"drei\\\"] }\",\n        \"    ],\",\n        \"   \\\"whee\\\": \\\"lhebs\\\"\",\n        \"}\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"zwei\\\" \\\\(Variable: ARGS:json.ops.array_3.eins.array_0\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRequestBodyAccess On\",\n      \"SecRule REQUEST_HEADERS:Content-Type \\\"application/json\\\" \\\"id:'200001',phase:1,t:none,t:lowercase,pass,nolog,ctl:requestBodyProcessor=JSON\\\"\",\n      \"SecRule ARGS \\\"asdf\\\" \\\"id:'200441',phase:3,log\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 209000,\n    \"version_max\": -1,\n    \"title\": \"JSON array should be handled even without a key (2)\",\n    \"url\": \"https://github.com/SpiderLabs/ModSecurity/issues/1576\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Cookie\": \"PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120\",\n        \"Content-Type\": \"application/json\",\n        \"Content-Length\": \"30\"\n      },\n      \"uri\": \"/?key=value&key=other_value\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"[\",\n        \"   \\\"one\\\",\",\n        \"   \\\"two\\\",\",\n        \"   \\\"three\\\"\",\n        \"]\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"three\\\" \\\\(Variable: ARGS:json.array_2\\\\)\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRequestBodyAccess On\",\n      \"SecRule REQUEST_HEADERS:Content-Type \\\"application/json\\\" \\\"id:'200001',phase:1,t:none,t:lowercase,pass,nolog,ctl:requestBodyProcessor=JSON\\\"\",\n      \"SecRule ARGS \\\"asdf\\\" \\\"id:'200441',phase:3,log\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 209000,\n    \"version_max\": -1,\n    \"title\": \"JSON array should be handled even without a key (3)\",\n    \"url\": \"https://github.com/SpiderLabs/ModSecurity/issues/1576\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Cookie\": \"PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120\",\n        \"Content-Type\": \"application/json\",\n        \"Content-Length\": \"215\"\n      },\n      \"uri\": \"/?key=value&key=other_value\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"{\",\n        \"   \\\"foo\\\":\\\"bar\\\",\",\n        \"   \\\"mod\\\":\\\"sec\\\",\",\n        \"   \\\"ops\\\": {\",\n        \"       \\\"um\\\": \\\"um e meio\\\", \",\n        \"       \\\"dois\\\": \\\"tres\\\",\",\n        \"       \\\"quatro\\\": \\\"cinco\\\",\",\n        \"       \\\"seis\\\": {\",\n        \"           \\\"dez\\\": \\\"onze\\\",\",\n        \"           \\\"doze\\\": \\\"treze\\\"\",\n        \"       }\",\n        \"    },\",\n        \"   \\\"whee\\\": \\\"lhebs\\\"\",\n        \"}\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"treze\\\" \\\\(Variable: ARGS:json.ops.seis.doze\\\\)\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRequestBodyAccess On\",\n      \"SecRule REQUEST_HEADERS:Content-Type \\\"application/json\\\" \\\"id:'200001',phase:1,t:none,t:lowercase,pass,nolog,ctl:requestBodyProcessor=JSON\\\"\",\n      \"SecRule ARGS \\\"asdf\\\" \\\"id:'200441',phase:3,log\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/issue-1591.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 209000,\n    \"version_max\": -1,\n    \"title\": \"Regular expressions in rule targets not respected (1/3)\",\n    \"url\": \"https://github.com/SpiderLabs/ModSecurity/issues/1591\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 2313\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\",\n        \"Cookie\": \"__utma=1.32168570.12572608.1259628772.2&__utmb=1.4.10.1259628772&\"\n      },\n      \"uri\": \"\",\n      \"method\": \"GET\",\n      \"http_version\": 1.1,\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Rule returned 0.\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule REQUEST_COOKIES|!REQUEST_COOKIES:/__utm/|!REQUEST_COOKIES:/_pk_ref/|!REQUEST_COOKIES:/__utm/|!REQUEST_COOKIES:/_pk_ref/ \\\"321\\\" \\\"id:1,log\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 209000,\n    \"version_max\": -1,\n    \"title\": \"Regular expressions in rule targets not respected (2/3)\",\n    \"url\": \"https://github.com/SpiderLabs/ModSecurity/issues/1591\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 2313\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\",\n        \"Cookie\": \"__utma=1.32168570.12572608.1259628772.2&__utmb=1.4.10.1259628772&\"\n      },\n      \"uri\": \"\",\n      \"method\": \"GET\",\n      \"http_version\": 1.1,\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Rule returned 1.\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule REQUEST_COOKIES \\\"321\\\" \\\"id:1,log\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 209000,\n    \"version_max\": -1,\n    \"title\": \"Regular expressions in rule targets not respected (3/3)\",\n    \"url\": \"https://github.com/SpiderLabs/ModSecurity/issues/1591\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 2313\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\",\n        \"Cookie\": \"__utma=1.32168570.12572608.1259628772.2&__utmb=1.4.10.1259628772&\"\n      },\n      \"uri\": \"\",\n      \"method\": \"GET\",\n      \"http_version\": 1.1,\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Variable: REQUEST_HEADERS:Content-Length\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule REQUEST_HEADERS:'/(Content-Length|Transfer-Encoding)/' \\\"321\\\" \\\"id:1,log\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/issue-1725.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 209000,\n    \"version_max\": -1,\n    \"title\": \"Macro expansion on msg and logdata does not work for DURATION\",\n    \"url\": \"https://github.com/SpiderLabs/ModSecurity/issues/1725\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 2313\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\",\n        \"Cookie\": \"__utma=1.32168570.12572608.1259628772.2&__utmb=1.4.10.1259628772&\"\n      },\n      \"uri\": \"/test\",\n      \"method\": \"GET\",\n      \"http_version\": 1.1,\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"/test; 0.[0-9]+; 0.[0-9]+;\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule DURATION \\\"@unconditionalMatch\\\" \\\"phase:2,id:10001,log,auditlog,pass,msg:'%{REQUEST_URI}; %{MATCHED_VAR}; %{DURATION};',logdata:'%{REQUEST_URI}; %{MATCHED_VAR}; %{DURATION};'\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/issue-1743.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 209000,\n    \"version_max\": -1,\n    \"title\": \"Regex match does not work when arg ends with unescaped equal char (1/2)\",\n    \"url\": \"https://github.com/SpiderLabs/ModSecurity/issues/1743\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 2313\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?x=foo%3d\",\n      \"method\": \"GET\",\n      \"http_version\": 1.1,\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Rule returned 1\",\n      \"error_log\": \"Value: `foo='\",\n      \"http_code\": 403\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule ARGS \\\"foo?=\\\" \\\"phase:2,id:1,capture,t:none,t:lowercase,deny,msg:'XSS Attack Detected',logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}'\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 209000,\n    \"version_max\": -1,\n    \"title\": \"Regex match does not work when arg ends with unescaped equal char (2/2)\",\n    \"url\": \"https://github.com/SpiderLabs/ModSecurity/issues/1743\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 2313\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?x=foo=\",\n      \"method\": \"GET\",\n      \"http_version\": 1.1,\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Rule returned 1\",\n      \"error_log\": \"Value: `foo='\",\n      \"http_code\": 403\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule ARGS \\\"foo?=\\\" \\\"phase:2,id:1,capture,t:none,t:lowercase,deny,msg:'XSS Attack Detected',logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VAR}'\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/issue-1785.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 209000,\n    \"version_max\": -1,\n    \"title\": \"Should libmodsec pass action clear m_actions?\",\n    \"url\": \"https://github.com/SpiderLabs/ModSecurity/issues/1152\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 2313\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"net.tutsplus.com\",\n        \"User-Agent\": \"\",\n        \"Accept\": \"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\",\n        \"Accept-Language\": \"en-us,en;q=0.5\",\n        \"Accept-Encoding\": \"gzip,deflate\",\n        \"Accept-Charset\": \"ISO-8859-1,utf-8;q=0.7,*;q=0.7\",\n        \"Keep-Alive\": \"300\",\n        \"Connection\": \"keep-alive\",\n        \"Cookie\": \"PHPSESSID=r2t5uvjq435r4q7ib3vtdjq120\",\n        \"Pragma\": \"no-cache\",\n        \"Cache-Control\": \"no-cache\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/test.pl?foo=bar\",\n      \"method\": \"GET\",\n      \"http_version\": 1.1,\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Type\": \"text/xml; charset=utf-8\\n\\r\",\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"http_code\": 403\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule REQUEST_HEADERS:User-Agent \\\"^$\\\" \\\"id:'900017',phase:1,t:none,deny,nolog,msg:'foo = bar'\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/issue-1812.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 209000,\n    \"version_max\": -1,\n    \"title\": \"Converting £ (%C2%A3) from query string\",\n    \"url\": \"https://github.com/SpiderLabs/ModSecurity/issues/1812\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 2313\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"net.tutsplus.com\",\n        \"User-Agent\": \"\",\n        \"Accept\": \"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\",\n        \"Accept-Language\": \"en-us,en;q=0.5\",\n        \"Accept-Encoding\": \"gzip,deflate\",\n        \"Accept-Charset\": \"ISO-8859-1,utf-8;q=0.7,*;q=0.7\",\n        \"Keep-Alive\": \"300\",\n        \"Connection\": \"keep-alive\",\n        \"Cookie\": \"PHPSESSID=r2t5uvjq435r4q7ib3vtdjq120\",\n        \"Pragma\": \"no-cache\",\n        \"Cache-Control\": \"no-cache\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/test.pl?foo=£&bar=%C2%A3\",\n      \"method\": \"GET\",\n      \"http_version\": 1.1,\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Type\": \"text/xml; charset=utf-8\\n\\r\",\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"/test.pl\\\\?foo=\\\\\\\\xc2\\\\\\\\xa3&bar=\\\\\\\\xc2\\\\\\\\xa3\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule ARGS:foo \\\"^$\\\" \\\"id:'900017',phase:1,t:none,deny,nolog,msg:'foo = bar'\\\"\",\n      \"SecRule ARGS:bar \\\"^$\\\" \\\"id:'900018',phase:1,t:none,deny,nolog,msg:'foo = bar'\\\"\",\n      \"SecRule REQUEST_URI \\\"@validatebyterange 1-255\\\" \\\"id:'900019',phase:1,t:none,deny,nolog,msg:'foo = bar'\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/issue-1825.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"multipart Content-Disposition should allow filename* field (1/7)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"350\",\n        \"Content-Type\": \"multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2\",\n        \"Expect\": \"100-continue\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"----------------------------756b6d74fa1a8ee2\\n\",\n        \"Content-Disposition: form-data; name=\\\"name\\\"\\n\",\n        \"\\n\",\n        \"test\\n\",\n        \"----------------------------756b6d74fa1a8ee2\\n\",\n        \"Content-Disposition: form-data; name=\\\"filedata\\\"; filename=\\\"03CB1664.txt\\\"; filename*=utf-8''03CB1664.txt\\n\",\n        \"Content-Type: text/plain\\n\",\n        \"\\n\",\n        \"This is a very small test file..\\n\",\n        \"----------------------------756b6d74fa1a8ee2--\\n\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"03CB1664.txt\\\" \\\\(Variable: MULTIPART_FILENAME\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule MULTIPART_FILENAME \\\"@contains 0\\\" \\\"id:1,phase:2,pass,t:trim\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"multipart Content-Disposition should allow filename* field (2/7)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"354\",\n        \"Content-Type\": \"multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2\",\n        \"Expect\": \"100-continue\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"----------------------------756b6d74fa1a8ee2\\n\",\n        \"Content-Disposition: form-data; name=\\\"name\\\"\\n\",\n        \"\\n\",\n        \"test\\n\",\n        \"----------------------------756b6d74fa1a8ee2\\n\",\n        \"Content-Disposition: form-data; name=\\\"filedata\\\"; filename*= ISO-8859-1''ab0-_xy.txt; filename=\\\"ab0-_xy.txt\\\"\\n\",\n        \"Content-Type: text/plain\\n\",\n        \"\\n\",\n        \"This is a very small test file..\\n\",\n        \"----------------------------756b6d74fa1a8ee2--\\n\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"ab0-_xy.txt\\\" \\\\(Variable: MULTIPART_FILENAME\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule MULTIPART_FILENAME \\\"@contains 0\\\" \\\"id:1,phase:2,pass,t:trim\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"multipart Content-Disposition should allow filename* field (3/7)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"326\",\n        \"Content-Type\": \"multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2\",\n        \"Expect\": \"100-continue\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"----------------------------756b6d74fa1a8ee2\\n\",\n        \"Content-Disposition: form-data; name=\\\"name\\\"\\n\",\n        \"\\n\",\n        \"test\\n\",\n        \"----------------------------756b6d74fa1a8ee2\\n\",\n        \"Content-Disposition: form-data; name=\\\"filedata\\\"; filename*=utf-8''03CB1664.txt\\n\",\n        \"Content-Type: text/plain\\n\",\n        \"\\n\",\n        \"This is a very small test file..\\n\",\n        \"----------------------------756b6d74fa1a8ee2--\\r\\n\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Warning: no filename= but filename*\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule MULTIPART_FILENAME \\\"@contains 0\\\" \\\"id:1,phase:2,pass,t:trim\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"multipart Content-Disposition should allow filename* field (4/7)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"345\",\n        \"Content-Type\": \"multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2\",\n        \"Expect\": \"100-continue\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"----------------------------756b6d74fa1a8ee2\\n\",\n        \"Content-Disposition: form-data; name=\\\"name\\\"\\n\",\n        \"\\n\",\n        \"test\\n\",\n        \"----------------------------756b6d74fa1a8ee2\\n\",\n        \"Content-Disposition: form-data; name=\\\"filedata\\\"; filename=\\\"03CB1664.txt\\\"; filename*=''03CB1664.txt\\n\",\n        \"Content-Type: text/plain\\n\",\n        \"\\n\",\n        \"This is a very small test file..\\n\",\n        \"----------------------------756b6d74fa1a8ee2--\\n\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Multipart: Invalid Content-Disposition header \\\\(-16\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule MULTIPART_FILENAME \\\"@contains 0\\\" \\\"id:1,phase:2,pass,t:trim\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"multipart Content-Disposition should allow filename* field (5/7)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"349\",\n        \"Content-Type\": \"multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2\",\n        \"Expect\": \"100-continue\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"----------------------------756b6d74fa1a8ee2\\n\",\n        \"Content-Disposition: form-data; name=\\\"name\\\"\\n\",\n        \"\\n\",\n        \"test\\n\",\n        \"----------------------------756b6d74fa1a8ee2\\n\",\n        \"Content-Disposition: form-data; name=\\\"filedata\\\"; filename=\\\"03CB1664.txt\\\"; filename*=UTF-8'03CB1664.txt\\n\",\n        \"Content-Type: text/plain\\n\",\n        \"\\n\",\n        \"This is a very small test file..\\n\",\n        \"----------------------------756b6d74fa1a8ee2--\\n\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Multipart: Invalid Content-Disposition header \\\\(-17\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule MULTIPART_FILENAME \\\"@contains 0\\\" \\\"id:1,phase:2,pass,t:trim\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"multipart Content-Disposition should allow filename* field (6/7)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"348\",\n        \"Content-Type\": \"multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2\",\n        \"Expect\": \"100-continue\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"----------------------------756b6d74fa1a8ee2\\n\",\n        \"Content-Disposition: form-data; name=\\\"name\\\"\\n\",\n        \"\\n\",\n        \"test\\n\",\n        \"----------------------------756b6d74fa1a8ee2\\n\",\n        \"Content-Disposition: form-data; name=\\\"filedata\\\"; filename=\\\"03CB1664.txt\\\"; filename*=utf-8''%61%4G.txt\\n\",\n        \"Content-Type: text/plain\\n\",\n        \"\\n\",\n        \"This is a very small test file..\\n\",\n        \"----------------------------756b6d74fa1a8ee2--\\n\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Multipart: Invalid Content-Disposition header \\\\(-18\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule MULTIPART_FILENAME \\\"@contains 0\\\" \\\"id:1,phase:2,pass,t:trim\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"multipart Content-Disposition should allow filename* field (7/7)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"348\",\n        \"Content-Type\": \"multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2\",\n        \"Expect\": \"100-continue\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"----------------------------756b6d74fa1a8ee2\\n\",\n        \"Content-Disposition: form-data; name=\\\"name\\\"\\n\",\n        \"\\n\",\n        \"test\\n\",\n        \"----------------------------756b6d74fa1a8ee2\\n\",\n        \"Content-Disposition: form-data; name=\\\"filedata\\\"; filename=\\\"03CB1664.txt\\\"; filename*=utf-8''%61%62.txt\\n\",\n        \"Content-Type: text/plain\\n\",\n        \"\\n\",\n        \"This is a very small test file..\\n\",\n        \"----------------------------756b6d74fa1a8ee2--\\n\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule REQBODY_ERROR \\\"!@eq 0\\\" \\\"id:1,phase:2,deny,status:403\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/issue-1831.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 209000,\n    \"version_max\": -1,\n    \"title\": \"Invalid actions break CRS 3.1 on rule 912160 - 1\",\n    \"url\": \"https://github.com/SpiderLabs/ModSecurity/issues/1830\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 2313\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"net.tutsplus.com\",\n        \"User-Agent\": \"\",\n        \"Accept\": \"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\",\n        \"Accept-Language\": \"en-us,en;q=0.5\",\n        \"Accept-Encoding\": \"gzip,deflate\",\n        \"Accept-Charset\": \"ISO-8859-1,utf-8;q=0.7,*;q=0.7\",\n        \"Keep-Alive\": \"300\",\n        \"Connection\": \"keep-alive\",\n        \"Cookie\": \"PHPSESSID=r2t5uvjq435r4q7ib3vtdjq120\",\n        \"Pragma\": \"no-cache\",\n        \"Cache-Control\": \"no-cache\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/test.pl?foo=£&bar=%C2%A3\",\n      \"method\": \"GET\",\n      \"http_version\": 1.1,\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Type\": \"text/xml; charset=utf-8\\n\\r\",\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"\\\\\\\\xc2\\\\\\\\xa3\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule ARGS:foo \\\"^$\\\" \\\"id:1,expirevar:'ip.dos_burst_counter=%{tx.dos_burst_time_slice}'\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 209000,\n    \"version_max\": -1,\n    \"title\": \"Invalid actions break CRS 3.1 on rule 912160 - 2\",\n    \"url\": \"https://github.com/SpiderLabs/ModSecurity/issues/1830\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 2313\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"net.tutsplus.com\",\n        \"User-Agent\": \"\",\n        \"Accept\": \"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\",\n        \"Accept-Language\": \"en-us,en;q=0.5\",\n        \"Accept-Encoding\": \"gzip,deflate\",\n        \"Accept-Charset\": \"ISO-8859-1,utf-8;q=0.7,*;q=0.7\",\n        \"Keep-Alive\": \"300\",\n        \"Connection\": \"keep-alive\",\n        \"Cookie\": \"PHPSESSID=r2t5uvjq435r4q7ib3vtdjq120\",\n        \"Pragma\": \"no-cache\",\n        \"Cache-Control\": \"no-cache\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/test.pl?foo=£&bar=%C2%A3\",\n      \"method\": \"GET\",\n      \"http_version\": 1.1,\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Type\": \"text/xml; charset=utf-8\\n\\r\",\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule ARGS:foo \\\".\\\" \\\"id:1,setvar:'ip.dos_counter=1',log\",\n      \"SecRule ip.dos_counter \\\".\\\" \\\"id:4,log\",\n      \"SecRule ARGS:foo \\\".\\\" \\\"id:2,setvar:'!ip.dos_counter',log\",\n      \"SecRule ip.dos_counter \\\".\\\" \\\"id:3,log,status:123,block,deny\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 209000,\n    \"version_max\": -1,\n    \"title\": \"Invalid actions break CRS 3.1 on rule 912160 - 3\",\n    \"url\": \"https://github.com/SpiderLabs/ModSecurity/issues/1830\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 2313\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"net.tutsplus.com\",\n        \"User-Agent\": \"\",\n        \"Accept\": \"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\",\n        \"Accept-Language\": \"en-us,en;q=0.5\",\n        \"Accept-Encoding\": \"gzip,deflate\",\n        \"Accept-Charset\": \"ISO-8859-1,utf-8;q=0.7,*;q=0.7\",\n        \"Keep-Alive\": \"300\",\n        \"Connection\": \"keep-alive\",\n        \"Cookie\": \"PHPSESSID=r2t5uvjq435r4q7ib3vtdjq120\",\n        \"Pragma\": \"no-cache\",\n        \"Cache-Control\": \"no-cache\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/test.pl?foo=£&bar=%C2%A3\",\n      \"method\": \"GET\",\n      \"http_version\": 1.1,\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Type\": \"text/xml; charset=utf-8\\n\\r\",\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"1\\\"\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule ARGS:foo \\\".\\\" \\\"id:1,setvar:'global.alerted_970018_iisDefLoc'\\\"\",\n      \"SecRule GLOBAL:alerted_970018_iisDefLoc \\\".\\\" \\\"id:4,log\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 209000,\n    \"version_max\": -1,\n    \"title\": \"Invalid actions break CRS 3.1 on rule 912160 - 4\",\n    \"url\": \"https://github.com/SpiderLabs/ModSecurity/issues/1830\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 2313\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"net.tutsplus.com\",\n        \"User-Agent\": \"\",\n        \"Accept\": \"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\",\n        \"Accept-Language\": \"en-us,en;q=0.5\",\n        \"Accept-Encoding\": \"gzip,deflate\",\n        \"Accept-Charset\": \"ISO-8859-1,utf-8;q=0.7,*;q=0.7\",\n        \"Keep-Alive\": \"300\",\n        \"Connection\": \"keep-alive\",\n        \"Cookie\": \"PHPSESSID=r2t5uvjq435r4q7ib3vtdjq120\",\n        \"Pragma\": \"no-cache\",\n        \"Cache-Control\": \"no-cache\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/test.pl?foo=£&bar=%C2%A3\",\n      \"method\": \"GET\",\n      \"http_version\": 1.1,\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Type\": \"text/xml; charset=utf-8\\n\\r\",\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"GLOBAL:alerted_970018_iisDefLoc with value: 1\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule ARGS \\\"@rx .\\\" \\\"id:954100,phase:1,block,capture,t:none,t:lowercase,msg:'Disclosure of IIS install location',logdata:'Matched Data',tag:'application-multi',tag:'language-multi',tag:'platform-iis',tag:'platform-windows',tag:'attack-disclosure',ctl:auditLogParts=+E,rev:3,ver:'OWASP_CRS/3.0.0',severity:'ERROR',chain\\\"\",\n      \"SecRule ARGS \\\"@eq 0\\\" \\\"setvar:'global.alerted_970018_iisDefLoc',setvar:'tx.msg=%{rule.msg}',setvar:'tx.outbound_anomaly_score=+%{tx.error_anomaly_score}',setvar:'tx.anomaly_score=+%{tx.error_anomaly_score}'\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/issue-1844.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"m_lineNumber ... mapping ... correct line number in file (1/n)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"26\",\n        \"Content-Type\": \"application/x-www-form-urlencoded\",\n        \"Authorization\": \"Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"param1=test1&param2=value2\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"error_log\": \"line \\\"29\\\"\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule WEBAPPID \\\"@contains test1\\\" \\\"id:1,phase:3,pass,t:trim\\\"\",\n      \"Include test-cases/data/big-file.conf\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"m_lineNumber ... mapping ... correct line number in file (2/n)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"12\",\n        \"Content-Type\": \"application/x-www-form-urlencoded\",\n        \"Authorization\": \"Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"param1=test2\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"error_log\": \"line \\\"55\\\"\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule WEBAPPID \\\"@contains test2\\\" \\\"id:1,phase:3,pass,t:trim\\\"\",\n      \"Include test-cases/data/big-file.conf\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"m_lineNumber ... mapping ... correct line number in file (3/n)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"12\",\n        \"Content-Type\": \"application/x-www-form-urlencoded\",\n        \"Authorization\": \"Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"param1=test3\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"error_log\": \"line \\\"84\\\"\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule WEBAPPID \\\"@contains test3\\\" \\\"id:1,phase:3,pass,t:trim\\\"\",\n      \"Include test-cases/data/big-file.conf\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"m_lineNumber ... mapping ... correct line number in file (4/n)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"12\",\n        \"Content-Type\": \"application/x-www-form-urlencoded\",\n        \"Authorization\": \"Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"param1=test4\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"error_log\": \"line \\\"116\\\"\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule WEBAPPID \\\"@contains test3\\\" \\\"id:1,phase:3,pass,t:trim\\\"\",\n      \"Include test-cases/data/big-file.conf\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"m_lineNumber ... mapping ... correct line number in file (5/n)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"12\",\n        \"Content-Type\": \"application/x-www-form-urlencoded\",\n        \"Authorization\": \"Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"param1=test5\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"error_log\": \"line \\\"174\\\"\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule WEBAPPID \\\"@contains test3\\\" \\\"id:1,phase:3,pass,t:trim\\\"\",\n      \"Include test-cases/data/big-file.conf\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"m_lineNumber ... mapping ... correct line number in file (6/n)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"12\",\n        \"Content-Type\": \"application/x-www-form-urlencoded\",\n        \"Authorization\": \"Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"param1=test5\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"error_log\": \"line \\\"174\\\"\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule WEBAPPID \\\"@contains test3\\\" \\\"id:1,phase:3,pass,t:trim\\\"\",\n      \"Include test-cases/data/not-so-big-file.conf\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/issue-1850.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 209000,\n    \"version_max\": -1,\n    \"title\": \"Override the default status code if not suitable to redirect action\",\n    \"url\": \"https://github.com/SpiderLabs/ModSecurity/issues/1850\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 2313\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"net.tutsplus.com\",\n        \"User-Agent\": \"\",\n        \"Accept\": \"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\",\n        \"Accept-Language\": \"en-us,en;q=0.5\",\n        \"Accept-Encoding\": \"gzip,deflate\",\n        \"Accept-Charset\": \"ISO-8859-1,utf-8;q=0.7,*;q=0.7\",\n        \"Keep-Alive\": \"300\",\n        \"Connection\": \"keep-alive\",\n        \"Cookie\": \"PHPSESSID=r2t5uvjq435r4q7ib3vtdjq120\",\n        \"Pragma\": \"no-cache\",\n        \"Cache-Control\": \"no-cache\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/test.pl?foo=£&bar=%C2%A3\",\n      \"method\": \"GET\",\n      \"http_version\": 1.1,\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Type\": \"text/xml; charset=utf-8\\n\\r\",\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"http_code\": 302\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecDefaultAction \\\"phase:1,status:404,deny\\\"\",\n      \"SecRule REQUEST_URI \\\"@contains /\\\" \\\"id:2000001,phase:1,log,redirect:'http://1.1.1.1/failed.html',t:none,msg:'Unauthorized administrator request'\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/issue-1941.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 209000,\n    \"version_max\": -1,\n    \"title\": \"Failed to load locate the unicode map file from: ... 1/n\",\n    \"url\": \"https://github.com/SpiderLabs/ModSecurity/issues/1941\",\n    \"client\": {\n      \"ip\": \"\",\n      \"port\": 0\n    },\n    \"server\": {\n      \"ip\": \"\",\n      \"port\": 0\n    },\n    \"request\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"\",\n      \"method\": \"\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"http_code\": 200,\n      \"parser_error\": \"Failed to locate the unicode map file from: does-not-exist-unicode.mapping\"\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecUnicodeMapFile does-not-exist-unicode.mapping 20127\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 209000,\n    \"version_max\": -1,\n    \"title\": \"Failed to load locate the unicode map file from: ... 2/n\",\n    \"url\": \"https://github.com/SpiderLabs/ModSecurity/issues/1941\",\n    \"client\": {\n      \"ip\": \"\",\n      \"port\": 0\n    },\n    \"server\": {\n      \"ip\": \"\",\n      \"port\": 0\n    },\n    \"request\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"\",\n      \"method\": \"\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"http_code\": 200,\n      \"parser_error\": \"Failed to locate the unicode map file from: um dois tres does-not-exist-unicode.mapping\"\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecUnicodeMapFile um dois tres does-not-exist-unicode.mapping 20127\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 209000,\n    \"version_max\": -1,\n    \"title\": \"Failed to load locate the unicode map file from: ... 3/n\",\n    \"url\": \"https://github.com/SpiderLabs/ModSecurity/issues/1941\",\n    \"client\": {\n      \"ip\": \"\",\n      \"port\": 0\n    },\n    \"server\": {\n      \"ip\": \"\",\n      \"port\": 0\n    },\n    \"request\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"\",\n      \"method\": \"\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"http_code\": 200,\n      \"parser_error\": \"Invalid input:  SecUnicodeMapFile does-not-exist-unicode.mapping eita\"\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecUnicodeMapFile does-not-exist-unicode.mapping eita\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"version_max\": 0,\n    \"title\": \"Failed to load locate the unicode map file from: ... 4/n\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 2313\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"net.tutsplus.com\",\n        \"User-Agent\": \"Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)\",\n        \"Accept\": \"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\",\n        \"Accept-Language\": \"en-us,en;q=0.5\",\n        \"Accept-Encoding\": \"gzip,deflate\",\n        \"Accept-Charset\": \"ISO-8859-1,utf-8;q=0.7,*;q=0.7\",\n        \"Keep-Alive\": \"300\",\n        \"Connection\": \"keep-alive\",\n        \"Cookie\": \"PHPSESSID=r2t5uvjq435r4q7ib3vtdjq120\",\n        \"Pragma\": \"no-cache\",\n        \"Cache-Control\": \"no-cache\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/test.pl?param1=   test   &param2=test2&pparam=дор\",\n      \"method\": \"GET\",\n      \"http_version\": 1.1,\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Type\": \"text/xml; charset=utf-8\\n\\r\",\n        \"Content-Length\": \"384\"\n      },\n      \"body\": [\n        \"<?xml version=\\\"1.0\\\" encoding=\\\"utf-8\\\"?>\\n\\r\",\n        \"<soap:Envelope xmlns:xsi=\\\"http://www.w3.org/2001/XMLSchema-instance\\\" xmlns:xsd=\\\"http://www.w3.org/2001/XMLSchema\\\" xmlns:soap=\\\"http://schemas.xmlsoap.org/soap/envelope/\\\">\\n\\r\",\n        \"  <soap:Body>\\n\\r\",\n        \"  <EnlightenResponse xmlns=\\\"http://clearforest.com/\\\">\\n\\r\",\n        \"  <EnlightenResult>string</EnlightenResult>\\n\\r\",\n        \"  </EnlightenResponse>\\n\\r\",\n        \"  </soap:Body>\\n\\r\",\n        \"</soap:Envelope>\\n\\r\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"dop\\\"\",\n      \"http_code\": 403\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecUnicodeMapFile test-cases/data/unicode.mapping-reduced 1251\",\n      \"SecRule ARGS \\\"@contains dop\\\" \\\"phase:1,id:999,deny,log,auditlog,t:none,t:utf8toUnicode,t:urlDecodeUni,multiMatch\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"version_max\": 0,\n    \"title\": \"Failed to load locate the unicode map file from: ... 5/n\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 2313\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"net.tutsplus.com\",\n        \"User-Agent\": \"Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)\",\n        \"Accept\": \"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\",\n        \"Accept-Language\": \"en-us,en;q=0.5\",\n        \"Accept-Encoding\": \"gzip,deflate\",\n        \"Accept-Charset\": \"ISO-8859-1,utf-8;q=0.7,*;q=0.7\",\n        \"Keep-Alive\": \"300\",\n        \"Connection\": \"keep-alive\",\n        \"Cookie\": \"PHPSESSID=r2t5uvjq435r4q7ib3vtdjq120\",\n        \"Pragma\": \"no-cache\",\n        \"Cache-Control\": \"no-cache\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/test.pl?param1=   test   &param2=test2&pparam=дор\",\n      \"method\": \"GET\",\n      \"http_version\": 1.1,\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Type\": \"text/xml; charset=utf-8\\n\\r\",\n        \"Content-Length\": \"384\"\n      },\n      \"body\": [\n        \"<?xml version=\\\"1.0\\\" encoding=\\\"utf-8\\\"?>\\n\\r\",\n        \"<soap:Envelope xmlns:xsi=\\\"http://www.w3.org/2001/XMLSchema-instance\\\" xmlns:xsd=\\\"http://www.w3.org/2001/XMLSchema\\\" xmlns:soap=\\\"http://schemas.xmlsoap.org/soap/envelope/\\\">\\n\\r\",\n        \"  <soap:Body>\\n\\r\",\n        \"  <EnlightenResponse xmlns=\\\"http://clearforest.com/\\\">\\n\\r\",\n        \"  <EnlightenResult>string</EnlightenResult>\\n\\r\",\n        \"  </EnlightenResponse>\\n\\r\",\n        \"  </soap:Body>\\n\\r\",\n        \"</soap:Envelope>\\n\\r\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"4>@\\\"\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule ARGS \\\"@contains dop\\\" \\\"phase:1,id:999,deny,log,auditlog,t:none,t:utf8toUnicode,t:urlDecodeUni,multiMatch\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/issue-1943.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"version_max\": 0,\n    \"title\": \"double macros bug 1/n\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 2313\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"net.tutsplus.com\",\n        \"User-Agent\": \"Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)\",\n        \"Accept\": \"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\",\n        \"Accept-Language\": \"en-us,en;q=0.5\",\n        \"Accept-Encoding\": \"gzip,deflate\",\n        \"Accept-Charset\": \"ISO-8859-1,utf-8;q=0.7,*;q=0.7\",\n        \"Keep-Alive\": \"300\",\n        \"Connection\": \"keep-alive\",\n        \"Cookie\": \"PHPSESSID=r2t5uvjq435r4q7ib3vtdjq120\",\n        \"Pragma\": \"no-cache\",\n        \"Cache-Control\": \"no-cache\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/test.pl?param1=   test   &param2=test2&pparam=дор\",\n      \"method\": \"GET\",\n      \"http_version\": 1.1,\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Type\": \"text/xml; charset=utf-8\\n\\r\",\n        \"Content-Length\": \"384\"\n      },\n      \"body\": [\n        \"<?xml version=\\\"1.0\\\" encoding=\\\"utf-8\\\"?>\\n\\r\",\n        \"<soap:Envelope xmlns:xsi=\\\"http://www.w3.org/2001/XMLSchema-instance\\\" xmlns:xsd=\\\"http://www.w3.org/2001/XMLSchema\\\" xmlns:soap=\\\"http://schemas.xmlsoap.org/soap/envelope/\\\">\\n\\r\",\n        \"  <soap:Body>\\n\\r\",\n        \"  <EnlightenResponse xmlns=\\\"http://clearforest.com/\\\">\\n\\r\",\n        \"  <EnlightenResult>string</EnlightenResult>\\n\\r\",\n        \"  </EnlightenResponse>\\n\\r\",\n        \"  </soap:Body>\\n\\r\",\n        \"</soap:Envelope>\\n\\r\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"TX:msg with value:    test      tes\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule ARGS \\\"@contains test2\\\" \\\"phase:1,id:999,setvar:tx.msg=%{ARGS:param1}%{ARGS:param1}\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"version_max\": 0,\n    \"title\": \"double macros bug 2/n\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 2313\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"net.tutsplus.com\",\n        \"User-Agent\": \"Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)\",\n        \"Accept\": \"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\",\n        \"Accept-Language\": \"en-us,en;q=0.5\",\n        \"Accept-Encoding\": \"gzip,deflate\",\n        \"Accept-Charset\": \"ISO-8859-1,utf-8;q=0.7,*;q=0.7\",\n        \"Keep-Alive\": \"300\",\n        \"Connection\": \"keep-alive\",\n        \"Cookie\": \"PHPSESSID=r2t5uvjq435r4q7ib3vtdjq120\",\n        \"Pragma\": \"no-cache\",\n        \"Cache-Control\": \"no-cache\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/test.pl?param1=   test   &param2=test2&pparam=дор\",\n      \"method\": \"GET\",\n      \"http_version\": 1.1,\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Type\": \"text/xml; charset=utf-8\\n\\r\",\n        \"Content-Length\": \"384\"\n      },\n      \"body\": [\n        \"<?xml version=\\\"1.0\\\" encoding=\\\"utf-8\\\"?>\\n\\r\",\n        \"<soap:Envelope xmlns:xsi=\\\"http://www.w3.org/2001/XMLSchema-instance\\\" xmlns:xsd=\\\"http://www.w3.org/2001/XMLSchema\\\" xmlns:soap=\\\"http://schemas.xmlsoap.org/soap/envelope/\\\">\\n\\r\",\n        \"  <soap:Body>\\n\\r\",\n        \"  <EnlightenResponse xmlns=\\\"http://clearforest.com/\\\">\\n\\r\",\n        \"  <EnlightenResult>string</EnlightenResult>\\n\\r\",\n        \"  </EnlightenResponse>\\n\\r\",\n        \"  </soap:Body>\\n\\r\",\n        \"</soap:Envelope>\\n\\r\"\n      ]\n    },\n    \"expected\": {\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule ARGS|XML|XML \\\"test\\\" \\\"id:123,phase:2,block,msg:'Possible harmful executable file detected',logdata:'Matched Data: %{TX.0} found within %{MATCHED_VAR_NAME}: %{MATCHED_VARS}',t:none,tag:'application-multi',tag:'platform-multi',tag:'attack-file-upload',tag:'OWASP_CRS/WEB_ATTACK/MALICIOUS_FILE',tag:'paranoia-level/1',ver:'OWASP_CRS/3.1.0',severity:'NOTICE',setvar:'tx.msg=%{rule.msg}',setvar:'tx.anomaly_score=+%{tx.notice_anomaly_score}',setvar:'tx.%{rule.id}-OWASP_CRS/WEB_ATTACK/MALICIOUS-FILE-%{matched_var_name}=%{tx.0}'\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/issue-1956.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 209000,\n    \"version_max\": -1,\n    \"title\": \"ctl:ruleRemoveById doesn't handle all ranges equally 1\",\n    \"url\": \"https://github.com/SpiderLabs/ModSecurity/issues/1956\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 2313\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"www.google.com\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/test.pl?param1=   test   &param2=<a href=\\\"javascript:alert(1)\\\">)\",\n      \"method\": \"GET\",\n      \"http_version\": 1.1,\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Rule id: 913104 was skipped due to a ruleRemoveById\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRule REQUEST_URI \\\"@beginsWith /test\\\" \\\"id:1001,phase:request,pass,nolog,t:none,ctl:ruleRemoveById=913103-913105\\\"\",\n      \"SecRule REQUEST_URI \\\"@beginsWith /test\\\" \\\"id:913104,phase:request,pass,nolog,t:none,msg:'whee'\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 209000,\n    \"version_max\": -1,\n    \"title\": \"ctl:ruleRemoveById doesn't handle all ranges equally 2\",\n    \"url\": \"https://github.com/SpiderLabs/ModSecurity/issues/1956\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 2313\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"www.google.com\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/test.pl?param1=   test   &param2=<a href=\\\"javascript:alert(1)\\\">)\",\n      \"method\": \"GET\",\n      \"http_version\": 1.1,\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Rule id: 913104 was skipped due to a ruleRemoveById\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRule REQUEST_URI \\\"@beginsWith /test\\\" \\\"id:1001,phase:request,pass,nolog,t:none,ctl:ruleRemoveById=913104\\\"\",\n      \"SecRule REQUEST_URI \\\"@beginsWith /test\\\" \\\"id:913104,phase:request,pass,nolog,t:none,msg:'whee'\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 209000,\n    \"version_max\": -1,\n    \"title\": \"ctl:ruleRemoveById doesn't handle all ranges equally 3\",\n    \"url\": \"https://github.com/SpiderLabs/ModSecurity/issues/1956\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 2313\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"www.google.com\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/test.pl?param1=   test   &param2=<a href=\\\"javascript:alert(1)\\\">)\",\n      \"method\": \"GET\",\n      \"http_version\": 1.1,\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Rule id: 913103 was skipped due to a ruleRemoveById\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRule REQUEST_URI \\\"@beginsWith /test\\\" \\\"id:1001,phase:request,pass,nolog,t:none,ctl:ruleRemoveById=913103-913105\\\"\",\n      \"SecRule REQUEST_URI \\\"@beginsWith /test\\\" \\\"id:913103,phase:request,pass,nolog,t:none,msg:'whee'\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 209000,\n    \"version_max\": -1,\n    \"title\": \"ctl:ruleRemoveById doesn't handle all ranges equally 4\",\n    \"url\": \"https://github.com/SpiderLabs/ModSecurity/issues/1956\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 2313\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"www.google.com\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/test.pl?param1=   test   &param2=<a href=\\\"javascript:alert(1)\\\">)\",\n      \"method\": \"GET\",\n      \"http_version\": 1.1,\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Rule id: 913105 was skipped due to a ruleRemoveById\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRule REQUEST_URI \\\"@beginsWith /test\\\" \\\"id:1001,phase:request,pass,nolog,t:none,ctl:ruleRemoveById=913103-913105\\\"\",\n      \"SecRule REQUEST_URI \\\"@beginsWith /test\\\" \\\"id:913105,phase:request,pass,nolog,t:none,msg:'whee'\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 209000,\n    \"version_max\": -1,\n    \"title\": \"ctl:ruleRemoveById doesn't handle all ranges equally 5\",\n    \"url\": \"https://github.com/SpiderLabs/ModSecurity/issues/1956\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 2313\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"www.google.com\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/test.pl?param1=   test   &param2=<a href=\\\"javascript:alert(1)\\\">)\",\n      \"method\": \"GET\",\n      \"http_version\": 1.1,\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Rule: 913102. Executing operator\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRule REQUEST_URI \\\"@beginsWith /test\\\" \\\"id:1001,phase:request,pass,nolog,t:none,ctl:ruleRemoveById=913103-913105\\\"\",\n      \"SecRule REQUEST_URI \\\"@beginsWith /test\\\" \\\"id:913102,phase:request,pass,nolog,t:none,msg:'whee'\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/issue-1960.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"SecRuleEngine DetectionOnly with disruptive SecDefaultAction\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"?a=a\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine DetectionOnly\",\n      \"SecDefaultAction \\\"phase:1,deny,status:403\\\"\",\n      \"SecRule ARGS \\\"@rx a\\\" \\\"id:1,phase:1,block\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/issue-2000.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing audit log part H should output when deny - issue-2000\",\n    \"client\": {\n      \"ip\": \"127.0.0.1\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"127.0.0.1\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"index.php?foo=bar&a=xxx\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"audit_log\": \"id \\\"1234\",\n      \"http_code\": 403\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecAuditLogParts ABIJDEFHZ\",\n      \"SecAuditEngine RelevantOnly\",\n      \"SecAuditLogParts ABCFHZ\",\n      \"SecAuditLog /tmp/test/modsec_audit.log\",\n      \"SecAuditLogDirMode 0766\",\n      \"SecAuditLogFileMode 0666\",\n      \"SecAuditLogType Serial\",\n      \"SecAuditLogRelevantStatus \\\"^(?:5|4(?!04))\\\"\",\n      \"SecRule ARGS:foo \\\"@rx ^bar$\\\" \\\"id:1234,phase:1,deny,status:403\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/issue-2099.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing ctl:ruleRemoveById - issue 2099\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/remote.php/webdav?bar=foo\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRequestBodyAccess On\",\n      \"SecRule REQUEST_FILENAME \\\"@contains /remote.php/webdav\\\" \\\"id:9003100,phase:2,pass,t:none,nolog,ctl:ruleRemoveByTag=attack-injection-php,ctl:ruleRemoveById=941000-942999,ctl:ruleRemoveById=951000-951999,ctl:ruleRemoveById=953100-953130,ctl:ruleRemoveById=920420,ctl:ruleRemoveById=920440\\\"\",\n      \"SecRule ARGS \\\"@contains foo\\\" \\\"id:951001,phase:2,t:none,drop\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing ctl:ruleRemoveById against - issue 2099\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/remote.php?bar=foo\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"http_code\": 403\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRequestBodyAccess On\",\n      \"SecRule REQUEST_FILENAME \\\"@contains /remote.php/webdav\\\" \\\"id:9003100,phase:2,pass,t:none,nolog,ctl:ruleRemoveByTag=attack-injection-php,ctl:ruleRemoveById=941000-942999,ctl:ruleRemoveById=951000-951999,ctl:ruleRemoveById=953100-953130,ctl:ruleRemoveById=920420,ctl:ruleRemoveById=920440\\\"\",\n      \"SecRule ARGS \\\"@contains foo\\\" \\\"id:951001,phase:2,t:none,drop\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing ctl:ruleRemoveByTag - issue 2099\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/remote.php/webdav?bar=foo\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRequestBodyAccess On\",\n      \"SecRule REQUEST_FILENAME \\\"@contains /remote.php/webdav\\\" \\\"id:1000001,phase:2,pass,t:none,nolog,ctl:ruleRemoveByTag=attack-injection-php,ctl:ruleRemoveById=1100000-2100000,ctl:ruleRemoveById=9990000\\\"\",\n      \"SecRule ARGS \\\"@contains foo\\\" \\\"id:4400000,tag:'attack-injection-php',phase:2,t:none,msg:'test rule',drop\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing ctl:ruleRemoveByTag against - issue 2099\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/remote.php?bar=foo\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"http_code\": 403\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRequestBodyAccess On\",\n      \"SecRule REQUEST_FILENAME \\\"@contains /remote.php/webdav\\\" \\\"id:1000001,phase:2,pass,t:none,nolog,ctl:ruleRemoveByTag=attack-injection-php,ctl:ruleRemoveById=1100000-2100000,ctl:ruleRemoveById=9990000\\\"\",\n      \"SecRule ARGS \\\"@contains foo\\\" \\\"id:4400000,tag:'attack-injection-php',phase:2,t:none,msg:'test rule',drop\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing ctl:ruleRemoveTargetByTag - issue 2099\",\n    \"client\": {\n      \"ip\": \"1.2.3.4\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/test.php?a=a\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRequestBodyAccess On\",\n      \"SecRule REQUEST_URI \\\"@contains /test.php\\\" \\\"id:100,phase:1,nolog,pass,ctl:ruleRemoveTargetByTag=attack-injection-php;ARGS:a,ctl:ruleRemoveTargetByTag=attack-rce;ARGS:a\\\"\",\n      \"SecRule ARGS \\\"@contains a\\\" \\\"id:4400000,tag:'attack-injection-php',phase:2,t:none,msg:'test rule',drop\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing ctl:ruleRemoveTargetByTag against - issue 2099\",\n    \"client\": {\n      \"ip\": \"1.2.3.4\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/index.php?a=a\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"http_code\": 403\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRequestBodyAccess On\",\n      \"SecRule REQUEST_URI \\\"@contains /test.php\\\" \\\"id:100,phase:1,nolog,pass,ctl:ruleRemoveTargetByTag=attack-injection-php;ARGS:a,ctl:ruleRemoveTargetByTag=attack-rce;ARGS:a\\\"\",\n      \"SecRule ARGS \\\"@contains a\\\" \\\"id:4400000,tag:'attack-injection-php',phase:2,t:none,msg:'test rule',drop\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/issue-2111.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing ctl:ruleRemoveById with range - issue 1444\",\n    \"client\": {\n      \"ip\": \"127.0.0.1\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"127.0.0.1\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"index.php?foo=bar&z=xxx\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule ARGS:foo \\\"@rx ^bar$\\\" \\\"id:100,phase:1,ctl:ruleRemoveById=200-1999\\\"\",\n      \"SecRule ARGS:z \\\"@rx ^xxx$\\\" \\\"id:1010,phase:1,deny,status:403\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/issue-2196.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing audit log not written when nolog - issue-2196\",\n    \"client\": {\n      \"ip\": \"127.0.0.1\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"127.0.0.1\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"index.php?foo=bar&a=xxx\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"audit_log\": \"\\\\A[\\\\s\\\\S]{0}\\\\z\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecAuditLogParts ABIJDEFHZ\",\n      \"SecAuditEngine RelevantOnly\",\n      \"SecAuditLogParts ABCFHZ\",\n      \"SecAuditLog /tmp/test/modsec_audit.log\",\n      \"SecAuditLogDirMode 0766\",\n      \"SecAuditLogFileMode 0666\",\n      \"SecAuditLogType Serial\",\n      \"SecAuditLogRelevantStatus \\\"^(?:5|4(?!04))\\\"\",\n      \"SecRule ARGS:foo \\\"@rx ^bar$\\\" \\\"id:1234,phase:1,nolog,pass\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/issue-2296.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Variable key selection using a regular expression (1/n)\",\n    \"url\": \"https://github.com/SpiderLabs/ModSecurity/issues/2296\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"name1\": \"value1\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?THIS=is+a+simple+test\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"is a simple test\\\"\",\n      \"error_log\": \"Operator `Rx' with parameter `test' against variable `ARGS:THIS'\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule ARGS:/^ThIs$/ \\\"test\\\" \\\"id:1\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Variable key selection using a regular expression (2/n)\",\n    \"url\": \"https://github.com/SpiderLabs/ModSecurity/issues/2296\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"name1\": \"value1\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?THIS=is+a+simple+test\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Rule returned 0\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule ARGS:/^ThIz$/ \\\"test\\\" \\\"id:1,deny,status:302\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Variable key selection using a regular expression - msg (3/n)\",\n    \"url\": \"https://github.com/SpiderLabs/ModSecurity/issues/2296\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"name1\": \"value1\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?THIS=is+a+simple+test\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"is a simple test\\\"\",\n      \"error_log\": \"msg \\\"Testing is a simple test\\\"\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule ARGS:/^ThIs$/ \\\"test\\\" \\\"id:1,msg:'Testing %{ARGS:/^ThIs$/}'\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Variable key selection using a regular expression - matched_vars (4/n)\",\n    \"url\": \"https://github.com/SpiderLabs/ModSecurity/issues/2296\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"name1\": \"value1\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?THIS=is+a+simple+test\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"is a simple test\\\"\",\n      \"error_log\": \"msg \\\"Testing is a simple test\\\"\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule ARGS:/^ThIs$/ \\\"test\\\" \\\"id:1,msg:'Testing %{ARGS:/^ThIs$/}',chain\\\"\",\n      \"SecRule MATCHED_VARS:/thIs/ \\\"is a simple test\\\" \\\"log\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Variable key selection using a regular expression - rule (5/n)\",\n    \"url\": \"https://github.com/SpiderLabs/ModSecurity/issues/2296\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"name1\": \"value1\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?THIS=is+a+simple+test\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: .1. .Variable: RULE:id.\",\n      \"error_log\": \"Operator `Rx' with parameter `1' against variable `RULE:id' .Value: `1' .\",\n      \"http_code\": 403\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule RULE:/^Id$/ \\\"1\\\" \\\"id:1,msg:'Testing %{RULE.id}% -- ',deny\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Variable key selection using a regular expression - TX (6/n)\",\n    \"url\": \"https://github.com/SpiderLabs/ModSecurity/issues/2296\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"name1\": \"value1\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"error_log\": \"`Within' with parameter `/name1/' against variable `TX:header_name_name1'\",\n      \"http_code\": 437\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecAction \\\"id:1,phase:1,setvar:'TX.restricted_headers=/name1/'\\\"\",\n      \"SecRule REQUEST_HEADERS_NAMES \\\"^.*$\\\" \\\"id:2,phase:2,setvar:'tx.header_name_%{tx.0}=/%{tx.0}/',deny,status:437,chain,capture\\\"\",\n      \"SecRule TX:/^header_name_/ \\\"@within %{TX:/esTrictEd_headers/}\\\" \\\"setvar:'tx.matched=1'\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Variable key selection using a regular expression - TX (7/n)\",\n    \"url\": \"https://github.com/SpiderLabs/ModSecurity/issues/2296\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"name1\": \"value1\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"error_log\": \"`Within' with parameter `/name1/' against variable `TX:header_name_name1'\",\n      \"http_code\": 437\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecAction \\\"id:1,phase:1,setvar:'TX.restricted_headers=/name1/'\\\"\",\n      \"SecRule REQUEST_HEADERS_NAMES \\\"^.*$\\\" \\\"id:2,phase:2,setvar:'tx.header_name_%{tx.0}=/%{tx.0}/',deny,status:437,capture,chain\\\"\",\n      \"SecRule TX:/^HEADER_NAME_/ \\\"@within %{tx.restricted_headers}\\\" \\\"setvar:'tx.matched=1',log\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Variable key selection using a regular expression - exclusion (8/n)\",\n    \"url\": \"https://github.com/SpiderLabs/ModSecurity/issues/2296\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"name1\": \"value1\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?THIS=is+a+simple+test\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule ARGS \\\"test\\\" \\\"id:1,msg:'Testing %{ARGS:/^ThIs$/}',deny,status:500,chain\\\"\",\n      \"SecRule MATCHED_VARS:/thIs/ \\\"is a simple test\\\" \\\"log\\\"\",\n      \"SecRuleUpdateTargetById 1 !ARGS:/ThIs/\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Variable key selection using a regular expression - exclusion/ARGS (9/n)\",\n    \"url\": \"https://github.com/SpiderLabs/ModSecurity/issues/2296\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"name1\": \"value1\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?THIS=is+a+simple+test\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule ARGS|!ARGS:/tHiS/ \\\"test\\\" \\\"id:1,msg:'Testing %{ARGS:/^ThIs$/}',deny,status:500,chain\\\"\",\n      \"SecRule MATCHED_VARS:/thIs/ \\\"is a simple test\\\" \\\"log\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Variable key selection using a regular expression - exclusion/TX (10/n)\",\n    \"url\": \"https://github.com/SpiderLabs/ModSecurity/issues/2296\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"name1\": \"value1\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?THIS=is+a+simple+test\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecAction \\\"phase:1,setvar:'tx.a=10'\\\"\",\n      \"SecRule TX|!TX:/a/ \\\"10\\\" \\\"id:10,deny,status:500\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/issue-2423-msg-in-chain.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Test match variable (1/n)\",\n    \"github_issue\": 2423,\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"Content-Length\": \"0\",\n        \"Transfer-Encoding\": \"deflate\"\n      },\n      \"uri\": \"/match-this\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"error_log\": \"against variable `REQUEST_HEADERS:Transfer-Encoding' .Value: `deflate'\",\n      \"http_code\": 437\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule REQUEST_URI \\\"^.*$\\\" \\\"phase:2,deny,capture,id:1,msg:'MatchedVar On Msg: [%{MATCHED_VAR}]',logdata:'MatchedVar On LogData %{MATCHED_VAR}',chain\\\"\",\n      \"SecRule REQUEST_HEADERS \\\"^.*$\\\" \\\"status:437\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Test match variable (2/n)\",\n    \"github_issue\": 2423,\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"Content-Length\": \"0\",\n        \"Transfer-Encoding\": \"deflate\"\n      },\n      \"uri\": \"/match-this\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"error_log\": \"MatchedVar On Msg: .deflate.\",\n      \"http_code\": 437\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule REQUEST_URI \\\"^.*$\\\" \\\"phase:2,deny,capture,id:1,msg:'MatchedVar On Msg: [%{MATCHED_VAR}]',logdata:'MatchedVar On LogData %{MATCHED_VAR}',chain\\\"\",\n      \"SecRule REQUEST_HEADERS \\\"^.*$\\\" \\\"status:437\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Test match variable (3/n)\",\n    \"github_issue\": 2423,\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"Content-Length\": \"0\",\n        \"Transfer-Encoding\": \"deflate\"\n      },\n      \"uri\": \"/match-this\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"error_log\": \"MatchedVar On LogData: deflate\",\n      \"http_code\": 437\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule REQUEST_URI \\\"^.*$\\\" \\\"phase:2,deny,capture,id:1,msg:'MatchedVar On Msg: [%{MATCHED_VAR}]',logdata:'MatchedVar On LogData: %{MATCHED_VAR}',chain\\\"\",\n      \"SecRule REQUEST_HEADERS \\\"^.*$\\\" \\\"status:437\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Test match variable (4/n)\",\n    \"github_issue\": 2423,\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"Restricted\": \"attack\",\n        \"Other\": \"Value\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"error_log\": \"msg \\\"Illegal header \\\\[/restricted/\\\\]\\\"\",\n      \"http_code\": 437\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule REQUEST_HEADERS_NAMES \\\"^.*$\\\" \\\"phase:2,setvar:'tx.header_name_%{TX.0}=/%{TX.0}/',deny,t:lowercase,capture,id:500065,msg:'Illegal header [%{MATCHED_VAR}]',logdata:'Restricted header detected: %{MATCHED_VAR}',chain\\\"\",\n      \"SecRule TX:/^header_name_/ \\\"@within /name1/restricted/name3/\\\" \\\"status:437\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/issue-2427.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Tmp file retained for @inspectFile (1/2)\",\n    \"resource\": \"lua\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"658\",\n        \"Content-Type\": \"multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2\",\n        \"Expect\": \"100-continue\"\n      },\n      \"uri\": \"/wheee/f%20i%20l%20e%20\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"----------------------------756b6d74fa1a8ee2\\n\",\n        \"Content-Disposition: form-data; name=\\\"name\\\"\\n\",\n        \"\\n\",\n        \"test\\n\",\n        \"----------------------------756b6d74fa1a8ee2\\n\",\n        \"Content-Disposition: form-data; name=\\\"name2\\\"\\n\",\n        \"\\n\",\n        \"test2\\n\",\n        \"----------------------------756b6d74fa1a8ee2\\n\",\n        \"Content-Disposition: form-data; name=\\\"filedata\\\"; filename=\\\"small_text_file1.txt\\\"\\n\",\n        \"Content-Type: text/plain\\n\",\n        \"\\n\",\n        \"This is a very small test file..\\n\",\n        \"----------------------------756b6d74fa1a8ee2\\n\",\n        \"Content-Disposition: form-data; filename=\\\"small_text_file2.txt\\\"; name=\\\"small2.txt\\\" \\n\",\n        \"Content-Type: text/plain\\n\",\n        \"\\n\",\n        \"This is another very small test file that contains the search content abcdef..\\n\",\n        \"----------------------------756b6d74fa1a8ee2--\\n\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Returning from lua script: abcdef.*Rule returned 1\",\n      \"http_code\": 403\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRequestBodyAccess On\",\n      \"SecTmpSaveUploadedFiles On\",\n      \"SecUploadKeepFiles Off\",\n      \"SecUploadDir /tmp\",\n      \"SecTmpDir /tmp\",\n      \"SecRule FILES_TMPNAMES \\\"@inspectFile test-cases/data/inspectFile-abcdef.lua\\\" \\\"id:1,phase:2,deny,status:403\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Tmp file retained for @inspectFile (2/2)\",\n    \"resource\": \"lua\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"677\",\n        \"Content-Type\": \"multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2\",\n        \"Expect\": \"100-continue\"\n      },\n      \"uri\": \"/wheee/f%20i%20l%20e%20\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"----------------------------756b6d74fa1a8ee2\\r\\n\",\n        \"Content-Disposition: form-data; name=\\\"name\\\"\\r\\n\",\n        \"\\r\\n\",\n        \"test\\r\\n\",\n        \"----------------------------756b6d74fa1a8ee2\\r\\n\",\n        \"Content-Disposition: form-data; name=\\\"name2\\\"\\r\\n\",\n        \"\\r\\n\",\n        \"test2\\r\\n\",\n        \"----------------------------756b6d74fa1a8ee2\\r\\n\",\n        \"Content-Disposition: form-data; name=\\\"filedata\\\"; filename=\\\"small_text_file1.txt\\\"\\r\\n\",\n        \"Content-Type: text/plain\\r\\n\",\n        \"\\r\\n\",\n        \"This is a very small test file..\\r\\n\",\n        \"----------------------------756b6d74fa1a8ee2\\r\\n\",\n        \"Content-Disposition: form-data; filename=\\\"small_text_file2.txt\\\"; name=\\\"small2.txt\\\" \\r\\n\",\n        \"Content-Type: text/plain\\r\\n\",\n        \"\\r\\n\",\n        \"This is another very small test file that does not contain the search content.\\r\\n\",\n        \"----------------------------756b6d74fa1a8ee2--\\r\\n\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRequestBodyAccess On\",\n      \"SecTmpSaveUploadedFiles On\",\n      \"SecUploadKeepFiles Off\",\n      \"SecUploadDir /tmp\",\n      \"SecTmpDir /tmp\",\n      \"SecRule FILES_TMPNAMES \\\"@inspectFile test-cases/data/inspectFile-abcdef.lua\\\" \\\"id:1,phase:2,deny,status:403\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/issue-3340.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"version_max\": 0,\n    \"title\": \"Decode HTML entities with padding\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 2313\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"&#x24;&#00000000000000000000000000000000000000000000000123;jndi:ldap://evil.om/w}\",\n        \"Accept\": \"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\",\n        \"Accept-Language\": \"en-us,en;q=0.5\",\n        \"Accept-Encoding\": \"gzip,deflate\",\n        \"Accept-Charset\": \"ISO-8859-1,utf-8;q=0.7,*;q=0.7\",\n        \"Keep-Alive\": \"300\",\n        \"Connection\": \"keep-alive\",\n        \"Cookie\": \"PHPSESSID=r2t5uvjq435r4q7ib3vtdjq120\",\n        \"Pragma\": \"no-cache\",\n        \"Cache-Control\": \"no-cache\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"GET\",\n      \"http_version\": 1.1,\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Type\": \"text/xml; charset=utf-8\",\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"http_code\": 403\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule REQUEST_HEADERS \\\"@rx (?i)(?:\\\\$|&dollar;?)(?:\\\\{|&l(?:brace|cub);?)(?:[^\\\\}]{0,15}(?:\\\\$|&dollar;?)(?:\\\\{|&l(?:brace|cub);?)|jndi|ctx)\\\" \\\"id:944150,phase:2,deny,t:none,t:urlDecodeUni,t:jsDecode,t:htmlEntityDecode,log\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/issue-394.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 209000,\n    \"version_max\": -1,\n    \"title\": \"Segmentation fault when uploading file with SecStreamInBodyInspection enabled\",\n    \"url\": \"https://github.com/SpiderLabs/ModSecurity/issues/394\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 2313\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"\",\n      \"method\": \"GET\",\n      \"http_version\": 1.1,\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRequestBodyAccess On\",\n      \"SecResponseBodyAccess On\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/issue-849.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 209000,\n    \"version_max\": -1,\n    \"title\": \"@ipMatch \\\"Could not add entry\\\" on slash/32 notation in 2.9.0 (1/2)\",\n    \"url\": \"https://github.com/SpiderLabs/ModSecurity/issues/849\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 2313\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"net.tutsplus.com\",\n        \"User-Agent\": \"\",\n        \"Accept\": \"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\",\n        \"Accept-Language\": \"en-us,en;q=0.5\",\n        \"Accept-Encoding\": \"gzip,deflate\",\n        \"Accept-Charset\": \"ISO-8859-1,utf-8;q=0.7,*;q=0.7\",\n        \"Keep-Alive\": \"300\",\n        \"Connection\": \"keep-alive\",\n        \"Cookie\": \"PHPSESSID=r2t5uvjq435r4q7ib3vtdjq120\",\n        \"Pragma\": \"no-cache\",\n        \"Cache-Control\": \"no-cache\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/test.pl?foo=bar\",\n      \"method\": \"GET\",\n      \"http_version\": 1.1,\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Type\": \"text/xml; charset=utf-8\\n\\r\",\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"http_code\": 403\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule REMOTE_ADDR \\\"@ipMatch 200.249.12.31/32\\\" \\\"phase:1,nolog,pass,msg:'Localhost connection',id:1,deny,status:403\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 209000,\n    \"version_max\": -1,\n    \"title\": \"@ipMatch \\\"Could not add entry\\\" on slash/32 notation in 2.9.0 (2/2)\",\n    \"url\": \"https://github.com/SpiderLabs/ModSecurity/issues/849\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 2313\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"net.tutsplus.com\",\n        \"User-Agent\": \"\",\n        \"Accept\": \"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\",\n        \"Accept-Language\": \"en-us,en;q=0.5\",\n        \"Accept-Encoding\": \"gzip,deflate\",\n        \"Accept-Charset\": \"ISO-8859-1,utf-8;q=0.7,*;q=0.7\",\n        \"Keep-Alive\": \"300\",\n        \"Connection\": \"keep-alive\",\n        \"Cookie\": \"PHPSESSID=r2t5uvjq435r4q7ib3vtdjq120\",\n        \"Pragma\": \"no-cache\",\n        \"Cache-Control\": \"no-cache\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/test.pl?foo=bar\",\n      \"method\": \"GET\",\n      \"http_version\": 1.1,\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Type\": \"text/xml; charset=utf-8\\n\\r\",\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"http_code\": 403\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule REMOTE_ADDR \\\"@ipMatch 200.249.12.31\\\" \\\"phase:1,nolog,pass,msg:'Localhost connection',id:1,deny,status:403\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/issue-960.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 209000,\n    \"version_max\": -1,\n    \"title\": \"!@within appears to fail (1/3)\",\n    \"url\": \"https://github.com/SpiderLabs/ModSecurity/issues/960\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 2313\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"www.google.com\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/test.pl?param1=   test   &param2=test2\",\n      \"method\": \"GET\",\n      \"http_version\": 1.1,\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"\\\\(Rule: 960032\\\\) .* Rule returned 0.\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecDefaultAction \\\"phase:1,log,deny,status:418,tag:'Host: %{request_headers.host}'\\\"\",\n      \"SecDefaultAction \\\"phase:2,log,deny,status:418,tag:'Host: %{request_headers.host}'\\\"\",\n      \"SecAction \\\"id:'900012',phase:request,nolog,pass,t:none,setvar:'tx.allowed_methods=GET HEAD POST OPTIONS'\\\"\",\n      \"SecRule REQUEST_METHOD \\\"!@within %{tx.allowed_methods}\\\" \\\"msg:'Method is not allowed by policy',severity:'WARNING',id:'960032',phase:request,block,rev:'2',ver:'OWASP_CRS/3.0.0',maturity:'9',accuracy:'9',tag:'application-multi',tag:'language-multi',tag:'platform-multi',tag:'attack-generic',tag:'OWASP_CRS/POLICY/METHOD_NOT_ALLOWED',tag:'WASCTC/WASC-15',tag:'OWASP_TOP_10/A6',tag:'OWASP_AppSensor/RE1',tag:'PCI/12.1',logdata:'%{matched_var}',setvar:'tx.msg=%{rule.msg}',setvar:tx.anomaly_score=+%{tx.warning_anomaly_score},setvar:tx.%{rule.id}-OWASP_CRS/POLICY/METHOD_NOT_ALLOWED-%{matched_var_name}=%{matched_var}\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 209000,\n    \"version_max\": -1,\n    \"title\": \"!@within appears to fail (2/3)\",\n    \"url\": \"https://github.com/SpiderLabs/ModSecurity/issues/960\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 2313\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"www.google.com\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/test.pl?param1=   test   &param2=test2\",\n      \"method\": \"GET\",\n      \"http_version\": 1.1,\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"http_code\": 418\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecDefaultAction \\\"phase:1,log,deny,status:418,tag:'Host: %{request_headers.host}'\\\"\",\n      \"SecDefaultAction \\\"phase:2,log,deny,status:418,tag:'Host: %{request_headers.host}'\\\"\",\n      \"SecAction \\\"id:'900012',phase:request,nolog,pass,t:none,setvar:'tx.allowed_methods=GET HEAD POST OPTIONS'\\\"\",\n      \"SecRule REQUEST_METHOD \\\"@within %{tx.allowed_methods}\\\" \\\"msg:'Method is not allowed by policy',severity:'WARNING',id:'960032',phase:request,block,rev:'2',ver:'OWASP_CRS/3.0.0',maturity:'9',accuracy:'9',tag:'application-multi',tag:'language-multi',tag:'platform-multi',tag:'attack-generic',tag:'OWASP_CRS/POLICY/METHOD_NOT_ALLOWED',tag:'WASCTC/WASC-15',tag:'OWASP_TOP_10/A6',tag:'OWASP_AppSensor/RE1',tag:'PCI/12.1',logdata:'%{matched_var}',setvar:'tx.msg=%{rule.msg}',setvar:tx.anomaly_score=+%{tx.warning_anomaly_score},setvar:tx.%{rule.id}-OWASP_CRS/POLICY/METHOD_NOT_ALLOWED-%{matched_var_name}=%{matched_var}\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 209000,\n    \"version_max\": -1,\n    \"title\": \"!@within appears to fail (3/3)\",\n    \"url\": \"https://github.com/SpiderLabs/ModSecurity/issues/960\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 2313\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"www.google.com\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/test.pl?param1=   test   &param2=test2\",\n      \"method\": \"GET\",\n      \"http_version\": 1.1,\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"http_code\": 418\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecDefaultAction \\\"phase:1,log,deny,status:418,tag:'Host: %{request_headers.host}'\\\"\",\n      \"SecDefaultAction \\\"phase:2,log,deny,status:418,tag:'Host: %{request_headers.host}'\\\"\",\n      \"SecAction \\\"id:'900012',phase:request,nolog,pass,t:none,setvar:'tx.allowed_methods=HEAD POST OPTIONS'\\\"\",\n      \"SecRule REQUEST_METHOD \\\"!@within %{tx.allowed_methods}\\\" \\\"msg:'Method is not allowed by policy',severity:'WARNING',id:'960032',phase:request,block,rev:'2',ver:'OWASP_CRS/3.0.0',maturity:'9',accuracy:'9',tag:'application-multi',tag:'language-multi',tag:'platform-multi',tag:'attack-generic',tag:'OWASP_CRS/POLICY/METHOD_NOT_ALLOWED',tag:'WASCTC/WASC-15',tag:'OWASP_TOP_10/A6',tag:'OWASP_AppSensor/RE1',tag:'PCI/12.1',logdata:'%{matched_var}',setvar:'tx.msg=%{rule.msg}',setvar:tx.anomaly_score=+%{tx.warning_anomaly_score},setvar:tx.%{rule.id}-OWASP_CRS/POLICY/METHOD_NOT_ALLOWED-%{matched_var_name}=%{matched_var}\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/misc-variable-under-quotes.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables (quoted) :: REQUEST_LINE - contains (1/2)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?key=value&key=other_value\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"t:lowercase:\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRule \\\"REQUEST_LINE\\\" \\\"@contains index.php/admin/cms/wysiwyg/directive/\\\" \\\"id:1,phase:1,t:lowercase,ctl:auditLogParts=+E\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables (quoted) :: REQUEST_LINE - regex (2/2)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?key=value&key=other_value\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"t:lowercase:\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRule \\\"REQUEST_LINE\\\" \\\"index.php/admin/cms/wysiwyg/directive/\\\" \\\"id:1,t:lowercase,ctl:auditLogParts=+E\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/misc.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"version_max\": 0,\n    \"title\": \"Testing action :: SecRule directives should be case insensitive\",\n    \"client\": {\n      \"ip\": \"\",\n      \"port\": 0\n    },\n    \"server\": {\n      \"ip\": \"\",\n      \"port\": 0\n    },\n    \"request\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"\",\n      \"method\": \"\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Executing operator \\\"Contains\\\" with param \\\"PHPSESSID\\\" against REQUEST_HEADERS.\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"secruleengine On\",\n      \"secrule REQUEST_HEADERS \\\"@contains PHPSESSID\\\" \\\"id:1,t:lowercase,t:none,msg:'This is a test, %{REQUEST_HEADERS:Accept}%'\\\"\",\n      \"secrule TX \\\"@contains to_test\\\" \\\"id:2,t:lowercase,t:none\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/offset-variable.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Variable offset - ARGS\",\n    \"client\": {\n      \"ip\": \"\",\n      \"port\": 0\n    },\n    \"server\": {\n      \"ip\": \"\",\n      \"port\": 0\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"Content-Length\": \"0\",\n        \"Content-Type\": \"application/x-www-form-urlencoded\"\n      },\n      \"uri\": \"/index.html?param1=value1&param2=value1\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"error_log\": \"o0,3v23,6t:trim\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRule ARGS \\\"@rx val\\\" \\\"id:1,phase:2,pass,t:trim,msg:'ops'\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Variable offset - ARGS_GET\",\n    \"client\": {\n      \"ip\": \"\",\n      \"port\": 0\n    },\n    \"server\": {\n      \"ip\": \"\",\n      \"port\": 0\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"Content-Length\": \"0\",\n        \"Content-Type\": \"application/x-www-form-urlencoded\"\n      },\n      \"uri\": \"/index.html?param1=value1&param2=value2\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"error_log\": \"o3,3v37,6t:trim\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRule ARGS_GET \\\"@rx ue2\\\" \\\"id:1,phase:2,pass,t:trim,msg:'ops'\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Variable offset - ARGS_POST 1\",\n    \"client\": {\n      \"ip\": \"\",\n      \"port\": 0\n    },\n    \"server\": {\n      \"ip\": \"\",\n      \"port\": 0\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"Content-Length\": \"27\",\n        \"Content-Type\": \"application/x-www-form-urlencoded\"\n      },\n      \"uri\": \"/index.html?param1=value1&param2=value1\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"param1=value1&param2=value1\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"error_log\": \"o3,3v142,6t:trim\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRequestBodyAccess On\",\n      \"SecRule ARGS_POST \\\"@rx ue1\\\" \\\"id:1,phase:2,pass,t:trim,msg:'ops'\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Variable offset - ARGS_POST 2\",\n    \"client\": {\n      \"ip\": \"\",\n      \"port\": 0\n    },\n    \"server\": {\n      \"ip\": \"\",\n      \"port\": 0\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"Content-Length\": \"41\",\n        \"Content-Type\": \"application/x-www-form-urlencoded\"\n      },\n      \"uri\": \"/index.html?param1=value1&param2=value1\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"param1=value1&param2=value2&param3=value3\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"error_log\": \"o3,3v156,6t:trim\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRequestBodyAccess On\",\n      \"SecRule ARGS_POST \\\"@rx ue2\\\" \\\"id:1,phase:2,pass,t:trim,msg:'ops'\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Variable offset - ARGS_GET_NAMES 1\",\n    \"client\": {\n      \"ip\": \"\",\n      \"port\": 0\n    },\n    \"server\": {\n      \"ip\": \"\",\n      \"port\": 0\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"Content-Length\": \"41\",\n        \"Content-Type\": \"application/x-www-form-urlencoded\"\n      },\n      \"uri\": \"/index.html?param1=value1&param2=value1\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"param1=value1&param2=value2&param3=value3\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"error_log\": \"o0,6v17,6t:trim\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRequestBodyAccess On\",\n      \"SecRule ARGS_GET_NAMES \\\"@rx param1\\\" \\\"id:1,phase:2,pass,t:trim,msg:'ops'\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Variable offset - ARGS_GET_NAMES 2\",\n    \"client\": {\n      \"ip\": \"\",\n      \"port\": 0\n    },\n    \"server\": {\n      \"ip\": \"\",\n      \"port\": 0\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"Content-Length\": \"41\",\n        \"Content-Type\": \"application/x-www-form-urlencoded\"\n      },\n      \"uri\": \"/index.html?param1=value1&param2=value1\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"param1=value1&param2=value2&param3=value3\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"error_log\": \"o0,6v31,6t:trim\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRequestBodyAccess On\",\n      \"SecRule ARGS_GET_NAMES \\\"@rx param2\\\" \\\"id:1,phase:2,pass,t:trim,msg:'ops'\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Variable offset - ARGS_GET_NAMES 3\",\n    \"client\": {\n      \"ip\": \"\",\n      \"port\": 0\n    },\n    \"server\": {\n      \"ip\": \"\",\n      \"port\": 0\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"Content-Length\": \"41\",\n        \"Content-Type\": \"application/x-www-form-urlencoded\"\n      },\n      \"uri\": \"/index.html?param1=value1&param2=value1\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"param1=value1&param2=value2&param3=value3\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRequestBodyAccess On\",\n      \"SecRule ARGS_GET_NAMES \\\"@rx am1 par\\\" \\\"id:1,phase:2,pass,t:trim,msg:'ops'\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Variable offset - ARGS_GET_NAMES 4\",\n    \"client\": {\n      \"ip\": \"\",\n      \"port\": 0\n    },\n    \"server\": {\n      \"ip\": \"\",\n      \"port\": 0\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"Content-Length\": \"41\",\n        \"Content-Type\": \"application/x-www-form-urlencoded\"\n      },\n      \"uri\": \"/index.html?param1=value1&param2=value1&param3=value1\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"param1=value1&param2=value2&param3=value3\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRequestBodyAccess On\",\n      \"SecRule ARGS_GET_NAMES \\\"@rx am1 param2 par\\\" \\\"id:1,phase:2,pass,t:trim,msg:'ops'\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Variable offset - ARGS_POST_NAMES\",\n    \"client\": {\n      \"ip\": \"\",\n      \"port\": 0\n    },\n    \"server\": {\n      \"ip\": \"\",\n      \"port\": 0\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"Content-Length\": \"41\",\n        \"Content-Type\": \"application/x-www-form-urlencoded\"\n      },\n      \"uri\": \"/index.html?param1=value1&param2=value1&param3=value1\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"param1=value1&param2=value2&param3=value3\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"error_log\": \"0,6v149,6t:trim\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRequestBodyAccess On\",\n      \"SecRule ARGS_POST_NAMES \\\"@rx param1\\\" \\\"id:1,phase:2,pass,t:trim,msg:'ops'\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Variable offset - ARGS_NAMES\",\n    \"client\": {\n      \"ip\": \"\",\n      \"port\": 0\n    },\n    \"server\": {\n      \"ip\": \"\",\n      \"port\": 0\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"Content-Length\": \"41\",\n        \"Content-Type\": \"application/x-www-form-urlencoded\"\n      },\n      \"uri\": \"/index.html?param1=value1&param2=value1&param3=value1\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"param1=value1&param2=value2&param3=value3\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"error_log\": \"o0,6v17,6t:trim\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRequestBodyAccess On\",\n      \"SecRule ARGS_NAMES \\\"@rx param1\\\" \\\"id:1,phase:2,pass,t:trim,msg:'ops'\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Variable offset - ARGS_COMBINED_SIZE 1\",\n    \"client\": {\n      \"ip\": \"\",\n      \"port\": 0\n    },\n    \"server\": {\n      \"ip\": \"\",\n      \"port\": 0\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"Content-Length\": \"0\",\n        \"Content-Type\": \"application/x-www-form-urlencoded\"\n      },\n      \"uri\": \"/index.html?param1=value1&param2=value1&param3=value1\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"error_log\": \"v16,6v23,6v30,6v37,6v44,6v51,6t:trim\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRequestBodyAccess On\",\n      \"SecRule ARGS_COMBINED_SIZE \\\"@gt 1\\\" \\\"id:1,phase:2,pass,t:trim,msg:'ops'\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Variable offset - ARGS_COMBINED_SIZE 2\",\n    \"client\": {\n      \"ip\": \"\",\n      \"port\": 0\n    },\n    \"server\": {\n      \"ip\": \"\",\n      \"port\": 0\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"Content-Length\": \"0\",\n        \"Content-Type\": \"application/x-www-form-urlencoded\"\n      },\n      \"uri\": \"/index.html?param1=value1&param2=value1&param3=value1\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"error_log\": \"v16,6v23,6v30,6v37,6v44,6v51,6t:trim\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRequestBodyAccess On\",\n      \"SecRule ARGS_COMBINED_SIZE \\\"@gt 1\\\" \\\"id:1,phase:2,pass,t:trim,msg:'ops'\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Variable offset - REQUEST_LINE\",\n    \"client\": {\n      \"ip\": \"\",\n      \"port\": 0\n    },\n    \"server\": {\n      \"ip\": \"\",\n      \"port\": 0\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"Content-Length\": \"0\",\n        \"Content-Type\": \"application/x-www-form-urlencoded\",\n        \"AuThOrIzAtIoN\": \"Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==\"\n      },\n      \"uri\": \"/index.html?param1=value1&param2=value1&param3=value1\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"error_log\": \"o23,6v0,63t:trim\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRequestBodyAccess On\",\n      \"SecRule REQUEST_LINE \\\"value1\\\" \\\"id:1,phase:2,pass,t:trim,msg:'ops'\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Variable offset - REQUEST_METHOD\",\n    \"client\": {\n      \"ip\": \"\",\n      \"port\": 0\n    },\n    \"server\": {\n      \"ip\": \"\",\n      \"port\": 0\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"Content-Length\": \"0\",\n        \"Content-Type\": \"application/x-www-form-urlencoded\",\n        \"AuThOrIzAtIoN\": \"Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==\"\n      },\n      \"uri\": \"/index.html?param1=value1&param2=value1&param3=value1\",\n      \"method\": \"GET\",\n      \"http_version\": 1.1,\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"error_log\": \"o0,3v0,3t:trim\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRequestBodyAccess On\",\n      \"SecRule REQUEST_METHOD \\\"GET\\\" \\\"id:1,phase:2,pass,t:trim,msg:'ops'\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Variable offset - REQUEST_PROTOCOL\",\n    \"client\": {\n      \"ip\": \"\",\n      \"port\": 0\n    },\n    \"server\": {\n      \"ip\": \"\",\n      \"port\": 0\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"Content-Length\": \"0\",\n        \"Content-Type\": \"application/x-www-form-urlencoded\",\n        \"AuThOrIzAtIoN\": \"Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==\"\n      },\n      \"uri\": \"/index.html?param1=value1&param2=value1&param3=value1\",\n      \"method\": \"GET\",\n      \"http_version\": 1.1,\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"error_log\": \"o5,3v58,8t:trim\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRequestBodyAccess On\",\n      \"SecRule REQUEST_PROTOCOL \\\"1.1\\\" \\\"id:1,phase:2,pass,t:trim,msg:'ops'\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Variable offset - PATH_INFO\",\n    \"client\": {\n      \"ip\": \"\",\n      \"port\": 0\n    },\n    \"server\": {\n      \"ip\": \"\",\n      \"port\": 0\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"Content-Length\": \"0\",\n        \"Content-Type\": \"application/x-www-form-urlencoded\",\n        \"AuThOrIzAtIoN\": \"Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==\"\n      },\n      \"uri\": \"/index.html?param1=value1&param2=value1&param3=value1\",\n      \"method\": \"GET\",\n      \"http_version\": 1.1,\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"error_log\": \"o1,5v4,11t:trim\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRequestBodyAccess On\",\n      \"SecRule PATH_INFO \\\"index\\\" \\\"id:1,phase:2,pass,t:trim,msg:'ops'\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Variable offset - QUERY_STRING\",\n    \"client\": {\n      \"ip\": \"\",\n      \"port\": 0\n    },\n    \"server\": {\n      \"ip\": \"\",\n      \"port\": 0\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"Content-Length\": \"0\",\n        \"Content-Type\": \"application/x-www-form-urlencoded\",\n        \"AuThOrIzAtIoN\": \"Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==\"\n      },\n      \"uri\": \"/index.html?param1=value1&param2=value1&param3=value1\",\n      \"method\": \"GET\",\n      \"http_version\": 1.1,\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"error_log\": \"o7,6v16,41t:trim\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRequestBodyAccess On\",\n      \"SecRule QUERY_STRING \\\"value1\\\" \\\"id:1,phase:2,pass,t:trim,msg:'ops'\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Variable offset - REQUEST_BASENAME\",\n    \"client\": {\n      \"ip\": \"\",\n      \"port\": 0\n    },\n    \"server\": {\n      \"ip\": \"\",\n      \"port\": 0\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"Content-Length\": \"0\",\n        \"Content-Type\": \"application/x-www-form-urlencoded\",\n        \"AuThOrIzAtIoN\": \"Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==\"\n      },\n      \"uri\": \"/index.html?param1=value1&param2=value1&param3=value1\",\n      \"method\": \"GET\",\n      \"http_version\": 1.1,\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"error_log\": \"o6,4v5,10t:trim\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRequestBodyAccess On\",\n      \"SecRule REQUEST_BASENAME \\\"html\\\" \\\"id:1,phase:2,pass,t:trim,msg:'ops'\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Variable offset - REQUEST_URI\",\n    \"client\": {\n      \"ip\": \"\",\n      \"port\": 0\n    },\n    \"server\": {\n      \"ip\": \"\",\n      \"port\": 0\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"Content-Length\": \"0\",\n        \"Content-Type\": \"application/x-www-form-urlencoded\",\n        \"AuThOrIzAtIoN\": \"Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==\"\n      },\n      \"uri\": \"/index.html%20%20?param1=value1&param2=value1&param3=value1\",\n      \"method\": \"GET\",\n      \"http_version\": 1.1,\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"error_log\": \"o7,4v4,59t:trim\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRequestBodyAccess On\",\n      \"SecRule REQUEST_URI \\\"html\\\" \\\"id:1,phase:2,pass,t:trim,msg:'ops'\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Variable offset - REQUEST_URI_RAW\",\n    \"client\": {\n      \"ip\": \"\",\n      \"port\": 0\n    },\n    \"server\": {\n      \"ip\": \"\",\n      \"port\": 0\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"Content-Length\": \"0\",\n        \"Content-Type\": \"application/x-www-form-urlencoded\",\n        \"AuThOrIzAtIoN\": \"Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==\"\n      },\n      \"uri\": \"/index.html%20%20?param1=value1&param2=value1&param3=value1\",\n      \"method\": \"GET\",\n      \"http_version\": 1.1,\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"error_log\": \"o7,4v4,59t:trim\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRequestBodyAccess On\",\n      \"SecRule REQUEST_URI_RAW \\\"html\\\" \\\"id:1,phase:2,pass,t:trim,msg:'ops'\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Variable offset - REQUEST_HEADERS\",\n    \"client\": {\n      \"ip\": \"\",\n      \"port\": 0\n    },\n    \"server\": {\n      \"ip\": \"\",\n      \"port\": 0\n    },\n    \"request\": {\n      \"headers\": {\n        \"Content-Length\": \"0\",\n        \"Host\": \"localhost\",\n        \"AuThOrIzAtIoN\": \"Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==\",\n        \"Content-Type\": \"application/x-www-form-urlencoded\"\n      },\n      \"uri\": \"/index.html?param1=value1&param2=value1&param3=value1\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"error_log\": \"o0,9v88,9t:trim\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRequestBodyAccess On\",\n      \"SecRule REQUEST_HEADERS \\\"localhost\\\" \\\"id:1,phase:2,pass,t:trim,msg:'ops'\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Variable offset - REQUEST_HEADERS:content-type\",\n    \"client\": {\n      \"ip\": \"\",\n      \"port\": 0\n    },\n    \"server\": {\n      \"ip\": \"\",\n      \"port\": 0\n    },\n    \"request\": {\n      \"headers\": {\n        \"Content-Length\": \"0\",\n        \"Host\": \"localhost\",\n        \"AuThOrIzAtIoN\": \"Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==\",\n        \"Content-Type\": \"application/x-www-form-urlencoded\"\n      },\n      \"uri\": \"/index.html?param1=value1&param2=value1&param3=value1\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"error_log\": \"o14,3v162,33t:trim\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRequestBodyAccess On\",\n      \"SecRule REQUEST_HEADERS \\\"www\\\" \\\"id:1,phase:2,pass,t:trim,msg:'ops'\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Variable offset - AUTH_TYPE 1\",\n    \"client\": {\n      \"ip\": \"\",\n      \"port\": 0\n    },\n    \"server\": {\n      \"ip\": \"\",\n      \"port\": 0\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"Content-Length\": \"0\",\n        \"Content-Type\": \"application/x-www-form-urlencoded\",\n        \"AuThOrIzAtIoN\": \"Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==\"\n      },\n      \"uri\": \"/index.html?param1=value1&param2=value1&param3=value1\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"error_log\": \"o0,5v161,5t:trim\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRequestBodyAccess On\",\n      \"SecRule AUTH_TYPE \\\"Basic\\\" \\\"id:1,phase:2,pass,t:trim,msg:'ops'\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Variable offset - AUTH_TYPE 2\",\n    \"client\": {\n      \"ip\": \"\",\n      \"port\": 0\n    },\n    \"server\": {\n      \"ip\": \"\",\n      \"port\": 0\n    },\n    \"request\": {\n      \"headers\": {\n        \"AuThOrIzAtIoN\": \"Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==\",\n        \"Host\": \"localhost\",\n        \"Content-Length\": \"0\",\n        \"Content-Type\": \"application/x-www-form-urlencoded\"\n      },\n      \"uri\": \"/index.html?param1=value1&param2=value1&param3=value1\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"error_log\": \"o0,5v79,5t:trim\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRequestBodyAccess On\",\n      \"SecRule AUTH_TYPE \\\"Basic\\\" \\\"id:1,phase:2,pass,t:trim,msg:'ops'\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Variable offset - REQUEST_HEADERS_NAMES\",\n    \"client\": {\n      \"ip\": \"\",\n      \"port\": 0\n    },\n    \"server\": {\n      \"ip\": \"\",\n      \"port\": 0\n    },\n    \"request\": {\n      \"headers\": {\n        \"AuThOrIzAtIoN\": \"Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==\",\n        \"Host\": \"localhost\",\n        \"Content-Length\": \"0\",\n        \"Content-Type\": \"application/x-www-form-urlencoded\"\n      },\n      \"uri\": \"/index.html?param1=value1&param2=value1&param3=value1\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"error_log\": \"o0,4v64,13t:lowercase\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRequestBodyAccess On\",\n      \"SecRule REQUEST_HEADERS_NAMES \\\"auth\\\" \\\"id:1,phase:2,pass,t:lowercase,msg:'ops'\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Variable offset - REQUEST_COOKIES 1\",\n    \"client\": {\n      \"ip\": \"\",\n      \"port\": 0\n    },\n    \"server\": {\n      \"ip\": \"\",\n      \"port\": 0\n    },\n    \"request\": {\n      \"headers\": {\n        \"AuThOrIzAtIoN\": \"Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==\",\n        \"Host\": \"localhost\",\n        \"Content-Length\": \"0\",\n        \"Content-Type\": \"application/x-www-form-urlencoded\",\n        \"Cookie\": \"USER_TOKEN=Yes; a=z; t=b\"\n      },\n      \"uri\": \"/index.html?param1=value1&param2=value1&param3=value1\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"error_log\": \"o1,2v215,3t:lowercase\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRequestBodyAccess On\",\n      \"SecRule REQUEST_COOKIES \\\"es\\\" \\\"id:1,phase:2,pass,t:lowercase,msg:'ops'\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Variable offset - REQUEST_COOKIES 2\",\n    \"client\": {\n      \"ip\": \"\",\n      \"port\": 0\n    },\n    \"server\": {\n      \"ip\": \"\",\n      \"port\": 0\n    },\n    \"request\": {\n      \"headers\": {\n        \"AuThOrIzAtIoN\": \"Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==\",\n        \"Host\": \"localhost\",\n        \"Content-Length\": \"0\",\n        \"Content-Type\": \"application/x-www-form-urlencoded\",\n        \"Cookie\": \"USER_TOKEN=Yes; a=z; t=b\"\n      },\n      \"uri\": \"/index.html?param1=value1&param2=value1&param3=value1\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"error_log\": \"o0,1v222,1t:lowercase\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRequestBodyAccess On\",\n      \"SecRule REQUEST_COOKIES \\\"z\\\" \\\"id:1,phase:2,pass,t:lowercase,msg:'ops'\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Variable offset - REQUEST_COOKIES 3\",\n    \"client\": {\n      \"ip\": \"\",\n      \"port\": 0\n    },\n    \"server\": {\n      \"ip\": \"\",\n      \"port\": 0\n    },\n    \"request\": {\n      \"headers\": {\n        \"AuThOrIzAtIoN\": \"Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==\",\n        \"Host\": \"localhost\",\n        \"Content-Length\": \"0\",\n        \"Content-Type\": \"application/x-www-form-urlencoded\",\n        \"Cookie\": \"USER_TOKEN=Yes; a=z; t=b\"\n      },\n      \"uri\": \"/index.html?param1=value1&param2=value1&param3=value1\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"error_log\": \"o0,1v227,1t:lowercase,t:trim\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRequestBodyAccess On\",\n      \"SecRule REQUEST_COOKIES \\\"b\\\" \\\"id:1,phase:2,pass,t:lowercase,t:trim,msg:'ops'\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Variable offset - REQUEST_COOKIES_NAMES\",\n    \"client\": {\n      \"ip\": \"\",\n      \"port\": 0\n    },\n    \"server\": {\n      \"ip\": \"\",\n      \"port\": 0\n    },\n    \"request\": {\n      \"headers\": {\n        \"AuThOrIzAtIoN\": \"Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==\",\n        \"Host\": \"localhost\",\n        \"Content-Length\": \"0\",\n        \"Content-Type\": \"application/x-www-form-urlencoded\",\n        \"Cookie\": \"USER_TOKEN=Yes; a=z; t=b\"\n      },\n      \"uri\": \"/index.html?param1=value1&param2=value1&param3=value1\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"error_log\": \"o0,1v225,1\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRequestBodyAccess On\",\n      \"SecRule REQUEST_COOKIES_NAMES \\\"t\\\" \\\"id:1,phase:2,pass,msg:'ops'\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: REMOTE_USER\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\",\n        \"Content-Type\": \"application/x-www-form-urlencoded\",\n        \"Authorization\": \"Basic QWxhZGRpbjpPcGVuU2VzYW1l\"\n      },\n      \"uri\": \"/one/two/three?key1=value1&key2=v%20a%20l%20u%20e%202\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"error_log\": \"o0,7v197,30t:trim\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule REMOTE_USER \\\"Aladdin\\\" \\\"id:1,phase:3,pass,t:trim,msg:'s'\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: REQUEST_BODY\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"516\",\n        \"Content-Type\": \"multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2\",\n        \"Expect\": \"100-continue\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"----------------------------756b6d74fa1a8ee2\\n\",\n        \"Content-Disposition: form-data; name=\\\"name\\\"\\n\",\n        \"\\n\",\n        \"test\\n\",\n        \"----------------------------756b6d74fa1a8ee2\\n\",\n        \"Content-Disposition: form-data; name=\\\"filedata\\\"; filename=\\\"small_text_file.txt\\\"\\n\",\n        \"Content-Type: text/plain\\n\",\n        \"\\n\",\n        \"This is a very small test file..\\n\",\n        \"----------------------------756b6d74fa1a8ee2\\n\",\n        \"Content-Disposition: form-data; name=\\\"filedata\\\"; filename=\\\"small_text_file.txt\\\"\\n\",\n        \"Content-Type: text/plain\\n\",\n        \"\\n\",\n        \"This is another very small test file..\\n\",\n        \"----------------------------756b6d74fa1a8ee2--\\n\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"error_log\": \"o45,30v193,516t:trim\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRequestBodyAccess On\",\n      \"SecRule REQUEST_BODY \\\"Content-Disposition: form-data\\\" \\\"id:1,phase:3,pass,t:trim,msg:'s'\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: REQUEST_BODY\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"516\",\n        \"Content-Type\": \"multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2\",\n        \"Expect\": \"100-continue\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"----------------------------756b6d74fa1a8ee2\\n\",\n        \"Content-Disposition: form-data; name=\\\"name\\\"\\n\",\n        \"\\n\",\n        \"test\\n\",\n        \"----------------------------756b6d74fa1a8ee2\\n\",\n        \"Content-Disposition: form-data; name=\\\"filedata\\\"; filename=\\\"small_text_file.txt\\\"\\n\",\n        \"Content-Type: text/plain\\n\",\n        \"\\n\",\n        \"This is a very small test file..\\n\",\n        \"----------------------------756b6d74fa1a8ee2\\n\",\n        \"Content-Disposition: form-data; name=\\\"filedata\\\"; filename=\\\"small_text_file.txt\\\"\\n\",\n        \"Content-Type: text/plain\\n\",\n        \"\\n\",\n        \"This is another very small test file..\\n\",\n        \"----------------------------756b6d74fa1a8ee2--\\n\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"error_log\": \"o45,30v193,516t:trim\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRequestBodyAccess On\",\n      \"SecRule REQUEST_BODY \\\"Content-Disposition: form-data\\\" \\\"id:1,phase:3,pass,t:trim,msg:'s'\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: REQUEST_BODY_LENGTH\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"516\",\n        \"Content-Type\": \"multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2\",\n        \"Expect\": \"100-continue\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"----------------------------756b6d74fa1a8ee2\\n\",\n        \"Content-Disposition: form-data; name=\\\"name\\\"\\n\",\n        \"\\n\",\n        \"test\\n\",\n        \"----------------------------756b6d74fa1a8ee2\\n\",\n        \"Content-Disposition: form-data; name=\\\"filedata\\\"; filename=\\\"small_text_file.txt\\\"\\n\",\n        \"Content-Type: text/plain\\n\",\n        \"\\n\",\n        \"This is a very small test file..\\n\",\n        \"----------------------------756b6d74fa1a8ee2\\n\",\n        \"Content-Disposition: form-data; name=\\\"filedata\\\"; filename=\\\"small_text_file.txt\\\"\\n\",\n        \"Content-Type: text/plain\\n\",\n        \"\\n\",\n        \"This is another very small test file..\\n\",\n        \"----------------------------756b6d74fa1a8ee2--\\n\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"error_log\": \"v193,516t:trim\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRequestBodyAccess On\",\n      \"SecRule REQUEST_BODY_LENGTH \\\"@gt 5\\\" \\\"id:1,phase:3,pass,t:trim,msg:'s'\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: REQUEST_FILENAME 1\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"531\",\n        \"Content-Type\": \"multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2\",\n        \"Expect\": \"100-continue\"\n      },\n      \"uri\": \"/wheee/file?something else\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"----------------------------756b6d74fa1a8ee2\\r\\n\",\n        \"Content-Disposition: form-data; name=\\\"name\\\"\\r\\n\",\n        \"\\r\\n\",\n        \"test\\r\\n\",\n        \"----------------------------756b6d74fa1a8ee2\\r\\n\",\n        \"Content-Disposition: form-data; name=\\\"filedata\\\"; filename=\\\"small_text_file.txt\\\"\\r\\n\",\n        \"Content-Type: text/plain\\r\\n\",\n        \"\\r\\n\",\n        \"This is a very small test file..\\r\\n\",\n        \"----------------------------756b6d74fa1a8ee2\\r\\n\",\n        \"Content-Disposition: form-data; name=\\\"filedata\\\"; filename=\\\"small_text_file.txt\\\"\\r\\n\",\n        \"Content-Type: text/plain\\r\\n\",\n        \"\\r\\n\",\n        \"This is another very small test file..\\r\\n\",\n        \"----------------------------756b6d74fa1a8ee2--\\r\\n\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"error_log\": \"o6,5v5,11t:trim\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRequestBodyAccess On\",\n      \"SecRule REQUEST_FILENAME \\\"/file\\\" \\\"id:1,phase:3,pass,t:trim,msg:'s'\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: REQUEST_FILENAME 2\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"531\",\n        \"Content-Type\": \"multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2\",\n        \"Expect\": \"100-continue\"\n      },\n      \"uri\": \"/wheee/f%20i%20l%20e%20?something else\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"----------------------------756b6d74fa1a8ee2\\r\\n\",\n        \"Content-Disposition: form-data; name=\\\"name\\\"\\r\\n\",\n        \"\\r\\n\",\n        \"test\\r\\n\",\n        \"----------------------------756b6d74fa1a8ee2\\r\\n\",\n        \"Content-Disposition: form-data; name=\\\"filedata\\\"; filename=\\\"small_text_file.txt\\\"\\r\\n\",\n        \"Content-Type: text/plain\\r\\n\",\n        \"\\r\\n\",\n        \"This is a very small test file..\\r\\n\",\n        \"----------------------------756b6d74fa1a8ee2\\r\\n\",\n        \"Content-Disposition: form-data; name=\\\"filedata\\\"; filename=\\\"small_text_file.txt\\\"\\r\\n\",\n        \"Content-Type: text/plain\\r\\n\",\n        \"\\r\\n\",\n        \"This is another very small test file..\\r\\n\",\n        \"----------------------------756b6d74fa1a8ee2--\\r\\n\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"error_log\": \"o6,8v5,23t:trim\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRequestBodyAccess On\",\n      \"SecRule REQUEST_FILENAME \\\"/f i l e\\\" \\\"id:1,phase:3,pass,t:trim,msg:'s'\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: REQUEST_FILENAME 3\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"531\",\n        \"Content-Type\": \"multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2\",\n        \"Expect\": \"100-continue\"\n      },\n      \"uri\": \"/wheee/f%20i%20l%20e%20\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"----------------------------756b6d74fa1a8ee2\\r\\n\",\n        \"Content-Disposition: form-data; name=\\\"name\\\"\\r\\n\",\n        \"\\r\\n\",\n        \"test\\r\\n\",\n        \"----------------------------756b6d74fa1a8ee2\\r\\n\",\n        \"Content-Disposition: form-data; name=\\\"filedata\\\"; filename=\\\"small_text_file.txt\\\"\\r\\n\",\n        \"Content-Type: text/plain\\r\\n\",\n        \"\\r\\n\",\n        \"This is a very small test file..\\r\\n\",\n        \"----------------------------756b6d74fa1a8ee2\\r\\n\",\n        \"Content-Disposition: form-data; name=\\\"filedata\\\"; filename=\\\"small_text_file.txt\\\"\\r\\n\",\n        \"Content-Type: text/plain\\r\\n\",\n        \"\\r\\n\",\n        \"This is another very small test file..\\r\\n\",\n        \"----------------------------756b6d74fa1a8ee2--\\r\\n\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"error_log\": \"o6,8v5,23t:trim\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRequestBodyAccess On\",\n      \"SecRule REQUEST_FILENAME \\\"/f i l e\\\" \\\"id:1,phase:3,pass,t:trim,msg:'s'\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: ARGS/Multipart 1\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"518\",\n        \"Content-Type\": \"multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2\",\n        \"Expect\": \"100-continue\"\n      },\n      \"uri\": \"/wheee/f%20i%20l%20e%20\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"----------------------------756b6d74fa1a8ee2\\n\",\n        \"Content-Disposition: form-data; name=\\\"name\\\"\\n\",\n        \"\\n\",\n        \"test\\n\",\n        \"----------------------------756b6d74fa1a8ee2\\n\",\n        \"Content-Disposition: form-data; name=\\\"filedata\\\"; filename=\\\"small_text_file1.txt\\\"\\n\",\n        \"Content-Type: text/plain\\n\",\n        \"\\n\",\n        \"This is a very small test file..\\n\",\n        \"----------------------------756b6d74fa1a8ee2\\n\",\n        \"Content-Disposition: form-data; name=\\\"filedata\\\"; filename=\\\"small_text_file2.txt\\\"\\n\",\n        \"Content-Type: text/plain\\n\",\n        \"\\n\",\n        \"This is another very small test file..\\n\",\n        \"----------------------------756b6d74fa1a8ee2--\\n\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"error_log\": \"o0,4v306,4t:trim\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRequestBodyAccess On\",\n      \"SecRule ARGS \\\"test\\\" \\\"id:1,phase:3,pass,t:trim,msg:'s'\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: ARGS/Multipart 2\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"615\",\n        \"Content-Type\": \"multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2\",\n        \"Expect\": \"100-continue\"\n      },\n      \"uri\": \"/wheee/f%20i%20l%20e%20\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"----------------------------756b6d74fa1a8ee2\\n\",\n        \"Content-Disposition: form-data; name=\\\"name\\\"\\n\",\n        \"\\n\",\n        \"test\\n\",\n        \"----------------------------756b6d74fa1a8ee2\\n\",\n        \"Content-Disposition: form-data; name=\\\"name2\\\"\\n\",\n        \"\\n\",\n        \"test2\\n\",\n        \"----------------------------756b6d74fa1a8ee2\\n\",\n        \"Content-Disposition: form-data; name=\\\"filedata\\\"; filename=\\\"small_text_file1.txt\\\"\\n\",\n        \"Content-Type: text/plain\\n\",\n        \"\\n\",\n        \"This is a very small test file..\\n\",\n        \"----------------------------756b6d74fa1a8ee2\\n\",\n        \"Content-Disposition: form-data; name=\\\"filedata\\\"; filename=\\\"small_text_file2.txt\\\"\\n\",\n        \"Content-Type: text/plain\\n\",\n        \"\\n\",\n        \"This is another very small test file..\\n\",\n        \"----------------------------756b6d74fa1a8ee2--\\n\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"error_log\": \"o0,5v402,5t:trim\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRequestBodyAccess On\",\n      \"SecRule ARGS \\\"test2\\\" \\\"id:1,phase:3,pass,t:trim,msg:'s'\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Variable offset - FILES\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"624\",\n        \"Content-Type\": \"multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2\",\n        \"Expect\": \"100-continue\"\n      },\n      \"uri\": \"/wheee/f%20i%20l%20e%20\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"----------------------------756b6d74fa1a8ee2\\n\",\n        \"Content-Disposition: form-data; name=\\\"name\\\"\\n\",\n        \"\\n\",\n        \"test\\n\",\n        \"----------------------------756b6d74fa1a8ee2\\n\",\n        \"Content-Disposition: form-data; name=\\\"name2\\\"\\n\",\n        \"\\n\",\n        \"test2\\n\",\n        \"----------------------------756b6d74fa1a8ee2\\n\",\n        \"Content-Disposition: form-data; name=\\\"filedata\\\"; filename=\\\"small_text_file1.txt\\\"\\n\",\n        \"Content-Type: text/plain\\n\",\n        \"\\n\",\n        \"This is a very small test file..\\n\",\n        \"----------------------------756b6d74fa1a8ee2\\n\",\n        \"Content-Disposition: form-data; filename=\\\"small_text_file2.txt\\\"; name=\\\"fiasdfasdfledata\\\" \\n\",\n        \"Content-Type: text/plain\\n\",\n        \"\\n\",\n        \"This is another very small test file..\\n\",\n        \"----------------------------756b6d74fa1a8ee2--\\n\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"error_log\": \"o0,16v680,20t:trim\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRequestBodyAccess On\",\n      \"SecRule FILES \\\"small_text_file2\\\" \\\"id:1,phase:3,pass,t:trim,msg:'s'\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Variable offset - FILES\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"624\",\n        \"Content-Type\": \"multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2\",\n        \"Expect\": \"100-continue\"\n      },\n      \"uri\": \"/wheee/f%20i%20l%20e%20\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"----------------------------756b6d74fa1a8ee2\\n\",\n        \"Content-Disposition: form-data; name=\\\"name\\\"\\n\",\n        \"\\n\",\n        \"test\\n\",\n        \"----------------------------756b6d74fa1a8ee2\\n\",\n        \"Content-Disposition: form-data; name=\\\"name2\\\"\\n\",\n        \"\\n\",\n        \"test2\\n\",\n        \"----------------------------756b6d74fa1a8ee2\\n\",\n        \"Content-Disposition: form-data; name=\\\"filedata\\\"; filename=\\\"small_text_file1.txt\\\"\\n\",\n        \"Content-Type: text/plain\\n\",\n        \"\\n\",\n        \"This is a very small test file..\\n\",\n        \"----------------------------756b6d74fa1a8ee2\\n\",\n        \"Content-Disposition: form-data; filename=\\\"small_text_file2.txt\\\"; name=\\\"fiasdfasdfledata\\\" \\n\",\n        \"Content-Type: text/plain\\n\",\n        \"\\n\",\n        \"This is another very small test file..\\n\",\n        \"----------------------------756b6d74fa1a8ee2--\\n\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"error_log\": \"o0,16v512,20t:trim\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRequestBodyAccess On\",\n      \"SecRule FILES \\\"small_text_file1\\\" \\\"id:1,phase:3,pass,t:trim,msg:'s'\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Variable offset - FILES_NAMES\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"624\",\n        \"Content-Type\": \"multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2\",\n        \"Expect\": \"100-continue\"\n      },\n      \"uri\": \"/wheee/f%20i%20l%20e%20\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"----------------------------756b6d74fa1a8ee2\\n\",\n        \"Content-Disposition: form-data; name=\\\"name\\\"\\n\",\n        \"\\n\",\n        \"test\\n\",\n        \"----------------------------756b6d74fa1a8ee2\\n\",\n        \"Content-Disposition: form-data; name=\\\"name2\\\"\\n\",\n        \"\\n\",\n        \"test2\\n\",\n        \"----------------------------756b6d74fa1a8ee2\\n\",\n        \"Content-Disposition: form-data; name=\\\"filedata\\\"; filename=\\\"small_text_file1.txt\\\"\\n\",\n        \"Content-Type: text/plain\\n\",\n        \"\\n\",\n        \"This is a very small test file..\\n\",\n        \"----------------------------756b6d74fa1a8ee2\\n\",\n        \"Content-Disposition: form-data; filename=\\\"small_text_file2.txt\\\"; name=\\\"fiasdfasdfledata\\\" \\n\",\n        \"Content-Type: text/plain\\n\",\n        \"\\n\",\n        \"This is another very small test file..\\n\",\n        \"----------------------------756b6d74fa1a8ee2--\\n\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"error_log\": \"o0,8o0,8v491,8t:trimo0,16o0,16v709,16t:trim\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRequestBodyAccess On\",\n      \"SecRule FILES_NAMES \\\"(fiasdfasdfledata|filedata)\\\" \\\"id:1,phase:3,pass,t:trim,msg:'s'\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Variable offset - FILES_SIZES 1\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"624\",\n        \"Content-Type\": \"multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2\",\n        \"Expect\": \"100-continue\"\n      },\n      \"uri\": \"/wheee/f%20i%20l%20e%20\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"----------------------------756b6d74fa1a8ee2\\n\",\n        \"Content-Disposition: form-data; name=\\\"name\\\"\\n\",\n        \"\\n\",\n        \"test\\n\",\n        \"----------------------------756b6d74fa1a8ee2\\n\",\n        \"Content-Disposition: form-data; name=\\\"name2\\\"\\n\",\n        \"\\n\",\n        \"test2\\n\",\n        \"----------------------------756b6d74fa1a8ee2\\n\",\n        \"Content-Disposition: form-data; name=\\\"filedata\\\"; filename=\\\"small_text_file1.txt\\\"\\n\",\n        \"Content-Type: text/plain\\n\",\n        \"\\n\",\n        \"This is a very small test file..\\n\",\n        \"----------------------------756b6d74fa1a8ee2\\n\",\n        \"Content-Disposition: form-data; filename=\\\"small_text_file2.txt\\\"; name=\\\"fiasdfasdfledata\\\" \\n\",\n        \"Content-Type: text/plain\\n\",\n        \"\\n\",\n        \"This is another very small test file..\\n\",\n        \"----------------------------756b6d74fa1a8ee2--\\n\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"error_log\": \"v560,32t:trim\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRequestBodyAccess On\",\n      \"SecRule FILES_SIZES:filedata \\\"@gt 0\\\" \\\"id:1,phase:3,pass,t:trim,msg:'s'\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Variable offset - FILES_SIZES 2\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"624\",\n        \"Content-Type\": \"multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2\",\n        \"Expect\": \"100-continue\"\n      },\n      \"uri\": \"/wheee/f%20i%20l%20e%20\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"----------------------------756b6d74fa1a8ee2\\n\",\n        \"Content-Disposition: form-data; name=\\\"name\\\"\\n\",\n        \"\\n\",\n        \"test\\n\",\n        \"----------------------------756b6d74fa1a8ee2\\n\",\n        \"Content-Disposition: form-data; name=\\\"name2\\\"\\n\",\n        \"\\n\",\n        \"test2\\n\",\n        \"----------------------------756b6d74fa1a8ee2\\n\",\n        \"Content-Disposition: form-data; name=\\\"filedata\\\"; filename=\\\"small_text_file1.txt\\\"\\n\",\n        \"Content-Type: text/plain\\n\",\n        \"\\n\",\n        \"This is a very small test file..\\n\",\n        \"----------------------------756b6d74fa1a8ee2\\n\",\n        \"Content-Disposition: form-data; filename=\\\"small_text_file2.txt\\\"; name=\\\"fiasdfasdfledata\\\" \\n\",\n        \"Content-Type: text/plain\\n\",\n        \"\\n\",\n        \"This is another very small test file..\\n\",\n        \"----------------------------756b6d74fa1a8ee2--\\n\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"error_log\": \"v754,38t:trim\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRequestBodyAccess On\",\n      \"SecRule FILES_SIZES:fiasdfasdfledata \\\"@gt 0\\\" \\\"id:1,phase:3,pass,t:trim,msg:'s'\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Variable offset - FILES_COMBINED_SIZE\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"624\",\n        \"Content-Type\": \"multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2\",\n        \"Expect\": \"100-continue\"\n      },\n      \"uri\": \"/wheee/f%20i%20l%20e%20\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"----------------------------756b6d74fa1a8ee2\\n\",\n        \"Content-Disposition: form-data; name=\\\"name\\\"\\n\",\n        \"\\n\",\n        \"test\\n\",\n        \"----------------------------756b6d74fa1a8ee2\\n\",\n        \"Content-Disposition: form-data; name=\\\"name2\\\"\\n\",\n        \"\\n\",\n        \"test2\\n\",\n        \"----------------------------756b6d74fa1a8ee2\\n\",\n        \"Content-Disposition: form-data; name=\\\"filedata\\\"; filename=\\\"small_text_file1.txt\\\"\\n\",\n        \"Content-Type: text/plain\\n\",\n        \"\\n\",\n        \"This is a very small test file..\\n\",\n        \"----------------------------756b6d74fa1a8ee2\\n\",\n        \"Content-Disposition: form-data; filename=\\\"small_text_file2.txt\\\"; name=\\\"fiasdfasdfledata\\\" \\n\",\n        \"Content-Type: text/plain\\n\",\n        \"\\n\",\n        \"This is another very small test file..\\n\",\n        \"----------------------------756b6d74fa1a8ee2--\\n\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"error_log\": \"v560,32v754,38t:trim\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRequestBodyAccess On\",\n      \"SecRule FILES_COMBINED_SIZE \\\"@gt 0\\\" \\\"id:1,phase:3,pass,t:trim,msg:'s'\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Variable offset - FILES_TMP_CONTENT 1\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"624\",\n        \"Content-Type\": \"multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2\",\n        \"Expect\": \"100-continue\"\n      },\n      \"uri\": \"/wheee/f%20i%20l%20e%20\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"----------------------------756b6d74fa1a8ee2\\n\",\n        \"Content-Disposition: form-data; name=\\\"name\\\"\\n\",\n        \"\\n\",\n        \"test\\n\",\n        \"----------------------------756b6d74fa1a8ee2\\n\",\n        \"Content-Disposition: form-data; name=\\\"name2\\\"\\n\",\n        \"\\n\",\n        \"test2\\n\",\n        \"----------------------------756b6d74fa1a8ee2\\n\",\n        \"Content-Disposition: form-data; name=\\\"filedata\\\"; filename=\\\"small_text_file1.txt\\\"\\n\",\n        \"Content-Type: text/plain\\n\",\n        \"\\n\",\n        \"This is a very small test file..\\n\",\n        \"----------------------------756b6d74fa1a8ee2\\n\",\n        \"Content-Disposition: form-data; filename=\\\"small_text_file2.txt\\\"; name=\\\"fiasdfasdfledata\\\" \\n\",\n        \"Content-Type: text/plain\\n\",\n        \"\\n\",\n        \"This is another very small test file..\\n\",\n        \"----------------------------756b6d74fa1a8ee2--\\n\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"error_log\": \"o8,7v754,38t:trim\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRequestBodyAccess On\",\n      \"SecUploadKeepFiles On\",\n      \"SecUploadDir /tmp\",\n      \"SecRule FILES_TMP_CONTENT \\\"another\\\" \\\"id:1,phase:3,pass,t:trim,msg:'s'\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Variable offset - FILES_TMP_CONTENT 2\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"624\",\n        \"Content-Type\": \"multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2\",\n        \"Expect\": \"100-continue\"\n      },\n      \"uri\": \"/wheee/f%20i%20l%20e%20\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"----------------------------756b6d74fa1a8ee2\\n\",\n        \"Content-Disposition: form-data; name=\\\"name\\\"\\n\",\n        \"\\n\",\n        \"test\\n\",\n        \"----------------------------756b6d74fa1a8ee2\\n\",\n        \"Content-Disposition: form-data; name=\\\"name2\\\"\\n\",\n        \"\\n\",\n        \"test2\\n\",\n        \"----------------------------756b6d74fa1a8ee2\\n\",\n        \"Content-Disposition: form-data; name=\\\"filedata\\\"; filename=\\\"small_text_file1.txt\\\"\\n\",\n        \"Content-Type: text/plain\\n\",\n        \"\\n\",\n        \"This is a very small test file..\\n\",\n        \"----------------------------756b6d74fa1a8ee2\\n\",\n        \"Content-Disposition: form-data; filename=\\\"small_text_file2.txt\\\"; name=\\\"fiasdfasdfledata\\\" \\n\",\n        \"Content-Type: text/plain\\n\",\n        \"\\n\",\n        \"This is another very small test file..\\n\",\n        \"----------------------------756b6d74fa1a8ee2--\\n\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"error_log\": \"o15,5v560,32t:trim\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRequestBodyAccess On\",\n      \"SecUploadKeepFiles On\",\n      \"SecUploadDir /tmp\",\n      \"SecRule FILES_TMP_CONTENT:filedata \\\"small\\\" \\\"id:1,phase:3,pass,t:trim,msg:'s'\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Variable offset - PATH_INFO\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"643\",\n        \"Content-Type\": \"multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2\",\n        \"Expect\": \"100-continue\"\n      },\n      \"uri\": \"/wheee/f%20i%20l%20e%20\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"----------------------------756b6d74fa1a8ee2\\r\\n\",\n        \"Content-Disposition: form-data; name=\\\"name\\\"\\r\\n\",\n        \"\\r\\n\",\n        \"test\\r\\n\",\n        \"----------------------------756b6d74fa1a8ee2\\r\\n\",\n        \"Content-Disposition: form-data; name=\\\"name2\\\"\\r\\n\",\n        \"\\r\\n\",\n        \"test2\\r\\n\",\n        \"----------------------------756b6d74fa1a8ee2\\r\\n\",\n        \"Content-Disposition: form-data; name=\\\"filedata\\\"; filename=\\\"small_text_file1.txt\\\"\\r\\n\",\n        \"Content-Type: text/plain\\r\\n\",\n        \"\\r\\n\",\n        \"This is a very small test file..\\r\\n\",\n        \"----------------------------756b6d74fa1a8ee2\\r\\n\",\n        \"Content-Disposition: form-data; filename=\\\"small_text_file2.txt\\\"; name=\\\"fiasdfasdfledata\\\" \\r\\n\",\n        \"Content-Type: text/plain\\r\\n\",\n        \"\\r\\n\",\n        \"This is another very small test file..\\r\\n\",\n        \"----------------------------756b6d74fa1a8ee2--\\r\\n\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"error_log\": \"o6,4v5,23t:trim\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRequestBodyAccess On\",\n      \"SecUploadKeepFiles On\",\n      \"SecUploadDir /tmp\",\n      \"SecRule PATH_INFO \\\"/f i\\\" \\\"id:1,phase:3,pass,t:trim,msg:'s'\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Variable offset - MULTIPART_FILENAME\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"624\",\n        \"Content-Type\": \"multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2\",\n        \"Expect\": \"100-continue\"\n      },\n      \"uri\": \"/wheee/f%20i%20l%20e%20\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"----------------------------756b6d74fa1a8ee2\\n\",\n        \"Content-Disposition: form-data; name=\\\"name\\\"\\n\",\n        \"\\n\",\n        \"test\\n\",\n        \"----------------------------756b6d74fa1a8ee2\\n\",\n        \"Content-Disposition: form-data; name=\\\"name2\\\"\\n\",\n        \"\\n\",\n        \"test2\\n\",\n        \"----------------------------756b6d74fa1a8ee2\\n\",\n        \"Content-Disposition: form-data; name=\\\"filedata\\\"; filename=\\\"small_text_file1.txt\\\"\\n\",\n        \"Content-Type: text/plain\\n\",\n        \"\\n\",\n        \"This is a very small test file..\\n\",\n        \"----------------------------756b6d74fa1a8ee2\\n\",\n        \"Content-Disposition: form-data; filename=\\\"small_text_file2.txt\\\"; name=\\\"fiasdfasdfledata\\\" \\n\",\n        \"Content-Type: text/plain\\n\",\n        \"\\n\",\n        \"This is another very small test file..\\n\",\n        \"----------------------------756b6d74fa1a8ee2--\\n\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"error_log\": \"o0,20v680,20t:trim\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRequestBodyAccess On\",\n      \"SecUploadKeepFiles On\",\n      \"SecUploadDir /tmp\",\n      \"SecRule MULTIPART_FILENAME \\\"small_text_file2.txt\\\" \\\"id:1,phase:3,pass,t:trim,msg:'s'\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Variable offset - MULTIPART_NAME\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"624\",\n        \"Content-Type\": \"multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2\",\n        \"Expect\": \"100-continue\"\n      },\n      \"uri\": \"/wheee/f%20i%20l%20e%20\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"----------------------------756b6d74fa1a8ee2\\n\",\n        \"Content-Disposition: form-data; name=\\\"name\\\"\\n\",\n        \"\\n\",\n        \"test\\n\",\n        \"----------------------------756b6d74fa1a8ee2\\n\",\n        \"Content-Disposition: form-data; name=\\\"name2\\\"\\n\",\n        \"\\n\",\n        \"test2\\n\",\n        \"----------------------------756b6d74fa1a8ee2\\n\",\n        \"Content-Disposition: form-data; name=\\\"filedata\\\"; filename=\\\"small_text_file1.txt\\\"\\n\",\n        \"Content-Type: text/plain\\n\",\n        \"\\n\",\n        \"This is a very small test file..\\n\",\n        \"----------------------------756b6d74fa1a8ee2\\n\",\n        \"Content-Disposition: form-data; filename=\\\"small_text_file2.txt\\\"; name=\\\"fiasdfasdfledata\\\" \\n\",\n        \"Content-Type: text/plain\\n\",\n        \"\\n\",\n        \"This is another very small test file..\\n\",\n        \"----------------------------756b6d74fa1a8ee2--\\n\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"error_log\": \"o0,16v709,16t:trim\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRequestBodyAccess On\",\n      \"SecUploadKeepFiles On\",\n      \"SecUploadDir /tmp\",\n      \"SecRule MULTIPART_NAME \\\"fiasdfasdfledata\\\" \\\"id:1,phase:3,pass,t:trim,msg:'s'\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Variable offset - ARGS n\",\n    \"client\": {\n      \"ip\": \"\",\n      \"port\": 0\n    },\n    \"server\": {\n      \"ip\": \"\",\n      \"port\": 0\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"Content-Length\": \"0\",\n        \"Content-Type\": \"application/x-www-form-urlencoded\"\n      },\n      \"uri\": \"/index.html?param01=5555&bbbbbbbmy_id=6\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"error_log\": \"o0,1v42,1\",\n      \"http_code\": 403\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule ARGS \\\"@contains 6\\\" \\\"id:1,phase:2,deny,status:403,log\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Variable offset - ARGS_NAMES n\",\n    \"client\": {\n      \"ip\": \"\",\n      \"port\": 0\n    },\n    \"server\": {\n      \"ip\": \"\",\n      \"port\": 0\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"Content-Length\": \"0\",\n        \"Content-Type\": \"application/x-www-form-urlencoded\"\n      },\n      \"uri\": \"/index.html?param01=5555&bbbbbbbmy_id=6\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"error_log\": \"o7,5v29,12\",\n      \"http_code\": 403\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule ARGS_NAMES \\\"@contains my_id\\\" \\\"id:1,phase:2,deny,status:403,log\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/operator-UnconditionalMatch.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Operator :: @UnconditionalMatch\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"27\",\n        \"Content-Type\": \"application/x-www-form-urlencoded\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"param1=value1&param2=value2\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Rule returned 1\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule ARGS \\\"@UnconditionalMatch\\\" \\\"id:1,phase:2,pass,t:trim\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/operator-detectsqli.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Operator :: @detectSQLi\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"61\",\n        \"Content-Type\": \"application/x-www-form-urlencoded\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"param1=ascii(substring(version() from 1 for 1))&param2=value2\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Added DetectSQLi match TX.0: f\\\\(f\\\\(f\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule ARGS \\\"@detectSQLi\\\" \\\"id:1,phase:2,capture,pass,t:trim\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/operator-detectxss.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Operator :: @detectXSS\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"45\",\n        \"Content-Type\": \"application/x-www-form-urlencoded\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"param1=<script>alert(1)</script&param2=value2\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Added DetectXSS match TX.0: <script>alert\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule ARGS \\\"@detectXSS\\\" \\\"id:1,phase:2,capture,pass,t:trim\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/operator-fuzzyhash.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Operator :: @fuzzyHash (1/2)\",\n    \"resource\": \"ssdeep\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"2432\",\n        \"Content-Type\": \"application/x-www-form-urlencoded\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"\\n\",\n        \"# -- Rule engine initialization ----------------------------------------------\\n\",\n        \"\\n\",\n        \"# Enable ModSecurity, attaching it to every transaction. Use detection\\n\",\n        \"# only to start with, because that minimises the chances of post-installation\\n\",\n        \"# disruption.\\n\",\n        \"#\\n\",\n        \"SecRuleEngine DetectionOnly\\n\",\n        \"\\n\",\n        \"\\n\",\n        \"# -- Request body handling ---------------------------------------------------\\n\",\n        \"\\n\",\n        \"# Allow ModSecurity to access request bodies. If you don't, ModSecurity\\n\",\n        \"# won't be able to see any POST parameters, which opens a large security\\n\",\n        \"# hole for attackers to exploit.\\n\",\n        \"#\\n\",\n        \"SecRequestBodyAccess On\\n\",\n        \"\\n\",\n        \"\\n\",\n        \"# Enable XML request body parser.\\n\",\n        \"# Initiate XML Processor in case of xml content-type\\n\",\n        \"#\\n\",\n        \"SecRule REQUEST_HEADERS:Content-Type \\\"text/xml\\\" \\\\\\n\",\n        \"     \\\"id:'200000',phase:1,t:none,t:lowercase,pass,nolog,ctl:requestBodyProcessor=XML\\\"\\n\",\n        \"\\n\",\n        \"# Enable JSON request body parser.\\n\",\n        \"# Initiate JSON Processor in case of JSON content-type; change accordingly\\n\",\n        \"# if your application does not use 'application/json'\\n\",\n        \"#\\n\",\n        \"SecRule REQUEST_HEADERS:Content-Type \\\"application/json\\\" \\\\\\n\",\n        \"     \\\"id:'200001',phase:1,t:none,t:lowercase,pass,nolog,ctl:requestBodyProcessor=JSON\\\"\\n\",\n        \"\\n\",\n        \"# Maximum request body size we will accept for buffering. If you support\\n\",\n        \"# file uploads then the value given on the first line has to be as large\\n\",\n        \"# as the largest file you are willing to accept. The second value refers\\n\",\n        \"# to the size of data, with files excluded. You want to keep that value as\\n\",\n        \"# low as practical.\\n\",\n        \"#\\n\",\n        \"SecRequestBodyLimit 13107200\\n\",\n        \"SecRequestBodyNoFilesLimit 131072\\n\",\n        \"\\n\",\n        \"# Store up to 128 KB of request body data in memory. When the multipart\\n\",\n        \"# parser reachers this limit, it will start using your hard disk for\\n\",\n        \"# storage. That is slow, but unavoidable.\\n\",\n        \"#\\n\",\n        \"SecRequestBodyInMemoryLimit 131072\\n\",\n        \"\\n\",\n        \"# What do do if the request body size is above our configured limit.\\n\",\n        \"# Keep in mind that this setting will automatically be set to ProcessPartial\\n\",\n        \"# when SecRuleEngine is set to DetectionOnly mode in order to minimize\\n\",\n        \"# disruptions when initially deploying ModSecurity.\\n\",\n        \"#\\n\",\n        \"SecRequestBodyLimitAction Reject\\n\",\n        \"\\n\",\n        \"# Verify that we've correctly processed the request body.\\n\",\n        \"# As a rule of thumb, when failing to process a request body\\n\",\n        \"# you should reject the request (when deployed in blocking mode)\\n\",\n        \"# or log a high-severity alert (when deployed in detection-only mode).\\n\",\n        \"#\\n\",\n        \"SecRule REQBODY_ERROR \\\"!\\\\@eq 0\\\" \\n\",\n        \"\\\"id:'200002', phase:2,t:none,log,deny,status:400,msg:'Failed to parse request body.',logdata:'%{reqbody_error_msg}',severity:2\\\"\\n\",\n        \"       \\n\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \" Fuzzy hash: matched with score: 54.\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRequestBodyAccess On\",\n      \"SecRule REQUEST_BODY \\\"@fuzzyHash test-cases/data/ssdeep.txt 1\\\" \\\"id:1,phase:2,pass,t:trim\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Operator :: @fuzzyHash (2/2)\",\n    \"resource\": \"ssdeep\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"2370\",\n        \"Content-Type\": \"application/x-www-form-urlencoded\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"\",\n        \"# -- Rule engine initialization ----------------------------------------------\",\n        \"\",\n        \"# Enable ModSecurity, attaching it to every transaction. Use detection\",\n        \"# only to start with, because that minimises the chances of post-installation\",\n        \"# disruption.\",\n        \"#\",\n        \"SecRuleEngine DetectionOnly\",\n        \"\",\n        \"\",\n        \"# -- Request body handling ---------------------------------------------------\",\n        \"\",\n        \"# Allow ModSecurity to access request bodies. If you don't, ModSecurity\",\n        \"# won't be able to see any POST parameters, which opens a large security\",\n        \"# hole for attackers to exploit.\",\n        \"#\",\n        \"SecRequestBodyAccess On\",\n        \"\",\n        \"\",\n        \"# Enable XML request body parser.\",\n        \"# Initiate XML Processor in case of xml content-type\",\n        \"#\",\n        \"SecRule REQUEST_HEADERS:Content-Type \\\"text/xml\\\" \\\\\",\n        \"     \\\"id:'200000',phase:1,t:none,t:lowercase,pass,nolog,ctl:requestBodyProcessor=XML\\\"\",\n        \"\",\n        \"# Enable JSON request body parser.\",\n        \"# Initiate JSON Processor in case of JSON content-type; change accordingly\",\n        \"# if your application does not use 'application/json'\",\n        \"#\",\n        \"SecRule REQUEST_HEADERS:Content-Type \\\"application/json\\\" \\\\\",\n        \"     \\\"id:'200001',phase:1,t:none,t:lowercase,pass,nolog,ctl:requestBodyProcessor=JSON\\\"\",\n        \"\",\n        \"# Maximum request body size we will accept for buffering. If you support\",\n        \"# file uploads then the value given on the first line has to be as large\",\n        \"# as the largest file you are willing to accept. The second value refers\",\n        \"# to the size of data, with files excluded. You want to keep that value as\",\n        \"# low as practical.\",\n        \"#\",\n        \"SecRequestBodyLimit 13107200\",\n        \"SecRequestBodyNoFilesLimit 131072\",\n        \"\",\n        \"# Store up to 128 KB of request body data in memory. When the multipart\",\n        \"# parser reachers this limit, it will start using your hard disk for\",\n        \"# storage. That is slow, but unavoidable.\",\n        \"#\",\n        \"SecRequestBodyInMemoryLimit 131072\",\n        \"\",\n        \"# What do do if the request body size is above our configured limit.\",\n        \"# Keep in mind that this setting will automatically be set to ProcessPartial\",\n        \"# when SecRuleEngine is set to DetectionOnly mode in order to minimize\",\n        \"# disruptions when initially deploying ModSecurity.\",\n        \"#\",\n        \"SecRequestBodyLimitAction Reject\",\n        \"\",\n        \"# Verify that we've correctly processed the request body.\",\n        \"# As a rule of thumb, when failing to process a request body\",\n        \"# you should reject the request (when deployed in blocking mode)\",\n        \"# or log a high-severity alert (when deployed in detection-only mode).\",\n        \"#\",\n        \"SecRule REQBODY_ERROR \\\"!\\\\@eq 0\\\" \",\n        \"\\\"id:'200002', phase:2,t:none,log,deny,status:400,msg:'Failed to parse request body.',logdata:'%{reqbody_error_msg}',severity:2\\\"\",\n        \"       \"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Rule returned 0.\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRequestBodyAccess On\",\n      \"SecRule REQUEST_BODY \\\"@fuzzyHash test-cases/data/ssdeep.txt 100\\\" \\\"id:1,phase:2,pass,t:trim\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/operator-inpectFile.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Operator :: @inspectFile (1/3)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\",\n        \"Content-Type\": \"application/x-www-form-urlencoded\"\n      },\n      \"uri\": \"/whee?res=1\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Rule returned 0.\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule ARGS:res \\\"@inspectFile /bin/echo\\\" \\\"id:1,phase:2,pass,t:trim\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Operator :: @inspectFile (2/3)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\",\n        \"Content-Type\": \"application/x-www-form-urlencoded\"\n      },\n      \"uri\": \"/whee?res=0\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Rule returned 1.\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule ARGS:res \\\"@inspectFile /bin/echo\\\" \\\"id:1,phase:2,pass,t:trim\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Operator :: @inspectFile (3/3)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\",\n        \"Content-Type\": \"application/x-www-form-urlencoded\"\n      },\n      \"uri\": \"/whee?res=whee\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Rule returned 1.\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule ARGS:res \\\"@inspectFile /bin/echo\\\" \\\"id:1,phase:2,pass,t:trim\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Operator :: @inspectFile - lua (1/7)\",\n    \"resource\": \"lua\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\",\n        \"Content-Type\": \"application/x-www-form-urlencoded\"\n      },\n      \"uri\": \"/whee?res=whee\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Rule returned 1.\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule ARGS:res \\\"@inspectFile test-cases/data/match.lua\\\" \\\"id:1,phase:2,pass,t:trim\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Operator :: @inspectFile - lua (2/7)\",\n    \"resource\": \"lua\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\",\n        \"Content-Type\": \"application/x-www-form-urlencoded\"\n      },\n      \"uri\": \"/whee?res=whee\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"echo 123\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule ARGS:res \\\"@inspectFile test-cases/data/match-log.lua\\\" \\\"id:1,phase:2,pass,t:trim\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Operator :: @inspectFile - lua (3/7)\",\n    \"resource\": \"lua\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\",\n        \"Content-Type\": \"application/x-www-form-urlencoded\"\n      },\n      \"uri\": \"/whee?res=whee\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"whee\\\" \",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule ARGS:res \\\"@inspectFile test-cases/data/match-set.lua\\\" \\\"id:1,phase:2,pass,t:trim\\\"\",\n      \"SecRule TX:test \\\"whee\\\" \\\"id:2,phase:2,pass,t:trim\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Operator :: @inspectFile - lua (4/7)\",\n    \"resource\": \"lua\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\",\n        \"Content-Type\": \"application/x-www-form-urlencoded\"\n      },\n      \"uri\": \"/whee?res=whee\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Number is bigger than one.\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule ARGS \\\".\\\" \\\"id:2,phase:2,setvar:tx.test=2\\\"\",\n      \"SecRule ARGS:res \\\"@inspectFile test-cases/data/match-getvar.lua\\\" \\\"id:1,phase:2,pass,t:trim\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Operator :: @inspectFile - lua (5/7)\",\n    \"resource\": \"lua\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\",\n        \"Content-Type\": \"application/x-www-form-urlencoded\"\n      },\n      \"uri\": \"/whee?res=whee&z=z&d=e\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Z: \\\\{ \\\\[1\\\\] = \\\\{ \\\\[\\\"\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule QUERY_STRING \\\".\\\" \\\"id:2,phase:2,setvar:tx.test=2\\\"\",\n      \"SecRule ARGS:res \\\"@inspectFile test-cases/data/match-getvars.lua\\\" \\\"id:1,phase:2,pass,t:trim\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Operator :: @inspectFile - lua (6/7)\",\n    \"resource\": \"lua\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\",\n        \"Content-Type\": \"application/x-www-form-urlencoded\"\n      },\n      \"uri\": \"/whee?res=whee&z=z&d=e\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Just fine.\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule QUERY_STRING \\\".\\\" \\\"id:2,phase:2,setvar:tx.test=FELIPE\\\"\",\n      \"SecRule QUERY_STRING \\\"@inspectFile test-cases/data/match-getvar-transformation.lua\\\" \\\"id:1,phase:2,pass\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Operator :: @inspectFile - lua (7/7)\",\n    \"resource\": \"lua\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\",\n        \"Content-Type\": \"application/x-www-form-urlencoded\"\n      },\n      \"uri\": \"/whee?res=whee&z=z&d=e\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Whee. Working like a charm. That is what we have: FELIPE\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule QUERY_STRING \\\".\\\" \\\"id:2,phase:2,setvar:tx.test=FeLiPe\\\"\",\n      \"SecRule QUERY_STRING \\\"@inspectFile test-cases/data/match-getvar-multi-transformations.lua\\\" \\\"id:1,phase:2,pass\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/operator-ipMatchFromFile.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Operator :: @ipMatchFromFile\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"27\",\n        \"Content-Type\": \"application/x-www-form-urlencoded\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"param1=value1&param2=value2\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Rule returned 1\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule REMOTE_ADDR \\\"@ipMatchFromFile test-cases/data/ipMatchFromFile.txt\\\" \\\"id:1,phase:3,pass,t:trim\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Operator :: @ipMatchFromFile - file not found\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"27\",\n        \"Content-Type\": \"application/x-www-form-urlencoded\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"param1=value1&param2=value2\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"http_code\": 200,\n      \"parser_error\": \"Rules error. File: operator-ipMatchFromFile.json. Line: 2. Column: 19. Looking at: 'file-not-found.txt', 'file-not-found.txt', 'operator-ipMatchFromFile.json/file-not-found.txt', 'operator-ipMatchFromFile.json/file-not-found.txt'.\"\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule REMOTE_ADDR \\\"@ipMatchFromFile file-not-found.txt\\\" \\\"id:1,phase:3,pass,t:trim\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Operator :: @ipMatchFromFile - https\",\n    \"resource\": \"curl\",\n    \"client\": {\n      \"ip\": \"8.8.4.4\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"27\",\n        \"Content-Type\": \"application/x-www-form-urlencoded\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"param1=value1&param2=value2\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Rule returned 1.\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule REMOTE_ADDR \\\"@ipMatchFromFile https://raw.githubusercontent.com/owasp-modsecurity/ModSecurity/refs/heads/v3/master/test/modsecurity-regression-ip-list.txt\\\" \\\"id:1,phase:3,pass,t:trim\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/operator-pm.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"version_max\": 0,\n    \"title\": \"pm operator test 1/6\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 2313\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"net.tutsplus.com\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/test.pl?param1=something`somenthing\",\n      \"method\": \"GET\",\n      \"http_version\": 1.1,\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Type\": \"text/xml; charset=utf-8\\n\\r\",\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Rule returned 1\",\n      \"http_code\": 500\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule ARGS \\\"@pm a ` b\\\" \\\"phase:1,id:999,deny,status:500\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"version_max\": 0,\n    \"title\": \"pm operater test 2/4\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 2313\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"net.tutsplus.com\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/test.pl?param1=`somenthing\",\n      \"method\": \"GET\",\n      \"http_version\": 1.1,\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Type\": \"text/xml; charset=utf-8\\n\\r\",\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"http_code\": 500\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule ARGS \\\"@pm a ` b\\\" \\\"phase:1,id:999,deny,status:500\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"version_max\": 0,\n    \"title\": \"pm operater test 3/6\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 2313\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"net.tutsplus.com\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/test.pl?param1=a\",\n      \"method\": \"GET\",\n      \"http_version\": 1.1,\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Type\": \"text/xml; charset=utf-8\\n\\r\",\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Rule returned 1\",\n      \"http_code\": 500\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule ARGS \\\"@pm a ` b\\\" \\\"phase:1,id:999,deny,status:500\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"version_max\": 0,\n    \"title\": \"pm operater test 4/6\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 2313\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"net.tutsplus.com\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/test.pl?param1=a`b\",\n      \"method\": \"GET\",\n      \"http_version\": 1.1,\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Type\": \"text/xml; charset=utf-8\\n\\r\",\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Rule returned 1\",\n      \"http_code\": 500\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule ARGS \\\"@pm a ` b\\\" \\\"phase:1,id:999,deny,status:500\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"version_max\": 0,\n    \"title\": \"pm operater test 5/6\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 2313\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"net.tutsplus.com\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/test.pl?param1=123\",\n      \"method\": \"GET\",\n      \"http_version\": 1.1,\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Type\": \"text/xml; charset=utf-8\\n\\r\",\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Rule returned 1\",\n      \"http_code\": 403\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule ARGS \\\"@pm 1 2 3\\\" \\\"phase:1,id:999,deny\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"version_max\": 0,\n    \"title\": \"pm operater test 6/6\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 2313\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"net.tutsplus.com\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/test.pl?param1=abc\",\n      \"method\": \"GET\",\n      \"http_version\": 1.1,\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Type\": \"text/xml; charset=utf-8\\n\\r\",\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Rule returned 0\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule ARGS \\\"@pm 1 2 3\\\" \\\"phase:1,id:999,deny\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/operator-pmfromfile.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"version_max\": 0,\n    \"title\": \"pmFromFile operator test\",\n    \"client\": {\n      \"ip\": \"10.20.30.40\",\n      \"port\": 2313\n    },\n    \"server\": {\n      \"ip\": \"1.2.3.4\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"foobar.com\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/test.php?param1=pattern2\",\n      \"method\": \"GET\",\n      \"http_version\": 1.1,\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Type\": \"text/html; charset=utf-8\\n\\r\",\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Rule returned 1\",\n      \"http_code\": 403\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule ARGS \\\"@pmFromFile test-cases/data/pattern-file1.data test-cases/data/pattern-file2.data\\\" \\\"phase:1,id:999,deny\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/operator-rx.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Operator :: @rx\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"27\",\n        \"Content-Type\": \"application/x-www-form-urlencoded\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"param1=value1&param2=value2\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Executing operator \\\"Rx\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule ARGS \\\"@rx (value1)\\\" \\\"id:1,phase:2,pass,t:trim\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Operator :: @rx in implicit form with negation ('!')\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"3\",\n        \"Content-Type\": \"application/x-www-form-urlencoded\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"HEAD\",\n      \"body\": [\n        \"a=1\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Executing operator \\\"Rx\\\" with param \\\"\\\\^0\\\\$\\\"\",\n      \"error_log\": \"Matched \\\"Operator `Rx' with parameter `\\\\^0\\\\$'\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule REQUEST_HEADERS:Content-Length \\\"!^0$\\\" \\\"id:1,phase:2,pass,t:trim,block\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Operator :: @rx with non-compiling pattern\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\",\n        \"Content-Type\": \"application/x-www-form-urlencoded\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"HEAD\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Error with regular expression\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule REQUEST_HEADERS:Content-Type \\\"@rx a(b\\\" \\\"id:1,phase:2,pass,t:trim,block\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Operator :: @rx with PCRE error\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\",\n        \"Content-Type\": \"application/x-www-form-urlencoded\"\n      },\n      \"uri\": \"/?rxtest=wwwwwwwwwwwwwwwwwwwwwowwwwwwwwwww\",\n      \"method\": \"HEAD\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"rx: regex error 'MATCH_LIMIT' for pattern\",\n      \"error_log\": \"Matched \\\"Operator `StrEq' with parameter `1' against variable `MSC_PCRE_ERROR'\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecPcreMatchLimit 2\",\n      \"SecRule ARGS:rxtest \\\"@rx (w+)+$\\\" \\\"id:1,phase:1,pass,t:trim,block\\\"\",\n      \"SecRule MSC_PCRE_ERROR \\\"@streq 1\\\" \\\"id:2,phase:1,pass,t:trim,block\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Operator :: @rx with PCRE match limits exceeded\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\",\n        \"Content-Type\": \"application/x-www-form-urlencoded\"\n      },\n      \"uri\": \"/?rxtest=wwwwwwwwwwwwwwwwwwwwwowwwwwwwwwww\",\n      \"method\": \"HEAD\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"rx: regex error 'MATCH_LIMIT' for pattern\",\n      \"error_log\": \"Matched \\\"Operator `StrEq' with parameter `1' against variable `MSC_PCRE_LIMITS_EXCEEDED'\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecPcreMatchLimit 2\",\n      \"SecRule ARGS:rxtest \\\"@rx (w+)+$\\\" \\\"id:1,phase:1,pass,t:trim,block\\\"\",\n      \"SecRule MSC_PCRE_LIMITS_EXCEEDED \\\"@streq 1\\\" \\\"id:2,phase:1,pass,t:trim,block\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Operator :: @rx with PCRE match limits exceeded\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\",\n        \"Content-Type\": \"application/x-www-form-urlencoded\"\n      },\n      \"uri\": \"/?rxtest=wwwwwwwwwwwwwwwwwwwwwowwwwwwwwwww\",\n      \"method\": \"HEAD\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"rx: regex error 'MATCH_LIMIT' for pattern\",\n      \"error_log\": \"Matched \\\"Operator `StrEq' with parameter `1' against variable `TX:MSC_PCRE_LIMITS_EXCEEDED'\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecPcreMatchLimit 2\",\n      \"SecRule ARGS:rxtest \\\"@rx (w+)+$\\\" \\\"id:1,phase:1,pass,t:trim,block\\\"\",\n      \"SecRule TX:MSC_PCRE_LIMITS_EXCEEDED \\\"@streq 1\\\" \\\"id:2,phase:1,pass,t:trim,block\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/operator-rxGlobal.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Operator :: @rxGlobal\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"27\",\n        \"Content-Type\": \"application/x-www-form-urlencoded\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"param1=value1&param2=value2\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Executing operator \\\"RxGlobal\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule ARGS \\\"@rxGlobal (value1)\\\" \\\"id:1,phase:2,pass,t:trim\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/operator-validate-byte-range.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Operator :: @validateByteRange with bytes > 127\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\",\n        \"Content-Type\": \"application/x-www-form-urlencoded\"\n      },\n      \"uri\": \"/%D0%A2%D0%B0%D1%80%D0%B0%D0%B1%D0%B0%D0%BD\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Rule returned 0.\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule REQUEST_URI \\\"@validateByteRange 37-102, 127-255\\\" \\\"id:1,phase:2,pass,t:trim\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/operator-verifycc.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Operator :: @verifycc\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"37\",\n        \"Content-Type\": \"application/x-www-form-urlencoded\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"param1=5484605089158216&param2=value2\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Added VerifyCC match TX.0: 5484605089158216\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule ARGS \\\"@verifycc \\\\d{13,16}\\\" \\\"id:1,phase:2,capture,pass,t:trim\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/operator-verifycpf.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Operator :: @verifycpf (1/2)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"35\",\n        \"Content-Type\": \"application/x-www-form-urlencoded\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"param1=010.817.514-60&param2=value2\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Added VerifyCPF match TX.0: 010.817.514-60\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule ARGS \\\"@verifycpf ^([0-9]{3}\\\\.){2}[0-9]{3}-[0-9]{2}$\\\" \\\"id:1,phase:2,capture,pass,t:trim\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/operator-verifyssn.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Operator :: @verifycpf (1/2)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"32\",\n        \"Content-Type\": \"application/x-www-form-urlencoded\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"param1=224-88-2046&param2=value2\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Added VerifySSN match TX.0: 224-88-2046\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule ARGS \\\"@verifyssn \\\\d{3}-?\\\\d{2}-?\\\\d{4}\\\" \\\"id:1,phase:2,capture,pass,t:trim\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/operator-verifysvnr.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Operator :: @verifysvnr (1/1)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"34\",\n        \"Content-Type\": \"application/x-www-form-urlencoded\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"param1=1237%20010180&param2=value2\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Added VerifySVNR match TX.0: 1237 010180\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule ARGS \\\"@verifysvnr \\\\d{4} ?\\\\d{6}\\\" \\\"id:1,phase:2,capture,pass,t:trim\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/request-body-parser-json.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing JSON request body parser 1/2\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Cookie\": \"PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120\",\n        \"Content-Type\": \"application/json\",\n        \"Content-Length\": \"39\"\n      },\n      \"uri\": \"/?key=value&key=other_value\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"{\",\n        \"       \\\"foo\\\":\\\"bar\\\",\",\n        \"       \\\"mod\\\":\\\"sec\\\"\",\n        \"}\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"bar\\\" \\\\(Variable: ARGS:json.foo\\\\)\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRequestBodyAccess On\",\n      \"SecRule REQUEST_HEADERS:Content-Type \\\"application/json\\\" \\\"id:'200001',phase:1,t:none,t:lowercase,pass,nolog,ctl:requestBodyProcessor=JSON\\\"\",\n      \"SecRule ARGS:json.foo \\\"bar\\\" \\\"id:'200441',phase:3,log\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing JSON request body parser 2/2\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Cookie\": \"PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120\",\n        \"Content-Type\": \"application/json\",\n        \"Content-Length\": \"68\"\n      },\n      \"uri\": \"/?key=value&key=other_value\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"{\",\n        \"\\\"first_level\\\":\",\n        \"{\",\n        \"       \\\"first_key\\\":\\\"bar\\\",\",\n        \"       \\\"second_key\\\":\\\"sec\\\"\",\n        \"}\",\n        \"}\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"bar\\\" \\\\(Variable: ARGS:json.first_level.first_key\\\\)\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRequestBodyAccess On\",\n      \"SecRule REQUEST_HEADERS:Content-Type \\\"application/json\\\" \\\"id:'200001',phase:1,t:none,t:lowercase,pass,nolog,ctl:requestBodyProcessor=JSON\\\"\",\n      \"SecRule ARGS \\\"bar\\\" \\\"id:'200441',phase:3,log\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing JSON request body parser - issue #1822 (1/2)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Cookie\": \"PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120\",\n        \"Content-Type\": \"application/json\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?key=value&key=other_value\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"0\\\" .Variable: REQBODY_ERROR.\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRequestBodyAccess On\",\n      \"SecRule REQUEST_HEADERS:Content-Type \\\"application/json\\\" \\\"id:'200001',phase:1,t:none,t:lowercase,pass,nolog,ctl:requestBodyProcessor=JSON\\\"\",\n      \"SecRule REQBODY_ERROR \\\"0\\\" \\\"id:'200441',phase:3,log\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing JSON request body parser - issue #1822 (2/2)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Cookie\": \"PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120\",\n        \"Content-Type\": \"application/json\",\n        \"Content-Length\": \"1\"\n      },\n      \"uri\": \"/?key=value&key=other_value\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"a\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"1\\\" .Variable: REQBODY_ERROR.\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRequestBodyAccess On\",\n      \"SecRule REQUEST_HEADERS:Content-Type \\\"application/json\\\" \\\"id:'200001',phase:1,t:none,t:lowercase,pass,nolog,ctl:requestBodyProcessor=JSON\\\"\",\n      \"SecRule REQBODY_ERROR \\\"0\\\" \\\"id:'200441',phase:3,log\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing JSON request body parser - depth not over limit\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Content-Type\": \"application/json\",\n        \"Content-Length\": \"70\"\n      },\n      \"uri\": \"/?foo=bar\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"{\",\n        \"   \\\"key1\\\":\",\n        \"{\",\n        \"   \\\"key2\\\":\",\n        \"{\",\n        \"   \\\"key3\\\":\",\n        \"{\",\n        \"   \\\"key4\\\":\",\n        \"{\",\n        \"   \\\"key5\\\":\\\"thevalue\\\"\",\n        \"}}}}}\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"json.key1.key2.key3.key4.key5\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRequestBodyJsonDepthLimit 5\",\n      \"SecRule REQUEST_HEADERS:Content-Type \\\"application/json\\\" \\\"id:'200001',phase:1,t:none,pass,nolog,ctl:requestBodyProcessor=JSON\\\"\",\n      \"SecRule REQBODY_ERROR \\\"!@eq 0\\\" \\\"id:'200002', phase:2,t:none,log,deny,status:403,msg:'Failed to parse request body.',logdata:'%{reqbody_error_msg}'\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing JSON request body parser - depth over limit\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Content-Type\": \"application/json\",\n        \"Content-Length\": \"70\"\n      },\n      \"uri\": \"/?foo=bar\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"{\",\n        \"   \\\"key1\\\":\",\n        \"{\",\n        \"   \\\"key2\\\":\",\n        \"{\",\n        \"   \\\"key3\\\":\",\n        \"{\",\n        \"   \\\"key4\\\":\",\n        \"{\",\n        \"   \\\"key5\\\":\\\"thevalue\\\"\",\n        \"}}}}}\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Failed to parse request body\",\n      \"http_code\": 403\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRequestBodyJsonDepthLimit 4\",\n      \"SecRule REQUEST_HEADERS:Content-Type \\\"application/json\\\" \\\"id:'200001',phase:1,t:none,pass,nolog,ctl:requestBodyProcessor=JSON\\\"\",\n      \"SecRule REQBODY_ERROR \\\"!@eq 0\\\" \\\"id:'200002', phase:2,t:none,log,deny,status:403,msg:'Failed to parse request body.',logdata:'%{reqbody_error_msg}'\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/request-body-parser-multipart-crlf.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"multipart parser (final boundary CRLF, other boundary LF)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"304\",\n        \"Content-Type\": \"multipart/form-data; boundary=---------------------------69343412719991675451336310646\",\n        \"Expect\": \"100-continue\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"-----------------------------69343412719991675451336310646\\n\",\n        \"Content-Disposition: form-data; name=\\\"a\\\"\\r\\n\",\n        \"\\r\\n\",\n        \"1\\r\\n\",\n        \"1.1\\r\\n\",\n        \"1.2\\r\\n\",\n        \"1.3\\r\\n\",\n        \"-----------------------------69343412719991675451336310646\\n\",\n        \"Content-Disposition: form-data; name=\\\"b\\\"\\r\\n\",\n        \"\\r\\n\",\n        \"2\\r\\n\",\n        \"2.1\\r\\n\",\n        \"2.2\\r\\n\",\n        \"2.3\\r\\n\",\n        \"-----------------------------69343412719991675451336310646--\\r\\n\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Adding request argument \\\\(BODY\\\\): name \\\"b\\\", value \\\"22.12.22.3\\\"\",\n      \"http_code\": 403\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRequestBodyAccess On\",\n      \"SecRule MULTIPART_STRICT_ERROR \\\"@eq 1\\\" \\\"phase:2,deny,id:500055\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/request-body-parser-multipart.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"multipart parser (normal)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"280\",\n        \"Content-Type\": \"multipart/form-data; boundary=0000\",\n        \"Expect\": \"100-continue\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"--0000\\r\\n\",\n        \"Content-Disposition: form-data; name=\\\"name\\\"\\r\\n\",\n        \"\\r\\n\",\n        \"Brian Rectanus\\r\\n\",\n        \"--0000\\r\\n\",\n        \"Content-Disposition: form-data; name=\\\"email\\\"\\r\\n\",\n        \"\\r\\n\",\n        \"brian.rectanus@breach.com\\r\\n\",\n        \"--0000\\r\\n\",\n        \"Content-Disposition: form-data; name=\\\"image\\\"; filename=\\\"image.jpg\\\"\\r\\n\",\n        \"Content-Type: image/jpeg\\r\\n\",\n        \"\\r\\n\",\n        \"BINARYDATA\\r\\n\",\n        \"--0000--\\r\\n\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Added file part to the list: name \\\"image\\\" file name \\\"image.jpg\\\" \\\\(offset 258, length 10\\\\)\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRequestBodyAccess On\",\n      \"SecRule MULTIPART_STRICT_ERROR \\\"@eq 1\\\" \\\"phase:2,deny,id:500055\\\"\",\n      \"SecRule MULTIPART_UNMATCHED_BOUNDARY \\\"@eq 1\\\" \\\"phase:2,deny,id:500056\\\"\",\n      \"SecRule REQBODY_PROCESSOR_ERROR \\\"@eq 1\\\" \\\"phase:2,deny,id:500057\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"multipart parser (final CRLF)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"276\",\n        \"Content-Type\": \"multipart/form-data; boundary=---------------------------69343412719991675451336310646\",\n        \"Expect\": \"100-continue\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"-----------------------------69343412719991675451336310646\\r\\n\",\n        \"Content-Disposition: form-data; name=\\\"a\\\"\\r\\n\",\n        \"\\r\\n\",\n        \"1\\r\\n\",\n        \"-----------------------------69343412719991675451336310646\\r\\n\",\n        \"Content-Disposition: form-data; name=\\\"b\\\"\\r\\n\",\n        \"\\r\\n\",\n        \"2\\r\\n\",\n        \"-----------------------------69343412719991675451336310646--\\r\\n\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Adding request argument \\\\(BODY\\\\): name \\\"a\\\", value \\\"1\\\"\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRequestBodyAccess On\",\n      \"SecRule MULTIPART_STRICT_ERROR \\\"@eq 1\\\" \\\"phase:2,deny,id:500055\\\"\",\n      \"SecRule MULTIPART_UNMATCHED_BOUNDARY \\\"@eq 1\\\" \\\"phase:2,deny,id:500056\\\"\",\n      \"SecRule REQBODY_PROCESSOR_ERROR \\\"@eq 1\\\" \\\"phase:2,deny,id:500057\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"multipart parser (no final CRLF)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"274\",\n        \"Content-Type\": \"multipart/form-data; boundary=---------------------------69343412719991675451336310646\",\n        \"Expect\": \"100-continue\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"-----------------------------69343412719991675451336310646\\r\\n\",\n        \"Content-Disposition: form-data; name=\\\"a\\\"\\r\\n\",\n        \"\\r\\n\",\n        \"1\\r\\n\",\n        \"-----------------------------69343412719991675451336310646\\r\\n\",\n        \"Content-Disposition: form-data; name=\\\"b\\\"\\r\\n\",\n        \"\\r\\n\",\n        \"2\\r\\n\",\n        \"-----------------------------69343412719991675451336310646--\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Adding request argument \\\\(BODY\\\\): name \\\"a\\\", value \\\"1\\\"\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRequestBodyAccess On\",\n      \"SecRule MULTIPART_STRICT_ERROR \\\"@eq 1\\\" \\\"phase:2,deny,id:500055\\\"\",\n      \"SecRule MULTIPART_UNMATCHED_BOUNDARY \\\"@eq 1\\\" \\\"phase:2,deny,id:500056\\\"\",\n      \"SecRule REQBODY_PROCESSOR_ERROR \\\"@eq 1\\\" \\\"phase:2,deny,id:500057\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"multipart parser (boundary contains \\\"boundary\\\")\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"276\",\n        \"Content-Type\": \"multipart/form-data; boundary=------------------------------------------------boundary\",\n        \"Expect\": \"100-continue\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"--------------------------------------------------boundary\\r\\n\",\n        \"Content-Disposition: form-data; name=\\\"a\\\"\\r\\n\",\n        \"\\r\\n\",\n        \"1\\r\\n\",\n        \"--------------------------------------------------boundary\\r\\n\",\n        \"Content-Disposition: form-data; name=\\\"b\\\"\\r\\n\",\n        \"\\r\\n\",\n        \"2\\r\\n\",\n        \"--------------------------------------------------boundary--\\r\\n\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Adding request argument \\\\(BODY\\\\): name \\\"a\\\", value \\\"1\\\"\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRequestBodyAccess On\",\n      \"SecRule MULTIPART_STRICT_ERROR \\\"@eq 1\\\" \\\"phase:2,deny,id:500055\\\"\",\n      \"SecRule MULTIPART_UNMATCHED_BOUNDARY \\\"@eq 1\\\" \\\"phase:2,deny,id:500056\\\"\",\n      \"SecRule REQBODY_PROCESSOR_ERROR \\\"@eq 1\\\" \\\"phase:2,deny,id:500057\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"multipart parser (boundary contains \\\"bOuNdArY\\\")\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"177\",\n        \"Content-Type\": \"multipart/form-data; boundary=--------0xKhTmLbOuNdArY\",\n        \"Expect\": \"100-continue\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"----------0xKhTmLbOuNdArY\\r\\n\",\n        \"Content-Disposition: form-data; name=\\\"a\\\"\\r\\n\",\n        \"\\r\\n\",\n        \"1\\r\\n\",\n        \"----------0xKhTmLbOuNdArY\\r\\n\",\n        \"Content-Disposition: form-data; name=\\\"b\\\"\\r\\n\",\n        \"\\r\\n\",\n        \"2\\r\\n\",\n        \"----------0xKhTmLbOuNdArY--\\r\\n\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Adding request argument \\\\(BODY\\\\): name \\\"a\\\", value \\\"1\\\"\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRequestBodyAccess On\",\n      \"SecRule MULTIPART_STRICT_ERROR \\\"@eq 1\\\" \\\"phase:2,deny,id:500055\\\"\",\n      \"SecRule MULTIPART_UNMATCHED_BOUNDARY \\\"@eq 1\\\" \\\"phase:2,deny,id:500056\\\"\",\n      \"SecRule REQBODY_PROCESSOR_ERROR \\\"@eq 1\\\" \\\"phase:2,deny,id:500057\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"multipart parser (data contains \\\"--\\\")\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"282\",\n        \"Content-Type\": \"multipart/form-data; boundary=---------------------------69343412719991675451336310646\",\n        \"Expect\": \"100-continue\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"-----------------------------69343412719991675451336310646\\r\\n\",\n        \"Content-Disposition: form-data; name=\\\"a\\\"\\r\\n\",\n        \"\\r\\n\",\n        \"--test\\r\\n\",\n        \"-----------------------------69343412719991675451336310646\\r\\n\",\n        \"Content-Disposition: form-data; name=\\\"b\\\"\\r\\n\",\n        \"\\r\\n\",\n        \"--\\r\\n\",\n        \"-----------------------------69343412719991675451336310646--\\r\\n\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Adding request argument \\\\(BODY\\\\): name \\\"a\\\", value \\\"--test\\\"\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRequestBodyAccess On\",\n      \"SecRule MULTIPART_STRICT_ERROR \\\"@eq 1\\\" \\\"phase:2,deny,id:500055\\\"\",\n      \"SecRule REQBODY_PROCESSOR_ERROR \\\"@eq 1\\\" \\\"phase:2,deny,id:500057\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"multipart parser error (no final boundary)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"214\",\n        \"Content-Type\": \"multipart/form-data; boundary=---------------------------69343412719991675451336310646\",\n        \"Expect\": \"100-continue\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"-----------------------------69343412719991675451336310646\\r\\n\",\n        \"Content-Disposition: form-data; name=\\\"a\\\"\\r\\n\",\n        \"\\r\\n\",\n        \"1\\r\\n\",\n        \"-----------------------------69343412719991675451336310646\\r\\n\",\n        \"Content-Disposition: form-data; name=\\\"b\\\"\\r\\n\",\n        \"\\r\\n\",\n        \"2\\r\\n\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Final boundary missing\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRequestBodyAccess On\",\n      \"SecRule MULTIPART_NAME \\\"@eq 1234\\\" \\\"phase:2,deny,id:500067\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"multipart parser error (no disposition)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"192\",\n        \"Content-Type\": \"multipart/form-data; boundary=---------------------------69343412719991675451336310646\",\n        \"Expect\": \"100-continue\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"-----------------------------69343412719991675451336310646\\r\\n\",\n        \"\\r\\n\",\n        \"1\\r\\n\",\n        \"-----------------------------69343412719991675451336310646\\r\\n\",\n        \"\\r\\n\",\n        \"2\\r\\n\",\n        \"-----------------------------69343412719991675451336310646--\\r\\n\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Part missing Content-Disposition header\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRequestBodyAccess On\",\n      \"SecRule MULTIPART_NAME \\\"@eq 1234\\\" \\\"phase:2,deny,id:500067\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"multipart parser error (bad disposition)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"274\",\n        \"Content-Type\": \"multipart/form-data; boundary=---------------------------69343412719991675451336310646\",\n        \"Expect\": \"100-continue\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"-----------------------------69343412719991675451336310646\\r\\n\",\n        \"Content-Disposition: form-data name=\\\"a\\\"\\r\\n\",\n        \"\\r\\n\",\n        \"1\\r\\n\",\n        \"-----------------------------69343412719991675451336310646\\r\\n\",\n        \"Content-Disposition: form-data name=\\\"b\\\"\\r\\n\",\n        \"\\r\\n\",\n        \"2\\r\\n\",\n        \"-----------------------------69343412719991675451336310646--\\r\\n\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Invalid Content-Disposition header\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRequestBodyAccess On\",\n      \"SecRule MULTIPART_NAME \\\"@eq 1234\\\" \\\"phase:2,deny,id:500067\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"multipart parser error (no disposition name)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"258\",\n        \"Content-Type\": \"multipart/form-data; boundary=---------------------------69343412719991675451336310646\",\n        \"Expect\": \"100-continue\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"-----------------------------69343412719991675451336310646\\r\\n\",\n        \"Content-Disposition: form-data;\\r\\n\",\n        \"\\r\\n\",\n        \"1\\r\\n\",\n        \"-----------------------------69343412719991675451336310646\\r\\n\",\n        \"Content-Disposition: form-data;\\r\\n\",\n        \"\\r\\n\",\n        \"2\\r\\n\",\n        \"-----------------------------69343412719991675451336310646--\\r\\n\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Content-Disposition header missing name field\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRequestBodyAccess On\",\n      \"SecRule MULTIPART_NAME \\\"@eq 1234\\\" \\\"phase:2,deny,id:500067\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"multipart parser error (no disposition name)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"339\",\n        \"Content-Type\": \"multipart/form-data; boundary=---------------------------69343412719991675451336310646\",\n        \"Expect\": \"100-continue\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"-----------------------------69343412719991675451336310646\\r\\n\",\n        \"Content-Disposition: form-data; name=\\\"a\\\"\\r\\n\",\n        \"\\r\\n\",\n        \"1\\r\\n\",\n        \"-----------------------------69343412719991675451336310646\\r\\n\",\n        \":\\r\\n\",\n        \"-----------------------------69343412719991675451336310646\\r\\n\",\n        \"Content-Disposition: form-data; name=\\\"b\\\"\\r\\n\",\n        \"\\r\\n\",\n        \"2\\r\\n\",\n        \"-----------------------------69343412719991675451336310646--\\r\\n\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"nvalid part header \\\\(header name missing\\\\)\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRequestBodyAccess On\",\n      \"SecRule MULTIPART_NAME \\\"@eq 1234\\\" \\\"phase:2,deny,id:500067\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"multipart parser (part header folding - space)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"283\",\n        \"Content-Type\": \"multipart/form-data; boundary=---------------------------69343412719991675451336310646\",\n        \"Expect\": \"100-continue\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"-----------------------------69343412719991675451336310646\\r\\n\",\n        \"Content-Disposition: form-data;\\r\\n\",\n        \" name=\\\"a\\\"\\r\\n\",\n        \"\\r\\n\",\n        \"1\\r\\n\",\n        \"-----------------------------69343412719991675451336310646\\r\\n\",\n        \"Content-Disposition: form-data;\\r\\n\",\n        \"    name=\\\"b\\\"\\r\\n\",\n        \"\\r\\n\",\n        \"2\\r\\n\",\n        \"-----------------------------69343412719991675451336310646--\\r\\n\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"name: a.*variable: 1.*\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule MULTIPART_STRICT_ERROR \\\"!@eq 1\\\" \\\"phase:2,deny,status:403,id:500074\\\"\",\n      \"SecRule MULTIPART_HEADER_FOLDING \\\"!@eq 1\\\" \\\"phase:2,deny,status:403,id:500075\\\"\",\n      \"SecRule MULTIPART_INVALID_HEADER_FOLDING \\\"!@eq 0\\\" \\\"phase:2,deny,status:403,id:500076\\\"\",\n      \"SecRule REQBODY_PROCESSOR_ERROR \\\"@eq 1\\\" \\\"phase:2,deny,status:403,id:500077\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"multipart parser (part header folding - tab)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"300\",\n        \"Content-Type\": \"multipart/form-data; boundary=---------------------------69343412719991675451336310646\",\n        \"Expect\": \"100-continue\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"-----------------------------69343412719991675451336310646\\r\\n\",\n        \"Content-Disposition: form-data;\\r\\n\",\n        \"       name=\\\"a\\\"\\r\\n\",\n        \"\\r\\n\",\n        \"1\\r\\n\",\n        \"-----------------------------69343412719991675451336310646\\r\\n\",\n        \"Content-Disposition: form-data;\\r\\n\",\n        \"               name=\\\"b\\\"\\r\\n\",\n        \"\\r\\n\",\n        \"2\\r\\n\",\n        \"-----------------------------69343412719991675451336310646--\\r\\n\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"name: a.*variable: 1.*\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule MULTIPART_STRICT_ERROR \\\"!@eq 1\\\" \\\"phase:2,deny,status:403,id:500074\\\"\",\n      \"SecRule MULTIPART_HEADER_FOLDING \\\"!@eq 1\\\" \\\"phase:2,deny,status:403,id:500075\\\"\",\n      \"SecRule MULTIPART_INVALID_HEADER_FOLDING \\\"!@eq 0\\\" \\\"phase:2,deny,status:403,id:500076\\\"\",\n      \"SecRule REQBODY_PROCESSOR_ERROR \\\"@eq 1\\\" \\\"phase:2,deny,status:403,id:500077\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"multipart parser (part header folding - mixed)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"292\",\n        \"Content-Type\": \"multipart/form-data; boundary=---------------------------69343412719991675451336310646\",\n        \"Expect\": \"100-continue\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"-----------------------------69343412719991675451336310646\\r\\n\",\n        \"Content-Disposition: form-data; name=\\\"a\\\"\\r\\n\",\n        \"\\r\\n\",\n        \"1\\r\\n\",\n        \"-----------------------------69343412719991675451336310646\\r\\n\",\n        \"Content-Disposition: form-data;\\r\\n\",\n        \"               name=\\\"b\\\"\\r\\n\",\n        \"\\r\\n\",\n        \"2\\r\\n\",\n        \"-----------------------------69343412719991675451336310646--\\r\\n\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"name: a.*variable: 1.*\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule MULTIPART_STRICT_ERROR \\\"!@eq 1\\\" \\\"phase:2,deny,status:403,id:500074\\\"\",\n      \"SecRule MULTIPART_HEADER_FOLDING \\\"!@eq 1\\\" \\\"phase:2,deny,status:403,id:500075\\\"\",\n      \"SecRule MULTIPART_INVALID_HEADER_FOLDING \\\"!@eq 0\\\" \\\"phase:2,deny,status:403,id:500076\\\"\",\n      \"SecRule REQBODY_PROCESSOR_ERROR \\\"@eq 1\\\" \\\"phase:2,deny,status:403,id:500077\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"multipart parser (part header folding - invalid)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"278\",\n        \"Content-Type\": \"multipart/form-data; boundary=---------------------------69343412719991675451336310646\",\n        \"Expect\": \"100-continue\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"-----------------------------69343412719991675451336310646\\r\\n\",\n        \"Content-Disposition: form-data; name=\\\"a\\\"\\r\\n\",\n        \"\\r\\n\",\n        \"1\\r\\n\",\n        \"-----------------------------69343412719991675451336310646\\r\\n\",\n        \"Content-Disposition: form-data;\\r\\n\",\n        \"\\fname=\\\"b\\\"\\r\\n\",\n        \"\\r\\n\",\n        \"2\\r\\n\",\n        \"-----------------------------69343412719991675451336310646--\\r\\n\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"name: a.*variable: 1.*\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule MULTIPART_STRICT_ERROR \\\"!@eq 1\\\" \\\"phase:2,deny,status:403,id:500074\\\"\",\n      \"SecRule MULTIPART_HEADER_FOLDING \\\"!@eq 1\\\" \\\"phase:2,deny,status:403,id:500075\\\"\",\n      \"SecRule MULTIPART_INVALID_HEADER_FOLDING \\\"!@eq 1\\\" \\\"phase:2,deny,status:403,id:500076\\\"\",\n      \"SecRule REQBODY_PROCESSOR_ERROR \\\"@eq 1\\\" \\\"phase:2,deny,status:403,id:500077\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"multipart parser (part header folding - mixed invalid)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"279\",\n        \"Content-Type\": \"multipart/form-data; boundary=---------------------------69343412719991675451336310646\",\n        \"Expect\": \"100-continue\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"-----------------------------69343412719991675451336310646\\r\\n\",\n        \"Content-Disposition: form-data; name=\\\"a\\\"\\r\\n\",\n        \"\\r\\n\",\n        \"1\\r\\n\",\n        \"-----------------------------69343412719991675451336310646\\r\\n\",\n        \"Content-Disposition: form-data;\\r\\n\",\n        \"\\f\\tname=\\\"b\\\"\\r\\n\",\n        \"\\r\\n\",\n        \"2\\r\\n\",\n        \"-----------------------------69343412719991675451336310646--\\r\\n\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"name: a.*variable: 1.*\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule MULTIPART_STRICT_ERROR \\\"!@eq 1\\\" \\\"phase:2,deny,status:403,id:500074\\\"\",\n      \"SecRule MULTIPART_HEADER_FOLDING \\\"!@eq 1\\\" \\\"phase:2,deny,status:403,id:500075\\\"\",\n      \"SecRule MULTIPART_INVALID_HEADER_FOLDING \\\"!@eq 1\\\" \\\"phase:2,deny,status:403,id:500076\\\"\",\n      \"SecRule REQBODY_PROCESSOR_ERROR \\\"@eq 1\\\" \\\"phase:2,deny,status:403,id:500077\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"multipart parser (data after final boundary)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"338\",\n        \"Content-Type\": \"multipart/form-data; boundary=---------------------------69343412719991675451336310646\",\n        \"Expect\": \"100-continue\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"-----------------------------69343412719991675451336310646\\r\\n\",\n        \"Content-Disposition: form-data; name=\\\"a\\\"\\r\\n\",\n        \"\\r\\n\",\n        \"1\\r\\n\",\n        \"-----------------------------69343412719991675451336310646--\\r\\n\",\n        \"-----------------------------69343412719991675451336310646\\r\\n\",\n        \"Content-Disposition: form-data; name=\\\"b\\\"\\r\\n\",\n        \"\\r\\n\",\n        \"2\\r\\n\",\n        \"-----------------------------69343412719991675451336310646--\\r\\n\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"name: a.*variable: 1.*\",\n      \"http_code\": 403\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule MULTIPART_DATA_AFTER \\\"@eq 1\\\" \\\"phase:2,deny,status:403,id:500074\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"multipart parser (C-D uses single quotes)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"300\",\n        \"Content-Type\": \"multipart/form-data; boundary=---------------------------69343412719991675451336310646\",\n        \"Expect\": \"100-continue\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"-----------------------------69343412719991675451336310646\\r\\n\",\n        \"Content-Disposition: form-data; name=\\\"a\\\"\\r\\n\",\n        \"\\r\\n\",\n        \"1\\r\\n\",\n        \"-----------------------------69343412719991675451336310646\\r\\n\",\n        \"Content-Disposition: form-data; name=';filename=\\\"dummy';name=b;\\\"\\r\\n\",\n        \"\\r\\n\",\n        \"2\\r\\n\",\n        \"-----------------------------69343412719991675451336310646--\\r\\n\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Duplicate Content-Disposition name\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule MULTIPART_STRICT_ERROR \\\"!@eq 1\\\" \\\"phase:2,deny,id:500095\\\"\",\n      \"SecRule MULTIPART_INVALID_QUOTING \\\"!@eq 1\\\" \\\"phase:2,deny,id:500096\\\"\",\n      \"SecRule REQBODY_PROCESSOR_ERROR \\\"@eq 1\\\" \\\"chain,phase:2,deny,id:500097\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"multipart parser (invalid C-T boundary separator - comma)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"266\",\n        \"Content-Type\": \"multipart/form-data, boundary=0000\",\n        \"Expect\": \"100-continue\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"--0000\\r\",\n        \"Content-Disposition: form-data; name=\\\"name\\\"\\r\",\n        \"\\r\",\n        \"Brian Rectanus\\r\",\n        \"--0000\\r\",\n        \"Content-Disposition: form-data; name=\\\"email\\\"\\r\",\n        \"\\r\",\n        \"brian.rectanus@breach.com\\r\",\n        \"--0000\\r\",\n        \"Content-Disposition: form-data; name=\\\"image\\\"; filename=\\\"image.jpg\\\"\\r\",\n        \"Content-Type: image/jpeg\\r\",\n        \"\\r\",\n        \"BINARYDATA\\r\",\n        \"--0000--\\r\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Invalid boundary in C-T \\\\(malformed\\\\)\",\n      \"http_code\": 403\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule MULTIPART_STRICT_ERROR \\\"!@eq 1\\\" \\\"phase:2,deny,id:500095\\\"\",\n      \"SecRule MULTIPART_UNMATCHED_BOUNDARY \\\"!@eq 1\\\" \\\"phase:2,deny,id:500096\\\"\",\n      \"SecRule REQBODY_PROCESSOR_ERROR \\\"@eq 1\\\" \\\"chain,phase:2,deny,id:500097\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"multipart parser (invalid C-T boundary separator - space)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"266\",\n        \"Content-Type\": \"multipart/form-data boundary=0000\",\n        \"Expect\": \"100-continue\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"--0000\\r\",\n        \"Content-Disposition: form-data; name=\\\"name\\\"\\r\",\n        \"\\r\",\n        \"Brian Rectanus\\r\",\n        \"--0000\\r\",\n        \"Content-Disposition: form-data; name=\\\"email\\\"\\r\",\n        \"\\r\",\n        \"brian.rectanus@breach.com\\r\",\n        \"--0000\\r\",\n        \"Content-Disposition: form-data; name=\\\"image\\\"; filename=\\\"image.jpg\\\"\\r\",\n        \"Content-Type: image/jpeg\\r\",\n        \"\\r\",\n        \"BINARYDATA\\r\",\n        \"--0000--\\r\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"http_code\": 403\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule MULTIPART_STRICT_ERROR \\\"!@eq 1\\\" \\\"phase:2,deny,id:500095\\\"\",\n      \"SecRule MULTIPART_UNMATCHED_BOUNDARY \\\"!@eq 1\\\" \\\"phase:2,deny,id:500096\\\"\",\n      \"SecRule REQBODY_PROCESSOR_ERROR \\\"@eq 1\\\" \\\"chain,phase:2,deny,id:500097\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"multipart parser (invalid C-T boundary parameter name - case)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"266\",\n        \"Content-Type\": \"multipart/form-data; bOundAry=0000\",\n        \"Expect\": \"100-continue\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"--0000\\r\",\n        \"Content-Disposition: form-data; name=\\\"name\\\"\\r\",\n        \"\\r\",\n        \"Brian Rectanus\\r\",\n        \"--0000\\r\",\n        \"Content-Disposition: form-data; name=\\\"email\\\"\\r\",\n        \"\\r\",\n        \"brian.rectanus@breach.com\\r\",\n        \"--0000\\r\",\n        \"Content-Disposition: form-data; name=\\\"image\\\"; filename=\\\"image.jpg\\\"\\r\",\n        \"Content-Type: image/jpeg\\r\",\n        \"\\r\",\n        \"BINARYDATA\\r\",\n        \"--0000--\\r\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Invalid boundary in C-T \\\\(case sensitivity\\\\)\",\n      \"http_code\": 403\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule MULTIPART_STRICT_ERROR \\\"!@eq 1\\\" \\\"phase:2,deny,id:500095\\\"\",\n      \"SecRule MULTIPART_UNMATCHED_BOUNDARY \\\"!@eq 1\\\" \\\"phase:2,deny,id:500096\\\"\",\n      \"SecRule REQBODY_PROCESSOR_ERROR \\\"@eq 1\\\" \\\"chain,phase:2,deny,id:500097\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"multipart parser (invalid C-T boundary parameter name - trailing chars)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"266\",\n        \"Content-Type\": \"multipart/form-data; boundary123=0000\",\n        \"Expect\": \"100-continue\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"--0000\\r\",\n        \"Content-Disposition: form-data; name=\\\"name\\\"\\r\",\n        \"\\r\",\n        \"Brian Rectanus\\r\",\n        \"--0000\\r\",\n        \"Content-Disposition: form-data; name=\\\"email\\\"\\r\",\n        \"\\r\",\n        \"brian.rectanus@breach.com\\r\",\n        \"--0000\\r\",\n        \"Content-Disposition: form-data; name=\\\"image\\\"; filename=\\\"image.jpg\\\"\\r\",\n        \"Content-Type: image/jpeg\\r\",\n        \"\\r\",\n        \"BINARYDATA\\r\",\n        \"--0000--\\r\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Invalid boundary in C-T \\\\(parameter name\\\\)\",\n      \"http_code\": 403\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule MULTIPART_STRICT_ERROR \\\"!@eq 1\\\" \\\"phase:2,deny,id:500095\\\"\",\n      \"SecRule MULTIPART_UNMATCHED_BOUNDARY \\\"!@eq 1\\\" \\\"phase:2,deny,id:500096\\\"\",\n      \"SecRule REQBODY_PROCESSOR_ERROR \\\"@eq 1\\\" \\\"chain,phase:2,deny,id:500097\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"multipart parser (multiple C-T boundaries - first quoted)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"266\",\n        \"Content-Type\": \"multipart/form-data; boundary=\\\"0000\\\"; boundary=1111\",\n        \"Expect\": \"100-continue\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"--0000\\r\",\n        \"Content-Disposition: form-data; name=\\\"name\\\"\\r\",\n        \"\\r\",\n        \"Brian Rectanus\\r\",\n        \"--0000\\r\",\n        \"Content-Disposition: form-data; name=\\\"email\\\"\\r\",\n        \"\\r\",\n        \"brian.rectanus@breach.com\\r\",\n        \"--0000\\r\",\n        \"Content-Disposition: form-data; name=\\\"image\\\"; filename=\\\"image.jpg\\\"\\r\",\n        \"Content-Type: image/jpeg\\r\",\n        \"\\r\",\n        \"BINARYDATA\\r\",\n        \"--0000--\\r\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Multiple boundary parameters in C-T\",\n      \"http_code\": 403\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule MULTIPART_STRICT_ERROR \\\"!@eq 1\\\" \\\"phase:2,deny,id:500095\\\"\",\n      \"SecRule MULTIPART_UNMATCHED_BOUNDARY \\\"!@eq 1\\\" \\\"phase:2,deny,id:500096\\\"\",\n      \"SecRule REQBODY_PROCESSOR_ERROR \\\"@eq 1\\\" \\\"chain,phase:2,deny,id:500097\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"multipart parser (multiple C-T boundaries - comma separated)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"266\",\n        \"Content-Type\": \"multipart/form-data; boundary=0000, boundary=1111\",\n        \"Expect\": \"100-continue\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"--0000\\r\",\n        \"Content-Disposition: form-data; name=\\\"name\\\"\\r\",\n        \"\\r\",\n        \"Brian Rectanus\\r\",\n        \"--0000\\r\",\n        \"Content-Disposition: form-data; name=\\\"email\\\"\\r\",\n        \"\\r\",\n        \"brian.rectanus@breach.com\\r\",\n        \"--0000\\r\",\n        \"Content-Disposition: form-data; name=\\\"image\\\"; filename=\\\"image.jpg\\\"\\r\",\n        \"Content-Type: image/jpeg\\r\",\n        \"\\r\",\n        \"BINARYDATA\\r\",\n        \"--0000--\\r\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Multiple boundary parameters in C-T\",\n      \"http_code\": 403\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule MULTIPART_STRICT_ERROR \\\"!@eq 1\\\" \\\"phase:2,deny,id:500095\\\"\",\n      \"SecRule MULTIPART_UNMATCHED_BOUNDARY \\\"!@eq 1\\\" \\\"phase:2,deny,id:500096\\\"\",\n      \"SecRule REQBODY_PROCESSOR_ERROR \\\"@eq 1\\\" \\\"chain,phase:2,deny,id:500097\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"multipart parser (boundary whitespace in C-T - after name)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"266\",\n        \"Content-Type\": \"multipart/form-data; boundary =0000\",\n        \"Expect\": \"100-continue\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"--0000\\r\",\n        \"Content-Disposition: form-data; name=\\\"name\\\"\\r\",\n        \"\\r\",\n        \"Brian Rectanus\\r\",\n        \"--0000\\r\",\n        \"Content-Disposition: form-data; name=\\\"email\\\"\\r\",\n        \"\\r\",\n        \"brian.rectanus@breach.com\\r\",\n        \"--0000\\r\",\n        \"Content-Disposition: form-data; name=\\\"image\\\"; filename=\\\"image.jpg\\\"\\r\",\n        \"Content-Type: image/jpeg\\r\",\n        \"\\r\",\n        \"BINARYDATA\\r\",\n        \"--0000--\\r\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"http_code\": 403\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule MULTIPART_STRICT_ERROR \\\"!@eq 1\\\" \\\"phase:2,deny,id:500095\\\"\",\n      \"SecRule MULTIPART_UNMATCHED_BOUNDARY \\\"!@eq 1\\\" \\\"phase:2,deny,id:500096\\\"\",\n      \"SecRule REQBODY_PROCESSOR_ERROR \\\"@eq 1\\\" \\\"chain,phase:2,deny,id:500097\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"multipart parser (boundary whitespace in C-T - before value)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"266\",\n        \"Content-Type\": \"multipart/form-data; boundary= 0000\",\n        \"Expect\": \"100-continue\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"--0000\\r\",\n        \"Content-Disposition: form-data; name=\\\"name\\\"\\r\",\n        \"\\r\",\n        \"Brian Rectanus\\r\",\n        \"--0000\\r\",\n        \"Content-Disposition: form-data; name=\\\"email\\\"\\r\",\n        \"\\r\",\n        \"brian.rectanus@breach.com\\r\",\n        \"--0000\\r\",\n        \"Content-Disposition: form-data; name=\\\"image\\\"; filename=\\\"image.jpg\\\"\\r\",\n        \"Content-Type: image/jpeg\\r\",\n        \"\\r\",\n        \"BINARYDATA\\r\",\n        \"--0000--\\r\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"boundary whitespace in C-T header\",\n      \"error_log\": \"msg \\\"Multipart request body failed strict validation:PE 1,BQ 0,BW 1,DB 0,DA 0,HF 0,LF 0,SM 0,IQ 0,IP 0,IH 0,FL \\\"\",\n      \"http_code\": 403\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule MULTIPART_STRICT_ERROR \\\"@eq 1\\\" \\\"phase:2,deny,id:500095,msg:'Multipart request body failed strict validation:PE %{REQBODY_PROCESSOR_ERROR},BQ %{MULTIPART_BOUNDARY_QUOTED},BW %{MULTIPART_BOUNDARY_WHITESPACE},DB %{MULTIPART_DATA_BEFORE},DA %{MULTIPART_DATA_AFTER},HF %{MULTIPART_HEADER_FOLDING},LF %{MULTIPART_LF_LINE},SM %{MULTIPART_MISSING_SEMICOLON},IQ %{MULTIPART_INVALID_QUOTING},IP %{MULTIPART_INVALID_PART},IH %{MULTIPART_INVALID_HEADER_FOLDING},FL %{MULTIPART_FILE_LIMIT_EXCEEDED}'\\\"\",\n      \"SecRule MULTIPART_UNMATCHED_BOUNDARY \\\"@eq 1\\\" \\\"phase:2,deny,id:500096\\\"\",\n      \"SecRule REQBODY_PROCESSOR_ERROR \\\"@eq 1\\\" \\\"chain,phase:2,deny,id:500097\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"multipart parser (boundary whitespace in C-T - after value) - apache removes the whitespace, not the case for us... TODO\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"266\",\n        \"Content-Type\": \"multipart/form-data; boundary=0000 \",\n        \"Expect\": \"100-continue\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"--0000\\r\",\n        \"Content-Disposition: form-data; name=\\\"name\\\"\\r\",\n        \"\\r\",\n        \"Brian Rectanus\\r\",\n        \"--0000\\r\",\n        \"Content-Disposition: form-data; name=\\\"email\\\"\\r\",\n        \"\\r\",\n        \"brian.rectanus@breach.com\\r\",\n        \"--0000\\r\",\n        \"Content-Disposition: form-data; name=\\\"image\\\"; filename=\\\"image.jpg\\\"\\r\",\n        \"Content-Type: image/jpeg\\r\",\n        \"\\r\",\n        \"BINARYDATA\\r\",\n        \"--0000--\\r\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"error_log\": \"msg \\\"Multipart request body failed strict validation:PE 1,BQ 0,BW 0,DB 0,DA 0,HF 0,LF 0,SM 0,IQ 0,IP 0,IH 0,FL \\\"\",\n      \"http_code\": 403\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule MULTIPART_STRICT_ERROR \\\"@eq 1\\\" \\\"phase:2,deny,id:500095,msg:'Multipart request body failed strict validation:PE %{REQBODY_PROCESSOR_ERROR},BQ %{MULTIPART_BOUNDARY_QUOTED},BW %{MULTIPART_BOUNDARY_WHITESPACE},DB %{MULTIPART_DATA_BEFORE},DA %{MULTIPART_DATA_AFTER},HF %{MULTIPART_HEADER_FOLDING},LF %{MULTIPART_LF_LINE},SM %{MULTIPART_MISSING_SEMICOLON},IQ %{MULTIPART_INVALID_QUOTING},IP %{MULTIPART_INVALID_PART},IH %{MULTIPART_INVALID_HEADER_FOLDING},FL %{MULTIPART_FILE_LIMIT_EXCEEDED}'\\\"\",\n      \"SecRule MULTIPART_UNMATCHED_BOUNDARY \\\"@eq 1\\\" \\\"phase:2,deny,id:500096\\\"\",\n      \"SecRule REQBODY_PROCESSOR_ERROR \\\"@eq 1\\\" \\\"chain,phase:2,deny,id:500097\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"multipart parser (boundary special char - trailing whitespace+token)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"280\",\n        \"Content-Type\": \"multipart/form-data;boundary=0000 1111\",\n        \"Expect\": \"100-continue\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"--0000\\r\\n\",\n        \"Content-Disposition: form-data; name=\\\"name\\\"\\r\\n\",\n        \"\\r\\n\",\n        \"Brian Rectanus\\r\\n\",\n        \"--0000\\r\\n\",\n        \"Content-Disposition: form-data; name=\\\"email\\\"\\r\\n\",\n        \"\\r\\n\",\n        \"brian.rectanus@breach.com\\r\\n\",\n        \"--0000\\r\\n\",\n        \"Content-Disposition: form-data; name=\\\"image\\\"; filename=\\\"image.jpg\\\"\\r\\n\",\n        \"Content-Type: image/jpeg\\r\\n\",\n        \"\\r\\n\",\n        \"BINARYDATA\\r\\n\",\n        \"--0000--\\r\\n\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"No boundaries found in payload\",\n      \"error_log\": \"msg \\\"Multipart request body failed strict validation:PE 1,BQ 0,BW 0,DB 1,DA 0,HF 0,LF 0,SM 0,IQ 0,IP 0,IH 0,FL \\\"\",\n      \"http_code\": 403\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule MULTIPART_STRICT_ERROR \\\"@eq 1\\\" \\\"phase:2,deny,id:500095,msg:'Multipart request body failed strict validation:PE %{REQBODY_PROCESSOR_ERROR},BQ %{MULTIPART_BOUNDARY_QUOTED},BW %{MULTIPART_BOUNDARY_WHITESPACE},DB %{MULTIPART_DATA_BEFORE},DA %{MULTIPART_DATA_AFTER},HF %{MULTIPART_HEADER_FOLDING},LF %{MULTIPART_LF_LINE},SM %{MULTIPART_MISSING_SEMICOLON},IQ %{MULTIPART_INVALID_QUOTING},IP %{MULTIPART_INVALID_PART},IH %{MULTIPART_INVALID_HEADER_FOLDING},FL %{MULTIPART_FILE_LIMIT_EXCEEDED}'\\\"\",\n      \"SecRule MULTIPART_UNMATCHED_BOUNDARY \\\"@eq 1\\\" \\\"phase:2,deny,id:500096\\\"\",\n      \"SecRule REQBODY_PROCESSOR_ERROR \\\"@eq 1\\\" \\\"chain,phase:2,deny,id:500097\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"multipart parser (boundary special char - trailing exclamation+token)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"266\",\n        \"Content-Type\": \"multipart/form-data;boundary=0000!1111\",\n        \"Expect\": \"100-continue\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"--0000\\r\",\n        \"Content-Disposition: form-data; name=\\\"name\\\"\\r\",\n        \"\\r\",\n        \"Brian Rectanus\\r\",\n        \"--0000\\r\",\n        \"Content-Disposition: form-data; name=\\\"email\\\"\\r\",\n        \"\\r\",\n        \"brian.rectanus@breach.com\\r\",\n        \"--0000\\r\",\n        \"Content-Disposition: form-data; name=\\\"image\\\"; filename=\\\"image.jpg\\\"\\r\",\n        \"Content-Type: image/jpeg\\r\",\n        \"\\r\",\n        \"BINARYDATA\\r\",\n        \"--0000--\\r\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Invalid boundary in C-T \\\\(characters\\\\)\",\n      \"error_log\": \"msg \\\"Multipart request body failed strict validation:PE 1,BQ 0,BW 0,DB 0,DA 0,HF 0,LF 0,SM 0,IQ 0,IP 0,IH 0,FL \\\"\",\n      \"http_code\": 403\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule MULTIPART_STRICT_ERROR \\\"@eq 1\\\" \\\"phase:2,deny,id:500095,msg:'Multipart request body failed strict validation:PE %{REQBODY_PROCESSOR_ERROR},BQ %{MULTIPART_BOUNDARY_QUOTED},BW %{MULTIPART_BOUNDARY_WHITESPACE},DB %{MULTIPART_DATA_BEFORE},DA %{MULTIPART_DATA_AFTER},HF %{MULTIPART_HEADER_FOLDING},LF %{MULTIPART_LF_LINE},SM %{MULTIPART_MISSING_SEMICOLON},IQ %{MULTIPART_INVALID_QUOTING},IP %{MULTIPART_INVALID_PART},IH %{MULTIPART_INVALID_HEADER_FOLDING},FL %{MULTIPART_FILE_LIMIT_EXCEEDED}'\\\"\",\n      \"SecRule MULTIPART_UNMATCHED_BOUNDARY \\\"@eq 1\\\" \\\"phase:2,deny,id:500096\\\"\",\n      \"SecRule REQBODY_PROCESSOR_ERROR \\\"@eq 1\\\" \\\"chain,phase:2,deny,id:500097\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"multipart parser (quoted boundary - normal)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"266\",\n        \"Content-Type\": \"multipart/form-data;boundary=\\\"0000\\\"\",\n        \"Expect\": \"100-continue\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"--0000\\r\",\n        \"Content-Disposition: form-data; name=\\\"name\\\"\\r\",\n        \"\\r\",\n        \"Brian Rectanus\\r\",\n        \"--0000\\r\",\n        \"Content-Disposition: form-data; name=\\\"email\\\"\\r\",\n        \"\\r\",\n        \"brian.rectanus@breach.com\\r\",\n        \"--0000\\r\",\n        \"Content-Disposition: form-data; name=\\\"image\\\"; filename=\\\"image.jpg\\\"\\r\",\n        \"Content-Type: image/jpeg\\r\",\n        \"\\r\",\n        \"BINARYDATA\\r\",\n        \"--0000--\\r\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"boundary was quoted\",\n      \"error_log\": \"msg \\\"Multipart request body failed strict validation:PE 1,BQ 1,BW 0,DB 0,DA 0,HF 0,LF 0,SM 0,IQ 0,IP 0,IH 0,FL \\\"\",\n      \"http_code\": 403\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule MULTIPART_STRICT_ERROR \\\"@eq 1\\\" \\\"phase:2,deny,id:500095,msg:'Multipart request body failed strict validation:PE %{REQBODY_PROCESSOR_ERROR},BQ %{MULTIPART_BOUNDARY_QUOTED},BW %{MULTIPART_BOUNDARY_WHITESPACE},DB %{MULTIPART_DATA_BEFORE},DA %{MULTIPART_DATA_AFTER},HF %{MULTIPART_HEADER_FOLDING},LF %{MULTIPART_LF_LINE},SM %{MULTIPART_MISSING_SEMICOLON},IQ %{MULTIPART_INVALID_QUOTING},IP %{MULTIPART_INVALID_PART},IH %{MULTIPART_INVALID_HEADER_FOLDING},FL %{MULTIPART_FILE_LIMIT_EXCEEDED}'\\\"\",\n      \"SecRule MULTIPART_UNMATCHED_BOUNDARY \\\"@eq 1\\\" \\\"phase:2,deny,id:500096\\\"\",\n      \"SecRule REQBODY_PROCESSOR_ERROR \\\"@eq 1\\\" \\\"chain,phase:2,deny,id:500097\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"multipart parser (quoted boundary value - whitespace before)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"266\",\n        \"Content-Type\": \"multipart/form-data;boundary=\\\" 0000\\\"\",\n        \"Expect\": \"100-continue\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"--0000\\r\",\n        \"Content-Disposition: form-data; name=\\\"name\\\"\\r\",\n        \"\\r\",\n        \"Brian Rectanus\\r\",\n        \"--0000\\r\",\n        \"Content-Disposition: form-data; name=\\\"email\\\"\\r\",\n        \"\\r\",\n        \"brian.rectanus@breach.com\\r\",\n        \"--0000\\r\",\n        \"Content-Disposition: form-data; name=\\\"image\\\"; filename=\\\"image.jpg\\\"\\r\",\n        \"Content-Type: image/jpeg\\r\",\n        \"\\r\",\n        \"BINARYDATA\\r\",\n        \"--0000--\\r\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"boundary was quoted.*No boundaries found in payload\",\n      \"error_log\": \"msg \\\"Multipart request body failed strict validation:PE 1,BQ 1,BW 0,DB 0,DA 0,HF 0,LF 0,SM 0,IQ 0,IP 0,IH 0,FL \\\"\",\n      \"http_code\": 403\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule MULTIPART_STRICT_ERROR \\\"@eq 1\\\" \\\"phase:2,deny,id:500095,msg:'Multipart request body failed strict validation:PE %{REQBODY_PROCESSOR_ERROR},BQ %{MULTIPART_BOUNDARY_QUOTED},BW %{MULTIPART_BOUNDARY_WHITESPACE},DB %{MULTIPART_DATA_BEFORE},DA %{MULTIPART_DATA_AFTER},HF %{MULTIPART_HEADER_FOLDING},LF %{MULTIPART_LF_LINE},SM %{MULTIPART_MISSING_SEMICOLON},IQ %{MULTIPART_INVALID_QUOTING},IP %{MULTIPART_INVALID_PART},IH %{MULTIPART_INVALID_HEADER_FOLDING},FL %{MULTIPART_FILE_LIMIT_EXCEEDED}'\\\"\",\n      \"SecRule MULTIPART_UNMATCHED_BOUNDARY \\\"@eq 1\\\" \\\"phase:2,deny,id:500096\\\"\",\n      \"SecRule REQBODY_PROCESSOR_ERROR \\\"@eq 1\\\" \\\"chain,phase:2,deny,id:500097\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"multipart parser (quoted boundary value - whitespace after)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"266\",\n        \"Content-Type\": \"multipart/form-data;boundary=\\\"0000 \\\"\",\n        \"Expect\": \"100-continue\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"--0000\\r\",\n        \"Content-Disposition: form-data; name=\\\"name\\\"\\r\",\n        \"\\r\",\n        \"Brian Rectanus\\r\",\n        \"--0000\\r\",\n        \"Content-Disposition: form-data; name=\\\"email\\\"\\r\",\n        \"\\r\",\n        \"brian.rectanus@breach.com\\r\",\n        \"--0000\\r\",\n        \"Content-Disposition: form-data; name=\\\"image\\\"; filename=\\\"image.jpg\\\"\\r\",\n        \"Content-Type: image/jpeg\\r\",\n        \"\\r\",\n        \"BINARYDATA\\r\",\n        \"--0000--\\r\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Invalid boundary in C-T \\\\(characters\\\\).*boundary was quoted.\",\n      \"error_log\": \"msg \\\"Multipart request body failed strict validation:PE 1,BQ 1,BW 0,DB 0,DA 0,HF 0,LF 0,SM 0,IQ 0,IP 0,IH 0,FL \\\"\",\n      \"http_code\": 403\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule MULTIPART_STRICT_ERROR \\\"@eq 1\\\" \\\"phase:2,deny,id:500095,msg:'Multipart request body failed strict validation:PE %{REQBODY_PROCESSOR_ERROR},BQ %{MULTIPART_BOUNDARY_QUOTED},BW %{MULTIPART_BOUNDARY_WHITESPACE},DB %{MULTIPART_DATA_BEFORE},DA %{MULTIPART_DATA_AFTER},HF %{MULTIPART_HEADER_FOLDING},LF %{MULTIPART_LF_LINE},SM %{MULTIPART_MISSING_SEMICOLON},IQ %{MULTIPART_INVALID_QUOTING},IP %{MULTIPART_INVALID_PART},IH %{MULTIPART_INVALID_HEADER_FOLDING},FL %{MULTIPART_FILE_LIMIT_EXCEEDED}'\\\"\",\n      \"SecRule MULTIPART_UNMATCHED_BOUNDARY \\\"@eq 1\\\" \\\"phase:2,deny,id:500096\\\"\",\n      \"SecRule REQBODY_PROCESSOR_ERROR \\\"@eq 1\\\" \\\"chain,phase:2,deny,id:500097\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"multipart parser (quoted boundary value - whitespace after)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"266\",\n        \"Content-Type\": \"multipart/form-data;boundary=\\\"0000 \\\"\",\n        \"Expect\": \"100-continue\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"--0000\\r\",\n        \"Content-Disposition: form-data; name=\\\"name\\\"\\r\",\n        \"\\r\",\n        \"Brian Rectanus\\r\",\n        \"--0000\\r\",\n        \"Content-Disposition: form-data; name=\\\"email\\\"\\r\",\n        \"\\r\",\n        \"brian.rectanus@breach.com\\r\",\n        \"--0000\\r\",\n        \"Content-Disposition: form-data; name=\\\"image\\\"; filename=\\\"image.jpg\\\"\\r\",\n        \"Content-Type: image/jpeg\\r\",\n        \"\\r\",\n        \"BINARYDATA\\r\",\n        \"--0000--\\r\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Invalid boundary in C-T \\\\(characters\\\\).*boundary was quoted.\",\n      \"error_log\": \"msg \\\"Multipart request body failed strict validation:PE 1,BQ 1,BW 0,DB 0,DA 0,HF 0,LF 0,SM 0,IQ 0,IP 0,IH 0,FL \\\"\",\n      \"http_code\": 403\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule MULTIPART_STRICT_ERROR \\\"@eq 1\\\" \\\"phase:2,deny,id:500095,msg:'Multipart request body failed strict validation:PE %{REQBODY_PROCESSOR_ERROR},BQ %{MULTIPART_BOUNDARY_QUOTED},BW %{MULTIPART_BOUNDARY_WHITESPACE},DB %{MULTIPART_DATA_BEFORE},DA %{MULTIPART_DATA_AFTER},HF %{MULTIPART_HEADER_FOLDING},LF %{MULTIPART_LF_LINE},SM %{MULTIPART_MISSING_SEMICOLON},IQ %{MULTIPART_INVALID_QUOTING},IP %{MULTIPART_INVALID_PART},IH %{MULTIPART_INVALID_HEADER_FOLDING},FL %{MULTIPART_FILE_LIMIT_EXCEEDED}'\\\"\",\n      \"SecRule MULTIPART_UNMATCHED_BOUNDARY \\\"@eq 1\\\" \\\"phase:2,deny,id:500096\\\"\",\n      \"SecRule REQBODY_PROCESSOR_ERROR \\\"@eq 1\\\" \\\"chain,phase:2,deny,id:500097\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"multipart parser (quoted boundary value - whitespace between)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"266\",\n        \"Content-Type\": \"multipart/form-data;boundary=\\\"0000 1111\\\"\",\n        \"Expect\": \"100-continue\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"--0000\\r\",\n        \"Content-Disposition: form-data; name=\\\"name\\\"\\r\",\n        \"\\r\",\n        \"Brian Rectanus\\r\",\n        \"--0000\\r\",\n        \"Content-Disposition: form-data; name=\\\"email\\\"\\r\",\n        \"\\r\",\n        \"brian.rectanus@breach.com\\r\",\n        \"--0000\\r\",\n        \"Content-Disposition: form-data; name=\\\"image\\\"; filename=\\\"image.jpg\\\"\\r\",\n        \"Content-Type: image/jpeg\\r\",\n        \"\\r\",\n        \"BINARYDATA\\r\",\n        \"--0000--\\r\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"boundary was quoted\",\n      \"error_log\": \"msg \\\"Multipart request body failed strict validation:PE 1,BQ 1,BW 0,DB 0,DA 0,HF 0,LF 0,SM 0,IQ 0,IP 0,IH 0,FL \\\"\",\n      \"http_code\": 403\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule MULTIPART_STRICT_ERROR \\\"@eq 1\\\" \\\"phase:2,deny,id:500095,msg:'Multipart request body failed strict validation:PE %{REQBODY_PROCESSOR_ERROR},BQ %{MULTIPART_BOUNDARY_QUOTED},BW %{MULTIPART_BOUNDARY_WHITESPACE},DB %{MULTIPART_DATA_BEFORE},DA %{MULTIPART_DATA_AFTER},HF %{MULTIPART_HEADER_FOLDING},LF %{MULTIPART_LF_LINE},SM %{MULTIPART_MISSING_SEMICOLON},IQ %{MULTIPART_INVALID_QUOTING},IP %{MULTIPART_INVALID_PART},IH %{MULTIPART_INVALID_HEADER_FOLDING},FL %{MULTIPART_FILE_LIMIT_EXCEEDED}'\\\"\",\n      \"SecRule MULTIPART_UNMATCHED_BOUNDARY \\\"@eq 1\\\" \\\"phase:2,deny,id:500096\\\"\",\n      \"SecRule REQBODY_PROCESSOR_ERROR \\\"@eq 1\\\" \\\"chain,phase:2,deny,id:500097\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"multipart parser (quoted boundary value - contained quote)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"270\",\n        \"Content-Type\": \"multipart/form-data;boundary=\\\"00\\\"00\\\"\",\n        \"Expect\": \"100-continue\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"--00\\\"00\\r\",\n        \"Content-Disposition: form-data; name=\\\"name\\\"\\r\",\n        \"\\r\",\n        \"Brian Rectanus\\r\",\n        \"--00\\\"00\\r\",\n        \"Content-Disposition: form-data; name=\\\"email\\\"\\r\",\n        \"\\r\",\n        \"brian.rectanus@breach.com\\r\",\n        \"--00\\\"00\\r\",\n        \"Content-Disposition: form-data; name=\\\"image\\\"; filename=\\\"image.jpg\\\"\\r\",\n        \"Content-Type: image/jpeg\\r\",\n        \"\\r\",\n        \"BINARYDATA\\r\",\n        \"--00\\\"00--\\r\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Invalid boundary in C-T \\\\(characters\\\\)\",\n      \"error_log\": \"msg \\\"Multipart request body failed strict validation:PE 1,BQ 1,BW 0,DB 0,DA 0,HF 0,LF 0,SM 0,IQ 0,IP 0,IH 0,FL \\\"\",\n      \"http_code\": 403\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule MULTIPART_STRICT_ERROR \\\"@eq 1\\\" \\\"phase:2,deny,id:500095,msg:'Multipart request body failed strict validation:PE %{REQBODY_PROCESSOR_ERROR},BQ %{MULTIPART_BOUNDARY_QUOTED},BW %{MULTIPART_BOUNDARY_WHITESPACE},DB %{MULTIPART_DATA_BEFORE},DA %{MULTIPART_DATA_AFTER},HF %{MULTIPART_HEADER_FOLDING},LF %{MULTIPART_LF_LINE},SM %{MULTIPART_MISSING_SEMICOLON},IQ %{MULTIPART_INVALID_QUOTING},IP %{MULTIPART_INVALID_PART},IH %{MULTIPART_INVALID_HEADER_FOLDING},FL %{MULTIPART_FILE_LIMIT_EXCEEDED}'\\\"\",\n      \"SecRule MULTIPART_UNMATCHED_BOUNDARY \\\"@eq 1\\\" \\\"phase:2,deny,id:500096\\\"\",\n      \"SecRule REQBODY_PROCESSOR_ERROR \\\"@eq 1\\\" \\\"chain,phase:2,deny,id:500097\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"multipart parser (quoted boundary value - two quoted values)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"270\",\n        \"Content-Type\": \"multipart/form-data;boundary=\\\"00\\\"\\\"00\\\"\",\n        \"Expect\": \"100-continue\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"--00\\\"00\\r\",\n        \"Content-Disposition: form-data; name=\\\"name\\\"\\r\",\n        \"\\r\",\n        \"Brian Rectanus\\r\",\n        \"--00\\\"00\\r\",\n        \"Content-Disposition: form-data; name=\\\"email\\\"\\r\",\n        \"\\r\",\n        \"brian.rectanus@breach.com\\r\",\n        \"--00\\\"00\\r\",\n        \"Content-Disposition: form-data; name=\\\"image\\\"; filename=\\\"image.jpg\\\"\\r\",\n        \"Content-Type: image/jpeg\\r\",\n        \"\\r\",\n        \"BINARYDATA\\r\",\n        \"--00\\\"00--\\r\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Invalid boundary in C-T \\\\(characters\\\\)\",\n      \"error_log\": \"msg \\\"Multipart request body failed strict validation:PE 1,BQ 1,BW 0,DB 0,DA 0,HF 0,LF 0,SM 0,IQ 0,IP 0,IH 0,FL \\\"\",\n      \"http_code\": 403\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule MULTIPART_STRICT_ERROR \\\"@eq 1\\\" \\\"phase:2,deny,id:500095,msg:'Multipart request body failed strict validation:PE %{REQBODY_PROCESSOR_ERROR},BQ %{MULTIPART_BOUNDARY_QUOTED},BW %{MULTIPART_BOUNDARY_WHITESPACE},DB %{MULTIPART_DATA_BEFORE},DA %{MULTIPART_DATA_AFTER},HF %{MULTIPART_HEADER_FOLDING},LF %{MULTIPART_LF_LINE},SM %{MULTIPART_MISSING_SEMICOLON},IQ %{MULTIPART_INVALID_QUOTING},IP %{MULTIPART_INVALID_PART},IH %{MULTIPART_INVALID_HEADER_FOLDING},FL %{MULTIPART_FILE_LIMIT_EXCEEDED}'\\\"\",\n      \"SecRule MULTIPART_UNMATCHED_BOUNDARY \\\"@eq 1\\\" \\\"phase:2,deny,id:500096\\\"\",\n      \"SecRule REQBODY_PROCESSOR_ERROR \\\"@eq 1\\\" \\\"chain,phase:2,deny,id:500097\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"multipart parser (partial quoted boundary value - only start quote)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"266\",\n        \"Content-Type\": \"multipart/form-data;boundary=\\\"0000\",\n        \"Expect\": \"100-continue\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"--0000\\r\",\n        \"Content-Disposition: form-data; name=\\\"name\\\"\\r\",\n        \"\\r\",\n        \"Brian Rectanus\\r\",\n        \"--0000\\r\",\n        \"Content-Disposition: form-data; name=\\\"email\\\"\\r\",\n        \"\\r\",\n        \"brian.rectanus@breach.com\\r\",\n        \"--0000\\r\",\n        \"Content-Disposition: form-data; name=\\\"image\\\"; filename=\\\"image.jpg\\\"\\r\",\n        \"Content-Type: image/jpeg\\r\",\n        \"\\r\",\n        \"BINARYDATA\\r\",\n        \"--0000--\\r\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Invalid boundary in C-T \\\\(quote\\\\)\",\n      \"error_log\": \"msg \\\"Multipart request body failed strict validation:PE 1,BQ 0,BW 0,DB 0,DA 0,HF 0,LF 0,SM 0,IQ 0,IP 0,IH 0,FL \\\"\",\n      \"http_code\": 403\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule MULTIPART_STRICT_ERROR \\\"@eq 1\\\" \\\"phase:2,deny,id:500095,msg:'Multipart request body failed strict validation:PE %{REQBODY_PROCESSOR_ERROR},BQ %{MULTIPART_BOUNDARY_QUOTED},BW %{MULTIPART_BOUNDARY_WHITESPACE},DB %{MULTIPART_DATA_BEFORE},DA %{MULTIPART_DATA_AFTER},HF %{MULTIPART_HEADER_FOLDING},LF %{MULTIPART_LF_LINE},SM %{MULTIPART_MISSING_SEMICOLON},IQ %{MULTIPART_INVALID_QUOTING},IP %{MULTIPART_INVALID_PART},IH %{MULTIPART_INVALID_HEADER_FOLDING},FL %{MULTIPART_FILE_LIMIT_EXCEEDED}'\\\"\",\n      \"SecRule MULTIPART_UNMATCHED_BOUNDARY \\\"@eq 1\\\" \\\"phase:2,deny,id:500096\\\"\",\n      \"SecRule REQBODY_PROCESSOR_ERROR \\\"@eq 1\\\" \\\"chain,phase:2,deny,id:500097\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"multipart parser (partial quoted boundary value - only end quote)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"266\",\n        \"Content-Type\": \"multipart/form-data;boundary=0000\\\"\",\n        \"Expect\": \"100-continue\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"--0000\\r\",\n        \"Content-Disposition: form-data; name=\\\"name\\\"\\r\",\n        \"\\r\",\n        \"Brian Rectanus\\r\",\n        \"--0000\\r\",\n        \"Content-Disposition: form-data; name=\\\"email\\\"\\r\",\n        \"\\r\",\n        \"brian.rectanus@breach.com\\r\",\n        \"--0000\\r\",\n        \"Content-Disposition: form-data; name=\\\"image\\\"; filename=\\\"image.jpg\\\"\\r\",\n        \"Content-Type: image/jpeg\\r\",\n        \"\\r\",\n        \"BINARYDATA\\r\",\n        \"--0000--\\r\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Invalid boundary in C-T \\\\(quote\\\\)\",\n      \"error_log\": \"msg \\\"Multipart request body failed strict validation:PE 1,BQ 0,BW 0,DB 0,DA 0,HF 0,LF 0,SM 0,IQ 0,IP 0,IH 0,FL \\\"\",\n      \"http_code\": 403\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule MULTIPART_STRICT_ERROR \\\"@eq 1\\\" \\\"phase:2,deny,id:500095,msg:'Multipart request body failed strict validation:PE %{REQBODY_PROCESSOR_ERROR},BQ %{MULTIPART_BOUNDARY_QUOTED},BW %{MULTIPART_BOUNDARY_WHITESPACE},DB %{MULTIPART_DATA_BEFORE},DA %{MULTIPART_DATA_AFTER},HF %{MULTIPART_HEADER_FOLDING},LF %{MULTIPART_LF_LINE},SM %{MULTIPART_MISSING_SEMICOLON},IQ %{MULTIPART_INVALID_QUOTING},IP %{MULTIPART_INVALID_PART},IH %{MULTIPART_INVALID_HEADER_FOLDING},FL %{MULTIPART_FILE_LIMIT_EXCEEDED}'\\\"\",\n      \"SecRule MULTIPART_UNMATCHED_BOUNDARY \\\"@eq 1\\\" \\\"phase:2,deny,id:500096\\\"\",\n      \"SecRule REQBODY_PROCESSOR_ERROR \\\"@eq 1\\\" \\\"chain,phase:2,deny,id:500097\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"multipart parser (multipart mixed - normal)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"523\",\n        \"Content-Type\": \"multipart/form-data; boundary=0000\",\n        \"Expect\": \"100-continue\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"--0000\\r\\n\",\n        \"Content-Disposition: form-data; name=\\\"name\\\"\\r\\n\",\n        \"\\r\\n\",\n        \"Brian Rectanus\\r\\n\",\n        \"--0000\\r\\n\",\n        \"Content-Disposition: form-data; name=\\\"email\\\"\\r\\n\",\n        \"\\r\\n\",\n        \"brian.rectanus@breach.com\\r\\n\",\n        \"--0000\\r\\n\",\n        \"Content-Disposition: attachment\\r\\n\",\n        \"Content-Type: multipart/mixed; boundary=BbC04y\\r\\n\",\n        \"\\r\\n\",\n        \"--BbC04y\\r\\n\",\n        \"Content-Disposition: file; filename=\\\"file1.txt\\\"\\r\\n\",\n        \"Content-Type: text/plain\\r\\n\",\n        \"\\r\\n\",\n        \"... contents of file1.txt ...\\r\\n\",\n        \"--BbC04y\\r\\n\",\n        \"Content-Disposition: file; filename=\\\"file2.gif\\r\\n\",\n        \"Content-Type: image/jpeg\\r\\n\",\n        \"Content-Transfer-Encoding: binary\\r\\n\",\n        \"\\r\\n\",\n        \"...contents of file2.gif...\\r\\n\",\n        \"--0000--\\r\\n\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Invalid Content-Disposition header\",\n      \"error_log\": \"msg \\\"Multipart request body failed strict validation:PE 1,BQ 0,BW 0,DB 0,DA 0,HF 0,LF 0,SM 0,IQ 0,IP 1,IH 0,FL \\\"\",\n      \"http_code\": 403\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule MULTIPART_STRICT_ERROR \\\"@eq 1\\\" \\\"phase:2,deny,id:500095,msg:'Multipart request body failed strict validation:PE %{REQBODY_PROCESSOR_ERROR},BQ %{MULTIPART_BOUNDARY_QUOTED},BW %{MULTIPART_BOUNDARY_WHITESPACE},DB %{MULTIPART_DATA_BEFORE},DA %{MULTIPART_DATA_AFTER},HF %{MULTIPART_HEADER_FOLDING},LF %{MULTIPART_LF_LINE},SM %{MULTIPART_MISSING_SEMICOLON},IQ %{MULTIPART_INVALID_QUOTING},IP %{MULTIPART_INVALID_PART},IH %{MULTIPART_INVALID_HEADER_FOLDING},FL %{MULTIPART_FILE_LIMIT_EXCEEDED}'\\\"\",\n      \"SecRule MULTIPART_UNMATCHED_BOUNDARY \\\"@eq 1\\\" \\\"phase:2,deny,id:500096\\\"\",\n      \"SecRule REQBODY_PROCESSOR_ERROR \\\"@eq 1\\\" \\\"chain,phase:2,deny,id:500097\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"multipart parser (multipart mixed - missing disposition)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"490\",\n        \"Content-Type\": \"multipart/form-data; boundary=0000\",\n        \"Expect\": \"100-continue\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"--0000\\r\\n\",\n        \"Content-Disposition: form-data; name=\\\"name\\\"\\r\\n\",\n        \"\\r\\n\",\n        \"Brian Rectanus\\r\\n\",\n        \"--0000\\r\\n\",\n        \"Content-Disposition: form-data; name=\\\"email\\\"\\r\\n\",\n        \"\\r\\n\",\n        \"brian.rectanus@breach.com\\r\\n\",\n        \"--0000\\r\\n\",\n        \"Content-Type: multipart/mixed; boundary=BbC04y\\r\\n\",\n        \"\\r\\n\",\n        \"--BbC04y\\r\\n\",\n        \"Content-Disposition: file; filename=\\\"file1.txt\\\"\\r\\n\",\n        \"Content-Type: text/plain\\r\\n\",\n        \"\\r\\n\",\n        \"... contents of file1.txt ...\\r\\n\",\n        \"--BbC04y\\r\\n\",\n        \"Content-Disposition: file; filename=\\\"file2.gif\\r\\n\",\n        \"Content-Type: image/jpeg\\r\\n\",\n        \"Content-Transfer-Encoding: binary\\r\\n\",\n        \"\\r\\n\",\n        \"...contents of file2.gif...\\r\\n\",\n        \"--0000--\\r\\n\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Part missing Content-Disposition header\",\n      \"error_log\": \"msg \\\"Multipart request body failed strict validation:PE 1,BQ 0,BW 0,DB 0,DA 0,HF 0,LF 0,SM 0,IQ 0,IP 1,IH 0,FL \\\"\",\n      \"http_code\": 403\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule MULTIPART_STRICT_ERROR \\\"@eq 1\\\" \\\"phase:2,deny,id:500095,msg:'Multipart request body failed strict validation:PE %{REQBODY_PROCESSOR_ERROR},BQ %{MULTIPART_BOUNDARY_QUOTED},BW %{MULTIPART_BOUNDARY_WHITESPACE},DB %{MULTIPART_DATA_BEFORE},DA %{MULTIPART_DATA_AFTER},HF %{MULTIPART_HEADER_FOLDING},LF %{MULTIPART_LF_LINE},SM %{MULTIPART_MISSING_SEMICOLON},IQ %{MULTIPART_INVALID_QUOTING},IP %{MULTIPART_INVALID_PART},IH %{MULTIPART_INVALID_HEADER_FOLDING},FL %{MULTIPART_FILE_LIMIT_EXCEEDED}'\\\"\",\n      \"SecRule MULTIPART_UNMATCHED_BOUNDARY \\\"@eq 1\\\" \\\"phase:2,deny,id:500096\\\"\",\n      \"SecRule REQBODY_PROCESSOR_ERROR \\\"@eq 1\\\" \\\"chain,phase:2,deny,id:500097\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"multipart parser (normal)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"596\",\n        \"Content-Type\": \"multipart/form-data; boundary=0000\",\n        \"Expect\": \"100-continue\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"--0000\\r\\n\",\n        \"Content-Disposition: form-data; name=\\\"name\\\"\\r\\n\",\n        \"\\r\\n\",\n        \"Brian Rectanus\\r\\n\",\n        \"--0000\\r\\n\",\n        \"Content-Disposition: form-data; name=\\\"email\\\"\\r\\n\",\n        \"\\r\\n\",\n        \"brian.rectanus@breach.com\\r\\n\",\n        \"--0000\\r\\n\",\n        \"Content-Disposition: form-data; name=\\\"image1\\\"; filename=\\\"image1.jpg\\\"\\r\\n\",\n        \"Content-Type: image/jpeg\\r\\n\",\n        \"\\r\\n\",\n        \"BINARYDATA1\\r\\n\",\n        \"--0000\\r\\n\",\n        \"Content-Disposition: form-data; name=\\\"image2\\\"; filename=\\\"image2.jpg\\\"\\r\\n\",\n        \"Content-Type: image/jpeg\\r\\n\",\n        \"\\r\\n\",\n        \"BINARYDATA2\\r\\n\",\n        \"--0000\\r\\n\",\n        \"Content-Disposition: form-data; name=\\\"image3\\\"; filename=\\\"image3.jpg\\\"\\r\\n\",\n        \"Content-Type: image/jpeg\\r\\n\",\n        \"\\r\\n\",\n        \"BINARYDATA3\\r\\n\",\n        \"--0000\\r\\n\",\n        \"Content-Disposition: form-data; name=\\\"test\\\"\\r\\n\",\n        \"\\r\\n\",\n        \"This is test data.\\r\\n\",\n        \"--0000--\\r\\n\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Upload file limit exceeded\",\n      \"http_code\": 403\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecUploadKeepFiles On\",\n      \"SecUploadDir /tmp\",\n      \"SecUploadFileLimit 2\",\n      \"SecRule MULTIPART_STRICT_ERROR \\\"!@eq 1\\\" \\\"phase:2,deny,id:500161\\\"\",\n      \"SecRule MULTIPART_FILE_LIMIT_EXCEEDED \\\"!@eq 1\\\" \\\"phase:2,deny,id:500162\\\"\",\n      \"SecRule REQBODY_PROCESSOR_ERROR \\\"@eq 1\\\" \\\"phase:2,deny,id:500163\\\"\",\n      \"SecRule &FILES \\\"!@eq 3\\\" \\\"phase:2,deny,id:500164\\\"\",\n      \"SecRule &FILES_NAMES \\\"!@eq 3\\\" \\\"phase:2,deny,id:500165\\\"\",\n      \"SecRule &FILES_SIZES \\\"!@eq 3\\\" \\\"phase:2,deny,id:500166\\\"\",\n      \"SecRule FILES_SIZES:/^image/ \\\"@eq 0\\\" \\\"phase:2,deny,id:500167\\\"\",\n      \"SecRule &FILES_TMPNAMES \\\"!@eq 2\\\" \\\"phase:2,deny,id:500168\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"multipart parser (contains foreign bound., no UNMATCH rule)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"549\",\n        \"Content-Type\": \"multipart/form-data; boundary=-----------------------------8842564605616207552020332273\",\n        \"Expect\": \"100-continue\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"-------------------------------8842564605616207552020332273\\r\",\n        \"Content-Disposition: form-data; name=\\\"_token\\\"\\r\",\n        \"\\r\",\n        \"9e433de44c9e9b4ce19603269aa34edb\\r\",\n        \"-------------------------------8842564605616207552020332273\\r\",\n        \"Content-Disposition: form-data; name=\\\"_attachments[]\\\"; filename=\\\"msg.txt\\\"\\r\",\n        \"Content-Type: text/plain\\r\",\n        \"\\r\",\n        \"----ea520cef1a2937d8e928e357992c8fdd\\r\",\n        \"Content-Transfer-Encoding: 7bit\\r\",\n        \"Content-Type: text/plain; charset=US-ASCII;\\r\",\n        \" format=flowed\\r\",\n        \"\\r\",\n        \"Test message, the txt file had been attached.\\r\",\n        \"\\r\",\n        \"--\\r\",\n        \"Ervin\\r\",\n        \"\\r\",\n        \"\\r\",\n        \"-------------------------------8842564605616207552020332273--\\r\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"multipart parser (contains foreign bound., strict mode)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"569\",\n        \"Content-Type\": \"multipart/form-data; boundary=-----------------------------8842564605616207552020332273\",\n        \"Expect\": \"100-continue\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"-------------------------------8842564605616207552020332273\\r\\n\",\n        \"Content-Disposition: form-data; name=\\\"_token\\\"\\r\\n\",\n        \"\\r\\n\",\n        \"9e433de44c9e9b4ce19603269aa34edb\\r\\n\",\n        \"-------------------------------8842564605616207552020332273\\r\\n\",\n        \"Content-Disposition: form-data; name=\\\"_attachments[]\\\"; filename=\\\"msg.txt\\\"\\r\\n\",\n        \"Content-Type: text/plain\\r\\n\",\n        \"\\r\\n\",\n        \"----ea520cef1a2937d8e928e357992c8fdd\\r\\n\",\n        \"Content-Transfer-Encoding: 7bit\\r\\n\",\n        \"Content-Type: text/plain; charset=US-ASCII;\\r\\n\",\n        \" format=flowed\\r\\n\",\n        \"\\r\\n\",\n        \"Test message, the txt file had been attached.\\r\\n\",\n        \"\\r\\n\",\n        \"--\\r\\n\",\n        \"Ervin\\r\\n\",\n        \"\\r\\n\",\n        \"\\r\\n\",\n        \"-------------------------------8842564605616207552020332273--\\r\\n\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"http_code\": 403\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule MULTIPART_UNMATCHED_BOUNDARY \\\"!@eq 0\\\" \\\"phase:2,deny,id:500095\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"multipart parser (ctest-cases/regression/request-body-parser-multipart.jsonontains foreign bound., wrong lead bound., strict mode)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"569\",\n        \"Content-Type\": \"multipart/form-data; boundary=-----------------------------8842564605616207552020332273\",\n        \"Expect\": \"100-continue\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"-------------------------------8842564605616207552020332274\\r\\n\",\n        \"Content-Disposition: form-data; name=\\\"_token\\\"\\r\\n\",\n        \"\\r\\n\",\n        \"9e433de44c9e9b4ce19603269aa34edb\\r\\n\",\n        \"-------------------------------8842564605616207552020332273\\r\\n\",\n        \"Content-Disposition: form-data; name=\\\"_attachments[]\\\"; filename=\\\"msg.txt\\\"\\r\\n\",\n        \"Content-Type: text/plain\\r\\n\",\n        \"\\r\\n\",\n        \"----ea520cef1a2937d8e928e357992c8fdd\\r\\n\",\n        \"Content-Transfer-Encoding: 7bit\\r\\n\",\n        \"Content-Type: text/plain; charset=US-ASCII;\\r\\n\",\n        \" format=flowed\\r\\n\",\n        \"\\r\\n\",\n        \"Test message, the txt file had been attached.\\r\\n\",\n        \"\\r\\n\",\n        \"--\\r\\n\",\n        \"Ervin\\r\\n\",\n        \"\\r\\n\",\n        \"\\r\\n\",\n        \"-------------------------------8842564605616207552020332273--\\r\\n\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"http_code\": 403\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule MULTIPART_UNMATCHED_BOUNDARY \\\"!@eq 0\\\" \\\"phase:2,deny,id:500095\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"multipart parser (contains foreign bound., wrong sep. bound., strict mode)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"569\",\n        \"Content-Type\": \"multipart/form-data; boundary=-----------------------------8842564605616207552020332273\",\n        \"Expect\": \"100-continue\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"-------------------------------8842564605616207552020332273\\r\\n\",\n        \"Content-Disposition: form-data; name=\\\"_token\\\"\\r\\n\",\n        \"\\r\\n\",\n        \"9e433de44c9e9b4ce19603269aa34edb\\r\\n\",\n        \"-------------------------------8842564605616207552020332274\\r\\n\",\n        \"Content-Disposition: form-data; name=\\\"_attachments[]\\\"; filename=\\\"msg.txt\\\"\\r\\n\",\n        \"Content-Type: text/plain\\r\\n\",\n        \"\\r\\n\",\n        \"----ea520cef1a2937d8e928e357992c8fdd\\r\\n\",\n        \"Content-Transfer-Encoding: 7bit\\r\\n\",\n        \"Content-Type: text/plain; charset=US-ASCII;\\r\\n\",\n        \" format=flowed\\r\\n\",\n        \"\\r\\n\",\n        \"Test message, the txt file had been attached.\\r\\n\",\n        \"\\r\\n\",\n        \"--\\r\\n\",\n        \"Ervin\\r\\n\",\n        \"\\r\\n\",\n        \"\\r\\n\",\n        \"-------------------------------8842564605616207552020332273--\\r\\n\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"http_code\": 403\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule MULTIPART_UNMATCHED_BOUNDARY \\\"!@eq 0\\\" \\\"phase:2,deny,id:500095\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"multipart parser (contains foreign bound., wrong final bound.)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"569\",\n        \"Content-Type\": \"multipart/form-data; boundary=-----------------------------8842564605616207552020332273\",\n        \"Expect\": \"100-continue\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"-------------------------------8842564605616207552020332273\\r\\n\",\n        \"Content-Disposition: form-data; name=\\\"_token\\\"\\r\\n\",\n        \"\\r\\n\",\n        \"9e433de44c9e9b4ce19603269aa34edb\\r\\n\",\n        \"-------------------------------8842564605616207552020332273\\r\\n\",\n        \"Content-Disposition: form-data; name=\\\"_attachments[]\\\"; filename=\\\"msg.txt\\\"\\r\\n\",\n        \"Content-Type: text/plain\\r\\n\",\n        \"\\r\\n\",\n        \"----ea520cef1a2937d8e928e357992c8fdd\\r\\n\",\n        \"Content-Transfer-Encoding: 7bit\\r\\n\",\n        \"Content-Type: text/plain; charset=US-ASCII;\\r\\n\",\n        \" format=flowed\\r\\n\",\n        \"\\r\\n\",\n        \"Test message, the txt file had been attached.\\r\\n\",\n        \"\\r\\n\",\n        \"--\\r\\n\",\n        \"Ervin\\r\\n\",\n        \"\\r\\n\",\n        \"\\r\\n\",\n        \"-------------------------------8842564605616207552020332274--\\r\\n\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"http_code\": 403\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule MULTIPART_UNMATCHED_BOUNDARY \\\"!@eq 0\\\" \\\"phase:2,deny,id:500095\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"multipart parser (contains foreign bound., one part, wrong lead)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"425\",\n        \"Content-Type\": \"multipart/form-data; boundary=-----------------------------8842564605616207552020332273\",\n        \"Expect\": \"100-continue\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"-------------------------------8842564605616207552020332274\\r\\n\",\n        \"Content-Disposition: form-data; name=\\\"_attachments[]\\\"; filename=\\\"msg.txt\\\"\\r\\n\",\n        \"Content-Type: text/plain\\r\\n\",\n        \"\\r\\n\",\n        \"----ea520cef1a2937d8e928e357992c8fdd\\r\\n\",\n        \"Content-Transfer-Encoding: 7bit\\r\\n\",\n        \"Content-Type: text/plain; charset=US-ASCII;\\r\\n\",\n        \" format=flowed\\r\\n\",\n        \"\\r\\n\",\n        \"Test message, the txt file had been attached.\\r\\n\",\n        \"\\r\\n\",\n        \"--\\r\\n\",\n        \"Ervin\\r\\n\",\n        \"\\r\\n\",\n        \"\\r\\n\",\n        \"-------------------------------8842564605616207552020332273--\\r\\n\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"http_code\": 403\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule MULTIPART_UNMATCHED_BOUNDARY \\\"!@eq 0\\\" \\\"phase:2,deny,id:500095\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"multipart parser (contains foreign bound., one part, wrong final)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"425\",\n        \"Content-Type\": \"multipart/form-data; boundary=-----------------------------8842564605616207552020332273\",\n        \"Expect\": \"100-continue\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"-------------------------------8842564605616207552020332273\\r\\n\",\n        \"Content-Disposition: form-data; name=\\\"_attachments[]\\\"; filename=\\\"msg.txt\\\"\\r\\n\",\n        \"Content-Type: text/plain\\r\\n\",\n        \"\\r\\n\",\n        \"----ea520cef1a2937d8e928e357992c8fdd\\r\\n\",\n        \"Content-Transfer-Encoding: 7bit\\r\\n\",\n        \"Content-Type: text/plain; charset=US-ASCII;\\r\\n\",\n        \" format=flowed\\r\\n\",\n        \"\\r\\n\",\n        \"Test message, the txt file had been attached.\\r\\n\",\n        \"\\r\\n\",\n        \"--\\r\\n\",\n        \"Ervin\\r\\n\",\n        \"\\r\\n\",\n        \"\\r\\n\",\n        \"-------------------------------8842564605616207552020332274--\\r\\n\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"http_code\": 403\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule MULTIPART_UNMATCHED_BOUNDARY \\\"!@eq 0\\\" \\\"phase:2,deny,id:500095\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"multipart parser (contains foreign bound., all valid, strict mode)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"777\",\n        \"Content-Type\": \"multipart/form-data; boundary=---------------------------3163850615828140691827348175\",\n        \"Expect\": \"100-continue\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"-----------------------------3163850615828140691827348175\\r\\n\",\n        \"Content-Disposition: form-data; name=\\\"_token\\\"\\r\\n\",\n        \"\\r\\n\",\n        \"3eeb646795ba8db63b05ba77df2a0b2c\\r\\n\",\n        \"-----------------------------3163850615828140691827348175\\r\\n\",\n        \"Content-Disposition: form-data; name=\\\"_attachments[]\\\"; filename=\\\"multipart_text.txt\\\"\\r\\n\",\n        \"Content-Type: text/plain\\r\\n\",\n        \"\\r\\n\",\n        \"Content-Type: multipart/alternative; boundary=\\\"00000000000041382f056d9314e6\\\"\\r\\n\",\n        \"\\r\\n\",\n        \"--00000000000041382f056d9314e6\\r\\n\",\n        \"Content-Type: text/plain; charset=\\\"UTF-8\\\"\\r\\n\",\n        \"Content-Transfer-Encoding: quoted-printable\\r\\n\",\n        \"\\r\\n\",\n        \"Hi,\\r\\n\",\n        \"\\r\\n\",\n        \"...\\r\\n\",\n        \"\\r\\n\",\n        \"--00000000000041382f056d9314e6\\r\\n\",\n        \"Content-Type: text/html; charset=\\\"UTF-8\\\"\\r\\n\",\n        \"Content-Transfer-Encoding: quoted-printable\\r\\n\",\n        \"\\r\\n\",\n        \"<div ...>\\r\\n\",\n        \"...\\r\\n\",\n        \"</div>\\r\\n\",\n        \"\\r\\n\",\n        \"--00000000000041382f056d9314e6--\\r\\n\",\n        \"\\r\\n\",\n        \"\\r\\n\",\n        \"-----------------------------3163850615828140691827348175--\\r\\n\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"http_code\": 403\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule MULTIPART_UNMATCHED_BOUNDARY \\\"!@eq 0\\\" \\\"phase:2,deny,id:500095\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"multipart parser (contains foreign bound., permissive mode)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"549\",\n        \"Content-Type\": \"multipart/form-data; boundary=-----------------------------8842564605616207552020332273\",\n        \"Expect\": \"100-continue\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"-------------------------------8842564605616207552020332273\\r\",\n        \"Content-Disposition: form-data; name=\\\"_token\\\"\\r\",\n        \"\\r\",\n        \"9e433de44c9e9b4ce19603269aa34edb\\r\",\n        \"-------------------------------8842564605616207552020332273\\r\",\n        \"Content-Disposition: form-data; name=\\\"_attachments[]\\\"; filename=\\\"msg.txt\\\"\\r\",\n        \"Content-Type: text/plain\\r\",\n        \"\\r\",\n        \"----ea520cef1a2937d8e928e357992c8fdd\\r\",\n        \"Content-Transfer-Encoding: 7bit\\r\",\n        \"Content-Type: text/plain; charset=US-ASCII;\\r\",\n        \" format=flowed\\r\",\n        \"\\r\",\n        \"Test message, the txt file had been attached.\\r\",\n        \"\\r\",\n        \"--\\r\",\n        \"Ervin\\r\",\n        \"\\r\",\n        \"\\r\",\n        \"-------------------------------8842564605616207552020332273--\\r\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule MULTIPART_UNMATCHED_BOUNDARY \\\"@eq 1\\\" \\\"phase:2,deny,id:500095\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"multipart parser (contains foreign bound., wrong lead bound., permissive mode)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"549\",\n        \"Content-Type\": \"multipart/form-data; boundary=-----------------------------8842564605616207552020332273\",\n        \"Expect\": \"100-continue\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"-------------------------------8842564605616207552020332274\\r\",\n        \"Content-Disposition: form-data; name=\\\"_token\\\"\\r\",\n        \"\\r\",\n        \"9e433de44c9e9b4ce19603269aa34edb\\r\",\n        \"-------------------------------8842564605616207552020332273\\r\",\n        \"Content-Disposition: form-data; name=\\\"_attachments[]\\\"; filename=\\\"msg.txt\\\"\\r\",\n        \"Content-Type: text/plain\\r\",\n        \"\\r\",\n        \"----ea520cef1a2937d8e928e357992c8fdd\\r\",\n        \"Content-Transfer-Encoding: 7bit\\r\",\n        \"Content-Type: text/plain; charset=US-ASCII;\\r\",\n        \" format=flowed\\r\",\n        \"\\r\",\n        \"Test message, the txt file had been attached.\\r\",\n        \"\\r\",\n        \"--\\r\",\n        \"Ervin\\r\",\n        \"\\r\",\n        \"\\r\",\n        \"-------------------------------8842564605616207552020332273--\\r\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule MULTIPART_UNMATCHED_BOUNDARY \\\"@eq 1\\\" \\\"phase:2,deny,id:500095\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"multipart parser (contains foreign bound., wrong sep. bound., permissive mode)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"549\",\n        \"Content-Type\": \"multipart/form-data; boundary=-----------------------------8842564605616207552020332273\",\n        \"Expect\": \"100-continue\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"-------------------------------8842564605616207552020332273\\r\",\n        \"Content-Disposition: form-data; name=\\\"_token\\\"\\r\",\n        \"\\r\",\n        \"9e433de44c9e9b4ce19603269aa34edb\\r\",\n        \"-------------------------------8842564605616207552020332274\\r\",\n        \"Content-Disposition: form-data; name=\\\"_attachments[]\\\"; filename=\\\"msg.txt\\\"\\r\",\n        \"Content-Type: text/plain\\r\",\n        \"\\r\",\n        \"----ea520cef1a2937d8e928e357992c8fdd\\r\",\n        \"Content-Transfer-Encoding: 7bit\\r\",\n        \"Content-Type: text/plain; charset=US-ASCII;\\r\",\n        \" format=flowed\\r\",\n        \"\\r\",\n        \"Test message, the txt file had been attached.\\r\",\n        \"\\r\",\n        \"--\\r\",\n        \"Ervin\\r\",\n        \"\\r\",\n        \"\\r\",\n        \"-------------------------------8842564605616207552020332273--\\r\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule MULTIPART_UNMATCHED_BOUNDARY \\\"@eq 1\\\" \\\"phase:2,deny,id:500095\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"multipart parser (contains foreign bound., all valid, permissive mode)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"747\",\n        \"Content-Type\": \"multipart/form-data; boundary=---------------------------3163850615828140691827348175\",\n        \"Expect\": \"100-continue\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"-----------------------------3163850615828140691827348175\\r\",\n        \"Content-Disposition: form-data; name=\\\"_token\\\"\\r\",\n        \"\\r\",\n        \"3eeb646795ba8db63b05ba77df2a0b2c\\r\",\n        \"-----------------------------3163850615828140691827348175\\r\",\n        \"Content-Disposition: form-data; name=\\\"_attachments[]\\\"; filename=\\\"multipart_text.txt\\\"\\r\",\n        \"Content-Type: text/plain\\r\",\n        \"\\r\",\n        \"Content-Type: multipart/alternative; boundary=\\\"00000000000041382f056d9314e6\\\"\\r\",\n        \"\\r\",\n        \"--00000000000041382f056d9314e6\\r\",\n        \"Content-Type: text/plain; charset=\\\"UTF-8\\\"\\r\",\n        \"Content-Transfer-Encoding: quoted-printable\\r\",\n        \"\\r\",\n        \"Hi,\\r\",\n        \"\\r\",\n        \"...\\r\",\n        \"\\r\",\n        \"--00000000000041382f056d9314e6\\r\",\n        \"Content-Type: text/html; charset=\\\"UTF-8\\\"\\r\",\n        \"Content-Transfer-Encoding: quoted-printable\\r\",\n        \"\\r\",\n        \"<div ...>\\r\",\n        \"...\\r\",\n        \"</div>\\r\",\n        \"\\r\",\n        \"--00000000000041382f056d9314e6--\\r\",\n        \"\\r\",\n        \"\\r\",\n        \"-----------------------------3163850615828140691827348175--\\r\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule MULTIPART_UNMATCHED_BOUNDARY \\\"@eq 1\\\" \\\"phase:2,deny,id:500095\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"multipart parser (C-T parm after boundary -- invalid but tolerated)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"144\",\n        \"Content-Type\": \"multipart/form-data; boundary=00000000; charset=UTF-8\",\n        \"Expect\": \"100-continue\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"--00000000\\r\\n\",\n        \"Content-Disposition: form-data; name=\\\"namea\\\"\\r\\n\",\n        \"\\r\\n\",\n        \"111\\r\\n\",\n        \"--00000000\\r\\n\",\n        \"Content-Disposition: form-data; name=\\\"nameb\\\"\\r\\n\",\n        \"\\r\\n\",\n        \"222\\r\\n\",\n        \"--00000000--\\r\\n\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Multipart: Invalid parameter after boundary in C-T \\\\(tolerated\\\\).*Added data\",\n      \"http_code\": 403\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRequestBodyAccess On\",\n      \"SecRule ARGS:namea \\\"@streq 111\\\" \\\"phase:2,deny,id:500096\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"multipart parser (invalid part header - contains invalid character)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"145\",\n        \"Content-Type\": \"multipart/form-data; boundary=a\",\n        \"Expect\": \"100-continue\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"--a\\r\\n\",\n        \"\\u000EContent-Disposition\\u000E: form-data; name=\\\"file\\\"; filename=\\\"1.jsp\\\"\\r\\n\",\n        \"Content-Disposition: form-data; name=\\\"post\\\";\\r\\n\",\n        \"\\r\\n\",\n        \"<%out.print(123)%>\\r\\n\",\n        \"--a--\\r\\n\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Multipart: Invalid part header \\\\(contains invalid character\\\\)\",\n      \"http_code\": 403\n    },\n    \"rules\": [\n      \"SecruleEngine On\",\n      \"SecRule REQBODY_PROCESSOR_ERROR \\\"@eq 1\\\" \\\"phase:2,deny,status:403,id:500077\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/request-body-parser-xml-validade-dtd.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing XML request body parser - validateDTD (validate ok)\",\n    \"resource\": \"libxml2\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Cookie\": \"PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120\",\n        \"Content-Type\": \"text/xml\",\n        \"Content-Length\": \"234\"\n      },\n      \"uri\": \"/?key=value&key=other_value\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"<?xml version=\\\"1.0\\\" encoding=\\\"utf-8\\\"?>\",\n        \"    <!DOCTYPE Envelope SYSTEM \\\"SoapEnvelope.dtd\\\">\",\n        \"    <Envelope>\",\n        \"        <Body>\",\n        \"            <getInput>\",\n        \"                <id type=\\\"string\\\">12123</id>\",\n        \"            </getInput>\",\n        \"        </Body>\",\n        \"    </Envelope>\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"XML: Successfully validated payload against DTD: test-cases/data/SoapEnvelope.dtd\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRequestBodyAccess On\",\n      \"SecXMLExternalEntity On\",\n      \"SecRule REQUEST_HEADERS:Content-Type \\\"^text/xml$\\\" \\\"id:500008,phase:1,t:none,t:lowercase,nolog,pass,ctl:requestBodyProcessor=XML\\\"\",\n      \"SecRule XML \\\"@validateDTD test-cases/data/SoapEnvelope.dtd\\\" \\\"id:500007,phase:3,deny\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing XML request body parser - validateDTD (validation failed)\",\n    \"resource\": \"libxml2\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Cookie\": \"PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120\",\n        \"Content-Type\": \"text/xml\",\n        \"Content-Length\": \"264\"\n      },\n      \"uri\": \"/?key=value&key=other_value\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"<?xml version=\\\"1.0\\\" encoding=\\\"utf-8\\\"?>\",\n        \"    <!DOCTYPE Envelope SYSTEM \\\"SoapEnvelope.dtd\\\">\",\n        \"        <Envelope>\",\n        \"            <xBody>\",\n        \"                <getInput>\",\n        \"                    <id type=\\\"string\\\">12123</id>\",\n        \"                </getInput>\",\n        \"            </xBody>\",\n        \"        </Envelope>\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"XML Error: No declaration for element xBody\",\n      \"http_code\": 403\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRequestBodyAccess On\",\n      \"SecXMLExternalEntity On\",\n      \"SecRule REQUEST_HEADERS:Content-Type \\\"^text/xml$\\\" \\\"id:500008,phase:1,t:none,t:lowercase,nolog,pass,ctl:requestBodyProcessor=XML\\\"\",\n      \"SecRule XML \\\"@validateDTD test-cases/data/SoapEnvelope.dtd\\\" \\\"id:500007,phase:3,deny\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing XML request body parser - validateDTD (bad XML)\",\n    \"resource\": \"libxml2\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Cookie\": \"PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120\",\n        \"Content-Type\": \"text/xml\",\n        \"Content-Length\": \"229\"\n      },\n      \"uri\": \"/?key=value&key=other_value\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"<?xml version=\\\"1.0\\\" encoding=\\\"utf-8\\\"?>\",\n        \"<!DOCTYPE Envelope SYSTEM \\\"SoapEnvelope.dtd\\\">\",\n        \"    <Envelop>\",\n        \"        <Body>\",\n        \"            <getInput>\",\n        \"                <id type=\\\"string\\\">12123</id>\",\n        \"            </getInput>\",\n        \"        </Body>\",\n        \"    </Envelope>\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"XML: DTD validation failed because content is not well formed\",\n      \"http_code\": 403\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRequestBodyAccess On\",\n      \"SecXMLExternalEntity On\",\n      \"SecRule REQUEST_HEADERS:Content-Type \\\"^text/xml$\\\" \\\"id:500008,phase:1,t:none,t:lowercase,nolog,pass,ctl:requestBodyProcessor=XML\\\"\",\n      \"SecRule XML \\\"@validateDTD test-cases/data/SoapEnvelope.dtd\\\" \\\"id:500007,phase:3,deny\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing XML request body parser - validateDTD (bad DTD)\",\n    \"resource\": \"libxml2\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Cookie\": \"PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120\",\n        \"Content-Type\": \"text/xml\",\n        \"Content-Length\": \"262\"\n      },\n      \"uri\": \"/?key=value&key=other_value\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"<?xml version=\\\"1.0\\\" encoding=\\\"utf-8\\\"?>\",\n        \"    <!DOCTYPE Envelope SYSTEM \\\"SoapEnvelope.dtd\\\">\",\n        \"        <Envelope>\",\n        \"            <Body>\",\n        \"                <getInput>\",\n        \"                    <id type=\\\"string\\\">12123</id>\",\n        \"                </getInput>\",\n        \"            </Body>\",\n        \"        </Envelope>\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Failed to load DTD: test-cases/data/SoapEnvelope-bad.dtd\",\n      \"http_code\": 403\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRequestBodyAccess On\",\n      \"SecXMLExternalEntity On\",\n      \"SecRule REQUEST_HEADERS:Content-Type \\\"^text/xml$\\\" \\\"id:500008,phase:1,t:none,t:lowercase,nolog,pass,ctl:requestBodyProcessor=XML\\\"\",\n      \"SecRule XML \\\"@validateDTD test-cases/data/SoapEnvelope-bad.dtd\\\" \\\"id:500007,phase:3,deny\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/request-body-parser-xml.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing XML request body parser (validate ok)\",\n    \"resource\": \"libxml2\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Cookie\": \"PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120\",\n        \"Content-Type\": \"text/xml\",\n        \"Content-Length\": \"675\"\n      },\n      \"uri\": \"/?key=value&key=other_value\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"<?xml version=\\\"1.0\\\" encoding=\\\"utf-8\\\"?>\",\n        \"    <soap:Envelope xmlns:soap=\\\"http://schemas.xmlsoap.org/soap/envelope/\\\"\",\n        \"       xmlns:soapenc=\\\"http://schemas.xmlsoap.org/soap/encoding/\\\"\",\n        \"       xmlns:tns=\\\"http://www.bluebank.example.com/axis/getBalance.jws\\\"\",\n        \"       xmlns:types=\\\"http://www.bluebank.example.com/axis/getBalance.jws/encodedTypes\\\"\",\n        \"       xmlns:xsi=\\\"http://www.w3.org/2001/XMLSchema-instance\\\"\",\n        \"       xmlns:xsd=\\\"http://www.w3.org/2001/XMLSchema\\\">\",\n        \"    <soap:Body soap:encodingStyle=\\\"http://schemas.xmlsoap.org/soap/encoding/\\\">\",\n        \"       <q1:getInput xmlns:q1=\\\"http://DefaultNamespace\\\">\",\n        \"           <id xsi:type=\\\"xsd:string\\\">12123</id>\",\n        \"       </q1:getInput>\",\n        \"    </soap:Body>\",\n        \"</soap:Envelope>\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"XML: Successfully validated payload against Schema:\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRequestBodyAccess On\",\n      \"SecXMLExternalEntity On\",\n      \"SecRule REQUEST_HEADERS:Content-Type \\\"^text/xml$\\\" \\\"id:500005,phase:1,t:none,t:lowercase,nolog,pass,ctl:requestBodyProcessor=XML\\\"\",\n      \"SecRule XML \\\"@validateSchema test-cases/data/SoapEnvelope.xsd\\\" \\\"id:500007,phase:3,deny\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing XML request body parser (validate attribute value failed)\",\n    \"resource\": \"libxml2\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Cookie\": \"PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120\",\n        \"Content-Type\": \"text/xml\",\n        \"Content-Length\": \"736\"\n      },\n      \"uri\": \"/?key=value&key=other_value\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"<?xml version=\\\"1.0\\\" encoding=\\\"utf-8\\\"?>\",\n        \"    <soap:Envelope xmlns:soap=\\\"http://schemas.xmlsoap.org/soap/envelope/\\\"\",\n        \"        xmlns:soapenc=\\\"http://schemas.xmlsoap.org/soap/encoding/\\\"\",\n        \"        xmlns:tns=\\\"http://www.bluebank.example.com/axis/getBalance.jws\\\"\",\n        \"        xmlns:types=\\\"http://www.bluebank.example.com/axis/getBalance.jws/encodedTypes\\\"\",\n        \"        xmlns:xsi=\\\"http://www.w3.org/2001/XMLSchema-instance\\\"\",\n        \"        xmlns:xsd=\\\"http://www.w3.org/2001/XMLSchema\\\">\",\n        \"        <soap:Body soap:mustUnderstand=\\\"badval\\\" soap:encodingStyle=\\\"http://schemas.xmlsoap.org/soap/encoding/\\\">\",\n        \"            <q1:getInput xmlns:q1=\\\"http://DefaultNamespace\\\">\",\n        \"                <id xsi:type=\\\"xsd:string\\\">12123</id>\",\n        \"            </q1:getInput>\",\n        \"        </soap:Body>\",\n        \"    </soap:Envelope>\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"'badval' is not a valid value of the local atomic type\",\n      \"http_code\": 403\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRequestBodyAccess On\",\n      \"SecXMLExternalEntity On\",\n      \"SecRule REQUEST_HEADERS:Content-Type \\\"^text/xml$\\\" \\\"id:500008,phase:1,t:none,t:lowercase,nolog,pass,ctl:requestBodyProcessor=XML\\\"\",\n      \"SecRule XML \\\"@validateSchema test-cases/data/SoapEnvelope.xsd\\\" \\\"id:500007,phase:3,deny\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing XML request body parser (validate failed)\",\n    \"resource\": \"libxml2\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Cookie\": \"PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120\",\n        \"Content-Type\": \"text/xml\",\n        \"Content-Length\": \"709\"\n      },\n      \"uri\": \"/?key=value&key=other_value\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"<?xml version=\\\"1.0\\\" encoding=\\\"utf-8\\\"?>\",\n        \"    <soap:Envelope xmlns:soap=\\\"http://schemas.xmlsoap.org/soap/envelope/\\\"\",\n        \"        xmlns:soapenc=\\\"http://schemas.xmlsoap.org/soap/encoding/\\\"\",\n        \"        xmlns:tns=\\\"http://www.bluebank.example.com/axis/getBalance.jws\\\"\",\n        \"        xmlns:types=\\\"http://www.bluebank.example.com/axis/getBalance.jws/encodedTypes\\\"\",\n        \"        xmlns:xsi=\\\"http://www.w3.org/2001/XMLSchema-instance\\\"\",\n        \"        xmlns:xsd=\\\"http://www.w3.org/2001/XMLSchema\\\">\",\n        \"        <soap:xBody soap:encodingStyle=\\\"http://schemas.xmlsoap.org/soap/encoding/\\\">\",\n        \"            <q1:getInput xmlns:q1=\\\"http://DefaultNamespace\\\">\",\n        \"                <id xsi:type=\\\"xsd:string\\\">12123</id>\",\n        \"            </q1:getInput>\",\n        \"        </soap:xBody>\",\n        \"    </soap:Envelope>\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"This element is not expected. Expected is one of\",\n      \"http_code\": 403\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRequestBodyAccess On\",\n      \"SecXMLExternalEntity On\",\n      \"SecRule REQUEST_HEADERS:Content-Type \\\"^text/xml$\\\" \\\"id:500008,phase:1,t:none,t:lowercase,nolog,pass,ctl:requestBodyProcessor=XML\\\"\",\n      \"SecRule XML \\\"@validateSchema test-cases/data/SoapEnvelope.xsd\\\" \\\"id:500007,phase:3,deny\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing XML request body parser (bad XML)\",\n    \"resource\": \"libxml2\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Cookie\": \"PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120\",\n        \"Content-Type\": \"text/xml\",\n        \"Content-Length\": \"709\"\n      },\n      \"uri\": \"/?key=value&key=other_value\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"<?xml version=\\\"1.0\\\" encoding=\\\"utf-8\\\"?>\",\n        \"    <soap:Envelope xmlns:soap=\\\"http://schemas.xmlsoap.org/soap/envelope/\\\"\",\n        \"        xmlns:soapenc=\\\"http://schemas.xmlsoap.org/soap/encoding/\\\"\",\n        \"        xmlns:tns=\\\"http://www.bluebank.example.com/axis/getBalance.jws\\\"\",\n        \"        xmlns:types=\\\"http://www.bluebank.example.com/axis/getBalance.jws/encodedTypes\\\"\",\n        \"        xmlns:xsi=\\\"http://www.w3.org/2001/XMLSchema-instance\\\"\",\n        \"        xmlns:xsd=\\\"http://www.w3.org/2001/XMLSchema\\\">\",\n        \"        <soap:xBody soap:encodingStyle=\\\"http://schemas.xmlsoap.org/soap/encoding/\\\">\",\n        \"            <q1:getInput xmlns:q1=\\\"http://DefaultNamespace\\\">\",\n        \"                <id xsi:type=\\\"xsd:string\\\">12123</id>\",\n        \"            </q1:getInput>\",\n        \"        </soap:xBody>\",\n        \"    </soap:Envelope>\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"XML Error: Element '{http://schemas.xmlsoap.org/soap/envelope/}xBody'\",\n      \"http_code\": 403\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRequestBodyAccess On\",\n      \"SecXMLExternalEntity On\",\n      \"SecRule REQUEST_HEADERS:Content-Type \\\"^text/xml$\\\" \\\"id:500008,phase:1,t:none,t:lowercase,nolog,pass,ctl:requestBodyProcessor=XML\\\"\",\n      \"SecRule XML \\\"@validateSchema test-cases/data/SoapEnvelope.xsd\\\" \\\"id:500007,phase:3,deny\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing XML request body parser (bad schema)\",\n    \"resource\": \"libxml2\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Cookie\": \"PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120\",\n        \"Content-Type\": \"text/xml\",\n        \"Content-Length\": \"683\"\n      },\n      \"uri\": \"/?key=value&key=other_value\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"<?xml version=\\\"1.0\\\" encoding=\\\"utf-8\\\"?>\",\n        \"    <soap:Envelope xmlns:soap=\\\"http://schemas.xmlsoap.org/soap/envelope/\\\"\",\n        \"        xmlns:soapenc=\\\"http://schemas.xmlsoap.org/soap/encoding/\\\"\",\n        \"        xmlns:tns=\\\"http://www.bluebank.example.com/axis/getBalance.jws\\\"\",\n        \"        xmlns:types=\\\"http://www.bluebank.example.com/axis/getBalance.jws/encodedTypes\\\"\",\n        \"        xmlns:xsi=\\\"http://www.w3.org/2001/XMLSchema-instance\\\"\",\n        \"        xmlns:xsd=\\\"http://www.w3.org/2001/XMLSchema\\\">\",\n        \"    <soap:Body soap:encodingStyle=\\\"http://schemas.xmlsoap.org/soap/encoding/\\\">\",\n        \"        <q1:getInput xmlns:q1=\\\"http://DefaultNamespace\\\">\",\n        \"            <id xsi:type=\\\"xsd:string\\\">12123</id>\",\n        \"        </q1:getInput>\",\n        \"    </soap:Body>\",\n        \"</soap:Envelope>\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"XML: Failed to load Schema: test-cases/data/SoapEnvelope-bad.xsd. XML Error: Failed to parse the XML resource 'test-cases/data/SoapEnvelope-bad.xsd\",\n      \"http_code\": 403\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRequestBodyAccess On\",\n      \"SecXMLExternalEntity On\",\n      \"SecRule REQUEST_HEADERS:Content-Type \\\"^text/xml$\\\" \\\"id:500008,phase:1,t:none,t:lowercase,nolog,pass,ctl:requestBodyProcessor=XML\\\"\",\n      \"SecRule XML \\\"@validateSchema test-cases/data/SoapEnvelope-bad.xsd\\\" \\\"id:500007,phase:3,deny\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/rule-920120.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: OWASP CRS id:920120\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept-Language\": \"en-us,en;q=0.5\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"413\",\n        \"Content-Type\": \"multipart/form-data; boundary=---------------------------265001916915724\",\n        \"Proxy-Connection\": \"keep-alive\",\n        \"Keep-Alive\": \"300\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"-----------------------------265001916915724\\r\\n\",\n        \"Content-Disposition: form-data; name=\\\"fi;le\\\"; filename=\\\"test\\\"\\r\\n\",\n        \"Content-Type: application/octet-stream\\r\\n\",\n        \"\\r\\n\",\n        \"Rotem & Ayala\\r\\n\",\n        \"\\r\\n\",\n        \"-----------------------------265001916915724\\r\\n\",\n        \"Content-Disposition: form-data; name=\\\"name\\\"\\r\\n\",\n        \"\\r\\n\",\n        \"tt2\\r\\n\",\n        \"-----------------------------265001916915724\\r\\n\",\n        \"Content-Disposition: form-data; name=\\\"B1\\\"\\r\\n\",\n        \"\\r\\n\",\n        \"Submit\\r\\n\",\n        \"-----------------------------265001916915724--\\r\\n\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"http_code\": 400\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecDefaultAction \\\"phase:2,deny,block,status:400,log\\\"\",\n      \"SecRule FILES_NAMES|FILES \\\"@rx (?<!&(?:[aAoOuUyY]uml)|&(?:[aAeEiIoOuU]circ)|&(?:[eEiIoOuUyY]acute)|&(?:[aAeEiIoOuU]grave)|&(?:[cC]cedil)|&(?:[aAnNoO]tilde)|&(?:amp)|&(?:apos));|['\\\\\\\"=]\\\" \\\"id:920120,phase:2,block,t:none,t:urlDecodeUni,msg:'Attempted multipart/form-data bypass',logdata:'%{MATCHED_VAR}',tag:'application-multi',tag:'language-multi',tag:'platform-multi',tag:'attack-protocol',tag:'OWASP_CRS/PROTOCOL_VIOLATION/INVALID_REQ',tag:'CAPEC-272',ver:'OWASP_CRS/3.1.0',severity:'CRITICAL',setvar:'tx.msg=%{rule.msg}',setvar:'tx.anomaly_score_pl1=+%{tx.critical_anomaly_score}',setvar:'tx.%{rule.id}-OWASP_CRS/PROTOCOL_VIOLATION/INVALID_REQ-%{MATCHED_VAR_NAME}=%{MATCHED_VAR}'\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/rule-920200.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Byte ranges :: OWASP CRS id:920200\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept-Language\": \"en-us,en;q=0.5\",\n        \"Accept\": \"*/*\",\n        \"Keep-Alive\": \"300\",\n        \"Range\": \"bytes=1-10,11-20,21-30,31-40,41-50,51-60\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"http_code\": 400\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecDefaultAction \\\"phase:2,deny,block,status:400,log\\\"\",\n      \"SecRule REQUEST_HEADERS:Range|REQUEST_HEADERS:Request-Range \\\"@rx ^bytes=(?:(?:\\\\d+)?\\\\-(?:\\\\d+)?\\\\s*,?\\\\s*){6}\\\" \\\"id:920200,phase:2,block,t:none,msg:'Range: Too many fields (6 or more)',logdata:'%{MATCHED_VAR}',tag:'application-multi',tag:'language-multi',tag:'platform-multi',tag:'attack-protocol',tag:'OWASP_CRS/PROTOCOL_VIOLATION/INVALID_HREQ',tag:'paranoia-level/2',ver:'OWASP_CRS/3.1.0',severity:'WARNING',chain\",\n      \"SecRule REQUEST_BASENAME \\\"!@endsWith .pdf\\\" \\\"setvar:'tx.msg=%{rule.msg}',setvar:'tx.anomaly_score_pl2=+%{tx.warning_anomaly_score}',setvar:'tx.%{rule.id}-OWASP_CRS/PROTOCOL_VIOLATION/INVALID_HREQ-%{MATCHED_VAR_NAME}=%{MATCHED_VAR}'\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/rule-920274.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Byte ranges :: OWASP CRS id:920274\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"Test\": \"ThisIsATest%60\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Invalid character in request headers\",\n      \"http_code\": 400\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecDefaultAction \\\"phase:2,deny,block,status:400,log\\\"\",\n      \"SecRule REQUEST_HEADERS|!REQUEST_HEADERS:User-Agent|!REQUEST_HEADERS:Referer|!REQUEST_HEADERS:Cookie \\\"@validateByteRange 32,34,38,42-59,61,65-90,95,97-122\\\" \\\"id:920274,phase:2,block,t:none,t:urlDecodeUni,msg:'Invalid character in request headers (outside of very strict set)',logdata:'%{MATCHED_VAR_NAME}=%{MATCHED_VAR}',tag:'application-multi',tag:'language-multi',tag:'platform-multi',tag:'attack-protocol',tag:'OWASP_CRS/PROTOCOL_VIOLATION/EVASION',tag:'paranoia-level/4',ver:'OWASP_CRS/3.1.0',severity:'CRITICAL',setvar:'tx.msg=%{rule.msg}',setvar:'tx.anomaly_score_pl4=+%{tx.critical_anomaly_score}',setvar:'tx.%{rule.id}-OWASP_CRS/PROTOCOL_VIOLATION/EVASION-%{MATCHED_VAR_NAME}=%{MATCHED_VAR}'\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/sec_component_signature.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"version_max\": 0,\n    \"title\": \"SecComponentSignature\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 2313\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"www.modsecurity.org\",\n        \"User-Agent\": \"Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)\",\n        \"Accept\": \"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\",\n        \"Accept-Language\": \"en-us,en;q=0.5\",\n        \"Accept-Encoding\": \"gzip,deflate\",\n        \"Accept-Charset\": \"ISO-8859-1,utf-8;q=0.7,*;q=0.7\",\n        \"Keep-Alive\": \"300\",\n        \"Connection\": \"keep-alive\",\n        \"Pragma\": \"no-cache\",\n        \"Cache-Control\": \"no-cache\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/test.pl?param1=   test   &param2=test2\",\n      \"method\": \"GET\",\n      \"http_version\": 1.1,\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Type\": \"plain/text\\n\\r\",\n        \"Content-Length\": \"4\"\n      },\n      \"body\": [\n        \"test\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \".*\",\n      \"http_code\": 403\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecComponentSignature \\\"OWASP_CRS/2.2.9\\\"\",\n      \"SecRule ARGS \\\"@contains test\\\" \\\"id:1,t:trim,deny,status:403,auditlog\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/secaction.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"version_max\": 0,\n    \"title\": \"sec action\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 2313\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"net.tutsplus.com\",\n        \"User-Agent\": \"Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)\",\n        \"Accept\": \"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\",\n        \"Accept-Language\": \"en-us,en;q=0.5\",\n        \"Accept-Encoding\": \"gzip,deflate\",\n        \"Accept-Charset\": \"ISO-8859-1,utf-8;q=0.7,*;q=0.7\",\n        \"Keep-Alive\": \"300\",\n        \"Connection\": \"keep-alive\",\n        \"Cookie\": \"PHPSESSID=r2t5uvjq435r4q7ib3vtdjq120\",\n        \"Pragma\": \"no-cache\",\n        \"Cache-Control\": \"no-cache\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/test.pl?param1=   test   &param2=test2\",\n      \"method\": \"GET\",\n      \"http_version\": 1.1,\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Type\": \"text/xml; charset=utf-8\\n\\r\",\n        \"Content-Length\": \"384\"\n      },\n      \"body\": [\n        \"<?xml version=\\\"1.0\\\" encoding=\\\"utf-8\\\"?>\\n\\r\",\n        \"<soap:Envelope xmlns:xsi=\\\"http://www.w3.org/2001/XMLSchema-instance\\\" xmlns:xsd=\\\"http://www.w3.org/2001/XMLSchema\\\" xmlns:soap=\\\"http://schemas.xmlsoap.org/soap/envelope/\\\">\\n\\r\",\n        \"  <soap:Body>\\n\\r\",\n        \"  <EnlightenResponse xmlns=\\\"http://clearforest.com/\\\">\\n\\r\",\n        \"  <EnlightenResult>string</EnlightenResult>\\n\\r\",\n        \"  </EnlightenResponse>\\n\\r\",\n        \"  </soap:Body>\\n\\r\",\n        \"</soap:Envelope>\\n\\r\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Executing unconditional rule\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule ARGS \\\"@contains test\\\" \\\"phase:2,id:1,t:trim\\\"\",\n      \"SecAction \\\"phase:2,nolog,pass\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/secargumentslimit.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing SecArgumentLimit not over limit (1/1)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Content-Type\": \"application/json\",\n        \"Content-Length\": \"86\"\n      },\n      \"uri\": \"/?foo=bar\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"{\",\n        \"       \\\"k1\\\":\\\"v1\\\",\",\n        \"       \\\"k2\\\":\\\"v2\\\",\",\n        \"       \\\"k3\\\":\\\"v3\\\",\",\n        \"       \\\"k4\\\":\\\"v4\\\",\",\n        \"       \\\"k5\\\":\\\"v5\\\"\",\n        \"}\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \" Running action deny\",\n      \"http_code\": 403\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecArgumentsLimit 6\",\n      \"SecRule REQUEST_HEADERS:Content-Type \\\"^application/json\\\" \\\"id:'200001',phase:1,t:none,pass,nolog,ctl:requestBodyProcessor=JSON\\\"\",\n      \"SecRule REQBODY_ERROR \\\"!@eq 0\\\" \\\"id:'200002', phase:2,t:none,log,deny,status:400,msg:'Failed to parse request body.',logdata:'%{reqbody_error_msg}'\\\"\",\n      \"SecRule ARGS:/k5/ \\\"@rx v5\\\" \\\"id:'1234',phase:2,deny,status:403,t:none,log,auditlog\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing SecArgumentLimit over limit (2/2)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Content-Type\": \"application/json\",\n        \"Content-Length\": \"86\"\n      },\n      \"uri\": \"/?foo=bar\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"{\",\n        \"       \\\"k1\\\":\\\"v1\\\",\",\n        \"       \\\"k2\\\":\\\"v2\\\",\",\n        \"       \\\"k3\\\":\\\"v3\\\",\",\n        \"       \\\"k4\\\":\\\"v4\\\",\",\n        \"       \\\"k5\\\":\\\"v5\\\"\",\n        \"}\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Skipping request argument, over limit\",\n      \"http_code\": 400\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecArgumentsLimit 5\",\n      \"SecRule REQUEST_HEADERS:Content-Type \\\"^application/json\\\" \\\"id:'200001',phase:1,t:none,pass,nolog,ctl:requestBodyProcessor=JSON\\\"\",\n      \"SecRule REQBODY_ERROR \\\"!@eq 0\\\" \\\"id:'200002', phase:2,t:none,log,deny,status:400,msg:'Failed to parse request body.',logdata:'%{reqbody_error_msg}'\\\"\",\n      \"SecRule ARGS:/k5/ \\\"@rx v5\\\" \\\"id:'1234',phase:2,deny,status:403,t:none,log,auditlog\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/secmarker.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"version_max\": 0,\n    \"title\": \"SecMarker 1\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 2313\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"net.tutsplus.com\",\n        \"User-Agent\": \"Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)\",\n        \"Accept\": \"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\",\n        \"Accept-Language\": \"en-us,en;q=0.5\",\n        \"Accept-Encoding\": \"gzip,deflate\",\n        \"Accept-Charset\": \"ISO-8859-1,utf-8;q=0.7,*;q=0.7\",\n        \"Keep-Alive\": \"300\",\n        \"Connection\": \"keep-alive\",\n        \"Cookie\": \"PHPSESSID=r2t5uvjq435r4q7ib3vtdjq120\",\n        \"Pragma\": \"no-cache\",\n        \"Cache-Control\": \"no-cache\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/test.pl?param1=   test   &param2=test2\",\n      \"method\": \"GET\",\n      \"http_version\": 1.1,\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Type\": \"text/xml; charset=utf-8\\n\\r\",\n        \"Content-Length\": \"384\"\n      },\n      \"body\": [\n        \"<?xml version=\\\"1.0\\\" encoding=\\\"utf-8\\\"?>\\n\\r\",\n        \"<soap:Envelope xmlns:xsi=\\\"http://www.w3.org/2001/XMLSchema-instance\\\" xmlns:xsd=\\\"http://www.w3.org/2001/XMLSchema\\\" xmlns:soap=\\\"http://schemas.xmlsoap.org/soap/envelope/\\\">\\n\\r\",\n        \"  <soap:Body>\\n\\r\",\n        \"  <EnlightenResponse xmlns=\\\"http://clearforest.com/\\\">\\n\\r\",\n        \"  <EnlightenResult>string</EnlightenResult>\\n\\r\",\n        \"  </EnlightenResponse>\\n\\r\",\n        \"  </soap:Body>\\n\\r\",\n        \"</soap:Envelope>\\n\\r\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"test\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule ARGS \\\"@contains test\\\" \\\"phase:2,id:1,t:trim\\\"\",\n      \"SecAction \\\"phase:2,nolog,pass\\\"\",\n      \"SecMarker HERE_GOES_A_MARKER\",\n      \"SecRule ARGS \\\"@contains test\\\" \\\"phase:2,id:2,t:trim\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"version_max\": 0,\n    \"title\": \"SecMarker 2\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 2313\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"net.tutsplus.com\",\n        \"User-Agent\": \"Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)\",\n        \"Accept\": \"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\",\n        \"Accept-Language\": \"en-us,en;q=0.5\",\n        \"Accept-Encoding\": \"gzip,deflate\",\n        \"Accept-Charset\": \"ISO-8859-1,utf-8;q=0.7,*;q=0.7\",\n        \"Keep-Alive\": \"300\",\n        \"Connection\": \"keep-alive\",\n        \"Cookie\": \"PHPSESSID=r2t5uvjq435r4q7ib3vtdjq120\",\n        \"Pragma\": \"no-cache\",\n        \"Cache-Control\": \"no-cache\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/test.pl?param1=   test   &param2=test2\",\n      \"method\": \"GET\",\n      \"http_version\": 1.1,\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Type\": \"text/xml; charset=utf-8\\n\\r\",\n        \"Content-Length\": \"384\"\n      },\n      \"body\": [\n        \"<?xml version=\\\"1.0\\\" encoding=\\\"utf-8\\\"?>\\n\\r\",\n        \"<soap:Envelope xmlns:xsi=\\\"http://www.w3.org/2001/XMLSchema-instance\\\" xmlns:xsd=\\\"http://www.w3.org/2001/XMLSchema\\\" xmlns:soap=\\\"http://schemas.xmlsoap.org/soap/envelope/\\\">\\n\\r\",\n        \"  <soap:Body>\\n\\r\",\n        \"  <EnlightenResponse xmlns=\\\"http://clearforest.com/\\\">\\n\\r\",\n        \"  <EnlightenResult>string</EnlightenResult>\\n\\r\",\n        \"  </EnlightenResponse>\\n\\r\",\n        \"  </soap:Body>\\n\\r\",\n        \"</soap:Envelope>\\n\\r\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Rule: 6\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule ARGS \\\"@contains test\\\" \\\"phase:2,id:1,t:trim,skipAfter:HERE_GOES_A_MARKER\\\"\",\n      \"SecRule ARGS \\\"@contains test1\\\" \\\"phase:2,id:2,t:trim\\\"\",\n      \"SecRule ARGS \\\"@contains test2\\\" \\\"phase:2,id:3,t:trim\\\"\",\n      \"SecRule ARGS \\\"@contains test3\\\" \\\"phase:2,id:4,t:trim\\\"\",\n      \"SecRule ARGS \\\"@contains test4\\\" \\\"phase:2,id:5,t:trim\\\"\",\n      \"SecAction \\\"phase:2,nolog,pass\\\"\",\n      \"SecMarker HERE_GOES_A_MARKER\",\n      \"SecRule ARGS \\\"@contains test5\\\" \\\"phase:2,id:6,t:trim\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/secruleengine.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Disruptive actions (1/n)\",\n    \"client\": {\n      \"ip\": \"\",\n      \"port\": 0\n    },\n    \"server\": {\n      \"ip\": \"\",\n      \"port\": 0\n    },\n    \"request\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \" Running action deny\",\n      \"http_code\": 403\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRuleEngine On\",\n      \"SecDefaultAction \\\"phase:2,deny,status:404\\\"\",\n      \"SecAction \\\"id:'900001',phase:request,nolog,status:403,t:none,block\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Disruptive actions (2/n)\",\n    \"client\": {\n      \"ip\": \"\",\n      \"port\": 0\n    },\n    \"server\": {\n      \"ip\": \"\",\n      \"port\": 0\n    },\n    \"request\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"\",\n      \"method\": \"\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Rule engine disabled, returning...\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRuleEngine Off\",\n      \"SecDefaultAction \\\"phase:2,deny,status:404\\\"\",\n      \"SecAction \\\"id:'1',phase:request,nolog,t:none,block\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Disruptive actions (3/n)\",\n    \"client\": {\n      \"ip\": \"\",\n      \"port\": 0\n    },\n    \"server\": {\n      \"ip\": \"\",\n      \"port\": 0\n    },\n    \"request\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"\",\n      \"method\": \"\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRuleEngine DetectionOnly\",\n      \"SecDefaultAction \\\"phase:2,deny,status:404\\\"\",\n      \"SecAction \\\"id:'1',phase:request,nolog,nolog,block,t:none,block\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Disruptive actions (4/n)\",\n    \"client\": {\n      \"ip\": \"\",\n      \"port\": 0\n    },\n    \"server\": {\n      \"ip\": \"\",\n      \"port\": 0\n    },\n    \"request\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"\",\n      \"method\": \"\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Rule engine disabled, returning...\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRuleEngine Off\",\n      \"SecDefaultAction \\\"phase:2,deny,status:404\\\"\",\n      \"SecAction \\\"id:'1',phase:request,nolog,t:none,block\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Disruptive actions (5/n)\",\n    \"client\": {\n      \"ip\": \"\",\n      \"port\": 0\n    },\n    \"server\": {\n      \"ip\": \"\",\n      \"port\": 0\n    },\n    \"request\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"\",\n      \"method\": \"\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Rule engine disabled, returning...\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRuleEngine Off\",\n      \"SecDefaultAction \\\"phase:2,deny,status:404\\\"\",\n      \"SecAction \\\"id:'1',phase:request,nolog,block,t:none,block\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/transformation-none.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"version_max\": 0,\n    \"title\": \"Testing transformations :: t:none\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 2313\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"net.tutsplus.com\",\n        \"User-Agent\": \"Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)\",\n        \"Accept\": \"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\",\n        \"Accept-Language\": \"en-us,en;q=0.5\",\n        \"Accept-Encoding\": \"gzip,deflate\",\n        \"Accept-Charset\": \"ISO-8859-1,utf-8;q=0.7,*;q=0.7\",\n        \"Keep-Alive\": \"300\",\n        \"Connection\": \"keep-alive\",\n        \"Cookie\": \"PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120\",\n        \"Pragma\": \"no-cache\",\n        \"Cache-Control\": \"no-cache\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/test.pl?param1=   test   &param2=test2\",\n      \"method\": \"GET\",\n      \"http_version\": 1.1,\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Type\": \"text/xml; charset=utf-8\\n\\r\",\n        \"Content-Length\": \"384\"\n      },\n      \"body\": [\n        \"<?xml version=\\\"1.0\\\" encoding=\\\"utf-8\\\"?>\\n\\r\",\n        \"<soap:Envelope xmlns:xsi=\\\"http://www.w3.org/2001/XMLSchema-instance\\\" xmlns:xsd=\\\"http://www.w3.org/2001/XMLSchema\\\" xmlns:soap=\\\"http://schemas.xmlsoap.org/soap/envelope/\\\">\\n\\r\",\n        \"  <soap:Body>\\n\\r\",\n        \"  <EnlightenResponse xmlns=\\\"http://clearforest.com/\\\">\\n\\r\",\n        \"  <EnlightenResult>string</EnlightenResult>\\n\\r\",\n        \"  </EnlightenResponse>\\n\\r\",\n        \"  </soap:Body>\\n\\r\",\n        \"</soap:Envelope>\\n\\r\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"rAAAAAAA2t5uvjq435r4q7ib3vtdjq120\\\" \\\\(Variable: REQUEST_COOKIES:PHPSESSID\\\\)\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule REQUEST_COOKIES \\\"@contains test \\\" \\\"id:1,t:lowercase,t:none\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"version_max\": 0,\n    \"title\": \"Testing transformations :: t:none\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 2313\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"net.tutsplus.com\",\n        \"User-Agent\": \"Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)\",\n        \"Accept\": \"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\",\n        \"Accept-Language\": \"en-us,en;q=0.5\",\n        \"Accept-Encoding\": \"gzip,deflate\",\n        \"Accept-Charset\": \"ISO-8859-1,utf-8;q=0.7,*;q=0.7\",\n        \"Keep-Alive\": \"300\",\n        \"Connection\": \"keep-alive\",\n        \"Cookie\": \"PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120\",\n        \"Pragma\": \"no-cache\",\n        \"Cache-Control\": \"no-cache\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/test.pl?param1=   test   &param2=test2\",\n      \"method\": \"GET\",\n      \"http_version\": 1.1,\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Type\": \"text/xml; charset=utf-8\\n\\r\",\n        \"Content-Length\": \"384\"\n      },\n      \"body\": [\n        \"<?xml version=\\\"1.0\\\" encoding=\\\"utf-8\\\"?>\\n\\r\",\n        \"<soap:Envelope xmlns:xsi=\\\"http://www.w3.org/2001/XMLSchema-instance\\\" xmlns:xsd=\\\"http://www.w3.org/2001/XMLSchema\\\" xmlns:soap=\\\"http://schemas.xmlsoap.org/soap/envelope/\\\">\\n\\r\",\n        \"  <soap:Body>\\n\\r\",\n        \"  <EnlightenResponse xmlns=\\\"http://clearforest.com/\\\">\\n\\r\",\n        \"  <EnlightenResult>string</EnlightenResult>\\n\\r\",\n        \"  </EnlightenResponse>\\n\\r\",\n        \"  </soap:Body>\\n\\r\",\n        \"</soap:Envelope>\\n\\r\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"raaaaaaa2t5uvjq435r4q7ib3vtdjq120\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule REQUEST_COOKIES \\\"@contains test \\\" \\\"id:14,t:none,t:lowercase\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/transformations.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"version_max\": 0,\n    \"title\": \"Testing transformations :: pass,t:trim\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 2313\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"net.tutsplus.com\",\n        \"User-Agent\": \"Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)\",\n        \"Accept\": \"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\",\n        \"Accept-Language\": \"en-us,en;q=0.5\",\n        \"Accept-Encoding\": \"gzip,deflate\",\n        \"Accept-Charset\": \"ISO-8859-1,utf-8;q=0.7,*;q=0.7\",\n        \"Keep-Alive\": \"300\",\n        \"Connection\": \"keep-alive\",\n        \"Cookie\": \"PHPSESSID=r2t5uvjq435r4q7ib3vtdjq120\",\n        \"Pragma\": \"no-cache\",\n        \"Cache-Control\": \"no-cache\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/test.pl?param1=   test   &param2=test2\",\n      \"method\": \"GET\",\n      \"http_version\": 1.1,\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Type\": \"text/xml; charset=utf-8\\n\\r\",\n        \"Content-Length\": \"384\"\n      },\n      \"body\": [\n        \"<?xml version=\\\"1.0\\\" encoding=\\\"utf-8\\\"?>\\n\\r\",\n        \"<soap:Envelope xmlns:xsi=\\\"http://www.w3.org/2001/XMLSchema-instance\\\" xmlns:xsd=\\\"http://www.w3.org/2001/XMLSchema\\\" xmlns:soap=\\\"http://schemas.xmlsoap.org/soap/envelope/\\\">\\n\\r\",\n        \"  <soap:Body>\\n\\r\",\n        \"  <EnlightenResponse xmlns=\\\"http://clearforest.com/\\\">\\n\\r\",\n        \"  <EnlightenResult>string</EnlightenResult>\\n\\r\",\n        \"  </EnlightenResponse>\\n\\r\",\n        \"  </soap:Body>\\n\\r\",\n        \"</soap:Envelope>\\n\\r\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \" t:trim: \\\"test\\\"\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule ARGS \\\"@contains test \\\" \\\"id:1,pass,t:trim\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"version_max\": 0,\n    \"title\": \"Testing transformations :: pass,t:trim,t:lowercase\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 2313\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"net.tutsplus.com\",\n        \"User-Agent\": \"Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)\",\n        \"Accept\": \"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\",\n        \"Accept-Language\": \"en-us,en;q=0.5\",\n        \"Accept-Encoding\": \"gzip,deflate\",\n        \"Accept-Charset\": \"ISO-8859-1,utf-8;q=0.7,*;q=0.7\",\n        \"Keep-Alive\": \"300\",\n        \"Connection\": \"keep-alive\",\n        \"Cookie\": \"PHPSESSID=r2t5uvjq435r4q7ib3vtdjq120\",\n        \"Pragma\": \"no-cache\",\n        \"Cache-Control\": \"no-cache\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/test.pl?param1=   WHEE   &param2=test2\",\n      \"method\": \"GET\",\n      \"http_version\": 1.1,\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Type\": \"text/xml; charset=utf-8\\n\\r\",\n        \"Content-Length\": \"384\"\n      },\n      \"body\": [\n        \"<?xml version=\\\"1.0\\\" encoding=\\\"utf-8\\\"?>\\n\\r\",\n        \"<soap:Envelope xmlns:xsi=\\\"http://www.w3.org/2001/XMLSchema-instance\\\" xmlns:xsd=\\\"http://www.w3.org/2001/XMLSchema\\\" xmlns:soap=\\\"http://schemas.xmlsoap.org/soap/envelope/\\\">\\n\\r\",\n        \"  <soap:Body>\\n\\r\",\n        \"  <EnlightenResponse xmlns=\\\"http://clearforest.com/\\\">\\n\\r\",\n        \"  <EnlightenResult>string</EnlightenResult>\\n\\r\",\n        \"  </EnlightenResponse>\\n\\r\",\n        \"  </soap:Body>\\n\\r\",\n        \"</soap:Envelope>\\n\\r\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"lowercase: \\\"test\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule ARGS \\\"@contains test \\\" \\\"id:1,pass,t:trim,t:lowercase\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/variable-ARGS.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: ARGS - GET (1/7)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?key=value&key=other_value\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"other_value\\\"\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule ARGS \\\"@contains test \\\" \\\"id:1,pass,t:trim\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: ARGS - GET (2/7)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?key=value&key=other_value\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"value\\\"\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule ARGS \\\"@contains test \\\" \\\"id:1,pass,t:trim\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: ARGS - POST (3/7)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"27\",\n        \"Content-Type\": \"application/x-www-form-urlencoded\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"param1=value1&param2=value2\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"value1\\\"\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule ARGS \\\"@contains test \\\" \\\"id:1,phase:3,pass,t:trim\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: ARGS - POST (4/7)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"27\",\n        \"Content-Type\": \"application/x-www-form-urlencoded\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"param1=value1&param2=value2\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"value2\\\"\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule ARGS \\\"@contains test \\\" \\\"id:1,phase:3,pass,t:trim\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: ARGS - POST (5/7)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"38\",\n        \"Content-Type\": \"application/x-www-form-urlencoded\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"param1=value1=morevalue1&param2=value2\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"value1=morevalue1\\\"\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule ARGS \\\"@contains test \\\" \\\"id:1,phase:3,pass,t:trim\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: ARGS - POST (6/7)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"46\",\n        \"Content-Type\": \"application/x-www-form-urlencoded\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"param1=value1=morevalue1&param2=value2&param3=\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"\\\" \\\\(Variable: ARGS:param3\\\\)\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule ARGS:param3 \\\"@contains test \\\" \\\"id:1,phase:3,pass,t:trim\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: ARGS - POST (7/7)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"43\",\n        \"Content-Type\": \"application/x-www-form-urlencoded\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"param1=value1=morevalue1&param2=value2&&&&&\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"value2\\\" \\\\(Variable: ARGS:param2\\\\)\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule ARGS:param2 \\\"@contains test \\\" \\\"id:1,phase:3,pass,t:trim\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/variable-ARGS_COMBINED_SIZE.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: ARGS_COMBINED_SIZE - GET (1/7)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?key=value&key=other_value\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"22.\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule ARGS_COMBINED_SIZE \\\"@gt 10 \\\" \\\"id:1,pass\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: ARGS_COMBINED_SIZE - GET (2/7)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?key=value&key=other_value&a=b\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"24.\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule ARGS_COMBINED_SIZE \\\"@gt 10 \\\" \\\"id:1,pass\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: ARGS_COMBINED_SIZE - POST (3/7)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"27\",\n        \"Content-Type\": \"application/x-www-form-urlencoded\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"param1=value1&param2=value2\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"24.\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule ARGS_COMBINED_SIZE \\\"@gt 10 \\\" \\\"id:1,phase:3,pass\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: ARGS_COMBINED_SIZE - POST (4/7)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"32\",\n        \"Content-Type\": \"application/x-www-form-urlencoded\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"param1=value1&param2=value2&a=b\\n\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"27.\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule ARGS_COMBINED_SIZE \\\"@gt 10 \\\" \\\"id:1,phase:3,pass,t:trim\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: ARGS_COMBINED_SIZE - POST (5/7)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"44\",\n        \"Content-Type\": \"application/x-www-form-urlencoded\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"a=%EC%A7%84%20%EB%A7%88%EC%9D%BC%20%EB%A6%AC\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"15.\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule ARGS_COMBINED_SIZE \\\"@gt 10 \\\" \\\"id:1,phase:3,pass,t:trim\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: ARGS_COMBINED_SIZE - GET (6/7)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\",\n        \"Content-Type\": \"application/x-www-form-urlencoded\"\n      },\n      \"uri\": \"/?z=%EC%A7%84%20%EB%A7%88%EC%9D%BC%20%EB%A6%AC\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"15.\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule ARGS_COMBINED_SIZE \\\"@gt 10 \\\" \\\"id:1,phase:3,pass,t:trim\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: ARGS_COMBINED_SIZE - GET (7/7)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\",\n        \"Content-Type\": \"application/x-www-form-urlencoded\"\n      },\n      \"uri\": \"/?z=진 마일 리\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"15.\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule ARGS_COMBINED_SIZE \\\"@gt 10 \\\" \\\"id:1,phase:3,pass,t:trim\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/variable-ARGS_GET.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: ARGS_GET (1/6)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?key=value&key=other_value\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"other_value\\\"\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule ARGS_GET \\\"@contains test \\\" \\\"id:1,pass,t:trim\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: ARGS_GET (2/6)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?key=value&key=other_value\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"value\\\"\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule ARGS_GET \\\"@contains test \\\" \\\"id:1,pass,t:trim\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: ARGS_GET (3/6)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?key=value&key=other_value%26withsomestuff=tootherstuff\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"other_value&withsomestuff=tootherstuff\\\"\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule ARGS_GET \\\"@contains test \\\" \\\"id:1,pass,t:trim\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: ARGS_GET (4/6)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?key=value&secondkey=&key3=val3\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"0\\\"\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule ARGS_GET:secondkey \\\"0\\\" \\\"id:1,phase:2,pass,t:none,t:length\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: ARGS_GET (5/6)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?key=value&secondkey=othervalue&\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"othervalue\\\"\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule ARGS_GET \\\"@rx ^othervalue$ \\\" \\\"id:1,pass,t:none\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: ARGS_GET (6/6)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?key=value&second_key=other_value#urifrag\",\n      \"method\": \"GET\",\n      \"http_version\": 1.1,\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"http_code\": 403\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule ARGS_GET \\\"@streq other_value\\\" \\\"id:1,phase:1,deny,status:403\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/variable-ARGS_GET_NAMES.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: ARGS_GET_NAMES (1/2)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?key1=value&key2=other_value\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"key1\\\"\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule ARGS_GET_NAMES \\\"@contains test \\\" \\\"id:1,pass,t:trim\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: ARGS_GET_NAMES (2/2)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?key1=value&key2=other_value\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"key2\\\"\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule ARGS_GET_NAMES \\\"@contains test \\\" \\\"id:1,pass,t:trim\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/variable-ARGS_NAMES.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: ARGS_NAMES - GET (1/4)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?key1=value&key2=other_value\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"key1\\\"\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule ARGS_NAMES \\\"@contains test \\\" \\\"id:1,pass,t:trim\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: ARGS_NAMES - GET (2/4)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?key1=value&key2=other_value\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"key2\\\"\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule ARGS_NAMES \\\"@contains test \\\" \\\"id:1,pass,t:trim\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: ARGS_NAMES - POST (3/4)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"27\",\n        \"Content-Type\": \"application/x-www-form-urlencoded\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"param1=value1&param2=value2\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"param1\\\"\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule ARGS_NAMES \\\"@contains test \\\" \\\"id:1,phase:3,pass,t:trim\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: ARGS_NAMES - POST (4/4)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"27\",\n        \"Content-Type\": \"application/x-www-form-urlencoded\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"param1=value1&param2=value2\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"param2\\\"\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule ARGS_NAMES \\\"@contains test \\\" \\\"id:1,phase:3,pass,t:trim\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: ARGS_POST_NAMES (3/x)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"142\",\n        \"Content-Type\": \"multipart/form-data; boundary=0000\",\n        \"Expect\": \"100-continue\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"--0000\\r\\n\",\n        \"Content-Disposition: form-data; name=\\\"name1\\\"\\r\\n\",\n        \"\\r\\n\",\n        \"content1\\r\\n\",\n        \"--0000\\r\\n\",\n        \"Content-Disposition: form-data; name=\\\"name2\\\"\\r\\n\",\n        \"\\r\\n\",\n        \"content2\\r\\n\",\n        \"--0000--\\r\\n\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"name1\\\" \\\\(Variable: ARGS_NAMES:name1\\\\)\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRequestBodyAccess On\",\n      \"SecRule ARGS_NAMES \\\"@contains test \\\" \\\"id:1,phase:3,pass,t:trim\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/variable-ARGS_POST.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: ARGS_POST (1/3)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"27\",\n        \"Content-Type\": \"application/x-www-form-urlencoded\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"param1=value1&param2=value2\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"value1\\\"\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule ARGS_POST \\\"@contains test \\\" \\\"id:1,phase:3,pass,t:trim\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: ARGS_POST (2/3)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"27\",\n        \"Content-Type\": \"application/x-www-form-urlencoded\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"param1=value1&param2=value2\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"value2\\\"\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule ARGS_POST \\\"@contains test \\\" \\\"id:1,phase:3,pass,t:trim\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: ARGS_POST (3/3)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"35\",\n        \"Content-Type\": \"application/x-www-form-urlencoded\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"param1=value1&param2=&param3=value3\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"0\\\"\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule ARGS_POST:param2 \\\"0\\\" \\\"id:1,phase:2,pass,t:none,t:length\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/variable-ARGS_POST_NAMES.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: ARGS_POST_NAMES (1/x)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"27\",\n        \"Content-Type\": \"application/x-www-form-urlencoded\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"param1=value1&param2=value2\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"param1\\\"\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule ARGS_POST_NAMES \\\"@contains test \\\" \\\"id:1,phase:3,pass,t:trim\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: ARGS_POST_NAMES (2/x)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"27\",\n        \"Content-Type\": \"application/x-www-form-urlencoded\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"param1=value1&param2=value2\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"param2\\\"\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule ARGS_POST_NAMES \\\"@contains test \\\" \\\"id:1,phase:3,pass,t:trim\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: ARGS_POST_NAMES (3/x)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"142\",\n        \"Content-Type\": \"multipart/form-data; boundary=0000\",\n        \"Expect\": \"100-continue\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"--0000\\r\\n\",\n        \"Content-Disposition: form-data; name=\\\"name1\\\"\\r\\n\",\n        \"\\r\\n\",\n        \"content1\\r\\n\",\n        \"--0000\\r\\n\",\n        \"Content-Disposition: form-data; name=\\\"name2\\\"\\r\\n\",\n        \"\\r\\n\",\n        \"content2\\r\\n\",\n        \"--0000--\\r\\n\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"name1\\\" \\\\(Variable: ARGS_POST_NAMES:name1\\\\)\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRequestBodyAccess On\",\n      \"SecRule ARGS_POST_NAMES \\\"@contains test \\\" \\\"id:1,phase:3,pass,t:trim\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: ARGS_POST_NAMES (3/x)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"142\",\n        \"Content-Type\": \"multipart/form-data; boundary=0000\",\n        \"Expect\": \"100-continue\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"--0000\\r\\n\",\n        \"Content-Disposition: form-data; name=\\\"name1\\\"\\r\\n\",\n        \"\\r\\n\",\n        \"content1\\r\\n\",\n        \"--0000\\r\\n\",\n        \"Content-Disposition: form-data; name=\\\"name2\\\"\\r\\n\",\n        \"\\r\\n\",\n        \"content2\\r\\n\",\n        \"--0000--\\r\\n\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"error_log\": \"o0,5v206,5t:trim\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRequestBodyAccess On\",\n      \"SecRule ARGS_POST_NAMES \\\"@contains name1\\\" \\\"id:1,phase:3,pass,t:trim\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/variable-AUTH_TYPE.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: AUTH_TYPE\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"27\",\n        \"Content-Type\": \"application/x-www-form-urlencoded\",\n        \"Authorization\": \"Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"param1=value1&param2=value2\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"Basic\\\"\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule AUTH_TYPE \\\"@contains test \\\" \\\"id:1,phase:3,pass,t:trim\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: AUTH_TYPE\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"27\",\n        \"Content-Type\": \"application/x-www-form-urlencoded\",\n        \"AuThOrIzAtIoN\": \"Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"param1=value1&param2=value2\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"Basic\\\"\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule AUTH_TYPE \\\"@contains test \\\" \\\"id:1,phase:3,pass,t:trim\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/variable-DURATION.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: AUTH_TYPE\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"27\",\n        \"Content-Type\": \"application/x-www-form-urlencoded\",\n        \"Authorization\": \"Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"param1=value1&param2=value2\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"[0-9\\\\.]+\\\"\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule DURATION \\\"@contains test \\\" \\\"id:1,phase:3,pass,t:trim\\\"\",\n      \"SecRule DURATION \\\"@contains test \\\" \\\"id:2,phase:3,pass,t:trim\\\"\",\n      \"SecRule DURATION \\\"@contains test \\\" \\\"id:3,phase:3,pass,t:trim\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/variable-ENV.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: ENV (1/4)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"27\",\n        \"Content-Type\": \"application/x-www-form-urlencoded\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"param1=value1&param2=value2\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Variable: ENV:PATH\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule ENV:PATH \\\"@contains test\\\" \\\"id:1,phase:3,pass,t:trim\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: ENV (2/4)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"27\",\n        \"Content-Type\": \"application/x-www-form-urlencoded\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"param1=value1&param2=value2\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"regression tests\\\" .Variable: ENV:MODSECURITY.\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule ENV:MODSECURITY \\\"@contains test\\\" \\\"id:1,phase:3,pass,t:trim\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: ENV (3/4)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"27\",\n        \"Content-Type\": \"application/x-www-form-urlencoded\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"param1=value1&param2=value2\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"bar\\\" .Variable: ENV:modfoo.\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule ARGS \\\"@contains value\\\" \\\"id:1,phase:3,pass,t:trim,setenv:modfoo=bar\\\"\",\n      \"SecRule ENV:modfoo \\\"@contains test\\\" \\\"id:2,phase:3,pass,t:trim\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: ENV (4/4)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"27\",\n        \"Content-Type\": \"application/x-www-form-urlencoded\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"param1=value1&param2=value2\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Variable: ENV:PATH\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule ENV \\\"@contains test\\\" \\\"id:1,phase:3,pass,t:trim\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/variable-FILES.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: FILES (1/2)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"516\",\n        \"Content-Type\": \"multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2\",\n        \"Expect\": \"100-continue\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"----------------------------756b6d74fa1a8ee2\\n\",\n        \"Content-Disposition: form-data; name=\\\"name\\\"\\n\",\n        \"\\n\",\n        \"test\\n\",\n        \"----------------------------756b6d74fa1a8ee2\\n\",\n        \"Content-Disposition: form-data; name=\\\"filedata\\\"; filename=\\\"small_text_file.txt\\\"\\n\",\n        \"Content-Type: text/plain\\n\",\n        \"\\n\",\n        \"This is a very small test file..\\n\",\n        \"----------------------------756b6d74fa1a8ee2\\n\",\n        \"Content-Disposition: form-data; name=\\\"filedata\\\"; filename=\\\"small_text_file.txt\\\"\\n\",\n        \"Content-Type: text/plain\\n\",\n        \"\\n\",\n        \"This is another very small test file..\\n\",\n        \"----------------------------756b6d74fa1a8ee2--\\n\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"T \\\\(0\\\\) t:trim: \\\"small_text_file\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule FILES \\\"@contains small_text_file.txt\\\" \\\"id:1,phase:3,pass,t:trim\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: FILES (2/2)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"502\",\n        \"Content-Type\": \"multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2\",\n        \"Expect\": \"100-continue\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"----------------------------756b6d74fa1a8ee2\\n\",\n        \"Content-Disposition: form-data; name=\\\"name\\\"\\n\",\n        \"\\n\",\n        \"test\\n\",\n        \"----------------------------756b6d74fa1a8ee2\\n\",\n        \"Content-Disposition: form-data; name=\\\"filedata1\\\"; filename=\\\"myfile.txt\\\"\\n\",\n        \"Content-Type: text/plain\\n\",\n        \"\\n\",\n        \"This is a very small test file..\\n\",\n        \"----------------------------756b6d74fa1a8ee2\\n\",\n        \"Content-Disposition: form-data; name=\\\"filedata2\\\"; filename=\\\"nextfile.txt\\\"\\n\",\n        \"Content-Type: text/plain\\n\",\n        \"\\n\",\n        \"This is another very small test file..\\n\",\n        \"----------------------------756b6d74fa1a8ee2--\\n\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"http_code\": 403\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule FILES:filedata1 \\\"@contains myfile.txt\\\" \\\"id:1,phase:2,deny,status:403\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/variable-FILES_COMBINED_SIZE.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: FILES_NAMES (1/1)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"516\",\n        \"Content-Type\": \"multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2\",\n        \"Expect\": \"100-continue\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"----------------------------756b6d74fa1a8ee2\\n\",\n        \"Content-Disposition: form-data; name=\\\"name\\\"\\n\",\n        \"\\n\",\n        \"test\\n\",\n        \"----------------------------756b6d74fa1a8ee2\\n\",\n        \"Content-Disposition: form-data; name=\\\"filedata\\\"; filename=\\\"small_text_file.txt\\\"\\n\",\n        \"Content-Type: text/plain\\n\",\n        \"\\n\",\n        \"This is a very small test file..\\n\",\n        \"----------------------------756b6d74fa1a8ee2\\n\",\n        \"Content-Disposition: form-data; name=\\\"filedata\\\"; filename=\\\"small_text_file.txt\\\"\\n\",\n        \"Content-Type: text/plain\\n\",\n        \"\\n\",\n        \"This is another very small test file..\\n\",\n        \"----------------------------756b6d74fa1a8ee2--\\n\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"70\\\" \\\\(Variable: FILES_COMBINED_SIZE\\\\)\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule FILES_COMBINED_SIZE \\\"@gt 70\\\" \\\"id:1,phase:3,pass,t:trim\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/variable-FILES_NAMES.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: FILES_NAMES (1/1)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"516\",\n        \"Content-Type\": \"multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2\",\n        \"Expect\": \"100-continue\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"----------------------------756b6d74fa1a8ee2\\n\",\n        \"Content-Disposition: form-data; name=\\\"name\\\"\\n\",\n        \"\\n\",\n        \"test\\n\",\n        \"----------------------------756b6d74fa1a8ee2\\n\",\n        \"Content-Disposition: form-data; name=\\\"filedata\\\"; filename=\\\"small_text_file.txt\\\"\\n\",\n        \"Content-Type: text/plain\\n\",\n        \"\\n\",\n        \"This is a very small test file..\\n\",\n        \"----------------------------756b6d74fa1a8ee2\\n\",\n        \"Content-Disposition: form-data; name=\\\"filedata\\\"; filename=\\\"small_text_file.txt\\\"\\n\",\n        \"Content-Type: text/plain\\n\",\n        \"\\n\",\n        \"This is another very small test file..\\n\",\n        \"----------------------------756b6d74fa1a8ee2--\\n\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"T \\\\(0\\\\) t:trim: \\\"filedata\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule FILES_NAMES \\\"@contains filedata\\\" \\\"id:1,phase:3,pass,t:trim\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/variable-FILES_SIZES.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: FILES_NAMES (1/1)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"516\",\n        \"Content-Type\": \"multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2\",\n        \"Expect\": \"100-continue\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"----------------------------756b6d74fa1a8ee2\\n\",\n        \"Content-Disposition: form-data; name=\\\"name\\\"\\n\",\n        \"\\n\",\n        \"test\\n\",\n        \"----------------------------756b6d74fa1a8ee2\\n\",\n        \"Content-Disposition: form-data; name=\\\"filedata\\\"; filename=\\\"small_text_file.txt\\\"\\n\",\n        \"Content-Type: text/plain\\n\",\n        \"\\n\",\n        \"This is a very small test file..\\n\",\n        \"----------------------------756b6d74fa1a8ee2\\n\",\n        \"Content-Disposition: form-data; name=\\\"filedata\\\"; filename=\\\"small_text_file.txt\\\"\\n\",\n        \"Content-Type: text/plain\\n\",\n        \"\\n\",\n        \"This is another very small test file..\\n\",\n        \"----------------------------756b6d74fa1a8ee2--\\n\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"38\\\" \\\\(Variable: FILES_SIZES:filedata\\\\)\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule FILES_SIZES \\\"@gt 70.000000\\\" \\\"id:1,phase:3,pass,t:trim\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/variable-FULL_REQUEST.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: FULL_REQUEST (1/1)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"523\",\n        \"Content-Type\": \"multipart/form-data; boundary=------------------------756b6d74fa1a8ee2\",\n        \"Expect\": \"100-continue\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"--------------------------756b6d74fa1a8ee2\\r\\n\",\n        \"Content-Disposition: form-data; name=\\\"name\\\"\\r\\n\",\n        \"\\r\\n\",\n        \"test\\r\\n\",\n        \"--------------------------756b6d74fa1a8ee2\\r\\n\",\n        \"Content-Disposition: form-data; name=\\\"filedata\\\"; filename=\\\"small_text_file.txt\\\"\\r\\n\",\n        \"Content-Type: text/plain\\r\\n\",\n        \"\\r\\n\",\n        \"This is a very small test file..\\r\\n\",\n        \"--------------------------756b6d74fa1a8ee2\\r\\n\",\n        \"Content-Disposition: form-data; name=\\\"filedata\\\"; filename=\\\"small_text_file.txt\\\"\\r\\n\",\n        \"Content-Type: text/plain\\r\\n\",\n        \"\\r\\n\",\n        \"This is another very small test file..\\r\\n\",\n        \"--------------------------756b6d74fa1a8ee2--\\r\\n\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Multipart: Boundary: ------------------------756b6d74fa1a8ee2\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRequestBodyAccess On\",\n      \"SecRule FULL_REQUEST \\\"@contains small_text_file.txt\\\" \\\"id:1,phase:3,pass,t:trim\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/variable-FULL_REQUEST_LENGTH.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: FULL_REQUEST_LENGTH (1/1)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"508\",\n        \"Content-Type\": \"multipart/form-data; boundary=------------------------756b6d74fa1a8ee2\",\n        \"Expect\": \"100-continue\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"--------------------------756b6d74fa1a8ee2\\n\",\n        \"Content-Disposition: form-data; name=\\\"name\\\"\\n\",\n        \"\\n\",\n        \"test\\n\",\n        \"--------------------------756b6d74fa1a8ee2\\n\",\n        \"Content-Disposition: form-data; name=\\\"filedata\\\"; filename=\\\"small_text_file.txt\\\"\\n\",\n        \"Content-Type: text/plain\\n\",\n        \"\\n\",\n        \"This is a very small test file..\\n\",\n        \"--------------------------756b6d74fa1a8ee2\\n\",\n        \"Content-Disposition: form-data; name=\\\"filedata\\\"; filename=\\\"small_text_file.txt\\\"\\n\",\n        \"Content-Type: text/plain\\n\",\n        \"\\n\",\n        \"This is another very small test file..\\n\",\n        \"--------------------------756b6d74fa1a8ee2--\\n\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"688\\\" \\\\(Variable: FULL_REQUEST_LENGTH\\\\)\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRequestBodyAccess On\",\n      \"SecRule FULL_REQUEST_LENGTH \\\"@contains small_text_file.txt\\\" \\\"id:1,phase:3,pass,t:trim\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/variable-GEO.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: GEO:LONGITUDE [GeoIP]\",\n    \"resource\": \"geoip\",\n    \"client\": {\n      \"ip\": \"64.17.254.216\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?key=value&key=other_value\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"-118.403999\\\" \\\\(Variable: GEO:LONGITUDE\\\\)\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecGeoLookupDb test-cases/data/geo/GeoIPCity.dat\",\n      \"SecRule REMOTE_ADDR \\\"@geoLookup\\\" \\\"id:1,pass,t:trim\\\"\",\n      \"SecRule GEO \\\"@contains test \\\" \\\"id:2,pass,t:trim\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: GEO:COUNTRY_NAME [maxmind]\",\n    \"resource\": \"maxmind\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?key=value&key=other_value\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"Brazil\\\" \\\\(Variable: GEO:COUNTRY_NAME\\\\)\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecGeoLookupDb test-cases/data/GeoIP2-City-Test.mmdb\",\n      \"SecRule REMOTE_ADDR \\\"@geoLookup\\\" \\\"id:1,pass,t:trim\\\"\",\n      \"SecRule GEO \\\"@contains test \\\" \\\"id:2,pass,t:trim\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: GEO:LATITUDE [GeoIP]\",\n    \"resource\": \"geoip\",\n    \"client\": {\n      \"ip\": \"64.17.254.216\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?key=value&key=other_value\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"33.916401\\\" \\\\(Variable: GEO:LATITUDE\\\\)\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecGeoLookupDb test-cases/data/geo/GeoIPCity.dat\",\n      \"SecRule REMOTE_ADDR \\\"@geoLookup\\\" \\\"id:1,pass,t:trim\\\"\",\n      \"SecRule GEO \\\"@contains test \\\" \\\"id:2,pass,t:trim\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: GEO:COUNTRY_CODE3 [GeoIP]\",\n    \"resource\": \"geoip\",\n    \"client\": {\n      \"ip\": \"64.17.254.216\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?key=value&key=other_value\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"USA\\\" \\\\(Variable: GEO:COUNTRY_CODE3\\\\)\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecGeoLookupDb test-cases/data/geo/GeoIPCity.dat\",\n      \"SecRule REMOTE_ADDR \\\"@geoLookup\\\" \\\"id:1,pass,t:trim\\\"\",\n      \"SecRule GEO \\\"@contains test \\\" \\\"id:2,pass,t:trim\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: GEO:COUNTRY_CODE [GeoIP]\",\n    \"resource\": \"geoip\",\n    \"client\": {\n      \"ip\": \"64.17.254.216\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?key=value&key=other_value\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"US\\\" \\\\(Variable: GEO:COUNTRY_CODE\\\\)\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecGeoLookupDb test-cases/data/geo/GeoIPCity.dat\",\n      \"SecRule REMOTE_ADDR \\\"@geoLookup\\\" \\\"id:1,pass,t:trim\\\"\",\n      \"SecRule GEO \\\"@contains test \\\" \\\"id:2,pass,t:trim\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: GEO:COUNTRY_CONTINENT [GeoIP]\",\n    \"resource\": \"geoip\",\n    \"client\": {\n      \"ip\": \"64.17.254.216\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?key=value&key=other_value\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"NA\\\" \\\\(Variable: GEO:COUNTRY_CONTINENT\\\\)\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecGeoLookupDb test-cases/data/geo/GeoIPCity.dat\",\n      \"SecRule REMOTE_ADDR \\\"@geoLookup\\\" \\\"id:1,pass,t:trim\\\"\",\n      \"SecRule GEO \\\"@contains test \\\" \\\"id:2,pass,t:trim\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: GEO:AREA_CODE [GeoIP]\",\n    \"resource\": \"geoip\",\n    \"client\": {\n      \"ip\": \"64.17.254.216\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?key=value&key=other_value\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"310\\\" \\\\(Variable: GEO:AREA_CODE\\\\)\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecGeoLookupDb test-cases/data/geo/GeoIPCity.dat\",\n      \"SecRule REMOTE_ADDR \\\"@geoLookup\\\" \\\"id:1,pass,t:trim\\\"\",\n      \"SecRule GEO \\\"@contains test \\\" \\\"id:2,pass,t:trim\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: GEO:DMA_CODE [GeoIP]\",\n    \"resource\": \"geoip\",\n    \"client\": {\n      \"ip\": \"64.17.254.216\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?key=value&key=other_value\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"803\\\" \\\\(Variable: GEO:DMA_CODE\\\\)\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecGeoLookupDb test-cases/data/geo/GeoIPCity.dat\",\n      \"SecRule REMOTE_ADDR \\\"@geoLookup\\\" \\\"id:1,pass,t:trim\\\"\",\n      \"SecRule GEO \\\"@contains test \\\" \\\"id:2,pass,t:trim\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: GEO:POSTAL_CODE [GeoIP]\",\n    \"resource\": \"geoip\",\n    \"client\": {\n      \"ip\": \"64.17.254.216\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?key=value&key=other_value\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"90245\\\" \\\\(Variable: GEO:POSTAL_CODE\\\\)\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecGeoLookupDb test-cases/data/geo/GeoIPCity.dat\",\n      \"SecRule REMOTE_ADDR \\\"@geoLookup\\\" \\\"id:1,pass,t:trim\\\"\",\n      \"SecRule GEO \\\"@contains test \\\" \\\"id:2,pass,t:trim\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: GEO:REGION [GeoIP]\",\n    \"resource\": \"geoip\",\n    \"client\": {\n      \"ip\": \"64.17.254.216\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?key=value&key=other_value\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"California\\\" \\\\(Variable: GEO:REGION\\\\)\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecGeoLookupDb test-cases/data/geo/GeoIPCity.dat\",\n      \"SecRule REMOTE_ADDR \\\"@geoLookup\\\" \\\"id:1,pass,t:trim\\\"\",\n      \"SecRule GEO \\\"@contains test \\\" \\\"id:2,pass,t:trim\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: GEO:CITY [GeoIP]\",\n    \"resource\": \"geoip\",\n    \"client\": {\n      \"ip\": \"64.17.254.216\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?key=value&key=other_value\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"El Segundo\\\" \\\\(Variable: GEO:CITY\\\\)\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecGeoLookupDb test-cases/data/geo/GeoIPCity.dat\",\n      \"SecRule REMOTE_ADDR \\\"@geoLookup\\\" \\\"id:1,pass,t:trim\\\"\",\n      \"SecRule GEO \\\"@contains test \\\" \\\"id:2,pass,t:trim\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: GEO:LONGITUDE [GeoIP]\",\n    \"resource\": \"geoip\",\n    \"client\": {\n      \"ip\": \"64.17.254.216\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?key=value&key=other_value\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"-118.403999\\\" \\\\(Variable: GEO:LONGITUDE\\\\)\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecGeoLookupDb test-cases/data/geo/GeoIPCity.dat\",\n      \"SecRule REMOTE_ADDR \\\"@geoLookup\\\" \\\"id:1,pass,t:trim\\\"\",\n      \"SecRule GEO \\\"@contains test \\\" \\\"id:2,pass,t:trim\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: GEO:COUNTRY_NAME [maxmind]\",\n    \"resource\": \"maxmind\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?key=value&key=other_value\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"Brazil\\\" \\\\(Variable: GEO:COUNTRY_NAME\\\\)\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecGeoLookupDb test-cases/data/GeoIP2-City-Test.mmdb\",\n      \"SecRule REMOTE_ADDR \\\"@geoLookup\\\" \\\"id:1,pass,t:trim\\\"\",\n      \"SecRule GEO \\\"@contains test \\\" \\\"id:2,pass,t:trim\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: GEO:LATITUDE [maxmind]\",\n    \"resource\": \"maxmind\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?key=value&key=other_value\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"-8.051502\\\" \\\\(Variable: GEO:LATITUDE\\\\)\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecGeoLookupDb test-cases/data/GeoIP2-City-Test.mmdb\",\n      \"SecRule REMOTE_ADDR \\\"@geoLookup\\\" \\\"id:1,pass,t:trim\\\"\",\n      \"SecRule GEO \\\"@contains test \\\" \\\"id:2,pass,t:trim\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: GEO:COUNTRY_CODE [maxmind]\",\n    \"resource\": \"maxmind\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?key=value&key=other_value\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"BR\\\" \\\\(Variable: GEO:COUNTRY_CODE\\\\)\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecGeoLookupDb test-cases/data/GeoIP2-City-Test.mmdb\",\n      \"SecRule REMOTE_ADDR \\\"@geoLookup\\\" \\\"id:1,pass,t:trim\\\"\",\n      \"SecRule GEO \\\"@contains test \\\" \\\"id:2,pass,t:trim\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: GEO:COUNTRY_CONTINENT [maxmind]\",\n    \"resource\": \"maxmind\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?key=value&key=other_value\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"South America\\\" \\\\(Variable: GEO:COUNTRY_CONTINENT\\\\)\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecGeoLookupDb test-cases/data/GeoIP2-City-Test.mmdb\",\n      \"SecRule REMOTE_ADDR \\\"@geoLookup\\\" \\\"id:1,pass,t:trim\\\"\",\n      \"SecRule GEO \\\"@contains test \\\" \\\"id:2,pass,t:trim\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: GEO:POSTAL_CODE [maxmind]\",\n    \"resource\": \"maxmind\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?key=value&key=other_value\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"50040090\\\" \\\\(Variable: GEO:POSTAL_CODE\\\\)\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecGeoLookupDb test-cases/data/GeoIP2-City-Test.mmdb\",\n      \"SecRule REMOTE_ADDR \\\"@geoLookup\\\" \\\"id:1,pass,t:trim\\\"\",\n      \"SecRule GEO \\\"@contains test \\\" \\\"id:2,pass,t:trim\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: GEO:CITY [maxmind]\",\n    \"resource\": \"maxmind\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?key=value&key=other_value\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"Recife\\\" \\\\(Variable: GEO:CITY\\\\)\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecGeoLookupDb test-cases/data/GeoIP2-City-Test.mmdb\",\n      \"SecRule REMOTE_ADDR \\\"@geoLookup\\\" \\\"id:1,pass,t:trim\\\"\",\n      \"SecRule GEO \\\"@contains test \\\" \\\"id:2,pass,t:trim\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/variable-HIGHEST_SEVERITY.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: HIGHEST_SEVERITY (1/2)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?key=value&key=other_value\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"0\\\" \\\\(Variable: HIGHEST_SEVERITY\\\\)\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule REMOTE_ADDR \\\"@contains 200.249\\\" \\\"id:1,pass,t:trim,severity:0\\\"\",\n      \"SecRule HIGHEST_SEVERITY \\\"@lt 10\\\" \\\"id:2,pass,t:trim\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: HIGHEST_SEVERITY (2/2)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?key=value&key=other_value\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"0\\\" \\\\(Variable: HIGHEST_SEVERITY\\\\)\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule REMOTE_ADDR \\\"@contains 200.249\\\" \\\"id:1,pass,t:trim,severity:EMERGENCY\\\"\",\n      \"SecRule HIGHEST_SEVERITY \\\"@lt 10\\\" \\\"id:2,pass,t:trim\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/variable-INBOUND_DATA_ERROR.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: INBOUND_DATA_ERROR (1/2)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?key=value&key=other_value\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"0\\\" \\\\(Variable: INBOUND_DATA_ERROR\\\\)\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule INBOUND_DATA_ERROR \\\"@eq 1\\\" \\\"id:1,phase:3,pass,t:trim\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: INBOUND_DATA_ERROR (1/1)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"523\",\n        \"Content-Type\": \"multipart/form-data; boundary=------------------------756b6d74fa1a8ee2\",\n        \"Expect\": \"100-continue\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"--------------------------756b6d74fa1a8ee2\\r\\n\",\n        \"Content-Disposition: form-data; name=\\\"name\\\"\\r\\n\",\n        \"\\r\\n\",\n        \"test\\r\\n\",\n        \"--------------------------756b6d74fa1a8ee2\\r\\n\",\n        \"Content-Disposition: form-data; name=\\\"filedata\\\"; filename=\\\"small_text_file.txt\\\"\\r\\n\",\n        \"Content-Type: text/plain\\r\\n\",\n        \"\\r\\n\",\n        \"This is a very small test file..\\r\\n\",\n        \"--------------------------756b6d74fa1a8ee2\\r\\n\",\n        \"Content-Disposition: form-data; name=\\\"filedata\\\"; filename=\\\"small_text_file.txt\\\"\\r\\n\",\n        \"Content-Type: text/plain\\r\\n\",\n        \"\\r\\n\",\n        \"This is another very small test file..\\r\\n\",\n        \"--------------------------756b6d74fa1a8ee2--\\r\\n\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"1\\\" \\\\(Variable: INBOUND_DATA_ERROR\\\\)\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRequestBodyLimit 2\",\n      \"SecRule INBOUND_DATA_ERROR \\\"@eq 1\\\" \\\"id:1,phase:3,pass,t:trim\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/variable-MATCHED_VAR.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: MATCHED_VAR (1/5)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?key=value&key=other_value\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"other_value\\\" \\\\(Variable: MATCHED_VAR\\\\)\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule ARGS:key \\\"@contains other_value\\\" \\\"chain,id:28,pass\\\"\",\n      \"SecRule MATCHED_VAR \\\"@contains asdf\\\" \\\"\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: MATCHED_VAR (2/5)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?key=value&key=other_value\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Rule returned 0\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule ARGS:key \\\"@contains other_value\\\" \\\"chain,id:28,pass\\\"\",\n      \"SecRule MATCHED_VAR \\\"@contains Aasdf\\\" \\\"\\\"\",\n      \"SecRule MATCHED_VAR \\\"@contains other_value\\\" \\\"id:29,pass\\\"\",\n      \"SecRule MATCHED_VAR \\\"@contains other_value\\\" \\\"id:30,pass\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: MATCHED_VAR (3/5)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?foo=1&bar=2&baz=2\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule ARGS \\\"@rx 1\\\" \\\"id:1,phase:1,pass\\\"\",\n      \"SecRule ARGS \\\"@rx 2\\\" \\\"id:2,phase:1,pass\\\"\",\n      \"SecRule MATCHED_VAR \\\"@eq 1\\\" \\\"id:3,phase:1,deny,status:403\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: MATCHED_VAR (4/5)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?foo=1&bar=2&baz=2\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule ARGS \\\"@rx 1\\\" \\\"id:1,phase:1,pass\\\"\",\n      \"SecRule ARGS \\\"@rx 2\\\" \\\"id:2,phase:1,pass\\\"\",\n      \"SecRule MATCHED_VAR \\\"@eq 2\\\" \\\"id:3,phase:1,deny,status:403\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: MATCHED_VAR (5/5)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?foo=1&bar=2&baz=2\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"http_code\": 403\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule ARGS \\\"@rx 1\\\" \\\"id:1,phase:1,pass\\\"\",\n      \"SecRule ARGS \\\"@rx 2\\\" \\\"id:2,phase:1,deny,status:403,chain\\\"\",\n      \"SecRule MATCHED_VAR \\\"@eq 2\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/variable-MATCHED_VARS.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: MATCHED_VARS (1/6)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?keyI=value&keyII=other_value\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"value\\\" \\\\(Variable: MATCHED_VARS:ARGS:keyI\\\\)\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule ARGS:keyI \\\"@contains value\\\" \\\"chain,id:28,pass\\\"\",\n      \"SecRule ARGS:keyII \\\"@contains other_value\\\" \\\"chain\\\"\",\n      \"SecRule MATCHED_VARS \\\"@contains asdf\\\" \\\"\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: MATCHED_VARS (2/6)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?keyI=value&keyII=other_value\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"value\\\" \\\\(Variable: MATCHED_VARS:ARGS:keyI\\\\)\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule ARGS:keyI \\\"@contains value\\\" \\\"chain,id:28,pass\\\"\",\n      \"SecRule ARGS:keyII \\\"@contains other_value\\\" \\\"chain\\\"\",\n      \"SecRule MATCHED_VARS \\\"@contains asdf\\\" \\\"\\\"\",\n      \"SecRule MATCHED_VARS \\\"@contains value\\\" \\\"id:29\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: MATCHED_VARS (3/6)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?foo=1&bar=2&baz=2\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule ARGS \\\"@rx 1\\\" \\\"id:1,phase:1,pass\\\"\",\n      \"SecRule ARGS \\\"@rx 2\\\" \\\"id:2,phase:1,pass\\\"\",\n      \"SecRule MATCHED_VARS \\\"@contains 1\\\" \\\"id:3,phase:1,deny,status:403\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: MATCHED_VARS (4/6)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?foo=1&bar=2&baz=2\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule ARGS \\\"@rx 1\\\" \\\"id:1,phase:1,pass\\\"\",\n      \"SecRule ARGS \\\"@rx 2\\\" \\\"id:2,phase:1,pass\\\"\",\n      \"SecRule MATCHED_VARS \\\"@contains 2\\\" \\\"id:3,phase:1,deny,status:403\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: MATCHED_VARS (5/6)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?foo=1&bar=2&baz=2\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule ARGS \\\"@rx 1\\\" \\\"id:1,phase:1,pass\\\"\",\n      \"SecRule ARGS \\\"@rx 2\\\" \\\"id:2,phase:1,pass\\\"\",\n      \"SecRule MATCHED_VARS \\\"@within 1 2\\\" \\\"id:3,phase:1,deny,status:403\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: MATCHED_VARS (6/6)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?foo=1&bar=2&baz=2\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"http_code\": 403\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule ARGS \\\"@rx 1\\\" \\\"id:1,phase:1,pass\\\"\",\n      \"SecRule ARGS \\\"@rx 2\\\" \\\"id:2,phase:1,deny,status:403,chain\\\"\",\n      \"SecRule MATCHED_VARS \\\"@eq 2\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/variable-MATCHED_VARS_NAMES.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: MATCHED_VARS_NAMES (1/5)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?keyI=value&keyII=other_value\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"ARGS:keyII\\\" \\\\(Variable: MATCHED_VARS_NAMES:ARGS:keyII\\\\)\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule ARGS:keyI \\\"@contains value\\\" \\\"chain,id:28,pass\\\"\",\n      \"SecRule ARGS:keyII \\\"@contains other_value\\\" \\\"chain\\\"\",\n      \"SecRule MATCHED_VARS_NAMES \\\"@contains asdf\\\" \\\"\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: MATCHED_VARS_NAMES (2/5)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?keyI=value&keyII=other_value\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"ARGS:keyI\\\" \\\\(Variable: MATCHED_VARS_NAMES:ARGS:keyI\\\\)\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule ARGS:keyI \\\"@contains value\\\" \\\"chain,id:28,pass\\\"\",\n      \"SecRule ARGS:keyII \\\"@contains other_value\\\" \\\"chain\\\"\",\n      \"SecRule MATCHED_VARS_NAMES \\\"@contains asdf\\\" \\\"\\\"\",\n      \"SecRule MATCHED_VARS_NAMES \\\"@contains value\\\" \\\"id:29\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: MATCHED_VARS_NAMES (3/5)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?foo=1&bar=2&baz=2\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule ARGS \\\"@rx 1\\\" \\\"id:1,phase:1,pass\\\"\",\n      \"SecRule ARGS \\\"@rx 2\\\" \\\"id:2,phase:1,pass\\\"\",\n      \"SecRule MATCHED_VARS_NAMES \\\"@within ARGS:foo ARGS:bar ARGS:baz\\\" \\\"id:3,phase:1,deny,status:403\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: MATCHED_VARS_NAMES (4/5)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?foo=1&bar=2&baz=2\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule ARGS \\\"@rx 1\\\" \\\"id:1,phase:1,pass\\\"\",\n      \"SecRule ARGS \\\"@rx 2\\\" \\\"id:2,phase:1,deny,status:403,chain\\\"\",\n      \"SecRule MATCHED_VARS_NAMES \\\"@strEq ARGS:foo\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: MATCHED_VARS_NAMES (5/5)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?foo=1&bar=2&baz=2\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"http_code\": 403\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule ARGS \\\"@rx 1\\\" \\\"id:1,phase:1,pass\\\"\",\n      \"SecRule ARGS \\\"@rx 2\\\" \\\"id:2,phase:1,deny,status:403,chain\\\"\",\n      \"SecRule MATCHED_VARS_NAMES \\\"@within ARGS:bar ARGS:baz\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/variable-MATCHED_VAR_NAME.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: MATCHED_VAR_NAME (1/7)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?keyI=value&keyII=other_value\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"ARGS:keyII\\\" \\\\(Variable: MATCHED_VAR_NAME\\\\)\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule ARGS:keyI \\\"@contains value\\\" \\\"chain,id:28,pass\\\"\",\n      \"SecRule ARGS:keyII \\\"@contains other_value\\\" \\\"chain\\\"\",\n      \"SecRule MATCHED_VAR_NAME \\\"@contains asdf\\\" \\\"\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: MATCHED_VAR_NAME (2/7)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?keyI=value&keyII=other_value\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \" Target value: \\\"ARGS:keyII\\\" \\\\(Variable: MATCHED_VAR_NAME\\\\)\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule ARGS:keyI \\\"@contains value\\\" \\\"chain,id:28,pass\\\"\",\n      \"SecRule ARGS:keyII \\\"@contains other_value\\\" \\\"chain\\\"\",\n      \"SecRule MATCHED_VAR_NAME \\\"@contains asdf\\\" \\\"\\\"\",\n      \"SecRule MATCHED_VAR_NAME \\\"@contains value\\\" \\\"id:29\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: MATCHED_VAR_NAME (3/7)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?key1=value&key2=other_value\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \" Target value: \\\"ARGS_NAMES:key1\\\" \\\\(Variable: MATCHED_VAR_NAME\\\\)\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule ARGS_NAMES \\\"@contains ey1\\\" \\\"chain,id:30,pass\\\"\",\n      \"SecRule MATCHED_VAR_NAME \\\"@contains key1\\\" \\\"id:31\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: MATCHED_VAR_NAME (4/7)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?foo=1&bar=2&baz=2\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule ARGS \\\"@rx 1\\\" \\\"id:1,phase:1,pass\\\"\",\n      \"SecRule ARGS \\\"@rx 2\\\" \\\"id:2,phase:1,pass\\\"\",\n      \"SecRule MATCHED_VAR_NAME \\\"@strEq ARGS:foo\\\" \\\"id:3,phase:1,deny,status:403\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: MATCHED_VAR_NAME (5/7)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?foo=1&bar=2&baz=2\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule ARGS \\\"@rx 1\\\" \\\"id:1,phase:1,pass\\\"\",\n      \"SecRule ARGS \\\"@rx 2\\\" \\\"id:2,phase:1,pass\\\"\",\n      \"SecRule MATCHED_VAR_NAME \\\"@strEq ARGS:bar\\\" \\\"id:3,phase:1,deny,status:403\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: MATCHED_VAR_NAME (6/7)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?foo=1&bar=2&baz=2\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule ARGS \\\"@rx 1\\\" \\\"id:1,phase:1,pass\\\"\",\n      \"SecRule ARGS \\\"@rx 2\\\" \\\"id:2,phase:1,pass\\\"\",\n      \"SecRule MATCHED_VAR_NAME \\\"@strEq ARGS:baz\\\" \\\"id:3,phase:1,deny,status:403\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: MATCHED_VAR_NAME (7/7)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?foo=1&bar=2&baz=2\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"http_code\": 403\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule ARGS \\\"@rx 1\\\" \\\"id:1,phase:1,pass\\\"\",\n      \"SecRule ARGS \\\"@rx 2\\\" \\\"id:2,phase:1,deny,status:403,chain\\\"\",\n      \"SecRule MATCHED_VAR_NAME \\\"@within ARGS:baz ARGS:bar\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/variable-MODSEC_BUILD.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: MODSEC_BUILD (1/1)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"27\",\n        \"Content-Type\": \"application/x-www-form-urlencoded\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"param1=value1&param2=value2\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"03([0-9]+)\\\" \\\\(Variable: MODSEC_BUILD\\\\)\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule MODSEC_BUILD \\\"@contains test\\\" \\\"id:1,phase:3,pass,t:trim\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/variable-MULTIPART_CRLF_LF_LINES.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: FILES (1/1)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"516\",\n        \"Content-Type\": \"multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2\",\n        \"Expect\": \"100-continue\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"----------------------------756b6d74fa1a8ee2\\n\",\n        \"Content-Disposition: form-data; name=\\\"name\\\"\\n\",\n        \"\\n\",\n        \"test\\n\",\n        \"----------------------------756b6d74fa1a8ee2\\n\",\n        \"Content-Disposition: form-data; name=\\\"filedata\\\"; filename=\\\"small_text_file.txt\\\"\\n\",\n        \"Content-Type: text/plain\\n\",\n        \"\\n\",\n        \"This is a very small test file..\\n\",\n        \"----------------------------756b6d74fa1a8ee2\\n\",\n        \"Content-Disposition: form-data; name=\\\"filedata\\\"; filename=\\\"small_text_file.txt\\\"\\n\",\n        \"Content-Type: text/plain\\n\",\n        \"\\n\",\n        \"This is another very small test file..\\n\",\n        \"----------------------------756b6d74fa1a8ee2--\\n\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"0\\\" \\\\(Variable: MULTIPART_CRLF_LF_LINES\\\\)\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule MULTIPART_CRLF_LF_LINES \\\"@contains 0\\\" \\\"id:1,phase:3,pass,t:trim\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: FILES (1/1)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"521\",\n        \"Content-Type\": \"multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2\",\n        \"Expect\": \"100-continue\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"----------------------------756b6d74fa1a8ee2\\n\",\n        \"Content-Disposition: form-data; name=\\\"name\\\"\\n\",\n        \"\\n\",\n        \"test\\n\",\n        \"----------------------------756b6d74fa1a8ee2\\n\",\n        \"Content-Disposition: form-data; name=\\\"filedata\\\"; filename=\\\"small_text_file.txt\\\"\\n\",\n        \"Content-Type: text/plain\\n\",\n        \"\\n\",\n        \"This is a very small test file..\\n\",\n        \"----------------------------756b6d74fa1a8ee2\\n\",\n        \"Content-Disposition: form-data; name=\\\"filedata\\\"; filename=\\\"small_text_file.txt\\\"\\r\\n\",\n        \"Content-Type: text/plain\\r\\n\",\n        \"\\r\\n\",\n        \"This is another very small test file..\\r\\n\",\n        \"----------------------------756b6d74fa1a8ee2--\\r\\n\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"1\\\" \\\\(Variable: MULTIPART_CRLF_LF_LINES\\\\)\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule MULTIPART_CRLF_LF_LINES \\\"@contains 0\\\" \\\"id:1,phase:3,pass,t:trim\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/variable-MULTIPART_FILENAME.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: MULTIPART_FILENAME\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"516\",\n        \"Content-Type\": \"multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2\",\n        \"Expect\": \"100-continue\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"----------------------------756b6d74fa1a8ee2\\n\",\n        \"Content-Disposition: form-data; name=\\\"name\\\"\\n\",\n        \"\\n\",\n        \"test\\n\",\n        \"----------------------------756b6d74fa1a8ee2\\n\",\n        \"Content-Disposition: form-data; name=\\\"filedata\\\"; filename=\\\"small_text_file.txt\\\"\\n\",\n        \"Content-Type: text/plain\\n\",\n        \"\\n\",\n        \"This is a very small test file..\\n\",\n        \"----------------------------756b6d74fa1a8ee2\\n\",\n        \"Content-Disposition: form-data; name=\\\"filedata\\\"; filename=\\\"small_text_file.txt\\\"\\n\",\n        \"Content-Type: text/plain\\n\",\n        \"\\n\",\n        \"This is another very small test file..\\n\",\n        \"----------------------------756b6d74fa1a8ee2--\\n\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"small_text_file.txt\\\" \\\\(Variable: MULTIPART_FILENAME\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule MULTIPART_FILENAME \\\"@contains 0\\\" \\\"id:1,phase:3,pass,t:trim\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: MULTIPART_FILENAME\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"522\",\n        \"Content-Type\": \"multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2\",\n        \"Expect\": \"100-continue\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"----------------------------756b6d74fa1a8ee2\\n\",\n        \"Content-Disposition: form-data; name=\\\"name\\\"\\n\",\n        \"\\n\",\n        \"test\\n\",\n        \"----------------------------756b6d74fa1a8ee2\\n\",\n        \"Content-Disposition: form-data; name=\\\"filedata\\\"; filename=\\\"small_text_file.txt\\\"\\n\",\n        \"Content-Type: text/plain\\n\",\n        \"\\n\",\n        \"This is a very small test file..\\n\",\n        \"----------------------------756b6d74fa1a8ee2\\n\",\n        \"Content-Disposition: form-data; name=\\\"filedata\\\"; filename=\\\"small_text_file2.txt\\\"\\r\\n\",\n        \"Content-Type: text/plain\\r\\n\",\n        \"\\r\\n\",\n        \"This is another very small test file..\\r\\n\",\n        \"----------------------------756b6d74fa1a8ee2--\\r\\n\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"small_text_file2.txt\\\" \\\\(Variable: MULTIPART_FILENAME\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule MULTIPART_FILENAME \\\"@contains 0\\\" \\\"id:1,phase:3,pass,t:trim\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/variable-MULTIPART_INVALID_HEADER_FOLDING.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: MULTIPART_INVALID_HEADER_FOLDING\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"278\",\n        \"Content-Type\": \"multipart/form-data; boundary=-----------------------------69343412719991675451336310646\",\n        \"Expect\": \"100-continue\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"-------------------------------69343412719991675451336310646\\n\",\n        \"Content-Disposition: form-data;\\n\",\n        \" name=\\\"a\\\"\\n\",\n        \"\\n\",\n        \"1\\n\",\n        \"-------------------------------69343412719991675451336310646\\n\",\n        \"Content-Disposition: form-data;\\n\",\n        \"    name=\\\"b\\\"\\n\",\n        \"\\n\",\n        \"2\\n\",\n        \"-------------------------------69343412719991675451336310646--\\n\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"ARGS:a\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRule MULTIPART_STRICT_ERROR \\\"!@eq 1\\\" \\\"phase:2,deny,status:403,id:500074\\\"\",\n      \"SecRule MULTIPART_HEADER_FOLDING \\\"!@eq 1\\\" \\\"phase:2,deny,status:403,id:500075\\\"\",\n      \"SecRule MULTIPART_INVALID_HEADER_FOLDING \\\"!@eq 0\\\" \\\"phase:2,deny,status:403,id:500076\\\"\",\n      \"SecRule REQBODY_PROCESSOR_ERROR \\\"@eq 1\\\" \\\"phase:2,deny,status:403,id:500077\\\"\",\n      \"SecRule ARGS \\\"@eq 1\\\" \\\"phase:2,deny,status:403,id:5000277\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/variable-MULTIPART_NAME.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: MULTIPART_FILENAME\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"516\",\n        \"Content-Type\": \"multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2\",\n        \"Expect\": \"100-continue\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"----------------------------756b6d74fa1a8ee2\\n\",\n        \"Content-Disposition: form-data; name=\\\"name\\\"\\n\",\n        \"\\n\",\n        \"test\\n\",\n        \"----------------------------756b6d74fa1a8ee2\\n\",\n        \"Content-Disposition: form-data; name=\\\"filedata\\\"; filename=\\\"small_text_file.txt\\\"\\n\",\n        \"Content-Type: text/plain\\n\",\n        \"\\n\",\n        \"This is a very small test file..\\n\",\n        \"----------------------------756b6d74fa1a8ee2\\n\",\n        \"Content-Disposition: form-data; name=\\\"filedata\\\"; filename=\\\"small_text_file.txt\\\"\\n\",\n        \"Content-Type: text/plain\\n\",\n        \"\\n\",\n        \"This is another very small test file..\\n\",\n        \"----------------------------756b6d74fa1a8ee2--\\n\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"filedata\\\" \\\\(Variable: MULTIPART_NAME\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule MULTIPART_NAME \\\"@contains 0\\\" \\\"id:1,phase:3,pass,t:trim\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: MULTIPART_FILENAME\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"523\",\n        \"Content-Type\": \"multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2\",\n        \"Expect\": \"100-continue\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"----------------------------756b6d74fa1a8ee2\\n\",\n        \"Content-Disposition: form-data; name=\\\"name\\\"\\n\",\n        \"\\n\",\n        \"test\\n\",\n        \"----------------------------756b6d74fa1a8ee2\\n\",\n        \"Content-Disposition: form-data; name=\\\"filedata\\\"; filename=\\\"small_text_file.txt\\\"\\n\",\n        \"Content-Type: text/plain\\n\",\n        \"\\n\",\n        \"This is a very small test file..\\n\",\n        \"----------------------------756b6d74fa1a8ee2\\n\",\n        \"Content-Disposition: form-data; name=\\\"filedata2\\\"; filename=\\\"small_text_file2.txt\\\"\\r\\n\",\n        \"Content-Type: text/plain\\r\\n\",\n        \"\\r\\n\",\n        \"This is another very small test file..\\r\\n\",\n        \"----------------------------756b6d74fa1a8ee2--\\r\\n\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"filedata2\\\" \\\\(Variable: MULTIPART_NAME\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule MULTIPART_NAME \\\"@contains 0\\\" \\\"id:1,phase:3,pass,t:trim\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/variable-MULTIPART_PART_HEADERS.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: MULTIPART_PART_HEADERS (all headers)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"302\",\n        \"Content-Type\": \"multipart/form-data; boundary=-----------------------------69343412719991675451336310646\",\n        \"Expect\": \"100-continue\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"-------------------------------69343412719991675451336310646\\n\",\n        \"Content-Disposition: form-data; name=parm1\\n\",\n        \"Content-Type: image/jpeg\\n\",\n        \"\\n\",\n        \"1\\n\",\n        \"-------------------------------69343412719991675451336310646\\n\",\n        \"Content-Disposition: form-data; name=parm2\\n\",\n        \"\\n\",\n        \"2\\n\",\n        \"-------------------------------69343412719991675451336310646--\\n\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Variable: MULTIPART_PART_HEADERS:parm1.*Rule returned 1\",\n      \"http_code\": 403\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule MULTIPART_PART_HEADERS \\\"@rx content-type:.*jpeg\\\" \\\"phase:2,deny,status:403,id:500074,t:lowercase\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: MULTIPART_PART_HEADERS (specific header - match)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"302\",\n        \"Content-Type\": \"multipart/form-data; boundary=-----------------------------69343412719991675451336310646\",\n        \"Expect\": \"100-continue\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"-------------------------------69343412719991675451336310646\\n\",\n        \"Content-Disposition: form-data; name=parm1\\n\",\n        \"Content-Type: image/jpeg\\n\",\n        \"\\n\",\n        \"1\\n\",\n        \"-------------------------------69343412719991675451336310646\\n\",\n        \"Content-Disposition: form-data; name=parm2\\n\",\n        \"\\n\",\n        \"2\\n\",\n        \"-------------------------------69343412719991675451336310646--\\n\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Variable: MULTIPART_PART_HEADERS:parm1.*Rule returned 1\",\n      \"http_code\": 403\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule MULTIPART_PART_HEADERS:parm1 \\\"@rx content-type:.*jpeg\\\" \\\"phase:2,deny,status:403,id:500074,t:lowercase\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: MULTIPART_PART_HEADERS (specific header - no match)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"312\",\n        \"Content-Type\": \"multipart/form-data; boundary=-----------------------------69343412719991675451336310646\",\n        \"Expect\": \"100-continue\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"-------------------------------69343412719991675451336310646\\r\\n\",\n        \"Content-Disposition: form-data; name=parm1\\r\\n\",\n        \"Content-Type: image/jpeg\\r\\n\",\n        \"\\r\\n\",\n        \"1\\r\\n\",\n        \"-------------------------------69343412719991675451336310646\\r\\n\",\n        \"Content-Disposition: form-data; name=parm2\\r\\n\",\n        \"\\r\\n\",\n        \"2\\r\\n\",\n        \"-------------------------------69343412719991675451336310646--\\r\\n\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule MULTIPART_PART_HEADERS:parm2 \\\"@rx content-type:.*jpeg\\\" \\\"phase:2,deny,status:403,id:500074,t:lowercase\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: MULTIPART_PART_HEADERS (check EOL)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"251\",\n        \"Content-Type\": \"multipart/form-data; boundary=-----------------------------69343412719991675451336310646\",\n        \"Expect\": \"100-continue\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"-------------------------------69343412719991675451336310646\\r\\n\",\n        \"Content-Disposition: form-data; name=\\\"file\\\"; filename=\\\"New Text Document.txt\\\"\\r\\n\",\n        \"Content-Type: text/plain; charset=utf-8\\r\\n\",\n        \"\\r\\n\",\n        \"1\\r\\n\",\n        \"-------------------------------69343412719991675451336310646--\\r\\n\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule MULTIPART_PART_HEADERS \\\"@rx ^content-type\\\\s*+:\\\\s*+(.*)$\\\" \\\"id:922110,phase:2,deny,capture,t:none,t:lowercase,chain\\\"\",\n      \"SecRule TX:1 \\\"!@rx ^text/plain; charset=(?:iso-8859-15?|windows-1252|utf-8)$\\\" \\\"t:lowercase\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/variable-MULTIPART_STRICT_ERROR.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: MULTIPART_STRICT_ERROR\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"508\",\n        \"Content-Type\": \"multipart/form-data; boundary= ------------------------756b6d74fa1a8ee2\",\n        \"Expect\": \"100-continue\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"--------------------------756b6d74fa1a8ee2\\n\",\n        \"Content-Disposition: form-data; name=\\\"name\\\"\\n\",\n        \"\\n\",\n        \"test\\n\",\n        \"--------------------------756b6d74fa1a8ee2\\n\",\n        \"Content-Disposition: form-data; name=\\\"filedata\\\"; filename=\\\"small_text_file.txt\\\"\\n\",\n        \"Content-Type: text/plain\\n\",\n        \"\\n\",\n        \"This is a very small test file..\\n\",\n        \"--------------------------756b6d74fa1a8ee2\\n\",\n        \"Content-Disposition: form-data; name=\\\"filedata\\\"; filename=\\\"small_text_file.txt\\\"\\n\",\n        \"Content-Type: text/plain\\n\",\n        \"\\n\",\n        \"This is another very small test file..\\n\",\n        \"--------------------------756b6d74fa1a8ee2--\\n\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Multipart: Warning: boundary whitespace in C-T header\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule MULTIPART_STRICT_ERROR \\\"@contains 0\\\" \\\"id:1,phase:3,pass,t:trim\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: MULTIPART_STRICT_ERROR\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"508\",\n        \"Content-Type\": \"multipart/form-data; boundary=\\\"------------------------756b6d74fa1a8ee2\\\"\",\n        \"Expect\": \"100-continue\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"--------------------------756b6d74fa1a8ee2\\n\",\n        \"Content-Disposition: form-data; name=\\\"name\\\"\\n\",\n        \"\\n\",\n        \"test\\n\",\n        \"--------------------------756b6d74fa1a8ee2\\n\",\n        \"Content-Disposition: form-data; name=\\\"filedata\\\"; filename=\\\"small_text_file.txt\\\"\\n\",\n        \"Content-Type: text/plain\\n\",\n        \"\\n\",\n        \"This is a very small test file..\\n\",\n        \"--------------------------756b6d74fa1a8ee2\\n\",\n        \"Content-Disposition: form-data; name=\\\"filedata\\\"; filename=\\\"small_text_file.txt\\\"\\n\",\n        \"Content-Type: text/plain\\n\",\n        \"\\n\",\n        \"This is another very small test file..\\n\",\n        \"--------------------------756b6d74fa1a8ee2--\\n\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Multipart: Warning: boundary was quoted.\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule MULTIPART_STRICT_ERROR \\\"@contains 0\\\" \\\"id:1,phase:3,pass,t:trim\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: MULTIPART_STRICT_ERROR\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"513\",\n        \"Content-Type\": \"multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2\",\n        \"Expect\": \"100-continue\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"--------------------------756b6d74fa1a8ee2\\n\",\n        \"Content-Disposition: form-data; name=\\\"name\\\"\\n\",\n        \"\\n\",\n        \"test\\n\",\n        \"--------------------------756b6d74fa1a8ee2\\n\",\n        \"Content-Disposition: form-data; name=\\\"filedata\\\"; filename=\\\"small_text_file.txt\\\"\\n\",\n        \"Content-Type: text/plain\\n\",\n        \"\\n\",\n        \"This is a very small test file..\\n\",\n        \"--------------------------756b6d74fa1a8ee2\\n\",\n        \"Content-Disposition: form-data; name=\\\"filedata\\\"; filename=\\\"small_text_file.txt\\\"\\n\",\n        \"Content-Type: text/plain\\n\",\n        \"\\n\",\n        \"This is another very small test file..\\n\",\n        \"--------------------------756b6d74fa1a8ee2--whee.\\n\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Multipart: Warning: seen data before first boundary\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule MULTIPART_STRICT_ERROR \\\"@contains 0\\\" \\\"id:1,phase:3,pass,t:trim\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: MULTIPART_STRICT_ERROR\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"516\",\n        \"Content-Type\": \"multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2\",\n        \"Expect\": \"100-continue\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"----------------------------756b6d74fa1a8ee2\\n\",\n        \"Content-Disposition: form-data; name=\\\"name\\\"\\n\",\n        \"\\n\",\n        \"test\\n\",\n        \"----------------------------756b6d74fa1a8ee2\\n\",\n        \"Content-Disposition: form-data; name=\\\"filedata\\\"; filename=\\\"small_text_file.txt\\\"\\n\",\n        \"Content-Type: text/plain\\n\",\n        \"\\n\",\n        \"This is a very small test file..\\n\",\n        \"----------------------------756b6d74fa1a8ee2\\n\",\n        \"Content-Disposition: form-data; name=\\\"filedata\\\"; filename=\\\"small_text_file.txt\\\"\\n\",\n        \"Content-Type: text/plain\\n\",\n        \"\\n\",\n        \"This is another very small test file..\\n\",\n        \"----------------------------756b6d74fa1a8ee2--\\n\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Warning: incorrect line endings used \\\\(LF\\\\)\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule MULTIPART_STRICT_ERROR \\\"@contains 0\\\" \\\"id:1,phase:3,pass,t:trim\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: MULTIPART_STRICT_ERROR\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"508\",\n        \"Content-Type\": \"multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2\",\n        \"Expect\": \"100-continue\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"--------------------------756b6d74fa1a8ee2\\n\",\n        \"Content-Disposition: form-data; name=\\\"name\\\"\\n\",\n        \"\\n\",\n        \"test\\n\",\n        \"--------------------------756b6d74fa1a8ee2\\n\",\n        \"Content-Disposition: form-data; name='filedata'; filename=\\\"small_text_file.txt\\\"\\n\",\n        \"Content-Type: text/plain\\n\",\n        \"\\n\",\n        \"This is a very small test file..\\n\",\n        \"--------------------------756b6d74fa1a8ee2\\n\",\n        \"Content-Disposition: form-data; name=\\\"filedata\\\"; filename=\\\"small_text_file.txt\\\"\\n\",\n        \"Content-Type: text/plain\\n\",\n        \"\\n\",\n        \"This is another very small test file..\\n\",\n        \"--------------------------756b6d74fa1a8ee2--\\n\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Multipart: Warning: seen data before first boundary\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule MULTIPART_STRICT_ERROR \\\"@contains 0\\\" \\\"id:1,phase:3,pass,t:trim\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: MULTIPART_STRICT_ERROR - RFC2046\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"205\",\n        \"Content-Type\": \"multipart/form-data; boundary=0123456789AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz '()+_,-./:=?\",\n        \"Expect\": \"100-continue\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"--0123456789AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz '()+_,-./:=?\\n\",\n        \"Content-Disposition: form-data; name=\\\"name\\\"\\n\",\n        \"\\n\",\n        \"1\\n\",\n        \"--0123456789AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz '()+_,-./:=?--\\n\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"0\\\" \\\\(Variable: REQBODY_ERROR\\\\)\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule REQBODY_ERROR \\\"@contains 0\\\" \\\"id:1,phase:3,pass,t:trim\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: MULTIPART_STRICT_ERROR - IQ \",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"515\",\n        \"Content-Type\": \"multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2\",\n        \"Expect\": \"100-continue\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"----------------------------756b6d74fa1a8ee2\\n\",\n        \"Content-Disposition: form-data; name=\\\"name\\\"\\n\",\n        \"\\n\",\n        \"test\\n\",\n        \"----------------------------756b6d74fa1a8ee2\\n\",\n        \"Content-Disposition: form-data; name=file'data; filename=\\\"small_text_file.txt\\\"\\n\",\n        \"Content-Type: text/plain\\n\",\n        \"\\n\",\n        \"This is a very small test file..\\n\",\n        \"----------------------------756b6d74fa1a8ee2\\n\",\n        \"Content-Disposition: form-data; name=\\\"filedata\\\"; filename=\\\"small_text_file.txt\\\"\\n\",\n        \"Content-Type: text/plain\\n\",\n        \"\\n\",\n        \"This is another very small test file..\\n\",\n        \"----------------------------756b6d74fa1a8ee2--\\n\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Warning: invalid quoting used\",\n      \"http_code\": 403\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule MULTIPART_STRICT_ERROR \\\"!@eq 0\\\" \\\"id:1,phase:2,deny,status:403\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: MULTIPART_STRICT_ERROR - IQ \",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"532\",\n        \"Content-Type\": \"multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2\",\n        \"Expect\": \"100-continue\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"----------------------------756b6d74fa1a8ee2\\r\\n\",\n        \"Content-Disposition: form-data; name=\\\"name\\\"\\r\\n\",\n        \"\\r\\n\",\n        \"test\\r\\n\",\n        \"----------------------------756b6d74fa1a8ee2\\r\\n\",\n        \"Content-Disposition: form-data; name=\\\"file'data\\\"; filename=\\\"small_text_file.txt\\\"\\r\\n\",\n        \"Content-Type: text/plain\\r\\n\",\n        \"\\r\\n\",\n        \"This is a very small test file..\\r\\n\",\n        \"----------------------------756b6d74fa1a8ee2\\r\\n\",\n        \"Content-Disposition: form-data; name=\\\"filedata\\\"; filename=\\\"small_text_file.txt\\\"\\r\\n\",\n        \"Content-Type: text/plain\\r\\n\",\n        \"\\r\\n\",\n        \"This is another very small test file..\\r\\n\",\n        \"----------------------------756b6d74fa1a8ee2--\\r\\n\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule MULTIPART_INVALID_QUOTING \\\"!@eq 0\\\" \\\"id:1,phase:2,deny,status:403\\\"\",\n      \"SecRule MULTIPART_STRICT_ERROR \\\"!@eq 0\\\" \\\"id:2,phase:2,pass\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/variable-MULTIPART_UNMATCHED_BOUNDARY.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: MULTIPART_UNMATCHED_BOUNDARY\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"464\",\n        \"Content-Type\": \"multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2\",\n        \"Expect\": \"100-continue\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"--------------------------756b6d74fa1a8ee2\\n\",\n        \"Content-Disposition: form-data; name=\\\"name\\\"\\n\",\n        \"\\n\",\n        \"test\\n\",\n        \"--------------------------756b6d74fa1a8ee2\\n\",\n        \"Content-Disposition: form-data; name=\\\"filedata\\\"; filename=\\\"small_text_file.txt\\\"\\n\",\n        \"Content-Type: text/plain\\n\",\n        \"\\n\",\n        \"This is a very small test file..\\n\",\n        \"--------------------------756b6d74fa1a8ee2\\n\",\n        \"Content-Disposition: form-data; name=\\\"filedata\\\"; filename=\\\"small_text_file.txt\\\"\\n\",\n        \"Content-Type: text/plain\\n\",\n        \"\\n\",\n        \"This is another very small test file..\\n\",\n        \"\\n\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"1\\\" \\\\(Variable: MULTIPART_UNMATCHED_BOUNDARY\\\\)\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule MULTIPART_UNMATCHED_BOUNDARY \\\"@contains small_text_file.txt\\\" \\\"id:1,phase:3,pass,t:trim\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/variable-OUTBOUND_DATA_ERROR.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: OUTBOUND_DATA_ERROR (1/2)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?key=value&key=other_value\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"0\\\" \\\\(Variable: OUTBOUND_DATA_ERROR\\\\)\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecResponseBodyAccess On\",\n      \"SecRule OUTBOUND_DATA_ERROR \\\"@eq 1\\\" \\\"id:1,phase:4,pass,t:trim\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: OUTBOUND_DATA_ERROR (2/2)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"523\",\n        \"Content-Type\": \"multipart/form-data; boundary=------------------------756b6d74fa1a8ee2\",\n        \"Expect\": \"100-continue\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"--------------------------756b6d74fa1a8ee2\\r\\n\",\n        \"Content-Disposition: form-data; name=\\\"name\\\"\\r\\n\",\n        \"\\r\\n\",\n        \"test\\r\\n\",\n        \"--------------------------756b6d74fa1a8ee2\\r\\n\",\n        \"Content-Disposition: form-data; name=\\\"filedata\\\"; filename=\\\"small_text_file.txt\\\"\\r\\n\",\n        \"Content-Type: text/plain\\r\\n\",\n        \"\\r\\n\",\n        \"This is a very small test file..\\r\\n\",\n        \"--------------------------756b6d74fa1a8ee2\\r\\n\",\n        \"Content-Disposition: form-data; name=\\\"filedata\\\"; filename=\\\"small_text_file.txt\\\"\\r\\n\",\n        \"Content-Type: text/plain\\r\\n\",\n        \"\\r\\n\",\n        \"This is another very small test file..\\r\\n\",\n        \"--------------------------756b6d74fa1a8ee2--\\r\\n\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"493\"\n      },\n      \"body\": [\n        \"--------------------------756b6d74fa1a8ee2\",\n        \"Content-Disposition: form-data; name=\\\"name\\\"\",\n        \"\",\n        \"test\",\n        \"--------------------------756b6d74fa1a8ee2\",\n        \"Content-Disposition: form-data; name=\\\"filedata\\\"; filename=\\\"small_text_file.txt\\\"\",\n        \"Content-Type: text/plain\",\n        \"\",\n        \"This is a very small test file..\",\n        \"--------------------------756b6d74fa1a8ee2\",\n        \"Content-Disposition: form-data; name=\\\"filedata\\\"; filename=\\\"small_text_file.txt\\\"\",\n        \"Content-Type: text/plain\",\n        \"\",\n        \"This is another very small test file..\",\n        \"--------------------------756b6d74fa1a8ee2--\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"1\\\" \\\\(Variable: OUTBOUND_DATA_ERROR\\\\)\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecResponseBodyAccess On\",\n      \"SecResponseBodyLimit 2\",\n      \"SecRule OUTBOUND_DATA_ERROR \\\"@eq 1\\\" \\\"id:1,phase:4,pass,t:trim\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/variable-PATH_INFO.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: PATH_INFO (1/4)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"27\",\n        \"Content-Type\": \"application/x-www-form-urlencoded\"\n      },\n      \"uri\": \"/one/two/three\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"param1=value1&param2=value2\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"/one/two/three\\\" \\\\(Variable: PATH_INFO\\\\)\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule PATH_INFO \\\"@contains test \\\" \\\"id:1,phase:3,pass,t:trim\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: PATH_INFO (2/4)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"27\",\n        \"Content-Type\": \"application/x-www-form-urlencoded\"\n      },\n      \"uri\": \"/one/two/three?key=value\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"param1=value1&param2=value2\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"/one/two/three\\\" \\\\(Variable: PATH_INFO\\\\)\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule PATH_INFO \\\"@contains test \\\" \\\"id:1,phase:3,pass,t:trim\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: PATH_INFO (3/4)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"27\",\n        \"Content-Type\": \"application/x-www-form-urlencoded\"\n      },\n      \"uri\": \"/one/two/%20/three?key=value\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"param1=value1&param2=value2\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"/one/two/ /three\\\" \\\\(Variable: PATH_INFO\\\\)\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule PATH_INFO \\\"@contains test \\\" \\\"id:1,phase:3,pass,t:trim\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: PATH_INFO (4/4)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"27\",\n        \"Content-Type\": \"application/x-www-form-urlencoded\"\n      },\n      \"uri\": \"/one/t%3fo/three?key=value\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"param1=value1&param2=value2\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"http_code\": 403\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule PATH_INFO \\\"@contains three\\\" \\\"id:1,phase:2,deny,status:403,t:trim\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/variable-QUERY_STRING.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: QUERY_STRING\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\",\n        \"Content-Type\": \"application/x-www-form-urlencoded\"\n      },\n      \"uri\": \"/one/two/three?key1=value1&key2=v%20a%20l%20u%20e%202\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"key2=v\\\\%20a\\\\%20l\\\\%20u\\\\%20e\\\\%202\\\" \\\\(Variable: QUERY_STRING\\\\)\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule QUERY_STRING \\\"@contains test \\\" \\\"id:1,phase:3,pass,t:trim\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: QUERY_STRING (URI contains fragment)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?key=value&key=other_value#urifrag\",\n      \"method\": \"GET\",\n      \"http_version\": 1.1,\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"http_code\": 403\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule QUERY_STRING \\\"!@contains urifrag\\\" \\\"id:1,phase:1,deny,status:403\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: QUERY_STRING (URI contains fragment)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/one/two/testpost.php#urifrag\",\n      \"method\": \"GET\",\n      \"http_version\": 1.1,\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"http_code\": 403\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule QUERY_STRING \\\"@eq 0\\\" \\\"id:1,phase:1,t:length,deny,status:403\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/variable-REMOTE_ADDR.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: REMOTE_ADDR\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\",\n        \"Content-Type\": \"application/x-www-form-urlencoded\"\n      },\n      \"uri\": \"/one/two/three?key1=value1&key2=v%20a%20l%20u%20e%202\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"200.249.12.31\\\" \\\\(Variable: REMOTE_ADDR\\\\)\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule REMOTE_ADDR \\\"@contains test \\\" \\\"id:1,phase:3,pass,t:trim\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: REMOTE_ADDR\",\n    \"client\": {\n      \"ip\": \"::1\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\",\n        \"Content-Type\": \"application/x-www-form-urlencoded\"\n      },\n      \"uri\": \"/one/two/three?key1=value1&key2=v%20a%20l%20u%20e%202\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"::1\\\" \\\\(Variable: REMOTE_ADDR\\\\)\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule REMOTE_ADDR \\\"@contains test \\\" \\\"id:1,phase:3,pass,t:trim\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/variable-REMOTE_HOST.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: REMOTE_HOST\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.11\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\",\n        \"Content-Type\": \"application/x-www-form-urlencoded\"\n      },\n      \"uri\": \"/one/two/three?key1=value1&key2=v%20a%20l%20u%20e%202\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"200.249.12.31\\\" \\\\(Variable: REMOTE_HOST\\\\)\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule REMOTE_HOST \\\"@contains test \\\" \\\"id:1,phase:3,pass,t:trim\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: REMOTE_HOST\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"::1\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\",\n        \"Content-Type\": \"application/x-www-form-urlencoded\"\n      },\n      \"uri\": \"/one/two/three?key1=value1&key2=v%20a%20l%20u%20e%202\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"200.249.12.31\\\" \\\\(Variable: REMOTE_HOST\\\\)\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule REMOTE_HOST \\\"@contains test \\\" \\\"id:1,phase:3,pass,t:trim\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/variable-REMOTE_PORT.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: REMOTE_PORT\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.11\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\",\n        \"Content-Type\": \"application/x-www-form-urlencoded\"\n      },\n      \"uri\": \"/one/two/three?key1=value1&key2=v%20a%20l%20u%20e%202\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"123\\\" \\\\(Variable: REMOTE_PORT\\\\)\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule REMOTE_PORT \\\"@contains test \\\" \\\"id:1,phase:3,pass,t:trim\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: REMOTE_PORT\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"::1\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\",\n        \"Content-Type\": \"application/x-www-form-urlencoded\"\n      },\n      \"uri\": \"/one/two/three?key1=value1&key2=v%20a%20l%20u%20e%202\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"123\\\" \\\\(Variable: REMOTE_PORT\\\\)\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule REMOTE_PORT \\\"@contains test \\\" \\\"id:1,phase:3,pass,t:trim\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/variable-REMOTE_USER.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: REMOTE_USER\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\",\n        \"Content-Type\": \"application/x-www-form-urlencoded\",\n        \"Authorization\": \"Basic QWxhZGRpbjpPcGVuU2VzYW1l\"\n      },\n      \"uri\": \"/one/two/three?key1=value1&key2=v%20a%20l%20u%20e%202\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"t:trim: \\\"Aladdin\\\"\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule REMOTE_USER \\\"@contains test \\\" \\\"id:1,phase:3,pass,t:trim\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/variable-REQBODY_PROCESSOR.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: REQBODY_PROCESSOR (1/3)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Type\": \"text/xml\",\n        \"Content-Length\": \"732\"\n      },\n      \"uri\": \"/?key=value&key=other_value\",\n      \"method\": \"POST\",\n      \"http_version\": 1.1,\n      \"body\": [\n        \"<?xml version=\\\"1.0\\\" encoding=\\\"UTF-8\\\"?>\",\n        \"<bookstore>\",\n        \"<book category=\\\"COOKING\\\">\",\n        \"<title lang=\\\"en\\\">Everyday Italian</title>\",\n        \"<author>Giada De Laurentiis</author>\",\n        \"<year>2005</year>\",\n        \"<price>30.00</price>\",\n        \"</book>\",\n        \"<book category=\\\"CHILDREN\\\">\",\n        \"<title lang=\\\"en\\\">Harry Potter</title>\",\n        \"<author>J K. Rowling</author>\",\n        \"<year>2005</year>\",\n        \"<price>29.99</price>\",\n        \"</book>\",\n        \"<book category=\\\"WEB\\\">\",\n        \"<title lang=\\\"en\\\">XQuery Kick Start</title>\",\n        \"<author>James McGovern</author>\",\n        \"<author>Per Bothner</author>\",\n        \"<author>Kurt Cagle</author>\",\n        \"<author>James Linn</author>\",\n        \"<author>Vaidyanathan Nagarajan</author>\",\n        \"<year>2003</year>\",\n        \"<price>49.99</price>\",\n        \"</book>\",\n        \"<book category=\\\"WEB\\\">\",\n        \"<title lang=\\\"en\\\">Learning XML</title>\",\n        \"<author>Erik T. Ray</author>\",\n        \"<year>2003</year>\",\n        \"<price>39.95</price>\",\n        \"</book>\",\n        \"</bookstore>\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"XML\\\" \\\\(Variable: REQBODY_PROCESSOR\\\\)\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule REQUEST_HEADERS:Content-Type \\\"^(?:application(?:/soap\\\\+|/)|text/)xml\\\" \\\"id:500005,phase:1,t:none,t:lowercase,nolog,pass,ctl:requestBodyProcessor=XML\\\"\",\n      \"SecRule REQBODY_PROCESSOR \\\"@contains test\\\" \\\"id:1,pass,phase:2,t:trim\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: REQBODY_PROCESSOR (2/3)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Type\": \"multipart/form-data; boundary=------------------------756b6d74fa1a8ee2\",\n        \"Content-Length\": \"523\"\n      },\n      \"uri\": \"/?key=value&key=other_value\",\n      \"method\": \"POST\",\n      \"http_version\": 1.1,\n      \"body\": [\n        \"--------------------------756b6d74fa1a8ee2\\r\\n\",\n        \"Content-Disposition: form-data; name=\\\"name\\\"\\r\\n\",\n        \"\\r\\n\",\n        \"test\\r\\n\",\n        \"--------------------------756b6d74fa1a8ee2\\r\\n\",\n        \"Content-Disposition: form-data; name=\\\"filedata\\\"; filename=\\\"small_text_file.txt\\\"\\r\\n\",\n        \"Content-Type: text/plain\\r\\n\",\n        \"\\r\\n\",\n        \"This is a very small test file..\\r\\n\",\n        \"--------------------------756b6d74fa1a8ee2\\r\\n\",\n        \"Content-Disposition: form-data; name=\\\"filedata\\\"; filename=\\\"small_text_file.txt\\\"\\r\\n\",\n        \"Content-Type: text/plain\\r\\n\",\n        \"\\r\\n\",\n        \"This is another very small test file..\\r\\n\",\n        \"--------------------------756b6d74fa1a8ee2--\\r\\n\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"MULTIPART\\\" \\\\(Variable: REQBODY_PROCESSOR\\\\)\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule REQBODY_PROCESSOR \\\"@contains test\\\" \\\"id:1,pass,t:trim\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: REQBODY_PROCESSOR (3/3)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Type\": \"application/x-www-form-urlencoded\",\n        \"Content-Length\": \"27\"\n      },\n      \"uri\": \"/?key=value&key=other_value\",\n      \"method\": \"POST\",\n      \"http_version\": 1.1,\n      \"body\": [\n        \"param1=value1&param2=value2\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"URLENCODED\\\" \\\\(Variable: REQBODY_PROCESSOR\\\\)\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule REQBODY_PROCESSOR \\\"@contains test\\\" \\\"id:1,pass,t:trim\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/variable-REQBODY_PROCESSOR_ERROR.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: REQBODY_PROCESSOR_ERROR_MSG (1/2)\",\n    \"resource\": \"libxml2\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Type\": \"text/xml\",\n        \"Content-Length\": \"736\"\n      },\n      \"uri\": \"/?key=value&key=other_value\",\n      \"method\": \"POST\",\n      \"http_version\": 1.1,\n      \"body\": [\n        \"<?xml version=\\\"1.0\\\" encoding=\\\"UTF-8\\\"?>\",\n        \"<bookstore>\",\n        \"<book category=\\\"COOKING\\\">\",\n        \"<title lang=\\\"en\\\">Everyday Italian</title>\",\n        \"<author>Giada De Laurentiis</author>\",\n        \"<year>2005</year>\",\n        \"<price>30.00</price>\",\n        \"</book>\",\n        \"<book category=\\\"CHILDREN\\\">\",\n        \"<title lang=\\\"en\\\">Harry Potter</title>\",\n        \"<author>J K. Rowling</author>\",\n        \"<year>2005</year>\",\n        \"<price>29.99</price>\",\n        \"</book>\",\n        \"<book category=\\\"WEB\\\">\",\n        \"<title lang=\\\"en\\\">XQuery Kick Start</title>\",\n        \"<author>James McGovern</author>\",\n        \"<author>Per Bothner</author>\",\n        \"<author>Kurt Cagle</author>\",\n        \"<author>James Linn</author>\",\n        \"<author>Vaidyanathan Nagarajan</author>\",\n        \"<year>2003</year>\",\n        \"<price>49.99</price>\",\n        \"</book>\",\n        \"<book category=\\\"WEB\\\">\",\n        \"<title lang=\\\"en\\\">Learning XML</title>\",\n        \"<author>Erik T. Ray</author>\",\n        \"<year>2003</year>\",\n        \"<price>39.95</price>\",\n        \"</bookasdf>\",\n        \"</bookstore>\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"XML parsing error: XML: Failed to parse document\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule REQUEST_HEADERS:Content-Type \\\"^text/xml$\\\" \\\"id:500005,phase:1,t:none,t:lowercase,nolog,pass,ctl:requestBodyProcessor=XML\\\"\",\n      \"SecRule REQBODY_PROCESSOR_ERROR \\\"@contains test\\\" \\\"phase:2,id:1,pass,t:trim\\\"\",\n      \"SecRule REQBODY_PROCESSOR_ERROR_MSG \\\"@contains test\\\" \\\"phase:2,id:2,pass,t:trim\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: REQBODY_PROCESSOR_ERROR_MSG (2/2)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Type\": \"multipart/form-data; boundary=--------------------------756b6d74fa1a8ee2\",\n        \"Content-Length\": \"469\"\n      },\n      \"uri\": \"/?key=value&key=other_value\",\n      \"method\": \"POST\",\n      \"http_version\": 1.1,\n      \"body\": [\n        \"----------------------------756b6d74fa1a8ee2\\n\",\n        \"Content-Disposition: form-data; name=\\\"name\\\"\\n\",\n        \"\\n\",\n        \"test\\n\",\n        \"----------------------------756b6d74fa1a8ee2\\n\",\n        \"Content-Disposition: form-data; name=\\\"filedata\\\"; filename=\\\"small_text_file.txt\\\"\\n\",\n        \"Content-Type: text/plain\\n\",\n        \"\\n\",\n        \"This is a very small test file..\\n\",\n        \"----------------------------756b6d74fa1a8ee2\\n\",\n        \"Content-Disposition: form-data; name=\\\"filedata\\\"; filename=\\\"small_text_file.txt\\\"\\n\",\n        \"Content-Type: text/plain\\n\",\n        \"\\n\",\n        \"This is another very small test file..\\n\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Multipart parsing error: Multipart: Final boundary missing.\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule REQUEST_HEADERS:Content-Type \\\"^text/xml$\\\" \\\"id:500005,phase:1,t:none,t:lowercase,nolog,pass,ctl:requestBodyProcessor=XML\\\"\",\n      \"SecRule REQBODY_PROCESSOR_ERROR \\\"@contains test\\\" \\\"phase:2,id:1,pass,t:trim\\\"\",\n      \"SecRule REQBODY_PROCESSOR_ERROR_MSG \\\"@contains test\\\" \\\"phase:2,id:2,pass,t:trim\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/variable-REQUEST_BASENAME.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: REQUEST_BASENAME\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.11\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\",\n        \"Content-Type\": \"application/x-www-form-urlencoded\"\n      },\n      \"uri\": \"/one/two/login.php?key1=value1&key2=v%20a%20l%20u%20e%202\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"login.php\\\" \\\\(Variable: REQUEST_BASENAME\\\\)\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule REQUEST_BASENAME \\\"@contains test \\\" \\\"id:1,phase:3,pass,t:trim\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: REQUEST_BASENAME\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.11\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\",\n        \"Content-Type\": \"application/x-www-form-urlencoded\"\n      },\n      \"uri\": \"/my_app.asp?apath=/my/cool/path.com\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"my_app.asp\\\" \\\\(Variable: REQUEST_BASENAME\\\\)\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule REQUEST_BASENAME \\\"@contains test \\\" \\\"id:1,phase:3,pass,t:trim\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/variable-REQUEST_BODY.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: REQUEST_BODY\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"508\",\n        \"Content-Type\": \"multipart/form-data; boundary=------------------------756b6d74fa1a8ee2\",\n        \"Expect\": \"100-continue\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"--------------------------756b6d74fa1a8ee2\\n\",\n        \"Content-Disposition: form-data; name=\\\"name\\\"\\n\",\n        \"\\n\",\n        \"test\\n\",\n        \"--------------------------756b6d74fa1a8ee2\\n\",\n        \"Content-Disposition: form-data; name=\\\"filedata\\\"; filename=\\\"small_text_file.txt\\\"\\n\",\n        \"Content-Type: text/plain\\n\",\n        \"\\n\",\n        \"This is a very small test file..\\n\",\n        \"--------------------------756b6d74fa1a8ee2\\n\",\n        \"Content-Disposition: form-data; name=\\\"filedata\\\"; filename=\\\"small_text_file.txt\\\"\\n\",\n        \"Content-Type: text/plain\\n\",\n        \"\\n\",\n        \"This is another very small test file..\\n\",\n        \"--------------------------756b6d74fa1a8ee2--\\n\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"--------------------------756b6d74fa1a8ee2\\\\x0aContent-Disposition: form-data; na\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRequestBodyAccess On\",\n      \"SecRule REQUEST_BODY \\\"@contains small_text_file.txt\\\" \\\"id:1,phase:3,pass,t:trim\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/variable-REQUEST_BODY_LENGTH.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: REQUEST_BODY_LENGTH\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"508\",\n        \"Content-Type\": \"multipart/form-data; boundary=------------------------756b6d74fa1a8ee2\",\n        \"Expect\": \"100-continue\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"--------------------------756b6d74fa1a8ee2\\n\",\n        \"Content-Disposition: form-data; name=\\\"name\\\"\\n\",\n        \"\\n\",\n        \"test\\n\",\n        \"--------------------------756b6d74fa1a8ee2\\n\",\n        \"Content-Disposition: form-data; name=\\\"filedata\\\"; filename=\\\"small_text_file.txt\\\"\\n\",\n        \"Content-Type: text/plain\\n\",\n        \"\\n\",\n        \"This is a very small test file..\\n\",\n        \"--------------------------756b6d74fa1a8ee2\\n\",\n        \"Content-Disposition: form-data; name=\\\"filedata\\\"; filename=\\\"small_text_file.txt\\\"\\n\",\n        \"Content-Type: text/plain\\n\",\n        \"\\n\",\n        \"This is another very small test file..\\n\",\n        \"--------------------------756b6d74fa1a8ee2--\\n\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"508\\\" \\\\(Variable: REQUEST_BODY_LENGTH\\\\)\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRequestBodyAccess On\",\n      \"SecRule REQUEST_BODY_LENGTH \\\"@contains small_text_file.txt\\\" \\\"id:1,phase:3,pass,t:trim\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/variable-REQUEST_COOKIES.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: REQUEST_COOKIES (1/6)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Cookie\": \"USER_TOKEN=Yes; a=z; t=b\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?key=value&key=other_value\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"Yes\\\" \\\\(Variable: REQUEST_COOKIES:USER_TOKEN\\\\)\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule REQUEST_COOKIES \\\"@contains test \\\" \\\"id:1,pass,t:trim\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: REQUEST_COOKIES (2/6)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Cookie\": \"USER_TOKEN=Yes; a=z; t=b\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?key=value&key=other_value\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"z\\\" \\\\(Variable: REQUEST_COOKIES:a\\\\)\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule REQUEST_COOKIES \\\"@contains test \\\" \\\"id:1,pass,t:trim\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: REQUEST_COOKIES (3/6)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Cookie\": \"USER_TOKEN=Yes; a=z; t=b\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?key=value&key=other_value\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"b\\\" \\\\(Variable: REQUEST_COOKIES:t\\\\)\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule REQUEST_COOKIES \\\"@contains test \\\" \\\"id:1,pass,t:trim\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: REQUEST_COOKIES (4/6)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Cookie\": \"USER_TOKEN=Yes; a=z; t=b;  foo= bar\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?key=value&key=other_value\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"bar\\\"\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule REQUEST_COOKIES \\\"@contains test \\\" \\\"id:1,pass,t:trim\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: REQUEST_COOKIES (5/6)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Cookie\": \"USER_TOKEN=Yes; a=z; t=b;  foo= bar; = ; = = ; baz=value1=insert here something\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?key=value&key=other_value\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"value1=insert here something\\\"\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule REQUEST_COOKIES \\\"@contains test \\\" \\\"id:1,pass,t:trim\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: REQUEST_COOKIES (6/6)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Cookie\": \"aaa=bbb;abc=def  \",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?key=value&key=other_value\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"def\\\" \\\\(Variable: REQUEST_COOKIES:abc\\\\)\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule REQUEST_COOKIES:abc \\\"@rx ^def$\\\" \\\"id:1,pass\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/variable-REQUEST_COOKIES_NAMES.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: REQUEST_COOKIES_NAMES (1/4)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Cookie\": \"USER_TOKEN=Yes; a=z; t=b\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?key=value&key=other_value\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"USER_TOKEN\\\" \\\\(Variable: REQUEST_COOKIES_NAMES:USER_TOKEN\\\\)\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule REQUEST_COOKIES_NAMES \\\"@contains test \\\" \\\"id:1,pass,t:trim\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: REQUEST_COOKIES_NAMES (2/4)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Cookie\": \"USER_TOKEN=Yes; a=z; t=b\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?key=value&key=other_value\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"a\\\" \\\\(Variable: REQUEST_COOKIES_NAMES:a\\\\)\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule REQUEST_COOKIES_NAMES \\\"@contains test \\\" \\\"id:1,pass,t:trim\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: REQUEST_COOKIES_NAMES (3/4)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Cookie\": \"USER_TOKEN=Yes; a=z; t=b\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?key=value&key=other_value\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"t\\\" \\\\(Variable: REQUEST_COOKIES_NAMES:t\\\\)\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule REQUEST_COOKIES_NAMES \\\"@contains test \\\" \\\"id:1,pass,t:trim\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: REQUEST_COOKIES_NAMES (4/4)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Cookie\": \"USER_TOKEN=Yes; a=z; t=b;  foobar\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?key=value&key=other_value\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"foobar\\\"\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule REQUEST_COOKIES_NAMES \\\"@contains foobar \\\" \\\"id:1,pass,t:trim\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/variable-REQUEST_FILENAME.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: REQUEST_FILENAME\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.11\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\",\n        \"Content-Type\": \"application/x-www-form-urlencoded\"\n      },\n      \"uri\": \"/one/two/login.php?key1=value1&key2=v%20a%20l%20u%20e%202\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"/one/two/login.php\\\" \\\\(Variable: REQUEST_FILENAME\\\\)\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule REQUEST_FILENAME \\\"@contains test \\\" \\\"id:1,phase:3,pass,t:trim\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/variable-REQUEST_HEADERS.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: REQUEST_HEADERS\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"523\",\n        \"Content-Type\": \"multipart/form-data; boundary=------------------------756b6d74fa1a8ee2\",\n        \"Expect\": \"100-continue\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"--------------------------756b6d74fa1a8ee2\\r\\n\",\n        \"Content-Disposition: form-data; name=\\\"name\\\"\\r\\n\",\n        \"\\r\\n\",\n        \"test\\r\\n\",\n        \"--------------------------756b6d74fa1a8ee2\\r\\n\",\n        \"Content-Disposition: form-data; name=\\\"filedata\\\"; filename=\\\"small_text_file.txt\\\"\\r\\n\",\n        \"Content-Type: text/plain\\r\\n\",\n        \"\\r\\n\",\n        \"This is a very small test file..\\r\\n\",\n        \"--------------------------756b6d74fa1a8ee2\\r\\n\",\n        \"Content-Disposition: form-data; name=\\\"filedata\\\"; filename=\\\"small_text_file.txt\\\"\\r\\n\",\n        \"Content-Type: text/plain\\r\\n\",\n        \"\\r\\n\",\n        \"This is another very small test file..\\r\\n\",\n        \"--------------------------756b6d74fa1a8ee2--\\r\\n\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"localhost\\\" \\\\(Variable: REQUEST_HEADERS:Host\\\\)\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule REQUEST_HEADERS \\\"@contains small_text_file.txt\\\" \\\"id:1,phase:3,pass,t:trim\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/variable-REQUEST_HEADERS_NAMES.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: REQUEST_HEADERS_NAMES\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"523\",\n        \"Content-Type\": \"multipart/form-data; boundary=------------------------756b6d74fa1a8ee2\",\n        \"Expect\": \"100-continue\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"--------------------------756b6d74fa1a8ee2\\r\\n\",\n        \"Content-Disposition: form-data; name=\\\"name\\\"\\r\\n\",\n        \"\\r\\n\",\n        \"test\\r\\n\",\n        \"--------------------------756b6d74fa1a8ee2\\r\\n\",\n        \"Content-Disposition: form-data; name=\\\"filedata\\\"; filename=\\\"small_text_file.txt\\\"\\r\\n\",\n        \"Content-Type: text/plain\\r\\n\",\n        \"\\r\\n\",\n        \"This is a very small test file..\\r\\n\",\n        \"--------------------------756b6d74fa1a8ee2\\r\\n\",\n        \"Content-Disposition: form-data; name=\\\"filedata\\\"; filename=\\\"small_text_file.txt\\\"\\r\\n\",\n        \"Content-Type: text/plain\\r\\n\",\n        \"\\r\\n\",\n        \"This is another very small test file..\\r\\n\",\n        \"--------------------------756b6d74fa1a8ee2--\\r\\n\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"Host\\\" \\\\(Variable: REQUEST_HEADERS_NAMES:Host\\\\)\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule REQUEST_HEADERS_NAMES \\\"@contains small_text_file.txt\\\" \\\"id:1,phase:3,pass,t:trim\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: REQUEST_HEADERS_NAMES\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"493\",\n        \"Content-Type\": \"multipart/form-data; boundary=------------------------756b6d74fa1a8ee2\",\n        \"Expect\": \"100-continue\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"--------------------------756b6d74fa1a8ee2\",\n        \"Content-Disposition: form-data; name=\\\"name\\\"\",\n        \"\",\n        \"test\",\n        \"--------------------------756b6d74fa1a8ee2\",\n        \"Content-Disposition: form-data; name=\\\"filedata\\\"; filename=\\\"small_text_file.txt\\\"\",\n        \"Content-Type: text/plain\",\n        \"\",\n        \"This is a very small test file..\",\n        \"--------------------------756b6d74fa1a8ee2\",\n        \"Content-Disposition: form-data; name=\\\"filedata\\\"; filename=\\\"small_text_file.txt\\\"\",\n        \"Content-Type: text/plain\",\n        \"\",\n        \"This is another very small test file..\",\n        \"--------------------------756b6d74fa1a8ee2--\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"User-Agent\\\" \\\\(Variable: REQUEST_HEADERS_NAMES:User-Agent\\\\)\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule REQUEST_HEADERS_NAMES \\\"@contains small_text_file.txt\\\" \\\"id:1,phase:3,pass,t:trim\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: REQUEST_HEADERS_NAMES\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"493\",\n        \"Content-Type\": \"multipart/form-data; boundary=------------------------756b6d74fa1a8ee2\",\n        \"Expect\": \"100-continue\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"--------------------------756b6d74fa1a8ee2\",\n        \"Content-Disposition: form-data; name=\\\"name\\\"\",\n        \"\",\n        \"test\",\n        \"--------------------------756b6d74fa1a8ee2\",\n        \"Content-Disposition: form-data; name=\\\"filedata\\\"; filename=\\\"small_text_file.txt\\\"\",\n        \"Content-Type: text/plain\",\n        \"\",\n        \"This is a very small test file..\",\n        \"--------------------------756b6d74fa1a8ee2\",\n        \"Content-Disposition: form-data; name=\\\"filedata\\\"; filename=\\\"small_text_file.txt\\\"\",\n        \"Content-Type: text/plain\",\n        \"\",\n        \"This is another very small test file..\",\n        \"--------------------------756b6d74fa1a8ee2--\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"Accept\\\" \\\\(Variable: REQUEST_HEADERS_NAMES:Accept\\\\)\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule REQUEST_HEADERS_NAMES \\\"@contains small_text_file.txt\\\" \\\"id:1,phase:3,pass,t:trim\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: REQUEST_HEADERS_NAMES\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"493\",\n        \"Content-Type\": \"multipart/form-data; boundary=------------------------756b6d74fa1a8ee2\",\n        \"Expect\": \"100-continue\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"--------------------------756b6d74fa1a8ee2\",\n        \"Content-Disposition: form-data; name=\\\"name\\\"\",\n        \"\",\n        \"test\",\n        \"--------------------------756b6d74fa1a8ee2\",\n        \"Content-Disposition: form-data; name=\\\"filedata\\\"; filename=\\\"small_text_file.txt\\\"\",\n        \"Content-Type: text/plain\",\n        \"\",\n        \"This is a very small test file..\",\n        \"--------------------------756b6d74fa1a8ee2\",\n        \"Content-Disposition: form-data; name=\\\"filedata\\\"; filename=\\\"small_text_file.txt\\\"\",\n        \"Content-Type: text/plain\",\n        \"\",\n        \"This is another very small test file..\",\n        \"--------------------------756b6d74fa1a8ee2--\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"Content-Length\\\" \\\\(Variable: REQUEST_HEADERS_NAMES:Content-Length\\\\)\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule REQUEST_HEADERS_NAMES \\\"@contains small_text_file.txt\\\" \\\"id:1,phase:3,pass,t:trim\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: REQUEST_HEADERS_NAMES\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"493\",\n        \"Content-Type\": \"multipart/form-data; boundary=------------------------756b6d74fa1a8ee2\",\n        \"Expect\": \"100-continue\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"--------------------------756b6d74fa1a8ee2\",\n        \"Content-Disposition: form-data; name=\\\"name\\\"\",\n        \"\",\n        \"test\",\n        \"--------------------------756b6d74fa1a8ee2\",\n        \"Content-Disposition: form-data; name=\\\"filedata\\\"; filename=\\\"small_text_file.txt\\\"\",\n        \"Content-Type: text/plain\",\n        \"\",\n        \"This is a very small test file..\",\n        \"--------------------------756b6d74fa1a8ee2\",\n        \"Content-Disposition: form-data; name=\\\"filedata\\\"; filename=\\\"small_text_file.txt\\\"\",\n        \"Content-Type: text/plain\",\n        \"\",\n        \"This is another very small test file..\",\n        \"--------------------------756b6d74fa1a8ee2--\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"Content-Type\\\" \\\\(Variable: REQUEST_HEADERS_NAMES:Content-Type\\\\)\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule REQUEST_HEADERS_NAMES \\\"@contains small_text_file.txt\\\" \\\"id:1,phase:3,pass,t:trim\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: REQUEST_HEADERS_NAMES\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"493\",\n        \"Content-Type\": \"multipart/form-data; boundary=------------------------756b6d74fa1a8ee2\",\n        \"Expect\": \"100-continue\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"--------------------------756b6d74fa1a8ee2\",\n        \"Content-Disposition: form-data; name=\\\"name\\\"\",\n        \"\",\n        \"test\",\n        \"--------------------------756b6d74fa1a8ee2\",\n        \"Content-Disposition: form-data; name=\\\"filedata\\\"; filename=\\\"small_text_file.txt\\\"\",\n        \"Content-Type: text/plain\",\n        \"\",\n        \"This is a very small test file..\",\n        \"--------------------------756b6d74fa1a8ee2\",\n        \"Content-Disposition: form-data; name=\\\"filedata\\\"; filename=\\\"small_text_file.txt\\\"\",\n        \"Content-Type: text/plain\",\n        \"\",\n        \"This is another very small test file..\",\n        \"--------------------------756b6d74fa1a8ee2--\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"Expect\\\" \\\\(Variable: REQUEST_HEADERS_NAMES:Expect\\\\)\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule REQUEST_HEADERS_NAMES \\\"@contains small_text_file.txt\\\" \\\"id:1,phase:3,pass,t:trim\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/variable-REQUEST_LINE.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: REQUEST_LINE\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?key=value&key=other_value\",\n      \"method\": \"GET\",\n      \"http_version\": 1.1,\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"GET /\\\\?key=value\\\\&key=other_value HTTP/1.1\\\" \\\\(Variable: REQUEST_LINE\\\\)\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule REQUEST_LINE \\\"@contains test \\\" \\\"id:1,pass,t:trim\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: REQUEST_LINE (with URI fragment)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?key=value&key=other_value#urifrag\",\n      \"method\": \"GET\",\n      \"http_version\": 1.1,\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"http_code\": 403\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule REQUEST_LINE \\\"@contains urifrag\\\" \\\"id:1,phase:1,deny,status:403\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: REQUEST_URI_RAW (with URI fragment)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/one/two/testpost.php#urifrag\",\n      \"method\": \"GET\",\n      \"http_version\": 1.1,\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"http_code\": 403\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule REQUEST_URI_RAW \\\"@contains urifrag\\\" \\\"id:1,phase:1,deny,status:403\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/variable-REQUEST_METHOD.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: REQUEST_METHOD\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?key=value&key=other_value\",\n      \"method\": \"GET\",\n      \"http_version\": 1.1,\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"GET\\\" \\\\(Variable: REQUEST_METHOD\\\\)\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule REQUEST_METHOD \\\"@contains test \\\" \\\"id:1,pass,t:trim\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/variable-REQUEST_PROTOCOL.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: REQUEST_PROTOCOL\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?key=value&key=other_value\",\n      \"method\": \"GET\",\n      \"http_version\": 1.1,\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"HTTP/1.1\\\" \\\\(Variable: REQUEST_PROTOCOL\\\\)\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule REQUEST_PROTOCOL \\\"@contains test \\\" \\\"id:1,pass,t:trim\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/variable-REQUEST_URI.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: REQUEST_URI\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?key=value&key=other_value\",\n      \"method\": \"GET\",\n      \"http_version\": 1.1,\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"/\\\\?key=value\\\\&key=other_value\\\" \\\\(Variable: REQUEST_URI\\\\)\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule REQUEST_URI \\\"@contains test \\\" \\\"id:1,pass,t:trim\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: REQUEST_URI (with URI fragment)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?key=value&key=other_value#urifrag\",\n      \"method\": \"GET\",\n      \"http_version\": 1.1,\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"http_code\": 403\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule REQUEST_URI \\\"!@contains urifrag\\\" \\\"id:1,phase:1,deny,status:403\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: REQUEST_URI (with URI fragment)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/one/two/testpost.php#urifrag\",\n      \"method\": \"GET\",\n      \"http_version\": 1.1,\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"http_code\": 403\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule REQUEST_URI \\\"!@contains urifrag\\\" \\\"id:1,phase:1,deny,status:403\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/variable-REQUEST_URI_RAW.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: REQUEST_URI_RAW\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?key=value&key=other_value\",\n      \"method\": \"GET\",\n      \"http_version\": 1.1,\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"/\\\\?key=value\\\\&key=other_value\\\" \\\\(Variable: REQUEST_URI_RAW\\\\)\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule REQUEST_URI_RAW \\\"@contains test \\\" \\\"id:1,pass,t:trim\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: REQUEST_URI_RAW (with URI fragment)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?key=value&key=other_value#urifrag\",\n      \"method\": \"GET\",\n      \"http_version\": 1.1,\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"http_code\": 403\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule REQUEST_URI_RAW \\\"@contains urifrag\\\" \\\"id:1,phase:1,deny,status:403\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: REQUEST_URI_RAW (with URI fragment)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/one/two/testpost.php#urifrag\",\n      \"method\": \"GET\",\n      \"http_version\": 1.1,\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"http_code\": 403\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule REQUEST_URI_RAW \\\"@contains urifrag\\\" \\\"id:1,phase:1,deny,status:403\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/variable-RESPONSE_BODY.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: RESPONSE_BODY\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 0\n    },\n    \"server\": {\n      \"ip\": \"\",\n      \"port\": 0\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/foo\",\n      \"method\": \"\",\n      \"http_version\": 1.1,\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/plain\",\n        \"Content-Length\": \"10\"\n      },\n      \"body\": [\n        \"denystring\"\n      ]\n    },\n    \"expected\": {\n      \"http_code\": 403\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecResponseBodyAccess On\",\n      \"SecRule RESPONSE_BODY \\\"@contains denystring\\\" \\\"id:1,phase:4,deny\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/variable-RESPONSE_CONTENT_LENGTH.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: RESPONSE_CONTENT_LENGTH\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?key=value&key=other_value\",\n      \"method\": \"GET\",\n      \"http_version\": 1.1,\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"8\\\" \\\\(Variable: RESPONSE_CONTENT_LENGTH\\\\)\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecResponseBodyAccess On\",\n      \"SecRule RESPONSE_CONTENT_LENGTH \\\"@contains test \\\" \\\"id:1,phase:4,pass,t:trim\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/variable-RESPONSE_CONTENT_TYPE.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: RESPONSE_CONTENT_TYPE\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?key=value&key=other_value\",\n      \"method\": \"GET\",\n      \"http_version\": 1.1,\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"text/html\\\" \\\\(Variable: RESPONSE_CONTENT_TYPE\\\\)\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule RESPONSE_CONTENT_TYPE \\\"@contains test \\\" \\\"id:1,phase:3,pass,t:trim\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/variable-RESPONSE_HEADERS.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: RESPONSE_HEADERS\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"523\",\n        \"Content-Type\": \"multipart/form-data; boundary=------------------------756b6d74fa1a8ee2\",\n        \"Expect\": \"100-continue\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"--------------------------756b6d74fa1a8ee2\\r\\n\",\n        \"Content-Disposition: form-data; name=\\\"name\\\"\\r\\n\",\n        \"\\r\\n\",\n        \"test\\r\\n\",\n        \"--------------------------756b6d74fa1a8ee2\\r\\n\",\n        \"Content-Disposition: form-data; name=\\\"filedata\\\"; filename=\\\"small_text_file.txt\\\"\\r\\n\",\n        \"Content-Type: text/plain\\r\\n\",\n        \"\\r\\n\",\n        \"This is a very small test file..\\r\\n\",\n        \"--------------------------756b6d74fa1a8ee2\\r\\n\",\n        \"Content-Disposition: form-data; name=\\\"filedata\\\"; filename=\\\"small_text_file.txt\\\"\\r\\n\",\n        \"Content-Type: text/plain\\r\\n\",\n        \"\\r\\n\",\n        \"This is another very small test file..\\r\\n\",\n        \"--------------------------756b6d74fa1a8ee2--\\r\\n\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"Mon, 13 Jul 2015 20:02:41 GMT\\\" \\\\(Variable: RESPONSE_HEADERS:Date\\\\)\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule RESPONSE_HEADERS \\\"@contains small_text_file.txt\\\" \\\"id:1,phase:3,pass,t:trim\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/variable-RESPONSE_HEADERS_NAMES.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: RESPONSE_HEADERS_NAMES\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"523\",\n        \"Content-Type\": \"multipart/form-data; boundary=------------------------756b6d74fa1a8ee2\",\n        \"Expect\": \"100-continue\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"--------------------------756b6d74fa1a8ee2\\r\\n\",\n        \"Content-Disposition: form-data; name=\\\"name\\\"\\r\\n\",\n        \"\\r\\n\",\n        \"test\\r\\n\",\n        \"--------------------------756b6d74fa1a8ee2\\r\\n\",\n        \"Content-Disposition: form-data; name=\\\"filedata\\\"; filename=\\\"small_text_file.txt\\\"\\r\\n\",\n        \"Content-Type: text/plain\\r\\n\",\n        \"\\r\\n\",\n        \"This is a very small test file..\\r\\n\",\n        \"--------------------------756b6d74fa1a8ee2\\r\\n\",\n        \"Content-Disposition: form-data; name=\\\"filedata\\\"; filename=\\\"small_text_file.txt\\\"\\r\\n\",\n        \"Content-Type: text/plain\\r\\n\",\n        \"\\r\\n\",\n        \"This is another very small test file..\\r\\n\",\n        \"--------------------------756b6d74fa1a8ee2--\\r\\n\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"Date\\\" \\\\(Variable: RESPONSE_HEADERS_NAMES:Date\\\\)\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule RESPONSE_HEADERS_NAMES \\\"@contains small_text_file.txt\\\" \\\"id:1,phase:3,pass,t:trim\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: RESPONSE_HEADERS_NAMES\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"493\",\n        \"Content-Type\": \"multipart/form-data; boundary=------------------------756b6d74fa1a8ee2\",\n        \"Expect\": \"100-continue\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"--------------------------756b6d74fa1a8ee2\",\n        \"Content-Disposition: form-data; name=\\\"name\\\"\",\n        \"\",\n        \"test\",\n        \"--------------------------756b6d74fa1a8ee2\",\n        \"Content-Disposition: form-data; name=\\\"filedata\\\"; filename=\\\"small_text_file.txt\\\"\",\n        \"Content-Type: text/plain\",\n        \"\",\n        \"This is a very small test file..\",\n        \"--------------------------756b6d74fa1a8ee2\",\n        \"Content-Disposition: form-data; name=\\\"filedata\\\"; filename=\\\"small_text_file.txt\\\"\",\n        \"Content-Type: text/plain\",\n        \"\",\n        \"This is another very small test file..\",\n        \"--------------------------756b6d74fa1a8ee2--\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"Last-Modified\\\" \\\\(Variable: RESPONSE_HEADERS_NAMES:Last-Modified\\\\)\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule RESPONSE_HEADERS_NAMES \\\"@contains small_text_file.txt\\\" \\\"id:1,phase:3,pass,t:trim\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: RESPONSE_HEADERS_NAMES\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"493\",\n        \"Content-Type\": \"multipart/form-data; boundary=------------------------756b6d74fa1a8ee2\",\n        \"Expect\": \"100-continue\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"--------------------------756b6d74fa1a8ee2\",\n        \"Content-Disposition: form-data; name=\\\"name\\\"\",\n        \"\",\n        \"test\",\n        \"--------------------------756b6d74fa1a8ee2\",\n        \"Content-Disposition: form-data; name=\\\"filedata\\\"; filename=\\\"small_text_file.txt\\\"\",\n        \"Content-Type: text/plain\",\n        \"\",\n        \"This is a very small test file..\",\n        \"--------------------------756b6d74fa1a8ee2\",\n        \"Content-Disposition: form-data; name=\\\"filedata\\\"; filename=\\\"small_text_file.txt\\\"\",\n        \"Content-Type: text/plain\",\n        \"\",\n        \"This is another very small test file..\",\n        \"--------------------------756b6d74fa1a8ee2--\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"Content-Type\\\" \\\\(Variable: RESPONSE_HEADERS_NAMES:Content-Type\\\\)\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule RESPONSE_HEADERS_NAMES \\\"@contains small_text_file.txt\\\" \\\"id:1,phase:3,pass,t:trim\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/variable-RESPONSE_PROTOCOL.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: RESPONSE_PROTOCOL\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?key=value&key=other_value\",\n      \"method\": \"GET\",\n      \"http_version\": 1.1,\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ],\n      \"protocol\": \"HTTP/1.1\"\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"HTTP/1.1\\\" \\\\(Variable: RESPONSE_PROTOCOL\\\\)\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule RESPONSE_PROTOCOL \\\"^HTTP\\\" \\\"id:1,phase:5,pass,t:trim\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/variable-RULE.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: RULE (1/7)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"27\",\n        \"Content-Type\": \"application/x-www-form-urlencoded\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"param1=value1&param2=value2\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"1\\\" \\\\(Variable: RULE:id\\\\)\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule RULE:id \\\"@contains test\\\" \\\"id:1,phase:3,rev:1.3,pass,t:trim\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: RULE (2/7)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"27\",\n        \"Content-Type\": \"application/x-www-form-urlencoded\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"param1=value1&param2=value2\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"200\\\" \\\\(Variable: RULE:rev\\\\)\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule RULE:rev \\\"@contains test\\\" \\\"id:1,rev:200,phase:3,pass,t:trim\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: RULE (3/7)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"27\",\n        \"Content-Type\": \"application/x-www-form-urlencoded\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"param1=value1&param2=value2\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"2\\\" \\\\(Variable: RULE:severity\\\\)\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule RULE:severity \\\"@contains test\\\" \\\"id:1,phase:3,severity:critical,pass,t:trim\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: RULE (4/7)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"27\",\n        \"Content-Type\": \"application/x-www-form-urlencoded\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"param1=value1&param2=value2\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"data123\\\" \\\\(Variable: RULE:logdata\\\\)\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule RULE:logdata \\\"@contains test\\\" \\\"id:1,logdata:'data123',phase:3,pass,t:trim\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: RULE (5/7)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"27\",\n        \"Content-Type\": \"application/x-www-form-urlencoded\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"param1=value1&param2=value2\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \" Target value: \\\"message123\\\" \\\\(Variable: RULE:msg\\\\)\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule RULE:msg \\\"@contains test\\\" \\\"id:1,msg:'message123',phase:3,pass,t:trim\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: RULE (6/7)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"27\",\n        \"Content-Type\": \"application/x-www-form-urlencoded\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"param1=value1&param2=value2\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \" Target value: \\\"message123\\\" \\\\(Variable: RULE:msg\\\\)\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule rule:msg \\\"@contains test\\\" \\\"id:1,msg:'message123',phase:3,pass,t:trim\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: RULE (7/7)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"27\",\n        \"Content-Type\": \"application/x-www-form-urlencoded\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"param1=value1&param2=value2\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Saving variable: IP:block_reason with value: message123\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule rule:msg \\\"@contains message\\\" \\\"id:1,msg:'message123',setvar:'ip.block_reason=%{RULE.msg}%',phase:3,pass,t:trim\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/variable-SERVER_ADDR.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: SERVER_ADDR\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.11\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\",\n        \"Content-Type\": \"application/x-www-form-urlencoded\"\n      },\n      \"uri\": \"/one/two/three?key1=value1&key2=v%20a%20l%20u%20e%202\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"200.249.12.11\\\" \\\\(Variable: SERVER_ADDR\\\\)\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule SERVER_ADDR \\\"@contains test \\\" \\\"id:1,phase:3,pass,t:trim\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: SERVER_ADDR\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"::1\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\",\n        \"Content-Type\": \"application/x-www-form-urlencoded\"\n      },\n      \"uri\": \"/one/two/three?key1=value1&key2=v%20a%20l%20u%20e%202\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"::1\\\" \\\\(Variable: SERVER_ADDR\\\\)\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule SERVER_ADDR \\\"@contains test \\\" \\\"id:1,phase:3,pass,t:trim\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/variable-SERVER_NAME.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: SERVER_NAME (1/2)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?key=value&key=other_value\",\n      \"method\": \"GET\",\n      \"http_version\": 1.1,\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ],\n      \"protocol\": \"HTTP/1.1\"\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"localhost\\\" \\\\(Variable: SERVER_NAME\\\\)\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule SERVER_NAME \\\"^HTTP\\\" \\\"id:1,phase:5,pass,t:trim\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: SERVER_NAME (2/2)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"www.zimmerle.org:4443\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?key=value&key=other_value\",\n      \"method\": \"GET\",\n      \"http_version\": 1.1,\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ],\n      \"protocol\": \"HTTP/1.1\"\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"www.zimmerle.org\\\" \\\\(Variable: SERVER_NAME\\\\)\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule SERVER_NAME \\\"^HTTP\\\" \\\"id:1,phase:5,pass,t:trim\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/variable-SERVER_PORT.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: SERVER_PORT\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.11\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\",\n        \"Content-Type\": \"application/x-www-form-urlencoded\"\n      },\n      \"uri\": \"/one/two/three?key1=value1&key2=v%20a%20l%20u%20e%202\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"80\\\" \\\\(Variable: SERVER_PORT\\\\)\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule SERVER_PORT \\\"@contains test \\\" \\\"id:1,phase:3,pass,t:trim\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: SERVER_PORT\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"::1\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\",\n        \"Content-Type\": \"application/x-www-form-urlencoded\"\n      },\n      \"uri\": \"/one/two/three?key1=value1&key2=v%20a%20l%20u%20e%202\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"80\\\" \\\\(Variable: SERVER_PORT\\\\)\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule SERVER_PORT \\\"@contains test \\\" \\\"id:1,phase:3,pass,t:trim\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/variable-SESSIONID.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing SESSIONID variable (1/2)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"User-Agent\": \"My sweet little browser\",\n        \"Cookie\": \"PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?key=value&key=other_value\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"rAAAAAAA2t5uvjq435r4q7ib3vtdjq1202\\\"\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule REQUEST_HEADERS:User-Agent \\\"^(.*)$\\\" \\\"id:'900018',phase:1,t:none,t:sha1,t:hexEncode,setsid:%{REQUEST_COOKIES:PHPSESSID}%,nolog,pass\\\"\",\n      \"SecRule REQUEST_HEADERS \\\".*\\\" \\\"id:'900021',phase:1,setvar:SESSION.score=+10\\\"\",\n      \"SecRule REQUEST_HEADERS:User-Agent \\\"^(.*)$\\\" \\\"id:'900068',phase:1,t:none,t:sha1,t:hexEncode,setsid:%{REQUEST_COOKIES:PHPSESSID}2,nolog,pass\\\"\",\n      \"SecRule REQUEST_HEADERS \\\".*\\\" \\\"id:'900022',phase:1,setvar:SESSION.score=+5\\\"\",\n      \"SecRule SESSIONID \\\".*\\\" \\\"id:1239,phase:1,log,pass\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing SESSIONID variable (2/2)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"User-Agent\": \"My sweet little browser\",\n        \"Cookie\": \"PHPSESSID=whee\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?key=value&key=other_value\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"whee\\\"\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule REQUEST_HEADERS:User-Agent \\\"^(.*)$\\\" \\\"id:'900018',phase:1,t:none,t:sha1,t:hexEncode,setsid:%{REQUEST_COOKIES:PHPSESSID}%,nolog,pass\\\"\",\n      \"SecRule REQUEST_HEADERS \\\".*\\\" \\\"id:'900021',phase:1,setvar:SESSION.score=+10\\\"\",\n      \"SecRule SESSIONID \\\".*\\\" \\\"id:1239,phase:1,log,pass\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/variable-STATUS.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: STATUS (1/2)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"27\",\n        \"Content-Type\": \"application/x-www-form-urlencoded\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"param1=value1&param2=value2\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"200\\\" \\\\(Variable: RESPONSE_STATUS\\\\)\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule RESPONSE_STATUS \\\"@contains test\\\" \\\"id:1,phase:5,rev:1.3,pass,t:trim\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: STATUS (2/2)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"27\",\n        \"Content-Type\": \"application/x-www-form-urlencoded\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"param1=value1&param2=value2\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"500\\\" \\\\(Variable: RESPONSE_STATUS\\\\)\",\n      \"http_code\": 500\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule ARGS \\\"@pm value\\\" \\\"id:1,phase:2,t:trim,status:500,deny\\\"\",\n      \"SecRule RESPONSE_STATUS \\\"@contains test\\\" \\\"id:2,phase:5,rev:1.3,pass,t:trim\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/variable-TIME.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: TIME\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.11\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\",\n        \"Content-Type\": \"application/x-www-form-urlencoded\"\n      },\n      \"uri\": \"/one/two/three?key1=value1&key2=v%20a%20l%20u%20e%202\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"([0-9]+):([0-9]+):([0-9]+)\\\" \\\\(Variable: TIME\\\\)\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule TIME \\\"@contains test \\\" \\\"id:1,phase:3,pass,t:trim\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/variable-TIME_DAY.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: TIME_DAY\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.11\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\",\n        \"Content-Type\": \"application/x-www-form-urlencoded\"\n      },\n      \"uri\": \"/one/two/three?key1=value1&key2=v%20a%20l%20u%20e%202\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"([0-9]+)\\\" \\\\(Variable: TIME_DAY\\\\)\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule TIME_DAY \\\"@contains test \\\" \\\"id:1,phase:3,pass,t:trim\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/variable-TIME_EPOCH.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: TIME_EPOCH\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.11\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\",\n        \"Content-Type\": \"application/x-www-form-urlencoded\"\n      },\n      \"uri\": \"/one/two/three?key1=value1&key2=v%20a%20l%20u%20e%202\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"([0-9]+)\\\" \\\\(Variable: TIME_EPOCH\\\\)\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule TIME_EPOCH \\\"@contains test \\\" \\\"id:1,phase:3,pass,t:trim\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/variable-TIME_HOUR.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: TIME_HOUR\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.11\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\",\n        \"Content-Type\": \"application/x-www-form-urlencoded\"\n      },\n      \"uri\": \"/one/two/three?key1=value1&key2=v%20a%20l%20u%20e%202\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"([0-9]+)\\\" \\\\(Variable: TIME_HOUR\\\\)\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule TIME_HOUR \\\"@contains test \\\" \\\"id:1,phase:3,pass,t:trim\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/variable-TIME_MIN.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: TIME_MIN\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.11\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\",\n        \"Content-Type\": \"application/x-www-form-urlencoded\"\n      },\n      \"uri\": \"/one/two/three?key1=value1&key2=v%20a%20l%20u%20e%202\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"([0-9]+)\\\" \\\\(Variable: TIME_MIN\\\\)\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule TIME_MIN \\\"@contains test \\\" \\\"id:1,phase:3,pass,t:trim\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/variable-TIME_MON.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: TIME_MON\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.11\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\",\n        \"Content-Type\": \"application/x-www-form-urlencoded\"\n      },\n      \"uri\": \"/one/two/three?key1=value1&key2=v%20a%20l%20u%20e%202\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"([1-9]|1[012])\\\" \\\\(Variable: TIME_MON\\\\)\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule TIME_MON \\\"@contains test \\\" \\\"id:1,phase:3,pass,t:trim\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/variable-TIME_SEC.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: TIME_SEC\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.11\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\",\n        \"Content-Type\": \"application/x-www-form-urlencoded\"\n      },\n      \"uri\": \"/one/two/three?key1=value1&key2=v%20a%20l%20u%20e%202\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"([0-9]+)\\\" \\\\(Variable: TIME_SEC\\\\)\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule TIME_SEC \\\"@contains test \\\" \\\"id:1,phase:3,pass,t:trim\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/variable-TIME_WDAY.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: TIME_WDAY\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.11\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\",\n        \"Content-Type\": \"application/x-www-form-urlencoded\"\n      },\n      \"uri\": \"/one/two/three?key1=value1&key2=v%20a%20l%20u%20e%202\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"([0-9]+)\\\" \\\\(Variable: TIME_WDAY\\\\)\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule TIME_WDAY \\\"@contains test \\\" \\\"id:1,phase:3,pass,t:trim\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/variable-TIME_YEAR.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: TIME_YEAR\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.11\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\",\n        \"Content-Type\": \"application/x-www-form-urlencoded\"\n      },\n      \"uri\": \"/one/two/three?key1=value1&key2=v%20a%20l%20u%20e%202\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"([0-9]+)\\\" \\\\(Variable: TIME_YEAR\\\\)\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule TIME_YEAR \\\"@contains test \\\" \\\"id:1,phase:3,pass,t:trim\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/variable-TX.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: TX:0 (1/2)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.11\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\",\n        \"Content-Type\": \"application/x-www-form-urlencoded\"\n      },\n      \"uri\": \"/one/two/three?key1=value1&key2=v%20a%20l%20u%20e%202\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"13\"\n      },\n      \"body\": [\n        \"whee test 123\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"(.*) Target value: \\\"123\\\" \\\\(Variable\\\\: TX\\\\:0(.*)\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecResponseBodyAccess On\",\n      \"SecRequestBodyAccess On\",\n      \"SecRule RESPONSE_BODY \\\"@rx ([0-9]+)\\\" \\\"id:1,phase:4,capture,id:105\\\"\",\n      \"SecRule TX \\\"@rx ([A-z]+)\\\" \\\"phase:4,id:106\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: TX:0 (2/2)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Cookie\": \"USER_TOKEN=Yes; a=z; t=b\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?key=value&key=other_value\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"USER_TOKEN\\\" \\\\(Variable: TX:0(.*)\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule REQUEST_HEADERS \\\"@rx ([A-z]+)\\\" \\\"id:1,log,pass,capture,id:14\\\"\",\n      \"SecRule TX:0 \\\"@rx ([A-z]+)\\\" \\\"id:15\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: capture group match after unused group\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?key=aadd\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Added regex subexpression TX\\\\.3: dd[\\\\s\\\\S]*Target value: \\\"dd\\\" \\\\(Variable\\\\: TX\\\\:3[\\\\s\\\\S]*Rule returned 1\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule ARGS \\\"@rx (aa)(bb|cc)?(dd)\\\" \\\"id:1,log,pass,capture,id:16\\\"\",\n      \"SecRule TX:3 \\\"@streq dd\\\" \\\"id:19,phase:2,log,pass\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: empty capture group match followed by nonempty capture group\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?key=aadd\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Added regex subexpression TX\\\\.3: dd[\\\\s\\\\S]*Target value: \\\"dd\\\" \\\\(Variable\\\\: TX\\\\:3[\\\\s\\\\S]*Rule returned 1\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule ARGS \\\"@rx (aa)(bb|cc|)(dd)\\\" \\\"id:18,phase:1,log,pass,capture\\\"\",\n      \"SecRule TX:3 \\\"@streq dd\\\" \\\"id:19,phase:2,log,pass\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: repeating capture group -- alternates\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?key=_abc123_\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Added regex subexpression TX\\\\.2: abc[\\\\s\\\\S]*Added regex subexpression TX\\\\.3: 123\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule ARGS \\\"@rx _((?:(abc)|(123))+)_\\\" \\\"id:18,phase:1,log,pass,capture\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: repeating capture group -- same (nested)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?key=a:5a:8a:9\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Added regex subexpression TX\\\\.1: 5[\\\\s\\\\S]*Added regex subexpression TX\\\\.2: 8[\\\\s\\\\S]*Added regex subexpression TX\\\\.3: 9\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule ARGS \\\"@rx a:([0-9])(?:a:([0-9])(?:a:([0-9]))*)*\\\" \\\"id:18,phase:1,log,pass,capture\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/variable-UNIQUE_ID.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: UNIQUE_ID\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.11\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\",\n        \"Content-Type\": \"application/x-www-form-urlencoded\"\n      },\n      \"uri\": \"/one/two/three?key1=value1&key2=v%20a%20l%20u%20e%202\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"([0-9.]+)\\\" \\\\(Variable: UNIQUE_ID\\\\)\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule UNIQUE_ID \\\"@contains test \\\" \\\"id:1,phase:3,pass,t:trim\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/variable-URLENCODED_ERROR.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: URLENCODED_ERROR - GET (1/7)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?key=value&key=other_value%2\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"1\\\" \\\\(Variable: URLENCODED_ERROR\\\\)\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule URLENCODED_ERROR \\\"@gt 10 \\\" \\\"id:1,pass\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: URLENCODED_ERROR - GET (2/7)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?key=value&key=other_value&a=b%2a\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"0\\\" \\\\(Variable: URLENCODED_ERROR\\\\)\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule URLENCODED_ERROR \\\"@gt 10 \\\" \\\"id:1,pass\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: URLENCODED_ERROR - POST (3/7)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"31\",\n        \"Content-Type\": \"application/x-www-form-urlencoded\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"param1=value12%&param2=value2%2\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"1\\\" \\\\(Variable: URLENCODED_ERROR\\\\)\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule URLENCODED_ERROR \\\"@gt 10 \\\" \\\"id:1,phase:3,pass\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: URLENCODED_ERROR - POST (4/7)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"36\",\n        \"Content-Type\": \"application/x-www-form-urlencoded\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"param1=value1&param2=value2&a=b5%2a\\n\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"0\\\" \\\\(Variable: URLENCODED_ERROR\\\\)\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule URLENCODED_ERROR \\\"@gt 10 \\\" \\\"id:1,phase:3,pass,t:trim\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: URLENCODED_ERROR - POST (5/7)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"44\",\n        \"Content-Type\": \"application/x-www-form-urlencoded\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"a=%EC%A7%84%20%EB%A7%88%EC%9D%BC%20%EB%A6%AC\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"0\\\" \\\\(Variable: URLENCODED_ERROR\\\\)\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule URLENCODED_ERROR \\\"@gt 10 \\\" \\\"id:1,phase:3,pass,t:trim\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: URLENCODED_ERROR - GET (6/7)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\",\n        \"Content-Type\": \"application/x-www-form-urlencoded\"\n      },\n      \"uri\": \"/?z=%EC%A7%84%20%EB%A7%88%EC%9D%BC%20%EB%A6%A%AC\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"1\\\" \\\\(Variable: URLENCODED_ERROR\\\\)\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule URLENCODED_ERROR \\\"@gt 10 \\\" \\\"id:1,phase:3,pass,t:trim\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: URLENCODED_ERROR - GET (7/7)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"0\",\n        \"Content-Type\": \"application/x-www-form-urlencoded\"\n      },\n      \"uri\": \"/?z=진 마일 리\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"0\\\" \\\\(Variable: URLENCODED_ERROR\\\\)\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule URLENCODED_ERROR \\\"@gt 10 \\\" \\\"id:1,phase:3,pass,t:trim\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/variable-USERID.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing USERID variable (1/2)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"User-Agent\": \"My sweet little browser\",\n        \"Cookie\": \"USER=zimmerle\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?key=value&key=other_value\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"zimmerle2\\\"\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule REQUEST_HEADERS:User-Agent \\\"^(.*)$\\\" \\\"id:'900018',phase:1,t:none,t:sha1,t:hexEncode,setuid:%{REQUEST_COOKIES:USER}%,nolog,pass\\\"\",\n      \"SecRule REQUEST_HEADERS:User-Agent \\\"^(.*)$\\\" \\\"id:'900068',phase:1,t:none,t:sha1,t:hexEncode,setuid:%{REQUEST_COOKIES:USER}2,nolog,pass\\\"\",\n      \"SecRule USERID \\\".*\\\" \\\"id:1239,phase:1,log,pass\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing USERID variable (2/2)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"User-Agent\": \"My sweet little browser\",\n        \"Cookie\": \"USER=whee\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/?key=value&key=other_value\",\n      \"method\": \"GET\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"whee\\\"\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule REQUEST_HEADERS:User-Agent \\\"^(.*)$\\\" \\\"id:'900018',phase:1,t:none,t:sha1,t:hexEncode,setuid:%{REQUEST_COOKIES:USER}%,nolog,pass\\\"\",\n      \"SecRule USERID \\\".*\\\" \\\"id:1239,phase:1,log,pass\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/variable-WEBAPPID.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: WEBAPPID (1)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"27\",\n        \"Content-Type\": \"application/x-www-form-urlencoded\",\n        \"Authorization\": \"Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"param1=value1&param2=value2\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"t:trim: \\\"\\\"\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule WEBAPPID \\\"@contains test \\\" \\\"id:1,phase:3,pass,t:trim\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing Variables :: WEBAPPID (2)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Length\": \"27\",\n        \"Content-Type\": \"application/x-www-form-urlencoded\",\n        \"AuThOrIzAtIoN\": \"Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"param1=value1&param2=value2\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Date\": \"Mon, 13 Jul 2015 20:02:41 GMT\",\n        \"Last-Modified\": \"Sun, 26 Oct 2014 22:33:37 GMT\",\n        \"Content-Type\": \"text/html\",\n        \"Content-Length\": \"8\"\n      },\n      \"body\": [\n        \"no need.\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"bisteka\\\"\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecWebAppId bisteka\",\n      \"SecRule WEBAPPID \\\"@contains test \\\" \\\"id:1,phase:3,pass,t:trim\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/variable-WEBSERVER_ERROR_LOG.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"version_max\": 0,\n    \"title\": \"Testing Variables :: WEBSERVER_ERROR_LOG (1/1)\",\n    \"client\": {\n      \"ip\": \"\",\n      \"port\": 0\n    },\n    \"server\": {\n      \"ip\": \"\",\n      \"port\": 0\n    },\n    \"request\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"\",\n      \"method\": \"\",\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"http_code\": 200,\n      \"parser_error\": \"Line: 1. Column: 27. Variable VARIABLE_WEBSERVER_ERROR_LOG is not supported by libModSecurity\"\n    },\n    \"rules\": [\n      \"secrule WEBSERVER_ERROR_LOG \\\"@contains test\\\" \\\"id:1,t:lowercase,t:none,msg:'This is a test, %{REQUEST_HEADERS:Accept}%'\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/variable-XML.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing XPath expression with equals sign\",\n    \"resource\": \"libxml2\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Type\": \"text/xml\",\n        \"Content-Length\": \"181\"\n      },\n      \"uri\": \"/?key=value&key=other_value\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"<?xml version=\\\"1.0\\\" encoding=\\\"UTF-8\\\"?>\",\n        \"<!DOCTYPE author [\",\n        \"<!ELEMENT book ANY>\",\n        \"<!ENTITY js SYSTEM \\\"/etc/passwd\\\">\",\n        \"]>\",\n        \"<bookstore>\",\n        \"<some-tag>aaa</some-tag><some-tag>bbb</some-tag>\",\n        \"</bookstore>\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"http_code\": 403\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRequestBodyAccess On\",\n      \"SecRule REQUEST_HEADERS:Content-Type \\\"^text/xml$\\\" \\\"id:500011,phase:1,t:none,t:lowercase,nolog,pass,ctl:requestBodyProcessor=XML\\\"\",\n      \"SecRule XML://bookstore/*[local-name()='some-tag'] \\\"bbb\\\" \\\"id:500012,phase:3,t:none,t:lowercase,log,deny,status:403\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing XML parsing to ARGS with On, check if ARGS is populated\",\n    \"resource\": \"libxml2\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Type\": \"text/xml\",\n        \"Content-Length\": \"181\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"<?xml version=\\\"1.0\\\" encoding=\\\"UTF-8\\\"?>\",\n        \"<!DOCTYPE author [\",\n        \"<!ELEMENT book ANY>\",\n        \"<!ENTITY js SYSTEM \\\"/etc/passwd\\\">\",\n        \"]>\",\n        \"<bookstore>\",\n        \"<some-tag>aaa</some-tag><some-tag>bbb</some-tag>\",\n        \"</bookstore>\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"http_code\": 403\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRequestBodyAccess On\",\n      \"SecParseXmlIntoArgs On\",\n      \"SecRule REQUEST_HEADERS:Content-Type \\\"^text/xml$\\\" \\\"id:500011,phase:1,t:none,t:lowercase,nolog,pass,ctl:requestBodyProcessor=XML\\\"\",\n      \"SecRule ARGS:xml.bookstore.some-tag \\\"@rx aaa\\\" \\\"id:500012,phase:2,t:none,t:lowercase,log,deny,status:403\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing XML parsing to ARGS with On, check if XML is populated\",\n    \"resource\": \"libxml2\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Type\": \"text/xml\",\n        \"Content-Length\": \"181\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"<?xml version=\\\"1.0\\\" encoding=\\\"UTF-8\\\"?>\",\n        \"<!DOCTYPE author [\",\n        \"<!ELEMENT book ANY>\",\n        \"<!ENTITY js SYSTEM \\\"/etc/passwd\\\">\",\n        \"]>\",\n        \"<bookstore>\",\n        \"<some-tag>aaa</some-tag><some-tag>bbb</some-tag>\",\n        \"</bookstore>\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"http_code\": 403\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRequestBodyAccess On\",\n      \"SecParseXmlIntoArgs On\",\n      \"SecRule REQUEST_HEADERS:Content-Type \\\"^text/xml$\\\" \\\"id:500011,phase:1,t:none,t:lowercase,nolog,pass,ctl:requestBodyProcessor=XML\\\"\",\n      \"SecRule XML:/* \\\"@rx aaa\\\" \\\"id:500012,phase:2,t:none,t:lowercase,log,deny,status:403\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing XML parsing to ARGS with OnlyArgs, check if ARGS is populated\",\n    \"resource\": \"libxml2\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Type\": \"text/xml\",\n        \"Content-Length\": \"181\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"<?xml version=\\\"1.0\\\" encoding=\\\"UTF-8\\\"?>\",\n        \"<!DOCTYPE author [\",\n        \"<!ELEMENT book ANY>\",\n        \"<!ENTITY js SYSTEM \\\"/etc/passwd\\\">\",\n        \"]>\",\n        \"<bookstore>\",\n        \"<some-tag>aaa</some-tag><some-tag>bbb</some-tag>\",\n        \"</bookstore>\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"http_code\": 403\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRequestBodyAccess On\",\n      \"SecParseXmlIntoArgs OnlyArgs\",\n      \"SecRule REQUEST_HEADERS:Content-Type \\\"^text/xml$\\\" \\\"id:500011,phase:1,t:none,t:lowercase,nolog,pass,ctl:requestBodyProcessor=XML\\\"\",\n      \"SecRule ARGS:xml.bookstore.some-tag \\\"@rx aaa\\\" \\\"id:500012,phase:2,t:none,t:lowercase,log,deny,status:403\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing XML parsing to ARGS with OnlyArgs, check if XML is populated\",\n    \"resource\": \"libxml2\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Type\": \"text/xml\",\n        \"Content-Length\": \"181\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"<?xml version=\\\"1.0\\\" encoding=\\\"UTF-8\\\"?>\",\n        \"<!DOCTYPE author [\",\n        \"<!ELEMENT book ANY>\",\n        \"<!ENTITY js SYSTEM \\\"/etc/passwd\\\">\",\n        \"]>\",\n        \"<bookstore>\",\n        \"<some-tag>aaa</some-tag><some-tag>bbb</some-tag>\",\n        \"</bookstore>\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRequestBodyAccess On\",\n      \"SecParseXmlIntoArgs OnlyArgs\",\n      \"SecRule REQUEST_HEADERS:Content-Type \\\"^text/xml$\\\" \\\"id:500011,phase:1,t:none,t:lowercase,nolog,pass,ctl:requestBodyProcessor=XML\\\"\",\n      \"SecRule XML:/* \\\"@rx aaa\\\" \\\"id:500012,phase:2,t:none,t:lowercase,log,deny,status:403\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing XML parsing to ARGS with Off, check if ARGS is populated\",\n    \"resource\": \"libxml2\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Type\": \"text/xml\",\n        \"Content-Length\": \"181\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"<?xml version=\\\"1.0\\\" encoding=\\\"UTF-8\\\"?>\",\n        \"<!DOCTYPE author [\",\n        \"<!ELEMENT book ANY>\",\n        \"<!ENTITY js SYSTEM \\\"/etc/passwd\\\">\",\n        \"]>\",\n        \"<bookstore>\",\n        \"<some-tag>aaa</some-tag><some-tag>bbb</some-tag>\",\n        \"</bookstore>\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRequestBodyAccess On\",\n      \"SecParseXmlIntoArgs Off\",\n      \"SecRule REQUEST_HEADERS:Content-Type \\\"^text/xml$\\\" \\\"id:500011,phase:1,t:none,t:lowercase,nolog,pass,ctl:requestBodyProcessor=XML\\\"\",\n      \"SecRule ARGS \\\"@rx aaa\\\" \\\"id:500012,phase:2,t:none,t:lowercase,log,deny,status:403\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing XML parsing to ARGS with Off, check if XML is populated\",\n    \"resource\": \"libxml2\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Type\": \"text/xml\",\n        \"Content-Length\": \"181\"\n      },\n      \"uri\": \"/\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"<?xml version=\\\"1.0\\\" encoding=\\\"UTF-8\\\"?>\",\n        \"<!DOCTYPE author [\",\n        \"<!ELEMENT book ANY>\",\n        \"<!ENTITY js SYSTEM \\\"/etc/passwd\\\">\",\n        \"]>\",\n        \"<bookstore>\",\n        \"<some-tag>aaa</some-tag><some-tag>bbb</some-tag>\",\n        \"</bookstore>\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"http_code\": 403\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRequestBodyAccess On\",\n      \"SecParseXmlIntoArgs Off\",\n      \"SecRule REQUEST_HEADERS:Content-Type \\\"^text/xml$\\\" \\\"id:500011,phase:1,t:none,t:lowercase,nolog,pass,ctl:requestBodyProcessor=XML\\\"\",\n      \"SecRule XML:/* \\\"@rx aaa\\\" \\\"id:500012,phase:2,t:none,t:lowercase,log,deny,status:403\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing XML parsing to ARGS with On, turn Off with ctl, check ARGS\",\n    \"resource\": \"libxml2\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Type\": \"text/xml\",\n        \"Content-Length\": \"181\"\n      },\n      \"uri\": \"/?q=xml\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"<?xml version=\\\"1.0\\\" encoding=\\\"UTF-8\\\"?>\",\n        \"<!DOCTYPE author [\",\n        \"<!ELEMENT book ANY>\",\n        \"<!ENTITY js SYSTEM \\\"/etc/passwd\\\">\",\n        \"]>\",\n        \"<bookstore>\",\n        \"<some-tag>aaa</some-tag><some-tag>bbb</some-tag>\",\n        \"</bookstore>\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRequestBodyAccess On\",\n      \"SecParseXmlIntoArgs On\",\n      \"SecRule REQUEST_HEADERS:Content-Type \\\"^text/xml$\\\" \\\"id:500011,phase:1,t:none,t:lowercase,nolog,pass,ctl:requestBodyProcessor=XML\\\"\",\n      \"SecRule ARGS_GET:q \\\"@rx xml\\\" \\\"id:500012,phase:1,t:none,t:lowercase,ctl:parseXmlIntoArgs=Off\\\"\",\n      \"SecRule ARGS:xml.bookstore.some-tag \\\"@rx aaa\\\" \\\"id:500013,phase:2,t:none,t:lowercase,log,deny,status:403\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing XML parsing to ARGS with On, turn Off with ctl, check XML\",\n    \"resource\": \"libxml2\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Type\": \"text/xml\",\n        \"Content-Length\": \"181\"\n      },\n      \"uri\": \"/?q=xml\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"<?xml version=\\\"1.0\\\" encoding=\\\"UTF-8\\\"?>\",\n        \"<!DOCTYPE author [\",\n        \"<!ELEMENT book ANY>\",\n        \"<!ENTITY js SYSTEM \\\"/etc/passwd\\\">\",\n        \"]>\",\n        \"<bookstore>\",\n        \"<some-tag>aaa</some-tag><some-tag>bbb</some-tag>\",\n        \"</bookstore>\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"http_code\": 403\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRequestBodyAccess On\",\n      \"SecParseXmlIntoArgs On\",\n      \"SecRule REQUEST_HEADERS:Content-Type \\\"^text/xml$\\\" \\\"id:500011,phase:1,t:none,t:lowercase,nolog,pass,ctl:requestBodyProcessor=XML\\\"\",\n      \"SecRule ARGS_GET:q \\\"@rx xml\\\" \\\"id:500012,phase:1,t:none,t:lowercase,ctl:parseXmlIntoArgs=Off\\\"\",\n      \"SecRule XML:/* \\\"@rx aaa\\\" \\\"id:500013,phase:2,t:none,t:lowercase,log,deny,status:403\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing XML parsing to ARGS with On, turn OnlyArgs with ctl, check ARGS\",\n    \"resource\": \"libxml2\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Type\": \"text/xml\",\n        \"Content-Length\": \"181\"\n      },\n      \"uri\": \"/?q=xml\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"<?xml version=\\\"1.0\\\" encoding=\\\"UTF-8\\\"?>\",\n        \"<!DOCTYPE author [\",\n        \"<!ELEMENT book ANY>\",\n        \"<!ENTITY js SYSTEM \\\"/etc/passwd\\\">\",\n        \"]>\",\n        \"<bookstore>\",\n        \"<some-tag>aaa</some-tag><some-tag>bbb</some-tag>\",\n        \"</bookstore>\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"http_code\": 403\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRequestBodyAccess On\",\n      \"SecParseXmlIntoArgs On\",\n      \"SecRule REQUEST_HEADERS:Content-Type \\\"^text/xml$\\\" \\\"id:500011,phase:1,t:none,t:lowercase,nolog,pass,ctl:requestBodyProcessor=XML\\\"\",\n      \"SecRule ARGS_GET:q \\\"@rx xml\\\" \\\"id:500012,phase:1,t:none,t:lowercase,ctl:parseXmlIntoArgs=OnlyArgs\\\"\",\n      \"SecRule ARGS:xml.bookstore.some-tag \\\"@rx aaa\\\" \\\"id:500013,phase:2,t:none,t:lowercase,log,deny,status:403\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing XML parsing to ARGS with On, turn OnlyArgs with ctl, check XML\",\n    \"resource\": \"libxml2\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Type\": \"text/xml\",\n        \"Content-Length\": \"181\"\n      },\n      \"uri\": \"/?q=xml\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"<?xml version=\\\"1.0\\\" encoding=\\\"UTF-8\\\"?>\",\n        \"<!DOCTYPE author [\",\n        \"<!ELEMENT book ANY>\",\n        \"<!ENTITY js SYSTEM \\\"/etc/passwd\\\">\",\n        \"]>\",\n        \"<bookstore>\",\n        \"<some-tag>aaa</some-tag><some-tag>bbb</some-tag>\",\n        \"</bookstore>\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRequestBodyAccess On\",\n      \"SecParseXmlIntoArgs On\",\n      \"SecRule REQUEST_HEADERS:Content-Type \\\"^text/xml$\\\" \\\"id:500011,phase:1,t:none,t:lowercase,nolog,pass,ctl:requestBodyProcessor=XML\\\"\",\n      \"SecRule ARGS_GET:q \\\"@rx xml\\\" \\\"id:500012,phase:1,t:none,t:lowercase,ctl:parseXmlIntoArgs=OnlyArgs\\\"\",\n      \"SecRule XML:/* \\\"@rx aaa\\\" \\\"id:500013,phase:2,t:none,t:lowercase,log,deny,status:403\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing XML parsing to ARGS with Off, turn On with ctl, check ARGS\",\n    \"resource\": \"libxml2\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Type\": \"text/xml\",\n        \"Content-Length\": \"181\"\n      },\n      \"uri\": \"/?q=xml\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"<?xml version=\\\"1.0\\\" encoding=\\\"UTF-8\\\"?>\",\n        \"<!DOCTYPE author [\",\n        \"<!ELEMENT book ANY>\",\n        \"<!ENTITY js SYSTEM \\\"/etc/passwd\\\">\",\n        \"]>\",\n        \"<bookstore>\",\n        \"<some-tag>aaa</some-tag><some-tag>bbb</some-tag>\",\n        \"</bookstore>\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"http_code\": 403\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRequestBodyAccess On\",\n      \"SecParseXmlIntoArgs Off\",\n      \"SecRule REQUEST_HEADERS:Content-Type \\\"^text/xml$\\\" \\\"id:500011,phase:1,t:none,t:lowercase,nolog,pass,ctl:requestBodyProcessor=XML\\\"\",\n      \"SecRule ARGS_GET:q \\\"@rx xml\\\" \\\"id:500012,phase:1,t:none,t:lowercase,ctl:parseXmlIntoArgs=On\\\"\",\n      \"SecRule ARGS:xml.bookstore.some-tag \\\"@rx aaa\\\" \\\"id:500013,phase:2,t:none,t:lowercase,log,deny,status:403\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing XML parsing to ARGS with Off, turn On with ctl, check XML\",\n    \"resource\": \"libxml2\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Type\": \"text/xml\",\n        \"Content-Length\": \"181\"\n      },\n      \"uri\": \"/?q=xml\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"<?xml version=\\\"1.0\\\" encoding=\\\"UTF-8\\\"?>\",\n        \"<!DOCTYPE author [\",\n        \"<!ELEMENT book ANY>\",\n        \"<!ENTITY js SYSTEM \\\"/etc/passwd\\\">\",\n        \"]>\",\n        \"<bookstore>\",\n        \"<some-tag>aaa</some-tag><some-tag>bbb</some-tag>\",\n        \"</bookstore>\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"http_code\": 403\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRequestBodyAccess On\",\n      \"SecParseXmlIntoArgs Off\",\n      \"SecRule REQUEST_HEADERS:Content-Type \\\"^text/xml$\\\" \\\"id:500011,phase:1,t:none,t:lowercase,nolog,pass,ctl:requestBodyProcessor=XML\\\"\",\n      \"SecRule ARGS_GET:q \\\"@rx xml\\\" \\\"id:500012,phase:1,t:none,t:lowercase,ctl:parseXmlIntoArgs=On\\\"\",\n      \"SecRule XML:/* \\\"@rx aaa\\\" \\\"id:500013,phase:2,t:none,t:lowercase,log,deny,status:403\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"title\": \"Testing XML parsing to ARGS with On, node contains utf8 character\",\n    \"resource\": \"libxml2\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 123\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"Host\": \"localhost\",\n        \"User-Agent\": \"curl/7.38.0\",\n        \"Accept\": \"*/*\",\n        \"Content-Type\": \"text/xml\",\n        \"Content-Length\": \"50\"\n      },\n      \"uri\": \"/?q=xml\",\n      \"method\": \"POST\",\n      \"body\": [\n        \"<pizza>\",\n        \"<has>pineapple</has><has>🍍</has>\",\n        \"</pizza>\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Length\": \"0\"\n      },\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"expected\": {\n      \"http_code\": 403\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRequestBodyAccess On\",\n      \"SecParseXmlIntoArgs On\",\n      \"SecRule REQUEST_HEADERS:Content-Type \\\"^text/xml$\\\" \\\"id:500011,phase:1,t:none,t:lowercase,nolog,pass,ctl:requestBodyProcessor=XML\\\"\",\n      \"SecRule ARGS \\\"@rx 🍍\\\" \\\"id:500013,phase:2,t:none,t:lowercase,log,deny,status:403\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/variable-variation-count.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"version_max\": 0,\n    \"title\": \"Testing variable variations :: count (1/3)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 2313\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"User-Agent\": \"Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)\",\n        \"Accept\": \"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\",\n        \"Accept-Language\": \"en-us,en;q=0.5\",\n        \"Accept-Encoding\": \"gzip,deflate\",\n        \"Accept-Charset\": \"ISO-8859-1,utf-8;q=0.7,*;q=0.7\",\n        \"Keep-Alive\": \"300\",\n        \"Connection\": \"keep-alive\",\n        \"Cookie\": \"PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120\",\n        \"Pragma\": \"no-cache\",\n        \"Cache-Control\": \"no-cache\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/test.pl?param1=   test   &param2=test2\",\n      \"method\": \"GET\",\n      \"http_version\": 1.1,\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Type\": \"text/xml; charset=utf-8\\n\\r\",\n        \"Content-Length\": \"384\"\n      },\n      \"body\": [\n        \"<?xml version=\\\"1.0\\\" encoding=\\\"utf-8\\\"?>\\n\\r\",\n        \"<soap:Envelope xmlns:xsi=\\\"http://www.w3.org/2001/XMLSchema-instance\\\" xmlns:xsd=\\\"http://www.w3.org/2001/XMLSchema\\\" xmlns:soap=\\\"http://schemas.xmlsoap.org/soap/envelope/\\\">\\n\\r\",\n        \"  <soap:Body>\\n\\r\",\n        \"  <EnlightenResponse xmlns=\\\"http://clearforest.com/\\\">\\n\\r\",\n        \"  <EnlightenResult>string</EnlightenResult>\\n\\r\",\n        \"  </EnlightenResponse>\\n\\r\",\n        \"  </soap:Body>\\n\\r\",\n        \"</soap:Envelope>\\n\\r\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"11\\\" \\\\(Variable: REQUEST_HEADERS\\\\)\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule &REQUEST_HEADERS \\\"@contains test \\\" \\\"id:1,t:lowercase,t:none\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"version_max\": 0,\n    \"title\": \"Testing variable variations :: count (2/3)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 2313\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"User-Agent\": \"Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)\",\n        \"Accept\": \"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\",\n        \"Accept-Language\": \"en-us,en;q=0.5\",\n        \"Accept-Encoding\": \"gzip,deflate\",\n        \"Accept-Charset\": \"ISO-8859-1,utf-8;q=0.7,*;q=0.7\",\n        \"Keep-Alive\": \"300\",\n        \"Connection\": \"keep-alive\",\n        \"Cookie\": \"PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120\",\n        \"Pragma\": \"no-cache\",\n        \"Cache-Control\": \"no-cache\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/test.pl?param1=   test   &param2=test2\",\n      \"method\": \"GET\",\n      \"http_version\": 1.1,\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Type\": \"text/xml; charset=utf-8\\n\\r\",\n        \"Content-Length\": \"384\"\n      },\n      \"body\": [\n        \"<?xml version=\\\"1.0\\\" encoding=\\\"utf-8\\\"?>\\n\\r\",\n        \"<soap:Envelope xmlns:xsi=\\\"http://www.w3.org/2001/XMLSchema-instance\\\" xmlns:xsd=\\\"http://www.w3.org/2001/XMLSchema\\\" xmlns:soap=\\\"http://schemas.xmlsoap.org/soap/envelope/\\\">\\n\\r\",\n        \"  <soap:Body>\\n\\r\",\n        \"  <EnlightenResponse xmlns=\\\"http://clearforest.com/\\\">\\n\\r\",\n        \"  <EnlightenResult>string</EnlightenResult>\\n\\r\",\n        \"  </EnlightenResponse>\\n\\r\",\n        \"  </soap:Body>\\n\\r\",\n        \"</soap:Envelope>\\n\\r\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"1\\\" \\\\(Variable: REQUEST_HEADERS:Accept\\\\)\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule &REQUEST_HEADERS:Accept \\\"@contains test \\\" \\\"id:1,t:lowercase,t:none\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"version_max\": 0,\n    \"title\": \"Testing variable variations :: count (3/3)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 2313\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"User-Agent\": \"Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)\",\n        \"Accept\": \"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\",\n        \"Accept-Language\": \"en-us,en;q=0.5\",\n        \"Accept-Encoding\": \"gzip,deflate\",\n        \"Accept-Charset\": \"ISO-8859-1,utf-8;q=0.7,*;q=0.7\",\n        \"Keep-Alive\": \"300\",\n        \"Connection\": \"keep-alive\",\n        \"Cookie\": \"PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120\",\n        \"Pragma\": \"no-cache\",\n        \"Cache-Control\": \"no-cache\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/test.pl?param1=   test   &param2=test2\",\n      \"method\": \"GET\",\n      \"http_version\": 1.1,\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Type\": \"text/xml; charset=utf-8\\n\\r\",\n        \"Content-Length\": \"384\"\n      },\n      \"body\": [\n        \"<?xml version=\\\"1.0\\\" encoding=\\\"utf-8\\\"?>\\n\\r\",\n        \"<soap:Envelope xmlns:xsi=\\\"http://www.w3.org/2001/XMLSchema-instance\\\" xmlns:xsd=\\\"http://www.w3.org/2001/XMLSchema\\\" xmlns:soap=\\\"http://schemas.xmlsoap.org/soap/envelope/\\\">\\n\\r\",\n        \"  <soap:Body>\\n\\r\",\n        \"  <EnlightenResponse xmlns=\\\"http://clearforest.com/\\\">\\n\\r\",\n        \"  <EnlightenResult>string</EnlightenResult>\\n\\r\",\n        \"  </EnlightenResponse>\\n\\r\",\n        \"  </soap:Body>\\n\\r\",\n        \"</soap:Envelope>\\n\\r\"\n      ]\n    },\n    \"expected\": {\n      \"debug_log\": \"Target value: \\\"0\\\" \\\\(Variable: REQUEST_HEADERS:missing\\\\)\",\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule &REQUEST_HEADERS:missing \\\"@contains test \\\" \\\"id:1,t:lowercase,t:none\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-cases/regression/variable-variation-exclusion.json",
    "content": "[\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"version_max\": 0,\n    \"title\": \"Testing variable variations :: exclusion (1/2)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 2313\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"User-Agent\": \"Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)\",\n        \"Accept\": \"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\",\n        \"Accept-Language\": \"en-us,en;q=0.5\",\n        \"Accept-Encoding\": \"gzip,deflate\",\n        \"Accept-Charset\": \"ISO-8859-1,utf-8;q=0.7,*;q=0.7\",\n        \"Keep-Alive\": \"300\",\n        \"Connection\": \"keep-alive\",\n        \"Cookie\": \"PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120\",\n        \"Pragma\": \"no-cache\",\n        \"Cache-Control\": \"no-cache\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/test.pl?param1=   test   &param2=test2\",\n      \"method\": \"GET\",\n      \"http_version\": 1.1,\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Type\": \"text/xml; charset=utf-8\\n\\r\",\n        \"Content-Length\": \"384\"\n      },\n      \"body\": [\n        \"<?xml version=\\\"1.0\\\" encoding=\\\"utf-8\\\"?>\\n\\r\",\n        \"<soap:Envelope xmlns:xsi=\\\"http://www.w3.org/2001/XMLSchema-instance\\\" xmlns:xsd=\\\"http://www.w3.org/2001/XMLSchema\\\" xmlns:soap=\\\"http://schemas.xmlsoap.org/soap/envelope/\\\">\\n\\r\",\n        \"  <soap:Body>\\n\\r\",\n        \"  <EnlightenResponse xmlns=\\\"http://clearforest.com/\\\">\\n\\r\",\n        \"  <EnlightenResult>string</EnlightenResult>\\n\\r\",\n        \"  </EnlightenResponse>\\n\\r\",\n        \"  </soap:Body>\\n\\r\",\n        \"</soap:Envelope>\\n\\r\"\n      ]\n    },\n    \"expected\": {\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule REQUEST_HEADERS|!REQUEST_HEADERS:Accept|!REMOTE_HOST \\\"@contains html\\\" \\\"id:1,t:lowercase,t:none,block,deny,status:300\\\"\"\n    ]\n  },\n  {\n    \"enabled\": 1,\n    \"version_min\": 300000,\n    \"version_max\": 0,\n    \"title\": \"Testing variable variations :: exclusion (2/2)\",\n    \"client\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 2313\n    },\n    \"server\": {\n      \"ip\": \"200.249.12.31\",\n      \"port\": 80\n    },\n    \"request\": {\n      \"headers\": {\n        \"User-Agent\": \"Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)\",\n        \"Accept\": \"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\",\n        \"Accept-Language\": \"en-us,en;q=0.5\",\n        \"Accept-Encoding\": \"gzip,deflate\",\n        \"Accept-Charset\": \"ISO-8859-1,utf-8;q=0.7,*;q=0.7\",\n        \"Keep-Alive\": \"300\",\n        \"Connection\": \"keep-alive\",\n        \"Cookie\": \"PHPSESSID=rAAAAAAA2t5uvjq435r4q7ib3vtdjq120\",\n        \"Pragma\": \"no-cache\",\n        \"Cache-Control\": \"no-cache\",\n        \"Content-Length\": \"0\"\n      },\n      \"uri\": \"/test.pl?param1=   test   &param2=test2\",\n      \"method\": \"GET\",\n      \"http_version\": 1.1,\n      \"body\": [\n        \"\"\n      ]\n    },\n    \"response\": {\n      \"headers\": {\n        \"Content-Type\": \"text/xml; charset=utf-8\\n\\r\",\n        \"Content-Length\": \"384\"\n      },\n      \"body\": [\n        \"<?xml version=\\\"1.0\\\" encoding=\\\"utf-8\\\"?>\\n\\r\",\n        \"<soap:Envelope xmlns:xsi=\\\"http://www.w3.org/2001/XMLSchema-instance\\\" xmlns:xsd=\\\"http://www.w3.org/2001/XMLSchema\\\" xmlns:soap=\\\"http://schemas.xmlsoap.org/soap/envelope/\\\">\\n\\r\",\n        \"  <soap:Body>\\n\\r\",\n        \"  <EnlightenResponse xmlns=\\\"http://clearforest.com/\\\">\\n\\r\",\n        \"  <EnlightenResult>string</EnlightenResult>\\n\\r\",\n        \"  </EnlightenResponse>\\n\\r\",\n        \"  </soap:Body>\\n\\r\",\n        \"</soap:Envelope>\\n\\r\"\n      ]\n    },\n    \"expected\": {\n      \"http_code\": 200\n    },\n    \"rules\": [\n      \"SecRuleEngine On\",\n      \"SecRule REQUEST_HEADERS|!REQUEST_HEADERS \\\"@contains html\\\" \\\"id:1,t:lowercase,t:none,block,deny,status:300\\\"\"\n    ]\n  }\n]\n"
  },
  {
    "path": "test/test-suite.in",
    "content": "# for i in `find test/test-cases -iname *.json`; do echo TESTS+=$i; done\nTESTS+=test/test-cases/regression/action-allow.json\nTESTS+=test/test-cases/regression/action-block.json\nTESTS+=test/test-cases/regression/action-ctl_request_body_access.json\nTESTS+=test/test-cases/regression/action-ctl_request_body_processor.json\nTESTS+=test/test-cases/regression/action-ctl_request_body_processor_urlencoded.json\nTESTS+=test/test-cases/regression/action-ctl_rule_engine.json\nTESTS+=test/test-cases/regression/action-ctl_audit_engine.json\nTESTS+=test/test-cases/regression/action-ctl_rule_remove_by_id.json\nTESTS+=test/test-cases/regression/action-ctl_rule_remove_by_tag.json\nTESTS+=test/test-cases/regression/action-ctl_rule_remove_target_by_id.json\nTESTS+=test/test-cases/regression/action-ctl_rule_remove_target_by_tag.json\nTESTS+=test/test-cases/regression/action-disruptive.json\nTESTS+=test/test-cases/regression/action-exec.json\nTESTS+=test/test-cases/regression/action-expirevar.json\nTESTS+=test/test-cases/regression/action-id.json\nTESTS+=test/test-cases/regression/action-initcol.json\nTESTS+=test/test-cases/regression/action-msg.json\nTESTS+=test/test-cases/regression/action-setenv.json\nTESTS+=test/test-cases/regression/action-setrsc.json\nTESTS+=test/test-cases/regression/action-setsid.json\nTESTS+=test/test-cases/regression/action-setuid.json\nTESTS+=test/test-cases/regression/actions.json\nTESTS+=test/test-cases/regression/action-skip.json\nTESTS+=test/test-cases/regression/action-tag.json\nTESTS+=test/test-cases/regression/action-tnf-base64.json\nTESTS+=test/test-cases/regression/action-xmlns.json\nTESTS+=test/test-cases/regression/auditlog.json\nTESTS+=test/test-cases/regression/collection-case-insensitive.json\nTESTS+=test/test-cases/regression/collection-lua.json\nTESTS+=test/test-cases/regression/collection-regular_expression_selection.json\nTESTS+=test/test-cases/regression/collection-resource.json\nTESTS+=test/test-cases/regression/collection-tx.json\nTESTS+=test/test-cases/regression/collection-tx-with-macro.json\nTESTS+=test/test-cases/regression/config-body_limits.json\nTESTS+=test/test-cases/regression/config-calling_phases_by_name.json\nTESTS+=test/test-cases/regression/config-include-bad.json\nTESTS+=test/test-cases/regression/config-include.json\nTESTS+=test/test-cases/regression/config-remove_by_id.json\nTESTS+=test/test-cases/regression/config-remove_by_msg.json\nTESTS+=test/test-cases/regression/config-remove_by_tag.json\nTESTS+=test/test-cases/regression/config-response_type.json\nTESTS+=test/test-cases/regression/config-secdefaultaction.json\nTESTS+=test/test-cases/regression/config-secremoterules.json\nTESTS+=test/test-cases/regression/config-update-action-by-id.json\nTESTS+=test/test-cases/regression/config-update-target-by-id.json\nTESTS+=test/test-cases/regression/config-update-target-by-msg.json\nTESTS+=test/test-cases/regression/config-update-target-by-tag.json\nTESTS+=test/test-cases/regression/config-xml_external_entity.json\nTESTS+=test/test-cases/regression/debug_log.json\nTESTS+=test/test-cases/regression/directive-sec_rule_script.json\nTESTS+=test/test-cases/regression/fn-setHostname.json\nTESTS+=test/test-cases/regression/issue-1152.json\nTESTS+=test/test-cases/regression/issue-1528.json\nTESTS+=test/test-cases/regression/issue-1565.json\nTESTS+=test/test-cases/regression/issue-1576.json\nTESTS+=test/test-cases/regression/issue-1591.json\nTESTS+=test/test-cases/regression/issue-1725.json\nTESTS+=test/test-cases/regression/issue-1743.json\nTESTS+=test/test-cases/regression/issue-1785.json\nTESTS+=test/test-cases/regression/issue-1812.json\nTESTS+=test/test-cases/regression/issue-1831.json\nTESTS+=test/test-cases/regression/issue-1844.json\nTESTS+=test/test-cases/regression/issue-1850.json\nTESTS+=test/test-cases/regression/issue-1941.json\nTESTS+=test/test-cases/regression/issue-1943.json\nTESTS+=test/test-cases/regression/issue-1956.json\nTESTS+=test/test-cases/regression/issue-1960.json\nTESTS+=test/test-cases/regression/issue-2099.json\nTESTS+=test/test-cases/regression/issue-2000.json\nTESTS+=test/test-cases/regression/issue-2111.json\nTESTS+=test/test-cases/regression/issue-2196.json\nTESTS+=test/test-cases/regression/issue-2423-msg-in-chain.json\nTESTS+=test/test-cases/regression/issue-2427.json\nTESTS+=test/test-cases/regression/issue-2296.json\nTESTS+=test/test-cases/regression/issue-3340.json\nTESTS+=test/test-cases/regression/issue-394.json\nTESTS+=test/test-cases/regression/issue-849.json\nTESTS+=test/test-cases/regression/issue-960.json\nTESTS+=test/test-cases/regression/misc.json\nTESTS+=test/test-cases/regression/misc-variable-under-quotes.json\nTESTS+=test/test-cases/regression/offset-variable.json\nTESTS+=test/test-cases/regression/operator-detectsqli.json\nTESTS+=test/test-cases/regression/operator-detectxss.json\nTESTS+=test/test-cases/regression/operator-fuzzyhash.json\nTESTS+=test/test-cases/regression/operator-inpectFile.json\nTESTS+=test/test-cases/regression/operator-ipMatchFromFile.json\nTESTS+=test/test-cases/regression/operator-pm.json\nTESTS+=test/test-cases/regression/operator-pmfromfile.json\nTESTS+=test/test-cases/regression/operator-rx.json\nTESTS+=test/test-cases/regression/operator-rxGlobal.json\nTESTS+=test/test-cases/regression/operator-UnconditionalMatch.json\nTESTS+=test/test-cases/regression/operator-validate-byte-range.json\nTESTS+=test/test-cases/regression/operator-verifycc.json\nTESTS+=test/test-cases/regression/operator-verifycpf.json\nTESTS+=test/test-cases/regression/operator-verifyssn.json\nTESTS+=test/test-cases/regression/operator-verifysvnr.json\nTESTS+=test/test-cases/regression/request-body-parser-json.json\nTESTS+=test/test-cases/regression/request-body-parser-multipart-crlf.json\nTESTS+=test/test-cases/regression/request-body-parser-multipart.json\nTESTS+=test/test-cases/regression/request-body-parser-xml.json\nTESTS+=test/test-cases/regression/request-body-parser-xml-validade-dtd.json\nTESTS+=test/test-cases/regression/rule-920120.json\nTESTS+=test/test-cases/regression/rule-920200.json\nTESTS+=test/test-cases/regression/rule-920274.json\nTESTS+=test/test-cases/regression/secaction.json\nTESTS+=test/test-cases/regression/secargumentslimit.json\nTESTS+=test/test-cases/regression/sec_component_signature.json\nTESTS+=test/test-cases/regression/secmarker.json\nTESTS+=test/test-cases/regression/secruleengine.json\nTESTS+=test/test-cases/regression/transformation-none.json\nTESTS+=test/test-cases/regression/transformations.json\nTESTS+=test/test-cases/regression/variable-ARGS_COMBINED_SIZE.json\nTESTS+=test/test-cases/regression/variable-ARGS_GET.json\nTESTS+=test/test-cases/regression/variable-ARGS_GET_NAMES.json\nTESTS+=test/test-cases/regression/variable-ARGS.json\nTESTS+=test/test-cases/regression/variable-ARGS_NAMES.json\nTESTS+=test/test-cases/regression/variable-ARGS_POST.json\nTESTS+=test/test-cases/regression/variable-ARGS_POST_NAMES.json\nTESTS+=test/test-cases/regression/variable-AUTH_TYPE.json\nTESTS+=test/test-cases/regression/variable-DURATION.json\nTESTS+=test/test-cases/regression/variable-ENV.json\nTESTS+=test/test-cases/regression/variable-FILES_COMBINED_SIZE.json\nTESTS+=test/test-cases/regression/variable-FILES.json\nTESTS+=test/test-cases/regression/variable-FILES_NAMES.json\nTESTS+=test/test-cases/regression/variable-FILES_SIZES.json\nTESTS+=test/test-cases/regression/variable-FULL_REQUEST.json\nTESTS+=test/test-cases/regression/variable-FULL_REQUEST_LENGTH.json\nTESTS+=test/test-cases/regression/variable-GEO.json\nTESTS+=test/test-cases/regression/variable-HIGHEST_SEVERITY.json\nTESTS+=test/test-cases/regression/variable-INBOUND_DATA_ERROR.json\nTESTS+=test/test-cases/regression/variable-MATCHED_VAR.json\nTESTS+=test/test-cases/regression/variable-MATCHED_VAR_NAME.json\nTESTS+=test/test-cases/regression/variable-MATCHED_VARS.json\nTESTS+=test/test-cases/regression/variable-MATCHED_VARS_NAMES.json\nTESTS+=test/test-cases/regression/variable-MODSEC_BUILD.json\nTESTS+=test/test-cases/regression/variable-MULTIPART_CRLF_LF_LINES.json\nTESTS+=test/test-cases/regression/variable-MULTIPART_FILENAME.json\nTESTS+=test/test-cases/regression/variable-MULTIPART_INVALID_HEADER_FOLDING.json\nTESTS+=test/test-cases/regression/variable-MULTIPART_NAME.json\nTESTS+=test/test-cases/regression/variable-MULTIPART_PART_HEADERS.json\nTESTS+=test/test-cases/regression/variable-MULTIPART_STRICT_ERROR.json\nTESTS+=test/test-cases/regression/variable-MULTIPART_UNMATCHED_BOUNDARY.json\nTESTS+=test/test-cases/regression/variable-OUTBOUND_DATA_ERROR.json\nTESTS+=test/test-cases/regression/variable-PATH_INFO.json\nTESTS+=test/test-cases/regression/variable-QUERY_STRING.json\nTESTS+=test/test-cases/regression/variable-REMOTE_ADDR.json\nTESTS+=test/test-cases/regression/variable-REMOTE_HOST.json\nTESTS+=test/test-cases/regression/variable-REMOTE_PORT.json\nTESTS+=test/test-cases/regression/variable-REMOTE_USER.json\nTESTS+=test/test-cases/regression/variable-REQBODY_PROCESSOR_ERROR.json\nTESTS+=test/test-cases/regression/variable-REQBODY_PROCESSOR.json\nTESTS+=test/test-cases/regression/variable-REQUEST_BASENAME.json\nTESTS+=test/test-cases/regression/variable-REQUEST_BODY.json\nTESTS+=test/test-cases/regression/variable-REQUEST_BODY_LENGTH.json\nTESTS+=test/test-cases/regression/variable-REQUEST_COOKIES.json\nTESTS+=test/test-cases/regression/variable-REQUEST_COOKIES_NAMES.json\nTESTS+=test/test-cases/regression/variable-REQUEST_FILENAME.json\nTESTS+=test/test-cases/regression/variable-REQUEST_HEADERS.json\nTESTS+=test/test-cases/regression/variable-REQUEST_HEADERS_NAMES.json\nTESTS+=test/test-cases/regression/variable-REQUEST_LINE.json\nTESTS+=test/test-cases/regression/variable-REQUEST_METHOD.json\nTESTS+=test/test-cases/regression/variable-REQUEST_PROTOCOL.json\nTESTS+=test/test-cases/regression/variable-REQUEST_URI.json\nTESTS+=test/test-cases/regression/variable-REQUEST_URI_RAW.json\nTESTS+=test/test-cases/regression/variable-RESPONSE_BODY.json\nTESTS+=test/test-cases/regression/variable-RESPONSE_CONTENT_LENGTH.json\nTESTS+=test/test-cases/regression/variable-RESPONSE_CONTENT_TYPE.json\nTESTS+=test/test-cases/regression/variable-RESPONSE_HEADERS.json\nTESTS+=test/test-cases/regression/variable-RESPONSE_HEADERS_NAMES.json\nTESTS+=test/test-cases/regression/variable-RESPONSE_PROTOCOL.json\nTESTS+=test/test-cases/regression/variable-RULE.json\nTESTS+=test/test-cases/regression/variable-SERVER_ADDR.json\nTESTS+=test/test-cases/regression/variable-SERVER_NAME.json\nTESTS+=test/test-cases/regression/variable-SERVER_PORT.json\nTESTS+=test/test-cases/regression/variable-SESSIONID.json\nTESTS+=test/test-cases/regression/variable-STATUS.json\nTESTS+=test/test-cases/regression/variable-TIME_DAY.json\nTESTS+=test/test-cases/regression/variable-TIME_EPOCH.json\nTESTS+=test/test-cases/regression/variable-TIME_HOUR.json\nTESTS+=test/test-cases/regression/variable-TIME.json\nTESTS+=test/test-cases/regression/variable-TIME_MIN.json\nTESTS+=test/test-cases/regression/variable-TIME_MON.json\nTESTS+=test/test-cases/regression/variable-TIME_SEC.json\nTESTS+=test/test-cases/regression/variable-TIME_WDAY.json\nTESTS+=test/test-cases/regression/variable-TIME_YEAR.json\nTESTS+=test/test-cases/regression/variable-TX.json\nTESTS+=test/test-cases/regression/variable-UNIQUE_ID.json\nTESTS+=test/test-cases/regression/variable-URLENCODED_ERROR.json\nTESTS+=test/test-cases/regression/variable-USERID.json\nTESTS+=test/test-cases/regression/variable-variation-count.json\nTESTS+=test/test-cases/regression/variable-variation-exclusion.json\nTESTS+=test/test-cases/regression/variable-WEBAPPID.json\nTESTS+=test/test-cases/regression/variable-WEBSERVER_ERROR_LOG.json\nTESTS+=test/test-cases/regression/variable-XML.json\nTESTS+=test/test-cases/secrules-language-tests/operators/beginsWith.json\nTESTS+=test/test-cases/secrules-language-tests/operators/contains.json\nTESTS+=test/test-cases/secrules-language-tests/operators/containsWord.json\nTESTS+=test/test-cases/secrules-language-tests/operators/detectSQLi.json\nTESTS+=test/test-cases/secrules-language-tests/operators/detectXSS.json\nTESTS+=test/test-cases/secrules-language-tests/operators/endsWith.json\nTESTS+=test/test-cases/secrules-language-tests/operators/eq.json\nTESTS+=test/test-cases/secrules-language-tests/operators/ge.json\nTESTS+=test/test-cases/secrules-language-tests/operators/geoLookup.json\nTESTS+=test/test-cases/secrules-language-tests/operators/gt.json\nTESTS+=test/test-cases/secrules-language-tests/operators/ipMatch.json\nTESTS+=test/test-cases/secrules-language-tests/operators/le.json\nTESTS+=test/test-cases/secrules-language-tests/operators/lt.json\nTESTS+=test/test-cases/secrules-language-tests/operators/noMatch.json\nTESTS+=test/test-cases/secrules-language-tests/operators/pmFromFile.json\nTESTS+=test/test-cases/secrules-language-tests/operators/pm.json\nTESTS+=test/test-cases/secrules-language-tests/operators/rx.json\nTESTS+=test/test-cases/secrules-language-tests/operators/rxGlobal.json\nTESTS+=test/test-cases/secrules-language-tests/operators/streq.json\nTESTS+=test/test-cases/secrules-language-tests/operators/strmatch.json\nTESTS+=test/test-cases/secrules-language-tests/operators/unconditionalMatch.json\nTESTS+=test/test-cases/secrules-language-tests/operators/validateByteRange.json\nTESTS+=test/test-cases/secrules-language-tests/operators/validateUrlEncoding.json\nTESTS+=test/test-cases/secrules-language-tests/operators/validateUtf8Encoding.json\nTESTS+=test/test-cases/secrules-language-tests/operators/verifyCC.json\nTESTS+=test/test-cases/secrules-language-tests/operators/verifycpf.json\nTESTS+=test/test-cases/secrules-language-tests/operators/verifyssn.json\nTESTS+=test/test-cases/secrules-language-tests/operators/verifysvnr.json\nTESTS+=test/test-cases/secrules-language-tests/operators/within.json\nTESTS+=test/test-cases/secrules-language-tests/transformations/base64DecodeExt.json\nTESTS+=test/test-cases/secrules-language-tests/transformations/base64Decode.json\nTESTS+=test/test-cases/secrules-language-tests/transformations/base64Encode.json\nTESTS+=test/test-cases/secrules-language-tests/transformations/cmdLine.json\nTESTS+=test/test-cases/secrules-language-tests/transformations/compressWhitespace.json\nTESTS+=test/test-cases/secrules-language-tests/transformations/cssDecode.json\nTESTS+=test/test-cases/secrules-language-tests/transformations/escapeSeqDecode.json\nTESTS+=test/test-cases/secrules-language-tests/transformations/hexDecode.json\nTESTS+=test/test-cases/secrules-language-tests/transformations/hexEncode.json\nTESTS+=test/test-cases/secrules-language-tests/transformations/htmlEntityDecode.json\nTESTS+=test/test-cases/secrules-language-tests/transformations/jsDecode.json\nTESTS+=test/test-cases/secrules-language-tests/transformations/length.json\nTESTS+=test/test-cases/secrules-language-tests/transformations/lowercase.json\nTESTS+=test/test-cases/secrules-language-tests/transformations/md5.json\nTESTS+=test/test-cases/secrules-language-tests/transformations/normalisePath.json\nTESTS+=test/test-cases/secrules-language-tests/transformations/normalisePathWin.json\nTESTS+=test/test-cases/secrules-language-tests/transformations/parityEven7bit.json\nTESTS+=test/test-cases/secrules-language-tests/transformations/parityOdd7bit.json\nTESTS+=test/test-cases/secrules-language-tests/transformations/parityZero7bit.json\nTESTS+=test/test-cases/secrules-language-tests/transformations/removeCommentsChar.json\nTESTS+=test/test-cases/secrules-language-tests/transformations/removeComments.json\nTESTS+=test/test-cases/secrules-language-tests/transformations/removeNulls.json\nTESTS+=test/test-cases/secrules-language-tests/transformations/removeWhitespace.json\nTESTS+=test/test-cases/secrules-language-tests/transformations/replaceComments.json\nTESTS+=test/test-cases/secrules-language-tests/transformations/replaceNulls.json\nTESTS+=test/test-cases/secrules-language-tests/transformations/sha1.json\nTESTS+=test/test-cases/secrules-language-tests/transformations/sqlHexDecode.json\nTESTS+=test/test-cases/secrules-language-tests/transformations/trim.json\nTESTS+=test/test-cases/secrules-language-tests/transformations/trimLeft.json\nTESTS+=test/test-cases/secrules-language-tests/transformations/trimRight.json\nTESTS+=test/test-cases/secrules-language-tests/transformations/urlDecode.json\nTESTS+=test/test-cases/secrules-language-tests/transformations/urlDecodeUni.json\nTESTS+=test/test-cases/secrules-language-tests/transformations/urlEncode.json\nTESTS+=test/test-cases/secrules-language-tests/transformations/utf8toUnicode.json\n"
  },
  {
    "path": "test/test-suite.sh",
    "content": "#!/usr/bin/env bash\n\ncd test 1> /dev/null\n\nlength=$(($#-1))\narray=${@:1:$length}\n\nPARAM=$array\nFILE=${@: -1}\n\nif [[ $FILE == *\"test-cases/regression/\"* ]]\nthen\n    AMOUNT=$(./regression_tests countall ../$FILE)\n    RET=$?\n    if [ $RET -ne 0 ]; then\n        echo \":test-result: SKIP: json is not enabled. (regression/$RET) ../$FILE\"\n        exit 0\n    fi\n\n    for i in `seq 1 $AMOUNT`; do\n        $VALGRIND $PARAM ./regression_tests ../$FILE:$i\n        RET=$?\n        if [ $RET -ne 0 ]; then\n            echo \":test-result: FAIL possible segfault/$RET: ../$FILE:$i\"\n        fi\n        echo $VALGRIND $PARAM ./regression_tests ../$FILE:$i\n    done;\nelse\n      $VALGRIND $PARAM ./unit_tests ../$FILE\n      RET=$?\n      if [ $RET -eq 127 ]\n      then\n          echo \":test-result: SKIP: json is not enabled. (unit/$RET) ../$FILE\"\n      elif [ $RET -ne 0 ]\n      then\n          echo \":test-result: FAIL possible segfault: (unit/$RET) ../$FILE\"\n      fi\nfi\n\ncd - 1> /dev/null\n"
  },
  {
    "path": "test/unit/unit.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2023 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <string.h>\n#include <cstring>\n#include <cassert>\n#include <thread>\n#include <array>\n#include <iostream>\n#include <ctime>\n#include <string>\n\n#include \"modsecurity/rules_set.h\"\n#include \"modsecurity/modsecurity.h\"\n#include \"src/operators/operator.h\"\n#include \"src/actions/transformations/transformation.h\"\n#include \"modsecurity/transaction.h\"\n#include \"modsecurity/actions/action.h\"\n\n\n#include \"test/common/modsecurity_test.h\"\n#include \"test/common/modsecurity_test_results.h\"\n#include \"test/common/modsecurity_test_context.h\"\n#include \"test/common/colors.h\"\n#include \"test/unit/unit_test.h\"\n#include \"src/utils/string.h\"\n\n\n\n\nusing modsecurity_test::UnitTest;\nusing modsecurity_test::UnitTestResult;\nusing modsecurity_test::ModSecurityTest;\nusing modsecurity_test::ModSecurityTestResults;\nusing modsecurity::actions::transformations::Transformation;\nusing modsecurity::operators::Operator;\n\nstd::string default_test_path = \"test-cases/secrules-language-tests/operators\";\nstatic std::list<std::string> resources;\n\nvoid print_help() {\n    std::cout << \"Use ./unit /path/to/file\" << std::endl;\n    std::cout << std::endl;\n    std::cout << std::endl;\n}\n\n\nstruct OperatorTest {\n    using ItemType = Operator;\n\n    static ItemType* init(const UnitTest &t) {\n        auto op = Operator::instantiate(t.name, t.param);\n        assert(op != nullptr);\n\n        std::string error;\n        op->init(t.filename, &error);\n\n        return op;\n    }\n\n    static UnitTestResult eval(ItemType &op, const UnitTest &t, modsecurity::Transaction &transaction) {\n        modsecurity::RuleWithActions rule{nullptr, nullptr, \"dummy.conf\", -1};\n        modsecurity::RuleMessage ruleMessage{rule, transaction};\n        return {op.evaluate(&transaction, &rule, t.input, ruleMessage), {}};\n    }\n\n    static bool check(const UnitTestResult &result, const UnitTest &t) {\n        return result.ret != t.ret;\n    }\n};\n\n\nstruct TransformationTest {\n    using ItemType = Transformation;\n\n    static ItemType* init(const UnitTest &t) {\n        auto tfn = Transformation::instantiate(\"t:\" + t.name);\n        assert(tfn != nullptr);\n\n        return tfn;\n    }\n\n    static UnitTestResult eval(const ItemType &tfn, const UnitTest &t, const modsecurity::Transaction &transaction) {\n        auto ret = t.input;\n        tfn.transform(ret, &transaction);\n        return {1, ret};\n    }\n\n    static bool check(const UnitTestResult &result, const UnitTest &t) {\n        return result.output != t.output;\n    }\n};\n\n\ntemplate<typename TestType>\nUnitTestResult perform_unit_test_once(const UnitTest &t, modsecurity::Transaction &transaction) { // cppcheck-suppress constParameterReference ; transaction can be const for transformations but not for operators\n    std::unique_ptr<typename TestType::ItemType> item(TestType::init(t));\n    assert(item.get() != nullptr);\n\n    return TestType::eval(*item.get(), t, transaction);\n}\n\n\ntemplate<typename TestType>\nUnitTestResult perform_unit_test_multithreaded(const UnitTest &t, modsecurity::Transaction &transaction) {\n\n    constexpr auto NUM_THREADS = 50;\n    constexpr auto ITERATIONS = 5'000;\n\n    std::array<std::thread, NUM_THREADS> threads;\n    std::array<UnitTestResult, NUM_THREADS> results;\n\n    std::unique_ptr<typename TestType::ItemType> item(TestType::init(t));\n    assert(item.get() != nullptr);\n\n    for (auto i = 0; i != threads.size(); ++i)\n    {\n        auto &result = results[i];\n        threads[i] = std::thread(\n            [&item, &t, &result, &transaction]()\n            {\n                for (auto j = 0; j != ITERATIONS; ++j)\n                    result = TestType::eval(*item.get(), t, transaction);\n            });\n    }\n\n    UnitTestResult ret;\n\n    for (auto i = 0; i != threads.size(); ++i)\n    {\n        threads[i].join();\n        if (TestType::check(results[i], t))\n            ret = results[i];   // error value, keep iterating to join all threads\n        else if(i == 0)\n            ret = results[i];   // initial value\n    }\n\n    return ret; // cppcheck-suppress uninitvar ; false positive, ret assigned at least once in previous loop\n}\n\n\ntemplate<typename TestType>\nvoid perform_unit_test_helper(const ModSecurityTest<UnitTest> &test, UnitTest &t,\n    ModSecurityTestResults<UnitTest> &res, modsecurity::Transaction &transaction) {\n\n    if (!test.m_test_multithreaded)\n        t.result = perform_unit_test_once<TestType>(t, transaction);\n    else\n        t.result = perform_unit_test_multithreaded<TestType>(t, transaction);\n\n    if (TestType::check(t.result, t)) {\n        res.push_back(&t);\n        if (test.m_automake_output) {\n            std::cout << \"FAIL \";\n        }\n    } else if (test.m_automake_output) {\n        std::cout << \"PASS \";\n    }\n}\n\n\nvoid perform_unit_test(const ModSecurityTest<UnitTest> &test, UnitTest &t,\n    ModSecurityTestResults<UnitTest> &res) {\n    bool found = true;\n\n    modsecurity_test::ModSecurityTestContext context(\"ModSecurity-unit v0.0.1-alpha\"\n                                                        \" (ModSecurity unit test utility)\");\n\n    auto transaction = context.create_transaction();\n\n    if (test.m_automake_output) {\n        std::cout << \":test-result: \";\n    }\n\n    if (t.resource.empty() == false) {\n        found = std::find(resources.begin(), resources.end(), t.resource)\n            != resources.end();\n    }\n\n    if (!found) {\n        t.skipped = true;\n        res.push_back(&t);\n        if (test.m_automake_output) {\n            std::cout << \"SKIP \";\n        }\n    }\n\n    if (t.type == \"op\") {\n        perform_unit_test_helper<OperatorTest>(test, t, res, transaction);\n    } else if (t.type == \"tfn\") {\n        perform_unit_test_helper<TransformationTest>(test, t, res, transaction);\n    } else {\n        std::cerr << \"Failed. Test type is unknown: << \" << t.type;\n        std::cerr << std::endl;\n    }\n\n    if (test.m_automake_output) {\n        std::cout << t.name << \" \"\n            << modsecurity::utils::string::toHexIfNeeded(t.input)\n            << std::endl;\n    }\n}\n\n\nint main(int argc, char **argv) {\n    int total = 0;\n    ModSecurityTest<UnitTest> test;\n    ModSecurityTestResults<UnitTest> results;\n\n#if defined(WITH_GEOIP) or defined(WITH_MAXMIND)\n    resources.push_back(\"geoip-or-maxmind\");\n#endif\n\n#if defined(WITH_MAXMIND)\n    resources.push_back(\"maxmind\");\n#endif\n\n#if defined(WITH_GEOIP)\n    resources.push_back(\"geoip\");\n#endif\n\n#ifdef WITH_CURL\n    resources.push_back(\"curl\");\n#endif\n#ifdef WITH_SSDEEP\n    resources.push_back(\"ssdeep\");\n#endif\n\n\n    test.cmd_options(argc, argv);\n    if (!test.m_automake_output) {\n        std::cout << test.header();\n    }\n\n    test.load_tests();\n    if (test.target == default_test_path) {\n        test.load_tests(\"test-cases/secrules-language-tests/transformations\");\n    }\n\n    for (auto& [filename, tests] : test) {\n        total += tests.size();\n        for (auto &t : tests) {\n            ModSecurityTestResults<UnitTest> r;\n\n            if (!test.m_automake_output) {\n                std::cout << \"  \" << filename << \"...\\t\";\n            }\n            perform_unit_test(test, *t, r);\n\n            if (!test.m_automake_output) {\n                int skp = 0;\n                if (r.size() == 0) {\n                    std::cout << KGRN << \"0 tests failed.\";\n                } else {\n                    for (const auto &i : r) {\n                        if (i->skipped == true) {\n                            skp++;\n                        }\n                    }\n                    std::cout << KRED << r.size()-skp << \" tests failed.\";\n                }\n                std::cout << RESET;\n                if (skp > 0) {\n                    std::cout << \" \" << std::to_string(skp) << \" \";\n                    std::cout << \"skipped.\";\n                }\n                std::cout << std::endl;\n            }\n\n            results.insert(results.end(), r.begin(), r.end());\n        }\n    }\n\n    if (!test.m_automake_output) {\n        std::cout << \"Total >> \"  << total << std::endl;\n\n        for (const auto t : results) {\n            std::cout << t->print() << std::endl;\n        }\n    }\n\n    const int skp = std::count_if(results.cbegin(), results.cend(), [](const auto &i)\n                                    { return i->skipped; });\n    const int failed = results.size() - skp;\n\n    if (!test.m_automake_output) {\n        std::cout << std::endl;\n\n        std::cout << \"Ran a total of: \" << total << \" unit tests - \";\n        if (results.size() == 0) {\n            std::cout << KGRN << \"All tests passed\" << RESET << std::endl;\n        } else {\n            std::cout << KRED << failed << \" failed.\";\n            std::cout << RESET << std::endl;\n            if (skp > 0) {\n                std::cout << \" \" << std::to_string(skp) << \" \";\n                std::cout << \"skipped.\";\n            }\n        }\n    }\n\n    return failed;\n}\n"
  },
  {
    "path": "test/unit/unit_test.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include \"test/unit/unit_test.h\"\n\n#include <string.h>\n\n#include <sstream>\n#include <string>\n#include <iostream>\n#include <iterator>\n#include <memory>\n\n#include \"test/common/colors.h\"\n#include \"src/utils/regex.h\"\n#include \"src/utils/string.h\"\n\n\nnamespace modsecurity_test {\n\n\nvoid replaceAll(std::string *s, const std::string &search,\n    const char replace) {\n    for (size_t pos = 0; ; pos += 0) {\n        pos = s->find(search, pos);\n        if (pos == std::string::npos) {\n            break;\n        }\n        s->erase(pos, search.length());\n        s->insert(pos, &replace, 1);\n    }\n}\n\n\nvoid json2bin(std::string *str) {\n    modsecurity::Utils::Regex re(\"\\\\\\\\x([a-z0-9A-Z]{2})\");\n    modsecurity::Utils::Regex re2(\"\\\\\\\\u([a-z0-9A-Z]{4})\");\n    modsecurity::Utils::SMatch match;\n\n    while (modsecurity::Utils::regex_search(*str, &match, re)) {\n        unsigned int p;\n        std::string toBeReplaced = match.str();\n        toBeReplaced.erase(0, 2);\n        sscanf(toBeReplaced.c_str(), \"%3x\", &p);\n        replaceAll(str, match.str(), p);\n    }\n\n    while (modsecurity::Utils::regex_search(*str, &match, re2)) {\n        unsigned int p;\n        std::string toBeReplaced = match.str();\n        toBeReplaced.erase(0, 2);\n        sscanf(toBeReplaced.c_str(), \"%4x\", &p);\n        replaceAll(str, match.str(), p);\n    }\n\n    /*\n    replaceAll(str, \"\\\\0\", '\\0');\n    replaceAll(str, \"\\\\b\", '\\b');\n    replaceAll(str, \"\\\\t\", '\\t');\n    replaceAll(str, \"\\\\n\", '\\n');\n    replaceAll(str, \"\\\\r\", '\\r');\n    */\n//    replaceAll(str, \"\\\\f\", '\\f');\n}\n\n\nstd::string UnitTest::print() const {\n    std::stringstream i;\n\n    i << KRED << \"Test failed.\" << RESET;\n    i << \" From: \" << this->filename << std::endl;\n    i << \"{\" << std::endl;\n    i << \"  \\\"ret\\\": \\\"\" << this->ret << \"\\\"\" << std::endl;\n    i << \"  \\\"type\\\": \\\"\" << this->type << \"\\\"\" << std::endl;\n    i << \"  \\\"name\\\": \\\"\" << this->name << \"\\\"\" << std::endl;\n    i << \"  \\\"input\\\": \\\"\" << this->input << \"\\\"\" << std::endl;\n    i << \"  \\\"param\\\": \\\"\" << this->param << \"\\\"\" << std::endl;\n    i << \"  \\\"output\\\": \\\"\" << this->output << \"\\\"\" << std::endl;\n    i << \"}\" << std::endl;\n    if (this->ret != this->result.ret) {\n        i << \"Expecting: \\\"\" << this->ret << \"\\\" - returned: \\\"\";\n        i << this->result.ret << \"\\\"\" << std::endl;\n    }\n    if (this->output != this->result.output) {\n        i << \"Expecting: \\\"\";\n        i << modsecurity::utils::string::toHexIfNeeded(this->output);\n        i << \"\\\" - returned: \\\"\";\n        i << modsecurity::utils::string::toHexIfNeeded(this->result.output);\n        i << \"\\\"\";\n        i << std::endl;\n    }\n\n    return i.str();\n}\n\n\nstd::unique_ptr<UnitTest> UnitTest::from_yajl_node(const yajl_val &node) {\n    size_t num_tests = node->u.object.len;\n    auto u = std::make_unique<UnitTest>();\n\n    for (int i = 0; i < num_tests; i++) {\n        const char *key = node->u.object.keys[ i ];\n        yajl_val val = node->u.object.values[ i ];\n\n        u->skipped = false;\n        if (strcmp(key, \"param\") == 0) {\n           u->param = YAJL_GET_STRING(val);\n        } else if (strcmp(key, \"input\") == 0) {\n           u->input = YAJL_GET_STRING(val);\n           json2bin(&u->input);\n        } else if (strcmp(key, \"resource\") == 0) {\n           u->resource = YAJL_GET_STRING(val);\n        } else if (strcmp(key, \"name\") == 0) {\n           u->name = YAJL_GET_STRING(val);\n        } else if (strcmp(key, \"type\") == 0) {\n           u->type = YAJL_GET_STRING(val);\n        } else if (strcmp(key, \"ret\") == 0) {\n           u->ret = YAJL_GET_INTEGER(val);\n        } else if (strcmp(key, \"output\") == 0) {\n           u->output = std::string(YAJL_GET_STRING(val));\n           json2bin(&u->output);\n           /*\n            * Converting \\\\u0000 to \\0 due to the following gcc bug:\n            * https://gcc.gnu.org/bugzilla/show_bug.cgi?id=53690\n            *\n            */\n        }\n    }\n\n    return u;\n}\n\n}  // namespace modsecurity_test\n"
  },
  {
    "path": "test/unit/unit_test.h",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <yajl/yajl_tree.h>\n\n#include <iostream>\n#include <vector>\n#include <string>\n#include <memory>\n\n#ifndef TEST_UNIT_UNIT_TEST_H_\n#define TEST_UNIT_UNIT_TEST_H_\n\nnamespace modsecurity_test {\n\nclass UnitTestResult {\n public:\n    int ret;\n    std::string output;\n};\n\nclass UnitTest {\n public:\n    static std::unique_ptr<UnitTest> from_yajl_node(const yajl_val &);\n\n    std::string print() const;\n\n    std::string param;\n    std::string input;\n    std::string resource;\n    std::string name;\n    std::string type;\n    std::string filename;\n    std::string output;\n    int ret;\n    int skipped;\n    UnitTestResult result;\n};\n\n}  // namespace modsecurity_test\n\n#endif  // TEST_UNIT_UNIT_TEST_H_\n"
  },
  {
    "path": "test/unit-tests-valgrind.sh",
    "content": "#!/usr/bin/env bash\n\nvalgrind --tool=massif ./unit-tests $*\nvalgrind --leak-check=full --suppressions=./valgrind_suppressions.txt ./unit-tests $*\n"
  },
  {
    "path": "test/valgrind_suppressions.txt",
    "content": "{\n   <insert_a_suppression_name_here>\n   Memcheck:Cond\n   obj:*\n   obj:*\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Cond\n   obj:/usr/lib/libcurl.so.4.4.0\n   fun:curl_mvsnprintf\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   fun:curl_multi_perform\n   fun:curl_easy_perform\n   fun:_ZN11modsecurity5Utils11HttpsClient8downloadERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z5yylexRN11modsecurity6Parser6DriverE\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   fun:____strtol_l_internal\n   fun:_IO_vfscanf\n   fun:__isoc99_vsscanf\n   fun:__isoc99_sscanf\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   fun:curl_multi_perform\n   fun:curl_easy_perform\n   fun:_ZN11modsecurity5Utils11HttpsClient8downloadERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z5yylexRN11modsecurity6Parser6DriverE\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   fun:_IO_vfscanf\n   fun:__isoc99_vsscanf\n   fun:__isoc99_sscanf\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   fun:curl_multi_perform\n   fun:curl_easy_perform\n   fun:_ZN11modsecurity5Utils11HttpsClient8downloadERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z5yylexRN11modsecurity6Parser6DriverE\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   fun:bn_mul4x_mont\n   obj:*\n   obj:*\n   obj:*\n   obj:*\n   obj:*\n   obj:*\n   obj:*\n   obj:*\n   obj:*\n   obj:*\n   obj:*\n   obj:*\n   obj:*\n   obj:*\n   obj:*\n   obj:*\n   obj:*\n   obj:*\n   obj:*\n   obj:*\n   obj:*\n   obj:*\n   obj:*\n   obj:*\n   obj:*\n   obj:*\n   obj:*\n   obj:*\n   obj:*\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   fun:bn_mul4x_mont\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   fun:bn_mul4x_mont\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   fun:bn_mul4x_mont\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   fun:bn_mul4x_mont\n   obj:*\n   obj:*\n   obj:*\n   obj:*\n   obj:*\n   obj:*\n   obj:*\n   obj:*\n   obj:*\n   obj:*\n   obj:*\n   obj:*\n   obj:*\n   obj:*\n   obj:*\n   obj:*\n   obj:*\n   obj:*\n   obj:*\n   obj:*\n   obj:*\n   obj:*\n   obj:*\n   obj:*\n   obj:*\n   obj:*\n   obj:*\n   obj:*\n   obj:*\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   fun:BN_from_montgomery_word\n   fun:BN_from_montgomery\n   fun:BN_mod_exp_mont\n   fun:RSA_eay_public_encrypt\n   fun:ssl3_send_client_key_exchange\n   fun:ssl3_connect\n   fun:ssl23_connect\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   fun:curl_multi_perform\n   fun:curl_easy_perform\n   fun:_ZN11modsecurity5Utils11HttpsClient8downloadERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z5yylexRN11modsecurity6Parser6DriverE\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   fun:BN_from_montgomery_word\n   fun:BN_from_montgomery\n   fun:BN_mod_exp_mont\n   fun:RSA_eay_public_encrypt\n   fun:ssl3_send_client_key_exchange\n   fun:ssl3_connect\n   fun:ssl23_connect\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   fun:curl_multi_perform\n   fun:curl_easy_perform\n   fun:_ZN11modsecurity5Utils11HttpsClient8downloadERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z5yylexRN11modsecurity6Parser6DriverE\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   fun:BN_from_montgomery_word\n   fun:BN_from_montgomery\n   fun:BN_mod_exp_mont\n   fun:RSA_eay_public_encrypt\n   fun:ssl3_send_client_key_exchange\n   fun:ssl3_connect\n   fun:ssl23_connect\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   fun:curl_multi_perform\n   fun:curl_easy_perform\n   fun:_ZN11modsecurity5Utils11HttpsClient8downloadERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z5yylexRN11modsecurity6Parser6DriverE\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   fun:BN_num_bits_word\n   fun:BN_num_bits\n   fun:RSA_eay_public_encrypt\n   fun:ssl3_send_client_key_exchange\n   fun:ssl3_connect\n   fun:ssl23_connect\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   fun:curl_multi_perform\n   fun:curl_easy_perform\n   fun:_ZN11modsecurity5Utils11HttpsClient8downloadERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z5yylexRN11modsecurity6Parser6DriverE\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   fun:BN_num_bits_word\n   fun:BN_num_bits\n   fun:BN_bn2bin\n   fun:RSA_eay_public_encrypt\n   fun:ssl3_send_client_key_exchange\n   fun:ssl3_connect\n   fun:ssl23_connect\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   fun:curl_multi_perform\n   fun:curl_easy_perform\n   fun:_ZN11modsecurity5Utils11HttpsClient8downloadERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z5yylexRN11modsecurity6Parser6DriverE\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Param\n   write(buf)\n   obj:/usr/lib/libc-2.24.so\n   fun:sock_write\n   fun:BIO_write\n   fun:buffer_ctrl\n   fun:ssl3_connect\n   fun:ssl23_connect\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   fun:curl_multi_perform\n   fun:curl_easy_perform\n   fun:_ZN11modsecurity5Utils11HttpsClient8downloadERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z5yylexRN11modsecurity6Parser6DriverE\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   fun:aesni_cbc_hmac_sha1_cipher\n   fun:tls1_enc\n   fun:ssl3_read_bytes\n   fun:ssl3_get_message\n   fun:ssl3_get_finished\n   fun:ssl3_connect\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   fun:curl_multi_perform\n   fun:curl_easy_perform\n   fun:_ZN11modsecurity5Utils11HttpsClient8downloadERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z5yylexRN11modsecurity6Parser6DriverE\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   fun:aesni_cbc_hmac_sha1_cipher\n   fun:tls1_enc\n   fun:ssl3_read_bytes\n   fun:ssl3_get_message\n   fun:ssl3_get_finished\n   fun:ssl3_connect\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   fun:curl_multi_perform\n   fun:curl_easy_perform\n   fun:_ZN11modsecurity5Utils11HttpsClient8downloadERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z5yylexRN11modsecurity6Parser6DriverE\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   fun:memset\n   fun:BUF_MEM_grow_clean\n   fun:ssl3_get_message\n   fun:ssl3_get_finished\n   fun:ssl3_connect\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   fun:curl_multi_perform\n   fun:curl_easy_perform\n   fun:_ZN11modsecurity5Utils11HttpsClient8downloadERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z5yylexRN11modsecurity6Parser6DriverE\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   fun:memset\n   fun:BUF_MEM_grow_clean\n   fun:ssl3_get_message\n   fun:ssl3_get_finished\n   fun:ssl3_connect\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   fun:curl_multi_perform\n   fun:curl_easy_perform\n   fun:_ZN11modsecurity5Utils11HttpsClient8downloadERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z5yylexRN11modsecurity6Parser6DriverE\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   fun:memmove\n   fun:ssl3_read_bytes\n   fun:ssl3_get_message\n   fun:ssl3_get_finished\n   fun:ssl3_connect\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   fun:curl_multi_perform\n   fun:curl_easy_perform\n   fun:_ZN11modsecurity5Utils11HttpsClient8downloadERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z5yylexRN11modsecurity6Parser6DriverE\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Param\n   write(buf)\n   obj:/usr/lib/libc-2.24.so\n   fun:sock_write\n   fun:BIO_write\n   fun:ssl3_write_pending\n   fun:ssl3_write_bytes\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   fun:curl_multi_perform\n   fun:curl_easy_perform\n   fun:_ZN11modsecurity5Utils11HttpsClient8downloadERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z5yylexRN11modsecurity6Parser6DriverE\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   fun:aesni_cbc_hmac_sha1_cipher\n   fun:tls1_enc\n   fun:ssl3_read_bytes\n   fun:ssl3_read\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   fun:curl_multi_perform\n   fun:curl_easy_perform\n   fun:_ZN11modsecurity5Utils11HttpsClient8downloadERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z5yylexRN11modsecurity6Parser6DriverE\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   fun:aesni_cbc_hmac_sha1_cipher\n   fun:tls1_enc\n   fun:ssl3_read_bytes\n   fun:ssl3_read\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   fun:curl_multi_perform\n   fun:curl_easy_perform\n   fun:_ZN11modsecurity5Utils11HttpsClient8downloadERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z5yylexRN11modsecurity6Parser6DriverE\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   fun:curl_multi_perform\n   fun:curl_easy_perform\n   fun:_ZN11modsecurity5Utils11HttpsClient8downloadERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z5yylexRN11modsecurity6Parser6DriverE\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   fun:BN_from_montgomery_word\n   fun:BN_from_montgomery\n   fun:BN_mod_exp_mont\n   fun:RSA_eay_public_encrypt\n   fun:ssl3_send_client_key_exchange\n   fun:ssl3_connect\n   fun:ssl23_connect\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   fun:curl_multi_perform\n   fun:curl_easy_perform\n   fun:_ZN11modsecurity5Utils11HttpsClient8downloadERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_ZN11modsecurity5Utils6IpTree10addFromUrlERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPS7_\n   fun:_ZN11modsecurity9operators15IpMatchFromFile4initERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPS7_\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   fun:BN_from_montgomery_word\n   fun:BN_from_montgomery\n   fun:BN_mod_exp_mont\n   fun:RSA_eay_public_encrypt\n   fun:ssl3_send_client_key_exchange\n   fun:ssl3_connect\n   fun:ssl23_connect\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   fun:curl_multi_perform\n   fun:curl_easy_perform\n   fun:_ZN11modsecurity5Utils11HttpsClient8downloadERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_ZN11modsecurity5Utils6IpTree10addFromUrlERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPS7_\n   fun:_ZN11modsecurity9operators15IpMatchFromFile4initERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPS7_\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   fun:BN_from_montgomery_word\n   fun:BN_from_montgomery\n   fun:BN_mod_exp_mont\n   fun:RSA_eay_public_encrypt\n   fun:ssl3_send_client_key_exchange\n   fun:ssl3_connect\n   fun:ssl23_connect\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   fun:curl_multi_perform\n   fun:curl_easy_perform\n   fun:_ZN11modsecurity5Utils11HttpsClient8downloadERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_ZN11modsecurity5Utils6IpTree10addFromUrlERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPS7_\n   fun:_ZN11modsecurity9operators15IpMatchFromFile4initERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPS7_\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   fun:BN_num_bits_word\n   fun:BN_num_bits\n   fun:RSA_eay_public_encrypt\n   fun:ssl3_send_client_key_exchange\n   fun:ssl3_connect\n   fun:ssl23_connect\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   fun:curl_multi_perform\n   fun:curl_easy_perform\n   fun:_ZN11modsecurity5Utils11HttpsClient8downloadERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_ZN11modsecurity5Utils6IpTree10addFromUrlERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPS7_\n   fun:_ZN11modsecurity9operators15IpMatchFromFile4initERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPS7_\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   fun:BN_num_bits_word\n   fun:BN_num_bits\n   fun:BN_bn2bin\n   fun:RSA_eay_public_encrypt\n   fun:ssl3_send_client_key_exchange\n   fun:ssl3_connect\n   fun:ssl23_connect\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   fun:curl_multi_perform\n   fun:curl_easy_perform\n   fun:_ZN11modsecurity5Utils11HttpsClient8downloadERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_ZN11modsecurity5Utils6IpTree10addFromUrlERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPS7_\n   fun:_ZN11modsecurity9operators15IpMatchFromFile4initERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPS7_\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Param\n   write(buf)\n   obj:/usr/lib/libc-2.24.so\n   fun:sock_write\n   fun:BIO_write\n   fun:buffer_ctrl\n   fun:ssl3_connect\n   fun:ssl23_connect\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   fun:curl_multi_perform\n   fun:curl_easy_perform\n   fun:_ZN11modsecurity5Utils11HttpsClient8downloadERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_ZN11modsecurity5Utils6IpTree10addFromUrlERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPS7_\n   fun:_ZN11modsecurity9operators15IpMatchFromFile4initERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPS7_\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   fun:aesni_cbc_hmac_sha1_cipher\n   fun:tls1_enc\n   fun:ssl3_read_bytes\n   fun:ssl3_get_message\n   fun:ssl3_get_finished\n   fun:ssl3_connect\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   fun:curl_multi_perform\n   fun:curl_easy_perform\n   fun:_ZN11modsecurity5Utils11HttpsClient8downloadERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_ZN11modsecurity5Utils6IpTree10addFromUrlERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPS7_\n   fun:_ZN11modsecurity9operators15IpMatchFromFile4initERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPS7_\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   fun:aesni_cbc_hmac_sha1_cipher\n   fun:tls1_enc\n   fun:ssl3_read_bytes\n   fun:ssl3_get_message\n   fun:ssl3_get_finished\n   fun:ssl3_connect\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   fun:curl_multi_perform\n   fun:curl_easy_perform\n   fun:_ZN11modsecurity5Utils11HttpsClient8downloadERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_ZN11modsecurity5Utils6IpTree10addFromUrlERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPS7_\n   fun:_ZN11modsecurity9operators15IpMatchFromFile4initERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPS7_\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   fun:memset\n   fun:BUF_MEM_grow_clean\n   fun:ssl3_get_message\n   fun:ssl3_get_finished\n   fun:ssl3_connect\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   fun:curl_multi_perform\n   fun:curl_easy_perform\n   fun:_ZN11modsecurity5Utils11HttpsClient8downloadERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_ZN11modsecurity5Utils6IpTree10addFromUrlERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPS7_\n   fun:_ZN11modsecurity9operators15IpMatchFromFile4initERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPS7_\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   fun:memset\n   fun:BUF_MEM_grow_clean\n   fun:ssl3_get_message\n   fun:ssl3_get_finished\n   fun:ssl3_connect\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   fun:curl_multi_perform\n   fun:curl_easy_perform\n   fun:_ZN11modsecurity5Utils11HttpsClient8downloadERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_ZN11modsecurity5Utils6IpTree10addFromUrlERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPS7_\n   fun:_ZN11modsecurity9operators15IpMatchFromFile4initERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPS7_\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   fun:memmove\n   fun:ssl3_read_bytes\n   fun:ssl3_get_message\n   fun:ssl3_get_finished\n   fun:ssl3_connect\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   fun:curl_multi_perform\n   fun:curl_easy_perform\n   fun:_ZN11modsecurity5Utils11HttpsClient8downloadERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_ZN11modsecurity5Utils6IpTree10addFromUrlERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPS7_\n   fun:_ZN11modsecurity9operators15IpMatchFromFile4initERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPS7_\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Param\n   write(buf)\n   obj:/usr/lib/libc-2.24.so\n   fun:sock_write\n   fun:BIO_write\n   fun:ssl3_write_pending\n   fun:ssl3_write_bytes\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   fun:curl_multi_perform\n   fun:curl_easy_perform\n   fun:_ZN11modsecurity5Utils11HttpsClient8downloadERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_ZN11modsecurity5Utils6IpTree10addFromUrlERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPS7_\n   fun:_ZN11modsecurity9operators15IpMatchFromFile4initERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPS7_\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   fun:aesni_cbc_hmac_sha1_cipher\n   fun:tls1_enc\n   fun:ssl3_read_bytes\n   fun:ssl3_read\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   fun:curl_multi_perform\n   fun:curl_easy_perform\n   fun:_ZN11modsecurity5Utils11HttpsClient8downloadERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_ZN11modsecurity5Utils6IpTree10addFromUrlERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPS7_\n   fun:_ZN11modsecurity9operators15IpMatchFromFile4initERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPS7_\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   fun:aesni_cbc_hmac_sha1_cipher\n   fun:tls1_enc\n   fun:ssl3_read_bytes\n   fun:ssl3_read\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   fun:curl_multi_perform\n   fun:curl_easy_perform\n   fun:_ZN11modsecurity5Utils11HttpsClient8downloadERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_ZN11modsecurity5Utils6IpTree10addFromUrlERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPS7_\n   fun:_ZN11modsecurity9operators15IpMatchFromFile4initERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPS7_\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   fun:memmove\n   fun:ssl3_read_bytes\n   fun:ssl3_read\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   fun:curl_multi_perform\n   fun:curl_easy_perform\n   fun:_ZN11modsecurity5Utils11HttpsClient8downloadERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_ZN11modsecurity5Utils6IpTree10addFromUrlERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPS7_\n   fun:_ZN11modsecurity9operators15IpMatchFromFile4initERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPS7_\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   fun:memmove\n   fun:ssl3_read_bytes\n   fun:ssl3_read\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   fun:curl_multi_perform\n   fun:curl_easy_perform\n   fun:_ZN11modsecurity5Utils11HttpsClient8downloadERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_ZN11modsecurity5Utils6IpTree10addFromUrlERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPS7_\n   fun:_ZN11modsecurity9operators15IpMatchFromFile4initERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPS7_\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   fun:curl_multi_perform\n   fun:curl_easy_perform\n   fun:_ZN11modsecurity5Utils11HttpsClient8downloadERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_ZN11modsecurity5Utils6IpTree10addFromUrlERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPS7_\n   fun:_ZN11modsecurity9operators15IpMatchFromFile4initERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPS7_\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   fun:_IO_vfscanf\n   fun:__isoc99_vsscanf\n   fun:__isoc99_sscanf\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   fun:curl_multi_perform\n   fun:curl_easy_perform\n   fun:_ZN11modsecurity5Utils11HttpsClient8downloadERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_ZN11modsecurity5Utils6IpTree10addFromUrlERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPS7_\n   fun:_ZN11modsecurity9operators15IpMatchFromFile4initERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPS7_\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   fun:_IO_vfscanf\n   fun:__isoc99_vsscanf\n   fun:__isoc99_sscanf\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   fun:curl_multi_perform\n   fun:curl_easy_perform\n   fun:_ZN11modsecurity5Utils11HttpsClient8downloadERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_ZN11modsecurity5Utils6IpTree10addFromUrlERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPS7_\n   fun:_ZN11modsecurity9operators15IpMatchFromFile4initERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPS7_\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   fun:____strtol_l_internal\n   fun:_IO_vfscanf\n   fun:__isoc99_vsscanf\n   fun:__isoc99_sscanf\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   fun:curl_multi_perform\n   fun:curl_easy_perform\n   fun:_ZN11modsecurity5Utils11HttpsClient8downloadERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_ZN11modsecurity5Utils6IpTree10addFromUrlERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPS7_\n   fun:_ZN11modsecurity9operators15IpMatchFromFile4initERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPS7_\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   fun:____strtol_l_internal\n   fun:_IO_vfscanf\n   fun:__isoc99_vsscanf\n   fun:__isoc99_sscanf\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   fun:curl_multi_perform\n   fun:curl_easy_perform\n   fun:_ZN11modsecurity5Utils11HttpsClient8downloadERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_ZN11modsecurity5Utils6IpTree10addFromUrlERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPS7_\n   fun:_ZN11modsecurity9operators15IpMatchFromFile4initERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPS7_\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   fun:____strtol_l_internal\n   fun:_IO_vfscanf\n   fun:__isoc99_vsscanf\n   fun:__isoc99_sscanf\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   fun:curl_multi_perform\n   fun:curl_easy_perform\n   fun:_ZN11modsecurity5Utils11HttpsClient8downloadERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_ZN11modsecurity5Utils6IpTree10addFromUrlERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPS7_\n   fun:_ZN11modsecurity9operators15IpMatchFromFile4initERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPS7_\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   fun:curl_multi_perform\n   fun:curl_easy_perform\n   fun:_ZN11modsecurity5Utils11HttpsClient8downloadERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_ZN11modsecurity5Utils6IpTree10addFromUrlERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPS7_\n   fun:_ZN11modsecurity9operators15IpMatchFromFile4initERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPS7_\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   fun:curl_multi_perform\n   fun:curl_easy_perform\n   fun:_ZN11modsecurity5Utils11HttpsClient8downloadERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_ZN11modsecurity5Utils6IpTree10addFromUrlERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPS7_\n   fun:_ZN11modsecurity9operators15IpMatchFromFile4initERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPS7_\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   fun:curl_multi_perform\n   fun:curl_easy_perform\n   fun:_ZN11modsecurity5Utils11HttpsClient8downloadERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_ZN11modsecurity5Utils6IpTree10addFromUrlERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPS7_\n   fun:_ZN11modsecurity9operators15IpMatchFromFile4initERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPS7_\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   fun:__GI_strchr\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   fun:curl_multi_perform\n   fun:curl_easy_perform\n   fun:_ZN11modsecurity5Utils11HttpsClient8downloadERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_ZN11modsecurity5Utils6IpTree10addFromUrlERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPS7_\n   fun:_ZN11modsecurity9operators15IpMatchFromFile4initERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPS7_\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   fun:__GI_strchr\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   fun:curl_multi_perform\n   fun:curl_easy_perform\n   fun:_ZN11modsecurity5Utils11HttpsClient8downloadERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_ZN11modsecurity5Utils6IpTree10addFromUrlERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPS7_\n   fun:_ZN11modsecurity9operators15IpMatchFromFile4initERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPS7_\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   fun:curl_multi_perform\n   fun:curl_easy_perform\n   fun:_ZN11modsecurity5Utils11HttpsClient8downloadERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_ZN11modsecurity5Utils6IpTree10addFromUrlERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPS7_\n   fun:_ZN11modsecurity9operators15IpMatchFromFile4initERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPS7_\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   fun:curl_multi_perform\n   fun:curl_easy_perform\n   fun:_ZN11modsecurity5Utils11HttpsClient8downloadERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_ZN11modsecurity5Utils6IpTree10addFromUrlERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPS7_\n   fun:_ZN11modsecurity9operators15IpMatchFromFile4initERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPS7_\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   fun:memmove\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   fun:curl_multi_perform\n   fun:curl_easy_perform\n   fun:_ZN11modsecurity5Utils11HttpsClient8downloadERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_ZN11modsecurity5Utils6IpTree10addFromUrlERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPS7_\n   fun:_ZN11modsecurity9operators15IpMatchFromFile4initERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPS7_\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   fun:memmove\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   fun:curl_multi_perform\n   fun:curl_easy_perform\n   fun:_ZN11modsecurity5Utils11HttpsClient8downloadERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_ZN11modsecurity5Utils6IpTree10addFromUrlERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPS7_\n   fun:_ZN11modsecurity9operators15IpMatchFromFile4initERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPS7_\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   fun:memmove\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   fun:curl_multi_perform\n   fun:curl_easy_perform\n   fun:_ZN11modsecurity5Utils11HttpsClient8downloadERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_ZN11modsecurity5Utils6IpTree10addFromUrlERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPS7_\n   fun:_ZN11modsecurity9operators15IpMatchFromFile4initERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPS7_\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   fun:memmove\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   fun:curl_multi_perform\n   fun:curl_easy_perform\n   fun:_ZN11modsecurity5Utils11HttpsClient8downloadERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_ZN11modsecurity5Utils6IpTree10addFromUrlERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPS7_\n   fun:_ZN11modsecurity9operators15IpMatchFromFile4initERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPS7_\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   fun:curl_multi_perform\n   fun:curl_easy_perform\n   fun:_ZN11modsecurity5Utils11HttpsClient8downloadERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_ZN11modsecurity5Utils6IpTree10addFromUrlERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPS7_\n   fun:_ZN11modsecurity9operators15IpMatchFromFile4initERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPS7_\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   fun:____strtol_l_internal\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   fun:curl_multi_perform\n   fun:curl_easy_perform\n   fun:_ZN11modsecurity5Utils11HttpsClient8downloadERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_ZN11modsecurity5Utils6IpTree10addFromUrlERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPS7_\n   fun:_ZN11modsecurity9operators15IpMatchFromFile4initERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPS7_\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   fun:____strtol_l_internal\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   fun:curl_multi_perform\n   fun:curl_easy_perform\n   fun:_ZN11modsecurity5Utils11HttpsClient8downloadERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_ZN11modsecurity5Utils6IpTree10addFromUrlERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPS7_\n   fun:_ZN11modsecurity9operators15IpMatchFromFile4initERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPS7_\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   fun:____strtol_l_internal\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   fun:curl_multi_perform\n   fun:curl_easy_perform\n   fun:_ZN11modsecurity5Utils11HttpsClient8downloadERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_ZN11modsecurity5Utils6IpTree10addFromUrlERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPS7_\n   fun:_ZN11modsecurity9operators15IpMatchFromFile4initERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPS7_\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   fun:____strtol_l_internal\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   fun:curl_multi_perform\n   fun:curl_easy_perform\n   fun:_ZN11modsecurity5Utils11HttpsClient8downloadERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_ZN11modsecurity5Utils6IpTree10addFromUrlERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPS7_\n   fun:_ZN11modsecurity9operators15IpMatchFromFile4initERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPS7_\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   fun:____strtol_l_internal\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   fun:curl_multi_perform\n   fun:curl_easy_perform\n   fun:_ZN11modsecurity5Utils11HttpsClient8downloadERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_ZN11modsecurity5Utils6IpTree10addFromUrlERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPS7_\n   fun:_ZN11modsecurity9operators15IpMatchFromFile4initERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPS7_\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   fun:curl_multi_perform\n   fun:curl_easy_perform\n   fun:_ZN11modsecurity5Utils11HttpsClient8downloadERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_ZN11modsecurity5Utils6IpTree10addFromUrlERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPS7_\n   fun:_ZN11modsecurity9operators15IpMatchFromFile4initERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPS7_\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   fun:curl_multi_perform\n   fun:curl_easy_perform\n   fun:_ZN11modsecurity5Utils11HttpsClient8downloadERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_ZN11modsecurity5Utils6IpTree10addFromUrlERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPS7_\n   fun:_ZN11modsecurity9operators15IpMatchFromFile4initERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPS7_\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   fun:curl_multi_perform\n   fun:curl_easy_perform\n   fun:_ZN11modsecurity5Utils11HttpsClient8downloadERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_ZN11modsecurity5Utils6IpTree10addFromUrlERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPS7_\n   fun:_ZN11modsecurity9operators15IpMatchFromFile4initERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPS7_\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   fun:curl_multi_perform\n   fun:curl_easy_perform\n   fun:_ZN11modsecurity5Utils11HttpsClient8downloadERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_ZN11modsecurity5Utils6IpTree10addFromUrlERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPS7_\n   fun:_ZN11modsecurity9operators15IpMatchFromFile4initERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPS7_\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   fun:__GI_strchr\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   fun:curl_multi_perform\n   fun:curl_easy_perform\n   fun:_ZN11modsecurity5Utils11HttpsClient8downloadERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_ZN11modsecurity5Utils6IpTree10addFromUrlERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPS7_\n   fun:_ZN11modsecurity9operators15IpMatchFromFile4initERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPS7_\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   fun:__GI_strchr\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   fun:curl_multi_perform\n   fun:curl_easy_perform\n   fun:_ZN11modsecurity5Utils11HttpsClient8downloadERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_ZN11modsecurity5Utils6IpTree10addFromUrlERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPS7_\n   fun:_ZN11modsecurity9operators15IpMatchFromFile4initERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPS7_\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   fun:curl_multi_perform\n   fun:curl_easy_perform\n   fun:_ZN11modsecurity5Utils11HttpsClient8downloadERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_ZN11modsecurity5Utils6IpTree10addFromUrlERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPS7_\n   fun:_ZN11modsecurity9operators15IpMatchFromFile4initERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPS7_\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   fun:curl_multi_perform\n   fun:curl_easy_perform\n   fun:_ZN11modsecurity5Utils11HttpsClient8downloadERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_ZN11modsecurity5Utils6IpTree10addFromUrlERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPS7_\n   fun:_ZN11modsecurity9operators15IpMatchFromFile4initERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPS7_\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   fun:memmove\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   fun:curl_multi_perform\n   fun:curl_easy_perform\n   fun:_ZN11modsecurity5Utils11HttpsClient8downloadERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_ZN11modsecurity5Utils6IpTree10addFromUrlERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPS7_\n   fun:_ZN11modsecurity9operators15IpMatchFromFile4initERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPS7_\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   fun:memmove\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   fun:curl_multi_perform\n   fun:curl_easy_perform\n   fun:_ZN11modsecurity5Utils11HttpsClient8downloadERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_ZN11modsecurity5Utils6IpTree10addFromUrlERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPS7_\n   fun:_ZN11modsecurity9operators15IpMatchFromFile4initERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPS7_\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   fun:curl_multi_perform\n   fun:curl_easy_perform\n   fun:_ZN11modsecurity5Utils11HttpsClient8downloadERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_ZN11modsecurity5Utils6IpTree10addFromUrlERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPS7_\n   fun:_ZN11modsecurity9operators15IpMatchFromFile4initERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPS7_\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   fun:memmove\n   fun:copy\n   fun:_S_copy\n   fun:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE9_M_mutateEmmPKcm\n   fun:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE9_M_appendEPKcm\n   fun:append\n   fun:_ZN11modsecurity5Utils11HttpsClient11handle_implEPcmm\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   fun:curl_multi_perform\n   fun:curl_easy_perform\n   fun:_ZN11modsecurity5Utils11HttpsClient8downloadERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_ZN11modsecurity5Utils6IpTree10addFromUrlERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPS7_\n   fun:_ZN11modsecurity9operators15IpMatchFromFile4initERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPS7_\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   fun:memmove\n   fun:copy\n   fun:_S_copy\n   fun:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE9_M_mutateEmmPKcm\n   fun:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE9_M_appendEPKcm\n   fun:append\n   fun:_ZN11modsecurity5Utils11HttpsClient11handle_implEPcmm\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   fun:curl_multi_perform\n   fun:curl_easy_perform\n   fun:_ZN11modsecurity5Utils11HttpsClient8downloadERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_ZN11modsecurity5Utils6IpTree10addFromUrlERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPS7_\n   fun:_ZN11modsecurity9operators15IpMatchFromFile4initERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPS7_\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   fun:assign\n   fun:_M_set_length\n   fun:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE9_M_appendEPKcm\n   fun:append\n   fun:_ZN11modsecurity5Utils11HttpsClient11handle_implEPcmm\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   fun:curl_multi_perform\n   fun:curl_easy_perform\n   fun:_ZN11modsecurity5Utils11HttpsClient8downloadERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_ZN11modsecurity5Utils6IpTree10addFromUrlERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPS7_\n   fun:_ZN11modsecurity9operators15IpMatchFromFile4initERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPS7_\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   fun:memmove\n   fun:copy\n   fun:_ZNSt15basic_streambufIcSt11char_traitsIcEE6xsputnEPKcl\n   fun:sputn\n   fun:__ostream_write<char, std::char_traits<char> >\n   fun:_ZSt16__ostream_insertIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_PKS3_l\n   fun:operator<< <char, std::char_traits<char>, std::allocator<char> >\n   fun:_ZN11modsecurity5Utils6IpTree13addFromBufferERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPS7_\n   fun:_ZN11modsecurity5Utils6IpTree10addFromUrlERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPS7_\n   fun:_ZN11modsecurity9operators15IpMatchFromFile4initERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPS7_\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   fun:memmove\n   fun:copy\n   fun:_ZNSt15basic_streambufIcSt11char_traitsIcEE6xsputnEPKcl\n   fun:sputn\n   fun:__ostream_write<char, std::char_traits<char> >\n   fun:_ZSt16__ostream_insertIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_PKS3_l\n   fun:operator<< <char, std::char_traits<char>, std::allocator<char> >\n   fun:_ZN11modsecurity5Utils6IpTree13addFromBufferERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPS7_\n   fun:_ZN11modsecurity5Utils6IpTree10addFromUrlERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPS7_\n   fun:_ZN11modsecurity9operators15IpMatchFromFile4initERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPS7_\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   fun:strtok_r\n   fun:add_ip_from_param\n   fun:_ZN11modsecurity5Utils6IpTree13addFromBufferEPSiPNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_ZN11modsecurity5Utils6IpTree13addFromBufferERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPS7_\n   fun:_ZN11modsecurity5Utils6IpTree10addFromUrlERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPS7_\n   fun:_ZN11modsecurity9operators15IpMatchFromFile4initERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPS7_\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   fun:strtok_r\n   fun:add_ip_from_param\n   fun:_ZN11modsecurity5Utils6IpTree13addFromBufferEPSiPNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_ZN11modsecurity5Utils6IpTree13addFromBufferERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPS7_\n   fun:_ZN11modsecurity5Utils6IpTree10addFromUrlERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPS7_\n   fun:_ZN11modsecurity9operators15IpMatchFromFile4initERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPS7_\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   fun:strtok_r\n   fun:add_ip_from_param\n   fun:_ZN11modsecurity5Utils6IpTree13addFromBufferEPSiPNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_ZN11modsecurity5Utils6IpTree13addFromBufferERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPS7_\n   fun:_ZN11modsecurity5Utils6IpTree10addFromUrlERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPS7_\n   fun:_ZN11modsecurity9operators15IpMatchFromFile4initERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPS7_\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   fun:strtok_r\n   fun:add_ip_from_param\n   fun:_ZN11modsecurity5Utils6IpTree13addFromBufferEPSiPNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_ZN11modsecurity5Utils6IpTree13addFromBufferERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPS7_\n   fun:_ZN11modsecurity5Utils6IpTree10addFromUrlERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPS7_\n   fun:_ZN11modsecurity9operators15IpMatchFromFile4initERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPS7_\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   fun:strtok_r\n   fun:add_ip_from_param\n   fun:_ZN11modsecurity5Utils6IpTree13addFromBufferEPSiPNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_ZN11modsecurity5Utils6IpTree13addFromBufferERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPS7_\n   fun:_ZN11modsecurity5Utils6IpTree10addFromUrlERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPS7_\n   fun:_ZN11modsecurity9operators15IpMatchFromFile4initERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPS7_\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   fun:memmove\n   fun:ssl3_read_bytes\n   fun:ssl3_read\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   fun:curl_multi_perform\n   fun:curl_easy_perform\n   fun:_ZN11modsecurity5Utils11HttpsClient8downloadERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z5yylexRN11modsecurity6Parser6DriverE\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   fun:memmove\n   fun:ssl3_read_bytes\n   fun:ssl3_read\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   fun:curl_multi_perform\n   fun:curl_easy_perform\n   fun:_ZN11modsecurity5Utils11HttpsClient8downloadERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z5yylexRN11modsecurity6Parser6DriverE\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   fun:memmove\n   fun:ssl3_read_bytes\n   fun:ssl3_read\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   fun:curl_multi_perform\n   fun:curl_easy_perform\n   fun:_ZN11modsecurity5Utils11HttpsClient8downloadERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z5yylexRN11modsecurity6Parser6DriverE\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   fun:memmove\n   fun:ssl3_read_bytes\n   fun:ssl3_read\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   fun:curl_multi_perform\n   fun:curl_easy_perform\n   fun:_ZN11modsecurity5Utils11HttpsClient8downloadERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z5yylexRN11modsecurity6Parser6DriverE\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   fun:curl_multi_perform\n   fun:curl_easy_perform\n   fun:_ZN11modsecurity5Utils11HttpsClient8downloadERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z5yylexRN11modsecurity6Parser6DriverE\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   fun:curl_multi_perform\n   fun:curl_easy_perform\n   fun:_ZN11modsecurity5Utils11HttpsClient8downloadERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z5yylexRN11modsecurity6Parser6DriverE\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   fun:curl_multi_perform\n   fun:curl_easy_perform\n   fun:_ZN11modsecurity5Utils11HttpsClient8downloadERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z5yylexRN11modsecurity6Parser6DriverE\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   fun:__GI_strchr\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   fun:curl_multi_perform\n   fun:curl_easy_perform\n   fun:_ZN11modsecurity5Utils11HttpsClient8downloadERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z5yylexRN11modsecurity6Parser6DriverE\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   fun:__GI_strchr\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   fun:curl_multi_perform\n   fun:curl_easy_perform\n   fun:_ZN11modsecurity5Utils11HttpsClient8downloadERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z5yylexRN11modsecurity6Parser6DriverE\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   fun:curl_multi_perform\n   fun:curl_easy_perform\n   fun:_ZN11modsecurity5Utils11HttpsClient8downloadERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z5yylexRN11modsecurity6Parser6DriverE\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   fun:curl_multi_perform\n   fun:curl_easy_perform\n   fun:_ZN11modsecurity5Utils11HttpsClient8downloadERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z5yylexRN11modsecurity6Parser6DriverE\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   fun:memmove\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   fun:curl_multi_perform\n   fun:curl_easy_perform\n   fun:_ZN11modsecurity5Utils11HttpsClient8downloadERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z5yylexRN11modsecurity6Parser6DriverE\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   fun:memmove\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   fun:curl_multi_perform\n   fun:curl_easy_perform\n   fun:_ZN11modsecurity5Utils11HttpsClient8downloadERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z5yylexRN11modsecurity6Parser6DriverE\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   fun:memmove\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   fun:curl_multi_perform\n   fun:curl_easy_perform\n   fun:_ZN11modsecurity5Utils11HttpsClient8downloadERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z5yylexRN11modsecurity6Parser6DriverE\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   fun:memmove\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   fun:curl_multi_perform\n   fun:curl_easy_perform\n   fun:_ZN11modsecurity5Utils11HttpsClient8downloadERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z5yylexRN11modsecurity6Parser6DriverE\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   fun:curl_multi_perform\n   fun:curl_easy_perform\n   fun:_ZN11modsecurity5Utils11HttpsClient8downloadERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z5yylexRN11modsecurity6Parser6DriverE\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   fun:____strtol_l_internal\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   fun:curl_multi_perform\n   fun:curl_easy_perform\n   fun:_ZN11modsecurity5Utils11HttpsClient8downloadERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z5yylexRN11modsecurity6Parser6DriverE\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   fun:____strtol_l_internal\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   fun:curl_multi_perform\n   fun:curl_easy_perform\n   fun:_ZN11modsecurity5Utils11HttpsClient8downloadERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z5yylexRN11modsecurity6Parser6DriverE\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   fun:____strtol_l_internal\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   fun:curl_multi_perform\n   fun:curl_easy_perform\n   fun:_ZN11modsecurity5Utils11HttpsClient8downloadERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z5yylexRN11modsecurity6Parser6DriverE\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   fun:____strtol_l_internal\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   fun:curl_multi_perform\n   fun:curl_easy_perform\n   fun:_ZN11modsecurity5Utils11HttpsClient8downloadERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z5yylexRN11modsecurity6Parser6DriverE\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   fun:____strtol_l_internal\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   fun:curl_multi_perform\n   fun:curl_easy_perform\n   fun:_ZN11modsecurity5Utils11HttpsClient8downloadERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z5yylexRN11modsecurity6Parser6DriverE\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   fun:curl_multi_perform\n   fun:curl_easy_perform\n   fun:_ZN11modsecurity5Utils11HttpsClient8downloadERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z5yylexRN11modsecurity6Parser6DriverE\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   fun:curl_multi_perform\n   fun:curl_easy_perform\n   fun:_ZN11modsecurity5Utils11HttpsClient8downloadERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z5yylexRN11modsecurity6Parser6DriverE\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   fun:curl_multi_perform\n   fun:curl_easy_perform\n   fun:_ZN11modsecurity5Utils11HttpsClient8downloadERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z5yylexRN11modsecurity6Parser6DriverE\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   fun:curl_multi_perform\n   fun:curl_easy_perform\n   fun:_ZN11modsecurity5Utils11HttpsClient8downloadERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z5yylexRN11modsecurity6Parser6DriverE\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   fun:__GI_strchr\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   fun:curl_multi_perform\n   fun:curl_easy_perform\n   fun:_ZN11modsecurity5Utils11HttpsClient8downloadERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z5yylexRN11modsecurity6Parser6DriverE\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   fun:__GI_strchr\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   fun:curl_multi_perform\n   fun:curl_easy_perform\n   fun:_ZN11modsecurity5Utils11HttpsClient8downloadERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z5yylexRN11modsecurity6Parser6DriverE\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   fun:curl_multi_perform\n   fun:curl_easy_perform\n   fun:_ZN11modsecurity5Utils11HttpsClient8downloadERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z5yylexRN11modsecurity6Parser6DriverE\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   fun:curl_multi_perform\n   fun:curl_easy_perform\n   fun:_ZN11modsecurity5Utils11HttpsClient8downloadERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z5yylexRN11modsecurity6Parser6DriverE\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   fun:memmove\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   fun:curl_multi_perform\n   fun:curl_easy_perform\n   fun:_ZN11modsecurity5Utils11HttpsClient8downloadERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z5yylexRN11modsecurity6Parser6DriverE\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   fun:memmove\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   fun:curl_multi_perform\n   fun:curl_easy_perform\n   fun:_ZN11modsecurity5Utils11HttpsClient8downloadERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z5yylexRN11modsecurity6Parser6DriverE\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   fun:curl_multi_perform\n   fun:curl_easy_perform\n   fun:_ZN11modsecurity5Utils11HttpsClient8downloadERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z5yylexRN11modsecurity6Parser6DriverE\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   fun:assign\n   fun:_M_set_length\n   fun:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE9_M_appendEPKcm\n   fun:append\n   fun:_ZN11modsecurity5Utils11HttpsClient11handle_implEPcmm\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   fun:curl_multi_perform\n   fun:curl_easy_perform\n   fun:_ZN11modsecurity5Utils11HttpsClient8downloadERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z5yylexRN11modsecurity6Parser6DriverE\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   fun:_Z5yylexRN11modsecurity6Parser6DriverE\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   fun:_IO_vfscanf\n   fun:__isoc99_vsscanf\n   fun:__isoc99_sscanf\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   fun:curl_multi_perform\n   fun:curl_easy_perform\n   fun:_ZN11modsecurity5Utils11HttpsClient8downloadERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_ZN11modsecurity9operators10PmFromFile4initERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPS7_\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   fun:_IO_vfscanf\n   fun:__isoc99_vsscanf\n   fun:__isoc99_sscanf\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   fun:curl_multi_perform\n   fun:curl_easy_perform\n   fun:_ZN11modsecurity5Utils11HttpsClient8downloadERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_ZN11modsecurity9operators10PmFromFile4initERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPS7_\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   fun:_IO_vfscanf\n   fun:__isoc99_vsscanf\n   fun:__isoc99_sscanf\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   fun:curl_multi_perform\n   fun:curl_easy_perform\n   fun:_ZN11modsecurity5Utils11HttpsClient8downloadERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_ZN11modsecurity9operators10PmFromFile4initERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPS7_\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   fun:_IO_vfscanf\n   fun:__isoc99_vsscanf\n   fun:__isoc99_sscanf\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   fun:curl_multi_perform\n   fun:curl_easy_perform\n   fun:_ZN11modsecurity5Utils11HttpsClient8downloadERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_ZN11modsecurity9operators10PmFromFile4initERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPS7_\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   fun:inet_pton\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   fun:curl_multi_perform\n   fun:curl_easy_perform\n   fun:_ZN11modsecurity5Utils11HttpsClient8downloadERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_ZN11modsecurity9operators10PmFromFile4initERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPS7_\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   fun:curl_multi_perform\n   fun:curl_easy_perform\n   fun:_ZN11modsecurity5Utils11HttpsClient8downloadERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_ZN11modsecurity9operators10PmFromFile4initERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPS7_\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   fun:curl_multi_perform\n   fun:curl_easy_perform\n   fun:_ZN11modsecurity5Utils11HttpsClient8downloadERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_ZN11modsecurity9operators10PmFromFile4initERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPS7_\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   fun:curl_multi_perform\n   fun:curl_easy_perform\n   fun:_ZN11modsecurity5Utils11HttpsClient8downloadERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_ZN11modsecurity9operators10PmFromFile4initERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPS7_\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   fun:curl_multi_perform\n   fun:curl_easy_perform\n   fun:_ZN11modsecurity5Utils11HttpsClient8downloadERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_ZN11modsecurity9operators10PmFromFile4initERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPS7_\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   fun:curl_multi_perform\n   fun:curl_easy_perform\n   fun:_ZN11modsecurity5Utils11HttpsClient8downloadERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_ZN11modsecurity9operators10PmFromFile4initERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPS7_\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   fun:inet_pton\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   fun:curl_multi_perform\n   fun:curl_easy_perform\n   fun:_ZN11modsecurity5Utils11HttpsClient8downloadERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_ZN11modsecurity9operators10PmFromFile4initERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPS7_\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   fun:curl_multi_perform\n   fun:curl_easy_perform\n   fun:_ZN11modsecurity5Utils11HttpsClient8downloadERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_ZN11modsecurity9operators10PmFromFile4initERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPS7_\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   fun:inet_pton\n   fun:gaih_inet.constprop.5\n   fun:getaddrinfo\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   fun:start_thread\n   fun:clone\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   fun:tolower\n   fun:strcasecmp\n   fun:_nss_files_gethostbyname4_r\n   fun:gaih_inet.constprop.5\n   fun:getaddrinfo\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   fun:start_thread\n   fun:clone\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   fun:tolower\n   fun:strcasecmp\n   fun:_nss_files_gethostbyname4_r\n   fun:gaih_inet.constprop.5\n   fun:getaddrinfo\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   fun:start_thread\n   fun:clone\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Param\n   open(filename)\n   obj:/usr/lib/libc-2.24.so\n   fun:_IO_file_open\n   fun:_IO_file_fopen@@GLIBC_2.2.5\n   fun:__fopen_internal\n   obj:/usr/lib/libnss_mymachines.so.2\n   obj:/usr/lib/libnss_mymachines.so.2\n   obj:/usr/lib/libnss_mymachines.so.2\n   fun:_nss_mymachines_gethostbyname4_r\n   fun:gaih_inet.constprop.5\n   fun:getaddrinfo\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   fun:start_thread\n   fun:clone\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Param\n   sendmsg(msg.msg_iov[1])\n   fun:sendmsg\n   obj:/usr/lib/libnss_resolve.so.2\n   obj:/usr/lib/libnss_resolve.so.2\n   obj:/usr/lib/libnss_resolve.so.2\n   obj:/usr/lib/libnss_resolve.so.2\n   fun:_nss_resolve_gethostbyname4_r\n   fun:gaih_inet.constprop.5\n   fun:getaddrinfo\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   fun:start_thread\n   fun:clone\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Param\n   sendmsg(mmsg[0].msg_hdr.msg_iov[0])\n   fun:sendmmsg\n   obj:/usr/lib/libresolv-2.24.so\n   fun:__libc_res_nquery\n   obj:/usr/lib/libresolv-2.24.so\n   fun:__libc_res_nsearch\n   fun:_nss_dns_gethostbyname4_r\n   fun:_nss_resolve_gethostbyname4_r\n   fun:gaih_inet.constprop.5\n   fun:getaddrinfo\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   fun:start_thread\n   fun:clone\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Param\n   sendmsg(mmsg[1].msg_hdr.msg_iov[0])\n   fun:sendmmsg\n   obj:/usr/lib/libresolv-2.24.so\n   fun:__libc_res_nquery\n   obj:/usr/lib/libresolv-2.24.so\n   fun:__libc_res_nsearch\n   fun:_nss_dns_gethostbyname4_r\n   fun:_nss_resolve_gethostbyname4_r\n   fun:gaih_inet.constprop.5\n   fun:getaddrinfo\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   fun:start_thread\n   fun:clone\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   fun:tolower\n   fun:strcasecmp\n   fun:ns_samename\n   fun:__res_nameinquery\n   fun:__res_queriesmatch\n   obj:/usr/lib/libresolv-2.24.so\n   fun:__libc_res_nquery\n   obj:/usr/lib/libresolv-2.24.so\n   fun:__libc_res_nsearch\n   fun:_nss_dns_gethostbyname4_r\n   fun:_nss_resolve_gethostbyname4_r\n   fun:gaih_inet.constprop.5\n   fun:getaddrinfo\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   fun:start_thread\n   fun:clone\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   fun:curl_multi_perform\n   fun:curl_easy_perform\n   fun:_ZN11modsecurity5Utils11HttpsClient8downloadERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_ZN11modsecurity9operators10PmFromFile4initERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPS7_\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   fun:inet_pton\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   fun:curl_multi_perform\n   fun:curl_easy_perform\n   fun:_ZN11modsecurity5Utils11HttpsClient8downloadERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_ZN11modsecurity9operators10PmFromFile4initERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPS7_\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Param\n   write(buf)\n   obj:/usr/lib/libc-2.24.so\n   fun:sock_write\n   fun:BIO_write\n   fun:ssl23_write_bytes\n   fun:ssl23_connect\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   fun:curl_multi_perform\n   fun:curl_easy_perform\n   fun:_ZN11modsecurity5Utils11HttpsClient8downloadERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_ZN11modsecurity9operators10PmFromFile4initERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPS7_\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   fun:memmove\n   fun:copy\n   fun:_S_copy\n   fun:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE9_M_mutateEmmPKcm\n   fun:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE9_M_appendEPKcm\n   fun:append\n   fun:_ZN11modsecurity5Utils11HttpsClient11handle_implEPcmm\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   fun:curl_multi_perform\n   fun:curl_easy_perform\n   fun:_ZN11modsecurity5Utils11HttpsClient8downloadERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_ZN11modsecurity9operators10PmFromFile4initERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPS7_\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   fun:memmove\n   fun:copy\n   fun:_S_copy\n   fun:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE9_M_mutateEmmPKcm\n   fun:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE9_M_appendEPKcm\n   fun:append\n   fun:_ZN11modsecurity5Utils11HttpsClient11handle_implEPcmm\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   fun:curl_multi_perform\n   fun:curl_easy_perform\n   fun:_ZN11modsecurity5Utils11HttpsClient8downloadERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_ZN11modsecurity9operators10PmFromFile4initERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPS7_\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   obj:/usr/lib/libcurl.so.4.4.0\n   fun:curl_multi_perform\n   fun:curl_easy_perform\n   fun:_ZN11modsecurity5Utils11HttpsClient8downloadERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_ZN11modsecurity9operators10PmFromFile4initERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPS7_\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   fun:memmove\n   fun:copy\n   fun:_S_copy\n   fun:_S_copy_chars\n   fun:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE12_M_constructIPKcEEvT_S8_St20forward_iterator_tag.isra.24\n   fun:_M_construct_aux<char const*>\n   fun:_M_construct<char const*>\n   fun:basic_string\n   fun:basic_stringbuf\n   fun:basic_stringstream\n   fun:_ZN11modsecurity9operators10PmFromFile4initERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPS7_\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   fun:memmove\n   fun:copy\n   fun:_S_copy\n   fun:_S_copy_chars\n   fun:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE12_M_constructIPKcEEvT_S8_St20forward_iterator_tag.isra.24\n   fun:_M_construct_aux<char const*>\n   fun:_M_construct<char const*>\n   fun:basic_string\n   fun:basic_stringbuf\n   fun:basic_stringstream\n   fun:_ZN11modsecurity9operators10PmFromFile4initERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPS7_\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   fun:assign\n   fun:_M_set_length\n   fun:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE12_M_constructIPKcEEvT_S8_St20forward_iterator_tag.isra.24\n   fun:_M_construct_aux<char const*>\n   fun:_M_construct<char const*>\n   fun:basic_string\n   fun:basic_stringbuf\n   fun:basic_stringstream\n   fun:_ZN11modsecurity9operators10PmFromFile4initERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPS7_\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   fun:tolower\n   fun:acmp_add_pattern\n   fun:_ZN11modsecurity9operators10PmFromFile4initERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPS7_\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   fun:____strtod_l_internal\n   fun:__stoa<double>\n   fun:stod\n   fun:_ZN11modsecurity7actions6RuleId4initEPNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   fun:__printf_fp_l\n   fun:vfprintf\n   fun:vsnprintf\n   fun:_ZSt16__convert_from_vRKP15__locale_structPciPKcz\n   fun:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE15_M_insert_floatIdEES3_S3_RSt8ios_baseccT_\n   fun:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE6do_putES3_RSt8ios_basecd\n   fun:put\n   fun:_ZNSo9_M_insertIdEERSoT_\n   fun:operator<<\n   fun:_ZN11modsecurity7actions6RuleId4initEPNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   fun:__mpn_lshift\n   fun:__printf_fp_l\n   fun:vfprintf\n   fun:vsnprintf\n   fun:_ZSt16__convert_from_vRKP15__locale_structPciPKcz\n   fun:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE15_M_insert_floatIdEES3_S3_RSt8ios_baseccT_\n   fun:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE6do_putES3_RSt8ios_basecd\n   fun:put\n   fun:_ZNSo9_M_insertIdEERSoT_\n   fun:operator<<\n   fun:_ZN11modsecurity7actions6RuleId4initEPNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   fun:__mpn_lshift\n   fun:__printf_fp_l\n   fun:vfprintf\n   fun:vsnprintf\n   fun:_ZSt16__convert_from_vRKP15__locale_structPciPKcz\n   fun:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE15_M_insert_floatIdEES3_S3_RSt8ios_baseccT_\n   fun:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE6do_putES3_RSt8ios_basecd\n   fun:put\n   fun:_ZNSo9_M_insertIdEERSoT_\n   fun:operator<<\n   fun:_ZN11modsecurity7actions6RuleId4initEPNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   fun:__printf_fp_l\n   fun:vfprintf\n   fun:vsnprintf\n   fun:_ZSt16__convert_from_vRKP15__locale_structPciPKcz\n   fun:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE15_M_insert_floatIdEES3_S3_RSt8ios_baseccT_\n   fun:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE6do_putES3_RSt8ios_basecd\n   fun:put\n   fun:_ZNSo9_M_insertIdEERSoT_\n   fun:operator<<\n   fun:_ZN11modsecurity7actions6RuleId4initEPNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   fun:memcpy@GLIBC_2.2.5\n   fun:__printf_fp_l\n   fun:vfprintf\n   fun:vsnprintf\n   fun:_ZSt16__convert_from_vRKP15__locale_structPciPKcz\n   fun:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE15_M_insert_floatIdEES3_S3_RSt8ios_baseccT_\n   fun:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE6do_putES3_RSt8ios_basecd\n   fun:put\n   fun:_ZNSo9_M_insertIdEERSoT_\n   fun:operator<<\n   fun:_ZN11modsecurity7actions6RuleId4initEPNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   fun:__mpn_cmp\n   fun:__printf_fp_l\n   fun:vfprintf\n   fun:vsnprintf\n   fun:_ZSt16__convert_from_vRKP15__locale_structPciPKcz\n   fun:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE15_M_insert_floatIdEES3_S3_RSt8ios_baseccT_\n   fun:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE6do_putES3_RSt8ios_basecd\n   fun:put\n   fun:_ZNSo9_M_insertIdEERSoT_\n   fun:operator<<\n   fun:_ZN11modsecurity7actions6RuleId4initEPNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   fun:__mpn_cmp\n   fun:__printf_fp_l\n   fun:vfprintf\n   fun:vsnprintf\n   fun:_ZSt16__convert_from_vRKP15__locale_structPciPKcz\n   fun:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE15_M_insert_floatIdEES3_S3_RSt8ios_baseccT_\n   fun:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE6do_putES3_RSt8ios_basecd\n   fun:put\n   fun:_ZNSo9_M_insertIdEERSoT_\n   fun:operator<<\n   fun:_ZN11modsecurity7actions6RuleId4initEPNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   fun:memcpy@GLIBC_2.2.5\n   fun:__printf_fp_l\n   fun:vfprintf\n   fun:vsnprintf\n   fun:_ZSt16__convert_from_vRKP15__locale_structPciPKcz\n   fun:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE15_M_insert_floatIdEES3_S3_RSt8ios_baseccT_\n   fun:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE6do_putES3_RSt8ios_basecd\n   fun:put\n   fun:_ZNSo9_M_insertIdEERSoT_\n   fun:operator<<\n   fun:_ZN11modsecurity7actions6RuleId4initEPNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   fun:memcpy@GLIBC_2.2.5\n   fun:__printf_fp_l\n   fun:vfprintf\n   fun:vsnprintf\n   fun:_ZSt16__convert_from_vRKP15__locale_structPciPKcz\n   fun:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE15_M_insert_floatIdEES3_S3_RSt8ios_baseccT_\n   fun:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE6do_putES3_RSt8ios_basecd\n   fun:put\n   fun:_ZNSo9_M_insertIdEERSoT_\n   fun:operator<<\n   fun:_ZN11modsecurity7actions6RuleId4initEPNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   fun:__printf_fp_l\n   fun:vfprintf\n   fun:vsnprintf\n   fun:_ZSt16__convert_from_vRKP15__locale_structPciPKcz\n   fun:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE15_M_insert_floatIdEES3_S3_RSt8ios_baseccT_\n   fun:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE6do_putES3_RSt8ios_basecd\n   fun:put\n   fun:_ZNSo9_M_insertIdEERSoT_\n   fun:operator<<\n   fun:_ZN11modsecurity7actions6RuleId4initEPNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   fun:__mpn_mul_1\n   fun:__mpn_mul\n   fun:__printf_fp_l\n   fun:vfprintf\n   fun:vsnprintf\n   fun:_ZSt16__convert_from_vRKP15__locale_structPciPKcz\n   fun:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE15_M_insert_floatIdEES3_S3_RSt8ios_baseccT_\n   fun:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE6do_putES3_RSt8ios_basecd\n   fun:put\n   fun:_ZNSo9_M_insertIdEERSoT_\n   fun:operator<<\n   fun:_ZN11modsecurity7actions6RuleId4initEPNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   fun:__mpn_mul_1\n   fun:__mpn_mul\n   fun:__printf_fp_l\n   fun:vfprintf\n   fun:vsnprintf\n   fun:_ZSt16__convert_from_vRKP15__locale_structPciPKcz\n   fun:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE15_M_insert_floatIdEES3_S3_RSt8ios_baseccT_\n   fun:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE6do_putES3_RSt8ios_basecd\n   fun:put\n   fun:_ZNSo9_M_insertIdEERSoT_\n   fun:operator<<\n   fun:_ZN11modsecurity7actions6RuleId4initEPNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   fun:__mpn_mul_1\n   fun:__mpn_mul\n   fun:__printf_fp_l\n   fun:vfprintf\n   fun:vsnprintf\n   fun:_ZSt16__convert_from_vRKP15__locale_structPciPKcz\n   fun:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE15_M_insert_floatIdEES3_S3_RSt8ios_baseccT_\n   fun:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE6do_putES3_RSt8ios_basecd\n   fun:put\n   fun:_ZNSo9_M_insertIdEERSoT_\n   fun:operator<<\n   fun:_ZN11modsecurity7actions6RuleId4initEPNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   fun:__mpn_mul\n   fun:__printf_fp_l\n   fun:vfprintf\n   fun:vsnprintf\n   fun:_ZSt16__convert_from_vRKP15__locale_structPciPKcz\n   fun:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE15_M_insert_floatIdEES3_S3_RSt8ios_baseccT_\n   fun:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE6do_putES3_RSt8ios_basecd\n   fun:put\n   fun:_ZNSo9_M_insertIdEERSoT_\n   fun:operator<<\n   fun:_ZN11modsecurity7actions6RuleId4initEPNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   fun:__printf_fp_l\n   fun:vfprintf\n   fun:vsnprintf\n   fun:_ZSt16__convert_from_vRKP15__locale_structPciPKcz\n   fun:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE15_M_insert_floatIdEES3_S3_RSt8ios_baseccT_\n   fun:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE6do_putES3_RSt8ios_basecd\n   fun:put\n   fun:_ZNSo9_M_insertIdEERSoT_\n   fun:operator<<\n   fun:_ZN11modsecurity7actions6RuleId4initEPNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   fun:__printf_fp_l\n   fun:vfprintf\n   fun:vsnprintf\n   fun:_ZSt16__convert_from_vRKP15__locale_structPciPKcz\n   fun:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE15_M_insert_floatIdEES3_S3_RSt8ios_baseccT_\n   fun:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE6do_putES3_RSt8ios_basecd\n   fun:put\n   fun:_ZNSo9_M_insertIdEERSoT_\n   fun:operator<<\n   fun:_ZN11modsecurity7actions6RuleId4initEPNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   fun:__printf_fp_l\n   fun:vfprintf\n   fun:vsnprintf\n   fun:_ZSt16__convert_from_vRKP15__locale_structPciPKcz\n   fun:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE15_M_insert_floatIdEES3_S3_RSt8ios_baseccT_\n   fun:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE6do_putES3_RSt8ios_basecd\n   fun:put\n   fun:_ZNSo9_M_insertIdEERSoT_\n   fun:operator<<\n   fun:_ZN11modsecurity7actions6RuleId4initEPNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   fun:__printf_fp_l\n   fun:vfprintf\n   fun:vsnprintf\n   fun:_ZSt16__convert_from_vRKP15__locale_structPciPKcz\n   fun:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE15_M_insert_floatIdEES3_S3_RSt8ios_baseccT_\n   fun:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE6do_putES3_RSt8ios_basecd\n   fun:put\n   fun:_ZNSo9_M_insertIdEERSoT_\n   fun:operator<<\n   fun:_ZN11modsecurity7actions6RuleId4initEPNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   fun:__printf_fp_l\n   fun:vfprintf\n   fun:vsnprintf\n   fun:_ZSt16__convert_from_vRKP15__locale_structPciPKcz\n   fun:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE15_M_insert_floatIdEES3_S3_RSt8ios_baseccT_\n   fun:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE6do_putES3_RSt8ios_basecd\n   fun:put\n   fun:_ZNSo9_M_insertIdEERSoT_\n   fun:operator<<\n   fun:_ZN11modsecurity7actions6RuleId4initEPNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   fun:__mpn_rshift\n   fun:__printf_fp_l\n   fun:vfprintf\n   fun:vsnprintf\n   fun:_ZSt16__convert_from_vRKP15__locale_structPciPKcz\n   fun:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE15_M_insert_floatIdEES3_S3_RSt8ios_baseccT_\n   fun:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE6do_putES3_RSt8ios_basecd\n   fun:put\n   fun:_ZNSo9_M_insertIdEERSoT_\n   fun:operator<<\n   fun:_ZN11modsecurity7actions6RuleId4initEPNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   fun:__mpn_rshift\n   fun:__printf_fp_l\n   fun:vfprintf\n   fun:vsnprintf\n   fun:_ZSt16__convert_from_vRKP15__locale_structPciPKcz\n   fun:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE15_M_insert_floatIdEES3_S3_RSt8ios_baseccT_\n   fun:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE6do_putES3_RSt8ios_basecd\n   fun:put\n   fun:_ZNSo9_M_insertIdEERSoT_\n   fun:operator<<\n   fun:_ZN11modsecurity7actions6RuleId4initEPNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   fun:__mpn_rshift\n   fun:__printf_fp_l\n   fun:vfprintf\n   fun:vsnprintf\n   fun:_ZSt16__convert_from_vRKP15__locale_structPciPKcz\n   fun:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE15_M_insert_floatIdEES3_S3_RSt8ios_baseccT_\n   fun:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE6do_putES3_RSt8ios_basecd\n   fun:put\n   fun:_ZNSo9_M_insertIdEERSoT_\n   fun:operator<<\n   fun:_ZN11modsecurity7actions6RuleId4initEPNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   fun:__mpn_rshift\n   fun:__printf_fp_l\n   fun:vfprintf\n   fun:vsnprintf\n   fun:_ZSt16__convert_from_vRKP15__locale_structPciPKcz\n   fun:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE15_M_insert_floatIdEES3_S3_RSt8ios_baseccT_\n   fun:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE6do_putES3_RSt8ios_basecd\n   fun:put\n   fun:_ZNSo9_M_insertIdEERSoT_\n   fun:operator<<\n   fun:_ZN11modsecurity7actions6RuleId4initEPNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   fun:__printf_fp_l\n   fun:vfprintf\n   fun:vsnprintf\n   fun:_ZSt16__convert_from_vRKP15__locale_structPciPKcz\n   fun:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE15_M_insert_floatIdEES3_S3_RSt8ios_baseccT_\n   fun:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE6do_putES3_RSt8ios_basecd\n   fun:put\n   fun:_ZNSo9_M_insertIdEERSoT_\n   fun:operator<<\n   fun:_ZN11modsecurity7actions6RuleId4initEPNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   fun:__mpn_divrem\n   fun:hack_digit\n   fun:__printf_fp_l\n   fun:vfprintf\n   fun:vsnprintf\n   fun:_ZSt16__convert_from_vRKP15__locale_structPciPKcz\n   fun:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE15_M_insert_floatIdEES3_S3_RSt8ios_baseccT_\n   fun:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE6do_putES3_RSt8ios_basecd\n   fun:put\n   fun:_ZNSo9_M_insertIdEERSoT_\n   fun:operator<<\n   fun:_ZN11modsecurity7actions6RuleId4initEPNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   fun:__mpn_divrem\n   fun:hack_digit\n   fun:__printf_fp_l\n   fun:vfprintf\n   fun:vsnprintf\n   fun:_ZSt16__convert_from_vRKP15__locale_structPciPKcz\n   fun:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE15_M_insert_floatIdEES3_S3_RSt8ios_baseccT_\n   fun:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE6do_putES3_RSt8ios_basecd\n   fun:put\n   fun:_ZNSo9_M_insertIdEERSoT_\n   fun:operator<<\n   fun:_ZN11modsecurity7actions6RuleId4initEPNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   fun:__mpn_divrem\n   fun:hack_digit\n   fun:__printf_fp_l\n   fun:vfprintf\n   fun:vsnprintf\n   fun:_ZSt16__convert_from_vRKP15__locale_structPciPKcz\n   fun:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE15_M_insert_floatIdEES3_S3_RSt8ios_baseccT_\n   fun:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE6do_putES3_RSt8ios_basecd\n   fun:put\n   fun:_ZNSo9_M_insertIdEERSoT_\n   fun:operator<<\n   fun:_ZN11modsecurity7actions6RuleId4initEPNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   fun:hack_digit\n   fun:__printf_fp_l\n   fun:vfprintf\n   fun:vsnprintf\n   fun:_ZSt16__convert_from_vRKP15__locale_structPciPKcz\n   fun:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE15_M_insert_floatIdEES3_S3_RSt8ios_baseccT_\n   fun:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE6do_putES3_RSt8ios_basecd\n   fun:put\n   fun:_ZNSo9_M_insertIdEERSoT_\n   fun:operator<<\n   fun:_ZN11modsecurity7actions6RuleId4initEPNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   fun:hack_digit\n   fun:__printf_fp_l\n   fun:vfprintf\n   fun:vsnprintf\n   fun:_ZSt16__convert_from_vRKP15__locale_structPciPKcz\n   fun:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE15_M_insert_floatIdEES3_S3_RSt8ios_baseccT_\n   fun:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE6do_putES3_RSt8ios_basecd\n   fun:put\n   fun:_ZNSo9_M_insertIdEERSoT_\n   fun:operator<<\n   fun:_ZN11modsecurity7actions6RuleId4initEPNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   fun:hack_digit\n   fun:__printf_fp_l\n   fun:vfprintf\n   fun:vsnprintf\n   fun:_ZSt16__convert_from_vRKP15__locale_structPciPKcz\n   fun:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE15_M_insert_floatIdEES3_S3_RSt8ios_baseccT_\n   fun:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE6do_putES3_RSt8ios_basecd\n   fun:put\n   fun:_ZNSo9_M_insertIdEERSoT_\n   fun:operator<<\n   fun:_ZN11modsecurity7actions6RuleId4initEPNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   fun:__mpn_mul_1\n   fun:hack_digit\n   fun:__printf_fp_l\n   fun:vfprintf\n   fun:vsnprintf\n   fun:_ZSt16__convert_from_vRKP15__locale_structPciPKcz\n   fun:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE15_M_insert_floatIdEES3_S3_RSt8ios_baseccT_\n   fun:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE6do_putES3_RSt8ios_basecd\n   fun:put\n   fun:_ZNSo9_M_insertIdEERSoT_\n   fun:operator<<\n   fun:_ZN11modsecurity7actions6RuleId4initEPNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   fun:__mpn_mul_1\n   fun:hack_digit\n   fun:__printf_fp_l\n   fun:vfprintf\n   fun:vsnprintf\n   fun:_ZSt16__convert_from_vRKP15__locale_structPciPKcz\n   fun:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE15_M_insert_floatIdEES3_S3_RSt8ios_baseccT_\n   fun:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE6do_putES3_RSt8ios_basecd\n   fun:put\n   fun:_ZNSo9_M_insertIdEERSoT_\n   fun:operator<<\n   fun:_ZN11modsecurity7actions6RuleId4initEPNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   fun:hack_digit\n   fun:__printf_fp_l\n   fun:vfprintf\n   fun:vsnprintf\n   fun:_ZSt16__convert_from_vRKP15__locale_structPciPKcz\n   fun:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE15_M_insert_floatIdEES3_S3_RSt8ios_baseccT_\n   fun:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE6do_putES3_RSt8ios_basecd\n   fun:put\n   fun:_ZNSo9_M_insertIdEERSoT_\n   fun:operator<<\n   fun:_ZN11modsecurity7actions6RuleId4initEPNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   fun:__mpn_divrem\n   fun:hack_digit\n   fun:__printf_fp_l\n   fun:vfprintf\n   fun:vsnprintf\n   fun:_ZSt16__convert_from_vRKP15__locale_structPciPKcz\n   fun:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE15_M_insert_floatIdEES3_S3_RSt8ios_baseccT_\n   fun:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE6do_putES3_RSt8ios_basecd\n   fun:put\n   fun:_ZNSo9_M_insertIdEERSoT_\n   fun:operator<<\n   fun:_ZN11modsecurity7actions6RuleId4initEPNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   fun:__mpn_divrem\n   fun:hack_digit\n   fun:__printf_fp_l\n   fun:vfprintf\n   fun:vsnprintf\n   fun:_ZSt16__convert_from_vRKP15__locale_structPciPKcz\n   fun:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE15_M_insert_floatIdEES3_S3_RSt8ios_baseccT_\n   fun:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE6do_putES3_RSt8ios_basecd\n   fun:put\n   fun:_ZNSo9_M_insertIdEERSoT_\n   fun:operator<<\n   fun:_ZN11modsecurity7actions6RuleId4initEPNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   fun:__printf_fp_l\n   fun:vfprintf\n   fun:vsnprintf\n   fun:_ZSt16__convert_from_vRKP15__locale_structPciPKcz\n   fun:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE15_M_insert_floatIdEES3_S3_RSt8ios_baseccT_\n   fun:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE6do_putES3_RSt8ios_basecd\n   fun:put\n   fun:_ZNSo9_M_insertIdEERSoT_\n   fun:operator<<\n   fun:_ZN11modsecurity7actions6RuleId4initEPNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   fun:__printf_fp_l\n   fun:vfprintf\n   fun:vsnprintf\n   fun:_ZSt16__convert_from_vRKP15__locale_structPciPKcz\n   fun:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE15_M_insert_floatIdEES3_S3_RSt8ios_baseccT_\n   fun:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE6do_putES3_RSt8ios_basecd\n   fun:put\n   fun:_ZNSo9_M_insertIdEERSoT_\n   fun:operator<<\n   fun:_ZN11modsecurity7actions6RuleId4initEPNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   fun:hack_digit\n   fun:__printf_fp_l\n   fun:vfprintf\n   fun:vsnprintf\n   fun:_ZSt16__convert_from_vRKP15__locale_structPciPKcz\n   fun:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE15_M_insert_floatIdEES3_S3_RSt8ios_baseccT_\n   fun:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE6do_putES3_RSt8ios_basecd\n   fun:put\n   fun:_ZNSo9_M_insertIdEERSoT_\n   fun:operator<<\n   fun:_ZN11modsecurity7actions6RuleId4initEPNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   fun:hack_digit\n   fun:__printf_fp_l\n   fun:vfprintf\n   fun:vsnprintf\n   fun:_ZSt16__convert_from_vRKP15__locale_structPciPKcz\n   fun:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE15_M_insert_floatIdEES3_S3_RSt8ios_baseccT_\n   fun:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE6do_putES3_RSt8ios_basecd\n   fun:put\n   fun:_ZNSo9_M_insertIdEERSoT_\n   fun:operator<<\n   fun:_ZN11modsecurity7actions6RuleId4initEPNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   fun:hack_digit\n   fun:__printf_fp_l\n   fun:vfprintf\n   fun:vsnprintf\n   fun:_ZSt16__convert_from_vRKP15__locale_structPciPKcz\n   fun:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE15_M_insert_floatIdEES3_S3_RSt8ios_baseccT_\n   fun:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE6do_putES3_RSt8ios_basecd\n   fun:put\n   fun:_ZNSo9_M_insertIdEERSoT_\n   fun:operator<<\n   fun:_ZN11modsecurity7actions6RuleId4initEPNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   fun:__printf_fp_l\n   fun:vfprintf\n   fun:vsnprintf\n   fun:_ZSt16__convert_from_vRKP15__locale_structPciPKcz\n   fun:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE15_M_insert_floatIdEES3_S3_RSt8ios_baseccT_\n   fun:_ZNKSt7num_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE6do_putES3_RSt8ios_basecd\n   fun:put\n   fun:_ZNSo9_M_insertIdEERSoT_\n   fun:operator<<\n   fun:_ZN11modsecurity7actions6RuleId4initEPNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   fun:tolower\n   fun:transform<__gnu_cxx::__normal_iterator<char*, std::__cxx11::basic_string<char> >, __gnu_cxx::__normal_iterator<char*, std::__cxx11::basic_string<char> >, int (*)(int) throw ()>\n   fun:_ZN11modsecurity5utils6string7tolowerENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_ZN11modsecurity7actions5Phase4initEPNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   fun:____strtol_l_internal\n   fun:__stoa<long int, int, char, int>\n   fun:stoi\n   fun:_ZN11modsecurity7actions5Phase4initEPNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   fun:____strtol_l_internal\n   fun:__stoa<long int, int, char, int>\n   fun:stoi\n   fun:_ZN11modsecurity7actions5Phase4initEPNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   fun:____strtol_l_internal\n   fun:__stoa<long int, int, char, int>\n   fun:stoi\n   fun:_ZN11modsecurity7actions5Phase4initEPNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   fun:_ZL21yy_get_previous_statev\n   fun:_Z5yylexRN11modsecurity6Parser6DriverE\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Value8\n   fun:_itoa_word\n   fun:vfprintf\n   fun:vsnprintf\n   fun:_ZN9__gnu_cxx12__to_xstringINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEcEET_PFiPT0_mPKS8_P13__va_list_tagEmSB_z\n   fun:to_string\n   fun:_ZN11modsecurity4Rule8evaluateEPNS_11TransactionE\n   fun:_ZN11modsecurity5Rules8evaluateEiPNS_11TransactionE\n   fun:_ZN11modsecurity11Transaction18processRequestBodyEv\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Leak\n   match-leak-kinds: definite\n   fun:malloc\n   fun:_Z14yy_scan_bufferPcm\n   fun:_Z13yy_scan_bytesPKci\n   fun:_ZN11modsecurity6Parser6Driver10scan_beginEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Leak\n   match-leak-kinds: definite\n   fun:_Znwm\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Leak\n   match-leak-kinds: definite\n   fun:realloc\n   fun:write\n   fun:_ZN11modsecurity6engine3Lua11blob_keeperEP9lua_StatePKvmPv\n   obj:/usr/lib/liblua.so.5.3.4\n   obj:/usr/lib/liblua.so.5.3.4\n   obj:/usr/lib/liblua.so.5.3.4\n   obj:/usr/lib/liblua.so.5.3.4\n   fun:_ZN11modsecurity6engine3Lua4loadENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPS7_\n   fun:_ZN11modsecurity10RuleScript4initEPNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Leak\n   match-leak-kinds: definite\n   fun:_Znwm\n   fun:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE9_M_assignERKS4_\n   fun:assign\n   fun:operator=\n   fun:_ZN11modsecurity6engine3Lua4loadENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPS7_\n   fun:_ZN11modsecurity10RuleScript4initEPNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Leak\n   match-leak-kinds: definite\n   fun:_Znwm\n   fun:_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE12_M_constructIPcEEvT_S7_St20forward_iterator_tag.isra.137\n   fun:_M_construct_aux<char*>\n   fun:_M_construct<char*>\n   fun:basic_string\n   fun:RuleScript\n   fun:_ZN2yy14seclang_parser5parseEv\n   fun:_ZN11modsecurity6Parser6Driver5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_\n   fun:_ZN11modsecurity5Rules4loadEPKcRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE\n   fun:_Z17perform_unit_testPN16modsecurity_test15ModSecurityTestINS_14RegressionTestEEEPSt6vectorIPS1_SaIS5_EEPNS_22ModSecurityTestResultsINS_20RegressionTestResultEEEPi\n   fun:main\n}\n{\n   <insert_a_suppression_name_here>\n   Memcheck:Leak\n   match-leak-kinds: definite\n   fun:malloc\n   fun:strdup\n   fun:main\n}\n"
  },
  {
    "path": "tools/Makefile.am",
    "content": "\nACLOCAL_AMFLAGS = -I build\n\n\nSUBDIRS = \\\n\trules-check\n\n# make clean\nCLEANFILES = \n\n# make maintainer-clean\nMAINTAINERCLEANFILES = \\\n\tMakefile.in\n\n"
  },
  {
    "path": "tools/rules-check/Makefile.am",
    "content": "\n\nbin_PROGRAMS = modsec-rules-check\n\nmodsec_rules_check_SOURCES = \\\n        rules-check.cc\n\nmodsec_rules_check_LDADD = \\\n\t$(top_builddir)/src/.libs/libmodsecurity.la \\\n\t$(CURL_LDADD) \\\n\t$(GEOIP_LDADD) \\\n\t$(MAXMIND_LDADD) \\\n\t$(GLOBAL_LDADD) \\\n\t$(LIBXML2_LDADD) \\\n\t$(LMDB_LDADD) \\\n\t$(LUA_LDADD) \\\n\t$(PCRE_LDADD) \\\n\t$(PCRE2_LDADD) \\\n\t$(SSDEEP_LDADD) \\\n\t$(YAJL_LDADD)\n\nmodsec_rules_check_LDFLAGS = \\\n\t$(GEOIP_LDFLAGS) \\\n\t$(MAXMIND_LDFLAGS) \\\n\t$(LDFLAGS) \\\n\t$(LMDB_LDFLAGS) \\\n\t$(LUA_LDFLAGS) \\\n\t$(SSDEEP_LDFLAGS) \\\n\t$(YAJL_LDFLAGS) \\\n\t$(LIBXML2_LDFLAGS)\n\nmodsec_rules_check_CPPFLAGS = \\\n\t-I$(top_builddir)/headers \\\n\t$(GLOBAL_CPPFLAGS) \\\n\t$(PCRE_CFLAGS) \\\n\t$(PCRE2_CFLAGS) \\\n\t$(LMDB_CFLAGS) \\\n\t$(MAXMIND_CFLAGS) \\\n\t$(LIBXML2_CFLAGS)\n\nMAINTAINERCLEANFILES = \\\n        Makefile.in\n\n"
  },
  {
    "path": "tools/rules-check/rules-check.cc",
    "content": "/*\n * ModSecurity, http://www.modsecurity.org/\n * Copyright (c) 2015 - 2021 Trustwave Holdings, Inc. (http://www.trustwave.com/)\n *\n * You may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * If any of the files related to licensing are missing or if you have any\n * other questions related to licensing please contact Trustwave Holdings, Inc.\n * directly using the email address security@modsecurity.org.\n *\n */\n\n#include <string.h>\n#include <sys/stat.h>\n#ifndef WIN32\n#include <unistd.h>\n#else\n#include <io.h>\n#endif\n\n#include <ctime>\n#include <iostream>\n#include <string>\n\n#include \"modsecurity/rules_set.h\"\n#include \"modsecurity/modsecurity.h\"\n\n\nvoid print_help(const char *name) {\n    std::cout << \"Use: \" << name << \" [<filename>|SecLangCommand]\" << std::endl;\n    std::cout << std::endl;\n}\n\n\nint main(int argc, char **argv) {\n    auto rules = std::make_unique<modsecurity::RulesSet>();\n    char **args = argv;\n    int ret = 0;\n\n    args++;\n\n    if (*args == NULL) {\n        print_help(argv[0]);\n        return 0;\n    }\n\n    while (*args != NULL) {\n        struct stat buffer;\n        std::string arg = *args;\n        std::string err;\n        int r;\n\n        // strip arg from leading and trailing '\"' chars\n        arg.erase(arg.find_last_not_of('\\\"')+1);\n        arg.erase(0, arg.find_first_not_of('\\\"'));\n\n        if (arg.empty() == true) {\n            args++;\n            continue;\n        }\n\n        std::cout << \" : \" << arg << \"  --  \";\n        if (stat(arg.c_str(), &buffer) == 0) {\n            r = rules->loadFromUri(arg.c_str());\n        } else {\n            r = rules->load(arg.c_str());\n        }\n\n        if (r < 0) {\n            err.assign(rules->m_parserError.str());\n            rules->m_parserError.str(\"\");\n            rules->m_parserError.clear();\n            ret = -1;\n        }\n        std::cout << \"Loaded \" << std::to_string(r) << \" rules.\" << std::endl;\n        if (err.empty() == false) {\n            std::cerr << \"    \" << err << std::endl;\n        }\n\n        args++;\n    }\n\n    if (ret < 0) {\n        std::cout << \"Test failed.\" << std::endl;\n    } else {\n        std::cout << \"Test ok.\" << std::endl;\n    }\n\n    return ret;\n}\n"
  },
  {
    "path": "unicode.mapping",
    "content": "(MAC - Roman)\r\n\r\n\r\n(MAC - Icelandic)\r\n\r\n\r\n1250  (ANSI - Central Europe)\r\n00a1:21 00a2:63 00a3:4c 00a5:59 00aa:61 00b2:32 00b3:33 00b9:31 00ba:6f 00bc:31 00bd:31 00be:33 00c0:41 00c3:41 00c5:41 00c6:41 00c8:45 00ca:45 00cc:49 00cf:49 00d1:4e 00d2:4f 00d5:4f 00d8:4f 00d9:55 00db:55 00e0:61 00e3:61 00e5:61 00e6:61 00e8:65 00ea:65 00ec:69 00ef:69 00f1:6e 00f2:6f 00f5:6f 00f8:6f 00f9:75 00fb:75 00ff:79 0100:41 0101:61 0108:43 0109:63 010a:43 010b:63 0112:45 0113:65 0114:45 0115:65 0116:45 0117:65 011c:47 011d:67 011e:47 011f:67 0120:47 0121:67 0122:47 0123:67 0124:48 0125:68 0126:48 0127:68 0128:49 0129:69 012a:49 012b:69 012c:49 012d:69 012e:49 012f:69 0130:49 0131:69 0134:4a 0135:6a 0136:4b 0137:6b 013b:4c 013c:6c 0145:4e 0146:6e 014c:4f 014d:6f 014e:4f 014f:6f 0152:4f 0153:6f 0156:52 0157:72 015c:53 015d:73 0166:54 0167:74 0168:55 0169:75 016a:55 016b:75 016c:55 016d:75 0172:55 0173:75 0174:57 0175:77 0176:59 0177:79 0178:59 0180:62 0191:46 0192:66 0197:49 019a:6c 019f:4f 01a0:4f 01a1:6f 01ab:74 01ae:54 01af:55 01b0:75 01b6:7a 01c0:7c 01c3:21 01cd:41 01ce:61 01cf:49 01d0:69 01d1:4f 01d2:6f 01d3:55 01d4:75 01d5:55 01d6:75 01d7:55 01d8:75 01d9:55 01da:75 01db:55 01dc:75 01de:41 01df:61 01e4:47 01e5:67 01e6:47 01e7:67 01e8:4b 01e9:6b 01ea:4f 01eb:6f 01ec:4f 01ed:6f 01f0:6a 0261:67 02b9:27 02ba:22 02bc:27 02c4:5e 02c6:5e 02c8:27 02cb:60 02cd:5f 02dc:7e 0300:60 0302:5e 0303:7e 030e:22 0331:5f 0332:5f 037e:3b 04bb:68 0589:3a 066a:25 2000:20 2001:20 2002:20 2003:20 2004:20 2005:20 2006:20 2010:2d 2011:2d 2032:27 2035:60 203c:21 2044:2f 2074:34 2075:35 2076:36 2077:37 2078:38 2080:30 2081:31 2082:32 2083:33 2084:34 2085:35 2086:36 2087:37 2088:38 2089:39 2102:43 2107:45 210a:67 210b:48 210c:48 210d:48 210e:68 2110:49 2111:49 2112:4c 2113:6c 2115:4e 2118:50 2119:50 211a:51 211b:52 211c:52 211d:52 2124:5a 2128:5a 212a:4b 212c:42 212d:43 212e:65 212f:65 2130:45 2131:46 2133:4d 2134:6f 2191:5e 2194:2d 2195:7c 21a8:7c 2212:2d 2215:2f 2216:5c 2217:2a 221f:4c 2223:7c 2236:3a 223c:7e 2303:5e 2329:3c 232a:3e 2502:2d 250c:2d 2514:4c 2518:2d 251c:2b 2524:2b 252c:54 2534:2b 253c:2b 2550:3d 2554:2d 255a:4c 255d:2d 2566:54 256c:2b 2580:2d 2584:2d 2588:2d 2591:2d 2592:2d 2593:2d 25ac:2d 25b2:5e 25ba:3e 25c4:3c 25cb:30 25d9:30 263c:30 2640:2b 2642:3e 266a:64 266b:64 2758:7c 3000:20 3008:3c 3009:3e 301a:5b 301b:5d ff01:21 ff02:22 ff03:23 ff04:24 ff05:25 ff06:26 ff07:27 ff08:28 ff09:29 ff0a:2a ff0b:2b ff0c:2c ff0d:2d ff0e:2e ff0f:2f ff10:30 ff11:31 ff12:32 ff13:33 ff14:34 ff15:35 ff16:36 ff17:37 ff18:38 ff19:39 ff1a:3a ff1b:3b ff1c:3c ff1d:3d ff1e:3e ff20:40 ff21:41 ff22:42 ff23:43 ff24:44 ff25:45 ff26:46 ff27:47 ff28:48 ff29:49 ff2a:4a ff2b:4b ff2c:4c ff2d:4d ff2e:4e ff2f:4f ff30:50 ff31:51 ff32:52 ff33:53 ff34:54 ff35:55 ff36:56 ff37:57 ff38:58 ff39:59 ff3a:5a ff3b:5b ff3c:5c ff3d:5d ff3e:5e ff3f:5f ff40:60 ff41:61 ff42:62 ff43:63 ff44:64 ff45:65 ff46:66 ff47:67 ff48:68 ff49:69 ff4a:6a ff4b:6b ff4c:6c ff4d:6d ff4e:6e ff4f:6f ff50:70 ff51:71 ff52:72 ff53:73 ff54:74 ff55:75 ff56:76 ff57:77 ff58:78 ff59:79 ff5a:7a ff5b:7b ff5c:7c ff5d:7d ff5e:7e \r\n\r\n1251  (ANSI - Cyrillic)\r\n00c0:41 00c1:41 00c2:41 00c3:41 00c4:41 00c5:41 00c7:43 00c8:45 00c9:45 00ca:45 00cb:45 00cc:49 00cd:49 00ce:49 00cf:49 00d1:4e 00d2:4f 00d3:4f 00d4:4f 00d5:4f 00d6:4f 00d8:4f 00d9:55 00da:55 00db:55 00dc:55 00dd:59 00e0:61 00e1:61 00e2:61 00e3:61 00e4:61 00e5:61 00e7:63 00e8:65 00e9:65 00ea:65 00eb:65 00ec:69 00ed:69 00ee:69 00ef:69 00f1:6e 00f2:6f 00f3:6f 00f4:6f 00f5:6f 00f6:6f 00f8:6f 00f9:75 00fa:75 00fb:75 00fc:75 00fd:79 00ff:79 0100:41 0101:61 0102:41 0103:61 0104:41 0105:61 0106:43 0107:63 0108:43 0109:63 010a:43 010b:63 010c:43 010d:63 010e:44 010f:64 0110:44 0111:64 0112:45 0113:65 0114:45 0115:65 0116:45 0117:65 0118:45 0119:65 011a:45 011b:65 011c:47 011d:67 011e:47 011f:67 0120:47 0121:67 0122:47 0123:67 0124:48 0125:68 0126:48 0127:68 0128:49 0129:69 012a:49 012b:69 012c:49 012d:69 012e:49 012f:69 0130:49 0134:4a 0135:6a 0136:4b 0137:6b 0139:4c 013a:6c 013b:4c 013c:6c 013d:4c 013e:6c 0141:4c 0142:6c 0143:4e 0144:6e 0145:4e 0146:6e 0147:4e 0148:6e 014c:4f 014d:6f 014e:4f 014f:6f 0150:4f 0151:6f 0154:52 0155:72 0156:52 0157:72 0158:52 0159:72 015a:53 015b:73 015c:53 015d:73 015e:53 015f:73 0160:53 0161:73 0162:54 0163:74 0164:54 0165:74 0166:54 0167:74 0168:55 0169:75 016a:55 016b:75 016c:55 016d:75 016e:55 016f:75 0170:55 0171:75 0172:55 0173:75 0174:57 0175:77 0176:59 0177:79 0178:59 0179:5a 017b:5a 017c:7a 017d:5a 017e:7a 0180:62 0197:49 019a:6c 019f:4f 01a0:4f 01a1:6f 01ab:74 01ae:54 01af:55 01b0:75 01cd:41 01ce:61 01cf:49 01d0:69 01d1:4f 01d2:6f 01d3:55 01d4:75 01d5:55 01d6:75 01d7:55 01d8:75 01d9:55 01da:75 01db:55 01dc:75 01de:41 01df:61 01e4:47 01e5:67 01e6:47 01e7:67 01e8:4b 01e9:6b 01ea:4f 01eb:6f 01ec:4f 01ed:6f 01f0:6a 203c:21 2190:3c 2191:5e 2192:3e 2193:76 2194:2d 221a:76 221f:4c 2500:2d 250c:2d 2514:4c 2518:2d 251c:2b 2524:2b 252c:54 2534:2b 253c:2b 2550:3d 2552:2d 2558:4c 2559:4c 255a:4c 255b:2d 255c:2d 255d:2d 2564:54 2565:54 2566:54 256a:2b 256b:2b 256c:2b 2580:2d 2584:2d 2588:2d 2591:2d 2592:2d 2593:2d 25ac:2d 25b2:5e 25ba:3e 25c4:3c 25cb:30 25d9:30 263a:4f 263b:4f 263c:30 2640:2b 2642:3e 266a:64 266b:64 ff01:21 ff02:22 ff03:23 ff04:24 ff05:25 ff06:26 ff07:27 ff08:28 ff09:29 ff0a:2a ff0b:2b ff0c:2c ff0d:2d ff0e:2e ff0f:2f ff10:30 ff11:31 ff12:32 ff13:33 ff14:34 ff15:35 ff16:36 ff17:37 ff18:38 ff19:39 ff1a:3a ff1b:3b ff1c:3c ff1d:3d ff1e:3e ff20:40 ff21:41 ff22:42 ff23:43 ff24:44 ff25:45 ff26:46 ff27:47 ff28:48 ff29:49 ff2a:4a ff2b:4b ff2c:4c ff2d:4d ff2e:4e ff2f:4f ff30:50 ff31:51 ff32:52 ff33:53 ff34:54 ff35:55 ff36:56 ff37:57 ff38:58 ff39:59 ff3a:5a ff3b:5b ff3c:5c ff3d:5d ff3e:5e ff3f:5f ff40:60 ff41:61 ff42:62 ff43:63 ff44:64 ff45:65 ff46:66 ff47:67 ff48:68 ff49:69 ff4a:6a ff4b:6b ff4c:6c ff4d:6d ff4e:6e ff4f:6f ff50:70 ff51:71 ff52:72 ff53:73 ff54:74 ff55:75 ff56:76 ff57:77 ff58:78 ff59:79 ff5a:7a ff5b:7b ff5c:7c ff5d:7d ff5e:7e \r\n\r\n1252  (ANSI - Latin I)\r\n0100:41 0101:61 0102:41 0103:61 0104:41 0105:61 0106:43 0107:63 0108:43 0109:63 010a:43 010b:63 010c:43 010d:63 010e:44 010f:64 0111:64 0112:45 0113:65 0114:45 0115:65 0116:45 0117:65 0118:45 0119:65 011a:45 011b:65 011c:47 011d:67 011e:47 011f:67 0120:47 0121:67 0122:47 0123:67 0124:48 0125:68 0126:48 0127:68 0128:49 0129:69 012a:49 012b:69 012c:49 012d:69 012e:49 012f:69 0130:49 0131:69 0134:4a 0135:6a 0136:4b 0137:6b 0139:4c 013a:6c 013b:4c 013c:6c 013d:4c 013e:6c 0141:4c 0142:6c 0143:4e 0144:6e 0145:4e 0146:6e 0147:4e 0148:6e 014c:4f 014d:6f 014e:4f 014f:6f 0150:4f 0151:6f 0154:52 0155:72 0156:52 0157:72 0158:52 0159:72 015a:53 015b:73 015c:53 015d:73 015e:53 015f:73 0162:54 0163:74 0164:54 0165:74 0166:54 0167:74 0168:55 0169:75 016a:55 016b:75 016c:55 016d:75 016e:55 016f:75 0170:55 0171:75 0172:55 0173:75 0174:57 0175:77 0176:59 0177:79 0179:5a 017b:5a 017c:7a 0180:62 0197:49 019a:6c 019f:4f 01a0:4f 01a1:6f 01ab:74 01ae:54 01af:55 01b0:75 01b6:7a 01c0:7c 01c3:21 01cd:41 01ce:61 01cf:49 01d0:69 01d1:4f 01d2:6f 01d3:55 01d4:75 01d5:55 01d6:75 01d7:55 01d8:75 01d9:55 01da:75 01db:55 01dc:75 01de:41 01df:61 01e4:47 01e5:67 01e6:47 01e7:67 01e8:4b 01e9:6b 01ea:4f 01eb:6f 01ec:4f 01ed:6f 01f0:6a 0261:67 02b9:27 02ba:22 02bc:27 02c4:5e 02c8:27 02cb:60 02cd:5f 0300:60 0302:5e 0303:7e 030e:22 0331:5f 0332:5f 037e:3b 0393:47 0398:54 03a3:53 03a6:46 03a9:4f 03b1:61 03b4:64 03b5:65 03c0:70 03c3:73 03c4:74 03c6:66 04bb:68 0589:3a 066a:25 2000:20 2001:20 2002:20 2003:20 2004:20 2005:20 2006:20 2010:2d 2011:2d 2017:3d 2032:27 2035:60 2044:2f 2074:34 2075:35 2076:36 2077:37 2078:38 207f:6e 2080:30 2081:31 2082:32 2083:33 2084:34 2085:35 2086:36 2087:37 2088:38 2089:39 20a7:50 2102:43 2107:45 210a:67 210b:48 210c:48 210d:48 210e:68 2110:49 2111:49 2112:4c 2113:6c 2115:4e 2118:50 2119:50 211a:51 211b:52 211c:52 211d:52 2124:5a 2128:5a 212a:4b 212c:42 212d:43 212e:65 212f:65 2130:45 2131:46 2133:4d 2134:6f 2212:2d 2215:2f 2216:5c 2217:2a 221a:76 221e:38 2223:7c 2229:6e 2236:3a 223c:7e 2261:3d 2264:3d 2265:3d 2303:5e 2320:28 2321:29 2329:3c 232a:3e 2500:2d 250c:2b 2510:2b 2514:2b 2518:2b 251c:2b 252c:2d 2534:2d 253c:2b 2550:2d 2552:2b 2553:2b 2554:2b 2555:2b 2556:2b 2557:2b 2558:2b 2559:2b 255a:2b 255b:2b 255c:2b 255d:2b 2564:2d 2565:2d 2566:2d 2567:2d 2568:2d 2569:2d 256a:2b 256b:2b 256c:2b 2584:5f 2758:7c 3000:20 3008:3c 3009:3e 301a:5b 301b:5d ff01:21 ff02:22 ff03:23 ff04:24 ff05:25 ff06:26 ff07:27 ff08:28 ff09:29 ff0a:2a ff0b:2b ff0c:2c ff0d:2d ff0e:2e ff0f:2f ff10:30 ff11:31 ff12:32 ff13:33 ff14:34 ff15:35 ff16:36 ff17:37 ff18:38 ff19:39 ff1a:3a ff1b:3b ff1c:3c ff1d:3d ff1e:3e ff20:40 ff21:41 ff22:42 ff23:43 ff24:44 ff25:45 ff26:46 ff27:47 ff28:48 ff29:49 ff2a:4a ff2b:4b ff2c:4c ff2d:4d ff2e:4e ff2f:4f ff30:50 ff31:51 ff32:52 ff33:53 ff34:54 ff35:55 ff36:56 ff37:57 ff38:58 ff39:59 ff3a:5a ff3b:5b ff3c:5c ff3d:5d ff3e:5e ff3f:5f ff40:60 ff41:61 ff42:62 ff43:63 ff44:64 ff45:65 ff46:66 ff47:67 ff48:68 ff49:69 ff4a:6a ff4b:6b ff4c:6c ff4d:6d ff4e:6e ff4f:6f ff50:70 ff51:71 ff52:72 ff53:73 ff54:74 ff55:75 ff56:76 ff57:77 ff58:78 ff59:79 ff5a:7a ff5b:7b ff5c:7c ff5d:7d ff5e:7e \r\n\r\n1253  (ANSI - Greek)\r\n00b4:2f 00c0:41 00c1:41 00c2:41 00c3:41 00c4:41 00c5:41 00c7:43 00c8:45 00c9:45 00ca:45 00cb:45 00cc:49 00cd:49 00ce:49 00cf:49 00d1:4e 00d2:4f 00d3:4f 00d4:4f 00d5:4f 00d6:4f 00d8:4f 00d9:55 00da:55 00db:55 00dc:55 00dd:59 00e0:61 00e1:61 00e2:61 00e3:61 00e4:61 00e5:61 00e7:63 00e8:65 00e9:65 00ea:65 00eb:65 00ec:69 00ed:69 00ee:69 00ef:69 00f1:6e 00f2:6f 00f3:6f 00f4:6f 00f5:6f 00f6:6f 00f8:6f 00f9:75 00fa:75 00fb:75 00fc:75 00fd:79 00ff:79 0100:41 0101:61 0102:41 0103:61 0104:41 0105:61 0106:43 0107:63 0108:43 0109:63 010a:43 010b:63 010c:43 010d:63 010e:44 010f:64 0110:44 0111:64 0112:45 0113:65 0114:45 0115:65 0116:45 0117:65 0118:45 0119:65 011a:45 011b:65 011c:47 011d:67 011e:47 011f:67 0120:47 0121:67 0122:47 0123:67 0124:48 0125:68 0126:48 0127:68 0128:49 0129:69 012a:49 012b:69 012c:49 012d:69 012e:49 012f:69 0130:49 0134:4a 0135:6a 0136:4b 0137:6b 0139:4c 013a:6c 013b:4c 013c:6c 013d:4c 013e:6c 0141:4c 0142:6c 0143:4e 0144:6e 0145:4e 0146:6e 0147:4e 0148:6e 014c:4f 014d:6f 014e:4f 014f:6f 0150:4f 0151:6f 0154:52 0155:72 0156:52 0157:72 0158:52 0159:72 015a:53 015b:73 015c:53 015d:73 015e:53 015f:73 0160:53 0161:73 0162:54 0163:74 0164:54 0165:74 0166:54 0167:74 0168:55 0169:75 016a:55 016b:75 016c:55 016d:75 016e:55 016f:75 0170:55 0171:75 0172:55 0173:75 0174:57 0175:77 0176:59 0177:79 0178:59 0179:5a 017b:5a 017c:7a 017d:5a 017e:7a 0180:62 0197:49 019a:6c 019f:4f 01a0:4f 01a1:6f 01ab:74 01ae:54 01af:55 01b0:75 01cd:41 01ce:61 01cf:49 01d0:69 01d1:4f 01d2:6f 01d3:55 01d4:75 01d5:55 01d6:75 01d7:55 01d8:75 01d9:55 01da:75 01db:55 01dc:75 01de:41 01df:61 01e4:47 01e5:67 01e6:47 01e7:67 01e8:4b 01e9:6b 01ea:4f 01eb:6f 01ec:4f 01ed:6f 01f0:6a 037e:3b 203c:21 2190:3c 2191:5e 2192:3e 2193:76 2194:2d 221f:4c 2500:2d 250c:2d 2514:4c 2518:2d 251c:2b 2524:2b 252c:54 2534:2b 253c:2b 2550:3d 2554:2d 255a:4c 255d:2d 2566:54 256c:2b 2580:2d 2584:2d 2588:2d 2591:2d 2592:2d 2593:2d 25ac:2d 25b2:5e 25ba:3e 25c4:3c 25cb:30 25d9:30 263a:4f 263b:4f 263c:30 2640:2b 2642:3e 266a:64 266b:64 ff01:21 ff02:22 ff03:23 ff04:24 ff05:25 ff06:26 ff07:27 ff08:28 ff09:29 ff0a:2a ff0b:2b ff0c:2c ff0d:2d ff0e:2e ff0f:2f ff10:30 ff11:31 ff12:32 ff13:33 ff14:34 ff15:35 ff16:36 ff17:37 ff18:38 ff19:39 ff1a:3a ff1b:3b ff1c:3c ff1d:3d ff1e:3e ff20:40 ff21:41 ff22:42 ff23:43 ff24:44 ff25:45 ff26:46 ff27:47 ff28:48 ff29:49 ff2a:4a ff2b:4b ff2c:4c ff2d:4d ff2e:4e ff2f:4f ff30:50 ff31:51 ff32:52 ff33:53 ff34:54 ff35:55 ff36:56 ff37:57 ff38:58 ff39:59 ff3a:5a ff3b:5b ff3c:5c ff3d:5d ff3e:5e ff3f:5f ff40:60 ff41:61 ff42:62 ff43:63 ff44:64 ff45:65 ff46:66 ff47:67 ff48:68 ff49:69 ff4a:6a ff4b:6b ff4c:6c ff4d:6d ff4e:6e ff4f:6f ff50:70 ff51:71 ff52:72 ff53:73 ff54:74 ff55:75 ff56:76 ff57:77 ff58:78 ff59:79 ff5a:7a ff5b:7b ff5c:7c ff5d:7d ff5e:7e \r\n\r\n1254  (ANSI - Turkish)\r\n00dd:59 00fd:79 0100:41 0101:61 0102:41 0103:61 0104:41 0105:61 0106:43 0107:63 0108:43 0109:63 010a:43 010b:63 010c:43 010d:63 010e:44 010f:64 0110:44 0111:64 0112:45 0113:65 0114:45 0115:65 0116:45 0117:65 0118:45 0119:65 011a:45 011b:65 011c:47 011d:67 0120:47 0121:67 0122:47 0123:67 0124:48 0125:68 0126:48 0127:68 0128:49 0129:69 012a:49 012b:69 012c:49 012d:69 012e:49 012f:69 0134:4a 0135:6a 0136:4b 0137:6b 0139:4c 013a:6c 013b:4c 013c:6c 013d:4c 013e:6c 0141:4c 0142:6c 0143:4e 0144:6e 0145:4e 0146:6e 0147:4e 0148:6e 014c:4f 014d:6f 014e:4f 014f:6f 0150:4f 0151:6f 0154:52 0155:72 0156:52 0157:72 0158:52 0159:72 015a:53 015b:73 015c:53 015d:73 0162:54 0163:74 0164:54 0165:74 0166:54 0167:74 0168:55 0169:75 016a:55 016b:75 016c:55 016d:75 016e:55 016f:75 0170:55 0171:75 0172:55 0173:75 0174:57 0175:77 0176:59 0177:79 0179:5a 017b:5a 017c:7a 017d:5a 017e:7a 0180:62 0189:44 0197:49 019a:6c 019f:4f 01a0:4f 01a1:6f 01ab:74 01ae:54 01af:55 01b0:75 01b6:7a 01c0:7c 01c3:21 01cd:41 01ce:61 01cf:49 01d0:69 01d1:4f 01d2:6f 01d3:55 01d4:75 01d5:55 01d6:75 01d7:55 01d8:75 01d9:55 01da:75 01db:55 01dc:75 01de:41 01df:61 01e4:47 01e5:67 01e6:47 01e7:67 01e8:4b 01e9:6b 01ea:4f 01eb:6f 01ec:4f 01ed:6f 01f0:6a 0261:67 02b9:27 02ba:22 02bc:27 02c4:5e 02c7:5e 02c8:27 02cb:60 02cd:5f 02d8:5e 02d9:27 0300:60 0302:5e 0331:5f 0332:5f 04bb:68 0589:3a 066a:25 2000:20 2001:20 2002:20 2003:20 2004:20 2005:20 2006:20 2010:2d 2011:2d 2032:27 2035:60 203c:21 2044:2f 2074:34 2075:35 2076:36 2077:37 2078:38 2081:30 2084:34 2085:35 2086:36 2087:37 2088:38 2089:39 2102:43 2107:45 210a:67 210b:48 210c:48 210d:48 210e:68 2110:49 2111:49 2112:4c 2113:6c 2115:4e 2118:50 2119:50 211a:51 211b:52 211c:52 211d:52 2124:5a 2128:5a 212a:4b 212c:42 212d:43 212e:65 212f:65 2130:45 2131:46 2133:4d 2134:6f 2191:5e 2193:76 2194:2d 2195:7c 21a8:7c 2212:2d 2215:2f 2216:5c 2217:2a 221f:4c 2223:7c 2236:3a 223c:7e 2303:5e 2329:3c 232a:3e 2502:2d 250c:2d 2514:4c 2518:2d 251c:2b 2524:2b 252c:54 2534:2b 253c:2b 2550:3d 2554:2d 255a:4c 255d:2d 2566:54 256c:2b 2580:2d 2584:2d 2588:2d 2591:2d 2592:2d 2593:2d 25ac:2d 25b2:5e 25ba:3e 25c4:3c 25cb:30 25d9:30 263a:4f 263b:4f 263c:30 2640:2b 2642:3e 266a:64 266b:64 2758:7c 3000:20 3008:3c 3009:3e 301a:5b 301b:3d 301d:22 301e:22 ff01:21 ff02:22 ff03:23 ff04:24 ff05:25 ff06:26 ff07:27 ff08:28 ff09:29 ff0a:2a ff0b:2b ff0c:2c ff0d:2d ff0e:2e ff0f:2f ff10:30 ff11:31 ff12:32 ff13:33 ff14:34 ff15:35 ff16:36 ff17:37 ff18:38 ff19:39 ff1a:3a ff1b:3b ff1c:3c ff1d:3d ff1e:3e ff20:40 ff21:41 ff22:42 ff23:43 ff24:44 ff25:45 ff26:46 ff27:47 ff28:48 ff29:49 ff2a:4a ff2b:4b ff2c:4c ff2d:4d ff2e:4e ff2f:4f ff30:50 ff31:51 ff32:52 ff33:53 ff34:54 ff35:55 ff36:56 ff37:57 ff38:58 ff39:59 ff3a:5a ff3b:5b ff3c:5c ff3d:5d ff3e:5e ff3f:5f ff40:60 ff41:61 ff42:62 ff43:63 ff44:64 ff45:65 ff46:66 ff47:67 ff48:68 ff49:69 ff4a:6a ff4b:6b ff4c:6c ff4d:6d ff4e:6e ff4f:6f ff50:70 ff51:71 ff52:72 ff53:73 ff54:74 ff55:75 ff56:76 ff57:77 ff58:78 ff59:79 ff5a:7a ff5b:7b ff5c:7c ff5d:7d ff5e:7e \r\n\r\n1255  (ANSI - Hebrew)\r\n0191:46 ff01:21 ff02:22 ff03:23 ff04:24 ff05:25 ff06:26 ff07:27 ff08:28 ff09:29 ff0a:2a ff0b:2b ff0c:2c ff0d:2d ff0e:2e ff0f:2f ff10:30 ff11:31 ff12:32 ff13:33 ff14:34 ff15:35 ff16:36 ff17:37 ff18:38 ff19:39 ff1a:3a ff1b:3b ff1c:3c ff1d:3d ff1e:3e ff20:40 ff21:41 ff22:42 ff23:43 ff24:44 ff25:45 ff26:46 ff27:47 ff28:48 ff29:49 ff2a:4a ff2b:4b ff2c:4c ff2d:4d ff2e:4e ff2f:4f ff30:50 ff31:51 ff32:52 ff33:53 ff34:54 ff35:55 ff36:56 ff37:57 ff38:58 ff39:59 ff3a:5a ff3b:5b ff3c:5c ff3d:5d ff3e:5e ff3f:5f ff40:60 ff41:61 ff42:62 ff43:63 ff44:64 ff45:65 ff46:66 ff47:67 ff48:68 ff49:69 ff4a:6a ff4b:6b ff4c:6c ff4d:6d ff4e:6e ff4f:6f ff50:70 ff51:71 ff52:72 ff53:73 ff54:74 ff55:75 ff56:76 ff57:77 ff58:78 ff59:79 ff5a:7a ff5b:7b ff5c:7c ff5d:7d ff5e:7e \r\n\r\n1256  (ANSI - Arabic)\r\n0620:41 0621:41 0622:43 0623:45 0624:45 0625:45 0626:45 0627:49 0628:49 0629:4f 062a:55 062b:55 062c:55 062d:46 062e:43 062f:44 0630:45 0631:46 0632:47 0633:48 0634:49 0635:4a 0636:4b 0637:4c 0638:4d 0639:4e 063a:4f 0641:41 0642:42 0643:43 0644:44 0645:45 0646:46 0647:47 0648:48 0649:49 064a:4a 064b:4b 064c:4c 064d:4d 064e:4e 064f:4f 0650:50 0651:51 0652:52 \r\n\r\n1257  (ANSI - Baltic)\r\nff01:21 ff02:22 ff03:23 ff04:24 ff05:25 ff06:26 ff07:27 ff08:28 ff09:29 ff0a:2a ff0b:2b ff0c:2c ff0d:2d ff0e:2e ff0f:2f ff10:30 ff11:31 ff12:32 ff13:33 ff14:34 ff15:35 ff16:36 ff17:37 ff18:38 ff19:39 ff1a:3a ff1b:3b ff1c:3c ff1d:3d ff1e:3e ff20:40 ff21:41 ff22:42 ff23:43 ff24:44 ff25:45 ff26:46 ff27:47 ff28:48 ff29:49 ff2a:4a ff2b:4b ff2c:4c ff2d:4d ff2e:4e ff2f:4f ff30:50 ff31:51 ff32:52 ff33:53 ff34:54 ff35:55 ff36:56 ff37:57 ff38:58 ff39:59 ff3a:5a ff3b:5b ff3c:5c ff3d:5d ff3e:5e ff3f:5f ff40:60 ff41:61 ff42:62 ff43:63 ff44:64 ff45:65 ff46:66 ff47:67 ff48:68 ff49:69 ff4a:6a ff4b:6b ff4c:6c ff4d:6d ff4e:6e ff4f:6f ff50:70 ff51:71 ff52:72 ff53:73 ff54:74 ff55:75 ff56:76 ff57:77 ff58:78 ff59:79 ff5a:7a ff5b:7b ff5c:7c ff5d:7d ff5e:7e \r\n\r\n1258  (ANSI/OEM - Viet Nam)\r\nff01:21 ff02:22 ff03:23 ff04:24 ff05:25 ff06:26 ff07:27 ff08:28 ff09:29 ff0a:2a ff0b:2b ff0c:2c ff0d:2d ff0e:2e ff0f:2f ff10:30 ff11:31 ff12:32 ff13:33 ff14:34 ff15:35 ff16:36 ff17:37 ff18:38 ff19:39 ff1a:3a ff1b:3b ff1c:3c ff1d:3d ff1e:3e ff20:40 ff21:41 ff22:42 ff23:43 ff24:44 ff25:45 ff26:46 ff27:47 ff28:48 ff29:49 ff2a:4a ff2b:4b ff2c:4c ff2d:4d ff2e:4e ff2f:4f ff30:50 ff31:51 ff32:52 ff33:53 ff34:54 ff35:55 ff36:56 ff37:57 ff38:58 ff39:59 ff3a:5a ff3b:5b ff3c:5c ff3d:5d ff3e:5e ff3f:5f ff40:60 ff41:61 ff42:62 ff43:63 ff44:64 ff45:65 ff46:66 ff47:67 ff48:68 ff49:69 ff4a:6a ff4b:6b ff4c:6c ff4d:6d ff4e:6e ff4f:6f ff50:70 ff51:71 ff52:72 ff53:73 ff54:74 ff55:75 ff56:76 ff57:77 ff58:78 ff59:79 ff5a:7a ff5b:7b ff5c:7c ff5d:7d ff5e:7e \r\n\r\n20127 (US-ASCII)\r\n00a0:20 00a1:21 00a2:63 00a4:24 00a5:59 00a6:7c 00a9:43 00aa:61 00ab:3c 00ad:2d 00ae:52 00b2:32 00b3:33 00b7:2e 00b8:2c 00b9:31 00ba:6f 00bb:3e 00c0:41 00c1:41 00c2:41 00c3:41 00c4:41 00c5:41 00c6:41 00c7:43 00c8:45 00c9:45 00ca:45 00cb:45 00cc:49 00cd:49 00ce:49 00cf:49 00d0:44 00d1:4e 00d2:4f 00d3:4f 00d4:4f 00d5:4f 00d6:4f 00d8:4f 00d9:55 00da:55 00db:55 00dc:55 00dd:59 00e0:61 00e1:61 00e2:61 00e3:61 00e4:61 00e5:61 00e6:61 00e7:63 00e8:65 00e9:65 00ea:65 00eb:65 00ec:69 00ed:69 00ee:69 00ef:69 00f1:6e 00f2:6f 00f3:6f 00f4:6f 00f5:6f 00f6:6f 00f8:6f 00f9:75 00fa:75 00fb:75 00fc:75 00fd:79 00ff:79 0100:41 0101:61 0102:41 0103:61 0104:41 0105:61 0106:43 0107:63 0108:43 0109:63 010a:43 010b:63 010c:43 010d:63 010e:44 010f:64 0110:44 0111:64 0112:45 0113:65 0114:45 0115:65 0116:45 0117:65 0118:45 0119:65 011a:45 011b:65 011c:47 011d:67 011e:47 011f:67 0120:47 0121:67 0122:47 0123:67 0124:48 0125:68 0126:48 0127:68 0128:49 0129:69 012a:49 012b:69 012c:49 012d:69 012e:49 012f:69 0130:49 0131:69 0134:4a 0135:6a 0136:4b 0137:6b 0139:4c 013a:6c 013b:4c 013c:6c 013d:4c 013e:6c 0141:4c 0142:6c 0143:4e 0144:6e 0145:4e 0146:6e 0147:4e 0148:6e 014c:4f 014d:6f 014e:4f 014f:6f 0150:4f 0151:6f 0152:4f 0153:6f 0154:52 0155:72 0156:52 0157:72 0158:52 0159:72 015a:53 015b:73 015c:53 015d:73 015e:53 015f:73 0160:53 0161:73 0162:54 0163:74 0164:54 0165:74 0166:54 0167:74 0168:55 0169:75 016a:55 016b:75 016c:55 016d:75 016e:55 016f:75 0170:55 0171:75 0172:55 0173:75 0174:57 0175:77 0176:59 0177:79 0178:59 0179:5a 017b:5a 017c:7a 017d:5a 017e:7a 0180:62 0189:44 0191:46 0192:66 0197:49 019a:6c 019f:4f 01a0:4f 01a1:6f 01ab:74 01ae:54 01af:55 01b0:75 01b6:7a 01cd:41 01ce:61 01cf:49 01d0:69 01d1:4f 01d2:6f 01d3:55 01d4:75 01d5:55 01d6:75 01d7:55 01d8:75 01d9:55 01da:75 01db:55 01dc:75 01de:41 01df:61 01e4:47 01e5:67 01e6:47 01e7:67 01e8:4b 01e9:6b 01ea:4f 01eb:6f 01ec:4f 01ed:6f 01f0:6a 0261:67 02b9:27 02ba:22 02bc:27 02c4:5e 02c6:5e 02c8:27 02cb:60 02cd:5f 02dc:7e 0300:60 0302:5e 0303:7e 030e:22 0331:5f 0332:5f 2000:20 2001:20 2002:20 2003:20 2004:20 2005:20 2006:20 2010:2d 2011:2d 2013:2d 2014:2d 2018:27 2019:27 201a:2c 201c:22 201d:22 201e:22 2022:2e 2026:2e 2032:27 2035:60 2039:3c 203a:3e 2122:54 ff01:21 ff02:22 ff03:23 ff04:24 ff05:25 ff06:26 ff07:27 ff08:28 ff09:29 ff0a:2a ff0b:2b ff0c:2c ff0d:2d ff0e:2e ff0f:2f ff10:30 ff11:31 ff12:32 ff13:33 ff14:34 ff15:35 ff16:36 ff17:37 ff18:38 ff19:39 ff1a:3a ff1b:3b ff1c:3c ff1d:3d ff1e:3e ff20:40 ff21:41 ff22:42 ff23:43 ff24:44 ff25:45 ff26:46 ff27:47 ff28:48 ff29:49 ff2a:4a ff2b:4b ff2c:4c ff2d:4d ff2e:4e ff2f:4f ff30:50 ff31:51 ff32:52 ff33:53 ff34:54 ff35:55 ff36:56 ff37:57 ff38:58 ff39:59 ff3a:5a ff3b:5b ff3c:5c ff3d:5d ff3e:5e ff3f:5f ff40:60 ff41:61 ff42:62 ff43:63 ff44:64 ff45:65 ff46:66 ff47:67 ff48:68 ff49:69 ff4a:6a ff4b:6b ff4c:6c ff4d:6d ff4e:6e ff4f:6f ff50:70 ff51:71 ff52:72 ff53:73 ff54:74 ff55:75 ff56:76 ff57:77 ff58:78 ff59:79 ff5a:7a ff5b:7b ff5c:7c ff5d:7d ff5e:7e \r\n\r\n20261 (T.61)\r\nf8dd:5c f8de:5e f8df:60 f8e0:7b f8fc:7d f8fd:7e f8fe:7f \r\n\r\n20866 (Russian - KOI8)\r\n00a7:15 00ab:3c 00ad:2d 00ae:52 00b1:2b 00b6:14 00bb:3e 00c0:41 00c1:41 00c2:41 00c3:41 00c4:41 00c5:41 00c7:43 00c8:45 00c9:45 00ca:45 00cb:45 00cc:49 00cd:49 00ce:49 00cf:49 00d1:4e 00d2:4f 00d3:4f 00d4:4f 00d5:4f 00d6:4f 00d8:4f 00d9:55 00da:55 00db:55 00dc:55 00dd:59 00e0:61 00e1:61 00e2:61 00e3:61 00e4:61 00e5:61 00e7:63 00e8:65 00e9:65 00ea:65 00eb:65 00ec:69 00ed:69 00ee:69 00ef:69 00f1:6e 00f2:6f 00f3:6f 00f4:6f 00f5:6f 00f6:6f 00f8:6f 00f9:75 00fa:75 00fb:75 00fc:75 00fd:79 00ff:79 0100:41 0101:61 0102:41 0103:61 0104:41 0105:61 0106:43 0107:63 0108:43 0109:63 010a:43 010b:63 010c:43 010d:63 010e:44 010f:64 0110:44 0111:64 0112:45 0113:65 0114:45 0115:65 0116:45 0117:65 0118:45 0119:65 011a:45 011b:65 011c:47 011d:67 011e:47 011f:67 0120:47 0121:67 0122:47 0123:67 0124:48 0125:68 0126:48 0127:68 0128:49 0129:69 012a:49 012b:69 012c:49 012d:69 012e:49 012f:69 0130:49 0134:4a 0135:6a 0136:4b 0137:6b 0139:4c 013a:6c 013b:4c 013c:6c 013d:4c 013e:6c 0141:4c 0142:6c 0143:4e 0144:6e 0145:4e 0146:6e 0147:4e 0148:6e 014c:4f 014d:6f 014e:4f 014f:6f 0150:4f 0151:6f 0154:52 0155:72 0156:52 0157:72 0158:52 0159:72 015a:53 015b:73 015c:53 015d:73 015e:53 015f:73 0160:53 0161:73 0162:54 0163:74 0164:54 0165:74 0166:54 0167:74 0168:55 0169:75 016a:55 016b:75 016c:55 016d:75 016e:55 016f:75 0170:55 0171:75 0172:55 0173:75 0174:57 0175:77 0176:59 0177:79 0178:59 0179:5a 017b:5a 017c:7a 017d:5a 017e:7a 0180:62 0197:49 019a:6c 019f:4f 01a0:4f 01a1:6f 01ab:74 01ae:54 01af:55 01b0:75 01cd:41 01ce:61 01cf:49 01d0:69 01d1:4f 01d2:6f 01d3:55 01d4:75 01d5:55 01d6:75 01d7:55 01d8:75 01d9:55 01da:75 01db:55 01dc:75 01de:41 01df:61 01e4:47 01e5:67 01e6:47 01e7:67 01e8:4b 01e9:6b 01ea:4f 01eb:6f 01ec:4f 01ed:6f 01f0:6a 2013:2d 2014:2d 2018:27 2019:27 201a:27 201c:22 201d:22 201e:22 2022:07 2026:3a 2030:25 2039:3c 203a:3e 203c:13 2122:54 2190:1b 2191:18 2192:1a 2193:19 2194:1d 2195:12 21a8:17 221f:1c 2302:7f 25ac:16 25b2:1e 25ba:10 25bc:1f 25c4:11 25cb:09 25d8:08 25d9:0a 263a:01 263b:02 263c:0f 2640:0c 2642:0b 2660:06 2663:05 2665:03 2666:04 266a:0d 266b:0e \r\n\r\n28591 (ISO 8859-1 Latin I)\r\n0100:41 0101:61 0102:41 0103:61 0104:41 0105:61 0106:43 0107:63 0108:43 0109:63 010a:43 010b:63 010c:43 010d:63 010e:44 010f:64 0110:44 0111:64 0112:45 0113:65 0114:45 0115:65 0116:45 0117:65 0118:45 0119:65 011a:45 011b:65 011c:47 011d:67 011e:47 011f:67 0120:47 0121:67 0122:47 0123:67 0124:48 0125:68 0126:48 0127:68 0128:49 0129:69 012a:49 012b:69 012c:49 012d:69 012e:49 012f:69 0130:49 0131:69 0134:4a 0135:6a 0136:4b 0137:6b 0139:4c 013a:6c 013b:4c 013c:6c 013d:4c 013e:6c 0141:4c 0142:6c 0143:4e 0144:6e 0145:4e 0146:6e 0147:4e 0148:6e 014c:4f 014d:6f 014e:4f 014f:6f 0150:4f 0151:6f 0152:4f 0153:6f 0154:52 0155:72 0156:52 0157:72 0158:52 0159:72 015a:53 015b:73 015c:53 015d:73 015e:53 015f:73 0160:53 0161:73 0162:54 0163:74 0164:54 0165:74 0166:54 0167:74 0168:55 0169:75 016a:55 016b:75 016c:55 016d:75 016e:55 016f:75 0170:55 0171:75 0172:55 0173:75 0174:57 0175:77 0176:59 0177:79 0178:59 0179:5a 017b:5a 017c:7a 017d:5a 017e:7a 0180:62 0189:44 0191:46 0192:66 0197:49 019a:6c 019f:4f 01a0:4f 01a1:6f 01ab:74 01ae:54 01af:55 01b0:75 01b6:7a 01cd:41 01ce:61 01cf:49 01d0:69 01d1:4f 01d2:6f 01d3:55 01d4:75 01d5:55 01d6:75 01d7:55 01d8:75 01d9:55 01da:75 01db:55 01dc:75 01de:41 01df:61 01e4:47 01e5:67 01e6:47 01e7:67 01e8:4b 01e9:6b 01ea:4f 01eb:6f 01ec:4f 01ed:6f 01f0:6a 0261:67 02b9:27 02ba:22 02bc:27 02c4:5e 02c6:5e 02c8:27 02cb:60 02cd:5f 02dc:7e 0300:60 0302:5e 0303:7e 030e:22 0331:5f 0332:5f 2000:20 2001:20 2002:20 2003:20 2004:20 2005:20 2006:20 2010:2d 2011:2d 2013:2d 2014:2d 2018:27 2019:27 201a:2c 201c:22 201d:22 201e:22 2022:2e 2026:2e 2032:27 2035:60 2039:3c 203a:3e 2122:54 ff01:21 ff02:22 ff03:23 ff04:24 ff05:25 ff06:26 ff07:27 ff08:28 ff09:29 ff0a:2a ff0b:2b ff0c:2c ff0d:2d ff0e:2e ff0f:2f ff10:30 ff11:31 ff12:32 ff13:33 ff14:34 ff15:35 ff16:36 ff17:37 ff18:38 ff19:39 ff1a:3a ff1b:3b ff1c:3c ff1d:3d ff1e:3e ff20:40 ff21:41 ff22:42 ff23:43 ff24:44 ff25:45 ff26:46 ff27:47 ff28:48 ff29:49 ff2a:4a ff2b:4b ff2c:4c ff2d:4d ff2e:4e ff2f:4f ff30:50 ff31:51 ff32:52 ff33:53 ff34:54 ff35:55 ff36:56 ff37:57 ff38:58 ff39:59 ff3a:5a ff3b:5b ff3c:5c ff3d:5d ff3e:5e ff3f:5f ff40:60 ff41:61 ff42:62 ff43:63 ff44:64 ff45:65 ff46:66 ff47:67 ff48:68 ff49:69 ff4a:6a ff4b:6b ff4c:6c ff4d:6d ff4e:6e ff4f:6f ff50:70 ff51:71 ff52:72 ff53:73 ff54:74 ff55:75 ff56:76 ff57:77 ff58:78 ff59:79 ff5a:7a ff5b:7b ff5c:7c ff5d:7d ff5e:7e \r\n\r\n28592 (ISO 8859-2 Central Europe)\r\n00a1:21 00a2:63 00a5:59 00a6:7c 00a9:43 00aa:61 00ab:3c 00ae:52 00b2:32 00b3:33 00b7:2e 00b9:31 00ba:6f 00bb:3e 00c0:41 00c3:41 00c5:41 00c6:41 00c8:45 00ca:45 00cc:49 00cf:49 00d0:44 00d1:4e 00d2:4f 00d5:4f 00d8:4f 00d9:55 00db:55 00e0:61 00e3:61 00e5:61 00e6:61 00e8:65 00ea:65 00ec:69 00ef:69 00f1:6e 00f2:6f 00f5:6f 00f8:6f 00f9:75 00fb:75 00ff:79 0100:41 0101:61 0108:43 0109:63 010a:43 010b:63 0112:45 0113:65 0114:45 0115:65 0116:45 0117:65 011c:47 011d:67 011e:47 011f:67 0120:47 0121:67 0122:47 0123:67 0124:48 0125:68 0126:48 0127:68 0128:49 0129:69 012a:49 012b:69 012c:49 012d:69 012e:49 012f:69 0130:49 0131:69 0134:4a 0135:6a 0136:4b 0137:6b 013b:4c 013c:6c 0145:4e 0146:6e 014c:4f 014d:6f 014e:4f 014f:6f 0152:4f 0153:6f 0156:52 0157:72 015c:53 015d:73 0166:54 0167:74 0168:55 0169:75 016a:55 016b:75 016c:55 016d:75 0172:55 0173:75 0174:57 0175:77 0176:59 0177:79 0178:59 0180:62 0189:44 0191:46 0192:66 0197:49 019a:6c 019f:4f 01a0:4f 01a1:6f 01ab:74 01ae:54 01af:55 01b0:75 01b6:7a 01cd:41 01ce:61 01cf:49 01d0:69 01d1:4f 01d2:6f 01d3:55 01d4:75 01d5:55 01d6:75 01d7:55 01d8:75 01d9:55 01da:75 01db:55 01dc:75 01de:41 01df:61 01e4:47 01e5:67 01e6:47 01e7:67 01e8:4b 01e9:6b 01ea:4f 01eb:6f 01ec:4f 01ed:6f 01f0:6a 0261:67 02b9:27 02ba:22 02bc:27 02c4:5e 02c6:5e 02c8:27 02cb:60 02cd:5f 02dc:7e 0300:60 0302:5e 0303:7e 030e:22 0331:5f 0332:5f 2000:20 2001:20 2002:20 2003:20 2004:20 2005:20 2006:20 2010:2d 2011:2d 2013:2d 2014:2d 2018:27 2019:27 201a:2c 201c:22 201d:22 201e:22 2022:2e 2026:2e 2032:27 2035:60 2039:3c 203a:3e 2122:54 ff01:21 ff02:22 ff03:23 ff04:24 ff05:25 ff06:26 ff07:27 ff08:28 ff09:29 ff0a:2a ff0b:2b ff0c:2c ff0d:2d ff0e:2e ff0f:2f ff10:30 ff11:31 ff12:32 ff13:33 ff14:34 ff15:35 ff16:36 ff17:37 ff18:38 ff19:39 ff1a:3a ff1b:3b ff1c:3c ff1d:3d ff1e:3e ff20:40 ff21:41 ff22:42 ff23:43 ff24:44 ff25:45 ff26:46 ff27:47 ff28:48 ff29:49 ff2a:4a ff2b:4b ff2c:4c ff2d:4d ff2e:4e ff2f:4f ff30:50 ff31:51 ff32:52 ff33:53 ff34:54 ff35:55 ff36:56 ff37:57 ff38:58 ff39:59 ff3a:5a ff3b:5b ff3c:5c ff3d:5d ff3e:5e ff3f:5f ff40:60 ff41:61 ff42:62 ff43:63 ff44:64 ff45:65 ff46:66 ff47:67 ff48:68 ff49:69 ff4a:6a ff4b:6b ff4c:6c ff4d:6d ff4e:6e ff4f:6f ff50:70 ff51:71 ff52:72 ff53:73 ff54:74 ff55:75 ff56:76 ff57:77 ff58:78 ff59:79 ff5a:7a ff5b:7b ff5c:7c ff5d:7d ff5e:7e \r\n\r\n28605 (ISO 8859-15 Latin 9)\r\n00a6:7c 0100:41 0101:61 0102:41 0103:61 0104:41 0105:61 0106:43 0107:63 0108:43 0109:63 010a:43 010b:63 010c:43 010d:63 010e:44 010f:64 0112:45 0113:65 0114:45 0115:65 0116:45 0117:65 0118:45 0119:65 011a:45 011b:65 011c:47 011d:67 011e:47 011f:67 0120:47 0121:67 0122:47 0123:67 0124:48 0125:68 0126:48 0127:68 0128:49 0129:69 012a:49 012b:69 012c:49 012d:69 012e:49 012f:69 0130:49 0131:69 0134:4a 0135:6a 0136:4b 0137:6b 0138:6b 0139:4c 013a:6c 013b:4c 013c:6c 013d:4c 013e:6c 0141:4c 0142:6c 0143:4e 0144:6e 0145:4e 0146:6e 0147:4e 0148:6e 014a:4e 014b:6e 014c:4f 014d:6f 014e:4f 014f:6f 0150:4f 0151:6f 0154:52 0155:72 0156:52 0157:72 0158:52 0159:72 015a:53 015b:73 015c:53 015d:73 015e:53 015f:73 0162:54 0163:74 0164:54 0165:74 0166:54 0167:74 0168:54 0169:74 016a:55 016b:75 016c:55 016d:75 016e:55 016f:75 0170:55 0171:75 0172:55 0173:75 0174:57 0175:77 0176:59 0177:79 0179:5a 017b:5a 017c:7a 0180:62 0189:44 0191:46 0192:66 0197:49 019a:6c 019f:4f 01a0:4f 01a1:6f 01ab:74 01ae:54 01af:55 01b0:75 01b6:7a 01cd:41 01ce:61 01cf:49 01d0:69 01d1:4f 01d2:6f 01d3:55 01d4:75 01d5:55 01d6:75 01d7:55 01d8:75 01d9:55 01da:75 01db:55 01dc:75 01de:41 01df:61 01e4:47 01e5:67 01e6:47 01e7:67 01e8:4b 01e9:6b 01ea:4f 01eb:6f 01ec:4f 01ed:6f 01f0:6a 0261:67 02b9:27 02ba:22 02bc:27 02c4:5e 02c6:5e 02c8:27 02cb:60 02cd:5f 02dc:7e 0300:60 0302:5e 0303:7e 030e:22 0331:5f 0332:5f 2000:20 2001:20 2002:20 2003:20 2004:20 2005:20 2006:20 2010:2d 2011:2d 2013:2d 2014:2d 2018:27 2019:27 201a:2c 201c:22 201d:22 201e:22 2022:2e 2026:2e 2032:27 2035:60 2039:3c 203a:3e 2122:54 ff01:21 ff02:22 ff03:23 ff04:24 ff05:25 ff06:26 ff07:27 ff08:28 ff09:29 ff0a:2a ff0b:2b ff0c:2c ff0d:2d ff0e:2e ff0f:2f ff10:30 ff11:31 ff12:32 ff13:33 ff14:34 ff15:35 ff16:36 ff17:37 ff18:38 ff19:39 ff1a:3a ff1b:3b ff1c:3c ff1d:3d ff1e:3e ff20:40 ff21:41 ff22:42 ff23:43 ff24:44 ff25:45 ff26:46 ff27:47 ff28:48 ff29:49 ff2a:4a ff2b:4b ff2c:4c ff2d:4d ff2e:4e ff2f:4f ff30:50 ff31:51 ff32:52 ff33:53 ff34:54 ff35:55 ff36:56 ff37:57 ff38:58 ff39:59 ff3a:5a ff3b:5b ff3c:5c ff3d:5d ff3e:5e ff3f:5f ff40:60 ff41:61 ff42:62 ff43:63 ff44:64 ff45:65 ff46:66 ff47:67 ff48:68 ff49:69 ff4a:6a ff4b:6b ff4c:6c ff4d:6d ff4e:6e ff4f:6f ff50:70 ff51:71 ff52:72 ff53:73 ff54:74 ff55:75 ff56:76 ff57:77 ff58:78 ff59:79 ff5a:7a ff5b:7b ff5c:7c ff5d:7d ff5e:7e \r\n\r\n37    (IBM EBCDIC - U.S./Canada)\r\n0004:37 0005:2d 0006:2e 0007:2f 0008:16 0009:05 000a:25 0014:3c 0015:3d 0016:32 0017:26 001a:3f 001b:27 0020:40 0021:5a 0022:7f 0023:7b 0024:5b 0025:6c 0026:50 0027:7d 0028:4d 0029:5d 002a:5c 002b:4e 002c:6b 002d:60 002e:4b 002f:61 003a:7a 003b:5e 003c:4c 003d:7e 003e:6e 003f:6f 0040:7c 005f:6d 0060:79 007c:4f 007f:07 0080:20 0081:21 0082:22 0083:23 0084:24 0085:15 0086:06 0087:17 0088:28 0089:29 008a:2a 008b:2b 008c:2c 008d:09 008e:0a 008f:1b 0090:30 0091:31 0092:1a 0093:33 0094:34 0095:35 0096:36 0097:08 0098:38 0099:39 009a:3a 009b:3b 009c:04 009d:14 009e:3e 00a0:41 00a2:4a 00a6:6a 00ac:5f 00c0:64 00c1:65 00c2:62 00c3:66 00c4:63 00c5:67 00c7:68 00c8:74 00c9:71 00ca:72 00cb:73 00cc:78 00cd:75 00ce:76 00cf:77 00d1:69 00df:59 00e0:44 00e1:45 00e2:42 00e3:46 00e4:43 00e5:47 00e7:48 00e8:54 00e9:51 00ea:52 00eb:53 00ec:58 00ed:55 00ee:56 00ef:57 00f1:49 00f8:70 ff01:5a ff02:7f ff03:7b ff04:5b ff05:6c ff06:50 ff07:7d ff08:4d ff09:5d ff0a:5c ff0b:4e ff0c:6b ff0d:60 ff0e:4b ff0f:61 ff1a:7a ff1b:5e ff1c:4c ff1d:7e ff1e:6e ff20:7c ff3f:6d ff40:79 ff5c:4f \r\n\r\n437   (OEM - United States)\r\n00a4:0f 00a7:15 00a8:22 00a9:63 00ad:2d 00ae:72 00af:5f 00b3:33 00b4:27 00b6:14 00b8:2c 00b9:31 00be:5f 00c0:41 00c1:41 00c2:41 00c3:41 00c8:45 00ca:45 00cb:45 00cc:49 00cd:49 00ce:49 00cf:49 00d0:44 00d2:4f 00d3:4f 00d4:4f 00d5:4f 00d7:78 00d8:4f 00d9:55 00da:55 00db:55 00dd:59 00de:5f 00e3:61 00f0:64 00f5:6f 00f8:6f 00fd:79 00fe:5f 0100:41 0101:61 0102:41 0103:61 0104:41 0105:61 0106:43 0107:63 0108:43 0109:63 010a:43 010b:63 010c:43 010d:63 010e:44 010f:64 0110:44 0111:64 0112:45 0113:65 0114:45 0115:65 0116:45 0117:65 0118:45 0119:65 011a:45 011b:65 011c:47 011d:67 011e:47 011f:67 0120:47 0121:67 0122:47 0123:67 0124:48 0125:68 0126:48 0127:68 0128:49 0129:69 012a:49 012b:69 012c:49 012d:69 012e:49 012f:69 0130:49 0131:69 0134:4a 0135:6a 0136:4b 0137:6b 0139:4c 013a:6c 013b:4c 013c:6c 013d:4c 013e:6c 0141:4c 0142:6c 0143:4e 0144:6e 0145:4e 0146:6e 0147:4e 0148:6e 014c:4f 014d:6f 014e:4f 014f:6f 0150:4f 0151:6f 0152:4f 0153:6f 0154:52 0155:72 0156:52 0157:72 0158:52 0159:72 015a:53 015b:73 015c:53 015d:73 015e:53 015f:73 0160:53 0161:73 0162:54 0163:74 0164:54 0165:74 0166:54 0167:74 0168:55 0169:75 016a:55 016b:75 016c:55 016d:75 016e:55 016f:75 0170:55 0171:75 0172:55 0173:75 0174:57 0175:77 0176:59 0177:79 0178:59 0179:5a 017b:5a 017c:7a 017d:5a 017e:7a 0180:62 0189:44 0197:49 019a:6c 019f:4f 01a0:4f 01a1:6f 01ab:74 01ae:54 01af:55 01b0:75 01b6:7a 01c0:7c 01c3:21 01cd:41 01ce:61 01cf:49 01d0:69 01d1:4f 01d2:6f 01d3:55 01d4:75 01d5:55 01d6:75 01d7:55 01d8:75 01d9:55 01da:75 01db:55 01dc:75 01de:41 01df:61 01e4:47 01e5:67 01e6:47 01e7:67 01e8:4b 01e9:6b 01ea:4f 01eb:6f 01ec:4f 01ed:6f 01f0:6a 0261:67 02b9:27 02ba:22 02bc:27 02c4:5e 02c6:5e 02c8:27 02ca:27 02cb:60 02cd:5f 02dc:7e 0300:60 0301:27 0302:5e 0303:7e 0308:22 030e:22 0327:2c 0331:5f 0332:5f 037e:3b 04bb:68 0589:3a 066a:25 2000:20 2001:20 2002:20 2003:20 2004:20 2005:20 2006:20 2010:2d 2011:2d 2013:2d 2014:2d 2017:5f 2018:60 2019:27 201a:2c 201c:22 201d:22 201e:2c 2020:2b 2022:07 2026:2e 2030:25 2032:27 2035:60 2039:3c 203a:3e 203c:13 2044:2f 2074:34 2075:35 2076:36 2077:37 2078:38 2080:30 2081:31 2082:32 2083:33 2084:34 2085:35 2086:36 2087:37 2088:38 2089:39 20dd:09 2102:43 2107:45 210a:67 210b:48 210c:48 210d:48 210e:68 2110:49 2111:49 2112:4c 2113:6c 2115:4e 2118:50 2119:50 211a:51 211b:52 211c:52 211d:52 2122:54 2124:5a 2128:5a 212a:4b 212c:42 212d:43 212e:65 212f:65 2130:45 2131:46 2133:4d 2134:6f 2190:1b 2191:18 2192:1a 2193:19 2194:1d 2195:12 21a8:17 2212:2d 2215:2f 2216:5c 2217:2a 221f:1c 2223:7c 2236:3a 223c:7e 2302:7f 2303:5e 2329:3c 232a:3e 25ac:16 25b2:1e 25ba:10 25bc:1f 25c4:11 25cb:09 25d8:08 25d9:0a 263a:01 263b:02 263c:0f 2640:0c 2642:0b 2660:06 2663:05 2665:03 2666:04 266a:0d 266b:0e 2758:7c 3000:20 3007:09 3008:3c 3009:3e 301a:5b 301b:5d ff01:21 ff02:22 ff03:23 ff04:24 ff05:25 ff06:26 ff07:27 ff08:28 ff09:29 ff0a:2a ff0b:2b ff0c:2c ff0d:2d ff0e:2e ff0f:2f ff10:30 ff11:31 ff12:32 ff13:33 ff14:34 ff15:35 ff16:36 ff17:37 ff18:38 ff19:39 ff1a:3a ff1b:3b ff1c:3c ff1d:3d ff1e:3e ff20:40 ff21:41 ff22:42 ff23:43 ff24:44 ff25:45 ff26:46 ff27:47 ff28:48 ff29:49 ff2a:4a ff2b:4b ff2c:4c ff2d:4d ff2e:4e ff2f:4f ff30:50 ff31:51 ff32:52 ff33:53 ff34:54 ff35:55 ff36:56 ff37:57 ff38:58 ff39:59 ff3a:5a ff3b:5b ff3c:5c ff3d:5d ff3e:5e ff3f:5f ff40:60 ff41:61 ff42:62 ff43:63 ff44:64 ff45:65 ff46:66 ff47:67 ff48:68 ff49:69 ff4a:6a ff4b:6b ff4c:6c ff4d:6d ff4e:6e ff4f:6f ff50:70 ff51:71 ff52:72 ff53:73 ff54:74 ff55:75 ff56:76 ff57:77 ff58:78 ff59:79 ff5a:7a ff5b:7b ff5c:7c ff5d:7d ff5e:7e \r\n\r\n500   (IBM EBCDIC - International)\r\n0004:37 0005:2d 0006:2e 0007:2f 0008:16 0009:05 000a:25 0014:3c 0015:3d 0016:32 0017:26 001a:3f 001b:27 0020:40 0021:4f 0022:7f 0023:7b 0024:5b 0025:6c 0026:50 0027:7d 0028:4d 0029:5d 002a:5c 002b:4e 002c:6b 002d:60 002e:4b 002f:61 003a:7a 003b:5e 003c:4c 003d:7e 003e:6e 003f:6f 0040:7c 005b:4a 005d:5a 005e:5f 005f:6d 0060:79 007f:07 0080:20 0081:21 0082:22 0083:23 0084:24 0085:15 0086:06 0087:17 0088:28 0089:29 008a:2a 008b:2b 008c:2c 008d:09 008e:0a 008f:1b 0090:30 0091:31 0092:1a 0093:33 0094:34 0095:35 0096:36 0097:08 0098:38 0099:39 009a:3a 009b:3b 009c:04 009d:14 009e:3e 00a0:41 00a6:6a 00c0:64 00c1:65 00c2:62 00c3:66 00c4:63 00c5:67 00c7:68 00c8:74 00c9:71 00ca:72 00cb:73 00cc:78 00cd:75 00ce:76 00cf:77 00d1:69 00df:59 00e0:44 00e1:45 00e2:42 00e3:46 00e4:43 00e5:47 00e7:48 00e8:54 00e9:51 00ea:52 00eb:53 00ec:58 00ed:55 00ee:56 00ef:57 00f1:49 00f8:70 ff01:4f ff02:7f ff03:7b ff04:5b ff05:6c ff06:50 ff07:7d ff08:4d ff09:5d ff0a:5c ff0b:4e ff0c:6b ff0d:60 ff0e:4b ff0f:61 ff1a:7a ff1b:5e ff1c:4c ff1d:7e ff1e:6e ff20:7c ff3b:4a ff3d:5a ff3e:5f ff3f:6d ff40:79 \r\n\r\n850   (OEM - Multilingual Latin I)\r\n0100:41 0101:61 0102:41 0103:61 0104:41 0105:61 0106:43 0107:63 0108:43 0109:63 010a:43 010b:63 010c:43 010d:63 010e:44 010f:64 0110:44 0111:64 0112:45 0113:65 0114:45 0115:65 0116:45 0117:65 0118:45 0119:65 011a:45 011b:65 011c:47 011d:67 011e:47 011f:67 0120:47 0121:67 0122:47 0123:67 0124:48 0125:68 0126:48 0127:68 0128:49 0129:69 012a:49 012b:69 012c:49 012d:69 012e:49 012f:69 0130:49 0134:4a 0135:6a 0136:4b 0137:6b 0139:4c 013a:6c 013b:4c 013c:6c 013d:4c 013e:6c 0141:4c 0142:6c 0143:4e 0144:6e 0145:4e 0146:6e 0147:4e 0148:6e 014c:4f 014d:6f 014e:4f 014f:6f 0150:4f 0151:6f 0152:4f 0153:6f 0154:52 0155:72 0156:52 0157:72 0158:52 0159:72 015a:53 015b:73 015c:53 015d:73 015e:53 015f:73 0160:53 0161:73 0162:54 0163:74 0164:54 0165:74 0166:54 0167:74 0168:55 0169:75 016a:55 016b:75 016c:55 016d:75 016e:55 016f:75 0170:55 0171:75 0172:55 0173:75 0174:57 0175:77 0176:59 0177:79 0178:59 0179:5a 017b:5a 017c:7a 017d:5a 017e:7a 0180:62 0189:44 0197:49 019a:6c 019f:4f 01a0:4f 01a1:6f 01a9:53 01ab:74 01ae:54 01af:55 01b0:75 01b6:5a 01c3:21 01cd:41 01ce:61 01cf:49 01d0:69 01d1:4f 01d2:6f 01d3:55 01d4:75 01d5:55 01d6:75 01d7:55 01d8:75 01d9:55 01da:75 01db:55 01dc:75 01de:41 01df:61 01e4:47 01e5:67 01e6:47 01e7:67 01e8:4b 01e9:6b 01ea:4f 01eb:6f 01ec:4f 01ed:6f 01f0:6a 0261:67 02ba:22 02bc:27 02c4:5e 02c6:5e 02c8:27 02cb:27 02cd:5f 02dc:7e 0300:27 0302:5e 0303:7e 030e:22 0331:5f 0332:5f 037e:3b 0393:47 03a3:53 03a6:46 03a9:4f 03b1:61 03b4:64 03b5:65 03c0:70 03c3:73 03c4:74 03c6:66 04bb:68 0589:3a 066a:25 2000:20 2001:20 2002:20 2003:20 2004:20 2005:20 2006:20 2010:2d 2011:2d 2013:2d 2014:2d 2018:27 2019:27 201a:27 201c:22 201d:22 201e:22 2022:07 2024:07 2026:2e 2030:25 2039:3c 203a:3e 203c:13 2044:2f 2070:30 2074:34 2075:35 2076:36 2077:37 2078:39 207f:6e 2080:30 2084:34 2085:35 2086:36 2087:37 2088:38 2089:39 20a7:50 20dd:4f 2102:43 2107:45 210a:67 210b:48 210c:48 210d:48 210e:68 2110:49 2111:49 2112:4c 2113:6c 2115:4e 2118:50 2119:50 211a:51 211b:52 211c:52 211d:52 2122:54 2124:5a 2126:4f 2128:5a 212a:4b 212c:42 212d:43 212e:65 212f:65 2130:45 2131:46 2133:4d 2134:6f 2190:1b 2191:18 2192:1a 2193:19 2194:1d 2195:12 21a8:17 2211:53 2212:2d 2215:2f 2216:2f 2217:2a 2219:07 221a:56 221e:38 221f:1c 2229:6e 2236:3a 223c:7e 2248:7e 2261:3d 2264:3d 2265:3d 2302:7f 2303:5e 2320:28 2321:29 2329:3c 232a:3e 25ac:16 25b2:1e 25ba:10 25bc:1f 25c4:11 25cb:09 25d8:08 25d9:0a 263a:01 263b:02 263c:0f 2640:0c 2642:0b 2660:06 2663:05 2665:03 2666:04 266a:0d 266b:0e 2713:56 3000:20 3007:4f 3008:3c 3009:3e 301a:5b 301b:5d ff01:21 ff02:22 ff03:23 ff04:24 ff05:25 ff06:26 ff07:27 ff08:28 ff09:29 ff0a:2a ff0b:2b ff0c:2c ff0d:2d ff0e:2e ff0f:2f ff10:30 ff11:31 ff12:32 ff13:33 ff14:34 ff15:35 ff16:36 ff17:37 ff18:38 ff19:39 ff1a:3a ff1b:3b ff1c:3c ff1d:3d ff1e:3e ff20:40 ff21:41 ff22:42 ff23:43 ff24:44 ff25:45 ff26:46 ff27:47 ff28:48 ff29:49 ff2a:4a ff2b:4b ff2c:4c ff2d:4d ff2e:4e ff2f:4f ff30:50 ff31:51 ff32:52 ff33:53 ff34:54 ff35:55 ff36:56 ff37:57 ff38:58 ff39:59 ff3a:5a ff3b:5b ff3c:5c ff3d:5d ff3e:5e ff3f:5f ff40:60 ff41:61 ff42:62 ff43:63 ff44:64 ff45:65 ff46:66 ff47:67 ff48:68 ff49:69 ff4a:6a ff4b:6b ff4c:6c ff4d:6d ff4e:6e ff4f:6f ff50:70 ff51:71 ff52:72 ff53:73 ff54:74 ff55:75 ff56:76 ff57:77 ff58:78 ff59:79 ff5a:7a ff5b:7b ff5c:7c ff5d:7d ff5e:7e \r\n\r\n860   (OEM - Portuguese)\r\n00a4:0f 00a5:59 00a7:15 00a8:22 00a9:63 00ad:5f 00ae:72 00af:16 00b3:33 00b4:2f 00b6:14 00b8:2c 00b9:31 00be:33 00c4:41 00c5:41 00c6:41 00cb:45 00ce:49 00cf:49 00d0:44 00d6:4f 00d7:58 00d8:4f 00db:55 00dd:59 00de:54 00e4:61 00e5:61 00e6:61 00eb:65 00ee:69 00ef:69 00f0:64 00f6:6f 00f8:6f 00fb:75 00fd:79 00fe:74 00ff:79 0100:41 0101:61 0102:41 0103:61 0104:41 0105:61 0106:43 0107:63 0108:43 0109:63 010a:43 010b:63 010c:43 010d:63 010e:44 010f:64 0110:44 0111:64 0112:45 0113:65 0114:45 0115:65 0116:45 0117:65 0118:45 0119:65 011a:45 011b:65 011c:47 011d:67 011e:47 011f:67 0120:47 0121:67 0122:47 0123:67 0124:48 0125:68 0126:48 0127:68 0128:49 0129:69 012a:49 012b:69 012c:49 012d:69 012e:49 012f:69 0130:49 0131:69 0134:4a 0135:6a 0136:4b 0137:6b 0139:4c 013a:6c 013b:4c 013c:6c 013d:4c 013e:6c 0141:4c 0142:6c 0143:4e 0144:6e 0145:4e 0146:6e 0147:4e 0148:6e 014c:4f 014d:6f 014e:4f 014f:6f 0150:4f 0151:6f 0152:4f 0153:6f 0154:52 0155:72 0156:52 0157:72 0158:52 0159:72 015a:53 015b:73 015c:53 015d:73 015e:53 015f:73 0160:5c 0161:7c 0162:54 0163:74 0164:54 0165:74 0166:54 0167:74 0168:55 0169:75 016a:55 016b:75 016c:55 016d:75 016e:55 016f:75 0170:55 0171:75 0172:55 0173:75 0174:57 0175:77 0176:59 0177:79 0178:59 0179:5a 017b:5a 017c:7a 017d:5a 017e:7a 0180:62 0189:44 0191:46 0192:66 0197:49 019a:6c 019f:4f 01a0:4f 01a1:6f 01ab:74 01ae:54 01af:55 01b0:75 01b6:7a 01c0:7c 01c3:21 01cd:41 01ce:61 01cf:49 01d0:69 01d1:4f 01d2:6f 01d3:55 01d4:75 01d5:55 01d6:75 01d7:55 01d8:75 01d9:55 01da:75 01db:55 01dc:75 01de:41 01df:61 01e4:47 01e5:67 01e6:47 01e7:67 01e8:4b 01e9:6b 01ea:4f 01eb:6f 01ec:4f 01ed:6f 01f0:6a 0261:67 0278:66 02b9:27 02ba:22 02bc:27 02c4:5e 02c6:5e 02c8:27 02c9:16 02ca:2f 02cb:60 02cd:5f 02dc:7e 0300:60 0301:2f 0302:5e 0303:7e 0304:16 0305:16 0308:22 030e:22 0327:2c 0331:5f 0332:5f 037e:3b 04bb:68 0589:3a 066a:25 2000:20 2001:20 2002:20 2003:20 2004:20 2005:20 2006:20 2010:5f 2011:5f 2013:5f 2014:5f 2017:5f 2018:27 2019:27 201a:2c 201c:22 201d:22 201e:22 2022:07 2024:07 2026:2e 2030:25 2032:27 2035:60 2039:3c 203a:3e 203c:13 2044:2f 2070:30 2074:34 2075:35 2076:36 2077:37 2078:38 2080:30 2081:31 2083:33 2084:34 2085:35 2086:36 2087:37 2088:38 2089:39 20dd:4f 2102:43 2107:45 210a:67 210b:48 210c:48 210d:48 210e:68 2110:49 2111:49 2112:4c 2113:6c 2115:4e 2118:70 2119:50 211a:51 211b:52 211c:52 211d:52 2122:74 2124:5a 2128:5a 212a:4b 212b:41 212c:42 212d:43 212e:65 212f:65 2130:45 2131:46 2133:4d 2134:6f 2190:1b 2191:18 2192:1a 2193:19 2194:1d 2195:12 21a8:17 2205:4f 2212:5f 2215:2f 2216:5c 2217:2a 221f:1c 2223:7c 2236:3a 223c:7e 22c5:07 2302:7f 2303:5e 2329:3c 232a:3e 25ac:16 25b2:1e 25ba:10 25bc:1f 25c4:11 25cb:09 25d8:08 25d9:0a 263a:01 263b:02 263c:0f 2640:0c 2642:0b 2660:06 2663:05 2665:03 2666:04 266a:0d 266b:0e 3000:20 3007:4f 3008:3c 3009:3e 301a:5b 301b:5d 30fb:07 \r\n\r\n861   (OEM - Icelandic)\r\n00a2:63 00a4:0f 00a5:59 00a7:15 00a8:22 00a9:63 00aa:61 00ad:5f 00ae:72 00af:16 00b3:33 00b4:2f 00b6:14 00b8:2c 00b9:31 00ba:6f 00be:33 00c0:41 00c2:41 00c3:41 00c8:45 00ca:45 00cb:45 00cc:49 00ce:49 00cf:49 00d1:4e 00d2:4f 00d4:4f 00d5:4f 00d7:58 00d9:55 00db:55 00e3:61 00ec:69 00ee:69 00ef:69 00f1:6e 00f2:6f 00f5:6f 00f9:75 00ff:79 0100:41 0101:61 0102:41 0103:61 0104:41 0105:61 0106:43 0107:63 0108:43 0109:63 010a:43 010b:63 010c:43 010d:63 010e:44 010f:64 0111:64 0112:45 0113:65 0114:45 0115:65 0116:45 0117:65 0118:45 0119:65 011a:45 011b:65 011c:47 011d:67 011e:47 011f:67 0120:47 0121:67 0122:47 0123:67 0124:48 0125:68 0126:48 0127:68 0128:49 0129:69 012a:49 012b:69 012c:49 012d:69 012e:49 012f:69 0130:49 0131:69 0134:4a 0135:6a 0136:4b 0137:6b 0139:4c 013a:6c 013b:4c 013c:6c 013d:4c 013e:6c 0141:4c 0142:6c 0143:4e 0144:6e 0145:4e 0146:6e 0147:4e 0148:6e 014c:4f 014d:6f 014e:4f 014f:6f 0150:4f 0151:6f 0152:4f 0153:6f 0154:52 0155:72 0156:52 0157:72 0158:52 0159:72 015a:53 015b:73 015c:53 015d:73 015e:53 015f:73 0160:53 0161:73 0162:54 0163:74 0164:54 0165:74 0166:54 0167:74 0168:55 0169:75 016a:55 016b:75 016c:55 016d:75 016e:55 016f:75 0170:55 0171:75 0172:55 0173:75 0174:57 0175:77 0176:59 0177:79 0178:59 0179:5a 017b:5a 017c:7a 017d:5a 017e:7a 0180:62 0197:49 019a:6c 019f:4f 01a0:4f 01a1:6f 01ab:74 01ae:54 01af:55 01b0:75 01b6:7a 01c3:21 01cd:41 01ce:61 01cf:49 01d0:69 01d1:4f 01d2:6f 01d3:55 01d4:75 01d5:55 01d6:75 01d7:55 01d8:75 01d9:55 01da:75 01db:55 01dc:75 01de:41 01df:61 01e4:47 01e5:67 01e6:47 01e7:67 01e8:4b 01e9:6b 01ea:4f 01eb:6f 01ec:4f 01ed:6f 01f0:6a 0261:67 0278:66 02b9:27 02ba:22 02bc:27 02c4:5e 02c6:5e 02c8:27 02c9:16 02ca:2f 02cb:60 02cd:5f 02dc:7e 0300:60 0301:2f 0302:5e 0303:7e 0304:16 0305:16 0308:22 030e:22 0327:2c 0331:5f 0332:5f 037e:3b 04bb:68 0589:3a 066a:25 2000:20 2001:20 2002:20 2003:20 2004:20 2005:20 2006:20 2010:2d 2011:2d 2013:2d 2014:2d 2017:5f 2018:27 2019:27 201a:27 201c:22 201d:22 201e:22 2022:07 2024:07 2026:07 2030:25 2032:27 2035:27 2039:3c 203a:3e 203c:13 2044:2f 2070:30 2074:34 2075:35 2076:36 2077:37 2078:38 2080:30 2081:31 2083:33 2084:34 2085:35 2086:36 2087:37 2088:38 2089:39 20dd:4f 2102:43 2107:45 210a:67 210b:48 210c:48 210d:48 210e:68 2110:49 2111:49 2112:4c 2113:6c 2115:4e 2118:70 2119:50 211a:51 211b:52 211c:52 211d:52 2122:74 2124:5a 2128:5a 212a:4b 212c:42 212d:43 212e:65 212f:65 2130:45 2131:46 2133:4d 2134:6f 2190:1b 2191:18 2192:1a 2193:19 2194:1d 2195:12 21a8:17 2205:4f 2212:5f 2215:2f 2216:5c 2217:2a 221f:1c 2223:7c 2236:3a 223c:7e 22c5:07 2302:7f 2303:5e 2329:3c 232a:3e 25ac:16 25b2:1e 25ba:10 25bc:1f 25c4:11 25cb:09 25d8:08 25d9:0a 263a:01 263b:02 263c:0f 2640:0c 2642:0b 2660:06 2663:05 2665:03 2666:04 266a:0d 266b:0e 3000:20 3007:4f 3008:3c 3009:3e 301a:5b 301b:5d 30fb:07 \r\n\r\n863   (OEM - Canadian French)\r\n00a1:21 00a5:59 00a9:63 00aa:61 00ad:16 00ae:72 00b9:33 00ba:6f 00c1:41 00c3:41 00c4:41 00c5:41 00c6:41 00cc:49 00cd:49 00d0:44 00d1:4e 00d2:4f 00d3:4f 00d5:4f 00d6:4f 00d7:58 00d8:4f 00da:55 00dd:59 00de:54 00e1:61 00e3:61 00e4:61 00e5:61 00e6:61 00ec:69 00ed:69 00f0:64 00f1:6e 00f2:6f 00f5:6f 00f6:6f 00f8:6f 00fd:79 00fe:74 00ff:79 0100:41 0101:61 0102:41 0103:61 0104:41 0105:61 0106:43 0107:63 0108:43 0109:63 010a:43 010b:63 010c:43 010d:63 010e:44 010f:64 0110:44 0111:64 0112:45 0113:65 0114:45 0115:65 0116:45 0117:65 0118:45 0119:65 011a:45 011b:65 011c:47 011d:67 011e:47 011f:67 0120:47 0121:67 0122:47 0123:67 0124:48 0125:68 0126:48 0127:68 0128:49 0129:69 012a:49 012b:69 012c:49 012d:69 012e:49 012f:69 0130:49 0131:69 0134:4a 0135:6a 0136:4b 0137:6b 0139:4c 013a:6c 013b:4c 013c:6c 013d:4c 013e:6c 0141:4c 0142:6c 0143:4e 0144:6e 0145:4e 0146:6e 0147:4e 0148:6e 014c:4f 014d:6f 014e:4f 014f:6f 0150:4f 0151:6f 0152:4f 0153:6f 0154:52 0155:72 0156:52 0157:72 0158:52 0159:72 015a:53 015b:73 015c:53 015d:73 015e:53 015f:73 0160:53 0161:73 0162:54 0163:74 0164:54 0165:74 0166:54 0167:74 0168:55 0169:75 016a:55 016b:75 016c:55 016d:75 016e:55 016f:75 0170:55 0171:75 0172:55 0173:75 0174:57 0175:77 0176:59 0177:79 0178:59 0179:5a 017b:5a 017c:7a 017d:5a 017e:7a 0180:62 0189:44 0197:49 019a:6c 019f:4f 01a0:4f 01a1:6f 01ab:74 01ae:54 01af:55 01b0:75 01b6:7a 01c3:21 01cd:41 01ce:61 01cf:49 01d0:69 01d1:4f 01d2:6f 01d3:55 01d4:75 01d5:55 01d6:75 01d7:55 01d8:75 01d9:55 01da:75 01db:55 01dc:75 01de:41 01df:61 01e4:47 01e5:67 01e6:47 01e7:67 01e8:4b 01e9:6b 01ea:4f 01eb:6f 01ec:4f 01ed:6f 01f0:6a 0261:67 02b9:22 02ba:27 02bc:27 02c4:5e 02c6:5e 02c8:27 02c9:16 02cb:60 02cd:5f 02dc:7e 0300:60 0302:5e 0303:7e 0304:16 0305:16 0331:5f 0332:5f 037e:3b 04bb:68 0589:3a 066a:25 2000:20 2001:20 2002:20 2003:20 2004:20 2005:20 2006:20 2010:2d 2011:2d 2013:2d 2014:2d 2018:27 2019:27 201a:27 201c:22 201d:22 201e:22 2022:07 2024:07 2026:07 2030:25 2032:27 2035:27 2039:3c 203a:3e 203c:13 2044:2f 2070:30 2074:34 2075:35 2076:36 2077:37 2078:38 2080:30 2081:31 2084:34 2085:35 2086:36 2087:37 2088:38 2089:39 20a7:50 20dd:4f 2102:43 2107:45 210a:67 210b:48 210c:48 210d:48 210e:68 2110:49 2111:49 2112:4c 2113:6c 2115:4e 2118:70 2119:50 211a:51 211b:52 211c:52 211d:52 2122:74 2124:5a 2128:5a 212a:4b 212b:41 212c:42 212d:43 212e:65 212f:65 2130:45 2131:46 2133:4d 2134:6f 2190:1b 2191:18 2192:1a 2193:19 2194:1d 2195:12 21a8:17 2205:4f 2212:5f 2215:2f 2216:5c 2217:2a 221f:1c 2223:7c 2236:3a 223c:7e 22c5:07 2302:7f 2303:5e 2329:3c 232a:3e 25ac:16 25b2:1e 25ba:10 25bc:1f 25c4:11 25cb:09 25d8:08 25d9:0a 263a:01 263b:02 263c:0f 2640:0c 2642:0b 2660:06 2663:05 2665:03 2666:04 266a:0d 266b:0e 3000:20 3007:4f 3008:3c 3009:3e 301a:5b 301b:5d 30fb:07 \r\n\r\n865   (OEM - Nordic)\r\n00a2:63 00a5:59 00a7:15 00a8:22 00a9:63 00ad:5f 00ae:72 00af:16 00b3:33 00b4:2f 00b6:14 00b8:2c 00b9:31 00bb:3e 00be:33 00c0:41 00c1:41 00c2:41 00c3:41 00c8:45 00ca:45 00cb:45 00cc:49 00cd:49 00ce:49 00cf:49 00d0:44 00d2:4f 00d3:4f 00d4:4f 00d5:4f 00d7:58 00d9:55 00da:55 00db:55 00dd:59 00de:54 00e3:61 00f0:64 00f5:6f 00fd:79 00fe:74 0100:41 0101:61 0102:41 0103:61 0104:41 0105:61 0106:43 0107:63 0108:43 0109:63 010a:43 010b:63 010c:43 010d:63 010e:44 010f:64 0110:44 0111:64 0112:45 0113:65 0114:45 0115:65 0116:45 0117:65 0118:45 0119:65 011a:45 011b:65 011c:47 011d:67 011e:47 011f:67 0120:47 0121:67 0122:47 0123:67 0124:48 0125:68 0126:48 0127:68 0128:49 0129:69 012a:49 012b:69 012c:49 012d:69 012e:49 012f:69 0130:49 0131:69 0134:4a 0135:6a 0136:4b 0137:6b 0139:4c 013a:6c 013b:4c 013c:6c 013d:4c 013e:6c 0141:4c 0142:6c 0143:4e 0144:6e 0145:4e 0146:6e 0147:4e 0148:6e 014c:4f 014d:6f 014e:4f 014f:6f 0150:4f 0151:6f 0152:4f 0153:6f 0154:52 0155:72 0156:52 0157:72 0158:52 0159:72 015a:53 015b:73 015c:53 015d:73 015e:53 015f:73 0160:53 0161:73 0162:54 0163:74 0164:54 0165:74 0166:54 0167:74 0168:55 0169:75 016a:55 016b:75 016c:55 016d:75 016e:55 016f:75 0170:55 0171:75 0172:55 0173:75 0174:57 0175:77 0176:59 0177:79 0178:59 0179:5a 017b:5a 017c:7a 017d:5a 017e:7a 0180:62 0189:44 0197:49 019a:6c 019f:4f 01a0:4f 01a1:6f 01ab:74 01ae:54 01af:55 01b0:75 01b6:7a 01c3:21 01cd:41 01ce:61 01cf:49 01d0:69 01d1:4f 01d2:6f 01d3:55 01d4:75 01d5:55 01d6:75 01d7:55 01d8:75 01d9:55 01da:75 01db:55 01dc:75 01de:41 01df:61 01e4:47 01e5:67 01e6:47 01e7:67 01e8:4b 01e9:6b 01ea:4f 01eb:6f 01ec:4f 01ed:6f 01f0:6a 0261:67 02b9:27 02ba:22 02bc:27 02c4:5e 02c6:5e 02c8:27 02c9:16 02ca:2f 02cb:60 02cd:5f 02dc:7e 0300:60 0301:2f 0302:5e 0303:7e 0304:16 0305:16 0308:22 030e:22 0327:2c 0331:5f 0332:5f 037e:3b 04bb:68 0589:3a 066a:25 2000:20 2001:20 2002:20 2003:20 2004:20 2005:20 2006:20 2010:2d 2011:2d 2013:2d 2014:2d 2017:5f 2018:27 2019:27 201a:27 201c:22 201d:22 201e:22 2022:07 2024:07 2026:07 2030:25 2032:27 2035:27 2039:3c 203a:3e 203c:13 2044:2f 2070:30 2074:34 2075:35 2076:36 2077:37 2078:38 2080:30 2081:31 2083:33 2084:34 2085:35 2086:36 2087:37 2088:38 2089:39 20dd:4f 2102:43 2107:45 210a:67 210b:48 210c:48 210d:48 210e:68 2110:49 2111:49 2112:4c 2113:6c 2115:4e 2118:70 2119:50 211a:51 211b:52 211c:52 211d:52 2122:74 2124:5a 2128:5a 212a:4b 212c:42 212d:43 212e:65 212f:65 2130:45 2131:46 2133:4d 2134:6f 2190:1b 2191:18 2192:1a 2193:19 2194:1d 2195:12 21a8:17 2205:4f 2212:5f 2215:2f 2216:5c 2217:2a 221f:1c 2223:7c 2236:3a 223c:7e 226b:3c 22c5:07 2302:7f 2303:5e 2329:3c 232a:3e 25ac:16 25b2:1e 25ba:10 25bc:1f 25c4:11 25cb:09 25d8:08 25d9:0a 263a:01 263b:02 263c:0f 2640:0c 2642:0b 2660:06 2663:05 2665:03 2666:04 266a:0d 266b:0e 3000:20 3007:4f 3008:3c 3009:3e 300b:3e 301a:5b 301b:5d 30fb:07 \r\n\r\n874   (ANSI/OEM - Thai)\r\n00a7:15 00b6:14 203c:13 2190:1b 2191:18 2192:1a 2193:19 2194:1d 2195:12 21a8:17 221f:1c 2302:7f 25ac:16 25b2:1e 25ba:10 25bc:1f 25c4:11 25cb:09 25d8:08 25d9:0a 263a:01 263b:02 263c:0f 2640:0c 2642:0b 2660:06 2663:05 2665:03 2666:04 266a:0d 266b:0e ff01:21 ff02:22 ff03:23 ff04:24 ff05:25 ff06:26 ff07:27 ff08:28 ff09:29 ff0a:2a ff0b:2b ff0c:2c ff0d:2d ff0e:2e ff0f:2f ff10:30 ff11:31 ff12:32 ff13:33 ff14:34 ff15:35 ff16:36 ff17:37 ff18:38 ff19:39 ff1a:3a ff1b:3b ff1c:3c ff1d:3d ff1e:3e ff20:40 ff21:41 ff22:42 ff23:43 ff24:44 ff25:45 ff26:46 ff27:47 ff28:48 ff29:49 ff2a:4a ff2b:4b ff2c:4c ff2d:4d ff2e:4e ff2f:4f ff30:50 ff31:51 ff32:52 ff33:53 ff34:54 ff35:55 ff36:56 ff37:57 ff38:58 ff39:59 ff3a:5a ff3b:5b ff3c:5c ff3d:5d ff3e:5e ff3f:5f ff40:60 ff41:61 ff42:62 ff43:63 ff44:64 ff45:65 ff46:66 ff47:67 ff48:68 ff49:69 ff4a:6a ff4b:6b ff4c:6c ff4d:6d ff4e:6e ff4f:6f ff50:70 ff51:71 ff52:72 ff53:73 ff54:74 ff55:75 ff56:76 ff57:77 ff58:78 ff59:79 ff5a:7a ff5b:7b ff5c:7c ff5d:7d ff5e:7e \r\n\r\n932   (ANSI/OEM - Japanese Shift-JIS)\r\n00a1:21 00a5:5c 00a6:7c 00a9:63 00aa:61 00ad:2d 00ae:52 00b2:32 00b3:33 00b9:31 00ba:6f 00c0:41 00c1:41 00c2:41 00c3:41 00c4:41 00c5:41 00c6:41 00c7:43 00c8:45 00c9:45 00ca:45 00cb:45 00cc:49 00cd:49 00ce:49 00cf:49 00d0:44 00d1:4e 00d2:4f 00d3:4f 00d4:4f 00d5:4f 00d6:4f 00d8:4f 00d9:55 00da:55 00db:55 00dc:55 00dd:59 00de:54 00df:73 00e0:61 00e1:61 00e2:61 00e3:61 00e4:61 00e5:61 00e6:61 00e7:63 00e8:65 00e9:65 00ea:65 00eb:65 00ec:69 00ed:69 00ee:69 00ef:69 00f0:64 00f1:6e 00f2:6f 00f3:6f 00f4:6f 00f5:6f 00f6:6f 00f8:6f 00f9:75 00fa:75 00fb:75 00fc:75 00fd:79 00fe:74 00ff:79 \r\n\r\n936   (ANSI/OEM - Simplified Chinese GBK)\r\n00a6:7c 00aa:61 00ad:2d 00b2:32 00b3:33 00b9:31 00ba:6f 00d0:44 00dd:59 00de:54 00e2:61 00f0:65 00fd:79 00fe:74 \r\n\r\n949   (ANSI/OEM - Korean)\r\n00a6:7c 00c0:41 00c1:41 00c2:41 00c3:41 00c4:41 00c5:41 00c7:43 00c8:45 00c9:45 00ca:45 00cb:45 00cc:49 00cd:49 00ce:49 00cf:49 00d1:4e 00d2:4f 00d3:4f 00d4:4f 00d5:4f 00d6:4f 00d9:55 00da:55 00db:55 00dc:55 00dd:59 00e0:61 00e1:61 00e2:61 00e3:61 00e4:61 00e5:61 00e7:63 00e8:65 00e9:65 00ea:65 00eb:65 00ec:69 00ed:69 00ee:69 00ef:69 00f1:6e 00f2:6f 00f3:6f 00f4:6f 00f5:6f 00f6:6f 00f9:75 00fa:75 00fb:75 00fc:75 00fd:79 00ff:79 20a9:5c \r\n\r\n950   (ANSI/OEM - Traditional Chinese Big5)\r\n00a1:21 00a6:7c 00a9:63 00aa:61 00ad:2d 00ae:52 00b2:32 00b3:33 00b9:31 00ba:6f 00c0:41 00c1:41 00c2:41 00c3:41 00c4:41 00c5:41 00c6:41 00c7:43 00c8:45 00c9:45 00ca:45 00cb:45 00cc:49 00cd:49 00ce:49 00cf:49 00d0:44 00d1:4e 00d2:4f 00d3:4f 00d4:4f 00d5:4f 00d6:4f 00d8:4f 00d9:55 00da:55 00db:55 00dc:55 00dd:59 00de:54 00df:73 00e0:61 00e1:61 00e2:61 00e3:61 00e4:61 00e5:61 00e6:61 00e7:63 00e8:65 00e9:65 00ea:65 00eb:65 00ec:69 00ed:69 00ee:69 00ef:69 00f0:65 00f1:6e 00f2:6f 00f3:6f 00f4:6f 00f5:6f 00f6:6f 00f8:6f 00f9:75 00fa:75 00fb:75 00fc:75 00fd:79 00fe:74 00ff:79 \r\n\r\n(UTF-7)\r\n\r\n\r\n(UTF-8)\r\n\r\n\r\n"
  },
  {
    "path": "vcbuild.bat",
    "content": "@rem For Windows build information, see build\\win32\\README.md\n\n@echo off\npushd %CD%\n\nif not \"%1\"==\"\" (set build_type=%1) else (set build_type=Release)\necho Build type: %build_type%\n\nif not \"%2\"==\"\" (set arch=%2) else (set arch=x86_64)\necho Arch: %arch%\n\nif \"%3\"==\"USE_ASAN\" (\n    echo Address Sanitizer: Enabled\n    set CI_ASAN=-c tools.build:cxxflags=\"[\"\"/fsanitize=address\"\"]\"\n    set ASAN_FLAG=ON\n) else (\n    echo Address Sanitizer: Disabled\n    set CI_ASAN=\n    set ASAN_FLAG=OFF\n)\n\ncd build\\win32\nconan install . -s compiler.cppstd=17 %CI_ASAN% --output-folder=build --build=missing --settings=build_type=%build_type% --settings=arch=%arch%\ncd build\ncmake --fresh .. -G \"Visual Studio 17 2022\" -DCMAKE_TOOLCHAIN_FILE=conan_toolchain.cmake -DUSE_ASAN=%ASAN_FLAG% %4 %5 %6 %7 %8 %9\ncmake --build . --config %build_type%\n\npopd\n"
  }
]