diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..eece033d --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +/vendor/* +/bin/* diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 00000000..58e89616 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,10 @@ +language: php +php: + - 5.5 + - 5.6 + - 7.0 + - 7.1 +install: composer install --no-interaction --prefer-source +script: + - bin/phpunit + - bin/phpcs --standard=PSR2 Magento/ --extensions=php diff --git a/Magento/Sniffs/Classes/ObjectInstantiationSniff.php b/Magento/Sniffs/Classes/ObjectInstantiationSniff.php new file mode 100644 index 00000000..3bdc6654 --- /dev/null +++ b/Magento/Sniffs/Classes/ObjectInstantiationSniff.php @@ -0,0 +1,84 @@ +getTokens(); + $leftLimit = $phpcsFile->findPrevious($this->leftRangeTokens, $stackPtr - 1, null, true); + $findThrow = $phpcsFile->findPrevious(T_THROW, $stackPtr - 1, $leftLimit); + if (!$findThrow) { + $classNameStart = $phpcsFile->findNext($this->rightRangeTokens, $stackPtr + 1); + $classNameEnd = $phpcsFile->findNext($this->rightRangeTokens, $classNameStart + 1, null, true); + $className = ''; + for ($i = $classNameStart; $i < $classNameEnd; $i++) { + $className .= $tokens[$i]['content']; + } + $phpcsFile->addWarning( + $this->warningMessage, + $classNameStart, + $this->warningCode, + [$className] + ); + } + } +} diff --git a/Magento/Sniffs/CodeAnalysis/EmptyBlockSniff.php b/Magento/Sniffs/CodeAnalysis/EmptyBlockSniff.php new file mode 100644 index 00000000..6b2a6357 --- /dev/null +++ b/Magento/Sniffs/CodeAnalysis/EmptyBlockSniff.php @@ -0,0 +1,28 @@ +getTokens(); + $endOfStatement = $phpcsFile->findEndOfStatement($stackPtr); + $posOfException = $phpcsFile->findNext(T_STRING, $stackPtr, $endOfStatement); + if ($tokens[$posOfException]['content'] === 'Exception') { + $phpcsFile->addWarning( + $this->warningMessage, + $stackPtr, + $this->warningCode, + $posOfException + ); + } + } +} diff --git a/Magento/Sniffs/Exceptions/NamespaceSniff.php b/Magento/Sniffs/Exceptions/NamespaceSniff.php new file mode 100644 index 00000000..8c2a244d --- /dev/null +++ b/Magento/Sniffs/Exceptions/NamespaceSniff.php @@ -0,0 +1,64 @@ +findNext(T_NAMESPACE, 0) === false) { + return; + } + + $tokens = $phpcsFile->getTokens(); + $endOfStatement = $phpcsFile->findEndOfStatement($stackPtr); + $posOfExceptionClassName = $phpcsFile->findNext(T_STRING, $stackPtr, $endOfStatement); + $posOfNsSeparator = $phpcsFile->findNext(T_NS_SEPARATOR, $stackPtr, $posOfExceptionClassName); + if ($posOfNsSeparator === false && $posOfExceptionClassName !== false) { + $exceptionClassName = trim($tokens[$posOfExceptionClassName]['content']); + $posOfClassInUse = $phpcsFile->findNext(T_STRING, 0, $stackPtr, false, $exceptionClassName); + if ($posOfClassInUse === false || $tokens[$posOfClassInUse]['level'] != 0) { + $phpcsFile->addError( + $this->errorMessage, + $stackPtr, + $this->errorCode, + $exceptionClassName + ); + } + } + } +} diff --git a/Magento/Sniffs/Legacy/MageEntitySniff.php b/Magento/Sniffs/Legacy/MageEntitySniff.php new file mode 100644 index 00000000..6750eec5 --- /dev/null +++ b/Magento/Sniffs/Legacy/MageEntitySniff.php @@ -0,0 +1,115 @@ +getTokens(); + if (in_array($tokens[$stackPtr]['code'], $this->nameBefore)) { + $oldPosition = $stackPtr; + $stackPtr = $phpcsFile->findPrevious(T_STRING, $stackPtr - 1, null, false, null, true); + if ($stackPtr === false) { + return; + } + $entityName = $tokens[$stackPtr]['content']; + $error = [$entityName . $tokens[$oldPosition]['content']]; + } else { + $oldPosition = $stackPtr; + $stackPtr = $phpcsFile->findNext(T_STRING, $oldPosition + 1, null, false, null, true); + if ($stackPtr === false) { + return; + } + $entityName = $tokens[$stackPtr]['content']; + $error = [$tokens[$oldPosition]['content'] . ' ' . $entityName]; + } + if ($entityName === $this->legacyEntity || $this->isPrefixLegacy($entityName)) { + $phpcsFile->addError( + $this->errorMessage, + $stackPtr, + $this->errorCode, + $error + ); + } + } + + /** + * Method checks if passed string contains legacy prefix from Magento 1. + * + * @param string $entityName + * @return bool + */ + private function isPrefixLegacy($entityName) + { + foreach ($this->legacyPrefixes as $entity) { + if (strpos($entityName, $entity) === 0) { + return true; + } + } + return false; + } +} diff --git a/Magento/Sniffs/NamingConvention/InterfaceNameSniff.php b/Magento/Sniffs/NamingConvention/InterfaceNameSniff.php new file mode 100644 index 00000000..6e5875f8 --- /dev/null +++ b/Magento/Sniffs/NamingConvention/InterfaceNameSniff.php @@ -0,0 +1,64 @@ +getTokens(); + $declarationLine = $tokens[$stackPtr]['line']; + $suffixLength = strlen($this->interfaceSuffix); + // Find first T_STRING after 'interface' keyword in the line and verify it + while ($tokens[$stackPtr]['line'] === $declarationLine) { + if ($tokens[$stackPtr]['type'] === 'T_STRING') { + if (substr($tokens[$stackPtr]['content'], 0 - $suffixLength) !== $this->interfaceSuffix) { + $sourceFile->addWarning($this->warningMessage, $stackPtr, $this->warningCode); + } + break; + } + $stackPtr++; + } + } +} diff --git a/Magento/Sniffs/PHP/DateTimeSniff.php b/Magento/Sniffs/PHP/DateTimeSniff.php new file mode 100644 index 00000000..4884cce0 --- /dev/null +++ b/Magento/Sniffs/PHP/DateTimeSniff.php @@ -0,0 +1,62 @@ +getTokens(); + $posOfClassName = $phpcsFile->findNext(T_STRING, $stackPtr); + $posOfNsSeparator = $phpcsFile->findNext(T_NS_SEPARATOR, $stackPtr, $posOfClassName); + if ($posOfNsSeparator !== false && in_array($tokens[$posOfClassName]['content'], $this->dateTimeClasses)) { + $phpcsFile->addWarning($this->warningMessage, $stackPtr, $this->warningCode); + } + } +} diff --git a/Magento/Sniffs/PHP/DiscouragedFunctionSniff.php b/Magento/Sniffs/PHP/DiscouragedFunctionSniff.php new file mode 100644 index 00000000..8a0fbe6e --- /dev/null +++ b/Magento/Sniffs/PHP/DiscouragedFunctionSniff.php @@ -0,0 +1,252 @@ + null, + '^bind_textdomain_codeset$' => null, + '^bindtextdomain$' => null, + '^bz.*$' => null, + '^call_user_func$' => null, + '^call_user_func_array$' => null, + '^chdir$' => null, + '^chgrp$' => null, + '^chmod$' => null, + '^chown$' => null, + '^chroot$' => null, + '^com_load_typelib$' => null, + '^copy$' => null, + '^create_function$' => null, + '^curl_.*$' => null, + '^cyrus_connect$' => null, + '^dba_.*$' => null, + '^dbase_.*$' => null, + '^dbx_.*$' => null, + '^dcgettext$' => null, + '^dcngettext$' => null, + '^dgettext$' => null, + '^dio_.*$' => null, + '^dirname$' => null, + '^dngettext$' => null, + '^domxml_.*$' => null, + '^exec$' => null, + '^fbsql_.*$' => null, + '^fdf_add_doc_javascript$' => null, + '^fdf_open$' => null, + '^fopen$' => null, + '^fclose$' => null, + '^fsockopen$' => null, + '^ftp_.*$' => null, + '^fwrite$' => null, + '^gettext$' => null, + '^gz.*$' => null, + '^header$' => null, + '^highlight_file$' => null, + '^ibase_.*$' => null, + '^id3_set_tag$' => null, + '^ifx_.*$' => null, + '^image.*$' => null, + '^imap_.*$' => null, + '^ingres_.*$' => null, + '^ircg_.*$' => null, + '^ldap_.*$' => null, + '^link$' => null, + '^mail$' => null, + '^mb_send_mail$' => null, + '^mkdir$' => null, + '^move_uploaded_file$' => null, + '^msession_.*$' => null, + '^msg_send$' => null, + '^msql$' => null, + '^msql_.*$' => null, + '^mssql_.*$' => null, + '^mysql_.*$' => null, + '^odbc_.*$' => null, + '^opendir$' => null, + '^openlog$' => null, + '^ora_.*$' => null, + '^ovrimos_.*$' => null, + '^parse_ini_file$' => null, + '^parse_str$' => null, + '^parse_url$' => null, + '^parsekit_compile_string$' => null, + '^passthru$' => null, + '^pathinfo$' => null, + '^pcntl_.*$' => null, + '^posix_.*$' => null, + '^pfpro_.*$' => null, + '^pfsockopen$' => null, + '^pg_.*$' => null, + '^php_check_syntax$' => null, + '^popen$' => null, + '^print_r$' => null, + '^printf$' => null, + '^proc_open$' => null, + '^putenv$' => null, + '^readfile$' => null, + '^readgzfile$' => null, + '^readline$' => null, + '^readlink$' => null, + '^register_shutdown_function$' => null, + '^register_tick_function$' => null, + '^rename$' => null, + '^rmdir$' => null, + '^scandir$' => null, + '^session_.*$' => null, + '^set_include_path$' => null, + '^ini_set$' => null, + '^set_time_limit$' => null, + '^setcookie$' => null, + '^setlocale$' => null, + '^setrawcookie$' => null, + '^shell_exec$' => null, + '^sleep$' => null, + '^socket_.*$' => null, + '^stream_.*$' => null, + '^sybase_.*$' => null, + '^symlink$' => null, + '^syslog$' => null, + '^system$' => null, + '^touch$' => null, + '^trigger_error$' => null, + '^unlink$' => null, + '^vprintf$' => null, + '^mysqli.*$' => null, + '^oci_connect$' => null, + '^oci_pconnect$' => null, + '^quotemeta$' => null, + '^sqlite_popen$' => null, + '^time_nanosleep$' => null, + '^base64_decode$' => null, + '^base_convert$' => null, + '^basename$' => null, + '^chr$' => null, + '^convert_cyr_string$' => null, + '^dba_nextkey$' => null, + '^dns_get_record$' => null, + '^extract$' => null, + '^fdf_.*$' => null, + '^fget.*$' => null, + '^fread$' => null, + '^fflush$' => null, + '^get_browser$' => null, + '^get_headers$' => null, + '^get_meta_tags$' => null, + '^getallheaders$' => null, + '^getenv$' => null, + '^getopt$' => null, + '^headers_list$' => null, + '^hebrev$' => null, + '^hebrevc$' => null, + '^highlight_string$' => null, + '^html_entity_decode$' => null, + '^ibase_blob_import$' => null, + '^id3_get_tag$' => null, + '^import_request_variables$' => null, + '^ircg_nickname_unescape$' => null, + '^ldap_get_values$' => null, + '^mb_decode_mimeheader$' => null, + '^mb_parse_str$' => null, + '^mcrypt_decrypt$' => null, + '^mdecrypt_generic$' => null, + '^msg_receive$' => null, + '^ngettext$' => null, + '^ob_get_contents$' => null, + '^ob_get_flush$' => null, + '^rawurldecode$' => null, + '^shm_get_var$' => null, + '^stripcslashes$' => null, + '^stripslashes$' => null, + '^token_get_all$' => null, + '^unpack$' => null, + '^convert_uudecode$' => null, + '^iconv_mime_decode$' => null, + '^iconv_mime_decode_headers$' => null, + '^iconv_mime_encode$' => null, + '^iconv_set_encoding$' => null, + '^php_strip_whitespace$' => null, + '^addcslashes$' => null, + '^addslashes$' => null, + '^escapeshellarg$' => null, + '^escapeshellcmd$' => null, + '^gettype$' => null, + '^var_dump$' => null, + '^tempnam$' => null, + '^realpath$' => null, + '^linkinfo$' => null, + '^lstat$' => null, + '^stat$' => null, + '^lchgrp$' => null, + '^lchown$' => null, + '^show_source$' => null, + '^is_dir$' => null, + '^is_executable$' => null, + '^is_file$' => null, + '^is_link$' => null, + '^is_readable$' => null, + '^is_writable$' => null, + '^is_writeable$' => null, + '^is_uploaded_file$' => null, + '^glob$' => null, + '^ssh2_.*$' => null, + '^delete$' => null, + '^file.*$' => null, + '^chop$' => 'rtrim()', + '^sizeof$' => 'count()', + '^is_null$' => 'strict comparison "=== null"', + '^intval$' => '(int) construction', + '^strval$' => '(string) construction', + '^md5$' => 'improved hash functions (SHA-256, SHA-512 etc.)', + '^serialize$' => 'json_encode', + '^unserialize$' => 'json_decode', + ]; + + /** + * Generates warning for this sniff. + * + * @param File $phpcsFile The file being scanned. + * @param int $stackPtr The position of the forbidden function in the token array. + * @param string $function The name of the forbidden function. + * @param string $pattern The pattern used for the match. + * + * @return void + */ + protected function addError($phpcsFile, $stackPtr, $function, $pattern = null) + { + $data = [$function]; + $warningMessage = 'The use of function %s() is discouraged'; + $warningCode = 'Found'; + if ($pattern === null) { + $pattern = $function; + } + if ($this->forbiddenFunctions[$pattern] !== null) { + $warningCode .= 'WithAlternative'; + $data[] = $this->forbiddenFunctions[$pattern]; + $warningMessage .= '; use %s instead.'; + } + $phpcsFile->addWarning($warningMessage, $stackPtr, $warningCode, $data); + } +} diff --git a/Magento/Sniffs/PHP/GotoSniff.php b/Magento/Sniffs/PHP/GotoSniff.php new file mode 100644 index 00000000..0a8dcdc4 --- /dev/null +++ b/Magento/Sniffs/PHP/GotoSniff.php @@ -0,0 +1,45 @@ +addError($this->errorMessage, $stackPtr, $this->errorCode); + } +} diff --git a/Magento/Sniffs/PHP/ReturnValueCheckSniff.php b/Magento/Sniffs/PHP/ReturnValueCheckSniff.php new file mode 100644 index 00000000..a51b926f --- /dev/null +++ b/Magento/Sniffs/PHP/ReturnValueCheckSniff.php @@ -0,0 +1,166 @@ +tokens = $phpcsFile->getTokens(); + $this->file = $phpcsFile; + $this->leftLimit = $open = $this->tokens[$stackPtr]['parenthesis_opener']; + $this->rightLimit = $close = $this->tokens[$stackPtr]['parenthesis_closer']; + for ($i = ($open + 1); $i < $close; $i++) { + if (($this->tokens[$i]['code'] === T_STRING && in_array($this->tokens[$i]['content'], $this->functions)) + && (!$this->findIdentical($i - 1, $this->findFunctionParenthesisCloser($i) + 1)) + ) { + $foundFunctionName = $this->tokens[$i]['content']; + $phpcsFile->addError($this->errorMessage, $i, $this->errorCode, [$foundFunctionName]); + } + } + } + + /** + * Recursively finds identical operators in current scope. + * + * @param int $leftCurrentPosition + * @param int $rightCurrentPosition + * @return bool + */ + protected function findIdentical($leftCurrentPosition, $rightCurrentPosition) + { + $leftBound = $this->file->findPrevious($this->leftRangeTokens, $leftCurrentPosition, $this->leftLimit - 1); + $rightBound = $this->file->findNext($this->rightRangeTokens, $rightCurrentPosition, $this->rightLimit + 1); + $leftToken = $this->tokens[$leftBound]; + $rightToken = $this->tokens[$rightBound]; + if ($leftToken['code'] === T_OPEN_PARENTHESIS && $rightToken['code'] === T_CLOSE_PARENTHESIS) { + return $this->findIdentical($leftBound - 1, $rightBound + 1); + } else { + return ( + in_array($leftToken['code'], $this->identical) || in_array($rightToken['code'], $this->identical) + ) ?: false; + } + } + + /** + * Finds the position of close parenthesis of detected function. + * + * @param int $currentPosition + * @return mixed + */ + protected function findFunctionParenthesisCloser($currentPosition) + { + $nextOpenParenthesis = $this->file->findNext(T_OPEN_PARENTHESIS, $currentPosition, $this->rightLimit); + return $nextOpenParenthesis ? $this->tokens[$nextOpenParenthesis]['parenthesis_closer'] : false; + } +} diff --git a/Magento/Sniffs/PHP/VarSniff.php b/Magento/Sniffs/PHP/VarSniff.php new file mode 100644 index 00000000..e150bf1e --- /dev/null +++ b/Magento/Sniffs/PHP/VarSniff.php @@ -0,0 +1,45 @@ +addWarning($this->warningMessage, $stackPtr, $this->warningCode); + } +} diff --git a/Magento/Sniffs/Performance/EmptyCheckSniff.php b/Magento/Sniffs/Performance/EmptyCheckSniff.php new file mode 100644 index 00000000..5afd2abd --- /dev/null +++ b/Magento/Sniffs/Performance/EmptyCheckSniff.php @@ -0,0 +1,141 @@ + [ + // phpcs:ignore Generic.Files.LineLength.TooLong + 'message' => 'count(...) function should not be used to check if array is empty. Use empty(...) language construct instead', + 'code' => 'FoundCount' + ], + 'strlen' => [ + // phpcs:ignore Generic.Files.LineLength.TooLong + 'message' => 'strlen(...) function should not be used to check if string is empty. Consider replace with (... === "") or (... !== "")', + 'code' => 'FoundStrlen' + ], + ]; + + /** + * All tokens from current file. + * + * @var array + */ + private $tokens; + + /** + * List of comparison operators that are used to check if statement is empty. + * + * @var array + */ + protected $comparisonOperators = [ + T_GREATER_THAN, + T_IS_NOT_IDENTICAL, + T_IS_NOT_EQUAL + ]; + + /** + * List of all other comparison operators that can follow the statement. + * + * @var array + */ + protected $otherComparisonOperators = [ + T_IS_GREATER_OR_EQUAL, + T_LESS_THAN, + T_IS_SMALLER_OR_EQUAL, + T_IS_IDENTICAL, + T_IS_EQUAL + ]; + + /** + * List of logic operators that show an end of condition. + * + * @var array + */ + protected $logicOperators = [ + T_BOOLEAN_AND, + T_BOOLEAN_OR, + T_LOGICAL_AND, + T_LOGICAL_OR + ]; + + /** + * @inheritdoc + */ + public function register() + { + return [T_IF, T_ELSEIF]; + } + + /** + * @inheritdoc + */ + public function process(File $phpcsFile, $stackPtr) + { + $this->tokens = $phpcsFile->getTokens(); + $functionPosition = $this->findFunctionPosition($stackPtr); + if ($functionPosition !== false + && array_key_exists('nested_parenthesis', $this->tokens[$functionPosition]) + ) { + $openParenthesisPosition = key($this->tokens[$functionPosition]['nested_parenthesis']); + $endOfStatementPosition = $this->tokens[$openParenthesisPosition]['parenthesis_closer']; + $nextOperatorPosition = $phpcsFile->findNext( + $this->logicOperators, + $functionPosition, + $endOfStatementPosition + ); + if ($nextOperatorPosition !== false) { + $endOfStatementPosition = $nextOperatorPosition; + } + $operatorPosition = $phpcsFile->findNext( + $this->comparisonOperators, + $functionPosition, + $endOfStatementPosition + ); + $code = $this->map[$this->tokens[$functionPosition]['content']]['code']; + $message = $this->map[$this->tokens[$functionPosition]['content']]['message']; + if ($operatorPosition !== false) { + if ($phpcsFile->findNext(T_LNUMBER, $operatorPosition, $endOfStatementPosition, false, '0') !== false) { + $phpcsFile->addWarning($message, $stackPtr, $code); + } + } else { + // phpcs:ignore Generic.Files.LineLength.TooLong + if ($phpcsFile->findNext($this->otherComparisonOperators, $functionPosition, $endOfStatementPosition) === false) { + $phpcsFile->addWarning($message, $stackPtr, $code); + } + } + } + } + + /** + * Find the position of discouraged function between parenthesis. + * + * @param int $index + * @return mixed + */ + private function findFunctionPosition($index) + { + // phpcs:ignore Generic.Files.LineLength.TooLong + for ($i = $this->tokens[$index]['parenthesis_opener'] + 1; $i < $this->tokens[$index]['parenthesis_closer']; $i++) { + if (array_key_exists($this->tokens[$i]['content'], $this->map)) { + return $i; + } + } + return false; + } +} diff --git a/Magento/Sniffs/Security/IncludeFileSniff.php b/Magento/Sniffs/Security/IncludeFileSniff.php new file mode 100644 index 00000000..9aac21e2 --- /dev/null +++ b/Magento/Sniffs/Security/IncludeFileSniff.php @@ -0,0 +1,101 @@ +getTokens(); + $firstToken = $phpcsFile->findNext(Tokens::$emptyTokens, $stackPtr + 1, null, true); + $message = '"%s" statement detected. File manipulations are discouraged.'; + if ($tokens[$firstToken]['code'] === T_OPEN_PARENTHESIS) { + $message .= ' Statement is not a function, no parentheses are required.'; + $firstToken = $phpcsFile->findNext(Tokens::$emptyTokens, $firstToken + 1, null, true); + } + $nextToken = $firstToken; + $ignoredTokens = array_merge(Tokens::$emptyTokens, [T_CLOSE_PARENTHESIS]); + $isConcatenated = false; + $isUrl = false; + $hasVariable = false; + $includePath = ''; + while ($tokens[$nextToken]['code'] !== T_SEMICOLON && + $tokens[$nextToken]['code'] !== T_CLOSE_TAG) { + switch ($tokens[$nextToken]['code']) { + case T_CONSTANT_ENCAPSED_STRING: + $includePath = trim($tokens[$nextToken]['content'], '"\''); + if (preg_match($this->urlPattern, $includePath)) { + $isUrl = true; + } + break; + case T_STRING_CONCAT: + $isConcatenated = true; + break; + case T_VARIABLE: + $hasVariable = true; + break; + } + $nextToken = $phpcsFile->findNext($ignoredTokens, $nextToken + 1, null, true); + } + if ($tokens[$stackPtr]['level'] === 0 && stripos($includePath, 'controller') !== false) { + $nextToken = $phpcsFile->findNext(T_CLASS, $nextToken + 1); + if ($nextToken) { + $nextToken = $phpcsFile->findNext(Tokens::$emptyTokens, $nextToken + 1, null, true); + $className = $tokens[$nextToken]['content']; + if (strripos($className, 'controller') !== false) { + return; + } + } + } + if ($isUrl) { + $message .= ' Passing urls is forbidden.'; + } + if ($isConcatenated) { + $message .= ' Concatenating is forbidden.'; + } + if ($hasVariable) { + $message .= ' Variables inside are insecure.'; + } + $phpcsFile->addWarning( + $message, + $stackPtr, + $this->warningCode, + [$tokens[$stackPtr]['content']] + ); + } +} diff --git a/Magento/Sniffs/Security/LanguageConstructSniff.php b/Magento/Sniffs/Security/LanguageConstructSniff.php new file mode 100644 index 00000000..78a71f5a --- /dev/null +++ b/Magento/Sniffs/Security/LanguageConstructSniff.php @@ -0,0 +1,85 @@ +getTokens(); + if ($tokens[$stackPtr]['code'] === T_BACKTICK) { + if ($phpcsFile->findNext(T_BACKTICK, $stackPtr + 1)) { + return; + } + $phpcsFile->addError($this->errorMessageBacktick, $stackPtr, $this->backtickCode); + return; + } + if ($tokens[$stackPtr]['code'] === T_EXIT) { + $code = $this->exitUsage; + } else { + $code = $this->directOutput; + } + $phpcsFile->addError($this->errorMessage, $stackPtr, $code, [$tokens[$stackPtr]['content']]); + } +} diff --git a/Magento/Sniffs/Security/SuperglobalSniff.php b/Magento/Sniffs/Security/SuperglobalSniff.php new file mode 100644 index 00000000..a87346f8 --- /dev/null +++ b/Magento/Sniffs/Security/SuperglobalSniff.php @@ -0,0 +1,96 @@ +getTokens(); + $var = $tokens[$stackPtr]['content']; + if (in_array($var, $this->superGlobalErrors)) { + $phpcsFile->addError( + $this->errorMessage, + $stackPtr, + $this->errorCode, + [$var] + ); + } elseif (in_array($var, $this->superGlobalWarning)) { + $phpcsFile->addWarning( + $this->warningMessage, + $stackPtr, + $this->warningCode, + [$var] + ); + } + } +} diff --git a/Magento/Sniffs/Security/XssTemplateSniff.php b/Magento/Sniffs/Security/XssTemplateSniff.php new file mode 100644 index 00000000..1ee8bf84 --- /dev/null +++ b/Magento/Sniffs/Security/XssTemplateSniff.php @@ -0,0 +1,332 @@ +file = $phpcsFile; + $this->tokens = $this->file->getTokens(); + + $annotation = $this->findSpecialAnnotation($stackPtr); + if ($annotation !== false) { + foreach ($this->allowedAnnotations as $allowedAnnotation) { + if (strpos($this->tokens[$annotation]['content'], $allowedAnnotation) !== false) { + return; + } + } + $this->hasDisallowedAnnotation = true; + } + + $endOfStatement = $phpcsFile->findNext([T_CLOSE_TAG, T_SEMICOLON], $stackPtr); + $this->addStatement($stackPtr + 1, $endOfStatement); + + while ($this->statements) { + $statement = array_shift($this->statements); + $this->detectUnescapedString($statement); + } + } + + /** + * Finds special annotations which are used for mark is output should be escaped. + * + * @param int $stackPtr + * @return int|bool + */ + private function findSpecialAnnotation($stackPtr) + { + if ($this->tokens[$stackPtr]['code'] === T_ECHO) { + $startOfStatement = $this->file->findPrevious(T_OPEN_TAG, $stackPtr); + return $this->file->findPrevious(T_COMMENT, $stackPtr, $startOfStatement); + } + return false; + } + + /** + * Find unescaped statement by following rules: + * + * See http://devdocs.magento.com/guides/v2.0/frontend-dev-guide/templates/template-security.html + * + * @param array $statement + * @return void + */ + private function detectUnescapedString($statement) + { + $posOfFirstElement = $this->file->findNext( + [T_WHITESPACE, T_COMMENT], + $statement['start'], + $statement['end'], + true + ); + if ($this->tokens[$posOfFirstElement]['code'] === T_OPEN_PARENTHESIS) { + $posOfLastElement = $this->file->findPrevious( + T_WHITESPACE, + $statement['end'] - 1, + $statement['start'], + true + ); + if ($this->tokens[$posOfFirstElement]['parenthesis_closer'] === $posOfLastElement) { + $this->addStatement($posOfFirstElement + 1, $this->tokens[$posOfFirstElement]['parenthesis_closer']); + return; + } + } + if ($this->parseLineStatement($statement['start'], $statement['end'])) { + return; + } + + $posOfArithmeticOperator = $this->findNextInScope( + [T_PLUS, T_MINUS, T_DIVIDE, T_MULTIPLY, T_MODULUS, T_POW], + $statement['start'], + $statement['end'] + ); + if ($posOfArithmeticOperator !== false) { + return; + } + switch ($this->tokens[$posOfFirstElement]['code']) { + case T_STRING: + if (!in_array($this->tokens[$posOfFirstElement]['content'], $this->allowedFunctions)) { + $this->addWarning($posOfFirstElement); + } + break; + case T_START_HEREDOC: + case T_DOUBLE_QUOTED_STRING: + $this->addWarning($posOfFirstElement); + break; + case T_VARIABLE: + $posOfObjOperator = $this->findLastInScope(T_OBJECT_OPERATOR, $posOfFirstElement, $statement['end']); + if ($posOfObjOperator === false) { + $this->addWarning($posOfFirstElement); + break; + } + $posOfMethod = $this->file->findNext([T_STRING, T_VARIABLE], $posOfObjOperator + 1, $statement['end']); + if ($this->tokens[$posOfMethod]['code'] === T_STRING && + (in_array($this->tokens[$posOfMethod]['content'], $this->allowedMethods) || + stripos($this->tokens[$posOfMethod]['content'], $this->methodNameContains) !== false) + ) { + break; + } else { + $this->addWarning($posOfMethod); + } + break; + case T_CONSTANT_ENCAPSED_STRING: + case T_DOUBLE_CAST: + case T_INT_CAST: + case T_BOOL_CAST: + default: + return; + } + } + + /** + * Split line from start to end by ternary operators and concatenations. + * + * @param int $start + * @param int $end + * @return bool + */ + private function parseLineStatement($start, $end) + { + $parsed = false; + $posOfLastInlineThen = $this->findLastInScope(T_INLINE_THEN, $start, $end); + if ($posOfLastInlineThen !== false) { + $posOfInlineElse = $this->file->findNext(T_INLINE_ELSE, $posOfLastInlineThen, $end); + $this->addStatement($posOfLastInlineThen + 1, $posOfInlineElse); + $this->addStatement($posOfInlineElse + 1, $end); + $parsed = true; + } else { + do { + $posOfConcat = $this->findNextInScope(T_STRING_CONCAT, $start, $end); + if ($posOfConcat !== false) { + $this->addStatement($start, $posOfConcat); + $parsed = true; + } elseif ($parsed) { + $this->addStatement($start, $end); + } + $start = $posOfConcat + 1; + } while ($posOfConcat !== false); + } + return $parsed; + } + + /** + * Push statement range in queue to check. + * + * @param int $start + * @param int $end + * @return void + */ + private function addStatement($start, $end) + { + $this->statements[] = [ + 'start' => $start, + 'end' => $end + ]; + } + + /** + * Finds next token position in current scope. + * + * @param int|array $types + * @param int $start + * @param int $end + * @return int|bool + */ + private function findNextInScope($types, $start, $end) + { + $types = (array)$types; + $next = $this->file->findNext(array_merge($types, [T_OPEN_PARENTHESIS]), $start, $end); + $nextToken = $this->tokens[$next]; + if ($nextToken['code'] === T_OPEN_PARENTHESIS) { + return $this->findNextInScope($types, $nextToken['parenthesis_closer'] + 1, $end); + } else { + return $next; + } + } + + /** + * Finds last token position in current scope. + * + * @param int|array $types + * @param int $start + * @param int $end + * @param int|bool $last + * @return int|bool + */ + private function findLastInScope($types, $start, $end, $last = false) + { + $types = (array)$types; + $nextInScope = $this->findNextInScope($types, $start, $end); + if ($nextInScope !== false && $nextInScope > $last) { + return $this->findLastInScope($types, $nextInScope + 1, $end, $nextInScope); + } else { + return $last; + } + } + + /** + * Adds CS warning message. + * + * @param int $position + * @return void + */ + private function addWarning($position) + { + if ($this->hasDisallowedAnnotation) { + $this->file->addWarning($this->warningMessage, $position, $this->warningCodeNotAllowed); + } else { + $this->file->addWarning($this->warningMessage, $position, $this->warningCodeUnescaped); + } + } +} diff --git a/Magento/Sniffs/Strings/RegExSniff.php b/Magento/Sniffs/Strings/RegExSniff.php new file mode 100644 index 00000000..df7e34e2 --- /dev/null +++ b/Magento/Sniffs/Strings/RegExSniff.php @@ -0,0 +1,85 @@ +getTokens(); + if (!in_array($tokens[$stackPtr]['content'], $this->functions)) { + return; + } + $prevToken = $phpcsFile->findPrevious(T_WHITESPACE, $stackPtr - 1, null, true); + if (in_array($tokens[$prevToken]['code'], $this->ignoreTokens)) { + return; + } + $nextToken = $phpcsFile->findNext([T_WHITESPACE, T_OPEN_PARENTHESIS], $stackPtr + 1, null, true); + if (in_array($tokens[$nextToken]['code'], Tokens::$stringTokens) + && preg_match('/[#\/|~\}\)][imsxADSUXJu]*e[imsxADSUXJu]*.$/', $tokens[$nextToken]['content']) + ) { + $phpcsFile->addError( + $this->errorMessage, + $stackPtr, + $this->errorCode, + [$tokens[$stackPtr]['content']] + ); + } + } +} diff --git a/Magento/Sniffs/Strings/StringConcatSniff.php b/Magento/Sniffs/Strings/StringConcatSniff.php new file mode 100644 index 00000000..78366f54 --- /dev/null +++ b/Magento/Sniffs/Strings/StringConcatSniff.php @@ -0,0 +1,59 @@ +getTokens(); + $prev = $phpcsFile->findPrevious(T_WHITESPACE, $stackPtr - 1, null, true); + $next = $phpcsFile->findNext(T_WHITESPACE, $stackPtr + 1, null, true); + if ($prev === false || $next === false) { + return; + } + $beforePrev = $phpcsFile->findPrevious(T_WHITESPACE, $prev - 1, null, true); + $stringTokens = Tokens::$stringTokens; + if ($tokens[$beforePrev]['code'] === T_STRING_CONCAT + || in_array($tokens[$prev]['code'], $stringTokens) + || in_array($tokens[$next]['code'], $stringTokens) + ) { + $phpcsFile->addWarning($this->warningMessage, $stackPtr, $this->warningCode); + } + } +} diff --git a/Magento/Sniffs/Templates/ThisInTemplateSniff.php b/Magento/Sniffs/Templates/ThisInTemplateSniff.php new file mode 100644 index 00000000..8c0337df --- /dev/null +++ b/Magento/Sniffs/Templates/ThisInTemplateSniff.php @@ -0,0 +1,49 @@ +getTokens(); + if ($tokens[$stackPtr]['content'] === '$this') { + $phpcsFile->addWarning($this->warningMessage, $stackPtr, $this->warningCode); + } + } +} diff --git a/Magento/Sniffs/Translation/ConstantUsageSniff.php b/Magento/Sniffs/Translation/ConstantUsageSniff.php new file mode 100644 index 00000000..2f149f94 --- /dev/null +++ b/Magento/Sniffs/Translation/ConstantUsageSniff.php @@ -0,0 +1,114 @@ +getTokens(); + $doubleColon = $tokens[$stackPtr]; + $currentLine = $doubleColon['line']; + $lineContent = $this->getLineContent($phpcsFile, $currentLine); + $previousLineContent = $this->getLineContent($phpcsFile, $currentLine - 1); + $previousLineRegexp = '~__\($|Phrase\($~'; + $currentLineRegexp = '~__\(.+\)|Phrase\(.+\)~'; + $currentLineMatch = preg_match($currentLineRegexp, $lineContent) !== 0; + $previousLineMatch = preg_match($previousLineRegexp, $previousLineContent) !== 0; + $this->previousLineContent = $lineContent; + $constantRegexp = '[^\'"]+::[A-Z_0-9]+.*'; + if ($currentLineMatch) { + $variableRegexp = "~__\({$constantRegexp}\)|Phrase\({$constantRegexp}\)~"; + if (preg_match($variableRegexp, $lineContent) !== 0) { + $phpcsFile->addWarning( + $this->warningMessage, + $this->getFirstLineToken($phpcsFile, $currentLine), + $this->warningCode + ); + } + } else { + if ($previousLineMatch) { + $variableRegexp = "~^\s+{$constantRegexp}~"; + if (preg_match($variableRegexp, $lineContent) !== 0) { + $phpcsFile->addWarning( + $this->warningMessage, + $this->getFirstLineToken($phpcsFile, $currentLine - 1), + $this->warningCode + ); + } + } + } + } + + /** + * Get line content by it's line number. + * + * @param File $phpcsFile + * @param int $line + * @return string + */ + private function getLineContent(File $phpcsFile, $line) + { + $tokens = $phpcsFile->getTokens(); + return implode('', array_column(array_filter($tokens, function ($item) use ($line) { + return $item['line'] == $line; + }), 'content')); + } + + /** + * Get index of first token in line. + * + * @param File $phpcsFile + * @param int $line + * @return int + */ + private function getFirstLineToken(File $phpcsFile, $line) + { + $tokens = $phpcsFile->getTokens(); + return array_keys(array_filter($tokens, function ($item) use ($line) { + return $item['line'] == $line; + }))[0]; + } +} diff --git a/Magento/Sniffs/Whitespace/MultipleEmptyLinesSniff.php b/Magento/Sniffs/Whitespace/MultipleEmptyLinesSniff.php new file mode 100644 index 00000000..639681ea --- /dev/null +++ b/Magento/Sniffs/Whitespace/MultipleEmptyLinesSniff.php @@ -0,0 +1,66 @@ +getTokens(); + if ($phpcsFile->hasCondition($stackPtr, T_FUNCTION) + || $phpcsFile->hasCondition($stackPtr, T_CLASS) + || $phpcsFile->hasCondition($stackPtr, T_INTERFACE) + ) { + if ($tokens[$stackPtr - 1]['line'] < $tokens[$stackPtr]['line'] + && $tokens[$stackPtr - 2]['line'] === $tokens[$stackPtr - 1]['line'] + ) { + // This is an empty line and the line before this one is not + // empty, so this could be the start of a multiple empty line block + $next = $phpcsFile->findNext(T_WHITESPACE, $stackPtr, null, true); + $lines = $tokens[$next]['line'] - $tokens[$stackPtr]['line']; + if ($lines > 1) { + $phpcsFile->addWarning( + $this->warningMessage, + $stackPtr, + $this->warningCode, + [$lines] + ); + } + } + } + } +} diff --git a/Magento/Tests/Classes/ObjectInstantiationUnitTest.inc b/Magento/Tests/Classes/ObjectInstantiationUnitTest.inc new file mode 100644 index 00000000..4fd399ab --- /dev/null +++ b/Magento/Tests/Classes/ObjectInstantiationUnitTest.inc @@ -0,0 +1,21 @@ + 1, + 6 => 1, + 8 => 1, + 10 => 1, + 12 => 1, + ]; + } +} diff --git a/Magento/Tests/CodeAnalysis/EmptyBlockUnitTest.inc b/Magento/Tests/CodeAnalysis/EmptyBlockUnitTest.inc new file mode 100644 index 00000000..2a50d42b --- /dev/null +++ b/Magento/Tests/CodeAnalysis/EmptyBlockUnitTest.inc @@ -0,0 +1,76 @@ +getTraceAsString(); + } +} + +try { + throw Exception('Error...'); +} catch (Exception $e) {} + +try { + throw Exception('Error...'); +} catch (Exception $e) { + // Handle this exception later :-) +} + +if (true) {} elseif (false) {} + +function emptyFunction () { /*Empty function block*/ } + +function nonEmptyFunction () { return true; } diff --git a/Magento/Tests/CodeAnalysis/EmptyBlockUnitTest.php b/Magento/Tests/CodeAnalysis/EmptyBlockUnitTest.php new file mode 100644 index 00000000..488c8015 --- /dev/null +++ b/Magento/Tests/CodeAnalysis/EmptyBlockUnitTest.php @@ -0,0 +1,45 @@ + 1, + 15 => 1, + 17 => 1, + 19 => 1, + 30 => 1, + 35 => 1, + 41 => 1, + 47 => 1, + 52 => 1, + 55 => 1, + 64 => 1, + 68 => 1, + 72 => 2, + 74 => 1, + ]; + } + + /** + * @inheritdoc + */ + public function getWarningList() + { + return []; + } +} diff --git a/Magento/Tests/Exceptions/DirectThrowUnitTest.inc b/Magento/Tests/Exceptions/DirectThrowUnitTest.inc new file mode 100644 index 00000000..1038bc00 --- /dev/null +++ b/Magento/Tests/Exceptions/DirectThrowUnitTest.inc @@ -0,0 +1,28 @@ +isEnabled) { + throw new Exception('Action disabled.'); + } + } + + public function exceptionTest() + { + if (!$this->isEnabled) { + throw new \Exception('Action disabled.'); + } + } + + public function localizedExceptionTest() + { + + if (!$this->isEnabled) { + throw new LocalizedException('Localized exception.'); + } + } +} diff --git a/Magento/Tests/Exceptions/DirectThrowUnitTest.php b/Magento/Tests/Exceptions/DirectThrowUnitTest.php new file mode 100644 index 00000000..cf98deb8 --- /dev/null +++ b/Magento/Tests/Exceptions/DirectThrowUnitTest.php @@ -0,0 +1,33 @@ + 1, + 17 => 1, + ]; + } +} diff --git a/Magento/Tests/Exceptions/NamespaceUnitTest.inc b/Magento/Tests/Exceptions/NamespaceUnitTest.inc new file mode 100644 index 00000000..c67f4569 --- /dev/null +++ b/Magento/Tests/Exceptions/NamespaceUnitTest.inc @@ -0,0 +1,62 @@ +setAuth($ch); + try { + switch (strtoupper($this->verb)) { + case 'GET': + $this->executeGet($ch); + break; + case 'POST': + $this->executePost($ch); + break; + case 'PUT': + $this->executePut($ch); + break; + case 'DELETE': + $this->executeDelete($ch); + break; + default: + throw new \InvalidArgumentException( + 'Current verb (' . $this->verb + . ') is an invalid REST verb.' + ); + } + } catch (InvalidArgumentException $e) { + curl_close($ch); + throw $e; + } catch (\Exception $e) { + curl_close($ch); + throw $e; + } + } +} + +try { + doSomethind(); +} catch (\Exception $e) { + logException($e->getMessage()); +} diff --git a/Magento/Tests/Exceptions/NamespaceUnitTest.php b/Magento/Tests/Exceptions/NamespaceUnitTest.php new file mode 100644 index 00000000..d52742a6 --- /dev/null +++ b/Magento/Tests/Exceptions/NamespaceUnitTest.php @@ -0,0 +1,34 @@ + 1, + 10 => 1, + 48 => 1, + ]; + } + + /** + * @inheritdoc + */ + public function getWarningList() + { + return []; + } +} diff --git a/Magento/Tests/Legacy/MageEntityUnitTest.inc b/Magento/Tests/Legacy/MageEntityUnitTest.inc new file mode 100644 index 00000000..d5be229e --- /dev/null +++ b/Magento/Tests/Legacy/MageEntityUnitTest.inc @@ -0,0 +1,16 @@ +getAttributeRawValue($categoryId, 'name', Mage::app()->getStore()); +$eavAttribute = new Mage_Eav_Model_Mysql4_Entity_Attribute(); +$lnk = Mage_Downloadable_Model_Link::getLinkDir(); +$lnk = Enterprise_Mage_Downloadable_Model_Link::getLinkDir(); +$lnk = new Enterprise_Mage_Downloadable_Model_Link; +$instance = new Mage(); + +$staticCall = SomeClass::call(); + +$directObject = new SomeClass; + +$instance = new MagentoAllowedClass(); +$model = MagentoAllowedClass :: getModel(); diff --git a/Magento/Tests/Legacy/MageEntityUnitTest.php b/Magento/Tests/Legacy/MageEntityUnitTest.php new file mode 100644 index 00000000..ebec4d6e --- /dev/null +++ b/Magento/Tests/Legacy/MageEntityUnitTest.php @@ -0,0 +1,38 @@ + 1, + 4 => 1, + 5 => 1, + 6 => 1, + 7 => 1, + 8 => 1, + 9 => 1 + ]; + } + + /** + * @inheritdoc + */ + public function getWarningList() + { + return []; + } +} diff --git a/Magento/Tests/NamingConvention/InterfaceNameUnitTest.inc b/Magento/Tests/NamingConvention/InterfaceNameUnitTest.inc new file mode 100644 index 00000000..fca78449 --- /dev/null +++ b/Magento/Tests/NamingConvention/InterfaceNameUnitTest.inc @@ -0,0 +1,5 @@ + 1, + 4 => 1, + 5 => 1, + ]; + } +} diff --git a/Magento/Tests/PHP/DateTimeUnitTest.inc b/Magento/Tests/PHP/DateTimeUnitTest.inc new file mode 100644 index 00000000..be0bdf49 --- /dev/null +++ b/Magento/Tests/PHP/DateTimeUnitTest.inc @@ -0,0 +1,33 @@ +localeDate = $localeDate; + } + + public function getDate() + { + return new \DateTime(); + } + + public function getTimeZone() + { + return new \DateTimeZone(); + } + + public function getTimeZoneInterfase() + { + return $this->localeDate->date(); + } +} diff --git a/Magento/Tests/PHP/DateTimeUnitTest.php b/Magento/Tests/PHP/DateTimeUnitTest.php new file mode 100644 index 00000000..e782ad8a --- /dev/null +++ b/Magento/Tests/PHP/DateTimeUnitTest.php @@ -0,0 +1,33 @@ + 1, + 26 => 1 + ]; + } +} diff --git a/Magento/Tests/PHP/DiscouragedFunctionUnitTest.inc b/Magento/Tests/PHP/DiscouragedFunctionUnitTest.inc new file mode 100644 index 00000000..a311427a --- /dev/null +++ b/Magento/Tests/PHP/DiscouragedFunctionUnitTest.inc @@ -0,0 +1,464 @@ + 'Radiohead']); + +$conn = ifx_connect('mydb@ol_srv1', 'username', 'password'); +ifx_close($conn); + +$src = imagecreatefromgif('php.gif'); +$img = imagecreatetruecolor(80, 40); + +$mbox = imap_open('{localhost:143}INBOX', 'username', 'password'); + +$conn = ingres_connect('mydb', 'username', 'password'); +ingres_close($conn); + +ircg_get_username(1); + +$conn = ldap_connect('ldap.example.com', 398); + +link('source.ext', 'newfile.ext'); + +mail('test@example.com', 'My Subject', 'Text message'); + +mb_send_mail('test@example.com', 'My Subject', 'Text message'); + +mkdir('/test1/test2', 0777, true); + +move_uploaded_file('name', 'dir_name'); + +msession_connect('host', 'port'); + +msg_send(msg_get_queue(1), 12, 'test', false); + +msql('db', 'query'); + +$conn = msql_connect('host'); +msql_close($conn); + +$conn = mssql_connect('TEST\SERVER', 'username', 'password'); +msql_close($conn); + +$conn = mysql_connect('localhost', 'username', 'password'); +if (!$conn) { + die('Could not connect: ' . mysql_error()); +} +mysql_close($conn); + +$connection = odbc_connect('Driver={SQL Server Native Client 10.0};Server=S;Database=DB;', 'username', 'password'); + +opendir('/etc/php5/'); + +openlog('test', LOG_PID, 1); + +$cursorId = ora_open($conn); +ora_do($cursorId, 'query'); + +$conn = ovrimos_connect('db_host', '8001', 'username', 'password'); +ovrimos_close($conn); + +$iniArray = parse_ini_file('sample.ini', true); + +$str = 'first=value&arr[]=foo+bar&arr[]=baz'; +parse_str($str); + +$url = 'http://username:password@hostname:9090/path?arg=value#anchor'; +parse_url($url, PHP_URL_USER); + +$ops = parsekit_compile_string('echo "Foo\n";', $errors); + +passthru('test.zip', $err); + +pcntl_alarm(300); + +posix_access('some_file', POSIX_R_OK | POSIX_W_OK); + +pfpro_init(); +pfpro_cleanup(); + +pfsockopen('ssl://www.example.com', 443, $errno, $errstr); + +$conn = pg_connect('dbname=test'); +pg_close($conn); + +php_check_syntax('filename'); + +$handle = popen('/bin/ls', 'r'); + +print_r(['key' => 'value']); + +printf('%d', '17,999'); + +proc_open('php', [0 => ['pipe', 'r']], $pipes, '/tmp', ['some_option' => 'test']); + +putenv('USER=test'); + +readfile('test.gif'); + +readgzfile('test.html.gz'); + +readline('Command: '); + +readlink('/vmlinuz'); + +register_shutdown_function(function () { + echo 'Script executed with success', PHP_EOL; +}); + +register_tick_function(function () { + echo 'cript executed with success', PHP_EOL; +}); + +rename('/tmp/tmp_file.txt', '/home/user/login/docs/my_file.txt'); + +rmdir('examples'); + +scandir('/tmp'); + +session_start(); + +set_include_path('/usr/lib/pear'); + +ini_set('display_errors', 1); + +set_time_limit(3); + +setcookie('TestCookie', 'Something from somewhere', time() + 3600); + +setlocale(LC_ALL, 'nl_NL'); + +setrawcookie('TestCookie', 'Something from somewhere', time() + 3600); + +shell_exec('ls -l'); + +sleep(10); + +socket_connect($socket, $address, $port); + +if ($stream = fopen('http://www.example.com', 'r')) { + echo stream_get_contents($stream, -1, 10); + fclose($stream); +} + +$conn = sybase_connect('SYBASE', '', ''); +sybase_close($conn); + +symlink('uploads.php', 'uploads'); + +syslog(LOG_WARNING, 'Message'); + +system('ls', $retval); + +touch('some_file.txt', time() - 3600); + +if ($divisor == 0) { + trigger_error('Cannot divide by zero', E_USER_ERROR); +} + +unlink('some_file.txt'); + +vprintf('%04d-%02d-%02d', explode('-', '1988-8-1')); + +mysqli_close($conn); + +$conn = oci_connect('username', 'password', 'localhost'); + +$conn = oci_pconnect('username', 'password', 'localhost'); + +quotemeta('Hello world. (can you hear me?)'); + +sqlite_popen('filename'); + +time_nanosleep(0, 500000000); + +base64_decode('VGhpcyBpcyBhbiBlbmNvZGVkIHN0cmluZw=='); + +base_convert('a37334', 16, 2); + +basename('/'); + +chr(27); + +convert_cyr_string('string', 'feom', 'to'); + +dba_nextkey($handle); + +dns_get_record('php.net'); + +$varArray = [ + 'color' => 'blue', + 'size' => 'medium', + 'shape' => 'sphere', +]; +extract($varArray, EXTR_PREFIX_SAME, 'wddx'); + +$outfdf = fdf_create(); +fdf_set_value($outfdf, 'volume', $volume, 0); + +$file = fopen(__FILE__, 'r'); +$input = fgetc($file); +$line = fgets($file); +$contents = fread($file, 100); +fflush($file); + +$browser = get_browser(null, true); + +get_headers('http://www.example.com'); + +$tags = get_meta_tags('http://www.example.com/'); + +$headers = getallheaders(); + +$ip = getenv('REMOTE_ADDR'); + +$options = getopt('f:hp:'); + +$headersList = headers_list(); + +$decodedText = hebrev('טקסטים מנוקדים'); + +$decodedText = hebrevc('טקסטים מנוקדים'); + +highlight_string('text"; ?>'); + +html_entity_decode('html<span>string</span>&<div>block</div>'); + +ibase_connect('/path/to/employees.gdb', 'username', 'password'); +$blob = ibase_blob_import($file); + +$tag = id3_get_tag('path/to/example.mp3'); + +import_request_variables('gP', 'rvar_'); + +$nickname = ircg_nickname_unescape('nickname'); + +$values = ldap_get_values('ds', 'entry', 'mail'); + +mb_decode_mimeheader($str); + +mb_parse_str('email=kehaovista@qq.com&city=shanghai&job=Phper', $result); + +$ivSize = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB); +$iv = mcrypt_create_iv($ivSize, MCRYPT_RAND); +mcrypt_decrypt(MCRYPT_RIJNDAEL_256, 'key', 'text', MCRYPT_MODE_ECB, $iv); + +$td = mcrypt_module_open('des', '', 'ecb', ''); +$cryptedText = mcrypt_generic($td, 'plain text'); +$plainText = mdecrypt_generic($td, $cryptedText); + +$key = msg_get_queue(ftok('/tmp/php_msgqueue.stat', 'R'), 0666 | IPC_CREAT); +msg_receive($key, 1, 1, 16384, 'message', true, 0); + +ngettext('%d window', '%d windows', 21); + +$out = ob_get_contents(); +$out = ob_get_flush(); + +rawurldecode('foo%20bar%40baz'); + +$var = shm_get_var(55, 'key'); + +$string = stripcslashes('He\xallo'); + +$string = stripslashes("Is your name O\'reilly?"); + +$tokens = token_get_all(''); + +$array = unpack('cchars/nint', '\x04\x00\xa0\x00'); + +$decodedText = convert_uudecode("+22!L;W9E(%!(4\"$`\n`"); + +$decodedText = iconv_mime_decode('Subject: =?UTF-8?B?UHLDvGZ1bmcgUHLDvGZ1bmc=?=', 0, 'ISO-8859-1'); + +$headersString = << +Received: from localhost (localhost [127.0.0.1]) by localhost + with SMTP id example for ; + Thu, 1 Jan 1970 00:00:00 +0000 (UTC) + (envelope-from example-return-0000-example=example.com@example.com) +Received: (qmail 0 invoked by uid 65534); 1 Thu 2003 00:00:00 +0000 +EOF; +$headers = iconv_mime_decode_headers($headersString, 0, 'ISO-8859-1'); + +$preferences = [ + 'input-charset' => 'ISO-8859-1', + 'output-charset' => 'UTF-8', + 'line-length' => 76, + 'line-break-chars' => "\n", + 'scheme' => 'Q', +]; +iconv_mime_encode('Subject', 'Prüfung Prüfung', $preferences); + +iconv_set_encoding('internal_encoding', 'UTF-8'); + +php_strip_whitespace(__FILE__); + +$connection = ssh2_connect('shell.example.com', 22); +$auth_methods = ssh2_auth_none($connection, 'user'); + +$lines = file(__FILE__); +$atime = fileatime(__FILE__); + +$message = addcslashes('foo[ ]', 'A..z'); + +$message = addslashes("Is your name O'Reilly?"); + +$message = escapeshellarg('shell:command:string'); + +$message = escapeshellcmd('shell string'); + +gettype(['a' => 5]); + +var_dump($message); + +tempnam('./tmp/', 'filePrefix'); + +realpath('./../../etc/passwd'); + +linkinfo('/'); + +lstat('./'); + +stat('./'); + +lchgrp('__FILE__', 8); + +lchown('__FILE__', 8); + +show_source(__FILE__); + +is_dir('./'); + +is_executable('./'); + +is_file('./'); + +is_link('./'); + +is_readable('./'); + +is_writable('./'); + +is_writeable('./'); + +is_uploaded_file('uploads.php'); + +glob('*.txt'); + +$size = sizeof($array); + +$check = is_null($size); + +$str = strval($str); + +$int = intval($int); + +$str = chop($text, 'ttt'); + +md5($text); diff --git a/Magento/Tests/PHP/DiscouragedFunctionUnitTest.php b/Magento/Tests/PHP/DiscouragedFunctionUnitTest.php new file mode 100644 index 00000000..8a3008fb --- /dev/null +++ b/Magento/Tests/PHP/DiscouragedFunctionUnitTest.php @@ -0,0 +1,263 @@ + 1, + 6 => 1, + 7 => 1, + 9 => 1, + 10 => 1, + 12 => 1, + 16 => 1, + 20 => 1, + 22 => 1, + 24 => 1, + 26 => 1, + 28 => 1, + 30 => 1, + 32 => 1, + 34 => 1, + 36 => 1, + 37 => 1, + 38 => 1, + 39 => 1, + 40 => 1, + 42 => 1, + 44 => 1, + 45 => 1, + 47 => 1, + 48 => 1, + 50 => 1, + 51 => 1, + 52 => 1, + 54 => 1, + 56 => 1, + 58 => 1, + 60 => 1, + 62 => 1, + 63 => 1, + 65 => 1, + 67 => 1, + 69 => 1, + 71 => 1, + 73 => 1, + 74 => 1, + 76 => 1, + 77 => 1, + 78 => 1, + 80 => 1, + 82 => 1, + 84 => 1, + 85 => 1, + 86 => 1, + 88 => 1, + 89 => 1, + 90 => 1, + 91 => 1, + 93 => 1, + 95 => 1, + 96 => 1, + 97 => 1, + 99 => 1, + 101 => 1, + 103 => 1, + 104 => 1, + 106 => 1, + 108 => 1, + 109 => 1, + 111 => 1, + 112 => 1, + 114 => 1, + 116 => 1, + 117 => 1, + 119 => 1, + 121 => 1, + 123 => 1, + 125 => 1, + 127 => 1, + 129 => 1, + 131 => 1, + 133 => 1, + 135 => 1, + 137 => 1, + 139 => 1, + 140 => 1, + 142 => 1, + 143 => 1, + 145 => 1, + 147 => 1, + 149 => 1, + 151 => 1, + 153 => 1, + 155 => 1, + 157 => 1, + 158 => 1, + 160 => 1, + 161 => 1, + 163 => 1, + 166 => 1, + 169 => 1, + 171 => 1, + 173 => 1, + 175 => 1, + 177 => 1, + 179 => 1, + 180 => 1, + 182 => 1, + 184 => 1, + 185 => 1, + 187 => 1, + 189 => 1, + 191 => 1, + 193 => 1, + 195 => 1, + 197 => 1, + 199 => 1, + 201 => 1, + 203 => 1, + 205 => 1, + 207 => 1, + 211 => 1, + 215 => 1, + 217 => 1, + 219 => 1, + 221 => 1, + 223 => 1, + 225 => 1, + 227 => 1, + 229 => 1, + 231 => 1, + 233 => 1, + 235 => 1, + 237 => 1, + 239 => 1, + 241 => 1, + 242 => 1, + 243 => 1, + 246 => 1, + 247 => 1, + 249 => 1, + 251 => 1, + 253 => 1, + 255 => 1, + 258 => 1, + 261 => 1, + 263 => 1, + 265 => 1, + 267 => 1, + 269 => 1, + 271 => 1, + 273 => 1, + 275 => 1, + 277 => 1, + 279 => 1, + 281 => 1, + 283 => 1, + 285 => 1, + 287 => 1, + 289 => 1, + 296 => 1, + 298 => 1, + 299 => 1, + 301 => 1, + 302 => 1, + 303 => 1, + 304 => 1, + 305 => 1, + 307 => 1, + 309 => 1, + 311 => 1, + 313 => 1, + 315 => 1, + 317 => 1, + 319 => 1, + 321 => 1, + 323 => 1, + 325 => 1, + 327 => 1, + 329 => 1, + 330 => 1, + 332 => 1, + 334 => 1, + 338 => 1, + 336 => 1, + 340 => 1, + 342 => 1, + 346 => 1, + 350 => 1, + 353 => 1, + 355 => 1, + 357 => 1, + 358 => 1, + 360 => 1, + 362 => 1, + 364 => 1, + 366 => 1, + 368 => 1, + 370 => 1, + 372 => 1, + 374 => 1, + 387 => 1, + 396 => 1, + 398 => 1, + 400 => 1, + 402 => 1, + 403 => 1, + 405 => 1, + 406 => 1, + 408 => 1, + 410 => 1, + 412 => 1, + 414 => 1, + 416 => 1, + 418 => 1, + 420 => 1, + 422 => 1, + 424 => 1, + 426 => 1, + 428 => 1, + 430 => 1, + 432 => 1, + 434 => 1, + 436 => 1, + 438 => 1, + 440 => 1, + 442 => 1, + 444 => 1, + 446 => 1, + 448 => 1, + 450 => 1, + 452 => 1, + 454 => 1, + 456 => 1, + 458 => 1, + 460 => 1, + 462 => 1, + 464 => 1, + ]; + } +} diff --git a/Magento/Tests/PHP/GotoUnitTest.inc b/Magento/Tests/PHP/GotoUnitTest.inc new file mode 100644 index 00000000..1ac56534 --- /dev/null +++ b/Magento/Tests/PHP/GotoUnitTest.inc @@ -0,0 +1,21 @@ + 1, + 4 => 1, + 15 => 1, + ]; + } + + /** + * @inheritdoc + */ + public function getWarningList() + { + return []; + } +} diff --git a/Magento/Tests/PHP/ReturnValueCheckUnitTest.inc b/Magento/Tests/PHP/ReturnValueCheckUnitTest.inc new file mode 100644 index 00000000..6135ade2 --- /dev/null +++ b/Magento/Tests/PHP/ReturnValueCheckUnitTest.inc @@ -0,0 +1,116 @@ +getId() === 'store_id' || $column->getId() === 'status') && $column->getFilter()->getValue() + && (strpos($column->getFilter()->getValue(), ',') !== false)) { + // +} + +if (($column->getId() === 'store_id' || $column->getId() === 'status') && $column->getFilter()->getValue() + && (strpos($column->getFilter()->getValue(), ',') != false)) { + // +} + +if (array_search($needle, $haystack)) { + // +} + +if (((!array_search($needle, $haystack)))) { + // +} + +if (!array_search($needle, $haystack) != false) { + // +} + +if (((array_search($needle, $haystack))) !== false) { + // +} diff --git a/Magento/Tests/PHP/ReturnValueCheckUnitTest.php b/Magento/Tests/PHP/ReturnValueCheckUnitTest.php new file mode 100644 index 00000000..e9ce6858 --- /dev/null +++ b/Magento/Tests/PHP/ReturnValueCheckUnitTest.php @@ -0,0 +1,49 @@ + 1, + 8 => 1, + 12 => 1, + 16 => 1, + 20 => 1, + 24 => 1, + 32 => 1, + 40 => 1, + 44 => 1, + 72 => 1, + 76 => 1, + 80 => 2, + 85 => 1, + 87 => 1, + 98 => 1, + 102 => 1, + 106 => 1, + 110 => 1, + ]; + } + + /** + * @inheritdoc + */ + public function getWarningList() + { + return []; + } +} diff --git a/Magento/Tests/PHP/VarUnitTest.inc b/Magento/Tests/PHP/VarUnitTest.inc new file mode 100644 index 00000000..8803c979 --- /dev/null +++ b/Magento/Tests/PHP/VarUnitTest.inc @@ -0,0 +1,16 @@ + 1, + 10 => 1, + 11 => 1, + 12 => 1, + ]; + } +} diff --git a/Magento/Tests/Performance/EmptyCheckUnitTest.inc b/Magento/Tests/Performance/EmptyCheckUnitTest.inc new file mode 100644 index 00000000..be2d1bd1 --- /dev/null +++ b/Magento/Tests/Performance/EmptyCheckUnitTest.inc @@ -0,0 +1,105 @@ + 0) { + // +} + +if ((anotherFunc($array) !== 0) && count($array) > 0) { + // +} + +if ((count($array) !== 0) && (((anotherFunc($array))))) { + // +} + +if (((count($array)))) { + // +} + +if (count($array) && (anotherFunc($array) !== 0)) { + // +} + +if ($findme === 'a' && (count($array) || $findme !== 'b') && $mystring !== false) { + // +} + +if ($findme === 'a' && (count($array) != 0 || $findme !== 'b') && $mystring !== false) { + // +} + +if ($findme === 'a' && (count($array) > 10 || $findme !== 'b') && $mystring !== false) { + // +} + +if (($column->getId() === 'store_id' || count($array) > 0 || $column->getId() === 'status') && $column->getFilter()->getValue()) { + // +} + +$length = count($array); + +if ('count' != $foo && count($bar)) { + // +} + +if ($findme === 'a' and (count($array) != 0 or $findme !== 'b') and $mystring !== false) { + // +} + +if (strlen($string) > 0) { + // +} + +if ((anotherFunc($string) !== 0) && strlen($string) > 0) { + // +} + +if ((strlen($string) !== 0) && (((anotherFunc($string))))) { + // +} + +if (((strlen($string)))) { + // +} + +if (strlen($string) && (anotherFunc($string) !== 0)) { + // +} + +if ($findme === 'a' && (strlen($string) || $findme !== 'b') && $mystring !== false) { + // +} + +if ($findme === 'a' && (strlen($string) != 0 || $findme !== 'b') && $mystring !== false) { + // +} + +if ($findme === 'a' && (strlen($string) > 10 || $findme !== 'b') && $mystring !== false) { + // +} + +if (($column->getId() === 'store_id' || strlen($string) > 0 || $column->getId() === 'status') && $column->getFilter()->getValue()) { + // +} + +if (strlen($string . implode(',', $array)) && (anotherFunc($string) !== 0)) { + // +} + +if (strlen($string . implode(',', $array)) > 10 && (anotherFunc($string) !== 0)) { + // +} + +$length = strlen($string); + +if ($findme === 'a' and (strlen($string) > 0 or $findme !== 'b') and $mystring !== false) { + // +} + +if (strlen($string) < $limit) { + // +} + +if (strlen($string) >= getLimit()) { + // +} diff --git a/Magento/Tests/Performance/EmptyCheckUnitTest.php b/Magento/Tests/Performance/EmptyCheckUnitTest.php new file mode 100644 index 00000000..0925a9d5 --- /dev/null +++ b/Magento/Tests/Performance/EmptyCheckUnitTest.php @@ -0,0 +1,51 @@ + 1, + 7 => 1, + 11 => 1, + 15 => 1, + 19 => 1, + 23 => 1, + 27 => 1, + 35 => 1, + 41 => 1, + 45 => 1, + 49 => 1, + 53 => 1, + 57 => 1, + 61 => 1, + 65 => 1, + 69 => 1, + 73 => 1, + 81 => 1, + 85 => 1, + 95 => 1, + ]; + } +} diff --git a/Magento/Tests/Security/IncludeFileUnitTest.inc b/Magento/Tests/Security/IncludeFileUnitTest.inc new file mode 100644 index 00000000..b63470b1 --- /dev/null +++ b/Magento/Tests/Security/IncludeFileUnitTest.inc @@ -0,0 +1,42 @@ + 1, + 4 => 1, + 6 => 1, + 7 => 1, + 9 => 1, + 10 => 1, + 12 => 1, + 13 => 1, + 15 => 1, + 17 => 1, + 23 => 1, + 24 => 1, + 28 => 1, + 34 => 1, + ]; + } +} diff --git a/Magento/Tests/Security/LanguageConstructUnitTest.inc b/Magento/Tests/Security/LanguageConstructUnitTest.inc new file mode 100644 index 00000000..ac927194 --- /dev/null +++ b/Magento/Tests/Security/LanguageConstructUnitTest.inc @@ -0,0 +1,15 @@ + 1, + 8 => 1, + 10 => 1, + 14 => 1, + 15 => 1, + ]; + } + + /** + * @inheritdoc + */ + public function getWarningList() + { + return []; + } +} diff --git a/Magento/Tests/Security/SuperglobalUnitTest.inc b/Magento/Tests/Security/SuperglobalUnitTest.inc new file mode 100644 index 00000000..d750570d --- /dev/null +++ b/Magento/Tests/Security/SuperglobalUnitTest.inc @@ -0,0 +1,10 @@ + 1, + 3 => 1, + 4 => 1, + 5 => 1, + 6 => 1, + 7 => 1, + 8 => 1, + ]; + } + + /** + * @inheritdoc + */ + public function getWarningList() + { + return [ + 9 => 1, + 10 => 1, + ]; + } +} diff --git a/Magento/Tests/Security/XssTemplateUnitTest.inc b/Magento/Tests/Security/XssTemplateUnitTest.inc new file mode 100644 index 00000000..95214531 --- /dev/null +++ b/Magento/Tests/Security/XssTemplateUnitTest.inc @@ -0,0 +1,58 @@ + + +getSomeData(); echo $block->getSomeData(); /* @escapeNotVerified */ echo $block->getSomeData();?> +getTitle();?> +getSomeMethod($block->getHtmlId());?> + +escapeUrl($var) . $var . 'bla';?> + + + + +methodHtml() . + $var . + $block->getSomeData(); +?> +escapeQuote($data['parentSymbol']) . '\''; ?> +escapeQuote($data['parentSymbol']) . "\""; ?> + +getExtendedElement($switchAttributeCode)->print() : 5; ?> + + +escapeUrl( $block->my_funct() . $var) : (false) ? sizeof ($var) :'bla bla'); ?> + + + + +" /> +echo $var; +getHtmlId("bla bla") ?> +getIdHtml("bla bla") ?> +getIdHtml("bla bla"); ?> + + + + + + + + +methodHtml(); ?> + +methodHtml() . + (bool)$var . + $block->escapeXssInUrl("bla bla"); +?> +escapeQuote($data['parentSymbol']) . '\''; ?> +getExtendedElement($switchAttributeCode)->toHtml(); ?> +escapeHtml($_filter->getFilter()->getClearLinkText()) ?> +default) ? $block->escapeHtml(__('Yes')) : $block->escapeHtml(__('No')); ?> +getExtendedElement($switchAttributeCode)->toHtml() : 5; ?> + + +escapeJs($js); ?> +escapeCss($css); ?> +getJsLayout($jsLayout); ?> diff --git a/Magento/Tests/Security/XssTemplateUnitTest.php b/Magento/Tests/Security/XssTemplateUnitTest.php new file mode 100644 index 00000000..2aff3903 --- /dev/null +++ b/Magento/Tests/Security/XssTemplateUnitTest.php @@ -0,0 +1,48 @@ + 2, + 4 => 1, + 5 => 1, + 6 => 1, + 7 => 1, + 8 => 1, + 9 => 1, + 10 => 1, + 13 => 1, + 14 => 1, + 16 => 1, + 17 => 1, + 18 => 1, + 19 => 1, + 20 => 1, + 21 => 1, + 25 => 2, + ]; + } +} diff --git a/Magento/Tests/Strings/RegExUnitTest.inc b/Magento/Tests/Strings/RegExUnitTest.inc new file mode 100644 index 00000000..27809a90 --- /dev/null +++ b/Magento/Tests/Strings/RegExUnitTest.inc @@ -0,0 +1,26 @@ +(.*?))xes', '"" . strtoupper("$2") . ""', $html); + +$a = preg_replace( + '#(.*?)#e', + '"" . strtoupper("$2") . ""', + $html +); + +$string = 'April 15, 2003'; +$replacement = '${1}1,$3'; +$b = preg_replace('/(\w+) (\d+), (\d+)/i', $replacement, $string); diff --git a/Magento/Tests/Strings/RegExUnitTest.php b/Magento/Tests/Strings/RegExUnitTest.php new file mode 100644 index 00000000..6ec3b53e --- /dev/null +++ b/Magento/Tests/Strings/RegExUnitTest.php @@ -0,0 +1,35 @@ + 1, + 10 => 1, + 16 => 1, + 18 => 1, + ]; + } + + /** + * @inheritdoc + */ + public function getWarningList() + { + return []; + } +} diff --git a/Magento/Tests/Strings/StringConcatUnitTest.inc b/Magento/Tests/Strings/StringConcatUnitTest.inc new file mode 100644 index 00000000..36be1e4f --- /dev/null +++ b/Magento/Tests/Strings/StringConcatUnitTest.inc @@ -0,0 +1,15 @@ + 1, + 4 => 1, + 6 => 1, + 10 => 1, + 11 => 1, + 15 => 1, + ]; + } +} diff --git a/Magento/Tests/Templates/ThisInTemplateUnitTest.inc b/Magento/Tests/Templates/ThisInTemplateUnitTest.inc new file mode 100644 index 00000000..f6bea712 --- /dev/null +++ b/Magento/Tests/Templates/ThisInTemplateUnitTest.inc @@ -0,0 +1,5 @@ +escapeHtml($block->getGroupCode()); +echo $this->escapeHtml($this->getGroupCode()); +$this->foo(); +$this->helper(); diff --git a/Magento/Tests/Templates/ThisInTemplateUnitTest.php b/Magento/Tests/Templates/ThisInTemplateUnitTest.php new file mode 100644 index 00000000..fc642318 --- /dev/null +++ b/Magento/Tests/Templates/ThisInTemplateUnitTest.php @@ -0,0 +1,34 @@ + 2, + 4 => 1, + 5 => 1, + ]; + } +} diff --git a/Magento/Tests/Translation/ConstantUsageUnitTest.inc b/Magento/Tests/Translation/ConstantUsageUnitTest.inc new file mode 100644 index 00000000..6fbec171 --- /dev/null +++ b/Magento/Tests/Translation/ConstantUsageUnitTest.inc @@ -0,0 +1,19 @@ + 1, + 11 => 1, + 12 => 1, + 15 => 1, + ]; + } +} diff --git a/Magento/Tests/Whitespace/MultipleEmptyLinesUnitTest.inc b/Magento/Tests/Whitespace/MultipleEmptyLinesUnitTest.inc new file mode 100644 index 00000000..280a33cd --- /dev/null +++ b/Magento/Tests/Whitespace/MultipleEmptyLinesUnitTest.inc @@ -0,0 +1,16 @@ + 1, + 12 => 1, + ]; + } +} diff --git a/Magento/ruleset.xml b/Magento/ruleset.xml new file mode 100644 index 00000000..112b031f --- /dev/null +++ b/Magento/ruleset.xml @@ -0,0 +1,186 @@ + + + Magento Coding Standard + + + + + + 8 + warning + + + 8 + + + 6 + + + 6 + + + 8 + + + 6 + + + 6 + + + 6 + + + 6 + warning + + + 6 + + + 10 + + + 8 + warning + + + 8 + + + 10 + *.phtml + + + 10 + + + 8 + + + 10 + + + 8 + + + 8 + warning + + + 8 + + + 8 + + + 10 + + + 6 + + + 8 + + + 6 + + + 8 + + + 10 + + + 10 + + + 8 + + + 8 + + + 10 + + + 10 + + + 8 + + + *.phtml + 8 + + + 10 + + + 8 + + + *.phtml + 6 + + + 6 + + + 6 + + + 6 + warning + + + 8 + warning + + + + 10 + error + + + 10 + error + *.phtml + + + 6 + warning + + + 6 + warning + + + 6 + + + + + + 10 + error + + + 8 + warning + + + 6 + + + 6 + warning + + + 6 + warning + + + 8 + + diff --git a/README.md b/README.md index 8586f169..7c56f229 100644 --- a/README.md +++ b/README.md @@ -1 +1,9 @@ -# magento-coding-standard \ No newline at end of file +# Magento Coding Standard + +A set of Magento rules for [PHP_CodeSniffer](https://github.com/squizlabs/PHP_CodeSniffer) tool. + +## Goals + +1. Make it easier to run static checks for core project contributors and extensions developers. +2. Store all Magento 2 sniffs in one place. +3. Make static check consistent. diff --git a/composer.json b/composer.json new file mode 100644 index 00000000..6500684e --- /dev/null +++ b/composer.json @@ -0,0 +1,23 @@ +{ + "name": "magento/magento-coding-standard", + "description": "A set of Magento specific PHP CodeSniffer rules.", + "license": [ + "OSL-3.0", + "AFL-3.0" + ], + "type": "phpcodesniffer-standard", + "require": { + "php": ">=5.5.0", + "squizlabs/php_codesniffer": "~3.3.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0" + }, + "config": { + "bin-dir": "bin" + }, + "scripts": { + "post-install-cmd": "bin/phpcs --config-set installed_paths ../../..", + "post-update-cmd": "bin/phpcs --config-set installed_paths ../../.." + } +} diff --git a/composer.lock b/composer.lock new file mode 100644 index 00000000..c8cc38b3 --- /dev/null +++ b/composer.lock @@ -0,0 +1,1450 @@ +{ + "_readme": [ + "This file locks the dependencies of your project to a known state", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", + "This file is @generated automatically" + ], + "content-hash": "19f88a3b77784a8a0a3327126105bed2", + "packages": [ + { + "name": "squizlabs/php_codesniffer", + "version": "3.3.2", + "source": { + "type": "git", + "url": "https://github.com/squizlabs/PHP_CodeSniffer.git", + "reference": "6ad28354c04b364c3c71a34e4a18b629cc3b231e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/6ad28354c04b364c3c71a34e4a18b629cc3b231e", + "reference": "6ad28354c04b364c3c71a34e4a18b629cc3b231e", + "shasum": "" + }, + "require": { + "ext-simplexml": "*", + "ext-tokenizer": "*", + "ext-xmlwriter": "*", + "php": ">=5.4.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0" + }, + "bin": [ + "bin/phpcs", + "bin/phpcbf" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.x-dev" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Greg Sherwood", + "role": "lead" + } + ], + "description": "PHP_CodeSniffer tokenizes PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.", + "homepage": "http://www.squizlabs.com/php-codesniffer", + "keywords": [ + "phpcs", + "standards" + ], + "time": "2018-09-23T23:08:17+00:00" + } + ], + "packages-dev": [ + { + "name": "doctrine/instantiator", + "version": "1.0.5", + "source": { + "type": "git", + "url": "https://github.com/doctrine/instantiator.git", + "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/instantiator/zipball/8e884e78f9f0eb1329e445619e04456e64d8051d", + "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d", + "shasum": "" + }, + "require": { + "php": ">=5.3,<8.0-DEV" + }, + "require-dev": { + "athletic/athletic": "~0.1.8", + "ext-pdo": "*", + "ext-phar": "*", + "phpunit/phpunit": "~4.0", + "squizlabs/php_codesniffer": "~2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Marco Pivetta", + "email": "ocramius@gmail.com", + "homepage": "http://ocramius.github.com/" + } + ], + "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", + "homepage": "https://github.com/doctrine/instantiator", + "keywords": [ + "constructor", + "instantiate" + ], + "time": "2015-06-14T21:17:01+00:00" + }, + { + "name": "myclabs/deep-copy", + "version": "1.7.0", + "source": { + "type": "git", + "url": "https://github.com/myclabs/DeepCopy.git", + "reference": "3b8a3a99ba1f6a3952ac2747d989303cbd6b7a3e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/3b8a3a99ba1f6a3952ac2747d989303cbd6b7a3e", + "reference": "3b8a3a99ba1f6a3952ac2747d989303cbd6b7a3e", + "shasum": "" + }, + "require": { + "php": "^5.6 || ^7.0" + }, + "require-dev": { + "doctrine/collections": "^1.0", + "doctrine/common": "^2.6", + "phpunit/phpunit": "^4.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "DeepCopy\\": "src/DeepCopy/" + }, + "files": [ + "src/DeepCopy/deep_copy.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Create deep copies (clones) of your objects", + "keywords": [ + "clone", + "copy", + "duplicate", + "object", + "object graph" + ], + "time": "2017-10-19T19:58:43+00:00" + }, + { + "name": "phpdocumentor/reflection-common", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/ReflectionCommon.git", + "reference": "21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6", + "reference": "21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6", + "shasum": "" + }, + "require": { + "php": ">=5.5" + }, + "require-dev": { + "phpunit/phpunit": "^4.6" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": [ + "src" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jaap van Otterdijk", + "email": "opensource@ijaap.nl" + } + ], + "description": "Common reflection classes used by phpdocumentor to reflect the code structure", + "homepage": "http://www.phpdoc.org", + "keywords": [ + "FQSEN", + "phpDocumentor", + "phpdoc", + "reflection", + "static analysis" + ], + "time": "2017-09-11T18:02:19+00:00" + }, + { + "name": "phpdocumentor/reflection-docblock", + "version": "3.3.2", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", + "reference": "bf329f6c1aadea3299f08ee804682b7c45b326a2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/bf329f6c1aadea3299f08ee804682b7c45b326a2", + "reference": "bf329f6c1aadea3299f08ee804682b7c45b326a2", + "shasum": "" + }, + "require": { + "php": "^5.6 || ^7.0", + "phpdocumentor/reflection-common": "^1.0.0", + "phpdocumentor/type-resolver": "^0.4.0", + "webmozart/assert": "^1.0" + }, + "require-dev": { + "mockery/mockery": "^0.9.4", + "phpunit/phpunit": "^4.4" + }, + "type": "library", + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": [ + "src/" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mike van Riel", + "email": "me@mikevanriel.com" + } + ], + "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", + "time": "2017-11-10T14:09:06+00:00" + }, + { + "name": "phpdocumentor/type-resolver", + "version": "0.4.0", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/TypeResolver.git", + "reference": "9c977708995954784726e25d0cd1dddf4e65b0f7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/9c977708995954784726e25d0cd1dddf4e65b0f7", + "reference": "9c977708995954784726e25d0cd1dddf4e65b0f7", + "shasum": "" + }, + "require": { + "php": "^5.5 || ^7.0", + "phpdocumentor/reflection-common": "^1.0" + }, + "require-dev": { + "mockery/mockery": "^0.9.4", + "phpunit/phpunit": "^5.2||^4.8.24" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": [ + "src/" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mike van Riel", + "email": "me@mikevanriel.com" + } + ], + "time": "2017-07-14T14:27:02+00:00" + }, + { + "name": "phpspec/prophecy", + "version": "1.8.0", + "source": { + "type": "git", + "url": "https://github.com/phpspec/prophecy.git", + "reference": "4ba436b55987b4bf311cb7c6ba82aa528aac0a06" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpspec/prophecy/zipball/4ba436b55987b4bf311cb7c6ba82aa528aac0a06", + "reference": "4ba436b55987b4bf311cb7c6ba82aa528aac0a06", + "shasum": "" + }, + "require": { + "doctrine/instantiator": "^1.0.2", + "php": "^5.3|^7.0", + "phpdocumentor/reflection-docblock": "^2.0|^3.0.2|^4.0", + "sebastian/comparator": "^1.1|^2.0|^3.0", + "sebastian/recursion-context": "^1.0|^2.0|^3.0" + }, + "require-dev": { + "phpspec/phpspec": "^2.5|^3.2", + "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.5 || ^7.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.8.x-dev" + } + }, + "autoload": { + "psr-0": { + "Prophecy\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Konstantin Kudryashov", + "email": "ever.zet@gmail.com", + "homepage": "http://everzet.com" + }, + { + "name": "Marcello Duarte", + "email": "marcello.duarte@gmail.com" + } + ], + "description": "Highly opinionated mocking framework for PHP 5.3+", + "homepage": "https://github.com/phpspec/prophecy", + "keywords": [ + "Double", + "Dummy", + "fake", + "mock", + "spy", + "stub" + ], + "time": "2018-08-05T17:53:17+00:00" + }, + { + "name": "phpunit/php-code-coverage", + "version": "4.0.8", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-code-coverage.git", + "reference": "ef7b2f56815df854e66ceaee8ebe9393ae36a40d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/ef7b2f56815df854e66ceaee8ebe9393ae36a40d", + "reference": "ef7b2f56815df854e66ceaee8ebe9393ae36a40d", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-xmlwriter": "*", + "php": "^5.6 || ^7.0", + "phpunit/php-file-iterator": "^1.3", + "phpunit/php-text-template": "^1.2", + "phpunit/php-token-stream": "^1.4.2 || ^2.0", + "sebastian/code-unit-reverse-lookup": "^1.0", + "sebastian/environment": "^1.3.2 || ^2.0", + "sebastian/version": "^1.0 || ^2.0" + }, + "require-dev": { + "ext-xdebug": "^2.1.4", + "phpunit/phpunit": "^5.7" + }, + "suggest": { + "ext-xdebug": "^2.5.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", + "homepage": "https://github.com/sebastianbergmann/php-code-coverage", + "keywords": [ + "coverage", + "testing", + "xunit" + ], + "time": "2017-04-02T07:44:40+00:00" + }, + { + "name": "phpunit/php-file-iterator", + "version": "1.4.5", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-file-iterator.git", + "reference": "730b01bc3e867237eaac355e06a36b85dd93a8b4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/730b01bc3e867237eaac355e06a36b85dd93a8b4", + "reference": "730b01bc3e867237eaac355e06a36b85dd93a8b4", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.4.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "FilterIterator implementation that filters files based on a list of suffixes.", + "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", + "keywords": [ + "filesystem", + "iterator" + ], + "time": "2017-11-27T13:52:08+00:00" + }, + { + "name": "phpunit/php-text-template", + "version": "1.2.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-text-template.git", + "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/31f8b717e51d9a2afca6c9f046f5d69fc27c8686", + "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Simple template engine.", + "homepage": "https://github.com/sebastianbergmann/php-text-template/", + "keywords": [ + "template" + ], + "time": "2015-06-21T13:50:34+00:00" + }, + { + "name": "phpunit/php-timer", + "version": "1.0.9", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-timer.git", + "reference": "3dcf38ca72b158baf0bc245e9184d3fdffa9c46f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/3dcf38ca72b158baf0bc245e9184d3fdffa9c46f", + "reference": "3dcf38ca72b158baf0bc245e9184d3fdffa9c46f", + "shasum": "" + }, + "require": { + "php": "^5.3.3 || ^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "Utility class for timing", + "homepage": "https://github.com/sebastianbergmann/php-timer/", + "keywords": [ + "timer" + ], + "time": "2017-02-26T11:10:40+00:00" + }, + { + "name": "phpunit/php-token-stream", + "version": "1.4.12", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-token-stream.git", + "reference": "1ce90ba27c42e4e44e6d8458241466380b51fa16" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/1ce90ba27c42e4e44e6d8458241466380b51fa16", + "reference": "1ce90ba27c42e4e44e6d8458241466380b51fa16", + "shasum": "" + }, + "require": { + "ext-tokenizer": "*", + "php": ">=5.3.3" + }, + "require-dev": { + "phpunit/phpunit": "~4.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.4-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Wrapper around PHP's tokenizer extension.", + "homepage": "https://github.com/sebastianbergmann/php-token-stream/", + "keywords": [ + "tokenizer" + ], + "time": "2017-12-04T08:55:13+00:00" + }, + { + "name": "phpunit/phpunit", + "version": "5.7.27", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpunit.git", + "reference": "b7803aeca3ccb99ad0a506fa80b64cd6a56bbc0c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/b7803aeca3ccb99ad0a506fa80b64cd6a56bbc0c", + "reference": "b7803aeca3ccb99ad0a506fa80b64cd6a56bbc0c", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-json": "*", + "ext-libxml": "*", + "ext-mbstring": "*", + "ext-xml": "*", + "myclabs/deep-copy": "~1.3", + "php": "^5.6 || ^7.0", + "phpspec/prophecy": "^1.6.2", + "phpunit/php-code-coverage": "^4.0.4", + "phpunit/php-file-iterator": "~1.4", + "phpunit/php-text-template": "~1.2", + "phpunit/php-timer": "^1.0.6", + "phpunit/phpunit-mock-objects": "^3.2", + "sebastian/comparator": "^1.2.4", + "sebastian/diff": "^1.4.3", + "sebastian/environment": "^1.3.4 || ^2.0", + "sebastian/exporter": "~2.0", + "sebastian/global-state": "^1.1", + "sebastian/object-enumerator": "~2.0", + "sebastian/resource-operations": "~1.0", + "sebastian/version": "^1.0.6|^2.0.1", + "symfony/yaml": "~2.1|~3.0|~4.0" + }, + "conflict": { + "phpdocumentor/reflection-docblock": "3.0.2" + }, + "require-dev": { + "ext-pdo": "*" + }, + "suggest": { + "ext-xdebug": "*", + "phpunit/php-invoker": "~1.1" + }, + "bin": [ + "phpunit" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.7.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "The PHP Unit Testing framework.", + "homepage": "https://phpunit.de/", + "keywords": [ + "phpunit", + "testing", + "xunit" + ], + "time": "2018-02-01T05:50:59+00:00" + }, + { + "name": "phpunit/phpunit-mock-objects", + "version": "3.4.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git", + "reference": "a23b761686d50a560cc56233b9ecf49597cc9118" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/a23b761686d50a560cc56233b9ecf49597cc9118", + "reference": "a23b761686d50a560cc56233b9ecf49597cc9118", + "shasum": "" + }, + "require": { + "doctrine/instantiator": "^1.0.2", + "php": "^5.6 || ^7.0", + "phpunit/php-text-template": "^1.2", + "sebastian/exporter": "^1.2 || ^2.0" + }, + "conflict": { + "phpunit/phpunit": "<5.4.0" + }, + "require-dev": { + "phpunit/phpunit": "^5.4" + }, + "suggest": { + "ext-soap": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.2.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sb@sebastian-bergmann.de", + "role": "lead" + } + ], + "description": "Mock Object library for PHPUnit", + "homepage": "https://github.com/sebastianbergmann/phpunit-mock-objects/", + "keywords": [ + "mock", + "xunit" + ], + "time": "2017-06-30T09:13:00+00:00" + }, + { + "name": "sebastian/code-unit-reverse-lookup", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", + "reference": "4419fcdb5eabb9caa61a27c7a1db532a6b55dd18" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/4419fcdb5eabb9caa61a27c7a1db532a6b55dd18", + "reference": "4419fcdb5eabb9caa61a27c7a1db532a6b55dd18", + "shasum": "" + }, + "require": { + "php": "^5.6 || ^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^5.7 || ^6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Looks up which function or method a line of code belongs to", + "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", + "time": "2017-03-04T06:30:41+00:00" + }, + { + "name": "sebastian/comparator", + "version": "1.2.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/comparator.git", + "reference": "2b7424b55f5047b47ac6e5ccb20b2aea4011d9be" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/2b7424b55f5047b47ac6e5ccb20b2aea4011d9be", + "reference": "2b7424b55f5047b47ac6e5ccb20b2aea4011d9be", + "shasum": "" + }, + "require": { + "php": ">=5.3.3", + "sebastian/diff": "~1.2", + "sebastian/exporter": "~1.2 || ~2.0" + }, + "require-dev": { + "phpunit/phpunit": "~4.4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.2.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@2bepublished.at" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides the functionality to compare PHP values for equality", + "homepage": "http://www.github.com/sebastianbergmann/comparator", + "keywords": [ + "comparator", + "compare", + "equality" + ], + "time": "2017-01-29T09:50:25+00:00" + }, + { + "name": "sebastian/diff", + "version": "1.4.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/diff.git", + "reference": "7f066a26a962dbe58ddea9f72a4e82874a3975a4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/7f066a26a962dbe58ddea9f72a4e82874a3975a4", + "reference": "7f066a26a962dbe58ddea9f72a4e82874a3975a4", + "shasum": "" + }, + "require": { + "php": "^5.3.3 || ^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.4-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Kore Nordmann", + "email": "mail@kore-nordmann.de" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Diff implementation", + "homepage": "https://github.com/sebastianbergmann/diff", + "keywords": [ + "diff" + ], + "time": "2017-05-22T07:24:03+00:00" + }, + { + "name": "sebastian/environment", + "version": "2.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/environment.git", + "reference": "5795ffe5dc5b02460c3e34222fee8cbe245d8fac" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/5795ffe5dc5b02460c3e34222fee8cbe245d8fac", + "reference": "5795ffe5dc5b02460c3e34222fee8cbe245d8fac", + "shasum": "" + }, + "require": { + "php": "^5.6 || ^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^5.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides functionality to handle HHVM/PHP environments", + "homepage": "http://www.github.com/sebastianbergmann/environment", + "keywords": [ + "Xdebug", + "environment", + "hhvm" + ], + "time": "2016-11-26T07:53:53+00:00" + }, + { + "name": "sebastian/exporter", + "version": "2.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/exporter.git", + "reference": "ce474bdd1a34744d7ac5d6aad3a46d48d9bac4c4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/ce474bdd1a34744d7ac5d6aad3a46d48d9bac4c4", + "reference": "ce474bdd1a34744d7ac5d6aad3a46d48d9bac4c4", + "shasum": "" + }, + "require": { + "php": ">=5.3.3", + "sebastian/recursion-context": "~2.0" + }, + "require-dev": { + "ext-mbstring": "*", + "phpunit/phpunit": "~4.4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@2bepublished.at" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + } + ], + "description": "Provides the functionality to export PHP variables for visualization", + "homepage": "http://www.github.com/sebastianbergmann/exporter", + "keywords": [ + "export", + "exporter" + ], + "time": "2016-11-19T08:54:04+00:00" + }, + { + "name": "sebastian/global-state", + "version": "1.1.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/global-state.git", + "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/bc37d50fea7d017d3d340f230811c9f1d7280af4", + "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "phpunit/phpunit": "~4.2" + }, + "suggest": { + "ext-uopz": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Snapshotting of global state", + "homepage": "http://www.github.com/sebastianbergmann/global-state", + "keywords": [ + "global state" + ], + "time": "2015-10-12T03:26:01+00:00" + }, + { + "name": "sebastian/object-enumerator", + "version": "2.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-enumerator.git", + "reference": "1311872ac850040a79c3c058bea3e22d0f09cbb7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/1311872ac850040a79c3c058bea3e22d0f09cbb7", + "reference": "1311872ac850040a79c3c058bea3e22d0f09cbb7", + "shasum": "" + }, + "require": { + "php": ">=5.6", + "sebastian/recursion-context": "~2.0" + }, + "require-dev": { + "phpunit/phpunit": "~5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Traverses array structures and object graphs to enumerate all referenced objects", + "homepage": "https://github.com/sebastianbergmann/object-enumerator/", + "time": "2017-02-18T15:18:39+00:00" + }, + { + "name": "sebastian/recursion-context", + "version": "2.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/recursion-context.git", + "reference": "2c3ba150cbec723aa057506e73a8d33bdb286c9a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/2c3ba150cbec723aa057506e73a8d33bdb286c9a", + "reference": "2c3ba150cbec723aa057506e73a8d33bdb286c9a", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "phpunit/phpunit": "~4.4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + } + ], + "description": "Provides functionality to recursively process PHP variables", + "homepage": "http://www.github.com/sebastianbergmann/recursion-context", + "time": "2016-11-19T07:33:16+00:00" + }, + { + "name": "sebastian/resource-operations", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/resource-operations.git", + "reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/ce990bb21759f94aeafd30209e8cfcdfa8bc3f52", + "reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52", + "shasum": "" + }, + "require": { + "php": ">=5.6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides a list of PHP built-in functions that operate on resources", + "homepage": "https://www.github.com/sebastianbergmann/resource-operations", + "time": "2015-07-28T20:34:47+00:00" + }, + { + "name": "sebastian/version", + "version": "2.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/version.git", + "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/99732be0ddb3361e16ad77b68ba41efc8e979019", + "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019", + "shasum": "" + }, + "require": { + "php": ">=5.6" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library that helps with managing the version number of Git-hosted PHP projects", + "homepage": "https://github.com/sebastianbergmann/version", + "time": "2016-10-03T07:35:21+00:00" + }, + { + "name": "symfony/polyfill-ctype", + "version": "v1.10.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-ctype.git", + "reference": "e3d826245268269cd66f8326bd8bc066687b4a19" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/e3d826245268269cd66f8326bd8bc066687b4a19", + "reference": "e3d826245268269cd66f8326bd8bc066687b4a19", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "suggest": { + "ext-ctype": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.9-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Ctype\\": "" + }, + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + }, + { + "name": "Gert de Pagter", + "email": "BackEndTea@gmail.com" + } + ], + "description": "Symfony polyfill for ctype functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "ctype", + "polyfill", + "portable" + ], + "time": "2018-08-06T14:22:27+00:00" + }, + { + "name": "symfony/yaml", + "version": "v3.4.20", + "source": { + "type": "git", + "url": "https://github.com/symfony/yaml.git", + "reference": "291e13d808bec481eab83f301f7bff3e699ef603" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/yaml/zipball/291e13d808bec481eab83f301f7bff3e699ef603", + "reference": "291e13d808bec481eab83f301f7bff3e699ef603", + "shasum": "" + }, + "require": { + "php": "^5.5.9|>=7.0.8", + "symfony/polyfill-ctype": "~1.8" + }, + "conflict": { + "symfony/console": "<3.4" + }, + "require-dev": { + "symfony/console": "~3.4|~4.0" + }, + "suggest": { + "symfony/console": "For validating YAML files using the lint command" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.4-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Yaml\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Yaml Component", + "homepage": "https://symfony.com", + "time": "2018-11-11T19:48:54+00:00" + }, + { + "name": "webmozart/assert", + "version": "1.3.0", + "source": { + "type": "git", + "url": "https://github.com/webmozart/assert.git", + "reference": "0df1908962e7a3071564e857d86874dad1ef204a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/webmozart/assert/zipball/0df1908962e7a3071564e857d86874dad1ef204a", + "reference": "0df1908962e7a3071564e857d86874dad1ef204a", + "shasum": "" + }, + "require": { + "php": "^5.3.3 || ^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.6", + "sebastian/version": "^1.0.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.3-dev" + } + }, + "autoload": { + "psr-4": { + "Webmozart\\Assert\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" + } + ], + "description": "Assertions to validate method input/output with nice error messages.", + "keywords": [ + "assert", + "check", + "validate" + ], + "time": "2018-01-29T19:49:41+00:00" + } + ], + "aliases": [], + "minimum-stability": "stable", + "stability-flags": [], + "prefer-stable": false, + "prefer-lowest": false, + "platform": { + "php": ">=5.5.0" + }, + "platform-dev": [] +} diff --git a/phpunit.xml.dist b/phpunit.xml.dist new file mode 100644 index 00000000..6d1afb07 --- /dev/null +++ b/phpunit.xml.dist @@ -0,0 +1,11 @@ + + + + + vendor/squizlabs/php_codesniffer/tests/Standards/AllSniffs.php + + + + + +