| 1 |
<?php |
| 2 |
/** |
| 3 |
* Class Minify_Controller_Version1 |
| 4 |
* @package Minify |
| 5 |
*/ |
| 6 |
|
| 7 |
/** |
| 8 |
* Controller class for emulating version 1 of minify.php (mostly a proof-of-concept) |
| 9 |
* |
| 10 |
* <code> |
| 11 |
* Minify::serve('Version1'); |
| 12 |
* </code> |
| 13 |
* |
| 14 |
* @package Minify |
| 15 |
* @author Stephen Clay <steve@mrclay.org> |
| 16 |
*/ |
| 17 |
class Minify_Controller_Version1 extends Minify_Controller_Base { |
| 18 |
|
| 19 |
/** |
| 20 |
* Set up groups of files as sources |
| 21 |
* |
| 22 |
* @param array $options controller and Minify options |
| 23 |
* @return array Minify options |
| 24 |
* |
| 25 |
*/ |
| 26 |
public function setupSources($options) { |
| 27 |
// PHP insecure by default: realpath() and other FS functions can't handle null bytes. |
| 28 |
if (isset($_GET['files'])) { |
| 29 |
$_GET['files'] = str_replace("\x00", '', (string)$_GET['files']); |
| 30 |
} |
| 31 |
|
| 32 |
self::_setupDefines(); |
| 33 |
if (MINIFY_USE_CACHE) { |
| 34 |
$cacheDir = defined('MINIFY_CACHE_DIR') |
| 35 |
? MINIFY_CACHE_DIR |
| 36 |
: ''; |
| 37 |
Minify::setCache($cacheDir); |
| 38 |
} |
| 39 |
$options['badRequestHeader'] = 'HTTP/1.0 404 Not Found'; |
| 40 |
$options['contentTypeCharset'] = MINIFY_ENCODING; |
| 41 |
|
| 42 |
// The following restrictions are to limit the URLs that minify will |
| 43 |
// respond to. Ideally there should be only one way to reference a file. |
| 44 |
if (! isset($_GET['files']) |
| 45 |
// verify at least one file, files are single comma separated, |
| 46 |
// and are all same extension |
| 47 |
|| ! preg_match('/^[^,]+\\.(css|js)(,[^,]+\\.\\1)*$/', $_GET['files'], $m) |
| 48 |
// no "//" (makes URL rewriting easier) |
| 49 |
|| strpos($_GET['files'], '//') !== false |
| 50 |
// no "\" |
| 51 |
|| strpos($_GET['files'], '\\') !== false |
| 52 |
// no "./" |
| 53 |
|| preg_match('/(?:^|[^\\.])\\.\\//', $_GET['files']) |
| 54 |
) { |
| 55 |
return $options; |
| 56 |
} |
| 57 |
|
| 58 |
$files = explode(',', $_GET['files']); |
| 59 |
if (count($files) > MINIFY_MAX_FILES) { |
| 60 |
return $options; |
| 61 |
} |
| 62 |
|
| 63 |
// strings for prepending to relative/absolute paths |
| 64 |
$prependRelPaths = dirname($_SERVER['SCRIPT_FILENAME']) |
| 65 |
. DIRECTORY_SEPARATOR; |
| 66 |
$prependAbsPaths = $_SERVER['DOCUMENT_ROOT']; |
| 67 |
|
| 68 |
$goodFiles = array(); |
| 69 |
$hasBadSource = false; |
| 70 |
|
| 71 |
$allowDirs = isset($options['allowDirs']) |
| 72 |
? $options['allowDirs'] |
| 73 |
: MINIFY_BASE_DIR; |
| 74 |
|
| 75 |
foreach ($files as $file) { |
| 76 |
// prepend appropriate string for abs/rel paths |
| 77 |
$file = ($file[0] === '/' ? $prependAbsPaths : $prependRelPaths) . $file; |
| 78 |
// make sure a real file! |
| 79 |
$file = realpath($file); |
| 80 |
// don't allow unsafe or duplicate files |
| 81 |
if (parent::_fileIsSafe($file, $allowDirs) |
| 82 |
&& !in_array($file, $goodFiles)) |
| 83 |
{ |
| 84 |
$goodFiles[] = $file; |
| 85 |
$srcOptions = array( |
| 86 |
'filepath' => $file |
| 87 |
); |
| 88 |
$this->sources[] = new Minify_Source($srcOptions); |
| 89 |
} else { |
| 90 |
$hasBadSource = true; |
| 91 |
break; |
| 92 |
} |
| 93 |
} |
| 94 |
if ($hasBadSource) { |
| 95 |
$this->sources = array(); |
| 96 |
} |
| 97 |
if (! MINIFY_REWRITE_CSS_URLS) { |
| 98 |
$options['rewriteCssUris'] = false; |
| 99 |
} |
| 100 |
return $options; |
| 101 |
} |
| 102 |
|
| 103 |
private static function _setupDefines() |
| 104 |
{ |
| 105 |
$defaults = array( |
| 106 |
'MINIFY_BASE_DIR' => realpath($_SERVER['DOCUMENT_ROOT']) |
| 107 |
,'MINIFY_ENCODING' => 'utf-8' |
| 108 |
,'MINIFY_MAX_FILES' => 16 |
| 109 |
,'MINIFY_REWRITE_CSS_URLS' => true |
| 110 |
,'MINIFY_USE_CACHE' => true |
| 111 |
); |
| 112 |
foreach ($defaults as $const => $val) { |
| 113 |
if (! defined($const)) { |
| 114 |
define($const, $val); |
| 115 |
} |
| 116 |
} |
| 117 |
} |
| 118 |
} |
| 119 |
|
| 120 |
|