3v4l.org

run code in 150+ php & hhvm versions
Bugs & Features
<?php error_reporting(-1); $fh = fopen(__FILE__, 'r'); fseek($fh, __COMPILER_HALT_OFFSET__, SEEK_SET); $mh = new MimeHalt($fh); var_dump($mh); eval('?>' . $mh->getFile('/test.php')); exit; class MimeHalt { public $config; protected $fh; protected $offset_diff = 0; protected $offset_after_main_header = 0; protected $offset_after_first_file_header = 0; protected $mime_boundary; public function __construct($fh) { $this->fh = $fh; $this->offset_diff = ftell($this->fh); $this->init(); } public function init() { $this->offset_after_first_file_header = 0; $this->resetOffset(); $first_line = stream_get_line($this->fh, PHP_INT_MAX, "\n"); $matches = array(); if(!preg_match('/^content\-type: multipart\/related; boundary=(.+)(?:;\s+.+)?$/i', $first_line, $matches)) { throw new RuntimeException('Invalid or corrupt file'); } $this->mime_boundary = '--' . $matches[1]; $this->resetOffset(); $header = static::readNextHeaderChunk($this->fh); #var_dump(static::processHeader($header)); fseek($this->fh, strlen($this->mime_boundary) + 1, SEEK_CUR); $this->offset_after_main_header = ftell($this->fh) - $this->offset_diff; $json_header = static::readNextHeaderChunk($this->fh); $json_body = static::readNextBodyChunk($this->fh, $this->mime_boundary); #var_dump($json_body); $this->config = json_decode($json_body, true); $this->offset_after_first_file_header = ftell($this->fh) - $this->offset_diff; $this->resetOffset(); if(!is_array($this->config['offset_map']) || !count($this->config['offset_map'])) $this->buildOffsetMap(); } public function resetOffset() { fseek($this->fh, $this->offset_diff + $this->offset_after_first_file_header, SEEK_SET); } public function buildOffsetMap() { #echo "Starting to rebuild offset map starting at position ", ftell($this->fh), "\n"; fseek($this->fh, $this->offset_diff + $this->offset_after_main_header, SEEK_SET); $header_text = ''; while($header_text = static::readNextHeaderChunk($this->fh)) { $headers = static::processHeader($header_text); #var_dump([$headers, $header_text]); $this->config['offset_map'][$headers['Content-ID']] = ftell($this->fh); static::readNextBodyChunk($this->fh, $this->mime_boundary); } #var_dump($this->config['offset_map']); } public function getFile($filename) { $content_id = $this->config['files'][$filename]; $offset = $this->config['offset_map'][$content_id]; fseek($this->fh, $offset, SEEK_SET); return static::readNextBodyChunk($this->fh, $this->mime_boundary); } protected static function readNextHeaderChunk($fh) { $line = stream_get_line($fh, PHP_INT_MAX, "\n\n"); if($line === false) return false; return $line . "\n"; } protected static function readNextBodyChunk($fh, $boundary) { $line = stream_get_line($fh, PHP_INT_MAX, "\n" . $boundary . "\n"); $end_of_body_string = "\n" . $boundary . "--\n"; $eobs_length = strlen($end_of_body_string); if(substr($line, $eobs_length * -1) == $end_of_body_string) $line = substr($line, 0, $eobs_length * -1); return $line; } protected static function processHeader($header_text) { $headers = array(); $matches = array(); $found = preg_match_all('/^(.+): ((.|\r\n\s)+)\r?\n/m', $header_text, $matches, PREG_SET_ORDER); if($found) { foreach($matches as $set) $headers[ $set[1] ] = $set[2]; } return $headers; } } __halt_compiler();Content-type: multipart/related; boundary=mimehalt_outer X-MimeHalt-Version: 1.0.0 --mimehalt_outer Content-Type: application/json Content-ID: 100000001 { "files": { "/mimehalt.json": "100000001", "/test.php": "100000002" }, "dirs": [ "/" ], "offset_map": null } --mimehalt_outer Content-Type: application/x-php Content-ID: 100000002 <?php echo "Hello, world!"; ?> --mimehalt_outer--
Output for 5.3.11 - 5.3.29, 5.4.1 - 7.1.0
object(MimeHalt)#1 (6) { ["config"]=> array(3) { ["files"]=> array(2) { ["/mimehalt.json"]=> string(9) "100000001" ["/test.php"]=> string(9) "100000002" } ["dirs"]=> array(1) { [0]=> string(1) "/" } ["offset_map"]=> array(2) { [100000001]=> int(4362) [100000002]=> int(4556) } } ["fh":protected]=> resource(5) of type (stream) ["offset_diff":protected]=> int(4207) ["offset_after_main_header":protected]=> int(101) ["offset_after_first_file_header":protected]=> int(294) ["mime_boundary":protected]=> string(16) "--mimehalt_outer" } Hello, world!--mimehalt_outer--
Output for 5.3.0 - 5.3.10, 5.4.0
Fatal error: Allowed memory size of 33554432 bytes exhausted (tried to allocate 9223372036854775808 bytes) in /in/eG1qd on line 90
Process exited with code 255.
Output for 5.1.0 - 5.2.17
Parse error: syntax error, unexpected T_STATIC in /in/eG1qd on line 41
Process exited with code 255.
Output for 5.0.0 - 5.0.5
Parse error: parse error, unexpected T_STATIC in /in/eG1qd on line 41
Process exited with code 255.
Output for 4.4.2 - 4.4.9
Parse error: syntax error, unexpected T_STRING, expecting T_OLD_FUNCTION or T_FUNCTION or T_VAR or '}' in /in/eG1qd on line 15
Process exited with code 255.
Output for 4.3.0 - 4.3.1, 4.3.5 - 4.4.1
Parse error: parse error, unexpected T_STRING, expecting T_OLD_FUNCTION or T_FUNCTION or T_VAR or '}' in /in/eG1qd on line 15
Process exited with code 255.
Output for 4.3.2 - 4.3.4
Parse error: parse error, expecting `T_OLD_FUNCTION' or `T_FUNCTION' or `T_VAR' or `'}'' in /in/eG1qd on line 15
Process exited with code 255.