@ 2014-02-16T06:49:14Z <?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--
Enable javascript to submit You have javascript disabled. You will not be able to edit any code.
Output for 5.3.11 - 5.3.29 , 5.4.1 - 5.4.45 , 5.5.0 - 5.5.38 , 5.6.0 - 5.6.40 , 7.0.0 - 7.0.33 , 7.1.0 - 7.1.33 , 7.2.0 - 7.2.33 , 7.3.0 - 7.3.33 , 7.4.0 - 7.4.33 , 8.0.0 - 8.0.30 , 8.1.0 - 8.1.28 , 8.2.0 - 8.2.18 , 8.3.0 - 8.3.6 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 67108864 bytes exhausted (tried to allocate 9223372036854775808 bytes) in /in/eG1qd on line 90
Process exited with code 255 . Output for 5.1.0 - 5.1.6 , 5.2.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.3.11 , 4.4.0 - 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 . preferences:dark mode live preview
282.33 ms | 401 KiB | 460 Q