/** * Processes this function call. * * @param PHP_CodeSniffer_File $phpcsFile * The file being scanned. * @param int $stackPtr * The position of the function call in the stack. * @param int $openBracket * The position of the opening parenthesis in the stack. * @param int $closeBracket * The position of the closing parenthesis in the stack. * @param Drupal_Sniffs_Semantics_FunctionCallSniff $sniff * Can be used to retreive the function's arguments with the getArgument() * method. * * @return void */ public function processFunctionCall(PHP_CodeSniffer_File $phpcsFile, $stackPtr, $openBracket, $closeBracket, Drupal_Sniffs_Semantics_FunctionCallSniff $sniff) { $tokens = $phpcsFile->getTokens(); $option = $sniff->getArgument(2); if ($tokens[$option['start']]['content'] !== 'CURLOPT_SSL_VERIFYPEER') { return; } $value = $sniff->getArgument(3); if ($tokens[$value['start']]['content'] === 'FALSE' || $tokens[$value['start']]['content'] === '0') { $warning = 'Potential security problem: SSL peer verification must not be disabled'; $phpcsFile->addWarning($warning, $value['start'], 'SslPeerVerificationDisabled'); } }
/** * Processes this function call. * * @param PHP_CodeSniffer_File $phpcsFile * The file being scanned. * @param int $stackPtr * The position of the function call in the stack. * @param int $openBracket * The position of the opening parenthesis in the stack. * @param int $closeBracket * The position of the closing parenthesis in the stack. * @param Drupal_Sniffs_Semantics_FunctionCallSniff $sniff * Can be used to retreive the function's arguments with the getArgument() * method. * * @return void */ public function processFunctionCall(PHP_CodeSniffer_File $phpcsFile, $stackPtr, $openBracket, $closeBracket, Drupal_Sniffs_Semantics_FunctionCallSniff $sniff) { $tokens = $phpcsFile->getTokens(); // We assume that the sequence '#default_value' => variable_get(...) // indicates a variable that the module owns. $arrow = $phpcsFile->findPrevious(PHP_CodeSniffer_Tokens::$emptyTokens, $stackPtr - 1, null, true); if ($arrow === false || $tokens[$arrow]['code'] !== T_DOUBLE_ARROW) { return; } $arrayKey = $phpcsFile->findPrevious(PHP_CodeSniffer_Tokens::$emptyTokens, $arrow - 1, null, true); if ($arrayKey === false || $tokens[$arrayKey]['code'] !== T_CONSTANT_ENCAPSED_STRING || substr($tokens[$arrayKey]['content'], 1, -1) !== '#default_value') { return; } $argument = $sniff->getArgument(1); // Variable name is not a literal string, so we return early. if ($argument === false || $tokens[$argument['start']]['code'] !== T_CONSTANT_ENCAPSED_STRING) { return; } $moduleName = DrupalPractice_Project::getName($phpcsFile); if ($moduleName === false) { return; } $variableName = substr($tokens[$argument['start']]['content'], 1, -1); if (strpos($variableName, $moduleName) !== 0) { $warning = 'All variables defined by your module must be prefixed with your module\'s name to avoid name collisions with others. Expected start with "%s" but found "%s"'; $data = array($moduleName, $variableName); $phpcsFile->addWarning($warning, $argument['start'], 'VariableName', $data); } }
/** * Processes this function call. * * @param PHP_CodeSniffer_File $phpcsFile * The file being scanned. * @param int $stackPtr * The position of the function call in the stack. * @param int $openBracket * The position of the opening parenthesis in the stack. * @param int $closeBracket * The position of the closing parenthesis in the stack. * @param Drupal_Sniffs_Semantics_FunctionCallSniff $sniff * Can be used to retreive the function's arguments with the getArgument() * method. * * @return void */ public function processFunctionCall(PHP_CodeSniffer_File $phpcsFile, $stackPtr, $openBracket, $closeBracket, Drupal_Sniffs_Semantics_FunctionCallSniff $sniff) { $tokens = $phpcsFile->getTokens(); $argument = $sniff->getArgument(1); if ($argument === false) { return; } if ($tokens[$argument['start']]['code'] !== T_CONSTANT_ENCAPSED_STRING) { // Not a string literal. // @TODO: Extend code to recognize patterns in variables. return; } $pattern = $tokens[$argument['start']]['content']; $quote = substr($pattern, 0, 1); // Check that the pattern is a string. if ($quote == '"' || $quote == "'") { // Get the delimiter - first char after the enclosing quotes. $delimiter = preg_quote(substr($pattern, 1, 1), '/'); // Check if there is the evil e flag. if (preg_match('/' . $delimiter . '[\\w]{0,}e[\\w]{0,}$/', substr($pattern, 0, -1))) { $warn = 'Using the e flag in %s is a possible security risk. For details see http://drupal.org/node/750148'; $phpcsFile->addError($warn, $argument['start'], 'PregEFlag', array($tokens[$stackPtr]['content'])); return; } } }
/** * Processes this function call. * * @param PHP_CodeSniffer_File $phpcsFile * The file being scanned. * @param int $stackPtr * The position of the function call in the stack. * @param int $openBracket * The position of the opening parenthesis in the stack. * @param int $closeBracket * The position of the closing parenthesis in the stack. * @param Drupal_Sniffs_Semantics_FunctionCallSniff $sniff * Can be used to retreive the function's arguments with the getArgument() * method. * * @return void */ public function processFunctionCall(PHP_CodeSniffer_File $phpcsFile, $stackPtr, $openBracket, $closeBracket, Drupal_Sniffs_Semantics_FunctionCallSniff $sniff) { $tokens = $phpcsFile->getTokens(); $argument = $sniff->getArgument(1); if ($argument === false) { $error = 'Empty calls to t() are not allowed'; $phpcsFile->addError($error, $stackPtr, 'EmptyT'); return; } if ($tokens[$argument['start']]['code'] !== T_CONSTANT_ENCAPSED_STRING) { // Not a translatable string literal. return; } $concatFound = $phpcsFile->findNext(T_STRING_CONCAT, $argument['start'], $argument['end']); if ($concatFound !== false) { $error = 'Concatenating translatable strings is not allowed, use placeholders instead and only one string literal'; $phpcsFile->addError($error, $concatFound, 'Concat'); } $string = $tokens[$argument['start']]['content']; // Check if there is a backslash escaped single quote in the string and // if the string makes use of double quotes. if ($string[0] === "'" && strpos($string, "\\'") !== false && strpos($string, '"') === false) { $warn = 'Avoid backslash escaping in translatable strings when possible, use "" quotes instead'; $phpcsFile->addWarning($warn, $argument['start'], 'BackslashSingleQuote'); return; } if ($string[0] === '"' && strpos($string, '\\"') !== false && strpos($string, "'") === false) { $warn = "Avoid backslash escaping in translatable strings when possible, use '' quotes instead"; $phpcsFile->addWarning($warn, $argument['start'], 'BackslashDoubleQuote'); } }
/** * Processes this function call. * * @param PHP_CodeSniffer_File $phpcsFile * The file being scanned. * @param int $stackPtr * The position of the function call in the stack. * @param int $openBracket * The position of the opening parenthesis in the stack. * @param int $closeBracket * The position of the closing parenthesis in the stack. * @param Drupal_Sniffs_Semantics_FunctionCallSniff $sniff * Can be used to retreive the function's arguments with the getArgument() * method. * * @return void */ public function processFunctionCall(PHP_CodeSniffer_File $phpcsFile, $stackPtr, $openBracket, $closeBracket, Drupal_Sniffs_Semantics_FunctionCallSniff $sniff) { $tokens = $phpcsFile->getTokens(); $argument = $sniff->getArgument(1); if ($argument !== false && $tokens[$argument['start']]['code'] === T_CONSTANT_ENCAPSED_STRING) { $warning = 'Messages are user facing text and must run through t() for translation'; $phpcsFile->addWarning($warning, $argument['start'], 'ErrorMessage'); } }
/** * Processes this function call. * * @param PHP_CodeSniffer_File $phpcsFile * The file being scanned. * @param int $stackPtr * The position of the function call in the stack. * @param int $openBracket * The position of the opening parenthesis in the stack. * @param int $closeBracket * The position of the closing parenthesis in the stack. * @param Drupal_Sniffs_Semantics_FunctionCallSniff $sniff * Can be used to retreive the function's arguments with the getArgument() * method. * * @return void */ public function processFunctionCall(PHP_CodeSniffer_File $phpcsFile, $stackPtr, $openBracket, $closeBracket, Drupal_Sniffs_Semantics_FunctionCallSniff $sniff) { $tokens = $phpcsFile->getTokens(); $argument = $sniff->getArgument(1); if ($tokens[$argument['start']]['content'] === 'check_plain') { $warning = 'Do not use check_plain() on the first argument of l(), because l() will sanitize it for you by default'; $phpcsFile->addWarning($warning, $argument['start'], 'LCheckPlain'); } }
/** * Processes this function call. * * @param PHP_CodeSniffer_File $phpcsFile * The file being scanned. * @param int $stackPtr * The position of the function call in the stack. * @param int $openBracket * The position of the opening parenthesis in the stack. * @param int $closeBracket * The position of the closing parenthesis in the stack. * @param Drupal_Sniffs_Semantics_FunctionCallSniff $sniff * Can be used to retreive the function's arguments with the getArgument() * method. * * @return void */ public function processFunctionCall(PHP_CodeSniffer_File $phpcsFile, $stackPtr, $openBracket, $closeBracket, Drupal_Sniffs_Semantics_FunctionCallSniff $sniff) { $tokens = $phpcsFile->getTokens(); // Get the first argument passed to l(). $argument = $sniff->getArgument(1); if ($tokens[$argument['start']]['code'] === T_CONSTANT_ENCAPSED_STRING) { $error = 'The $text argument to l() should be enclosed within t() so that it is translatable'; $phpcsFile->addError($error, $stackPtr, 'LArg'); } }
/** * Processes this function call. * * @param PHP_CodeSniffer_File $phpcsFile * The file being scanned. * @param int $stackPtr * The position of the function call in the stack. * @param int $openBracket * The position of the opening parenthesis in the stack. * @param int $closeBracket * The position of the closing parenthesis in the stack. * @param Drupal_Sniffs_Semantics_FunctionCallSniff $sniff * Can be used to retreive the function's arguments with the getArgument() * method. * * @return void */ public function processFunctionCall(PHP_CodeSniffer_File $phpcsFile, $stackPtr, $openBracket, $closeBracket, Drupal_Sniffs_Semantics_FunctionCallSniff $sniff) { $tokens = $phpcsFile->getTokens(); if ($tokens[$stackPtr]['content'] === 't') { $argument = $sniff->getArgument(2); } else { // For watchdog() the placeholders are in the third argument. $argument = $sniff->getArgument(3); } if ($argument === false) { return; } if ($tokens[$argument['start']]['code'] !== T_ARRAY) { return; } $checkPlain = $argument['start']; while ($checkPlain = $phpcsFile->findNext(T_STRING, $checkPlain + 1, $tokens[$argument['start']]['parenthesis_closer'])) { if ($tokens[$checkPlain]['content'] === 'check_plain') { $warning = 'The extra check_plain() is not necessary for placeholders, "@" and "%" will automatically run check_plain()'; $phpcsFile->addWarning($warning, $checkPlain, 'CheckPlain'); } } }
/** * Processes this function call. * * @param PHP_CodeSniffer_File $phpcsFile * The file being scanned. * @param int $stackPtr * The position of the function call in the stack. * @param int $openBracket * The position of the opening parenthesis in the stack. * @param int $closeBracket * The position of the closing parenthesis in the stack. * @param Drupal_Sniffs_Semantics_FunctionCallSniff $sniff * Can be used to retreive the function's arguments with the getArgument() * method. * * @return void */ public function processFunctionCall(PHP_CodeSniffer_File $phpcsFile, $stackPtr, $openBracket, $closeBracket, Drupal_Sniffs_Semantics_FunctionCallSniff $sniff) { $tokens = $phpcsFile->getTokens(); // Get the second argument passed to watchdog(). $argument = $sniff->getArgument(2); if ($argument === false) { $error = 'The second argument to watchdog() is missing'; $phpcsFile->addError($error, $stackPtr, 'WatchdogArgument'); return; } if ($tokens[$argument['start']]['code'] === T_STRING && $tokens[$argument['start']]['content'] === 't') { $error = 'The second argument to watchdog() should not be enclosed with t()'; $phpcsFile->addError($error, $argument['start'], 'WatchdogT'); } }
/** * Processes this function call. * * @param PHP_CodeSniffer_File $phpcsFile * The file being scanned. * @param int $stackPtr * The position of the function call in the stack. * @param int $openBracket * The position of the opening parenthesis in the stack. * @param int $closeBracket * The position of the closing parenthesis in the stack. * @param Drupal_Sniffs_Semantics_FunctionCallSniff $sniff * Can be used to retreive the function's arguments with the getArgument() * method. * * @return void */ public function processFunctionCall(PHP_CodeSniffer_File $phpcsFile, $stackPtr, $openBracket, $closeBracket, Drupal_Sniffs_Semantics_FunctionCallSniff $sniff) { $tokens = $phpcsFile->getTokens(); $argument = $sniff->getArgument(1); if ($argument === false) { $error = 'Empty calls to t() are not allowed'; $phpcsFile->addError($error, $stackPtr, 'EmptyT'); return; } if ($tokens[$argument['start']]['code'] !== T_CONSTANT_ENCAPSED_STRING) { // Not a translatable string literal. $warning = 'Only string literals should be passed to t() where possible'; $phpcsFile->addWarning($warning, $argument['start'], 'NotLiteralString'); return; } $string = $tokens[$argument['start']]['content']; if ($string === '""' || $string === "''") { $warning = 'Do not pass empty strings to t()'; $phpcsFile->addWarning($warning, $argument['start'], 'EmptyString'); return; } $lastChar = substr($string, -1); if ($lastChar === '"' || $lastChar === "'") { $message = substr($string, 1, -1); if ($message !== trim($message)) { $warning = 'Translatable strings must not begin or end with white spaces, use placeholders with t() for variables'; $phpcsFile->addWarning($warning, $argument['start'], 'WhiteSpace'); } } $concatFound = $phpcsFile->findNext(T_STRING_CONCAT, $argument['start'], $argument['end']); if ($concatFound !== false) { $error = 'Concatenating translatable strings is not allowed, use placeholders instead and only one string literal'; $phpcsFile->addError($error, $concatFound, 'Concat'); } // Check if there is a backslash escaped single quote in the string and // if the string makes use of double quotes. if ($string[0] === "'" && strpos($string, "\\'") !== false && strpos($string, '"') === false) { $warn = 'Avoid backslash escaping in translatable strings when possible, use "" quotes instead'; $phpcsFile->addWarning($warn, $argument['start'], 'BackslashSingleQuote'); return; } if ($string[0] === '"' && strpos($string, '\\"') !== false && strpos($string, "'") === false) { $warn = "Avoid backslash escaping in translatable strings when possible, use '' quotes instead"; $phpcsFile->addWarning($warn, $argument['start'], 'BackslashDoubleQuote'); } }
/** * Processes this function call. * * @param PHP_CodeSniffer_File $phpcsFile * The file being scanned. * @param int $stackPtr * The position of the function call in the stack. * @param int $openBracket * The position of the opening parenthesis in the stack. * @param int $closeBracket * The position of the closing parenthesis in the stack. * @param Drupal_Sniffs_Semantics_FunctionCallSniff $sniff * Can be used to retreive the function's arguments with the getArgument() * method. * * @return void */ public function processFunctionCall(PHP_CodeSniffer_File $phpcsFile, $stackPtr, $openBracket, $closeBracket, Drupal_Sniffs_Semantics_FunctionCallSniff $sniff) { $fileExtension = strtolower(substr($phpcsFile->getFilename(), -6)); // Only check in *.module files. if ($fileExtension !== 'module') { return; } $tokens = $phpcsFile->getTokens(); $argument = $sniff->getArgument(1); if ($tokens[$argument['start']]['code'] !== T_CONSTANT_ENCAPSED_STRING) { // Not a string literal, so this is some obscure constant that we ignore. return; } $moduleName = substr(basename($phpcsFile->getFilename()), 0, -7); $expectedStart = strtoupper($moduleName); // Remove the quotes around the string litral. $constant = substr($tokens[$argument['start']]['content'], 1, -1); if (strpos($constant, $expectedStart) !== 0) { $warning = 'All constants defined by a module must be prefixed with the module\'s name, expected "%s" but found "%s"'; $data = array($expectedStart . "_{$constant}", $constant); $phpcsFile->addWarning($warning, $stackPtr, 'ConstantStart', $data); } }