diff options
| author | jvoisin | 2017-09-20 10:51:22 +0200 |
|---|---|---|
| committer | jvoisin | 2017-09-21 16:09:28 +0200 |
| commit | 6487590b4fd55dddd59b43f1fcf2ebd8d56f20ac (patch) | |
| tree | 22ff7c8ee4b34a0978093afcc5b747073c625d06 | |
| parent | 09a71ec9b889af34173e354ecba935a9db010a19 (diff) | |
Add travis
| -rw-r--r-- | .travis.yml | 23 | ||||
| -rw-r--r-- | Makefile | 2 | ||||
| -rw-r--r-- | src/config.m4 | 4 | ||||
| -rw-r--r-- | src/php_snuffleupagus.h | 14 | ||||
| -rw-r--r-- | src/sp_config.c | 2 | ||||
| -rw-r--r-- | src/sp_cookie_encryption.c | 4 | ||||
| -rw-r--r-- | src/sp_disabled_functions.c | 5 | ||||
| -rw-r--r-- | src/sp_execute.c | 6 | ||||
| -rw-r--r-- | src/sp_unserialize.c | 6 | ||||
| -rw-r--r-- | src/sp_upload_validation.c | 2 | ||||
| -rw-r--r-- | src/sp_utils.c | 55 | ||||
| -rw-r--r-- | src/sp_utils.h | 12 | ||||
| -rw-r--r-- | src/tests/config/dump_request.ini | 2 | ||||
| -rw-r--r-- | src/tests/disable_xxe_dom.phpt | 1 | ||||
| -rw-r--r-- | src/tests/disable_xxe_dom_disabled.phpt | 1 | ||||
| -rw-r--r-- | src/tests/disable_xxe_simplexml.phpt | 1 | ||||
| -rw-r--r-- | src/tests/disable_xxe_simplexml_oop.phpt | 1 | ||||
| -rw-r--r-- | src/tests/disable_xxe_xml_parse.phpt | 1 | ||||
| -rw-r--r-- | src/tests/disabled_functions_ret3.phpt | 1 | ||||
| -rw-r--r-- | src/tests/disabled_functions_ret_type.phpt | 8 | ||||
| -rw-r--r-- | src/tests/disabled_option.phpt | 14 | ||||
| -rw-r--r-- | src/tests/dump_request.phpt | 10 | ||||
| -rw-r--r-- | src/tests/dump_request_too_big.phpt | 8 |
23 files changed, 119 insertions, 64 deletions
diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..057c080 --- /dev/null +++ b/.travis.yml | |||
| @@ -0,0 +1,23 @@ | |||
| 1 | language: php | ||
| 2 | |||
| 3 | php: | ||
| 4 | - '7.0' | ||
| 5 | - '7.1' | ||
| 6 | |||
| 7 | env: | ||
| 8 | - CC=gcc | ||
| 9 | - CC=clang | ||
| 10 | |||
| 11 | addons: | ||
| 12 | apt: | ||
| 13 | packages: | ||
| 14 | - gdb | ||
| 15 | - gcc | ||
| 16 | - lcov | ||
| 17 | - valgrind | ||
| 18 | - libpcre3 | ||
| 19 | - libpcre3-dev | ||
| 20 | |||
| 21 | script: | ||
| 22 | - php-config --configure-options | ||
| 23 | - make debug | ||
| @@ -4,7 +4,7 @@ clean: | |||
| 4 | 4 | ||
| 5 | debug: | 5 | debug: |
| 6 | cd src; phpize | 6 | cd src; phpize |
| 7 | export CFLAGS="-Wall -Wextra -g3 -ggdb -Wno-unused-function"; cd src; ./configure --enable-snuffleupagus --enable-debug | 7 | export CFLAGS="-Wall -Wextra -g3 -ggdb -O1 -g -Wno-unused-function"; cd src; ./configure --enable-snuffleupagus --enable-debug |
| 8 | make -C src | 8 | make -C src |
| 9 | TEST_PHP_ARGS='-q' REPORT_EXIT_STATUS=1 make -C src test | 9 | TEST_PHP_ARGS='-q' REPORT_EXIT_STATUS=1 make -C src test |
| 10 | 10 | ||
diff --git a/src/config.m4 b/src/config.m4 index aba355c..84ca2f4 100644 --- a/src/config.m4 +++ b/src/config.m4 | |||
| @@ -20,10 +20,14 @@ CFLAGS="$CFLAGS -lpcre" | |||
| 20 | CFLAGS="$CFLAGS -D_DEFAULT_SOURCE=1 -std=c99" | 20 | CFLAGS="$CFLAGS -D_DEFAULT_SOURCE=1 -std=c99" |
| 21 | CFLAGS="$CFLAGS -Wall -Wextra -Wno-unused-parameter" | 21 | CFLAGS="$CFLAGS -Wall -Wextra -Wno-unused-parameter" |
| 22 | 22 | ||
| 23 | LFLAGS="$LFLAGS -lpcre" | ||
| 24 | |||
| 23 | if test "$PHP_DEBUG" = "yes"; then | 25 | if test "$PHP_DEBUG" = "yes"; then |
| 24 | AC_DEFINE(SP_DEBUG, 1, [Wether you want to enable debug messages]) | 26 | AC_DEFINE(SP_DEBUG, 1, [Wether you want to enable debug messages]) |
| 25 | fi | 27 | fi |
| 26 | 28 | ||
| 29 | AC_CHECK_LIB(pcre, pcre_compile, AC_DEFINE(HAVE_PCRE, 1, [have pcre])) | ||
| 30 | |||
| 27 | if test "$PHP_SNUFFLEUPAGUS" != "no"; then | 31 | if test "$PHP_SNUFFLEUPAGUS" != "no"; then |
| 28 | if test "$PHP_COVERAGE" != "no"; then | 32 | if test "$PHP_COVERAGE" != "no"; then |
| 29 | CFLAGS="$CFLAGS --coverage -fprofile-arcs -ftest-coverage" | 33 | CFLAGS="$CFLAGS --coverage -fprofile-arcs -ftest-coverage" |
diff --git a/src/php_snuffleupagus.h b/src/php_snuffleupagus.h index e7a3d59..9f85cc1 100644 --- a/src/php_snuffleupagus.h +++ b/src/php_snuffleupagus.h | |||
| @@ -16,6 +16,7 @@ | |||
| 16 | 16 | ||
| 17 | #include "SAPI.h" | 17 | #include "SAPI.h" |
| 18 | #include "ext/standard/info.h" | 18 | #include "ext/standard/info.h" |
| 19 | #include "ext/pcre/php_pcre.h" | ||
| 19 | #include "php.h" | 20 | #include "php.h" |
| 20 | #include "php_ini.h" | 21 | #include "php_ini.h" |
| 21 | #include "zend_hash.h" | 22 | #include "zend_hash.h" |
| @@ -37,6 +38,7 @@ | |||
| 37 | #include "sp_upload_validation.h" | 38 | #include "sp_upload_validation.h" |
| 38 | #include "sp_utils.h" | 39 | #include "sp_utils.h" |
| 39 | 40 | ||
| 41 | |||
| 40 | extern zend_module_entry snuffleupagus_module_entry; | 42 | extern zend_module_entry snuffleupagus_module_entry; |
| 41 | #define phpext_snuffleupagus_ptr &snuffleupagus_module_entry | 43 | #define phpext_snuffleupagus_ptr &snuffleupagus_module_entry |
| 42 | 44 | ||
| @@ -64,6 +66,18 @@ ZEND_END_MODULE_GLOBALS(snuffleupagus) | |||
| 64 | ZEND_TSRMLS_CACHE_EXTERN() | 66 | ZEND_TSRMLS_CACHE_EXTERN() |
| 65 | #endif | 67 | #endif |
| 66 | 68 | ||
| 69 | #if HAVE_BUNDLED_PCRE | ||
| 70 | #include "ext/pcre/pcrelib/pcre.h" | ||
| 71 | #undef pcre_exec | ||
| 72 | #undef pcre_compile | ||
| 73 | #define sp_pcre_exec pcre_exec | ||
| 74 | #define sp_pcre_compile pcre_compile | ||
| 75 | #else | ||
| 76 | #include "pcre.h" | ||
| 77 | #define sp_pcre_exec pcre_exec | ||
| 78 | #define sp_pcre_compile pcre_compile | ||
| 79 | #endif | ||
| 80 | |||
| 67 | PHP_FUNCTION(check_disabled_function); | 81 | PHP_FUNCTION(check_disabled_function); |
| 68 | 82 | ||
| 69 | static inline void sp_terminate() { zend_bailout(); } | 83 | static inline void sp_terminate() { zend_bailout(); } |
diff --git a/src/sp_config.c b/src/sp_config.c index f73347d..37a34b9 100644 --- a/src/sp_config.c +++ b/src/sp_config.c | |||
| @@ -145,7 +145,7 @@ int parse_regexp(char *restrict line, char *restrict keyword, void *retval) { | |||
| 145 | if (value) { | 145 | if (value) { |
| 146 | const char *pcre_error; | 146 | const char *pcre_error; |
| 147 | int pcre_error_offset; | 147 | int pcre_error_offset; |
| 148 | pcre *compiled_re = pcre_compile(value, PCRE_CASELESS, &pcre_error, | 148 | pcre *compiled_re = sp_pcre_compile(value, PCRE_CASELESS, &pcre_error, |
| 149 | &pcre_error_offset, NULL); | 149 | &pcre_error_offset, NULL); |
| 150 | if (NULL == compiled_re) { | 150 | if (NULL == compiled_re) { |
| 151 | sp_log_err("config", "Failed to compile '%s': %s.", value, pcre_error); | 151 | sp_log_err("config", "Failed to compile '%s': %s.", value, pcre_error); |
diff --git a/src/sp_cookie_encryption.c b/src/sp_cookie_encryption.c index 5248486..ad8438a 100644 --- a/src/sp_cookie_encryption.c +++ b/src/sp_cookie_encryption.c | |||
| @@ -63,7 +63,7 @@ int decrypt_cookie(zval *pDest, int num_args, va_list args, | |||
| 63 | 63 | ||
| 64 | if (value_len < | 64 | if (value_len < |
| 65 | crypto_secretbox_NONCEBYTES + crypto_secretbox_ZEROBYTES) { | 65 | crypto_secretbox_NONCEBYTES + crypto_secretbox_ZEROBYTES) { |
| 66 | sp_log_msg("cookie_encryption", LOG_DROP, | 66 | sp_log_msg("cookie_encryption", SP_LOG_DROP, |
| 67 | "Buffer underflow tentative detected in cookie encryption handling."); | 67 | "Buffer underflow tentative detected in cookie encryption handling."); |
| 68 | return ZEND_HASH_APPLY_REMOVE; | 68 | return ZEND_HASH_APPLY_REMOVE; |
| 69 | } | 69 | } |
| @@ -77,7 +77,7 @@ int decrypt_cookie(zval *pDest, int num_args, va_list args, | |||
| 77 | (unsigned char *)ZSTR_VAL(debase64), key); | 77 | (unsigned char *)ZSTR_VAL(debase64), key); |
| 78 | 78 | ||
| 79 | if (ret == -1) { | 79 | if (ret == -1) { |
| 80 | sp_log_msg("cookie_encryption", LOG_DROP, | 80 | sp_log_msg("cookie_encryption", SP_LOG_DROP, |
| 81 | "Something went wrong with the decryption of %s.", | 81 | "Something went wrong with the decryption of %s.", |
| 82 | ZSTR_VAL(hash_key->key)); | 82 | ZSTR_VAL(hash_key->key)); |
| 83 | return ZEND_HASH_APPLY_REMOVE; | 83 | return ZEND_HASH_APPLY_REMOVE; |
diff --git a/src/sp_disabled_functions.c b/src/sp_disabled_functions.c index 55d782b..b3e5cbc 100644 --- a/src/sp_disabled_functions.c +++ b/src/sp_disabled_functions.c | |||
| @@ -271,7 +271,7 @@ static bool should_drop_on_ret(zval* return_value, | |||
| 271 | } | 271 | } |
| 272 | } | 272 | } |
| 273 | 273 | ||
| 274 | ret_value_str = sp_convert_to_string(return_value); // FIXME memleak | 274 | ret_value_str = sp_convert_to_string(return_value); |
| 275 | 275 | ||
| 276 | bool match_type = (config_node->ret_type) && | 276 | bool match_type = (config_node->ret_type) && |
| 277 | (config_node->ret_type == Z_TYPE_P(return_value)); | 277 | (config_node->ret_type == Z_TYPE_P(return_value)); |
| @@ -282,15 +282,18 @@ static bool should_drop_on_ret(zval* return_value, | |||
| 282 | if (true == match_type || match_value) { | 282 | if (true == match_type || match_value) { |
| 283 | if (true == config_node->allow) { | 283 | if (true == config_node->allow) { |
| 284 | efree(complete_path_function); | 284 | efree(complete_path_function); |
| 285 | efree(ret_value_str); | ||
| 285 | return false; | 286 | return false; |
| 286 | } | 287 | } |
| 287 | sp_log_disable_ret(complete_path_function, ret_value_str, config_node); | 288 | sp_log_disable_ret(complete_path_function, ret_value_str, config_node); |
| 288 | if (false == config_node->simulation) { | 289 | if (false == config_node->simulation) { |
| 289 | efree(complete_path_function); | 290 | efree(complete_path_function); |
| 291 | efree(ret_value_str); | ||
| 290 | return true; | 292 | return true; |
| 291 | } | 293 | } |
| 292 | } | 294 | } |
| 293 | next: | 295 | next: |
| 296 | efree(ret_value_str); | ||
| 294 | config = config->next; | 297 | config = config->next; |
| 295 | } | 298 | } |
| 296 | efree(complete_path_function); | 299 | efree(complete_path_function); |
diff --git a/src/sp_execute.c b/src/sp_execute.c index faf126c..7d62e88 100644 --- a/src/sp_execute.c +++ b/src/sp_execute.c | |||
| @@ -13,10 +13,10 @@ static int (*orig_zend_stream_open)(const char *filename, | |||
| 13 | ZEND_COLD static inline void terminate_if_writable(const char *filename) { | 13 | ZEND_COLD static inline void terminate_if_writable(const char *filename) { |
| 14 | if (0 == access(filename, W_OK)) { | 14 | if (0 == access(filename, W_OK)) { |
| 15 | if (true == SNUFFLEUPAGUS_G(config).config_readonly_exec->simulation) { | 15 | if (true == SNUFFLEUPAGUS_G(config).config_readonly_exec->simulation) { |
| 16 | sp_log_msg("readonly_exec", LOG_NOTICE, | 16 | sp_log_msg("readonly_exec", SP_LOG_NOTICE, |
| 17 | "Attempted execution of a writable file (%s).", filename); | 17 | "Attempted execution of a writable file (%s).", filename); |
| 18 | } else { | 18 | } else { |
| 19 | sp_log_msg("readonly_exec", LOG_DROP, | 19 | sp_log_msg("readonly_exec", SP_LOG_DROP, |
| 20 | "Attempted execution of a writable file (%s).", filename); | 20 | "Attempted execution of a writable file (%s).", filename); |
| 21 | sp_terminate(); | 21 | sp_terminate(); |
| 22 | } | 22 | } |
| @@ -37,7 +37,7 @@ static void check_inclusion_regexp(const char * const filename) { | |||
| 37 | while (config) { | 37 | while (config) { |
| 38 | pcre *config_node = (pcre*)(config->data); | 38 | pcre *config_node = (pcre*)(config->data); |
| 39 | if (false == is_regexp_matching(config_node, filename)) { | 39 | if (false == is_regexp_matching(config_node, filename)) { |
| 40 | sp_log_msg("include", LOG_DROP, "Inclusion of a forbidden file (%s).", filename); | 40 | sp_log_msg("include", SP_LOG_DROP, "Inclusion of a forbidden file (%s).", filename); |
| 41 | sp_terminate(); | 41 | sp_terminate(); |
| 42 | } | 42 | } |
| 43 | config = config->next; | 43 | config = config->next; |
diff --git a/src/sp_unserialize.c b/src/sp_unserialize.c index b5b67b4..c8503de 100644 --- a/src/sp_unserialize.c +++ b/src/sp_unserialize.c | |||
| @@ -57,7 +57,7 @@ PHP_FUNCTION(sp_unserialize) { | |||
| 57 | 57 | ||
| 58 | /* 64 is the length of HMAC-256 */ | 58 | /* 64 is the length of HMAC-256 */ |
| 59 | if (buf_len < 64) { | 59 | if (buf_len < 64) { |
| 60 | sp_log_msg("unserialize", LOG_DROP, "The serialized object is too small."); | 60 | sp_log_msg("unserialize", SP_LOG_DROP, "The serialized object is too small."); |
| 61 | RETURN_FALSE; | 61 | RETURN_FALSE; |
| 62 | } | 62 | } |
| 63 | 63 | ||
| @@ -88,13 +88,13 @@ PHP_FUNCTION(sp_unserialize) { | |||
| 88 | } | 88 | } |
| 89 | } else { | 89 | } else { |
| 90 | if ( true == SNUFFLEUPAGUS_G(config).config_unserialize->simulation) { | 90 | if ( true == SNUFFLEUPAGUS_G(config).config_unserialize->simulation) { |
| 91 | sp_log_msg("unserialize", LOG_NOTICE, "Invalid HMAC for %s", serialized_str); | 91 | sp_log_msg("unserialize", SP_LOG_NOTICE, "Invalid HMAC for %s", serialized_str); |
| 92 | if ((orig_handler = zend_hash_str_find_ptr(SNUFFLEUPAGUS_G(sp_internal_functions_hook), | 92 | if ((orig_handler = zend_hash_str_find_ptr(SNUFFLEUPAGUS_G(sp_internal_functions_hook), |
| 93 | "unserialize", 11))) { | 93 | "unserialize", 11))) { |
| 94 | orig_handler(INTERNAL_FUNCTION_PARAM_PASSTHRU); | 94 | orig_handler(INTERNAL_FUNCTION_PARAM_PASSTHRU); |
| 95 | } | 95 | } |
| 96 | } else { | 96 | } else { |
| 97 | sp_log_msg("unserialize", LOG_DROP, "Invalid HMAC for %s", serialized_str); | 97 | sp_log_msg("unserialize", SP_LOG_DROP, "Invalid HMAC for %s", serialized_str); |
| 98 | } | 98 | } |
| 99 | } | 99 | } |
| 100 | efree(serialized_str); | 100 | efree(serialized_str); |
diff --git a/src/sp_upload_validation.c b/src/sp_upload_validation.c index bbd7eae..6655e11 100644 --- a/src/sp_upload_validation.c +++ b/src/sp_upload_validation.c | |||
| @@ -79,7 +79,7 @@ int sp_rfc1867_callback(unsigned int event, void *event_data, void **extra) { | |||
| 79 | if (WEXITSTATUS(waitstatus) != 0) { // Nope | 79 | if (WEXITSTATUS(waitstatus) != 0) { // Nope |
| 80 | char *uri = sp_getenv("REQUEST_URI"); | 80 | char *uri = sp_getenv("REQUEST_URI"); |
| 81 | int sim = SNUFFLEUPAGUS_G(config).config_upload_validation->simulation; | 81 | int sim = SNUFFLEUPAGUS_G(config).config_upload_validation->simulation; |
| 82 | sp_log_msg("upload_valiation", sim?LOG_NOTICE:LOG_DROP, | 82 | sp_log_msg("upload_valiation", sim?SP_LOG_NOTICE:SP_LOG_DROP, |
| 83 | "The upload of %s on %s was rejected.", filename, uri?uri:"?"); | 83 | "The upload of %s on %s was rejected.", filename, uri?uri:"?"); |
| 84 | if (!SNUFFLEUPAGUS_G(config).config_upload_validation->simulation) { | 84 | if (!SNUFFLEUPAGUS_G(config).config_upload_validation->simulation) { |
| 85 | zend_bailout(); | 85 | zend_bailout(); |
diff --git a/src/sp_utils.c b/src/sp_utils.c index 087f431..56512df 100644 --- a/src/sp_utils.c +++ b/src/sp_utils.c | |||
| @@ -201,7 +201,7 @@ bool sp_match_value(const char* value, const char* to_match, const pcre* rx) { | |||
| 201 | } | 201 | } |
| 202 | } else if (rx) { | 202 | } else if (rx) { |
| 203 | int substrvec[30]; | 203 | int substrvec[30]; |
| 204 | int ret = pcre_exec(rx, NULL, value, strlen(value), 0, 0, substrvec, 30); | 204 | int ret = sp_pcre_exec(rx, NULL, value, strlen(value), 0, 0, substrvec, 30); |
| 205 | 205 | ||
| 206 | if (ret < 0) { | 206 | if (ret < 0) { |
| 207 | if (ret != PCRE_ERROR_NOMATCH) { | 207 | if (ret != PCRE_ERROR_NOMATCH) { |
| @@ -223,14 +223,14 @@ void sp_log_disable(const char* restrict path, const char* restrict arg_name, | |||
| 223 | const int sim = config_node->simulation; | 223 | const int sim = config_node->simulation; |
| 224 | if (arg_name) { | 224 | if (arg_name) { |
| 225 | if (alias) { | 225 | if (alias) { |
| 226 | sp_log_msg("disabled_function", sim?LOG_NOTICE:LOG_DROP, | 226 | sp_log_msg("disabled_function", sim?SP_LOG_NOTICE:SP_LOG_DROP, |
| 227 | "The call to the function '%s' in %s:%d has been disabled, " | 227 | "The call to the function '%s' in %s:%d has been disabled, " |
| 228 | "because its argument '%s' content (%s) matched the rule '%s'.", | 228 | "because its argument '%s' content (%s) matched the rule '%s'.", |
| 229 | path, zend_get_executed_filename(TSRMLS_C), | 229 | path, zend_get_executed_filename(TSRMLS_C), |
| 230 | zend_get_executed_lineno(TSRMLS_C), arg_name, arg_value?arg_value:"?", | 230 | zend_get_executed_lineno(TSRMLS_C), arg_name, arg_value?arg_value:"?", |
| 231 | alias); | 231 | alias); |
| 232 | } else { | 232 | } else { |
| 233 | sp_log_msg("disabled_function", sim?LOG_NOTICE:LOG_DROP, | 233 | sp_log_msg("disabled_function", sim?SP_LOG_NOTICE:SP_LOG_DROP, |
| 234 | "The call to the function '%s' in %s:%d has been disabled, " | 234 | "The call to the function '%s' in %s:%d has been disabled, " |
| 235 | "because its argument '%s' content (%s) matched a rule.", | 235 | "because its argument '%s' content (%s) matched a rule.", |
| 236 | path, zend_get_executed_filename(TSRMLS_C), | 236 | path, zend_get_executed_filename(TSRMLS_C), |
| @@ -239,13 +239,13 @@ void sp_log_disable(const char* restrict path, const char* restrict arg_name, | |||
| 239 | } | 239 | } |
| 240 | } else { | 240 | } else { |
| 241 | if (alias) { | 241 | if (alias) { |
| 242 | sp_log_msg("disabled_function", sim?LOG_NOTICE:LOG_DROP, | 242 | sp_log_msg("disabled_function", sim?SP_LOG_NOTICE:SP_LOG_DROP, |
| 243 | "The call to the function '%s' in %s:%d has been disabled, " | 243 | "The call to the function '%s' in %s:%d has been disabled, " |
| 244 | "because of the the rule '%s'.",path, | 244 | "because of the the rule '%s'.",path, |
| 245 | zend_get_executed_filename(TSRMLS_C), | 245 | zend_get_executed_filename(TSRMLS_C), |
| 246 | zend_get_executed_lineno(TSRMLS_C), alias); | 246 | zend_get_executed_lineno(TSRMLS_C), alias); |
| 247 | } else { | 247 | } else { |
| 248 | sp_log_msg("disabled_function", sim?LOG_NOTICE:LOG_DROP, | 248 | sp_log_msg("disabled_function", sim?SP_LOG_NOTICE:SP_LOG_DROP, |
| 249 | "The call to the function '%s' in %s:%d has been disabled.", | 249 | "The call to the function '%s' in %s:%d has been disabled.", |
| 250 | path, zend_get_executed_filename(TSRMLS_C), | 250 | path, zend_get_executed_filename(TSRMLS_C), |
| 251 | zend_get_executed_lineno(TSRMLS_C)); | 251 | zend_get_executed_lineno(TSRMLS_C)); |
| @@ -263,13 +263,13 @@ void sp_log_disable_ret(const char* restrict path, | |||
| 263 | const char* alias = config_node->alias; | 263 | const char* alias = config_node->alias; |
| 264 | const int sim = config_node->simulation; | 264 | const int sim = config_node->simulation; |
| 265 | if (alias) { | 265 | if (alias) { |
| 266 | sp_log_msg("disabled_function", sim?LOG_NOTICE:LOG_DROP, | 266 | sp_log_msg("disabled_function", sim?SP_LOG_NOTICE:SP_LOG_DROP, |
| 267 | "The execution has been aborted in %s:%d, " | 267 | "The execution has been aborted in %s:%d, " |
| 268 | "because the function '%s' returned '%s', which matched the rule '%s'.", | 268 | "because the function '%s' returned '%s', which matched the rule '%s'.", |
| 269 | zend_get_executed_filename(TSRMLS_C), | 269 | zend_get_executed_filename(TSRMLS_C), |
| 270 | zend_get_executed_lineno(TSRMLS_C), path, ret_value?ret_value:"?", alias); | 270 | zend_get_executed_lineno(TSRMLS_C), path, ret_value?ret_value:"?", alias); |
| 271 | } else { | 271 | } else { |
| 272 | sp_log_msg("disabled_function", sim?LOG_NOTICE:LOG_DROP, | 272 | sp_log_msg("disabled_function", sim?SP_LOG_NOTICE:SP_LOG_DROP, |
| 273 | "The execution has been aborted in %s:%d, " | 273 | "The execution has been aborted in %s:%d, " |
| 274 | "because the return value (%s) of the function '%s' matched a rule.", | 274 | "because the return value (%s) of the function '%s' matched a rule.", |
| 275 | zend_get_executed_filename(TSRMLS_C), | 275 | zend_get_executed_filename(TSRMLS_C), |
| @@ -349,7 +349,7 @@ zend_always_inline char* sp_getenv(char* var) { | |||
| 349 | 349 | ||
| 350 | zend_always_inline int is_regexp_matching(const pcre* regexp, const char* str) { | 350 | zend_always_inline int is_regexp_matching(const pcre* regexp, const char* str) { |
| 351 | int vec[30]; | 351 | int vec[30]; |
| 352 | int ret = pcre_exec(regexp, NULL, str, strlen(str), 0, 0, vec, sizeof(vec)); | 352 | int ret = sp_pcre_exec(regexp, NULL, str, strlen(str), 0, 0, vec, sizeof(vec)); |
| 353 | if (ret < 0) { | 353 | if (ret < 0) { |
| 354 | if (ret != PCRE_ERROR_NOMATCH) { | 354 | if (ret != PCRE_ERROR_NOMATCH) { |
| 355 | sp_log_err("regexp", "Something went wrong with a regexp."); | 355 | sp_log_err("regexp", "Something went wrong with a regexp."); |
| @@ -367,22 +367,14 @@ int hook_function(const char* original_name, HashTable* hook_table, | |||
| 367 | 367 | ||
| 368 | /* The `mb` module likes to hook functions, like strlen->mb_strlen, | 368 | /* The `mb` module likes to hook functions, like strlen->mb_strlen, |
| 369 | * so we have to hook both of them. */ | 369 | * so we have to hook both of them. */ |
| 370 | if (0 == strncmp(original_name, "mb_", 3)) { | 370 | |
| 371 | CG(compiler_options) |= ZEND_COMPILE_NO_BUILTIN_STRLEN; | 371 | if ((func = zend_hash_str_find_ptr(ht, |
| 372 | if (zend_hash_str_find(ht, | 372 | VAR_AND_LEN(original_name)))) { |
| 373 | VAR_AND_LEN(original_name + 3))) { | 373 | if (func->handler == new_function) { |
| 374 | hook_function(original_name + 3, hook_table, new_function, hook_execution_table); | 374 | return SUCCESS; |
| 375 | } | ||
| 376 | } else { // TODO this can be moved somewhere else to gain some marginal perfs | ||
| 377 | CG(compiler_options) |= ZEND_COMPILE_NO_BUILTIN_STRLEN; | ||
| 378 | char* mb_name = pecalloc(strlen(original_name) + 3 + 1, 1, 0); | ||
| 379 | memcpy(mb_name, "mb_", 3); | ||
| 380 | memcpy(mb_name + 3, VAR_AND_LEN(original_name)); | ||
| 381 | if (zend_hash_str_find(CG(function_table), VAR_AND_LEN(mb_name))) { | ||
| 382 | hook_function(mb_name, hook_table, new_function, hook_execution_table); | ||
| 383 | } | 375 | } |
| 384 | } | 376 | } |
| 385 | 377 | ||
| 386 | if ((func = zend_hash_str_find_ptr(CG(function_table), | 378 | if ((func = zend_hash_str_find_ptr(CG(function_table), |
| 387 | VAR_AND_LEN(original_name)))) { | 379 | VAR_AND_LEN(original_name)))) { |
| 388 | if (func->handler == new_function) { | 380 | if (func->handler == new_function) { |
| @@ -397,6 +389,23 @@ int hook_function(const char* original_name, HashTable* hook_table, | |||
| 397 | func->handler = new_function; | 389 | func->handler = new_function; |
| 398 | } | 390 | } |
| 399 | } | 391 | } |
| 392 | |||
| 393 | if (0 == strncmp(original_name, "mb_", 3)) { | ||
| 394 | CG(compiler_options) |= ZEND_COMPILE_NO_BUILTIN_STRLEN; | ||
| 395 | if (zend_hash_str_find(ht, | ||
| 396 | VAR_AND_LEN(original_name + 3))) { | ||
| 397 | hook_function(original_name + 3, hook_table, new_function, hook_execution_table); | ||
| 398 | } | ||
| 399 | } else { // TODO this can be moved somewhere else to gain some marginal perfs | ||
| 400 | CG(compiler_options) |= ZEND_COMPILE_NO_BUILTIN_STRLEN; | ||
| 401 | char* mb_name = pecalloc(strlen(original_name) + 3 + 1, 1, 0); | ||
| 402 | memcpy(mb_name, "mb_", 3); | ||
| 403 | memcpy(mb_name + 3, VAR_AND_LEN(original_name)); | ||
| 404 | if (zend_hash_str_find(CG(function_table), VAR_AND_LEN(mb_name))) { | ||
| 405 | hook_function(mb_name, hook_table, new_function, hook_execution_table); | ||
| 406 | } | ||
| 407 | } | ||
| 408 | |||
| 400 | return SUCCESS; | 409 | return SUCCESS; |
| 401 | } | 410 | } |
| 402 | 411 | ||
| @@ -409,7 +418,7 @@ int hook_regexp(const pcre* regexp, HashTable* hook_table, | |||
| 409 | ZEND_HASH_FOREACH_STR_KEY(ht, key) { | 418 | ZEND_HASH_FOREACH_STR_KEY(ht, key) { |
| 410 | if (key) { | 419 | if (key) { |
| 411 | int vec[30]; | 420 | int vec[30]; |
| 412 | int ret = pcre_exec(regexp, NULL, key->val, key->len, 0, 0, vec, 30); | 421 | int ret = sp_pcre_exec(regexp, NULL, key->val, key->len, 0, 0, vec, 30); |
| 413 | if (ret < 0) { /* Error or no match*/ | 422 | if (ret < 0) { /* Error or no match*/ |
| 414 | if (PCRE_ERROR_NOMATCH != ret) { | 423 | if (PCRE_ERROR_NOMATCH != ret) { |
| 415 | sp_log_err("pcre", "Runtime error with pcre, error code: %d", ret); | 424 | sp_log_err("pcre", "Runtime error with pcre, error code: %d", ret); |
diff --git a/src/sp_utils.h b/src/sp_utils.h index 37dd2c0..3b14205 100644 --- a/src/sp_utils.h +++ b/src/sp_utils.h | |||
| @@ -35,14 +35,14 @@ | |||
| 35 | #define HOOK_FUNCTION_BY_REGEXP(regexp, hook_table, new_function, execution) \ | 35 | #define HOOK_FUNCTION_BY_REGEXP(regexp, hook_table, new_function, execution) \ |
| 36 | hook_regexp(regexp, SNUFFLEUPAGUS_G(hook_table), new_function, execution) | 36 | hook_regexp(regexp, SNUFFLEUPAGUS_G(hook_table), new_function, execution) |
| 37 | 37 | ||
| 38 | #define LOG_NOTICE "notice" | 38 | #define SP_LOG_NOTICE "notice" |
| 39 | #define LOG_DROP "drop" | 39 | #define SP_LOG_DROP "drop" |
| 40 | #define LOG_DEBUG "debug" | 40 | #define SP_LOG_DEBUG "debug" |
| 41 | #define LOG_ERROR "error" | 41 | #define SP_LOG_ERROR "error" |
| 42 | 42 | ||
| 43 | #define sp_log_err(feature, ...) sp_log_msg(feature, LOG_ERROR, __VA_ARGS__) | 43 | #define sp_log_err(feature, ...) sp_log_msg(feature, SP_LOG_ERROR, __VA_ARGS__) |
| 44 | #ifdef SP_DEBUG | 44 | #ifdef SP_DEBUG |
| 45 | #define sp_log_debug(...) sp_log_msg("DEBUG", LOG_DEBUG, __VA_ARGS__) | 45 | #define sp_log_debug(...) sp_log_msg("DEBUG", SP_LOG_DEBUG, __VA_ARGS__) |
| 46 | #else | 46 | #else |
| 47 | #define sp_log_debug(...) | 47 | #define sp_log_debug(...) |
| 48 | #endif | 48 | #endif |
diff --git a/src/tests/config/dump_request.ini b/src/tests/config/dump_request.ini index 8c595f9..00ee7b8 100644 --- a/src/tests/config/dump_request.ini +++ b/src/tests/config/dump_request.ini | |||
| @@ -1 +1 @@ | |||
| sp.disable_functions.function("system").drop().dump("./dump_results/"); | sp.disable_functions.function("system").drop().dump("/tmp/dump_results/"); | ||
diff --git a/src/tests/disable_xxe_dom.phpt b/src/tests/disable_xxe_dom.phpt index 47f3db3..864b2a1 100644 --- a/src/tests/disable_xxe_dom.phpt +++ b/src/tests/disable_xxe_dom.phpt | |||
| @@ -6,7 +6,6 @@ Disable XXE | |||
| 6 | if (!extension_loaded("dom")) die "skip"; | 6 | if (!extension_loaded("dom")) die "skip"; |
| 7 | ?> | 7 | ?> |
| 8 | --INI-- | 8 | --INI-- |
| 9 | extension=`php-config --extension-dir`/dom.so | ||
| 10 | sp.configuration_file={PWD}/config/disable_xxe.ini | 9 | sp.configuration_file={PWD}/config/disable_xxe.ini |
| 11 | --FILE-- | 10 | --FILE-- |
| 12 | <?php | 11 | <?php |
diff --git a/src/tests/disable_xxe_dom_disabled.phpt b/src/tests/disable_xxe_dom_disabled.phpt index b89b595..a7ccd60 100644 --- a/src/tests/disable_xxe_dom_disabled.phpt +++ b/src/tests/disable_xxe_dom_disabled.phpt | |||
| @@ -6,7 +6,6 @@ Disable XXE | |||
| 6 | if (!extension_loaded("dom")) die "skip"; | 6 | if (!extension_loaded("dom")) die "skip"; |
| 7 | ?> | 7 | ?> |
| 8 | --INI-- | 8 | --INI-- |
| 9 | extension=`php-config --extension-dir`/dom.so | ||
| 10 | sp.configuration_file={PWD}/config/disable_xxe_disable.ini | 9 | sp.configuration_file={PWD}/config/disable_xxe_disable.ini |
| 11 | --FILE-- | 10 | --FILE-- |
| 12 | <?php | 11 | <?php |
diff --git a/src/tests/disable_xxe_simplexml.phpt b/src/tests/disable_xxe_simplexml.phpt index 54404a3..7825167 100644 --- a/src/tests/disable_xxe_simplexml.phpt +++ b/src/tests/disable_xxe_simplexml.phpt | |||
| @@ -6,7 +6,6 @@ Disable XXE | |||
| 6 | if (!extension_loaded("simplexml")) die "skip"; | 6 | if (!extension_loaded("simplexml")) die "skip"; |
| 7 | ?> | 7 | ?> |
| 8 | --INI-- | 8 | --INI-- |
| 9 | extension=`php-config --extension-dir`/simplexml.so | ||
| 10 | sp.configuration_file={PWD}/config/disable_xxe.ini | 9 | sp.configuration_file={PWD}/config/disable_xxe.ini |
| 11 | --FILE-- | 10 | --FILE-- |
| 12 | <?php | 11 | <?php |
diff --git a/src/tests/disable_xxe_simplexml_oop.phpt b/src/tests/disable_xxe_simplexml_oop.phpt index 62762eb..65e4574 100644 --- a/src/tests/disable_xxe_simplexml_oop.phpt +++ b/src/tests/disable_xxe_simplexml_oop.phpt | |||
| @@ -6,7 +6,6 @@ Disable XXE | |||
| 6 | if (!extension_loaded("simplexml")) die "skip"; | 6 | if (!extension_loaded("simplexml")) die "skip"; |
| 7 | ?> | 7 | ?> |
| 8 | --INI-- | 8 | --INI-- |
| 9 | extension=`php-config --extension-dir`/simplexml.so | ||
| 10 | sp.configuration_file={PWD}/config/disable_xxe.ini | 9 | sp.configuration_file={PWD}/config/disable_xxe.ini |
| 11 | --FILE-- | 10 | --FILE-- |
| 12 | <?php | 11 | <?php |
diff --git a/src/tests/disable_xxe_xml_parse.phpt b/src/tests/disable_xxe_xml_parse.phpt index 944bc38..2bbf0be 100644 --- a/src/tests/disable_xxe_xml_parse.phpt +++ b/src/tests/disable_xxe_xml_parse.phpt | |||
| @@ -6,7 +6,6 @@ Disable XXE | |||
| 6 | if (!extension_loaded("xml")) die "skip"; | 6 | if (!extension_loaded("xml")) die "skip"; |
| 7 | ?> | 7 | ?> |
| 8 | --INI-- | 8 | --INI-- |
| 9 | extension=`php-config --extension-dir`/xml.so | ||
| 10 | sp.configuration_file={PWD}/config/disable_xxe.ini | 9 | sp.configuration_file={PWD}/config/disable_xxe.ini |
| 11 | --FILE-- | 10 | --FILE-- |
| 12 | <?php | 11 | <?php |
diff --git a/src/tests/disabled_functions_ret3.phpt b/src/tests/disabled_functions_ret3.phpt index d5f96d0..a705333 100644 --- a/src/tests/disabled_functions_ret3.phpt +++ b/src/tests/disabled_functions_ret3.phpt | |||
| @@ -4,6 +4,7 @@ Disable functions check on `ret`. | |||
| 4 | <?php if (!extension_loaded("snuffleupagus")) die "skip"; ?> | 4 | <?php if (!extension_loaded("snuffleupagus")) die "skip"; ?> |
| 5 | --INI-- | 5 | --INI-- |
| 6 | sp.configuration_file={PWD}/config/disabled_functions_ret.ini | 6 | sp.configuration_file={PWD}/config/disabled_functions_ret.ini |
| 7 | memory_limit=-1 | ||
| 7 | --FILE-- | 8 | --FILE-- |
| 8 | <?php | 9 | <?php |
| 9 | class Bob { | 10 | class Bob { |
diff --git a/src/tests/disabled_functions_ret_type.phpt b/src/tests/disabled_functions_ret_type.phpt index f1c6e4c..0e01ee2 100644 --- a/src/tests/disabled_functions_ret_type.phpt +++ b/src/tests/disabled_functions_ret_type.phpt | |||
| @@ -1,16 +1,16 @@ | |||
| 1 | --TEST-- | 1 | --TEST-- |
| 2 | Disable functions check on `ret` by type matching on boolean | 2 | Disable functions check on `ret` by type matching (false) |
| 3 | --SKIPIF-- | 3 | --SKIPIF-- |
| 4 | <?php if (!extension_loaded("snuffleupagus")) die "skip"; ?> | 4 | <?php if (!extension_loaded("snuffleupagus")) die "skip"; ?> |
| 5 | --INI-- | 5 | --INI-- |
| 6 | sp.configuration_file={PWD}/config/disabled_functions_ret_type.ini | 6 | sp.configuration_file={PWD}/config/disabled_functions_ret_type.ini |
| 7 | --FILE-- | 7 | --FILE-- |
| 8 | <?php | 8 | <?php |
| 9 | echo strpos("pouet", "p") . "\n"; | 9 | var_dump(strpos("pouet", "p")) . "\n"; |
| 10 | echo "1337\n"; | 10 | echo "1337\n"; |
| 11 | echo strpos("pouet", "123"); | 11 | echo strpos("pouet", "123"); |
| 12 | ?> | 12 | ?> |
| 13 | --EXPECTF-- | 13 | --EXPECTF-- |
| 14 | 0 | 14 | int(0) |
| 15 | 1337 | 15 | 1337 |
| 16 | [snuffleupagus][0.0.0.0][disabled_function][drop] The execution has been aborted in %a/tests/disabled_functions_ret_type.php:%d, because the function 'strpos' returned 'FALSE', which matched the rule 'Return value is FALSE'. | 16 | [snuffleupagus][0.0.0.0][disabled_function][drop] The execution has been aborted in %a/disabled_functions_ret_type.php:%d, because the function 'strpos' returned 'FALSE', which matched the rule 'Return value is FALSE'. |
diff --git a/src/tests/disabled_option.phpt b/src/tests/disabled_option.phpt index 8bc7e39..70e1382 100644 --- a/src/tests/disabled_option.phpt +++ b/src/tests/disabled_option.phpt | |||
| @@ -7,10 +7,16 @@ sp.configuration_file={PWD}/config/config_rand_harden_disabled.ini | |||
| 7 | --FILE-- | 7 | --FILE-- |
| 8 | <?php | 8 | <?php |
| 9 | srand(0); | 9 | srand(0); |
| 10 | echo rand(0,100)."\n"; | 10 | $a = rand(0,100)."\n"; |
| 11 | srand(0); | 11 | srand(0); |
| 12 | echo rand(0,100)."\n"; | 12 | $b = rand(0,100)."\n"; |
| 13 | srand(0); | ||
| 14 | $c = rand(0,100)."\n"; | ||
| 15 | if ($a == $b && $a == $c) { | ||
| 16 | echo "win"; | ||
| 17 | } else { | ||
| 18 | echo "lose"; | ||
| 19 | } | ||
| 13 | ?> | 20 | ?> |
| 14 | --EXPECT-- | 21 | --EXPECT-- |
| 15 | 84 | 22 | win |
| 16 | 84 | ||
diff --git a/src/tests/dump_request.phpt b/src/tests/dump_request.phpt index a752def..5fa43c4 100644 --- a/src/tests/dump_request.phpt +++ b/src/tests/dump_request.phpt | |||
| @@ -6,10 +6,10 @@ if (!extension_loaded("snuffleupagus")) { | |||
| 6 | print "skip"; | 6 | print "skip"; |
| 7 | } | 7 | } |
| 8 | 8 | ||
| 9 | foreach (glob("./tests/dump_results/*.dump") as $dump) { | 9 | foreach (glob("/tmp/dump_results/*.dump") as $dump) { |
| 10 | unlink($dump); | 10 | @unlink($dump); |
| 11 | } | 11 | } |
| 12 | rmdir("./tests/dump_results/"); | 12 | @rmdir("/tmp/dump_results/"); |
| 13 | ?> | 13 | ?> |
| 14 | --POST-- | 14 | --POST-- |
| 15 | post_a=data_post_a&post_b=data_post_b | 15 | post_a=data_post_a&post_b=data_post_b |
| @@ -21,10 +21,10 @@ cookie_a=data_cookie_a&cookie_b=data_cookie_b | |||
| 21 | sp.configuration_file={PWD}/config/dump_request.ini | 21 | sp.configuration_file={PWD}/config/dump_request.ini |
| 22 | --FILE-- | 22 | --FILE-- |
| 23 | <?php | 23 | <?php |
| 24 | mkdir("./dump_results/"); | 24 | mkdir("/tmp/dump_results/"); |
| 25 | echo "1\n"; | 25 | echo "1\n"; |
| 26 | echo system("echo 1337;"); | 26 | echo system("echo 1337;"); |
| 27 | $filename = glob('./dump_results/*.dump')[0]; | 27 | $filename = glob('/tmp/dump_results/*.dump')[0]; |
| 28 | $res = file($filename); | 28 | $res = file($filename); |
| 29 | if ($res[1] != "GET:get_a=data_get_a&get_b=data_get_b\n") { | 29 | if ($res[1] != "GET:get_a=data_get_a&get_b=data_get_b\n") { |
| 30 | echo "1\n"; | 30 | echo "1\n"; |
diff --git a/src/tests/dump_request_too_big.phpt b/src/tests/dump_request_too_big.phpt index 81eb71c..c99203c 100644 --- a/src/tests/dump_request_too_big.phpt +++ b/src/tests/dump_request_too_big.phpt | |||
| @@ -6,10 +6,10 @@ if (!extension_loaded("snuffleupagus")) { | |||
| 6 | print "skip"; | 6 | print "skip"; |
| 7 | } | 7 | } |
| 8 | 8 | ||
| 9 | foreach (glob("./tests/dump_results/*.dump") as $dump) { | 9 | foreach (glob("/tmp/dump_results/*.dump") as $dump) { |
| 10 | unlink($dump); | 10 | @unlink($dump); |
| 11 | } | 11 | } |
| 12 | rmdir("./tests/dump_results/"); | 12 | @rmdir("/tmp/tests/dump_results/"); |
| 13 | ?> | 13 | ?> |
| 14 | --POST-- | 14 | --POST-- |
| 15 | post_a=data_post_a&post_b=data_post_b&post_c=c | 15 | post_a=data_post_a&post_b=data_post_b&post_c=c |
| @@ -27,7 +27,7 @@ sp.configuration_file={PWD}/config/dump_request.ini | |||
| 27 | <?php | 27 | <?php |
| 28 | echo "1\n"; | 28 | echo "1\n"; |
| 29 | echo system("echo 1337;"); | 29 | echo system("echo 1337;"); |
| 30 | $filename = glob('./dump_results/*.dump')[0]; | 30 | $filename = glob('/tmp/dump_results/*.dump')[0]; |
| 31 | $res = file($filename); | 31 | $res = file($filename); |
| 32 | if ($res[1] != "GET:get_a=data_get_a&get_b=data_get_b&get_c=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n") { | 32 | if ($res[1] != "GET:get_a=data_get_a&get_b=data_get_b&get_c=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n") { |
| 33 | echo "1\n"; | 33 | echo "1\n"; |
