phar_setdefaultstub.phpt 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944
  1. --TEST--
  2. Phar: Phar::setDefaultStub() with and without arg
  3. --SKIPIF--
  4. <?php if (!extension_loaded("phar")) die("skip"); ?>
  5. --INI--
  6. phar.readonly=0
  7. --FILE--
  8. <?php
  9. $fname = dirname(__FILE__) . '/' . basename(__FILE__, '.php') . '.phar';
  10. $phar = new Phar($fname);
  11. $phar['a.php'] = '<php echo "this is a\n"; ?>';
  12. $phar['b.php'] = '<php echo "this is b\n"; ?>';
  13. $phar->setDefaultStub();
  14. $phar->stopBuffering();
  15. var_dump($phar->getStub());
  16. echo "============================================================================\n";
  17. echo "============================================================================\n";
  18. $phar->setDefaultStub('my/custom/thingy.php');
  19. $phar->stopBuffering();
  20. var_dump($phar->getStub());
  21. echo "============================================================================\n";
  22. echo "============================================================================\n";
  23. $phar->setDefaultStub('my/custom/thingy.php', 'the/web.php');
  24. $phar->stopBuffering();
  25. var_dump($phar->getStub());
  26. echo "============================================================================\n";
  27. echo "============================================================================\n";
  28. try {
  29. $phar->setDefaultStub(str_repeat('a', 400));
  30. $phar->stopBuffering();
  31. var_dump(strlen($phar->getStub()));
  32. $phar->setDefaultStub(str_repeat('a', 401));
  33. $phar->stopBuffering();
  34. var_dump(strlen($phar->getStub()));
  35. } catch(Exception $e) {
  36. echo $e->getMessage() . "\n";
  37. }
  38. ?>
  39. ===DONE===
  40. --CLEAN--
  41. <?php
  42. unlink(dirname(__FILE__) . '/' . basename(__FILE__, '.clean.php') . '.phar');
  43. ?>
  44. --EXPECT--
  45. string(6675) "<?php
  46. $web = 'index.php';
  47. if (in_array('phar', stream_get_wrappers()) && class_exists('Phar', 0)) {
  48. Phar::interceptFileFuncs();
  49. set_include_path('phar://' . __FILE__ . PATH_SEPARATOR . get_include_path());
  50. Phar::webPhar(null, $web);
  51. include 'phar://' . __FILE__ . '/' . Extract_Phar::START;
  52. return;
  53. }
  54. if (@(isset($_SERVER['REQUEST_URI']) && isset($_SERVER['REQUEST_METHOD']) && ($_SERVER['REQUEST_METHOD'] == 'GET' || $_SERVER['REQUEST_METHOD'] == 'POST'))) {
  55. Extract_Phar::go(true);
  56. $mimes = array(
  57. 'phps' => 2,
  58. 'c' => 'text/plain',
  59. 'cc' => 'text/plain',
  60. 'cpp' => 'text/plain',
  61. 'c++' => 'text/plain',
  62. 'dtd' => 'text/plain',
  63. 'h' => 'text/plain',
  64. 'log' => 'text/plain',
  65. 'rng' => 'text/plain',
  66. 'txt' => 'text/plain',
  67. 'xsd' => 'text/plain',
  68. 'php' => 1,
  69. 'inc' => 1,
  70. 'avi' => 'video/avi',
  71. 'bmp' => 'image/bmp',
  72. 'css' => 'text/css',
  73. 'gif' => 'image/gif',
  74. 'htm' => 'text/html',
  75. 'html' => 'text/html',
  76. 'htmls' => 'text/html',
  77. 'ico' => 'image/x-ico',
  78. 'jpe' => 'image/jpeg',
  79. 'jpg' => 'image/jpeg',
  80. 'jpeg' => 'image/jpeg',
  81. 'js' => 'application/x-javascript',
  82. 'midi' => 'audio/midi',
  83. 'mid' => 'audio/midi',
  84. 'mod' => 'audio/mod',
  85. 'mov' => 'movie/quicktime',
  86. 'mp3' => 'audio/mp3',
  87. 'mpg' => 'video/mpeg',
  88. 'mpeg' => 'video/mpeg',
  89. 'pdf' => 'application/pdf',
  90. 'png' => 'image/png',
  91. 'swf' => 'application/shockwave-flash',
  92. 'tif' => 'image/tiff',
  93. 'tiff' => 'image/tiff',
  94. 'wav' => 'audio/wav',
  95. 'xbm' => 'image/xbm',
  96. 'xml' => 'text/xml',
  97. );
  98. header("Cache-Control: no-cache, must-revalidate");
  99. header("Pragma: no-cache");
  100. $basename = basename(__FILE__);
  101. if (!strpos($_SERVER['REQUEST_URI'], $basename)) {
  102. chdir(Extract_Phar::$temp);
  103. include $web;
  104. return;
  105. }
  106. $pt = substr($_SERVER['REQUEST_URI'], strpos($_SERVER['REQUEST_URI'], $basename) + strlen($basename));
  107. if (!$pt || $pt == '/') {
  108. $pt = $web;
  109. header('HTTP/1.1 301 Moved Permanently');
  110. header('Location: ' . $_SERVER['REQUEST_URI'] . '/' . $pt);
  111. exit;
  112. }
  113. $a = realpath(Extract_Phar::$temp . DIRECTORY_SEPARATOR . $pt);
  114. if (!$a || strlen(dirname($a)) < strlen(Extract_Phar::$temp)) {
  115. header('HTTP/1.0 404 Not Found');
  116. echo "<html>\n <head>\n <title>File Not Found<title>\n </head>\n <body>\n <h1>404 - File Not Found</h1>\n </body>\n</html>";
  117. exit;
  118. }
  119. $b = pathinfo($a);
  120. if (!isset($b['extension'])) {
  121. header('Content-Type: text/plain');
  122. header('Content-Length: ' . filesize($a));
  123. readfile($a);
  124. exit;
  125. }
  126. if (isset($mimes[$b['extension']])) {
  127. if ($mimes[$b['extension']] === 1) {
  128. include $a;
  129. exit;
  130. }
  131. if ($mimes[$b['extension']] === 2) {
  132. highlight_file($a);
  133. exit;
  134. }
  135. header('Content-Type: ' .$mimes[$b['extension']]);
  136. header('Content-Length: ' . filesize($a));
  137. readfile($a);
  138. exit;
  139. }
  140. }
  141. class Extract_Phar
  142. {
  143. static $temp;
  144. static $origdir;
  145. const GZ = 0x1000;
  146. const BZ2 = 0x2000;
  147. const MASK = 0x3000;
  148. const START = 'index.php';
  149. const LEN = 6675;
  150. static function go($return = false)
  151. {
  152. $fp = fopen(__FILE__, 'rb');
  153. fseek($fp, self::LEN);
  154. $L = unpack('V', $a = (binary)fread($fp, 4));
  155. $m = (binary)'';
  156. do {
  157. $read = 8192;
  158. if ($L[1] - strlen($m) < 8192) {
  159. $read = $L[1] - strlen($m);
  160. }
  161. $last = (binary)fread($fp, $read);
  162. $m .= $last;
  163. } while (strlen($last) && strlen($m) < $L[1]);
  164. if (strlen($m) < $L[1]) {
  165. die('ERROR: manifest length read was "' .
  166. strlen($m) .'" should be "' .
  167. $L[1] . '"');
  168. }
  169. $info = self::_unpack($m);
  170. $f = $info['c'];
  171. if ($f & self::GZ) {
  172. if (!function_exists('gzinflate')) {
  173. die('Error: zlib extension is not enabled -' .
  174. ' gzinflate() function needed for zlib-compressed .phars');
  175. }
  176. }
  177. if ($f & self::BZ2) {
  178. if (!function_exists('bzdecompress')) {
  179. die('Error: bzip2 extension is not enabled -' .
  180. ' bzdecompress() function needed for bz2-compressed .phars');
  181. }
  182. }
  183. $temp = self::tmpdir();
  184. if (!$temp || !is_writable($temp)) {
  185. $sessionpath = session_save_path();
  186. if (strpos ($sessionpath, ";") !== false)
  187. $sessionpath = substr ($sessionpath, strpos ($sessionpath, ";")+1);
  188. if (!file_exists($sessionpath) || !is_dir($sessionpath)) {
  189. die('Could not locate temporary directory to extract phar');
  190. }
  191. $temp = $sessionpath;
  192. }
  193. $temp .= '/pharextract/'.basename(__FILE__, '.phar');
  194. self::$temp = $temp;
  195. self::$origdir = getcwd();
  196. @mkdir($temp, 0777, true);
  197. $temp = realpath($temp);
  198. if (!file_exists($temp . DIRECTORY_SEPARATOR . md5_file(__FILE__))) {
  199. self::_removeTmpFiles($temp, getcwd());
  200. @mkdir($temp, 0777, true);
  201. @file_put_contents($temp . '/' . md5_file(__FILE__), '');
  202. foreach ($info['m'] as $path => $file) {
  203. $a = !file_exists(dirname($temp . '/' . $path));
  204. @mkdir(dirname($temp . '/' . $path), 0777, true);
  205. clearstatcache();
  206. if ($path[strlen($path) - 1] == '/') {
  207. @mkdir($temp . '/' . $path, 0777);
  208. } else {
  209. file_put_contents($temp . '/' . $path, self::extractFile($path, $file, $fp));
  210. @chmod($temp . '/' . $path, 0666);
  211. }
  212. }
  213. }
  214. chdir($temp);
  215. if (!$return) {
  216. include self::START;
  217. }
  218. }
  219. static function tmpdir()
  220. {
  221. if (strpos(PHP_OS, 'WIN') !== false) {
  222. if ($var = getenv('TMP') ? getenv('TMP') : getenv('TEMP')) {
  223. return $var;
  224. }
  225. if (is_dir('/temp') || mkdir('/temp')) {
  226. return realpath('/temp');
  227. }
  228. return false;
  229. }
  230. if ($var = getenv('TMPDIR')) {
  231. return $var;
  232. }
  233. return realpath('/tmp');
  234. }
  235. static function _unpack($m)
  236. {
  237. $info = unpack('V', substr($m, 0, 4));
  238. $l = unpack('V', substr($m, 10, 4));
  239. $m = substr($m, 14 + $l[1]);
  240. $s = unpack('V', substr($m, 0, 4));
  241. $o = 0;
  242. $start = 4 + $s[1];
  243. $ret['c'] = 0;
  244. for ($i = 0; $i < $info[1]; $i++) {
  245. $len = unpack('V', substr($m, $start, 4));
  246. $start += 4;
  247. $savepath = substr($m, $start, $len[1]);
  248. $start += $len[1];
  249. $ret['m'][$savepath] = array_values(unpack('Va/Vb/Vc/Vd/Ve/Vf', substr($m, $start, 24)));
  250. $ret['m'][$savepath][3] = sprintf('%u', $ret['m'][$savepath][3]
  251. & 0xffffffff);
  252. $ret['m'][$savepath][7] = $o;
  253. $o += $ret['m'][$savepath][2];
  254. $start += 24 + $ret['m'][$savepath][5];
  255. $ret['c'] |= $ret['m'][$savepath][4] & self::MASK;
  256. }
  257. return $ret;
  258. }
  259. static function extractFile($path, $entry, $fp)
  260. {
  261. $data = '';
  262. $c = $entry[2];
  263. while ($c) {
  264. if ($c < 8192) {
  265. $data .= @fread($fp, $c);
  266. $c = 0;
  267. } else {
  268. $c -= 8192;
  269. $data .= @fread($fp, 8192);
  270. }
  271. }
  272. if ($entry[4] & self::GZ) {
  273. $data = gzinflate($data);
  274. } elseif ($entry[4] & self::BZ2) {
  275. $data = bzdecompress($data);
  276. }
  277. if (strlen($data) != $entry[0]) {
  278. die("Invalid internal .phar file (size error " . strlen($data) . " != " .
  279. $stat[7] . ")");
  280. }
  281. if ($entry[3] != sprintf("%u", crc32((binary)$data) & 0xffffffff)) {
  282. die("Invalid internal .phar file (checksum error)");
  283. }
  284. return $data;
  285. }
  286. static function _removeTmpFiles($temp, $origdir)
  287. {
  288. chdir($temp);
  289. foreach (glob('*') as $f) {
  290. if (file_exists($f)) {
  291. is_dir($f) ? @rmdir($f) : @unlink($f);
  292. if (file_exists($f) && is_dir($f)) {
  293. self::_removeTmpFiles($f, getcwd());
  294. }
  295. }
  296. }
  297. @rmdir($temp);
  298. clearstatcache();
  299. chdir($origdir);
  300. }
  301. }
  302. Extract_Phar::go();
  303. __HALT_COMPILER(); ?>
  304. "
  305. ============================================================================
  306. ============================================================================
  307. string(6686) "<?php
  308. $web = 'index.php';
  309. if (in_array('phar', stream_get_wrappers()) && class_exists('Phar', 0)) {
  310. Phar::interceptFileFuncs();
  311. set_include_path('phar://' . __FILE__ . PATH_SEPARATOR . get_include_path());
  312. Phar::webPhar(null, $web);
  313. include 'phar://' . __FILE__ . '/' . Extract_Phar::START;
  314. return;
  315. }
  316. if (@(isset($_SERVER['REQUEST_URI']) && isset($_SERVER['REQUEST_METHOD']) && ($_SERVER['REQUEST_METHOD'] == 'GET' || $_SERVER['REQUEST_METHOD'] == 'POST'))) {
  317. Extract_Phar::go(true);
  318. $mimes = array(
  319. 'phps' => 2,
  320. 'c' => 'text/plain',
  321. 'cc' => 'text/plain',
  322. 'cpp' => 'text/plain',
  323. 'c++' => 'text/plain',
  324. 'dtd' => 'text/plain',
  325. 'h' => 'text/plain',
  326. 'log' => 'text/plain',
  327. 'rng' => 'text/plain',
  328. 'txt' => 'text/plain',
  329. 'xsd' => 'text/plain',
  330. 'php' => 1,
  331. 'inc' => 1,
  332. 'avi' => 'video/avi',
  333. 'bmp' => 'image/bmp',
  334. 'css' => 'text/css',
  335. 'gif' => 'image/gif',
  336. 'htm' => 'text/html',
  337. 'html' => 'text/html',
  338. 'htmls' => 'text/html',
  339. 'ico' => 'image/x-ico',
  340. 'jpe' => 'image/jpeg',
  341. 'jpg' => 'image/jpeg',
  342. 'jpeg' => 'image/jpeg',
  343. 'js' => 'application/x-javascript',
  344. 'midi' => 'audio/midi',
  345. 'mid' => 'audio/midi',
  346. 'mod' => 'audio/mod',
  347. 'mov' => 'movie/quicktime',
  348. 'mp3' => 'audio/mp3',
  349. 'mpg' => 'video/mpeg',
  350. 'mpeg' => 'video/mpeg',
  351. 'pdf' => 'application/pdf',
  352. 'png' => 'image/png',
  353. 'swf' => 'application/shockwave-flash',
  354. 'tif' => 'image/tiff',
  355. 'tiff' => 'image/tiff',
  356. 'wav' => 'audio/wav',
  357. 'xbm' => 'image/xbm',
  358. 'xml' => 'text/xml',
  359. );
  360. header("Cache-Control: no-cache, must-revalidate");
  361. header("Pragma: no-cache");
  362. $basename = basename(__FILE__);
  363. if (!strpos($_SERVER['REQUEST_URI'], $basename)) {
  364. chdir(Extract_Phar::$temp);
  365. include $web;
  366. return;
  367. }
  368. $pt = substr($_SERVER['REQUEST_URI'], strpos($_SERVER['REQUEST_URI'], $basename) + strlen($basename));
  369. if (!$pt || $pt == '/') {
  370. $pt = $web;
  371. header('HTTP/1.1 301 Moved Permanently');
  372. header('Location: ' . $_SERVER['REQUEST_URI'] . '/' . $pt);
  373. exit;
  374. }
  375. $a = realpath(Extract_Phar::$temp . DIRECTORY_SEPARATOR . $pt);
  376. if (!$a || strlen(dirname($a)) < strlen(Extract_Phar::$temp)) {
  377. header('HTTP/1.0 404 Not Found');
  378. echo "<html>\n <head>\n <title>File Not Found<title>\n </head>\n <body>\n <h1>404 - File Not Found</h1>\n </body>\n</html>";
  379. exit;
  380. }
  381. $b = pathinfo($a);
  382. if (!isset($b['extension'])) {
  383. header('Content-Type: text/plain');
  384. header('Content-Length: ' . filesize($a));
  385. readfile($a);
  386. exit;
  387. }
  388. if (isset($mimes[$b['extension']])) {
  389. if ($mimes[$b['extension']] === 1) {
  390. include $a;
  391. exit;
  392. }
  393. if ($mimes[$b['extension']] === 2) {
  394. highlight_file($a);
  395. exit;
  396. }
  397. header('Content-Type: ' .$mimes[$b['extension']]);
  398. header('Content-Length: ' . filesize($a));
  399. readfile($a);
  400. exit;
  401. }
  402. }
  403. class Extract_Phar
  404. {
  405. static $temp;
  406. static $origdir;
  407. const GZ = 0x1000;
  408. const BZ2 = 0x2000;
  409. const MASK = 0x3000;
  410. const START = 'my/custom/thingy.php';
  411. const LEN = 6686;
  412. static function go($return = false)
  413. {
  414. $fp = fopen(__FILE__, 'rb');
  415. fseek($fp, self::LEN);
  416. $L = unpack('V', $a = (binary)fread($fp, 4));
  417. $m = (binary)'';
  418. do {
  419. $read = 8192;
  420. if ($L[1] - strlen($m) < 8192) {
  421. $read = $L[1] - strlen($m);
  422. }
  423. $last = (binary)fread($fp, $read);
  424. $m .= $last;
  425. } while (strlen($last) && strlen($m) < $L[1]);
  426. if (strlen($m) < $L[1]) {
  427. die('ERROR: manifest length read was "' .
  428. strlen($m) .'" should be "' .
  429. $L[1] . '"');
  430. }
  431. $info = self::_unpack($m);
  432. $f = $info['c'];
  433. if ($f & self::GZ) {
  434. if (!function_exists('gzinflate')) {
  435. die('Error: zlib extension is not enabled -' .
  436. ' gzinflate() function needed for zlib-compressed .phars');
  437. }
  438. }
  439. if ($f & self::BZ2) {
  440. if (!function_exists('bzdecompress')) {
  441. die('Error: bzip2 extension is not enabled -' .
  442. ' bzdecompress() function needed for bz2-compressed .phars');
  443. }
  444. }
  445. $temp = self::tmpdir();
  446. if (!$temp || !is_writable($temp)) {
  447. $sessionpath = session_save_path();
  448. if (strpos ($sessionpath, ";") !== false)
  449. $sessionpath = substr ($sessionpath, strpos ($sessionpath, ";")+1);
  450. if (!file_exists($sessionpath) || !is_dir($sessionpath)) {
  451. die('Could not locate temporary directory to extract phar');
  452. }
  453. $temp = $sessionpath;
  454. }
  455. $temp .= '/pharextract/'.basename(__FILE__, '.phar');
  456. self::$temp = $temp;
  457. self::$origdir = getcwd();
  458. @mkdir($temp, 0777, true);
  459. $temp = realpath($temp);
  460. if (!file_exists($temp . DIRECTORY_SEPARATOR . md5_file(__FILE__))) {
  461. self::_removeTmpFiles($temp, getcwd());
  462. @mkdir($temp, 0777, true);
  463. @file_put_contents($temp . '/' . md5_file(__FILE__), '');
  464. foreach ($info['m'] as $path => $file) {
  465. $a = !file_exists(dirname($temp . '/' . $path));
  466. @mkdir(dirname($temp . '/' . $path), 0777, true);
  467. clearstatcache();
  468. if ($path[strlen($path) - 1] == '/') {
  469. @mkdir($temp . '/' . $path, 0777);
  470. } else {
  471. file_put_contents($temp . '/' . $path, self::extractFile($path, $file, $fp));
  472. @chmod($temp . '/' . $path, 0666);
  473. }
  474. }
  475. }
  476. chdir($temp);
  477. if (!$return) {
  478. include self::START;
  479. }
  480. }
  481. static function tmpdir()
  482. {
  483. if (strpos(PHP_OS, 'WIN') !== false) {
  484. if ($var = getenv('TMP') ? getenv('TMP') : getenv('TEMP')) {
  485. return $var;
  486. }
  487. if (is_dir('/temp') || mkdir('/temp')) {
  488. return realpath('/temp');
  489. }
  490. return false;
  491. }
  492. if ($var = getenv('TMPDIR')) {
  493. return $var;
  494. }
  495. return realpath('/tmp');
  496. }
  497. static function _unpack($m)
  498. {
  499. $info = unpack('V', substr($m, 0, 4));
  500. $l = unpack('V', substr($m, 10, 4));
  501. $m = substr($m, 14 + $l[1]);
  502. $s = unpack('V', substr($m, 0, 4));
  503. $o = 0;
  504. $start = 4 + $s[1];
  505. $ret['c'] = 0;
  506. for ($i = 0; $i < $info[1]; $i++) {
  507. $len = unpack('V', substr($m, $start, 4));
  508. $start += 4;
  509. $savepath = substr($m, $start, $len[1]);
  510. $start += $len[1];
  511. $ret['m'][$savepath] = array_values(unpack('Va/Vb/Vc/Vd/Ve/Vf', substr($m, $start, 24)));
  512. $ret['m'][$savepath][3] = sprintf('%u', $ret['m'][$savepath][3]
  513. & 0xffffffff);
  514. $ret['m'][$savepath][7] = $o;
  515. $o += $ret['m'][$savepath][2];
  516. $start += 24 + $ret['m'][$savepath][5];
  517. $ret['c'] |= $ret['m'][$savepath][4] & self::MASK;
  518. }
  519. return $ret;
  520. }
  521. static function extractFile($path, $entry, $fp)
  522. {
  523. $data = '';
  524. $c = $entry[2];
  525. while ($c) {
  526. if ($c < 8192) {
  527. $data .= @fread($fp, $c);
  528. $c = 0;
  529. } else {
  530. $c -= 8192;
  531. $data .= @fread($fp, 8192);
  532. }
  533. }
  534. if ($entry[4] & self::GZ) {
  535. $data = gzinflate($data);
  536. } elseif ($entry[4] & self::BZ2) {
  537. $data = bzdecompress($data);
  538. }
  539. if (strlen($data) != $entry[0]) {
  540. die("Invalid internal .phar file (size error " . strlen($data) . " != " .
  541. $stat[7] . ")");
  542. }
  543. if ($entry[3] != sprintf("%u", crc32((binary)$data) & 0xffffffff)) {
  544. die("Invalid internal .phar file (checksum error)");
  545. }
  546. return $data;
  547. }
  548. static function _removeTmpFiles($temp, $origdir)
  549. {
  550. chdir($temp);
  551. foreach (glob('*') as $f) {
  552. if (file_exists($f)) {
  553. is_dir($f) ? @rmdir($f) : @unlink($f);
  554. if (file_exists($f) && is_dir($f)) {
  555. self::_removeTmpFiles($f, getcwd());
  556. }
  557. }
  558. }
  559. @rmdir($temp);
  560. clearstatcache();
  561. chdir($origdir);
  562. }
  563. }
  564. Extract_Phar::go();
  565. __HALT_COMPILER(); ?>
  566. "
  567. ============================================================================
  568. ============================================================================
  569. string(6688) "<?php
  570. $web = 'the/web.php';
  571. if (in_array('phar', stream_get_wrappers()) && class_exists('Phar', 0)) {
  572. Phar::interceptFileFuncs();
  573. set_include_path('phar://' . __FILE__ . PATH_SEPARATOR . get_include_path());
  574. Phar::webPhar(null, $web);
  575. include 'phar://' . __FILE__ . '/' . Extract_Phar::START;
  576. return;
  577. }
  578. if (@(isset($_SERVER['REQUEST_URI']) && isset($_SERVER['REQUEST_METHOD']) && ($_SERVER['REQUEST_METHOD'] == 'GET' || $_SERVER['REQUEST_METHOD'] == 'POST'))) {
  579. Extract_Phar::go(true);
  580. $mimes = array(
  581. 'phps' => 2,
  582. 'c' => 'text/plain',
  583. 'cc' => 'text/plain',
  584. 'cpp' => 'text/plain',
  585. 'c++' => 'text/plain',
  586. 'dtd' => 'text/plain',
  587. 'h' => 'text/plain',
  588. 'log' => 'text/plain',
  589. 'rng' => 'text/plain',
  590. 'txt' => 'text/plain',
  591. 'xsd' => 'text/plain',
  592. 'php' => 1,
  593. 'inc' => 1,
  594. 'avi' => 'video/avi',
  595. 'bmp' => 'image/bmp',
  596. 'css' => 'text/css',
  597. 'gif' => 'image/gif',
  598. 'htm' => 'text/html',
  599. 'html' => 'text/html',
  600. 'htmls' => 'text/html',
  601. 'ico' => 'image/x-ico',
  602. 'jpe' => 'image/jpeg',
  603. 'jpg' => 'image/jpeg',
  604. 'jpeg' => 'image/jpeg',
  605. 'js' => 'application/x-javascript',
  606. 'midi' => 'audio/midi',
  607. 'mid' => 'audio/midi',
  608. 'mod' => 'audio/mod',
  609. 'mov' => 'movie/quicktime',
  610. 'mp3' => 'audio/mp3',
  611. 'mpg' => 'video/mpeg',
  612. 'mpeg' => 'video/mpeg',
  613. 'pdf' => 'application/pdf',
  614. 'png' => 'image/png',
  615. 'swf' => 'application/shockwave-flash',
  616. 'tif' => 'image/tiff',
  617. 'tiff' => 'image/tiff',
  618. 'wav' => 'audio/wav',
  619. 'xbm' => 'image/xbm',
  620. 'xml' => 'text/xml',
  621. );
  622. header("Cache-Control: no-cache, must-revalidate");
  623. header("Pragma: no-cache");
  624. $basename = basename(__FILE__);
  625. if (!strpos($_SERVER['REQUEST_URI'], $basename)) {
  626. chdir(Extract_Phar::$temp);
  627. include $web;
  628. return;
  629. }
  630. $pt = substr($_SERVER['REQUEST_URI'], strpos($_SERVER['REQUEST_URI'], $basename) + strlen($basename));
  631. if (!$pt || $pt == '/') {
  632. $pt = $web;
  633. header('HTTP/1.1 301 Moved Permanently');
  634. header('Location: ' . $_SERVER['REQUEST_URI'] . '/' . $pt);
  635. exit;
  636. }
  637. $a = realpath(Extract_Phar::$temp . DIRECTORY_SEPARATOR . $pt);
  638. if (!$a || strlen(dirname($a)) < strlen(Extract_Phar::$temp)) {
  639. header('HTTP/1.0 404 Not Found');
  640. echo "<html>\n <head>\n <title>File Not Found<title>\n </head>\n <body>\n <h1>404 - File Not Found</h1>\n </body>\n</html>";
  641. exit;
  642. }
  643. $b = pathinfo($a);
  644. if (!isset($b['extension'])) {
  645. header('Content-Type: text/plain');
  646. header('Content-Length: ' . filesize($a));
  647. readfile($a);
  648. exit;
  649. }
  650. if (isset($mimes[$b['extension']])) {
  651. if ($mimes[$b['extension']] === 1) {
  652. include $a;
  653. exit;
  654. }
  655. if ($mimes[$b['extension']] === 2) {
  656. highlight_file($a);
  657. exit;
  658. }
  659. header('Content-Type: ' .$mimes[$b['extension']]);
  660. header('Content-Length: ' . filesize($a));
  661. readfile($a);
  662. exit;
  663. }
  664. }
  665. class Extract_Phar
  666. {
  667. static $temp;
  668. static $origdir;
  669. const GZ = 0x1000;
  670. const BZ2 = 0x2000;
  671. const MASK = 0x3000;
  672. const START = 'my/custom/thingy.php';
  673. const LEN = 6688;
  674. static function go($return = false)
  675. {
  676. $fp = fopen(__FILE__, 'rb');
  677. fseek($fp, self::LEN);
  678. $L = unpack('V', $a = (binary)fread($fp, 4));
  679. $m = (binary)'';
  680. do {
  681. $read = 8192;
  682. if ($L[1] - strlen($m) < 8192) {
  683. $read = $L[1] - strlen($m);
  684. }
  685. $last = (binary)fread($fp, $read);
  686. $m .= $last;
  687. } while (strlen($last) && strlen($m) < $L[1]);
  688. if (strlen($m) < $L[1]) {
  689. die('ERROR: manifest length read was "' .
  690. strlen($m) .'" should be "' .
  691. $L[1] . '"');
  692. }
  693. $info = self::_unpack($m);
  694. $f = $info['c'];
  695. if ($f & self::GZ) {
  696. if (!function_exists('gzinflate')) {
  697. die('Error: zlib extension is not enabled -' .
  698. ' gzinflate() function needed for zlib-compressed .phars');
  699. }
  700. }
  701. if ($f & self::BZ2) {
  702. if (!function_exists('bzdecompress')) {
  703. die('Error: bzip2 extension is not enabled -' .
  704. ' bzdecompress() function needed for bz2-compressed .phars');
  705. }
  706. }
  707. $temp = self::tmpdir();
  708. if (!$temp || !is_writable($temp)) {
  709. $sessionpath = session_save_path();
  710. if (strpos ($sessionpath, ";") !== false)
  711. $sessionpath = substr ($sessionpath, strpos ($sessionpath, ";")+1);
  712. if (!file_exists($sessionpath) || !is_dir($sessionpath)) {
  713. die('Could not locate temporary directory to extract phar');
  714. }
  715. $temp = $sessionpath;
  716. }
  717. $temp .= '/pharextract/'.basename(__FILE__, '.phar');
  718. self::$temp = $temp;
  719. self::$origdir = getcwd();
  720. @mkdir($temp, 0777, true);
  721. $temp = realpath($temp);
  722. if (!file_exists($temp . DIRECTORY_SEPARATOR . md5_file(__FILE__))) {
  723. self::_removeTmpFiles($temp, getcwd());
  724. @mkdir($temp, 0777, true);
  725. @file_put_contents($temp . '/' . md5_file(__FILE__), '');
  726. foreach ($info['m'] as $path => $file) {
  727. $a = !file_exists(dirname($temp . '/' . $path));
  728. @mkdir(dirname($temp . '/' . $path), 0777, true);
  729. clearstatcache();
  730. if ($path[strlen($path) - 1] == '/') {
  731. @mkdir($temp . '/' . $path, 0777);
  732. } else {
  733. file_put_contents($temp . '/' . $path, self::extractFile($path, $file, $fp));
  734. @chmod($temp . '/' . $path, 0666);
  735. }
  736. }
  737. }
  738. chdir($temp);
  739. if (!$return) {
  740. include self::START;
  741. }
  742. }
  743. static function tmpdir()
  744. {
  745. if (strpos(PHP_OS, 'WIN') !== false) {
  746. if ($var = getenv('TMP') ? getenv('TMP') : getenv('TEMP')) {
  747. return $var;
  748. }
  749. if (is_dir('/temp') || mkdir('/temp')) {
  750. return realpath('/temp');
  751. }
  752. return false;
  753. }
  754. if ($var = getenv('TMPDIR')) {
  755. return $var;
  756. }
  757. return realpath('/tmp');
  758. }
  759. static function _unpack($m)
  760. {
  761. $info = unpack('V', substr($m, 0, 4));
  762. $l = unpack('V', substr($m, 10, 4));
  763. $m = substr($m, 14 + $l[1]);
  764. $s = unpack('V', substr($m, 0, 4));
  765. $o = 0;
  766. $start = 4 + $s[1];
  767. $ret['c'] = 0;
  768. for ($i = 0; $i < $info[1]; $i++) {
  769. $len = unpack('V', substr($m, $start, 4));
  770. $start += 4;
  771. $savepath = substr($m, $start, $len[1]);
  772. $start += $len[1];
  773. $ret['m'][$savepath] = array_values(unpack('Va/Vb/Vc/Vd/Ve/Vf', substr($m, $start, 24)));
  774. $ret['m'][$savepath][3] = sprintf('%u', $ret['m'][$savepath][3]
  775. & 0xffffffff);
  776. $ret['m'][$savepath][7] = $o;
  777. $o += $ret['m'][$savepath][2];
  778. $start += 24 + $ret['m'][$savepath][5];
  779. $ret['c'] |= $ret['m'][$savepath][4] & self::MASK;
  780. }
  781. return $ret;
  782. }
  783. static function extractFile($path, $entry, $fp)
  784. {
  785. $data = '';
  786. $c = $entry[2];
  787. while ($c) {
  788. if ($c < 8192) {
  789. $data .= @fread($fp, $c);
  790. $c = 0;
  791. } else {
  792. $c -= 8192;
  793. $data .= @fread($fp, 8192);
  794. }
  795. }
  796. if ($entry[4] & self::GZ) {
  797. $data = gzinflate($data);
  798. } elseif ($entry[4] & self::BZ2) {
  799. $data = bzdecompress($data);
  800. }
  801. if (strlen($data) != $entry[0]) {
  802. die("Invalid internal .phar file (size error " . strlen($data) . " != " .
  803. $stat[7] . ")");
  804. }
  805. if ($entry[3] != sprintf("%u", crc32((binary)$data) & 0xffffffff)) {
  806. die("Invalid internal .phar file (checksum error)");
  807. }
  808. return $data;
  809. }
  810. static function _removeTmpFiles($temp, $origdir)
  811. {
  812. chdir($temp);
  813. foreach (glob('*') as $f) {
  814. if (file_exists($f)) {
  815. is_dir($f) ? @rmdir($f) : @unlink($f);
  816. if (file_exists($f) && is_dir($f)) {
  817. self::_removeTmpFiles($f, getcwd());
  818. }
  819. }
  820. }
  821. @rmdir($temp);
  822. clearstatcache();
  823. chdir($origdir);
  824. }
  825. }
  826. Extract_Phar::go();
  827. __HALT_COMPILER(); ?>
  828. "
  829. ============================================================================
  830. ============================================================================
  831. int(7066)
  832. Illegal filename passed in for stub creation, was 401 characters long, and only 400 or less is allowed
  833. ===DONE===