diff --git a/ext/curl/interface.c b/ext/curl/interface.c index 1dff14b7c8c2..09c7009068b6 100644 --- a/ext/curl/interface.c +++ b/ext/curl/interface.c @@ -2030,42 +2030,42 @@ static zend_result _php_curl_setopt(php_curl *ch, zend_long option, zval *zvalue HashTable *ph; zend_string *val, *tmp_val; struct curl_slist *slist = NULL; + const char *name = NULL; - if (Z_TYPE_P(zvalue) != IS_ARRAY) { - const char *name = NULL; - switch (option) { - case CURLOPT_HTTPHEADER: - name = "CURLOPT_HTTPHEADER"; - break; - case CURLOPT_QUOTE: - name = "CURLOPT_QUOTE"; - break; - case CURLOPT_HTTP200ALIASES: - name = "CURLOPT_HTTP200ALIASES"; - break; - case CURLOPT_POSTQUOTE: - name = "CURLOPT_POSTQUOTE"; - break; - case CURLOPT_PREQUOTE: - name = "CURLOPT_PREQUOTE"; - break; - case CURLOPT_TELNETOPTIONS: - name = "CURLOPT_TELNETOPTIONS"; - break; - case CURLOPT_MAIL_RCPT: - name = "CURLOPT_MAIL_RCPT"; - break; - case CURLOPT_RESOLVE: - name = "CURLOPT_RESOLVE"; - break; - case CURLOPT_PROXYHEADER: - name = "CURLOPT_PROXYHEADER"; - break; - case CURLOPT_CONNECT_TO: - name = "CURLOPT_CONNECT_TO"; - break; - } + switch (option) { + case CURLOPT_HTTPHEADER: + name = "CURLOPT_HTTPHEADER"; + break; + case CURLOPT_QUOTE: + name = "CURLOPT_QUOTE"; + break; + case CURLOPT_HTTP200ALIASES: + name = "CURLOPT_HTTP200ALIASES"; + break; + case CURLOPT_POSTQUOTE: + name = "CURLOPT_POSTQUOTE"; + break; + case CURLOPT_PREQUOTE: + name = "CURLOPT_PREQUOTE"; + break; + case CURLOPT_TELNETOPTIONS: + name = "CURLOPT_TELNETOPTIONS"; + break; + case CURLOPT_MAIL_RCPT: + name = "CURLOPT_MAIL_RCPT"; + break; + case CURLOPT_RESOLVE: + name = "CURLOPT_RESOLVE"; + break; + case CURLOPT_PROXYHEADER: + name = "CURLOPT_PROXYHEADER"; + break; + case CURLOPT_CONNECT_TO: + name = "CURLOPT_CONNECT_TO"; + break; + } + if (Z_TYPE_P(zvalue) != IS_ARRAY) { zend_type_error("%s(): The %s option must have an array value", get_active_function_name(), name); return FAILURE; } @@ -2074,6 +2074,14 @@ static zend_result _php_curl_setopt(php_curl *ch, zend_long option, zval *zvalue ZEND_HASH_FOREACH_VAL(ph, current) { ZVAL_DEREF(current); val = zval_get_tmp_string(current, &tmp_val); + + if (zend_str_has_nul_byte(val)) { + curl_slist_free_all(slist); + zend_tmp_string_release(tmp_val); + zend_value_error("%s(): cURL option %s must not contain any null bytes", get_active_function_name(), name); + return FAILURE; + } + struct curl_slist *new_slist = curl_slist_append(slist, ZSTR_VAL(val)); zend_tmp_string_release(tmp_val); if (!new_slist) { diff --git a/ext/curl/tests/curl_setopt_error_nul_byte.phpt b/ext/curl/tests/curl_setopt_error_nul_byte.phpt new file mode 100644 index 000000000000..23be973b82c2 --- /dev/null +++ b/ext/curl/tests/curl_setopt_error_nul_byte.phpt @@ -0,0 +1,52 @@ +--TEST-- +curl_setopt() throws ValueError for NUL bytes in lists +--EXTENSIONS-- +curl +--FILE-- +getMessage() . "\n\n"; + } +} + +$ch = null; +?> +--EXPECT-- +CURLOPT_HTTP200ALIASES: curl_setopt(): cURL option CURLOPT_HTTP200ALIASES must not contain any null bytes + +CURLOPT_HTTPHEADER: curl_setopt(): cURL option CURLOPT_HTTPHEADER must not contain any null bytes + +CURLOPT_POSTQUOTE: curl_setopt(): cURL option CURLOPT_POSTQUOTE must not contain any null bytes + +CURLOPT_PREQUOTE: curl_setopt(): cURL option CURLOPT_PREQUOTE must not contain any null bytes + +CURLOPT_QUOTE: curl_setopt(): cURL option CURLOPT_QUOTE must not contain any null bytes + +CURLOPT_TELNETOPTIONS: curl_setopt(): cURL option CURLOPT_TELNETOPTIONS must not contain any null bytes + +CURLOPT_MAIL_RCPT: curl_setopt(): cURL option CURLOPT_MAIL_RCPT must not contain any null bytes + +CURLOPT_RESOLVE: curl_setopt(): cURL option CURLOPT_RESOLVE must not contain any null bytes + +CURLOPT_PROXYHEADER: curl_setopt(): cURL option CURLOPT_PROXYHEADER must not contain any null bytes + +CURLOPT_CONNECT_TO: curl_setopt(): cURL option CURLOPT_CONNECT_TO must not contain any null bytes