mirror of
https://github.com/php/php-src.git
synced 2025-08-16 05:58:45 +02:00
Merge branch 'PHP-7.0' into PHP-7.1
This commit is contained in:
commit
43f88f25bb
3 changed files with 95 additions and 5 deletions
|
@ -236,15 +236,16 @@ zend_op_array *phpdbg_compile_file(zend_file_handle *file, int type) {
|
||||||
phpdbg_file_source data, *dataptr;
|
phpdbg_file_source data, *dataptr;
|
||||||
zend_file_handle fake;
|
zend_file_handle fake;
|
||||||
zend_op_array *ret;
|
zend_op_array *ret;
|
||||||
char *filename = (char *)(file->opened_path ? ZSTR_VAL(file->opened_path) : file->filename);
|
char *filename;
|
||||||
uint line;
|
uint line;
|
||||||
char *bufptr, *endptr;
|
char *bufptr, *endptr;
|
||||||
char resolved_path_buf[MAXPATHLEN];
|
|
||||||
|
|
||||||
if (zend_stream_fixup(file, &bufptr, &data.len) == FAILURE) {
|
if (zend_stream_fixup(file, &bufptr, &data.len) == FAILURE) {
|
||||||
return PHPDBG_G(compile_file)(file, type);
|
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);
|
data.buf = emalloc(data.len + ZEND_MMAP_AHEAD + 1);
|
||||||
if (data.len > 0) {
|
if (data.len > 0) {
|
||||||
memcpy(data.buf, bufptr, data.len);
|
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;
|
fake.opened_path = file->opened_path;
|
||||||
|
|
||||||
*(dataptr = emalloc(sizeof(phpdbg_file_source) + sizeof(uint) * data.len)) = data;
|
*(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;) {
|
for (line = 0, bufptr = data.buf - 1, endptr = data.buf + data.len; ++bufptr < endptr;) {
|
||||||
if (*bufptr == '\n') {
|
if (*bufptr == '\n') {
|
||||||
|
@ -324,6 +322,8 @@ zend_op_array *phpdbg_init_compile_file(zend_file_handle *file, int type) {
|
||||||
return NULL;
|
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));
|
dataptr = zend_hash_str_find_ptr(&PHPDBG_G(file_sources), filename, strlen(filename));
|
||||||
ZEND_ASSERT(dataptr != NULL);
|
ZEND_ASSERT(dataptr != NULL);
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
function foo()
|
||||||
|
{
|
||||||
|
return '<result>'; // line 5 is executable
|
||||||
|
}
|
84
sapi/phpdbg/tests/phpdbg_get_executable_stream_wrapper.phpt
Normal file
84
sapi/phpdbg/tests/phpdbg_get_executable_stream_wrapper.phpt
Normal 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]);
|
||||||
|
|
||||||
|
?>
|
Loading…
Add table
Add a link
Reference in a new issue