Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ PHP NEWS
- Curl:
. curl_multi_exec() now throws a TypeError when still_running is not an int.
(arshidkv12)
. curl_write(): Check whether the PHP_CURL_USER callback returns an integer

- FPM:
. Use recommended TYPE, HELP order for OpenMetrics metadata.
Expand Down
2 changes: 2 additions & 0 deletions UPGRADING
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ PHP 8.7 UPGRADE NOTES

- Curl:
. curl_multi_exec() now throws a TypeError when still_running is not an int.
. The CURLOPT_WRITEFUNCTION callback should return an integer. Returning other
types may trigger implicit conversion deprecations or conversion failures.

- PDO:
. PDOStatement::bindColumn() now throws a ValueError when the column name is
Expand Down
7 changes: 5 additions & 2 deletions ext/curl/interface.c
Original file line number Diff line number Diff line change
Expand Up @@ -606,7 +606,6 @@ static size_t curl_write(char *data, size_t size, size_t nmemb, void *ctx)
php_curl_call_callback(ch, &write_handler->fcc, &retval, /* argc */ 2, argv);
if (!Z_ISUNDEF(retval)) {
_php_curl_verify_handlers(ch, /* reporterror */ true);
/* TODO Check callback returns an int or something castable to int */
length = php_curl_get_long(&retval);
} else {
length = -1;
Expand Down Expand Up @@ -1339,8 +1338,12 @@ zend_long php_curl_get_long(zval *zv)
if (EXPECTED(Z_TYPE_P(zv) == IS_LONG)) {
return Z_LVAL_P(zv);
} else {
zend_long ret = zval_get_long(zv);
bool failed;
zend_long ret = zval_try_get_long(zv, &failed);
zval_ptr_dtor(zv);
if(failed) {
return -1;
}
return ret;
}
}
Expand Down
92 changes: 92 additions & 0 deletions ext/curl/tests/curl_write_callback_return.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
--TEST--
curl_write(): edge cases for write callback return values
--EXTENSIONS--
curl
--FILE--
<?php
include 'server.inc';

$host = curl_cli_server_start('echo "Hello World!";');

$values = [
'valid length' => 'valid',
'null' => null,
'false' => false,
'true' => true,
'zero' => 0,
'one' => 1,
'negative one' => -1,
'PHP_INT_MAX' => PHP_INT_MAX,
'PHP_INT_MIN' => PHP_INT_MIN,
'float' => 1.5,
'negative float' => -1.5,
'numeric string' => '25',
'empty string' => '',
'non-numeric string' => 'abc',
'large numeric string' => '999999999999999999999999999999999999',
'empty array' => [],
'array' => [1],
'object' => new stdClass(),
];

foreach ($values as $label => $value) {
echo "-- $label --\n";

$ch = curl_init($host);
curl_setopt($ch, CURLOPT_WRITEFUNCTION,
static function ($ch, $data) use ($value) {
return $value === 'valid' ? strlen($data) : $value;
}
);

try {
var_dump(curl_exec($ch));
} catch (Throwable $e) {
echo get_class($e), "\n";
}

}
?>
--EXPECTF--
-- valid length --
bool(true)
-- null --
bool(false)
-- false --
bool(false)
-- true --
bool(false)
-- zero --
bool(false)
-- one --
bool(false)
-- negative one --
bool(false)
-- PHP_INT_MAX --
bool(false)
-- PHP_INT_MIN --
bool(false)
-- float --

Deprecated: Implicit conversion from float 1.5 to int loses precision in %s on line 38
bool(false)
-- negative float --

Deprecated: Implicit conversion from float -1.5 to int loses precision in %s on line 38
bool(false)
-- numeric string --
bool(true)
-- empty string --
bool(false)
-- non-numeric string --
bool(false)
-- large numeric string --

Deprecated: Implicit conversion from float-string "999999999999999999999999999999999999" to int loses precision in %s on line 38
bool(false)
-- empty array --
bool(false)
-- array --
bool(false)
-- object --
bool(false)
Loading