Browse Source

Mise à jour de la lib getid3 en 1.9.18, nous étions en 1.9.16.

Le changelog est dispo ici: https://github.com/JamesHeinrich/getID3/blob/v1.9.18/changelog.txt
pull/1/head
spip.franck@lien-d-amis.net 2 years ago
parent
commit
570f5ff2c9
  1. 1
      .gitattributes
  2. 2
      lib/getid3/extension.cache.mysql.php
  3. 72
      lib/getid3/extension.cache.mysqli.php
  4. 239
      lib/getid3/getid3.lib.php
  5. 63
      lib/getid3/getid3.php
  6. 4
      lib/getid3/module.archive.tar.php
  7. 42
      lib/getid3/module.archive.xz.php
  8. 18
      lib/getid3/module.archive.zip.php
  9. 42
      lib/getid3/module.audio-video.asf.php
  10. 2
      lib/getid3/module.audio-video.matroska.php
  11. 10
      lib/getid3/module.audio-video.mpeg.php
  12. 69
      lib/getid3/module.audio-video.quicktime.php
  13. 97
      lib/getid3/module.audio-video.riff.php
  14. 16
      lib/getid3/module.audio.ac3.php
  15. 2
      lib/getid3/module.audio.bonk.php
  16. 4
      lib/getid3/module.audio.dss.php
  17. 8
      lib/getid3/module.audio.dts.php
  18. 2
      lib/getid3/module.audio.flac.php
  19. 10
      lib/getid3/module.audio.midi.php
  20. 2
      lib/getid3/module.audio.monkey.php
  21. 49
      lib/getid3/module.audio.mp3.php
  22. 6
      lib/getid3/module.audio.tta.php
  23. 2
      lib/getid3/module.audio.voc.php
  24. 10
      lib/getid3/module.audio.wavpack.php
  25. 10
      lib/getid3/module.graphic.bmp.php
  26. 23
      lib/getid3/module.graphic.gif.php
  27. 8
      lib/getid3/module.graphic.pcd.php
  28. 83
      lib/getid3/module.graphic.tiff.php
  29. 20
      lib/getid3/module.misc.iso.php
  30. 18
      lib/getid3/module.tag.apetag.php
  31. 10
      lib/getid3/module.tag.id3v1.php
  32. 228
      lib/getid3/module.tag.id3v2.php
  33. 16
      lib/getid3/module.tag.xmp.php
  34. 16
      lib/getid3/write.id3v1.php
  35. 17
      lib/getid3/write.id3v2.php
  36. 24
      lib/getid3/write.php
  37. 2
      paquet.xml

1
.gitattributes

@ -142,6 +142,7 @@ lib/getid3/module.archive.gzip.php -text
lib/getid3/module.archive.rar.php -text
lib/getid3/module.archive.szip.php -text
lib/getid3/module.archive.tar.php -text
lib/getid3/module.archive.xz.php -text
lib/getid3/module.archive.zip.php -text
lib/getid3/module.audio-video.asf.php -text
lib/getid3/module.audio-video.bink.php -text

2
lib/getid3/extension.cache.mysql.php

