[SPIP] ~maj v3.2.9-->v3.2.11
[lhc/web/www.git] / www / plugins-dist / medias / lib / getid3 / module.graphic.tiff.php
index 57d500f..5d40494 100644 (file)
@@ -14,6 +14,9 @@
 //                                                            ///
 /////////////////////////////////////////////////////////////////
 
+if (!defined('GETID3_INCLUDEPATH')) { // prevent path-exposing attacks that access modules directly on public webservers
+       exit;
+}
 
 class getid3_tiff extends getid3_handler
 {
@@ -36,14 +39,13 @@ class getid3_tiff extends getid3_handler
                        default:
                                $this->error('Invalid TIFF byte order identifier ('.substr($TIFFheader, 0, 2).') at offset '.$info['avdataoffset']);
                                return false;
-                               break;
                }
 
                $info['fileformat']          = 'tiff';
                $info['video']['dataformat'] = 'tiff';
                $info['video']['lossless']   = true;
                $info['tiff']['ifd']         = array();
-               $CurrentIFD                          = array();
+               $CurrentIFD                  = array();
 
                $FieldTypeByteLength = array(1=>1, 2=>1, 3=>2, 4=>4, 5=>8);
 
@@ -57,47 +59,61 @@ class getid3_tiff extends getid3_handler
                        $CurrentIFD['fieldcount'] = $this->TIFFendian2Int($this->fread(2), $info['tiff']['byte_order']);
 
                        for ($i = 0; $i < $CurrentIFD['fieldcount']; $i++) {
-                               $CurrentIFD['fields'][$i]['raw']['tag']    = $this->TIFFendian2Int($this->fread(2), $info['tiff']['byte_order']);
-                               $CurrentIFD['fields'][$i]['raw']['type']   = $this->TIFFendian2Int($this->fread(2), $info['tiff']['byte_order']);
-                               $CurrentIFD['fields'][$i]['raw']['length'] = $this->TIFFendian2Int($this->fread(4), $info['tiff']['byte_order']);
-                               $CurrentIFD['fields'][$i]['raw']['offset'] =                       $this->fread(4);
-
+                               $CurrentIFD['fields'][$i]['raw']['tag']      = $this->TIFFendian2Int($this->fread(2), $info['tiff']['byte_order']);
+                               $CurrentIFD['fields'][$i]['raw']['type']     = $this->TIFFendian2Int($this->fread(2), $info['tiff']['byte_order']);
+                               $CurrentIFD['fields'][$i]['raw']['length']   = $this->TIFFendian2Int($this->fread(4), $info['tiff']['byte_order']);
+                               $CurrentIFD['fields'][$i]['raw']['valoff']   =                       $this->fread(4); // To save time and space the Value Offset contains the Value instead of pointing to the Value if and only if the Value fits into 4 bytes. If the Value is shorter than 4 bytes, it is left-justified within the 4-byte Value Offset, i.e., stored in the lowernumbered bytes. Whether the Value fits within 4 bytes is determined by the Type and Count of the field.
                                $CurrentIFD['fields'][$i]['raw']['tag_name'] = $this->TIFFcommentName($CurrentIFD['fields'][$i]['raw']['tag']);
 
                                switch ($CurrentIFD['fields'][$i]['raw']['type']) {
                                        case 1: // BYTE  An 8-bit unsigned integer.
                                                if ($CurrentIFD['fields'][$i]['raw']['length'] <= 4) {
-                                                       $CurrentIFD['fields'][$i]['value']  = $this->TIFFendian2Int(substr($CurrentIFD['fields'][$i]['raw']['offset'], 0, 1), $info['tiff']['byte_order']);
+                                                       $CurrentIFD['fields'][$i]['value']  = $this->TIFFendian2Int(substr($CurrentIFD['fields'][$i]['raw']['valoff'], 0, 1), $info['tiff']['byte_order']);
                                                } else {
-                                                       $CurrentIFD['fields'][$i]['offset'] = $this->TIFFendian2Int($CurrentIFD['fields'][$i]['raw']['offset'], $info['tiff']['byte_order']);
+                                                       $CurrentIFD['fields'][$i]['offset'] = $this->TIFFendian2Int($CurrentIFD['fields'][$i]['raw']['valoff'], $info['tiff']['byte_order']);
                                                }
                                                break;
 
                                        case 2: // ASCII 8-bit bytes  that store ASCII codes; the last byte must be null.
                                                if ($CurrentIFD['fields'][$i]['raw']['length'] <= 4) {
-                                                       $CurrentIFD['fields'][$i]['value']  = substr($CurrentIFD['fields'][$i]['raw']['offset'], 3);
+                                                       $CurrentIFD['fields'][$i]['value']  = substr($CurrentIFD['fields'][$i]['raw']['valoff'], 3);
                                                } else {
-                                                       $CurrentIFD['fields'][$i]['offset'] = $this->TIFFendian2Int($CurrentIFD['fields'][$i]['raw']['offset'], $info['tiff']['byte_order']);
+                                                       $CurrentIFD['fields'][$i]['offset'] = $this->TIFFendian2Int($CurrentIFD['fields'][$i]['raw']['valoff'], $info['tiff']['byte_order']);
                                                }
                                                break;
 
                                        case 3: // SHORT A 16-bit (2-byte) unsigned integer.
                                                if ($CurrentIFD['fields'][$i]['raw']['length'] <= 2) {
-                                                       $CurrentIFD['fields'][$i]['value']  = $this->TIFFendian2Int(substr($CurrentIFD['fields'][$i]['raw']['offset'], 0, 2), $info['tiff']['byte_order']);
+                                                       $CurrentIFD['fields'][$i]['value']  = $this->TIFFendian2Int(substr($CurrentIFD['fields'][$i]['raw']['valoff'], 0, 2), $info['tiff']['byte_order']);
                                                } else {
-                                                       $CurrentIFD['fields'][$i]['offset'] = $this->TIFFendian2Int($CurrentIFD['fields'][$i]['raw']['offset'], $info['tiff']['byte_order']);
+                                                       $CurrentIFD['fields'][$i]['offset'] = $this->TIFFendian2Int($CurrentIFD['fields'][$i]['raw']['valoff'], $info['tiff']['byte_order']);
                                                }
                                                break;
 
                                        case 4: // LONG  A 32-bit (4-byte) unsigned integer.
-                                               if ($CurrentIFD['fields'][$i]['raw']['length'] <= 1) {
-                                                       $CurrentIFD['fields'][$i]['value']  = $this->TIFFendian2Int($CurrentIFD['fields'][$i]['raw']['offset'], $info['tiff']['byte_order']);
+                                               if ($CurrentIFD['fields'][$i]['raw']['length'] <= 4) {
+                                                       $CurrentIFD['fields'][$i]['value']  = $this->TIFFendian2Int($CurrentIFD['fields'][$i]['raw']['valoff'], $info['tiff']['byte_order']);
                                                } else {
-                                                       $CurrentIFD['fields'][$i]['offset'] = $this->TIFFendian2Int($CurrentIFD['fields'][$i]['raw']['offset'], $info['tiff']['byte_order']);
+                                                       $CurrentIFD['fields'][$i]['offset'] = $this->TIFFendian2Int($CurrentIFD['fields'][$i]['raw']['valoff'], $info['tiff']['byte_order']);
                                                }
                                                break;
 
                                        case 5: // RATIONAL   Two LONG_s:  the first represents the numerator of a fraction, the second the denominator.
+                                       case 7: // UNDEFINED An 8-bit byte that may contain anything, depending on the definition of the field.
+                                               $CurrentIFD['fields'][$i]['offset'] = $this->TIFFendian2Int($CurrentIFD['fields'][$i]['raw']['valoff'], $info['tiff']['byte_order']);
+                                               break;
+
+                                       // Warning: It is possible that other TIFF field types will be added in the future. Readers should skip over fields containing an unexpected field type.
+                                       // In TIFF 6.0, some new field types have been defined:
+                                       // These new field types are also governed by the byte order (II or MM) in the TIFF header.
+                                       case 6: // SBYTE An 8-bit signed (twos-complement) integer.
+                                       case 8: // SSHORT A 16-bit (2-byte) signed (twos-complement) integer.
+                                       case 9: // SLONG A 32-bit (4-byte) signed (twos-complement) integer.
+                                       case 10: // SRATIONAL Two SLONGs: the first represents the numerator of a fraction, the second the denominator.
+                                       case 11: // FLOAT Single precision (4-byte) IEEE format
+                                       case 12: // DOUBLE Double precision (8-byte) IEEE format
+                                       default:
+                                               $this->warning('unhandled IFD field type '.$CurrentIFD['fields'][$i]['raw']['type'].' for IFD entry '.$i);
                                                break;
                                }
                        }
@@ -137,6 +153,16 @@ class getid3_tiff extends getid3_handler
 
                                                }
                                                break;
