RemovedIniDirectivesSniff.php 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424
  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\IniDirectives;
  11. use PHPCompatibility\AbstractRemovedFeatureSniff;
  12. use PHP_CodeSniffer_File as File;
  13. /**
  14. * Detect the use of deprecated and removed INI directives through `ini_set()` or `ini_get()`.
  15. *
  16. * PHP version All
  17. *
  18. * @link https://www.php.net/manual/en/ini.list.php
  19. * @link https://www.php.net/manual/en/ini.core.php
  20. *
  21. * @since 5.5
  22. * @since 7.0.0 This sniff now throws a warning (deprecated) or an error (removed) depending
  23. * on the `testVersion` set. Previously it would always throw a warning.
  24. * @since 7.0.1 The sniff will now only throw warnings for `ini_get()`.
  25. * @since 7.1.0 Now extends the `AbstractRemovedFeatureSniff` instead of the base `Sniff` class.
  26. * @since 9.0.0 Renamed from `DeprecatedIniDirectivesSniff` to `RemovedIniDirectivesSniff`.
  27. */
  28. class RemovedIniDirectivesSniff extends AbstractRemovedFeatureSniff
  29. {
  30. /**
  31. * A list of deprecated/removed INI directives.
  32. *
  33. * The array lists : version number with false (deprecated) and true (removed).
  34. * If's sufficient to list the first version where the ini directive was deprecated/removed.
  35. *
  36. * @since 5.5
  37. * @since 7.0.3 Support for 'alternative' has been added.
  38. *
  39. * @var array(string)
  40. */
  41. protected $deprecatedIniDirectives = array(
  42. 'fbsql.batchSize' => array(
  43. '5.1' => true,
  44. 'alternative' => 'fbsql.batchsize',
  45. ),
  46. 'pfpro.defaulthost' => array(
  47. '5.1' => true,
  48. ),
  49. 'pfpro.defaultport' => array(
  50. '5.1' => true,
  51. ),
  52. 'pfpro.defaulttimeout' => array(
  53. '5.1' => true,
  54. ),
  55. 'pfpro.proxyaddress' => array(
  56. '5.1' => true,
  57. ),
  58. 'pfpro.proxyport' => array(
  59. '5.1' => true,
  60. ),
  61. 'pfpro.proxylogon' => array(
  62. '5.1' => true,
  63. ),
  64. 'pfpro.proxypassword' => array(
  65. '5.1' => true,
  66. ),
  67. 'ifx.allow_persistent' => array(
  68. '5.2.1' => true,
  69. ),
  70. 'ifx.blobinfile' => array(
  71. '5.2.1' => true,
  72. ),
  73. 'ifx.byteasvarchar' => array(
  74. '5.2.1' => true,
  75. ),
  76. 'ifx.charasvarchar' => array(
  77. '5.2.1' => true,
  78. ),
  79. 'ifx.default_host' => array(
  80. '5.2.1' => true,
  81. ),
  82. 'ifx.default_password' => array(
  83. '5.2.1' => true,
  84. ),
  85. 'ifx.default_user' => array(
  86. '5.2.1' => true,
  87. ),
  88. 'ifx.max_links' => array(
  89. '5.2.1' => true,
  90. ),
  91. 'ifx.max_persistent' => array(
  92. '5.2.1' => true,
  93. ),
  94. 'ifx.nullformat' => array(
  95. '5.2.1' => true,
  96. ),
  97. 'ifx.textasvarchar' => array(
  98. '5.2.1' => true,
  99. ),
  100. 'zend.ze1_compatibility_mode' => array(
  101. '5.3' => true,
  102. ),
  103. 'allow_call_time_pass_reference' => array(
  104. '5.3' => false,
  105. '5.4' => true,
  106. ),
  107. 'define_syslog_variables' => array(
  108. '5.3' => false,
  109. '5.4' => true,
  110. ),
  111. 'detect_unicode' => array(
  112. '5.4' => true,
  113. 'alternative' => 'zend.detect_unicode',
  114. ),
  115. 'highlight.bg' => array(
  116. '5.3' => false,
  117. '5.4' => true,
  118. ),
  119. 'magic_quotes_gpc' => array(
  120. '5.3' => false,
  121. '5.4' => true,
  122. ),
  123. 'magic_quotes_runtime' => array(
  124. '5.3' => false,
  125. '5.4' => true,
  126. ),
  127. 'magic_quotes_sybase' => array(
  128. '5.3' => false,
  129. '5.4' => true,
  130. ),
  131. 'mbstring.script_encoding' => array(
  132. '5.4' => true,
  133. 'alternative' => 'zend.script_encoding',
  134. ),
  135. 'register_globals' => array(
  136. '5.3' => false,
  137. '5.4' => true,
  138. ),
  139. 'register_long_arrays' => array(
  140. '5.3' => false,
  141. '5.4' => true,
  142. ),
  143. 'safe_mode' => array(
  144. '5.3' => false,
  145. '5.4' => true,
  146. ),
  147. 'safe_mode_allowed_env_vars' => array(
  148. '5.3' => false,
  149. '5.4' => true,
  150. ),
  151. 'safe_mode_exec_dir' => array(
  152. '5.3' => false,
  153. '5.4' => true,
  154. ),
  155. 'safe_mode_gid' => array(
  156. '5.3' => false,
  157. '5.4' => true,
  158. ),
  159. 'safe_mode_include_dir' => array(
  160. '5.3' => false,
  161. '5.4' => true,
  162. ),
  163. 'safe_mode_protected_env_vars' => array(
  164. '5.3' => false,
  165. '5.4' => true,
  166. ),
  167. 'session.bug_compat_42' => array(
  168. '5.3' => false,
  169. '5.4' => true,
  170. ),
  171. 'session.bug_compat_warn' => array(
  172. '5.3' => false,
  173. '5.4' => true,
  174. ),
  175. 'y2k_compliance' => array(
  176. '5.3' => false,
  177. '5.4' => true,
  178. ),
  179. 'always_populate_raw_post_data' => array(
  180. '5.6' => false,
  181. '7.0' => true,
  182. ),
  183. 'iconv.input_encoding' => array(
  184. '5.6' => false,
  185. ),
  186. 'iconv.output_encoding' => array(
  187. '5.6' => false,
  188. ),
  189. 'iconv.internal_encoding' => array(
  190. '5.6' => false,
  191. ),
  192. 'mbstring.http_input' => array(
  193. '5.6' => false,
  194. ),
  195. 'mbstring.http_output' => array(
  196. '5.6' => false,
  197. ),
  198. 'mbstring.internal_encoding' => array(
  199. '5.6' => false,
  200. ),
  201. 'asp_tags' => array(
  202. '7.0' => true,
  203. ),
  204. 'xsl.security_prefs' => array(
  205. '7.0' => true,
  206. ),
  207. 'opcache.load_comments' => array(
  208. '7.0' => true,
  209. ),
  210. 'mcrypt.algorithms_dir' => array(
  211. '7.1' => false,
  212. '7.2' => true,
  213. ),
  214. 'mcrypt.modes_dir' => array(
  215. '7.1' => false,
  216. '7.2' => true,
  217. ),
  218. 'session.entropy_file' => array(
  219. '7.1' => true,
  220. ),
  221. 'session.entropy_length' => array(
  222. '7.1' => true,
  223. ),
  224. 'session.hash_function' => array(
  225. '7.1' => true,
  226. ),
  227. 'session.hash_bits_per_character' => array(
  228. '7.1' => true,
  229. ),
  230. 'mbstring.func_overload' => array(
  231. '7.2' => false,
  232. ),
  233. 'sql.safe_mode' => array(
  234. '7.2' => true,
  235. ),
  236. 'track_errors' => array(
  237. '7.2' => false,
  238. ),
  239. 'opcache.fast_shutdown' => array(
  240. '7.2' => true,
  241. ),
  242. 'birdstep.max_links' => array(
  243. '7.3' => true,
  244. ),
  245. 'opcache.inherited_hack' => array(
  246. '5.3' => false, // Soft deprecated, i.e. ignored.
  247. '7.3' => true,
  248. ),
  249. 'pdo_odbc.db2_instance_name' => array(
  250. '7.3' => false, // Has been marked as deprecated in the manual from before this time. Now hard-deprecated.
  251. ),
  252. 'allow_url_include' => array(
  253. '7.4' => false,
  254. ),
  255. 'ibase.allow_persistent' => array(
  256. '7.4' => true,
  257. ),
  258. 'ibase.max_persistent' => array(
  259. '7.4' => true,
  260. ),
  261. 'ibase.max_links' => array(
  262. '7.4' => true,
  263. ),
  264. 'ibase.default_db' => array(
  265. '7.4' => true,
  266. ),
  267. 'ibase.default_user' => array(
  268. '7.4' => true,
  269. ),
  270. 'ibase.default_password' => array(
  271. '7.4' => true,
  272. ),
  273. 'ibase.default_charset' => array(
  274. '7.4' => true,
  275. ),
  276. 'ibase.timestampformat' => array(
  277. '7.4' => true,
  278. ),
  279. 'ibase.dateformat' => array(
  280. '7.4' => true,
  281. ),
  282. 'ibase.timeformat' => array(
  283. '7.4' => true,
  284. ),
  285. );
  286. /**
  287. * Returns an array of tokens this test wants to listen for.
  288. *
  289. * @since 5.5
  290. *
  291. * @return array
  292. */
  293. public function register()
  294. {
  295. return array(\T_STRING);
  296. }
  297. /**
  298. * Processes this test, when one of its tokens is encountered.
  299. *
  300. * @since 5.5
  301. *
  302. * @param \PHP_CodeSniffer_File $phpcsFile The file being scanned.
  303. * @param int $stackPtr The position of the current token in the
  304. * stack passed in $tokens.
  305. *
  306. * @return void
  307. */
  308. public function process(File $phpcsFile, $stackPtr)
  309. {
  310. $tokens = $phpcsFile->getTokens();
  311. $ignore = array(
  312. \T_DOUBLE_COLON => true,
  313. \T_OBJECT_OPERATOR => true,
  314. \T_FUNCTION => true,
  315. \T_CONST => true,
  316. );
  317. $prevToken = $phpcsFile->findPrevious(\T_WHITESPACE, ($stackPtr - 1), null, true);
  318. if (isset($ignore[$tokens[$prevToken]['code']]) === true) {
  319. // Not a call to a PHP function.
  320. return;
  321. }
  322. $functionLc = strtolower($tokens[$stackPtr]['content']);
  323. if (isset($this->iniFunctions[$functionLc]) === false) {
  324. return;
  325. }
  326. $iniToken = $this->getFunctionCallParameter($phpcsFile, $stackPtr, $this->iniFunctions[$functionLc]);
  327. if ($iniToken === false) {
  328. return;
  329. }
  330. $filteredToken = $this->stripQuotes($iniToken['raw']);
  331. if (isset($this->deprecatedIniDirectives[$filteredToken]) === false) {
  332. return;
  333. }
  334. $itemInfo = array(
  335. 'name' => $filteredToken,
  336. 'functionLc' => $functionLc,
  337. );
  338. $this->handleFeature($phpcsFile, $iniToken['end'], $itemInfo);
  339. }
  340. /**
  341. * Get the relevant sub-array for a specific item from a multi-dimensional array.
  342. *
  343. * @since 7.1.0
  344. *
  345. * @param array $itemInfo Base information about the item.
  346. *
  347. * @return array Version and other information about the item.
  348. */
  349. public function getItemArray(array $itemInfo)
  350. {
  351. return $this->deprecatedIniDirectives[$itemInfo['name']];
  352. }
  353. /**
  354. * Retrieve the relevant detail (version) information for use in an error message.
  355. *
  356. * @since 7.1.0
  357. *
  358. * @param array $itemArray Version and other information about the item.
  359. * @param array $itemInfo Base information about the item.
  360. *
  361. * @return array
  362. */
  363. public function getErrorInfo(array $itemArray, array $itemInfo)
  364. {
  365. $errorInfo = parent::getErrorInfo($itemArray, $itemInfo);
  366. // Lower error level to warning if the function used was ini_get.
  367. if ($errorInfo['error'] === true && $itemInfo['functionLc'] === 'ini_get') {
  368. $errorInfo['error'] = false;
  369. }
  370. return $errorInfo;
  371. }
  372. /**
  373. * Get the error message template for this sniff.
  374. *
  375. * @since 7.1.0
  376. *
  377. * @return string
  378. */
  379. protected function getErrorMsgTemplate()
  380. {
  381. return "INI directive '%s' is ";
  382. }
  383. /**
  384. * Get the error message template for suggesting an alternative for a specific sniff.
  385. *
  386. * @since 7.1.0
  387. *
  388. * @return string
  389. */
  390. protected function getAlternativeOptionTemplate()
  391. {
  392. return str_replace('%s', "'%s'", parent::getAlternativeOptionTemplate());
  393. }
  394. }