1<?php
2
3/////////////////////////////////////////////////////////////////
4/// getID3() by James Heinrich <info@getid3.org>               //
5//  available at https://github.com/JamesHeinrich/getID3       //
6//            or https://www.getid3.org                        //
7//            or http://getid3.sourceforge.net                 //
8//  see readme.txt for more details                            //
9/////////////////////////////////////////////////////////////////
10//                                                             //
11// module.audio.mod.php                                        //
12// module for analyzing MOD Audio files                        //
13// dependencies: NONE                                          //
14//                                                            ///
15/////////////////////////////////////////////////////////////////
16
17if (!defined('GETID3_INCLUDEPATH')) { // prevent path-exposing attacks that access modules directly on public webservers
18	exit;
19}
20
21class getid3_mod extends getid3_handler
22{
23	/**
24	 * @return bool
25	 */
26	public function Analyze() {
27		$info = &$this->getid3->info;
28		$this->fseek($info['avdataoffset']);
29		$fileheader = $this->fread(1088);
30		if (preg_match('#^IMPM#', $fileheader)) {
31			return $this->getITheaderFilepointer();
32		} elseif (preg_match('#^Extended Module#', $fileheader)) {
33			return $this->getXMheaderFilepointer();
34		} elseif (preg_match('#^.{44}SCRM#', $fileheader)) {
35			return $this->getS3MheaderFilepointer();
36		} elseif (preg_match('#^.{1080}(M\\.K\\.|M!K!|FLT4|FLT8|[5-9]CHN|[1-3][0-9]CH)#', $fileheader)) {
37			return $this->getMODheaderFilepointer();
38		}
39		$this->error('This is not a known type of MOD file');
40		return false;
41	}
42
43	/**
44	 * @return bool
45	 */
46	public function getMODheaderFilepointer() {
47		$info = &$this->getid3->info;
48		$this->fseek($info['avdataoffset'] + 1080);
49		$FormatID = $this->fread(4);
50		if (!preg_match('#^(M.K.|[5-9]CHN|[1-3][0-9]CH)$#', $FormatID)) {
51			$this->error('This is not a known type of MOD file');
52			return false;
53		}
54
55		$info['fileformat'] = 'mod';
56
57		$this->error('MOD parsing not enabled in this version of getID3() ['.$this->getid3->version().']');
58		return false;
59	}
60
61	/**
62	 * @return bool
63	 */
64	public function getXMheaderFilepointer() {
65		$info = &$this->getid3->info;
66		$this->fseek($info['avdataoffset']);
67		$FormatID = $this->fread(15);
68		if (!preg_match('#^Extended Module$#', $FormatID)) {
69			$this->error('This is not a known type of XM-MOD file');
70			return false;
71		}
72
73		$info['fileformat'] = 'xm';
74
75		$this->error('XM-MOD parsing not enabled in this version of getID3() ['.$this->getid3->version().']');
76		return false;
77	}
78
79	/**
80	 * @return bool
81	 */
82	public function getS3MheaderFilepointer() {
83		$info = &$this->getid3->info;
84		$this->fseek($info['avdataoffset'] + 44);
85		$FormatID = $this->fread(4);
86		if (!preg_match('#^SCRM$#', $FormatID)) {
87			$this->error('This is not a ScreamTracker MOD file');
88			return false;
89		}
90
91		$info['fileformat'] = 's3m';
92
93		$this->error('ScreamTracker parsing not enabled in this version of getID3() ['.$this->getid3->version().']');
94		return false;
95	}
96
97	/**
98	 * @return bool
99	 */
100	public function getITheaderFilepointer() {
101		$info = &$this->getid3->info;
102		$this->fseek($info['avdataoffset']);
103		$FormatID = $this->fread(4);
104		if (!preg_match('#^IMPM$#', $FormatID)) {
105			$this->error('This is not an ImpulseTracker MOD file');
106			return false;
107		}
108
109		$info['fileformat'] = 'it';
110
111		$this->error('ImpulseTracker parsing not enabled in this version of getID3() ['.$this->getid3->version().']');
112		return false;
113	}
114
115}
116