Merge branch 'PHP-7.0' into PHP-7.1

This commit is contained in:
Bob Weinand 2016-12-06 18:30:37 +01:00
commit 43f88f25bb
3 changed files with 95 additions and 5 deletions

View file

@ -236,15 +236,16 @@ zend_op_array *phpdbg_compile_file(zend_file_handle *file, int type) {
phpdbg_file_source data, *dataptr;
zend_file_handle fake;
zend_op_array *ret;
char *filename = (char *)(file->opened_path ? ZSTR_VAL(file->opened_path) : file->filename);
char *filename;
uint line;
char *bufptr, *endptr;
char resolved_path_buf[MAXPATHLEN];
if (zend_stream_fixup(file, &bufptr, &data.len) == FAILURE) {
return PHPDBG_G(compile_file)(file, type);
}
filename = (char *)(file->opened_path ? ZSTR_VAL(file->opened_path) : file->filename);
data.buf = emalloc(data.len + ZEND_MMAP_AHEAD + 1);
if (data.len > 0) {
memcpy(data.buf, bufptr, data.len);
@ -262,9 +263,6 @@ zend_op_array *phpdbg_compile_file(zend_file_handle *file, int type) {
fake.opened_path = file->opened_path;
*(dataptr = emalloc(sizeof(phpdbg_file_source) + sizeof(uint) * data.len)) = data;
if (VCWD_REALPATH(filename, resolved_path_buf)) {
filename = resolved_path_buf;
}
for (line = 0, bufptr = data.buf - 1, endptr = data.buf + data.len; ++bufptr < endptr;) {
if (*bufptr == '\n') {
@ -324,6 +322,8 @@ zend_op_array *phpdbg_init_compile_file(zend_file_handle *file, int type) {
return NULL;
}
filename = (char *)(file->opened_path ? ZSTR_VAL(file->opened_path) : file->filename);
dataptr = zend_hash_str_find_ptr(&PHPDBG_G(file_sources), filename, strlen(filename));
ZEND_ASSERT(dataptr != NULL);

View file

@ -0,0 +1,6 @@
<?php
function foo()
{
return '<result>'; // line 5 is executable
}

View file

@ -0,0 +1,84 @@
--TEST--
Getting executable lines from custom wrappers
--PHPDBG--
r
q
--EXPECTF--
[Successful compilation of %s]
prompt> array(1) {
[5]=>
int(0)
}
[Script ended normally]
prompt>
--FILE--
<?php
/**
* This example demonstrates how phpdbg_get_executable() behaves differently
* when passed the 'files' option vs without, in the face of some mild abuse
* of stream wrappers.
*/
/**
* First, we define a stream wrapper that simply maps to a real file on disk.
*/
final class StreamWrapper
{
public function stream_open(
string $path,
string $mode,
int $options = 0,
string &$openedPath = null
) : bool {
if ($mode[0] !== 'r') {
return false;
}
list($scheme, $path) = explode('://', $path, 2);
$stream = \fopen($path, $mode);
if ($stream === false) {
return false;
}
$this->stream = $stream;
/**
* The $openedPath reference variable is assigned, indicating the
* *actual* path that was opened. This affects the behaviour of
* constants like __FILE__.
*/
$openedPath = \realpath($path);
return true;
}
public function stream_read(int $count) : string { return \fread($this->stream, $count); }
public function stream_close() : bool { return \fclose($this->stream); }
public function stream_eof() : bool { return \feof($this->stream); }
public function stream_stat() { return \fstat($this->stream); }
private $stream = false;
}
stream_wrapper_register('wrapper', StreamWrapper::class);
/**
* Next, we include a PHP file that contains executable lines, via the stream
* wrapper.
*/
$filename = __DIR__ . '/phpdbg_get_executable_stream_wrapper.inc';
require 'wrapper://' . $filename;
/**
* If we call phpdbg_get_executable() and pass no options, the realpath of the
* included file is present in the array, but indicates no executable lines.
*/
$x = phpdbg_get_executable();
// We expect [5 => 0], but got an empty array ...
var_dump($x[$filename]);
?>