summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBeF2022-07-20 12:15:07 +0200
committerGitHub2022-07-20 12:15:07 +0200
commit2aed4220c2d019cc9b46fec70cfd79d249498e14 (patch)
treee7cc3d1d4db617fc5ab1dbcc60f2366407eb5da5
parent72109c9bf016145364b19162a5ff998fc5858a9c (diff)
parent75595945d1d868fbd6db743809ca8a3eb5de3113 (diff)
Merge pull request #1 from jvoisin/pr1
pr for fetching upstream
-rw-r--r--.github/workflows/distributions_php7.yml25
-rw-r--r--.github/workflows/release.yml71
-rw-r--r--README.md2
-rw-r--r--config/default.rules6
-rw-r--r--debian/changelog36
-rw-r--r--debian/control2
-rwxr-xr-xdebian/rules4
-rw-r--r--doc/source/changelog.rst74
-rw-r--r--doc/source/config.rst16
-rw-r--r--doc/source/papers.rst5
-rw-r--r--src/Makefile.frag2
-rw-r--r--src/php_snuffleupagus.h17
-rw-r--r--src/snuffleupagus.c27
-rw-r--r--src/sp_config.c20
-rw-r--r--src/sp_config.h6
-rw-r--r--src/sp_config_keywords.c6
-rw-r--r--src/sp_config_scanner.cached.c1169
-rw-r--r--src/sp_config_scanner.h6
-rw-r--r--src/sp_config_scanner.re15
-rw-r--r--src/sp_config_utils.c6
-rw-r--r--src/sp_config_utils.h2
-rw-r--r--src/sp_crypt.c7
-rw-r--r--src/sp_disabled_functions.c10
-rw-r--r--src/sp_execute.c105
-rw-r--r--src/sp_ifilter.c2
-rw-r--r--src/sp_ini.c11
-rw-r--r--src/sp_sloppy.c41
-rw-r--r--src/sp_sloppy.h1
-rw-r--r--src/sp_unserialize.c2
-rw-r--r--src/sp_utils.c107
-rw-r--r--src/sp_utils.h6
-rw-r--r--src/sp_var_parser.c6
-rw-r--r--src/sp_var_parser.h2
-rw-r--r--src/sp_var_value.c9
-rw-r--r--src/tests/deny_writable/config/config_disable_writable_simulation.ini2
-rw-r--r--src/tests/deny_writable/deny_writable_execution_simulation.phpt11
-rw-r--r--src/tests/disable_function/config/config_disabled_functions_eval_param.ini1
-rw-r--r--src/tests/disable_function/config/config_disabled_functions_name_type_php8.ini1
-rw-r--r--src/tests/disable_function/config/config_disabled_functions_param_str_representation_php8.ini1
-rw-r--r--src/tests/disable_function/disabled_functions_eval_param.phpt14
-rw-r--r--src/tests/disable_function/disabled_functions_name_type_php8.phpt16
-rw-r--r--src/tests/disable_function/disabled_functions_param_str_representation_php8.phpt26
-rw-r--r--src/tests/dump_request/dump_eval_blacklist.phpt2
-rw-r--r--src/tests/ini/ini_min_policy_drop.phpt2
-rw-r--r--src/tests/ini/ini_minmax.phpt2
-rw-r--r--src/tests/ini/ini_null.phpt2
-rw-r--r--src/tests/ini/ini_regexp.phpt2
-rw-r--r--src/tests/ini/ini_regexp_drop.phpt2
-rw-r--r--src/tests/xxe/disable_xxe_dom_disabled.phpt2
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 @@
1name: Release Builder
2on:
3 push:
4 branches:
5 - "release-*"
6 tags:
7 - "v*"
8 pull_request:
9 branches:
10 - "release-*"
11
12jobs:
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
diff --git a/README.md b/README.md
index b291628..2302d26 100644
--- a/README.md
+++ b/README.md
@@ -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()
49sp.disable_function.function("putenv").param("setting").value_r("GCONV_").drop() 49sp.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
52sp.disable_function.function("extract").param("var_array").value_r("^_").drop() 52sp.disable_function.function("extract").pos("0").value_r("^_").drop()
53sp.disable_function.function("extract").param("extract_type").value("0").drop() 53sp.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
73sp.disable_function.function("system").param("command").value_r("[$|;&`\\n\\(\\)\\\\]").drop(); 73sp.disable_function.function("system").param("command").value_r("[$|;&`\\n\\(\\)\\\\]").drop();
74sp.disable_function.function("shell_exec").param("command").value_r("[$|;&`\\n\\(\\)\\\\]").drop(); 74sp.disable_function.function("shell_exec").pos("0").value_r("[$|;&`\\n\\(\\)\\\\]").drop();
75sp.disable_function.function("exec").param("command").value_r("[$|;&`\\n\\(\\)\\\\]").drop(); 75sp.disable_function.function("exec").param("command").value_r("[$|;&`\\n\\(\\)\\\\]").drop();
76sp.disable_function.function("proc_open").param("command").value_r("[$|;&`\\n\\(\\)\\\\]").drop(); 76sp.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 @@
1snuffleupagus (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
8snuffleupagus (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
15snuffleupagus (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
1snuffleupagus (0.7.1) UNRELEASED; urgency=low 37snuffleupagus (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 @@
1Source: snuffleupagus 1Source: snuffleupagus
2Priority: optional 2Priority: optional
3Maintainer: Julien (jvoisin) Voisin <julien.voisin+snuffleupagus@dustri.org> 3Maintainer: Julien (jvoisin) Voisin <julien.voisin+snuffleupagus@dustri.org>
4Build-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 4Build-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
5Standards-Version: 4.1.3 5Standards-Version: 4.1.3
6Homepage: https://github.com/jvoisin/snuffleupagus 6Homepage: https://github.com/jvoisin/snuffleupagus
7Section: php 7Section: 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
29override_dh_auto_test: 29override_dh_auto_test:
30ifeq ($(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
33else
34 echo "skip tests"
35endif \ 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 @@
1Changelog 1Changelog
2========= 2=========
3 3
40.8.0 - Woolly Mammoth 40.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 7Bug 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 130.8.1 - `Batyr <https://github.com/jvoisin/snuffleupagus/releases/tag/v0.8.1>`__ 2022/05/16
14 - Maximum length for session id 14-------------------------------------------------------------------------------------------
15
16Bug fixes
17^^^^^^^^^
18* Fix the version number
19* Fix a test on PHP7
20
21Breaking Changes
22^^^^^^^^^^^^^^^^
23* `disable_xxe` is changed to `xxe_protection`
24
25
260.8.0 - `Woolly Mammoth <https://github.com/jvoisin/snuffleupagus/releases/tag/v0.8.0>`__ 2022/05/15
27-----------------------------------------------------------------------------------------------------
28
29New 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
43Improvements
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
51Bug fixes
52^^^^^^^^^
53* XML and Session support are now checked at runtime instead of at compile time
15 54
16 55
170.7.1 - `Proboscidea <https://github.com/jvoisin/snuffleupagus/releases/tag/v0.7.0>`__ 2021/08/02 560.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 59Improvements
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
68Bug 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
310.7.0 - `Los Elefantes <https://github.com/jvoisin/snuffleupagus/releases/tag/v0.7.0>`__ 2021/01/02 750.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
47Bug fixes 91Bug fixes
48^^^^^^^^^ 92^^^^^^^^^
49* The strict mode is now disableable 93* The strict mode can now be disabled
50 94
51 95
520.6.0 - `Elephant in the room <https://github.com/jvoisin/snuffleupagus/releases/tag/v0.6.0>`__ 2020/11/06 960.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
75Miscellaneous 75Miscellaneous
76------------- 76-------------
77 77
78conditions
79^^^^^^^^^^
80
81It's possible to use conditions to have configuration portables accross
82several 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
78global 91global
79^^^^^^ 92^^^^^^
80 93
@@ -261,6 +274,9 @@ readonly_exec
261the execution of writeable PHP files. 274the execution of writeable PHP files.
262 275
263It can either be ``enabled`` or ``disabled`` and can be used in ``simulation`` mode. 276It 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
278file or the folder containing it is owned by the user the PHP process is
279running 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;
148HashTable *disabled_functions_hook; 156HashTable *disabled_functions_hook;
149HashTable *sp_internal_functions_hook; 157HashTable *sp_internal_functions_hook;
150HashTable *sp_eval_blacklist_functions_hook; 158HashTable *sp_eval_blacklist_functions_hook;
159
160#if PHP_VERSION_ID >= 80000
161const zend_string* eval_source_string;
162#else
163const zval* eval_source_string;
164#endif
165
151ZEND_END_MODULE_GLOBALS(snuffleupagus) 166ZEND_END_MODULE_GLOBALS(snuffleupagus)
152 167
153ZEND_EXTERN_MODULE_GLOBALS(snuffleupagus) 168ZEND_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
265static void add_df_to_arr(zval *arr, sp_disabled_function *df) { 257static 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 7static const sp_config_keyword sp_func[] = {
8static 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
29static 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
32zend_result sp_parse_config(const char *filename) { 33zend_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
68zend_result sp_process_rule(sp_parsed_keyword *parsed_rule, sp_config_keyword *config_keywords) { 69zend_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
273zend_result sp_process_rule(sp_parsed_keyword *parsed_rule, sp_config_keyword *config_keywords); 273zend_result sp_process_rule(sp_parsed_keyword *parsed_rule, const sp_config_keyword *const config_keywords);
274 274
275zend_result sp_parse_config(const char *filename); 275zend_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) \
278if (!value) { \ 278if (!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
419out: 419out:
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
4enum YYCONDTYPE { 6enum 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
17zend_string *sp_get_arg_string(sp_parsed_keyword *kw) { 19zend_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
43zend_string *sp_get_textual_representation(sp_parsed_keyword *parsed_rule) { 45zend_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 }
252yy2: 255yy1:
253 ++YYCURSOR; 256 ++YYCURSOR;
254 { ret = SUCCESS; goto out; } 257 { ret = SUCCESS; goto out; }
255yy4: 258yy2:
256 ++YYCURSOR; 259 ++YYCURSOR;
257yy5: 260yy3:
258 { cs_log_error("Parser error on line %d", lineno); goto out; } 261 { cs_log_error("Parser error on line %d", lineno); goto out; }
259yy6: 262yy4:
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; }
265yy9: 268yy5:
266 ++YYCURSOR; 269 ++YYCURSOR;
267 { lineno++; goto yyc_init; } 270 { lineno++; goto yyc_init; }
268yy11: 271yy6:
269 yych = *++YYCURSOR; 272 yych = *++YYCURSOR;
270 if (yych == '\n') goto yy9; 273 if (yych == '\n') goto yy5;
271 goto yy5; 274 goto yy3;
272yy12: 275yy7:
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; }
278yy15: 281yy8:
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 }
290yy16: 293yy9:
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;
296yy17: 299yy10:
297 yych = *++YYCURSOR; 300 yych = *++YYCURSOR;
298 if (yych == 'o') goto yy27; 301 if (yych == 'o') goto yy19;
299yy18: 302yy11:
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 }
341yy12:
342 yych = *++YYCURSOR;
343 if (yych == 'n') goto yy20;
344 if (yych == 'r') goto yy21;
345 goto yy11;
346yy13:
347 yych = *++YYCURSOR;
348 if (yych == 'n') goto yy22;
349 goto yy11;
350yy14:
351 yych = *++YYCURSOR;
352 if (yych == 'o') goto yy23;
353 goto yy11;
354yy15:
355 yych = *++YYCURSOR;
356 if (yych == 'e') goto yy17;
357 goto yy11;
358yy16:
359 yych = *++YYCURSOR;
360 if (yych == 'a') goto yy24;
361 goto yy11;
362yy17:
363 yych = *++YYCURSOR;
364 if (yych == 't') goto yy25;
365 goto yy11;
366yy18:
367 ++YYCURSOR;
368 { kw_i = 0; goto yyc_rule; }
338yy19: 369yy19:
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;
343yy20: 373yy20:
344 yych = *++YYCURSOR; 374 yych = *++YYCURSOR;
345 if (yych == 'n') goto yy30; 375 if (yych == 'd') goto yy27;
346 goto yy18; 376 goto yy11;
347yy21: 377yy21:
348 yych = *++YYCURSOR; 378 yych = *++YYCURSOR;
349 if (yych == 'o') goto yy31; 379 if (yych == 'r') goto yy28;
350 goto yy18; 380 goto yy11;
351yy22: 381yy22:
352 yych = *++YYCURSOR; 382 yych = *++YYCURSOR;
353 if (yych == 'e') goto yy24; 383 if (yych == 'f') goto yy29;
354 goto yy18; 384 goto yy11;
355yy23: 385yy23:
356 yych = *++YYCURSOR; 386 yych = *++YYCURSOR;
357 if (yych == 'a') goto yy32; 387 if (yych == 'g') goto yy30;
358 goto yy18; 388 goto yy11;
359yy24: 389yy24:
360 yych = *++YYCURSOR; 390 yych = *++YYCURSOR;
361 if (yych == 't') goto yy33; 391 if (yych == 'r') goto yy31;
362 goto yy18; 392 goto yy11;
363yy25: 393yy25:
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;
398yy26:
399 yych = *++YYCURSOR;
400 if (yych == 'd') goto yy33;
401 goto yy11;
366yy27: 402yy27:
367 yych = *++YYCURSOR; 403 yych = *++YYCURSOR;
368 if (yych == 'n') goto yy34; 404 if (yych == '_') goto yy34;
369 goto yy18; 405 goto yy11;
370yy28: 406yy28:
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;
374yy29: 411yy29:
375 yych = *++YYCURSOR; 412 yych = *++YYCURSOR;
376 if (yych == 'r') goto yy36; 413 if (yych != 'o') goto yy11;
377 goto yy18;
378yy30: 414yy30:
379 yych = *++YYCURSOR; 415 yych = *++YYCURSOR;
380 if (yych == 'f') goto yy37; 416 if (yych == '"') goto yy11;
381 goto yy18; 417 goto yy39;
382yy31: 418yy31:
383 yych = *++YYCURSOR; 419 yych = *++YYCURSOR;
384 if (yych == 'g') goto yy38; 420 if (yych == 'n') goto yy40;
385 goto yy18; 421 goto yy11;
386yy32: 422yy32:
387 yych = *++YYCURSOR; 423 yych = *++YYCURSOR;
388 if (yych == 'r') goto yy39;
389 goto yy18;
390yy33:
391 yych = *++YYCURSOR;
392 if (yych == '\t') goto yy40;
393 if (yych == ' ') goto yy40;
394 goto yy18;
395yy34:
396 yych = *++YYCURSOR;
397 if (yych == 'd') goto yy42;
398 goto yy18;
399yy35:
400 yych = *++YYCURSOR;
401 if (yych == '_') goto yy43;
402 goto yy18;
403yy36:
404 yych = *++YYCURSOR;
405 if (yych == '"') goto yy18;
406 if (yych == 'o') goto yy46;
407 goto yy45;
408yy37:
409 yych = *++YYCURSOR;
410 if (yych != 'o') goto yy18;
411yy38:
412 yych = *++YYCURSOR;
413 if (yych == '"') goto yy18;
414 goto yy48;
415yy39:
416 yych = *++YYCURSOR;
417 if (yych == 'n') goto yy49;
418 goto yy18;
419yy40:
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 }
447yy42: 450yy33:
448 yych = *++YYCURSOR; 451 yych = *++YYCURSOR;
449 if (yych == 'i') goto yy52; 452 if (yych == 'i') goto yy42;
450 goto yy18; 453 goto yy11;
451yy43: 454yy34:
452 yych = *++YYCURSOR; 455 yych = *++YYCURSOR;
453 if (yych == 'c') goto yy53; 456 if (yych == 'c') goto yy43;
454 goto yy18; 457 goto yy11;
455yy44: 458yy35:
456 yych = *++YYCURSOR; 459 yych = *++YYCURSOR;
457yy45: 460yy36:
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 }
469yy46: 472yy37:
470 yych = *++YYCURSOR; 473 yych = *++YYCURSOR;
471 if (yych == 'r') goto yy56; 474 if (yych == 'r') goto yy45;
472 goto yy18; 475 goto yy11;
473yy47: 476yy38:
474 yych = *++YYCURSOR; 477 yych = *++YYCURSOR;
475yy48: 478yy39:
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 }
487yy49: 490yy40:
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;
492yy50: 495yy41:
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;
506yy52: 509yy42:
507 yych = *++YYCURSOR; 510 yych = *++YYCURSOR;
508 if (yych == 't') goto yy64; 511 if (yych == 't') goto yy51;
509 goto yy18; 512 goto yy11;
510yy53: 513yy43:
511 yych = *++YYCURSOR; 514 yych = *++YYCURSOR;
512 if (yych == 'o') goto yy65; 515 if (yych == 'o') goto yy52;
513 goto yy18; 516 goto yy11;
514yy54: 517yy44:
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;
522yy56: 525yy45:
523 yych = *++YYCURSOR; 526 yych = *++YYCURSOR;
524 if (yych == '"') goto yy18; 527 if (yych == '"') goto yy11;
525 goto yy45; 528 goto yy36;
526yy57: 529yy46:
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 }
541yy59: 544yy47:
542 yych = *++YYCURSOR; 545 yych = *++YYCURSOR;
543yy60: 546yy48:
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 }
555yy61: 558yy49:
556 yych = *++YYCURSOR; 559 yych = *++YYCURSOR;
557 if (yych == 'n') goto yy76; 560 if (yych == 'n') goto yy60;
558 goto yy18; 561 goto yy11;
559yy62: 562yy50:
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 }
572yy64: 575yy51:
573 yych = *++YYCURSOR; 576 yych = *++YYCURSOR;
574 if (yych == 'i') goto yy79; 577 if (yych == 'i') goto yy62;
575 goto yy18; 578 goto yy11;
576yy65: 579yy52:
577 yych = *++YYCURSOR; 580 yych = *++YYCURSOR;
578 if (yych == 'n') goto yy80; 581 if (yych == 'n') goto yy63;
579 goto yy18; 582 goto yy11;
580yy66: 583yy53:
581 yych = *++YYCURSOR; 584 yych = *++YYCURSOR;
582 yyt2 = YYCURSOR; 585 yyt2 = YYCURSOR;
583 if (yych == ';') goto yy81; 586 if (yych == ';') goto yy64;
584yy67: 587yy54:
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 }
593yy68: 596yy55:
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;
601yy70: 604yy56:
602 yych = *++YYCURSOR; 605 yych = *++YYCURSOR;
603 yyt2 = YYCURSOR; 606 yyt2 = YYCURSOR;
604 if (yych == ';') goto yy83; 607 if (yych == ';') goto yy66;
605yy71: 608yy57:
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 }
614yy72: 617yy58:
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 }
629yy74: 632yy59:
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 }
644yy76: 647yy60:
645 yych = *++YYCURSOR; 648 yych = *++YYCURSOR;
646 if (yych == 'g') goto yy89; 649 if (yych == 'g') goto yy71;
647 goto yy18; 650 goto yy11;
648yy77: 651yy61:
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 }
663yy79: 666yy62:
664 yych = *++YYCURSOR; 667 yych = *++YYCURSOR;
665 if (yych == 'o') goto yy94; 668 if (yych == 'o') goto yy75;
666 goto yy18; 669 goto yy11;
667yy80: 670yy63:
668 yych = *++YYCURSOR; 671 yych = *++YYCURSOR;
669 if (yych == 'd') goto yy95; 672 if (yych == 'd') goto yy76;
670 goto yy18; 673 goto yy11;
671yy81: 674yy64:
672 ++YYCURSOR; 675 ++YYCURSOR;
673 goto yy67; 676 goto yy54;
674yy82: 677yy65:
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 }
700yy83: 703yy66:
701 ++YYCURSOR; 704 ++YYCURSOR;
702 goto yy71; 705 goto yy57;
703yy84: 706yy67:
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 }
729yy85: 732yy68:
730 yych = *++YYCURSOR; 733 yych = *++YYCURSOR;
731 yyt2 = YYCURSOR; 734 yyt2 = YYCURSOR;
732 if (yych == ';') goto yy98; 735 if (yych == ';') goto yy79;
733yy86: 736yy69:
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 }
742yy87: 745yy70:
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 }
757yy89: 760yy71:
758 yych = *++YYCURSOR; 761 yych = *++YYCURSOR;
759 if (yych == '"') goto yy18; 762 if (yych == '"') goto yy11;
760 goto yy60; 763 goto yy48;
761yy90: 764yy72:
762 yych = *++YYCURSOR; 765 yych = *++YYCURSOR;
763 yyt4 = YYCURSOR; 766 yyt4 = YYCURSOR;
764 goto yy101; 767 goto yy82;
765yy91: 768yy73:
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 }
782yy92: 785yy74:
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 }
797yy94: 800yy75:
798 yych = *++YYCURSOR; 801 yych = *++YYCURSOR;
799 if (yych == 'n') goto yy104; 802 if (yych == 'n') goto yy84;
800 goto yy18; 803 goto yy11;
801yy95: 804yy76:
802 yych = *++YYCURSOR; 805 yych = *++YYCURSOR;
803 if (yych == 'i') goto yy105; 806 if (yych == 'i') goto yy85;
804 goto yy18; 807 goto yy11;
805yy96: 808yy77:
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;
814yy97: 817yy78:
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 }
830yy98: 833yy79:
831 ++YYCURSOR; 834 ++YYCURSOR;
832 goto yy86; 835 goto yy69;
833yy99: 836yy80:
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 }
859yy100: 862yy81:
860 yych = *++YYCURSOR; 863 yych = *++YYCURSOR;
861yy101: 864yy82:
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;
871yy103: 874yy83:
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 }
905yy104: 908yy84:
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;
910yy105: 913yy85:
911 yych = *++YYCURSOR; 914 yych = *++YYCURSOR;
912 if (yych == 't') goto yy113; 915 if (yych == 't') goto yy90;
913 goto yy18; 916 goto yy11;
914yy106: 917yy86:
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 }
930yy107: 933yy87:
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 }
953yy109: 956yy88:
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 }
969yy110: 972yy89:
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; }
974yy113: 977yy90:
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;
981yy116: 984yy91:
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 }
1070yy122: 1073yy93:
1071 ++YYCURSOR; 1074 ++YYCURSOR;
1072yy123: 1075yy94:
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; }
1074yy124: 1077yy95:
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; }
1080yy127: 1083yy96:
1081 ++YYCURSOR; 1084 ++YYCURSOR;
1082 { lineno++; goto yyc_cond; } 1085 { lineno++; goto yyc_cond; }
1083yy129: 1086yy97:
1084 yych = *++YYCURSOR; 1087 yych = *++YYCURSOR;
1085 if (yych == '\n') goto yy127; 1088 if (yych == '\n') goto yy96;
1086 goto yy123; 1089 goto yy94;
1087yy130: 1090yy98:
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; }
1091yy132: 1094yy99:
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; }
1095yy134: 1098yy100:
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; }
1103yy137: 1106yy101:
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;
1110yy139: 1113yy102:
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 }
1122yy140: 1125yy103:
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 }
1132yy141: 1135yy104:
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 }
1139yy142: 1142yy105:
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;
1147yy144: 1150yy106:
1148 ++YYCURSOR; 1151 ++YYCURSOR;
1149yy145: 1152yy107:
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 }
1164yy146: 1167yy108:
1165 yych = *++YYCURSOR; 1168 yych = *++YYCURSOR;
1166 if (yych == ')') goto yy144; 1169 if (yych == ')') goto yy106;
1167 goto yy141; 1170 goto yy104;
1168yy147: 1171yy109:
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/* *********************************** */
1201yyc_cond_op: 1204yyc_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 }
1274yy153: 1277yy111:
1275 ++YYCURSOR; 1278 ++YYCURSOR;
1276yy154: 1279yy112:
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; }
1278yy155: 1281yy113:
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; }
1284yy158: 1287yy114:
1285 ++YYCURSOR; 1288 ++YYCURSOR;
1286 { lineno++; goto yyc_cond_op; } 1289 { lineno++; goto yyc_cond_op; }
1287yy160: 1290yy115:
1288 yych = *++YYCURSOR; 1291 yych = *++YYCURSOR;
1289 if (yych == '\n') goto yy158; 1292 if (yych == '\n') goto yy114;
1290 goto yy154; 1293 goto yy112;
1291yy161: 1294yy116:
1292 yych = *++YYCURSOR; 1295 yych = *++YYCURSOR;
1293 if (yych == '&') goto yy170; 1296 if (yych == '&') goto yy123;
1294 goto yy154; 1297 goto yy112;
1295yy162: 1298yy117:
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 }
1307yy164: 1310yy118:
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 }
1317yy166: 1320yy119:
1318 yych = *++YYCURSOR; 1321 yych = *++YYCURSOR;
1319 if (yych == '=') goto yy170; 1322 if (yych == '=') goto yy123;
1320yy167: 1323yy120:
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 }
1337yy168: 1340yy121:
1338 yych = *++YYCURSOR; 1341 yych = *++YYCURSOR;
1339 if (yych == '=') goto yy170; 1342 if (yych == '=') goto yy123;
1340 goto yy154; 1343 goto yy112;
1341yy169: 1344yy122:
1342 yych = *++YYCURSOR; 1345 yych = *++YYCURSOR;
1343 if (yych != '|') goto yy154; 1346 if (yych != '|') goto yy112;
1344yy170: 1347yy123:
1345 ++YYCURSOR; 1348 ++YYCURSOR;
1346 goto yy167; 1349 goto yy120;
1347 } 1350 }
1348/* *********************************** */ 1351/* *********************************** */
1349yyc_rule: 1352yyc_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 }
1400yy173: 1403yy125:
1401 ++YYCURSOR; 1404 ++YYCURSOR;
1402yy174: 1405yy126:
1403 { goto end_of_rule; } 1406 { goto end_of_rule; }
1404yy175: 1407yy127:
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; }
1410yy178: 1413yy128:
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 }
1435yy179: 1438yy129:
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;
1440yy180: 1443yy130:
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 }
1457yy181: 1460yy131:
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 }
1468yy183: 1471yy132:
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;
1475yy185: 1478yy133:
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 }
1488yy186: 1491yy134:
1489 yych = *++YYCURSOR; 1492 yych = *++YYCURSOR;
1490 if (yych == '\n') goto yy183; 1493 if (yych == '\n') goto yy132;
1491 goto yy185; 1494 goto yy133;
1492yy187: 1495yy135:
1493 ++YYCURSOR; 1496 ++YYCURSOR;
1494 YYCURSOR = yyt1; 1497 YYCURSOR = yyt1;
1495 { lineno++; goto yyc_rule; } 1498 { lineno++; goto yyc_rule; }
1496yy189: 1499yy136:
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 }
1520yy190: 1523yy137:
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;
1532yy192: 1535yy138:
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 }
1567yy193: 1570yy139:
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 }
1598yy194: 1601yy140:
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;
1606yy196: 1609yy141:
1607 ++YYCURSOR; 1610 ++YYCURSOR;
1608 goto yy192; 1611 goto yy138;
1609yy197: 1612yy142:
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 }
1632yy199: 1635yy143:
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;
1639yy200: 1642yy144:
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
1674out: 1677out:
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
21zend_result sp_config_scan(char *data, zend_result (*process_rule)(sp_parsed_keyword*)); 21zend_result sp_config_scan(char *data, zend_result (*process_rule)(sp_parsed_keyword*));
22zend_string *sp_get_arg_string(sp_parsed_keyword *kw); 22zend_string *sp_get_arg_string(sp_parsed_keyword const *const kw);
23zend_string *sp_get_textual_representation(sp_parsed_keyword *parsed_rule); 23zend_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
10zend_string *sp_get_arg_string(sp_parsed_keyword *kw) { 12zend_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
36zend_string *sp_get_textual_representation(sp_parsed_keyword *parsed_rule) { 38zend_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
322out: 325out:
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
4sp_list_node *parse_functions_list(char *value) { 4sp_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
4sp_list_node *parse_functions_list(char *value); 4sp_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
117out: 117out:
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
14ZEND_COLD static inline void terminate_if_writable(const char *filename) { 14ZEND_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
69violation: 65violation:
@@ -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
96static void ZEND_HOT is_in_eval_and_whitelisted(const zend_execute_data *execute_data) { 92static 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
128out: 124out:
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
262static void sp_execute_ex(zend_execute_data *execute_data) { 258static 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
337ZEND_API zend_op_array* (*orig_zend_compile_file)(zend_file_handle* file_handle,
338 int type) = NULL;
339#if PHP_VERSION_ID >= 80000
340ZEND_API zend_op_array* (*orig_zend_compile_string)(
341 zend_string* source_string, const char* filename) = NULL;
342#else
343ZEND_API zend_op_array* (*orig_zend_compile_string)(zval* source_string,
344 char* filename) = NULL;
345#endif
346
347#if PHP_VERSION_ID >= 80000
348ZEND_API zend_op_array* sp_compile_string(zend_string* source_string,
349 const char* filename) {
350#else
351ZEND_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
360ZEND_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
345int hook_execute(void) { 367int 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
98void sp_hook_register_server_variables() 98void 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
15static bool /* success */ sp_ini_check(zend_string *varname, zend_string *new_value, sp_ini_entry **sp_entry_p) { 15static 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
78static PHP_INI_MH(sp_ini_onmodify) { 78static 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
93void sp_hook_ini() { 92void 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
127void sp_unhook_ini() { 126void 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
3ZEND_API zend_op_array* (*orig_zend_compile_file)(zend_file_handle* file_handle, 3void sp_sloppy_modify_opcode(zend_op_array* opline) {
4 int type) = NULL;
5#if PHP_VERSION_ID >= 80000
6ZEND_API zend_op_array* (*orig_zend_compile_string)(
7 zend_string* source_string, const char* filename) = NULL;
8#else
9ZEND_API zend_op_array* (*orig_zend_compile_string)(zval* source_string,
10 char* filename) = NULL;
11#endif
12
13static 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
29ZEND_API zend_op_array* sp_compile_string(zend_string* source_string,
30 const char* filename) {
31#else
32ZEND_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
39ZEND_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
46static void array_handler(INTERNAL_FUNCTION_PARAMETERS, const char* name, 18static 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) {
99void hook_sloppy() { 71void 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
6void hook_sloppy(void); 6void hook_sloppy(void);
7void 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
11static zend_string *sp_do_hash_hmac_sha256(char *data, size_t data_len, char *key, size_t key_len) 11static 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
3static const char* default_ipaddr = "0.0.0.0"; 3static char const* const default_ipaddr = "0.0.0.0";
4const char* get_ipaddr() { 4const 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
18void sp_log_msgf(char const* restrict feature, int level, int type, 18void 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
66int compute_hash(const char* const restrict filename, 66int 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
93static int construct_filename(char* filename, 93int 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
119int 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
73const char *get_ipaddr(void); 73const char *get_ipaddr(void);
74void sp_log_msgf(char const *restrict feature, int level, int type, const char *restrict fmt, ...); 74void sp_log_msgf(char const* const restrict feature, int level, int type, char const* const restrict fmt, ...);
75int compute_hash(const char *const restrict filename, char *restrict file_hash); 75int compute_hash(char const* const restrict filename, char *restrict file_hash);
76const zend_string *sp_zval_to_zend_string(const zval *); 76const zend_string *sp_zval_to_zend_string(const zval *);
77bool sp_match_value(const zend_string* value, const zend_string* to_match, const sp_regexp* rx); 77bool sp_match_value(const zend_string* value, const zend_string* to_match, const sp_regexp* rx);
78bool sp_match_array_key(const zval *, const zend_string *, const sp_regexp *); 78bool sp_match_array_key(const zval *, const zend_string *, const sp_regexp *);
@@ -83,7 +83,7 @@ bool hook_function(const char *, HashTable *, zif_handler);
83void unhook_functions(HashTable *ht); 83void unhook_functions(HashTable *ht);
84int hook_regexp(const sp_pcre *, HashTable *, zif_handler); 84int hook_regexp(const sp_pcre *, HashTable *, zif_handler);
85bool check_is_in_eval_whitelist(const char* function_name); 85bool check_is_in_eval_whitelist(const char* function_name);
86int sp_log_request(const zend_string *restrict folder, const zend_string *restrict text_repr); 86int 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)
88static inline bool sp_zend_string_equals_str(const zend_string* s1, const char *str, size_t len) { 88static 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
247sp_tree *sp_parse_var(const char *line) { 247sp_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
5typedef struct sp_token_s { 5typedef 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
112static zval *get_array_value(zend_execute_data *ed, const zval *const zvalue, 112static 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,
129static zval *get_object_property(zend_execute_data *ed, zval *object, 129static 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--
2Readonly execution attempt (simulation mode) 2Readonly execution attempt (simulation mode)
3--SKIPIF-- 3--SKIPIF--
4<?php if (PHP_VERSION_ID >= 80000) print "skip"; ?>
5<?php 4<?php
6if (!extension_loaded("snuffleupagus")) { print "skip"; }; 5if (!extension_loaded("snuffleupagus")) { print "skip"; };
7 6
@@ -42,10 +41,14 @@ unlink("$dir/non_writable_file.txt");
42unlink("$dir/writable_file.txt"); 41unlink("$dir/writable_file.txt");
43?> 42?>
44--EXPECTF-- 43--EXPECTF--
45Warning: [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 44Warning: [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
47Warning: [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 46Warning: [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
49Warning: [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 48Warning: [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
50Code execution within a writable file. 49Code execution within a writable file.
50
51Warning: [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
53Warning: [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
51Code execution within a non-writable file. 54Code 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--
2Disable functions - eval, on matching parameter
3--SKIPIF--
4<?php if (!extension_loaded("snuffleupagus")) print "skip"; ?>
5--INI--
6sp.configuration_file={PWD}/config/config_disabled_functions_eval_param.ini
7--FILE--
8<?php
9$var = 123456789;
10eval('$var = 1337 + 1337;');
11print("Variable: $var\n");
12?>
13--EXPECTF--
14Fatal 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--
2Disable functions
3--SKIPIF--
4<?php if (!extension_loaded("snuffleupagus")) print "skip"; ?>
5<?php if (PHP_VERSION_ID < 80000) print "skip"; ?>
6--INI--
7sp.configuration_file={PWD}/config/config_disabled_functions_name_type_php8.ini
8--FILE--
9<?php
10echo strcmp("pouet", "pouet") . "\n";
11echo strcmp([1,23], "pouet") . "\n";
12?>
13--EXPECTF--
140
15
16Fatal 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--
2Disable 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--
7sp.configuration_file={PWD}/config/config_disabled_functions_param_str_representation_php8.ini
8--FILE--
9<?php
10echo var_export(true) . "\n";
11echo var_export(false) . "\n";
12echo var_export(null) . "\n";
13echo var_export(1) . "\n";
14echo var_export(1.0) . "\n";
15function f(&$a) {
16 echo var_export($a) . "\n";
17}
18$a = 123; f($a);
19?>
20--EXPECTF--
21true
22false
23NULL
241
251.0
26123
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);
10var_dump(ini_get("max_execution_time")); 10var_dump(ini_get("max_execution_time"));
11?> 11?>
12--EXPECTF-- 12--EXPECTF--
13Fatal error: [snuffleupagus][0.0.0.0][ini_protection][drop] INI value out of range in %a/ini_min_policy_drop.php on line 2 13Fatal 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
32Warning: [snuffleupagus][0.0.0.0][ini_protection][log] INI value out of range in %a/ini_minmax.php on line 11 32Warning: [snuffleupagus][0.0.0.0][ini_protection][log] INI value out of range in %a/ini_minmax.php on line 11
33bool(true) 33bool(true)
34string(3) "300" \ No newline at end of file 34string(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
24Warning: [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 24Warning: [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
25bool(true) 25bool(true)
26string(3) "def" \ No newline at end of file 26string(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"));
16string(7) "#000aBc" 16string(7) "#000aBc"
17 17
18Warning: [snuffleupagus][0.0.0.0][ini_protection][log] INI value does not match regex in %a/ini_regexp.php on line 5 18Warning: [snuffleupagus][0.0.0.0][ini_protection][log] INI value does not match regex in %a/ini_regexp.php on line 5
19string(7) "#000aBc" 19string(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);
10var_dump(ini_get("user_agent")); 10var_dump(ini_get("user_agent"));
11?> 11?>
12--EXPECTF-- 12--EXPECTF--
13Fatal error: [snuffleupagus][0.0.0.0][ini_protection][drop] INI value does not match regex in %a/ini_regexp_drop.php on line 2 13Fatal 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--
2Disable XXE (feature enabled) 2Disable 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--
7sp.configuration_file={PWD}/config/disable_xxe.ini 7sp.configuration_file={PWD}/config/disable_xxe.ini