diff --git a/min/index.php b/min/index.php index 51c3525..4af69dd 100644 --- a/min/index.php +++ b/min/index.php @@ -28,6 +28,7 @@ if ($min_documentRoot) { } elseif (0 === stripos(PHP_OS, 'win')) { Minify::setDocRoot(); // IIS may need help } +$_SERVER['DOCUMENT_ROOT'] = rtrim($_SERVER['DOCUMENT_ROOT'], '/\\'); $min_serveOptions['minifierOptions']['text/css']['symlinks'] = $min_symlinks; diff --git a/min/test/_inc.php b/min/test/_inc.php new file mode 100644 index 0000000..0a77395 --- /dev/null +++ b/min/test/_inc.php @@ -0,0 +1,182 @@ +%s: %s
", $class, $outMode, $html); + return (bool)$test; +} + +function h($txt) +{ + return htmlspecialchars($txt); +} + +function e($value) +{ + return htmlspecialchars(var_export($value, 1)); +} + +function _gzdecode($data) +{ + $filename = $error = ''; + return _phpman_gzdecode($data, $filename, $error); +} + +// http://www.php.net/manual/en/function.gzdecode.php#82930 +function _phpman_gzdecode($data, &$filename='', &$error='', $maxlength=null) +{ + $len = strlen($data); + if ($len < 18 || strcmp(substr($data,0,2),"\x1f\x8b")) { + $error = "Not in GZIP format."; + return null; // Not GZIP format (See RFC 1952) + } + $method = ord(substr($data,2,1)); // Compression method + $flags = ord(substr($data,3,1)); // Flags + if ($flags & 31 != $flags) { + $error = "Reserved bits not allowed."; + return null; + } + // NOTE: $mtime may be negative (PHP integer limitations) + $mtime = unpack("V", substr($data,4,4)); + $mtime = $mtime[1]; + $xfl = substr($data,8,1); + $os = substr($data,8,1); + $headerlen = 10; + $extralen = 0; + $extra = ""; + if ($flags & 4) { + // 2-byte length prefixed EXTRA data in header + if ($len - $headerlen - 2 < 8) { + return false; // invalid + } + $extralen = unpack("v",substr($data,8,2)); + $extralen = $extralen[1]; + if ($len - $headerlen - 2 - $extralen < 8) { + return false; // invalid + } + $extra = substr($data,10,$extralen); + $headerlen += 2 + $extralen; + } + $filenamelen = 0; + $filename = ""; + if ($flags & 8) { + // C-style string + if ($len - $headerlen - 1 < 8) { + return false; // invalid + } + $filenamelen = strpos(substr($data,$headerlen),chr(0)); + if ($filenamelen === false || $len - $headerlen - $filenamelen - 1 < 8) { + return false; // invalid + } + $filename = substr($data,$headerlen,$filenamelen); + $headerlen += $filenamelen + 1; + } + $commentlen = 0; + $comment = ""; + if ($flags & 16) { + // C-style string COMMENT data in header + if ($len - $headerlen - 1 < 8) { + return false; // invalid + } + $commentlen = strpos(substr($data,$headerlen),chr(0)); + if ($commentlen === false || $len - $headerlen - $commentlen - 1 < 8) { + return false; // Invalid header format + } + $comment = substr($data,$headerlen,$commentlen); + $headerlen += $commentlen + 1; + } + $headercrc = ""; + if ($flags & 2) { + // 2-bytes (lowest order) of CRC32 on header present + if ($len - $headerlen - 2 < 8) { + return false; // invalid + } + $calccrc = crc32(substr($data,0,$headerlen)) & 0xffff; + $headercrc = unpack("v", substr($data,$headerlen,2)); + $headercrc = $headercrc[1]; + if ($headercrc != $calccrc) { + $error = "Header checksum failed."; + return false; // Bad header CRC + } + $headerlen += 2; + } + // GZIP FOOTER + $datacrc = unpack("V",substr($data,-8,4)); + $datacrc = sprintf('%u',$datacrc[1] & 0xFFFFFFFF); + $isize = unpack("V",substr($data,-4)); + $isize = $isize[1]; + // decompression: + $bodylen = $len-$headerlen-8; + if ($bodylen < 1) { + // IMPLEMENTATION BUG! + return null; + } + $body = substr($data,$headerlen,$bodylen); + $data = ""; + if ($bodylen > 0) { + switch ($method) { + case 8: + // Currently the only supported compression method: + $data = gzinflate($body,$maxlength); + break; + default: + $error = "Unknown compression method."; + return false; + } + } // zero-byte body content is allowed + // Verifiy CRC32 + $crc = sprintf("%u",crc32($data)); + $crcOK = $crc == $datacrc; + $lenOK = $isize == strlen($data); + if (!$lenOK || !$crcOK) { + $error = ( $lenOK ? '' : 'Length check FAILED. ') . ( $crcOK ? '' : 'Checksum FAILED.'); + return false; + } + return $data; +} \ No newline at end of file diff --git a/min/test/index.php b/min/test/index.php new file mode 100644 index 0000000..850f553 --- /dev/null +++ b/min/test/index.php @@ -0,0 +1,161 @@ + +$_SERVER['DOCUMENT_ROOT']
(set by PHP/env)= e($origDocRoot) ?>
$_SERVER['DOCUMENT_ROOT']
(altered by Minify/your config.php)= e($_SERVER['DOCUMENT_ROOT']) ?>
realpath($_SERVER['DOCUMENT_ROOT'])
= e(realpath($_SERVER['DOCUMENT_ROOT'])) ?>
__FILE__
= e(__FILE__) ?>
\$_SERVER['SUBDOMAIN_DOCUMENT_ROOT']
"
+ . " is set to " . e($_SERVER['SUBDOMAIN_DOCUMENT_ROOT']) . ". You may need to set"
+ . " \$min_documentRoot
to this in config.php.";
+}
+
+$passed = assertTrue(
+ 0 === strpos(__FILE__, realpath($_SERVER['DOCUMENT_ROOT']))
+ ,'__FILE__
is within realpath of docroot'
+);
+if ($passed) {
+ $thisPath = str_replace(
+ '\\'
+ ,'/'
+ ,substr(__FILE__, strlen(realpath($_SERVER['DOCUMENT_ROOT'])))
+ );
+} else {
+ // try HTTP requests anyway
+ $thisPath = '/min/test/index.php';
+}
+
+if ($thisPath !== '/min/test/index.php') {
+ echo "!NOTE: /min/ is not directly inside DOCUMENT_ROOT.
"; +} + +?> + +!NOTE: zlib.output_compression" + . " was enabled by default, but this is OK if the next test passes.
"; + } + + $fp = fopen($thisUrl . '?hello=1', 'r', false, stream_context_create(array( + 'http' => array( + 'method' => "GET", + 'header' => "Accept-Encoding: deflate, gzip\r\n" + ) + ))); + + $meta = stream_get_meta_data($fp); + + $passed = true; + foreach ($meta['wrapper_data'] as $i => $header) { + if ((preg_match('@^Content-Length: (\\d+)$@i', $header, $m) && $m[1] !== '6') + || preg_match('@^Content-Encoding:@i', $header, $m) + ) { + $passed = false; + break; + } + } + if ($passed && stream_get_contents($fp) !== 'World!') { + $passed = false; + } + assertTrue( + $passed + ,'PHP/server can serve non-encoded content' + ); + fclose($fp); + + if (__FILE__ === realpath($_SERVER['SCRIPT_FILENAME'])) { + if (! $passed) { + echo "Returned content should be 6 bytes and not HTTP encoded.
"
+ . "Headers returned by: " . h($thisUrl . '?hello=1') . "
" . h(var_export($meta['wrapper_data'], 1)) . "
";
+ }
+ }
+}
+
+if (assertTrue(function_exists('gzencode'), 'gzencode() exists')) {
+ // test encode/decode
+ $data = str_repeat(md5('testing'), 160);
+ $gzipped = @gzencode($data, 6);
+ assertTrue(is_string($gzipped) && strlen($gzipped) < strlen($data), 'gzip works');
+ assertTrue(_gzdecode($gzipped) === $data, 'gzdecode works');
+}
+
+?>
+
+$min_cachePath
in config.php= e($min_cachePath) ?>
= e($cache) ?>
\$min_cachePath
for best performance.";
+}
+
+$data = str_repeat(md5('testing'), 160);
+$id = 'Minify_test_cache';
+assertTrue(true === $cache->store($id, $data), 'Cache store');
+assertTrue(strlen($data) === $cache->getSize($id), 'Cache getSize');
+assertTrue(true === $cache->isValid($id, $_SERVER['REQUEST_TIME'] - 10), 'Cache isValid');
+ob_start();
+$cache->display($id);
+$displayed = ob_get_contents();
+ob_end_clean();
+assertTrue($data === $displayed, 'Cache display');
+assertTrue($data === $cache->fetch($id), 'Cache fetch');
diff --git a/min_unit_tests/README.txt b/min_unit_tests/README.txt
new file mode 100644
index 0000000..0be59e3
--- /dev/null
+++ b/min_unit_tests/README.txt
@@ -0,0 +1,4 @@
+UNIT TESTING
+
+Do not modify the "simpletest" directory as it's linked via svn:externals.
+
diff --git a/min_unit_tests/test_simpletest.php b/min_unit_tests/test_simpletest.php
new file mode 100644
index 0000000..114fe8a
--- /dev/null
+++ b/min_unit_tests/test_simpletest.php
@@ -0,0 +1,20 @@
+UnitTestCase(preg_replace('/^Test_/', '', get_class($this)));
+ }
+}
+
+class Test_Sample extends MinifyTestCase {
+ function test_Hello() {
+ $this->assertTrue(true, 'Hello World!');
+ }
+}
+
+$test = new Grouptest('All tests');
+$test->addTestCase(new Test_Sample());
+$test->run(new HtmlReporter());