diff options
| author | BeF | 2022-07-20 12:15:07 +0200 |
|---|---|---|
| committer | GitHub | 2022-07-20 12:15:07 +0200 |
| commit | 2aed4220c2d019cc9b46fec70cfd79d249498e14 (patch) | |
| tree | e7cc3d1d4db617fc5ab1dbcc60f2366407eb5da5 | |
| parent | 72109c9bf016145364b19162a5ff998fc5858a9c (diff) | |
| parent | 75595945d1d868fbd6db743809ca8a3eb5de3113 (diff) | |
Merge pull request #1 from jvoisin/pr1
pr for fetching upstream
49 files changed, 1082 insertions, 830 deletions
diff --git a/.github/workflows/distributions_php7.yml b/.github/workflows/distributions_php7.yml index 12fa207..60eedd2 100644 --- a/.github/workflows/distributions_php7.yml +++ b/.github/workflows/distributions_php7.yml | |||
| @@ -94,28 +94,3 @@ jobs: | |||
| 94 | if: ${{ failure() }} | 94 | if: ${{ failure() }} |
| 95 | run: | | 95 | run: | |
| 96 | grep -r . --include='*.log' src/tests | 96 | grep -r . --include='*.log' src/tests |
| 97 | |||
| 98 | alpine: | ||
| 99 | runs-on: ubuntu-latest | ||
| 100 | container: alpine:latest | ||
| 101 | steps: | ||
| 102 | - name: Checkout code | ||
| 103 | uses: actions/checkout@v2 | ||
| 104 | - name: Remove php8 tests for php7 | ||
| 105 | run: rm -rf src/tests/*php8*/ src/tests/*/*_php8.phpt | ||
| 106 | - name: Remove tests failing on alpine for wathever reason | ||
| 107 | run: rm -rf src/tests/cookies_encryption_warning src/tests/upload_validation/upload_validation.phpt /tests/broken_configuration/encrypt_regexp_cookies_bad_regexp.phpt | ||
| 108 | - name: Install dependencies | ||
| 109 | run: apk add php7-dev php7-cgi php7-simplexml php7-xml pcre-dev build-base php7-pear php7-openssl php7-session bash grep re2c | ||
| 110 | - name: Install pecl | ||
| 111 | continue-on-error: true | ||
| 112 | run: pecl install vld-beta | ||
| 113 | - name: Build SP and run the testsuite | ||
| 114 | run: | | ||
| 115 | make release | ||
| 116 | ln -s $(php -r 'echo ini_get("extension_dir");')/* src/modules/ | ||
| 117 | make tests | ||
| 118 | - name: Show logs in case of failure | ||
| 119 | if: ${{ failure() }} | ||
| 120 | run: | | ||
| 121 | grep -r . --include='*.log' src/tests | ||
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..6d8d3d7 --- /dev/null +++ b/.github/workflows/release.yml | |||
| @@ -0,0 +1,71 @@ | |||
| 1 | name: Release Builder | ||
| 2 | on: | ||
| 3 | push: | ||
| 4 | branches: | ||
| 5 | - "release-*" | ||
| 6 | tags: | ||
| 7 | - "v*" | ||
| 8 | pull_request: | ||
| 9 | branches: | ||
| 10 | - "release-*" | ||
| 11 | |||
| 12 | jobs: | ||
| 13 | build-deb: | ||
| 14 | runs-on: ubuntu-latest | ||
| 15 | name: ${{ matrix.name }} | ||
| 16 | container: ${{ matrix.container }} | ||
| 17 | strategy: | ||
| 18 | fail-fast: false | ||
| 19 | matrix: | ||
| 20 | name: | ||
| 21 | [ | ||
| 22 | "debian-buster", | ||
| 23 | "debian-stretch", | ||
| 24 | "debian-bullseye", | ||
| 25 | "debian-sid", | ||
| 26 | "debian-bookworm", | ||
| 27 | "ubuntu-bionic", | ||
| 28 | "ubuntu-focal", | ||
| 29 | "ubuntu-jammy", | ||
| 30 | "ubuntu-impish", | ||
| 31 | ] | ||
| 32 | include: | ||
| 33 | - name: debian-buster | ||
| 34 | container: debian:buster | ||
| 35 | - name: debian-stretch | ||
| 36 | container: debian:stretch | ||
| 37 | - name: debian-bullseye | ||
| 38 | container: debian:bullseye | ||
| 39 | - name: debian-sid | ||
| 40 | container: debian:sid | ||
| 41 | - name: debian-bookworm | ||
| 42 | container: debian:bookworm | ||
| 43 | - name: ubuntu-bionic | ||
| 44 | container: ubuntu:bionic | ||
| 45 | - name: ubuntu-focal | ||
| 46 | container: ubuntu:focal | ||
| 47 | - name: ubuntu-jammy | ||
| 48 | container: ubuntu:jammy | ||
| 49 | - name: ubuntu-impish | ||
| 50 | container: ubuntu:impish | ||
| 51 | steps: | ||
| 52 | - name: Checkout code | ||
| 53 | uses: actions/checkout@v2 | ||
| 54 | - name: Set timezone | ||
| 55 | if: startsWith(matrix.container, 'ubuntu:') | ||
| 56 | run: ln -snf /usr/share/zoneinfo/Europe/Paris /etc/localtime && echo Europe/Paris > /etc/timezone | ||
| 57 | - name: Update OS | ||
| 58 | run: apt-get -qqy update | ||
| 59 | - name: Install deps | ||
| 60 | run: DEBIAN_FRONTEND=noninteractive apt-get -qqy --no-install-recommends install fakeroot php-xml php-curl dpkg-dev gcc make libpcre3-dev dh-php php-dev build-essential | ||
| 61 | - name: Build debs | ||
| 62 | run: DPKG_SKIP_TESTS=1 dpkg-buildpackage -i -us -uc -tc -I -rfakeroot | ||
| 63 | - name: Move built debs and rename | ||
| 64 | run: | | ||
| 65 | mv -v ../*.deb ./ | ||
| 66 | ls *.deb | xargs -I % mv -v % ${{ matrix.name }}-% | ||
| 67 | - name: Upload artifacts | ||
| 68 | uses: actions/upload-artifact@v3 | ||
| 69 | with: | ||
| 70 | name: snuffleupagus-${{ matrix.name }} | ||
| 71 | path: ./*.deb | ||
| @@ -88,7 +88,7 @@ without having to touch the PHP code. | |||
| 88 | * Every commit is tested on [several distributions](https://gitlab.com/jvoisin/snuffleupagus/pipelines) | 88 | * Every commit is tested on [several distributions](https://gitlab.com/jvoisin/snuffleupagus/pipelines) |
| 89 | * An `clang-format`-enforced code style | 89 | * An `clang-format`-enforced code style |
| 90 | * A [comprehensive documentation](https://snuffleupagus.rtfd.io) | 90 | * A [comprehensive documentation](https://snuffleupagus.rtfd.io) |
| 91 | * Usage of [coverity](https://scan.coverity.com/projects/jvoisin-snuffleupagus) | 91 | * Usage of [coverity](https://scan.coverity.com/projects/jvoisin-snuffleupagus), codeql, [scan-build](https://clang-analyzer.llvm.org/scan-build.html), … |
| 92 | 92 | ||
| 93 | ## Download | 93 | ## Download |
| 94 | 94 | ||
diff --git a/config/default.rules b/config/default.rules index f6d8893..a19d678 100644 --- a/config/default.rules +++ b/config/default.rules | |||
| @@ -49,8 +49,8 @@ sp.disable_function.function("putenv").param("setting").value_r("LD_").drop() | |||
| 49 | sp.disable_function.function("putenv").param("setting").value_r("GCONV_").drop() | 49 | sp.disable_function.function("putenv").param("setting").value_r("GCONV_").drop() |
| 50 | 50 | ||
| 51 | # Since people are stupid enough to use `extract` on things like $_GET or $_POST, we might as well mitigate this vector | 51 | # Since people are stupid enough to use `extract` on things like $_GET or $_POST, we might as well mitigate this vector |
| 52 | sp.disable_function.function("extract").param("var_array").value_r("^_").drop() | 52 | sp.disable_function.function("extract").pos("0").value_r("^_").drop() |
| 53 | sp.disable_function.function("extract").param("extract_type").value("0").drop() | 53 | sp.disable_function.function("extract").pos("1").value("0").drop() |
| 54 | 54 | ||
| 55 | # This is also burned: | 55 | # This is also burned: |
| 56 | # ini_set('open_basedir','..');chdir('..');…;chdir('..');ini_set('open_basedir','/');echo(file_get_contents('/etc/passwd')); | 56 | # ini_set('open_basedir','..');chdir('..');…;chdir('..');ini_set('open_basedir','/');echo(file_get_contents('/etc/passwd')); |
| @@ -71,7 +71,7 @@ sp.disable_function.function("include").drop() | |||
| 71 | 71 | ||
| 72 | # Prevent `system`-related injections | 72 | # Prevent `system`-related injections |
| 73 | sp.disable_function.function("system").param("command").value_r("[$|;&`\\n\\(\\)\\\\]").drop(); | 73 | sp.disable_function.function("system").param("command").value_r("[$|;&`\\n\\(\\)\\\\]").drop(); |
| 74 | sp.disable_function.function("shell_exec").param("command").value_r("[$|;&`\\n\\(\\)\\\\]").drop(); | 74 | sp.disable_function.function("shell_exec").pos("0").value_r("[$|;&`\\n\\(\\)\\\\]").drop(); |
| 75 | sp.disable_function.function("exec").param("command").value_r("[$|;&`\\n\\(\\)\\\\]").drop(); | 75 | sp.disable_function.function("exec").param("command").value_r("[$|;&`\\n\\(\\)\\\\]").drop(); |
| 76 | sp.disable_function.function("proc_open").param("command").value_r("[$|;&`\\n\\(\\)\\\\]").drop(); | 76 | sp.disable_function.function("proc_open").param("command").value_r("[$|;&`\\n\\(\\)\\\\]").drop(); |
| 77 | 77 | ||
diff --git a/debian/changelog b/debian/changelog index 51ca43d..034a34d 100644 --- a/debian/changelog +++ b/debian/changelog | |||
| @@ -1,3 +1,39 @@ | |||
| 1 | snuffleupagus (0.8.2) UNRELEASED; urgency=low | ||
| 2 | [ jvoisin ] | ||
| 3 | * Fix compilation when ZTS is used | ||
| 4 | * Fix a possible infinite loop | ||
| 5 | |||
| 6 | -- jvoisin <julien.voisin+snuffleupagus@dustri.org> Sun, 20 Apr 2022 22:00:00 +0200 | ||
| 7 | |||
| 8 | snuffleupagus (0.8.1) UNRELEASED; urgency=low | ||
| 9 | [ jvoisin ] | ||
| 10 | * Fix the version number | ||
| 11 | * Fix a test on PHP7 | ||
| 12 | |||
| 13 | -- jvoisin <julien.voisin+snuffleupagus@dustri.org> Sun, 16 Apr 2022 19:45:00 +0200 | ||
| 14 | |||
| 15 | snuffleupagus (0.8.0) UNRELEASED; urgency=low | ||
| 16 | [ jvoisin ] | ||
| 17 | * Compatibility with PHP8.1 | ||
| 18 | * Check for unsupported PHP version | ||
| 19 | * Backport of Suhosin-ng patches: | ||
| 20 | * Maximum stack depth/recursion limit | ||
| 21 | * Maximum length for session id | ||
| 22 | * $_SERVER strip/encode | ||
| 23 | * Configuration dump | ||
| 24 | * Support for conditional rules | ||
| 25 | * INI settings protection | ||
| 26 | * Output SP logs to stderr | ||
| 27 | * Ported Suhosin rules to SP | ||
| 28 | * Massive simplification of the configuration parser | ||
| 29 | * Better memory management | ||
| 30 | * Removal of internal calls to `call_user_func` | ||
| 31 | * Increased portability of the default rules access different version of PHP | ||
| 32 | * Start SP as late as possible, to hook as many things as possible | ||
| 33 | * XML and Session support are now checked at runtime instead of at compile time | ||
| 34 | |||
| 35 | -- jvoisin <julien.voisin+snuffleupagus@dustri.org> Sun, 15 Apr 2022 18:00:00 +0200 | ||
| 36 | |||
| 1 | snuffleupagus (0.7.1) UNRELEASED; urgency=low | 37 | snuffleupagus (0.7.1) UNRELEASED; urgency=low |
| 2 | [ jvoisin ] | 38 | [ jvoisin ] |
| 3 | * Fixed possible memory-leaks when hooking via regular expressions | 39 | * Fixed possible memory-leaks when hooking via regular expressions |
diff --git a/debian/control b/debian/control index 9e313b6..03fa0fd 100644 --- a/debian/control +++ b/debian/control | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | Source: snuffleupagus | 1 | Source: snuffleupagus |
| 2 | Priority: optional | 2 | Priority: optional |
| 3 | Maintainer: Julien (jvoisin) Voisin <julien.voisin+snuffleupagus@dustri.org> | 3 | Maintainer: Julien (jvoisin) Voisin <julien.voisin+snuffleupagus@dustri.org> |
| 4 | Build-Depends: debhelper (>= 9), php-curl, php-xml, php7.0-dev | php7.1-dev | php7.2-dev | php7.3-dev | php7.4-dev | php8.0-dev | 4 | Build-Depends: debhelper (>= 9), php-curl, php-xml, php7.0-dev | php7.1-dev | php7.2-dev | php7.3-dev | php7.4-dev | php8.0-dev | php8.1-dev |
| 5 | Standards-Version: 4.1.3 | 5 | Standards-Version: 4.1.3 |
| 6 | Homepage: https://github.com/jvoisin/snuffleupagus | 6 | Homepage: https://github.com/jvoisin/snuffleupagus |
| 7 | Section: php | 7 | Section: php |
diff --git a/debian/rules b/debian/rules index 70965bb..40eb4ac 100755 --- a/debian/rules +++ b/debian/rules | |||
| @@ -27,5 +27,9 @@ override_dh_auto_install: | |||
| 27 | install -m 644 -o root -g root config/snuffleupagus.ini debian/snuffleupagus/etc/php/$$(/usr/bin/php-config --version | cut -d '.' -f1-2)/mods-available/snuffleupagus.ini | 27 | install -m 644 -o root -g root config/snuffleupagus.ini debian/snuffleupagus/etc/php/$$(/usr/bin/php-config --version | cut -d '.' -f1-2)/mods-available/snuffleupagus.ini |
| 28 | 28 | ||
| 29 | override_dh_auto_test: | 29 | override_dh_auto_test: |
| 30 | ifeq ($(strip $(DPKG_SKIP_TESTS)),) | ||
| 30 | sed -i "s/\$$ext_params -d display_errors=0 -r/-d display_errors=0 -r/" src/run-tests.php | 31 | sed -i "s/\$$ext_params -d display_errors=0 -r/-d display_errors=0 -r/" src/run-tests.php |
| 31 | TEST_PHP_ARGS="-q" REPORT_EXIST_STATUS=1 make -C src test | 32 | TEST_PHP_ARGS="-q" REPORT_EXIST_STATUS=1 make -C src test |
| 33 | else | ||
| 34 | echo "skip tests" | ||
| 35 | endif \ No newline at end of file | ||
diff --git a/doc/source/changelog.rst b/doc/source/changelog.rst index 6eaccd2..a406953 100644 --- a/doc/source/changelog.rst +++ b/doc/source/changelog.rst | |||
| @@ -1,32 +1,76 @@ | |||
| 1 | Changelog | 1 | Changelog |
| 2 | ========= | 2 | ========= |
| 3 | 3 | ||
| 4 | 0.8.0 - Woolly Mammoth | 4 | 0.8.2 - `Surus <https://github.com/jvoisin/snuffleupagus/releases/tag/v0.8.2>`__ 2022/05/20 |
| 5 | ---------------------- | 5 | ------------------------------------------------------------------------------------------- |
| 6 | 6 | ||
| 7 | - Massive simplification of the configuration parser | 7 | Bug fixes |
| 8 | - Better memory management | 8 | ^^^^^^^^^ |
| 9 | - Removal of internal calls to `call_user_func` | 9 | * Fix compilation when ZTS is used |
| 10 | - Check for unsupported PHP version | 10 | * Fix a possible infinite loop |
| 11 | - Compatibility with PHP8.1 | 11 | |
| 12 | - Suhosin features backports: | 12 | |
| 13 | - Maximum stack depth/recursion limit | 13 | 0.8.1 - `Batyr <https://github.com/jvoisin/snuffleupagus/releases/tag/v0.8.1>`__ 2022/05/16 |
| 14 | - Maximum length for session id | 14 | ------------------------------------------------------------------------------------------- |
| 15 | |||
| 16 | Bug fixes | ||
| 17 | ^^^^^^^^^ | ||
| 18 | * Fix the version number | ||
| 19 | * Fix a test on PHP7 | ||
| 20 | |||
| 21 | Breaking Changes | ||
| 22 | ^^^^^^^^^^^^^^^^ | ||
| 23 | * `disable_xxe` is changed to `xxe_protection` | ||
| 24 | |||
| 25 | |||
| 26 | 0.8.0 - `Woolly Mammoth <https://github.com/jvoisin/snuffleupagus/releases/tag/v0.8.0>`__ 2022/05/15 | ||
| 27 | ----------------------------------------------------------------------------------------------------- | ||
| 28 | |||
| 29 | New features | ||
| 30 | ^^^^^^^^^^^^ | ||
| 31 | * Compatibility with PHP8.1 | ||
| 32 | * Check for unsupported PHP version | ||
| 33 | * Backport of Suhosin-ng patches: | ||
| 34 | * Maximum stack depth/recursion limit | ||
| 35 | * Maximum length for session id | ||
| 36 | * $_SERVER strip/encode | ||
| 37 | * Configuration dump | ||
| 38 | * Support for conditional rules | ||
| 39 | * INI settings protection | ||
| 40 | * Output SP logs to stderr | ||
| 41 | * Ported Suhosin rules to SP | ||
| 42 | |||
| 43 | Improvements | ||
| 44 | ^^^^^^^^^^^^ | ||
| 45 | * Massive simplification of the configuration parser | ||
| 46 | * Better memory management | ||
| 47 | * Removal of internal calls to `call_user_func` | ||
| 48 | * Increased portability of the default rules access different version of PHP | ||
| 49 | * Start SP as late as possible, to hook as many things as possible | ||
| 50 | |||
| 51 | Bug fixes | ||
| 52 | ^^^^^^^^^ | ||
| 53 | * XML and Session support are now checked at runtime instead of at compile time | ||
| 15 | 54 | ||
| 16 | 55 | ||
| 17 | 0.7.1 - `Proboscidea <https://github.com/jvoisin/snuffleupagus/releases/tag/v0.7.0>`__ 2021/08/02 | 56 | 0.7.1 - `Proboscidea <https://github.com/jvoisin/snuffleupagus/releases/tag/v0.7.0>`__ 2021/08/02 |
| 18 | ------------------------------------------------------------------------------------------------- | 57 | ------------------------------------------------------------------------------------------------- |
| 19 | 58 | ||
| 20 | * Fixed possible memory-leaks when hooking via regular expressions | 59 | Improvements |
| 21 | * Modernise the code by removing usage of `strtok` | 60 | ^^^^^^^^^^^^ |
| 22 | * Prevent a possible crash during configuration reloading | ||
| 23 | * Fix the default rules to catch dangerous `chmod` calls | ||
| 24 | * Improve compatibility with various `libpcre` configurations/versions | 61 | * Improve compatibility with various `libpcre` configurations/versions |
| 62 | * Modernise the code by removing usage of `strtok` | ||
| 25 | * Improve the default rules' compatibility with php8 | 63 | * Improve the default rules' compatibility with php8 |
| 26 | * Prevent XXE in php8 as well | 64 | * Prevent XXE in php8 as well |
| 27 | * Improve a bit the verbosity of the logs | 65 | * Improve a bit the verbosity of the logs |
| 28 | * Add a rules file for php8 | 66 | * Add a rules file for php8 |
| 29 | 67 | ||
| 68 | Bug fixes | ||
| 69 | ^^^^^^^^^ | ||
| 70 | * Prevent a possible crash during configuration reloading | ||
| 71 | * Fix the default rules to catch dangerous `chmod` calls | ||
| 72 | * Fixed possible memory-leaks when hooking via regular expressions | ||
| 73 | |||
| 30 | 74 | ||
| 31 | 0.7.0 - `Los Elefantes <https://github.com/jvoisin/snuffleupagus/releases/tag/v0.7.0>`__ 2021/01/02 | 75 | 0.7.0 - `Los Elefantes <https://github.com/jvoisin/snuffleupagus/releases/tag/v0.7.0>`__ 2021/01/02 |
| 32 | --------------------------------------------------------------------------------------------------- | 76 | --------------------------------------------------------------------------------------------------- |
| @@ -46,7 +90,7 @@ Improvements | |||
| 46 | 90 | ||
| 47 | Bug fixes | 91 | Bug fixes |
| 48 | ^^^^^^^^^ | 92 | ^^^^^^^^^ |
| 49 | * The strict mode is now disableable | 93 | * The strict mode can now be disabled |
| 50 | 94 | ||
| 51 | 95 | ||
| 52 | 0.6.0 - `Elephant in the room <https://github.com/jvoisin/snuffleupagus/releases/tag/v0.6.0>`__ 2020/11/06 | 96 | 0.6.0 - `Elephant in the room <https://github.com/jvoisin/snuffleupagus/releases/tag/v0.6.0>`__ 2020/11/06 |
diff --git a/doc/source/config.rst b/doc/source/config.rst index 0b7b7fd..d7f7f24 100644 --- a/doc/source/config.rst +++ b/doc/source/config.rst | |||
| @@ -75,6 +75,19 @@ The terminating ``;`` is optional for now, but it should be used for future comp | |||
| 75 | Miscellaneous | 75 | Miscellaneous |
| 76 | ------------- | 76 | ------------- |
| 77 | 77 | ||
| 78 | conditions | ||
| 79 | ^^^^^^^^^^ | ||
| 80 | |||
| 81 | It's possible to use conditions to have configuration portables accross | ||
| 82 | several setups. | ||
| 83 | |||
| 84 | :: | ||
| 85 | @condition PHP_VERSION_ID < 80000; | ||
| 86 | # some rules | ||
| 87 | @condition PHP_VERSION_ID >= 80000; | ||
| 88 | # some other rules | ||
| 89 | @end_condition; | ||
| 90 | |||
| 78 | global | 91 | global |
| 79 | ^^^^^^ | 92 | ^^^^^^ |
| 80 | 93 | ||
| @@ -261,6 +274,9 @@ readonly_exec | |||
| 261 | the execution of writeable PHP files. | 274 | the execution of writeable PHP files. |
| 262 | 275 | ||
| 263 | It can either be ``enabled`` or ``disabled`` and can be used in ``simulation`` mode. | 276 | It can either be ``enabled`` or ``disabled`` and can be used in ``simulation`` mode. |
| 277 | ``extended_checks`` can be specified to abort the execution if the executed | ||
| 278 | file or the folder containing it is owned by the user the PHP process is | ||
| 279 | running under. | ||
| 264 | 280 | ||
| 265 | :: | 281 | :: |
| 266 | 282 | ||
diff --git a/doc/source/papers.rst b/doc/source/papers.rst index 3d043f0..d13f33a 100644 --- a/doc/source/papers.rst +++ b/doc/source/papers.rst | |||
| @@ -123,9 +123,14 @@ Notable users | |||
| 123 | 123 | ||
| 124 | - `AdwCleaner <https://www.malwarebytes.com/adwcleaner/>`__'s backend- a notorious anti-pup | 124 | - `AdwCleaner <https://www.malwarebytes.com/adwcleaner/>`__'s backend- a notorious anti-pup |
| 125 | - `Alertot <https://www.alertot.com/>`__ - a Chilean continuous web security monitoring company | 125 | - `Alertot <https://www.alertot.com/>`__ - a Chilean continuous web security monitoring company |
| 126 | - `Control Web Panel <https://control-webpanel.com/>`__ - a free modern and intuitive control panel for servers and VPS | ||
| 127 | - `Mangadex <https://mangadex.dev/mangadex-v5-infrastructure-overview/>`__ - a major manga website | ||
| 126 | - `NBS System <https://www.nbs-system.com/>`__ - a French hosting/security company and author of snuffleupagus | 128 | - `NBS System <https://www.nbs-system.com/>`__ - a French hosting/security company and author of snuffleupagus |
| 127 | - `Net4All <https://net4all.ch/>`__ - a Swiss hosting company | 129 | - `Net4All <https://net4all.ch/>`__ - a Swiss hosting company |
| 128 | - `Oceanet Technology <https://www.oceanet-technology.com/>`__ - a French hosting company | 130 | - `Oceanet Technology <https://www.oceanet-technology.com/>`__ - a French hosting company |
| 131 | - The `Swedish team <https://ccdcoe.org/news/2021/sweden-scored-highest-at-the-cyber-defence-exercise-locked-shields-2021/>`__ | ||
| 132 | of the `NATO <https://www.nato.int/>`__'s `CCDCOE <https://ccdcoe.org/>`__ | ||
| 133 | `Locked Shields <https://ccdcoe.org/exercises/locked-shields/>`__ exercise. | ||
| 129 | - `SwissCenter <https://swisscenter.com>`__ - a Swiss datacenter & web hosting company | 134 | - `SwissCenter <https://swisscenter.com>`__ - a Swiss datacenter & web hosting company |
| 130 | - `Toolslib <https://toolslib.net/>`__ - an `Alexa top 10k <https://www.alexa.com/siteinfo/toolslib.net>`__ website | 135 | - `Toolslib <https://toolslib.net/>`__ - an `Alexa top 10k <https://www.alexa.com/siteinfo/toolslib.net>`__ website |
| 131 | - `cPanel <https://cpanel.net/>`__ - one of the most popular web hosting control panel | 136 | - `cPanel <https://cpanel.net/>`__ - one of the most popular web hosting control panel |
diff --git a/src/Makefile.frag b/src/Makefile.frag index e110544..454ba60 100644 --- a/src/Makefile.frag +++ b/src/Makefile.frag | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | $(srcdir)/sp_config_scanner.c: $(srcdir)/sp_config_scanner.re | 1 | $(srcdir)/sp_config_scanner.c: $(srcdir)/sp_config_scanner.re |
| 2 | if re2c -v |grep ' 2\.' 2>/dev/null; then \ | 2 | if re2c -v |grep ' [23]\.' 2>/dev/null; then \ |
| 3 | re2c -bc -o $@ $<; \ | 3 | re2c -bc -o $@ $<; \ |
| 4 | re2c --no-generation-date --no-version -bci -o $(srcdir)/sp_config_scanner.cached.c $<; \ | 4 | re2c --no-generation-date --no-version -bci -o $(srcdir)/sp_config_scanner.cached.c $<; \ |
| 5 | else \ | 5 | else \ |
diff --git a/src/php_snuffleupagus.h b/src/php_snuffleupagus.h index 8dc7ccb..3eeb9db 100644 --- a/src/php_snuffleupagus.h +++ b/src/php_snuffleupagus.h | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | #ifndef PHP_SNUFFLEUPAGUS_H | 1 | #ifndef PHP_SNUFFLEUPAGUS_H |
| 2 | #define PHP_SNUFFLEUPAGUS_H | 2 | #define PHP_SNUFFLEUPAGUS_H |
| 3 | 3 | ||
| 4 | #define PHP_SNUFFLEUPAGUS_VERSION "0.8.0" | 4 | #define PHP_SNUFFLEUPAGUS_VERSION "0.8.2" |
| 5 | #define PHP_SNUFFLEUPAGUS_EXTNAME "snuffleupagus" | 5 | #define PHP_SNUFFLEUPAGUS_EXTNAME "snuffleupagus" |
| 6 | #define PHP_SNUFFLEUPAGUS_AUTHOR "NBS System & Julien (jvoisin) Voisin & SektionEins GmbH" | 6 | #define PHP_SNUFFLEUPAGUS_AUTHOR "NBS System & Julien (jvoisin) Voisin & SektionEins GmbH" |
| 7 | #define PHP_SNUFFLEUPAGUS_URL "https://github.com/jvoisin/snuffleupagus" | 7 | #define PHP_SNUFFLEUPAGUS_URL "https://github.com/jvoisin/snuffleupagus" |
| @@ -11,6 +11,12 @@ | |||
| 11 | #include "config.h" | 11 | #include "config.h" |
| 12 | #endif | 12 | #endif |
| 13 | 13 | ||
| 14 | #ifdef PHP_WIN32 | ||
| 15 | #include "win32/glob.h" | ||
| 16 | #else | ||
| 17 | #include <glob.h> | ||
| 18 | #endif | ||
| 19 | |||
| 14 | #include <errno.h> | 20 | #include <errno.h> |
| 15 | #include <fcntl.h> | 21 | #include <fcntl.h> |
| 16 | #include <inttypes.h> | 22 | #include <inttypes.h> |
| @@ -32,6 +38,7 @@ | |||
| 32 | #include "ext/standard/head.h" | 38 | #include "ext/standard/head.h" |
| 33 | #include "ext/standard/info.h" | 39 | #include "ext/standard/info.h" |
| 34 | #include "ext/standard/url.h" | 40 | #include "ext/standard/url.h" |
| 41 | #include "ext/standard/php_string.h" | ||
| 35 | #include "ext/standard/php_var.h" | 42 | #include "ext/standard/php_var.h" |
| 36 | #include "ext/session/php_session.h" | 43 | #include "ext/session/php_session.h" |
| 37 | #include "php.h" | 44 | #include "php.h" |
| @@ -41,6 +48,7 @@ | |||
| 41 | #include "zend_extensions.h" | 48 | #include "zend_extensions.h" |
| 42 | #include "zend_hash.h" | 49 | #include "zend_hash.h" |
| 43 | #include "zend_string.h" | 50 | #include "zend_string.h" |
| 51 | #include "zend_smart_str.h" | ||
| 44 | #include "zend_types.h" | 52 | #include "zend_types.h" |
| 45 | #include "zend_vm.h" | 53 | #include "zend_vm.h" |
| 46 | 54 | ||
| @@ -148,6 +156,13 @@ u_long execution_depth; | |||
| 148 | HashTable *disabled_functions_hook; | 156 | HashTable *disabled_functions_hook; |
| 149 | HashTable *sp_internal_functions_hook; | 157 | HashTable *sp_internal_functions_hook; |
| 150 | HashTable *sp_eval_blacklist_functions_hook; | 158 | HashTable *sp_eval_blacklist_functions_hook; |
| 159 | |||
| 160 | #if PHP_VERSION_ID >= 80000 | ||
| 161 | const zend_string* eval_source_string; | ||
| 162 | #else | ||
| 163 | const zval* eval_source_string; | ||
| 164 | #endif | ||
| 165 | |||
| 151 | ZEND_END_MODULE_GLOBALS(snuffleupagus) | 166 | ZEND_END_MODULE_GLOBALS(snuffleupagus) |
| 152 | 167 | ||
| 153 | ZEND_EXTERN_MODULE_GLOBALS(snuffleupagus) | 168 | ZEND_EXTERN_MODULE_GLOBALS(snuffleupagus) |
diff --git a/src/snuffleupagus.c b/src/snuffleupagus.c index 74af0ed..30f6b3d 100644 --- a/src/snuffleupagus.c +++ b/src/snuffleupagus.c | |||
| @@ -1,11 +1,3 @@ | |||
| 1 | #ifdef PHP_WIN32 | ||
| 2 | #include "win32/glob.h" | ||
| 3 | #else | ||
| 4 | #include <glob.h> | ||
| 5 | #endif | ||
| 6 | |||
| 7 | #include "zend_smart_str.h" | ||
| 8 | |||
| 9 | #include "php_snuffleupagus.h" | 1 | #include "php_snuffleupagus.h" |
| 10 | 2 | ||
| 11 | #ifndef ZEND_EXT_API | 3 | #ifndef ZEND_EXT_API |
| @@ -262,7 +254,7 @@ PHP_MINFO_FUNCTION(snuffleupagus) { | |||
| 262 | #define ADD_ASSOC_ZSTR(arr, key, zstr) if (zstr) { add_assoc_str(arr, key, zstr); } else { add_assoc_null(arr, key); } | 254 | #define ADD_ASSOC_ZSTR(arr, key, zstr) if (zstr) { add_assoc_str(arr, key, zstr); } else { add_assoc_null(arr, key); } |
| 263 | #define ADD_ASSOC_REGEXP(arr, key, regexp) if (regexp && regexp->pattern) { add_assoc_str(arr, key, regexp->pattern); } else { add_assoc_null(arr, key); } | 255 | #define ADD_ASSOC_REGEXP(arr, key, regexp) if (regexp && regexp->pattern) { add_assoc_str(arr, key, regexp->pattern); } else { add_assoc_null(arr, key); } |
| 264 | 256 | ||
| 265 | static void add_df_to_arr(zval *arr, sp_disabled_function *df) { | 257 | static void add_df_to_arr(zval *arr, sp_disabled_function const *const df) { |
| 266 | zval arr_df; | 258 | zval arr_df; |
| 267 | array_init(&arr_df); | 259 | array_init(&arr_df); |
| 268 | 260 | ||
| @@ -375,7 +367,7 @@ static void dump_config() { | |||
| 375 | if (splist) { \ | 367 | if (splist) { \ |
| 376 | zval arr_sp; \ | 368 | zval arr_sp; \ |
| 377 | array_init(&arr_sp); \ | 369 | array_init(&arr_sp); \ |
| 378 | for (sp_list_node *p = splist; p; p = p->next) { add_next_index_str(&arr_sp, p->data); } \ | 370 | for (const sp_list_node *p = splist; p; p = p->next) { add_next_index_str(&arr_sp, p->data); } \ |
| 379 | add_assoc_zval(arr, key, &arr_sp); \ | 371 | add_assoc_zval(arr, key, &arr_sp); \ |
| 380 | } else { add_assoc_null(arr, key); } | 372 | } else { add_assoc_null(arr, key); } |
| 381 | 373 | ||
| @@ -391,6 +383,8 @@ static void dump_config() { | |||
| 391 | 383 | ||
| 392 | ADD_ASSOC_SPLIST(&arr, SP_TOKEN_ALLOW_WRAPPERS, SPCFG(wrapper).whitelist); | 384 | ADD_ASSOC_SPLIST(&arr, SP_TOKEN_ALLOW_WRAPPERS, SPCFG(wrapper).whitelist); |
| 393 | 385 | ||
| 386 | #undef ADD_ASSOC_SPLIST | ||
| 387 | |||
| 394 | add_assoc_bool(&arr, SP_TOKEN_INI_PROTECTION "." SP_TOKEN_ENABLE, SPCFG(ini).enable); | 388 | add_assoc_bool(&arr, SP_TOKEN_INI_PROTECTION "." SP_TOKEN_ENABLE, SPCFG(ini).enable); |
| 395 | add_assoc_bool(&arr, SP_TOKEN_INI_PROTECTION "." SP_TOKEN_SIM, SPCFG(ini).simulation); | 389 | add_assoc_bool(&arr, SP_TOKEN_INI_PROTECTION "." SP_TOKEN_SIM, SPCFG(ini).simulation); |
| 396 | add_assoc_bool(&arr, SP_TOKEN_INI_PROTECTION "." "policy_ro", SPCFG(ini).policy_readonly); | 390 | add_assoc_bool(&arr, SP_TOKEN_INI_PROTECTION "." "policy_ro", SPCFG(ini).policy_readonly); |
| @@ -402,7 +396,7 @@ static void dump_config() { | |||
| 402 | zval arr_ini; | 396 | zval arr_ini; |
| 403 | array_init(&arr_ini); | 397 | array_init(&arr_ini); |
| 404 | 398 | ||
| 405 | sp_ini_entry *sp_entry; | 399 | const sp_ini_entry *sp_entry; |
| 406 | ZEND_HASH_FOREACH_PTR(SPCFG(ini).entries, sp_entry) | 400 | ZEND_HASH_FOREACH_PTR(SPCFG(ini).entries, sp_entry) |
| 407 | zval arr_ini_entry; | 401 | zval arr_ini_entry; |
| 408 | array_init(&arr_ini_entry); | 402 | array_init(&arr_ini_entry); |
| @@ -428,7 +422,7 @@ static void dump_config() { | |||
| 428 | array_init(&arr_cookies); | 422 | array_init(&arr_cookies); |
| 429 | 423 | ||
| 430 | sp_cookie *cookie; | 424 | sp_cookie *cookie; |
| 431 | sp_list_node *p = SPCFG(cookie).cookies; | 425 | const sp_list_node *p = SPCFG(cookie).cookies; |
| 432 | for (; p; p = p->next) { | 426 | for (; p; p = p->next) { |
| 433 | zval arr_cookie; | 427 | zval arr_cookie; |
| 434 | array_init(&arr_cookie); | 428 | array_init(&arr_cookie); |
| @@ -452,7 +446,8 @@ static void dump_config() { | |||
| 452 | zval arr_dfs; | 446 | zval arr_dfs; |
| 453 | array_init(&arr_dfs); | 447 | array_init(&arr_dfs); |
| 454 | size_t num_df = 0; | 448 | size_t num_df = 0; |
| 455 | sp_list_node *dflist, *dfp; | 449 | const sp_list_node *dflist; |
| 450 | const sp_list_node *dfp; | ||
| 456 | ZEND_HASH_FOREACH_PTR(SPCFG(disabled_functions), dflist) | 451 | ZEND_HASH_FOREACH_PTR(SPCFG(disabled_functions), dflist) |
| 457 | for (dfp = dflist; dfp; dfp = dfp->next) { | 452 | for (dfp = dflist; dfp; dfp = dfp->next) { |
| 458 | add_df_to_arr(&arr_dfs, dfp->data); | 453 | add_df_to_arr(&arr_dfs, dfp->data); |
| @@ -608,12 +603,14 @@ static PHP_INI_MH(OnUpdateConfiguration) { | |||
| 608 | (SPCFG(disabled_functions_ret) && zend_hash_num_elements(SPCFG(disabled_functions_ret))); | 603 | (SPCFG(disabled_functions_ret) && zend_hash_num_elements(SPCFG(disabled_functions_ret))); |
| 609 | 604 | ||
| 610 | if (SPCFG(show_old_php_warning) && getenv("SP_SKIP_OLD_PHP_CHECK") == NULL) { | 605 | if (SPCFG(show_old_php_warning) && getenv("SP_SKIP_OLD_PHP_CHECK") == NULL) { |
| 611 | time_t ts = time(NULL); | 606 | const time_t ts = time(NULL); |
| 612 | if ((PHP_VERSION_ID < 70300) || | 607 | if ((PHP_VERSION_ID < 70300) || |
| 613 | (PHP_VERSION_ID < 70400 && ts >= (time_t)1638745200L) || | 608 | (PHP_VERSION_ID < 70400 && ts >= (time_t)1638745200L) || |
| 614 | (PHP_VERSION_ID < 80000 && ts >= (time_t)1669590000L) || | 609 | (PHP_VERSION_ID < 80000 && ts >= (time_t)1669590000L) || |
| 615 | (PHP_VERSION_ID < 80100 && ts >= (time_t)1700953200L)) { | 610 | (PHP_VERSION_ID < 80100 && ts >= (time_t)1700953200L)) { |
| 616 | sp_log_warn("End-of-Life Check", "Your PHP version '" PHP_VERSION "' is not officially mainained anymore. Please upgrade as soon as possible. - Note: This message can be switched off by setting 'sp.global.show_old_php_warning.disable();' in your rules file or by setting the environment variable SP_SKIP_OLD_PHP_CHECK=1."); | 611 | sp_log_warn("End-of-Life Check", "Your PHP version '" PHP_VERSION "' is not officially maintained anymore. " \ |
| 612 | "Please upgrade as soon as possible. - Note: This message can be switched off by setting " \ | ||
| 613 | "'sp.global.show_old_php_warning.disable();' in your rules file or by setting the environment variable SP_SKIP_OLD_PHP_CHECK=1."); | ||
| 617 | } | 614 | } |
| 618 | } | 615 | } |
| 619 | return SUCCESS; | 616 | return SUCCESS; |
diff --git a/src/sp_config.c b/src/sp_config.c index 7294b0e..ff6cdd9 100644 --- a/src/sp_config.c +++ b/src/sp_config.c | |||
| @@ -4,9 +4,7 @@ | |||
| 4 | 4 | ||
| 5 | #include "php_snuffleupagus.h" | 5 | #include "php_snuffleupagus.h" |
| 6 | 6 | ||
| 7 | 7 | static const sp_config_keyword sp_func[] = { | |
| 8 | static zend_result sp_process_config_root(sp_parsed_keyword *parsed_rule) { | ||
| 9 | sp_config_keyword sp_func[] = { | ||
| 10 | {parse_unserialize, SP_TOKEN_UNSERIALIZE_HMAC, &(SPCFG(unserialize))}, | 8 | {parse_unserialize, SP_TOKEN_UNSERIALIZE_HMAC, &(SPCFG(unserialize))}, |
| 11 | {parse_enable, SP_TOKEN_HARDEN_RANDOM, &(SPCFG(random).enable)}, | 9 | {parse_enable, SP_TOKEN_HARDEN_RANDOM, &(SPCFG(random).enable)}, |
| 12 | {parse_log_media, SP_TOKEN_LOG_MEDIA, &(SPCFG(log_media))}, | 10 | {parse_log_media, SP_TOKEN_LOG_MEDIA, &(SPCFG(log_media))}, |
| @@ -25,11 +23,14 @@ static zend_result sp_process_config_root(sp_parsed_keyword *parsed_rule) { | |||
| 25 | {parse_wrapper_whitelist, SP_TOKEN_ALLOW_WRAPPERS, &(SPCFG(wrapper))}, | 23 | {parse_wrapper_whitelist, SP_TOKEN_ALLOW_WRAPPERS, &(SPCFG(wrapper))}, |
| 26 | {parse_ini_protection, SP_TOKEN_INI_PROTECTION, &(SPCFG(ini))}, | 24 | {parse_ini_protection, SP_TOKEN_INI_PROTECTION, &(SPCFG(ini))}, |
| 27 | {parse_ini_entry, SP_TOKEN_INI, NULL}, | 25 | {parse_ini_entry, SP_TOKEN_INI, NULL}, |
| 28 | {NULL, NULL, NULL}}; | 26 | {NULL, NULL, NULL} |
| 27 | }; | ||
| 28 | |||
| 29 | static zend_result sp_process_config_root(sp_parsed_keyword *parsed_rule) { | ||
| 29 | return sp_process_rule(parsed_rule, sp_func); | 30 | return sp_process_rule(parsed_rule, sp_func); |
| 30 | } | 31 | } |
| 31 | 32 | ||
| 32 | zend_result sp_parse_config(const char *filename) { | 33 | zend_result sp_parse_config(const char *const filename) { |
| 33 | FILE *fd = fopen(filename, "rb"); | 34 | FILE *fd = fopen(filename, "rb"); |
| 34 | if (fd == NULL) { | 35 | if (fd == NULL) { |
| 35 | sp_log_err("config", "Could not open configuration file %s : %s", filename, strerror(errno)); | 36 | sp_log_err("config", "Could not open configuration file %s : %s", filename, strerror(errno)); |
| @@ -65,10 +66,10 @@ zend_result sp_parse_config(const char *filename) { | |||
| 65 | } | 66 | } |
| 66 | 67 | ||
| 67 | 68 | ||
| 68 | zend_result sp_process_rule(sp_parsed_keyword *parsed_rule, sp_config_keyword *config_keywords) { | 69 | zend_result sp_process_rule(sp_parsed_keyword *parsed_rule, const sp_config_keyword *const config_keywords) { |
| 69 | for (sp_parsed_keyword *kw = parsed_rule; kw->kw; kw++) { | 70 | for (sp_parsed_keyword *kw = parsed_rule; kw->kw; kw++) { |
| 70 | bool found_kw = false; | 71 | bool found_kw = false; |
| 71 | for (sp_config_keyword *ckw = config_keywords; ckw->func; ckw++) { | 72 | for (const sp_config_keyword *ckw = config_keywords; ckw->func; ckw++) { |
| 72 | if (kw->kwlen == strlen(ckw->token) && !strncmp(kw->kw, ckw->token, kw->kwlen)) { | 73 | if (kw->kwlen == strlen(ckw->token) && !strncmp(kw->kw, ckw->token, kw->kwlen)) { |
| 73 | if (ckw->func) { | 74 | if (ckw->func) { |
| 74 | int ret = ckw->func(ckw->token, kw, ckw->retval); | 75 | int ret = ckw->func(ckw->token, kw, ckw->retval); |
| @@ -119,13 +120,12 @@ SP_PARSEKW_FN(parse_list) { | |||
| 119 | CHECK_DUPLICATE_KEYWORD(retval); | 120 | CHECK_DUPLICATE_KEYWORD(retval); |
| 120 | 121 | ||
| 121 | sp_list_node **list = retval; | 122 | sp_list_node **list = retval; |
| 122 | char *tok, *tmp; | ||
| 123 | 123 | ||
| 124 | SP_PARSE_ARG(value); | 124 | SP_PARSE_ARG(value); |
| 125 | 125 | ||
| 126 | tmp = ZSTR_VAL(value); | 126 | char* tmp = ZSTR_VAL(value); |
| 127 | while (1) { | 127 | while (1) { |
| 128 | tok = strsep(&tmp, ","); | 128 | const char* const tok = strsep(&tmp, ","); |
| 129 | if (tok == NULL) { | 129 | if (tok == NULL) { |
| 130 | break; | 130 | break; |
| 131 | } | 131 | } |
diff --git a/src/sp_config.h b/src/sp_config.h index e7d4e4d..ec73310 100644 --- a/src/sp_config.h +++ b/src/sp_config.h | |||
| @@ -177,7 +177,7 @@ typedef struct { | |||
| 177 | HashTable *entries; // ht of sp_ini_entry | 177 | HashTable *entries; // ht of sp_ini_entry |
| 178 | } sp_config_ini; | 178 | } sp_config_ini; |
| 179 | 179 | ||
| 180 | #define SP_PARSE_FN_(fname, kwvar) int fname(char *token, sp_parsed_keyword *kwvar, void *retval) | 180 | #define SP_PARSE_FN_(fname, kwvar) int fname(char const *const token, sp_parsed_keyword *kwvar, void *retval) |
| 181 | #define SP_PARSE_FN(fname) SP_PARSE_FN_(fname, parsed_rule) | 181 | #define SP_PARSE_FN(fname) SP_PARSE_FN_(fname, parsed_rule) |
| 182 | #define SP_PARSEKW_FN(fname) SP_PARSE_FN_(fname, kw) | 182 | #define SP_PARSEKW_FN(fname) SP_PARSE_FN_(fname, kw) |
| 183 | 183 | ||
| @@ -270,9 +270,9 @@ typedef struct { | |||
| 270 | 270 | ||
| 271 | #define SP_TOKEN_LIST "list" | 271 | #define SP_TOKEN_LIST "list" |
| 272 | 272 | ||
| 273 | zend_result sp_process_rule(sp_parsed_keyword *parsed_rule, sp_config_keyword *config_keywords); | 273 | zend_result sp_process_rule(sp_parsed_keyword *parsed_rule, const sp_config_keyword *const config_keywords); |
| 274 | 274 | ||
| 275 | zend_result sp_parse_config(const char *filename); | 275 | zend_result sp_parse_config(const char *const filename); |
| 276 | 276 | ||
| 277 | #define SP_PARSE_CHECK_ARG_EXISTS(value) \ | 277 | #define SP_PARSE_CHECK_ARG_EXISTS(value) \ |
| 278 | if (!value) { \ | 278 | if (!value) { \ |
diff --git a/src/sp_config_keywords.c b/src/sp_config_keywords.c index c3ef24e..fa26635 100644 --- a/src/sp_config_keywords.c +++ b/src/sp_config_keywords.c | |||
| @@ -417,10 +417,8 @@ SP_PARSE_FN(parse_disabled_functions) { | |||
| 417 | return SP_PARSER_STOP; | 417 | return SP_PARSER_STOP; |
| 418 | 418 | ||
| 419 | out: | 419 | out: |
| 420 | if (df) { | 420 | sp_free_disabled_function(df); |
| 421 | sp_free_disabled_function(df); | 421 | pefree(df, 1); |
| 422 | pefree(df, 1); | ||
| 423 | } | ||
| 424 | if (param) { zend_string_release(param); } | 422 | if (param) { zend_string_release(param); } |
| 425 | if (var) { zend_string_release(var); } | 423 | if (var) { zend_string_release(var); } |
| 426 | 424 | ||
diff --git a/src/sp_config_scanner.cached.c b/src/sp_config_scanner.cached.c index 7617ebf..3114918 100644 --- a/src/sp_config_scanner.cached.c +++ b/src/sp_config_scanner.cached.c | |||
| @@ -1,6 +1,8 @@ | |||
| 1 | /* Generated by re2c */ | 1 | /* Generated by re2c */ |
| 2 | #include "php_snuffleupagus.h" | 2 | #include "php_snuffleupagus.h" |
| 3 | 3 | ||
| 4 | #pragma GCC diagnostic ignored "-Wmaybe-uninitialized" | ||
| 5 | |||
| 4 | enum YYCONDTYPE { | 6 | enum YYCONDTYPE { |
| 5 | yycinit, | 7 | yycinit, |
| 6 | yyccond, | 8 | yyccond, |
| @@ -14,7 +16,7 @@ enum YYCONDTYPE { | |||
| 14 | #define cs_log_warning(fmt, ...) sp_log_warn("config", fmt, ##__VA_ARGS__) | 16 | #define cs_log_warning(fmt, ...) sp_log_warn("config", fmt, ##__VA_ARGS__) |
| 15 | 17 | ||
| 16 | 18 | ||
| 17 | zend_string *sp_get_arg_string(sp_parsed_keyword *kw) { | 19 | zend_string *sp_get_arg_string(sp_parsed_keyword const *const kw) { |
| 18 | if (!kw || !kw->arg) { | 20 | if (!kw || !kw->arg) { |
| 19 | return NULL; | 21 | return NULL; |
| 20 | } | 22 | } |
| @@ -40,11 +42,10 @@ zend_string *sp_get_arg_string(sp_parsed_keyword *kw) { | |||
| 40 | return ret; | 42 | return ret; |
| 41 | } | 43 | } |
| 42 | 44 | ||
| 43 | zend_string *sp_get_textual_representation(sp_parsed_keyword *parsed_rule) { | 45 | zend_string *sp_get_textual_representation(sp_parsed_keyword const *const parsed_rule) { |
| 44 | // a rule is "sp.keyword...keyword(arg);\0" | 46 | // a rule is "sp.keyword...keyword(arg);\0" |
| 45 | size_t len = 3; // sp + ; | 47 | size_t len = 3; // sp + ; |
| 46 | sp_parsed_keyword *kw; | 48 | for (const sp_parsed_keyword *kw = parsed_rule; kw->kw; kw++) { |
| 47 | for (kw = parsed_rule; kw->kw; kw++) { | ||
| 48 | len++; // . | 49 | len++; // . |
| 49 | len += kw->kwlen; | 50 | len += kw->kwlen; |
| 50 | if (kw->argtype == SP_ARGTYPE_EMPTY) { | 51 | if (kw->argtype == SP_ARGTYPE_EMPTY) { |
| @@ -54,10 +55,12 @@ zend_string *sp_get_textual_representation(sp_parsed_keyword *parsed_rule) { | |||
| 54 | len += kw->arglen; | 55 | len += kw->arglen; |
| 55 | } | 56 | } |
| 56 | } | 57 | } |
| 58 | |||
| 57 | zend_string *ret = zend_string_alloc(len, 1); | 59 | zend_string *ret = zend_string_alloc(len, 1); |
| 58 | char *ptr = ZSTR_VAL(ret); | 60 | char *ptr = ZSTR_VAL(ret); |
| 61 | |||
| 59 | memcpy(ptr, "sp", 2); ptr += 2; | 62 | memcpy(ptr, "sp", 2); ptr += 2; |
| 60 | for (kw = parsed_rule; kw->kw; kw++) { | 63 | for (const sp_parsed_keyword *kw = parsed_rule; kw->kw; kw++) { |
| 61 | *ptr++ = '.'; | 64 | *ptr++ = '.'; |
| 62 | memcpy(ptr, kw->kw, kw->kwlen); ptr += kw->kwlen; | 65 | memcpy(ptr, kw->kw, kw->kwlen); ptr += kw->kwlen; |
| 63 | if (kw->argtype == SP_ARGTYPE_EMPTY || kw->argtype == SP_ARGTYPE_STR || kw->argtype == SP_ARGTYPE_UNKNOWN) { | 66 | if (kw->argtype == SP_ARGTYPE_EMPTY || kw->argtype == SP_ARGTYPE_STR || kw->argtype == SP_ARGTYPE_UNKNOWN) { |
| @@ -227,361 +230,361 @@ yyc_init: | |||
| 227 | }; | 230 | }; |
| 228 | yych = *YYCURSOR; | 231 | yych = *YYCURSOR; |
| 229 | if (yybm[0+yych] & 8) { | 232 | if (yybm[0+yych] & 8) { |
| 230 | goto yy6; | 233 | goto yy4; |
| 231 | } | 234 | } |
| 232 | if (yych <= '#') { | 235 | if (yych <= '#') { |
| 233 | if (yych <= '\n') { | 236 | if (yych <= '\n') { |
| 234 | if (yych <= 0x00) goto yy2; | 237 | if (yych <= 0x00) goto yy1; |
| 235 | if (yych <= 0x08) goto yy4; | 238 | if (yych <= 0x08) goto yy2; |
| 236 | goto yy9; | 239 | goto yy5; |
| 237 | } else { | 240 | } else { |
| 238 | if (yych == '\r') goto yy11; | 241 | if (yych == '\r') goto yy6; |
| 239 | if (yych <= '"') goto yy4; | 242 | if (yych <= '"') goto yy2; |
| 240 | goto yy12; | 243 | goto yy7; |
| 241 | } | 244 | } |
| 242 | } else { | 245 | } else { |
| 243 | if (yych <= '?') { | 246 | if (yych <= '?') { |
| 244 | if (yych == ';') goto yy12; | 247 | if (yych == ';') goto yy7; |
| 245 | goto yy4; | 248 | goto yy2; |
| 246 | } else { | 249 | } else { |
| 247 | if (yych <= '@') goto yy15; | 250 | if (yych <= '@') goto yy8; |
| 248 | if (yych == 's') goto yy16; | 251 | if (yych == 's') goto yy9; |
| 249 | goto yy4; | 252 | goto yy2; |
| 250 | } | 253 | } |
| 251 | } | 254 | } |
| 252 | yy2: | 255 | yy1: |
| 253 | ++YYCURSOR; | 256 | ++YYCURSOR; |
| 254 | { ret = SUCCESS; goto out; } | 257 | { ret = SUCCESS; goto out; } |
| 255 | yy4: | 258 | yy2: |
| 256 | ++YYCURSOR; | 259 | ++YYCURSOR; |
| 257 | yy5: | 260 | yy3: |
| 258 | { cs_log_error("Parser error on line %d", lineno); goto out; } | 261 | { cs_log_error("Parser error on line %d", lineno); goto out; } |
| 259 | yy6: | 262 | yy4: |
| 260 | yych = *++YYCURSOR; | 263 | yych = *++YYCURSOR; |
| 261 | if (yybm[0+yych] & 8) { | 264 | if (yybm[0+yych] & 8) { |
| 262 | goto yy6; | 265 | goto yy4; |
| 263 | } | 266 | } |
| 264 | { goto yyc_init; } | 267 | { goto yyc_init; } |
| 265 | yy9: | 268 | yy5: |
| 266 | ++YYCURSOR; | 269 | ++YYCURSOR; |
| 267 | { lineno++; goto yyc_init; } | 270 | { lineno++; goto yyc_init; } |
| 268 | yy11: | 271 | yy6: |
| 269 | yych = *++YYCURSOR; | 272 | yych = *++YYCURSOR; |
| 270 | if (yych == '\n') goto yy9; | 273 | if (yych == '\n') goto yy5; |
| 271 | goto yy5; | 274 | goto yy3; |
| 272 | yy12: | 275 | yy7: |
| 273 | yych = *++YYCURSOR; | 276 | yych = *++YYCURSOR; |
| 274 | if (yybm[0+yych] & 16) { | 277 | if (yybm[0+yych] & 16) { |
| 275 | goto yy12; | 278 | goto yy7; |
| 276 | } | 279 | } |
| 277 | { goto yyc_init; } | 280 | { goto yyc_init; } |
| 278 | yy15: | 281 | yy8: |
| 279 | yyaccept = 0; | 282 | yyaccept = 0; |
| 280 | yych = *(YYMARKER = ++YYCURSOR); | 283 | yych = *(YYMARKER = ++YYCURSOR); |
| 281 | switch (yych) { | 284 | switch (yych) { |
| 282 | case 'c': goto yy17; | 285 | case 'c': goto yy10; |
| 283 | case 'e': goto yy19; | 286 | case 'e': goto yy12; |
| 284 | case 'i': goto yy20; | 287 | case 'i': goto yy13; |
| 285 | case 'l': goto yy21; | 288 | case 'l': goto yy14; |
| 286 | case 's': goto yy22; | 289 | case 's': goto yy15; |
| 287 | case 'w': goto yy23; | 290 | case 'w': goto yy16; |
| 288 | default: goto yy5; | 291 | default: goto yy3; |
| 289 | } | 292 | } |
| 290 | yy16: | 293 | yy9: |
| 291 | yyaccept = 0; | 294 | yyaccept = 0; |
| 292 | yych = *(YYMARKER = ++YYCURSOR); | 295 | yych = *(YYMARKER = ++YYCURSOR); |
| 293 | if (yych == 'e') goto yy24; | 296 | if (yych == 'e') goto yy17; |
| 294 | if (yych == 'p') goto yy25; | 297 | if (yych == 'p') goto yy18; |
| 295 | goto yy5; | 298 | goto yy3; |
| 296 | yy17: | 299 | yy10: |
| 297 | yych = *++YYCURSOR; | 300 | yych = *++YYCURSOR; |
| 298 | if (yych == 'o') goto yy27; | 301 | if (yych == 'o') goto yy19; |
| 299 | yy18: | 302 | yy11: |
| 300 | YYCURSOR = YYMARKER; | 303 | YYCURSOR = YYMARKER; |
| 301 | if (yyaccept <= 4) { | 304 | if (yyaccept <= 4) { |
| 302 | if (yyaccept <= 2) { | 305 | if (yyaccept <= 2) { |
| 303 | if (yyaccept <= 1) { | 306 | if (yyaccept <= 1) { |
| 304 | if (yyaccept == 0) { | 307 | if (yyaccept == 0) { |
| 305 | goto yy5; | 308 | goto yy3; |
| 306 | } else { | 309 | } else { |
| 307 | yyt2 = YYCURSOR; | 310 | yyt2 = YYCURSOR; |
| 308 | goto yy67; | 311 | goto yy54; |
| 309 | } | 312 | } |
| 310 | } else { | 313 | } else { |
| 311 | yyt2 = YYCURSOR; | 314 | yyt2 = YYCURSOR; |
| 312 | goto yy71; | 315 | goto yy57; |
| 313 | } | 316 | } |
| 314 | } else { | 317 | } else { |
| 315 | if (yyaccept == 3) { | 318 | if (yyaccept == 3) { |
| 316 | goto yy67; | 319 | goto yy54; |
| 317 | } else { | 320 | } else { |
| 318 | goto yy71; | 321 | goto yy57; |
| 319 | } | 322 | } |
| 320 | } | 323 | } |
| 321 | } else { | 324 | } else { |
| 322 | if (yyaccept <= 6) { | 325 | if (yyaccept <= 6) { |
| 323 | if (yyaccept == 5) { | 326 | if (yyaccept == 5) { |
| 324 | yyt2 = YYCURSOR; | 327 | yyt2 = YYCURSOR; |
| 325 | goto yy86; | 328 | goto yy69; |
| 326 | } else { | 329 | } else { |
| 327 | yyt4 = YYCURSOR; | 330 | yyt4 = YYCURSOR; |
| 328 | goto yy91; | 331 | goto yy73; |
| 329 | } | 332 | } |
| 330 | } else { | 333 | } else { |
| 331 | if (yyaccept == 7) { | 334 | if (yyaccept == 7) { |
| 332 | goto yy86; | 335 | goto yy69; |
| 333 | } else { | 336 | } else { |
| 334 | goto yy91; | 337 | goto yy73; |
| 335 | } | 338 | } |
| 336 | } | 339 | } |
| 337 | } | 340 | } |
| 341 | yy12: | ||
| 342 | yych = *++YYCURSOR; | ||
| 343 | if (yych == 'n') goto yy20; | ||
| 344 | if (yych == 'r') goto yy21; | ||
| 345 | goto yy11; | ||
| 346 | yy13: | ||
| 347 | yych = *++YYCURSOR; | ||
| 348 | if (yych == 'n') goto yy22; | ||
| 349 | goto yy11; | ||
| 350 | yy14: | ||
| 351 | yych = *++YYCURSOR; | ||
| 352 | if (yych == 'o') goto yy23; | ||
| 353 | goto yy11; | ||
| 354 | yy15: | ||
| 355 | yych = *++YYCURSOR; | ||
| 356 | if (yych == 'e') goto yy17; | ||
| 357 | goto yy11; | ||
| 358 | yy16: | ||
| 359 | yych = *++YYCURSOR; | ||
| 360 | if (yych == 'a') goto yy24; | ||
| 361 | goto yy11; | ||
| 362 | yy17: | ||
| 363 | yych = *++YYCURSOR; | ||
| 364 | if (yych == 't') goto yy25; | ||
| 365 | goto yy11; | ||
| 366 | yy18: | ||
| 367 | ++YYCURSOR; | ||
| 368 | { kw_i = 0; goto yyc_rule; } | ||
| 338 | yy19: | 369 | yy19: |
| 339 | yych = *++YYCURSOR; | 370 | yych = *++YYCURSOR; |
| 340 | if (yych == 'n') goto yy28; | 371 | if (yych == 'n') goto yy26; |
| 341 | if (yych == 'r') goto yy29; | 372 | goto yy11; |
| 342 | goto yy18; | ||
| 343 | yy20: | 373 | yy20: |
| 344 | yych = *++YYCURSOR; | 374 | yych = *++YYCURSOR; |
| 345 | if (yych == 'n') goto yy30; | 375 | if (yych == 'd') goto yy27; |
| 346 | goto yy18; | 376 | goto yy11; |
| 347 | yy21: | 377 | yy21: |
| 348 | yych = *++YYCURSOR; | 378 | yych = *++YYCURSOR; |
| 349 | if (yych == 'o') goto yy31; | 379 | if (yych == 'r') goto yy28; |
| 350 | goto yy18; | 380 | goto yy11; |
| 351 | yy22: | 381 | yy22: |
| 352 | yych = *++YYCURSOR; | 382 | yych = *++YYCURSOR; |
| 353 | if (yych == 'e') goto yy24; | 383 | if (yych == 'f') goto yy29; |
| 354 | goto yy18; | 384 | goto yy11; |
| 355 | yy23: | 385 | yy23: |
| 356 | yych = *++YYCURSOR; | 386 | yych = *++YYCURSOR; |
| 357 | if (yych == 'a') goto yy32; | 387 | if (yych == 'g') goto yy30; |
| 358 | goto yy18; | 388 | goto yy11; |
| 359 | yy24: | 389 | yy24: |
| 360 | yych = *++YYCURSOR; | 390 | yych = *++YYCURSOR; |
| 361 | if (yych == 't') goto yy33; | 391 | if (yych == 'r') goto yy31; |
| 362 | goto yy18; | 392 | goto yy11; |
| 363 | yy25: | 393 | yy25: |
| 364 | ++YYCURSOR; | 394 | yych = *++YYCURSOR; |
| 365 | { kw_i = 0; goto yyc_rule; } | 395 | if (yych == '\t') goto yy32; |
| 396 | if (yych == ' ') goto yy32; | ||
| 397 | goto yy11; | ||
| 398 | yy26: | ||
| 399 | yych = *++YYCURSOR; | ||
| 400 | if (yych == 'd') goto yy33; | ||
| 401 | goto yy11; | ||
| 366 | yy27: | 402 | yy27: |
| 367 | yych = *++YYCURSOR; | 403 | yych = *++YYCURSOR; |
| 368 | if (yych == 'n') goto yy34; | 404 | if (yych == '_') goto yy34; |
| 369 | goto yy18; | 405 | goto yy11; |
| 370 | yy28: | 406 | yy28: |
| 371 | yych = *++YYCURSOR; | 407 | yych = *++YYCURSOR; |
| 372 | if (yych == 'd') goto yy35; | 408 | if (yych == '"') goto yy11; |
| 373 | goto yy18; | 409 | if (yych == 'o') goto yy37; |
| 410 | goto yy36; | ||
| 374 | yy29: | 411 | yy29: |
| 375 | yych = *++YYCURSOR; | 412 | yych = *++YYCURSOR; |
| 376 | if (yych == 'r') goto yy36; | 413 | if (yych != 'o') goto yy11; |
| 377 | goto yy18; | ||
| 378 | yy30: | 414 | yy30: |
| 379 | yych = *++YYCURSOR; | 415 | yych = *++YYCURSOR; |
| 380 | if (yych == 'f') goto yy37; | 416 | if (yych == '"') goto yy11; |
| 381 | goto yy18; | 417 | goto yy39; |
| 382 | yy31: | 418 | yy31: |
| 383 | yych = *++YYCURSOR; | 419 | yych = *++YYCURSOR; |
| 384 | if (yych == 'g') goto yy38; | 420 | if (yych == 'n') goto yy40; |
| 385 | goto yy18; | 421 | goto yy11; |
| 386 | yy32: | 422 | yy32: |
| 387 | yych = *++YYCURSOR; | 423 | yych = *++YYCURSOR; |
| 388 | if (yych == 'r') goto yy39; | ||
| 389 | goto yy18; | ||
| 390 | yy33: | ||
| 391 | yych = *++YYCURSOR; | ||
| 392 | if (yych == '\t') goto yy40; | ||
| 393 | if (yych == ' ') goto yy40; | ||
| 394 | goto yy18; | ||
| 395 | yy34: | ||
| 396 | yych = *++YYCURSOR; | ||
| 397 | if (yych == 'd') goto yy42; | ||
| 398 | goto yy18; | ||
| 399 | yy35: | ||
| 400 | yych = *++YYCURSOR; | ||
| 401 | if (yych == '_') goto yy43; | ||
| 402 | goto yy18; | ||
| 403 | yy36: | ||
| 404 | yych = *++YYCURSOR; | ||
| 405 | if (yych == '"') goto yy18; | ||
| 406 | if (yych == 'o') goto yy46; | ||
| 407 | goto yy45; | ||
| 408 | yy37: | ||
| 409 | yych = *++YYCURSOR; | ||
| 410 | if (yych != 'o') goto yy18; | ||
| 411 | yy38: | ||
| 412 | yych = *++YYCURSOR; | ||
| 413 | if (yych == '"') goto yy18; | ||
| 414 | goto yy48; | ||
| 415 | yy39: | ||
| 416 | yych = *++YYCURSOR; | ||
| 417 | if (yych == 'n') goto yy49; | ||
| 418 | goto yy18; | ||
| 419 | yy40: | ||
| 420 | yych = *++YYCURSOR; | ||
| 421 | if (yych <= '@') { | 424 | if (yych <= '@') { |
| 422 | if (yych <= '\t') { | 425 | if (yych <= '\t') { |
| 423 | if (yych <= 0x08) goto yy18; | 426 | if (yych <= 0x08) goto yy11; |
| 424 | goto yy40; | 427 | goto yy32; |
| 425 | } else { | 428 | } else { |
| 426 | if (yych == ' ') goto yy40; | 429 | if (yych == ' ') goto yy32; |
| 427 | goto yy18; | 430 | goto yy11; |
| 428 | } | 431 | } |
| 429 | } else { | 432 | } else { |
| 430 | if (yych <= '_') { | 433 | if (yych <= '_') { |
| 431 | if (yych <= 'Z') { | 434 | if (yych <= 'Z') { |
| 432 | yyt1 = YYCURSOR; | 435 | yyt1 = YYCURSOR; |
| 433 | goto yy50; | 436 | goto yy41; |
| 434 | } | 437 | } |
| 435 | if (yych <= '^') goto yy18; | 438 | if (yych <= '^') goto yy11; |
| 436 | yyt1 = YYCURSOR; | 439 | yyt1 = YYCURSOR; |
| 437 | goto yy50; | 440 | goto yy41; |
| 438 | } else { | 441 | } else { |
| 439 | if (yych <= '`') goto yy18; | 442 | if (yych <= '`') goto yy11; |
| 440 | if (yych <= 'z') { | 443 | if (yych <= 'z') { |
| 441 | yyt1 = YYCURSOR; | 444 | yyt1 = YYCURSOR; |
| 442 | goto yy50; | 445 | goto yy41; |
| 443 | } | 446 | } |
| 444 | goto yy18; | 447 | goto yy11; |
| 445 | } | 448 | } |
| 446 | } | 449 | } |
| 447 | yy42: | 450 | yy33: |
| 448 | yych = *++YYCURSOR; | 451 | yych = *++YYCURSOR; |
| 449 | if (yych == 'i') goto yy52; | 452 | if (yych == 'i') goto yy42; |
| 450 | goto yy18; | 453 | goto yy11; |
| 451 | yy43: | 454 | yy34: |
| 452 | yych = *++YYCURSOR; | 455 | yych = *++YYCURSOR; |
| 453 | if (yych == 'c') goto yy53; | 456 | if (yych == 'c') goto yy43; |
| 454 | goto yy18; | 457 | goto yy11; |
| 455 | yy44: | 458 | yy35: |
| 456 | yych = *++YYCURSOR; | 459 | yych = *++YYCURSOR; |
| 457 | yy45: | 460 | yy36: |
| 458 | if (yych <= 0x1F) { | 461 | if (yych <= 0x1F) { |
| 459 | if (yych == '\t') goto yy44; | 462 | if (yych == '\t') goto yy35; |
| 460 | goto yy18; | 463 | goto yy11; |
| 461 | } else { | 464 | } else { |
| 462 | if (yych <= ' ') goto yy44; | 465 | if (yych <= ' ') goto yy35; |
| 463 | if (yych == '"') { | 466 | if (yych == '"') { |
| 464 | yyt1 = YYCURSOR; | 467 | yyt1 = YYCURSOR; |
| 465 | goto yy54; | 468 | goto yy44; |
| 466 | } | 469 | } |
| 467 | goto yy18; | 470 | goto yy11; |
| 468 | } | 471 | } |
| 469 | yy46: | 472 | yy37: |
| 470 | yych = *++YYCURSOR; | 473 | yych = *++YYCURSOR; |
| 471 | if (yych == 'r') goto yy56; | 474 | if (yych == 'r') goto yy45; |
| 472 | goto yy18; | 475 | goto yy11; |
| 473 | yy47: | 476 | yy38: |
| 474 | yych = *++YYCURSOR; | 477 | yych = *++YYCURSOR; |
| 475 | yy48: | 478 | yy39: |
| 476 | if (yych <= 0x1F) { | 479 | if (yych <= 0x1F) { |
| 477 | if (yych == '\t') goto yy47; | 480 | if (yych == '\t') goto yy38; |
| 478 | goto yy18; | 481 | goto yy11; |
| 479 | } else { | 482 | } else { |
| 480 | if (yych <= ' ') goto yy47; | 483 | if (yych <= ' ') goto yy38; |
| 481 | if (yych == '"') { | 484 | if (yych == '"') { |
| 482 | yyt1 = YYCURSOR; | 485 | yyt1 = YYCURSOR; |
| 483 | goto yy57; | 486 | goto yy46; |
| 484 | } | 487 | } |
| 485 | goto yy18; | 488 | goto yy11; |
| 486 | } | 489 | } |
| 487 | yy49: | 490 | yy40: |
| 488 | yych = *++YYCURSOR; | 491 | yych = *++YYCURSOR; |
| 489 | if (yych == '"') goto yy18; | 492 | if (yych == '"') goto yy11; |
| 490 | if (yych == 'i') goto yy61; | 493 | if (yych == 'i') goto yy49; |
| 491 | goto yy60; | 494 | goto yy48; |
| 492 | yy50: | 495 | yy41: |
| 493 | yych = *++YYCURSOR; | 496 | yych = *++YYCURSOR; |
| 494 | if (yybm[0+yych] & 32) { | 497 | if (yybm[0+yych] & 32) { |
| 495 | goto yy50; | 498 | goto yy41; |
| 496 | } | 499 | } |
| 497 | if (yych == '\t') { | 500 | if (yych == '\t') { |
| 498 | yyt2 = YYCURSOR; | 501 | yyt2 = YYCURSOR; |
| 499 | goto yy62; | 502 | goto yy50; |
| 500 | } | 503 | } |
| 501 | if (yych == ' ') { | 504 | if (yych == ' ') { |
| 502 | yyt2 = YYCURSOR; | 505 | yyt2 = YYCURSOR; |
| 503 | goto yy62; | 506 | goto yy50; |
| 504 | } | 507 | } |
| 505 | goto yy18; | 508 | goto yy11; |
| 506 | yy52: | 509 | yy42: |
| 507 | yych = *++YYCURSOR; | 510 | yych = *++YYCURSOR; |
| 508 | if (yych == 't') goto yy64; | 511 | if (yych == 't') goto yy51; |
| 509 | goto yy18; | 512 | goto yy11; |
| 510 | yy53: | 513 | yy43: |
| 511 | yych = *++YYCURSOR; | 514 | yych = *++YYCURSOR; |
| 512 | if (yych == 'o') goto yy65; | 515 | if (yych == 'o') goto yy52; |
| 513 | goto yy18; | 516 | goto yy11; |
| 514 | yy54: | 517 | yy44: |
| 515 | yych = *++YYCURSOR; | 518 | yych = *++YYCURSOR; |
| 516 | if (yybm[0+yych] & 64) { | 519 | if (yybm[0+yych] & 64) { |
| 517 | goto yy54; | 520 | goto yy44; |
| 518 | } | 521 | } |
| 519 | if (yych <= '\r') goto yy18; | 522 | if (yych <= '\r') goto yy11; |
| 520 | if (yych <= '"') goto yy66; | 523 | if (yych <= '"') goto yy53; |
| 521 | goto yy68; | 524 | goto yy55; |
| 522 | yy56: | 525 | yy45: |
| 523 | yych = *++YYCURSOR; | 526 | yych = *++YYCURSOR; |
| 524 | if (yych == '"') goto yy18; | 527 | if (yych == '"') goto yy11; |
| 525 | goto yy45; | 528 | goto yy36; |
| 526 | yy57: | 529 | yy46: |
| 527 | yych = *++YYCURSOR; | 530 | yych = *++YYCURSOR; |
| 528 | if (yych <= '\r') { | 531 | if (yych <= '\r') { |
| 529 | if (yych == '\n') goto yy18; | 532 | if (yych == '\n') goto yy11; |
| 530 | if (yych <= '\f') goto yy57; | 533 | if (yych <= '\f') goto yy46; |
| 531 | goto yy18; | 534 | goto yy11; |
| 532 | } else { | 535 | } else { |
| 533 | if (yych <= '"') { | 536 | if (yych <= '"') { |
| 534 | if (yych <= '!') goto yy57; | 537 | if (yych <= '!') goto yy46; |
| 535 | goto yy70; | 538 | goto yy56; |
| 536 | } else { | 539 | } else { |
| 537 | if (yych == '\\') goto yy72; | 540 | if (yych == '\\') goto yy58; |
| 538 | goto yy57; | 541 | goto yy46; |
| 539 | } | 542 | } |
| 540 | } | 543 | } |
| 541 | yy59: | 544 | yy47: |
| 542 | yych = *++YYCURSOR; | 545 | yych = *++YYCURSOR; |
| 543 | yy60: | 546 | yy48: |
| 544 | if (yych <= 0x1F) { | 547 | if (yych <= 0x1F) { |
| 545 | if (yych == '\t') goto yy59; | 548 | if (yych == '\t') goto yy47; |
| 546 | goto yy18; | 549 | goto yy11; |
| 547 | } else { | 550 | } else { |
| 548 | if (yych <= ' ') goto yy59; | 551 | if (yych <= ' ') goto yy47; |
| 549 | if (yych == '"') { | 552 | if (yych == '"') { |
| 550 | yyt1 = YYCURSOR; | 553 | yyt1 = YYCURSOR; |
| 551 | goto yy74; | 554 | goto yy59; |
| 552 | } | 555 | } |
| 553 | goto yy18; | 556 | goto yy11; |
| 554 | } | 557 | } |
| 555 | yy61: | 558 | yy49: |
| 556 | yych = *++YYCURSOR; | 559 | yych = *++YYCURSOR; |
| 557 | if (yych == 'n') goto yy76; | 560 | if (yych == 'n') goto yy60; |
| 558 | goto yy18; | 561 | goto yy11; |
| 559 | yy62: | 562 | yy50: |
| 560 | yych = *++YYCURSOR; | 563 | yych = *++YYCURSOR; |
| 561 | if (yych <= 0x1F) { | 564 | if (yych <= 0x1F) { |
| 562 | if (yych == '\t') goto yy62; | 565 | if (yych == '\t') goto yy50; |
| 563 | goto yy18; | 566 | goto yy11; |
| 564 | } else { | 567 | } else { |
| 565 | if (yych <= ' ') goto yy62; | 568 | if (yych <= ' ') goto yy50; |
| 566 | if (yych == '"') { | 569 | if (yych == '"') { |
| 567 | yyt3 = YYCURSOR; | 570 | yyt3 = YYCURSOR; |
| 568 | goto yy77; | 571 | goto yy61; |
| 569 | } | 572 | } |
| 570 | goto yy18; | 573 | goto yy11; |
| 571 | } | 574 | } |
| 572 | yy64: | 575 | yy51: |
| 573 | yych = *++YYCURSOR; | 576 | yych = *++YYCURSOR; |
| 574 | if (yych == 'i') goto yy79; | 577 | if (yych == 'i') goto yy62; |
| 575 | goto yy18; | 578 | goto yy11; |
| 576 | yy65: | 579 | yy52: |
| 577 | yych = *++YYCURSOR; | 580 | yych = *++YYCURSOR; |
| 578 | if (yych == 'n') goto yy80; | 581 | if (yych == 'n') goto yy63; |
| 579 | goto yy18; | 582 | goto yy11; |
| 580 | yy66: | 583 | yy53: |
| 581 | yych = *++YYCURSOR; | 584 | yych = *++YYCURSOR; |
| 582 | yyt2 = YYCURSOR; | 585 | yyt2 = YYCURSOR; |
| 583 | if (yych == ';') goto yy81; | 586 | if (yych == ';') goto yy64; |
| 584 | yy67: | 587 | yy54: |
| 585 | t1 = yyt1; | 588 | t1 = yyt1; |
| 586 | t2 = yyt2; | 589 | t2 = yyt2; |
| 587 | { | 590 | { |
| @@ -590,19 +593,19 @@ yy67: | |||
| 590 | cs_log_error("[line %d]: %s", lineno, tmpstr); | 593 | cs_log_error("[line %d]: %s", lineno, tmpstr); |
| 591 | goto out; | 594 | goto out; |
| 592 | } | 595 | } |
| 593 | yy68: | 596 | yy55: |
| 594 | yych = *++YYCURSOR; | 597 | yych = *++YYCURSOR; |
| 595 | if (yybm[0+yych] & 64) { | 598 | if (yybm[0+yych] & 64) { |
| 596 | goto yy54; | 599 | goto yy44; |
| 597 | } | 600 | } |
| 598 | if (yych <= '\r') goto yy18; | 601 | if (yych <= '\r') goto yy11; |
| 599 | if (yych <= '"') goto yy82; | 602 | if (yych <= '"') goto yy65; |
| 600 | goto yy68; | 603 | goto yy55; |
| 601 | yy70: | 604 | yy56: |
| 602 | yych = *++YYCURSOR; | 605 | yych = *++YYCURSOR; |
| 603 | yyt2 = YYCURSOR; | 606 | yyt2 = YYCURSOR; |
| 604 | if (yych == ';') goto yy83; | 607 | if (yych == ';') goto yy66; |
| 605 | yy71: | 608 | yy57: |
| 606 | t1 = yyt1; | 609 | t1 = yyt1; |
| 607 | t2 = yyt2; | 610 | t2 = yyt2; |
| 608 | { | 611 | { |
| @@ -611,126 +614,126 @@ yy71: | |||
| 611 | cs_log_info("[line %d]: %s", lineno, tmpstr); | 614 | cs_log_info("[line %d]: %s", lineno, tmpstr); |
| 612 | goto yyc_init; | 615 | goto yyc_init; |
| 613 | } | 616 | } |
| 614 | yy72: | 617 | yy58: |
| 615 | yych = *++YYCURSOR; | 618 | yych = *++YYCURSOR; |
| 616 | if (yych <= '\r') { | 619 | if (yych <= '\r') { |
| 617 | if (yych == '\n') goto yy18; | 620 | if (yych == '\n') goto yy11; |
| 618 | if (yych <= '\f') goto yy57; | 621 | if (yych <= '\f') goto yy46; |
| 619 | goto yy18; | 622 | goto yy11; |
| 620 | } else { | 623 | } else { |
| 621 | if (yych <= '"') { | 624 | if (yych <= '"') { |
| 622 | if (yych <= '!') goto yy57; | 625 | if (yych <= '!') goto yy46; |
| 623 | goto yy84; | 626 | goto yy67; |
| 624 | } else { | 627 | } else { |
| 625 | if (yych == '\\') goto yy72; | 628 | if (yych == '\\') goto yy58; |
| 626 | goto yy57; | 629 | goto yy46; |
| 627 | } | 630 | } |
| 628 | } | 631 | } |
| 629 | yy74: | 632 | yy59: |
| 630 | yych = *++YYCURSOR; | 633 | yych = *++YYCURSOR; |
| 631 | if (yych <= '\r') { | 634 | if (yych <= '\r') { |
| 632 | if (yych == '\n') goto yy18; | 635 | if (yych == '\n') goto yy11; |
| 633 | if (yych <= '\f') goto yy74; | 636 | if (yych <= '\f') goto yy59; |
| 634 | goto yy18; | 637 | goto yy11; |
| 635 | } else { | 638 | } else { |
| 636 | if (yych <= '"') { | 639 | if (yych <= '"') { |
| 637 | if (yych <= '!') goto yy74; | 640 | if (yych <= '!') goto yy59; |
| 638 | goto yy85; | 641 | goto yy68; |
| 639 | } else { | 642 | } else { |
| 640 | if (yych == '\\') goto yy87; | 643 | if (yych == '\\') goto yy70; |
| 641 | goto yy74; | 644 | goto yy59; |
| 642 | } | 645 | } |
| 643 | } | 646 | } |
| 644 | yy76: | 647 | yy60: |
| 645 | yych = *++YYCURSOR; | 648 | yych = *++YYCURSOR; |
| 646 | if (yych == 'g') goto yy89; | 649 | if (yych == 'g') goto yy71; |
| 647 | goto yy18; | 650 | goto yy11; |
| 648 | yy77: | 651 | yy61: |
| 649 | yych = *++YYCURSOR; | 652 | yych = *++YYCURSOR; |
| 650 | if (yych <= '\r') { | 653 | if (yych <= '\r') { |
| 651 | if (yych == '\n') goto yy18; | 654 | if (yych == '\n') goto yy11; |
| 652 | if (yych <= '\f') goto yy77; | 655 | if (yych <= '\f') goto yy61; |
| 653 | goto yy18; | 656 | goto yy11; |
| 654 | } else { | 657 | } else { |
| 655 | if (yych <= '"') { | 658 | if (yych <= '"') { |
| 656 | if (yych <= '!') goto yy77; | 659 | if (yych <= '!') goto yy61; |
| 657 | goto yy90; | 660 | goto yy72; |
| 658 | } else { | 661 | } else { |
| 659 | if (yych == '\\') goto yy92; | 662 | if (yych == '\\') goto yy74; |
| 660 | goto yy77; | 663 | goto yy61; |
| 661 | } | 664 | } |
| 662 | } | 665 | } |
| 663 | yy79: | 666 | yy62: |
| 664 | yych = *++YYCURSOR; | 667 | yych = *++YYCURSOR; |
| 665 | if (yych == 'o') goto yy94; | 668 | if (yych == 'o') goto yy75; |
| 666 | goto yy18; | 669 | goto yy11; |
| 667 | yy80: | 670 | yy63: |
| 668 | yych = *++YYCURSOR; | 671 | yych = *++YYCURSOR; |
| 669 | if (yych == 'd') goto yy95; | 672 | if (yych == 'd') goto yy76; |
| 670 | goto yy18; | 673 | goto yy11; |
| 671 | yy81: | 674 | yy64: |
| 672 | ++YYCURSOR; | 675 | ++YYCURSOR; |
| 673 | goto yy67; | 676 | goto yy54; |
| 674 | yy82: | 677 | yy65: |
| 675 | yyaccept = 1; | 678 | yyaccept = 1; |
| 676 | yych = *(YYMARKER = ++YYCURSOR); | 679 | yych = *(YYMARKER = ++YYCURSOR); |
| 677 | if (yybm[0+yych] & 128) { | 680 | if (yybm[0+yych] & 128) { |
| 678 | goto yy68; | 681 | goto yy55; |
| 679 | } | 682 | } |
| 680 | if (yych <= '\r') { | 683 | if (yych <= '\r') { |
| 681 | if (yych == '\n') { | 684 | if (yych == '\n') { |
| 682 | yyt2 = YYCURSOR; | 685 | yyt2 = YYCURSOR; |
| 683 | goto yy67; | 686 | goto yy54; |
| 684 | } | 687 | } |
| 685 | if (yych <= '\f') goto yy54; | 688 | if (yych <= '\f') goto yy44; |
| 686 | yyt2 = YYCURSOR; | 689 | yyt2 = YYCURSOR; |
| 687 | goto yy67; | 690 | goto yy54; |
| 688 | } else { | 691 | } else { |
| 689 | if (yych <= '"') { | 692 | if (yych <= '"') { |
| 690 | if (yych <= '!') goto yy54; | 693 | if (yych <= '!') goto yy44; |
| 691 | goto yy66; | 694 | goto yy53; |
| 692 | } else { | 695 | } else { |
| 693 | if (yych == ';') { | 696 | if (yych == ';') { |
| 694 | yyt2 = YYCURSOR; | 697 | yyt2 = YYCURSOR; |
| 695 | goto yy96; | 698 | goto yy77; |
| 696 | } | 699 | } |
| 697 | goto yy54; | 700 | goto yy44; |
| 698 | } | 701 | } |
| 699 | } | 702 | } |
| 700 | yy83: | 703 | yy66: |
| 701 | ++YYCURSOR; | 704 | ++YYCURSOR; |
| 702 | goto yy71; | 705 | goto yy57; |
| 703 | yy84: | 706 | yy67: |
| 704 | yyaccept = 2; | 707 | yyaccept = 2; |
| 705 | yych = *(YYMARKER = ++YYCURSOR); | 708 | yych = *(YYMARKER = ++YYCURSOR); |
| 706 | if (yych <= '!') { | 709 | if (yych <= '!') { |
| 707 | if (yych <= '\n') { | 710 | if (yych <= '\n') { |
| 708 | if (yych <= '\t') goto yy57; | 711 | if (yych <= '\t') goto yy46; |
| 709 | yyt2 = YYCURSOR; | 712 | yyt2 = YYCURSOR; |
| 710 | goto yy71; | 713 | goto yy57; |
| 711 | } else { | 714 | } else { |
| 712 | if (yych == '\r') { | 715 | if (yych == '\r') { |
| 713 | yyt2 = YYCURSOR; | 716 | yyt2 = YYCURSOR; |
| 714 | goto yy71; | 717 | goto yy57; |
| 715 | } | 718 | } |
| 716 | goto yy57; | 719 | goto yy46; |
| 717 | } | 720 | } |
| 718 | } else { | 721 | } else { |
| 719 | if (yych <= ';') { | 722 | if (yych <= ';') { |
| 720 | if (yych <= '"') goto yy70; | 723 | if (yych <= '"') goto yy56; |
| 721 | if (yych <= ':') goto yy57; | 724 | if (yych <= ':') goto yy46; |
| 722 | yyt2 = YYCURSOR; | 725 | yyt2 = YYCURSOR; |
| 723 | goto yy97; | 726 | goto yy78; |
| 724 | } else { | 727 | } else { |
| 725 | if (yych == '\\') goto yy72; | 728 | if (yych == '\\') goto yy58; |
| 726 | goto yy57; | 729 | goto yy46; |
| 727 | } | 730 | } |
| 728 | } | 731 | } |
| 729 | yy85: | 732 | yy68: |
| 730 | yych = *++YYCURSOR; | 733 | yych = *++YYCURSOR; |
| 731 | yyt2 = YYCURSOR; | 734 | yyt2 = YYCURSOR; |
| 732 | if (yych == ';') goto yy98; | 735 | if (yych == ';') goto yy79; |
| 733 | yy86: | 736 | yy69: |
| 734 | t1 = yyt1; | 737 | t1 = yyt1; |
| 735 | t2 = yyt2; | 738 | t2 = yyt2; |
| 736 | { | 739 | { |
| @@ -739,30 +742,30 @@ yy86: | |||
| 739 | cs_log_warning("[line %d]: %s", lineno, tmpstr); | 742 | cs_log_warning("[line %d]: %s", lineno, tmpstr); |
| 740 | goto yyc_init; | 743 | goto yyc_init; |
| 741 | } | 744 | } |
| 742 | yy87: | 745 | yy70: |
| 743 | yych = *++YYCURSOR; | 746 | yych = *++YYCURSOR; |
| 744 | if (yych <= '\r') { | 747 | if (yych <= '\r') { |
| 745 | if (yych == '\n') goto yy18; | 748 | if (yych == '\n') goto yy11; |
| 746 | if (yych <= '\f') goto yy74; | 749 | if (yych <= '\f') goto yy59; |
| 747 | goto yy18; | 750 | goto yy11; |
| 748 | } else { | 751 | } else { |
| 749 | if (yych <= '"') { | 752 | if (yych <= '"') { |
| 750 | if (yych <= '!') goto yy74; | 753 | if (yych <= '!') goto yy59; |
| 751 | goto yy99; | 754 | goto yy80; |
| 752 | } else { | 755 | } else { |
| 753 | if (yych == '\\') goto yy87; | 756 | if (yych == '\\') goto yy70; |
| 754 | goto yy74; | 757 | goto yy59; |
| 755 | } | 758 | } |
| 756 | } | 759 | } |
| 757 | yy89: | 760 | yy71: |
| 758 | yych = *++YYCURSOR; | 761 | yych = *++YYCURSOR; |
| 759 | if (yych == '"') goto yy18; | 762 | if (yych == '"') goto yy11; |
| 760 | goto yy60; | 763 | goto yy48; |
| 761 | yy90: | 764 | yy72: |
| 762 | yych = *++YYCURSOR; | 765 | yych = *++YYCURSOR; |
| 763 | yyt4 = YYCURSOR; | 766 | yyt4 = YYCURSOR; |
| 764 | goto yy101; | 767 | goto yy82; |
| 765 | yy91: | 768 | yy73: |
| 766 | t1 = yyt1; | 769 | t1 = yyt1; |
| 767 | t2 = yyt2; | 770 | t2 = yyt2; |
| 768 | t3 = yyt3; | 771 | t3 = yyt3; |
| @@ -779,213 +782,213 @@ yy91: | |||
| 779 | zend_hash_str_add_ptr(&vars, key, keylen, tmp); | 782 | zend_hash_str_add_ptr(&vars, key, keylen, tmp); |
| 780 | goto yyc_init; | 783 | goto yyc_init; |
| 781 | } | 784 | } |
| 782 | yy92: | 785 | yy74: |
| 783 | yych = *++YYCURSOR; | 786 | yych = *++YYCURSOR; |
| 784 | if (yych <= '\r') { | 787 | if (yych <= '\r') { |
| 785 | if (yych == '\n') goto yy18; | 788 | if (yych == '\n') goto yy11; |
| 786 | if (yych <= '\f') goto yy77; | 789 | if (yych <= '\f') goto yy61; |
| 787 | goto yy18; | 790 | goto yy11; |
| 788 | } else { | 791 | } else { |
| 789 | if (yych <= '"') { | 792 | if (yych <= '"') { |
| 790 | if (yych <= '!') goto yy77; | 793 | if (yych <= '!') goto yy61; |
| 791 | goto yy103; | 794 | goto yy83; |
| 792 | } else { | 795 | } else { |
| 793 | if (yych == '\\') goto yy92; | 796 | if (yych == '\\') goto yy74; |
| 794 | goto yy77; | 797 | goto yy61; |
| 795 | } | 798 | } |
| 796 | } | 799 | } |
| 797 | yy94: | 800 | yy75: |
| 798 | yych = *++YYCURSOR; | 801 | yych = *++YYCURSOR; |
| 799 | if (yych == 'n') goto yy104; | 802 | if (yych == 'n') goto yy84; |
| 800 | goto yy18; | 803 | goto yy11; |
| 801 | yy95: | 804 | yy76: |
| 802 | yych = *++YYCURSOR; | 805 | yych = *++YYCURSOR; |
| 803 | if (yych == 'i') goto yy105; | 806 | if (yych == 'i') goto yy85; |
| 804 | goto yy18; | 807 | goto yy11; |
| 805 | yy96: | 808 | yy77: |
| 806 | yyaccept = 3; | 809 | yyaccept = 3; |
| 807 | yych = *(YYMARKER = ++YYCURSOR); | 810 | yych = *(YYMARKER = ++YYCURSOR); |
| 808 | if (yybm[0+yych] & 64) { | 811 | if (yybm[0+yych] & 64) { |
| 809 | goto yy54; | 812 | goto yy44; |
| 810 | } | 813 | } |
| 811 | if (yych <= '\r') goto yy67; | 814 | if (yych <= '\r') goto yy54; |
| 812 | if (yych <= '"') goto yy66; | 815 | if (yych <= '"') goto yy53; |
| 813 | goto yy68; | 816 | goto yy55; |
| 814 | yy97: | 817 | yy78: |
| 815 | yyaccept = 4; | 818 | yyaccept = 4; |
| 816 | yych = *(YYMARKER = ++YYCURSOR); | 819 | yych = *(YYMARKER = ++YYCURSOR); |
| 817 | if (yych <= '\r') { | 820 | if (yych <= '\r') { |
| 818 | if (yych == '\n') goto yy71; | 821 | if (yych == '\n') goto yy57; |
| 819 | if (yych <= '\f') goto yy57; | 822 | if (yych <= '\f') goto yy46; |
| 820 | goto yy71; | 823 | goto yy57; |
| 821 | } else { | 824 | } else { |
| 822 | if (yych <= '"') { | 825 | if (yych <= '"') { |
| 823 | if (yych <= '!') goto yy57; | 826 | if (yych <= '!') goto yy46; |
| 824 | goto yy70; | 827 | goto yy56; |
| 825 | } else { | 828 | } else { |
| 826 | if (yych == '\\') goto yy72; | 829 | if (yych == '\\') goto yy58; |
| 827 | goto yy57; | 830 | goto yy46; |
| 828 | } | 831 | } |
| 829 | } | 832 | } |
| 830 | yy98: | 833 | yy79: |
| 831 | ++YYCURSOR; | 834 | ++YYCURSOR; |
| 832 | goto yy86; | 835 | goto yy69; |
| 833 | yy99: | 836 | yy80: |
| 834 | yyaccept = 5; | 837 | yyaccept = 5; |
| 835 | yych = *(YYMARKER = ++YYCURSOR); | 838 | yych = *(YYMARKER = ++YYCURSOR); |
| 836 | if (yych <= '!') { | 839 | if (yych <= '!') { |
| 837 | if (yych <= '\n') { | 840 | if (yych <= '\n') { |
| 838 | if (yych <= '\t') goto yy74; | 841 | if (yych <= '\t') goto yy59; |
| 839 | yyt2 = YYCURSOR; | 842 | yyt2 = YYCURSOR; |
| 840 | goto yy86; | 843 | goto yy69; |
| 841 | } else { | 844 | } else { |
| 842 | if (yych == '\r') { | 845 | if (yych == '\r') { |
| 843 | yyt2 = YYCURSOR; | 846 | yyt2 = YYCURSOR; |
| 844 | goto yy86; | 847 | goto yy69; |
| 845 | } | 848 | } |
| 846 | goto yy74; | 849 | goto yy59; |
| 847 | } | 850 | } |
| 848 | } else { | 851 | } else { |
| 849 | if (yych <= ';') { | 852 | if (yych <= ';') { |
| 850 | if (yych <= '"') goto yy85; | 853 | if (yych <= '"') goto yy68; |
| 851 | if (yych <= ':') goto yy74; | 854 | if (yych <= ':') goto yy59; |
| 852 | yyt2 = YYCURSOR; | 855 | yyt2 = YYCURSOR; |
| 853 | goto yy106; | 856 | goto yy86; |
| 854 | } else { | 857 | } else { |
| 855 | if (yych == '\\') goto yy87; | 858 | if (yych == '\\') goto yy70; |
| 856 | goto yy74; | 859 | goto yy59; |
| 857 | } | 860 | } |
| 858 | } | 861 | } |
| 859 | yy100: | 862 | yy81: |
| 860 | yych = *++YYCURSOR; | 863 | yych = *++YYCURSOR; |
| 861 | yy101: | 864 | yy82: |
| 862 | if (yych <= 0x1F) { | 865 | if (yych <= 0x1F) { |
| 863 | if (yych == '\t') goto yy100; | 866 | if (yych == '\t') goto yy81; |
| 864 | goto yy91; | 867 | goto yy73; |
| 865 | } else { | 868 | } else { |
| 866 | if (yych <= ' ') goto yy100; | 869 | if (yych <= ' ') goto yy81; |
| 867 | if (yych != ';') goto yy91; | 870 | if (yych != ';') goto yy73; |
| 868 | } | 871 | } |
| 869 | ++YYCURSOR; | 872 | ++YYCURSOR; |
| 870 | goto yy91; | 873 | goto yy73; |
| 871 | yy103: | 874 | yy83: |
| 872 | yyaccept = 6; | 875 | yyaccept = 6; |
| 873 | yych = *(YYMARKER = ++YYCURSOR); | 876 | yych = *(YYMARKER = ++YYCURSOR); |
| 874 | if (yych <= ' ') { | 877 | if (yych <= ' ') { |
| 875 | if (yych <= '\n') { | 878 | if (yych <= '\n') { |
| 876 | if (yych <= 0x08) goto yy77; | 879 | if (yych <= 0x08) goto yy61; |
| 877 | if (yych <= '\t') { | 880 | if (yych <= '\t') { |
| 878 | yyt4 = YYCURSOR; | 881 | yyt4 = YYCURSOR; |
| 879 | goto yy107; | 882 | goto yy87; |
| 880 | } | 883 | } |
| 881 | yyt4 = YYCURSOR; | 884 | yyt4 = YYCURSOR; |
| 882 | goto yy91; | 885 | goto yy73; |
| 883 | } else { | 886 | } else { |
| 884 | if (yych == '\r') { | 887 | if (yych == '\r') { |
| 885 | yyt4 = YYCURSOR; | 888 | yyt4 = YYCURSOR; |
| 886 | goto yy91; | 889 | goto yy73; |
| 887 | } | 890 | } |
| 888 | if (yych <= 0x1F) goto yy77; | 891 | if (yych <= 0x1F) goto yy61; |
| 889 | yyt4 = YYCURSOR; | 892 | yyt4 = YYCURSOR; |
| 890 | goto yy107; | 893 | goto yy87; |
| 891 | } | 894 | } |
| 892 | } else { | 895 | } else { |
| 893 | if (yych <= ':') { | 896 | if (yych <= ':') { |
| 894 | if (yych == '"') goto yy90; | 897 | if (yych == '"') goto yy72; |
| 895 | goto yy77; | 898 | goto yy61; |
| 896 | } else { | 899 | } else { |
| 897 | if (yych <= ';') { | 900 | if (yych <= ';') { |
| 898 | yyt4 = YYCURSOR; | 901 | yyt4 = YYCURSOR; |
| 899 | goto yy109; | 902 | goto yy88; |
| 900 | } | 903 | } |
| 901 | if (yych == '\\') goto yy92; | 904 | if (yych == '\\') goto yy74; |
| 902 | goto yy77; | 905 | goto yy61; |
| 903 | } | 906 | } |
| 904 | } | 907 | } |
| 905 | yy104: | 908 | yy84: |
| 906 | yych = *++YYCURSOR; | 909 | yych = *++YYCURSOR; |
| 907 | if (yych == '\t') goto yy110; | 910 | if (yych == '\t') goto yy89; |
| 908 | if (yych == ' ') goto yy110; | 911 | if (yych == ' ') goto yy89; |
| 909 | goto yy18; | 912 | goto yy11; |
| 910 | yy105: | 913 | yy85: |
| 911 | yych = *++YYCURSOR; | 914 | yych = *++YYCURSOR; |
| 912 | if (yych == 't') goto yy113; | 915 | if (yych == 't') goto yy90; |
| 913 | goto yy18; | 916 | goto yy11; |
| 914 | yy106: | 917 | yy86: |
| 915 | yyaccept = 7; | 918 | yyaccept = 7; |
| 916 | yych = *(YYMARKER = ++YYCURSOR); | 919 | yych = *(YYMARKER = ++YYCURSOR); |
| 917 | if (yych <= '\r') { | 920 | if (yych <= '\r') { |
| 918 | if (yych == '\n') goto yy86; | 921 | if (yych == '\n') goto yy69; |
| 919 | if (yych <= '\f') goto yy74; | 922 | if (yych <= '\f') goto yy59; |
| 920 | goto yy86; | 923 | goto yy69; |
| 921 | } else { | 924 | } else { |
| 922 | if (yych <= '"') { | 925 | if (yych <= '"') { |
| 923 | if (yych <= '!') goto yy74; | 926 | if (yych <= '!') goto yy59; |
| 924 | goto yy85; | 927 | goto yy68; |
| 925 | } else { | 928 | } else { |
| 926 | if (yych == '\\') goto yy87; | 929 | if (yych == '\\') goto yy70; |
| 927 | goto yy74; | 930 | goto yy59; |
| 928 | } | 931 | } |
| 929 | } | 932 | } |
| 930 | yy107: | 933 | yy87: |
| 931 | yyaccept = 8; | 934 | yyaccept = 8; |
| 932 | yych = *(YYMARKER = ++YYCURSOR); | 935 | yych = *(YYMARKER = ++YYCURSOR); |
| 933 | if (yych <= ' ') { | 936 | if (yych <= ' ') { |
| 934 | if (yych <= '\n') { | 937 | if (yych <= '\n') { |
| 935 | if (yych <= 0x08) goto yy77; | 938 | if (yych <= 0x08) goto yy61; |
| 936 | if (yych <= '\t') goto yy107; | 939 | if (yych <= '\t') goto yy87; |
| 937 | goto yy91; | 940 | goto yy73; |
| 938 | } else { | 941 | } else { |
| 939 | if (yych == '\r') goto yy91; | 942 | if (yych == '\r') goto yy73; |
| 940 | if (yych <= 0x1F) goto yy77; | 943 | if (yych <= 0x1F) goto yy61; |
| 941 | goto yy107; | 944 | goto yy87; |
| 942 | } | 945 | } |
| 943 | } else { | 946 | } else { |
| 944 | if (yych <= ':') { | 947 | if (yych <= ':') { |
| 945 | if (yych == '"') goto yy90; | 948 | if (yych == '"') goto yy72; |
| 946 | goto yy77; | 949 | goto yy61; |
| 947 | } else { | 950 | } else { |
| 948 | if (yych <= ';') goto yy109; | 951 | if (yych <= ';') goto yy88; |
| 949 | if (yych == '\\') goto yy92; | 952 | if (yych == '\\') goto yy74; |
| 950 | goto yy77; | 953 | goto yy61; |
| 951 | } | 954 | } |
| 952 | } | 955 | } |
| 953 | yy109: | 956 | yy88: |
| 954 | yyaccept = 8; | 957 | yyaccept = 8; |
| 955 | yych = *(YYMARKER = ++YYCURSOR); | 958 | yych = *(YYMARKER = ++YYCURSOR); |
| 956 | if (yych <= '\r') { | 959 | if (yych <= '\r') { |
| 957 | if (yych == '\n') goto yy91; | 960 | if (yych == '\n') goto yy73; |
| 958 | if (yych <= '\f') goto yy77; | 961 | if (yych <= '\f') goto yy61; |
| 959 | goto yy91; | 962 | goto yy73; |
| 960 | } else { | 963 | } else { |
| 961 | if (yych <= '"') { | 964 | if (yych <= '"') { |
| 962 | if (yych <= '!') goto yy77; | 965 | if (yych <= '!') goto yy61; |
| 963 | goto yy90; | 966 | goto yy72; |
| 964 | } else { | 967 | } else { |
| 965 | if (yych == '\\') goto yy92; | 968 | if (yych == '\\') goto yy74; |
| 966 | goto yy77; | 969 | goto yy61; |
| 967 | } | 970 | } |
| 968 | } | 971 | } |
| 969 | yy110: | 972 | yy89: |
| 970 | yych = *++YYCURSOR; | 973 | yych = *++YYCURSOR; |
| 971 | if (yych == '\t') goto yy110; | 974 | if (yych == '\t') goto yy89; |
| 972 | if (yych == ' ') goto yy110; | 975 | if (yych == ' ') goto yy89; |
| 973 | { cond_res_i = 0; goto yyc_cond; } | 976 | { cond_res_i = 0; goto yyc_cond; } |
| 974 | yy113: | 977 | yy90: |
| 975 | yych = *++YYCURSOR; | 978 | yych = *++YYCURSOR; |
| 976 | if (yych != 'i') goto yy18; | 979 | if (yych != 'i') goto yy11; |
| 977 | yych = *++YYCURSOR; | 980 | yych = *++YYCURSOR; |
| 978 | if (yych != 'o') goto yy18; | 981 | if (yych != 'o') goto yy11; |
| 979 | yych = *++YYCURSOR; | 982 | yych = *++YYCURSOR; |
| 980 | if (yych != 'n') goto yy18; | 983 | if (yych != 'n') goto yy11; |
| 981 | yy116: | 984 | yy91: |
| 982 | yych = *++YYCURSOR; | 985 | yych = *++YYCURSOR; |
| 983 | if (yych <= 0x1F) { | 986 | if (yych <= 0x1F) { |
| 984 | if (yych == '\t') goto yy116; | 987 | if (yych == '\t') goto yy91; |
| 985 | goto yy18; | 988 | goto yy11; |
| 986 | } else { | 989 | } else { |
| 987 | if (yych <= ' ') goto yy116; | 990 | if (yych <= ' ') goto yy91; |
| 988 | if (yych != ';') goto yy18; | 991 | if (yych != ';') goto yy11; |
| 989 | } | 992 | } |
| 990 | ++YYCURSOR; | 993 | ++YYCURSOR; |
| 991 | { cond_res[0] = 1; cond_res_i = 0; goto yyc_init; } | 994 | { cond_res[0] = 1; cond_res_i = 0; goto yyc_init; } |
| @@ -1029,85 +1032,85 @@ yyc_cond: | |||
| 1029 | }; | 1032 | }; |
| 1030 | yych = *YYCURSOR; | 1033 | yych = *YYCURSOR; |
| 1031 | if (yybm[0+yych] & 8) { | 1034 | if (yybm[0+yych] & 8) { |
| 1032 | goto yy124; | 1035 | goto yy95; |
| 1033 | } | 1036 | } |
| 1034 | if (yych <= '(') { | 1037 | if (yych <= '(') { |
| 1035 | if (yych <= '\r') { | 1038 | if (yych <= '\r') { |
| 1036 | if (yych <= 0x08) goto yy122; | 1039 | if (yych <= 0x08) goto yy93; |
| 1037 | if (yych <= '\n') goto yy127; | 1040 | if (yych <= '\n') goto yy96; |
| 1038 | if (yych >= '\r') goto yy129; | 1041 | if (yych >= '\r') goto yy97; |
| 1039 | } else { | 1042 | } else { |
| 1040 | if (yych <= 0x1F) goto yy122; | 1043 | if (yych <= 0x1F) goto yy93; |
| 1041 | if (yych <= '!') goto yy130; | 1044 | if (yych <= '!') goto yy98; |
| 1042 | if (yych >= '(') goto yy132; | 1045 | if (yych >= '(') goto yy99; |
| 1043 | } | 1046 | } |
| 1044 | } else { | 1047 | } else { |
| 1045 | if (yych <= 'Z') { | 1048 | if (yych <= 'Z') { |
| 1046 | if (yych <= '/') goto yy122; | 1049 | if (yych <= '/') goto yy93; |
| 1047 | if (yych <= '9') { | 1050 | if (yych <= '9') { |
| 1048 | yyt1 = YYCURSOR; | 1051 | yyt1 = YYCURSOR; |
| 1049 | goto yy134; | 1052 | goto yy100; |
| 1050 | } | 1053 | } |
| 1051 | if (yych >= 'A') { | 1054 | if (yych >= 'A') { |
| 1052 | yyt1 = YYCURSOR; | 1055 | yyt1 = YYCURSOR; |
| 1053 | goto yy137; | 1056 | goto yy101; |
| 1054 | } | 1057 | } |
| 1055 | } else { | 1058 | } else { |
| 1056 | if (yych <= '_') { | 1059 | if (yych <= '_') { |
| 1057 | if (yych >= '_') { | 1060 | if (yych >= '_') { |
| 1058 | yyt1 = YYCURSOR; | 1061 | yyt1 = YYCURSOR; |
| 1059 | goto yy137; | 1062 | goto yy101; |
| 1060 | } | 1063 | } |
| 1061 | } else { | 1064 | } else { |
| 1062 | if (yych <= '`') goto yy122; | 1065 | if (yych <= '`') goto yy93; |
| 1063 | if (yych <= 'z') { | 1066 | if (yych <= 'z') { |
| 1064 | yyt1 = YYCURSOR; | 1067 | yyt1 = YYCURSOR; |
| 1065 | goto yy137; | 1068 | goto yy101; |
| 1066 | } | 1069 | } |
| 1067 | } | 1070 | } |
| 1068 | } | 1071 | } |
| 1069 | } | 1072 | } |
| 1070 | yy122: | 1073 | yy93: |
| 1071 | ++YYCURSOR; | 1074 | ++YYCURSOR; |
| 1072 | yy123: | 1075 | yy94: |
| 1073 | { cs_log_error("Syntax error in condition on line %d", lineno); goto out; } | 1076 | { cs_log_error("Syntax error in condition on line %d", lineno); goto out; } |
| 1074 | yy124: | 1077 | yy95: |
| 1075 | yych = *++YYCURSOR; | 1078 | yych = *++YYCURSOR; |
| 1076 | if (yybm[0+yych] & 8) { | 1079 | if (yybm[0+yych] & 8) { |
| 1077 | goto yy124; | 1080 | goto yy95; |
| 1078 | } | 1081 | } |
| 1079 | { goto yyc_cond; } | 1082 | { goto yyc_cond; } |
| 1080 | yy127: | 1083 | yy96: |
| 1081 | ++YYCURSOR; | 1084 | ++YYCURSOR; |
| 1082 | { lineno++; goto yyc_cond; } | 1085 | { lineno++; goto yyc_cond; } |
| 1083 | yy129: | 1086 | yy97: |
| 1084 | yych = *++YYCURSOR; | 1087 | yych = *++YYCURSOR; |
| 1085 | if (yych == '\n') goto yy127; | 1088 | if (yych == '\n') goto yy96; |
| 1086 | goto yy123; | 1089 | goto yy94; |
| 1087 | yy130: | 1090 | yy98: |
| 1088 | ++YYCURSOR; | 1091 | ++YYCURSOR; |
| 1089 | t1 = YYCURSOR - 1; | 1092 | t1 = YYCURSOR - 1; |
| 1090 | { sy_op_push(*t1); goto yyc_cond; } | 1093 | { sy_op_push(*t1); goto yyc_cond; } |
| 1091 | yy132: | 1094 | yy99: |
| 1092 | ++YYCURSOR; | 1095 | ++YYCURSOR; |
| 1093 | t1 = YYCURSOR - 1; | 1096 | t1 = YYCURSOR - 1; |
| 1094 | { sy_op_push(*t1); goto yyc_cond; } | 1097 | { sy_op_push(*t1); goto yyc_cond; } |
| 1095 | yy134: | 1098 | yy100: |
| 1096 | yych = *++YYCURSOR; | 1099 | yych = *++YYCURSOR; |
| 1097 | if (yybm[0+yych] & 16) { | 1100 | if (yybm[0+yych] & 16) { |
| 1098 | goto yy134; | 1101 | goto yy100; |
| 1099 | } | 1102 | } |
| 1100 | t1 = yyt1; | 1103 | t1 = yyt1; |
| 1101 | t2 = YYCURSOR; | 1104 | t2 = YYCURSOR; |
| 1102 | { sy_res_push(atoi(t1)); goto yyc_cond_op; } | 1105 | { sy_res_push(atoi(t1)); goto yyc_cond_op; } |
| 1103 | yy137: | 1106 | yy101: |
| 1104 | yyaccept = 0; | 1107 | yyaccept = 0; |
| 1105 | yych = *(YYMARKER = ++YYCURSOR); | 1108 | yych = *(YYMARKER = ++YYCURSOR); |
| 1106 | if (yybm[0+yych] & 32) { | 1109 | if (yybm[0+yych] & 32) { |
| 1107 | goto yy137; | 1110 | goto yy101; |
| 1108 | } | 1111 | } |
| 1109 | if (yych == '(') goto yy140; | 1112 | if (yych == '(') goto yy103; |
| 1110 | yy139: | 1113 | yy102: |
| 1111 | t1 = yyt1; | 1114 | t1 = yyt1; |
| 1112 | t2 = YYCURSOR; | 1115 | t2 = YYCURSOR; |
| 1113 | { | 1116 | { |
| @@ -1119,34 +1122,34 @@ yy139: | |||
| 1119 | sy_res_push(atoi(ZSTR_VAL(tmp))); | 1122 | sy_res_push(atoi(ZSTR_VAL(tmp))); |
| 1120 | goto yyc_cond_op; | 1123 | goto yyc_cond_op; |
| 1121 | } | 1124 | } |
| 1122 | yy140: | 1125 | yy103: |
| 1123 | yych = *++YYCURSOR; | 1126 | yych = *++YYCURSOR; |
| 1124 | if (yych == '"') { | 1127 | if (yych == '"') { |
| 1125 | yyt2 = YYCURSOR; | 1128 | yyt2 = YYCURSOR; |
| 1126 | goto yy142; | 1129 | goto yy105; |
| 1127 | } | 1130 | } |
| 1128 | if (yych == ')') { | 1131 | if (yych == ')') { |
| 1129 | yyt2 = YYCURSOR; | 1132 | yyt2 = YYCURSOR; |
| 1130 | goto yy144; | 1133 | goto yy106; |
| 1131 | } | 1134 | } |
| 1132 | yy141: | 1135 | yy104: |
| 1133 | YYCURSOR = YYMARKER; | 1136 | YYCURSOR = YYMARKER; |
| 1134 | if (yyaccept == 0) { | 1137 | if (yyaccept == 0) { |
| 1135 | goto yy139; | 1138 | goto yy102; |
| 1136 | } else { | 1139 | } else { |
| 1137 | goto yy145; | 1140 | goto yy107; |
| 1138 | } | 1141 | } |
| 1139 | yy142: | 1142 | yy105: |
| 1140 | yych = *++YYCURSOR; | 1143 | yych = *++YYCURSOR; |
| 1141 | if (yybm[0+yych] & 64) { | 1144 | if (yybm[0+yych] & 64) { |
| 1142 | goto yy142; | 1145 | goto yy105; |
| 1143 | } | 1146 | } |
| 1144 | if (yych <= '\r') goto yy141; | 1147 | if (yych <= '\r') goto yy104; |
| 1145 | if (yych <= '"') goto yy146; | 1148 | if (yych <= '"') goto yy108; |
| 1146 | goto yy147; | 1149 | goto yy109; |
| 1147 | yy144: | 1150 | yy106: |
| 1148 | ++YYCURSOR; | 1151 | ++YYCURSOR; |
| 1149 | yy145: | 1152 | yy107: |
| 1150 | t1 = yyt1; | 1153 | t1 = yyt1; |
| 1151 | t3 = yyt2; | 1154 | t3 = yyt2; |
| 1152 | t2 = yyt2 - 1; | 1155 | t2 = yyt2 - 1; |
| @@ -1161,41 +1164,41 @@ yy145: | |||
| 1161 | } | 1164 | } |
| 1162 | goto yyc_cond_op; | 1165 | goto yyc_cond_op; |
| 1163 | } | 1166 | } |
| 1164 | yy146: | 1167 | yy108: |
| 1165 | yych = *++YYCURSOR; | 1168 | yych = *++YYCURSOR; |
| 1166 | if (yych == ')') goto yy144; | 1169 | if (yych == ')') goto yy106; |
| 1167 | goto yy141; | 1170 | goto yy104; |
| 1168 | yy147: | 1171 | yy109: |
| 1169 | yych = *++YYCURSOR; | 1172 | yych = *++YYCURSOR; |
| 1170 | if (yybm[0+yych] & 64) { | 1173 | if (yybm[0+yych] & 64) { |
| 1171 | goto yy142; | 1174 | goto yy105; |
| 1172 | } | 1175 | } |
| 1173 | if (yych <= '\r') goto yy141; | 1176 | if (yych <= '\r') goto yy104; |
| 1174 | if (yych >= '#') goto yy147; | 1177 | if (yych >= '#') goto yy109; |
| 1175 | yych = *++YYCURSOR; | 1178 | yych = *++YYCURSOR; |
| 1176 | if (yybm[0+yych] & 128) { | 1179 | if (yybm[0+yych] & 128) { |
| 1177 | goto yy147; | 1180 | goto yy109; |
| 1178 | } | 1181 | } |
| 1179 | if (yych <= '\r') { | 1182 | if (yych <= '\r') { |
| 1180 | if (yych == '\n') goto yy141; | 1183 | if (yych == '\n') goto yy104; |
| 1181 | if (yych <= '\f') goto yy142; | 1184 | if (yych <= '\f') goto yy105; |
| 1182 | goto yy141; | 1185 | goto yy104; |
| 1183 | } else { | 1186 | } else { |
| 1184 | if (yych <= '"') { | 1187 | if (yych <= '"') { |
| 1185 | if (yych <= '!') goto yy142; | 1188 | if (yych <= '!') goto yy105; |
| 1186 | goto yy146; | 1189 | goto yy108; |
| 1187 | } else { | 1190 | } else { |
| 1188 | if (yych != ')') goto yy142; | 1191 | if (yych != ')') goto yy105; |
| 1189 | } | 1192 | } |
| 1190 | } | 1193 | } |
| 1191 | yyaccept = 1; | 1194 | yyaccept = 1; |
| 1192 | yych = *(YYMARKER = ++YYCURSOR); | 1195 | yych = *(YYMARKER = ++YYCURSOR); |
| 1193 | if (yybm[0+yych] & 64) { | 1196 | if (yybm[0+yych] & 64) { |
| 1194 | goto yy142; | 1197 | goto yy105; |
| 1195 | } | 1198 | } |
| 1196 | if (yych <= '\r') goto yy145; | 1199 | if (yych <= '\r') goto yy107; |
| 1197 | if (yych <= '"') goto yy146; | 1200 | if (yych <= '"') goto yy108; |
| 1198 | goto yy147; | 1201 | goto yy109; |
| 1199 | } | 1202 | } |
| 1200 | /* *********************************** */ | 1203 | /* *********************************** */ |
| 1201 | yyc_cond_op: | 1204 | yyc_cond_op: |
| @@ -1236,63 +1239,63 @@ yyc_cond_op: | |||
| 1236 | }; | 1239 | }; |
| 1237 | yych = *YYCURSOR; | 1240 | yych = *YYCURSOR; |
| 1238 | if (yybm[0+yych] & 128) { | 1241 | if (yybm[0+yych] & 128) { |
| 1239 | goto yy155; | 1242 | goto yy113; |
| 1240 | } | 1243 | } |
| 1241 | if (yych <= ')') { | 1244 | if (yych <= ')') { |
| 1242 | if (yych <= '\r') { | 1245 | if (yych <= '\r') { |
| 1243 | if (yych <= 0x08) goto yy153; | 1246 | if (yych <= 0x08) goto yy111; |
| 1244 | if (yych <= '\n') goto yy158; | 1247 | if (yych <= '\n') goto yy114; |
| 1245 | if (yych >= '\r') goto yy160; | 1248 | if (yych >= '\r') goto yy115; |
| 1246 | } else { | 1249 | } else { |
| 1247 | if (yych == '&') { | 1250 | if (yych == '&') { |
| 1248 | yyt1 = YYCURSOR; | 1251 | yyt1 = YYCURSOR; |
| 1249 | goto yy161; | 1252 | goto yy116; |
| 1250 | } | 1253 | } |
| 1251 | if (yych >= ')') goto yy162; | 1254 | if (yych >= ')') goto yy117; |
| 1252 | } | 1255 | } |
| 1253 | } else { | 1256 | } else { |
| 1254 | if (yych <= '=') { | 1257 | if (yych <= '=') { |
| 1255 | if (yych <= ':') goto yy153; | 1258 | if (yych <= ':') goto yy111; |
| 1256 | if (yych <= ';') goto yy164; | 1259 | if (yych <= ';') goto yy118; |
| 1257 | if (yych <= '<') { | 1260 | if (yych <= '<') { |
| 1258 | yyt1 = YYCURSOR; | 1261 | yyt1 = YYCURSOR; |
| 1259 | goto yy166; | 1262 | goto yy119; |
| 1260 | } | 1263 | } |
| 1261 | yyt1 = YYCURSOR; | 1264 | yyt1 = YYCURSOR; |
| 1262 | goto yy168; | 1265 | goto yy121; |
| 1263 | } else { | 1266 | } else { |
| 1264 | if (yych <= '>') { | 1267 | if (yych <= '>') { |
| 1265 | yyt1 = YYCURSOR; | 1268 | yyt1 = YYCURSOR; |
| 1266 | goto yy166; | 1269 | goto yy119; |
| 1267 | } | 1270 | } |
| 1268 | if (yych == '|') { | 1271 | if (yych == '|') { |
| 1269 | yyt1 = YYCURSOR; | 1272 | yyt1 = YYCURSOR; |
| 1270 | goto yy169; | 1273 | goto yy122; |
| 1271 | } | 1274 | } |
| 1272 | } | 1275 | } |
| 1273 | } | 1276 | } |
| 1274 | yy153: | 1277 | yy111: |
| 1275 | ++YYCURSOR; | 1278 | ++YYCURSOR; |
| 1276 | yy154: | 1279 | yy112: |
| 1277 | { cs_log_error("Syntax error in condition on line %d", lineno); goto out; } | 1280 | { cs_log_error("Syntax error in condition on line %d", lineno); goto out; } |
| 1278 | yy155: | 1281 | yy113: |
| 1279 | yych = *++YYCURSOR; | 1282 | yych = *++YYCURSOR; |
| 1280 | if (yybm[0+yych] & 128) { | 1283 | if (yybm[0+yych] & 128) { |
| 1281 | goto yy155; | 1284 | goto yy113; |
| 1282 | } | 1285 | } |
| 1283 | { goto yyc_cond_op; } | 1286 | { goto yyc_cond_op; } |
| 1284 | yy158: | 1287 | yy114: |
| 1285 | ++YYCURSOR; | 1288 | ++YYCURSOR; |
| 1286 | { lineno++; goto yyc_cond_op; } | 1289 | { lineno++; goto yyc_cond_op; } |
| 1287 | yy160: | 1290 | yy115: |
| 1288 | yych = *++YYCURSOR; | 1291 | yych = *++YYCURSOR; |
| 1289 | if (yych == '\n') goto yy158; | 1292 | if (yych == '\n') goto yy114; |
| 1290 | goto yy154; | 1293 | goto yy112; |
| 1291 | yy161: | 1294 | yy116: |
| 1292 | yych = *++YYCURSOR; | 1295 | yych = *++YYCURSOR; |
| 1293 | if (yych == '&') goto yy170; | 1296 | if (yych == '&') goto yy123; |
| 1294 | goto yy154; | 1297 | goto yy112; |
| 1295 | yy162: | 1298 | yy117: |
| 1296 | ++YYCURSOR; | 1299 | ++YYCURSOR; |
| 1297 | { | 1300 | { |
| 1298 | while (cond_op_i && sy_op_peek() != '(') { | 1301 | while (cond_op_i && sy_op_peek() != '(') { |
| @@ -1304,7 +1307,7 @@ yy162: | |||
| 1304 | cond_op_i--; | 1307 | cond_op_i--; |
| 1305 | goto yyc_cond_op; | 1308 | goto yyc_cond_op; |
| 1306 | } | 1309 | } |
| 1307 | yy164: | 1310 | yy118: |
| 1308 | ++YYCURSOR; | 1311 | ++YYCURSOR; |
| 1309 | { | 1312 | { |
| 1310 | while (cond_op_i) { | 1313 | while (cond_op_i) { |
| @@ -1314,10 +1317,10 @@ yy164: | |||
| 1314 | if (cond_res_i > 1) { cs_log_error("invalid condition on line %d", lineno); goto out; } | 1317 | if (cond_res_i > 1) { cs_log_error("invalid condition on line %d", lineno); goto out; } |
| 1315 | goto yyc_init; | 1318 | goto yyc_init; |
| 1316 | } | 1319 | } |
| 1317 | yy166: | 1320 | yy119: |
| 1318 | yych = *++YYCURSOR; | 1321 | yych = *++YYCURSOR; |
| 1319 | if (yych == '=') goto yy170; | 1322 | if (yych == '=') goto yy123; |
| 1320 | yy167: | 1323 | yy120: |
| 1321 | t1 = yyt1; | 1324 | t1 = yyt1; |
| 1322 | t2 = YYCURSOR; | 1325 | t2 = YYCURSOR; |
| 1323 | { | 1326 | { |
| @@ -1334,16 +1337,16 @@ yy167: | |||
| 1334 | sy_op_push(*t1); | 1337 | sy_op_push(*t1); |
| 1335 | goto yyc_cond; | 1338 | goto yyc_cond; |
| 1336 | } | 1339 | } |
| 1337 | yy168: | 1340 | yy121: |
| 1338 | yych = *++YYCURSOR; | 1341 | yych = *++YYCURSOR; |
| 1339 | if (yych == '=') goto yy170; | 1342 | if (yych == '=') goto yy123; |
| 1340 | goto yy154; | 1343 | goto yy112; |
| 1341 | yy169: | 1344 | yy122: |
| 1342 | yych = *++YYCURSOR; | 1345 | yych = *++YYCURSOR; |
| 1343 | if (yych != '|') goto yy154; | 1346 | if (yych != '|') goto yy112; |
| 1344 | yy170: | 1347 | yy123: |
| 1345 | ++YYCURSOR; | 1348 | ++YYCURSOR; |
| 1346 | goto yy167; | 1349 | goto yy120; |
| 1347 | } | 1350 | } |
| 1348 | /* *********************************** */ | 1351 | /* *********************************** */ |
| 1349 | yyc_rule: | 1352 | yyc_rule: |
| @@ -1384,77 +1387,77 @@ yyc_rule: | |||
| 1384 | }; | 1387 | }; |
| 1385 | yych = *YYCURSOR; | 1388 | yych = *YYCURSOR; |
| 1386 | if (yybm[0+yych] & 8) { | 1389 | if (yybm[0+yych] & 8) { |
| 1387 | goto yy175; | 1390 | goto yy127; |
| 1388 | } | 1391 | } |
| 1389 | if (yych <= '\r') { | 1392 | if (yych <= '\r') { |
| 1390 | if (yych <= 0x08) goto yy173; | 1393 | if (yych <= 0x08) goto yy125; |
| 1391 | if (yych <= '\n') goto yy178; | 1394 | if (yych <= '\n') goto yy128; |
| 1392 | if (yych >= '\r') goto yy179; | 1395 | if (yych >= '\r') goto yy129; |
| 1393 | } else { | 1396 | } else { |
| 1394 | if (yych <= '.') { | 1397 | if (yych <= '.') { |
| 1395 | if (yych >= '.') goto yy180; | 1398 | if (yych >= '.') goto yy130; |
| 1396 | } else { | 1399 | } else { |
| 1397 | if (yych == ';') goto yy181; | 1400 | if (yych == ';') goto yy131; |
| 1398 | } | 1401 | } |
| 1399 | } | 1402 | } |
| 1400 | yy173: | 1403 | yy125: |
| 1401 | ++YYCURSOR; | 1404 | ++YYCURSOR; |
| 1402 | yy174: | 1405 | yy126: |
| 1403 | { goto end_of_rule; } | 1406 | { goto end_of_rule; } |
| 1404 | yy175: | 1407 | yy127: |
| 1405 | yych = *++YYCURSOR; | 1408 | yych = *++YYCURSOR; |
| 1406 | if (yybm[0+yych] & 8) { | 1409 | if (yybm[0+yych] & 8) { |
| 1407 | goto yy175; | 1410 | goto yy127; |
| 1408 | } | 1411 | } |
| 1409 | { goto yyc_rule; } | 1412 | { goto yyc_rule; } |
| 1410 | yy178: | 1413 | yy128: |
| 1411 | yyaccept = 0; | 1414 | yyaccept = 0; |
| 1412 | yych = *(YYMARKER = ++YYCURSOR); | 1415 | yych = *(YYMARKER = ++YYCURSOR); |
| 1413 | if (yych <= '\r') { | 1416 | if (yych <= '\r') { |
| 1414 | if (yych <= 0x08) goto yy174; | 1417 | if (yych <= 0x08) goto yy126; |
| 1415 | if (yych <= '\n') { | 1418 | if (yych <= '\n') { |
| 1416 | yyt1 = YYCURSOR; | 1419 | yyt1 = YYCURSOR; |
| 1417 | goto yy183; | 1420 | goto yy132; |
| 1418 | } | 1421 | } |
| 1419 | if (yych <= '\f') goto yy174; | 1422 | if (yych <= '\f') goto yy126; |
| 1420 | yyt1 = YYCURSOR; | 1423 | yyt1 = YYCURSOR; |
| 1421 | goto yy186; | 1424 | goto yy134; |
| 1422 | } else { | 1425 | } else { |
| 1423 | if (yych <= ' ') { | 1426 | if (yych <= ' ') { |
| 1424 | if (yych <= 0x1F) goto yy174; | 1427 | if (yych <= 0x1F) goto yy126; |
| 1425 | yyt1 = YYCURSOR; | 1428 | yyt1 = YYCURSOR; |
| 1426 | goto yy183; | 1429 | goto yy132; |
| 1427 | } else { | 1430 | } else { |
| 1428 | if (yych == '.') { | 1431 | if (yych == '.') { |
| 1429 | yyt1 = YYCURSOR; | 1432 | yyt1 = YYCURSOR; |
| 1430 | goto yy187; | 1433 | goto yy135; |
| 1431 | } | 1434 | } |
| 1432 | goto yy174; | 1435 | goto yy126; |
| 1433 | } | 1436 | } |
| 1434 | } | 1437 | } |
| 1435 | yy179: | 1438 | yy129: |
| 1436 | yyaccept = 0; | 1439 | yyaccept = 0; |
| 1437 | yych = *(YYMARKER = ++YYCURSOR); | 1440 | yych = *(YYMARKER = ++YYCURSOR); |
| 1438 | if (yych == '\n') goto yy189; | 1441 | if (yych == '\n') goto yy136; |
| 1439 | goto yy174; | 1442 | goto yy126; |
| 1440 | yy180: | 1443 | yy130: |
| 1441 | yych = *++YYCURSOR; | 1444 | yych = *++YYCURSOR; |
| 1442 | if (yych <= '^') { | 1445 | if (yych <= '^') { |
| 1443 | if (yych <= '@') goto yy174; | 1446 | if (yych <= '@') goto yy126; |
| 1444 | if (yych <= 'Z') { | 1447 | if (yych <= 'Z') { |
| 1445 | yyt1 = YYCURSOR; | 1448 | yyt1 = YYCURSOR; |
| 1446 | goto yy190; | 1449 | goto yy137; |
| 1447 | } | 1450 | } |
| 1448 | goto yy174; | 1451 | goto yy126; |
| 1449 | } else { | 1452 | } else { |
| 1450 | if (yych == '`') goto yy174; | 1453 | if (yych == '`') goto yy126; |
| 1451 | if (yych <= 'z') { | 1454 | if (yych <= 'z') { |
| 1452 | yyt1 = YYCURSOR; | 1455 | yyt1 = YYCURSOR; |
| 1453 | goto yy190; | 1456 | goto yy137; |
| 1454 | } | 1457 | } |
| 1455 | goto yy174; | 1458 | goto yy126; |
| 1456 | } | 1459 | } |
| 1457 | yy181: | 1460 | yy131: |
| 1458 | ++YYCURSOR; | 1461 | ++YYCURSOR; |
| 1459 | { | 1462 | { |
| 1460 | end_of_rule: | 1463 | end_of_rule: |
| @@ -1465,71 +1468,71 @@ yy181: | |||
| 1465 | } | 1468 | } |
| 1466 | goto yyc_init; | 1469 | goto yyc_init; |
| 1467 | } | 1470 | } |
| 1468 | yy183: | 1471 | yy132: |
| 1469 | yych = *++YYCURSOR; | 1472 | yych = *++YYCURSOR; |
| 1470 | if (yybm[0+yych] & 16) { | 1473 | if (yybm[0+yych] & 16) { |
| 1471 | goto yy183; | 1474 | goto yy132; |
| 1472 | } | 1475 | } |
| 1473 | if (yych == '\r') goto yy186; | 1476 | if (yych == '\r') goto yy134; |
| 1474 | if (yych == '.') goto yy187; | 1477 | if (yych == '.') goto yy135; |
| 1475 | yy185: | 1478 | yy133: |
| 1476 | YYCURSOR = YYMARKER; | 1479 | YYCURSOR = YYMARKER; |
| 1477 | if (yyaccept <= 1) { | 1480 | if (yyaccept <= 1) { |
| 1478 | if (yyaccept == 0) { | 1481 | if (yyaccept == 0) { |
| 1479 | goto yy174; | 1482 | goto yy126; |
| 1480 | } else { | 1483 | } else { |
| 1481 | yyt3 = yyt4 = NULL; | 1484 | yyt3 = yyt4 = NULL; |
| 1482 | yyt2 = YYCURSOR; | 1485 | yyt2 = YYCURSOR; |
| 1483 | goto yy192; | 1486 | goto yy138; |
| 1484 | } | 1487 | } |
| 1485 | } else { | 1488 | } else { |
| 1486 | goto yy192; | 1489 | goto yy138; |
| 1487 | } | 1490 | } |
| 1488 | yy186: | 1491 | yy134: |
| 1489 | yych = *++YYCURSOR; | 1492 | yych = *++YYCURSOR; |
| 1490 | if (yych == '\n') goto yy183; | 1493 | if (yych == '\n') goto yy132; |
| 1491 | goto yy185; | 1494 | goto yy133; |
| 1492 | yy187: | 1495 | yy135: |
| 1493 | ++YYCURSOR; | 1496 | ++YYCURSOR; |
| 1494 | YYCURSOR = yyt1; | 1497 | YYCURSOR = yyt1; |
| 1495 | { lineno++; goto yyc_rule; } | 1498 | { lineno++; goto yyc_rule; } |
| 1496 | yy189: | 1499 | yy136: |
| 1497 | yych = *++YYCURSOR; | 1500 | yych = *++YYCURSOR; |
| 1498 | if (yych <= '\r') { | 1501 | if (yych <= '\r') { |
| 1499 | if (yych <= 0x08) goto yy185; | 1502 | if (yych <= 0x08) goto yy133; |
| 1500 | if (yych <= '\n') { | 1503 | if (yych <= '\n') { |
| 1501 | yyt1 = YYCURSOR; | 1504 | yyt1 = YYCURSOR; |
| 1502 | goto yy183; | 1505 | goto yy132; |
| 1503 | } | 1506 | } |
| 1504 | if (yych <= '\f') goto yy185; | 1507 | if (yych <= '\f') goto yy133; |
| 1505 | yyt1 = YYCURSOR; | 1508 | yyt1 = YYCURSOR; |
| 1506 | goto yy186; | 1509 | goto yy134; |
| 1507 | } else { | 1510 | } else { |
| 1508 | if (yych <= ' ') { | 1511 | if (yych <= ' ') { |
| 1509 | if (yych <= 0x1F) goto yy185; | 1512 | if (yych <= 0x1F) goto yy133; |
| 1510 | yyt1 = YYCURSOR; | 1513 | yyt1 = YYCURSOR; |
| 1511 | goto yy183; | 1514 | goto yy132; |
| 1512 | } else { | 1515 | } else { |
| 1513 | if (yych == '.') { | 1516 | if (yych == '.') { |
| 1514 | yyt1 = YYCURSOR; | 1517 | yyt1 = YYCURSOR; |
| 1515 | goto yy187; | 1518 | goto yy135; |
| 1516 | } | 1519 | } |
| 1517 | goto yy185; | 1520 | goto yy133; |
| 1518 | } | 1521 | } |
| 1519 | } | 1522 | } |
| 1520 | yy190: | 1523 | yy137: |
| 1521 | yyaccept = 1; | 1524 | yyaccept = 1; |
| 1522 | yych = *(YYMARKER = ++YYCURSOR); | 1525 | yych = *(YYMARKER = ++YYCURSOR); |
| 1523 | if (yybm[0+yych] & 32) { | 1526 | if (yybm[0+yych] & 32) { |
| 1524 | goto yy190; | 1527 | goto yy137; |
| 1525 | } | 1528 | } |
| 1526 | if (yych == '(') { | 1529 | if (yych == '(') { |
| 1527 | yyt2 = YYCURSOR; | 1530 | yyt2 = YYCURSOR; |
| 1528 | goto yy193; | 1531 | goto yy139; |
| 1529 | } | 1532 | } |
| 1530 | yyt3 = yyt4 = NULL; | 1533 | yyt3 = yyt4 = NULL; |
| 1531 | yyt2 = YYCURSOR; | 1534 | yyt2 = YYCURSOR; |
| 1532 | yy192: | 1535 | yy138: |
| 1533 | t1 = yyt1; | 1536 | t1 = yyt1; |
| 1534 | t2 = yyt2; | 1537 | t2 = yyt2; |
| 1535 | t3 = yyt3; | 1538 | t3 = yyt3; |
| @@ -1564,114 +1567,114 @@ yy192: | |||
| 1564 | parsed_rule[kw_i++] = kw; | 1567 | parsed_rule[kw_i++] = kw; |
| 1565 | goto yyc_rule; | 1568 | goto yyc_rule; |
| 1566 | } | 1569 | } |
| 1567 | yy193: | 1570 | yy139: |
| 1568 | yych = *++YYCURSOR; | 1571 | yych = *++YYCURSOR; |
| 1569 | if (yych <= '@') { | 1572 | if (yych <= '@') { |
| 1570 | if (yych <= '"') { | 1573 | if (yych <= '"') { |
| 1571 | if (yych <= '!') goto yy185; | 1574 | if (yych <= '!') goto yy133; |
| 1572 | yyt3 = YYCURSOR; | 1575 | yyt3 = YYCURSOR; |
| 1573 | } else { | 1576 | } else { |
| 1574 | if (yych == ')') { | 1577 | if (yych == ')') { |
| 1575 | yyt3 = yyt4 = YYCURSOR; | 1578 | yyt3 = yyt4 = YYCURSOR; |
| 1576 | goto yy196; | 1579 | goto yy141; |
| 1577 | } | 1580 | } |
| 1578 | goto yy185; | 1581 | goto yy133; |
| 1579 | } | 1582 | } |
| 1580 | } else { | 1583 | } else { |
| 1581 | if (yych <= '_') { | 1584 | if (yych <= '_') { |
| 1582 | if (yych <= 'Z') { | 1585 | if (yych <= 'Z') { |
| 1583 | yyt3 = YYCURSOR; | 1586 | yyt3 = YYCURSOR; |
| 1584 | goto yy197; | 1587 | goto yy142; |
| 1585 | } | 1588 | } |
| 1586 | if (yych <= '^') goto yy185; | 1589 | if (yych <= '^') goto yy133; |
| 1587 | yyt3 = YYCURSOR; | 1590 | yyt3 = YYCURSOR; |
| 1588 | goto yy197; | 1591 | goto yy142; |
| 1589 | } else { | 1592 | } else { |
| 1590 | if (yych <= '`') goto yy185; | 1593 | if (yych <= '`') goto yy133; |
| 1591 | if (yych <= 'z') { | 1594 | if (yych <= 'z') { |
| 1592 | yyt3 = YYCURSOR; | 1595 | yyt3 = YYCURSOR; |
| 1593 | goto yy197; | 1596 | goto yy142; |
| 1594 | } | 1597 | } |
| 1595 | goto yy185; | 1598 | goto yy133; |
| 1596 | } | 1599 | } |
| 1597 | } | 1600 | } |
| 1598 | yy194: | 1601 | yy140: |
| 1599 | yych = *++YYCURSOR; | 1602 | yych = *++YYCURSOR; |
| 1600 | if (yybm[0+yych] & 64) { | 1603 | if (yybm[0+yych] & 64) { |
| 1601 | goto yy194; | 1604 | goto yy140; |
| 1602 | } | 1605 | } |
| 1603 | if (yych <= '\r') goto yy185; | 1606 | if (yych <= '\r') goto yy133; |
| 1604 | if (yych <= '"') goto yy199; | 1607 | if (yych <= '"') goto yy143; |
| 1605 | goto yy200; | 1608 | goto yy144; |
| 1606 | yy196: | 1609 | yy141: |
| 1607 | ++YYCURSOR; | 1610 | ++YYCURSOR; |
| 1608 | goto yy192; | 1611 | goto yy138; |
| 1609 | yy197: | 1612 | yy142: |
| 1610 | yych = *++YYCURSOR; | 1613 | yych = *++YYCURSOR; |
| 1611 | if (yych <= '@') { | 1614 | if (yych <= '@') { |
| 1612 | if (yych <= ')') { | 1615 | if (yych <= ')') { |
| 1613 | if (yych <= '(') goto yy185; | 1616 | if (yych <= '(') goto yy133; |
| 1614 | yyt4 = YYCURSOR; | 1617 | yyt4 = YYCURSOR; |
| 1615 | goto yy196; | 1618 | goto yy141; |
| 1616 | } else { | 1619 | } else { |
| 1617 | if (yych <= '/') goto yy185; | 1620 | if (yych <= '/') goto yy133; |
| 1618 | if (yych <= '9') goto yy197; | 1621 | if (yych <= '9') goto yy142; |
| 1619 | goto yy185; | 1622 | goto yy133; |
| 1620 | } | 1623 | } |
| 1621 | } else { | 1624 | } else { |
| 1622 | if (yych <= '_') { | 1625 | if (yych <= '_') { |
| 1623 | if (yych <= 'Z') goto yy197; | 1626 | if (yych <= 'Z') goto yy142; |
| 1624 | if (yych <= '^') goto yy185; | 1627 | if (yych <= '^') goto yy133; |
| 1625 | goto yy197; | 1628 | goto yy142; |
| 1626 | } else { | 1629 | } else { |
| 1627 | if (yych <= '`') goto yy185; | 1630 | if (yych <= '`') goto yy133; |
| 1628 | if (yych <= 'z') goto yy197; | 1631 | if (yych <= 'z') goto yy142; |
| 1629 | goto yy185; | 1632 | goto yy133; |
| 1630 | } | 1633 | } |
| 1631 | } | 1634 | } |
| 1632 | yy199: | 1635 | yy143: |
| 1633 | yych = *++YYCURSOR; | 1636 | yych = *++YYCURSOR; |
| 1634 | if (yych == ')') { | 1637 | if (yych == ')') { |
| 1635 | yyt4 = YYCURSOR; | 1638 | yyt4 = YYCURSOR; |
| 1636 | goto yy196; | 1639 | goto yy141; |
| 1637 | } | 1640 | } |
| 1638 | goto yy185; | 1641 | goto yy133; |
| 1639 | yy200: | 1642 | yy144: |
| 1640 | yych = *++YYCURSOR; | 1643 | yych = *++YYCURSOR; |
| 1641 | if (yybm[0+yych] & 64) { | 1644 | if (yybm[0+yych] & 64) { |
| 1642 | goto yy194; | 1645 | goto yy140; |
| 1643 | } | 1646 | } |
| 1644 | if (yych <= '\r') goto yy185; | 1647 | if (yych <= '\r') goto yy133; |
| 1645 | if (yych >= '#') goto yy200; | 1648 | if (yych >= '#') goto yy144; |
| 1646 | yych = *++YYCURSOR; | 1649 | yych = *++YYCURSOR; |
| 1647 | if (yybm[0+yych] & 128) { | 1650 | if (yybm[0+yych] & 128) { |
| 1648 | goto yy200; | 1651 | goto yy144; |
| 1649 | } | 1652 | } |
| 1650 | if (yych <= '\r') { | 1653 | if (yych <= '\r') { |
| 1651 | if (yych == '\n') goto yy185; | 1654 | if (yych == '\n') goto yy133; |
| 1652 | if (yych <= '\f') goto yy194; | 1655 | if (yych <= '\f') goto yy140; |
| 1653 | goto yy185; | 1656 | goto yy133; |
| 1654 | } else { | 1657 | } else { |
| 1655 | if (yych <= '"') { | 1658 | if (yych <= '"') { |
| 1656 | if (yych <= '!') goto yy194; | 1659 | if (yych <= '!') goto yy140; |
| 1657 | goto yy199; | 1660 | goto yy143; |
| 1658 | } else { | 1661 | } else { |
| 1659 | if (yych != ')') goto yy194; | 1662 | if (yych != ')') goto yy140; |
| 1660 | yyt4 = YYCURSOR; | 1663 | yyt4 = YYCURSOR; |
| 1661 | } | 1664 | } |
| 1662 | } | 1665 | } |
| 1663 | yyaccept = 2; | 1666 | yyaccept = 2; |
| 1664 | yych = *(YYMARKER = ++YYCURSOR); | 1667 | yych = *(YYMARKER = ++YYCURSOR); |
| 1665 | if (yybm[0+yych] & 64) { | 1668 | if (yybm[0+yych] & 64) { |
| 1666 | goto yy194; | 1669 | goto yy140; |
| 1667 | } | 1670 | } |
| 1668 | if (yych <= '\r') goto yy192; | 1671 | if (yych <= '\r') goto yy138; |
| 1669 | if (yych <= '"') goto yy199; | 1672 | if (yych <= '"') goto yy143; |
| 1670 | goto yy200; | 1673 | goto yy144; |
| 1671 | } | 1674 | } |
| 1672 | } | 1675 | } |
| 1673 | 1676 | ||
| 1674 | out: | 1677 | out: |
| 1675 | zend_hash_destroy(&vars); | 1678 | zend_hash_destroy(&vars); |
| 1676 | return ret; | 1679 | return ret; |
| 1677 | } \ No newline at end of file | 1680 | } |
diff --git a/src/sp_config_scanner.h b/src/sp_config_scanner.h index 3284713..8ce1fb7 100644 --- a/src/sp_config_scanner.h +++ b/src/sp_config_scanner.h | |||
| @@ -19,7 +19,7 @@ typedef struct { | |||
| 19 | } sp_parsed_keyword; | 19 | } sp_parsed_keyword; |
| 20 | 20 | ||
| 21 | zend_result sp_config_scan(char *data, zend_result (*process_rule)(sp_parsed_keyword*)); | 21 | zend_result sp_config_scan(char *data, zend_result (*process_rule)(sp_parsed_keyword*)); |
| 22 | zend_string *sp_get_arg_string(sp_parsed_keyword *kw); | 22 | zend_string *sp_get_arg_string(sp_parsed_keyword const *const kw); |
| 23 | zend_string *sp_get_textual_representation(sp_parsed_keyword *parsed_rule); | 23 | zend_string *sp_get_textual_representation(sp_parsed_keyword const *const parsed_rule); |
| 24 | 24 | ||
| 25 | #endif \ No newline at end of file | 25 | #endif |
diff --git a/src/sp_config_scanner.re b/src/sp_config_scanner.re index d7c9884..6a14a11 100644 --- a/src/sp_config_scanner.re +++ b/src/sp_config_scanner.re | |||
| @@ -1,5 +1,7 @@ | |||
| 1 | #include "php_snuffleupagus.h" | 1 | #include "php_snuffleupagus.h" |
| 2 | 2 | ||
| 3 | #pragma GCC diagnostic ignored "-Wmaybe-uninitialized" | ||
| 4 | |||
| 3 | /*!types:re2c*/ | 5 | /*!types:re2c*/ |
| 4 | 6 | ||
| 5 | #define cs_log_error(fmt, ...) sp_log_err("config", fmt, ##__VA_ARGS__) | 7 | #define cs_log_error(fmt, ...) sp_log_err("config", fmt, ##__VA_ARGS__) |
| @@ -7,7 +9,7 @@ | |||
| 7 | #define cs_log_warning(fmt, ...) sp_log_warn("config", fmt, ##__VA_ARGS__) | 9 | #define cs_log_warning(fmt, ...) sp_log_warn("config", fmt, ##__VA_ARGS__) |
| 8 | 10 | ||
| 9 | 11 | ||
| 10 | zend_string *sp_get_arg_string(sp_parsed_keyword *kw) { | 12 | zend_string *sp_get_arg_string(sp_parsed_keyword const *const kw) { |
| 11 | if (!kw || !kw->arg) { | 13 | if (!kw || !kw->arg) { |
| 12 | return NULL; | 14 | return NULL; |
| 13 | } | 15 | } |
| @@ -33,11 +35,10 @@ zend_string *sp_get_arg_string(sp_parsed_keyword *kw) { | |||
| 33 | return ret; | 35 | return ret; |
| 34 | } | 36 | } |
| 35 | 37 | ||
| 36 | zend_string *sp_get_textual_representation(sp_parsed_keyword *parsed_rule) { | 38 | zend_string *sp_get_textual_representation(sp_parsed_keyword const *const parsed_rule) { |
| 37 | // a rule is "sp.keyword...keyword(arg);\0" | 39 | // a rule is "sp.keyword...keyword(arg);\0" |
| 38 | size_t len = 3; // sp + ; | 40 | size_t len = 3; // sp + ; |
| 39 | sp_parsed_keyword *kw; | 41 | for (const sp_parsed_keyword *kw = parsed_rule; kw->kw; kw++) { |
| 40 | for (kw = parsed_rule; kw->kw; kw++) { | ||
| 41 | len++; // . | 42 | len++; // . |
| 42 | len += kw->kwlen; | 43 | len += kw->kwlen; |
| 43 | if (kw->argtype == SP_ARGTYPE_EMPTY) { | 44 | if (kw->argtype == SP_ARGTYPE_EMPTY) { |
| @@ -47,10 +48,12 @@ zend_string *sp_get_textual_representation(sp_parsed_keyword *parsed_rule) { | |||
| 47 | len += kw->arglen; | 48 | len += kw->arglen; |
| 48 | } | 49 | } |
| 49 | } | 50 | } |
| 51 | |||
| 50 | zend_string *ret = zend_string_alloc(len, 1); | 52 | zend_string *ret = zend_string_alloc(len, 1); |
| 51 | char *ptr = ZSTR_VAL(ret); | 53 | char *ptr = ZSTR_VAL(ret); |
| 54 | |||
| 52 | memcpy(ptr, "sp", 2); ptr += 2; | 55 | memcpy(ptr, "sp", 2); ptr += 2; |
| 53 | for (kw = parsed_rule; kw->kw; kw++) { | 56 | for (const sp_parsed_keyword *kw = parsed_rule; kw->kw; kw++) { |
| 54 | *ptr++ = '.'; | 57 | *ptr++ = '.'; |
| 55 | memcpy(ptr, kw->kw, kw->kwlen); ptr += kw->kwlen; | 58 | memcpy(ptr, kw->kw, kw->kwlen); ptr += kw->kwlen; |
| 56 | if (kw->argtype == SP_ARGTYPE_EMPTY || kw->argtype == SP_ARGTYPE_STR || kw->argtype == SP_ARGTYPE_UNKNOWN) { | 59 | if (kw->argtype == SP_ARGTYPE_EMPTY || kw->argtype == SP_ARGTYPE_STR || kw->argtype == SP_ARGTYPE_UNKNOWN) { |
| @@ -322,4 +325,4 @@ zend_result sp_config_scan(char *data, zend_result (*process_rule)(sp_parsed_key | |||
| 322 | out: | 325 | out: |
| 323 | zend_hash_destroy(&vars); | 326 | zend_hash_destroy(&vars); |
| 324 | return ret; | 327 | return ret; |
| 325 | } \ No newline at end of file | 328 | } |
diff --git a/src/sp_config_utils.c b/src/sp_config_utils.c index e93ef31..84b1f30 100644 --- a/src/sp_config_utils.c +++ b/src/sp_config_utils.c | |||
| @@ -1,8 +1,8 @@ | |||
| 1 | #include "php_snuffleupagus.h" | 1 | #include "php_snuffleupagus.h" |
| 2 | 2 | ||
| 3 | 3 | ||
| 4 | sp_list_node *parse_functions_list(char *value) { | 4 | sp_list_node *parse_functions_list(const char *const value) { |
| 5 | static const char *sep = ">"; | 5 | static const char *const sep = ">"; |
| 6 | 6 | ||
| 7 | if (NULL == strchr(value, sep[0])) { | 7 | if (NULL == strchr(value, sep[0])) { |
| 8 | return NULL; | 8 | return NULL; |
| @@ -10,7 +10,7 @@ sp_list_node *parse_functions_list(char *value) { | |||
| 10 | 10 | ||
| 11 | sp_list_node *list = NULL; | 11 | sp_list_node *list = NULL; |
| 12 | char *tmp = strdup(value); | 12 | char *tmp = strdup(value); |
| 13 | char *function_name; | 13 | const char *function_name; |
| 14 | char *next_token = tmp; | 14 | char *next_token = tmp; |
| 15 | while ((function_name = strtok_r(NULL, sep, &next_token))) { | 15 | while ((function_name = strtok_r(NULL, sep, &next_token))) { |
| 16 | list = sp_list_prepend(list, strdup(function_name)); | 16 | list = sp_list_prepend(list, strdup(function_name)); |
diff --git a/src/sp_config_utils.h b/src/sp_config_utils.h index 64817a0..a3a2c81 100644 --- a/src/sp_config_utils.h +++ b/src/sp_config_utils.h | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | #ifndef SP_CONFIG_UTILS | 1 | #ifndef SP_CONFIG_UTILS |
| 2 | #define SP_CONFIG_UTILS | 2 | #define SP_CONFIG_UTILS |
| 3 | 3 | ||
| 4 | sp_list_node *parse_functions_list(char *value); | 4 | sp_list_node *parse_functions_list(const char *const value); |
| 5 | 5 | ||
| 6 | #endif /* SP_CONFIG_UTILS */ | 6 | #endif /* SP_CONFIG_UTILS */ |
diff --git a/src/sp_crypt.c b/src/sp_crypt.c index c1d9403..a27cc67 100644 --- a/src/sp_crypt.c +++ b/src/sp_crypt.c | |||
| @@ -115,10 +115,9 @@ int decrypt_zval(zval *pDest, bool simulation, zend_hash_key *hash_key) { | |||
| 115 | ret = ZEND_HASH_APPLY_KEEP; | 115 | ret = ZEND_HASH_APPLY_KEEP; |
| 116 | 116 | ||
| 117 | out: | 117 | out: |
| 118 | 118 | zend_string_efree(debase64); | |
| 119 | if (debase64) { zend_string_efree(debase64); } | 119 | efree(decrypted); |
| 120 | if (decrypted) { efree(decrypted); } | 120 | efree(backup); |
| 121 | if (backup) { efree(backup); } | ||
| 122 | 121 | ||
| 123 | return ret; | 122 | return ret; |
| 124 | } | 123 | } |
diff --git a/src/sp_disabled_functions.c b/src/sp_disabled_functions.c index 95e19ad..10a9466 100644 --- a/src/sp_disabled_functions.c +++ b/src/sp_disabled_functions.c | |||
| @@ -16,7 +16,7 @@ char* get_complete_function_path(zend_execute_data const* const execute_data) { | |||
| 16 | if (!execute_data) { | 16 | if (!execute_data) { |
| 17 | return NULL; // LCOV_EXCL_LINE | 17 | return NULL; // LCOV_EXCL_LINE |
| 18 | } | 18 | } |
| 19 | zend_function *func = execute_data->func; | 19 | const zend_function *const func = execute_data->func; |
| 20 | if (!(func->common.function_name)) { | 20 | if (!(func->common.function_name)) { |
| 21 | return NULL; | 21 | return NULL; |
| 22 | } | 22 | } |
| @@ -25,7 +25,7 @@ char* get_complete_function_path(zend_execute_data const* const execute_data) { | |||
| 25 | char* complete_path_function = NULL; | 25 | char* complete_path_function = NULL; |
| 26 | 26 | ||
| 27 | if ((func->type == ZEND_USER_FUNCTION || func->type == ZEND_INTERNAL_FUNCTION) && func->common.scope) { | 27 | if ((func->type == ZEND_USER_FUNCTION || func->type == ZEND_INTERNAL_FUNCTION) && func->common.scope) { |
| 28 | char const* class_name = ZSTR_VAL(func->common.scope->name); | 28 | const char *const class_name = ZSTR_VAL(func->common.scope->name); |
| 29 | const size_t len = strlen(class_name) + 2 + strlen(function_name) + 1; | 29 | const size_t len = strlen(class_name) + 2 + strlen(function_name) + 1; |
| 30 | complete_path_function = emalloc(len); | 30 | complete_path_function = emalloc(len); |
| 31 | snprintf(complete_path_function, len, "%s::%s", class_name, function_name); | 31 | snprintf(complete_path_function, len, "%s::%s", class_name, function_name); |
| @@ -515,7 +515,11 @@ ZEND_FUNCTION(eval_blacklist_callback) { | |||
| 515 | zif_handler orig_handler; | 515 | zif_handler orig_handler; |
| 516 | char* current_function_name = get_complete_function_path(EG(current_execute_data)); | 516 | char* current_function_name = get_complete_function_path(EG(current_execute_data)); |
| 517 | 517 | ||
| 518 | if (!current_function_name || true == check_is_in_eval_whitelist(current_function_name)) { | 518 | if (!current_function_name) { |
| 519 | return; | ||
| 520 | } | ||
| 521 | |||
| 522 | if( true == check_is_in_eval_whitelist(current_function_name)) { | ||
| 519 | goto whitelisted; | 523 | goto whitelisted; |
| 520 | } | 524 | } |
| 521 | 525 | ||
diff --git a/src/sp_execute.c b/src/sp_execute.c index 3a474a3..b4e5c6c 100644 --- a/src/sp_execute.c +++ b/src/sp_execute.c | |||
| @@ -11,11 +11,10 @@ static zend_result (*orig_zend_stream_open)(zend_file_handle *handle) = NULL; | |||
| 11 | #endif | 11 | #endif |
| 12 | 12 | ||
| 13 | // FIXME handle symlink | 13 | // FIXME handle symlink |
| 14 | ZEND_COLD static inline void terminate_if_writable(const char *filename) { | 14 | ZEND_COLD static inline void terminate_if_writable(char const* const filename) { |
| 15 | const sp_config_readonly_exec *config_ro_exec = &(SPCFG(readonly_exec)); | 15 | sp_config_readonly_exec const* const config_ro_exec = &(SPCFG(readonly_exec)); |
| 16 | char *errmsg = "unknown access problem"; | 16 | char const *errmsg = "unknown access problem"; |
| 17 | 17 | ||
| 18 | // check write access | ||
| 19 | if (0 == access(filename, W_OK)) { | 18 | if (0 == access(filename, W_OK)) { |
| 20 | errmsg = "Attempted execution of a writable file"; | 19 | errmsg = "Attempted execution of a writable file"; |
| 21 | goto violation; | 20 | goto violation; |
| @@ -29,21 +28,20 @@ ZEND_COLD static inline void terminate_if_writable(const char *filename) { | |||
| 29 | return; | 28 | return; |
| 30 | } | 29 | } |
| 31 | 30 | ||
| 32 | // check effective uid | ||
| 33 | struct stat buf; | 31 | struct stat buf; |
| 34 | if (0 != stat(filename, &buf)) { | 32 | if (0 != stat(filename, &buf)) { |
| 35 | goto err; | 33 | goto err; |
| 36 | } | 34 | } |
| 37 | if (buf.st_uid == geteuid()) { | 35 | if (buf.st_uid == geteuid()) { |
| 38 | errmsg = "Attempted execution of file owned by process"; | 36 | errmsg = "Attempted execution of a file owned by the PHP process"; |
| 39 | goto violation; | 37 | goto violation; |
| 40 | } | 38 | } |
| 41 | 39 | ||
| 42 | // check write access on directory | 40 | char *const dirname = estrndup(filename, strlen(filename)); |
| 43 | char *dirname = estrndup(filename, strlen(filename)); | ||
| 44 | php_dirname(dirname, strlen(dirname)); | 41 | php_dirname(dirname, strlen(dirname)); |
| 45 | if (0 == access(dirname, W_OK)) { | 42 | if (0 == access(dirname, W_OK)) { |
| 46 | errmsg = "Attempted execution of file in writable directory"; | 43 | errmsg = "Attempted execution of a file in a writable directory"; |
| 44 | |||
| 47 | efree(dirname); | 45 | efree(dirname); |
| 48 | goto violation; | 46 | goto violation; |
| 49 | } | 47 | } |
| @@ -52,18 +50,16 @@ ZEND_COLD static inline void terminate_if_writable(const char *filename) { | |||
| 52 | goto err; | 50 | goto err; |
| 53 | } | 51 | } |
| 54 | 52 | ||
| 55 | // check effecite uid of directory | ||
| 56 | if (0 != stat(dirname, &buf)) { | 53 | if (0 != stat(dirname, &buf)) { |
| 57 | efree(dirname); | 54 | efree(dirname); |
| 58 | goto err; | 55 | goto err; |
| 59 | } | 56 | } |
| 60 | efree(dirname); | 57 | efree(dirname); |
| 61 | if (buf.st_uid == geteuid()) { | 58 | if (buf.st_uid == geteuid()) { |
| 62 | errmsg = "Attempted execution of file in directory owned by process"; | 59 | errmsg = "Attempted execution of a file in directory owned by the PHP process"; |
| 63 | goto violation; | 60 | goto violation; |
| 64 | } | 61 | } |
| 65 | 62 | ||
| 66 | // we would actually need to check all parent directories as well, but that task is left for other tools | ||
| 67 | return; | 63 | return; |
| 68 | 64 | ||
| 69 | violation: | 65 | violation: |
| @@ -93,8 +89,8 @@ inline static void is_builtin_matching( | |||
| 93 | should_disable_ht(EG(current_execute_data), function_name, param_value, param_name, SPCFG(disabled_functions_reg).disabled_functions, ht); | 89 | should_disable_ht(EG(current_execute_data), function_name, param_value, param_name, SPCFG(disabled_functions_reg).disabled_functions, ht); |
| 94 | } | 90 | } |
| 95 | 91 | ||
| 96 | static void ZEND_HOT is_in_eval_and_whitelisted(const zend_execute_data *execute_data) { | 92 | static void ZEND_HOT is_in_eval_and_whitelisted(zend_execute_data const* const execute_data) { |
| 97 | const sp_config_eval *config_eval = &(SPCFG(eval)); | 93 | sp_config_eval const* const config_eval = &(SPCFG(eval)); |
| 98 | 94 | ||
| 99 | if (EXPECTED(0 == SPG(in_eval))) { | 95 | if (EXPECTED(0 == SPG(in_eval))) { |
| 100 | return; | 96 | return; |
| @@ -113,18 +109,18 @@ static void ZEND_HOT is_in_eval_and_whitelisted(const zend_execute_data *execute | |||
| 113 | return; | 109 | return; |
| 114 | } | 110 | } |
| 115 | 111 | ||
| 116 | if (UNEXPECTED(false == check_is_in_eval_whitelist(function_name))) { | 112 | if (UNEXPECTED(false == check_is_in_eval_whitelist(function_name))) { |
| 117 | if (config_eval->dump) { | 113 | if (config_eval->dump) { |
| 118 | sp_log_request(config_eval->dump, config_eval->textual_representation); | 114 | sp_log_request(config_eval->dump, config_eval->textual_representation); |
| 119 | } | ||
| 120 | if (config_eval->simulation) { | ||
| 121 | sp_log_simulation("Eval_whitelist", "The function '%s' isn't in the eval whitelist, logging its call.", function_name); | ||
| 122 | goto out; | ||
| 123 | } else { | ||
| 124 | sp_log_drop("Eval_whitelist", "The function '%s' isn't in the eval whitelist, dropping its call.", function_name); | ||
| 125 | } | ||
| 126 | } | 115 | } |
| 127 | // } | 116 | if (config_eval->simulation) { |
| 117 | sp_log_simulation("Eval_whitelist", "The function '%s' isn't in the eval whitelist, logging its call.", function_name); | ||
| 118 | goto out; | ||
| 119 | } else { | ||
| 120 | sp_log_drop("Eval_whitelist", "The function '%s' isn't in the eval whitelist, dropping its call.", function_name); | ||
| 121 | } | ||
| 122 | } | ||
| 123 | |||
| 128 | out: | 124 | out: |
| 129 | efree(function_name); | 125 | efree(function_name); |
| 130 | } | 126 | } |
| @@ -185,11 +181,13 @@ static inline void sp_execute_handler(INTERNAL_FUNCTION_PARAMETERS, bool interna | |||
| 185 | 181 | ||
| 186 | if (!internal) { | 182 | if (!internal) { |
| 187 | if (UNEXPECTED(EX(func)->op_array.type == ZEND_EVAL_CODE)) { | 183 | if (UNEXPECTED(EX(func)->op_array.type == ZEND_EVAL_CODE)) { |
| 188 | const sp_list_node *config = zend_hash_str_find_ptr(SPCFG(disabled_functions), ZEND_STRL("eval")); | 184 | sp_list_node const* const config = zend_hash_str_find_ptr(SPCFG(disabled_functions), ZEND_STRL("eval")); |
| 189 | 185 | ||
| 190 | zend_string *filename = get_eval_filename(zend_get_executed_filename()); | 186 | #if PHP_VERSION_ID >= 80000 |
| 191 | is_builtin_matching(filename, "eval", NULL, config, SPCFG(disabled_functions)); | 187 | is_builtin_matching(SPG(eval_source_string), "eval", "code", config, SPCFG(disabled_functions)); |
| 192 | zend_string_release(filename); | 188 | #else |
| 189 | is_builtin_matching(Z_STR_P(SPG(eval_source_string)), "eval", "code", config, SPCFG(disabled_functions)); | ||
| 190 | #endif | ||
| 193 | 191 | ||
| 194 | SPG(in_eval)++; | 192 | SPG(in_eval)++; |
| 195 | sp_orig_execute(execute_data); | 193 | sp_orig_execute(execute_data); |
| @@ -255,10 +253,8 @@ static inline void sp_execute_handler(INTERNAL_FUNCTION_PARAMETERS, bool interna | |||
| 255 | if (EX(return_value) == &ret_val) { | 253 | if (EX(return_value) == &ret_val) { |
| 256 | return_value = EX(return_value) = NULL; | 254 | return_value = EX(return_value) = NULL; |
| 257 | } | 255 | } |
| 258 | |||
| 259 | } | 256 | } |
| 260 | 257 | ||
| 261 | |||
| 262 | static void sp_execute_ex(zend_execute_data *execute_data) { | 258 | static void sp_execute_ex(zend_execute_data *execute_data) { |
| 263 | sp_execute_handler(execute_data, execute_data ? EX(return_value) : NULL, false); | 259 | sp_execute_handler(execute_data, execute_data ? EX(return_value) : NULL, false); |
| 264 | } | 260 | } |
| @@ -275,7 +271,7 @@ static inline void sp_stream_open_checks(zend_string *zend_filename, zend_file_h | |||
| 275 | return; | 271 | return; |
| 276 | } | 272 | } |
| 277 | 273 | ||
| 278 | const HashTable *disabled_functions_hooked = SPCFG(disabled_functions_hooked); | 274 | HashTable const* const disabled_functions_hooked = SPCFG(disabled_functions_hooked); |
| 279 | 275 | ||
| 280 | switch (data->opline->opcode) { | 276 | switch (data->opline->opcode) { |
| 281 | case ZEND_INCLUDE_OR_EVAL: | 277 | case ZEND_INCLUDE_OR_EVAL: |
| @@ -316,10 +312,6 @@ static inline void sp_stream_open_checks(zend_string *zend_filename, zend_file_h | |||
| 316 | EMPTY_SWITCH_DEFAULT_CASE(); // LCOV_EXCL_LINE | 312 | EMPTY_SWITCH_DEFAULT_CASE(); // LCOV_EXCL_LINE |
| 317 | } | 313 | } |
| 318 | } | 314 | } |
| 319 | // efree(zend_filename); | ||
| 320 | |||
| 321 | // end: | ||
| 322 | // return orig_zend_stream_open(filename, handle); | ||
| 323 | } | 315 | } |
| 324 | 316 | ||
| 325 | #if PHP_VERSION_ID < 80100 | 317 | #if PHP_VERSION_ID < 80100 |
| @@ -342,6 +334,36 @@ static zend_result sp_stream_open(zend_file_handle *handle) { | |||
| 342 | 334 | ||
| 343 | #endif | 335 | #endif |
| 344 | 336 | ||
| 337 | ZEND_API zend_op_array* (*orig_zend_compile_file)(zend_file_handle* file_handle, | ||
| 338 | int type) = NULL; | ||
| 339 | #if PHP_VERSION_ID >= 80000 | ||
| 340 | ZEND_API zend_op_array* (*orig_zend_compile_string)( | ||
| 341 | zend_string* source_string, const char* filename) = NULL; | ||
| 342 | #else | ||
| 343 | ZEND_API zend_op_array* (*orig_zend_compile_string)(zval* source_string, | ||
| 344 | char* filename) = NULL; | ||
| 345 | #endif | ||
| 346 | |||
| 347 | #if PHP_VERSION_ID >= 80000 | ||
| 348 | ZEND_API zend_op_array* sp_compile_string(zend_string* source_string, | ||
| 349 | const char* filename) { | ||
| 350 | #else | ||
| 351 | ZEND_API zend_op_array* sp_compile_string(zval* source_string, char* filename) { | ||
| 352 | #endif | ||
| 353 | // TODO(jvoisin) handle recursive calls to `eval` | ||
| 354 | SPG(eval_source_string) = source_string; | ||
| 355 | zend_op_array* opline = orig_zend_compile_string(source_string, filename); | ||
| 356 | sp_sloppy_modify_opcode(opline); | ||
| 357 | return opline; | ||
| 358 | } | ||
| 359 | |||
| 360 | ZEND_API zend_op_array* sp_compile_file(zend_file_handle* file_handle, | ||
| 361 | int type) { | ||
| 362 | zend_op_array* opline = orig_zend_compile_file(file_handle, type); | ||
| 363 | sp_sloppy_modify_opcode(opline); | ||
| 364 | return opline; | ||
| 365 | } | ||
| 366 | |||
| 345 | int hook_execute(void) { | 367 | int hook_execute(void) { |
| 346 | TSRMLS_FETCH(); | 368 | TSRMLS_FETCH(); |
| 347 | 369 | ||
| @@ -365,5 +387,16 @@ int hook_execute(void) { | |||
| 365 | } | 387 | } |
| 366 | } | 388 | } |
| 367 | 389 | ||
| 390 | if (NULL == orig_zend_compile_file && zend_compile_file != sp_compile_file) { | ||
| 391 | orig_zend_compile_file = zend_compile_file; | ||
| 392 | zend_compile_file = sp_compile_file; | ||
| 393 | } | ||
| 394 | |||
| 395 | if (NULL == orig_zend_compile_string && | ||
| 396 | zend_compile_string != sp_compile_string) { | ||
| 397 | orig_zend_compile_string = zend_compile_string; | ||
| 398 | zend_compile_string = sp_compile_string; | ||
| 399 | } | ||
| 400 | |||
| 368 | return SUCCESS; | 401 | return SUCCESS; |
| 369 | } | 402 | } |
diff --git a/src/sp_ifilter.c b/src/sp_ifilter.c index 8099882..9c46875 100644 --- a/src/sp_ifilter.c +++ b/src/sp_ifilter.c | |||
| @@ -97,7 +97,7 @@ static void sp_register_server_variables(zval *track_vars_array) { | |||
| 97 | 97 | ||
| 98 | void sp_hook_register_server_variables() | 98 | void sp_hook_register_server_variables() |
| 99 | { | 99 | { |
| 100 | if (sapi_module.register_server_variables) { | 100 | if (sapi_module.register_server_variables && sapi_module.register_server_variables != sp_register_server_variables) { |
| 101 | orig_register_server_variables = sapi_module.register_server_variables; | 101 | orig_register_server_variables = sapi_module.register_server_variables; |
| 102 | sapi_module.register_server_variables = sp_register_server_variables; | 102 | sapi_module.register_server_variables = sp_register_server_variables; |
| 103 | } | 103 | } |
diff --git a/src/sp_ini.c b/src/sp_ini.c index 7fec297..ed23fb7 100644 --- a/src/sp_ini.c +++ b/src/sp_ini.c | |||
| @@ -12,12 +12,12 @@ | |||
| 12 | } | 12 | } |
| 13 | 13 | ||
| 14 | 14 | ||
| 15 | static bool /* success */ sp_ini_check(zend_string *varname, zend_string *new_value, sp_ini_entry **sp_entry_p) { | 15 | static bool /* success */ sp_ini_check(zend_string *const restrict varname, zend_string const *const restrict new_value, sp_ini_entry **sp_entry_p) { |
| 16 | if (!varname || ZSTR_LEN(varname) == 0) { | 16 | if (!varname || ZSTR_LEN(varname) == 0) { |
| 17 | return false; | 17 | return false; |
| 18 | } | 18 | } |
| 19 | 19 | ||
| 20 | sp_config_ini *cfg = &(SPCFG(ini)); | 20 | sp_config_ini const* const cfg = &(SPCFG(ini)); |
| 21 | sp_ini_entry *entry = zend_hash_find_ptr(cfg->entries, varname); | 21 | sp_ini_entry *entry = zend_hash_find_ptr(cfg->entries, varname); |
| 22 | if (sp_entry_p) { | 22 | if (sp_entry_p) { |
| 23 | *sp_entry_p = entry; | 23 | *sp_entry_p = entry; |
| @@ -76,10 +76,9 @@ static bool /* success */ sp_ini_check(zend_string *varname, zend_string *new_va | |||
| 76 | } | 76 | } |
| 77 | 77 | ||
| 78 | static PHP_INI_MH(sp_ini_onmodify) { | 78 | static PHP_INI_MH(sp_ini_onmodify) { |
| 79 | zend_ini_entry *ini_entry = entry; | ||
| 80 | sp_ini_entry *sp_entry = NULL; | 79 | sp_ini_entry *sp_entry = NULL; |
| 81 | 80 | ||
| 82 | if (!sp_ini_check(ini_entry->name, new_value, &sp_entry)) { | 81 | if (!sp_ini_check(entry->name, new_value, &sp_entry)) { |
| 83 | return FAILURE; | 82 | return FAILURE; |
| 84 | } | 83 | } |
| 85 | 84 | ||
| @@ -91,7 +90,7 @@ static PHP_INI_MH(sp_ini_onmodify) { | |||
| 91 | } | 90 | } |
| 92 | 91 | ||
| 93 | void sp_hook_ini() { | 92 | void sp_hook_ini() { |
| 94 | sp_config_ini *cfg = &(SPCFG(ini)); | 93 | sp_config_ini const* const cfg = &(SPCFG(ini)); |
| 95 | sp_ini_entry *sp_entry; | 94 | sp_ini_entry *sp_entry; |
| 96 | zend_ini_entry *ini_entry; | 95 | zend_ini_entry *ini_entry; |
| 97 | ZEND_HASH_FOREACH_PTR(cfg->entries, sp_entry) | 96 | ZEND_HASH_FOREACH_PTR(cfg->entries, sp_entry) |
| @@ -126,8 +125,8 @@ void sp_hook_ini() { | |||
| 126 | 125 | ||
| 127 | void sp_unhook_ini() { | 126 | void sp_unhook_ini() { |
| 128 | sp_ini_entry *sp_entry; | 127 | sp_ini_entry *sp_entry; |
| 129 | zend_ini_entry *ini_entry; | ||
| 130 | ZEND_HASH_FOREACH_PTR(SPCFG(ini).entries, sp_entry) | 128 | ZEND_HASH_FOREACH_PTR(SPCFG(ini).entries, sp_entry) |
| 129 | zend_ini_entry *ini_entry; | ||
| 131 | if (!sp_entry->orig_onmodify) { | 130 | if (!sp_entry->orig_onmodify) { |
| 132 | // not hooked or no original onmodify | 131 | // not hooked or no original onmodify |
| 133 | continue; | 132 | continue; |
diff --git a/src/sp_sloppy.c b/src/sp_sloppy.c index fca4be5..2c6ef6a 100644 --- a/src/sp_sloppy.c +++ b/src/sp_sloppy.c | |||
| @@ -1,16 +1,6 @@ | |||
| 1 | #include "php_snuffleupagus.h" | 1 | #include "php_snuffleupagus.h" |
| 2 | 2 | ||
| 3 | ZEND_API zend_op_array* (*orig_zend_compile_file)(zend_file_handle* file_handle, | 3 | void sp_sloppy_modify_opcode(zend_op_array* opline) { |
| 4 | int type) = NULL; | ||
| 5 | #if PHP_VERSION_ID >= 80000 | ||
| 6 | ZEND_API zend_op_array* (*orig_zend_compile_string)( | ||
| 7 | zend_string* source_string, const char* filename) = NULL; | ||
| 8 | #else | ||
| 9 | ZEND_API zend_op_array* (*orig_zend_compile_string)(zval* source_string, | ||
| 10 | char* filename) = NULL; | ||
| 11 | #endif | ||
| 12 | |||
| 13 | static void modify_opcode(zend_op_array* opline) { | ||
| 14 | if (NULL != opline) { | 4 | if (NULL != opline) { |
| 15 | for (size_t i = 0; i < opline->last; i++) { | 5 | for (size_t i = 0; i < opline->last; i++) { |
| 16 | zend_op* orig_opline = &(opline->opcodes[i]); | 6 | zend_op* orig_opline = &(opline->opcodes[i]); |
| @@ -25,24 +15,6 @@ static void modify_opcode(zend_op_array* opline) { | |||
| 25 | } | 15 | } |
| 26 | } | 16 | } |
| 27 | 17 | ||
| 28 | #if PHP_VERSION_ID >= 80000 | ||
| 29 | ZEND_API zend_op_array* sp_compile_string(zend_string* source_string, | ||
| 30 | const char* filename) { | ||
| 31 | #else | ||
| 32 | ZEND_API zend_op_array* sp_compile_string(zval* source_string, char* filename) { | ||
| 33 | #endif | ||
| 34 | zend_op_array* opline = orig_zend_compile_string(source_string, filename); | ||
| 35 | modify_opcode(opline); | ||
| 36 | return opline; | ||
| 37 | } | ||
| 38 | |||
| 39 | ZEND_API zend_op_array* sp_compile_file(zend_file_handle* file_handle, | ||
| 40 | int type) { | ||
| 41 | zend_op_array* opline = orig_zend_compile_file(file_handle, type); | ||
| 42 | modify_opcode(opline); | ||
| 43 | return opline; | ||
| 44 | } | ||
| 45 | |||
| 46 | static void array_handler(INTERNAL_FUNCTION_PARAMETERS, const char* name, | 18 | static void array_handler(INTERNAL_FUNCTION_PARAMETERS, const char* name, |
| 47 | size_t size, zif_handler orig_handler, | 19 | size_t size, zif_handler orig_handler, |
| 48 | const char* spec) { | 20 | const char* spec) { |
| @@ -99,17 +71,6 @@ PHP_FUNCTION(sp_array_keys) { | |||
| 99 | void hook_sloppy() { | 71 | void hook_sloppy() { |
| 100 | TSRMLS_FETCH(); | 72 | TSRMLS_FETCH(); |
| 101 | 73 | ||
| 102 | if (NULL == orig_zend_compile_file && zend_compile_file != sp_compile_file) { | ||
| 103 | orig_zend_compile_file = zend_compile_file; | ||
| 104 | zend_compile_file = sp_compile_file; | ||
| 105 | } | ||
| 106 | |||
| 107 | if (NULL == orig_zend_compile_string && | ||
| 108 | zend_compile_string != sp_compile_string) { | ||
| 109 | orig_zend_compile_string = zend_compile_string; | ||
| 110 | zend_compile_string = sp_compile_string; | ||
| 111 | } | ||
| 112 | |||
| 113 | HOOK_FUNCTION("in_array", sp_internal_functions_hook, PHP_FN(sp_in_array)); | 74 | HOOK_FUNCTION("in_array", sp_internal_functions_hook, PHP_FN(sp_in_array)); |
| 114 | HOOK_FUNCTION("array_search", sp_internal_functions_hook, | 75 | HOOK_FUNCTION("array_search", sp_internal_functions_hook, |
| 115 | PHP_FN(sp_array_search)); | 76 | PHP_FN(sp_array_search)); |
diff --git a/src/sp_sloppy.h b/src/sp_sloppy.h index cd9f304..4c5d121 100644 --- a/src/sp_sloppy.h +++ b/src/sp_sloppy.h | |||
| @@ -4,5 +4,6 @@ | |||
| 4 | #include "zend_vm.h" | 4 | #include "zend_vm.h" |
| 5 | 5 | ||
| 6 | void hook_sloppy(void); | 6 | void hook_sloppy(void); |
| 7 | void sp_sloppy_modify_opcode(zend_op_array* opline); | ||
| 7 | 8 | ||
| 8 | #endif | 9 | #endif |
diff --git a/src/sp_unserialize.c b/src/sp_unserialize.c index 2e7c173..64cf1b5 100644 --- a/src/sp_unserialize.c +++ b/src/sp_unserialize.c | |||
| @@ -8,7 +8,7 @@ static inline void *php_hash_alloc_context(const php_hash_ops *ops) { | |||
| 8 | } | 8 | } |
| 9 | #endif | 9 | #endif |
| 10 | 10 | ||
| 11 | static zend_string *sp_do_hash_hmac_sha256(char *data, size_t data_len, char *key, size_t key_len) | 11 | static zend_string *sp_do_hash_hmac_sha256(char* restrict data, size_t data_len, char* restrict key, size_t key_len) |
| 12 | { | 12 | { |
| 13 | #if PHP_VERSION_ID < 80000 | 13 | #if PHP_VERSION_ID < 80000 |
| 14 | const php_hash_ops *ops = php_hash_fetch_ops(ZEND_STRL("sha256")); | 14 | const php_hash_ops *ops = php_hash_fetch_ops(ZEND_STRL("sha256")); |
diff --git a/src/sp_utils.c b/src/sp_utils.c index 6161859..42f7871 100644 --- a/src/sp_utils.c +++ b/src/sp_utils.c | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | #include "php_snuffleupagus.h" | 1 | #include "php_snuffleupagus.h" |
| 2 | 2 | ||
| 3 | static const char* default_ipaddr = "0.0.0.0"; | 3 | static char const* const default_ipaddr = "0.0.0.0"; |
| 4 | const char* get_ipaddr() { | 4 | const char* get_ipaddr() { |
| 5 | const char* client_ip = getenv("REMOTE_ADDR"); | 5 | const char* client_ip = getenv("REMOTE_ADDR"); |
| 6 | if (client_ip) { | 6 | if (client_ip) { |
| @@ -15,8 +15,8 @@ const char* get_ipaddr() { | |||
| 15 | return default_ipaddr; | 15 | return default_ipaddr; |
| 16 | } | 16 | } |
| 17 | 17 | ||
| 18 | void sp_log_msgf(char const* restrict feature, int level, int type, | 18 | void sp_log_msgf(char const* const restrict feature, int level, int type, |
| 19 | const char* restrict fmt, ...) { | 19 | char const* const restrict fmt, ...) { |
| 20 | char* msg; | 20 | char* msg; |
| 21 | va_list args; | 21 | va_list args; |
| 22 | 22 | ||
| @@ -63,7 +63,7 @@ void sp_log_msgf(char const* restrict feature, int level, int type, | |||
| 63 | } | 63 | } |
| 64 | } | 64 | } |
| 65 | 65 | ||
| 66 | int compute_hash(const char* const restrict filename, | 66 | int compute_hash(char const* const restrict filename, |
| 67 | char* restrict file_hash) { | 67 | char* restrict file_hash) { |
| 68 | unsigned char buf[1024] = {0}; | 68 | unsigned char buf[1024] = {0}; |
| 69 | unsigned char digest[SHA256_SIZE] = {0}; | 69 | unsigned char digest[SHA256_SIZE] = {0}; |
| @@ -90,9 +90,18 @@ int compute_hash(const char* const restrict filename, | |||
| 90 | return SUCCESS; | 90 | return SUCCESS; |
| 91 | } | 91 | } |
| 92 | 92 | ||
| 93 | static int construct_filename(char* filename, | 93 | int sp_log_request(zend_string const* const restrict folder, zend_string const* const restrict text_repr) { |
| 94 | const zend_string* restrict folder, | 94 | FILE* file; |
| 95 | const zend_string* restrict textual) { | 95 | char const* const current_filename = zend_get_executed_filename(TSRMLS_C); |
| 96 | const int current_line = zend_get_executed_lineno(TSRMLS_C); | ||
| 97 | char filename[PATH_MAX] = {0}; | ||
| 98 | static const struct { | ||
| 99 | char const* const str; | ||
| 100 | const int key; | ||
| 101 | } zones[] = {{"GET", TRACK_VARS_GET}, {"POST", TRACK_VARS_POST}, | ||
| 102 | {"COOKIE", TRACK_VARS_COOKIE}, {"SERVER", TRACK_VARS_SERVER}, | ||
| 103 | {"ENV", TRACK_VARS_ENV}, {NULL, 0}}; | ||
| 104 | |||
| 96 | PHP_SHA256_CTX context; | 105 | PHP_SHA256_CTX context; |
| 97 | unsigned char digest[SHA256_SIZE] = {0}; | 106 | unsigned char digest[SHA256_SIZE] = {0}; |
| 98 | char strhash[65] = {0}; | 107 | char strhash[65] = {0}; |
| @@ -103,52 +112,54 @@ static int construct_filename(char* filename, | |||
| 103 | return -1; | 112 | return -1; |
| 104 | } | 113 | } |
| 105 | 114 | ||
| 106 | /* We're using the sha256 sum of the rule's textual representation | 115 | /* We're using the sha256 sum of the rule's textual representation, as well |
| 107 | * as filename, in order to only have one dump per rule, to mitigate | 116 | * as the stacktrace as filename, in order to only have one dump per rule, to |
| 108 | * DoS attacks. */ | 117 | * mitigate DoS attacks. We're doing the walk-the-execution-context dance |
| 118 | * twice because it's easier than to cache it in a linked-list. It doesn't | ||
| 119 | * really matter, since this is a super-cold path anyway. | ||
| 120 | */ | ||
| 109 | PHP_SHA256Init(&context); | 121 | PHP_SHA256Init(&context); |
| 110 | PHP_SHA256Update(&context, (const unsigned char*)ZSTR_VAL(textual), | 122 | PHP_SHA256Update(&context, (const unsigned char*)ZSTR_VAL(text_repr), ZSTR_LEN(text_repr)); |
| 111 | ZSTR_LEN(textual)); | 123 | zend_execute_data* orig_execute_data = EG(current_execute_data); |
| 124 | zend_execute_data* current = EG(current_execute_data); | ||
| 125 | while (current) { | ||
| 126 | EG(current_execute_data) = current; | ||
| 127 | char* const complete_path_function = get_complete_function_path(current); | ||
| 128 | if (complete_path_function) { | ||
| 129 | PHP_SHA256Update(&context, (const unsigned char*)complete_path_function, strlen(complete_path_function)); | ||
| 130 | efree(complete_path_function); | ||
| 131 | } | ||
| 132 | current = current->prev_execute_data; | ||
| 133 | } | ||
| 134 | EG(current_execute_data) = orig_execute_data; | ||
| 112 | PHP_SHA256Final(digest, &context); | 135 | PHP_SHA256Final(digest, &context); |
| 113 | make_digest_ex(strhash, digest, SHA256_SIZE); | 136 | make_digest_ex(strhash, digest, SHA256_SIZE); |
| 114 | snprintf(filename, PATH_MAX - 1, "%s/sp_dump.%s", ZSTR_VAL(folder), strhash); | 137 | snprintf(filename, PATH_MAX - 1, "%s/sp_dump.%s", ZSTR_VAL(folder), strhash); |
| 115 | 138 | ||
| 116 | return 0; | ||
| 117 | } | ||
| 118 | |||
| 119 | int sp_log_request(const zend_string* restrict folder, const zend_string* restrict text_repr) { | ||
| 120 | FILE* file; | ||
| 121 | const char* current_filename = zend_get_executed_filename(TSRMLS_C); | ||
| 122 | const int current_line = zend_get_executed_lineno(TSRMLS_C); | ||
| 123 | char filename[PATH_MAX] = {0}; | ||
| 124 | const struct { | ||
| 125 | char const* const str; | ||
| 126 | const int key; | ||
| 127 | } zones[] = {{"GET", TRACK_VARS_GET}, {"POST", TRACK_VARS_POST}, | ||
| 128 | {"COOKIE", TRACK_VARS_COOKIE}, {"SERVER", TRACK_VARS_SERVER}, | ||
| 129 | {"ENV", TRACK_VARS_ENV}, {NULL, 0}}; | ||
| 130 | |||
| 131 | if (0 != construct_filename(filename, folder, text_repr)) { | ||
| 132 | return -1; | ||
| 133 | } | ||
| 134 | if (NULL == (file = fopen(filename, "w+"))) { | 139 | if (NULL == (file = fopen(filename, "w+"))) { |
| 135 | sp_log_warn("request_logging", "Unable to open %s: %s", filename, | 140 | sp_log_warn("request_logging", "Unable to open %s: %s", filename, |
| 136 | strerror(errno)); | 141 | strerror(errno)); |
| 137 | return -1; | 142 | return -1; |
| 138 | } | 143 | } |
| 139 | 144 | ||
| 140 | fprintf(file, "RULE: %s\n", ZSTR_VAL(text_repr)); | 145 | fputs("RULE: ", file); |
| 146 | fputs(ZSTR_VAL(text_repr), file); | ||
| 147 | fputc('\n', file); | ||
| 141 | 148 | ||
| 142 | fprintf(file, "FILE: %s:%d\n", current_filename, current_line); | 149 | fputs("FILE: ", file); |
| 150 | fputs(current_filename, file); | ||
| 151 | fprintf(file, ":%d\n", current_line); | ||
| 143 | 152 | ||
| 144 | zend_execute_data* orig_execute_data = EG(current_execute_data); | 153 | orig_execute_data = EG(current_execute_data); |
| 145 | zend_execute_data* current = EG(current_execute_data); | 154 | current = EG(current_execute_data); |
| 146 | while (current) { | 155 | while (current) { |
| 147 | EG(current_execute_data) = current; | 156 | EG(current_execute_data) = current; |
| 148 | char* const complete_path_function = get_complete_function_path(current); | 157 | char* const complete_path_function = get_complete_function_path(current); |
| 149 | if (complete_path_function) { | 158 | if (complete_path_function) { |
| 150 | const int current_line = zend_get_executed_lineno(TSRMLS_C); | 159 | const int current_line = zend_get_executed_lineno(TSRMLS_C); |
| 151 | fprintf(file, "STACKTRACE: %s:%d\n", complete_path_function, current_line); | 160 | fputs("STACKTRACE: ", file); |
| 161 | fputs(complete_path_function, file); | ||
| 162 | fprintf(file, ":%d\n", current_line); | ||
| 152 | efree(complete_path_function); | 163 | efree(complete_path_function); |
| 153 | } | 164 | } |
| 154 | current = current->prev_execute_data; | 165 | current = current->prev_execute_data; |
| @@ -164,19 +175,32 @@ int sp_log_request(const zend_string* restrict folder, const zend_string* restri | |||
| 164 | } | 175 | } |
| 165 | 176 | ||
| 166 | HashTable* ht = Z_ARRVAL(PG(http_globals)[zones[i].key]); | 177 | HashTable* ht = Z_ARRVAL(PG(http_globals)[zones[i].key]); |
| 167 | fprintf(file, "%s:", zones[i].str); | 178 | fputs(zones[i].str, file); |
| 179 | fputc(':', file); | ||
| 168 | ZEND_HASH_FOREACH_STR_KEY_VAL(ht, variable_key, variable_value) { | 180 | ZEND_HASH_FOREACH_STR_KEY_VAL(ht, variable_key, variable_value) { |
| 169 | smart_str a; | 181 | smart_str a = {0}; |
| 170 | |||
| 171 | memset(&a, 0, sizeof(a)); | ||
| 172 | php_var_export_ex(variable_value, 1, &a); | 182 | php_var_export_ex(variable_value, 1, &a); |
| 173 | ZSTR_VAL(a.s)[ZSTR_LEN(a.s)] = '\0'; | 183 | ZSTR_VAL(a.s)[ZSTR_LEN(a.s)] = '\0'; |
| 174 | fprintf(file, "%s=%s ", ZSTR_VAL(variable_key), ZSTR_VAL(a.s)); | 184 | fputs(ZSTR_VAL(variable_key), file); |
| 185 | fputc('=', file); | ||
| 186 | fputs(ZSTR_VAL(a.s), file); | ||
| 187 | fputc(' ', file); | ||
| 175 | zend_string_release(a.s); | 188 | zend_string_release(a.s); |
| 176 | } | 189 | } |
| 177 | ZEND_HASH_FOREACH_END(); | 190 | ZEND_HASH_FOREACH_END(); |
| 178 | fputs("\n", file); | 191 | fputc('\n', file); |
| 179 | } | 192 | } |
| 193 | |||
| 194 | if (UNEXPECTED(0 != SPG(in_eval))) { | ||
| 195 | fputs("EVAL_CODE: ", file); | ||
| 196 | #if PHP_VERSION_ID >= 80000 | ||
| 197 | fputs(ZSTR_VAL(SPG(eval_source_string)), file); | ||
| 198 | #else | ||
| 199 | fputs(Z_STRVAL_P(SPG(eval_source_string)), file); | ||
| 200 | #endif | ||
| 201 | fputc('\n', file); | ||
| 202 | } | ||
| 203 | |||
| 180 | fclose(file); | 204 | fclose(file); |
| 181 | 205 | ||
| 182 | return 0; | 206 | return 0; |
| @@ -448,6 +472,7 @@ void unhook_functions(HashTable *ht) { | |||
| 448 | if (func && func->type == ZEND_INTERNAL_FUNCTION && orig_handler) { | 472 | if (func && func->type == ZEND_INTERNAL_FUNCTION && orig_handler) { |
| 449 | func->internal_function.handler = orig_handler; | 473 | func->internal_function.handler = orig_handler; |
| 450 | } | 474 | } |
| 475 | (void)idx;//silence a -Wunused-but-set-variable | ||
| 451 | ZEND_HASH_FOREACH_END_DEL(); | 476 | ZEND_HASH_FOREACH_END_DEL(); |
| 452 | } | 477 | } |
| 453 | 478 | ||
diff --git a/src/sp_utils.h b/src/sp_utils.h index 0e595d8..7bab4ba 100644 --- a/src/sp_utils.h +++ b/src/sp_utils.h | |||
| @@ -71,8 +71,8 @@ extern int sp_debug_stderr; | |||
| 71 | #define GET_SUFFIX(x) (x == 1) ? "st" : ((x == 2) ? "nd" : "th") | 71 | #define GET_SUFFIX(x) (x == 1) ? "st" : ((x == 2) ? "nd" : "th") |
| 72 | 72 | ||
| 73 | const char *get_ipaddr(void); | 73 | const char *get_ipaddr(void); |
| 74 | void sp_log_msgf(char const *restrict feature, int level, int type, const char *restrict fmt, ...); | 74 | void sp_log_msgf(char const* const restrict feature, int level, int type, char const* const restrict fmt, ...); |
| 75 | int compute_hash(const char *const restrict filename, char *restrict file_hash); | 75 | int compute_hash(char const* const restrict filename, char *restrict file_hash); |
| 76 | const zend_string *sp_zval_to_zend_string(const zval *); | 76 | const zend_string *sp_zval_to_zend_string(const zval *); |
| 77 | bool sp_match_value(const zend_string* value, const zend_string* to_match, const sp_regexp* rx); | 77 | bool sp_match_value(const zend_string* value, const zend_string* to_match, const sp_regexp* rx); |
| 78 | bool sp_match_array_key(const zval *, const zend_string *, const sp_regexp *); | 78 | bool sp_match_array_key(const zval *, const zend_string *, const sp_regexp *); |
| @@ -83,7 +83,7 @@ bool hook_function(const char *, HashTable *, zif_handler); | |||
| 83 | void unhook_functions(HashTable *ht); | 83 | void unhook_functions(HashTable *ht); |
| 84 | int hook_regexp(const sp_pcre *, HashTable *, zif_handler); | 84 | int hook_regexp(const sp_pcre *, HashTable *, zif_handler); |
| 85 | bool check_is_in_eval_whitelist(const char* function_name); | 85 | bool check_is_in_eval_whitelist(const char* function_name); |
| 86 | int sp_log_request(const zend_string *restrict folder, const zend_string *restrict text_repr); | 86 | int sp_log_request(zend_string const* const restrict folder, zend_string const* const restrict text_repr); |
| 87 | #define sp_zend_string_equals(s1, s2) zend_string_equals((zend_string*)s1, (zend_string*)s2) | 87 | #define sp_zend_string_equals(s1, s2) zend_string_equals((zend_string*)s1, (zend_string*)s2) |
| 88 | static inline bool sp_zend_string_equals_str(const zend_string* s1, const char *str, size_t len) { | 88 | static inline bool sp_zend_string_equals_str(const zend_string* s1, const char *str, size_t len) { |
| 89 | return (ZSTR_LEN(s1) == len && !memcmp(ZSTR_VAL(s1), str, len)); | 89 | return (ZSTR_LEN(s1) == len && !memcmp(ZSTR_VAL(s1), str, len)); |
diff --git a/src/sp_var_parser.c b/src/sp_var_parser.c index 2639991..e7ff766 100644 --- a/src/sp_var_parser.c +++ b/src/sp_var_parser.c | |||
| @@ -245,15 +245,15 @@ static sp_tree *parse_tokens(const char *restrict str, | |||
| 245 | } | 245 | } |
| 246 | 246 | ||
| 247 | sp_tree *sp_parse_var(const char *line) { | 247 | sp_tree *sp_parse_var(const char *line) { |
| 248 | sp_list_node *tokens_list = NULL; | 248 | static const sp_conf_token delimiter_list[] = { |
| 249 | sp_tree *tree = NULL; | ||
| 250 | const sp_conf_token delimiter_list[] = { | ||
| 251 | {.type = OBJECT, .text_repr = OBJECT_TOKEN}, | 249 | {.type = OBJECT, .text_repr = OBJECT_TOKEN}, |
| 252 | {.type = ARRAY, .text_repr = ARRAY_TOKEN}, | 250 | {.type = ARRAY, .text_repr = ARRAY_TOKEN}, |
| 253 | {.type = ARRAY_END, .text_repr = ARRAY_END_TOKEN}, | 251 | {.type = ARRAY_END, .text_repr = ARRAY_END_TOKEN}, |
| 254 | {.type = INTERPRETED_STRING, .text_repr = STRING_TOKEN}, | 252 | {.type = INTERPRETED_STRING, .text_repr = STRING_TOKEN}, |
| 255 | {.type = LITERAL_STRING, .text_repr = ESC_STRING_TOKEN}, | 253 | {.type = LITERAL_STRING, .text_repr = ESC_STRING_TOKEN}, |
| 256 | {.type = CLASS, .text_repr = CLASS_TOKEN}}; | 254 | {.type = CLASS, .text_repr = CLASS_TOKEN}}; |
| 255 | sp_list_node *tokens_list = NULL; | ||
| 256 | sp_tree *tree = NULL; | ||
| 257 | 257 | ||
| 258 | if (!line) { | 258 | if (!line) { |
| 259 | return NULL; | 259 | return NULL; |
diff --git a/src/sp_var_parser.h b/src/sp_var_parser.h index 6d53691..c2981a3 100644 --- a/src/sp_var_parser.h +++ b/src/sp_var_parser.h | |||
| @@ -4,7 +4,7 @@ | |||
| 4 | 4 | ||
| 5 | typedef struct sp_token_s { | 5 | typedef struct sp_token_s { |
| 6 | elem_type type; | 6 | elem_type type; |
| 7 | char *text_repr; | 7 | const char *text_repr; |
| 8 | size_t pos; | 8 | size_t pos; |
| 9 | } sp_conf_token; | 9 | } sp_conf_token; |
| 10 | 10 | ||
diff --git a/src/sp_var_value.c b/src/sp_var_value.c index fe37f99..c9e5ade 100644 --- a/src/sp_var_value.c +++ b/src/sp_var_value.c | |||
| @@ -111,7 +111,7 @@ static void *get_entry_hashtable(const HashTable *const ht, | |||
| 111 | 111 | ||
| 112 | static zval *get_array_value(zend_execute_data *ed, const zval *const zvalue, | 112 | static zval *get_array_value(zend_execute_data *ed, const zval *const zvalue, |
| 113 | const sp_tree *const tree) { | 113 | const sp_tree *const tree) { |
| 114 | zval *idx_value = sp_get_var_value(ed, tree->idx, false); | 114 | const zval *const idx_value = sp_get_var_value(ed, tree->idx, false); |
| 115 | 115 | ||
| 116 | if (!zvalue || !idx_value) { | 116 | if (!zvalue || !idx_value) { |
| 117 | return NULL; | 117 | return NULL; |
| @@ -129,9 +129,8 @@ static zval *get_array_value(zend_execute_data *ed, const zval *const zvalue, | |||
| 129 | static zval *get_object_property(zend_execute_data *ed, zval *object, | 129 | static zval *get_object_property(zend_execute_data *ed, zval *object, |
| 130 | const char *property, bool is_param) { | 130 | const char *property, bool is_param) { |
| 131 | const char *const class_name = object->value.obj->ce->name->val; | 131 | const char *const class_name = object->value.obj->ce->name->val; |
| 132 | HashTable *array = Z_OBJPROP_P(object); | 132 | const HashTable *const array = Z_OBJPROP_P(object); |
| 133 | zval *zvalue = NULL; | 133 | const zval *const property_val = get_var_value(ed, property, is_param); |
| 134 | const zval *property_val = get_var_value(ed, property, is_param); | ||
| 135 | size_t len; | 134 | size_t len; |
| 136 | 135 | ||
| 137 | if (property_val) { | 136 | if (property_val) { |
| @@ -141,7 +140,7 @@ static zval *get_object_property(zend_execute_data *ed, zval *object, | |||
| 141 | property = Z_STRVAL_P(property_val); | 140 | property = Z_STRVAL_P(property_val); |
| 142 | } | 141 | } |
| 143 | } | 142 | } |
| 144 | zvalue = get_entry_hashtable(array, property, strlen(property)); | 143 | zval *zvalue = get_entry_hashtable(array, property, strlen(property)); |
| 145 | // TODO do we want to log overflow? | 144 | // TODO do we want to log overflow? |
| 146 | if (!zvalue) { | 145 | if (!zvalue) { |
| 147 | len = strlen(property) + 4; | 146 | len = strlen(property) + 4; |
diff --git a/src/tests/deny_writable/config/config_disable_writable_simulation.ini b/src/tests/deny_writable/config/config_disable_writable_simulation.ini index 52a43ba..3aafe3f 100644 --- a/src/tests/deny_writable/config/config_disable_writable_simulation.ini +++ b/src/tests/deny_writable/config/config_disable_writable_simulation.ini | |||
| @@ -1 +1 @@ | |||
| sp.readonly_exec.enable().simulation(); | sp.readonly_exec.enable().extended_checks().simulation(); | ||
diff --git a/src/tests/deny_writable/deny_writable_execution_simulation.phpt b/src/tests/deny_writable/deny_writable_execution_simulation.phpt index 1118dc0..d4e4801 100644 --- a/src/tests/deny_writable/deny_writable_execution_simulation.phpt +++ b/src/tests/deny_writable/deny_writable_execution_simulation.phpt | |||
| @@ -1,7 +1,6 @@ | |||
| 1 | --TEST-- | 1 | --TEST-- |
| 2 | Readonly execution attempt (simulation mode) | 2 | Readonly execution attempt (simulation mode) |
| 3 | --SKIPIF-- | 3 | --SKIPIF-- |
| 4 | <?php if (PHP_VERSION_ID >= 80000) print "skip"; ?> | ||
| 5 | <?php | 4 | <?php |
| 6 | if (!extension_loaded("snuffleupagus")) { print "skip"; }; | 5 | if (!extension_loaded("snuffleupagus")) { print "skip"; }; |
| 7 | 6 | ||
| @@ -42,10 +41,14 @@ unlink("$dir/non_writable_file.txt"); | |||
| 42 | unlink("$dir/writable_file.txt"); | 41 | unlink("$dir/writable_file.txt"); |
| 43 | ?> | 42 | ?> |
| 44 | --EXPECTF-- | 43 | --EXPECTF-- |
| 45 | Warning: [snuffleupagus][0.0.0.0][readonly_exec][simulation] Attempted execution of a writable file (%a/deny_writable_execution_simulation.php). in %a/deny_writable_execution_simulation.php on line 2 | 44 | Warning: [snuffleupagus][0.0.0.0][readonly_exec][simulation] Attempted execution of a writable file (%a/deny_writable_execution_simulation.php) in %a/deny_writable_execution_simulation.php on line 2 |
| 46 | 45 | ||
| 47 | Warning: [snuffleupagus][0.0.0.0][readonly_exec][simulation] Attempted execution of a writable file (%a/writable_file.txt). in %a/deny_writable_execution_simulation.php on line 12 | 46 | Warning: [snuffleupagus][0.0.0.0][readonly_exec][simulation] Attempted execution of a writable file (%a/writable_file.txt) in %a/deny_writable_execution_simulation.php on line 12 |
| 48 | 47 | ||
| 49 | Warning: [snuffleupagus][0.0.0.0][readonly_exec][simulation] Attempted execution of a writable file (%a/writable_file.txt). in %a/writable_file.txt on line 1 | 48 | Warning: [snuffleupagus][0.0.0.0][readonly_exec][simulation] Attempted execution of a writable file (%a/writable_file.txt) in %a/writable_file.txt on line 1 |
| 50 | Code execution within a writable file. | 49 | Code execution within a writable file. |
| 50 | |||
| 51 | Warning: [snuffleupagus][0.0.0.0][readonly_exec][simulation] Attempted execution of a file owned by the PHP process (%s/tests/deny_writable/non_writable_file.txt) in %s/tests/deny_writable/deny_writable_execution_simulation.php on line 13 | ||
| 52 | |||
| 53 | Warning: [snuffleupagus][0.0.0.0][readonly_exec][simulation] Attempted execution of a file owned by the PHP process (%s/tests/deny_writable/non_writable_file.txt) in %src/tests/deny_writable/non_writable_file.txt on line 1 | ||
| 51 | Code execution within a non-writable file. | 54 | Code execution within a non-writable file. |
diff --git a/src/tests/disable_function/config/config_disabled_functions_eval_param.ini b/src/tests/disable_function/config/config_disabled_functions_eval_param.ini new file mode 100644 index 0000000..b43faf1 --- /dev/null +++ b/src/tests/disable_function/config/config_disabled_functions_eval_param.ini | |||
| @@ -0,0 +1 @@ | |||
| sp.disable_function.function("eval").param("code").drop(); | |||
diff --git a/src/tests/disable_function/config/config_disabled_functions_name_type_php8.ini b/src/tests/disable_function/config/config_disabled_functions_name_type_php8.ini new file mode 100644 index 0000000..0f521e7 --- /dev/null +++ b/src/tests/disable_function/config/config_disabled_functions_name_type_php8.ini | |||
| @@ -0,0 +1 @@ | |||
| sp.disable_function.function_r("^strcmp$").param("string1").param_type("array").drop(); | |||
diff --git a/src/tests/disable_function/config/config_disabled_functions_param_str_representation_php8.ini b/src/tests/disable_function/config/config_disabled_functions_param_str_representation_php8.ini new file mode 100644 index 0000000..710ddb3 --- /dev/null +++ b/src/tests/disable_function/config/config_disabled_functions_param_str_representation_php8.ini | |||
| @@ -0,0 +1 @@ | |||
| sp.disable_function.function("var_export").param("value").value("bla").drop(); | |||
diff --git a/src/tests/disable_function/disabled_functions_eval_param.phpt b/src/tests/disable_function/disabled_functions_eval_param.phpt new file mode 100644 index 0000000..4f3f1ef --- /dev/null +++ b/src/tests/disable_function/disabled_functions_eval_param.phpt | |||
| @@ -0,0 +1,14 @@ | |||
| 1 | --TEST-- | ||
| 2 | Disable functions - eval, on matching parameter | ||
| 3 | --SKIPIF-- | ||
| 4 | <?php if (!extension_loaded("snuffleupagus")) print "skip"; ?> | ||
| 5 | --INI-- | ||
| 6 | sp.configuration_file={PWD}/config/config_disabled_functions_eval_param.ini | ||
| 7 | --FILE-- | ||
| 8 | <?php | ||
| 9 | $var = 123456789; | ||
| 10 | eval('$var = 1337 + 1337;'); | ||
| 11 | print("Variable: $var\n"); | ||
| 12 | ?> | ||
| 13 | --EXPECTF-- | ||
| 14 | Fatal error: [snuffleupagus][0.0.0.0][disabled_function][drop] Aborted execution on call of the function 'eval', because its argument 'code' content ($var = 1337 + 1337;) matched a rule in %s/tests/disable_function/disabled_functions_eval_param.php(3) : eval()'d code on line 1 | ||
diff --git a/src/tests/disable_function/disabled_functions_name_type_php8.phpt b/src/tests/disable_function/disabled_functions_name_type_php8.phpt new file mode 100644 index 0000000..8670b4d --- /dev/null +++ b/src/tests/disable_function/disabled_functions_name_type_php8.phpt | |||
| @@ -0,0 +1,16 @@ | |||
| 1 | --TEST-- | ||
| 2 | Disable functions | ||
| 3 | --SKIPIF-- | ||
| 4 | <?php if (!extension_loaded("snuffleupagus")) print "skip"; ?> | ||
| 5 | <?php if (PHP_VERSION_ID < 80000) print "skip"; ?> | ||
| 6 | --INI-- | ||
| 7 | sp.configuration_file={PWD}/config/config_disabled_functions_name_type_php8.ini | ||
| 8 | --FILE-- | ||
| 9 | <?php | ||
| 10 | echo strcmp("pouet", "pouet") . "\n"; | ||
| 11 | echo strcmp([1,23], "pouet") . "\n"; | ||
| 12 | ?> | ||
| 13 | --EXPECTF-- | ||
| 14 | 0 | ||
| 15 | |||
| 16 | Fatal error: [snuffleupagus][0.0.0.0][disabled_function][drop] Aborted execution on call of the function 'strcmp', because its argument '$string1' content (?) matched a rule in %s/disabled_functions_name_type_php8.php on line 3 | ||
diff --git a/src/tests/disable_function/disabled_functions_param_str_representation_php8.phpt b/src/tests/disable_function/disabled_functions_param_str_representation_php8.phpt new file mode 100644 index 0000000..aa5782b --- /dev/null +++ b/src/tests/disable_function/disabled_functions_param_str_representation_php8.phpt | |||
| @@ -0,0 +1,26 @@ | |||
| 1 | --TEST-- | ||
| 2 | Disable functions - casting various types to string internally in php8 | ||
| 3 | --SKIPIF-- | ||
| 4 | <?php if (!extension_loaded("snuffleupagus")) print "skip"; ?> | ||
| 5 | <?php if (PHP_VERSION_ID < 80000) print "skip"; ?> | ||
| 6 | --INI-- | ||
| 7 | sp.configuration_file={PWD}/config/config_disabled_functions_param_str_representation_php8.ini | ||
| 8 | --FILE-- | ||
| 9 | <?php | ||
| 10 | echo var_export(true) . "\n"; | ||
| 11 | echo var_export(false) . "\n"; | ||
| 12 | echo var_export(null) . "\n"; | ||
| 13 | echo var_export(1) . "\n"; | ||
| 14 | echo var_export(1.0) . "\n"; | ||
| 15 | function f(&$a) { | ||
| 16 | echo var_export($a) . "\n"; | ||
| 17 | } | ||
| 18 | $a = 123; f($a); | ||
| 19 | ?> | ||
| 20 | --EXPECTF-- | ||
| 21 | true | ||
| 22 | false | ||
| 23 | NULL | ||
| 24 | 1 | ||
| 25 | 1.0 | ||
| 26 | 123 | ||
diff --git a/src/tests/dump_request/dump_eval_blacklist.phpt b/src/tests/dump_request/dump_eval_blacklist.phpt index c9f48e4..a8c1618 100644 --- a/src/tests/dump_request/dump_eval_blacklist.phpt +++ b/src/tests/dump_request/dump_eval_blacklist.phpt | |||
| @@ -38,6 +38,8 @@ if ($res[3] != "GET:get_a='data_get_a' get_b='data_get_b' \n") { | |||
| 38 | echo "Invalid POST"; | 38 | echo "Invalid POST"; |
| 39 | } elseif ($res[5] != "COOKIE:cookie_a='data_cookie_a&cookie_b=data_cookie_b' \n") { | 39 | } elseif ($res[5] != "COOKIE:cookie_a='data_cookie_a&cookie_b=data_cookie_b' \n") { |
| 40 | echo "Invalid COOKIE"; | 40 | echo "Invalid COOKIE"; |
| 41 | } elseif ($res[6] != "EVAL_CODE: \$a = strtoupper(\"1234\");\n") { | ||
| 42 | echo "Invalid EVAL_CODE"; | ||
| 41 | } | 43 | } |
| 42 | ?> | 44 | ?> |
| 43 | --EXPECTF-- | 45 | --EXPECTF-- |
diff --git a/src/tests/ini/ini_min_policy_drop.phpt b/src/tests/ini/ini_min_policy_drop.phpt index ef40ebc..1ec9f9a 100644 --- a/src/tests/ini/ini_min_policy_drop.phpt +++ b/src/tests/ini/ini_min_policy_drop.phpt | |||
| @@ -10,4 +10,4 @@ var_dump(ini_set("max_execution_time", "29") === false); | |||
| 10 | var_dump(ini_get("max_execution_time")); | 10 | var_dump(ini_get("max_execution_time")); |
| 11 | ?> | 11 | ?> |
| 12 | --EXPECTF-- | 12 | --EXPECTF-- |
| 13 | Fatal error: [snuffleupagus][0.0.0.0][ini_protection][drop] INI value out of range in %a/ini_min_policy_drop.php on line 2 | 13 | Fatal error: [snuffleupagus][0.0.0.0][ini_protection][drop] INI value out of range in %a/ini_min_policy_drop.php on line 2%A |
diff --git a/src/tests/ini/ini_minmax.phpt b/src/tests/ini/ini_minmax.phpt index 4cd6bc4..facb73e 100644 --- a/src/tests/ini/ini_minmax.phpt +++ b/src/tests/ini/ini_minmax.phpt | |||
| @@ -31,4 +31,4 @@ string(3) "300" | |||
| 31 | 31 | ||
| 32 | Warning: [snuffleupagus][0.0.0.0][ini_protection][log] INI value out of range in %a/ini_minmax.php on line 11 | 32 | Warning: [snuffleupagus][0.0.0.0][ini_protection][log] INI value out of range in %a/ini_minmax.php on line 11 |
| 33 | bool(true) | 33 | bool(true) |
| 34 | string(3) "300" \ No newline at end of file | 34 | string(3) "300"%A |
diff --git a/src/tests/ini/ini_null.phpt b/src/tests/ini/ini_null.phpt index 32a12c1..dfc2555 100644 --- a/src/tests/ini/ini_null.phpt +++ b/src/tests/ini/ini_null.phpt | |||
| @@ -23,4 +23,4 @@ string(0) "" | |||
| 23 | 23 | ||
| 24 | Warning: [snuffleupagus][0.0.0.0][ini_protection][log] new INI value must not be NULL or empty in %a/ini_null.php on line 8 | 24 | Warning: [snuffleupagus][0.0.0.0][ini_protection][log] new INI value must not be NULL or empty in %a/ini_null.php on line 8 |
| 25 | bool(true) | 25 | bool(true) |
| 26 | string(3) "def" \ No newline at end of file | 26 | string(3) "def"%A |
diff --git a/src/tests/ini/ini_regexp.phpt b/src/tests/ini/ini_regexp.phpt index f6c5198..c7cab35 100644 --- a/src/tests/ini/ini_regexp.phpt +++ b/src/tests/ini/ini_regexp.phpt | |||
| @@ -16,4 +16,4 @@ var_dump(ini_get("highlight.comment")); | |||
| 16 | string(7) "#000aBc" | 16 | string(7) "#000aBc" |
| 17 | 17 | ||
| 18 | Warning: [snuffleupagus][0.0.0.0][ini_protection][log] INI value does not match regex in %a/ini_regexp.php on line 5 | 18 | Warning: [snuffleupagus][0.0.0.0][ini_protection][log] INI value does not match regex in %a/ini_regexp.php on line 5 |
| 19 | string(7) "#000aBc" | 19 | string(7) "#000aBc"%A |
diff --git a/src/tests/ini/ini_regexp_drop.phpt b/src/tests/ini/ini_regexp_drop.phpt index 9225470..432be8d 100644 --- a/src/tests/ini/ini_regexp_drop.phpt +++ b/src/tests/ini/ini_regexp_drop.phpt | |||
| @@ -10,4 +10,4 @@ var_dump(ini_set("user_agent", "Foo") === false); | |||
| 10 | var_dump(ini_get("user_agent")); | 10 | var_dump(ini_get("user_agent")); |
| 11 | ?> | 11 | ?> |
| 12 | --EXPECTF-- | 12 | --EXPECTF-- |
| 13 | Fatal error: [snuffleupagus][0.0.0.0][ini_protection][drop] INI value does not match regex in %a/ini_regexp_drop.php on line 2 | 13 | Fatal error: [snuffleupagus][0.0.0.0][ini_protection][drop] INI value does not match regex in %a/ini_regexp_drop.php on line 2%A%A%A%A |
diff --git a/src/tests/xxe/disable_xxe_dom_disabled.phpt b/src/tests/xxe/disable_xxe_dom_disabled.phpt index 107171c..4a888ed 100644 --- a/src/tests/xxe/disable_xxe_dom_disabled.phpt +++ b/src/tests/xxe/disable_xxe_dom_disabled.phpt | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | --TEST-- | 1 | --TEST-- |
| 2 | Disable XXE (feature enabled) | 2 | Disable XXE (feature enabled) |
| 3 | --SKIPIF-- | 3 | --SKIPIF-- |
| 4 | <?php if (!extension_loaded("snuffleupagus") || !extension_loaded("dom")) print("skip"); ?> | 4 | <?php if (!extension_loaded("snuffleupagus") || !extension_loaded("dom") || !extension_loaded("xml")) print("skip"); ?> |
| 5 | <?php if (PHP_VERSION_ID >= 80000) print "skip"; ?> | 5 | <?php if (PHP_VERSION_ID >= 80000) print "skip"; ?> |
| 6 | --INI-- | 6 | --INI-- |
| 7 | sp.configuration_file={PWD}/config/disable_xxe.ini | 7 | sp.configuration_file={PWD}/config/disable_xxe.ini |
