http://www.mediawiki.org/wiki/Special:Code/MediaWiki/89245

Revision: 89245
Author:   tstarling
Date:     2011-06-01 00:51:09 +0000 (Wed, 01 Jun 2011)
Log Message:
-----------
Fixes for r88883, r89197:
* Modified WebRequest::findIE6Extension() to fix the performance issue and the 
hash parsing issue I noted on CR 
* In FindIE6ExtensionTest, fixed all the assertEquals() calls, I had the 
expected and actual around the wrong way
* Added a couple of extra tests for cases that seemed important during the 
rewrite.

Modified Paths:
--------------
    trunk/phase3/includes/WebRequest.php
    trunk/phase3/tests/phpunit/includes/FindIE6ExtensionTest.php

Modified: trunk/phase3/includes/WebRequest.php
===================================================================
--- trunk/phase3/includes/WebRequest.php        2011-06-01 00:15:02 UTC (rev 
89244)
+++ trunk/phase3/includes/WebRequest.php        2011-06-01 00:51:09 UTC (rev 
89245)
@@ -814,44 +814,52 @@
         * insecure.
         *
         * The criteria for finding an extension are as follows:
-        * * a possible extension is a dot followed by one or more characters 
not in <>\"/:|?.#
-        * * if we find a possible extension followed by the end of the string 
or a #, that's our extension
-        * * if we find a possible extension followed by a ?, that's our 
extension
-        * ** UNLESS it's exe, dll or cgi, in which case we ignore it and 
continue searching for another possible extension
-        * * if we find a possible extension followed by a dot or another 
illegal character, we ignore it and continue searching
+        * - a possible extension is a dot followed by one or more characters 
not 
+        *   in <>\"/:|?.#
+        * - if we find a possible extension followed by the end of the string 
or 
+        *   a #, that's our extension
+        * - if we find a possible extension followed by a ?, that's our 
extension
+        *    - UNLESS it's exe, dll or cgi, in which case we ignore it and 
continue 
+        *      searching for another possible extension
+        * - if we find a possible extension followed by a dot or another 
illegal 
+        *   character, we ignore it and continue searching
         * 
         * @param $url string URL
         * @return mixed Detected extension (string), or false if none found
         */
        public static function findIE6Extension( $url ) {
-               $remaining = $url;
-               while ( $remaining !== '' ) {
+               $pos = 0;
+               $hashPos = strpos( $url, '#' );
+               if ( $hashPos !== false ) {
+                       $urlLength = $hashPos;
+               } else {
+                       $urlLength = strlen( $url );
+               }
+               $remainingLength = $urlLength;
+               while ( $remainingLength > 0 ) {
                        // Skip ahead to the next dot
-                       $pos = strcspn( $remaining, '.' );
-                       if ( $pos === strlen( $remaining ) || $remaining[$pos] 
=== '#' ) {
+                       $pos += strcspn( $url, '.', $pos, $remainingLength );
+                       if ( $pos >= $urlLength ) {
                                // End of string, we're done
                                return false;
                        }
                        
                        // We found a dot. Skip past it
-                       $remaining = substr( $remaining, $pos + 1 );
+                       $pos++;
+                       $remainingLength = $urlLength - $pos;
+
                        // Check for illegal characters in our prospective 
extension,
-                       // or for another dot, or for a hash sign
-                       $pos = strcspn( $remaining, "<>\\\"/:|?*.#" );
-                       if ( $pos === strlen( $remaining ) ) {
-                               // No illegal character or next dot or hash
+                       // or for another dot
+                       $nextPos = $pos + strcspn( $url, "<>\\\"/:|?*.", $pos, 
$remainingLength );
+                       if ( $nextPos >= $urlLength ) {
+                               // No illegal character or next dot
                                // We have our extension
-                               return $remaining;
+                               return substr( $url, $pos, $urlLength - $pos );
                        }
-                       if ( $remaining[$pos] === '#' ) {
-                               // We've found a legal extension followed by a 
hash
-                               // Trim the hash and everything after it, then 
return that
-                               return substr( $remaining, 0, $pos );
-                       }
-                       if ( $remaining[$pos] === '?' ) {
+                       if ( $url[$nextPos] === '?' ) {
                                // We've found a legal extension followed by a 
question mark
                                // If the extension is NOT exe, dll or cgi, 
return it
-                               $extension = substr( $remaining, 0, $pos );
+                               $extension = substr( $url, $pos, $nextPos - 
$pos );
                                if ( strcasecmp( $extension, 'exe' ) && 
strcasecmp( $extension, 'dll' ) &&
                                        strcasecmp( $extension, 'cgi' ) )
                                {
@@ -861,7 +869,8 @@
                        }
                        // We found an illegal character or another dot
                        // Skip to that character and continue the loop
-                       $remaining = substr( $remaining, $pos );
+                       $pos = $nextPos + 1;
+                       $remainingLength = $urlLength - $pos;
                }
                return false;
        }

Modified: trunk/phase3/tests/phpunit/includes/FindIE6ExtensionTest.php
===================================================================
--- trunk/phase3/tests/phpunit/includes/FindIE6ExtensionTest.php        
2011-06-01 00:15:02 UTC (rev 89244)
+++ trunk/phase3/tests/phpunit/includes/FindIE6ExtensionTest.php        
2011-06-01 00:51:09 UTC (rev 89245)
@@ -6,97 +6,113 @@
 class FindIE6ExtensionTest extends MediaWikiTestCase {
        function testSimple() {
                $this->assertEquals( 
+                       'y',
                        WebRequest::findIE6Extension( 'x.y' ),
-                       'y',
                        'Simple extension'
                );
        }
 
        function testSimpleNoExt() {
                $this->assertEquals(
+                       '',
                        WebRequest::findIE6Extension( 'x' ),
-                       '',
                        'No extension'
                );
        }
 
        function testEmpty() {
                $this->assertEquals(
+                       '',
                        WebRequest::findIE6Extension( '' ),
-                       '',
                        'Empty string'
                );
        }
 
        function testQuestionMark() {
                $this->assertEquals(
+                       '',
                        WebRequest::findIE6Extension( '?' ),
-                       '',
                        'Question mark only'
                );
        }
 
        function testExtQuestionMark() {
                $this->assertEquals(
+                       'x',
                        WebRequest::findIE6Extension( '.x?' ),
-                       'x',
                        'Extension then question mark'
                );
        }
 
        function testQuestionMarkExt() {
                $this->assertEquals(
+                       'x',
                        WebRequest::findIE6Extension( '?.x' ),
-                       'x',
                        'Question mark then extension'
                );
        }
 
        function testInvalidChar() {
                $this->assertEquals(
+                       '',
                        WebRequest::findIE6Extension( '.x*' ),
-                       '',
                        'Extension with invalid character'
                );
        }
 
+       function testInvalidCharThenExtension() {
+               $this->assertEquals(
+                       'x',
+                       WebRequest::findIE6Extension( '*.x' ),
+                       'Invalid character followed by an extension'
+               );
+       }
+
        function testMultipleQuestionMarks() {
                $this->assertEquals(
+                       'c',
                        WebRequest::findIE6Extension( 'a?b?.c?.d?e?f' ),
-                       'c',
                        'Multiple question marks'
                );
        }
 
        function testExeException() {
                $this->assertEquals(
+                       'd',
                        WebRequest::findIE6Extension( 'a?b?.exe?.d?.e' ),
-                       'd',
                        '.exe exception'
                );
        }
 
        function testExeException2() {
                $this->assertEquals(
+                       'exe',
                        WebRequest::findIE6Extension( 'a?b?.exe' ),
-                       'exe',
                        '.exe exception 2'
                );
        }
 
        function testHash() {
                $this->assertEquals(
+                       '',
                        WebRequest::findIE6Extension( 'a#b.c' ),
-                       '',
                        'Hash character preceding extension'
                );
        }
 
        function testHash2() {
                $this->assertEquals(
+                       '',
                        WebRequest::findIE6Extension( 'a?#b.c' ),
-                       '',
                        'Hash character preceding extension 2'
                );
        }
+
+       function testDotAtEnd() {
+               $this->assertEquals(
+                       '',
+                       WebRequest::findIE6Extension( '.' ),
+                       'Dot at end of string'
+               );
+       }
 }


_______________________________________________
MediaWiki-CVS mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-cvs

Reply via email to