NewFopenModesSniff.php 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. <?php
  2. /**
  3. * PHPCompatibility, an external standard for PHP_CodeSniffer.
  4. *
  5. * @package PHPCompatibility
  6. * @copyright 2012-2019 PHPCompatibility Contributors
  7. * @license https://opensource.org/licenses/LGPL-3.0 LGPL3
  8. * @link https://github.com/PHPCompatibility/PHPCompatibility
  9. */
  10. namespace PHPCompatibility\Sniffs\ParameterValues;
  11. use PHPCompatibility\AbstractFunctionCallParameterSniff;
  12. use PHP_CodeSniffer_File as File;
  13. /**
  14. * Check for valid values for the `fopen()` `$mode` parameter.
  15. *
  16. * PHP version 5.2+
  17. *
  18. * @link https://www.php.net/manual/en/function.fopen.php#refsect1-function.fopen-changelog
  19. *
  20. * @since 9.0.0
  21. */
  22. class NewFopenModesSniff extends AbstractFunctionCallParameterSniff
  23. {
  24. /**
  25. * Functions to check for.
  26. *
  27. * @since 9.0.0
  28. *
  29. * @var array
  30. */
  31. protected $targetFunctions = array(
  32. 'fopen' => true,
  33. );
  34. /**
  35. * Do a version check to determine if this sniff needs to run at all.
  36. *
  37. * @since 9.0.0
  38. *
  39. * @return bool
  40. */
  41. protected function bowOutEarly()
  42. {
  43. // Version used here should be (above) the highest version from the `newModes` control,
  44. // structure below, i.e. the last PHP version in which a new mode was introduced.
  45. return ($this->supportsBelow('7.1') === false);
  46. }
  47. /**
  48. * Process the parameters of a matched function.
  49. *
  50. * @since 9.0.0
  51. *
  52. * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
  53. * @param int $stackPtr The position of the current token in the stack.
  54. * @param string $functionName The token content (function name) which was matched.
  55. * @param array $parameters Array with information about the parameters.
  56. *
  57. * @return int|void Integer stack pointer to skip forward or void to continue
  58. * normal file processing.
  59. */
  60. public function processParameters(File $phpcsFile, $stackPtr, $functionName, $parameters)
  61. {
  62. if (isset($parameters[2]) === false) {
  63. return;
  64. }
  65. $tokens = $phpcsFile->getTokens();
  66. $targetParam = $parameters[2];
  67. $errors = array();
  68. for ($i = $targetParam['start']; $i <= $targetParam['end']; $i++) {
  69. if ($tokens[$i]['code'] !== \T_CONSTANT_ENCAPSED_STRING) {
  70. continue;
  71. }
  72. if (strpos($tokens[$i]['content'], 'c+') !== false && $this->supportsBelow('5.2.5')) {
  73. $errors['cplusFound'] = array(
  74. 'c+',
  75. '5.2.5',
  76. $targetParam['raw'],
  77. );
  78. } elseif (strpos($tokens[$i]['content'], 'c') !== false && $this->supportsBelow('5.2.5')) {
  79. $errors['cFound'] = array(
  80. 'c',
  81. '5.2.5',
  82. $targetParam['raw'],
  83. );
  84. }
  85. if (strpos($tokens[$i]['content'], 'e') !== false && $this->supportsBelow('7.0.15')) {
  86. $errors['eFound'] = array(
  87. 'e',
  88. '7.0.15',
  89. $targetParam['raw'],
  90. );
  91. }
  92. }
  93. if (empty($errors) === true) {
  94. return;
  95. }
  96. foreach ($errors as $errorCode => $errorData) {
  97. $phpcsFile->addError(
  98. 'Passing "%s" as the $mode to fopen() is not supported in PHP %s or lower. Found %s',
  99. $targetParam['start'],
  100. $errorCode,
  101. $errorData
  102. );
  103. }
  104. }
  105. }