@ -167,7 +167,7 @@ class getID3_cached_mysql extends getID3
*/
public function analyze($filename, $filesize=null, $original_filename='') {
$filetime = 0;
$filetime = 0;
if (file_exists($filename)) {
// Short-hands

72
lib/getid3/extension.cache.mysqli.php

@ -87,6 +87,11 @@ class getID3_cached_mysqli extends getID3
*/
private $table;
/**
* @var bool
*/
private $db_structure_check;
/**
* constructor - see top of this file for cache type and cache_options
@ -124,14 +129,15 @@ class getID3_cached_mysqli extends getID3
// Create cache table if not exists
$this->create_table();
$this->db_structure_check = true; // set to false if you know your table structure has already been migrated to use `hash` as the primary key to avoid
$this->migrate_db_structure();
// Check version number and clear cache if changed
$version = '';
$SQLquery = 'SELECT `value`';
$SQLquery .= ' FROM `'.$this->mysqli->real_escape_string($this->table).'`';
$SQLquery .= ' WHERE (`filename` = \''.$this->mysqli->real_escape_string(getID3::VERSION).'\')';
$SQLquery .= ' AND (`filesize` = -1)';
$SQLquery .= ' AND (`filetime` = -1)';
$SQLquery .= ' AND (`analyzetime` = -1)';
$SQLquery .= ' AND (`hash` = \'getID3::VERSION\')';
if ($this->cursor = $this->mysqli->query($SQLquery)) {
list($version) = $this->cursor->fetch_array();
}
@ -147,8 +153,39 @@ class getID3_cached_mysqli extends getID3
* clear cache
*/
public function clear_cache() {
$this->mysqli->query('DELETE FROM `'.$this->mysqli->real_escape_string($this->table).'`');
$this->mysqli->query('INSERT INTO `'.$this->mysqli->real_escape_string($this->table).'` (`filename`, `filesize`, `filetime`, `analyzetime`, `value`) VALUES (\''.getID3::VERSION.'\', -1, -1, -1, \''.getID3::VERSION.'\')');
$this->mysqli->query('TRUNCATE TABLE `'.$this->mysqli->real_escape_string($this->table).'`');
$this->mysqli->query('INSERT INTO `'.$this->mysqli->real_escape_string($this->table).'` (`hash`, `filename`, `filesize`, `filetime`, `analyzetime`, `value`) VALUES (\'getID3::VERSION\', \''.getID3::VERSION.'\', -1, -1, -1, \''.getID3::VERSION.'\')');
}
/**
* migrate database structure if needed
*/
public function migrate_db_structure() {
// Check for table structure
if ($this->db_structure_check) {
$SQLquery = 'SHOW COLUMNS';
$SQLquery .= ' FROM `'.$this->mysqli->real_escape_string($this->table).'`';
$SQLquery .= ' LIKE \'hash\'';
$this->cursor = $this->mysqli->query($SQLquery);
if ($this->cursor->num_rows == 0) {
// table has not been migrated, add column, add hashes, change index
$SQLquery = 'ALTER TABLE `getid3_cache` DROP PRIMARY KEY, ADD `hash` CHAR(32) NOT NULL DEFAULT \'\' FIRST, ADD PRIMARY KEY(`hash`)';
$this->mysqli->query($SQLquery);
$SQLquery = 'UPDATE `getid3_cache` SET';
$SQLquery .= ' `hash` = MD5(`filename`, `filesize`, `filetime`)';
$SQLquery .= ' WHERE (`filesize` > -1)';
$this->mysqli->query($SQLquery);
$SQLquery = 'UPDATE `getid3_cache` SET';
$SQLquery .= ' `hash` = \'getID3::VERSION\'';
$SQLquery .= ' WHERE (`filesize` = -1)';
$SQLquery .= ' AND (`filetime` = -1)';
$SQLquery .= ' AND (`filetime` = -1)';
$this->mysqli->query($SQLquery);
}
}
}
@ -163,7 +200,7 @@ class getID3_cached_mysqli extends getID3
*/
public function analyze($filename, $filesize=null, $original_filename='') {
$filetime = 0;
$filetime = 0;
if (file_exists($filename)) {
// Short-hands
@ -173,9 +210,7 @@ class getID3_cached_mysqli extends getID3
// Lookup file
$SQLquery = 'SELECT `value`';
$SQLquery .= ' FROM `'.$this->mysqli->real_escape_string($this->table).'`';
$SQLquery .= ' WHERE (`filename` = \''.$this->mysqli->real_escape_string($filename).'\')';
$SQLquery .= ' AND (`filesize` = \''.$this->mysqli->real_escape_string($filesize).'\')';
$SQLquery .= ' AND (`filetime` = \''.$this->mysqli->real_escape_string($filetime).'\')';
$SQLquery .= ' WHERE (`hash` = \''.$this->mysqli->real_escape_string(md5($filename.$filesize.$filetime)).'\')';
$this->cursor = $this->mysqli->query($SQLquery);
if ($this->cursor->num_rows > 0) {
// Hit
@ -189,12 +224,14 @@ class getID3_cached_mysqli extends getID3
// Save result
if (file_exists($filename)) {
$SQLquery = 'INSERT INTO `'.$this->mysqli->real_escape_string($this->table).'` (`filename`, `filesize`, `filetime`, `analyzetime`, `value`) VALUES (';
$SQLquery .= '\''.$this->mysqli->real_escape_string($filename).'\'';
$SQLquery = 'INSERT INTO `'.$this->mysqli->real_escape_string($this->table).'` (`hash`, `filename`, `filesize`, `filetime`, `analyzetime`, `value`) VALUES (';
$SQLquery .= '\''.$this->mysqli->real_escape_string(md5($filename.$filesize.$filetime)).'\'';
$SQLquery .= ', \''.$this->mysqli->real_escape_string($filename).'\'';
$SQLquery .= ', \''.$this->mysqli->real_escape_string($filesize).'\'';
$SQLquery .= ', \''.$this->mysqli->real_escape_string($filetime).'\'';
$SQLquery .= ', \''.$this->mysqli->real_escape_string(time() ).'\'';
$SQLquery .= ', \''.$this->mysqli->real_escape_string(base64_encode(serialize($analysis))).'\')';
$SQLquery .= ', UNIX_TIMESTAMP()';
$SQLquery .= ', \''.$this->mysqli->real_escape_string(base64_encode(serialize($analysis))).'\'';
$SQLquery .= ')';
$this->cursor = $this->mysqli->query($SQLquery);
}
return $analysis;
@ -207,13 +244,18 @@ class getID3_cached_mysqli extends getID3
* @param bool $drop
*/
private function create_table($drop=false) {
if ($drop) {
$SQLquery = 'DROP TABLE IF EXISTS `'.$this->mysqli->real_escape_string($this->table).'`';
$this->mysqli->query($SQLquery);
}
$SQLquery = 'CREATE TABLE IF NOT EXISTS `'.$this->mysqli->real_escape_string($this->table).'` (';
$SQLquery .= '`filename` VARCHAR(990) NOT NULL DEFAULT \'\'';
$SQLquery .= '`hash` CHAR(32) NOT NULL DEFAULT \'\'';
$SQLquery .= ', `filename` VARCHAR(1000) NOT NULL DEFAULT \'\'';
$SQLquery .= ', `filesize` INT(11) NOT NULL DEFAULT \'0\'';
$SQLquery .= ', `filetime` INT(11) NOT NULL DEFAULT \'0\'';
$SQLquery .= ', `analyzetime` INT(11) NOT NULL DEFAULT \'0\'';
$SQLquery .= ', `value` LONGTEXT NOT NULL';
$SQLquery .= ', PRIMARY KEY (`filename`, `filesize`, `filetime`))';
$SQLquery .= ', PRIMARY KEY (`hash`))';
$this->cursor = $this->mysqli->query($SQLquery);
echo $this->mysqli->error;
}

239
lib/getid3/getid3.lib.php

@ -26,9 +26,9 @@ class getid3_lib
$returnstring = '';
for ($i = 0; $i < strlen($string); $i++) {
if ($hex) {
$returnstring .= str_pad(dechex(ord($string{$i})), 2, '0', STR_PAD_LEFT);
$returnstring .= str_pad(dechex(ord($string[$i])), 2, '0', STR_PAD_LEFT);
} else {
$returnstring .= ' '.(preg_match("#[\x20-\x7E]#", $string{$i}) ? $string{$i} : '¤');
$returnstring .= ' '.(preg_match("#[\x20-\x7E]#", $string[$i]) ? $string[$i] : '¤');
}
if ($spaces) {
$returnstring .= ' ';
@ -152,11 +152,11 @@ class getid3_lib
public static function NormalizeBinaryPoint($binarypointnumber, $maxbits=52) {
if (strpos($binarypointnumber, '.') === false) {
$binarypointnumber = '0.'.$binarypointnumber;
} elseif ($binarypointnumber{0} == '.') {
} elseif ($binarypointnumber[0] == '.') {
$binarypointnumber = '0'.$binarypointnumber;
}
$exponent = 0;
while (($binarypointnumber{0} != '1') || (substr($binarypointnumber, 1, 1) != '.')) {
while (($binarypointnumber[0] != '1') || (substr($binarypointnumber, 1, 1) != '.')) {
if (substr($binarypointnumber, 1, 1) == '.') {
$exponent--;
$binarypointnumber = substr($binarypointnumber, 2, 1).'.'.substr($binarypointnumber, 3);
@ -164,7 +164,7 @@ class getid3_lib
$pointpos = strpos($binarypointnumber, '.');
$exponent += ($pointpos - 1);
$binarypointnumber = str_replace('.', '', $binarypointnumber);
$binarypointnumber = $binarypointnumber{0}.'.'.substr($binarypointnumber, 1);
$binarypointnumber = $binarypointnumber[0].'.'.substr($binarypointnumber, 1);
}
}
$binarypointnumber = str_pad(substr($binarypointnumber, 0, $maxbits + 2), $maxbits + 2, '0', STR_PAD_RIGHT);
@ -255,7 +255,7 @@ class getid3_lib
if (!$bitword) {
return 0;
}
$signbit = $bitword{0};
$signbit = $bitword[0];
$floatvalue = 0;
$exponentbits = 0;
$fractionbits = 0;
@ -275,7 +275,7 @@ class getid3_lib
// 80-bit Apple SANE format
// http://www.mactech.com/articles/mactech/Vol.06/06.01/SANENormalized/
$exponentstring = substr($bitword, 1, 15);
$isnormalized = intval($bitword{16});
$isnormalized = intval($bitword[16]);
$fractionstring = substr($bitword, 17, 63);
$exponent = pow(2, self::Bin2Dec($exponentstring) - 16383);
$fraction = $isnormalized + self::DecimalBinary2Float($fractionstring);
@ -343,9 +343,9 @@ class getid3_lib
for ($i = 0; $i < $bytewordlen; $i++) {
if ($synchsafe) { // disregard MSB, effectively 7-bit bytes
//$intvalue = $intvalue | (ord($byteword{$i}) & 0x7F) << (($bytewordlen - 1 - $i) * 7); // faster, but runs into problems past 2^31 on 32-bit systems
$intvalue += (ord($byteword{$i}) & 0x7F) * pow(2, ($bytewordlen - 1 - $i) * 7);
$intvalue += (ord($byteword[$i]) & 0x7F) * pow(2, ($bytewordlen - 1 - $i) * 7);
} else {
$intvalue += ord($byteword{$i}) * pow(256, ($bytewordlen - 1 - $i));
$intvalue += ord($byteword[$i]) * pow(256, ($bytewordlen - 1 - $i));
}
}
if ($signed && !$synchsafe) {
@ -390,7 +390,7 @@ class getid3_lib
$binvalue = '';
$bytewordlen = strlen($byteword);
for ($i = 0; $i < $bytewordlen; $i++) {
$binvalue .= str_pad(decbin(ord($byteword{$i})), 8, '0', STR_PAD_LEFT);
$binvalue .= str_pad(decbin(ord($byteword[$i])), 8, '0', STR_PAD_LEFT);
}
return $binvalue;
}
@ -451,7 +451,7 @@ class getid3_lib
public static function Bin2Dec($binstring, $signed=false) {
$signmult = 1;
if ($signed) {
if ($binstring{0} == '1') {
if ($binstring[0] == '1') {
$signmult = -1;
}
$binstring = substr($binstring, 1);
@ -751,9 +751,7 @@ class getid3_lib
}
/**
* self::md5_data() - returns md5sum for a file from startuing position to absolute end position
*
* @author Allan Hansen <ahØartemis*dk>
* Returns checksum for a file from starting position to absolute end position.
*
* @param string $file
* @param int $offset
@ -761,97 +759,30 @@ class getid3_lib
* @param string $algorithm
*
* @return string|false
* @throws Exception
* @throws getid3_exception
*/
public static function hash_data($file, $offset, $end, $algorithm) {
static $tempdir = '';
$windows_call = null;
$unix_call = null;
$hash_length = null;
$hash_function = null;
if (!self::intValueSupported($end)) {
return false;
}
switch ($algorithm) {
case 'md5':
$hash_function = 'md5_file';
$unix_call = 'md5sum';
$windows_call = 'md5sum.exe';
$hash_length = 32;
break;
case 'sha1':
$hash_function = 'sha1_file';
$unix_call = 'sha1sum';
$windows_call = 'sha1sum.exe';
$hash_length = 40;
break;
default:
throw new Exception('Invalid algorithm ('.$algorithm.') in self::hash_data()');
break;
if (!in_array($algorithm, array('md5', 'sha1'))) {
throw new getid3_exception('Invalid algorithm ('.$algorithm.') in self::hash_data()');
}
$size = $end - $offset;
while (true) {
if (GETID3_OS_ISWINDOWS) {
// It seems that sha1sum.exe for Windows only works on physical files, does not accept piped data
// Fall back to create-temp-file method:
if ($algorithm == 'sha1') {
break;
}
$RequiredFiles = array('cygwin1.dll', 'head.exe', 'tail.exe', $windows_call);
foreach ($RequiredFiles as $required_file) {
if (!is_readable(GETID3_HELPERAPPSDIR.$required_file)) {
// helper apps not available - fall back to old method
break 2;
}
}
$commandline = GETID3_HELPERAPPSDIR.'head.exe -c '.$end.' '.escapeshellarg(str_replace('/', DIRECTORY_SEPARATOR, $file)).' | ';
$commandline .= GETID3_HELPERAPPSDIR.'tail.exe -c '.$size.' | ';
$commandline .= GETID3_HELPERAPPSDIR.$windows_call;
} else {
$commandline = 'head -c'.$end.' '.escapeshellarg($file).' | ';
$commandline .= 'tail -c'.$size.' | ';
$commandline .= $unix_call;
}
if (preg_match('#(1|ON)#i', ini_get('safe_mode'))) {
//throw new Exception('PHP running in Safe Mode - backtick operator not available, using slower non-system-call '.$algorithm.' algorithm');
break;
}
return substr(`$commandline`, 0, $hash_length);
}
$size = $end - $offset;
if (empty($tempdir)) {
// yes this is ugly, feel free to suggest a better way
require_once(dirname(__FILE__).'/getid3.php');
$getid3_temp = new getID3();
$tempdir = $getid3_temp->tempdir;
unset($getid3_temp);
}
// try to create a temporary file in the system temp directory - invalid dirname should force to system temp dir
if (($data_filename = tempnam($tempdir, 'gI3')) === false) {
// can't find anywhere to create a temp file, just fail
return false;
$fp = fopen($file, 'rb');
fseek($fp, $offset);
$ctx = hash_init($algorithm);
while ($size > 0) {
$buffer = fread($fp, min($size, getID3::FREAD_BUFFER_SIZE));
hash_update($ctx, $buffer);
$size -= getID3::FREAD_BUFFER_SIZE;
}
$hash = hash_final($ctx);
fclose($fp);
// Init
$result = false;
// copy parts of file
try {
self::CopyFileParts($file, $data_filename, $offset, $end - $offset);
$result = $hash_function($data_filename);
} catch (Exception $e) {
throw new Exception('self::CopyFileParts() failed in getid_lib::hash_data(): '.$e->getMessage());
}
unlink($data_filename);
return $result;
return $hash;
}
/**
@ -862,6 +793,8 @@ class getid3_lib
*
* @return bool
* @throws Exception
*
* @deprecated Unused, may be removed in future versions of getID3
*/
public static function CopyFileParts($filename_source, $filename_dest, $offset, $length) {
if (!self::intValueSupported($offset + $length)) {
@ -935,7 +868,7 @@ class getid3_lib
$newcharstring .= "\xEF\xBB\xBF";
}
for ($i = 0; $i < strlen($string); $i++) {
$charval = ord($string{$i});
$charval = ord($string[$i]);
$newcharstring .= self::iconv_fallback_int_utf8($charval);
}
return $newcharstring;
@ -955,7 +888,7 @@ class getid3_lib
$newcharstring .= "\xFE\xFF";
}
for ($i = 0; $i < strlen($string); $i++) {
$newcharstring .= "\x00".$string{$i};
$newcharstring .= "\x00".$string[$i];
}
return $newcharstring;
}
@ -974,7 +907,7 @@ class getid3_lib
$newcharstring .= "\xFF\xFE";
}
for ($i = 0; $i < strlen($string); $i++) {
$newcharstring .= $string{$i}."\x00";
$newcharstring .= $string[$i]."\x00";
}
return $newcharstring;
}
@ -1006,27 +939,27 @@ class getid3_lib
$offset = 0;
$stringlength = strlen($string);
while ($offset < $stringlength) {
if ((ord($string{$offset}) | 0x07) == 0xF7) {
if ((ord($string[$offset]) | 0x07) == 0xF7) {
// 11110bbb 10bbbbbb 10bbbbbb 10bbbbbb
$charval = ((ord($string{($offset + 0)}) & 0x07) << 18) &
((ord($string{($offset + 1)}) & 0x3F) << 12) &
((ord($string{($offset + 2)}) & 0x3F) << 6) &
(ord($string{($offset + 3)}) & 0x3F);
$charval = ((ord($string[($offset + 0)]) & 0x07) << 18) &
((ord($string[($offset + 1)]) & 0x3F) << 12) &
((ord($string[($offset + 2)]) & 0x3F) << 6) &
(ord($string[($offset + 3)]) & 0x3F);
$offset += 4;
} elseif ((ord($string{$offset}) | 0x0F) == 0xEF) {
} elseif ((ord($string[$offset]) | 0x0F) == 0xEF) {
// 1110bbbb 10bbbbbb 10bbbbbb
$charval = ((ord($string{($offset + 0)}) & 0x0F) << 12) &
((ord($string{($offset + 1)}) & 0x3F) << 6) &
(ord($string{($offset + 2)}) & 0x3F);
$charval = ((ord($string[($offset + 0)]) & 0x0F) << 12) &
((ord($string[($offset + 1)]) & 0x3F) << 6) &
(ord($string[($offset + 2)]) & 0x3F);
$offset += 3;
} elseif ((ord($string{$offset}) | 0x1F) == 0xDF) {
} elseif ((ord($string[$offset]) | 0x1F) == 0xDF) {
// 110bbbbb 10bbbbbb
$charval = ((ord($string{($offset + 0)}) & 0x1F) << 6) &
(ord($string{($offset + 1)}) & 0x3F);
$charval = ((ord($string[($offset + 0)]) & 0x1F) << 6) &
(ord($string[($offset + 1)]) & 0x3F);
$offset += 2;
} elseif ((ord($string{$offset}) | 0x7F) == 0x7F) {
} elseif ((ord($string[$offset]) | 0x7F) == 0x7F) {
// 0bbbbbbb
$charval = ord($string{$offset});
$charval = ord($string[$offset]);
$offset += 1;
} else {
// error? throw some kind of warning here?
@ -1056,27 +989,27 @@ class getid3_lib
$offset = 0;
$stringlength = strlen($string);
while ($offset < $stringlength) {
if ((ord($string{$offset}) | 0x07) == 0xF7) {
if ((ord($string[$offset]) | 0x07) == 0xF7) {
// 11110bbb 10bbbbbb 10bbbbbb 10bbbbbb
$charval = ((ord($string{($offset + 0)}) & 0x07) << 18) &
((ord($string{($offset + 1)}) & 0x3F) << 12) &
((ord($string{($offset + 2)}) & 0x3F) << 6) &
(ord($string{($offset + 3)}) & 0x3F);
$charval = ((ord($string[($offset + 0)]) & 0x07) << 18) &
((ord($string[($offset + 1)]) & 0x3F) << 12) &
((ord($string[($offset + 2)]) & 0x3F) << 6) &
(ord($string[($offset + 3)]) & 0x3F);
$offset += 4;
} elseif ((ord($string{$offset}) | 0x0F) == 0xEF) {
} elseif ((ord($string[$offset]) | 0x0F) == 0xEF) {
// 1110bbbb 10bbbbbb 10bbbbbb
$charval = ((ord($string{($offset + 0)}) & 0x0F) << 12) &
((ord($string{($offset + 1)}) & 0x3F) << 6) &
(ord($string{($offset + 2)}) & 0x3F);
$charval = ((ord($string[($offset + 0)]) & 0x0F) << 12) &
((ord($string[($offset + 1)]) & 0x3F) << 6) &
(ord($string[($offset + 2)]) & 0x3F);
$offset += 3;
} elseif ((ord($string{$offset}) | 0x1F) == 0xDF) {
} elseif ((ord($string[$offset]) | 0x1F) == 0xDF) {
// 110bbbbb 10bbbbbb
$charval = ((ord($string{($offset + 0)}) & 0x1F) << 6) &
(ord($string{($offset + 1)}) & 0x3F);
$charval = ((ord($string[($offset + 0)]) & 0x1F) << 6) &
(ord($string[($offset + 1)]) & 0x3F);
$offset += 2;
} elseif ((ord($string{$offset}) | 0x7F) == 0x7F) {
} elseif ((ord($string[$offset]) | 0x7F) == 0x7F) {
// 0bbbbbbb
$charval = ord($string{$offset});
$charval = ord($string[$offset]);
$offset += 1;
} else {
// error? throw some kind of warning here?
@ -1106,27 +1039,27 @@ class getid3_lib
$offset = 0;
$stringlength = strlen($string);
while ($offset < $stringlength) {
if ((ord($string{$offset}) | 0x07) == 0xF7) {
if ((ord($string[$offset]) | 0x07) == 0xF7) {
// 11110bbb 10bbbbbb 10bbbbbb 10bbbbbb
$charval = ((ord($string{($offset + 0)}) & 0x07) << 18) &
((ord($string{($offset + 1)}) & 0x3F) << 12) &
((ord($string{($offset + 2)}) & 0x3F) << 6) &
(ord($string{($offset + 3)}) & 0x3F);
$charval = ((ord($string[($offset + 0)]) & 0x07) << 18) &
((ord($string[($offset + 1)]) & 0x3F) << 12) &
((ord($string[($offset + 2)]) & 0x3F) << 6) &
(ord($string[($offset + 3)]) & 0x3F);
$offset += 4;
} elseif ((ord($string{$offset}) | 0x0F) == 0xEF) {
} elseif ((ord($string[$offset]) | 0x0F) == 0xEF) {
// 1110bbbb 10bbbbbb 10bbbbbb
$charval = ((ord($string{($offset + 0)}) & 0x0F) << 12) &
((ord($string{($offset + 1)}) & 0x3F) << 6) &
(ord($string{($offset + 2)}) & 0x3F);
$charval = ((ord($string[($offset + 0)]) & 0x0F) << 12) &
((ord($string[($offset + 1)]) & 0x3F) << 6) &
(ord($string[($offset + 2)]) & 0x3F);
$offset += 3;
} elseif ((ord($string{$offset}) | 0x1F) == 0xDF) {
} elseif ((ord($string[$offset]) | 0x1F) == 0xDF) {
// 110bbbbb 10bbbbbb
$charval = ((ord($string{($offset + 0)}) & 0x1F) << 6) &
(ord($string{($offset + 1)}) & 0x3F);
$charval = ((ord($string[($offset + 0)]) & 0x1F) << 6) &
(ord($string[($offset + 1)]) & 0x3F);
$offset += 2;
} elseif ((ord($string{$offset}) | 0x7F) == 0x7F) {
} elseif ((ord($string[$offset]) | 0x7F) == 0x7F) {
// 0bbbbbbb
$charval = ord($string{$offset});
$charval = ord($string[$offset]);
$offset += 1;
} else {
// error? maybe throw some warning here?
@ -1281,6 +1214,16 @@ class getid3_lib
// mb_convert_encoding() available
if (function_exists('mb_convert_encoding')) {
if ((strtoupper($in_charset) == 'UTF-16') && (substr($string, 0, 2) != "\xFE\xFF") && (substr($string, 0, 2) != "\xFF\xFE")) {
// if BOM missing, mb_convert_encoding will mishandle the conversion, assume UTF-16BE and prepend appropriate BOM
$string = "\xFF\xFE".$string;
}
if ((strtoupper($in_charset) == 'UTF-16') && (strtoupper($out_charset) == 'UTF-8')) {
if (($string == "\xFF\xFE") || ($string == "\xFE\xFF")) {
// if string consists of only BOM, mb_convert_encoding will return the BOM unmodified
return '';
}
}
if ($converted_string = @mb_convert_encoding($string, $out_charset, $in_charset)) {
switch ($out_charset) {
case 'ISO-8859-1':
@ -1290,9 +1233,9 @@ class getid3_lib
return $converted_string;
}
return $string;
}
// iconv() available
else if (function_exists('iconv')) {
} elseif (function_exists('iconv')) {
if ($converted_string = @iconv($in_charset, $out_charset.'//TRANSLIT', $string)) {
switch ($out_charset) {
case 'ISO-8859-1':
@ -1397,22 +1340,22 @@ class getid3_lib
case 'utf-8':
$strlen = strlen($string);
for ($i = 0; $i < $strlen; $i++) {
$char_ord_val = ord($string{$i});
$char_ord_val = ord($string[$i]);
$charval = 0;
if ($char_ord_val < 0x80) {
$charval = $char_ord_val;
} elseif ((($char_ord_val & 0xF0) >> 4) == 0x0F && $i+3 < $strlen) {
$charval = (($char_ord_val & 0x07) << 18);
$charval += ((ord($string{++$i}) & 0x3F) << 12);
$charval += ((ord($string{++$i}) & 0x3F) << 6);
$charval += (ord($string{++$i}) & 0x3F);
$charval += ((ord($string[++$i]) & 0x3F) << 12);
$charval += ((ord($string[++$i]) & 0x3F) << 6);
$charval += (ord($string[++$i]) & 0x3F);
} elseif ((($char_ord_val & 0xE0) >> 5) == 0x07 && $i+2 < $strlen) {
$charval = (($char_ord_val & 0x0F) << 12);
$charval += ((ord($string{++$i}) & 0x3F) << 6);
$charval += (ord($string{++$i}) & 0x3F);
$charval += ((ord($string[++$i]) & 0x3F) << 6);
$charval += (ord($string[++$i]) & 0x3F);
} elseif ((($char_ord_val & 0xC0) >> 6) == 0x03 && $i+1 < $strlen) {
$charval = (($char_ord_val & 0x1F) << 6);
$charval += (ord($string{++$i}) & 0x3F);
$charval += (ord($string[++$i]) & 0x3F);
}
if (($charval >= 32) && ($charval <= 127)) {
$HTMLstring .= htmlentities(chr($charval));

63
lib/getid3/getid3.php

@ -1,5 +1,4 @@
<?php
/////////////////////////////////////////////////////////////////
/// getID3() by James Heinrich <info@getid3.org> //
// available at https://github.com/JamesHeinrich/getID3 //
@ -251,7 +250,7 @@ class getID3
*/
protected $startup_warning = '';
const VERSION = '1.9.16-201810171314';
const VERSION = '1.9.18-201907240906';
const FREAD_BUFFER_SIZE = 32768;
const ATTACHMENTS_NONE = false;
@ -321,7 +320,7 @@ class getID3
// Needed for Windows only:
// Define locations of helper applications for Shorten, VorbisComment, MetaFLAC
// as well as other helper functions such as head, tail, md5sum, etc
// as well as other helper functions such as head, etc
// This path cannot contain spaces, but the below code will attempt to get the
// 8.3-equivalent path automatically
// IMPORTANT: This path must include the trailing slash
@ -406,7 +405,7 @@ class getID3
*
* @throws getid3_exception
*/
public function openfile($filename, $filesize=null) {
public function openfile($filename, $filesize=null, $fp=null) {
try {
if (!empty($this->startup_error)) {
throw new getid3_exception($this->startup_error);
@ -433,7 +432,9 @@ class getID3
// open local file
//if (is_readable($filename) && is_file($filename) && ($this->fp = fopen($filename, 'rb'))) { // see https://www.getid3.org/phpBB3/viewtopic.php?t=1720
if ((is_readable($filename) || file_exists($filename)) && is_file($filename) && ($this->fp = fopen($filename, 'rb'))) {
if (($fp != null) && ((get_resource_type($fp) == 'file') || (get_resource_type($fp) == 'stream'))) {
$this->fp = $fp;
} elseif ((is_readable($filename) || file_exists($filename)) && is_file($filename) && ($this->fp = fopen($filename, 'rb'))) {
// great
} else {
$errormessagelist = array();
@ -514,9 +515,9 @@ class getID3
*
* @return array
*/
public function analyze($filename, $filesize=null, $original_filename='') {
public function analyze($filename, $filesize=null, $original_filename='', $fp=null) {
try {
if (!$this->openfile($filename, $filesize)) {
if (!$this->openfile($filename, $filesize, $fp)) {
return $this->info;
}
@ -550,8 +551,8 @@ class getID3
$header = fread($this->fp, 10);
if ((substr($header, 0, 3) == 'ID3') && (strlen($header) == 10)) {
$this->info['id3v2']['header'] = true;
$this->info['id3v2']['majorversion'] = ord($header{3});
$this->info['id3v2']['minorversion'] = ord($header{4});
$this->info['id3v2']['majorversion'] = ord($header[3]);
$this->info['id3v2']['minorversion'] = ord($header[4]);
$this->info['avdataoffset'] += getid3_lib::BigEndian2Int(substr($header, 6, 4), 1) + 10; // length of ID3v2 tag in 10-byte header doesn't include 10-byte header length
}
}
@ -833,7 +834,7 @@ class getID3
// DSS - audio - Digital Speech Standard
'dss' => array(
'pattern' => '^[\\x02-\\x06]ds[s2]',
'pattern' => '^[\\x02-\\x08]ds[s2]',
'group' => 'audio',
'module' => 'dss',
'mime_type' => 'application/octet-stream',
@ -1252,6 +1253,16 @@ class getID3
'fail_ape' => 'ERROR',
),
// XZ - data - XZ compressed data
'xz' => array(
'pattern' => '^\\xFD7zXZ\\x00',
'group' => 'archive',
'module' => 'xz',
'mime_type' => 'application/x-xz',
'fail_id3' => 'ERROR',
'fail_ape' => 'ERROR',
),
// Misc other formats
@ -1323,7 +1334,7 @@ class getID3
if (preg_match('#\\.mp[123a]$#i', $filename)) {
// Too many mp3 encoders on the market put gabage in front of mpeg files
// Too many mp3 encoders on the market put garbage in front of mpeg files
// use assume format on these if format detection failed
$GetFileFormatArray = $this->GetFileFormatArray();
$info = $GetFileFormatArray['mp3'];
@ -1427,6 +1438,7 @@ class getID3
}
}
if ($tag_key == 'picture') {
// pictures can take up a lot of space, and we don't need multiple copies of them; let there be a single copy in [comments][picture], and not elsewhere
unset($this->info[$comment_name]['comments'][$tag_key]);
}
}
@ -1440,6 +1452,11 @@ class getID3
if ($this->option_tags_html) {
foreach ($this->info['tags'][$tag_name] as $tag_key => $valuearray) {
if ($tag_key == 'picture') {
// Do not to try to convert binary picture data to HTML
// https://github.com/JamesHeinrich/getID3/issues/178
continue;
}
$this->info['tags_html'][$tag_name][$tag_key] = getid3_lib::recursiveMultiByteCharString2HTML($valuearray, $this->info[$comment_name]['encoding']);
}
}
@ -1448,8 +1465,7 @@ class getID3
}
// pictures can take up a lot of space, and we don't need multiple copies of them
// let there be a single copy in [comments][picture], and not elsewhere
// pictures can take up a lot of space, and we don't need multiple copies of them; let there be a single copy in [comments][picture], and not elsewhere
if (!empty($this->info['tags'])) {
$unset_keys = array('tags', 'tags_html');
foreach ($this->info['tags'] as $tagtype => $tagarray) {
@ -1824,16 +1840,14 @@ class getID3
*
* @return bool
*/
public static function is_writable ($filename) {
$ret = is_writable($filename);
if (!$ret) {
$perms = fileperms($filename);
$ret = ($perms & 0x0080) || ($perms & 0x0010) || ($perms & 0x0002);
}
return $ret;
}
public static function is_writable ($filename) {
$ret = is_writable($filename);
if (!$ret) {
$perms = fileperms($filename);
$ret = ($perms & 0x0080) || ($perms & 0x0010) || ($perms & 0x0002);
}
return $ret;
}
}
@ -1976,7 +1990,8 @@ abstract class getid3_handler
*/
$contents = '';
do {
if (($this->getid3->memory_limit > 0) && ($bytes > $this->getid3->memory_limit)) {
//if (($this->getid3->memory_limit > 0) && ($bytes > $this->getid3->memory_limit)) {
if (($this->getid3->memory_limit > 0) && (($bytes / $this->getid3->memory_limit) > 0.99)) { // enable a more-fuzzy match to prevent close misses generating errors like "PHP Fatal error: Allowed memory size of 33554432 bytes exhausted (tried to allocate 33554464 bytes)"
throw new getid3_exception('cannot fread('.$bytes.' from '.$this->ftell().') that is more than available PHP memory ('.$this->getid3->memory_limit.')', 10);
}
$part = fread($this->getid3->fp, $bytes);

4
lib/getid3/module.archive.tar.php

@ -44,13 +44,13 @@ class getid3_tar extends getid3_handler
// check the block
$checksum = 0;
for ($i = 0; $i < 148; $i++) {
$checksum += ord($buffer{$i});
$checksum += ord($buffer[$i]);
}
for ($i = 148; $i < 156; $i++) {
$checksum += ord(' ');
}
for ($i = 156; $i < 512; $i++) {
$checksum += ord($buffer{$i});
$checksum += ord($buffer[$i]);
}
$attr = unpack($unpack_header, $buffer);
$name = (isset($attr['fname'] ) ? trim($attr['fname'] ) : '');

42
lib/getid3/module.archive.xz.php

@ -0,0 +1,42 @@
<?php
/////////////////////////////////////////////////////////////////
/// getID3() by James Heinrich <info@getid3.org> //
// available at https://github.com/JamesHeinrich/getID3 //
// or https://www.getid3.org //
// or http://getid3.sourceforge.net //
// see readme.txt for more details //
/////////////////////////////////////////////////////////////////
// //
// module.archive.xz.php //
// module for analyzing XZ files //
// dependencies: NONE //
// ///
/////////////////////////////////////////////////////////////////
class getid3_xz extends getid3_handler
{
/**
* @return bool
*/
public function Analyze() {
$info = &$this->getid3->info;
$this->fseek($info['avdataoffset']);
$xzheader = $this->fread(6);
// https://tukaani.org/xz/xz-file-format-1.0.4.txt
$info['xz']['stream_header']['magic'] = substr($xzheader, 0, 6);
if ($info['xz']['stream_header']['magic'] != "\xFD".'7zXZ'."\x00") {
$this->error('Invalid XZ stream header magic (expecting FD 37 7A 58 5A 00, found '.getid3_lib::PrintHexBytes($info['xz']['stream_header']['magic']).') at offset '.$info['avdataoffset']);
return false;
}
$info['fileformat'] = 'xz';
$this->error('XZ parsing not enabled in this version of getID3() ['.$this->getid3->version().']');
return false;
}
}

18
lib/getid3/module.archive.zip.php

@ -96,15 +96,15 @@ class getid3_zip extends getid3_handler
!empty($info['zip']['files']['_rels']['.rels']) &&
!empty($info['zip']['files']['docProps']['app.xml']) &&
!empty($info['zip']['files']['docProps']['core.xml'])) {
// http://technet.microsoft.com/en-us/library/cc179224.aspx
$info['fileformat'] = 'zip.msoffice';
if (!empty($ThisFileInfo['zip']['files']['ppt'])) {
$info['mime_type'] = 'application/vnd.openxmlformats-officedocument.presentationml.presentation';
} elseif (!empty($ThisFileInfo['zip']['files']['xl'])) {
$info['mime_type'] = 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet';
} elseif (!empty($ThisFileInfo['zip']['files']['word'])) {
$info['mime_type'] = 'application/vnd.openxmlformats-officedocument.wordprocessingml.document';
}
// http://technet.microsoft.com/en-us/library/cc179224.aspx
$info['fileformat'] = 'zip.msoffice';
if (!empty($ThisFileInfo['zip']['files']['ppt'])) {
$info['mime_type'] = 'application/vnd.openxmlformats-officedocument.presentationml.presentation';
} elseif (!empty($ThisFileInfo['zip']['files']['xl'])) {
$info['mime_type'] = 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet';
} elseif (!empty($ThisFileInfo['zip']['files']['word'])) {
$info['mime_type'] = 'application/vnd.openxmlformats-officedocument.wordprocessingml.document';
}
}
return true;

42
lib/getid3/module.audio-video.asf.php

@ -797,17 +797,17 @@ class getid3_asf extends getid3_handler
case 'wm/tracknumber':
case 'tracknumber':
// be careful casting to int: casting unicode strings to int gives unexpected results (stops parsing at first non-numeric character)
$thisfile_asf_comments['track'] = array($this->TrimTerm($thisfile_asf_extendedcontentdescriptionobject_contentdescriptor_current['value']));
foreach ($thisfile_asf_comments['track'] as $key => $value) {
$thisfile_asf_comments['track_number'] = array($this->TrimTerm($thisfile_asf_extendedcontentdescriptionobject_contentdescriptor_current['value']));
foreach ($thisfile_asf_comments['track_number'] as $key => $value) {
if (preg_match('/^[0-9\x00]+$/', $value)) {
$thisfile_asf_comments['track'][$key] = intval(str_replace("\x00", '', $value));
$thisfile_asf_comments['track_number'][$key] = intval(str_replace("\x00", '', $value));
}
}
break;
case 'wm/track':
if (empty($thisfile_asf_comments['track'])) {
$thisfile_asf_comments['track'] = array(1 + $this->TrimConvert($thisfile_asf_extendedcontentdescriptionobject_contentdescriptor_current['value']));
if (empty($thisfile_asf_comments['track_number'])) {
$thisfile_asf_comments['track_number'] = array(1 + $this->TrimConvert($thisfile_asf_extendedcontentdescriptionobject_contentdescriptor_current['value']));
}
break;
@ -1653,26 +1653,26 @@ class getid3_asf extends getid3_handler
* @return string
*/
public static function BytestringToGUID($Bytestring) {
$GUIDstring = str_pad(dechex(ord($Bytestring{3})), 2, '0', STR_PAD_LEFT);
$GUIDstring .= str_pad(dechex(ord($Bytestring{2})), 2, '0', STR_PAD_LEFT);
$GUIDstring .= str_pad(dechex(ord($Bytestring{1})), 2, '0', STR_PAD_LEFT);
$GUIDstring .= str_pad(dechex(ord($Bytestring{0})), 2, '0', STR_PAD_LEFT);
$GUIDstring = str_pad(dechex(ord($Bytestring[3])), 2, '0', STR_PAD_LEFT);
$GUIDstring .= str_pad(dechex(ord($Bytestring[2])), 2, '0', STR_PAD_LEFT);
$GUIDstring .= str_pad(dechex(ord($Bytestring[1])), 2, '0', STR_PAD_LEFT);
$GUIDstring .= str_pad(dechex(ord($Bytestring[0])), 2, '0', STR_PAD_LEFT);
$GUIDstring .= '-';
$GUIDstring .= str_pad(dechex(ord($Bytestring{5})), 2, '0', STR_PAD_LEFT);
$GUIDstring .= str_pad(dechex(ord($Bytestring{4})), 2, '0', STR_PAD_LEFT);
$GUIDstring .= str_pad(dechex(ord($Bytestring[5])), 2, '0', STR_PAD_LEFT);
$GUIDstring .= str_pad(dechex(ord($Bytestring[4])), 2, '0', STR_PAD_LEFT);
$GUIDstring .= '-';
$GUIDstring .= str_pad(dechex(ord($Bytestring{7})), 2, '0', STR_PAD_LEFT);
$GUIDstring .= str_pad(dechex(ord($Bytestring{6})), 2, '0', STR_PAD_LEFT);
$GUIDstring .= str_pad(dechex(ord($Bytestring[7])), 2, '0', STR_PAD_LEFT);
$GUIDstring .= str_pad(dechex(ord($Bytestring[6])), 2, '0', STR_PAD_LEFT);
$GUIDstring .= '-';
$GUIDstring .= str_pad(dechex(ord($Bytestring{8})), 2, '0', STR_PAD_LEFT);
$GUIDstring .= str_pad(dechex(ord($Bytestring{9})), 2, '0', STR_PAD_LEFT);
$GUIDstring .= str_pad(dechex(ord($Bytestring[8])), 2, '0', STR_PAD_LEFT);
$GUIDstring .= str_pad(dechex(ord($Bytestring[9])), 2, '0', STR_PAD_LEFT);
$GUIDstring .= '-';
$GUIDstring .= str_pad(dechex(ord($Bytestring{10})), 2, '0', STR_PAD_LEFT);
$GUIDstring .= str_pad(dechex(ord($Bytestring{11})), 2, '0', STR_PAD_LEFT);
$GUIDstring .= str_pad(dechex(ord($Bytestring{12})), 2, '0', STR_PAD_LEFT);
$GUIDstring .= str_pad(dechex(ord($Bytestring{13})), 2, '0', STR_PAD_LEFT);
$GUIDstring .= str_pad(dechex(ord($Bytestring{14})), 2, '0', STR_PAD_LEFT);
$GUIDstring .= str_pad(dechex(ord($Bytestring{15})), 2, '0', STR_PAD_LEFT);
$GUIDstring .= str_pad(dechex(ord($Bytestring[10])), 2, '0', STR_PAD_LEFT);
$GUIDstring .= str_pad(dechex(ord($Bytestring[11])), 2, '0', STR_PAD_LEFT);
$GUIDstring .= str_pad(dechex(ord($Bytestring[12])), 2, '0', STR_PAD_LEFT);
$GUIDstring .= str_pad(dechex(ord($Bytestring[13])), 2, '0', STR_PAD_LEFT);
$GUIDstring .= str_pad(dechex(ord($Bytestring[14])), 2, '0', STR_PAD_LEFT);
$GUIDstring .= str_pad(dechex(ord($Bytestring[15])), 2, '0', STR_PAD_LEFT);
return strtoupper($GUIDstring);
}

2
lib/getid3/module.audio-video.matroska.php

@ -342,7 +342,7 @@ class getid3_matroska extends getid3_handler
switch ($trackarray['CodecID']) {
case 'A_PCM/INT/LIT':
case 'A_PCM/INT/BIG':
$track_info['bitrate'] = $trackarray['SamplingFrequency'] * $trackarray['Channels'] * $trackarray['BitDepth'];
$track_info['bitrate'] = $track_info['sample_rate'] * $track_info['channels'] * $trackarray['BitDepth'];
break;
case 'A_AC3':

10
lib/getid3/module.audio-video.mpeg.php

@ -90,11 +90,9 @@ class getid3_mpeg extends getid3_handler
break;
case 0xB3: // sequence_header_code
/*
Note: purposely doing the less-pretty (and probably a bit slower) method of using string of bits rather than bitwise operations.
Mostly because PHP 32-bit doesn't handle unsigned integers well for bitwise operation.
Also the MPEG stream is designed as a bitstream and often doesn't align nicely with byte boundaries.
*/
// Note: purposely doing the less-pretty (and probably a bit slower) method of using string of bits rather than bitwise operations.
// Mostly because PHP 32-bit doesn't handle unsigned integers well for bitwise operation.
// Also the MPEG stream is designed as a bitstream and often doesn't align nicely with byte boundaries.
$info['video']['codec'] = 'MPEG-1'; // will be updated if extension_start_code found
$bitstream = getid3_lib::BigEndian2Bin(substr($MPEGstreamData, $StartCodeOffset + 4, 8));
@ -622,7 +620,7 @@ echo 'average_File_bitrate = '.number_format(array_sum($vbr_bitrates) / count($v
/**
* @param int $rawaspectratio
* @param int $mpeg_version
* @param int $mpeg_version
*
* @return string
*/

69
lib/getid3/module.audio-video.quicktime.php

@ -38,7 +38,7 @@ class getid3_quicktime extends getid3_handler
$offset = 0;
$atomcounter = 0;
$atom_data_read_buffer_size = max($this->getid3->option_fread_buffer_size * 1024, ($info['php_memory_limit'] ? round($info['php_memory_limit'] / 4) : 1024)); // set read buffer to 25% of PHP memory limit (if one is specified), otherwise use option_fread_buffer_size [default: 32MB]
$atom_data_read_buffer_size = $info['php_memory_limit'] ? round($info['php_memory_limit'] / 4) : $this->getid3->option_fread_buffer_size * 1024; // set read buffer to 25% of PHP memory limit (if one is specified), otherwise use option_fread_buffer_size [default: 32MB]
while ($offset < $info['avdataend']) {
if (!getid3_lib::intValueSupported($offset)) {
$this->error('Unable to parse atom at offset '.$offset.' because beyond '.round(PHP_INT_MAX / 1073741824).'GB limit of PHP filesystem functions');
@ -568,8 +568,8 @@ class getid3_quicktime extends getid3_handler
}
}
}
$this->CopyToAppropriateCommentsSection($atomname, $atom_structure['data'], $atom_structure['name']);
break;
$this->CopyToAppropriateCommentsSection($atomname, $atom_structure['data'], $atom_structure['name']);
break;
case 'play': // auto-PLAY atom
@ -2654,7 +2654,7 @@ class getid3_quicktime extends getid3_handler
$handyatomtranslatorarray["\xA9".'src'] = 'source_credit';
$handyatomtranslatorarray["\xA9".'swr'] = 'software';
$handyatomtranslatorarray["\xA9".'too'] = 'encoding_tool'; // iTunes 4.0
$handyatomtranslatorarray["\xA9".'trk'] = 'track';
$handyatomtranslatorarray["\xA9".'trk'] = 'track_number';
$handyatomtranslatorarray["\xA9".'url'] = 'url';
$handyatomtranslatorarray["\xA9".'wrn'] = 'warning';
$handyatomtranslatorarray["\xA9".'wrt'] = 'composer';
@ -2752,38 +2752,35 @@ class getid3_quicktime extends getid3_handler
*
* @return string
*/
public function LociString($lstring, &$count) {
// Loci strings are UTF-8 or UTF-16 and null (x00/x0000) terminated. UTF-16 has a BOM
// Also need to return the number of bytes the string occupied so additional fields can be extracted
$len = strlen($lstring);
if ($len == 0) {
$count = 0;
return '';
}
if ($lstring[0] == "\x00") {
$count = 1;
return '';
}
//check for BOM
if ($len > 2 && (($lstring[0] == "\xFE" && $lstring[1] == "\xFF") || ($lstring[0] == "\xFF" && $lstring[1] == "\xFE"))) {
//UTF-16
if (preg_match('/(.*)\x00/', $lstring, $lmatches)){
$count = strlen($lmatches[1]) * 2 + 2; //account for 2 byte characters and trailing \x0000
return getid3_lib::iconv_fallback_utf16_utf8($lmatches[1]);
} else {
return '';
}
} else {
//UTF-8
if (preg_match('/(.*)\x00/', $lstring, $lmatches)){
$count = strlen($lmatches[1]) + 1; //account for trailing \x00
return $lmatches[1];
}else {
return '';
}
}
}
public function LociString($lstring, &$count) {
// Loci strings are UTF-8 or UTF-16 and null (x00/x0000) terminated. UTF-16 has a BOM
// Also need to return the number of bytes the string occupied so additional fields can be extracted
$len = strlen($lstring);
if ($len == 0) {
$count = 0;
return '';
}
if ($lstring[0] == "\x00") {
$count = 1;
return '';
}
// check for BOM
if (($len > 2) && ((($lstring[0] == "\xFE") && ($lstring[1] == "\xFF")) || (($lstring[0] == "\xFF") && ($lstring[1] == "\xFE")))) {
// UTF-16
if (preg_match('/(.*)\x00/', $lstring, $lmatches)) {
$count = strlen($lmatches[1]) * 2 + 2; //account for 2 byte characters and trailing \x0000
return getid3_lib::iconv_fallback_utf16_utf8($lmatches[1]);
} else {
return '';
}
}
// UTF-8
if (preg_match('/(.*)\x00/', $lstring, $lmatches)) {
$count = strlen($lmatches[1]) + 1; //account for trailing \x00
return $lmatches[1];
}
return '';
}
/**
* @param string $nullterminatedstring

97
lib/getid3/module.audio-video.riff.php

@ -51,7 +51,7 @@ class getid3_riff extends getid3_handler
$thisfile_audio_dataformat = &$thisfile_audio['dataformat'];
$thisfile_riff_audio = &$thisfile_riff['audio'];
$thisfile_riff_video = &$thisfile_riff['video'];
$thisfile_riff_WAVE = array();
$thisfile_riff_WAVE = array();
$Original['avdataoffset'] = $info['avdataoffset'];
$Original['avdataend'] = $info['avdataend'];
@ -703,13 +703,13 @@ class getid3_riff extends getid3_handler
'capturedfile' => 0x00010000,
'copyrighted' => 0x00020010,
);
foreach ($flags as $flag => $value) {
foreach ($flags as $flag => $value) {
$thisfile_riff_raw_avih['flags'][$flag] = (bool) ($thisfile_riff_raw_avih['dwFlags'] & $value);
}
// shortcut
$thisfile_riff_video[$streamindex] = array();
/** @var array $thisfile_riff_video_current */
/** @var array $thisfile_riff_video_current */
$thisfile_riff_video_current = &$thisfile_riff_video[$streamindex];
if ($thisfile_riff_raw_avih['dwWidth'] > 0) {
@ -923,7 +923,7 @@ class getid3_riff extends getid3_handler
// http://en.wikipedia.org/wiki/CD-DA
case 'CDDA':
$info['fileformat'] = 'cda';
unset($info['mime_type']);
unset($info['mime_type']);
$thisfile_audio_dataformat = 'cda';
@ -943,7 +943,7 @@ class getid3_riff extends getid3_handler
$thisfile_riff_CDDA_fmt_0['start_offset_seconds'] = (float) $thisfile_riff_CDDA_fmt_0['start_offset_frame'] / 75;
$thisfile_riff_CDDA_fmt_0['playtime_seconds'] = (float) $thisfile_riff_CDDA_fmt_0['playtime_frames'] / 75;
$info['comments']['track'] = $thisfile_riff_CDDA_fmt_0['track_num'];
$info['comments']['track_number'] = $thisfile_riff_CDDA_fmt_0['track_num'];
$info['playtime_seconds'] = $thisfile_riff_CDDA_fmt_0['playtime_seconds'];
// hardcoded data for CD-audio
@ -956,7 +956,7 @@ class getid3_riff extends getid3_handler
}
break;
// http://en.wikipedia.org/wiki/AIFF
// http://en.wikipedia.org/wiki/AIFF
case 'AIFF':
case 'AIFC':
$info['fileformat'] = 'aiff';
@ -1066,7 +1066,7 @@ class getid3_riff extends getid3_handler
if (isset($thisfile_riff[$RIFFsubtype]['ID3 '])) {
getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.tag.id3v2.php', __FILE__, true);
$getid3_temp = new getID3();
$getid3_temp->openfile($this->getid3->filename);
$getid3_temp->openfile($this->getid3->filename, null, $this->getid3->fp);
$getid3_id3v2 = new getid3_id3v2($getid3_temp);
$getid3_id3v2->StartingOffset = $thisfile_riff[$RIFFsubtype]['ID3 '][0]['offset'] + 8;
if ($thisfile_riff[$RIFFsubtype]['ID3 '][0]['valid'] = $getid3_id3v2->Analyze()) {
@ -1169,7 +1169,7 @@ class getid3_riff extends getid3_handler
getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.audio-video.mpeg.php', __FILE__, true);
$getid3_temp = new getID3();
$getid3_temp->openfile($this->getid3->filename);
$getid3_temp->openfile($this->getid3->filename, null, $this->getid3->fp);
$getid3_mpeg = new getid3_mpeg($getid3_temp);
$getid3_mpeg->Analyze();
if (empty($getid3_temp->info['error'])) {
@ -1255,7 +1255,7 @@ class getid3_riff extends getid3_handler
getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.tag.id3v2.php', __FILE__, true);
$getid3_temp = new getID3();
$getid3_temp->openfile($this->getid3->filename);
$getid3_temp->openfile($this->getid3->filename, null, $this->getid3->fp);
$getid3_id3v2 = new getid3_id3v2($getid3_temp);
$getid3_id3v2->StartingOffset = $thisfile_riff[$RIFFsubtype]['id3 '][0]['offset'] + 8;
if ($thisfile_riff[$RIFFsubtype]['id3 '][0]['valid'] = $getid3_id3v2->Analyze()) {
@ -1554,7 +1554,7 @@ class getid3_riff extends getid3_handler
// MP3
if (getid3_mp3::MPEGaudioHeaderBytesValid($FirstFourBytes)) {
$getid3_temp = new getID3();
$getid3_temp->openfile($this->getid3->filename);
$getid3_temp->openfile($this->getid3->filename, null, $this->getid3->fp);
$getid3_temp->info['avdataoffset'] = $this->ftell() - 4;
$getid3_temp->info['avdataend'] = $this->ftell() + $AudioChunkSize;
$getid3_mp3 = new getid3_mp3($getid3_temp, __CLASS__);
@ -1576,7 +1576,7 @@ class getid3_riff extends getid3_handler
// AC3
$getid3_temp = new getID3();
$getid3_temp->openfile($this->getid3->filename);
$getid3_temp->openfile($this->getid3->filename, null, $this->getid3->fp);
$getid3_temp->info['avdataoffset'] = $this->ftell() - 4;
$getid3_temp->info['avdataend'] = $this->ftell() + $AudioChunkSize;
$getid3_ac3 = new getid3_ac3($getid3_temp);
@ -1637,7 +1637,7 @@ class getid3_riff extends getid3_handler
// Probably is MP3 data
if (getid3_mp3::MPEGaudioHeaderBytesValid(substr($testData, 0, 4))) {
$getid3_temp = new getID3();
$getid3_temp->openfile($this->getid3->filename);
$getid3_temp->openfile($this->getid3->filename, null, $this->getid3->fp);
$getid3_temp->info['avdataoffset'] = $info['avdataoffset'];
$getid3_temp->info['avdataend'] = $info['avdataend'];
$getid3_mp3 = new getid3_mp3($getid3_temp, __CLASS__);
@ -1654,7 +1654,7 @@ class getid3_riff extends getid3_handler
// This is probably AC-3 data
$getid3_temp = new getID3();
if ($isRegularAC3) {
$getid3_temp->openfile($this->getid3->filename);
$getid3_temp->openfile($this->getid3->filename, null, $this->getid3->fp);
$getid3_temp->info['avdataoffset'] = $info['avdataoffset'];
$getid3_temp->info['avdataend'] = $info['avdataend'];
}
@ -1688,7 +1688,7 @@ class getid3_riff extends getid3_handler
// This is probably DTS data
$getid3_temp = new getID3();
$getid3_temp->openfile($this->getid3->filename);
$getid3_temp->openfile($this->getid3->filename, null, $this->getid3->fp);
$getid3_temp->info['avdataoffset'] = $info['avdataoffset'];
$getid3_dts = new getid3_dts($getid3_temp);
$getid3_dts->Analyze();
@ -1756,6 +1756,75 @@ class getid3_riff extends getid3_handler
// $info['divxtag']['comments'] = self::ParseDIVXTAG($this->fread($chunksize));
// break;
case 'scot':
// https://cmsdk.com/node-js/adding-scot-chunk-to-wav-file.html
$RIFFchunk[$chunkname][$thisindex]['data'] = $this->fread($chunksize);
$RIFFchunk[$chunkname][$thisindex]['parsed']['alter'] = substr($RIFFchunk[$chunkname][$thisindex]['data'], 0, 1);
$RIFFchunk[$chunkname][$thisindex]['parsed']['attrib'] = substr($RIFFchunk[$chunkname][$thisindex]['data'], 1, 1);
$RIFFchunk[$chunkname][$thisindex]['parsed']['artnum'] = getid3_lib::LittleEndian2Int(substr($RIFFchunk[$chunkname][$thisindex]['data'], 2, 2));
$RIFFchunk[$chunkname][$thisindex]['parsed']['title'] = substr($RIFFchunk[$chunkname][$thisindex]['data'], 4, 43); // "name" in other documentation
$RIFFchunk[$chunkname][$thisindex]['parsed']['copy'] = substr($RIFFchunk[$chunkname][$thisindex]['data'], 47, 4);
$RIFFchunk[$chunkname][$thisindex]['parsed']['padd'] = substr($RIFFchunk[$chunkname][$thisindex]['data'], 51, 1);
$RIFFchunk[$chunkname][$thisindex]['parsed']['asclen'] = substr($RIFFchunk[$chunkname][$thisindex]['data'], 52, 5);
$RIFFchunk[$chunkname][$thisindex]['parsed']['startseconds'] = getid3_lib::LittleEndian2Int(substr($RIFFchunk[$chunkname][$thisindex]['data'], 57, 2));
$RIFFchunk[$chunkname][$thisindex]['parsed']['starthundredths'] = getid3_lib::LittleEndian2Int(substr($RIFFchunk[$chunkname][$thisindex]['data'], 59, 2));
$RIFFchunk[$chunkname][$thisindex]['parsed']['endseconds'] = getid3_lib::LittleEndian2Int(substr($RIFFchunk[$chunkname][$thisindex]['data'], 61, 2));
$RIFFchunk[$chunkname][$thisindex]['parsed']['endhundreths'] = getid3_lib::LittleEndian2Int(substr($RIFFchunk[$chunkname][$thisindex]['data'], 63, 2));
$RIFFchunk[$chunkname][$thisindex]['parsed']['sdate'] = substr($RIFFchunk[$chunkname][$thisindex]['data'], 65, 6);
$RIFFchunk[$chunkname][$thisindex]['parsed']['kdate'] = substr($RIFFchunk[$chunkname][$thisindex]['data'], 71, 6);
$RIFFchunk[$chunkname][$thisindex]['parsed']['start_hr'] = substr($RIFFchunk[$chunkname][$thisindex]['data'], 77, 1);
$RIFFchunk[$chunkname][$thisindex]['parsed']['kill_hr'] = substr($RIFFchunk[$chunkname][$thisindex]['data'], 78, 1);
$RIFFchunk[$chunkname][$thisindex]['parsed']['digital'] = substr($RIFFchunk[$chunkname][$thisindex]['data'], 79, 1);
$RIFFchunk[$chunkname][$thisindex]['parsed']['sample_rate'] = getid3_lib::LittleEndian2Int(substr($RIFFchunk[$chunkname][$thisindex]['data'], 80, 2));
$RIFFchunk[$chunkname][$thisindex]['parsed']['stereo'] = substr($RIFFchunk[$chunkname][$thisindex]['data'], 82, 1);
$RIFFchunk[$chunkname][$thisindex]['parsed']['compress'] = substr($RIFFchunk[$chunkname][$thisindex]['data'], 83, 1);
$RIFFchunk[$chunkname][$thisindex]['parsed']['eomstrt'] = getid3_lib::LittleEndian2Int(substr($RIFFchunk[$chunkname][$thisindex]['data'], 84, 4));
$RIFFchunk[$chunkname][$thisindex]['parsed']['eomlen'] = getid3_lib::LittleEndian2Int(substr($RIFFchunk[$chunkname][$thisindex]['data'], 88, 2));
$RIFFchunk[$chunkname][$thisindex]['parsed']['attrib2'] = getid3_lib::LittleEndian2Int(substr($RIFFchunk[$chunkname][$thisindex]['data'], 90, 4));
$RIFFchunk[$chunkname][$thisindex]['parsed']['future1'] = substr($RIFFchunk[$chunkname][$thisindex]['data'], 94, 12);
$RIFFchunk[$chunkname][$thisindex]['parsed']['catfontcolor'] = getid3_lib::LittleEndian2Int(substr($RIFFchunk[$chunkname][$thisindex]['data'], 106, 4));
$RIFFchunk[$chunkname][$thisindex]['parsed']['catcolor'] = getid3_lib::LittleEndian2Int(substr($RIFFchunk[$chunkname][$thisindex]['data'], 110, 4));
$RIFFchunk[$chunkname][$thisindex]['parsed']['segeompos'] = getid3_lib::LittleEndian2Int(substr($RIFFchunk[$chunkname][$thisindex]['data'], 114, 4));
$RIFFchunk[$chunkname][$thisindex]['parsed']['vt_startsecs'] = getid3_lib::LittleEndian2Int(substr($RIFFchunk[$chunkname][$thisindex]['data'], 118, 2));
$RIFFchunk[$chunkname][$thisindex]['parsed']['vt_starthunds'] = getid3_lib::LittleEndian2Int(substr($RIFFchunk[$chunkname][$thisindex]['data'], 120, 2));
$RIFFchunk[$chunkname][$thisindex]['parsed']['priorcat'] = substr($RIFFchunk[$chunkname][$thisindex]['data'], 122, 3);
$RIFFchunk[$chunkname][$thisindex]['parsed']['priorcopy'] = substr($RIFFchunk[$chunkname][$thisindex]['data'], 125, 4);
$RIFFchunk[$chunkname][$thisindex]['parsed']['priorpadd'] = substr($RIFFchunk[$chunkname][$thisindex]['data'], 129, 1);
$RIFFchunk[$chunkname][$thisindex]['parsed']['postcat'] = substr($RIFFchunk[$chunkname][$thisindex]['data'], 130, 3);
$RIFFchunk[$chunkname][$thisindex]['parsed']['postcopy'] = substr($RIFFchunk[$chunkname][$thisindex]['data'], 133, 4);
$RIFFchunk[$chunkname][$thisindex]['parsed']['postpadd'] = substr($RIFFchunk[$chunkname][$thisindex]['data'], 137, 1);
$RIFFchunk[$chunkname][$thisindex]['parsed']['hrcanplay'] = substr($RIFFchunk[$chunkname][$thisindex]['data'], 138, 21);
$RIFFchunk[$chunkname][$thisindex]['parsed']['future2'] = substr($RIFFchunk[$chunkname][$thisindex]['data'], 159, 108);
$RIFFchunk[$chunkname][$thisindex]['parsed']['artist'] = substr($RIFFchunk[$chunkname][$thisindex]['data'], 267, 34);
$RIFFchunk[$chunkname][$thisindex<