r89245 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r89244‎ | r89245 | r89246 >
Date:00:51, 1 June 2011
Author:tstarling
Status:ok (Comments)
Tags:
Comment:
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 (modified) (history)
  • /trunk/phase3/tests/phpunit/includes/FindIE6ExtensionTest.php (modified) (history)

Diff [purge]

Index: trunk/phase3/tests/phpunit/includes/FindIE6ExtensionTest.php
@@ -6,97 +6,113 @@
77 class FindIE6ExtensionTest extends MediaWikiTestCase {
88 function testSimple() {
99 $this->assertEquals(
 10+ 'y',
1011 WebRequest::findIE6Extension( 'x.y' ),
11 - 'y',
1212 'Simple extension'
1313 );
1414 }
1515
1616 function testSimpleNoExt() {
1717 $this->assertEquals(
 18+ '',
1819 WebRequest::findIE6Extension( 'x' ),
19 - '',
2020 'No extension'
2121 );
2222 }
2323
2424 function testEmpty() {
2525 $this->assertEquals(
 26+ '',
2627 WebRequest::findIE6Extension( '' ),
27 - '',
2828 'Empty string'
2929 );
3030 }
3131
3232 function testQuestionMark() {
3333 $this->assertEquals(
 34+ '',
3435 WebRequest::findIE6Extension( '?' ),
35 - '',
3636 'Question mark only'
3737 );
3838 }
3939
4040 function testExtQuestionMark() {
4141 $this->assertEquals(
 42+ 'x',
4243 WebRequest::findIE6Extension( '.x?' ),
43 - 'x',
4444 'Extension then question mark'
4545 );
4646 }
4747
4848 function testQuestionMarkExt() {
4949 $this->assertEquals(
 50+ 'x',
5051 WebRequest::findIE6Extension( '?.x' ),
51 - 'x',
5252 'Question mark then extension'
5353 );
5454 }
5555
5656 function testInvalidChar() {
5757 $this->assertEquals(
 58+ '',
5859 WebRequest::findIE6Extension( '.x*' ),
59 - '',
6060 'Extension with invalid character'
6161 );
6262 }
6363
 64+ function testInvalidCharThenExtension() {
 65+ $this->assertEquals(
 66+ 'x',
 67+ WebRequest::findIE6Extension( '*.x' ),
 68+ 'Invalid character followed by an extension'
 69+ );
 70+ }
 71+
6472 function testMultipleQuestionMarks() {
6573 $this->assertEquals(
 74+ 'c',
6675 WebRequest::findIE6Extension( 'a?b?.c?.d?e?f' ),
67 - 'c',
6876 'Multiple question marks'
6977 );
7078 }
7179
7280 function testExeException() {
7381 $this->assertEquals(
 82+ 'd',
7483 WebRequest::findIE6Extension( 'a?b?.exe?.d?.e' ),
75 - 'd',
7684 '.exe exception'
7785 );
7886 }
7987
8088 function testExeException2() {
8189 $this->assertEquals(
 90+ 'exe',
8291 WebRequest::findIE6Extension( 'a?b?.exe' ),
83 - 'exe',
8492 '.exe exception 2'
8593 );
8694 }
8795
8896 function testHash() {
8997 $this->assertEquals(
 98+ '',
9099 WebRequest::findIE6Extension( 'a#b.c' ),
91 - '',
92100 'Hash character preceding extension'
93101 );
94102 }
95103
96104 function testHash2() {
97105 $this->assertEquals(
 106+ '',
98107 WebRequest::findIE6Extension( 'a?#b.c' ),
99 - '',
100108 'Hash character preceding extension 2'
101109 );
102110 }
 111+
 112+ function testDotAtEnd() {
 113+ $this->assertEquals(
 114+ '',
 115+ WebRequest::findIE6Extension( '.' ),
 116+ 'Dot at end of string'
 117+ );
 118+ }
103119 }
Index: trunk/phase3/includes/WebRequest.php
@@ -814,44 +814,52 @@
815815 * insecure.
816816 *
817817 * The criteria for finding an extension are as follows:
818 - * * a possible extension is a dot followed by one or more characters not in <>\"/:|?.#
819 - * * if we find a possible extension followed by the end of the string or a #, that's our extension
820 - * * if we find a possible extension followed by a ?, that's our extension
821 - * ** UNLESS it's exe, dll or cgi, in which case we ignore it and continue searching for another possible extension
822 - * * if we find a possible extension followed by a dot or another illegal character, we ignore it and continue searching
 818+ * - a possible extension is a dot followed by one or more characters not
 819+ * in <>\"/:|?.#
 820+ * - if we find a possible extension followed by the end of the string or
 821+ * a #, that's our extension
 822+ * - if we find a possible extension followed by a ?, that's our extension
 823+ * - UNLESS it's exe, dll or cgi, in which case we ignore it and continue
 824+ * searching for another possible extension
 825+ * - if we find a possible extension followed by a dot or another illegal
 826+ * character, we ignore it and continue searching
