diff --git a/.github/ISSUE_TEMPLATE/bug-report-for-version-2-x.md b/.github/ISSUE_TEMPLATE/bug-report-for-version-2-x.md
new file mode 100644
index 0000000000..b39db8633f
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/bug-report-for-version-2-x.md
@@ -0,0 +1,46 @@
+---
+name: Bug report for version 2.x
+about: Create a report to help us improve
+
+---
+
+**Describe the bug**
+
+A clear and concise description of what the bug is.
+
+**Logs and dumps**
+
+Output of:
+ 1. DebugLogs (level 9)
+ 2. AuditLogs
+ 3. Error logs
+ 4. If there is a crash, the core dump file.
+
+_Notice:_ Be carefully to not leak any confidential information.
+
+**To Reproduce**
+
+Steps to reproduce the behavior:
+
+A **curl** command line that mimics the original request and reproduces the problem. Or a ModSecurity v3 test case.
+
+[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)]
+
+
+**Expected behavior**
+
+A clear and concise description of what you expected to happen.
+
+**Server (please complete the following information):**
+ - ModSecurity version (and connector): [e.g. ModSecurity v3.0.1 with nginx-connector v1.0.0]
+ - WebServer: [e.g. nginx-1.15.5]
+ - OS (and distro): [e.g. Linux, archlinux]
+
+
+**Rule Set (please complete the following information):**
+ - Running any public or commercial rule set? [e.g. SpiderLabs commercial rules]
+ - What is the version number? [e.g. 2018-08-11]
+
+**Additional context**
+
+Add any other context about the problem here.
diff --git a/.github/ISSUE_TEMPLATE/bug-report-for-version-3-x.md b/.github/ISSUE_TEMPLATE/bug-report-for-version-3-x.md
new file mode 100644
index 0000000000..58874dfb42
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/bug-report-for-version-3-x.md
@@ -0,0 +1,47 @@
+---
+name: Bug report for version 3.x
+about: Create a report to help us improve. If you don't know a specific detail or
+ piece of information leave it blank, if necessary we will help you to figure out.
+
+---
+
+**Describe the bug**
+
+A clear and concise description of what the bug is.
+
+**Logs and dumps**
+
+Output of:
+ 1. DebugLogs (level 9)
+ 2. AuditLogs
+ 3. Error logs
+ 4. If there is a crash, the core dump file.
+
+_Notice:_ Be carefully to not leak any confidential information.
+
+**To Reproduce**
+
+Steps to reproduce the behavior:
+
+A **curl** command line that mimics the original request and reproduces the problem. Or a ModSecurity v3 test case.
+
+[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)]
+
+
+**Expected behavior**
+
+A clear and concise description of what you expected to happen.
+
+**Server (please complete the following information):**
+ - ModSecurity version (and connector): [e.g. ModSecurity v3.0.1 with nginx-connector v1.0.0]
+ - WebServer: [e.g. nginx-1.15.5]
+ - OS (and distro): [e.g. Linux, archlinux]
+
+
+**Rule Set (please complete the following information):**
+ - Running any public or commercial rule set? [e.g. SpiderLabs commercial rules]
+ - What is the version number? [e.g. 2018-08-11]
+
+**Additional context**
+
+Add any other context about the problem here.
diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md
new file mode 100644
index 0000000000..4d274644a4
--- /dev/null
+++ b/.github/PULL_REQUEST_TEMPLATE.md
@@ -0,0 +1,24 @@
+
+
+
+## what
+
+
+
+## why
+
+
+
+## references
+
+
diff --git a/.github/security2.conf b/.github/security2.conf
new file mode 100644
index 0000000000..d9051b007c
--- /dev/null
+++ b/.github/security2.conf
@@ -0,0 +1,8 @@
+LoadModule security2_module /usr/lib/apache2/modules/mod_security2.so
+
+
+ SecDataDir /var/cache/modsecurity
+ Include /etc/apache2/modsecurity.conf
+
+
+SecAuditLog /var/log/apache2/modsec_audit.log
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
new file mode 100644
index 0000000000..8ba565f099
--- /dev/null
+++ b/.github/workflows/ci.yml
@@ -0,0 +1,112 @@
+name: Quality Assurance
+
+on:
+ push:
+ pull_request:
+
+jobs:
+ build-linux:
+ runs-on: ${{ matrix.os }}
+ strategy:
+ matrix:
+ os: [ubuntu-22.04]
+ platform: [x32, x64]
+ compiler: [gcc, clang]
+ configure:
+ - {label: "with pcre2, no study, no jit", opt: "--enable-pcre-study=no" }
+ - {label: "with pcre2, with study, no jit", opt: "--enable-pcre-study=yes" }
+ - {label: "with pcre2, no study, with jit", opt: "--enable-pcre-study=no --enable-pcre-jit" }
+ - {label: "with pcre2, with study, with jit", opt: "--enable-pcre-study=yes --enable-pcre-jit" }
+ - {label: "with pcre", opt: "--with-pcre --enable-pcre-study=no" }
+ - {label: "with pcre, with study, no jit", opt: "--with-pcre --enable-pcre-study=yes" }
+ - {label: "with pcre, no study, with jit", opt: "--with-pcre --enable-pcre-study=no --enable-pcre-jit" }
+ - {label: "with pcre, with study, with jit", opt: "--with-pcre --enable-pcre-study=yes --enable-pcre-jit" }
+ - {label: "with lua", opt: "--with-lua" }
+ - {label: "wo lua", opt: "--without-lua" }
+ steps:
+ - name: Setup Dependencies
+ run: |
+ sudo apt-get update -y -qq
+ sudo apt-get install -y apache2-dev libxml2-dev liblua5.1-0-dev libcurl4-gnutls-dev libpcre2-dev pkg-config libyajl-dev apache2 apache2-bin apache2-data
+ - uses: actions/checkout@v2
+ - name: autogen.sh
+ run: ./autogen.sh
+ - name: configure ${{ matrix.configure.label }}
+ run: ./configure --enable-assertions ${{ matrix.configure.opt }} 'CFLAGS=-Werror=format-security'
+ - uses: ammaraskar/gcc-problem-matcher@master
+ - name: make
+ run: make -j `nproc`
+ - name: install module
+ run: sudo make install
+ - name: prepare config
+ run: |
+ sudo cp .github/security2.conf /etc/apache2/mods-enabled/
+ sudo cp modsecurity.conf-recommended /etc/apache2/modsecurity.conf
+ sudo cp unicode.mapping /etc/apache2/
+ sudo mkdir -p /var/cache/modsecurity
+ sudo chown -R www-data:www-data /var/cache/modsecurity
+ - name: first check config (to get syntax errors)
+ run: sudo apachectl configtest
+ - name: start apache with module
+ run: sudo systemctl restart apache2.service
+ - name: Search for errors/warnings in error log
+ run: |
+ # '|| :' handles the case grep doesn't match, otherwise the script exits with 1 (error)
+ errors=$(grep -E ':(?error|warn)[]]' /var/log/apache2/error.log) || :
+ if [[ -z "${errors}" ]]; then exit 0; fi
+ echo "::error:: Found errors/warnings in error.log"
+ echo "${errors}"
+ exit 1
+ - name: Check error.log
+ run: |
+ # Send requests & check log format
+ # Valid request
+ curl -s http://127.0.01/ > /dev/null || echo $?
+ # Invalid request
+ curl -s http://127.0.01/%2e%2f > /dev/null || echo $?
+ # Check log format
+ grep -F ModSecurity < /var/log/apache2/error.log | grep -vP "^\[[^\]]+\] \[security2:[a-z]+\] \[pid [0-9]+:tid [0-9]+\] (?:\[client [0-9.:]+\] )?ModSecurity" || exit 0
+ # grep -v succeeded => found some lines with invalid format
+ exit 1
+ - name: Show httpd error log
+ if: always()
+ run: sudo cat /var/log/apache2/error.log
+ - name: Show mod_security2 audit log
+ if: always()
+ run: sudo cat /var/log/apache2/modsec_audit.log
+
+ test-linux:
+ runs-on: ${{ matrix.os }}
+ strategy:
+ matrix:
+ os: [ubuntu-22.04]
+ platform: [x32, x64]
+ compiler: [gcc, clang]
+ configure:
+ - {label: "with pcre2, no study, no jit", opt: "--enable-pcre-study=no" }
+ - {label: "with pcre2, with study, no jit", opt: "--enable-pcre-study=yes" }
+ - {label: "with pcre2, no study, with jit", opt: "--enable-pcre-study=no --enable-pcre-jit" }
+ - {label: "with pcre2, with study, with jit", opt: "--enable-pcre-study=yes --enable-pcre-jit" }
+ - {label: "with pcre", opt: "--with-pcre --enable-pcre-study=no" }
+ - {label: "with pcre, with study, no jit", opt: "--with-pcre --enable-pcre-study=yes" }
+ - {label: "with pcre, no study, with jit", opt: "--with-pcre --enable-pcre-study=no --enable-pcre-jit" }
+ - {label: "with pcre, with study, with jit", opt: "--with-pcre --enable-pcre-study=yes --enable-pcre-jit" }
+ - {label: "with lua", opt: "--with-lua" }
+ - {label: "wo lua", opt: "--without-lua" }
+ steps:
+ - name: Setup Dependencies
+ run: |
+ sudo apt-get update -y -qq
+ sudo apt-get install -y --no-install-recommends apache2-dev libxml2-dev liblua5.1-0-dev libcurl4-gnutls-dev libpcre2-dev pkg-config libyajl-dev apache2 apache2-bin apache2-data
+ - uses: actions/checkout@v2
+ - name: autogen.sh
+ run: ./autogen.sh
+ - name: configure ${{ matrix.configure.label }}
+ run: ./configure ${{ matrix.configure.opt }} 'CFLAGS=-Werror=format-security'
+ - uses: ammaraskar/gcc-problem-matcher@master
+ - name: make
+ run: make -j `nproc`
+ - name: install module
+ run: sudo make install
+ - name: run tests
+ run: make test
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000000..d8d6784f63
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,119 @@
+# Prerequisites
+*.d
+
+# Object files
+*.o
+*.ko
+*.obj
+*.elf
+
+# Linker output
+*.ilk
+*.map
+*.exp
+
+# Precompiled Headers
+*.gch
+*.pch
+
+# Libraries
+*.lib
+*.a
+*.la
+*.lo
+
+# Shared objects (inc. Windows DLLs)
+*.dll
+*.so
+*.so.*
+*.dylib
+
+# Executables
+*.exe
+*.out
+*.app
+*.i*86
+*.x86_64
+*.hex
+
+# Debug files
+*.dSYM/
+*.su
+*.idb
+*.pdb
+
+# Backup files
+*~
+
+# Kernel Module Compile Results
+*.mod*
+*.cmd
+.tmp_versions/
+modules.order
+Module.symvers
+Mkfile.old
+dkms.conf
+
+# http://www.gnu.org/software/automake
+
+Makefile.in
+/ar-lib
+/mdate-sh
+/py-compile
+/test-driver
+/ylwrap
+.deps/
+.dirstamp
+
+# http://www.gnu.org/software/autoconf
+
+autom4te.cache
+/autoscan.log
+/autoscan-*.log
+/aclocal.m4
+/compile
+/config.cache
+/config.guess
+/config.h.in
+/config.log
+/config.status
+/config.sub
+/configure
+/configure.scan
+/depcomp
+/install-sh
+/missing
+/stamp-h1
+
+# https://www.gnu.org/software/libtool/
+
+/ltmain.sh
+
+# http://www.gnu.org/software/texinfo
+
+/texinfo.tex
+
+# http://www.gnu.org/software/m4/
+
+m4/libtool.m4
+m4/ltoptions.m4
+m4/ltsugar.m4
+m4/ltversion.m4
+m4/lt~obsolete.m4
+
+# Generated Makefile
+# (meta build system like autotools,
+# can automatically generate from config.status script
+# (which is called by configure script))
+Makefile
+
+# IDEs
+.idea
+
+# tests
+tests/regression/server_root/**
+tests/*.pl
+tests/*.trs
+tests/*.log
+
+
diff --git a/CHANGES b/CHANGES
index 031648e4d5..4cf9c09356 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,9 +1,507 @@
-DD mmm YYYY - X.Y.Z (To be released)
-------------------------------------
+05 Aug 2025 - 2.9.12
+--------------------
+
+ * fix: Improper error handling
+ [PR from private repo - @orangetw, @pgajdos, @ylavic, @theseion, @fzipi, @airween
+ fixed CVE-2025-54571]
+ * fix: mod_security2's regression tests [Issue #3425 - @airween]
+ * fix: remove unused condition from msc_status_engine.c [Issue #3412 - @airween]
+ * fix: remove unwanted '\0' string terminator from argument's value [Issue #3411 - @airween]
+
+01 Jul 2025 - 2.9.11
+--------------------
+
+ * fix: prevent segmentation fault if the XML node is empty
+ [PR from private repo - @theseion, @fzipi, @RedXanadu, @airween; fixed CVE-2025-52891]
+ * Plug memory leak when msre_op_validateSchema_execute() exits normally (validateSchema)
+ [Issue #3401 - @nic-prgs]
+ * chore: bump version in MSI installer.wxs
+ [Issue #3400 - @airween]
+ * Fix resource leaks in `msc_status_engine_mac_address`
+ [Issue #3391 - @amezin]
+
+02 Jun 2025 - 2.9.10
+--------------------
+
+ * fix: DoS vulnerability
+ [PR from private repo - @theseion, @fzipi, @airween; fixed CVE-2025-48866]
+
+21 May 2025 - 2.9.9
+-------------------
+
+ * fix: DoS vulnerability
+ [PR from private repo - @theseion, @fzipi, @airween; fixed CVE-2025-47947]
+ * chore: log error codes for global mutex failure modes.
+ [Issue #3387 - @airween]
+ * chore: refactor build system to use PCRE2
+ [Issue #3383 - @airween]
+ * feat: add 'make test' to v2's workflow
+ [Issue #3379 - @airween]
+ * fix: 'make test' is able to run again
+ [Issue #3378 - @airween]
+ * fix: add PCRE2 capability to standalone module
+ [Issue #3377 - @airween]
+ * chore: remove unnecessary @LIBXML2_CFLAGS@ from linker flags
+ [Issue #3376 - @airween]
+ * fix: add msc_fullinfo() to check JIT compilation
+ [Issue #3375 - @airween]
+ * Fix error logging for standalone module
+ [Issue #3374 - @RedXanadu]
+ * Fix compiler warnings from GCC
+ [Issue #3372 - @notroj]
+ * feat: improved XMLArgs processing
+ [Issue #3358 - @airween]
+ * Incorrect utf8toUnicode transformation for 00xx
+ [Issue #3284 - @marcstern]
+ * Fixed PCRE2 error message
+ [Issue #3279 - @marcstern]
+ * make rootpath and incpath consts for apr_filepath_root
+ [Issue #3270 - @Marcool04]
+ * Fix apr_global_mutex_create() usage
+ [Issue #3269 - @marcstern]
+ * chore: add 'log' action to rule 200005 (v2/master)
+ [Issue #3267 - @airween]
+ * Move id_log() to msc_util to fix unit tests; it is declared on msc_ut…
+ [Issue #3265 - @rainerjung]
+ * Missing #include
+ [Issue #3262 - @marcstern]
+ * Fixed apr_global_mutex_create() usage (no filename)
+ [PR #3269 - @marcstern]
+ * handle errors from apr_global_mutex_lock
+ [PR #3257 - @marcstern]
+
+03 Sep 2024 - 2.9.8
+-------------------
+
+ * Fixed ap_log_perror() usage
+ [PR #3241 - @marcstern]
+ * Memory leaks + enhanced logging
+ [PR #3191 - @marcstern]
+ * CI improvement: First check syntax & always display error/audit logs
+ [PR #3190 - @marcstern]
+ * Fixed assert() usage
+ [PR #3202 - @marcstern]
+ * Removed useless code
+ [PR #3193 - @marcstern]
+ * feat: Check if the MP header contains invalid character
+ [PR #3226 - @airween]
+ * Use standard httpd logging format in error log
+ [PR #3192 - @marcstern]
+ * fix msc_regexec() != PCRE_ERROR_NOMATCH strict check
+ [PR #3194 - @marcstern]
+ * Move xmlFree() call to the right place
+ [Issue #3199 - @airween]
+ * Add collection size in log in case of writing error
+ [Issue #3198 - @marcstern]
+ * Passing address of lock instead of lock in acquire_global_lock()
+ [Issue #3188 - @marcstern]
+ * Invalid pointer access in case rule id == NOT_SET_P
+ [Issue #3187 - @marcstern]
+ * Show error.log after httpd start in CI
+ [Issue #3171 - @marcstern]
+ * chore: add pull request template
+ [Issue #3159 - @fzipi]
+ * chore: add gitignore file
+ [Issue #3158 - @fzipi]
+ * Possible double free
+ [Issue #3155 - @marcstern]
+ * Set 'jit' variable's initial value
+ [Issue #3154 - @marcstern]
+ * Missing null byte + optimization
+ [Issue #3153 - @marcstern]
+ * fix: remove usage of insecure tmpname
+ [Issue #3149 - @fzipi]
+ * docs: update copyright
+ [Issue #3148 - @fzipi]
+ * Enhanced logging [Issue #3107]
+ [Issue #3139 - @marcstern]
+ * Check for null pointer dereference (almost) everywhere
+ [Issue #3120 - @marcstern]
+ * Fix possible segfault in collection_unpack
+ [Issue #3099 - @twouters]
+ * fix: Replace obsolete macros
+ [Issue #3094 - @airween]
+ * chore: update bug-report-for-version-2-x.md
+ [Issue #3087 - @fzipi]
+ * feat: Add more steps: install built module and restart the server
+ [Issue #3078 - @airween]
+ * Add new flag: --without-lua
+ [Issue #3076 - @airween]
+ * Initial release of CI worklow
+ [Issue #3075 - @airween]
+ * V2/fixbuildissue
+ [Issue #3074 - @airween]
+ * ; incorrectly replaced by space in cmdline
+ [Issue #3051 - @marcstern]
+ * Detailed error message when writing collections
+ [Issue #3050 - @marcstern]
+ * docs: Fix organization name in references and security e-mail (v2)
+ [Issue #3043 - @airween]
+ * ctl:ruleRemoveByTag isn't executed if no rule id is present in the rule
+ [Issue #3012 - @marcstern]
+ * Suppress useless loop on tag matching
+ [Issue #3009 - @marcstern]
+ * Optimization: Avoid last loop and storing an empty value in case nothing
+ after last %{..} macro
+ [Issue #3004 - @marcstern]
+ * Ignore (consistently) empty actions
+ [Issue #3003 - @marcstern]
+ * Add context info to error message
+ [Issue #2997 - @marcstern]
+ * Implement msre_action_phase_validate()
+ [Issue #2994 - @marcstern]
+ * Avoid some useless code and memory allocation in case no macro is present
+ [Issue #2992 - @marcstern]
+ * 'jit' variable not initialized when WITH_PCRE2 is defined
+ [Issue #2987 - @marcstern]
+ * Configure: do not check for pcre1 if pcre2 requested
+ [Issue #2975 - @martinhsv]
+ * Double memory allocation
+ [Issue #2969 - @marcstern]
+ * Fix for DEBUG_CONF compile flag
+ [Issue #2963 - @marcstern]
+ * Enhance logging
+ [Issue #3107 - @marcstern]
+ * Fix possible segfault in collection_unpack
+ [Issue #3072 - @twouters]
+ * Set the minimum security protocol version for SecRemoteRules
+ [Issue security/code-scanning/2 - @airween]
+ * Allow lua version 5.4
+ [Issue #2996 - @3eka, @martinhsv]
+ * Configure: do not check for pcre1 if pcre2 requested
+ [Issue #2975 - @zhaoshikui, @martinhsv]
+ * Check return code of apr_procattr_io_set()
+ [Issue #2958 - @marcstern]
+ * Do not escape special chars in rx pattern with macro
+ [Issue #2357 - @marcstern, @martinhsv]
+ * Substitute two equals-equals operators in build
+ [Issue #2883 - @Polynomial-C]
+
+04 Jan 2023 - 2.9.7
+-------------------
+
+ * Fix: FILES_TMP_CONTENT may sometimes lack complete content
+ [Issue #2857 - gieltje, @airween, @dune73, @martinhsv]
+ * Support configurable limit on number of arguments processed
+ [Issue #2844 - @jleproust, @martinhsv]
+ * Silence compiler warning about discarded const
+ [Issue #2843 - @Steve8291, @martinhsv]
+ * Support for JIT option for PCRE2
+ [Issue #2840 - @martinhsv]
+ * Use uid for user if apr_uid_name_get() fails
+ [Issue #2046 - @arminabf, @marcstern]
+ * Fix: handle error with SecConnReadStateLimit configuration
+ [Issue #2815, #2834 - @marcstern, @martinhsv]
+ * Only check for pcre2 install if required
+ [Issue #2833 - @martinhsv]
+ * Adjustment of previous fix for log messages
+ [Issue #2832 - @marcstern, @erkia]
+ * Mark apache error log messages as from mod_security2
+ [Issue #2781 - @erkia]
+ * Use pkg-config to find libxml2 first
+ [Issue #2818 - @hughmcmaster]
+ * Support for PCRE2 in mlogc
+ [Issue #2737, #2827 - @martinhsv]
+ * Support for PCRE2
+ [Issue #2737 - @martinhsv]
+
+07 Sep 2022 - 2.9.6
+-------------------
+
+ * Adjust parser activation rules in modsecurity.conf-recommended
+ [Issue #2799 - @terjanq, @martinhsv]
+ * Multipart parsing fixes and new MULTIPART_PART_HEADERS collection
+ [Issue #2797 - @terjanq, @martinhsv]
+ * Limit rsub null termination to where necessary
+ [Issue #2794 - @marcstern, @martinhsv]
+ * IIS: Update dependencies for next planned release
+ [@martinhsv]
+ * XML parser cleanup: NULL duplicate pointer
+ [Issue #2760 - @martinhsv]
+ * Properly cleanup XML parser contexts upon completion
+ [Issue #2239 - @argenet]
+ * Fix memory leak in streams
+ [Issue #2208 - @marcstern, @vloup, @JamesColeman-LW]
+ * Fix: negative usec on log line when data type long is 32b
+ [Issue #2753 - @ABrauer-CPT, @martinhsv]
+ * mlogc log-line parsing fails due to enhanced timestamp
+ [Issue #2682 - @bozhinov, @ABrauer-CPT, @martinhsv]
+ * Allow no-key, single-value JSON body
+ [Issue #2735 - @marcstern, @martinhsv]
+ * Set SecStatusEngine Off in modsecurity.conf-recommended
+ [Issue #2717 - @un99known99, @martinhsv]
+ * Fix memory leak that occurs on JSON parsing error
+ [Issue #2236 @argenet, @vloup, @martinhsv]
+ * Multipart names/filenames may include single quote if double-quote enclosed
+ [Issue #2352 @martinhsv]
+ * Add SecRequestBodyJsonDepthLimit to modsecurity.conf-recommended
+ [Issue #2647 @theMiddleBlue, @airween, @877509395 ,@martinhsv]
+ * IIS: Update dependencies for Windows build as of v2.9.5
+ [@martinhsv]
+
+22 Nov 2021 - 2.9.5
+-------------------
+
+ * Support configurable limit on depth of JSON parsing
+ [@theMiddleBlue, @airween, @dune73, @martinhsv]
+
+21 Jun 2021 - 2.9.4
+-------------------
+
+ * Add microsec timestamp resolution to the formatted log timestamp
+ [Issue #2095 - @rainerjung]
+ * Store temporaries in the request pool for regexes compiled per-request.
+ [Issue #890, #2049 - @lightsey]
+ * Fix other usage of the global pool for request temporaries in re_operators.c
+ [Issue #890, #2049 - @lightsey]
+ * Adds a sanity check before use ctl:ruleRemoveTargetById and ctl:ruleRemoveTargetByMsg.
+ [Issue #2033 - @studersi]
+ * Fix the order of error_msg validation
+ [Issue #2128 - @marcstern, @zimmerle]
+ * Added missing Geo Countries
+ [Issue #2123, #2124 - @emphazer]
+ * When the input filter finishes, check whether we returned data
+ [Issue #2091, #2092 - @rainerjung]
+ * fix: care non-null terminated chunk data
+ [Issue #2097 - @orisano]
+ * Fix for apr_global_mutex_create() crashes with mod_security
+ [Issue #1957 - @blappm]
+ * Fix inet addr handling on 64 bit big endian systems
+ [Issue #1980 - @zimmerle, @airween]
+
+
+05 Dec 2018 - 2.9.3
+-------------------
+
+ * Enable optimization for large stream input by default on IIS
+ [Issue #1299 - @victorhora, @zimmerle]
+ * Allow 0 length JSON requests.
+ [Issue #1822 - @allanbomsft, @zimmerle, @victorhora, @marcstern]
+ * Include unanmed JSON values in unnamed ARGS
+ [Issue #1577, #1576 - @marcstern, @victorhora, @zimmerle]
+ * Fix buffer size for utf8toUnicode transformation
+ [Issue #1208 - @katef, @victorhora]
+ * Fix sanitizing JSON request bodies in native audit log format
+ [p0pr0ck5, @victorhora]
+ * IIS: Update Wix installer to bundle a supported CRS version (3.0)
+ [@victorhora, @zimmerle]
+ * IIS: Update dependencies for Windows build
+ [Issue #1848 - @victorhora, @hsluoyz]
+ * IIS: Set SecStreamInBodyInspection by default on IIS builds (#1299)
+ [Issue #1299 - @victorhora]
+ * IIS: Update modsecurity.conf
+ [Issue #788 - @victorhora, @brianclark]
+ * Add sanity check for a couple malloc() and make code more resilient
+ [Issue #979 - @dogbert2, @victorhora, @zimmerl]
+ * Fix NetBSD build by renaming the hmac function to avoid conflicts
+ [Issue #1241 - @victorhora, @joerg, @sevan]
+ * IIS: Windows build, fix duplicate YAJL dir in script
+ [Issue #1612 - @allanbomsft, @victorhora]
+ * IIS: Remove body prebuffering due to no locking in modsecProcessRequest
+ [Issue #1917 - @allanbomsft, @victorhora]
+ * Fix mpm-itk / mod_ruid2 compatibility
+ [Issue #712 - @ju5t , @derhansen, @meatlayer, @victorhora]
+ * Code cosmetics: checks if actionset is not null before use it
+ [Issue #1556 - @marcstern, @zimmerle, @victorhora]
+ * Only generate SecHashKey when SecHashEngine is On
+ [Issue #1671 - @dmuey, @monkburger, @zimmerle]
+ * Docs: Reformat README to Markdown and update dependencies
+ [Issue #1857 - @hsluoyz, @victorhora]
+ * IIS: no lock on ProcessRequest. No reload of config.
+ [Issue #1826 - @allanbomsft]
+ * IIS: buffer request body before taking lock
+ [Issue #1651 - @allanbomsft]
+ * good practices: Initialize variables before use it
+ [Issue #1889 - Marc Stern]
+ * Let body parsers observe SecRequestBodyNoFilesLimit
+ [Issue #1613 - @allanbomsft]
+ * potential off by one in parse_arguments
+ [Issue #1799 - @tinselcity, @zimmerle]
+ * Fix utf-8 character encoding conversion
+ [Issue #1794 - @tinselcity, @zimmerle]
+ * Fix ip tree lookup on netmask content
+ [Issue #1793 - @tinselcity, @zimmerle]
+ * IIS: set overrideModeDefault to Allow so that individual websites can
+ add to their web.config file
+ [Issue #1781 - @default-kramer]
+ * modsecurity.conf-recommended: Fix spelling
+ [Issue #1721 - @padraigdoran]
+ * build: fix when multiple lines for curl version
+ [Issue #1771 - @Artistan]
+ * Fix arabic charset in unicode_mapping file
+ [Issue #1619 - @alaa-ahmed-a]
+ * Optionally preallocates memory when SecStreamInBodyInspection is on
+ [Issue #1366 - @allanbomsft, @zimmerle]
+ * Fixed typo in build_yajl.bat
+ [Issue #1366 - @allanbomsft]
+ * Fixes SecConnWriteStateLimit
+ [Issue #1545 - @nicjansma]
+ * Added "empy chunk" check
+ [Issue #1347, #1446 - @gravagli, @bostrt, @zimmerle]
+ * Add capture action to @detectXSS operator
+ [Issue #1488, #1482 - @victorhora]
+ * Fix for wildcard operator when loading conf files on Nginx / IIS
+ [Issue #1486, #1285 - @victorhora and @thierry-f-78]
+ * Set of fixies to make windows build workable with the buildbots
+ [Commit 94fe3 - @zimmerle]
+ * Uses LOG_NO_STOPWATCH instead of DLOG_NO_STOPWATCH
+ [Issue #1510 - @marcstern]
+ * Adds missing headers
+ [Issue #1454 - @devnexen]
+
+
+18 Jul 2017 - 2.9.2
+-------------------
+
+ * IIS build refactoring and dependencies update
+ [Issue #1487 - @victorhora]
+ * Best practice: Initialize msre_var pointers
+ [Commit fbd57 - Allan Boll]
+ * nginx: Obtain port from r->connection->local_sockaddr.
+ [Commit 51314 - @defanator]
+ * Updates libinjection to v3.10.0
+ [Issue #1412 - @client9, @zimmerle and @bjdijk]
+ * Avoid log flood while using SecConnEngine
+ [Issue #1436 - @victorhora]
+ * Make url path absolute for SecHashEngine only when it is relative
+ in the first place.
+ [Issue #752, #1071 - @hideaki]
+ * Fix the hex digit size for SHA1 on msc_crypt implementation.
+ [Issue #1354 - @zimmerle and @parthasarathi204]
+ * Avoid to flush xml buffer while assembling the injected html.
+ [Issue #742 - @zimmerle]
+ * Avoid additional operator invokation if last transform of a multimatch
+ doesn't modify the input
+ [Issue #1086, #1087 - Daniel Stelter-Gliese]
+ * Adds a sanity check before use ctl:ruleRemoveTargetByTag.
+ [Issue #1353 - @LukeP21 and @zimmerle]
+ * Uses an optional global lock while manipulating collections.
+ [Issues #1224 - @mturk and @zimmerle]
+ * Fix collection naming problem while merging collections.
+ [Issue #1274 - Coty Sutherland and @zimmerle]
+ * Fix --enable-docs adding missing Makefile, modifying autoconf and filenames
+ [Issue #1322 - @victorhora]
+ * Change from using rand() to thread-safe ap_random_pick.
+ [Issue #1289 - Robert Bost]
+ * Cosmetics: added comments on odd looking code to prevent future
+ scrutiny
+ [Issue #1279 - Coty Sutherland]
+ * {dis|en}able-server-context-logging: Option to disable logging of
+ server info (log producer, sanitized objects, ...) in audit log.
+ [Issue #1069 - Marc Stern]
+ * Allow drop to work with mod_http2
+ [Issue #1308, #992 - @bazzadp]
+ * Fix SecConn(Read|Write)StateLimit on Apache 2.4
+ [Issue #1340, #1337, #786 - Sander Hoentjen]
+ * {dis|en}able-stopwatch-logging: Option to disable logging of stopwatches
+ in audit log.
+ [Issue #1067 - Marc Stern]
+ * {dis|en}able-dechunk-logging: Option to disable logging of
+ dechunking in audit log when log level < 9.
+ [Issue #1068 - Marc Stern]
+ * Updates libinjection to: da027ab52f9cf14401dd92e34e6683d183bdb3b4
+ [ModSecurity team]
+ * {dis|en}able-handler-logging: Option to disable logging of Apache handler
+ in audit log
+ [Issue #1070, #1381 - Marc Stern]
+ * {dis|en}able-collection-delete-problem-logging: Option to disable logging of
+ collection delete problem in audit log when log level < 9.
+ [Issue #1380 - Marc Stern]
+ * Adds rule id in logs whenever a rule fail.
+ [Issue #1379, #391 - Marc Stern]
+ * {dis|en}able-server-logging: Option to disable logging of
+ "Server" in audit log when log level < 9.
+ [Issue #1070 - Marc Stern]
+ * {dis|en}able-filename-logging: Option to disable logging of filename
+ in audit log.
+ [Issue #1065 - Marc Stern]
+ * Reads fuzzy hash databases on init
+ [Issue #1339 - Robert Paprocki and @Rendername]
+ * Changes the configuration to recognize soap+xml as XML
+ [Issue #1374 - @emphazer and Chaim Sanders]
+ * Fix building with nginx >= 1.11.11
+ [Issue #1373, #1359 - Andrei Belov and Thomas Deutschmann]
+ * Using Czechia instea of Czech Republic
+ [Issue #1258 - Michael Kjeldsen]
+ * {dis|en}able-rule-id-validation: Option to disable rule id validation
+ [Issue #1150 - Marc Stern and ModSecurity team]
+ * JSON Log: Append a newline to concurrent JSON audit logs
+ [Issue #1233 - Robert Paprocki]
+ * JSON Log: Don't unnecessarily rename request body parts in cleanup
+ [Issue #1223 - Robert Paprocki]
+ * Fix error message inside audit logs
+ [Issue #1216 and #1073 - Armin Abfalterer]
+ * Remove port from IPV4 address when running under IIS.
+ [Issue #1220, #1109 and #734 - Robert Culyer]
+ * Remove logdata and msg fields from JSON audit log rule.
+ [Issue #1190 and #1174 - Robert Paprocki]
+ * Better handle the json parser cleanup
+ [Issue #1204 - Ephraim Vider]
+ * Fix status failing to report in Nginx auditlogs
+ [Issue #977, #1171 - @charlymps and Chaim Sanders]
+ * Fix file upload JSON audit log entry
+ [Issue #1181 and #1173 - Robert Paprocki and Christian Folini]
+ * configure: Fix detection whether libcurl is linked against gnutls and,
+ move verbose_output declaration up to the beginning.
+ [Issue #1158 - Thomas Deutschmann (@Whissi)]
+ * Treat APR_INCOMPLETE as APR_EOF while receiving the request body.
+ [Issue #1060, #334 - Alexey Sintsov]
+
+
+Security issues
+
+ * Allan Boll reported an uninitialized variable that may lead to a crash on
+ Windows platform.
+ * Brian Adeloye reported an infinite loop on the version of libinjection used
+ on ModSecurity 2.9.1.
+
+
+09 Mar 2016 - 2.9.1
+-------------------
+
+ * No changes.
+
+03 Feb 2016 - 2.9.1-RC1
+-----------------------
+ * Added support to generate audit logs in JSON format.
+ [Issue #914, #897, #656 - Robert Paprocki]
+ * Creating AuditLog serial file (or parallel index) respecting the
+ permission configured with SecAuditLogFileMode. Previously, it was
+ used only to save the transactions while in parallel mode.
+ [Issue #852 - @littlecho and ModSecurity team]
+ * Checking for hashing injection response, to report in case of failure.
+ [Issue #1041 - ModSecurity team]
+ * Stop buffering when the request is larger than SecRequestBodyLimit
+ in ProcessPartial mode
+ [Issue #709, #705, #728 - Justin Gerace and ModSecurity team]
+ * Extended Lua support to include version 5.3
+ [Issue #837, #762, #814 - Athmane Madjoudj and ModSecurity team]
+ * mlogc: Allows user to choose between TLS versions (TLSProtocol option
+ introduced).
+ [Issue #881 - Ishwor Gurung]
+ * Allows mod_proxy's "nocanon" behavior to be specified in proxy actions
+ [Issue #1031, #961, #763 - Mario D. Santana and ModSecurity team]
+ * Refactoring conditional #if/#defs directives.
+ [Issue #996 - Wesley M and ModSecurity team]
+ * mlogc-batch-load.pl.in: fix searching SecAuditLogStorageDir
+ files with Apache 2.4
+ [Issue #775 - Elia Pinto]
+ * Understands IIS 10 as compatible on Windows installer.
+ [Issue #931 - Anton Serbulov, Pavel Vasilevich and ModSecurity team]
+ * Fix apache logging limitation by using correct Apache call.
+ [Issue #840 - Christian Folini]
+ * Fix apr_crypto.h check on 32-bit Linux platform
+ [Issue #882, #883 - Kurt Newman]
+ * Fix variable resolution duration (Content of the DURATION variable).
+ [Issue #662 - Andrew Elble]
+ * Fix crash while adding empty keys to persistent collections.
+ [Issue #927 - Eugene Alekseev, Marc Stern and ModSecurity team]
+ * Remove misguided call to srand()
+ [Issues #778, #781 and #836 - Michael Bunk, @gilperon]
* Fix compilation problem while ssdeep is installed in non-standard
location.
- [Issude #872 - Kurt Newman]
+ [Issue #872 - Kurt Newman]
* Fix invalid storage reference by apr_psprintf at msc_crypt.c
[Issue #609 - Jeff Trawick]
diff --git a/LICENSE b/LICENSE
index 261eeb9e9f..9135230d95 100644
--- a/LICENSE
+++ b/LICENSE
@@ -175,18 +175,7 @@
END OF TERMS AND CONDITIONS
- APPENDIX: How to apply the Apache License to your work.
-
- To apply the Apache License to your work, attach the following
- boilerplate notice, with the fields enclosed by brackets "[]"
- replaced with your own identifying information. (Don't include
- the brackets!) The text should be enclosed in the appropriate
- comment syntax for the file format. We also recommend that a
- file or class name and description of purpose be included on the
- same "printed page" as the copyright notice for easier
- identification within third-party archives.
-
- Copyright [yyyy] [name of copyright owner]
+ Copyright 2016 ModSecurity
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
diff --git a/README.TXT b/README.TXT
deleted file mode 100644
index 9442e83a2f..0000000000
--- a/README.TXT
+++ /dev/null
@@ -1,110 +0,0 @@
-ModSecurity for Apache 2.x, http://www.modsecurity.org/
-Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/)
-
-You may not use this file except in compliance with
-the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-If any of the files related to licensing are missing or if you have any
-other questions related to licensing please contact Trustwave Holdings, Inc.
-directly using the email address security@modsecurity.org.
-
-
-DOCUMENTATION
-
-Please refer to the documentation folder (/doc) for
-the reference manual.
-
-
-##############################################
-----------------------------------
-OWASP ModSecurity Core Rule Set (CRS)
-
-
-Project Site:
-https://www.owasp.org/index.php/Category:OWASP_ModSecurity_Core_Rule_Set_Project
-
-
-Download:
-https://github.com/SpiderLabs/owasp-modsecurity-crs
-
-----------------------------------
-
-ModSecurity™ is a web application firewall engine that provides very
-little protection on its own. In order to become useful, ModSecurity™ must
-be configured with rules. In order to enable users to take full advantage
-of ModSecurity™ out of the box, Trustwave's SpiderLabs is providing a free
-certified rule set for ModSecurity™ 2.x. Unlike intrusion detection and
-prevention systems, which rely on signatures specific to known
-vulnerabilities, the Core Rules provide generic protection from unknown
-vulnerabilities often found in web applications, which are in most cases
-custom coded. The Core Rules are heavily commented to allow it to be used
-as a step-by-step deployment guide for ModSecurity™.
-Core Rules Content
-
-In order to provide generic web applications protection, the Core Rules
-use the following techniques:
-
-* HTTP Protection - detecting violations of the HTTP protocol and a
-locally defined usage policy.
-* Real-time Blacklist Lookups - utilizes 3rd Party IP Reputation
-* Web-based Malware Detection - identifies malicious web content by check
-against the Google Safe Browsing API.
-* HTTP Denial of Service Protections - defense against HTTP Flooding and
-Slow HTTP DoS Attacks.
-* Common Web Attacks Protection - detecting common web application
-security attack.
-* Automation Detection - Detecting bots, crawlers, scanners and other
-surface malicious activity.
-* Integration with AV Scanning for File Uploads - detects malicious files
-uploaded through the web application.
-* Tracking Sensitive Data - Tracks Credit Card usage and blocks leakages.
-* Trojan Protection - Detecting access to Trojans horses.
-* Identification of Application Defects - alerts on application
-misconfigurations.
-* Error Detection and Hiding - Disguising error messages sent by the
-server.
-
-
-----------------------------------
-ModSecurity Rules from Trustwave SpiderLabs
-
-Project Site:
-https://www.trustwave.com/modsecurity-rules-support.php
-
-Download:
-https://ssl.trustwave.com/web-application-firewall
-
-----------------------------------
-
-
-
-Trustwave now provides a commercial certified rule set for ModSecurity 2.x
-that protects against known attacks that target vulnerabilities in public
-software and are based on intelligence gathered from real-world
-investigations, honeypot data and research.
-
-1. More than 16,000 specific rules, broken out into the following attack
-categories:
- * SQL injection
- * Cross-site Scripting (XSS)
- * Local File Include
- * Remote File Include
-
-2. User option for application specific rules, covering the same
-vulnerability classes for applications such as:
- * WordPress
- * cPanel
- * osCommerce
- * Joomla
- * For a complete listing of application coverage, please refer to this
-link (which is updated daily).
-https://modsecurity.org/projects/commercial/rules/application_coverage.html
-
-3. Complements and integrates with the OWASP Core Rule Set
-4. IP Reputation capabilities which provide protection against malicious
-clients identified by the Trustwave SpiderLabs Distributed Web Honeypots
-5. Malware Detection capabilities which prevent your web site from
-distributing malicious code to clients.
-##############################################
diff --git a/README.md b/README.md
new file mode 100644
index 0000000000..a823585172
--- /dev/null
+++ b/README.md
@@ -0,0 +1,22 @@
+# ModSecurity 2
+
+https://www.modsecurity.org/
+
+Copyright (c) 2004-2024 Trustwave Holdings, Inc. (https://www.trustwave.com/)
+Copyright (c) 2024-2024 OWASP ModSecurity Project (https://www.owasp.org/)
+
+You may not use this file except in compliance with the License. You may obtain a copy of the License at: https://www.apache.org/licenses/LICENSE-2.0
+
+If any of the files related to licensing are missing or if you have any other questions related to licensing please contact us here: modsecurity@owasp.org.
+
+## Documentation
+
+Please refer to: [the documentation folder](https://github.com/owasp-modsecurity/ModSecurity/tree/v2/master/doc) for the reference manual.
+
+## Sponsor Note
+
+Original Development of ModSecurity was sponsored by Trustwave. In 2024, [stewardship was transferred to OWASP](https://www.trustwave.com/en-us/resources/blogs/spiderlabs-blog/trustwave-transfers-modsecurity-custodianship-to-the-open-worldwide-application-security-project/).
+
+Contact us for sponsorship!
+
+You can also send us donations using the [OWASP donations page](https://owasp.org/donate/?reponame=www-project-modsecurity&title=OWASP+ModSecurity).
diff --git a/README_WINDOWS.TXT b/README_WINDOWS.TXT
deleted file mode 100644
index 94c2bc9db9..0000000000
--- a/README_WINDOWS.TXT
+++ /dev/null
@@ -1,192 +0,0 @@
-=====================================================================
-MOD_SECURITY 2.6 Command-line Build notes for Windows 4/2/2011
-by Tom Donovam
-=====================================================================
-
-PREREQUISITES:
-
- Microsoft Visual Studio C++ tested with Visual Studio 2008 (aka VC9)
-
- CMake build system from: http://www.cmake.org/ tested with CMake v2.8.0
-
- Apache 2.2.x from: http://httpd.apache.org/ tested with Apache 2.2.17
- Apache must be built from source using the same Visual Studio compiler as mod_security.
-
- PCRE Perl Compatible Regular Expression library from: http://www.pcre.org/ tested with PCRE v8.12
-
- LibXML2 from: http://xmlsoft.org/ tested with LibXML2 v2.7.7
- Note that LibXML2 v2.7.8 does not build correctly for Windows
-
- Lua Scripting Language from: http://www.lua.org/ tested with Lua v5.1.4
-
- cURL multiprotocol file transfer library from: http://curl.haxx.se/ tested with cURL v7.21.4
-
-
-BEFORE BUILDING
-
-The directory where you build software from source ( C:\work in this exmaple)
-must contain the Apache source you used to build the Apache web serverand the mod_security source
-
- Apache source is in C:\work\httpd-2.2.17 in this example.
- Apache has been installed to C:\Apache2217 in this example.
- Mod_security source is in C:\work\mod_security in this example.
-
-Download and untar the prerequite library sources:
-
- Download pcre-8.12.tar.gz from ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/
- untar it into C:\work\ creating C:\work\pcre-8.12
-
- Download libxml2-2.7.7.tar.gz from ftp://xmlsoft.org/libxml2/
- untar it into C:\work\ creating C:\work\libxml2-2.7.7
-
- Download lua-5.1.4.tar.gz from http://www.lua.org/ftp/
- untar it into C:\work\ creating C:\work\lua-5.1.4
-
- Download curl-7.21.4.tar.gz from http://curl.haxx.se/download.html
- untar it into C:\work\ creating C:\work\curl-7.21.4
-
-Setup your build environment:
-
- The PATH environment variable must include the Visual Studio variables as set by vsvars32.bat
- The PATH environment variable must also include the CMAKE bin\ directory
-
- Set an environment variable to the Apache source code directory:
-
- SET HTTPD_BUILD=C:\work\httpd-2.2.17
-
- If OpenSSL and Zlib support were included when you built Apache 2.2, and you want them available to LIBXML2 and CURL
-
- Ensure that cURL and libXML2 can find the OpenSSL and Zlib includes and libraries that Apache was built with.
-
- SET INCLUDE=%INCLUDE%;%HTTPD_BUILD%\srclib\openssl\inc32;%HTTPD_BUILD%\srclib\zlib
- SET LIB=%LIB%;%HTTPD_BUILD%\srclib\openssl\out32dll;%HTTPD_BUILD%\srclib\zlib
-
- Ensure that cURL and libXML2 don't use the static zlib library: zlib.lib.
- Force cURL and libXML2 to use zdll.lib instead, requiring zlib1.dll at runtime:
-
- IF EXIST %HTTPD_BUILD%\srclib\zlib\zlib.lib DEL %HTTPD_BUILD%\srclib\zlib\zlib.lib
-
-BUILD PCRE-8.12
-
- CD C:\work\pcre-8.12
- CMAKE -G "NMake Makefiles" -DCMAKE_BUILD_TYPE=RelWithDebInfo -DBUILD_SHARED_LIBS=True
- NMAKE
-
-BUILD LIBXML2-2.7.7 (note: the more recent version: 2.7.8 does not build correctly on Windows)
-
- CD C:\work\libxml2-2.7.7\win32
- CSCRIPT configure.js iconv=no vcmanifest=yes zlib=yes
- NMAKE -f Makefile.msvc
-
-BUILD LUA-5.1.4
-
- CD C:\work\lua-5.1.4\src
- CL /Ox /arch:SSE2 /GF /GL /Gy /FD /EHsc /MD /Zi /TC /wd4005 /D "_MBCS" /D "LUA_CORE" /D "LUA_BUILD_AS_DLL" /D "_CRT_SECURE_NO_WARNINGS" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_WIN32" /D "_WINDLL" /c *.c
- DEL lua.obj luac.obj
- LINK /DLL /LTCG /DEBUG /OUT:lua5.1.dll *.obj
- IF EXIST lua5.1.dll.manifest MT -manifest lua5.1.dll.manifest -outputresource:lua5.1.dll;2
-
-BUILD CURL-7.21.4
-
- CD C:\work\curl-7.21.4
- CMAKE -G "NMake Makefiles" -DCMAKE_BUILD_TYPE=RelWithDebInfo -DBUILD_SHARED_LIBS=True -DCURL_ZLIB=True
- NMAKE
-
-BUILD MOD_SECURITY-2.6
-
- CD C:\work\mod_security\apache2
- NMAKE -f Makefile.win APACHE=C:\Apache2217 PCRE=C:\work\pcre-8.12 LIBXML2=C:\work\libxml2-2.7.7 LUA=C:\work\lua-5.1.4\src
-
-INSTALL MOD_SECURITY AND RUN APACHE
-
-Copy these five files to C:\Apache2217\bin:
- C:\work\pcre-8.12\pcre.dll C:\Apache2217\bin\
- C:\work\lua-5.1.4\src\lua5.1.dll C:\Apache2217\bin\
- C:\work\libxml2-2.7.7\win32\bin.msvc\libxml2.dll C:\Apache2217\bin\
- C:\work\curl-7.21.4\libcurl.dll C:\Apache2217\bin\
- C:\work\mod_security\apache2\mlogc-src\mlogc.exe
-
-Copy this one file to C:\Apache2217\modules:
-
- C:\work\mod_security\apache2\mod_security2.so
-
-You may also copy C:\work\curl-7.21.4\curl.exe to C:\Apache2217\bin, if you want to use the cURL command-line program.
-
-Download the core rules from http://sourceforge.net/projects/mod-security/files/modsecurity-crs/0-CURRENT/
-and unzip them into C:\Apache2217\conf\modsecurity_crs
-
-Add configuration directives to your Apache conf\httpd.conf:
-
- # mod_security requires mod_unique_id
- LoadModule unique_id_module modules/mod_unique_id.so
-
- # mod_security
- LoadModule security2_module modules/mod_security2.so
-
- SecRuleEngine On
- SecDataDir logs
- Include conf/modsecurity_crs/*.conf
- Include conf/modsecurity_crs/base_rules/*.conf
- SecAuditEngine RelevantOnly
- SecAuditLogRelevantStatus "^(?:5|4\d[^4])"
- SecAuditLogType Serial
- SecAuditLogParts ABCDEFGHZ
- SecAuditLog logs/modsecurity.log
-
-
-
-==============================================================================================
-OPTIONAL: BUILD AND CONFIGURE THE MOD_SECURITY-2.6 MLOGC piped-logging program
-
-Edit the top of C:\work\mod_security\apache2\mlogc-src\Makefile.win and set your local paths
-
- # Path to Apache httpd installation
- BASE = C:\Apache2217
-
- # Paths to required libraries
- PCRE = C:\work\pcre-8.12
- CURL = C:\work\curl-7.21.4
-
- # Linking libraries
- LIBS = $(BASE)\lib\libapr-1.lib \
- $(BASE)\lib\libaprutil-1.lib \
- $(PCRE)\pcre.lib \
- $(CURL)\libcurl_imp.lib \
- wsock32.lib
-
-Build the mlogc.exe program:
-
- CD C:\work\mod_security_trunk\mlogc
- NMAKE -f Makefile.win
-
-Copy mlocg.exe to C:\Apache2217\bin\
-
-Create a new command file C:\Apache2217\bin\mlogc.bat with one line:
-
- C:\Apache2217\bin\mlogc.exe C:\Apache2217\conf\mlogc.conf
-
-Create a new configuration file C:\Apache2217\conf\mlogc.conf to control the piped-logging program mlogc.exe.
-Here is an example conf\mlogc.conf:
-
- CollectorRoot "C:/Apache2217/logs"
- ConsoleURI "https://localhost:8888/rpc/auditLogReceiver"
- SensorUsername "test"
- SensorPassword "testtest"
- LogStorageDir "data"
- TransactionLog "mlogc-transaction.log"
- QueuePath "mlogc-queue.log"
- ErrorLog "mlogc-error.log"
- LockFile "mlogc.lck"
- KeepEntries 0
- ErrorLogLevel 2
- MaxConnections 10
- MaxWorkerRequests 1000
- TransactionDelay 50
- StartupDelay 5000
- CheckpointInterval 15
- ServerErrorTimeout 60
-
-Change the SecAuditLog directive in conf\httpd.conf to pipe the log data to mlogc
-instead of writing them to a file:
-
- SecAuditLog |C:/Apache2217/bin/mlogc.bat
diff --git a/README_WINDOWS.md b/README_WINDOWS.md
new file mode 100644
index 0000000000..dcb7e0db3a
--- /dev/null
+++ b/README_WINDOWS.md
@@ -0,0 +1,194 @@
+
+## ModSecurity 2.x Command-line build notes for Windows
+
+by Tom Donovam, 4/2/2011
+
+
+## Prerequisites:
+
+Dependency | Tested with | Note
+----|------|----
+Microsoft Visual Studio C++ | Visual Studio 2013 (aka VC12) |
+[CMake build system](http://www.cmake.org/) | CMake v3.8.2 |
+[Apache 2.4.x](http://httpd.apache.org/) | Apache 2.4.27 | Apache must be built from source using the same Visual Studio compiler as mod_security.
+[PCRE, Perl Compatible Regular Expression library](http://www.pcre.org/) | PCRE v8.40
+[LibXML2](http://xmlsoft.org/) | LibXML2 v2.9.4 |
+[Lua Scripting Language](http://www.lua.org/) | Lua v5.3.4
+[cURL multiprotocol file transfer library](http://curl.haxx.se/) | cURL v7.54.0
+
+
+## Before building
+
+The directory where you build software from source ( ``C:\work`` in this exmaple)
+must contain the Apache source you used to build the Apache web serverand the mod_security source
+
+ Apache source is in C:\work\httpd-2.4.27 in this example.
+ Apache has been installed to C:\Apache2427 in this example.
+ Mod_security source is in C:\work\mod_security in this example.
+
+## Download and untar the prerequisite library sources:
+
+ Download pcre-8.40.tar.gz from ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/
+ untar it into C:\work\ creating C:\work\pcre-8.40
+
+ Download libxml2-2.9.4.tar.gz from ftp://xmlsoft.org/libxml2/
+ untar it into C:\work\ creating C:\work\libxml2-2.9.4
+
+ Download lua-5.3.4.tar.gz from http://www.lua.org/ftp/
+ untar it into C:\work\ creating C:\work\lua-5.3.4
+
+ Download curl-7.54.0.tar.gz from http://curl.haxx.se/download.html
+ untar it into C:\work\ creating C:\work\curl-7.54.0
+
+## Setup your build environment:
+
+1. The ``PATH`` environment variable must include the Visual Studio variables as set by ``vsvars32.bat``
+
+2. The ``PATH`` environment variable must also include the CMAKE ``bin\`` directory
+
+3. Set an environment variable to the Apache source code directory:
+
+```
+ SET HTTPD_BUILD=C:\work\httpd-2.4.27
+```
+
+### Optional:
+
+If OpenSSL and zlib support were included when you built Apache 2.4, and you want them available to LibXML2 and cURL
+
+1. Ensure that cURL and LibXML2 can find the OpenSSL and zlib includes and libraries that Apache was built with.
+
+```
+ SET INCLUDE=%INCLUDE%;%HTTPD_BUILD%\srclib\openssl\inc32;%HTTPD_BUILD%\srclib\zlib
+ SET LIB=%LIB%;%HTTPD_BUILD%\srclib\openssl\out32dll;%HTTPD_BUILD%\srclib\zlib
+```
+
+2. Ensure that cURL and libXML2 don't use the static zlib library: ``zlib.lib``. Force cURL and libXML2 to use ``zdll.lib`` instead, requiring ``zlib1.dll`` at runtime:
+
+```
+ IF EXIST %HTTPD_BUILD%\srclib\zlib\zlib.lib DEL %HTTPD_BUILD%\srclib\zlib\zlib.lib
+```
+
+## Build
+
+### PCRE-8.40
+
+ CD C:\work\pcre-8.40
+ CMAKE -G "NMake Makefiles" -DCMAKE_BUILD_TYPE=RelWithDebInfo -DBUILD_SHARED_LIBS=True
+ NMAKE
+
+### LibXML2-2.9.4
+
+ CD C:\work\libxml2-2.9.4\win32
+ CSCRIPT configure.js iconv=no vcmanifest=yes zlib=yes
+ NMAKE -f Makefile.msvc
+
+### Lua-5.3.4
+
+ CD C:\work\lua-5.3.4\src
+ CL /Ox /arch:SSE2 /GF /GL /Gy /FD /EHsc /MD /Zi /TC /wd4005 /D "_MBCS" /D "LUA_CORE" /D "LUA_BUILD_AS_DLL" /D "_CRT_SECURE_NO_WARNINGS" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_WIN32" /D "_WINDLL" /c *.c
+ DEL lua.obj luac.obj
+ LINK /DLL /LTCG /DEBUG /OUT:lua5.1.dll *.obj
+ IF EXIST lua5.1.dll.manifest MT -manifest lua5.1.dll.manifest -outputresource:lua5.1.dll;2
+
+### cURL-7.54.0
+
+ CD C:\work\curl-7.54.0
+ CMAKE -G "NMake Makefiles" -DCMAKE_BUILD_TYPE=RelWithDebInfo -DBUILD_SHARED_LIBS=True -DCURL_ZLIB=True
+ NMAKE
+
+### ModSecurity-2.9.x
+
+ CD C:\work\mod_security\apache2
+ NMAKE -f Makefile.win APACHE=C:\Apache2427 PCRE=C:\work\pcre-8.40 LIBXML2=C:\work\libxml2-2.9.4 LUA=C:\work\lua-5.3.4\src
+
+## Install ModSecurity and run Apache
+
+Copy these five files to ``C:\Apache2427\bin``:
+
+ C:\work\pcre-8.40\pcre.dll C:\Apache2427\bin\
+ C:\work\lua-5.3.4\src\lua5.1.dll C:\Apache2427\bin\
+ C:\work\libxml2-2.9.4\win32\bin.msvc\libxml2.dll C:\Apache2427\bin\
+ C:\work\curl-7.54.0\libcurl.dll C:\Apache2427\bin\
+ C:\work\mod_security\apache2\mlogc-src\mlogc.exe
+
+Copy this one file to ``C:\Apache2427\modules``:
+
+ C:\work\mod_security\apache2\mod_security2.so
+
+You may also copy ``C:\work\curl-7.54.0\curl.exe`` to ``C:\Apache2427\bin``, if you want to use the cURL command-line program.
+
+Download the core rules from http://sourceforge.net/projects/mod-security/files/modsecurity-crs/0-CURRENT/ and unzip them into ``C:\Apache2427\conf\modsecurity_crs``
+
+Add configuration directives to your Apache conf\httpd.conf:
+
+ # mod_security requires mod_unique_id
+ LoadModule unique_id_module modules/mod_unique_id.so
+
+ # mod_security
+ LoadModule security2_module modules/mod_security2.so
+
+ SecRuleEngine On
+ SecDataDir logs
+ Include conf/modsecurity_crs/*.conf
+ Include conf/modsecurity_crs/base_rules/*.conf
+ SecAuditEngine RelevantOnly
+ SecAuditLogRelevantStatus "^(?:5|4\d[^4])"
+ SecAuditLogType Serial
+ SecAuditLogParts ABCDEFGHZ
+ SecAuditLog logs/modsecurity.log
+
+
+## Optional: Build and configure the ModSecurity-2.x MLOGC piped-logging program
+
+Edit the top of ``C:\work\mod_security\apache2\mlogc-src\Makefile.win`` and set your local paths
+
+ # Path to Apache httpd installation
+ BASE = C:\Apache2427
+
+ # Paths to required libraries
+ PCRE = C:\work\pcre-8.40
+ CURL = C:\work\curl-7.54.0
+
+ # Linking libraries
+ LIBS = $(BASE)\lib\libapr-1.lib \
+ $(BASE)\lib\libaprutil-1.lib \
+ $(PCRE)\pcre.lib \
+ $(CURL)\libcurl_imp.lib \
+ wsock32.lib
+
+Build the ``mlogc.exe`` program:
+
+ CD C:\work\mod_security_trunk\mlogc
+ NMAKE -f Makefile.win
+
+Copy ``mlocg.exe`` to ``C:\Apache2427\bin\``
+
+Create a new command file ``C:\Apache2427\bin\mlogc.bat`` with one line:
+
+ C:\Apache2427\bin\mlogc.exe C:\Apache2427\conf\mlogc.conf
+
+Create a new configuration file ``C:\Apache2427\conf\mlogc.conf`` to control the piped-logging program ``mlogc.exe``.
+Here is an example ``conf\mlogc.conf``:
+
+ CollectorRoot "C:/Apache2427/logs"
+ ConsoleURI "https://localhost:8888/rpc/auditLogReceiver"
+ SensorUsername "test"
+ SensorPassword "testtest"
+ LogStorageDir "data"
+ TransactionLog "mlogc-transaction.log"
+ QueuePath "mlogc-queue.log"
+ ErrorLog "mlogc-error.log"
+ LockFile "mlogc.lck"
+ KeepEntries 0
+ ErrorLogLevel 2
+ MaxConnections 10
+ MaxWorkerRequests 1000
+ TransactionDelay 50
+ StartupDelay 5000
+ CheckpointInterval 15
+ ServerErrorTimeout 60
+
+Change the SecAuditLog directive in ``conf\httpd.conf`` to pipe the log data to mlogc instead of writing them to a file:
+
+ SecAuditLog |C:/Apache2427/bin/mlogc.bat
diff --git a/apache2/Makefile.am b/apache2/Makefile.am
index e7bf787bdc..50246829bd 100644
--- a/apache2/Makefile.am
+++ b/apache2/Makefile.am
@@ -42,6 +42,7 @@ mod_security2_la_CFLAGS = @APR_CFLAGS@ \
@LUA_CFLAGS@ \
@MODSEC_EXTRA_CFLAGS@ \
@PCRE_CFLAGS@ \
+ @PCRE2_CFLAGS@ \
@YAJL_CFLAGS@ \
@SSDEEP_CFLAGS@
@@ -50,15 +51,16 @@ mod_security2_la_CPPFLAGS = @APR_CPPFLAGS@ \
@CURL_CPPFLAGS@ \
@LIBXML2_CFLAGS@ \
@LIBXML2_CPPFLAGS@ \
- @PCRE_CPPFLAGS@
+ @PCRE_CPPFLAGS@ \
+ @PCRE2_CPPFLAGS@
mod_security2_la_LIBADD = @APR_LDADD@ \
@APU_LDADD@ \
@CURL_LDADD@ \
- @LIBXML2_CFLAGS@ \
@LIBXML2_LDADD@ \
@LUA_LDADD@ \
@PCRE_LDADD@ \
+ @PCRE2_LDADD@ \
@YAJL_LDADD@
if AIX
@@ -67,10 +69,10 @@ mod_security2_la_LDFLAGS = -module -avoid-version \
@APU_LDFLAGS@ \
@APXS_LDFLAGS@ \
@CURL_LDFLAGS@ \
- @LIBXML2_CFLAGS@ \
@LIBXML2_LDFLAGS@ \
@LUA_LDFLAGS@ \
@PCRE_LDFLAGS@ \
+ @PCRE2_LDFLAGS@ \
@YAJL_LDFLAGS@ \
@SSDEEP_LDFLAGS@
endif
@@ -81,10 +83,10 @@ mod_security2_la_LDFLAGS = -module -avoid-version \
@APU_LDFLAGS@ \
@APXS_LDFLAGS@ \
@CURL_LDFLAGS@ \
- @LIBXML2_CFLAGS@ \
@LIBXML2_LDFLAGS@ \
@LUA_LDFLAGS@ \
@PCRE_LDFLAGS@ \
+ @PCRE2_LDFLAGS@ \
@YAJL_LDFLAGS@ \
@SSDEEP_LDFLAGS@
endif
@@ -95,10 +97,10 @@ mod_security2_la_LDFLAGS = -module -avoid-version \
@APU_LDFLAGS@ \
@APXS_LDFLAGS@ \
@CURL_LDFLAGS@ \
- @LIBXML2_CFLAGS@ \
@LIBXML2_LDFLAGS@ \
@LUA_LDFLAGS@ \
@PCRE_LDFLAGS@ \
+ @PCRE2_LDFLAGS@ \
@YAJL_LDFLAGS@ \
@SSDEEP_LDFLAGS@
endif
@@ -109,10 +111,10 @@ mod_security2_la_LDFLAGS = -module -avoid-version \
@APU_LDFLAGS@ \
@APXS_LDFLAGS@ \
@CURL_LDFLAGS@ \
- @LIBXML2_CFLAGS@ \
@LIBXML2_LDFLAGS@ \
@LUA_LDFLAGS@ \
@PCRE_LDFLAGS@ \
+ @PCRE2_LDFLAGS@ \
@YAJL_LDFLAGS@ \
@SSDEEP_LDFLAGS@
endif
@@ -123,10 +125,10 @@ mod_security2_la_LDFLAGS = -no-undefined -module -avoid-version -R @PCRE_LD_PATH
@APU_LDFLAGS@ \
@APXS_LDFLAGS@ \
@CURL_LDFLAGS@ \
- @LIBXML2_CFLAGS@ \
@LIBXML2_LDFLAGS@ \
@LUA_LDFLAGS@ \
@PCRE_LDFLAGS@ \
+ @PCRE2_LDFLAGS@ \
@YAJL_LDFLAGS@ \
@SSDEEP_LDFLAGS@
endif
@@ -137,10 +139,10 @@ mod_security2_la_LDFLAGS = -no-undefined -module -avoid-version \
@APU_LDFLAGS@ \
@APXS_LDFLAGS@ \
@CURL_LDFLAGS@ \
- @LIBXML2_CFLAGS@ \
@LIBXML2_LDFLAGS@ \
@LUA_LDFLAGS@ \
@PCRE_LDFLAGS@ \
+ @PCRE2_LDFLAGS@ \
@YAJL_LDFLAGS@ \
@SSDEEP_LDFLAGS@
endif
@@ -151,10 +153,10 @@ mod_security2_la_LDFLAGS = -no-undefined -module -avoid-version \
@APU_LDFLAGS@ \
@APXS_LDFLAGS@ \
@CURL_LDFLAGS@ \
- @LIBXML2_CFLAGS@ \
@LIBXML2_LDFLAGS@ \
@LUA_LDFLAGS@ \
@PCRE_LDFLAGS@ \
+ @PCRE2_LDFLAGS@ \
@YAJL_LDFLAGS@ \
@SSDEEP_LDFLAGS@
endif
@@ -165,10 +167,10 @@ mod_security2_la_LDFLAGS = -no-undefined -module -avoid-version \
@APU_LDFLAGS@ \
@APXS_LDFLAGS@ \
@CURL_LDFLAGS@ \
- @LIBXML2_CFLAGS@ \
@LIBXML2_LDFLAGS@ \
@LUA_LDFLAGS@ \
@PCRE_LDFLAGS@ \
+ @PCRE2_LDFLAGS@ \
@YAJL_LDFLAGS@ \
@SSDEEP_LDFLAGS@
endif
diff --git a/apache2/acmp.c b/apache2/acmp.c
index 6e796b38db..3691dd12e5 100644
--- a/apache2/acmp.c
+++ b/apache2/acmp.c
@@ -251,18 +251,6 @@ static void acmp_add_node_to_parent(acmp_node_t *parent, acmp_node_t *child) {
}
}
-/**
- * Copies values from one node to another, without child/sibling/fail pointers
- * and without state variables.
- */
-static void acmp_clone_node_no_state(acmp_node_t *from, acmp_node_t *to) {
- memcpy(to, from, sizeof(acmp_node_t));
- to->child = NULL;
- to->sibling = NULL;
- to->fail = NULL;
- to->hit_count = 0;
-}
-
static inline acmp_node_t *acmp_btree_find(acmp_node_t *node, acmp_utf8_char_t letter) {
acmp_btree_node_t *bnode = node->btree;
for (;;) {
diff --git a/apache2/apache2_config.c b/apache2/apache2_config.c
index bfbcb83468..f410f40ed5 100644
--- a/apache2/apache2_config.c
+++ b/apache2/apache2_config.c
@@ -1,6 +1,6 @@
/*
* ModSecurity for Apache 2.x, http://www.modsecurity.org/
-* Copyright (c) 2004-2013 Trustwave Holdings, Inc. (http://www.trustwave.com/)
+* Copyright (c) 2004-2022 Trustwave Holdings, Inc. (http://www.trustwave.com/)
*
* You may not use this file except in compliance with
* the License. You may obtain a copy of the License at
@@ -26,6 +26,9 @@
#include "msc_lua.h"
#endif
+#ifdef APLOG_USE_MODULE
+ APLOG_USE_MODULE(security2);
+#endif
/* -- Directory context creation and initialisation -- */
@@ -50,6 +53,8 @@ void *create_directory_config(apr_pool_t *mp, char *path)
dcfg->reqbody_inmemory_limit = NOT_SET;
dcfg->reqbody_limit = NOT_SET;
dcfg->reqbody_no_files_limit = NOT_SET;
+ dcfg->reqbody_json_depth_limit = NOT_SET;
+ dcfg->arguments_limit = NOT_SET;
dcfg->resbody_access = NOT_SET;
dcfg->debuglog_name = NOT_SET_P;
@@ -73,6 +78,9 @@ void *create_directory_config(apr_pool_t *mp, char *path)
/* audit log variables */
dcfg->auditlog_flag = NOT_SET;
dcfg->auditlog_type = NOT_SET;
+ #ifdef WITH_YAJL
+ dcfg->auditlog_format = NOT_SET;
+ #endif
dcfg->max_rule_time = NOT_SET;
dcfg->auditlog_dirperms = NOT_SET;
dcfg->auditlog_fileperms = NOT_SET;
@@ -158,6 +166,7 @@ void *create_directory_config(apr_pool_t *mp, char *path)
/* xml external entity */
dcfg->xml_external_entity = NOT_SET;
+ dcfg->parse_xml_into_args = NOT_SET;
return dcfg;
}
@@ -171,6 +180,9 @@ static void copy_rules_phase(apr_pool_t *mp,
apr_array_header_t *child_phase_arr,
apr_array_header_t *exceptions_arr)
{
+ assert(parent_phase_arr != NULL);
+ assert(child_phase_arr != NULL);
+ assert(exceptions_arr != NULL);
rule_exception **exceptions;
msre_rule **rules;
int i, j;
@@ -179,11 +191,14 @@ static void copy_rules_phase(apr_pool_t *mp,
rules = (msre_rule **)parent_phase_arr->elts;
for(i = 0; i < parent_phase_arr->nelts; i++) {
msre_rule *rule = (msre_rule *)rules[i];
+ assert(rule != NULL);
+ assert(rule->actionset != NULL);
int copy = 1;
if (mode == 0) {
/* First rule in the chain. */
exceptions = (rule_exception **)exceptions_arr->elts;
+ assert(exceptions != NULL);
for(j = 0; j < exceptions_arr->nelts; j++) {
/* Process exceptions. */
@@ -231,7 +246,7 @@ static void copy_rules_phase(apr_pool_t *mp,
if (copy > 0) {
#ifdef DEBUG_CONF
- ap_log_perror(APLOG_MARK, APLOG_STARTUP|APLOG_NOERRNO, 0, mp, "Copy rule %pp [id \"%s\"]", rule, rule->actionset->id);
+ ap_log_perror(APLOG_MARK, APLOG_STARTUP|APLOG_NOERRNO, 0, mp, "Copy rule %pp [id \"%s\"]", rule, id_log(rule));
#endif
/* Copy the rule. */
@@ -243,7 +258,7 @@ static void copy_rules_phase(apr_pool_t *mp,
} else {
if (mode == 2) {
#ifdef DEBUG_CONF
- ap_log_perror(APLOG_MARK, APLOG_STARTUP|APLOG_NOERRNO, 0, mp, "Copy chain %pp for rule %pp [id \"%s\"]", rule, rule->chain_starter, rule->chain_starter->actionset->id);
+ ap_log_perror(APLOG_MARK, APLOG_STARTUP|APLOG_NOERRNO, 0, mp, "Copy chain %pp for rule %pp [id \"%s\"]", rule, rule->chain_starter, id_log(rule->chain_starter));
#endif
/* Copy the rule (it belongs to the chain we want to include. */
@@ -269,18 +284,21 @@ static void copy_rules_phase(apr_pool_t *mp,
* @retval -1 Something went wrong.
*
*/
-static int copy_rules(apr_pool_t *mp, msre_ruleset *parent_ruleset,
+static void copy_rules(apr_pool_t *mp, msre_ruleset *parent_ruleset,
msre_ruleset *child_ruleset,
apr_array_header_t *exceptions_arr)
{
- int ret = 0;
-
- if (parent_ruleset == NULL || child_ruleset == NULL ||
- exceptions_arr == NULL) {
- ret = -1;
- goto failed;
+ assert(parent_ruleset != NULL);
+ assert(child_ruleset != NULL);
+ assert(exceptions_arr != NULL);
+ // Normally useless code, left to be safe for the moment
+ if (parent_ruleset == NULL || child_ruleset == NULL || exceptions_arr == NULL) {
+ if (parent_ruleset == NULL) ap_log_perror(APLOG_MARK, APLOG_EMERG, 0, mp, "copy_rules: parent_ruleset is NULL");
+ if (child_ruleset == NULL) ap_log_perror(APLOG_MARK, APLOG_EMERG, 0, mp, "copy_rules: child_ruleset is NULL");
+ if (exceptions_arr == NULL) ap_log_perror(APLOG_MARK, APLOG_EMERG, 0, mp, "copy_rules: exceptions_arr is NULL");
+ return;
}
-
+
copy_rules_phase(mp, parent_ruleset->phase_request_headers,
child_ruleset->phase_request_headers, exceptions_arr);
copy_rules_phase(mp, parent_ruleset->phase_request_body,
@@ -291,9 +309,6 @@ static int copy_rules(apr_pool_t *mp, msre_ruleset *parent_ruleset,
child_ruleset->phase_response_body, exceptions_arr);
copy_rules_phase(mp, parent_ruleset->phase_logging,
child_ruleset->phase_logging, exceptions_arr);
-
-failed:
- return ret;
}
/**
@@ -301,6 +316,8 @@ static int copy_rules(apr_pool_t *mp, msre_ruleset *parent_ruleset,
*/
void *merge_directory_configs(apr_pool_t *mp, void *_parent, void *_child)
{
+ assert(_parent != NULL);
+ assert(_child != NULL);
directory_config *parent = (directory_config *)_parent;
directory_config *child = (directory_config *)_child;
directory_config *merged = create_directory_config(mp, NULL);
@@ -329,6 +346,10 @@ void *merge_directory_configs(apr_pool_t *mp, void *_parent, void *_child)
? parent->reqbody_limit : child->reqbody_limit);
merged->reqbody_no_files_limit = (child->reqbody_no_files_limit == NOT_SET
? parent->reqbody_no_files_limit : child->reqbody_no_files_limit);
+ merged->reqbody_json_depth_limit = (child->reqbody_json_depth_limit == NOT_SET
+ ? parent->reqbody_json_depth_limit : child->reqbody_json_depth_limit);
+ merged->arguments_limit = (child->arguments_limit == NOT_SET
+ ? parent->arguments_limit : child->arguments_limit);
merged->resbody_access = (child->resbody_access == NOT_SET
? parent->resbody_access : child->resbody_access);
@@ -412,7 +433,6 @@ void *merge_directory_configs(apr_pool_t *mp, void *_parent, void *_child)
/* Copy the rules from the parent context. */
merged->ruleset = msre_ruleset_create(parent->ruleset->engine, mp);
- /* TODO: copy_rules return code should be taken into consideration. */
copy_rules(mp, parent->ruleset, merged->ruleset, child->rule_exceptions);
} else
if (parent->ruleset == NULL) {
@@ -439,7 +459,6 @@ void *merge_directory_configs(apr_pool_t *mp, void *_parent, void *_child)
/* Copy parent rules, then add child rules to it. */
merged->ruleset = msre_ruleset_create(parent->ruleset->engine, mp);
- /* TODO: copy_rules return code should be taken into consideration. */
copy_rules(mp, parent->ruleset, merged->ruleset, child->rule_exceptions);
apr_array_cat(merged->ruleset->phase_request_headers,
@@ -503,6 +522,10 @@ void *merge_directory_configs(apr_pool_t *mp, void *_parent, void *_child)
merged->auditlog2_fd = parent->auditlog2_fd;
merged->auditlog2_name = parent->auditlog2_name;
}
+ #ifdef WITH_YAJL
+ merged->auditlog_format = (child->auditlog_format == NOT_SET
+ ? parent->auditlog_format : child->auditlog_format);
+ #endif
merged->auditlog_storage_dir = (child->auditlog_storage_dir == NOT_SET_P
? parent->auditlog_storage_dir : child->auditlog_storage_dir);
merged->auditlog_parts = (child->auditlog_parts == NOT_SET_P
@@ -618,6 +641,8 @@ void *merge_directory_configs(apr_pool_t *mp, void *_parent, void *_child)
/* xml external entity */
merged->xml_external_entity = (child->xml_external_entity == NOT_SET
? parent->xml_external_entity : child->xml_external_entity);
+ merged->parse_xml_into_args = (child->parse_xml_into_args == NOT_SET
+ ? parent->parse_xml_into_args : child->parse_xml_into_args);
return merged;
}
@@ -641,6 +666,8 @@ void init_directory_config(directory_config *dcfg)
dcfg->reqbody_inmemory_limit = REQUEST_BODY_DEFAULT_INMEMORY_LIMIT;
if (dcfg->reqbody_limit == NOT_SET) dcfg->reqbody_limit = REQUEST_BODY_DEFAULT_LIMIT;
if (dcfg->reqbody_no_files_limit == NOT_SET) dcfg->reqbody_no_files_limit = REQUEST_BODY_NO_FILES_DEFAULT_LIMIT;
+ if (dcfg->reqbody_json_depth_limit == NOT_SET) dcfg->reqbody_json_depth_limit = REQUEST_BODY_JSON_DEPTH_DEFAULT_LIMIT;
+ if (dcfg->arguments_limit == NOT_SET) dcfg->arguments_limit = ARGUMENTS_LIMIT;
if (dcfg->resbody_access == NOT_SET) dcfg->resbody_access = 0;
if (dcfg->of_limit == NOT_SET) dcfg->of_limit = RESPONSE_BODY_DEFAULT_LIMIT;
if (dcfg->if_limit_action == NOT_SET) dcfg->if_limit_action = REQUEST_BODY_LIMIT_ACTION_REJECT;
@@ -667,6 +694,9 @@ void init_directory_config(directory_config *dcfg)
/* audit log variables */
if (dcfg->auditlog_flag == NOT_SET) dcfg->auditlog_flag = 0;
if (dcfg->auditlog_type == NOT_SET) dcfg->auditlog_type = AUDITLOG_SERIAL;
+ #ifdef WITH_YAJL
+ if (dcfg->auditlog_format == NOT_SET) dcfg->auditlog_format = AUDITLOGFORMAT_NATIVE;
+ #endif
if (dcfg->max_rule_time == NOT_SET) dcfg->max_rule_time = 0;
if (dcfg->auditlog_dirperms == NOT_SET) dcfg->auditlog_dirperms = CREATEMODE_DIR;
if (dcfg->auditlog_fileperms == NOT_SET) dcfg->auditlog_fileperms = CREATEMODE;
@@ -722,8 +752,13 @@ void init_directory_config(directory_config *dcfg)
if (dcfg->col_timeout == NOT_SET) dcfg->col_timeout = 3600;
/* Hash */
- if (dcfg->crypto_key == NOT_SET_P) dcfg->crypto_key = getkey(dcfg->mp);
- if (dcfg->crypto_key_len == NOT_SET) dcfg->crypto_key_len = strlen(dcfg->crypto_key);
+ if (dcfg->hash_is_enabled == HASH_ENABLED) {
+ if (dcfg->crypto_key == NOT_SET_P) dcfg->crypto_key = getkey(dcfg->mp);
+ if (dcfg->crypto_key_len == NOT_SET) dcfg->crypto_key_len = strlen(dcfg->crypto_key);
+ } else {
+ if (dcfg->crypto_key == NOT_SET_P) dcfg->crypto_key = "";
+ if (dcfg->crypto_key_len == NOT_SET) dcfg->crypto_key_len = 0;
+ }
if (dcfg->crypto_key_add == NOT_SET) dcfg->crypto_key_add = HASH_KEYONLY;
if (dcfg->crypto_param_name == NOT_SET_P) dcfg->crypto_param_name = "crypt";
if (dcfg->hash_is_enabled == NOT_SET) dcfg->hash_is_enabled = HASH_DISABLED;
@@ -741,6 +776,7 @@ void init_directory_config(directory_config *dcfg)
/* xml external entity */
if (dcfg->xml_external_entity == NOT_SET) dcfg->xml_external_entity = 0;
+ if (dcfg->parse_xml_into_args == NOT_SET) dcfg->parse_xml_into_args = 0;
}
@@ -750,12 +786,17 @@ void init_directory_config(directory_config *dcfg)
static const char *add_rule(cmd_parms *cmd, directory_config *dcfg, int type,
const char *p1, const char *p2, const char *p3)
{
+ assert(cmd != NULL);
+ assert(dcfg != NULL);
char *my_error_msg = NULL;
//msre_rule *rule = NULL, *tmp_rule = NULL;
char *rid = NULL;
msre_rule *rule = NULL;
extern msc_engine *modsecurity;
- int offset = 0;
+ assert(modsecurity != NULL);
+ int type_with_lua = 1;
+ int type_rule;
+ int rule_actionset;
#ifdef DEBUG_CONF
ap_log_perror(APLOG_MARK, APLOG_STARTUP|APLOG_NOERRNO, 0, cmd->pool,
@@ -786,26 +827,27 @@ static const char *add_rule(cmd_parms *cmd, directory_config *dcfg, int type,
return my_error_msg;
}
- /* Rules must have uniq ID */
- if (
+#ifndef ALLOW_ID_NOT_UNIQUE
+ /* Rules must have uniq ID */
+ type_rule = (dcfg->tmp_chain_starter == NULL);
#if defined(WITH_LUA)
- type != RULE_TYPE_LUA &&
+ type_rule = (type != RULE_TYPE_LUA && type_rule);
#endif
- (dcfg->tmp_chain_starter == NULL))
+ if (type_rule)
if(rule->actionset == NULL)
return "ModSecurity: Rules must have at least id action";
if(rule->actionset != NULL && (dcfg->tmp_chain_starter == NULL)) {
- if(rule->actionset->id == NOT_SET_P
+ rule_actionset = (rule->actionset->id == NOT_SET_P);
#if defined(WITH_LUA)
- && (type != RULE_TYPE_LUA)
+ rule_actionset = (rule_actionset && (type != RULE_TYPE_LUA));
#endif
- )
- return "ModSecurity: No action id present within the rule";
+ if (rule_actionset)
+ return "ModSecurity: No action id present within the rule";
#if defined(WITH_LUA)
- if(type != RULE_TYPE_LUA)
+ type_with_lua = (type != RULE_TYPE_LUA);
#endif
- {
+ if (type_with_lua){
rid = apr_hash_get(dcfg->rule_id_htab, rule->actionset->id, APR_HASH_KEY_STRING);
if(rid != NULL) {
return "ModSecurity: Found another rule with the same id";
@@ -818,6 +860,7 @@ static const char *add_rule(cmd_parms *cmd, directory_config *dcfg, int type,
// return "ModSecurity: Found another rule with the same id";
}
}
+#endif
/* Create default actionset if one does not already exist. */
if (dcfg->tmp_default_actionset == NULL) {
@@ -875,14 +918,14 @@ static const char *add_rule(cmd_parms *cmd, directory_config *dcfg, int type,
*/
rule->actionset = msre_actionset_merge(modsecurity->msre, cmd->pool, dcfg->tmp_default_actionset,
rule->actionset, 1);
+ if (rule->actionset == NULL) return apr_psprintf(cmd->pool, "ModSecurity: cannot merge actionset (memory full?).");
/* Keep track of the parent action for "block" */
rule->actionset->parent_intercept_action_rec = dcfg->tmp_default_actionset->intercept_action_rec;
rule->actionset->parent_intercept_action = dcfg->tmp_default_actionset->intercept_action;
/* Must NOT specify a disruptive action in logging phase. */
- if ((rule->actionset != NULL)
- && (rule->actionset->phase == PHASE_LOGGING)
+ if ( (rule->actionset->phase == PHASE_LOGGING)
&& (rule->actionset->intercept_action != ACTION_ALLOW)
&& (rule->actionset->intercept_action != ACTION_ALLOW_REQUEST)
&& (rule->actionset->intercept_action != ACTION_NONE)
@@ -932,8 +975,7 @@ static const char *add_rule(cmd_parms *cmd, directory_config *dcfg, int type,
#ifdef DEBUG_CONF
ap_log_perror(APLOG_MARK, APLOG_STARTUP|APLOG_NOERRNO, 0, cmd->pool,
- "Adding rule %pp phase=%d id=\"%s\".", rule, rule->actionset->phase, (rule->actionset->id == NOT_SET_P
- ? "(none)" : rule->actionset->id));
+ "Adding rule %pp phase=%d id=\"%s\".", rule, rule->actionset->phase, id_log(rule));
#endif
/* Add rule to the recipe. */
@@ -978,9 +1020,12 @@ static const char *add_rule(cmd_parms *cmd, directory_config *dcfg, int type,
static const char *add_marker(cmd_parms *cmd, directory_config *dcfg,
const char *p1, const char *p2, const char *p3)
{
+ assert(cmd != NULL);
+ assert(dcfg != NULL);
char *my_error_msg = NULL;
msre_rule *rule = NULL;
extern msc_engine *modsecurity;
+ assert(modsecurity != NULL);
int p;
#ifdef DEBUG_CONF
@@ -1007,8 +1052,7 @@ static const char *add_marker(cmd_parms *cmd, directory_config *dcfg,
for (p = PHASE_FIRST; p <= PHASE_LAST; p++) {
#ifdef DEBUG_CONF
ap_log_perror(APLOG_MARK, APLOG_STARTUP|APLOG_NOERRNO, 0, cmd->pool,
- "Adding marker %pp phase=%d id=\"%s\".", rule, p, (rule->actionset->id == NOT_SET_P
- ? "(none)" : rule->actionset->id));
+ "Adding marker %pp phase=%d id=\"%s\".", rule, p, id_log(rule));
#endif
if (msre_ruleset_rule_add(dcfg->ruleset, rule, p) < 0) {
@@ -1030,11 +1074,14 @@ static const char *add_marker(cmd_parms *cmd, directory_config *dcfg,
static const char *update_rule_action(cmd_parms *cmd, directory_config *dcfg,
const char *p1, const char *p2, int offset)
{
+ assert(cmd != NULL);
+ assert(dcfg != NULL);
char *my_error_msg = NULL;
msre_rule *rule = NULL;
msre_actionset *new_actionset = NULL;
msre_ruleset *ruleset = dcfg->ruleset;
extern msc_engine *modsecurity;
+ assert(modsecurity != NULL);
/* Get the ruleset if one exists */
if ((ruleset == NULL)||(ruleset == NOT_SET_P)) {
@@ -1056,11 +1103,7 @@ static const char *update_rule_action(cmd_parms *cmd, directory_config *dcfg,
return NULL;
}
- /* Check the rule actionset */
- /* ENH: Can this happen? */
- if (rule->actionset == NULL) {
- return apr_psprintf(cmd->pool, "ModSecurity: Attempt to update action for rule \"%s\" failed: Rule does not have an actionset.", p1);
- }
+ assert(rule->actionset != NULL);
/* Create a new actionset */
new_actionset = msre_actionset_create(modsecurity->msre, cmd->pool, p2, &my_error_msg);
@@ -1082,9 +1125,7 @@ static const char *update_rule_action(cmd_parms *cmd, directory_config *dcfg,
char *actions = msre_actionset_generate_action_string(ruleset->mp, rule->actionset);
ap_log_perror(APLOG_MARK, APLOG_STARTUP|APLOG_NOERRNO, 0, cmd->pool,
"Update rule %pp id=\"%s\" old action: \"%s\"",
- rule,
- (rule->actionset->id == NOT_SET_P ? "(none)" : rule->actionset->id),
- actions);
+ rule, id_log(rule), actions);
}
#endif
@@ -1092,6 +1133,7 @@ static const char *update_rule_action(cmd_parms *cmd, directory_config *dcfg,
/* ENH: Will this leak the old actionset? */
rule->actionset = msre_actionset_merge(modsecurity->msre, cmd->pool, rule->actionset,
new_actionset, 1);
+ if (rule->actionset == NULL) return apr_psprintf(cmd->pool, "ModSecurity: cannot merge actionset (memory full?).");
msre_actionset_set_defaults(rule->actionset);
/* Update the unparsed rule */
@@ -1102,9 +1144,7 @@ static const char *update_rule_action(cmd_parms *cmd, directory_config *dcfg,
char *actions = msre_actionset_generate_action_string(ruleset->mp, rule->actionset);
ap_log_perror(APLOG_MARK, APLOG_STARTUP|APLOG_NOERRNO, 0, cmd->pool,
"Update rule %pp id=\"%s\" new action: \"%s\"",
- rule,
- (rule->actionset->id == NOT_SET_P ? "(none)" : rule->actionset->id),
- actions);
+ rule, id_log(rule), actions);
}
#endif
@@ -1120,6 +1160,12 @@ static const char *cmd_action(cmd_parms *cmd, void *_dcfg, const char *p1)
static const char *cmd_marker(cmd_parms *cmd, void *_dcfg, const char *p1)
{
+ assert(_dcfg != NULL);
+ // Normally useless code, left to be safe for the moment
+ if (_dcfg == NULL) {
+ ap_log_perror(APLOG_MARK, APLOG_EMERG, 0, cmd->pool, "cmd_marker: _dcfg is NULL");
+ return NULL;
+ }
directory_config *dcfg = (directory_config *)_dcfg;
const char *action = apr_pstrcat(dcfg->mp, SECMARKER_BASE_ACTIONS, p1, NULL);
return add_marker(cmd, (directory_config *)_dcfg, SECMARKER_TARGETS, SECMARKER_ARGS, action);
@@ -1128,6 +1174,14 @@ static const char *cmd_marker(cmd_parms *cmd, void *_dcfg, const char *p1)
static const char *cmd_cookiev0_separator(cmd_parms *cmd, void *_dcfg,
const char *p1)
{
+ assert(cmd != NULL);
+ assert(_dcfg != NULL);
+ assert(p1 != NULL);
+ // Normally useless code, left to be safe for the moment
+ if (_dcfg == NULL) {
+ ap_log_perror(APLOG_MARK, APLOG_EMERG, 0, cmd->pool, "cmd_cookiev0_separator: _dcfg is NULL");
+ return NULL;
+ }
directory_config *dcfg = (directory_config *)_dcfg;
if (strlen(p1) != 1) {
@@ -1142,6 +1196,14 @@ static const char *cmd_cookiev0_separator(cmd_parms *cmd, void *_dcfg,
static const char *cmd_argument_separator(cmd_parms *cmd, void *_dcfg,
const char *p1)
{
+ assert(cmd != NULL);
+ assert(_dcfg != NULL);
+ assert(p1 != NULL);
+ // Normally useless code, left to be safe for the moment
+ if (_dcfg == NULL) {
+ ap_log_perror(APLOG_MARK, APLOG_EMERG, 0, cmd->pool, "cmd_argument_separator: _dcfg is NULL");
+ return NULL;
+ }
directory_config *dcfg = (directory_config *)_dcfg;
if (strlen(p1) != 1) {
@@ -1155,6 +1217,9 @@ static const char *cmd_argument_separator(cmd_parms *cmd, void *_dcfg,
static const char *cmd_audit_engine(cmd_parms *cmd, void *_dcfg, const char *p1)
{
+ assert(cmd != NULL);
+ assert(_dcfg != NULL);
+ assert(p1 != NULL);
directory_config *dcfg = _dcfg;
if (strcasecmp(p1, "On") == 0) dcfg->auditlog_flag = AUDITLOG_ON;
@@ -1171,6 +1236,9 @@ static const char *cmd_audit_engine(cmd_parms *cmd, void *_dcfg, const char *p1)
static const char *cmd_audit_log(cmd_parms *cmd, void *_dcfg, const char *p1)
{
+ assert(cmd != NULL);
+ assert(_dcfg != NULL);
+ assert(p1 != NULL);
directory_config *dcfg = _dcfg;
dcfg->auditlog_name = (char *)p1;
@@ -1189,10 +1257,13 @@ static const char *cmd_audit_log(cmd_parms *cmd, void *_dcfg, const char *p1)
else {
const char *file_name = ap_server_root_relative(cmd->pool, dcfg->auditlog_name);
apr_status_t rc;
-
+
+ if (dcfg->auditlog_fileperms == NOT_SET) {
+ dcfg->auditlog_fileperms = CREATEMODE;
+ }
rc = apr_file_open(&dcfg->auditlog_fd, file_name,
APR_WRITE | APR_APPEND | APR_CREATE | APR_BINARY,
- CREATEMODE, cmd->pool);
+ dcfg->auditlog_fileperms, cmd->pool);
if (rc != APR_SUCCESS) {
return apr_psprintf(cmd->pool, "ModSecurity: Failed to open the audit log file: %s",
@@ -1205,6 +1276,9 @@ static const char *cmd_audit_log(cmd_parms *cmd, void *_dcfg, const char *p1)
static const char *cmd_audit_log2(cmd_parms *cmd, void *_dcfg, const char *p1)
{
+ assert(cmd != NULL);
+ assert(_dcfg != NULL);
+ assert(p1 != NULL);
directory_config *dcfg = _dcfg;
if (dcfg->auditlog_name == NOT_SET_P) {
@@ -1228,9 +1302,12 @@ static const char *cmd_audit_log2(cmd_parms *cmd, void *_dcfg, const char *p1)
const char *file_name = ap_server_root_relative(cmd->pool, dcfg->auditlog2_name);
apr_status_t rc;
+ if (dcfg->auditlog_fileperms == NOT_SET) {
+ dcfg->auditlog_fileperms = CREATEMODE;
+ }
rc = apr_file_open(&dcfg->auditlog2_fd, file_name,
APR_WRITE | APR_APPEND | APR_CREATE | APR_BINARY,
- CREATEMODE, cmd->pool);
+ dcfg->auditlog_fileperms, cmd->pool);
if (rc != APR_SUCCESS) {
return apr_psprintf(cmd->pool, "ModSecurity: Failed to open the secondary audit log file: %s",
@@ -1244,6 +1321,9 @@ static const char *cmd_audit_log2(cmd_parms *cmd, void *_dcfg, const char *p1)
static const char *cmd_audit_log_parts(cmd_parms *cmd, void *_dcfg,
const char *p1)
{
+ assert(cmd != NULL);
+ assert(_dcfg != NULL);
+ assert(p1 != NULL);
directory_config *dcfg = _dcfg;
if (is_valid_parts_specification((char *)p1) != 1) {
@@ -1257,9 +1337,16 @@ static const char *cmd_audit_log_parts(cmd_parms *cmd, void *_dcfg,
static const char *cmd_audit_log_relevant_status(cmd_parms *cmd, void *_dcfg,
const char *p1)
{
+ assert(cmd != NULL);
+ assert(_dcfg != NULL);
+ assert(p1 != NULL);
directory_config *dcfg = _dcfg;
+#ifndef WITH_PCRE
+ dcfg->auditlog_relevant_regex = msc_pregcomp(cmd->pool, p1, PCRE2_DOTALL, NULL, NULL);
+#else
dcfg->auditlog_relevant_regex = msc_pregcomp(cmd->pool, p1, PCRE_DOTALL, NULL, NULL);
+#endif
if (dcfg->auditlog_relevant_regex == NULL) {
return apr_psprintf(cmd->pool, "ModSecurity: Invalid regular expression: %s", p1);
}
@@ -1270,6 +1357,9 @@ static const char *cmd_audit_log_relevant_status(cmd_parms *cmd, void *_dcfg,
static const char *cmd_audit_log_type(cmd_parms *cmd, void *_dcfg,
const char *p1)
{
+ assert(cmd != NULL);
+ assert(_dcfg != NULL);
+ assert(p1 != NULL);
directory_config *dcfg = _dcfg;
if (strcasecmp(p1, "Serial") == 0) dcfg->auditlog_type = AUDITLOG_SERIAL;
@@ -1282,13 +1372,39 @@ static const char *cmd_audit_log_type(cmd_parms *cmd, void *_dcfg,
return NULL;
}
+#ifdef WITH_YAJL
+static const char *cmd_audit_log_mode(cmd_parms *cmd, void *_dcfg,
+ const char *p1)
+{
+ assert(cmd != NULL);
+ assert(_dcfg != NULL);
+ assert(p1 != NULL);
+ directory_config *dcfg = _dcfg;
+
+ if (strcasecmp(p1, "JSON") == 0) dcfg->auditlog_format = AUDITLOGFORMAT_JSON;
+ else
+ if (strcasecmp(p1, "Native") == 0) dcfg->auditlog_format = AUDITLOGFORMAT_NATIVE;
+ else
+ return (const char *)apr_psprintf(cmd->pool,
+ "ModSecurity: Unrecognised parameter value for SecAuditLogFormat: %s", p1);
+
+ return NULL;
+}
+#endif
+
static const char *cmd_audit_log_dirmode(cmd_parms *cmd, void *_dcfg,
const char *p1)
{
+ assert(cmd != NULL);
+ assert(_dcfg != NULL);
+ assert(p1 != NULL);
+ // Normally useless code, left to be safe for the moment
+ if (_dcfg == NULL) {
+ ap_log_perror(APLOG_MARK, APLOG_EMERG, 0, cmd->pool, "cmd_audit_log_dirmode: _dcfg is NULL");
+ return NULL;
+ }
directory_config *dcfg = (directory_config *)_dcfg;
- if (dcfg == NULL) return NULL;
-
if (strcasecmp(p1, "default") == 0) {
dcfg->auditlog_dirperms = NOT_SET;
}
@@ -1307,10 +1423,16 @@ static const char *cmd_audit_log_dirmode(cmd_parms *cmd, void *_dcfg,
static const char *cmd_audit_log_filemode(cmd_parms *cmd, void *_dcfg,
const char *p1)
{
+ assert(cmd != NULL);
+ assert(_dcfg != NULL);
+ assert(p1 != NULL);
+ // Normally useless code, left to be safe for the moment
+ if (_dcfg == NULL) {
+ ap_log_perror(APLOG_MARK, APLOG_EMERG, 0, cmd->pool, "cmd_audit_log_filemode: _dcfg is NULL");
+ return NULL;
+ }
directory_config *dcfg = (directory_config *)_dcfg;
- if (dcfg == NULL) return NULL;
-
if (strcasecmp(p1, "default") == 0) {
dcfg->auditlog_fileperms = NOT_SET;
}
@@ -1329,6 +1451,9 @@ static const char *cmd_audit_log_filemode(cmd_parms *cmd, void *_dcfg,
static const char *cmd_audit_log_storage_dir(cmd_parms *cmd, void *_dcfg,
const char *p1)
{
+ assert(cmd != NULL);
+ assert(_dcfg != NULL);
+ assert(p1 != NULL);
directory_config *dcfg = _dcfg;
dcfg->auditlog_storage_dir = ap_server_root_relative(cmd->pool, p1);
@@ -1339,6 +1464,9 @@ static const char *cmd_audit_log_storage_dir(cmd_parms *cmd, void *_dcfg,
static const char *cmd_cookie_format(cmd_parms *cmd, void *_dcfg,
const char *p1)
{
+ assert(cmd != NULL);
+ assert(_dcfg != NULL);
+ assert(p1 != NULL);
directory_config *dcfg = (directory_config *)_dcfg;
if (strcmp(p1, "0") == 0) dcfg->cookie_format = COOKIES_V0;
@@ -1353,6 +1481,8 @@ static const char *cmd_cookie_format(cmd_parms *cmd, void *_dcfg,
static const char *cmd_chroot_dir(cmd_parms *cmd, void *_dcfg, const char *p1)
{
+ assert(cmd != NULL);
+ assert(p1 != NULL);
char cwd[1025] = "";
if (cmd->server->is_virtual) {
@@ -1384,6 +1514,13 @@ static const char *cmd_chroot_dir(cmd_parms *cmd, void *_dcfg, const char *p1)
static const char *cmd_component_signature(cmd_parms *cmd, void *_dcfg,
const char *p1)
{
+ assert(_dcfg != NULL);
+ assert(p1 != NULL);
+ // Normally useless code, left to be safe for the moment
+ if (_dcfg == NULL) {
+ ap_log_perror(APLOG_MARK, APLOG_EMERG, 0, cmd->pool, "cmd_component_signature: _dcfg is NULL");
+ return NULL;
+ }
directory_config *dcfg = (directory_config *)_dcfg;
/* ENH Enforce "Name/VersionX.Y.Z (comment)" format. */
@@ -1394,14 +1531,22 @@ static const char *cmd_component_signature(cmd_parms *cmd, void *_dcfg,
static const char *cmd_content_injection(cmd_parms *cmd, void *_dcfg, int flag)
{
+ assert(_dcfg != NULL);
+ // Normally useless code, left to be safe for the moment
+ if (_dcfg == NULL) {
+ ap_log_perror(APLOG_MARK, APLOG_EMERG, 0, cmd->pool, "cmd_content_injection: _dcfg is NULL");
+ return NULL;
+ }
directory_config *dcfg = (directory_config *)_dcfg;
- if (dcfg == NULL) return NULL;
dcfg->content_injection_enabled = flag;
return NULL;
}
static const char *cmd_data_dir(cmd_parms *cmd, void *_dcfg, const char *p1)
{
+ assert(cmd != NULL);
+ assert(_dcfg != NULL);
+ assert(p1 != NULL);
directory_config *dcfg = (directory_config *)_dcfg;
if (cmd->server->is_virtual) {
@@ -1415,6 +1560,9 @@ static const char *cmd_data_dir(cmd_parms *cmd, void *_dcfg, const char *p1)
static const char *cmd_debug_log(cmd_parms *cmd, void *_dcfg, const char *p1)
{
+ assert(cmd != NULL);
+ assert(_dcfg != NULL);
+ assert(p1 != NULL);
directory_config *dcfg = (directory_config *)_dcfg;
apr_status_t rc;
@@ -1445,6 +1593,9 @@ static const char *cmd_debug_log(cmd_parms *cmd, void *_dcfg, const char *p1)
static const char *cmd_collection_timeout(cmd_parms *cmd, void *_dcfg,
const char *p1)
{
+ assert(cmd != NULL);
+ assert(_dcfg != NULL);
+ assert(p1 != NULL);
directory_config *dcfg = (directory_config *)_dcfg;
dcfg->col_timeout = atoi(p1);
@@ -1457,6 +1608,9 @@ static const char *cmd_collection_timeout(cmd_parms *cmd, void *_dcfg,
static const char *cmd_debug_log_level(cmd_parms *cmd, void *_dcfg,
const char *p1)
{
+ assert(cmd != NULL);
+ assert(_dcfg != NULL);
+ assert(p1 != NULL);
directory_config *dcfg = (directory_config *)_dcfg;
dcfg->debuglog_level = atoi(p1);
@@ -1468,6 +1622,8 @@ static const char *cmd_debug_log_level(cmd_parms *cmd, void *_dcfg,
static const char *cmd_default_action(cmd_parms *cmd, void *_dcfg,
const char *p1)
{
+ assert(cmd != NULL);
+ assert(_dcfg != NULL);
directory_config *dcfg = (directory_config *)_dcfg;
extern msc_engine *modsecurity;
char *my_error_msg = NULL;
@@ -1544,8 +1700,13 @@ static const char *cmd_default_action(cmd_parms *cmd, void *_dcfg,
static const char *cmd_disable_backend_compression(cmd_parms *cmd, void *_dcfg, int flag)
{
- directory_config *dcfg = (directory_config *)_dcfg;
- if (dcfg == NULL) return NULL;
+ assert(_dcfg != NULL);
+ // Normally useless code, left to be safe for the moment
+ if (_dcfg == NULL) {
+ ap_log_perror(APLOG_MARK, APLOG_EMERG, 0, cmd->pool, "cmd_disable_backend_compression: _dcfg is NULL");
+ return NULL;
+ }
+ directory_config* dcfg = (directory_config*)_dcfg;
dcfg->disable_backend_compression = flag;
return NULL;
}
@@ -1553,6 +1714,8 @@ static const char *cmd_disable_backend_compression(cmd_parms *cmd, void *_dcfg,
static const char *cmd_guardian_log(cmd_parms *cmd, void *_dcfg,
const char *p1, const char *p2)
{
+ assert(cmd != NULL);
+ assert(p1 != NULL);
extern char *guardianlog_name;
extern apr_file_t *guardianlog_fd;
extern char *guardianlog_condition;
@@ -1613,8 +1776,13 @@ static const char *cmd_guardian_log(cmd_parms *cmd, void *_dcfg,
*/
static const char *cmd_stream_inbody_inspection(cmd_parms *cmd, void *_dcfg, int flag)
{
+ assert(_dcfg != NULL);
+ // Normally useless code, left to be safe for the moment
+ if (_dcfg == NULL) {
+ ap_log_perror(APLOG_MARK, APLOG_EMERG, 0, cmd->pool, "cmd_stream_inbody_inspection: _dcfg is NULL");
+ return NULL;
+ }
directory_config *dcfg = (directory_config *)_dcfg;
- if (dcfg == NULL) return NULL;
dcfg->stream_inbody_inspection = flag;
return NULL;
}
@@ -1632,8 +1800,13 @@ static const char *cmd_stream_inbody_inspection(cmd_parms *cmd, void *_dcfg, int
*/
static const char *cmd_stream_outbody_inspection(cmd_parms *cmd, void *_dcfg, int flag)
{
+ assert(_dcfg != NULL);
+ // Normally useless code, left to be safe for the moment
+ if (_dcfg == NULL) {
+ ap_log_perror(APLOG_MARK, APLOG_EMERG, 0, cmd->pool, "cmd_stream_outbody_inspection: _dcfg is NULL");
+ return NULL;
+ }
directory_config *dcfg = (directory_config *)_dcfg;
- if (dcfg == NULL) return NULL;
dcfg->stream_outbody_inspection = flag;
return NULL;
}
@@ -1650,11 +1823,17 @@ static const char *cmd_stream_outbody_inspection(cmd_parms *cmd, void *_dcfg, in
static const char *cmd_rule_perf_time(cmd_parms *cmd, void *_dcfg,
const char *p1)
{
+ assert(cmd != NULL);
+ assert(_dcfg != NULL);
+ assert(p1 != NULL);
+ // Normally useless code, left to be safe for the moment
+ if (_dcfg == NULL) {
+ ap_log_perror(APLOG_MARK, APLOG_EMERG, 0, cmd->pool, "cmd_rule_perf_time: _dcfg is NULL");
+ return NULL;
+ }
directory_config *dcfg = (directory_config *)_dcfg;
long int limit;
- if (dcfg == NULL) return NULL;
-
limit = strtol(p1, NULL, 10);
if ((limit == LONG_MAX)||(limit == LONG_MIN)||(limit <= 0)) {
return apr_psprintf(cmd->pool, "ModSecurity: Invalid value for SecRulePerfTime: %s", p1);
@@ -1666,18 +1845,31 @@ static const char *cmd_rule_perf_time(cmd_parms *cmd, void *_dcfg,
}
char *parser_conn_limits_operator(apr_pool_t *mp, const char *p2,
- TreeRoot **whitelist, TreeRoot **suspicious_list,
+ TreeRoot **whitelist, TreeRoot **suspicious_list,
const char *filename)
{
+ assert(p2 != NULL);
+ assert(whitelist != NULL);
+ assert(suspicious_list != NULL);
+ assert(filename != NULL);
int res = 0;
char *config_orig_path;
char *param = strchr(p2, ' ');
char *file = NULL;
char *error_msg = NULL;
+
+ if (param == NULL) {
+ return apr_psprintf(mp, "ModSecurity: Space character between operator " \
+ "and parameter not found with ConnReadStateLimit: %s", p2);
+ }
+
param++;
config_orig_path = apr_pstrndup(mp, filename,
strlen(filename) - strlen(apr_filepath_name_get(filename)));
+ if (config_orig_path == NULL) {
+ return apr_psprintf(mp, "ModSecurity: failed to duplicate filename in parser_conn_limits_operator");
+ }
apr_filepath_merge(&file, config_orig_path, param, APR_FILEPATH_TRUENAME,
mp);
@@ -1734,11 +1926,16 @@ char *parser_conn_limits_operator(apr_pool_t *mp, const char *p2,
static const char *cmd_conn_read_state_limit(cmd_parms *cmd, void *_dcfg,
const char *p1, const char *p2)
{
- directory_config *dcfg = (directory_config *)_dcfg;
+ assert(cmd != NULL);
+ assert(_dcfg != NULL);
+ assert(p1 != NULL);
+ // Normally useless code, left to be safe for the moment
+ if (_dcfg == NULL) {
+ ap_log_perror(APLOG_MARK, APLOG_EMERG, 0, cmd->pool, "cmd_conn_read_state_limit: _dcfg is NULL");
+ return NULL;
+ }
long int limit;
- if (dcfg == NULL) return NULL;
-
limit = strtol(p1, NULL, 10);
if ((limit == LONG_MAX) || (limit == LONG_MIN) || (limit <= 0)) {
return apr_psprintf(cmd->pool, "ModSecurity: Invalid value for " \
@@ -1753,7 +1950,7 @@ static const char *cmd_conn_read_state_limit(cmd_parms *cmd, void *_dcfg,
if (param)
return param;
}
-
+
conn_read_state_limit = limit;
return NULL;
@@ -1762,6 +1959,7 @@ static const char *cmd_conn_read_state_limit(cmd_parms *cmd, void *_dcfg,
static const char *cmd_read_state_limit(cmd_parms *cmd, void *_dcfg,
const char *p1, const char *p2)
{
+ assert(cmd != NULL);
ap_log_perror(APLOG_MARK, APLOG_STARTUP|APLOG_NOERRNO, 0, cmd->pool,
"SecReadStateLimit is depricated, use SecConnReadStateLimit " \
"instead.");
@@ -1783,11 +1981,16 @@ static const char *cmd_read_state_limit(cmd_parms *cmd, void *_dcfg,
static const char *cmd_conn_write_state_limit(cmd_parms *cmd, void *_dcfg,
const char *p1, const char *p2)
{
- directory_config *dcfg = (directory_config *)_dcfg;
+ assert(cmd != NULL);
+ assert(_dcfg != NULL);
+ assert(p1 != NULL);
+ // Normally useless code, left to be safe for the moment
+ if (_dcfg == NULL) {
+ ap_log_perror(APLOG_MARK, APLOG_EMERG, 0, cmd->pool, "cmd_conn_write_state_limit: _dcfg is NULL");
+ return NULL;
+ }
long int limit;
- if (dcfg == NULL) return NULL;
-
limit = strtol(p1, NULL, 10);
if ((limit == LONG_MAX) || (limit == LONG_MIN) || (limit <= 0)) {
return apr_psprintf(cmd->pool, "ModSecurity: Invalid value for " \
@@ -1810,6 +2013,7 @@ static const char *cmd_conn_write_state_limit(cmd_parms *cmd, void *_dcfg,
static const char *cmd_write_state_limit(cmd_parms *cmd, void *_dcfg,
const char *p1, const char *p2)
{
+ assert(cmd != NULL);
ap_log_perror(APLOG_MARK, APLOG_STARTUP|APLOG_NOERRNO, 0, cmd->pool,
"SecWriteStateLimit is depricated, use SecConnWriteStateLimit " \
"instead.");
@@ -1822,11 +2026,17 @@ static const char *cmd_write_state_limit(cmd_parms *cmd, void *_dcfg,
static const char *cmd_request_body_inmemory_limit(cmd_parms *cmd, void *_dcfg,
const char *p1)
{
+ assert(cmd != NULL);
+ assert(_dcfg != NULL);
+ assert(p1 != NULL);
+ // Normally useless code, left to be safe for the moment
+ if (_dcfg == NULL) {
+ ap_log_perror(APLOG_MARK, APLOG_EMERG, 0, cmd->pool, "cmd_request_body_inmemory_limit: _dcfg is NULL");
+ return NULL;
+ }
directory_config *dcfg = (directory_config *)_dcfg;
long int limit;
- if (dcfg == NULL) return NULL;
-
limit = strtol(p1, NULL, 10);
if ((limit == LONG_MAX)||(limit == LONG_MIN)||(limit <= 0)) {
return apr_psprintf(cmd->pool, "ModSecurity: Invalid value for SecRequestBodyInMemoryLimit: %s", p1);
@@ -1840,11 +2050,17 @@ static const char *cmd_request_body_inmemory_limit(cmd_parms *cmd, void *_dcfg,
static const char *cmd_request_body_limit(cmd_parms *cmd, void *_dcfg,
const char *p1)
{
+ assert(cmd != NULL);
+ assert(_dcfg != NULL);
+ assert(p1 != NULL);
+ // Normally useless code, left to be safe for the moment
+ if (_dcfg == NULL) {
+ ap_log_perror(APLOG_MARK, APLOG_EMERG, 0, cmd->pool, "cmd_request_body_limit: _dcfg is NULL");
+ return NULL;
+ }
directory_config *dcfg = (directory_config *)_dcfg;
long int limit;
- if (dcfg == NULL) return NULL;
-
limit = strtol(p1, NULL, 10);
if ((limit == LONG_MAX)||(limit == LONG_MIN)||(limit <= 0)) {
return apr_psprintf(cmd->pool, "ModSecurity: Invalid value for SecRequestBodyLimit: %s", p1);
@@ -1858,11 +2074,17 @@ static const char *cmd_request_body_limit(cmd_parms *cmd, void *_dcfg,
static const char *cmd_request_body_no_files_limit(cmd_parms *cmd, void *_dcfg,
const char *p1)
{
+ assert(cmd != NULL);
+ assert(_dcfg != NULL);
+ assert(p1 != NULL);
+ // Normally useless code, left to be safe for the moment
+ if (_dcfg == NULL) {
+ ap_log_perror(APLOG_MARK, APLOG_EMERG, 0, cmd->pool, "cmd_request_body_no_files_limit: _dcfg is NULL");
+ return NULL;
+ }
directory_config *dcfg = (directory_config *)_dcfg;
long int limit;
- if (dcfg == NULL) return NULL;
-
limit = strtol(p1, NULL, 10);
if ((limit == LONG_MAX)||(limit == LONG_MIN)||(limit <= 0)) {
return apr_psprintf(cmd->pool, "ModSecurity: Invalid value for SecRequestBodyNoFilesLimit: %s", p1);
@@ -1873,12 +2095,67 @@ static const char *cmd_request_body_no_files_limit(cmd_parms *cmd, void *_dcfg,
return NULL;
}
+static const char *cmd_request_body_json_depth_limit(cmd_parms *cmd, void *_dcfg,
+ const char *p1)
+{
+ assert(cmd != NULL);
+ assert(_dcfg != NULL);
+ assert(p1 != NULL);
+ // Normally useless code, left to be safe for the moment
+ if (_dcfg == NULL) {
+ ap_log_perror(APLOG_MARK, APLOG_EMERG, 0, cmd->pool, "cmd_request_body_json_depth_limit: _dcfg is NULL");
+ return NULL;
+ }
+ directory_config *dcfg = (directory_config *)_dcfg;
+ long int limit;
+
+ limit = strtol(p1, NULL, 10);
+ if ((limit == LONG_MAX)||(limit == LONG_MIN)||(limit <= 0)) {
+ return apr_psprintf(cmd->pool, "ModSecurity: Invalid value for SecRequestBodyJsonDepthLimit: %s", p1);
+ }
+
+ dcfg->reqbody_json_depth_limit = limit;
+
+ return NULL;
+}
+
+static const char *cmd_arguments_limit(cmd_parms *cmd, void *_dcfg,
+ const char *p1)
+{
+ assert(cmd != NULL);
+ assert(_dcfg != NULL);
+ assert(p1 != NULL);
+ // Normally useless code, left to be safe for the moment
+ if (_dcfg == NULL) {
+ ap_log_perror(APLOG_MARK, APLOG_EMERG, 0, cmd->pool, "cmd_arguments_limit: _dcfg is NULL");
+ return NULL;
+ }
+ directory_config *dcfg = (directory_config *)_dcfg;
+ long int limit;
+
+ limit = strtol(p1, NULL, 10);
+ if ((limit == LONG_MAX)||(limit == LONG_MIN)||(limit <= 0)) {
+ return apr_psprintf(cmd->pool, "ModSecurity: Invalid value for SecArgumentsLimit: %s", p1);
+ }
+
+ dcfg->arguments_limit = limit;
+
+ return NULL;
+}
+
static const char *cmd_request_body_access(cmd_parms *cmd, void *_dcfg,
const char *p1)
{
+ assert(cmd != NULL);
+ assert(_dcfg != NULL);
+ assert(p1 != NULL);
+ // Normally useless code, left to be safe for the moment
+ if (_dcfg == NULL) {
+ ap_log_perror(APLOG_MARK, APLOG_EMERG, 0, cmd->pool, "cmd_request_body_access: _dcfg is NULL");
+ return NULL;
+ }
directory_config *dcfg = (directory_config *)_dcfg;
- if (dcfg == NULL) return NULL;
-
+
if (strcasecmp(p1, "on") == 0) dcfg->reqbody_access = 1;
else
if (strcasecmp(p1, "off") == 0) dcfg->reqbody_access = 0;
@@ -1901,9 +2178,16 @@ static const char *cmd_request_body_access(cmd_parms *cmd, void *_dcfg,
static const char *cmd_request_intercept_on_error(cmd_parms *cmd, void *_dcfg,
const char *p1)
{
+ assert(cmd != NULL);
+ assert(_dcfg != NULL);
+ assert(p1 != NULL);
+ // Normally useless code, left to be safe for the moment
+ if (_dcfg == NULL) {
+ ap_log_perror(APLOG_MARK, APLOG_EMERG, 0, cmd->pool, "cmd_request_intercept_on_error: _dcfg is NULL");
+ return NULL;
+ }
directory_config *dcfg = (directory_config *)_dcfg;
- if (dcfg == NULL) return NULL;
-
+
if (strcasecmp(p1, "on") == 0) dcfg->reqintercept_oe = 1;
else
if (strcasecmp(p1, "off") == 0) dcfg->reqintercept_oe = 0;
@@ -1917,11 +2201,15 @@ static const char *cmd_request_intercept_on_error(cmd_parms *cmd, void *_dcfg,
static const char *cmd_request_encoding(cmd_parms *cmd, void *_dcfg,
const char *p1)
{
+ assert(_dcfg != NULL);
+ // Normally useless code, left to be safe for the moment
+ if (_dcfg == NULL) {
+ ap_log_perror(APLOG_MARK, APLOG_EMERG, 0, cmd->pool, "cmd_request_encoding: _dcfg is NULL");
+ return NULL;
+ }
directory_config *dcfg = (directory_config *)_dcfg;
- if (dcfg == NULL) return NULL;
-
+
/* ENH Validate encoding */
-
dcfg->request_encoding = p1;
return NULL;
@@ -1930,9 +2218,16 @@ static const char *cmd_request_encoding(cmd_parms *cmd, void *_dcfg,
static const char *cmd_response_body_access(cmd_parms *cmd, void *_dcfg,
const char *p1)
{
+ assert(cmd != NULL);
+ assert(_dcfg != NULL);
+ assert(p1 != NULL);
+ // Normally useless code, left to be safe for the moment
+ if (_dcfg == NULL) {
+ ap_log_perror(APLOG_MARK, APLOG_EMERG, 0, cmd->pool, "cmd_response_body_access: _dcfg is NULL");
+ return NULL;
+ }
directory_config *dcfg = (directory_config *)_dcfg;
- if (dcfg == NULL) return NULL;
-
+
if (strcasecmp(p1, "on") == 0) dcfg->resbody_access = 1;
else
if (strcasecmp(p1, "off") == 0) dcfg->resbody_access = 0;
@@ -1945,6 +2240,14 @@ static const char *cmd_response_body_access(cmd_parms *cmd, void *_dcfg,
static const char *cmd_response_body_limit(cmd_parms *cmd, void *_dcfg,
const char *p1)
{
+ assert(cmd != NULL);
+ assert(_dcfg != NULL);
+ assert(p1 != NULL);
+ // Normally useless code, left to be safe for the moment
+ if (_dcfg == NULL) {
+ ap_log_perror(APLOG_MARK, APLOG_EMERG, 0, cmd->pool, "cmd_response_body_limit: _dcfg is NULL");
+ return NULL;
+ }
directory_config *dcfg = (directory_config *)_dcfg;
long int limit;
@@ -1965,9 +2268,16 @@ static const char *cmd_response_body_limit(cmd_parms *cmd, void *_dcfg,
static const char *cmd_response_body_limit_action(cmd_parms *cmd, void *_dcfg,
const char *p1)
{
+ assert(cmd != NULL);
+ assert(_dcfg != NULL);
+ assert(p1 != NULL);
+ // Normally useless code, left to be safe for the moment
+ if (_dcfg == NULL) {
+ ap_log_perror(APLOG_MARK, APLOG_EMERG, 0, cmd->pool, "cmd_response_body_limit_action: _dcfg is NULL");
+ return NULL;
+ }
directory_config *dcfg = (directory_config *)_dcfg;
- if (dcfg == NULL) return NULL;
-
+
if (dcfg->is_enabled == MODSEC_DETECTION_ONLY) {
dcfg->of_limit_action = RESPONSE_BODY_LIMIT_ACTION_PARTIAL;
return NULL;
@@ -1995,9 +2305,16 @@ static const char *cmd_response_body_limit_action(cmd_parms *cmd, void *_dcfg,
static const char *cmd_resquest_body_limit_action(cmd_parms *cmd, void *_dcfg,
const char *p1)
{
+ assert(cmd != NULL);
+ assert(_dcfg != NULL);
+ assert(p1 != NULL);
+ // Normally useless code, left to be safe for the moment
+ if (_dcfg == NULL) {
+ ap_log_perror(APLOG_MARK, APLOG_EMERG, 0, cmd->pool, "cmd_resquest_body_limit_action: _dcfg is NULL");
+ return NULL;
+ }
directory_config *dcfg = (directory_config *)_dcfg;
- if (dcfg == NULL) return NULL;
-
+
if (dcfg->is_enabled == MODSEC_DETECTION_ONLY) {
dcfg->if_limit_action = REQUEST_BODY_LIMIT_ACTION_PARTIAL;
return NULL;
@@ -2015,6 +2332,14 @@ static const char *cmd_resquest_body_limit_action(cmd_parms *cmd, void *_dcfg,
static const char *cmd_response_body_mime_type(cmd_parms *cmd, void *_dcfg,
const char *_p1)
{
+ assert(cmd != NULL);
+ assert(_dcfg != NULL);
+ assert(_p1 != NULL);
+ // Normally useless code, left to be safe for the moment
+ if (_dcfg == NULL) {
+ ap_log_perror(APLOG_MARK, APLOG_EMERG, 0, cmd->pool, "cmd_response_body_mime_type: _dcfg is NULL");
+ return NULL;
+ }
directory_config *dcfg = (directory_config *)_dcfg;
char *p1 = apr_pstrdup(cmd->pool, _p1);
@@ -2033,9 +2358,14 @@ static const char *cmd_response_body_mime_type(cmd_parms *cmd, void *_dcfg,
static const char *cmd_response_body_mime_types_clear(cmd_parms *cmd,
void *_dcfg)
{
+ assert(_dcfg != NULL);
+ // Normally useless code, left to be safe for the moment
+ if (_dcfg == NULL) {
+ ap_log_perror(APLOG_MARK, APLOG_EMERG, 0, cmd->pool, "cmd_response_body_mime_types_clear: _dcfg is NULL");
+ return NULL;
+ }
directory_config *dcfg = (directory_config *)_dcfg;
- if (dcfg == NULL) return NULL;
-
+
dcfg->of_mime_types_cleared = 1;
if ((dcfg->of_mime_types != NULL)&&(dcfg->of_mime_types != NOT_SET_P)) {
@@ -2059,10 +2389,16 @@ static const char *cmd_response_body_mime_types_clear(cmd_parms *cmd,
static const char *cmd_rule_update_target_by_id(cmd_parms *cmd, void *_dcfg,
const char *p1, const char *p2, const char *p3)
{
+ assert(cmd != NULL);
+ assert(_dcfg != NULL);
+ // Normally useless code, left to be safe for the moment
+ if (_dcfg == NULL) {
+ ap_log_perror(APLOG_MARK, APLOG_EMERG, 0, cmd->pool, "cmd_rule_update_target_by_id: _dcfg is NULL");
+ return NULL;
+ }
directory_config *dcfg = (directory_config *)_dcfg;
rule_exception *re = apr_pcalloc(cmd->pool, sizeof(rule_exception));
- if (dcfg == NULL) return NULL;
-
+
if(p1 == NULL) {
return apr_psprintf(cmd->pool, "Updating target by ID with no ID");
}
@@ -2096,10 +2432,16 @@ static const char *cmd_rule_update_target_by_id(cmd_parms *cmd, void *_dcfg,
static const char *cmd_rule_update_target_by_tag(cmd_parms *cmd, void *_dcfg,
const char *p1, const char *p2, const char *p3)
{
+ assert(cmd != NULL);
+ assert(_dcfg != NULL);
+ // Normally useless code, left to be safe for the moment
+ if (_dcfg == NULL) {
+ ap_log_perror(APLOG_MARK, APLOG_EMERG, 0, cmd->pool, "cmd_rule_update_target_by_tag: _dcfg is NULL");
+ return NULL;
+ }
directory_config *dcfg = (directory_config *)_dcfg;
rule_exception *re = apr_pcalloc(cmd->pool, sizeof(rule_exception));
- if (dcfg == NULL) return NULL;
-
+
if(p1 == NULL) {
return apr_psprintf(cmd->pool, "Updating target by tag with no tag");
}
@@ -2131,10 +2473,17 @@ static const char *cmd_rule_update_target_by_tag(cmd_parms *cmd, void *_dcfg,
static const char *cmd_rule_update_target_by_msg(cmd_parms *cmd, void *_dcfg,
const char *p1, const char *p2, const char *p3)
{
+ assert(cmd != NULL);
+ assert(_dcfg != NULL);
+ assert(p1 != NULL);
+ // Normally useless code, left to be safe for the moment
+ if (_dcfg == NULL) {
+ ap_log_perror(APLOG_MARK, APLOG_EMERG, 0, cmd->pool, "cmd_rule_update_target_by_msg: _dcfg is NULL");
+ return NULL;
+ }
directory_config *dcfg = (directory_config *)_dcfg;
rule_exception *re = apr_pcalloc(cmd->pool, sizeof(rule_exception));
- if (dcfg == NULL) return NULL;
-
+
if(p1 == NULL) {
return apr_psprintf(cmd->pool, "Updating target by message with no message");
}
@@ -2159,9 +2508,14 @@ static const char *cmd_rule(cmd_parms *cmd, void *_dcfg,
static const char *cmd_sever_conn_filters_engine(cmd_parms *cmd, void *_dcfg,
const char *p1)
{
- directory_config *dcfg = (directory_config *)_dcfg;
-
- if (dcfg == NULL) return NULL;
+ assert(cmd != NULL);
+ assert(_dcfg != NULL);
+ assert(p1 != NULL);
+ // Normally useless code, left to be safe for the moment
+ if (_dcfg == NULL) {
+ ap_log_perror(APLOG_MARK, APLOG_EMERG, 0, cmd->pool, "cmd_sever_conn_filters_engine: _dcfg is NULL");
+ return NULL;
+ }
if (strcasecmp(p1, "on") == 0)
{
@@ -2186,10 +2540,16 @@ static const char *cmd_sever_conn_filters_engine(cmd_parms *cmd, void *_dcfg,
static const char *cmd_rule_engine(cmd_parms *cmd, void *_dcfg, const char *p1)
{
+ assert(cmd != NULL);
+ assert(_dcfg != NULL);
+ assert(p1 != NULL);
+ // Normally useless code, left to be safe for the moment
+ if (_dcfg == NULL) {
+ ap_log_perror(APLOG_MARK, APLOG_EMERG, 0, cmd->pool, "cmd_rule_engine: _dcfg is NULL");
+ return NULL;
+ }
directory_config *dcfg = (directory_config *)_dcfg;
- if (dcfg == NULL) return NULL;
-
if (strcasecmp(p1, "on") == 0)
{
dcfg->is_enabled = MODSEC_ENABLED;
@@ -2215,8 +2575,15 @@ static const char *cmd_rule_engine(cmd_parms *cmd, void *_dcfg, const char *p1)
static const char *cmd_remote_rules_fail(cmd_parms *cmd, void *_dcfg, const char *p1)
{
- directory_config *dcfg = (directory_config *)_dcfg;
- if (dcfg == NULL) return NULL;
+ assert(cmd != NULL);
+ assert(_dcfg != NULL);
+ assert(p1 != NULL);
+ // Normally useless code, left to be safe for the moment
+ if (_dcfg == NULL) {
+ ap_log_perror(APLOG_MARK, APLOG_EMERG, 0, cmd->pool, "cmd_remote_rules_fail: _dcfg is NULL");
+ return NULL;
+ }
+
if (strncasecmp(p1, "warn", 4) == 0)
{
remote_rules_fail_action = REMOTE_RULES_WARN_ON_FAIL;
@@ -2237,7 +2604,15 @@ static const char *cmd_remote_rules_fail(cmd_parms *cmd, void *_dcfg, const char
static const char *cmd_remote_rules(cmd_parms *cmd, void *_dcfg, const char *p1,
const char *p2, const char *p3)
{
+ assert(cmd != NULL);
+ assert(_dcfg != NULL);
+ assert(p1 != NULL);
char *error_msg = NULL;
+ // Normally useless code, left to be safe for the moment
+ if (_dcfg == NULL) {
+ ap_log_perror(APLOG_MARK, APLOG_EMERG, 0, cmd->pool, "cmd_remote_rules: _dcfg is NULL");
+ return NULL;
+ }
directory_config *dcfg = (directory_config *)_dcfg;
#ifdef WITH_REMOTE_RULES
int crypto = 0;
@@ -2245,8 +2620,6 @@ static const char *cmd_remote_rules(cmd_parms *cmd, void *_dcfg, const char *p1,
const char *key = p1;
#endif
- if (dcfg == NULL) return NULL;
-
#ifdef WITH_REMOTE_RULES
if (strncasecmp(p1, "crypto", 6) == 0)
{
@@ -2309,6 +2682,8 @@ static const char *cmd_remote_rules(cmd_parms *cmd, void *_dcfg, const char *p1,
static const char *cmd_status_engine(cmd_parms *cmd, void *_dcfg, const char *p1)
{
+ assert(cmd != NULL);
+ assert(p1 != NULL);
if (strcasecmp(p1, "on") == 0) {
status_engine_state = STATUS_ENGINE_ENABLED;
}
@@ -2326,8 +2701,13 @@ static const char *cmd_status_engine(cmd_parms *cmd, void *_dcfg, const char *p1
static const char *cmd_rule_inheritance(cmd_parms *cmd, void *_dcfg, int flag)
{
+ assert(_dcfg != NULL);
+ // Normally useless code, left to be safe for the moment
+ if (_dcfg == NULL) {
+ ap_log_perror(APLOG_MARK, APLOG_EMERG, 0, cmd->pool, "cmd_rule_inheritance: _dcfg is NULL");
+ return NULL;
+ }
directory_config *dcfg = (directory_config *)_dcfg;
- if (dcfg == NULL) return NULL;
dcfg->rule_inheritance = flag;
return NULL;
}
@@ -2335,7 +2715,9 @@ static const char *cmd_rule_inheritance(cmd_parms *cmd, void *_dcfg, int flag)
static const char *cmd_rule_script(cmd_parms *cmd, void *_dcfg,
const char *p1, const char *p2)
{
- #if defined(WITH_LUA)
+ assert(cmd != NULL);
+ assert(p1 != NULL);
+#if defined(WITH_LUA)
const char *filename = resolve_relative_path(cmd->pool, cmd->directive->filename, p1);
return add_rule(cmd, (directory_config *)_dcfg, RULE_TYPE_LUA, filename, p2, NULL);
#else
@@ -2347,9 +2729,20 @@ static const char *cmd_rule_script(cmd_parms *cmd, void *_dcfg,
static const char *cmd_rule_remove_by_id(cmd_parms *cmd, void *_dcfg,
const char *p1)
{
+ assert(cmd != NULL);
+ assert(_dcfg != NULL);
+ assert(p1 != NULL);
+ // Normally useless code, left to be safe for the moment
+ if (_dcfg == NULL) {
+ ap_log_perror(APLOG_MARK, APLOG_EMERG, 0, cmd->pool, "cmd_rule_remove_by_id: _dcfg is NULL");
+ return NULL;
+ }
directory_config *dcfg = (directory_config *)_dcfg;
- rule_exception *re = apr_pcalloc(cmd->pool, sizeof(rule_exception));
- if (dcfg == NULL) return NULL;
+ rule_exception* re = apr_pcalloc(cmd->pool, sizeof(rule_exception));
+ if (re == NULL) {
+ ap_log_perror(APLOG_MARK, APLOG_STARTUP | APLOG_NOERRNO, 0, cmd->pool, "cmd_rule_remove_by_id: Cannot allocate memory");
+ return NULL;
+ }
re->type = RULE_EXCEPTION_REMOVE_ID;
re->param = p1;
@@ -2374,10 +2767,21 @@ static const char *cmd_rule_remove_by_id(cmd_parms *cmd, void *_dcfg,
static const char *cmd_rule_remove_by_tag(cmd_parms *cmd, void *_dcfg,
const char *p1)
{
+ assert(cmd != NULL);
+ assert(_dcfg != NULL);
+ assert(p1 != NULL);
+ // Normally useless code, left to be safe for the moment
+ if (_dcfg == NULL) {
+ ap_log_perror(APLOG_MARK, APLOG_EMERG, 0, cmd->pool, "cmd_rule_remove_by_tag: _dcfg is NULL");
+ return NULL;
+ }
+ if (p1 == NULL) {
+ ap_log_perror(APLOG_MARK, APLOG_EMERG, 0, cmd->pool, "cmd_rule_remove_by_tag: p1 is NULL");
+ return NULL;
+ }
directory_config *dcfg = (directory_config *)_dcfg;
rule_exception *re = apr_pcalloc(cmd->pool, sizeof(rule_exception));
- if (dcfg == NULL) return NULL;
-
+
re->type = RULE_EXCEPTION_REMOVE_TAG;
re->param = p1;
re->param_data = msc_pregcomp(cmd->pool, p1, 0, NULL, NULL);
@@ -2399,10 +2803,17 @@ static const char *cmd_rule_remove_by_tag(cmd_parms *cmd, void *_dcfg,
static const char *cmd_rule_remove_by_msg(cmd_parms *cmd, void *_dcfg,
const char *p1)
{
+ assert(cmd != NULL);
+ assert(_dcfg != NULL);
+ assert(p1 != NULL);
+ // Normally useless code, left to be safe for the moment
+ if (_dcfg == NULL) {
+ ap_log_perror(APLOG_MARK, APLOG_EMERG, 0, cmd->pool, "cmd_rule_remove_by_msg: _dcfg is NULL");
+ return NULL;
+ }
directory_config *dcfg = (directory_config *)_dcfg;
rule_exception *re = apr_pcalloc(cmd->pool, sizeof(rule_exception));
- if (dcfg == NULL) return NULL;
-
+
re->type = RULE_EXCEPTION_REMOVE_MSG;
re->param = p1;
re->param_data = msc_pregcomp(cmd->pool, p1, 0, NULL, NULL);
@@ -2424,6 +2835,8 @@ static const char *cmd_rule_remove_by_msg(cmd_parms *cmd, void *_dcfg,
static const char *cmd_rule_update_action_by_id(cmd_parms *cmd, void *_dcfg,
const char *p1, const char *p2)
{
+ assert(cmd != NULL);
+ assert(p1 != NULL);
int offset = 0, rule_id = atoi(p1);
char *opt = strchr(p1,':');
char *savedptr = NULL;
@@ -2446,6 +2859,8 @@ static const char *cmd_rule_update_action_by_id(cmd_parms *cmd, void *_dcfg,
static const char *cmd_server_signature(cmd_parms *cmd, void *_dcfg,
const char *p1)
{
+ assert(cmd != NULL);
+ assert(p1 != NULL);
if (cmd->server->is_virtual) {
return "ModSecurity: SecServerSignature not allowed in VirtualHost";
}
@@ -2455,10 +2870,16 @@ static const char *cmd_server_signature(cmd_parms *cmd, void *_dcfg,
static const char *cmd_tmp_dir(cmd_parms *cmd, void *_dcfg, const char *p1)
{
+ assert(cmd != NULL);
+ assert(_dcfg != NULL);
+ assert(p1 != NULL);
+ // Normally useless code, left to be safe for the moment
+ if (_dcfg == NULL) {
+ ap_log_perror(APLOG_MARK, APLOG_EMERG, 0, cmd->pool, "cmd_tmp_dir: _dcfg is NULL");
+ return NULL;
+ }
directory_config *dcfg = (directory_config *)_dcfg;
- if (dcfg == NULL) return NULL;
-
if (strcasecmp(p1, "none") == 0) dcfg->tmp_dir = NULL;
else dcfg->tmp_dir = ap_server_root_relative(cmd->pool, p1);
@@ -2467,10 +2888,16 @@ static const char *cmd_tmp_dir(cmd_parms *cmd, void *_dcfg, const char *p1)
static const char *cmd_upload_dir(cmd_parms *cmd, void *_dcfg, const char *p1)
{
+ assert(cmd != NULL);
+ assert(_dcfg != NULL);
+ assert(p1 != NULL);
+ // Normally useless code, left to be safe for the moment
+ if (_dcfg == NULL) {
+ ap_log_perror(APLOG_MARK, APLOG_EMERG, 0, cmd->pool, "cmd_upload_dir: _dcfg is NULL");
+ return NULL;
+ }
directory_config *dcfg = (directory_config *)_dcfg;
- if (dcfg == NULL) return NULL;
-
if (strcasecmp(p1, "none") == 0) dcfg->upload_dir = NULL;
else dcfg->upload_dir = ap_server_root_relative(cmd->pool, p1);
@@ -2480,10 +2907,16 @@ static const char *cmd_upload_dir(cmd_parms *cmd, void *_dcfg, const char *p1)
static const char *cmd_upload_file_limit(cmd_parms *cmd, void *_dcfg,
const char *p1)
{
+ assert(cmd != NULL);
+ assert(_dcfg != NULL);
+ assert(p1 != NULL);
+ // Normally useless code, left to be safe for the moment
+ if (_dcfg == NULL) {
+ ap_log_perror(APLOG_MARK, APLOG_EMERG, 0, cmd->pool, "cmd_upload_file_limit: _dcfg is NULL");
+ return NULL;
+ }
directory_config *dcfg = (directory_config *)_dcfg;
- if (dcfg == NULL) return NULL;
-
if (strcasecmp(p1, "default") == 0) {
dcfg->upload_file_limit = NOT_SET;
}
@@ -2497,10 +2930,16 @@ static const char *cmd_upload_file_limit(cmd_parms *cmd, void *_dcfg,
static const char *cmd_upload_filemode(cmd_parms *cmd, void *_dcfg,
const char *p1)
{
+ assert(cmd != NULL);
+ assert(_dcfg != NULL);
+ assert(p1 != NULL);
+ // Normally useless code, left to be safe for the moment
+ if (_dcfg == NULL) {
+ ap_log_perror(APLOG_MARK, APLOG_EMERG, 0, cmd->pool, "cmd_upload_filemode: _dcfg is NULL");
+ return NULL;
+ }
directory_config *dcfg = (directory_config *)_dcfg;
- if (dcfg == NULL) return NULL;
-
if (strcasecmp(p1, "default") == 0) {
dcfg->upload_filemode = NOT_SET;
}
@@ -2519,10 +2958,16 @@ static const char *cmd_upload_filemode(cmd_parms *cmd, void *_dcfg,
static const char *cmd_upload_keep_files(cmd_parms *cmd, void *_dcfg,
const char *p1)
{
+ assert(cmd != NULL);
+ assert(_dcfg != NULL);
+ assert(p1 != NULL);
+ // Normally useless code, left to be safe for the moment
+ if (_dcfg == NULL) {
+ ap_log_perror(APLOG_MARK, APLOG_EMERG, 0, cmd->pool, "cmd_upload_keep_files: _dcfg is NULL");
+ return NULL;
+ }
directory_config *dcfg = (directory_config *)_dcfg;
- if (dcfg == NULL) return NULL;
-
if (strcasecmp(p1, "on") == 0) {
dcfg->upload_keep_files = KEEP_FILES_ON;
} else
@@ -2541,10 +2986,16 @@ static const char *cmd_upload_keep_files(cmd_parms *cmd, void *_dcfg,
static const char *cmd_upload_save_tmp_files(cmd_parms *cmd, void *_dcfg,
const char *p1)
{
+ assert(cmd != NULL);
+ assert(_dcfg != NULL);
+ assert(p1 != NULL);
+ // Normally useless code, left to be safe for the moment
+ if (_dcfg == NULL) {
+ ap_log_perror(APLOG_MARK, APLOG_EMERG, 0, cmd->pool, "cmd_upload_save_tmp_files: _dcfg is NULL");
+ return NULL;
+ }
directory_config *dcfg = (directory_config *)_dcfg;
- if (dcfg == NULL) return NULL;
-
if (strcasecmp(p1, "on") == 0)
{
dcfg->upload_validates_files = 1;
@@ -2564,6 +3015,14 @@ static const char *cmd_upload_save_tmp_files(cmd_parms *cmd, void *_dcfg,
static const char *cmd_web_app_id(cmd_parms *cmd, void *_dcfg, const char *p1)
{
+ assert(cmd != NULL);
+ assert(_dcfg != NULL);
+ assert(p1 != NULL);
+ // Normally useless code, left to be safe for the moment
+ if (_dcfg == NULL) {
+ ap_log_perror(APLOG_MARK, APLOG_EMERG, 0, cmd->pool, "cmd_web_app_id: _dcfg is NULL");
+ return NULL;
+ }
directory_config *dcfg = (directory_config *)_dcfg;
/* ENH enforce format (letters, digits, ., _, -) */
@@ -2574,6 +3033,14 @@ static const char *cmd_web_app_id(cmd_parms *cmd, void *_dcfg, const char *p1)
static const char *cmd_sensor_id(cmd_parms *cmd, void *_dcfg, const char *p1)
{
+ assert(cmd != NULL);
+ assert(_dcfg != NULL);
+ assert(p1 != NULL);
+ // Normally useless code, left to be safe for the moment
+ if (_dcfg == NULL) {
+ ap_log_perror(APLOG_MARK, APLOG_EMERG, 0, cmd->pool, "cmd_sensor_id: _dcfg is NULL");
+ return NULL;
+ }
directory_config *dcfg = (directory_config *)_dcfg;
/* ENH enforce format (letters, digits, ., _, -) */
@@ -2594,9 +3061,15 @@ static const char *cmd_sensor_id(cmd_parms *cmd, void *_dcfg, const char *p1)
*/
static const char *cmd_xml_external_entity(cmd_parms *cmd, void *_dcfg, const char *p1)
{
+ assert(cmd != NULL);
+ assert(_dcfg != NULL);
+ assert(p1 != NULL);
+ // Normally useless code, left to be safe for the moment
+ if (_dcfg == NULL) {
+ ap_log_perror(APLOG_MARK, APLOG_EMERG, 0, cmd->pool, "cmd_xml_external_entity: _dcfg is NULL");
+ return NULL;
+ }
directory_config *dcfg = (directory_config *)_dcfg;
- if (dcfg == NULL) return NULL;
-
if (strcasecmp(p1, "on") == 0) {
dcfg->xml_external_entity = 1;
}
@@ -2621,9 +3094,15 @@ static const char *cmd_xml_external_entity(cmd_parms *cmd, void *_dcfg, const ch
*/
static const char *cmd_hash_engine(cmd_parms *cmd, void *_dcfg, const char *p1)
{
+ assert(cmd != NULL);
+ assert(_dcfg != NULL);
+ assert(p1 != NULL);
+ // Normally useless code, left to be safe for the moment
+ if (_dcfg == NULL) {
+ ap_log_perror(APLOG_MARK, APLOG_EMERG, 0, cmd->pool, "cmd_hash_engine: _dcfg is NULL");
+ return NULL;
+ }
directory_config *dcfg = (directory_config *)_dcfg;
- if (dcfg == NULL) return NULL;
-
if (strcasecmp(p1, "on") == 0) {
dcfg->hash_is_enabled = HASH_ENABLED;
dcfg->hash_enforcement = HASH_ENABLED;
@@ -2638,7 +3117,7 @@ static const char *cmd_hash_engine(cmd_parms *cmd, void *_dcfg, const char *p1)
}
/**
-* \brief Add SecHashPram configuration option
+* \brief Add SecHashParam configuration option
*
* \param cmd Pointer to configuration data
* \param _dcfg Pointer to directory configuration
@@ -2648,11 +3127,20 @@ static const char *cmd_hash_engine(cmd_parms *cmd, void *_dcfg, const char *p1)
*/
static const char *cmd_hash_param(cmd_parms *cmd, void *_dcfg, const char *p1)
{
+ assert(cmd != NULL);
+ assert(_dcfg != NULL);
+ assert(p1 != NULL);
+ // Normally useless code, left to be safe for the moment
+ if (_dcfg == NULL) {
+ ap_log_perror(APLOG_MARK, APLOG_EMERG, 0, cmd->pool, "cmd_hash_param: _dcfg is NULL");
+ return NULL;
+ }
+ if (p1 == NULL) {
+ ap_log_perror(APLOG_MARK, APLOG_EMERG, 0, cmd->pool, "cmd_hash_param: p1 is NULL");
+ return NULL;
+ }
directory_config *dcfg = (directory_config *)_dcfg;
- if (dcfg == NULL) return NULL;
-
- if (p1 == NULL) return NULL;
dcfg->crypto_param_name = p1;
return NULL;
@@ -2670,12 +3158,26 @@ static const char *cmd_hash_param(cmd_parms *cmd, void *_dcfg, const char *p1)
*/
static const char *cmd_hash_key(cmd_parms *cmd, void *_dcfg, const char *_p1, const char *_p2)
{
+ assert(cmd != NULL);
+ assert(_dcfg != NULL);
+ assert(_p1 != NULL);
+ assert(_p2 != NULL);
+ // Normally useless code, left to be safe for the moment
+ if (_dcfg == NULL) {
+ ap_log_perror(APLOG_MARK, APLOG_EMERG, 0, cmd->pool, "cmd_hash_key: _dcfg is NULL");
+ return NULL;
+ }
+ if (_p1 == NULL) {
+ ap_log_perror(APLOG_MARK, APLOG_EMERG, 0, cmd->pool, "cmd_hash_key: _p1 is NULL");
+ return NULL;
+ }
+ if (_p2 == NULL) {
+ ap_log_perror(APLOG_MARK, APLOG_EMERG, 0, cmd->pool, "cmd_hash_key: _p2 is NULL");
+ return NULL;
+ }
directory_config *dcfg = (directory_config *)_dcfg;
char *p1 = NULL;
- if (dcfg == NULL) return NULL;
- if (_p1 == NULL) return NULL;
-
if (strcasecmp(_p1, "Rand") == 0) {
p1 = apr_pstrdup(cmd->pool, getkey(cmd->pool));
dcfg->crypto_key = p1;
@@ -2686,16 +3188,13 @@ static const char *cmd_hash_key(cmd_parms *cmd, void *_dcfg, const char *_p1, co
dcfg->crypto_key_len = strlen(p1);
}
- if(_p2 == NULL) {
- return NULL;
- } else {
- if (strcasecmp(_p2, "KeyOnly") == 0)
- dcfg->crypto_key_add = HASH_KEYONLY;
- else if (strcasecmp(_p2, "SessionID") == 0)
- dcfg->crypto_key_add = HASH_SESSIONID;
- else if (strcasecmp(_p2, "RemoteIP") == 0)
- dcfg->crypto_key_add = HASH_REMOTEIP;
- }
+ if (strcasecmp(_p2, "KeyOnly") == 0)
+ dcfg->crypto_key_add = HASH_KEYONLY;
+ else if (strcasecmp(_p2, "SessionID") == 0)
+ dcfg->crypto_key_add = HASH_SESSIONID;
+ else if (strcasecmp(_p2, "RemoteIP") == 0)
+ dcfg->crypto_key_add = HASH_REMOTEIP;
+
return NULL;
}
@@ -2713,6 +3212,19 @@ static const char *cmd_hash_key(cmd_parms *cmd, void *_dcfg, const char *_p1, co
static const char *cmd_hash_method_pm(cmd_parms *cmd, void *_dcfg,
const char *p1, const char *p2)
{
+ assert(cmd != NULL);
+ assert(_dcfg != NULL);
+ assert(p1 != NULL);
+ assert(p2 != NULL);
+ // Normally useless code, left to be safe for the moment
+ if (_dcfg == NULL) {
+ ap_log_perror(APLOG_MARK, APLOG_EMERG, 0, cmd->pool, "cmd_hash_method_pm: _dcfg is NULL");
+ return NULL;
+ }
+ if (p1 == NULL) {
+ ap_log_perror(APLOG_MARK, APLOG_EMERG, 0, cmd->pool, "cmd_hash_method_pm: p1 is NULL");
+ return NULL;
+ }
directory_config *dcfg = (directory_config *)_dcfg;
rule_exception *re = apr_pcalloc(cmd->pool, sizeof(hash_method));
const char *_p2 = apr_pstrdup(cmd->pool, p2);
@@ -2720,8 +3232,6 @@ static const char *cmd_hash_method_pm(cmd_parms *cmd, void *_dcfg,
const char *phrase = NULL;
const char *next = NULL;
- if (dcfg == NULL) return NULL;
-
p = acmp_create(0, cmd->pool);
if (p == NULL) return NULL;
@@ -2804,11 +3314,19 @@ static const char *cmd_hash_method_pm(cmd_parms *cmd, void *_dcfg,
static const char *cmd_hash_method_rx(cmd_parms *cmd, void *_dcfg,
const char *p1, const char *p2)
{
+ assert(cmd != NULL);
+ assert(_dcfg != NULL);
+ assert(p1 != NULL);
+ assert(p2 != NULL);
+ // Normally useless code, left to be safe for the moment
+ if (_dcfg == NULL) {
+ ap_log_perror(APLOG_MARK, APLOG_EMERG, 0, cmd->pool, "cmd_hash_method_rx: _dcfg is NULL");
+ return NULL;
+ }
directory_config *dcfg = (directory_config *)_dcfg;
rule_exception *re = apr_pcalloc(cmd->pool, sizeof(hash_method));
const char *_p2 = apr_pstrdup(cmd->pool, p2);
- if (dcfg == NULL) return NULL;
-
+
if (strcasecmp(p1, "HashHref") == 0) {
re->type = HASH_URL_HREF_HASH_RX;
re->param = _p2;
@@ -2871,11 +3389,20 @@ static const char *cmd_hash_method_rx(cmd_parms *cmd, void *_dcfg,
*/
static const char *cmd_httpBl_key(cmd_parms *cmd, void *_dcfg, const char *p1)
{
+ assert(cmd != NULL);
+ assert(_dcfg != NULL);
+ assert(p1 != NULL);
+ // Normally useless code, left to be safe for the moment
+ if (_dcfg == NULL) {
+ ap_log_perror(APLOG_MARK, APLOG_EMERG, 0, cmd->pool, "cmd_httpBl_key: _dcfg is NULL");
+ return NULL;
+ }
+ if (p1 == NULL) {
+ ap_log_perror(APLOG_MARK, APLOG_EMERG, 0, cmd->pool, "cmd_httpBl_key: p1 is NULL");
+ return NULL;
+ }
directory_config *dcfg = (directory_config *)_dcfg;
- if (dcfg == NULL) return NULL;
-
- if (p1 == NULL) return NULL;
dcfg->httpBlkey = p1;
return NULL;
@@ -2886,6 +3413,13 @@ static const char *cmd_httpBl_key(cmd_parms *cmd, void *_dcfg, const char *p1)
static const char *cmd_pcre_match_limit(cmd_parms *cmd,
void *_dcfg, const char *p1)
{
+ assert(cmd != NULL);
+ assert(p1 != NULL);
+ // Normally useless code, left to be safe for the moment
+ if (p1 == NULL) {
+ ap_log_perror(APLOG_MARK, APLOG_EMERG, 0, cmd->pool, "cmd_pcre_match_limit: p1 is NULL");
+ return NULL;
+ }
long val;
if (cmd->server->is_virtual) {
@@ -2905,6 +3439,13 @@ static const char *cmd_pcre_match_limit(cmd_parms *cmd,
static const char *cmd_pcre_match_limit_recursion(cmd_parms *cmd,
void *_dcfg, const char *p1)
{
+ assert(cmd != NULL);
+ assert(p1 != NULL);
+ // Normally useless code, left to be safe for the moment
+ if (p1 == NULL) {
+ ap_log_perror(APLOG_MARK, APLOG_EMERG, 0, cmd->pool, "cmd_pcre_match_limit_recursion: p1 is NULL");
+ return NULL;
+ }
long val;
if (cmd->server->is_virtual) {
@@ -2927,11 +3468,22 @@ static const char *cmd_pcre_match_limit_recursion(cmd_parms *cmd,
static const char *cmd_geo_lookup_db(cmd_parms *cmd, void *_dcfg,
const char *p1)
{
+ assert(cmd != NULL);
+ assert(p1 != NULL);
+ assert(_dcfg != NULL);
+ // Normally useless code, left to be safe for the moment
+ if (_dcfg == NULL) {
+ ap_log_perror(APLOG_MARK, APLOG_EMERG, 0, cmd->pool, "cmd_geo_lookup_db: _dcfg is NULL");
+ return NULL;
+ }
+ if (p1 == NULL) {
+ ap_log_perror(APLOG_MARK, APLOG_EMERG, 0, cmd->pool, "cmd_geo_lookup_db: p1 is NULL");
+ return NULL;
+ }
const char *filename = resolve_relative_path(cmd->pool, cmd->directive->filename, p1);
char *error_msg;
directory_config *dcfg = (directory_config *)_dcfg;
- if (dcfg == NULL) return NULL;
-
+
if (geo_init(dcfg, filename, &error_msg) <= 0) {
return error_msg;
}
@@ -2953,6 +3505,8 @@ static const char *cmd_geo_lookup_db(cmd_parms *cmd, void *_dcfg,
static const char *cmd_unicode_codepage(cmd_parms *cmd,
void *_dcfg, const char *p1)
{
+ assert(cmd != NULL);
+ assert(p1 != NULL);
long val;
val = atol(p1);
@@ -2978,12 +3532,19 @@ static const char *cmd_unicode_codepage(cmd_parms *cmd,
static const char *cmd_unicode_map(cmd_parms *cmd, void *_dcfg,
const char *p1, const char *p2)
{
+ assert(cmd != NULL);
+ assert(p1 != NULL);
+ assert(p2 != NULL);
+ // Normally useless code, left to be safe for the moment
+ if (_dcfg == NULL) {
+ ap_log_perror(APLOG_MARK, APLOG_EMERG, 0, cmd->pool, "cmd_unicode_map: _dcfg is NULL");
+ return NULL;
+ }
const char *filename = resolve_relative_path(cmd->pool, cmd->directive->filename, p1);
char *error_msg;
long val = 0;
directory_config *dcfg = (directory_config *)_dcfg;
- if (dcfg == NULL) return NULL;
-
+
if(p2 != NULL) {
val = atol(p2);
if (val <= 0) {
@@ -3013,11 +3574,12 @@ static const char *cmd_unicode_map(cmd_parms *cmd, void *_dcfg,
static const char *cmd_gsb_lookup_db(cmd_parms *cmd, void *_dcfg,
const char *p1)
{
+ assert(cmd != NULL);
+ assert(p1 != NULL);
const char *filename = resolve_relative_path(cmd->pool, cmd->directive->filename, p1);
char *error_msg;
directory_config *dcfg = (directory_config *)_dcfg;
- if (dcfg == NULL) return NULL;
-
+
if (gsb_db_init(dcfg, filename, &error_msg) <= 0) {
return error_msg;
}
@@ -3030,10 +3592,16 @@ static const char *cmd_gsb_lookup_db(cmd_parms *cmd, void *_dcfg,
static const char *cmd_cache_transformations(cmd_parms *cmd, void *_dcfg,
const char *p1, const char *p2)
{
+ assert(cmd != NULL);
+ assert(_dcfg != NULL);
+ assert(p1 != NULL);
+ // Normally useless code, left to be safe for the moment
+ if (_dcfg == NULL) {
+ ap_log_perror(APLOG_MARK, APLOG_EMERG, 0, cmd->pool, "cmd_cache_transformations: _dcfg is NULL");
+ return NULL;
+ }
directory_config *dcfg = (directory_config *)_dcfg;
- if (dcfg == NULL) return NULL;
-
if (strcasecmp(p1, "on") == 0)
dcfg->cache_trans = MODSEC_CACHE_ENABLED;
else if (strcasecmp(p1, "off") == 0)
@@ -3129,6 +3697,34 @@ static const char *cmd_cache_transformations(cmd_parms *cmd, void *_dcfg,
return NULL;
}
+/**
+* \brief Add SecParseXmlIntoArgs configuration option
+*
+* \param cmd Pointer to configuration data
+* \param _dcfg Pointer to directory configuration
+* \param p1 Pointer to configuration option
+*
+* \retval NULL On Success
+* \retval apr_psprintf On error
+*/
+static const char *cmd_parse_xml_into_args(cmd_parms *cmd, void *_dcfg, const char *p1)
+{
+ assert(cmd != NULL);
+ assert(_dcfg != NULL);
+ assert(p1 != NULL);
+ // Normally useless code, left to be safe for the moment
+ if (_dcfg == NULL) {
+ ap_log_perror(APLOG_MARK, APLOG_EMERG, 0, cmd->pool, "cmd_parse_xml_into_args: _dcfg is NULL");
+ return NULL;
+ }
+ directory_config *dcfg = (directory_config *)_dcfg;
+ if (strcasecmp(p1, "on") == 0) { dcfg->parse_xml_into_args = MSC_XML_ARGS_ON; }
+ else if (strcasecmp(p1, "off") == 0) { dcfg->parse_xml_into_args = MSC_XML_ARGS_OFF; }
+ else if (strcasecmp(p1, "onlyargs") == 0) { dcfg->parse_xml_into_args = MSC_XML_ARGS_ONLYARGS; }
+ else return apr_psprintf(cmd->pool, "ModSecurity: Invalid value for SecParseXmlIntoArgs: %s", p1);
+
+ return NULL;
+}
/* -- Configuration directives definitions -- */
@@ -3223,6 +3819,16 @@ const command_rec module_directives[] = {
"whether to use the old audit log format (Serial) or new (Concurrent)"
),
+#ifdef WITH_YAJL
+ AP_INIT_TAKE1 (
+ "SecAuditLogFormat",
+ cmd_audit_log_mode,
+ NULL,
+ CMD_SCOPE_ANY,
+ "whether to emit audit log data in native format or JSON"
+ ),
+#endif
+
AP_INIT_TAKE1 (
"SecAuditLogStorageDir",
cmd_audit_log_storage_dir,
@@ -3496,6 +4102,22 @@ const command_rec module_directives[] = {
"maximum request body size ModSecurity will accept, but excluding the size of uploaded files."
),
+ AP_INIT_TAKE1 (
+ "SecRequestBodyJsonDepthLimit",
+ cmd_request_body_json_depth_limit,
+ NULL,
+ CMD_SCOPE_ANY,
+ "maximum request body JSON parsing depth ModSecurity will accept."
+ ),
+
+ AP_INIT_TAKE1 (
+ "SecArgumentsLimit",
+ cmd_arguments_limit,
+ NULL,
+ CMD_SCOPE_ANY,
+ "maximum number of ARGS that ModSecurity will accept."
+ ),
+
AP_INIT_TAKE1 (
"SecRequestEncoding",
cmd_request_encoding,
@@ -3871,5 +4493,13 @@ const command_rec module_directives[] = {
"Set Hash parameter"
),
+ AP_INIT_TAKE1 (
+ "SecParseXmlIntoArgs",
+ cmd_parse_xml_into_args,
+ NULL,
+ CMD_SCOPE_ANY,
+ "On, Off or OnlyArgs"
+ ),
+
{ NULL }
};
diff --git a/apache2/apache2_io.c b/apache2/apache2_io.c
index 88f1903183..8deeb01c9a 100644
--- a/apache2/apache2_io.c
+++ b/apache2/apache2_io.c
@@ -18,6 +18,10 @@
#include "apache2.h"
#include "msc_crypt.h"
+#ifdef APLOG_USE_MODULE
+ APLOG_USE_MODULE(security2);
+#endif
+
/* -- Input filter -- */
#if 0
@@ -36,6 +40,7 @@ apr_status_t input_filter(ap_filter_t *f, apr_bucket_brigade *bb_out,
msc_data_chunk *chunk = NULL;
apr_bucket *bucket;
apr_status_t rc;
+ int no_data = 1;
char *my_error_msg = NULL;
if (msr == NULL) {
@@ -85,10 +90,11 @@ apr_status_t input_filter(ap_filter_t *f, apr_bucket_brigade *bb_out,
return APR_EGENERAL;
}
- if (chunk && (!msr->txcfg->stream_inbody_inspection || (msr->txcfg->stream_inbody_inspection && msr->if_stream_changed == 0))) {
- /* Copy the data we received in the chunk */
- bucket = apr_bucket_heap_create(chunk->data, chunk->length, NULL,
- f->r->connection->bucket_alloc);
+ if (chunk && chunk->length > 0) {
+ if (chunk && (!msr->txcfg->stream_inbody_inspection || (msr->txcfg->stream_inbody_inspection && msr->if_stream_changed == 0))) {
+ /* Copy the data we received in the chunk */
+ bucket = apr_bucket_heap_create(chunk->data, chunk->length, NULL,
+ f->r->connection->bucket_alloc);
#if 0
@@ -107,44 +113,50 @@ apr_status_t input_filter(ap_filter_t *f, apr_bucket_brigade *bb_out,
#endif
- if (bucket == NULL) return APR_EGENERAL;
- APR_BRIGADE_INSERT_TAIL(bb_out, bucket);
+ if (bucket == NULL) return APR_EGENERAL;
+ APR_BRIGADE_INSERT_TAIL(bb_out, bucket);
+ no_data = 0;
- if (msr->txcfg->debuglog_level >= 4) {
- msr_log(msr, 4, "Input filter: Forwarded %" APR_SIZE_T_FMT " bytes.", chunk->length);
- }
- } else if (msr->stream_input_data != NULL) {
+ if (msr->txcfg->debuglog_level >= 4) {
+ msr_log(msr, 4, "Input filter: Forwarded %" APR_SIZE_T_FMT " bytes.", chunk->length);
+ }
+ } else if (msr->stream_input_data != NULL) {
- msr->if_stream_changed = 0;
+ msr->if_stream_changed = 0;
- bucket = apr_bucket_heap_create(msr->stream_input_data, msr->stream_input_length, NULL,
- f->r->connection->bucket_alloc);
+ bucket = apr_bucket_heap_create(msr->stream_input_data, msr->stream_input_length, NULL,
+ f->r->connection->bucket_alloc);
- if (msr->txcfg->stream_inbody_inspection) {
- if(msr->stream_input_data != NULL) {
- free(msr->stream_input_data);
- msr->stream_input_data = NULL;
+ if (msr->txcfg->stream_inbody_inspection) {
+ if(msr->stream_input_data != NULL) {
+ free(msr->stream_input_data);
+ msr->stream_input_data = NULL;
+ }
}
- }
- if (bucket == NULL) return APR_EGENERAL;
- APR_BRIGADE_INSERT_TAIL(bb_out, bucket);
+ if (bucket == NULL) return APR_EGENERAL;
+ APR_BRIGADE_INSERT_TAIL(bb_out, bucket);
+ no_data = 0;
- if (msr->txcfg->debuglog_level >= 4) {
- msr_log(msr, 4, "Input stream filter: Forwarded %" APR_SIZE_T_FMT " bytes.", msr->stream_input_length);
- }
+ if (msr->txcfg->debuglog_level >= 4) {
+ msr_log(msr, 4, "Input stream filter: Forwarded %" APR_SIZE_T_FMT " bytes.", msr->stream_input_length);
+ }
+ }
}
if (rc == 0) {
modsecurity_request_body_retrieve_end(msr);
- bucket = apr_bucket_eos_create(f->r->connection->bucket_alloc);
- if (bucket == NULL) return APR_EGENERAL;
- APR_BRIGADE_INSERT_TAIL(bb_out, bucket);
+ if (msr->if_seen_eos) {
+ bucket = apr_bucket_eos_create(f->r->connection->bucket_alloc);
+ if (bucket == NULL) return APR_EGENERAL;
+ APR_BRIGADE_INSERT_TAIL(bb_out, bucket);
+ no_data = 0;
- if (msr->txcfg->debuglog_level >= 4) {
- msr_log(msr, 4, "Input filter: Sent EOS.");
+ if (msr->txcfg->debuglog_level >= 4) {
+ msr_log(msr, 4, "Input filter: Sent EOS.");
+ }
}
/* We're done */
@@ -154,6 +166,10 @@ apr_status_t input_filter(ap_filter_t *f, apr_bucket_brigade *bb_out,
if (msr->txcfg->debuglog_level >= 4) {
msr_log(msr, 4, "Input filter: Input forwarding complete.");
}
+
+ if (no_data) {
+ return ap_get_brigade(f->next, bb_out, mode, block, nbytes);
+ }
}
return APR_SUCCESS;
@@ -163,39 +179,42 @@ apr_status_t input_filter(ap_filter_t *f, apr_bucket_brigade *bb_out,
* Reads request body from a client.
*/
apr_status_t read_request_body(modsec_rec *msr, char **error_msg) {
+ assert(msr != NULL);
+ assert(error_msg!= NULL);
request_rec *r = msr->r;
- unsigned int seen_eos;
+ unsigned int finished_reading;
apr_bucket_brigade *bb_in;
apr_bucket *bucket;
- if (error_msg == NULL) return -1;
*error_msg = NULL;
if (msr->reqbody_should_exist != 1) {
if (msr->txcfg->debuglog_level >= 4) {
msr_log(msr, 4, "Input filter: This request does not have a body.");
}
- return 0;
+ return APR_SUCCESS;
}
if (msr->txcfg->reqbody_access != 1) {
if (msr->txcfg->debuglog_level >= 4) {
msr_log(msr, 4, "Input filter: Request body access not enabled.");
}
- return 0;
+ return APR_SUCCESS;
}
if (msr->txcfg->debuglog_level >= 4) {
msr_log(msr, 4, "Input filter: Reading request body.");
}
-
if (modsecurity_request_body_start(msr, error_msg) < 0) {
- return -1;
+ return HTTP_INTERNAL_SERVER_ERROR;
}
- seen_eos = 0;
+ finished_reading = 0;
+ msr->if_seen_eos = 0;
bb_in = apr_brigade_create(msr->mp, r->connection->bucket_alloc);
- if (bb_in == NULL) return -1;
+ if (bb_in == NULL) {
+ return HTTP_INTERNAL_SERVER_ERROR;
+ }
do {
apr_status_t rc;
@@ -205,22 +224,17 @@ apr_status_t read_request_body(modsec_rec *msr, char **error_msg) {
* too large and APR_EGENERAL when the client disconnects.
*/
switch(rc) {
- case APR_EOF :
- *error_msg = apr_psprintf(msr->mp, "Error reading request body: %s", get_apr_error(msr->mp, rc));
- return -6;
- case APR_TIMEUP :
- *error_msg = apr_psprintf(msr->mp, "Error reading request body: %s", get_apr_error(msr->mp, rc));
- return -4;
case AP_FILTER_ERROR :
*error_msg = apr_psprintf(msr->mp, "Error reading request body: HTTP Error 413 - Request entity too large. (Most likely.)");
- return -3;
+ break;
case APR_EGENERAL :
*error_msg = apr_psprintf(msr->mp, "Error reading request body: Client went away.");
- return -2;
+ break;
default :
*error_msg = apr_psprintf(msr->mp, "Error reading request body: %s", get_apr_error(msr->mp, rc));
- return -1;
+ break;
}
+ return ap_map_http_request_error(rc, HTTP_BAD_REQUEST);
}
/* Loop through the buckets in the brigade in order
@@ -236,7 +250,7 @@ apr_status_t read_request_body(modsec_rec *msr, char **error_msg) {
rc = apr_bucket_read(bucket, &buf, &buflen, APR_BLOCK_READ);
if (rc != APR_SUCCESS) {
*error_msg = apr_psprintf(msr->mp, "Failed reading input / bucket (%d): %s", rc, get_apr_error(msr->mp, rc));
- return -1;
+ return HTTP_INTERNAL_SERVER_ERROR;
}
if (msr->txcfg->debuglog_level >= 9) {
@@ -249,7 +263,7 @@ apr_status_t read_request_body(modsec_rec *msr, char **error_msg) {
if((msr->txcfg->is_enabled == MODSEC_ENABLED) && (msr->txcfg->if_limit_action == REQUEST_BODY_LIMIT_ACTION_REJECT)) {
*error_msg = apr_psprintf(msr->mp, "Request body is larger than the "
"configured limit (%ld).", msr->txcfg->reqbody_limit);
- return -5;
+ return HTTP_REQUEST_ENTITY_TOO_LARGE;
} else if((msr->txcfg->is_enabled == MODSEC_ENABLED) && (msr->txcfg->if_limit_action == REQUEST_BODY_LIMIT_ACTION_PARTIAL)) {
*error_msg = apr_psprintf(msr->mp, "Request body is larger than the "
@@ -270,25 +284,36 @@ apr_status_t read_request_body(modsec_rec *msr, char **error_msg) {
*error_msg = apr_psprintf(msr->mp, "Request body is larger than the "
"configured limit (%ld).", msr->txcfg->reqbody_limit);
- return -5;
+ return HTTP_REQUEST_ENTITY_TOO_LARGE;
}
}
if (msr->txcfg->stream_inbody_inspection == 1) {
+#ifndef MSC_LARGE_STREAM_INPUT
msr->stream_input_length+=buflen;
modsecurity_request_body_to_stream(msr, buf, buflen, error_msg);
+#else
+ if (modsecurity_request_body_to_stream(msr, buf, buflen, error_msg) < 0) {
+ return HTTP_INTERNAL_SERVER_ERROR;
+ }
+#endif
}
msr->reqbody_length += buflen;
if (buflen != 0) {
int rcbs = modsecurity_request_body_store(msr, buf, buflen, error_msg);
+
+ if (msr->reqbody_length > (apr_size_t)msr->txcfg->reqbody_limit && msr->txcfg->if_limit_action == REQUEST_BODY_LIMIT_ACTION_PARTIAL) {
+ finished_reading = 1;
+ }
+
if (rcbs < 0) {
if (rcbs == -5) {
if((msr->txcfg->is_enabled == MODSEC_ENABLED) && (msr->txcfg->if_limit_action == REQUEST_BODY_LIMIT_ACTION_REJECT)) {
*error_msg = apr_psprintf(msr->mp, "Request body no files data length is larger than the "
"configured limit (%ld).", msr->txcfg->reqbody_no_files_limit);
- return -5;
+ return HTTP_REQUEST_ENTITY_TOO_LARGE;
} else if ((msr->txcfg->is_enabled == MODSEC_ENABLED) && (msr->txcfg->if_limit_action == REQUEST_BODY_LIMIT_ACTION_PARTIAL)) {
*error_msg = apr_psprintf(msr->mp, "Request body no files data length is larger than the "
"configured limit (%ld).", msr->txcfg->reqbody_no_files_limit);
@@ -298,26 +323,26 @@ apr_status_t read_request_body(modsec_rec *msr, char **error_msg) {
} else {
*error_msg = apr_psprintf(msr->mp, "Request body no files data length is larger than the "
"configured limit (%ld).", msr->txcfg->reqbody_no_files_limit);
- return -5;
+ return HTTP_REQUEST_ENTITY_TOO_LARGE;
}
}
if((msr->txcfg->is_enabled == MODSEC_ENABLED) && (msr->txcfg->if_limit_action == REQUEST_BODY_LIMIT_ACTION_REJECT))
- return -1;
+ return HTTP_INTERNAL_SERVER_ERROR;
}
}
if (APR_BUCKET_IS_EOS(bucket)) {
- seen_eos = 1;
+ finished_reading = 1;
+ msr->if_seen_eos = 1;
}
}
apr_brigade_cleanup(bb_in);
- } while(!seen_eos);
+ } while(!finished_reading);
- // TODO: Why ignore the return code here?
- modsecurity_request_body_end(msr, error_msg);
+ apr_status_t rcbe = modsecurity_request_body_end(msr, error_msg);
if (msr->txcfg->debuglog_level >= 4) {
msr_log(msr, 4, "Input filter: Completed receiving request body (length %" APR_SIZE_T_FMT ").",
@@ -326,7 +351,13 @@ apr_status_t read_request_body(modsec_rec *msr, char **error_msg) {
msr->if_status = IF_STATUS_WANTS_TO_RUN;
- return 1;
+ if (rcbe == -5) {
+ return HTTP_REQUEST_ENTITY_TOO_LARGE;
+ }
+ if (rcbe < 0) {
+ return HTTP_INTERNAL_SERVER_ERROR;
+ }
+ return APR_SUCCESS;
}
@@ -338,6 +369,8 @@ apr_status_t read_request_body(modsec_rec *msr, char **error_msg) {
* run or not.
*/
static int output_filter_should_run(modsec_rec *msr, request_rec *r) {
+ assert(msr != NULL);
+ assert(r != NULL);
char *content_type = NULL;
/* Check configuration. */
@@ -399,10 +432,13 @@ static int output_filter_should_run(modsec_rec *msr, request_rec *r) {
static apr_status_t output_filter_init(modsec_rec *msr, ap_filter_t *f,
apr_bucket_brigade *bb_in)
{
+ assert(msr != NULL);
+ assert(f != NULL);
request_rec *r = f->r;
const char *s_content_length = NULL;
apr_status_t rc;
+ assert(msr != NULL);
msr->of_brigade = apr_brigade_create(msr->mp, f->c->bucket_alloc);
if (msr->of_brigade == NULL) {
msr_log(msr, 1, "Output filter: Failed to create brigade.");
@@ -466,6 +502,8 @@ static apr_status_t output_filter_init(modsec_rec *msr, ap_filter_t *f,
* and to the client.
*/
static apr_status_t send_of_brigade(modsec_rec *msr, ap_filter_t *f) {
+ assert(msr != NULL);
+ assert(f != NULL);
apr_status_t rc;
rc = ap_pass_brigade(f->next, msr->of_brigade);
@@ -507,6 +545,8 @@ static apr_status_t send_of_brigade(modsec_rec *msr, ap_filter_t *f) {
*
*/
static void inject_content_to_of_brigade(modsec_rec *msr, ap_filter_t *f) {
+ assert(msr != NULL);
+ assert(f != NULL);
apr_bucket *b;
if (msr->txcfg->content_injection_enabled && msr->stream_output_data != NULL) {
@@ -533,6 +573,8 @@ static void inject_content_to_of_brigade(modsec_rec *msr, ap_filter_t *f) {
*
*/
static void prepend_content_to_of_brigade(modsec_rec *msr, ap_filter_t *f) {
+ assert(msr != NULL);
+ assert(f != NULL);
if ((msr->txcfg->content_injection_enabled) && (msr->content_prepend) && (!msr->of_skipping)) {
apr_bucket *bucket_ci = NULL;
@@ -587,7 +629,6 @@ static int flatten_response_body(modsec_rec *msr) {
return -1;
}
- memset(msr->stream_output_data, 0, msr->stream_output_length+1);
memcpy(msr->stream_output_data, msr->resbody_data, msr->stream_output_length);
msr->stream_output_data[msr->stream_output_length] = '\0';
} else if (msr->txcfg->stream_outbody_inspection && msr->txcfg->hash_is_enabled == HASH_ENABLED) {
@@ -600,8 +641,12 @@ static int flatten_response_body(modsec_rec *msr) {
retval = hash_response_body_links(msr);
if(retval > 0) {
retval = inject_hashed_response_body(msr, retval);
- if (msr->txcfg->debuglog_level >= 4) {
- msr_log(msr, 4, "Hash completed in %" APR_TIME_T_FMT " usec.", (apr_time_now() - time1));
+ if(retval < 0){
+ msr_log(msr, 1, "inject_hashed_response_body: Unable to inject hash into response body. Returning response without changes." );
+ }else{
+ if (msr->txcfg->debuglog_level >= 4) {
+ msr_log(msr, 4, "Hash completed in %" APR_TIME_T_FMT " usec.", (apr_time_now() - time1));
+ }
}
}
@@ -616,7 +661,6 @@ static int flatten_response_body(modsec_rec *msr) {
return -1;
}
- memset(msr->stream_output_data, 0, msr->stream_output_length+1);
memcpy(msr->stream_output_data, msr->resbody_data, msr->stream_output_length);
msr->stream_output_data[msr->stream_output_length] = '\0';
}
@@ -974,6 +1018,12 @@ apr_status_t output_filter(ap_filter_t *f, apr_bucket_brigade *bb_in) {
/* Now send data down the filter stream
* (full-buffering only).
*/
+ if (!eos_bucket) {
+ ap_log_error(APLOG_MARK, APLOG_ERR | APLOG_NOERRNO, 0, f->r->server,
+ "ModSecurity: Internal Error: eos_bucket is NULL.");
+ return APR_EGENERAL;
+ }
+
if ((msr->of_skipping == 0)&&(!msr->of_partial)) {
if(msr->of_stream_changed == 1) {
inject_content_to_of_brigade(msr,f);
diff --git a/apache2/apache2_util.c b/apache2/apache2_util.c
index 0960dc8e63..e13c64b905 100644
--- a/apache2/apache2_util.c
+++ b/apache2/apache2_util.c
@@ -17,10 +17,16 @@
#include "http_core.h"
#include "util_script.h"
+#ifdef APLOG_USE_MODULE
+ APLOG_USE_MODULE(security2);
+#endif
+
/**
* Sends a brigade with an error bucket down the filter chain.
*/
apr_status_t send_error_bucket(modsec_rec *msr, ap_filter_t *f, int status) {
+ assert(msr != NULL);
+ assert(f != NULL);
apr_bucket_brigade *brigade = NULL;
apr_bucket *bucket = NULL;
@@ -57,6 +63,9 @@ apr_status_t send_error_bucket(modsec_rec *msr, ap_filter_t *f, int status) {
* the "output" parameter.
*/
int apache2_exec(modsec_rec *msr, const char *command, const char **argv, char **output) {
+ assert(msr != NULL);
+ assert(command != NULL);
+
apr_procattr_t *procattr = NULL;
apr_proc_t *procnew = NULL;
apr_status_t rc = APR_SUCCESS;
@@ -95,7 +104,12 @@ int apache2_exec(modsec_rec *msr, const char *command, const char **argv, char *
return -1;
}
- apr_procattr_io_set(procattr, APR_NO_PIPE, APR_FULL_BLOCK, APR_NO_PIPE);
+ rc = apr_procattr_io_set(procattr, APR_NO_PIPE, APR_FULL_BLOCK, APR_NO_PIPE);
+ if (rc != APR_SUCCESS) {
+ msr_log(msr, 1, "Exec: apr_procattr_io_set failed: %d (%s)", rc, get_apr_error(r->pool, rc));
+ return -1;
+ }
+
apr_procattr_cmdtype_set(procattr, APR_SHELLCMD);
if (msr->txcfg->debuglog_level >= 9) {
@@ -195,13 +209,12 @@ char *get_env_var(request_rec *r, char *name) {
static void internal_log_ex(request_rec *r, directory_config *dcfg, modsec_rec *msr,
int level, int fixup, const char *text, va_list ap)
{
+ assert(r != NULL);
+ assert(msr != NULL);
+ assert(text != NULL);
apr_size_t nbytes, nbytes_written;
apr_file_t *debuglog_fd = NULL;
int filter_debug_level = 0;
- char *remote = NULL;
- char *parse_remote = NULL;
- char *saved = NULL;
- char *str = NULL;
char str1[1024] = "";
char str2[1256] = "";
@@ -267,21 +280,33 @@ static void internal_log_ex(request_rec *r, directory_config *dcfg, modsec_rec *
}
else hostname = "";
-#if AP_SERVER_MAJORVERSION_NUMBER > 1 && AP_SERVER_MINORVERSION_NUMBER > 2
+/* Non-standalone modules use amended format string for logging */
+#if !(defined(VERSION_STANDALONE))
+ #if AP_SERVER_MAJORVERSION_NUMBER > 1 && AP_SERVER_MINORVERSION_NUMBER > 2
+ ap_log_rerror(APLOG_MARK, APLOG_ERR | APLOG_NOERRNO, 0, r,
+ "ModSecurity: %s%s [uri \"%s\"]%s", str1, hostname, log_escape(msr->mp, r->uri), unique_id);
+ #else
ap_log_error(APLOG_MARK, APLOG_ERR | APLOG_NOERRNO, 0, r->server,
+ "ModSecurity: %s%s [uri \"%s\"]%s", str1, hostname, log_escape(msr->mp, r->uri), unique_id);
+ #endif
+/* Standalone module must use original format string for logging with explicit
+ * "[client %s]" to log client IP address (no Apache to implicitly add this) */
+#else
+ #if AP_SERVER_MAJORVERSION_NUMBER > 1 && AP_SERVER_MINORVERSION_NUMBER > 2
+ ap_log_rerror(APLOG_MARK, APLOG_ERR | APLOG_NOERRNO, 0, r,
"[client %s] ModSecurity: %s%s [uri \"%s\"]%s", r->useragent_ip ? r->useragent_ip : r->connection->client_ip, str1,
hostname, log_escape(msr->mp, r->uri), unique_id);
-#else
+ #else
ap_log_error(APLOG_MARK, APLOG_ERR | APLOG_NOERRNO, 0, r->server,
- "[client %s] ModSecurity: %s%s [uri \"%s\"]%s", msr->remote_addr ? msr->remote_addr : r->connection->remote_ip, str1,
- hostname, log_escape(msr->mp, r->uri), unique_id);
+ "[client %s] ModSecurity: %s%s [uri \"%s\"]%s", msr->remote_addr ? msr->remote_addr : r->connection->remote_ip, str1,
+ hostname, log_escape(msr->mp, r->uri), unique_id);
+ #endif
#endif
/* Add this message to the list. */
if (msr != NULL) {
/* Force relevency if this is an alert */
msr->is_relevant++;
-
*(const char **)apr_array_push(msr->alerts) = apr_pstrdup(msr->mp, str1);
}
}
@@ -294,6 +319,8 @@ static void internal_log_ex(request_rec *r, directory_config *dcfg, modsec_rec *
* Apache error log if the message is important enough.
*/
void msr_log(modsec_rec *msr, int level, const char *text, ...) {
+ assert(msr != NULL);
+ assert(text != NULL);
va_list ap;
va_start(ap, text);
@@ -307,6 +334,8 @@ void msr_log(modsec_rec *msr, int level, const char *text, ...) {
* Apache error log. This is intended for error callbacks.
*/
void msr_log_error(modsec_rec *msr, const char *text, ...) {
+ assert(msr != NULL);
+ assert(text != NULL);
va_list ap;
va_start(ap, text);
@@ -321,6 +350,8 @@ void msr_log_error(modsec_rec *msr, const char *text, ...) {
* The 'text' will first be escaped.
*/
void msr_log_warn(modsec_rec *msr, const char *text, ...) {
+ assert(msr != NULL);
+ assert(text != NULL);
va_list ap;
va_start(ap, text);
@@ -339,6 +370,7 @@ char *format_error_log_message(apr_pool_t *mp, error_message_t *em) {
if (em == NULL) return NULL;
+#ifndef LOG_NO_FILENAME
if (em->file != NULL) {
s_file = apr_psprintf(mp, "[file \"%s\"] ",
log_escape(mp, (char *)em->file));
@@ -349,6 +381,7 @@ char *format_error_log_message(apr_pool_t *mp, error_message_t *em) {
s_line = apr_psprintf(mp, "[line %d] ", em->line);
if (s_line == NULL) return NULL;
}
+#endif
s_level = apr_psprintf(mp, "[level %d] ", em->level);
if (s_level == NULL) return NULL;
diff --git a/apache2/libinjection/libinjection.h b/apache2/libinjection/libinjection.h
index 11b14ac5f3..6b40b1df6a 100644
--- a/apache2/libinjection/libinjection.h
+++ b/apache2/libinjection/libinjection.h
@@ -1,5 +1,5 @@
/**
- * Copyright 2012, 2013 Nick Galbreath
+ * Copyright 2012-2016 Nick Galbreath
* nickg@client9.com
* BSD License -- see COPYING.txt for details
*
@@ -7,8 +7,8 @@
*
*/
-#ifndef _LIBINJECTION_H
-#define _LIBINJECTION_H
+#ifndef LIBINJECTION_H
+#define LIBINJECTION_H
#ifdef __cplusplus
# define LIBINJECTION_BEGIN_DECLS extern "C" {
@@ -49,9 +49,9 @@ const char* libinjection_version(void);
*/
int libinjection_sqli(const char* s, size_t slen, char fingerprint[]);
-/** ALPHA version of xss detector.
+/** ALPHA version of xss detector.
*
- * NOT DONE.
+ * NOT DONE.
*
* \param[in] s input string, may contain nulls, does not need to be null-terminated
* \param[in] slen input string length
@@ -62,4 +62,4 @@ int libinjection_xss(const char* s, size_t slen);
LIBINJECTION_END_DECLS
-#endif /* _LIBINJECTION_H */
+#endif /* LIBINJECTION_H */
diff --git a/apache2/libinjection/libinjection_html5.c b/apache2/libinjection/libinjection_html5.c
index 38ef9f0f64..a380ca0ad6 100644
--- a/apache2/libinjection/libinjection_html5.c
+++ b/apache2/libinjection/libinjection_html5.c
@@ -71,20 +71,20 @@ void libinjection_h5_init(h5_state_t* hs, const char* s, size_t len, enum html5_
switch (flags) {
case DATA_STATE:
- hs->state = h5_state_data;
- break;
+ hs->state = h5_state_data;
+ break;
case VALUE_NO_QUOTE:
- hs->state = h5_state_before_attribute_name;
- break;
+ hs->state = h5_state_before_attribute_name;
+ break;
case VALUE_SINGLE_QUOTE:
- hs->state = h5_state_attribute_value_single_quote;
- break;
+ hs->state = h5_state_attribute_value_single_quote;
+ break;
case VALUE_DOUBLE_QUOTE:
- hs->state = h5_state_attribute_value_double_quote;
- break;
+ hs->state = h5_state_attribute_value_double_quote;
+ break;
case VALUE_BACK_QUOTE:
- hs->state = h5_state_attribute_value_back_quote;
- break;
+ hs->state = h5_state_attribute_value_back_quote;
+ break;
}
}
@@ -100,10 +100,18 @@ int libinjection_h5_next(h5_state_t* hs)
/**
* Everything below here is private
*
-*/
+ */
+
static int h5_is_white(char ch)
{
+ /*
+ * \t = horizontal tab = 0x09
+ * \n = newline = 0x0A
+ * \v = vertical tab = 0x0B
+ * \f = form feed = 0x0C
+ * \r = cr = 0x0D
+ */
return strchr(" \t\n\v\f\r", ch) != NULL;
}
@@ -112,19 +120,19 @@ static int h5_skip_white(h5_state_t* hs)
char ch;
while (hs->pos < hs->len) {
ch = hs->s[hs->pos];
- switch (ch) {
- case 0x00: /* IE only */
- case 0x20:
- case 0x09:
- case 0x0A:
- case 0x0B: /* IE only */
- case 0x0C:
+ switch (ch) {
+ case 0x00: /* IE only */
+ case 0x20:
+ case 0x09:
+ case 0x0A:
+ case 0x0B: /* IE only */
+ case 0x0C:
case 0x0D: /* IE only */
hs->pos += 1;
- break;
- default:
+ break;
+ default:
return ch;
- }
+ }
}
return CHAR_EOF;
}
@@ -172,6 +180,9 @@ static int h5_state_tag_open(h5_state_t* hs)
char ch;
TRACE();
+ if (hs->pos >= hs->len) {
+ return 0;
+ }
ch = hs->s[hs->pos];
if (ch == CHAR_BANG) {
hs->pos += 1;
@@ -259,12 +270,12 @@ static int h5_state_tag_name(h5_state_t* hs)
pos = hs->pos;
while (pos < hs->len) {
ch = hs->s[pos];
- if (ch == 0) {
- /* special non-standard case */
- /* allow nulls in tag name */
- /* some old browsers apparently allow and ignore them */
- pos += 1;
- } else if (h5_is_white(ch)) {
+ if (ch == 0) {
+ /* special non-standard case */
+ /* allow nulls in tag name */
+ /* some old browsers apparently allow and ignore them */
+ pos += 1;
+ } else if (h5_is_white(ch)) {
hs->token_start = hs->s + hs->pos;
hs->token_len = pos - hs->pos;
hs->token_type = TAG_NAME_OPEN;
@@ -332,7 +343,7 @@ static int h5_state_before_attribute_name(h5_state_t* hs)
default: {
return h5_state_attribute_name(hs);
}
- }
+ }
}
static int h5_state_attribute_name(h5_state_t* hs)
@@ -450,12 +461,12 @@ static int h5_state_attribute_value_quote(h5_state_t* hs, char qchar)
TRACE();
/* skip initial quote in normal case.
- * dont do this is pos == 0 since it means we have started
+ * don't do this "if (pos == 0)" since it means we have started
* in a non-data state. given an input of '>pos > 0) {
- hs->pos += 1;
+ hs->pos += 1;
}
@@ -705,10 +716,13 @@ static int h5_state_comment(h5_state_t* hs)
char ch;
const char* idx;
size_t pos;
+ size_t offset;
+ const char* end = hs->s + hs->len;
TRACE();
pos = hs->pos;
while (1) {
+
idx = (const char*) memchr(hs->s + pos, CHAR_DASH, hs->len - pos);
/* did not find anything or has less than 3 chars left */
@@ -719,21 +733,62 @@ static int h5_state_comment(h5_state_t* hs)
hs->token_type = TAG_COMMENT;
return 1;
}
- ch = *(idx + 1);
+ offset = 1;
+
+ /* skip all nulls */
+ while (idx + offset < end && *(idx + offset) == 0) {
+ offset += 1;
+ }
+ if (idx + offset == end) {
+ hs->state = h5_state_eof;
+ hs->token_start = hs->s + hs->pos;
+ hs->token_len = hs->len - hs->pos;
+ hs->token_type = TAG_COMMENT;
+ return 1;
+ }
+
+ ch = *(idx + offset);
if (ch != CHAR_DASH && ch != CHAR_BANG) {
pos = (size_t)(idx - hs->s) + 1;
continue;
}
- ch = *(idx + 2);
+
+ /* need to test */
+#if 0
+ /* skip all nulls */
+ while (idx + offset < end && *(idx + offset) == 0) {
+ offset += 1;
+ }
+ if (idx + offset == end) {
+ hs->state = h5_state_eof;
+ hs->token_start = hs->s + hs->pos;
+ hs->token_len = hs->len - hs->pos;
+ hs->token_type = TAG_COMMENT;
+ return 1;
+ }
+#endif
+
+ offset += 1;
+ if (idx + offset == end) {
+ hs->state = h5_state_eof;
+ hs->token_start = hs->s + hs->pos;
+ hs->token_len = hs->len - hs->pos;
+ hs->token_type = TAG_COMMENT;
+ return 1;
+ }
+
+
+ ch = *(idx + offset);
if (ch != CHAR_GT) {
pos = (size_t)(idx - hs->s) + 1;
continue;
}
+ offset += 1;
/* ends in --> or -!> */
hs->token_start = hs->s + hs->pos;
hs->token_len = (size_t)(idx - hs->s) - hs->pos;
- hs->pos = (size_t)(idx - hs->s) + 3;
+ hs->pos = (size_t)(idx + offset - hs->s);
hs->state = h5_state_data;
hs->token_type = TAG_COMMENT;
return 1;
diff --git a/apache2/libinjection/libinjection_sqli.c b/apache2/libinjection/libinjection_sqli.c
index 0b67c5cc49..cecbbea3fb 100644
--- a/apache2/libinjection/libinjection_sqli.c
+++ b/apache2/libinjection/libinjection_sqli.c
@@ -1,5 +1,5 @@
/**
- * Copyright 2012,2013 Nick Galbreath
+ * Copyright 2012,2016 Nick Galbreath
* nickg@client9.com
* BSD License -- see COPYING.txt for details
*
@@ -18,7 +18,7 @@
#include "libinjection_sqli.h"
#include "libinjection_sqli_data.h"
-#define LIBINJECTION_VERSION "3.9.1"
+#define LIBINJECTION_VERSION "3.9.2"
#define LIBINJECTION_SQLI_TOKEN_SIZE sizeof(((stoken_t*)(0))->val)
#define LIBINJECTION_SQLI_MAX_TOKENS 5
@@ -112,15 +112,11 @@ memchr2(const char *haystack, size_t haystack_len, char c0, char c1)
}
while (cur < last) {
- if (cur[0] == c0) {
- if (cur[1] == c1) {
- return cur;
- } else {
- cur += 2; /* (c0 == c1) ? 1 : 2; */
- }
- } else {
- cur += 1;
+ /* safe since cur < len - 1 always */
+ if (cur[0] == c0 && cur[1] == c1) {
+ return cur;
}
+ cur += 1;
}
return NULL;
@@ -191,11 +187,11 @@ static int char_is_white(char ch) {
/* ' ' space is 0x32
'\t 0x09 \011 horizontal tab
'\n' 0x0a \012 new line
- '\v' 0x0b \013 verical tab
+ '\v' 0x0b \013 vertical tab
'\f' 0x0c \014 new page
'\r' 0x0d \015 carriage return
0x00 \000 null (oracle)
- 0xa0 \240 is latin1
+ 0xa0 \240 is Latin-1
*/
return strchr(" \t\n\v\f\r\240\000", ch) != NULL;
}
@@ -294,7 +290,7 @@ static void st_clear(stoken_t * st)
static void st_assign_char(stoken_t * st, const char stype, size_t pos, size_t len,
const char value)
{
- /* done to elimiate unused warning */
+ /* done to eliminate unused warning */
(void)len;
st->type = (char) stype;
st->pos = pos;
@@ -402,7 +398,7 @@ static size_t parse_eol_comment(struct libinjection_sqli_state * sf)
}
}
-/** In Ansi mode, hash is an operator
+/** In ANSI mode, hash is an operator
* In MYSQL mode, it's a EOL comment like '--'
*/
static size_t parse_hash(struct libinjection_sqli_state * sf)
@@ -842,7 +838,7 @@ static size_t parse_bstring(struct libinjection_sqli_state *sf)
/*
* hex literal string
- * re: [XX]'[0123456789abcdefABCDEF]*'
+ * re: [xX]'[0123456789abcdefABCDEF]*'
* mysql has requirement of having EVEN number of chars,
* but pgsql does not
*/
@@ -1072,7 +1068,7 @@ static size_t parse_money(struct libinjection_sqli_state *sf)
/* we have $foobar$ ... find it again */
strend = my_memmem(cs+xlen+2, slen - (pos+xlen+2), cs + pos, xlen+2);
- if (strend == NULL) {
+ if (strend == NULL || ((size_t)(strend - cs) < (pos+xlen+2))) {
/* fell off edge */
st_assign(sf->current, TYPE_STRING, pos+xlen+2, slen - pos - xlen - 2, cs+pos+xlen+2);
sf->current->str_open = '$';
@@ -1104,7 +1100,6 @@ static size_t parse_number(struct libinjection_sqli_state * sf)
const char *cs = sf->s;
const size_t slen = sf->slen;
size_t pos = sf->pos;
- int have_dot = 0;
int have_e = 0;
int have_exp = 0;
@@ -1136,7 +1131,6 @@ static size_t parse_number(struct libinjection_sqli_state * sf)
}
if (pos < slen && cs[pos] == '.') {
- have_dot = 1;
pos += 1;
while (pos < slen && ISDIGIT(cs[pos])) {
pos += 1;
@@ -1185,7 +1179,7 @@ static size_t parse_number(struct libinjection_sqli_state * sf)
}
}
- if (have_dot == 1 && have_e == 1 && have_exp == 0) {
+ if (have_e == 1 && have_exp == 0) {
/* very special form of
* "1234.e"
* "10.10E"
@@ -1242,29 +1236,13 @@ int libinjection_sqli_tokenize(struct libinjection_sqli_state * sf)
const unsigned char ch = (unsigned char) (s[*pos]);
/*
- * if not ascii, then continue...
- * actually probably need to just assuming
- * it's a string
+ * look up the parser, and call it
+ *
+ * Porting Note: this is mapping of char to function
+ * charparsers[ch]()
*/
- if (ch > 127) {
+ fnptr = char_parse_map[ch];
- /* 160 or 0xA0 or octal 240 is "latin1 non-breaking space"
- * but is treated as a space in mysql.
- */
- if (ch == 160) {
- fnptr = parse_white;
- } else {
- fnptr = parse_word;
- }
- } else {
- /*
- * look up the parser, and call it
- *
- * Porting Note: this is mapping of char to function
- * charparsers[ch]()
- */
- fnptr = char_parse_map[ch];
- }
*pos = (*fnptr) (sf);
/*
@@ -1349,16 +1327,22 @@ static int syntax_merge_words(struct libinjection_sqli_state * sf,stoken_t * a,
a->type == TYPE_UNION ||
a->type == TYPE_FUNCTION ||
a->type == TYPE_EXPRESSION ||
+ a->type == TYPE_TSQL ||
a->type == TYPE_SQLTYPE)) {
- return CHAR_NULL;
+ return FALSE;
}
- if (b->type != TYPE_KEYWORD && b->type != TYPE_BAREWORD &&
- b->type != TYPE_OPERATOR && b->type != TYPE_SQLTYPE &&
- b->type != TYPE_LOGIC_OPERATOR &&
- b->type != TYPE_FUNCTION &&
- b->type != TYPE_UNION && b->type != TYPE_EXPRESSION) {
- return CHAR_NULL;
+ if (!
+ (b->type == TYPE_KEYWORD ||
+ b->type == TYPE_BAREWORD ||
+ b->type == TYPE_OPERATOR ||
+ b->type == TYPE_UNION ||
+ b->type == TYPE_FUNCTION ||
+ b->type == TYPE_EXPRESSION ||
+ b->type == TYPE_TSQL ||
+ b->type == TYPE_SQLTYPE ||
+ b->type == TYPE_LOGIC_OPERATOR)) {
+ return FALSE;
}
sz1 = a->len;
@@ -1374,7 +1358,6 @@ static int syntax_merge_words(struct libinjection_sqli_state * sf,stoken_t * a,
tmp[sz1] = ' ';
memcpy(tmp + sz1 + 1, b->val, sz2);
tmp[sz3] = CHAR_NULL;
-
ch = sf->lookup(sf, LOOKUP_WORD, tmp, sz3);
if (ch != CHAR_NULL) {
@@ -1450,6 +1433,13 @@ int libinjection_sqli_fold(struct libinjection_sqli_state * sf)
sf->tokenvec[2].type == TYPE_COMMA &&
sf->tokenvec[3].type == TYPE_LEFTPARENS &&
sf->tokenvec[4].type == TYPE_NUMBER
+ ) ||
+ (
+ sf->tokenvec[0].type == TYPE_BAREWORD &&
+ sf->tokenvec[1].type == TYPE_RIGHTPARENS &&
+ sf->tokenvec[2].type == TYPE_OPERATOR &&
+ sf->tokenvec[3].type == TYPE_LEFTPARENS &&
+ sf->tokenvec[4].type == TYPE_BAREWORD
)
)
{
@@ -1506,16 +1496,6 @@ int libinjection_sqli_fold(struct libinjection_sqli_state * sf)
pos -= 1;
sf->stats_folds += 1;
continue;
- } else if (sf->tokenvec[left].type == TYPE_SEMICOLON &&
- sf->tokenvec[left+1].type == TYPE_FUNCTION &&
- cstrcasecmp("IF", sf->tokenvec[left+1].val, sf->tokenvec[left+1].len) == 0) {
- /* IF is normally a function, except in Transact-SQL where it can be used as a
- * standalone control flow operator, e.g. ; IF 1=1 ...
- * if found after a semicolon, convert from 'f' type to 'T' type
- */
- sf->tokenvec[left+1].type = TYPE_TSQL;
- left += 2;
- continue; /* reparse everything, but we probably can advance left, and pos */
} else if ((sf->tokenvec[left].type == TYPE_OPERATOR ||
sf->tokenvec[left].type == TYPE_LOGIC_OPERATOR) &&
(st_is_unary_op(&sf->tokenvec[left+1]) ||
@@ -1539,9 +1519,22 @@ int libinjection_sqli_fold(struct libinjection_sqli_state * sf)
left -= 1;
}
continue;
+ } else if (sf->tokenvec[left].type == TYPE_SEMICOLON &&
+ sf->tokenvec[left+1].type == TYPE_FUNCTION &&
+ (sf->tokenvec[left+1].val[0] == 'I' ||
+ sf->tokenvec[left+1].val[0] == 'i' ) &&
+ (sf->tokenvec[left+1].val[1] == 'F' ||
+ sf->tokenvec[left+1].val[1] == 'f' )) {
+ /* IF is normally a function, except in Transact-SQL where it can be used as a
+ * standalone control flow operator, e.g. ; IF 1=1 ...
+ * if found after a semicolon, convert from 'f' type to 'T' type
+ */
+ sf->tokenvec[left+1].type = TYPE_TSQL;
+ /* left += 2; */
+ continue; /* reparse everything, but we probably can advance left, and pos */
} else if ((sf->tokenvec[left].type == TYPE_BAREWORD || sf->tokenvec[left].type == TYPE_VARIABLE) &&
sf->tokenvec[left+1].type == TYPE_LEFTPARENS && (
- /* TSQL functions but common enough to be collumn names */
+ /* TSQL functions but common enough to be column names */
cstrcasecmp("USER_ID", sf->tokenvec[left].val, sf->tokenvec[left].len) == 0 ||
cstrcasecmp("USER_NAME", sf->tokenvec[left].val, sf->tokenvec[left].len) == 0 ||
@@ -1564,7 +1557,7 @@ int libinjection_sqli_fold(struct libinjection_sqli_state * sf)
/* pos is the same
* other conversions need to go here... for instance
- * password CAN be a function, coalese CAN be a function
+ * password CAN be a function, coalesce CAN be a function
*/
sf->tokenvec[left].type = TYPE_FUNCTION;
continue;
@@ -1828,7 +1821,7 @@ int libinjection_sqli_fold(struct libinjection_sqli_state * sf)
* 1,-sin(1) --> 1 (1)
* Here, just do
* 1,-sin(1) --> 1,sin(1)
- * just remove unary opartor
+ * just remove unary operator
*/
st_copy(&sf->tokenvec[left+1], &sf->tokenvec[left+2]);
pos -= 1;
@@ -1852,9 +1845,21 @@ int libinjection_sqli_fold(struct libinjection_sqli_state * sf)
pos -= 1;
left = 0;
continue;
+ } else if ((sf->tokenvec[left].type == TYPE_FUNCTION) &&
+ (sf->tokenvec[left+1].type == TYPE_LEFTPARENS) &&
+ (sf->tokenvec[left+2].type != TYPE_RIGHTPARENS)) {
+ /*
+ * whats going on here
+ * Some SQL functions like USER() have 0 args
+ * if we get User(foo), then User is not a function
+ * This should be expanded since it eliminated a lot of false
+ * positives.
+ */
+ if (cstrcasecmp("USER", sf->tokenvec[left].val, sf->tokenvec[left].len) == 0) {
+ sf->tokenvec[left].type = TYPE_BAREWORD;
+ }
}
-
/* no folding -- assume left-most token is
is good, now use the existing 2 tokens --
do not get another
@@ -2019,7 +2024,7 @@ int libinjection_sqli_blacklist(struct libinjection_sqli_state* sql_state)
}
/*
- * return TRUE if sqli, false is benign
+ * return TRUE if SQLi, false is benign
*/
int libinjection_sqli_not_whitelist(struct libinjection_sqli_state* sql_state)
{
@@ -2033,10 +2038,10 @@ int libinjection_sqli_not_whitelist(struct libinjection_sqli_state* sql_state)
if (tlen > 1 && sql_state->fingerprint[tlen-1] == TYPE_COMMENT) {
/*
- * if ending comment is contains 'sp_password' then it's sqli!
+ * if ending comment is contains 'sp_password' then it's SQLi!
* MS Audit log apparently ignores anything with
- * 'sp_password' in it. Unable to find primary refernece to
- * this "feature" of SQL Server but seems to be known sqli
+ * 'sp_password' in it. Unable to find primary reference to
+ * this "feature" of SQL Server but seems to be known SQLi
* technique
*/
if (my_memmem(sql_state->s, sql_state->slen,
@@ -2055,7 +2060,7 @@ int libinjection_sqli_not_whitelist(struct libinjection_sqli_state* sql_state)
if (sql_state->fingerprint[1] == TYPE_UNION) {
if (sql_state->stats_tokens == 2) {
- /* not sure why but 1U comes up in Sqli attack
+ /* not sure why but 1U comes up in SQLi attack
* likely part of parameter splitting/etc.
* lots of reasons why "1 union" might be normal
* input, so beep only if other SQLi things are present
@@ -2080,7 +2085,7 @@ int libinjection_sqli_not_whitelist(struct libinjection_sqli_state* sql_state)
/*
* for fingerprint like 'nc', only comments of /x are treated
- * as SQL... ending comments of "--" and "#" are not sqli
+ * as SQL... ending comments of "--" and "#" are not SQLi
*/
if (sql_state->tokenvec[0].type == TYPE_BAREWORD &&
sql_state->tokenvec[1].type == TYPE_COMMENT &&
@@ -2090,7 +2095,7 @@ int libinjection_sqli_not_whitelist(struct libinjection_sqli_state* sql_state)
}
/*
- * if '1c' ends with '/x' then it's sqli
+ * if '1c' ends with '/x' then it's SQLi
*/
if (sql_state->tokenvec[0].type == TYPE_NUMBER &&
sql_state->tokenvec[1].type == TYPE_COMMENT &&
@@ -2113,13 +2118,13 @@ int libinjection_sqli_not_whitelist(struct libinjection_sqli_state* sql_state)
if (sql_state->tokenvec[0].type == TYPE_NUMBER &&
sql_state->tokenvec[1].type == TYPE_COMMENT) {
if (sql_state->stats_tokens > 2) {
- /* we have some folding going on, highly likely sqli */
+ /* we have some folding going on, highly likely SQLi */
sql_state->reason = __LINE__;
return TRUE;
}
/*
* we check that next character after the number is either whitespace,
- * or '/' or a '-' ==> sqli.
+ * or '/' or a '-' ==> SQLi.
*/
ch = sql_state->s[sql_state->tokenvec[0].len];
if ( ch <= 32 ) {
@@ -2141,7 +2146,7 @@ int libinjection_sqli_not_whitelist(struct libinjection_sqli_state* sql_state)
}
/*
- * detect obvious sqli scans.. many people put '--' in plain text
+ * detect obvious SQLi scans.. many people put '--' in plain text
* so only detect if input ends with '--', e.g. 1-- but not 1-- foo
*/
if ((sql_state->tokenvec[1].len > 2)
@@ -2177,7 +2182,7 @@ int libinjection_sqli_not_whitelist(struct libinjection_sqli_state* sql_state)
}
/*
- * not sqli
+ * not SQLi
*/
sql_state->reason = __LINE__;
return FALSE;
@@ -2186,8 +2191,8 @@ int libinjection_sqli_not_whitelist(struct libinjection_sqli_state* sql_state)
streq(sql_state->fingerprint, "1&1") ||
streq(sql_state->fingerprint, "1&v") ||
streq(sql_state->fingerprint, "1&s")) {
- /* 'sexy and 17' not sqli
- * 'sexy and 17<18' sqli
+ /* 'sexy and 17' not SQLi
+ * 'sexy and 17<18' SQLi
*/
if (sql_state->stats_tokens == 3) {
sql_state->reason = __LINE__;
@@ -2243,7 +2248,7 @@ int libinjection_is_sqli(struct libinjection_sqli_state * sql_state)
size_t slen = sql_state->slen;
/*
- * no input? not sqli
+ * no input? not SQLi
*/
if (slen == 0) {
return FALSE;
diff --git a/apache2/libinjection/libinjection_sqli.h b/apache2/libinjection/libinjection_sqli.h
index 4f16db8dbf..b9746555a7 100644
--- a/apache2/libinjection/libinjection_sqli.h
+++ b/apache2/libinjection/libinjection_sqli.h
@@ -1,14 +1,14 @@
/**
- * Copyright 2012, 2013 Nick Galbreath
+ * Copyright 2012-2016 Nick Galbreath
* nickg@client9.com
- * BSD License -- see COPYING.txt for details
+ * BSD License -- see `COPYING.txt` for details
*
* https://libinjection.client9.com/
*
*/
-#ifndef _LIBINJECTION_SQLI_H
-#define _LIBINJECTION_SQLI_H
+#ifndef LIBINJECTION_SQLI_H
+#define LIBINJECTION_SQLI_H
#ifdef __cplusplus
extern "C" {
@@ -40,10 +40,6 @@ struct libinjection_sqli_token {
#ifdef SWIG
%immutable;
#endif
- char type;
- char str_open;
- char str_close;
-
/*
* position and length of token
* in original string
@@ -53,17 +49,20 @@ struct libinjection_sqli_token {
/* count:
* in type 'v', used for number of opening '@'
- * but maybe unsed in other contexts
+ * but maybe used in other contexts
*/
int count;
+ char type;
+ char str_open;
+ char str_close;
char val[32];
};
typedef struct libinjection_sqli_token stoken_t;
/**
- * Pointer to function, takes cstr input,
+ * Pointer to function, takes c-string input,
* returns '\0' for no match, else a char
*/
struct libinjection_sqli_state;
@@ -97,7 +96,7 @@ struct libinjection_sqli_state {
int flags;
/*
- * pos is index in string we are at when tokenizing
+ * pos is the index in the string during tokenization
*/
size_t pos;
@@ -118,7 +117,7 @@ struct libinjection_sqli_state {
/*
* fingerprint pattern c-string
* +1 for ending null
- * Mimimum of 8 bytes to add gcc's -fstack-protector to work
+ * Minimum of 8 bytes to add gcc's -fstack-protector to work
*/
char fingerprint[8];
@@ -156,7 +155,7 @@ struct libinjection_sqli_state {
*/
int stats_comment_c;
- /* '#' operators or mysql EOL comments found
+ /* '#' operators or MySQL EOL comments found
*
*/
int stats_comment_hash;
@@ -208,8 +207,8 @@ void libinjection_sqli_init(struct libinjection_sqli_state* sql_state,
*/
int libinjection_is_sqli(struct libinjection_sqli_state* sql_state);
-/* FOR H@CKERS ONLY
- *
+/* FOR HACKERS ONLY
+ * provides deep hooks into the decision making process
*/
void libinjection_sqli_callback(struct libinjection_sqli_state* sql_state,
ptr_lookup_fn fn,
@@ -269,7 +268,7 @@ int libinjection_sqli_fold(struct libinjection_sqli_state * sql_state);
* two functions. With this, you over-ride one part or the other.
*
* return libinjection_sqli_blacklist(sql_state) &&
- * libinject_sqli_not_whitelist(sql_state);
+ * libinjection_sqli_not_whitelist(sql_state);
*
* \param sql_state should be filled out after libinjection_sqli_fingerprint is called
*/
@@ -284,7 +283,7 @@ int libinjection_sqli_blacklist(struct libinjection_sqli_state* sql_state);
/* Given a positive match for a pattern (i.e. pattern is SQLi), this function
* does additional analysis to reduce false positives.
*
- * \return TRUE if sqli, false otherwise
+ * \return TRUE if SQLi, false otherwise
*/
int libinjection_sqli_not_whitelist(struct libinjection_sqli_state * sql_state);
@@ -292,4 +291,4 @@ int libinjection_sqli_not_whitelist(struct libinjection_sqli_state * sql_state);
}
#endif
-#endif /* _LIBINJECTION_SQLI_H */
+#endif /* LIBINJECTION_SQLI_H */
diff --git a/apache2/libinjection/libinjection_sqli_data.h b/apache2/libinjection/libinjection_sqli_data.h
index 8f3a2e0e23..f5e1454143 100644
--- a/apache2/libinjection/libinjection_sqli_data.h
+++ b/apache2/libinjection/libinjection_sqli_data.h
@@ -1,6 +1,6 @@
-#ifndef _LIBINJECTION_SQLI_DATA_H
-#define _LIBINJECTION_SQLI_DATA_H
+#ifndef LIBINJECTION_SQLI_DATA_H
+#define LIBINJECTION_SQLI_DATA_H
#include "libinjection.h"
#include "libinjection_sqli.h"
@@ -164,6 +164,134 @@ static const pt2Function char_parse_map[] = {
&parse_char, /* 125 */
&parse_operator1, /* 126 */
&parse_white, /* 127 */
+ &parse_word, /* 128 */
+ &parse_word, /* 129 */
+ &parse_word, /* 130 */
+ &parse_word, /* 131 */
+ &parse_word, /* 132 */
+ &parse_word, /* 133 */
+ &parse_word, /* 134 */
+ &parse_word, /* 135 */
+ &parse_word, /* 136 */
+ &parse_word, /* 137 */
+ &parse_word, /* 138 */
+ &parse_word, /* 139 */
+ &parse_word, /* 140 */
+ &parse_word, /* 141 */
+ &parse_word, /* 142 */
+ &parse_word, /* 143 */
+ &parse_word, /* 144 */
+ &parse_word, /* 145 */
+ &parse_word, /* 146 */
+ &parse_word, /* 147 */
+ &parse_word, /* 148 */
+ &parse_word, /* 149 */
+ &parse_word, /* 150 */
+ &parse_word, /* 151 */
+ &parse_word, /* 152 */
+ &parse_word, /* 153 */
+ &parse_word, /* 154 */
+ &parse_word, /* 155 */
+ &parse_word, /* 156 */
+ &parse_word, /* 157 */
+ &parse_word, /* 158 */
+ &parse_word, /* 159 */
+ &parse_white, /* 160 */
+ &parse_word, /* 161 */
+ &parse_word, /* 162 */
+ &parse_word, /* 163 */
+ &parse_word, /* 164 */
+ &parse_word, /* 165 */
+ &parse_word, /* 166 */
+ &parse_word, /* 167 */
+ &parse_word, /* 168 */
+ &parse_word, /* 169 */
+ &parse_word, /* 170 */
+ &parse_word, /* 171 */
+ &parse_word, /* 172 */
+ &parse_word, /* 173 */
+ &parse_word, /* 174 */
+ &parse_word, /* 175 */
+ &parse_word, /* 176 */
+ &parse_word, /* 177 */
+ &parse_word, /* 178 */
+ &parse_word, /* 179 */
+ &parse_word, /* 180 */
+ &parse_word, /* 181 */
+ &parse_word, /* 182 */
+ &parse_word, /* 183 */
+ &parse_word, /* 184 */
+ &parse_word, /* 185 */
+ &parse_word, /* 186 */
+ &parse_word, /* 187 */
+ &parse_word, /* 188 */
+ &parse_word, /* 189 */
+ &parse_word, /* 190 */
+ &parse_word, /* 191 */
+ &parse_word, /* 192 */
+ &parse_word, /* 193 */
+ &parse_word, /* 194 */
+ &parse_word, /* 195 */
+ &parse_word, /* 196 */
+ &parse_word, /* 197 */
+ &parse_word, /* 198 */
+ &parse_word, /* 199 */
+ &parse_word, /* 200 */
+ &parse_word, /* 201 */
+ &parse_word, /* 202 */
+ &parse_word, /* 203 */
+ &parse_word, /* 204 */
+ &parse_word, /* 205 */
+ &parse_word, /* 206 */
+ &parse_word, /* 207 */
+ &parse_word, /* 208 */
+ &parse_word, /* 209 */
+ &parse_word, /* 210 */
+ &parse_word, /* 211 */
+ &parse_word, /* 212 */
+ &parse_word, /* 213 */
+ &parse_word, /* 214 */
+ &parse_word, /* 215 */
+ &parse_word, /* 216 */
+ &parse_word, /* 217 */
+ &parse_word, /* 218 */
+ &parse_word, /* 219 */
+ &parse_word, /* 220 */
+ &parse_word, /* 221 */
+ &parse_word, /* 222 */
+ &parse_word, /* 223 */
+ &parse_word, /* 224 */
+ &parse_word, /* 225 */
+ &parse_word, /* 226 */
+ &parse_word, /* 227 */
+ &parse_word, /* 228 */
+ &parse_word, /* 229 */
+ &parse_word, /* 230 */
+ &parse_word, /* 231 */
+ &parse_word, /* 232 */
+ &parse_word, /* 233 */
+ &parse_word, /* 234 */
+ &parse_word, /* 235 */
+ &parse_word, /* 236 */
+ &parse_word, /* 237 */
+ &parse_word, /* 238 */
+ &parse_word, /* 239 */
+ &parse_word, /* 240 */
+ &parse_word, /* 241 */
+ &parse_word, /* 242 */
+ &parse_word, /* 243 */
+ &parse_word, /* 244 */
+ &parse_word, /* 245 */
+ &parse_word, /* 246 */
+ &parse_word, /* 247 */
+ &parse_word, /* 248 */
+ &parse_word, /* 249 */
+ &parse_word, /* 250 */
+ &parse_word, /* 251 */
+ &parse_word, /* 252 */
+ &parse_word, /* 253 */
+ &parse_word, /* 254 */
+ &parse_word, /* 255 */
};
static const keyword_t sql_keywords[] = {
@@ -317,6 +445,8 @@ static const keyword_t sql_keywords[] = {
{"0&VUEN", 'F'},
{"0&VUES", 'F'},
{"0&VUEV", 'F'},
+ {"0)&(EK", 'F'},
+ {"0)&(EN", 'F'},
{"0)UE(1", 'F'},
{"0)UE(F", 'F'},
{"0)UE(N", 'F'},
@@ -395,7 +525,6 @@ static const keyword_t sql_keywords[] = {
{"01&1KV", 'F'},
{"01&1O(", 'F'},
{"01&1OF", 'F'},
- {"01&1OO", 'F'},
{"01&1OS", 'F'},
{"01&1OV", 'F'},
{"01&1TN", 'F'},
@@ -458,6 +587,7 @@ static const keyword_t sql_keywords[] = {
{"01&K(S", 'F'},
{"01&K(V", 'F'},
{"01&K1O", 'F'},
+ {"01&KC", 'F'},
{"01&KF(", 'F'},
{"01&KNK", 'F'},
{"01&KO(", 'F'},
@@ -522,7 +652,6 @@ static const keyword_t sql_keywords[] = {
{"01&S1", 'F'},
{"01&S1;", 'F'},
{"01&S1C", 'F'},
- {"01&S1O", 'F'},
{"01&S;", 'F'},
{"01&S;C", 'F'},
{"01&S;E", 'F'},
@@ -547,7 +676,6 @@ static const keyword_t sql_keywords[] = {
{"01&SO1", 'F'},
{"01&SOF", 'F'},
{"01&SON", 'F'},
- {"01&SOO", 'F'},
{"01&SOS", 'F'},
{"01&SOV", 'F'},
{"01&STN", 'F'},
@@ -593,7 +721,6 @@ static const keyword_t sql_keywords[] = {
{"01&VKV", 'F'},
{"01&VO(", 'F'},
{"01&VOF", 'F'},
- {"01&VOO", 'F'},
{"01&VOS", 'F'},
{"01&VS", 'F'},
{"01&VS;", 'F'},
@@ -730,6 +857,7 @@ static const keyword_t sql_keywords[] = {
{"01)ESO", 'F'},
{"01)EVC", 'F'},
{"01)EVO", 'F'},
+ {"01)F(F", 'F'},
{"01)K(1", 'F'},
{"01)K(F", 'F'},
{"01)K(N", 'F'},
@@ -751,6 +879,7 @@ static const keyword_t sql_keywords[] = {
{"01)KN&", 'F'},
{"01)KN;", 'F'},
{"01)KNB", 'F'},
+ {"01)KNC", 'F'},
{"01)KNE", 'F'},
{"01)KNK", 'F'},
{"01)KNU", 'F'},
@@ -877,11 +1006,13 @@ static const keyword_t sql_keywords[] = {
{"01;EVT", 'F'},
{"01;N:T", 'F'},
{"01;T(1", 'F'},
+ {"01;T(C", 'F'},
{"01;T(E", 'F'},
{"01;T(F", 'F'},
{"01;T(N", 'F'},
{"01;T(S", 'F'},
{"01;T(V", 'F'},
+ {"01;T1(", 'F'},
{"01;T1,", 'F'},
{"01;T1;", 'F'},
{"01;T1C", 'F'},
@@ -913,6 +1044,7 @@ static const keyword_t sql_keywords[] = {
{"01;TNT", 'F'},
{"01;TNV", 'F'},
{"01;TO(", 'F'},
+ {"01;TS(", 'F'},
{"01;TS,", 'F'},
{"01;TS;", 'F'},
{"01;TSC", 'F'},
@@ -920,12 +1052,8 @@ static const keyword_t sql_keywords[] = {
{"01;TSK", 'F'},
{"01;TSO", 'F'},
{"01;TST", 'F'},
- {"01;TT(", 'F'},
- {"01;TT1", 'F'},
- {"01;TTF", 'F'},
{"01;TTN", 'F'},
- {"01;TTS", 'F'},
- {"01;TTV", 'F'},
+ {"01;TV(", 'F'},
{"01;TV,", 'F'},
{"01;TV;", 'F'},
{"01;TVC", 'F'},
@@ -967,7 +1095,6 @@ static const keyword_t sql_keywords[] = {
{"01B(1)", 'F'},
{"01B(1O", 'F'},
{"01B(F(", 'F'},
- {"01B(N)", 'F'},
{"01B(NO", 'F'},
{"01B(S)", 'F'},
{"01B(SO", 'F'},
@@ -1116,11 +1243,18 @@ static const keyword_t sql_keywords[] = {
{"01E(SO", 'F'},
{"01E(V)", 'F'},
{"01E(VO", 'F'},
+ {"01E1;T", 'F'},
{"01E1C", 'F'},
{"01E1O(", 'F'},
{"01E1OF", 'F'},
{"01E1OS", 'F'},
{"01E1OV", 'F'},
+ {"01E1T(", 'F'},
+ {"01E1T1", 'F'},
+ {"01E1TF", 'F'},
+ {"01E1TN", 'F'},
+ {"01E1TS", 'F'},
+ {"01E1TV", 'F'},
{"01E1UE", 'F'},
{"01EF()", 'F'},
{"01EF(1", 'F'},
@@ -1134,35 +1268,50 @@ static const keyword_t sql_keywords[] = {
{"01EK(N", 'F'},
{"01EK(S", 'F'},
{"01EK(V", 'F'},
+ {"01EK1;", 'F'},
{"01EK1C", 'F'},
{"01EK1O", 'F'},
+ {"01EK1T", 'F'},
{"01EK1U", 'F'},
{"01EKF(", 'F'},
+ {"01EKN;", 'F'},
{"01EKNC", 'F'},
{"01EKNE", 'F'},
+ {"01EKNT", 'F'},
{"01EKNU", 'F'},
{"01EKOK", 'F'},
+ {"01EKS;", 'F'},
{"01EKSC", 'F'},
{"01EKSO", 'F'},
+ {"01EKST", 'F'},
{"01EKSU", 'F'},
{"01EKU(", 'F'},
{"01EKU1", 'F'},
{"01EKUE", 'F'},
{"01EKUF", 'F'},
- {"01EKUN", 'F'},
{"01EKUS", 'F'},
{"01EKUV", 'F'},
+ {"01EKV;", 'F'},
{"01EKVC", 'F'},
{"01EKVO", 'F'},
+ {"01EKVT", 'F'},
{"01EKVU", 'F'},
+ {"01EN;T", 'F'},
{"01ENC", 'F'},
{"01ENEN", 'F'},
{"01ENO(", 'F'},
{"01ENOF", 'F'},
{"01ENOS", 'F'},
{"01ENOV", 'F'},
+ {"01ENT(", 'F'},
+ {"01ENT1", 'F'},
+ {"01ENTF", 'F'},
+ {"01ENTN", 'F'},
+ {"01ENTS", 'F'},
+ {"01ENTV", 'F'},
{"01ENUE", 'F'},
{"01EOKN", 'F'},
+ {"01ES;T", 'F'},
{"01ESC", 'F'},
{"01ESO(", 'F'},
{"01ESO1", 'F'},
@@ -1170,6 +1319,12 @@ static const keyword_t sql_keywords[] = {
{"01ESON", 'F'},
{"01ESOS", 'F'},
{"01ESOV", 'F'},
+ {"01EST(", 'F'},
+ {"01EST1", 'F'},
+ {"01ESTF", 'F'},
+ {"01ESTN", 'F'},
+ {"01ESTS", 'F'},
+ {"01ESTV", 'F'},
{"01ESUE", 'F'},
{"01EU(1", 'F'},
{"01EU(F", 'F'},
@@ -1182,19 +1337,23 @@ static const keyword_t sql_keywords[] = {
{"01EUEF", 'F'},
{"01EUEK", 'F'},
{"01EUF(", 'F'},
- {"01EUN,", 'F'},
- {"01EUNC", 'F'},
- {"01EUNO", 'F'},
{"01EUS,", 'F'},
{"01EUSC", 'F'},
{"01EUSO", 'F'},
{"01EUV,", 'F'},
{"01EUVC", 'F'},
{"01EUVO", 'F'},
+ {"01EV;T", 'F'},
{"01EVC", 'F'},
{"01EVO(", 'F'},
{"01EVOF", 'F'},
{"01EVOS", 'F'},
+ {"01EVT(", 'F'},
+ {"01EVT1", 'F'},
+ {"01EVTF", 'F'},
+ {"01EVTN", 'F'},
+ {"01EVTS", 'F'},
+ {"01EVTV", 'F'},
{"01EVUE", 'F'},
{"01F()1", 'F'},
{"01F()F", 'F'},
@@ -1251,6 +1410,8 @@ static const keyword_t sql_keywords[] = {
{"01K)EN", 'F'},
{"01K)ES", 'F'},
{"01K)EV", 'F'},
+ {"01K)F(", 'F'},
+ {"01K)O(", 'F'},
{"01K)OF", 'F'},
{"01K)UE", 'F'},
{"01K1", 'F'},
@@ -1387,7 +1548,6 @@ static const keyword_t sql_keywords[] = {
{"01KVU(", 'F'},
{"01KVUE", 'F'},
{"01N&F(", 'F'},
- {"01N(1)", 'F'},
{"01N(1O", 'F'},
{"01N(F(", 'F'},
{"01N(S)", 'F'},
@@ -1410,12 +1570,6 @@ static const keyword_t sql_keywords[] = {
{"01NESO", 'F'},
{"01NEVC", 'F'},
{"01NEVO", 'F'},
- {"01NF()", 'F'},
- {"01NF(1", 'F'},
- {"01NF(F", 'F'},
- {"01NF(N", 'F'},
- {"01NF(S", 'F'},
- {"01NF(V", 'F'},
{"01NU(E", 'F'},
{"01NUE", 'F'},
{"01NUE(", 'F'},
@@ -1437,6 +1591,7 @@ static const keyword_t sql_keywords[] = {
{"01O(EF", 'F'},
{"01O(EK", 'F'},
{"01O(EN", 'F'},
+ {"01O(EO", 'F'},
{"01O(ES", 'F'},
{"01O(EV", 'F'},
{"01O(F(", 'F'},
@@ -1502,6 +1657,7 @@ static const keyword_t sql_keywords[] = {
{"01OS)B", 'F'},
{"01OS)C", 'F'},
{"01OS)E", 'F'},
+ {"01OS)F", 'F'},
{"01OS)K", 'F'},
{"01OS)O", 'F'},
{"01OS)U", 'F'},
@@ -1550,6 +1706,14 @@ static const keyword_t sql_keywords[] = {
{"01OSKS", 'F'},
{"01OSKU", 'F'},
{"01OSKV", 'F'},
+ {"01OST(", 'F'},
+ {"01OST1", 'F'},
+ {"01OSTE", 'F'},
+ {"01OSTF", 'F'},
+ {"01OSTN", 'F'},
+ {"01OSTS", 'F'},
+ {"01OSTT", 'F'},
+ {"01OSTV", 'F'},
{"01OSU", 'F'},
{"01OSU(", 'F'},
{"01OSU1", 'F'},
@@ -1558,7 +1722,6 @@ static const keyword_t sql_keywords[] = {
{"01OSUE", 'F'},
{"01OSUF", 'F'},
{"01OSUK", 'F'},
- {"01OSUN", 'F'},
{"01OSUO", 'F'},
{"01OSUS", 'F'},
{"01OSUT", 'F'},
@@ -1589,6 +1752,7 @@ static const keyword_t sql_keywords[] = {
{"01OV)B", 'F'},
{"01OV)C", 'F'},
{"01OV)E", 'F'},
+ {"01OV)F", 'F'},
{"01OV)K", 'F'},
{"01OV)O", 'F'},
{"01OV)U", 'F'},
@@ -1642,6 +1806,14 @@ static const keyword_t sql_keywords[] = {
{"01OVSO", 'F'},
{"01OVSU", 'F'},
{"01OVSV", 'F'},
+ {"01OVT(", 'F'},
+ {"01OVT1", 'F'},
+ {"01OVTE", 'F'},
+ {"01OVTF", 'F'},
+ {"01OVTN", 'F'},
+ {"01OVTS", 'F'},
+ {"01OVTT", 'F'},
+ {"01OVTV", 'F'},
{"01OVU", 'F'},
{"01OVU(", 'F'},
{"01OVU1", 'F'},
@@ -1650,7 +1822,6 @@ static const keyword_t sql_keywords[] = {
{"01OVUE", 'F'},
{"01OVUF", 'F'},
{"01OVUK", 'F'},
- {"01OVUN", 'F'},
{"01OVUO", 'F'},
{"01OVUS", 'F'},
{"01OVUT", 'F'},
@@ -1672,6 +1843,96 @@ static const keyword_t sql_keywords[] = {
{"01SVO(", 'F'},
{"01SVOF", 'F'},
{"01SVOS", 'F'},
+ {"01T(1)", 'F'},
+ {"01T(1O", 'F'},
+ {"01T(F(", 'F'},
+ {"01T(N)", 'F'},
+ {"01T(NO", 'F'},
+ {"01T(S)", 'F'},
+ {"01T(SO", 'F'},
+ {"01T(V)", 'F'},
+ {"01T(VO", 'F'},
+ {"01T1(F", 'F'},
+ {"01T1O(", 'F'},
+ {"01T1OF", 'F'},
+ {"01T1OS", 'F'},
+ {"01T1OV", 'F'},
+ {"01TE(1", 'F'},
+ {"01TE(F", 'F'},
+ {"01TE(N", 'F'},
+ {"01TE(S", 'F'},
+ {"01TE(V", 'F'},
+ {"01TE1N", 'F'},
+ {"01TE1O", 'F'},
+ {"01TEF(", 'F'},
+ {"01TEK(", 'F'},
+ {"01TEK1", 'F'},
+ {"01TEKF", 'F'},
+ {"01TEKN", 'F'},
+ {"01TEKS", 'F'},
+ {"01TEKV", 'F'},
+ {"01TENN", 'F'},
+ {"01TENO", 'F'},
+ {"01TESN", 'F'},
+ {"01TESO", 'F'},
+ {"01TEVN", 'F'},
+ {"01TEVO", 'F'},
+ {"01TF()", 'F'},
+ {"01TF(1", 'F'},
+ {"01TF(F", 'F'},
+ {"01TF(N", 'F'},
+ {"01TF(S", 'F'},
+ {"01TF(V", 'F'},
+ {"01TN(1", 'F'},
+ {"01TN(F", 'F'},
+ {"01TN(S", 'F'},
+ {"01TN(V", 'F'},
+ {"01TN1C", 'F'},
+ {"01TN1O", 'F'},
+ {"01TN;E", 'F'},
+ {"01TN;N", 'F'},
+ {"01TN;T", 'F'},
+ {"01TNE(", 'F'},
+ {"01TNE1", 'F'},
+ {"01TNEF", 'F'},
+ {"01TNEN", 'F'},
+ {"01TNES", 'F'},
+ {"01TNEV", 'F'},
+ {"01TNF(", 'F'},
+ {"01TNKN", 'F'},
+ {"01TNN:", 'F'},
+ {"01TNNC", 'F'},
+ {"01TNNO", 'F'},
+ {"01TNO(", 'F'},
+ {"01TNOF", 'F'},
+ {"01TNOS", 'F'},
+ {"01TNOV", 'F'},
+ {"01TNSC", 'F'},
+ {"01TNSO", 'F'},
+ {"01TNT(", 'F'},
+ {"01TNT1", 'F'},
+ {"01TNTF", 'F'},
+ {"01TNTN", 'F'},
+ {"01TNTS", 'F'},
+ {"01TNTV", 'F'},
+ {"01TNVC", 'F'},
+ {"01TNVO", 'F'},
+ {"01TS(F", 'F'},
+ {"01TSO(", 'F'},
+ {"01TSO1", 'F'},
+ {"01TSOF", 'F'},
+ {"01TSON", 'F'},
+ {"01TSOS", 'F'},
+ {"01TSOV", 'F'},
+ {"01TTNE", 'F'},
+ {"01TTNK", 'F'},
+ {"01TTNN", 'F'},
+ {"01TTNT", 'F'},
+ {"01TV(1", 'F'},
+ {"01TV(F", 'F'},
+ {"01TVO(", 'F'},
+ {"01TVOF", 'F'},
+ {"01TVOS", 'F'},
{"01U", 'F'},
{"01U(1)", 'F'},
{"01U(1O", 'F'},
@@ -1757,7 +2018,6 @@ static const keyword_t sql_keywords[] = {
{"01UENU", 'F'},
{"01UEOK", 'F'},
{"01UEON", 'F'},
- {"01UEOO", 'F'},
{"01UES", 'F'},
{"01UES&", 'F'},
{"01UES(", 'F'},
@@ -1793,30 +2053,6 @@ static const keyword_t sql_keywords[] = {
{"01UF(S", 'F'},
{"01UF(V", 'F'},
{"01UK(E", 'F'},
- {"01UN(1", 'F'},
- {"01UN(F", 'F'},
- {"01UN(S", 'F'},
- {"01UN(V", 'F'},
- {"01UN,(", 'F'},
- {"01UN,F", 'F'},
- {"01UN1(", 'F'},
- {"01UN1,", 'F'},
- {"01UN1O", 'F'},
- {"01UNC", 'F'},
- {"01UNE(", 'F'},
- {"01UNE1", 'F'},
- {"01UNEF", 'F'},
- {"01UNEN", 'F'},
- {"01UNES", 'F'},
- {"01UNEV", 'F'},
- {"01UNF(", 'F'},
- {"01UNO(", 'F'},
- {"01UNOF", 'F'},
- {"01UNOS", 'F'},
- {"01UNOV", 'F'},
- {"01UNS(", 'F'},
- {"01UNS,", 'F'},
- {"01UNSO", 'F'},
{"01UO(E", 'F'},
{"01UON(", 'F'},
{"01UON1", 'F'},
@@ -1834,7 +2070,9 @@ static const keyword_t sql_keywords[] = {
{"01UTN(", 'F'},
{"01UTN1", 'F'},
{"01UTNF", 'F'},
+ {"01UTNN", 'F'},
{"01UTNS", 'F'},
+ {"01UTNV", 'F'},
{"01UV,(", 'F'},
{"01UV,F", 'F'},
{"01UVC", 'F'},
@@ -1872,6 +2110,8 @@ static const keyword_t sql_keywords[] = {
{"01VUE;", 'F'},
{"01VUEC", 'F'},
{"01VUEK", 'F'},
+ {"0;T(EF", 'F'},
+ {"0;T(EK", 'F'},
{"0;TKNC", 'F'},
{"0E(1&(", 'F'},
{"0E(1&1", 'F'},
@@ -1986,7 +2226,6 @@ static const keyword_t sql_keywords[] = {
{"0E(S)V", 'F'},
{"0E(S,F", 'F'},
{"0E(S1)", 'F'},
- {"0E(S1O", 'F'},
{"0E(SF(", 'F'},
{"0E(SO(", 'F'},
{"0E(SO1", 'F'},
@@ -2270,7 +2509,6 @@ static const keyword_t sql_keywords[] = {
{"0EK1N)", 'F'},
{"0EK1N;", 'F'},
{"0EK1NC", 'F'},
- {"0EK1NF", 'F'},
{"0EK1NK", 'F'},
{"0EK1O(", 'F'},
{"0EK1OF", 'F'},
@@ -2321,7 +2559,6 @@ static const keyword_t sql_keywords[] = {
{"0EKN1", 'F'},
{"0EKN1;", 'F'},
{"0EKN1C", 'F'},
- {"0EKN1F", 'F'},
{"0EKN1K", 'F'},
{"0EKN1O", 'F'},
{"0EKN;(", 'F'},
@@ -2367,7 +2604,6 @@ static const keyword_t sql_keywords[] = {
{"0EKS1C", 'F'},
{"0EKS1F", 'F'},
{"0EKS1K", 'F'},
- {"0EKS1O", 'F'},
{"0EKS;(", 'F'},
{"0EKSB(", 'F'},
{"0EKSB1", 'F'},
@@ -2486,7 +2722,6 @@ static const keyword_t sql_keywords[] = {
{"0EN,F(", 'F'},
{"0EN1;", 'F'},
{"0EN1;C", 'F'},
- {"0EN1C", 'F'},
{"0EN1O(", 'F'},
{"0EN1OF", 'F'},
{"0EN1OS", 'F'},
@@ -2620,10 +2855,6 @@ static const keyword_t sql_keywords[] = {
{"0ES1;", 'F'},
{"0ES1;C", 'F'},
{"0ES1C", 'F'},
- {"0ES1O(", 'F'},
- {"0ES1OF", 'F'},
- {"0ES1OS", 'F'},
- {"0ES1OV", 'F'},
{"0ES;(E", 'F'},
{"0ESB(1", 'F'},
{"0ESB(F", 'F'},
@@ -2942,6 +3173,14 @@ static const keyword_t sql_keywords[] = {
{"0F()SO", 'F'},
{"0F()SU", 'F'},
{"0F()SV", 'F'},
+ {"0F()T(", 'F'},
+ {"0F()T1", 'F'},
+ {"0F()TE", 'F'},
+ {"0F()TF", 'F'},
+ {"0F()TN", 'F'},
+ {"0F()TS", 'F'},
+ {"0F()TT", 'F'},
+ {"0F()TV", 'F'},
{"0F()U", 'F'},
{"0F()U(", 'F'},
{"0F()U1", 'F'},
@@ -2950,7 +3189,6 @@ static const keyword_t sql_keywords[] = {
{"0F()UE", 'F'},
{"0F()UF", 'F'},
{"0F()UK", 'F'},
- {"0F()UN", 'F'},
{"0F()UO", 'F'},
{"0F()US", 'F'},
{"0F()UT", 'F'},
@@ -2980,6 +3218,7 @@ static const keyword_t sql_keywords[] = {
{"0F(1)N", 'F'},
{"0F(1)O", 'F'},
{"0F(1)S", 'F'},
+ {"0F(1)T", 'F'},
{"0F(1)U", 'F'},
{"0F(1)V", 'F'},
{"0F(1,(", 'F'},
@@ -3003,12 +3242,14 @@ static const keyword_t sql_keywords[] = {
{"0F(EK1", 'F'},
{"0F(EKF", 'F'},
{"0F(EKN", 'F'},
+ {"0F(EKO", 'F'},
{"0F(EKS", 'F'},
{"0F(EKV", 'F'},
{"0F(EN&", 'F'},
{"0F(EN)", 'F'},
{"0F(ENK", 'F'},
{"0F(ENO", 'F'},
+ {"0F(EOK", 'F'},
{"0F(ES&", 'F'},
{"0F(ES)", 'F'},
{"0F(ESK", 'F'},
@@ -3047,6 +3288,7 @@ static const keyword_t sql_keywords[] = {
{"0F(N)N", 'F'},
{"0F(N)O", 'F'},
{"0F(N)S", 'F'},
+ {"0F(N)T", 'F'},
{"0F(N)U", 'F'},
{"0F(N)V", 'F'},
{"0F(N,(", 'F'},
@@ -3075,6 +3317,7 @@ static const keyword_t sql_keywords[] = {
{"0F(S)N", 'F'},
{"0F(S)O", 'F'},
{"0F(S)S", 'F'},
+ {"0F(S)T", 'F'},
{"0F(S)U", 'F'},
{"0F(S)V", 'F'},
{"0F(S,(", 'F'},
@@ -3107,6 +3350,7 @@ static const keyword_t sql_keywords[] = {
{"0F(V)N", 'F'},
{"0F(V)O", 'F'},
{"0F(V)S", 'F'},
+ {"0F(V)T", 'F'},
{"0F(V)U", 'F'},
{"0F(V)V", 'F'},
{"0F(V,(", 'F'},
@@ -3395,7 +3639,6 @@ static const keyword_t sql_keywords[] = {
{"0N&1KV", 'F'},
{"0N&1O(", 'F'},
{"0N&1OF", 'F'},
- {"0N&1OO", 'F'},
{"0N&1OS", 'F'},
{"0N&1OV", 'F'},
{"0N&1TN", 'F'},
@@ -3455,6 +3698,7 @@ static const keyword_t sql_keywords[] = {
{"0N&K(S", 'F'},
{"0N&K(V", 'F'},
{"0N&K1O", 'F'},
+ {"0N&KC", 'F'},
{"0N&KF(", 'F'},
{"0N&KNK", 'F'},
{"0N&KO(", 'F'},
@@ -3481,7 +3725,6 @@ static const keyword_t sql_keywords[] = {
{"0N&NB(", 'F'},
{"0N&NB1", 'F'},
{"0N&NBF", 'F'},
- {"0N&NBN", 'F'},
{"0N&NBS", 'F'},
{"0N&NBV", 'F'},
{"0N&NF(", 'F'},
@@ -3512,7 +3755,6 @@ static const keyword_t sql_keywords[] = {
{"0N&S1", 'F'},
{"0N&S1;", 'F'},
{"0N&S1C", 'F'},
- {"0N&S1O", 'F'},
{"0N&S;", 'F'},
{"0N&S;C", 'F'},
{"0N&S;E", 'F'},
@@ -3537,7 +3779,6 @@ static const keyword_t sql_keywords[] = {
{"0N&SO1", 'F'},
{"0N&SOF", 'F'},
{"0N&SON", 'F'},
- {"0N&SOO", 'F'},
{"0N&SOS", 'F'},
{"0N&SOV", 'F'},
{"0N&STN", 'F'},
@@ -3583,7 +3824,6 @@ static const keyword_t sql_keywords[] = {
{"0N&VKV", 'F'},
{"0N&VO(", 'F'},
{"0N&VOF", 'F'},
- {"0N&VOO", 'F'},
{"0N&VOS", 'F'},
{"0N&VS", 'F'},
{"0N&VS;", 'F'},
@@ -3595,48 +3835,6 @@ static const keyword_t sql_keywords[] = {
{"0N&VU;", 'F'},
{"0N&VUC", 'F'},
{"0N&VUE", 'F'},
- {"0N(1)F", 'F'},
- {"0N(1)O", 'F'},
- {"0N(1)U", 'F'},
- {"0N(1)V", 'F'},
- {"0N(1O(", 'F'},
- {"0N(1OF", 'F'},
- {"0N(1OS", 'F'},
- {"0N(1OV", 'F'},
- {"0N(EF(", 'F'},
- {"0N(EKF", 'F'},
- {"0N(EKN", 'F'},
- {"0N(ENK", 'F'},
- {"0N(F()", 'F'},
- {"0N(F(1", 'F'},
- {"0N(F(F", 'F'},
- {"0N(F(N", 'F'},
- {"0N(F(S", 'F'},
- {"0N(F(V", 'F'},
- {"0N(S)1", 'F'},
- {"0N(S)F", 'F'},
- {"0N(S)N", 'F'},
- {"0N(S)O", 'F'},
- {"0N(S)S", 'F'},
- {"0N(S)U", 'F'},
- {"0N(S)V", 'F'},
- {"0N(SO(", 'F'},
- {"0N(SO1", 'F'},
- {"0N(SOF", 'F'},
- {"0N(SON", 'F'},
- {"0N(SOS", 'F'},
- {"0N(SOV", 'F'},
- {"0N(U(E", 'F'},
- {"0N(V)1", 'F'},
- {"0N(V)F", 'F'},
- {"0N(V)N", 'F'},
- {"0N(V)O", 'F'},
- {"0N(V)S", 'F'},
- {"0N(V)U", 'F'},
- {"0N(V)V", 'F'},
- {"0N(VO(", 'F'},
- {"0N(VOF", 'F'},
- {"0N(VOS", 'F'},
{"0N)&(1", 'F'},
{"0N)&(E", 'F'},
{"0N)&(F", 'F'},
@@ -3756,6 +3954,7 @@ static const keyword_t sql_keywords[] = {
{"0N)ESO", 'F'},
{"0N)EVC", 'F'},
{"0N)EVO", 'F'},
+ {"0N)F(F", 'F'},
{"0N)K(1", 'F'},
{"0N)K(F", 'F'},
{"0N)K(N", 'F'},
@@ -3777,6 +3976,7 @@ static const keyword_t sql_keywords[] = {
{"0N)KN&", 'F'},
{"0N)KN;", 'F'},
{"0N)KNB", 'F'},
+ {"0N)KNC", 'F'},
{"0N)KNE", 'F'},
{"0N)KNK", 'F'},
{"0N)KNU", 'F'},
@@ -3807,7 +4007,6 @@ static const keyword_t sql_keywords[] = {
{"0N)O1K", 'F'},
{"0N)O1U", 'F'},
{"0N)OF(", 'F'},
- {"0N)ON", 'F'},
{"0N)ON&", 'F'},
{"0N)ON)", 'F'},
{"0N)ON;", 'F'},
@@ -3861,12 +4060,6 @@ static const keyword_t sql_keywords[] = {
{"0N,F(N", 'F'},
{"0N,F(S", 'F'},
{"0N,F(V", 'F'},
- {"0N1F()", 'F'},
- {"0N1F(1", 'F'},
- {"0N1F(F", 'F'},
- {"0N1F(N", 'F'},
- {"0N1F(S", 'F'},
- {"0N1F(V", 'F'},
{"0N1O(1", 'F'},
{"0N1O(F", 'F'},
{"0N1O(N", 'F'},
@@ -3937,11 +4130,13 @@ static const keyword_t sql_keywords[] = {
{"0N;EVT", 'F'},
{"0N;N:T", 'F'},
{"0N;T(1", 'F'},
+ {"0N;T(C", 'F'},
{"0N;T(E", 'F'},
{"0N;T(F", 'F'},
{"0N;T(N", 'F'},
{"0N;T(S", 'F'},
{"0N;T(V", 'F'},
+ {"0N;T1(", 'F'},
{"0N;T1,", 'F'},
{"0N;T1;", 'F'},
{"0N;T1C", 'F'},
@@ -3956,7 +4151,6 @@ static const keyword_t sql_keywords[] = {
{"0N;TK1", 'F'},
{"0N;TKF", 'F'},
{"0N;TKK", 'F'},
- {"0N;TKN", 'F'},
{"0N;TKO", 'F'},
{"0N;TKS", 'F'},
{"0N;TKV", 'F'},
@@ -3974,6 +4168,7 @@ static const keyword_t sql_keywords[] = {
{"0N;TNT", 'F'},
{"0N;TNV", 'F'},
{"0N;TO(", 'F'},
+ {"0N;TS(", 'F'},
{"0N;TS,", 'F'},
{"0N;TS;", 'F'},
{"0N;TSC", 'F'},
@@ -3981,12 +4176,8 @@ static const keyword_t sql_keywords[] = {
{"0N;TSK", 'F'},
{"0N;TSO", 'F'},
{"0N;TST", 'F'},
- {"0N;TT(", 'F'},
- {"0N;TT1", 'F'},
- {"0N;TTF", 'F'},
{"0N;TTN", 'F'},
- {"0N;TTS", 'F'},
- {"0N;TTV", 'F'},
+ {"0N;TV(", 'F'},
{"0N;TV,", 'F'},
{"0N;TV;", 'F'},
{"0N;TVC", 'F'},
@@ -4025,13 +4216,16 @@ static const keyword_t sql_keywords[] = {
{"0NAVOF", 'F'},
{"0NAVOS", 'F'},
{"0NAVUE", 'F'},
+ {"0NB(1&", 'F'},
{"0NB(1)", 'F'},
{"0NB(1O", 'F'},
{"0NB(F(", 'F'},
- {"0NB(N)", 'F'},
+ {"0NB(N&", 'F'},
{"0NB(NO", 'F'},
+ {"0NB(S&", 'F'},
{"0NB(S)", 'F'},
{"0NB(SO", 'F'},
+ {"0NB(V&", 'F'},
{"0NB(V)", 'F'},
{"0NB(VO", 'F'},
{"0NB1", 'F'},
@@ -4176,11 +4370,18 @@ static const keyword_t sql_keywords[] = {
{"0NE(SO", 'F'},
{"0NE(V)", 'F'},
{"0NE(VO", 'F'},
+ {"0NE1;T", 'F'},
{"0NE1C", 'F'},
{"0NE1O(", 'F'},
{"0NE1OF", 'F'},
{"0NE1OS", 'F'},
{"0NE1OV", 'F'},
+ {"0NE1T(", 'F'},
+ {"0NE1T1", 'F'},
+ {"0NE1TF", 'F'},
+ {"0NE1TN", 'F'},
+ {"0NE1TS", 'F'},
+ {"0NE1TV", 'F'},
{"0NE1UE", 'F'},
{"0NEF()", 'F'},
{"0NEF(1", 'F'},
@@ -4188,13 +4389,20 @@ static const keyword_t sql_keywords[] = {
{"0NEF(N", 'F'},
{"0NEF(S", 'F'},
{"0NEF(V", 'F'},
- {"0NENC", 'F'},
+ {"0NEN;T", 'F'},
{"0NENO(", 'F'},
{"0NENOF", 'F'},
{"0NENOS", 'F'},
{"0NENOV", 'F'},
+ {"0NENT(", 'F'},
+ {"0NENT1", 'F'},
+ {"0NENTF", 'F'},
+ {"0NENTN", 'F'},
+ {"0NENTS", 'F'},
+ {"0NENTV", 'F'},
{"0NENUE", 'F'},
{"0NEOKN", 'F'},
+ {"0NES;T", 'F'},
{"0NESC", 'F'},
{"0NESO(", 'F'},
{"0NESO1", 'F'},
@@ -4202,6 +4410,12 @@ static const keyword_t sql_keywords[] = {
{"0NESON", 'F'},
{"0NESOS", 'F'},
{"0NESOV", 'F'},
+ {"0NEST(", 'F'},
+ {"0NEST1", 'F'},
+ {"0NESTF", 'F'},
+ {"0NESTN", 'F'},
+ {"0NESTS", 'F'},
+ {"0NESTV", 'F'},
{"0NESUE", 'F'},
{"0NEU(1", 'F'},
{"0NEU(F", 'F'},
@@ -4214,19 +4428,23 @@ static const keyword_t sql_keywords[] = {
{"0NEUEF", 'F'},
{"0NEUEK", 'F'},
{"0NEUF(", 'F'},
- {"0NEUN,", 'F'},
- {"0NEUNC", 'F'},
- {"0NEUNO", 'F'},
{"0NEUS,", 'F'},
{"0NEUSC", 'F'},
{"0NEUSO", 'F'},
{"0NEUV,", 'F'},
{"0NEUVC", 'F'},
{"0NEUVO", 'F'},
+ {"0NEV;T", 'F'},
{"0NEVC", 'F'},
{"0NEVO(", 'F'},
{"0NEVOF", 'F'},
{"0NEVOS", 'F'},
+ {"0NEVT(", 'F'},
+ {"0NEVT1", 'F'},
+ {"0NEVTF", 'F'},
+ {"0NEVTN", 'F'},
+ {"0NEVTS", 'F'},
+ {"0NEVTV", 'F'},
{"0NEVUE", 'F'},
{"0NF()1", 'F'},
{"0NF()F", 'F'},
@@ -4237,7 +4455,6 @@ static const keyword_t sql_keywords[] = {
{"0NF()U", 'F'},
{"0NF()V", 'F'},
{"0NF(1)", 'F'},
- {"0NF(1N", 'F'},
{"0NF(1O", 'F'},
{"0NF(E(", 'F'},
{"0NF(E1", 'F'},
@@ -4247,7 +4464,6 @@ static const keyword_t sql_keywords[] = {
{"0NF(ES", 'F'},
{"0NF(EV", 'F'},
{"0NF(F(", 'F'},
- {"0NF(N)", 'F'},
{"0NF(N,", 'F'},
{"0NF(NO", 'F'},
{"0NF(S)", 'F'},
@@ -4257,7 +4473,6 @@ static const keyword_t sql_keywords[] = {
{"0NK(1)", 'F'},
{"0NK(1O", 'F'},
{"0NK(F(", 'F'},
- {"0NK(N)", 'F'},
{"0NK(NO", 'F'},
{"0NK(S)", 'F'},
{"0NK(SO", 'F'},
@@ -4284,6 +4499,8 @@ static const keyword_t sql_keywords[] = {
{"0NK)EN", 'F'},
{"0NK)ES", 'F'},
{"0NK)EV", 'F'},
+ {"0NK)F(", 'F'},
+ {"0NK)O(", 'F'},
{"0NK)OF", 'F'},
{"0NK)UE", 'F'},
{"0NK1", 'F'},
@@ -4337,7 +4554,6 @@ static const keyword_t sql_keywords[] = {
{"0NKNBN", 'F'},
{"0NKNBS", 'F'},
{"0NKNBV", 'F'},
- {"0NKNC", 'F'},
{"0NKNE(", 'F'},
{"0NKNE1", 'F'},
{"0NKNEF", 'F'},
@@ -4425,6 +4641,7 @@ static const keyword_t sql_keywords[] = {
{"0NO(EF", 'F'},
{"0NO(EK", 'F'},
{"0NO(EN", 'F'},
+ {"0NO(EO", 'F'},
{"0NO(ES", 'F'},
{"0NO(EV", 'F'},
{"0NO(F(", 'F'},
@@ -4448,11 +4665,6 @@ static const keyword_t sql_keywords[] = {
{"0NOF(S", 'F'},
{"0NOF(V", 'F'},
{"0NOK&(", 'F'},
- {"0NOK&1", 'F'},
- {"0NOK&F", 'F'},
- {"0NOK&N", 'F'},
- {"0NOK&S", 'F'},
- {"0NOK&V", 'F'},
{"0NOK(1", 'F'},
{"0NOK(F", 'F'},
{"0NOK(N", 'F'},
@@ -4490,6 +4702,7 @@ static const keyword_t sql_keywords[] = {
{"0NOS)B", 'F'},
{"0NOS)C", 'F'},
{"0NOS)E", 'F'},
+ {"0NOS)F", 'F'},
{"0NOS)K", 'F'},
{"0NOS)O", 'F'},
{"0NOS)U", 'F'},
@@ -4498,7 +4711,6 @@ static const keyword_t sql_keywords[] = {
{"0NOS1(", 'F'},
{"0NOS1F", 'F'},
{"0NOS1N", 'F'},
- {"0NOS1O", 'F'},
{"0NOS1S", 'F'},
{"0NOS1U", 'F'},
{"0NOS1V", 'F'},
@@ -4538,6 +4750,14 @@ static const keyword_t sql_keywords[] = {
{"0NOSKS", 'F'},
{"0NOSKU", 'F'},
{"0NOSKV", 'F'},
+ {"0NOST(", 'F'},
+ {"0NOST1", 'F'},
+ {"0NOSTE", 'F'},
+ {"0NOSTF", 'F'},
+ {"0NOSTN", 'F'},
+ {"0NOSTS", 'F'},
+ {"0NOSTT", 'F'},
+ {"0NOSTV", 'F'},
{"0NOSU", 'F'},
{"0NOSU(", 'F'},
{"0NOSU1", 'F'},
@@ -4546,7 +4766,6 @@ static const keyword_t sql_keywords[] = {
{"0NOSUE", 'F'},
{"0NOSUF", 'F'},
{"0NOSUK", 'F'},
- {"0NOSUN", 'F'},
{"0NOSUO", 'F'},
{"0NOSUS", 'F'},
{"0NOSUT", 'F'},
@@ -4576,6 +4795,7 @@ static const keyword_t sql_keywords[] = {
{"0NOV)B", 'F'},
{"0NOV)C", 'F'},
{"0NOV)E", 'F'},
+ {"0NOV)F", 'F'},
{"0NOV)K", 'F'},
{"0NOV)O", 'F'},
{"0NOV)U", 'F'},
@@ -4629,6 +4849,14 @@ static const keyword_t sql_keywords[] = {
{"0NOVSO", 'F'},
{"0NOVSU", 'F'},
{"0NOVSV", 'F'},
+ {"0NOVT(", 'F'},
+ {"0NOVT1", 'F'},
+ {"0NOVTE", 'F'},
+ {"0NOVTF", 'F'},
+ {"0NOVTN", 'F'},
+ {"0NOVTS", 'F'},
+ {"0NOVTT", 'F'},
+ {"0NOVTV", 'F'},
{"0NOVU", 'F'},
{"0NOVU(", 'F'},
{"0NOVU1", 'F'},
@@ -4637,7 +4865,6 @@ static const keyword_t sql_keywords[] = {
{"0NOVUE", 'F'},
{"0NOVUF", 'F'},
{"0NOVUK", 'F'},
- {"0NOVUN", 'F'},
{"0NOVUO", 'F'},
{"0NOVUS", 'F'},
{"0NOVUT", 'F'},
@@ -4650,6 +4877,96 @@ static const keyword_t sql_keywords[] = {
{"0NSUE;", 'F'},
{"0NSUEC", 'F'},
{"0NSUEK", 'F'},
+ {"0NT(1)", 'F'},
+ {"0NT(1O", 'F'},
+ {"0NT(F(", 'F'},
+ {"0NT(N)", 'F'},
+ {"0NT(NO", 'F'},
+ {"0NT(S)", 'F'},
+ {"0NT(SO", 'F'},
+ {"0NT(V)", 'F'},
+ {"0NT(VO", 'F'},
+ {"0NT1(F", 'F'},
+ {"0NT1O(", 'F'},
+ {"0NT1OF", 'F'},
+ {"0NT1OS", 'F'},
+ {"0NT1OV", 'F'},
+ {"0NTE(1", 'F'},
+ {"0NTE(F", 'F'},
+ {"0NTE(N", 'F'},
+ {"0NTE(S", 'F'},
+ {"0NTE(V", 'F'},
+ {"0NTE1N", 'F'},
+ {"0NTE1O", 'F'},
+ {"0NTEF(", 'F'},
+ {"0NTEK(", 'F'},
+ {"0NTEK1", 'F'},
+ {"0NTEKF", 'F'},
+ {"0NTEKN", 'F'},
+ {"0NTEKS", 'F'},
+ {"0NTEKV", 'F'},
+ {"0NTENN", 'F'},
+ {"0NTENO", 'F'},
+ {"0NTESN", 'F'},
+ {"0NTESO", 'F'},
+ {"0NTEVN", 'F'},
+ {"0NTEVO", 'F'},
+ {"0NTF()", 'F'},
+ {"0NTF(1", 'F'},
+ {"0NTF(F", 'F'},
+ {"0NTF(N", 'F'},
+ {"0NTF(S", 'F'},
+ {"0NTF(V", 'F'},
+ {"0NTN(1", 'F'},
+ {"0NTN(F", 'F'},
+ {"0NTN(S", 'F'},
+ {"0NTN(V", 'F'},
+ {"0NTN1C", 'F'},
+ {"0NTN1O", 'F'},
+ {"0NTN;E", 'F'},
+ {"0NTN;N", 'F'},
+ {"0NTN;T", 'F'},
+ {"0NTNE(", 'F'},
+ {"0NTNE1", 'F'},
+ {"0NTNEF", 'F'},
+ {"0NTNEN", 'F'},
+ {"0NTNES", 'F'},
+ {"0NTNEV", 'F'},
+ {"0NTNF(", 'F'},
+ {"0NTNKN", 'F'},
+ {"0NTNN:", 'F'},
+ {"0NTNNC", 'F'},
+ {"0NTNNO", 'F'},
+ {"0NTNO(", 'F'},
+ {"0NTNOF", 'F'},
+ {"0NTNOS", 'F'},
+ {"0NTNOV", 'F'},
+ {"0NTNSC", 'F'},
+ {"0NTNSO", 'F'},
+ {"0NTNT(", 'F'},
+ {"0NTNT1", 'F'},
+ {"0NTNTF", 'F'},
+ {"0NTNTN", 'F'},
+ {"0NTNTS", 'F'},
+ {"0NTNTV", 'F'},
+ {"0NTNVC", 'F'},
+ {"0NTNVO", 'F'},
+ {"0NTS(F", 'F'},
+ {"0NTSO(", 'F'},
+ {"0NTSO1", 'F'},
+ {"0NTSOF", 'F'},
+ {"0NTSON", 'F'},
+ {"0NTSOS", 'F'},
+ {"0NTSOV", 'F'},
+ {"0NTTNE", 'F'},
+ {"0NTTNK", 'F'},
+ {"0NTTNN", 'F'},
+ {"0NTTNT", 'F'},
+ {"0NTV(1", 'F'},
+ {"0NTV(F", 'F'},
+ {"0NTVO(", 'F'},
+ {"0NTVOF", 'F'},
+ {"0NTVOS", 'F'},
{"0NU(1)", 'F'},
{"0NU(1O", 'F'},
{"0NU(E(", 'F'},
@@ -4733,7 +5050,6 @@ static const keyword_t sql_keywords[] = {
{"0NUENU", 'F'},
{"0NUEOK", 'F'},
{"0NUEON", 'F'},
- {"0NUEOO", 'F'},
{"0NUES", 'F'},
{"0NUES&", 'F'},
{"0NUES(", 'F'},
@@ -4769,30 +5085,6 @@ static const keyword_t sql_keywords[] = {
{"0NUF(S", 'F'},
{"0NUF(V", 'F'},
{"0NUK(E", 'F'},
- {"0NUN(1", 'F'},
- {"0NUN(F", 'F'},
- {"0NUN(S", 'F'},
- {"0NUN(V", 'F'},
- {"0NUN,(", 'F'},
- {"0NUN,F", 'F'},
- {"0NUN1(", 'F'},
- {"0NUN1,", 'F'},
- {"0NUN1O", 'F'},
- {"0NUNC", 'F'},
- {"0NUNE(", 'F'},
- {"0NUNE1", 'F'},
- {"0NUNEF", 'F'},
- {"0NUNEN", 'F'},
- {"0NUNES", 'F'},
- {"0NUNEV", 'F'},
- {"0NUNF(", 'F'},
- {"0NUNO(", 'F'},
- {"0NUNOF", 'F'},
- {"0NUNOS", 'F'},
- {"0NUNOV", 'F'},
- {"0NUNS(", 'F'},
- {"0NUNS,", 'F'},
- {"0NUNSO", 'F'},
{"0NUO(E", 'F'},
{"0NUON(", 'F'},
{"0NUON1", 'F'},
@@ -4810,110 +5102,15 @@ static const keyword_t sql_keywords[] = {
{"0NUTN(", 'F'},
{"0NUTN1", 'F'},
{"0NUTNF", 'F'},
+ {"0NUTNN", 'F'},
{"0NUTNS", 'F'},
+ {"0NUTNV", 'F'},
{"0NUV,(", 'F'},
{"0NUV,F", 'F'},
{"0NUVC", 'F'},
{"0NUVO(", 'F'},
{"0NUVOF", 'F'},
{"0NUVOS", 'F'},
- {"0O(1)O", 'F'},
- {"0O(1)U", 'F'},
- {"0O(1O(", 'F'},
- {"0O(1OF", 'F'},
- {"0O(1OS", 'F'},
- {"0O(1OV", 'F'},
- {"0O(F()", 'F'},
- {"0O(F(1", 'F'},
- {"0O(F(F", 'F'},
- {"0O(F(N", 'F'},
- {"0O(F(S", 'F'},
- {"0O(F(V", 'F'},
- {"0O(N)O", 'F'},
- {"0O(N)U", 'F'},
- {"0O(NO(", 'F'},
- {"0O(NOF", 'F'},
- {"0O(NOS", 'F'},
- {"0O(NOV", 'F'},
- {"0O(S)O", 'F'},
- {"0O(S)U", 'F'},
- {"0O(SO(", 'F'},
- {"0O(SO1", 'F'},
- {"0O(SOF", 'F'},
- {"0O(SON", 'F'},
- {"0O(SOS", 'F'},
- {"0O(SOV", 'F'},
- {"0O(V)O", 'F'},
- {"0O(V)U", 'F'},
- {"0O(VO(", 'F'},
- {"0O(VOF", 'F'},
- {"0O(VOS", 'F'},
- {"0O1UE(", 'F'},
- {"0O1UE1", 'F'},
- {"0O1UEF", 'F'},
- {"0O1UEK", 'F'},
- {"0O1UEN", 'F'},
- {"0O1UES", 'F'},
- {"0O1UEV", 'F'},
- {"0OF()O", 'F'},
- {"0OF()U", 'F'},
- {"0OF(1)", 'F'},
- {"0OF(1O", 'F'},
- {"0OF(F(", 'F'},
- {"0OF(N)", 'F'},
- {"0OF(NO", 'F'},
- {"0OF(S)", 'F'},
- {"0OF(SO", 'F'},
- {"0OF(V)", 'F'},
- {"0OF(VO", 'F'},
- {"0ONUE(", 'F'},
- {"0ONUE1", 'F'},
- {"0ONUEF", 'F'},
- {"0ONUEK", 'F'},
- {"0ONUEN", 'F'},
- {"0ONUES", 'F'},
- {"0ONUEV", 'F'},
- {"0OSUE(", 'F'},
- {"0OSUE1", 'F'},
- {"0OSUEF", 'F'},
- {"0OSUEK", 'F'},
- {"0OSUEN", 'F'},
- {"0OSUES", 'F'},
- {"0OSUEV", 'F'},
- {"0OUE(1", 'F'},
- {"0OUE(F", 'F'},
- {"0OUE(N", 'F'},
- {"0OUE(S", 'F'},
- {"0OUE(V", 'F'},
- {"0OUE1,", 'F'},
- {"0OUE1O", 'F'},
- {"0OUEF(", 'F'},
- {"0OUEK(", 'F'},
- {"0OUEK1", 'F'},
- {"0OUEKF", 'F'},
- {"0OUEKN", 'F'},
- {"0OUEKS", 'F'},
- {"0OUEKV", 'F'},
- {"0OUEN,", 'F'},
- {"0OUENO", 'F'},
- {"0OUES,", 'F'},
- {"0OUESO", 'F'},
- {"0OUEV,", 'F'},
- {"0OUEVO", 'F'},
- {"0OVO(1", 'F'},
- {"0OVO(F", 'F'},
- {"0OVO(N", 'F'},
- {"0OVO(S", 'F'},
- {"0OVO(V", 'F'},
- {"0OVOF(", 'F'},
- {"0OVOSU", 'F'},
- {"0OVUE(", 'F'},
- {"0OVUE1", 'F'},
- {"0OVUEF", 'F'},
- {"0OVUEK", 'F'},
- {"0OVUEN", 'F'},
- {"0OVUES", 'F'},
- {"0OVUEV", 'F'},
{"0S&(1&", 'F'},
{"0S&(1)", 'F'},
{"0S&(1,", 'F'},
@@ -4972,7 +5169,6 @@ static const keyword_t sql_keywords[] = {
{"0S&1KV", 'F'},
{"0S&1O(", 'F'},
{"0S&1OF", 'F'},
- {"0S&1OO", 'F'},
{"0S&1OS", 'F'},
{"0S&1OV", 'F'},
{"0S&1TN", 'F'},
@@ -5033,6 +5229,7 @@ static const keyword_t sql_keywords[] = {
{"0S&K(S", 'F'},
{"0S&K(V", 'F'},
{"0S&K1O", 'F'},
+ {"0S&KC", 'F'},
{"0S&KF(", 'F'},
{"0S&KNK", 'F'},
{"0S&KO(", 'F'},
@@ -5098,7 +5295,6 @@ static const keyword_t sql_keywords[] = {
{"0S&S1", 'F'},
{"0S&S1;", 'F'},
{"0S&S1C", 'F'},
- {"0S&S1O", 'F'},
{"0S&S;", 'F'},
{"0S&S;C", 'F'},
{"0S&S;E", 'F'},
@@ -5123,7 +5319,6 @@ static const keyword_t sql_keywords[] = {
{"0S&SO1", 'F'},
{"0S&SOF", 'F'},
{"0S&SON", 'F'},
- {"0S&SOO", 'F'},
{"0S&SOS", 'F'},
{"0S&SOV", 'F'},
{"0S&STN", 'F'},
@@ -5169,7 +5364,6 @@ static const keyword_t sql_keywords[] = {
{"0S&VKV", 'F'},
{"0S&VO(", 'F'},
{"0S&VOF", 'F'},
- {"0S&VOO", 'F'},
{"0S&VOS", 'F'},
{"0S&VS", 'F'},
{"0S&VS;", 'F'},
@@ -5306,6 +5500,7 @@ static const keyword_t sql_keywords[] = {
{"0S)ESO", 'F'},
{"0S)EVC", 'F'},
{"0S)EVO", 'F'},
+ {"0S)F(F", 'F'},
{"0S)K(1", 'F'},
{"0S)K(F", 'F'},
{"0S)K(N", 'F'},
@@ -5327,6 +5522,7 @@ static const keyword_t sql_keywords[] = {
{"0S)KN&", 'F'},
{"0S)KN;", 'F'},
{"0S)KNB", 'F'},
+ {"0S)KNC", 'F'},
{"0S)KNE", 'F'},
{"0S)KNK", 'F'},
{"0S)KNU", 'F'},
@@ -5419,22 +5615,6 @@ static const keyword_t sql_keywords[] = {
{"0S1F(S", 'F'},
{"0S1F(V", 'F'},
{"0S1NC", 'F'},
- {"0S1O(1", 'F'},
- {"0S1O(F", 'F'},
- {"0S1O(N", 'F'},
- {"0S1O(S", 'F'},
- {"0S1O(V", 'F'},
- {"0S1OF(", 'F'},
- {"0S1OS(", 'F'},
- {"0S1OS1", 'F'},
- {"0S1OSF", 'F'},
- {"0S1OSU", 'F'},
- {"0S1OSV", 'F'},
- {"0S1OV(", 'F'},
- {"0S1OVF", 'F'},
- {"0S1OVO", 'F'},
- {"0S1OVS", 'F'},
- {"0S1OVU", 'F'},
{"0S1S;", 'F'},
{"0S1S;C", 'F'},
{"0S1SC", 'F'},
@@ -5490,11 +5670,13 @@ static const keyword_t sql_keywords[] = {
{"0S;EVT", 'F'},
{"0S;N:T", 'F'},
{"0S;T(1", 'F'},
+ {"0S;T(C", 'F'},
{"0S;T(E", 'F'},
{"0S;T(F", 'F'},
{"0S;T(N", 'F'},
{"0S;T(S", 'F'},
{"0S;T(V", 'F'},
+ {"0S;T1(", 'F'},
{"0S;T1,", 'F'},
{"0S;T1;", 'F'},
{"0S;T1C", 'F'},
@@ -5527,6 +5709,7 @@ static const keyword_t sql_keywords[] = {
{"0S;TNT", 'F'},
{"0S;TNV", 'F'},
{"0S;TO(", 'F'},
+ {"0S;TS(", 'F'},
{"0S;TS,", 'F'},
{"0S;TS;", 'F'},
{"0S;TSC", 'F'},
@@ -5534,12 +5717,8 @@ static const keyword_t sql_keywords[] = {
{"0S;TSK", 'F'},
{"0S;TSO", 'F'},
{"0S;TST", 'F'},
- {"0S;TT(", 'F'},
- {"0S;TT1", 'F'},
- {"0S;TTF", 'F'},
{"0S;TTN", 'F'},
- {"0S;TTS", 'F'},
- {"0S;TTV", 'F'},
+ {"0S;TV(", 'F'},
{"0S;TV,", 'F'},
{"0S;TV;", 'F'},
{"0S;TVC", 'F'},
@@ -5581,7 +5760,6 @@ static const keyword_t sql_keywords[] = {
{"0SB(1)", 'F'},
{"0SB(1O", 'F'},
{"0SB(F(", 'F'},
- {"0SB(N)", 'F'},
{"0SB(NO", 'F'},
{"0SB(S)", 'F'},
{"0SB(SO", 'F'},
@@ -5730,11 +5908,18 @@ static const keyword_t sql_keywords[] = {
{"0SE(SO", 'F'},
{"0SE(V)", 'F'},
{"0SE(VO", 'F'},
+ {"0SE1;T", 'F'},
{"0SE1C", 'F'},
{"0SE1O(", 'F'},
{"0SE1OF", 'F'},
{"0SE1OS", 'F'},
{"0SE1OV", 'F'},
+ {"0SE1T(", 'F'},
+ {"0SE1T1", 'F'},
+ {"0SE1TF", 'F'},
+ {"0SE1TN", 'F'},
+ {"0SE1TS", 'F'},
+ {"0SE1TV", 'F'},
{"0SE1UE", 'F'},
{"0SEF()", 'F'},
{"0SEF(1", 'F'},
@@ -5748,35 +5933,50 @@ static const keyword_t sql_keywords[] = {
{"0SEK(N", 'F'},
{"0SEK(S", 'F'},
{"0SEK(V", 'F'},
+ {"0SEK1;", 'F'},
{"0SEK1C", 'F'},
{"0SEK1O", 'F'},
+ {"0SEK1T", 'F'},
{"0SEK1U", 'F'},
{"0SEKF(", 'F'},
+ {"0SEKN;", 'F'},
{"0SEKNC", 'F'},
{"0SEKNE", 'F'},
+ {"0SEKNT", 'F'},
{"0SEKNU", 'F'},
{"0SEKOK", 'F'},
+ {"0SEKS;", 'F'},
{"0SEKSC", 'F'},
{"0SEKSO", 'F'},
+ {"0SEKST", 'F'},
{"0SEKSU", 'F'},
{"0SEKU(", 'F'},
{"0SEKU1", 'F'},
{"0SEKUE", 'F'},
{"0SEKUF", 'F'},
- {"0SEKUN", 'F'},
{"0SEKUS", 'F'},
{"0SEKUV", 'F'},
+ {"0SEKV;", 'F'},
{"0SEKVC", 'F'},
{"0SEKVO", 'F'},
+ {"0SEKVT", 'F'},
{"0SEKVU", 'F'},
+ {"0SEN;T", 'F'},
{"0SENC", 'F'},
{"0SENEN", 'F'},
{"0SENO(", 'F'},
{"0SENOF", 'F'},
{"0SENOS", 'F'},
{"0SENOV", 'F'},
+ {"0SENT(", 'F'},
+ {"0SENT1", 'F'},
+ {"0SENTF", 'F'},
+ {"0SENTN", 'F'},
+ {"0SENTS", 'F'},
+ {"0SENTV", 'F'},
{"0SENUE", 'F'},
{"0SEOKN", 'F'},
+ {"0SES;T", 'F'},
{"0SESC", 'F'},
{"0SESO(", 'F'},
{"0SESO1", 'F'},
@@ -5784,6 +5984,12 @@ static const keyword_t sql_keywords[] = {
{"0SESON", 'F'},
{"0SESOS", 'F'},
{"0SESOV", 'F'},
+ {"0SEST(", 'F'},
+ {"0SEST1", 'F'},
+ {"0SESTF", 'F'},
+ {"0SESTN", 'F'},
+ {"0SESTS", 'F'},
+ {"0SESTV", 'F'},
{"0SESUE", 'F'},
{"0SEU(1", 'F'},
{"0SEU(F", 'F'},
@@ -5796,19 +6002,23 @@ static const keyword_t sql_keywords[] = {
{"0SEUEF", 'F'},
{"0SEUEK", 'F'},
{"0SEUF(", 'F'},
- {"0SEUN,", 'F'},
- {"0SEUNC", 'F'},
- {"0SEUNO", 'F'},
{"0SEUS,", 'F'},
{"0SEUSC", 'F'},
{"0SEUSO", 'F'},
{"0SEUV,", 'F'},
{"0SEUVC", 'F'},
{"0SEUVO", 'F'},
+ {"0SEV;T", 'F'},
{"0SEVC", 'F'},
{"0SEVO(", 'F'},
{"0SEVOF", 'F'},
{"0SEVOS", 'F'},
+ {"0SEVT(", 'F'},
+ {"0SEVT1", 'F'},
+ {"0SEVTF", 'F'},
+ {"0SEVTN", 'F'},
+ {"0SEVTS", 'F'},
+ {"0SEVTV", 'F'},
{"0SEVUE", 'F'},
{"0SF()1", 'F'},
{"0SF()F", 'F'},
@@ -5866,6 +6076,8 @@ static const keyword_t sql_keywords[] = {
{"0SK)EN", 'F'},
{"0SK)ES", 'F'},
{"0SK)EV", 'F'},
+ {"0SK)F(", 'F'},
+ {"0SK)O(", 'F'},
{"0SK)OF", 'F'},
{"0SK)UE", 'F'},
{"0SK1", 'F'},
@@ -6011,6 +6223,7 @@ static const keyword_t sql_keywords[] = {
{"0SO(EF", 'F'},
{"0SO(EK", 'F'},
{"0SO(EN", 'F'},
+ {"0SO(EO", 'F'},
{"0SO(ES", 'F'},
{"0SO(EV", 'F'},
{"0SO(F(", 'F'},
@@ -6043,6 +6256,7 @@ static const keyword_t sql_keywords[] = {
{"0SO1)B", 'F'},
{"0SO1)C", 'F'},
{"0SO1)E", 'F'},
+ {"0SO1)F", 'F'},
{"0SO1)K", 'F'},
{"0SO1)O", 'F'},
{"0SO1)U", 'F'},
@@ -6089,12 +6303,17 @@ static const keyword_t sql_keywords[] = {
{"0SO1N(", 'F'},
{"0SO1N,", 'F'},
{"0SO1NE", 'F'},
- {"0SO1NF", 'F'},
{"0SO1NU", 'F'},
- {"0SO1S(", 'F'},
- {"0SO1SF", 'F'},
{"0SO1SU", 'F'},
{"0SO1SV", 'F'},
+ {"0SO1T(", 'F'},
+ {"0SO1T1", 'F'},
+ {"0SO1TE", 'F'},
+ {"0SO1TF", 'F'},
+ {"0SO1TN", 'F'},
+ {"0SO1TS", 'F'},
+ {"0SO1TT", 'F'},
+ {"0SO1TV", 'F'},
{"0SO1U", 'F'},
{"0SO1U(", 'F'},
{"0SO1U1", 'F'},
@@ -6103,7 +6322,6 @@ static const keyword_t sql_keywords[] = {
{"0SO1UE", 'F'},
{"0SO1UF", 'F'},
{"0SO1UK", 'F'},
- {"0SO1UN", 'F'},
{"0SO1UO", 'F'},
{"0SO1US", 'F'},
{"0SO1UT", 'F'},
@@ -6166,16 +6384,14 @@ static const keyword_t sql_keywords[] = {
{"0SON)B", 'F'},
{"0SON)C", 'F'},
{"0SON)E", 'F'},
+ {"0SON)F", 'F'},
{"0SON)K", 'F'},
{"0SON)O", 'F'},
{"0SON)U", 'F'},
{"0SON,(", 'F'},
{"0SON,F", 'F'},
{"0SON1(", 'F'},
- {"0SON1F", 'F'},
- {"0SON1N", 'F'},
{"0SON1O", 'F'},
- {"0SON1S", 'F'},
{"0SON1U", 'F'},
{"0SON1V", 'F'},
{"0SON;", 'F'},
@@ -6213,6 +6429,14 @@ static const keyword_t sql_keywords[] = {
{"0SONKU", 'F'},
{"0SONKV", 'F'},
{"0SONSU", 'F'},
+ {"0SONT(", 'F'},
+ {"0SONT1", 'F'},
+ {"0SONTE", 'F'},
+ {"0SONTF", 'F'},
+ {"0SONTN", 'F'},
+ {"0SONTS", 'F'},
+ {"0SONTT", 'F'},
+ {"0SONTV", 'F'},
{"0SONU", 'F'},
{"0SONU(", 'F'},
{"0SONU1", 'F'},
@@ -6221,7 +6445,6 @@ static const keyword_t sql_keywords[] = {
{"0SONUE", 'F'},
{"0SONUF", 'F'},
{"0SONUK", 'F'},
- {"0SONUN", 'F'},
{"0SONUO", 'F'},
{"0SONUS", 'F'},
{"0SONUT", 'F'},
@@ -6244,6 +6467,7 @@ static const keyword_t sql_keywords[] = {
{"0SOS)B", 'F'},
{"0SOS)C", 'F'},
{"0SOS)E", 'F'},
+ {"0SOS)F", 'F'},
{"0SOS)K", 'F'},
{"0SOS)O", 'F'},
{"0SOS)U", 'F'},
@@ -6252,7 +6476,6 @@ static const keyword_t sql_keywords[] = {
{"0SOS1(", 'F'},
{"0SOS1F", 'F'},
{"0SOS1N", 'F'},
- {"0SOS1O", 'F'},
{"0SOS1S", 'F'},
{"0SOS1U", 'F'},
{"0SOS1V", 'F'},
@@ -6293,6 +6516,14 @@ static const keyword_t sql_keywords[] = {
{"0SOSKS", 'F'},
{"0SOSKU", 'F'},
{"0SOSKV", 'F'},
+ {"0SOST(", 'F'},
+ {"0SOST1", 'F'},
+ {"0SOSTE", 'F'},
+ {"0SOSTF", 'F'},
+ {"0SOSTN", 'F'},
+ {"0SOSTS", 'F'},
+ {"0SOSTT", 'F'},
+ {"0SOSTV", 'F'},
{"0SOSU", 'F'},
{"0SOSU(", 'F'},
{"0SOSU1", 'F'},
@@ -6301,7 +6532,6 @@ static const keyword_t sql_keywords[] = {
{"0SOSUE", 'F'},
{"0SOSUF", 'F'},
{"0SOSUK", 'F'},
- {"0SOSUN", 'F'},
{"0SOSUO", 'F'},
{"0SOSUS", 'F'},
{"0SOSUT", 'F'},
@@ -6332,6 +6562,7 @@ static const keyword_t sql_keywords[] = {
{"0SOV)B", 'F'},
{"0SOV)C", 'F'},
{"0SOV)E", 'F'},
+ {"0SOV)F", 'F'},
{"0SOV)K", 'F'},
{"0SOV)O", 'F'},
{"0SOV)U", 'F'},
@@ -6385,6 +6616,14 @@ static const keyword_t sql_keywords[] = {
{"0SOVSO", 'F'},
{"0SOVSU", 'F'},
{"0SOVSV", 'F'},
+ {"0SOVT(", 'F'},
+ {"0SOVT1", 'F'},
+ {"0SOVTE", 'F'},
+ {"0SOVTF", 'F'},
+ {"0SOVTN", 'F'},
+ {"0SOVTS", 'F'},
+ {"0SOVTT", 'F'},
+ {"0SOVTV", 'F'},
{"0SOVU", 'F'},
{"0SOVU(", 'F'},
{"0SOVU1", 'F'},
@@ -6393,11 +6632,100 @@ static const keyword_t sql_keywords[] = {
{"0SOVUE", 'F'},
{"0SOVUF", 'F'},
{"0SOVUK", 'F'},
- {"0SOVUN", 'F'},
{"0SOVUO", 'F'},
{"0SOVUS", 'F'},
{"0SOVUT", 'F'},
{"0SOVUV", 'F'},
+ {"0ST(1)", 'F'},
+ {"0ST(1O", 'F'},
+ {"0ST(F(", 'F'},
+ {"0ST(N)", 'F'},
+ {"0ST(NO", 'F'},
+ {"0ST(S)", 'F'},
+ {"0ST(SO", 'F'},
+ {"0ST(V)", 'F'},
+ {"0ST(VO", 'F'},
+ {"0ST1(F", 'F'},
+ {"0ST1O(", 'F'},
+ {"0ST1OF", 'F'},
+ {"0ST1OS", 'F'},
+ {"0ST1OV", 'F'},
+ {"0STE(1", 'F'},
+ {"0STE(F", 'F'},
+ {"0STE(N", 'F'},
+ {"0STE(S", 'F'},
+ {"0STE(V", 'F'},
+ {"0STE1N", 'F'},
+ {"0STE1O", 'F'},
+ {"0STEF(", 'F'},
+ {"0STEK(", 'F'},
+ {"0STEK1", 'F'},
+ {"0STEKF", 'F'},
+ {"0STEKN", 'F'},
+ {"0STEKS", 'F'},
+ {"0STEKV", 'F'},
+ {"0STENN", 'F'},
+ {"0STENO", 'F'},
+ {"0STESN", 'F'},
+ {"0STESO", 'F'},
+ {"0STEVN", 'F'},
+ {"0STEVO", 'F'},
+ {"0STF()", 'F'},
+ {"0STF(1", 'F'},
+ {"0STF(F", 'F'},
+ {"0STF(N", 'F'},
+ {"0STF(S", 'F'},
+ {"0STF(V", 'F'},
+ {"0STN(1", 'F'},
+ {"0STN(F", 'F'},
+ {"0STN(S", 'F'},
+ {"0STN(V", 'F'},
+ {"0STN1C", 'F'},
+ {"0STN1O", 'F'},
+ {"0STN;E", 'F'},
+ {"0STN;N", 'F'},
+ {"0STN;T", 'F'},
+ {"0STNE(", 'F'},
+ {"0STNE1", 'F'},
+ {"0STNEF", 'F'},
+ {"0STNEN", 'F'},
+ {"0STNES", 'F'},
+ {"0STNEV", 'F'},
+ {"0STNF(", 'F'},
+ {"0STNKN", 'F'},
+ {"0STNN:", 'F'},
+ {"0STNNC", 'F'},
+ {"0STNNO", 'F'},
+ {"0STNO(", 'F'},
+ {"0STNOF", 'F'},
+ {"0STNOS", 'F'},
+ {"0STNOV", 'F'},
+ {"0STNSC", 'F'},
+ {"0STNSO", 'F'},
+ {"0STNT(", 'F'},
+ {"0STNT1", 'F'},
+ {"0STNTF", 'F'},
+ {"0STNTN", 'F'},
+ {"0STNTS", 'F'},
+ {"0STNTV", 'F'},
+ {"0STNVC", 'F'},
+ {"0STNVO", 'F'},
+ {"0STS(F", 'F'},
+ {"0STSO(", 'F'},
+ {"0STSO1", 'F'},
+ {"0STSOF", 'F'},
+ {"0STSON", 'F'},
+ {"0STSOS", 'F'},
+ {"0STSOV", 'F'},
+ {"0STTNE", 'F'},
+ {"0STTNK", 'F'},
+ {"0STTNN", 'F'},
+ {"0STTNT", 'F'},
+ {"0STV(1", 'F'},
+ {"0STV(F", 'F'},
+ {"0STVO(", 'F'},
+ {"0STVOF", 'F'},
+ {"0STVOS", 'F'},
{"0SU(1)", 'F'},
{"0SU(1O", 'F'},
{"0SU(E(", 'F'},
@@ -6481,7 +6809,6 @@ static const keyword_t sql_keywords[] = {
{"0SUENU", 'F'},
{"0SUEOK", 'F'},
{"0SUEON", 'F'},
- {"0SUEOO", 'F'},
{"0SUES", 'F'},
{"0SUES&", 'F'},
{"0SUES(", 'F'},
@@ -6517,30 +6844,6 @@ static const keyword_t sql_keywords[] = {
{"0SUF(S", 'F'},
{"0SUF(V", 'F'},
{"0SUK(E", 'F'},
- {"0SUN(1", 'F'},
- {"0SUN(F", 'F'},
- {"0SUN(S", 'F'},
- {"0SUN(V", 'F'},
- {"0SUN,(", 'F'},
- {"0SUN,F", 'F'},
- {"0SUN1(", 'F'},
- {"0SUN1,", 'F'},
- {"0SUN1O", 'F'},
- {"0SUNC", 'F'},
- {"0SUNE(", 'F'},
- {"0SUNE1", 'F'},
- {"0SUNEF", 'F'},
- {"0SUNEN", 'F'},
- {"0SUNES", 'F'},
- {"0SUNEV", 'F'},
- {"0SUNF(", 'F'},
- {"0SUNO(", 'F'},
- {"0SUNOF", 'F'},
- {"0SUNOS", 'F'},
- {"0SUNOV", 'F'},
- {"0SUNS(", 'F'},
- {"0SUNS,", 'F'},
- {"0SUNSO", 'F'},
{"0SUO(E", 'F'},
{"0SUON(", 'F'},
{"0SUON1", 'F'},
@@ -6558,7 +6861,9 @@ static const keyword_t sql_keywords[] = {
{"0SUTN(", 'F'},
{"0SUTN1", 'F'},
{"0SUTNF", 'F'},
+ {"0SUTNN", 'F'},
{"0SUTNS", 'F'},
+ {"0SUTNV", 'F'},
{"0SUV,(", 'F'},
{"0SUV,F", 'F'},
{"0SUVC", 'F'},
@@ -6582,7 +6887,6 @@ static const keyword_t sql_keywords[] = {
{"0SVOSF", 'F'},
{"0SVOSU", 'F'},
{"0SVOSV", 'F'},
- {"0SVS", 'F'},
{"0SVS;", 'F'},
{"0SVS;C", 'F'},
{"0SVSC", 'F'},
@@ -6622,16 +6926,19 @@ static const keyword_t sql_keywords[] = {
{"0T(N1)", 'F'},
{"0T(N1O", 'F'},
{"0T(NF(", 'F'},
+ {"0T(NN)", 'F'},
+ {"0T(NNO", 'F'},
{"0T(NO(", 'F'},
{"0T(NOF", 'F'},
{"0T(NOS", 'F'},
{"0T(NOV", 'F'},
{"0T(NS)", 'F'},
{"0T(NSO", 'F'},
+ {"0T(NV)", 'F'},
+ {"0T(NVO", 'F'},
{"0T(S)F", 'F'},
{"0T(S)O", 'F'},
{"0T(S1)", 'F'},
- {"0T(S1O", 'F'},
{"0T(SF(", 'F'},
{"0T(SN)", 'F'},
{"0T(SNO", 'F'},
@@ -6696,6 +7003,12 @@ static const keyword_t sql_keywords[] = {
{"0TNF(N", 'F'},
{"0TNF(S", 'F'},
{"0TNF(V", 'F'},
+ {"0TNN;", 'F'},
+ {"0TNN;C", 'F'},
+ {"0TNNO(", 'F'},
+ {"0TNNOF", 'F'},
+ {"0TNNOS", 'F'},
+ {"0TNNOV", 'F'},
{"0TNO(1", 'F'},
{"0TNO(F", 'F'},
{"0TNO(N", 'F'},
@@ -6714,6 +7027,9 @@ static const keyword_t sql_keywords[] = {
{"0TNSOS", 'F'},
{"0TNSOV", 'F'},
{"0TNV;", 'F'},
+ {"0TNV;C", 'F'},
+ {"0TNVO(", 'F'},
+ {"0TNVOF", 'F'},
{"0TNVOS", 'F'},
{"0TSF(1", 'F'},
{"0TSF(F", 'F'},
@@ -6944,7 +7260,6 @@ static const keyword_t sql_keywords[] = {
{"0V&1KV", 'F'},
{"0V&1O(", 'F'},
{"0V&1OF", 'F'},
- {"0V&1OO", 'F'},
{"0V&1OS", 'F'},
{"0V&1OV", 'F'},
{"0V&1TN", 'F'},
@@ -7005,6 +7320,7 @@ static const keyword_t sql_keywords[] = {
{"0V&K(S", 'F'},
{"0V&K(V", 'F'},
{"0V&K1O", 'F'},
+ {"0V&KC", 'F'},
{"0V&KF(", 'F'},
{"0V&KNK", 'F'},
{"0V&KO(", 'F'},
@@ -7070,7 +7386,6 @@ static const keyword_t sql_keywords[] = {
{"0V&S1", 'F'},
{"0V&S1;", 'F'},
{"0V&S1C", 'F'},
- {"0V&S1O", 'F'},
{"0V&S;", 'F'},
{"0V&S;C", 'F'},
{"0V&S;E", 'F'},
@@ -7095,7 +7410,6 @@ static const keyword_t sql_keywords[] = {
{"0V&SO1", 'F'},
{"0V&SOF", 'F'},
{"0V&SON", 'F'},
- {"0V&SOO", 'F'},
{"0V&SOS", 'F'},
{"0V&SOV", 'F'},
{"0V&STN", 'F'},
@@ -7141,7 +7455,6 @@ static const keyword_t sql_keywords[] = {
{"0V&VKV", 'F'},
{"0V&VO(", 'F'},
{"0V&VOF", 'F'},
- {"0V&VOO", 'F'},
{"0V&VOS", 'F'},
{"0V&VS", 'F'},
{"0V&VS;", 'F'},
@@ -7278,6 +7591,7 @@ static const keyword_t sql_keywords[] = {
{"0V)ESO", 'F'},
{"0V)EVC", 'F'},
{"0V)EVO", 'F'},
+ {"0V)F(F", 'F'},
{"0V)K(1", 'F'},
{"0V)K(F", 'F'},
{"0V)K(N", 'F'},
@@ -7299,6 +7613,7 @@ static const keyword_t sql_keywords[] = {
{"0V)KN&", 'F'},
{"0V)KN;", 'F'},
{"0V)KNB", 'F'},
+ {"0V)KNC", 'F'},
{"0V)KNE", 'F'},
{"0V)KNK", 'F'},
{"0V)KNU", 'F'},
@@ -7426,11 +7741,13 @@ static const keyword_t sql_keywords[] = {
{"0V;EVT", 'F'},
{"0V;N:T", 'F'},
{"0V;T(1", 'F'},
+ {"0V;T(C", 'F'},
{"0V;T(E", 'F'},
{"0V;T(F", 'F'},
{"0V;T(N", 'F'},
{"0V;T(S", 'F'},
{"0V;T(V", 'F'},
+ {"0V;T1(", 'F'},
{"0V;T1,", 'F'},
{"0V;T1;", 'F'},
{"0V;T1C", 'F'},
@@ -7463,6 +7780,7 @@ static const keyword_t sql_keywords[] = {
{"0V;TNT", 'F'},
{"0V;TNV", 'F'},
{"0V;TO(", 'F'},
+ {"0V;TS(", 'F'},
{"0V;TS,", 'F'},
{"0V;TS;", 'F'},
{"0V;TSC", 'F'},
@@ -7470,12 +7788,8 @@ static const keyword_t sql_keywords[] = {
{"0V;TSK", 'F'},
{"0V;TSO", 'F'},
{"0V;TST", 'F'},
- {"0V;TT(", 'F'},
- {"0V;TT1", 'F'},
- {"0V;TTF", 'F'},
{"0V;TTN", 'F'},
- {"0V;TTS", 'F'},
- {"0V;TTV", 'F'},
+ {"0V;TV(", 'F'},
{"0V;TV,", 'F'},
{"0V;TV;", 'F'},
{"0V;TVC", 'F'},
@@ -7517,7 +7831,6 @@ static const keyword_t sql_keywords[] = {
{"0VB(1)", 'F'},
{"0VB(1O", 'F'},
{"0VB(F(", 'F'},
- {"0VB(N)", 'F'},
{"0VB(NO", 'F'},
{"0VB(S)", 'F'},
{"0VB(SO", 'F'},
@@ -7666,11 +7979,18 @@ static const keyword_t sql_keywords[] = {
{"0VE(SO", 'F'},
{"0VE(V)", 'F'},
{"0VE(VO", 'F'},
+ {"0VE1;T", 'F'},
{"0VE1C", 'F'},
{"0VE1O(", 'F'},
{"0VE1OF", 'F'},
{"0VE1OS", 'F'},
{"0VE1OV", 'F'},
+ {"0VE1T(", 'F'},
+ {"0VE1T1", 'F'},
+ {"0VE1TF", 'F'},
+ {"0VE1TN", 'F'},
+ {"0VE1TS", 'F'},
+ {"0VE1TV", 'F'},
{"0VE1UE", 'F'},
{"0VEF()", 'F'},
{"0VEF(1", 'F'},
@@ -7684,35 +8004,50 @@ static const keyword_t sql_keywords[] = {
{"0VEK(N", 'F'},
{"0VEK(S", 'F'},
{"0VEK(V", 'F'},
+ {"0VEK1;", 'F'},
{"0VEK1C", 'F'},
{"0VEK1O", 'F'},
+ {"0VEK1T", 'F'},
{"0VEK1U", 'F'},
{"0VEKF(", 'F'},
+ {"0VEKN;", 'F'},
{"0VEKNC", 'F'},
{"0VEKNE", 'F'},
+ {"0VEKNT", 'F'},
{"0VEKNU", 'F'},
{"0VEKOK", 'F'},
+ {"0VEKS;", 'F'},
{"0VEKSC", 'F'},
{"0VEKSO", 'F'},
+ {"0VEKST", 'F'},
{"0VEKSU", 'F'},
{"0VEKU(", 'F'},
{"0VEKU1", 'F'},
{"0VEKUE", 'F'},
{"0VEKUF", 'F'},
- {"0VEKUN", 'F'},
{"0VEKUS", 'F'},
{"0VEKUV", 'F'},
+ {"0VEKV;", 'F'},
{"0VEKVC", 'F'},
{"0VEKVO", 'F'},
+ {"0VEKVT", 'F'},
{"0VEKVU", 'F'},
+ {"0VEN;T", 'F'},
{"0VENC", 'F'},
{"0VENEN", 'F'},
{"0VENO(", 'F'},
{"0VENOF", 'F'},
{"0VENOS", 'F'},
{"0VENOV", 'F'},
+ {"0VENT(", 'F'},
+ {"0VENT1", 'F'},
+ {"0VENTF", 'F'},
+ {"0VENTN", 'F'},
+ {"0VENTS", 'F'},
+ {"0VENTV", 'F'},
{"0VENUE", 'F'},
{"0VEOKN", 'F'},
+ {"0VES;T", 'F'},
{"0VESC", 'F'},
{"0VESO(", 'F'},
{"0VESO1", 'F'},
@@ -7720,6 +8055,12 @@ static const keyword_t sql_keywords[] = {
{"0VESON", 'F'},
{"0VESOS", 'F'},
{"0VESOV", 'F'},
+ {"0VEST(", 'F'},
+ {"0VEST1", 'F'},
+ {"0VESTF", 'F'},
+ {"0VESTN", 'F'},
+ {"0VESTS", 'F'},
+ {"0VESTV", 'F'},
{"0VESUE", 'F'},
{"0VEU(1", 'F'},
{"0VEU(F", 'F'},
@@ -7732,19 +8073,23 @@ static const keyword_t sql_keywords[] = {
{"0VEUEF", 'F'},
{"0VEUEK", 'F'},
{"0VEUF(", 'F'},
- {"0VEUN,", 'F'},
- {"0VEUNC", 'F'},
- {"0VEUNO", 'F'},
{"0VEUS,", 'F'},
{"0VEUSC", 'F'},
{"0VEUSO", 'F'},
{"0VEUV,", 'F'},
{"0VEUVC", 'F'},
{"0VEUVO", 'F'},
+ {"0VEV;T", 'F'},
{"0VEVC", 'F'},
{"0VEVO(", 'F'},
{"0VEVOF", 'F'},
{"0VEVOS", 'F'},
+ {"0VEVT(", 'F'},
+ {"0VEVT1", 'F'},
+ {"0VEVTF", 'F'},
+ {"0VEVTN", 'F'},
+ {"0VEVTS", 'F'},
+ {"0VEVTV", 'F'},
{"0VEVUE", 'F'},
{"0VF()1", 'F'},
{"0VF()F", 'F'},
@@ -7802,6 +8147,8 @@ static const keyword_t sql_keywords[] = {
{"0VK)EN", 'F'},
{"0VK)ES", 'F'},
{"0VK)EV", 'F'},
+ {"0VK)F(", 'F'},
+ {"0VK)O(", 'F'},
{"0VK)OF", 'F'},
{"0VK)UE", 'F'},
{"0VK1", 'F'},
@@ -7947,6 +8294,7 @@ static const keyword_t sql_keywords[] = {
{"0VO(EF", 'F'},
{"0VO(EK", 'F'},
{"0VO(EN", 'F'},
+ {"0VO(EO", 'F'},
{"0VO(ES", 'F'},
{"0VO(EV", 'F'},
{"0VO(F(", 'F'},
@@ -8012,6 +8360,7 @@ static const keyword_t sql_keywords[] = {
{"0VOS)B", 'F'},
{"0VOS)C", 'F'},
{"0VOS)E", 'F'},
+ {"0VOS)F", 'F'},
{"0VOS)K", 'F'},
{"0VOS)O", 'F'},
{"0VOS)U", 'F'},
@@ -8020,7 +8369,6 @@ static const keyword_t sql_keywords[] = {
{"0VOS1(", 'F'},
{"0VOS1F", 'F'},
{"0VOS1N", 'F'},
- {"0VOS1O", 'F'},
{"0VOS1S", 'F'},
{"0VOS1U", 'F'},
{"0VOS1V", 'F'},
@@ -8061,6 +8409,14 @@ static const keyword_t sql_keywords[] = {
{"0VOSKS", 'F'},
{"0VOSKU", 'F'},
{"0VOSKV", 'F'},
+ {"0VOST(", 'F'},
+ {"0VOST1", 'F'},
+ {"0VOSTE", 'F'},
+ {"0VOSTF", 'F'},
+ {"0VOSTN", 'F'},
+ {"0VOSTS", 'F'},
+ {"0VOSTT", 'F'},
+ {"0VOSTV", 'F'},
{"0VOSU", 'F'},
{"0VOSU(", 'F'},
{"0VOSU1", 'F'},
@@ -8069,7 +8425,6 @@ static const keyword_t sql_keywords[] = {
{"0VOSUE", 'F'},
{"0VOSUF", 'F'},
{"0VOSUK", 'F'},
- {"0VOSUN", 'F'},
{"0VOSUO", 'F'},
{"0VOSUS", 'F'},
{"0VOSUT", 'F'},
@@ -8082,6 +8437,96 @@ static const keyword_t sql_keywords[] = {
{"0VOU(E", 'F'},
{"0VOUEK", 'F'},
{"0VOUEN", 'F'},
+ {"0VT(1)", 'F'},
+ {"0VT(1O", 'F'},
+ {"0VT(F(", 'F'},
+ {"0VT(N)", 'F'},
+ {"0VT(NO", 'F'},
+ {"0VT(S)", 'F'},
+ {"0VT(SO", 'F'},
+ {"0VT(V)", 'F'},
+ {"0VT(VO", 'F'},
+ {"0VT1(F", 'F'},
+ {"0VT1O(", 'F'},
+ {"0VT1OF", 'F'},
+ {"0VT1OS", 'F'},
+ {"0VT1OV", 'F'},
+ {"0VTE(1", 'F'},
+ {"0VTE(F", 'F'},
+ {"0VTE(N", 'F'},
+ {"0VTE(S", 'F'},
+ {"0VTE(V", 'F'},
+ {"0VTE1N", 'F'},
+ {"0VTE1O", 'F'},
+ {"0VTEF(", 'F'},
+ {"0VTEK(", 'F'},
+ {"0VTEK1", 'F'},
+ {"0VTEKF", 'F'},
+ {"0VTEKN", 'F'},
+ {"0VTEKS", 'F'},
+ {"0VTEKV", 'F'},
+ {"0VTENN", 'F'},
+ {"0VTENO", 'F'},
+ {"0VTESN", 'F'},
+ {"0VTESO", 'F'},
+ {"0VTEVN", 'F'},
+ {"0VTEVO", 'F'},
+ {"0VTF()", 'F'},
+ {"0VTF(1", 'F'},
+ {"0VTF(F", 'F'},
+ {"0VTF(N", 'F'},
+ {"0VTF(S", 'F'},
+ {"0VTF(V", 'F'},
+ {"0VTN(1", 'F'},
+ {"0VTN(F", 'F'},
+ {"0VTN(S", 'F'},
+ {"0VTN(V", 'F'},
+ {"0VTN1C", 'F'},
+ {"0VTN1O", 'F'},
+ {"0VTN;E", 'F'},
+ {"0VTN;N", 'F'},
+ {"0VTN;T", 'F'},
+ {"0VTNE(", 'F'},
+ {"0VTNE1", 'F'},
+ {"0VTNEF", 'F'},
+ {"0VTNEN", 'F'},
+ {"0VTNES", 'F'},
+ {"0VTNEV", 'F'},
+ {"0VTNF(", 'F'},
+ {"0VTNKN", 'F'},
+ {"0VTNN:", 'F'},
+ {"0VTNNC", 'F'},
+ {"0VTNNO", 'F'},
+ {"0VTNO(", 'F'},
+ {"0VTNOF", 'F'},
+ {"0VTNOS", 'F'},
+ {"0VTNOV", 'F'},
+ {"0VTNSC", 'F'},
+ {"0VTNSO", 'F'},
+ {"0VTNT(", 'F'},
+ {"0VTNT1", 'F'},
+ {"0VTNTF", 'F'},
+ {"0VTNTN", 'F'},
+ {"0VTNTS", 'F'},
+ {"0VTNTV", 'F'},
+ {"0VTNVC", 'F'},
+ {"0VTNVO", 'F'},
+ {"0VTS(F", 'F'},
+ {"0VTSO(", 'F'},
+ {"0VTSO1", 'F'},
+ {"0VTSOF", 'F'},
+ {"0VTSON", 'F'},
+ {"0VTSOS", 'F'},
+ {"0VTSOV", 'F'},
+ {"0VTTNE", 'F'},
+ {"0VTTNK", 'F'},
+ {"0VTTNN", 'F'},
+ {"0VTTNT", 'F'},
+ {"0VTV(1", 'F'},
+ {"0VTV(F", 'F'},
+ {"0VTVO(", 'F'},
+ {"0VTVOF", 'F'},
+ {"0VTVOS", 'F'},
{"0VU", 'F'},
{"0VU(1)", 'F'},
{"0VU(1O", 'F'},
@@ -8166,7 +8611,6 @@ static const keyword_t sql_keywords[] = {
{"0VUENU", 'F'},
{"0VUEOK", 'F'},
{"0VUEON", 'F'},
- {"0VUEOO", 'F'},
{"0VUES", 'F'},
{"0VUES&", 'F'},
{"0VUES(", 'F'},
@@ -8202,30 +8646,6 @@ static const keyword_t sql_keywords[] = {
{"0VUF(S", 'F'},
{"0VUF(V", 'F'},
{"0VUK(E", 'F'},
- {"0VUN(1", 'F'},
- {"0VUN(F", 'F'},
- {"0VUN(S", 'F'},
- {"0VUN(V", 'F'},
- {"0VUN,(", 'F'},
- {"0VUN,F", 'F'},
- {"0VUN1(", 'F'},
- {"0VUN1,", 'F'},
- {"0VUN1O", 'F'},
- {"0VUNC", 'F'},
- {"0VUNE(", 'F'},
- {"0VUNE1", 'F'},
- {"0VUNEF", 'F'},
- {"0VUNEN", 'F'},
- {"0VUNES", 'F'},
- {"0VUNEV", 'F'},
- {"0VUNF(", 'F'},
- {"0VUNO(", 'F'},
- {"0VUNOF", 'F'},
- {"0VUNOS", 'F'},
- {"0VUNOV", 'F'},
- {"0VUNS(", 'F'},
- {"0VUNS,", 'F'},
- {"0VUNSO", 'F'},
{"0VUO(E", 'F'},
{"0VUON(", 'F'},
{"0VUON1", 'F'},
@@ -8243,7 +8663,9 @@ static const keyword_t sql_keywords[] = {
{"0VUTN(", 'F'},
{"0VUTN1", 'F'},
{"0VUTNF", 'F'},
+ {"0VUTNN", 'F'},
{"0VUTNS", 'F'},
+ {"0VUTNV", 'F'},
{"0VUV,(", 'F'},
{"0VUV,F", 'F'},
{"0VUVC", 'F'},
@@ -8264,7 +8686,6 @@ static const keyword_t sql_keywords[] = {
{"ABS", 'f'},
{"ACCESSIBLE", 'k'},
{"ACOS", 'f'},
- {"ADD", 'k'},
{"ADDDATE", 'f'},
{"ADDTIME", 'f'},
{"AES_DECRYPT", 'f'},
@@ -8310,6 +8731,10 @@ static const keyword_t sql_keywords[] = {
{"AVG", 'f'},
{"BEFORE", 'k'},
{"BEGIN", 'T'},
+ {"BEGIN DECLARE", 'T'},
+ {"BEGIN GOTO", 'T'},
+ {"BEGIN TRY", 'T'},
+ {"BEGIN TRY DECLARE", 'T'},
{"BENCHMARK", 'f'},
{"BETWEEN", 'o'},
{"BIGINT", 't'},
@@ -8361,7 +8786,7 @@ static const keyword_t sql_keywords[] = {
{"CHAR_LENGTH", 'f'},
{"CHDIR", 'f'},
{"CHDRIVE", 'f'},
- {"CHECK", 'k'},
+ {"CHECK", 'n'},
{"CHECKSUM_AGG", 'f'},
{"CHOOSE", 'f'},
{"CHR", 'f'},
@@ -8466,6 +8891,7 @@ static const keyword_t sql_keywords[] = {
{"DAY_SECOND", 'k'},
{"DBMS_LOCK.SLEEP", 'f'},
{"DBMS_PIPE.RECEIVE_MESSAGE", 'f'},
+ {"DBMS_UTILITY.SQLID_TO_SQLHASH", 'f'},
{"DB_ID", 'f'},
{"DB_NAME", 'f'},
{"DCOUNT", 'f'},
@@ -8544,6 +8970,8 @@ static const keyword_t sql_keywords[] = {
{"FILEGROUP_NAME", 'f'},
{"FILELEN", 'f'},
{"FILEPROPERTY", 'f'},
+ {"FILETOBLOB", 'f'},
+ {"FILETOCLOB", 'f'},
{"FILE_ID", 'f'},
{"FILE_IDEX", 'f'},
{"FILE_NAME", 'f'},
@@ -8611,7 +9039,7 @@ static const keyword_t sql_keywords[] = {
{"IDENT_SEED", 'f'},
{"IF", 'f'},
{"IF EXISTS", 'f'},
- {"IF NOT", 'n'},
+ {"IF NOT", 'f'},
{"IF NOT EXISTS", 'f'},
{"IFF", 'f'},
{"IFNULL", 'f'},
@@ -8676,6 +9104,7 @@ static const keyword_t sql_keywords[] = {
{"IS_USED_LOCK", 'f'},
{"ITERATE", 'k'},
{"JOIN", 'k'},
+ {"JSON_KEYS", 'f'},
{"JULIANDAY", 'f'},
{"JUSTIFY_DAYS", 'f'},
{"JUSTIFY_HOURS", 'f'},
@@ -8694,7 +9123,7 @@ static const keyword_t sql_keywords[] = {
{"LEADING", 'k'},
{"LEAST", 'f'},
{"LEAVE", 'k'},
- {"LEFT", 'n'},
+ {"LEFT", 'f'},
{"LEFT JOIN", 'k'},
{"LEFT OUTER", 'k'},
{"LEFT OUTER JOIN", 'k'},
@@ -8818,7 +9247,7 @@ static const keyword_t sql_keywords[] = {
{"ORDER BY", 'B'},
{"ORIGINAL_DB_NAME", 'f'},
{"ORIGINAL_LOGIN", 'f'},
- {"OUT", 'k'},
+ {"OUT", 'n'},
{"OUTER", 'n'},
{"OUTFILE", 'k'},
{"OVERLAPS", 'f'},
@@ -8987,6 +9416,7 @@ static const keyword_t sql_keywords[] = {
{"SPLIT_PART", 'f'},
{"SQL", 'k'},
{"SQLEXCEPTION", 'k'},
+ {"SQLITE_VERSION", 'f'},
{"SQLSTATE", 'k'},
{"SQLWARNING", 'k'},
{"SQL_BIG_RESULT", 'k'},
@@ -9037,7 +9467,7 @@ static const keyword_t sql_keywords[] = {
{"SYSTEM_USER", 'f'},
{"SYSUSERS", 'k'},
{"SYSUTCDATETME", 'f'},
- {"TABLE", 'k'},
+ {"TABLE", 'n'},
{"TAN", 'f'},
{"TERMINATED", 'k'},
{"TERTIARY_WEIGHTS", 'f'},
@@ -9081,6 +9511,7 @@ static const keyword_t sql_keywords[] = {
{"TRUE", '1'},
{"TRUNC", 'f'},
{"TRUNCATE", 'f'},
+ {"TRY", 'T'},
{"TRY_CAST", 'f'},
{"TRY_CONVERT", 'f'},
{"TRY_PARSE", 'f'},
@@ -9217,5 +9648,5 @@ static const keyword_t sql_keywords[] = {
{"||", '&'},
{"~*", 'o'},
};
-static const size_t sql_keywords_sz = 9049;
+static const size_t sql_keywords_sz = 9352;
#endif
diff --git a/apache2/libinjection/libinjection_xss.c b/apache2/libinjection/libinjection_xss.c
index 2807c22f08..f0df4d84ac 100644
--- a/apache2/libinjection/libinjection_xss.c
+++ b/apache2/libinjection/libinjection_xss.c
@@ -6,13 +6,6 @@
#include
#include
-#ifndef DEBUG
-#include
-#define TRACE() printf("%s:%d\n", __FUNCTION__, __LINE__)
-#else
-#define TRACE()
-#endif
-
typedef enum attribute {
TYPE_NONE
, TYPE_BLACK /* ban always */
@@ -37,109 +30,109 @@ typedef struct stringtype {
static const int gsHexDecodeMap[256] = {
- 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256,
- 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256,
- 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256,
- 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256,
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 256, 256,
- 256, 256, 256, 256, 256, 10, 11, 12, 13, 14, 15, 256,
- 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256,
- 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256,
- 256, 10, 11, 12, 13, 14, 15, 256, 256, 256, 256, 256,
- 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256,
- 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256,
- 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256,
- 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256,
- 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256,
- 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256,
- 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256,
- 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256,
- 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256,
- 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256,
- 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256,
- 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256,
- 256, 256, 256, 256
+ 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256,
+ 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256,
+ 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256,
+ 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256,
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 256, 256,
+ 256, 256, 256, 256, 256, 10, 11, 12, 13, 14, 15, 256,
+ 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256,
+ 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256,
+ 256, 10, 11, 12, 13, 14, 15, 256, 256, 256, 256, 256,
+ 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256,
+ 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256,
+ 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256,
+ 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256,
+ 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256,
+ 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256,
+ 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256,
+ 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256,
+ 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256,
+ 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256,
+ 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256,
+ 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256,
+ 256, 256, 256, 256
};
static int html_decode_char_at(const char* src, size_t len, size_t* consumed)
{
- int val = 0;
- size_t i;
- int ch;
-
- if (len == 0 || src == NULL) {
- *consumed = 0;
- return -1;
- }
-
- *consumed = 1;
- if (*src != '&' || len < 2) {
- return (unsigned char)(*src);
- }
-
-
- if (*(src+1) != '#') {
- /* normally this would be for named entities
- * but for this case we don't actually care
- */
- return '&';
- }
-
- if (*(src+2) == 'x' || *(src+2) == 'X') {
- ch = (unsigned char) (*(src+3));
- ch = gsHexDecodeMap[ch];
- if (ch == 256) {
- /* degenerate case '[?]' */
- return '&';
+ int val = 0;
+ size_t i;
+ int ch;
+
+ if (len == 0 || src == NULL) {
+ *consumed = 0;
+ return -1;
}
- val = ch;
- i = 4;
- while (i < len) {
- ch = (unsigned char) src[i];
- if (ch == ';') {
- *consumed = i + 1;
- return val;
- }
- ch = gsHexDecodeMap[ch];
- if (ch == 256) {
- *consumed = i;
- return val;
- }
- val = (val * 16) + ch;
- if (val > 0x1000FF) {
- return '&';
- }
- ++i;
+
+ *consumed = 1;
+ if (*src != '&' || len < 2) {
+ return (unsigned char)(*src);
}
- *consumed = i;
- return val;
- } else {
- i = 2;
- ch = (unsigned char) src[i];
- if (ch < '0' || ch > '9') {
- return '&';
+
+
+ if (*(src+1) != '#') {
+ /* normally this would be for named entities
+ * but for this case we don't actually care
+ */
+ return '&';
}
- val = ch - '0';
- i += 1;
- while (i < len) {
- ch = (unsigned char) src[i];
- if (ch == ';') {
- *consumed = i + 1;
- return val;
- }
- if (ch < '0' || ch > '9') {
- *consumed = i;
- return val;
- }
- val = (val * 10) + (ch - '0');
- if (val > 0x1000FF) {
- return '&';
- }
- ++i;
+
+ if (*(src+2) == 'x' || *(src+2) == 'X') {
+ ch = (unsigned char) (*(src+3));
+ ch = gsHexDecodeMap[ch];
+ if (ch == 256) {
+ /* degenerate case '[?]' */
+ return '&';
+ }
+ val = ch;
+ i = 4;
+ while (i < len) {
+ ch = (unsigned char) src[i];
+ if (ch == ';') {
+ *consumed = i + 1;
+ return val;
+ }
+ ch = gsHexDecodeMap[ch];
+ if (ch == 256) {
+ *consumed = i;
+ return val;
+ }
+ val = (val * 16) + ch;
+ if (val > 0x1000FF) {
+ return '&';
+ }
+ ++i;
+ }
+ *consumed = i;
+ return val;
+ } else {
+ i = 2;
+ ch = (unsigned char) src[i];
+ if (ch < '0' || ch > '9') {
+ return '&';
+ }
+ val = ch - '0';
+ i += 1;
+ while (i < len) {
+ ch = (unsigned char) src[i];
+ if (ch == ';') {
+ *consumed = i + 1;
+ return val;
+ }
+ if (ch < '0' || ch > '9') {
+ *consumed = i;
+ return val;
+ }
+ val = (val * 10) + (ch - '0');
+ if (val > 0x1000FF) {
+ return '&';
+ }
+ ++i;
+ }
+ *consumed = i;
+ return val;
}
- *consumed = i;
- return val;
- }
}
@@ -157,7 +150,7 @@ static stringtype_t BLACKATTR[] = {
, { "DATASRC", TYPE_BLACK } /* IE */
, { "DYNSRC", TYPE_ATTR_URL } /* Obsolete img attribute */
, { "FILTER", TYPE_STYLE } /* Opera, SVG inline style */
- , { "FORMACTION", TYPE_ATTR_URL } /* HTML5 */
+ , { "FORMACTION", TYPE_ATTR_URL } /* HTML 5 */
, { "FOLDER", TYPE_ATTR_URL } /* Only on A tags, IE-only */
, { "FROM", TYPE_ATTR_URL } /* SVG */
, { "HANDLER", TYPE_ATTR_URL } /* SVG Tiny, Opera */
@@ -173,20 +166,20 @@ static stringtype_t BLACKATTR[] = {
};
/* xmlns */
-/* xml-stylesheet > , */
+/* `xml-stylesheet` > , */
/*
-static const char* BLACKATTR[] = {
- "ATTRIBUTENAME",
- "BACKGROUND",
- "DATAFORMATAS",
- "HREF",
- "SCROLL",
- "SRC",
- "STYLE",
- "SRCDOC",
- NULL
-};
+ static const char* BLACKATTR[] = {
+ "ATTRIBUTENAME",
+ "BACKGROUND",
+ "DATAFORMATAS",
+ "HREF",
+ "SCROLL",
+ "SRC",
+ "STYLE",
+ "SRCDOC",
+ NULL
+ };
*/
static const char* BLACKTAG[] = {
@@ -220,36 +213,36 @@ static const char* BLACKTAG[] = {
static int cstrcasecmp_with_null(const char *a, const char *b, size_t n)
{
- char ca;
- char cb;
- /* printf("Comparing to %s %.*s\n", a, (int)n, b); */
- while (n-- > 0) {
- cb = *b++;
- if (cb == '\0') continue;
+ char ca;
+ char cb;
+ /* printf("Comparing to %s %.*s\n", a, (int)n, b); */
+ while (n-- > 0) {
+ cb = *b++;
+ if (cb == '\0') continue;
- ca = *a++;
+ ca = *a++;
- if (cb >= 'a' && cb <= 'z') {
- cb -= 0x20;
- }
- /* printf("Comparing %c vs %c with %d left\n", ca, cb, (int)n); */
- if (ca != cb) {
- return 1;
+ if (cb >= 'a' && cb <= 'z') {
+ cb -= 0x20;
+ }
+ /* printf("Comparing %c vs %c with %d left\n", ca, cb, (int)n); */
+ if (ca != cb) {
+ return 1;
+ }
}
- }
- if (*a == 0) {
- /* printf(" MATCH \n"); */
- return 0;
- } else {
- return 1;
- }
+ if (*a == 0) {
+ /* printf(" MATCH \n"); */
+ return 0;
+ } else {
+ return 1;
+ }
}
/*
- * Does an HTML encoded binary string (const char*, lenght) start with
- * a all uppercase c-string (null terminated), case insenstive!
- *
+ * Does an HTML encoded binary string (const char*, length) start with
+ * a all uppercase c-string (null terminated), case insensitive!
+ *
* also ignore any embedded nulls in the HTML string!
*
* return 1 if match / starts with
@@ -257,47 +250,47 @@ static int cstrcasecmp_with_null(const char *a, const char *b, size_t n)
*/
static int htmlencode_startswith(const char *a, const char *b, size_t n)
{
- size_t consumed;
- int cb;
- int first = 1;
- /* printf("Comparing %s with %.*s\n", a,(int)n,b); */
+ size_t consumed;
+ int cb;
+ int first = 1;
+ /* printf("Comparing %s with %.*s\n", a,(int)n,b); */
while (n > 0) {
- if (*a == 0) {
- /* printf("Match EOL!\n"); */
- return 1;
- }
- cb = html_decode_char_at(b, n, &consumed);
- b += consumed;
- n -= consumed;
-
- if (first && cb <= 32) {
- /* ignore all leading whitespace and control characters */
- continue;
- }
- first = 0;
+ if (*a == 0) {
+ /* printf("Match EOL!\n"); */
+ return 1;
+ }
+ cb = html_decode_char_at(b, n, &consumed);
+ b += consumed;
+ n -= consumed;
+
+ if (first && cb <= 32) {
+ /* ignore all leading whitespace and control characters */
+ continue;
+ }
+ first = 0;
if (cb == 0) {
- /* always ignore null characters in user input */
- continue;
- }
+ /* always ignore null characters in user input */
+ continue;
+ }
if (cb == 10) {
- /* always ignore vtab characters in user input */
- /* who allows this?? */
- continue;
- }
+ /* always ignore vertical tab characters in user input */
+ /* who allows this?? */
+ continue;
+ }
if (cb >= 'a' && cb <= 'z') {
- /* upcase */
+ /* upcase */
cb -= 0x20;
}
if (*a != (char) cb) {
- /* printf(" %c != %c\n", *a, cb); */
- /* mismatch */
- return 0;
+ /* printf(" %c != %c\n", *a, cb); */
+ /* mismatch */
+ return 0;
}
- a++;
+ a++;
}
return (*a == 0) ? 1 : 0;
@@ -313,8 +306,8 @@ static int is_black_tag(const char* s, size_t len)
black = BLACKTAG;
while (*black != NULL) {
- if (cstrcasecmp_with_null(*black, s, len) == 0) {
- /* printf("Got black tag %s\n", *black); */
+ if (cstrcasecmp_with_null(*black, s, len) == 0) {
+ /* printf("Got black tag %s\n", *black); */
return 1;
}
black += 1;
@@ -324,7 +317,7 @@ static int is_black_tag(const char* s, size_t len)
if ((s[0] == 's' || s[0] == 'S') &&
(s[1] == 'v' || s[1] == 'V') &&
(s[2] == 'g' || s[2] == 'G')) {
- /* printf("Got SVG tag \n"); */
+ /* printf("Got SVG tag \n"); */
return 1;
}
@@ -332,7 +325,7 @@ static int is_black_tag(const char* s, size_t len)
if ((s[0] == 'x' || s[0] == 'X') &&
(s[1] == 's' || s[1] == 'S') &&
(s[2] == 'l' || s[2] == 'L')) {
- /* printf("Got XSL tag\n"); */
+ /* printf("Got XSL tag\n"); */
return 1;
}
@@ -347,17 +340,18 @@ static attribute_t is_black_attr(const char* s, size_t len)
return TYPE_NONE;
}
- /* javascript on.* */
- if ((s[0] == 'o' || s[0] == 'O') && (s[1] == 'n' || s[1] == 'N')) {
- /* printf("Got javascript on- attribute name\n"); */
- return TYPE_BLACK;
- }
+ if (len >= 5) {
+ /* JavaScript on.* */
+ if ((s[0] == 'o' || s[0] == 'O') && (s[1] == 'n' || s[1] == 'N')) {
+ /* printf("Got JavaScript on- attribute name\n"); */
+ return TYPE_BLACK;
+ }
+
- if (len >= 5) {
/* XMLNS can be used to create arbitrary tags */
if (cstrcasecmp_with_null("XMLNS", s, 5) == 0 || cstrcasecmp_with_null("XLINK", s, 5) == 0) {
- /* printf("Got XMLNS and XLINK tags\n"); */
+ /* printf("Got XMLNS and XLINK tags\n"); */
return TYPE_BLACK;
}
}
@@ -365,7 +359,7 @@ static attribute_t is_black_attr(const char* s, size_t len)
black = BLACKATTR;
while (black->name != NULL) {
if (cstrcasecmp_with_null(black->name, s, len) == 0) {
- /* printf("Got banned attribute name %s\n", black->name); */
+ /* printf("Got banned attribute name %s\n", black->name); */
return black->atype;
}
black += 1;
@@ -387,20 +381,18 @@ static int is_black_url(const char* s, size_t len)
static const char* javascript_url = "JAVA";
/* skip whitespace */
- while (len > 0) {
+ while (len > 0 && (*s <= 32 || *s >= 127)) {
/*
* HEY: this is a signed character.
* We are intentionally skipping high-bit characters too
- * since they are not ascii, and Opera sometimes uses UTF8 whitespace
+ * since they are not ASCII, and Opera sometimes uses UTF-8 whitespace.
+ *
+ * Also in EUC-JP some of the high bytes are just ignored.
*/
- if (*s <= 32) {
- ++s;
- --len;
- }
- break;
+ ++s;
+ --len;
}
-
if (htmlencode_startswith(data_url, s, len)) {
return 1;
}
@@ -442,16 +434,16 @@ int libinjection_is_xss(const char* s, size_t len, int flags)
/*
* IE6,7,8 parsing works a bit differently so
* a whole