diff --git a/ext/curl/interface.c b/ext/curl/interface.c index c0286069776e..c3001696483a 100644 --- a/ext/curl/interface.c +++ b/ext/curl/interface.c @@ -820,6 +820,17 @@ static size_t curl_read(char *data, size_t size, size_t nmemb, void *ctx) memcpy(data, Z_STRVAL(retval), length); } else if (Z_TYPE(retval) == IS_LONG) { length = Z_LVAL_P(&retval); + + switch (length) { + // Acceptable long values: + case 0: + case CURL_READFUNC_ABORT: + case CURL_READFUNC_PAUSE: + break; + default: + zend_value_error("The CURLOPT_READFUNCTION callback must return a string or CURL_READFUNC_ABORT or CURL_READFUNC_PAUSE"); + length = CURL_READFUNC_ABORT; + } } // TODO Do type error if invalid type? zval_ptr_dtor(&retval); diff --git a/ext/curl/tests/curl_read_function_error_on_int.phpt b/ext/curl/tests/curl_read_function_error_on_int.phpt new file mode 100644 index 000000000000..30ba97737727 --- /dev/null +++ b/ext/curl/tests/curl_read_function_error_on_int.phpt @@ -0,0 +1,30 @@ +--TEST-- +error when CURLOPT_READFUNCTION returns an integer +--EXTENSIONS-- +curl +--FILE-- + 'f']); +curl_setopt($ch, CURLOPT_TIMEOUT, 2); +curl_setopt($ch, CURLOPT_READFUNCTION, "custom_readfunction" ); + +try { + curl_exec($ch); +} catch (ValueError $e) { + echo $e->getMessage() . "\n"; +} +var_dump(curl_error($ch)); +?> +--EXPECT-- +The CURLOPT_READFUNCTION callback must return a string or CURL_READFUNC_ABORT or CURL_READFUNC_PAUSE +string(29) "operation aborted by callback"