823827 *
824828 * @param $url string URL
825829 * @return mixed Detected extension (string), or false if none found
826830 */
827831 public static function findIE6Extension( $url ) {
828 - $remaining = $url;
829 - while ( $remaining !== '' ) {
 832+ $pos = 0;
 833+ $hashPos = strpos( $url, '#' );
 834+ if ( $hashPos !== false ) {
 835+ $urlLength = $hashPos;
 836+ } else {
 837+ $urlLength = strlen( $url );
 838+ }
 839+ $remainingLength = $urlLength;
 840+ while ( $remainingLength > 0 ) {
830841 // Skip ahead to the next dot
831 - $pos = strcspn( $remaining, '.' );
832 - if ( $pos === strlen( $remaining ) || $remaining[$pos] === '#' ) {
 842+ $pos += strcspn( $url, '.', $pos, $remainingLength );
 843+ if ( $pos >= $urlLength ) {
833844 // End of string, we're done
834845 return false;
835846 }
836847
837848 // We found a dot. Skip past it
838 - $remaining = substr( $remaining, $pos + 1 );
 849+ $pos++;
 850+ $remainingLength = $urlLength - $pos;
 851+
839852 // Check for illegal characters in our prospective extension,
840 - // or for another dot, or for a hash sign
841 - $pos = strcspn( $remaining, "<>\\\"/:|?*.#" );
842 - if ( $pos === strlen( $remaining ) ) {
843 - // No illegal character or next dot or hash
 853+ // or for another dot
 854+ $nextPos = $pos + strcspn( $url, "<>\\\"/:|?*.", $pos, $remainingLength );
 855+ if ( $nextPos >= $urlLength ) {
 856+ // No illegal character or next dot
844857 // We have our extension
845 - return $remaining;
 858+ return substr( $url, $pos, $urlLength - $pos );
846859 }
847 - if ( $remaining[$pos] === '#' ) {
848 - // We've found a legal extension followed by a hash
849 - // Trim the hash and everything after it, then return that
850 - return substr( $remaining, 0, $pos );
851 - }
852 - if ( $remaining[$pos] === '?' ) {
 860+ if ( $url[$nextPos] === '?' ) {
853861 // We've found a legal extension followed by a question mark
854862 // If the extension is NOT exe, dll or cgi, return it
855 - $extension = substr( $remaining, 0, $pos );
 863+ $extension = substr( $url, $pos, $nextPos - $pos );
856864 if ( strcasecmp( $extension, 'exe' ) && strcasecmp( $extension, 'dll' ) &&
857865 strcasecmp( $extension, 'cgi' ) )
858866 {
@@ -861,7 +869,8 @@
862870 }
863871 // We found an illegal character or another dot
864872 // Skip to that character and continue the loop
865 - $remaining = substr( $remaining, $pos );
 873+ $pos = $nextPos + 1;
 874+ $remainingLength = $urlLength - $pos;
866875 }
867876 return false;
868877 }

Past revisions this follows-up on

RevisionCommit summaryAuthorDate
r88883(bug 28840) URLs with dots break because of IE6 security check...catrope09:49, 26 May 2011
r89197Tests for r88883, including two failing tests.tstarling02:09, 31 May 2011

Comments

#Comment by Tim Starling (talk | contribs)   06:42, 5 July 2011

Untagging 1.17wmf1 since it is superseded by r91440.

Status & tagging log