From 14f74d141ab5580688bfd46d2f74c026e43ed967 Mon Sep 17 00:00:00 2001 From: Pierre Schmitz Date: Wed, 1 Apr 2015 06:11:44 +0200 Subject: Update to MediaWiki 1.24.2 --- tests/phpunit/includes/upload/UploadBaseTest.php | 427 +++++++++++++++++++++++ 1 file changed, 427 insertions(+) create mode 100644 tests/phpunit/includes/upload/UploadBaseTest.php (limited to 'tests/phpunit/includes/upload/UploadBaseTest.php') diff --git a/tests/phpunit/includes/upload/UploadBaseTest.php b/tests/phpunit/includes/upload/UploadBaseTest.php new file mode 100644 index 00000000..3d3b0068 --- /dev/null +++ b/tests/phpunit/includes/upload/UploadBaseTest.php @@ -0,0 +1,427 @@ +upload = new UploadTestHandler; + $this->hooks = $wgHooks; + $wgHooks['InterwikiLoadPrefix'][] = function ( $prefix, &$data ) { + return false; + }; + } + + protected function tearDown() { + global $wgHooks; + $wgHooks = $this->hooks; + + parent::tearDown(); + } + + /** + * First checks the return code + * of UploadBase::getTitle() and then the actual returned title + * + * @dataProvider provideTestTitleValidation + * @covers UploadBase::getTitle + */ + public function testTitleValidation( $srcFilename, $dstFilename, $code, $msg ) { + /* Check the result code */ + $this->assertEquals( $code, + $this->upload->testTitleValidation( $srcFilename ), + "$msg code" ); + + /* If we expect a valid title, check the title itself. */ + if ( $code == UploadBase::OK ) { + $this->assertEquals( $dstFilename, + $this->upload->getTitle()->getText(), + "$msg text" ); + } + } + + /** + * Test various forms of valid and invalid titles that can be supplied. + */ + public static function provideTestTitleValidation() { + return array( + /* Test a valid title */ + array( 'ValidTitle.jpg', 'ValidTitle.jpg', UploadBase::OK, + 'upload valid title' ), + /* A title with a slash */ + array( 'A/B.jpg', 'B.jpg', UploadBase::OK, + 'upload title with slash' ), + /* A title with illegal char */ + array( 'A:B.jpg', 'A-B.jpg', UploadBase::OK, + 'upload title with colon' ), + /* Stripping leading File: prefix */ + array( 'File:C.jpg', 'C.jpg', UploadBase::OK, + 'upload title with File prefix' ), + /* Test illegal suggested title (r94601) */ + array( '%281%29.JPG', null, UploadBase::ILLEGAL_FILENAME, + 'illegal title for upload' ), + /* A title without extension */ + array( 'A', null, UploadBase::FILETYPE_MISSING, + 'upload title without extension' ), + /* A title with no basename */ + array( '.jpg', null, UploadBase::MIN_LENGTH_PARTNAME, + 'upload title without basename' ), + /* A title that is longer than 255 bytes */ + array( str_repeat( 'a', 255 ) . '.jpg', null, UploadBase::FILENAME_TOO_LONG, + 'upload title longer than 255 bytes' ), + /* A title that is longer than 240 bytes */ + array( str_repeat( 'a', 240 ) . '.jpg', null, UploadBase::FILENAME_TOO_LONG, + 'upload title longer than 240 bytes' ), + ); + } + + /** + * Test the upload verification functions + * @covers UploadBase::verifyUpload + */ + public function testVerifyUpload() { + /* Setup with zero file size */ + $this->upload->initializePathInfo( '', '', 0 ); + $result = $this->upload->verifyUpload(); + $this->assertEquals( UploadBase::EMPTY_FILE, + $result['status'], + 'upload empty file' ); + } + + // Helper used to create an empty file of size $size. + private function createFileOfSize( $size ) { + $filename = tempnam( wfTempDir(), "mwuploadtest" ); + + $fh = fopen( $filename, 'w' ); + ftruncate( $fh, $size ); + fclose( $fh ); + + return $filename; + } + + /** + * test uploading a 100 bytes file with $wgMaxUploadSize = 100 + * + * This method should be abstracted so we can test different settings. + */ + public function testMaxUploadSize() { + global $wgMaxUploadSize; + $savedGlobal = $wgMaxUploadSize; // save global + global $wgFileExtensions; + $wgFileExtensions[] = 'txt'; + + $wgMaxUploadSize = 100; + + $filename = $this->createFileOfSize( $wgMaxUploadSize ); + $this->upload->initializePathInfo( basename( $filename ) . '.txt', $filename, 100 ); + $result = $this->upload->verifyUpload(); + unlink( $filename ); + + $this->assertEquals( + array( 'status' => UploadBase::OK ), $result ); + + $wgMaxUploadSize = $savedGlobal; // restore global + } + + + /** + * @dataProvider provideCheckSvgScriptCallback + */ + public function testCheckSvgScriptCallback( $svg, $wellFormed, $filterMatch, $message ) { + list( $formed, $match ) = $this->upload->checkSvgString( $svg ); + $this->assertSame( $wellFormed, $formed, $message ); + $this->assertSame( $filterMatch, $match, $message ); + } + + public static function provideCheckSvgScriptCallback() { + return array( + // html5sec SVG vectors + array( + '', + true, + true, + 'Script tag in svg (http://html5sec.org/#47)' + ), + array( + '', + true, + true, + 'SVG with onload property (http://html5sec.org/#11)' + ), + array( + '', + true, + true, + 'SVG with onload property (http://html5sec.org/#65)' + ), + array( + ' ', + true, + true, + 'SVG with javascript xlink (http://html5sec.org/#87)' + ), + array( + ' ', + true, + true, + 'SVG with Opera image xlink (http://html5sec.org/#88 - c)' + ), + array( + ' ', + true, + true, + 'SVG with Opera animation xlink (http://html5sec.org/#88 - a)' + ), + array( + ' ', + true, + true, + 'SVG with Opera animation xlink (http://html5sec.org/#88 - b)' + ), + array( + ' ', + true, + true, + 'SVG with Opera image xlink (http://html5sec.org/#88 - c)' + ), + array( + ' ', + true, + true, + 'SVG with Opera foreignObject xlink (http://html5sec.org/#88 - d)' + ), + array( + ' ', + true, + true, + 'SVG with Opera foreignObject xlink (http://html5sec.org/#88 - e)' + ), + array( + ' ', + true, + true, + 'SVG with event handler set (http://html5sec.org/#89 - a)' + ), + array( + ' ', + true, + true, + 'SVG with event handler animate (http://html5sec.org/#89 - a)' + ), + array( + ' alert(1) ', + true, + true, + 'SVG with element handler (http://html5sec.org/#94)' + ), + array( + ' ', + true, + true, + 'SVG with href to data: url (http://html5sec.org/#95)' + ), + array( + ' ', + true, + true, + 'SVG with Tiny handler (http://html5sec.org/#104)' + ), + array( + ' ', + true, + true, + 'SVG with new CSS styles properties (http://html5sec.org/#109)' + ), + array( + ' ', + true, + true, + 'SVG with new CSS styles properties as attributes' + ), + array( + ' ', + true, + true, + 'SVG with new CSS styles properties as attributes (2)' + ), + array( + ' ', + true, + true, + 'SVG with path marker-start (http://html5sec.org/#110)' + ), + array( + ' ]> ', + true, + true, + 'SVG with embedded stylesheet (http://html5sec.org/#125)' + ), + array( + ' alert(1) ', + true, + true, + 'SVG with handler attribute (http://html5sec.org/#127)' + ), + array( + // Haven't found a browser that accepts this particular example, but we + // don't want to allow embeded svgs, ever + ' ', + true, + true, + 'SVG with image filter via style (http://html5sec.org/#129)' + ), + array( + // This doesn't seem possible without embedding the svg, but just in case + ' ', + true, + true, + 'SVG with animate from (http://html5sec.org/#137)' + ), + array( + ' Click me ', + true, + true, + 'SVG with animate xlink:href (http://html5sec.org/#137)' + ), + array( + ' Click me ', + true, + true, + 'SVG with animate y:href (http://html5sec.org/#137)' + ), + + // Other hostile SVG's + array( + ' ', + true, + true, + 'SVG with non-local image href (bug 65839)' + ), + array( + ' 50 100 ', + true, + true, + 'SVG with remote stylesheet (bug 57550)' + ), + array( + ' B ', + true, + true, + 'SVG with rembeded iframe (bug 60771)' + ), + array( + ' WebPlatform.org ', + true, + true, + 'SVG with @import in style element (bug 69008)' + ), + array( + ' WebPlatform.org ', + true, + true, + 'SVG with @import in style element and child element (bug 69008#c11)' + ), + array( + ' WebPlatform.org ', + true, + true, + 'SVG with case-insensitive @import in style element (bug T85349)' + ), + array( + ' ', + true, + true, + 'SVG with remote background image (bug 69008)' + ), + array( + ' ', + true, + true, + 'SVG with remote background image, encoded (bug 69008)' + ), + array( + ' ', + true, + true, + 'SVG with remote background image, in style element (bug 69008)' + ), + array( + // This currently doesn't seem to work in any browsers, but in case + // http://www.w3.org/TR/css3-images/ is implemented for SVG files + ' ', + true, + true, + 'SVG with remote background image using image() (bug 69008)' + ), + array( + // As reported by Cure53 + ' ', + true, + true, + 'SVG with data:text/html link target (firefox only)' + ), + array( + ' ]> &lol2; ', + true, + true, + 'SVG with encoded script tag in internal entity (reported by Beyond Security)' + ), + array( + ' ]> &foo; ', + false, + false, + 'SVG with external entity' + ), + + // Test good, but strange files that we want to allow + array( + ' ', + true, + false, + 'SVG with link to a remote site' + ), + array( + ' 12345 ', + true, + false, + 'SVG with local urls, including filter: in style' + ), + ); + } +} + +class UploadTestHandler extends UploadBase { + public function initializeFromRequest( &$request ) { + } + + public function testTitleValidation( $name ) { + $this->mTitle = false; + $this->mDesiredDestName = $name; + $this->mTitleError = UploadBase::OK; + $this->getTitle(); + + return $this->mTitleError; + } + + /** + * Almost the same as UploadBase::detectScriptInSvg, except it's + * public, works on an xml string instead of filename, and returns + * the result instead of interpreting them. + */ + public function checkSvgString( $svg ) { + $check = new XmlTypeCheck( + $svg, + array( $this, 'checkSvgScriptCallback' ), + false, + array( 'processing_instruction_handler' => 'UploadBase::checkSvgPICallback' ) + ); + return array( $check->wellFormed, $check->filterMatch ); + } +} -- cgit v1.2.2