if (internal_file->fp) {
/* transfer ownership */
ret->fp = internal_file->fp;
+ php_stream_seek(ret->fp, 0, SEEK_SET);
internal_file->fp = 0;
} else {
ret->fp = 0;
PHAR_GET_VAL(buffer, entry.offset_within_phar);
PHAR_GET_VAL(buffer, entry.compressed_filesize);
if (entry.uncompressed_filesize + 8 != entry.compressed_filesize) {
+#ifndef HAVE_PHAR_ZLIB
+ if (!compressed) {
+ MAPPHAR_FAIL("zlib extension is required for compressed .phar file \"%s\"");
+ }
+#endif
compressed = 1;
}
entry.crc_checked = 0;
RETURN_BOOL(phar_open_compiled_file(alias, alias_len, compressed TSRMLS_CC) == SUCCESS);
} /* }}} */
+/* {{{ proto mixed Phar::loadPhar(string url, string alias)
+ * Loads a phar archive with an alias */
+PHP_METHOD(Phar, loadPhar)
+{
+ char *fname, *alias;
+ int fname_len, alias_len;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &fname, &fname_len, &alias, &alias_len) == FAILURE) {
+ return;
+ }
+ RETURN_BOOL(phar_open_filename(fname, fname_len, alias, alias_len, 0 TSRMLS_CC) == SUCCESS);
+} /* }}} */
+
static php_stream_ops phar_ops = {
phar_write, /* write (does nothing) */
phar_read, /* read */
ZEND_ARG_INFO(0, compressed)
ZEND_END_ARG_INFO();
+static
+ZEND_BEGIN_ARG_INFO(arginfo_phar_loadPhar, 0)
+ ZEND_ARG_INFO(0, fname)
+ ZEND_ARG_INFO(0, alias)
+ZEND_END_ARG_INFO();
+
zend_function_entry php_archive_methods[] = {
- PHP_ME(Phar, mapPhar, arginfo_phar_mapPhar, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC|ZEND_ACC_FINAL)
- PHP_ME(Phar, apiVersion, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC|ZEND_ACC_FINAL)
- PHP_ME(Phar, canCompress, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC|ZEND_ACC_FINAL)
+ PHP_ME(Phar, apiVersion, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC|ZEND_ACC_FINAL)
+ PHP_ME(Phar, canCompress, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC|ZEND_ACC_FINAL)
+ PHP_ME(Phar, mapPhar, arginfo_phar_mapPhar, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC|ZEND_ACC_FINAL)
+ PHP_ME(Phar, loadPhar, arginfo_phar_loadPhar, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC|ZEND_ACC_FINAL)
{NULL, NULL, NULL}
};
/* }}} */
--- /dev/null
+--TEST--
+Phar: loadPhar
+--INI--
+magic_quotes_runtime=0
+--SKIPIF--
+<?php if (!extension_loaded("phar")) print "skip"; ?>
+--FILE--
+<?php
+$fname = dirname(__FILE__) . '/' . basename(__FILE__, '.php') . '.phar.php';
+$pname = 'phar://test';
+$file = '<?php include "' . $pname . '/a.php"; __HALT_COMPILER(); ?>';
+$a = '<?php echo "This is a\n"; include "'.$pname.'/b.php"; ?>';
+$b = '<?php echo "This is b\n"; include "'.$pname.'/b/c.php"; ?>';
+$c = '<?php echo "This is b/c\n"; include "'.$pname.'/b/d.php"; ?>';
+$d = '<?php echo "This is b/d\n"; include "'.$pname.'/e.php"; ?>';
+$e = '<?php echo "This is e\n"; ?>';
+
+$manifest = '';
+$manifest .= pack('V', 5) . 'a.php' . pack('VVVV', strlen($a), time(), 0, strlen($a) + 8);
+$manifest .= pack('V', 5) . 'b.php' . pack('VVVV', strlen($b), time(), strlen($a) + 8, strlen($b) + 8);
+$manifest .= pack('V', 7) . 'b/c.php' . pack('VVVV', strlen($c), time(), strlen($a.$b) + 16, strlen($c) + 8);
+$manifest .= pack('V', 7) . 'b/d.php' . pack('VVVV', strlen($d), time(), strlen($a.$b.$c) + 24, strlen($d) + 8);
+$manifest .= pack('V', 5) . 'e.php' . pack('VVVV', strlen($e), time(), strlen($a.$b.$c.$d) + 32, strlen($e) + 8);
+$file .= pack('VV', strlen($manifest) + 4, 5) .
+ $manifest .
+ pack('VV', crc32($a), strlen($a)) . $a .
+ pack('VV', crc32($b), strlen($b)) . $b .
+ pack('VV', crc32($c), strlen($c)) . $c .
+ pack('VV', crc32($d), strlen($d)) . $d .
+ pack('VV', crc32($e), strlen($e)) . $e;
+
+file_put_contents($fname, $file);
+
+Phar::loadPhar($fname, 'test');
+
+include $fname;
+
+echo "======\n";
+
+include $pname . '/a.php';
+
+?>
+===DONE===
+--CLEAN--
+<?php unlink(dirname(__FILE__) . '/' . basename(__FILE__, '.clean.php') . '.phar.php'); ?>
+--EXPECTF--
+This is a
+This is b
+This is b/c
+This is b/d
+This is e
+======
+This is a
+This is b
+This is b/c
+This is b/d
+This is e
+===DONE===