+                                       case 700:
+                                               $XMPmagic = '<?xpacket';
+                                               $this->fseek($fieldarray['offset']);
+                                               $xmpkey = (isset($info['tiff']['XMP']) ? count($info['tiff']['XMP']) : 0);
+                                               $info['tiff']['XMP'][$xmpkey]['raw'] = $this->fread($fieldarray['raw']['length']);
+                                               if (substr($info['tiff']['XMP'][$xmpkey]['raw'], 0, strlen($XMPmagic)) != $XMPmagic) {
+                                                       $this->warning('did not find expected XMP data at offset '.$fieldarray['offset']);
+                                                       unset($info['tiff']['XMP'][$xmpkey]['raw']);
+                                               }
+                                               break;
                                }
                                switch ($fieldarray['raw']['tag']) {
                                        case 256: // ImageWidth
@@ -207,14 +233,33 @@ class getid3_tiff extends getid3_handler
         * @return string
         */
        public function TIFFcompressionMethod($id) {
+               // https://en.wikipedia.org/wiki/TIFF#TIFF_Compression_Tag
                static $TIFFcompressionMethod = array();
                if (empty($TIFFcompressionMethod)) {
                        $TIFFcompressionMethod = array(
-                               1     => 'Uncompressed',
-                               2     => 'Huffman',
-                               3     => 'Fax - CCITT 3',
-                               5     => 'LZW',
-                               32773 => 'PackBits',
+                               0x0001 => 'Uncompressed',
+                               0x0002 => 'Huffman',
+                               0x0003 => 'CCITT T.4',
+                               0x0004 => 'CCITT T.6',
+                               0x0005 => 'LZW',
+                               0x0006 => 'JPEG-old',
+                               0x0007 => 'JPEG',
+                               0x0008 => 'deflate',
+                               0x0009 => 'JBIG ITU-T T.85',
+                               0x000A => 'JBIG ITU-T T.43',
+                               0x7FFE => 'NeXT RLE 2-bit',
+                               0x8005 => 'PackBits',
+                               0x8029 => 'ThunderScan RLE 4-bit',
+                               0x807F => 'RasterPadding',
+                               0x8080 => 'RLE-LW',
+                               0x8081 => 'RLE-CT',
+                               0x8082 => 'RLE-BL',
+                               0x80B2 => 'deflate-PK',
+                               0x80B3 => 'Kodak-DCS',
+                               0x8765 => 'JBIG',
+                               0x8798 => 'JPEG2000',
+                               0x8799 => 'Nikon NEF',
+                               0x879B => 'JBIG2',
                        );
                }
                return (isset($TIFFcompressionMethod[$id]) ? $TIFFcompressionMethod[$id] : 'unknown/invalid ('.$id.')');