diff options
| author | jvoisin | 2022-03-20 18:20:45 +0100 |
|---|---|---|
| committer | jvoisin | 2022-03-20 18:20:45 +0100 |
| commit | 81dd7f2ef07af306fe83d7755cbac4529aa9fc8d (patch) | |
| tree | 32cc44c6231b30db5ac7b15699297863460784aa /src/sp_ifilter.c | |
| parent | 83b01942dfc80474cc05e09aeef4b44307a7120b (diff) | |
| parent | c38df1077a6c1dfbca1baca049214d053e2e7684 (diff) | |
Merge remote-tracking branch 'sektioneins/master'
Diffstat (limited to 'src/sp_ifilter.c')
| -rw-r--r-- | src/sp_ifilter.c | 104 |
1 files changed, 104 insertions, 0 deletions
diff --git a/src/sp_ifilter.c b/src/sp_ifilter.c new file mode 100644 index 0000000..8099882 --- /dev/null +++ b/src/sp_ifilter.c | |||
| @@ -0,0 +1,104 @@ | |||
| 1 | #include "php_snuffleupagus.h" | ||
| 2 | |||
| 3 | static void (*orig_register_server_variables)(zval *track_vars_array) = NULL; | ||
| 4 | |||
| 5 | static const unsigned char sp_hexchars[] = "0123456789ABCDEF"; | ||
| 6 | |||
| 7 | static const char sp_is_dangerous_char[256] = { | ||
| 8 | /* |-> 0 1 2 3 4 5 6 7 8 9 a b c d e f */ | ||
| 9 | /* 0x00 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, | ||
| 10 | /* 0x10 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 11 | /* 0x20 */ 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 12 | /* 0x30 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, | ||
| 13 | /* 0x40 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 14 | /* 0x50 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 15 | /* 0x60 */ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 16 | /* 0x70 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 17 | /* 0x80 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 18 | /* 0x90 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 19 | /* 0xa0 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 20 | /* 0xb0 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 21 | /* 0xc0 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 22 | /* 0xd0 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 23 | /* 0xe0 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | ||
| 24 | /* 0xf0 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 | ||
| 25 | }; | ||
| 26 | |||
| 27 | static void sp_server_strip(HashTable *svars, char *key, int keylen) { | ||
| 28 | zval *value = zend_hash_str_find(svars, key, keylen); | ||
| 29 | if (!value || Z_TYPE_P(value) != IS_STRING) { return; } | ||
| 30 | |||
| 31 | zend_string *tmp_zstr = Z_STR_P(value); | ||
| 32 | char *tmp = ZSTR_VAL(tmp_zstr); | ||
| 33 | char *tmpend = tmp + ZSTR_LEN(tmp_zstr); | ||
| 34 | |||
| 35 | for (char *p = tmp; p < tmpend; p++) { | ||
| 36 | if (sp_is_dangerous_char[(int)*p]) { | ||
| 37 | *p = '_'; | ||
| 38 | } | ||
| 39 | } | ||
| 40 | } | ||
| 41 | |||
| 42 | static void sp_server_encode(HashTable *svars, char *key, int keylen) { | ||
| 43 | zval *value = zend_hash_str_find(svars, key, keylen); | ||
| 44 | if (!value || Z_TYPE_P(value) != IS_STRING) { return; } | ||
| 45 | |||
| 46 | zend_string *tmp_zstr = Z_STR_P(value); | ||
| 47 | char *tmp = ZSTR_VAL(tmp_zstr); | ||
| 48 | char *tmpend = tmp + ZSTR_LEN(tmp_zstr); | ||
| 49 | int extra = 0; | ||
| 50 | |||
| 51 | for (char *p = tmp; p < tmpend; p++) { | ||
| 52 | extra += sp_is_dangerous_char[(int)*p] * 2; | ||
| 53 | } | ||
| 54 | if (!extra) { return; } | ||
| 55 | |||
| 56 | zend_string *new_zstr = zend_string_alloc(ZSTR_LEN(tmp_zstr) + extra, 0); | ||
| 57 | char *n = ZSTR_VAL(new_zstr); | ||
| 58 | for (char *p = tmp; p < tmpend; p++, n++) { | ||
| 59 | if (sp_is_dangerous_char[(int)*p]) { | ||
| 60 | *n++ = '%'; | ||
| 61 | *n++ = sp_hexchars[*p >> 4]; | ||
| 62 | *n = sp_hexchars[*p & 15]; | ||
| 63 | } else { | ||
| 64 | *n = *p; | ||
| 65 | } | ||
| 66 | } | ||
| 67 | ZSTR_VAL(new_zstr)[ZSTR_LEN(new_zstr)] = 0; | ||
| 68 | Z_STR_P(value) = new_zstr; | ||
| 69 | |||
| 70 | zend_string_release_ex(tmp_zstr, 0); | ||
| 71 | } | ||
| 72 | |||
| 73 | static void sp_register_server_variables(zval *track_vars_array) { | ||
| 74 | orig_register_server_variables(track_vars_array); | ||
| 75 | |||
| 76 | HashTable *svars; | ||
| 77 | svars = Z_ARRVAL_P(track_vars_array); | ||
| 78 | |||
| 79 | |||
| 80 | if (SPCFG(server_encode)) { | ||
| 81 | sp_server_encode(svars, ZEND_STRL("REQUEST_URI")); | ||
| 82 | sp_server_encode(svars, ZEND_STRL("QUERY_STRING")); | ||
| 83 | } | ||
| 84 | |||
| 85 | if (SPCFG(server_strip)) { | ||
| 86 | sp_server_strip(svars, ZEND_STRL("PHP_SELF")); | ||
| 87 | sp_server_strip(svars, ZEND_STRL("HTTP_HOST")); | ||
| 88 | sp_server_strip(svars, ZEND_STRL("HTTP_USER_AGENT")); | ||
| 89 | |||
| 90 | // for cgi + fpm | ||
| 91 | sp_server_strip(svars, ZEND_STRL("PATH_INFO")); | ||
| 92 | sp_server_strip(svars, ZEND_STRL("PATH_TRANSLATED")); | ||
| 93 | sp_server_strip(svars, ZEND_STRL("ORIG_PATH_TRANSLATED")); | ||
| 94 | sp_server_strip(svars, ZEND_STRL("ORIG_PATH_INFO")); | ||
| 95 | } | ||
| 96 | } | ||
| 97 | |||
| 98 | void sp_hook_register_server_variables() | ||
| 99 | { | ||
| 100 | if (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; | ||
| 103 | } | ||
| 104 | } | ||
