mirror of
https://we.phorge.it/source/arcanist.git
synced 2024-11-21 22:32:41 +01:00
Fix ArcanistFormattedStringXHPASTLinterRule for PHP 8
Summary: PHP 8's sprintf raises a ValueError when encountering unknown format specifiers (previously it would eat the argument and print nothing), so linting format strings like %Ls dies with an uncaught ValueError. Fix this by using a custom callback during linting to turn all format specifiers into %s and replace the dummy null argument with the original format specifier, ensuring we always end up providing valid input to the sprintf at the end. This has the nice property that the output of the call to xsprintf is the original format string, though any transformation into valid input would do. Test Plan: Ran arc lint Reviewers: epriestley, #blessed_reviewers Reviewed By: epriestley, #blessed_reviewers Subscribers: Korvin Maniphest Tasks: T13588 Differential Revision: https://secure.phabricator.com/D21500
This commit is contained in:
parent
0adef03fdf
commit
90ac9a2ff2
1 changed files with 23 additions and 1 deletions
|
@ -94,7 +94,10 @@ final class ArcanistFormattedStringXHPASTLinterRule
|
|||
$argv = array($format->evalStatic()) + array_fill(0, $argc, null);
|
||||
|
||||
try {
|
||||
xsprintf(null, null, $argv);
|
||||
xsprintf(
|
||||
'ArcanistFormattedStringXHPASTLinterRule::processXsprintfCallback',
|
||||
null,
|
||||
$argv);
|
||||
} catch (BadFunctionCallException $ex) {
|
||||
$this->raiseLintAtNode(
|
||||
$call,
|
||||
|
@ -105,4 +108,23 @@ final class ArcanistFormattedStringXHPASTLinterRule
|
|||
}
|
||||
}
|
||||
|
||||
public static function processXsprintfCallback(
|
||||
$userdata,
|
||||
&$pattern,
|
||||
&$pos,
|
||||
&$value,
|
||||
&$length) {
|
||||
|
||||
if ($value !== null) {
|
||||
throw new Exception('Expected dummy value to be null');
|
||||
}
|
||||
|
||||
// Turn format "%$pattern" with argument null into format "%s" with
|
||||
// argument "%$pattern". This ensures we always provide valid input for
|
||||
// sprintf to avoid getting a ValueError when using custom format
|
||||
// specifiers.
|
||||
$value = '%'.$pattern[$pos];
|
||||
$pattern[$pos] = 's';
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue