media: Log and fail gracefully on invalid EXIF coordinates
[lhc/web/wiklou.git] / includes / media / FormatMetadata.php
index f683da2..2a5a56f 100644 (file)
@@ -271,7 +271,7 @@ class FormatMetadata extends ContextSource {
                                        // TODO: YCbCrCoefficients  #p27 (see annex E)
                                        case 'ExifVersion':
                                        case 'FlashpixVersion':
-                                               $val = "$val" / 100;
+                                               $val = (int)$val / 100;
                                                break;
 
                                        case 'ColorSpace':
@@ -1400,11 +1400,16 @@ class FormatMetadata extends ContextSource {
         * Format a coordinate value, convert numbers from floating point
         * into degree minute second representation.
         *
-        * @param int $coord Degrees, minutes and seconds
-        * @param string $type Latitude or longitude (for if its a NWS or E)
-        * @return mixed A floating point number or whatever we were fed
+        * @param float|string $coord Expected to be a number or numeric string in degrees
+        * @param string $type "latitude" or "longitude"
+        * @return string
         */
        private function formatCoords( $coord, $type ) {
+               if ( !is_numeric( $coord ) ) {
+                       wfDebugLog( 'exif', __METHOD__ . ": \"$coord\" is not a number" );
+                       return (string)$coord;
+               }
+
                $ref = '';
                if ( $coord < 0 ) {
                        $nCoord = -$coord;
@@ -1414,7 +1419,7 @@ class FormatMetadata extends ContextSource {
                                $ref = 'W';
                        }
                } else {
-                       $nCoord = $coord;
+                       $nCoord = (float)$coord;
                        if ( $type === 'latitude' ) {
                                $ref = 'N';
                        } elseif ( $type === 'longitude' ) {
@@ -1423,13 +1428,14 @@ class FormatMetadata extends ContextSource {
                }
 
                $deg = floor( $nCoord );
-               $min = floor( ( $nCoord - $deg ) * 60.0 );
-               $sec = round( ( ( $nCoord - $deg ) - $min / 60 ) * 3600, 2 );
+               $min = floor( ( $nCoord - $deg ) * 60 );
+               $sec = round( ( ( $nCoord - $deg ) * 60 - $min ) * 60, 2 );
 
                $deg = $this->formatNum( $deg );
                $min = $this->formatNum( $min );
                $sec = $this->formatNum( $sec );
 
+               // Note the default message "$1° $2′ $3″ $4" ignores the 5th parameter
                return $this->msg( 'exif-coordinate-format', $deg, $min, $sec, $ref, $coord )->text();
        }
 
@@ -1859,9 +1865,9 @@ class FormatMetadata extends ContextSource {
                // drop all characters which are not valid in an XML tag name
                // a bunch of non-ASCII letters would be valid but probably won't
                // be used so we take the easy way
-               $key = preg_replace( '/[^a-zA-z0-9_:.-]/', '', $key );
+               $key = preg_replace( '/[^a-zA-z0-9_:.\-]/', '', $key );
                // drop characters which are invalid at the first position
-               $key = preg_replace( '/^[\d-.]+/', '', $key );
+               $key = preg_replace( '/^[\d\-.]+/', '', $key );
 
                if ( $key == '' ) {
                        $key = '_';