diff --git a/.travis.yml b/.travis.yml index 0dcf5be4aa..71746a0ca2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -35,6 +35,9 @@ matrix: env: PHPCS_BRANCH=2.9 - php: nightly env: PHPCS_BRANCH=2.9 + # Test PHP 5.3 with short_open_tags set to On (is Off by default) + - php: 5.3 + env: PHPCS_BRANCH=master SHORT_OPEN_TAGS=true allow_failures: # Allow failures for unstable builds. - php: nightly @@ -52,6 +55,7 @@ before_install: # test suite is currently not compatible with PHPUnit 6.x. # Fixed at a very specific PHPUnit version which is also compatible with HHVM. - if [[ ${TRAVIS_PHP_VERSION:0:2} != "5." ]]; then wget -P $PHPUNIT_DIR https://phar.phpunit.de/phpunit-5.7.17.phar && chmod +x $PHPUNIT_DIR/phpunit-5.7.17.phar; fi + - if [[ "$SHORT_OPEN_TAGS" == "true" ]]; then echo "short_open_tag = On" >> ~/.phpenv/versions/$(phpenv version-name)/etc/php.ini; fi script: # Lint the PHP files against parse errors. diff --git a/WordPress/Sniffs/XSS/EscapeOutputSniff.php b/WordPress/Sniffs/XSS/EscapeOutputSniff.php index 52e2396e11..c6f7625ce3 100644 --- a/WordPress/Sniffs/XSS/EscapeOutputSniff.php +++ b/WordPress/Sniffs/XSS/EscapeOutputSniff.php @@ -144,19 +144,42 @@ class WordPress_Sniffs_XSS_EscapeOutputSniff extends WordPress_Sniff { 'T_END_NOWDOC' => true, ); + /** + * Status of short_open_tag feature + * + * @since 0.11.0 + * + * @var bool + */ + private $short_open_tag_enabled = true; + /** * Returns an array of tokens this test wants to listen for. * * @return array */ public function register() { - return array( + // Check whether short_open_tag is disabled on PHP version < 5.4 (it's enabled by default in later versions). + if ( PHP_VERSION_ID < 50400 && false === (bool) ini_get( 'short_open_tag' ) ) { + $this->short_open_tag_enabled = false; + } + + $tokens = array( T_ECHO, T_PRINT, T_EXIT, T_STRING, + T_OPEN_TAG_WITH_ECHO, ); + /* + * In case short_open_tag is turned off, we can attempt to regex T_INLINE_HTML + * which is how short open tags are being handled in that case. + */ + if ( false === $this->short_open_tag_enabled ) { + $tokens[] = T_INLINE_HTML; + } + return $tokens; } /** @@ -191,6 +214,24 @@ public function process_token( $stackPtr ) { if ( in_array( $function, array( 'trigger_error', 'user_error' ), true ) ) { $end_of_statement = $this->phpcsFile->findEndOfStatement( $open_paren + 1 ); } + } else if ( false === $this->short_open_tag_enabled && T_INLINE_HTML === $this->tokens[ $stackPtr ]['code'] ) { + // Skip if no PHP short_open_tag is in the string. + if ( false === strpos( $this->tokens[ $stackPtr ]['content'], '\S+|\[[^\]]+\]))*)[\s]*;?[\s]*\?\>/', $this->tokens[ $stackPtr ]['content'], $matches ) ) { + $this->phpcsFile->addError( 'Expected next thing to be an escaping function, not %s.', $stackPtr, 'OutputNotEscaped', $matches[1] ); + return; + } + + // Throw warning in case the T_INLINE_HTML looks like a open_short_tag. + if ( false !== strpos( $this->tokens[ $stackPtr ]['content'], 'phpcsFile->addWarning( 'Possible use of PHP short open tag ( " + + + +foo ?> + 1, 207 => 1, 212 => ( PHP_VERSION_ID < 50300 ) ? 1 : 0, // PHPCS on PHP 5.2 does not recognize T_NOWDOC. + 210 => 1, + 212 => 1, + 213 => 1, ); } // end getErrorList() @@ -74,8 +77,14 @@ public function getErrorList() { * @return array => */ public function getWarningList() { - return array(); + $list = array(); + // Adding Warning which is triggerred in case open_short_tag is set to Off. + if ( PHP_VERSION_ID < 50400 && false === (bool) ini_get( 'short_open_tag' ) ) { + $list[211] = 1; + } + + return $list; } } // End class.