Validate callback signatures for curl_setopt callback options like CURLOPT_PREREQFUNCTION#6050
Open
phpstan-bot wants to merge 1 commit into
Open
Conversation
…RLOPT_PREREQFUNCTION - Map curl callback options (CURLOPT_WRITEFUNCTION, CURLOPT_HEADERFUNCTION, CURLOPT_READFUNCTION, CURLOPT_PROGRESSFUNCTION, CURLOPT_XFERINFOFUNCTION and CURLOPT_PREREQFUNCTION) to precise `(callable(...): ...)|null` value types in ParametersAcceptorSelector::getCurlOptValueType(). - The callback's first parameter is typed as `CurlHandle` (PHP 8+) or `resource`, followed by the option-specific parameters, and the expected return type (`int` for the write/header/progress/xferinfo/prereq callbacks, `string` for the read callback). Passing a callback with a wrong return type (e.g. returning `bool`) now triggers an argument.type error. - `null` is accepted so resetting a callback keeps working. - The same value types flow through the curl_setopt_array path, so callbacks supplied via the options array are validated identically.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
curl_setopt($ch, CURLOPT_PREREQFUNCTION, $cb)(and the other curl callbackoptions) accepted any value: passing a callback with the wrong return type was
not reported. PHPStan now knows the exact signature each curl callback option
expects and reports a mismatch such as a
bool-returning callback whereintis required.
Changes
src/Reflection/ParametersAcceptorSelector.php:getCurlOptValueType()nowmaps the curl callback options to a
(callable(...): ...)|nullvalue type:CURLOPT_WRITEFUNCTION—callable(CurlHandle, string): intCURLOPT_HEADERFUNCTION—callable(CurlHandle, string): intCURLOPT_READFUNCTION—callable(CurlHandle, resource, int): stringCURLOPT_PROGRESSFUNCTION—callable(CurlHandle, int, int, int, int): intCURLOPT_XFERINFOFUNCTION—callable(CurlHandle, int, int, int, int): intCURLOPT_PREREQFUNCTION—callable(CurlHandle, string, string, int, int): intThe handle parameter is typed
CurlHandleon PHP 8+ andresourceotherwise,reusing the existing
PhpVersion::supportsCurlShareHandle()gate.nullispart of the union so resetting a callback is still allowed.
curl_setopt_callback.phpdata file plustestCurlSetOptCallbackin
CallToFunctionParametersRuleTest, a PHP 8.4-gatedcurl_setopt_prereq.php/
testCurlSetOptPrereqCallbackforCURLOPT_PREREQFUNCTION, and a callbackcase added to the
curl-setopt-array.phpdata /testCurlSetOptArrayto coverthe array form.
Root cause
getCurlOptValueType()had entries for bool/int/string/array/resource optionsbut none for the callback options, so it returned
nulland no override wasapplied — the third
curl_setoptargument (and the option array values) stayedmixedand were never checked. Adding callable value types for the whole familyof curl callback options lets the existing argument-type check verify both the
parameters and the return type of the passed callback.
Test
testCurlSetOptCallbackasserts errors for write/header/read/progress/xferinfocallbacks with the wrong return type, and no error for correctly-typed
callbacks or
null.testCurlSetOptPrereqCallback(PHP 8.4+) covers the reportedCURLOPT_PREREQFUNCTIONcase.testCurlSetOptArraynow also covers a callback option passed through thecurl_setopt_arrayoptions array.Fixes phpstan/phpstan#14956