From e5ce70a3c1562091149c2506ebc9f4ddcf94113e Mon Sep 17 00:00:00 2001 From: jrfnl Date: Fri, 29 Mar 2024 02:50:11 +0100 Subject: [PATCH] PEAR/Functions/FunctionDeclaration: add extra defensive coding When the sniff is run during live coding, the sniff could encounter a situation where a function declaration does not have a scope opener, not a function body. In that case, the "SpaceBeforeSemicolon" check would try to find a semi-colon, presuming the function is an abstract method or interface method, but would not find one, which would result in the `if ($tokens[($end - 1)]['content'] === $phpcsFile->eolChar)` condition throwing a _"Undefined array key -1"_ notice. Fixed now. Includes test safeguarding the fix. Note: this fix will, by extension, fix this same error for the `PSR2.Methods.FunctionCallSignature` sniff and the `Squiz.Functions.MultiLineFunctionDeclaration` sniff. :point_right: this commit will be easier to review while ignoring whitespace changes. --- .../Functions/FunctionDeclarationSniff.php | 30 ++++++++++--------- .../FunctionDeclarationUnitTest.2.inc | 7 +++++ 2 files changed, 23 insertions(+), 14 deletions(-) create mode 100644 src/Standards/PEAR/Tests/Functions/FunctionDeclarationUnitTest.2.inc diff --git a/src/Standards/PEAR/Sniffs/Functions/FunctionDeclarationSniff.php b/src/Standards/PEAR/Sniffs/Functions/FunctionDeclarationSniff.php index d5374882d1..1d0745b98b 100644 --- a/src/Standards/PEAR/Sniffs/Functions/FunctionDeclarationSniff.php +++ b/src/Standards/PEAR/Sniffs/Functions/FunctionDeclarationSniff.php @@ -128,23 +128,25 @@ public function process(File $phpcsFile, $stackPtr) // Must be no space before semicolon in abstract/interface methods. if ($methodProps['has_body'] === false) { $end = $phpcsFile->findNext(T_SEMICOLON, $closeBracket); - if ($tokens[($end - 1)]['content'] === $phpcsFile->eolChar) { - $spaces = 'newline'; - } else if ($tokens[($end - 1)]['code'] === T_WHITESPACE) { - $spaces = $tokens[($end - 1)]['length']; - } else { - $spaces = 0; - } + if ($end !== false) { + if ($tokens[($end - 1)]['content'] === $phpcsFile->eolChar) { + $spaces = 'newline'; + } else if ($tokens[($end - 1)]['code'] === T_WHITESPACE) { + $spaces = $tokens[($end - 1)]['length']; + } else { + $spaces = 0; + } - if ($spaces !== 0) { - $error = 'Expected 0 spaces before semicolon; %s found'; - $data = [$spaces]; - $fix = $phpcsFile->addFixableError($error, $end, 'SpaceBeforeSemicolon', $data); - if ($fix === true) { - $phpcsFile->fixer->replaceToken(($end - 1), ''); + if ($spaces !== 0) { + $error = 'Expected 0 spaces before semicolon; %s found'; + $data = [$spaces]; + $fix = $phpcsFile->addFixableError($error, $end, 'SpaceBeforeSemicolon', $data); + if ($fix === true) { + $phpcsFile->fixer->replaceToken(($end - 1), ''); + } } } - } + }//end if }//end if // Must be one space before and after USE keyword for closures. diff --git a/src/Standards/PEAR/Tests/Functions/FunctionDeclarationUnitTest.2.inc b/src/Standards/PEAR/Tests/Functions/FunctionDeclarationUnitTest.2.inc new file mode 100644 index 0000000000..719f703b0d --- /dev/null +++ b/src/Standards/PEAR/Tests/Functions/FunctionDeclarationUnitTest.2.inc @@ -0,0 +1,7 @@ +