r94433 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r94432‎ | r94433 | r94434 >
Date:21:25, 13 August 2011
Author:catrope
Status:ok (Comments)
Tags:
Comment:
(bug 26486) ResourceLoader modules with paths to nonexistent files cause PHP warnings/notices to be thrown. Worked around all of them using file_exists() checks, and introduced a safe wrapper around filemtime() that checks for file_exists(). The only warning I couldn't squash is "Warning: array_map(): An error occurred while invoking the map callback" but that's due to a bug in PHP, which I've reported at https://bugs.php.net/bug.php?id=55416
Modified paths:
  • /trunk/phase3/RELEASE-NOTES-1.19 (modified) (history)
  • /trunk/phase3/includes/resourceloader/ResourceLoaderFileModule.php (modified) (history)

Diff [purge]

Index: trunk/phase3/RELEASE-NOTES-1.19
@@ -48,6 +48,8 @@
4949 * Do not convert text in the user interface language to another script.
5050 * (bug 26283) Previewing user JS/CSS pages doesn't load other user JS/CSS pages
5151 * (bug 11374) Improved diff readability for colorblind people.
 52+* (bug 26486) ResourceLoader modules with paths to nonexistent files cause PHP
 53+ warnings/notices to be thrown
5254
5355 === API changes in 1.19 ===
5456 * (bug 19838) siprop=interwikimap can now use the interwiki cache.
Index: trunk/phase3/includes/resourceloader/ResourceLoaderFileModule.php
@@ -367,7 +367,7 @@
368368 }
369369
370370 wfProfileIn( __METHOD__.'-filemtime' );
371 - $filesMtime = max( array_map( 'filemtime', $files ) );
 371+ $filesMtime = max( array_map( array( __CLASS__, 'safeFilemtime' ), $files ) );
372372 wfProfileOut( __METHOD__.'-filemtime' );
373373 $this->modifiedTime[$context->getHash()] = max(
374374 $filesMtime,
@@ -493,10 +493,10 @@
494494 $js = '';
495495 foreach ( array_unique( $scripts ) as $fileName ) {
496496 $localPath = $this->getLocalPath( $fileName );
497 - $contents = file_get_contents( $localPath );
498 - if ( $contents === false ) {
 497+ if ( !file_exists( $localPath ) ) {
499498 throw new MWException( __METHOD__.": script file not found: \"$localPath\"" );
500499 }
 500+ $contents = file_get_contents( $localPath );
501501 if ( $wgResourceLoaderValidateStaticJS ) {
502502 // Static files don't really need to be checked as often; unlike
503503 // on-wiki module they shouldn't change unexpectedly without
@@ -542,17 +542,18 @@
543543 *
544544 * This method can be used as a callback for array_map()
545545 *
546 - * @param $path String: File path of script file to read
 546+ * @param $path String: File path of style file to read
547547 * @param $flip bool
548548 *
549549 * @return String: CSS data in script file
 550+ * @throws MWException if the file doesn't exist
550551 */
551552 protected function readStyleFile( $path, $flip ) {
552553 $localPath = $this->getLocalPath( $path );
553 - $style = file_get_contents( $localPath );
554 - if ( $style === false ) {
 554+ if ( !file_exists( $localPath ) ) {
555555 throw new MWException( __METHOD__.": style file not found: \"$localPath\"" );
556556 }
 557+ $style = file_get_contents( $localPath );
557558 if ( $flip ) {
558559 $style = CSSJanus::transform( $style, true, false );
559560 }
@@ -571,6 +572,23 @@
572573 $style, $dir, $remoteDir, true
573574 );
574575 }
 576+
 577+ /**
 578+ * Safe version of filemtime(), which doesn't throw a PHP warning if the file doesn't exist
 579+ * but returns 1 instead.
 580+ * @param $filename string File name
 581+ * @return int UNIX timestamp, or 1 if the file doesn't exist
 582+ */
 583+ protected static function safeFilemtime( $filename ) {
 584+ if ( file_exists( $filename ) ) {
 585+ return filemtime( $filename );
 586+ } else {
 587+ // We only ever map this function on an array if we're gonna call max() after,
 588+ // so return our standard minimum timestamps here. This is 1, not 0, because
 589+ // wfTimestamp(0) == NOW
 590+ return 1;
 591+ }
 592+ }
575593
576594 /**
577595 * Get whether CSS for this module should be flipped

Follow-up revisions

RevisionCommit summaryAuthorDate
r96559MFT r92422, r93520, r93563, r94107, r94433, r95042, r95332, r95451, r96386...reedy12:49, 8 September 2011

Comments

#Comment by Krinkle (talk | contribs)   18:54, 14 August 2011

Wouldn't this make debugging harder if a script isn't loaded ? Is there some indication somewhere if there's a ResourceLoaderFileModule with an inexistent file path as a script ?

#Comment by Krinkle (talk | contribs)   18:55, 14 August 2011

Ah, scripts already have a MWException thrown if it doesn't file_exist(). Nice :)

#Comment by Catrope (talk | contribs)   20:38, 14 August 2011

Yes, we already throw exceptions if a file doesn't exist when we try to load it, but not when we check its timestamp. That seems reasonable to me. Actually, the remaining warning is thrown precisely because we map readScriptFile() on an array of script files and then throw an exception from inside that function.

#Comment by MaxSem (talk | contribs)   19:02, 23 August 2011

Seems to have shutted up the filemtime() warnings for me. Freaky stuff: all these warnings were for files that actually existed :/

Status & tagging log