Permalink
Browse files

Fixed issue #1514: Variable names with a NULL char are cut off at NUL…

…L char
  • Loading branch information...
derickr committed Jan 13, 2018
1 parent 10529fb commit 63cd0b7901395a36ac4aa67a9920c626b75ed07d
Showing with 242 additions and 132 deletions.
  1. +2 −2 tests/bug01202.phpt
  2. +2 −2 tests/bug01203.phpt
  3. +6 −0 tests/bug01514.inc
  4. +47 −0 tests/bug01514.phpt
  5. +12 −14 xdebug.c
  6. +7 −7 xdebug_handler_dbgp.c
  7. +17 −7 xdebug_private.c
  8. +15 −14 xdebug_private.h
  9. +18 −15 xdebug_stack.c
  10. +115 −70 xdebug_var.c
  11. +1 −1 xdebug_var.h
View
@@ -32,11 +32,11 @@ dbgpRun( $data, $commands );
-> context_get -i 3
<?xml version="1.0" encoding="iso-8859-1"?>
<response xmlns="urn:debugger_protocol_v1" xmlns:xdebug="http://xdebug.org/dbgp/xdebug" command="context_get" transaction_id="3" context="0"><property name="$a" fullname="$a" type="object" classname="class@anonymous" children="1" numchildren="1" page="0" pagesize="32"><property name="a" fullname="$a-&gt;a" facet="public" type="int"><![CDATA[42]]></property></property></response>
<response xmlns="urn:debugger_protocol_v1" xmlns:xdebug="http://xdebug.org/dbgp/xdebug" command="context_get" transaction_id="3" context="0"><property name="$a" fullname="$a" type="object" classname="class@anonymous&#0;/tmp/xdebug-dbgp-test.php0x%s" children="1" numchildren="1" page="0" pagesize="32"><property name="a" fullname="$a-&gt;a" facet="public" type="int"><![CDATA[42]]></property></property></response>
-> property_get -i 4 -n $a
<?xml version="1.0" encoding="iso-8859-1"?>
<response xmlns="urn:debugger_protocol_v1" xmlns:xdebug="http://xdebug.org/dbgp/xdebug" command="property_get" transaction_id="4"><property name="$a" fullname="$a" type="object" classname="class@anonymous" children="1" numchildren="1" page="0" pagesize="32"><property name="a" fullname="$a-&gt;a" facet="public" type="int"><![CDATA[42]]></property></property></response>
<response xmlns="urn:debugger_protocol_v1" xmlns:xdebug="http://xdebug.org/dbgp/xdebug" command="property_get" transaction_id="4"><property name="$a" fullname="$a" type="object" classname="class@anonymous&#0;/tmp/xdebug-dbgp-test.php0x%s" children="1" numchildren="1" page="0" pagesize="32"><property name="a" fullname="$a-&gt;a" facet="public" type="int"><![CDATA[42]]></property></property></response>
-> property_get -i 5 -n $a->a
<?xml version="1.0" encoding="iso-8859-1"?>
View
@@ -32,11 +32,11 @@ dbgpRun( $data, $commands );
-> context_get -i 3
<?xml version="1.0" encoding="iso-8859-1"?>
<response xmlns="urn:debugger_protocol_v1" xmlns:xdebug="http://xdebug.org/dbgp/xdebug" command="context_get" transaction_id="3" context="0"><property name="$a" fullname="$a" type="object" classname="class@anonymous" children="1" numchildren="1" page="0" pagesize="32"><property name="a" fullname="$a-&gt;a" facet="public" type="int"><![CDATA[42]]></property></property></response>
<response xmlns="urn:debugger_protocol_v1" xmlns:xdebug="http://xdebug.org/dbgp/xdebug" command="context_get" transaction_id="3" context="0"><property name="$a" fullname="$a" type="object" classname="class@anonymous&#0;/tmp/xdebug-dbgp-test.php0x%s" children="1" numchildren="1" page="0" pagesize="32"><property name="a" fullname="$a-&gt;a" facet="public" type="int"><![CDATA[42]]></property></property></response>
-> property_get -i 4 -n $a
<?xml version="1.0" encoding="iso-8859-1"?>
<response xmlns="urn:debugger_protocol_v1" xmlns:xdebug="http://xdebug.org/dbgp/xdebug" command="property_get" transaction_id="4"><property name="$a" fullname="$a" type="object" classname="class@anonymous" children="1" numchildren="1" page="0" pagesize="32"><property name="a" fullname="$a-&gt;a" facet="public" type="int"><![CDATA[42]]></property></property></response>
<response xmlns="urn:debugger_protocol_v1" xmlns:xdebug="http://xdebug.org/dbgp/xdebug" command="property_get" transaction_id="4"><property name="$a" fullname="$a" type="object" classname="class@anonymous&#0;/tmp/xdebug-dbgp-test.php0x%s" children="1" numchildren="1" page="0" pagesize="32"><property name="a" fullname="$a-&gt;a" facet="public" type="int"><![CDATA[42]]></property></property></response>
-> property_get -i 5 -n $a::a
<?xml version="1.0" encoding="iso-8859-1"?>
View
@@ -0,0 +1,6 @@
<?php
$name = "with_\0_null_char";
$$name = 42;
die();
?>
View
@@ -0,0 +1,47 @@
--TEST--
Test for bug #1514: (Root) Variable names with a NULL char are cut off at NULL char
--SKIPIF--
<?php if (getenv("SKIP_DBGP_TESTS")) { exit("skip Excluding DBGp tests"); } ?>
--FILE--
<?php
require 'dbgp/dbgpclient.php';
$data = file_get_contents(dirname(__FILE__) . '/bug01514.inc');
$commands = array(
'step_into',
'step_into',
'step_into',
'context_get',
'property_get -d 0 -c 0 -n $with_\0_null_char',
'property_get -d 0 -c 0 -n "$with_\\\0_null_char"',
);
dbgpRun( $data, $commands );
?>
--EXPECTF--
<?xml version="1.0" encoding="iso-8859-1"?>
<init xmlns="urn:debugger_protocol_v1" xmlns:xdebug="http://xdebug.org/dbgp/xdebug" fileuri="file:///tmp/xdebug-dbgp-test.php" language="PHP" xdebug:language_version="" protocol_version="1.0" appid="" idekey=""><engine version=""><![CDATA[Xdebug]]></engine><author><![CDATA[Derick Rethans]]></author><url><![CDATA[http://xdebug.org]]></url><copyright><![CDATA[Copyright (c) 2002-2099 by Derick Rethans]]></copyright></init>
-> step_into -i 1
<?xml version="1.0" encoding="iso-8859-1"?>
<response xmlns="urn:debugger_protocol_v1" xmlns:xdebug="http://xdebug.org/dbgp/xdebug" command="step_into" transaction_id="1" status="break" reason="ok"><xdebug:message filename="file:///tmp/xdebug-dbgp-test.php" lineno="2"></xdebug:message></response>
-> step_into -i 2
<?xml version="1.0" encoding="iso-8859-1"?>
<response xmlns="urn:debugger_protocol_v1" xmlns:xdebug="http://xdebug.org/dbgp/xdebug" command="step_into" transaction_id="2" status="break" reason="ok"><xdebug:message filename="file:///tmp/xdebug-dbgp-test.php" lineno="3"></xdebug:message></response>
-> step_into -i 3
<?xml version="1.0" encoding="iso-8859-1"?>
<response xmlns="urn:debugger_protocol_v1" xmlns:xdebug="http://xdebug.org/dbgp/xdebug" command="step_into" transaction_id="3" status="break" reason="ok"><xdebug:message filename="file:///tmp/xdebug-dbgp-test.php" lineno="5"></xdebug:message></response>
-> context_get -i 4
<?xml version="1.0" encoding="iso-8859-1"?>
<response xmlns="urn:debugger_protocol_v1" xmlns:xdebug="http://xdebug.org/dbgp/xdebug" command="context_get" transaction_id="4" context="0"><property name="$name" fullname="$name" type="string" size="16" encoding="base64"><![CDATA[d2l0aF8AX251bGxfY2hhcg==]]></property><property name="$with_&#0;_null_char" fullname="$with_&#0;_null_char" type="uninitialized"></property></response>
-> property_get -i 5 -d 0 -c 0 -n $with_\0_null_char
<?xml version="1.0" encoding="iso-8859-1"?>
<response xmlns="urn:debugger_protocol_v1" xmlns:xdebug="http://xdebug.org/dbgp/xdebug" command="property_get" transaction_id="5"><property name="$with_\0_null_char" fullname="$with_\0_null_char" type="int"><![CDATA[42]]></property></response>
-> property_get -i 6 -d 0 -c 0 -n "$with_\\0_null_char"
<?xml version="1.0" encoding="iso-8859-1"?>
<response xmlns="urn:debugger_protocol_v1" xmlns:xdebug="http://xdebug.org/dbgp/xdebug" command="property_get" transaction_id="6"><property name="$with_\0_null_char" fullname="$with_\0_null_char" type="int"><![CDATA[42]]></property></response>
View
@@ -1051,13 +1051,11 @@ static void xdebug_llist_string_dtor(void *dummy, void *elem)
}
}
static void xdebug_used_var_dtor(void *dummy, void *elem)
static void xdebug_declared_var_dtor(void *dummy, void *elem)
{
char *s = elem;
xdebug_str *s = (xdebug_str*) elem;
if (s) {
xdfree(s);
}
xdebug_str_free(s);
}
static void xdebug_stack_element_dtor(void *dummy, void *elem)
@@ -1091,9 +1089,9 @@ static void xdebug_stack_element_dtor(void *dummy, void *elem)
xdfree(e->include_filename);
}
if (e->used_vars) {
xdebug_llist_destroy(e->used_vars, NULL);
e->used_vars = NULL;
if (e->declared_vars) {
xdebug_llist_destroy(e->declared_vars, NULL);
e->declared_vars = NULL;
}
if (e->profile.call_list) {
@@ -1489,20 +1487,20 @@ static void add_used_variables(function_stack_entry *fse, zend_op_array *op_arra
{
unsigned int i = 0;
if (!fse->used_vars) {
fse->used_vars = xdebug_llist_alloc(xdebug_used_var_dtor);
if (!fse->declared_vars) {
fse->declared_vars = xdebug_llist_alloc(xdebug_declared_var_dtor);
}
/* Check parameters */
for (i = 0; i < fse->varc; i++) {
if (fse->var[i].name) {
xdebug_llist_insert_next(fse->used_vars, XDEBUG_LLIST_TAIL(fse->used_vars), xdstrdup(fse->var[i].name));
xdebug_llist_insert_next(fse->declared_vars, XDEBUG_LLIST_TAIL(fse->declared_vars), xdebug_str_create(fse->var[i].name, fse->var[i].length));
}
}
/* gather used variables from compiled vars information */
while (i < (unsigned int) op_array->last_var) {
xdebug_llist_insert_next(fse->used_vars, XDEBUG_LLIST_TAIL(fse->used_vars), xdstrdup(STR_NAME_VAL(op_array->vars[i])));
xdebug_llist_insert_next(fse->declared_vars, XDEBUG_LLIST_TAIL(fse->declared_vars), xdebug_str_create(STR_NAME_VAL(op_array->vars[i]), STR_NAME_LEN(op_array->vars[i])));
i++;
}
@@ -1513,11 +1511,11 @@ static void add_used_variables(function_stack_entry *fse, zend_op_array *op_arra
if (op_array->opcodes[i].op1_type == IS_CV) {
cv = (char *) xdebug_get_compiled_variable_name(op_array, op_array->opcodes[i].op1.var, &cv_len);
xdebug_llist_insert_next(fse->used_vars, XDEBUG_LLIST_TAIL(fse->used_vars), xdstrdup(cv));
xdebug_llist_insert_next(fse->declared_vars, XDEBUG_LLIST_TAIL(fse->declared_vars), xdebug_str_create(cv, cv_len));
}
if (op_array->opcodes[i].op2_type == IS_CV) {
cv = (char *) xdebug_get_compiled_variable_name(op_array, op_array->opcodes[i].op2.var, &cv_len);
xdebug_llist_insert_next(fse->used_vars, XDEBUG_LLIST_TAIL(fse->used_vars), xdstrdup(cv));
xdebug_llist_insert_next(fse->declared_vars, XDEBUG_LLIST_TAIL(fse->declared_vars), xdebug_str_create(cv, cv_len));
}
i++;
}
View
@@ -1622,14 +1622,14 @@ DBGP_FUNC(property_value)
options->max_data = old_max_data;
}
static void attach_used_var_with_contents(void *xml, xdebug_hash_element* he, void *options)
static void attach_declared_var_with_contents(void *xml, xdebug_hash_element* he, void *options)
{
char *name = (char*) he->ptr;
xdebug_str *name = (xdebug_str*) he->ptr;
xdebug_xml_node *node = (xdebug_xml_node *) xml;
xdebug_xml_node *contents;
TSRMLS_FETCH();
contents = get_symbol(name, options TSRMLS_CC);
contents = get_symbol(name->d, options TSRMLS_CC);
if (contents) {
xdebug_xml_add_child(node, contents);
} else {
@@ -1676,7 +1676,7 @@ static int xdebug_add_filtered_symboltable_var(zval *symbol TSRMLS_DC, int num_a
}
if (strcmp("GLOBALS", HASH_KEY_VAL(hash_key)) == 0) { return 0; }
xdebug_hash_add(tmp_hash, (char*) HASH_KEY_VAL(hash_key), strlen(HASH_KEY_VAL(hash_key)), HASH_KEY_VAL(hash_key));
xdebug_hash_add(tmp_hash, (char*) HASH_KEY_VAL(hash_key), HASH_KEY_LEN(hash_key), xdebug_str_create(HASH_KEY_VAL(hash_key), HASH_KEY_LEN(hash_key)));
return 0;
}
@@ -1742,11 +1742,11 @@ static int attach_context_vars(xdebug_xml_node *node, xdebug_var_export_options
XG(This) = fse->This;
/* Only show vars when they are scanned */
if (fse->used_vars) {
if (fse->declared_vars) {
xdebug_hash *tmp_hash;
/* Get a hash from all the used vars (which can have duplicates) */
tmp_hash = xdebug_used_var_hash_from_llist(fse->used_vars);
tmp_hash = xdebug_declared_var_hash_from_llist(fse->declared_vars);
/* Check for dynamically defined variables, but make sure we don't already
* have them. Also blacklist superglobals and argv/argc */
@@ -1856,7 +1856,7 @@ DBGP_FUNC(context_get)
/* Always reset to page = 0, as it might have been modified by property_get or property_value */
options->runtime[0].page = 0;
res = attach_context_vars(*retval, options, context_id, depth, attach_used_var_with_contents TSRMLS_CC);
res = attach_context_vars(*retval, options, context_id, depth, attach_declared_var_with_contents TSRMLS_CC);
switch (res) {
case 1:
RETURN_RESULT(XG(status), XG(reason), XDEBUG_ERROR_STACK_DEPTH_INVALID);
View
@@ -79,19 +79,29 @@ function_stack_entry *xdebug_get_stack_tail(TSRMLS_D)
static void xdebug_used_var_hash_from_llist_dtor(void *data)
{
/* We are not freeing anything as the list creating didn't copy the data */
xdebug_str *var_name = (xdebug_str*) data;
xdebug_str_free(var_name);
}
static int xdebug_compare_le_xdebug_str(const void *le1, const void *le2)
{
return strcmp(
((xdebug_str *) XDEBUG_LLIST_VALP(*(xdebug_llist_element **) le1))->d,
((xdebug_str *) XDEBUG_LLIST_VALP(*(xdebug_llist_element **) le2))->d
);
}
xdebug_hash* xdebug_used_var_hash_from_llist(xdebug_llist *list)
xdebug_hash* xdebug_declared_var_hash_from_llist(xdebug_llist *list)
{
xdebug_hash *tmp;
xdebug_hash *tmp;
xdebug_llist_element *le;
char *var_name;
xdebug_str *var_name;
tmp = xdebug_hash_alloc(32, xdebug_used_var_hash_from_llist_dtor);
tmp = xdebug_hash_alloc_with_sort(32, xdebug_used_var_hash_from_llist_dtor, xdebug_compare_le_xdebug_str);
for (le = XDEBUG_LLIST_HEAD(list); le != NULL; le = XDEBUG_LLIST_NEXT(le)) {
var_name = (char*) XDEBUG_LLIST_VALP(le);
xdebug_hash_add(tmp, var_name, strlen(var_name), var_name);
var_name = (xdebug_str*) XDEBUG_LLIST_VALP(le);
xdebug_hash_add(tmp, var_name->d, var_name->l, xdebug_str_copy(var_name));
}
return tmp;
View
@@ -43,11 +43,12 @@
char* xdebug_start_trace(char* fname, char *script_filename, long options TSRMLS_DC);
void xdebug_stop_trace(TSRMLS_D);
typedef struct xdebug_var {
char *name;
void *addr;
int is_variadic;
} xdebug_var;
typedef struct xdebug_var_name {
char *name;
size_t length;
void *addr;
int is_variadic;
} xdebug_var_name;
#define XFUNC_UNKNOWN 0x00
#define XFUNC_NORMAL 0x01
@@ -179,15 +180,15 @@ typedef struct _function_stack_entry {
int function_nr;
/* argument properties */
int arg_done;
unsigned int varc;
xdebug_var *var;
int is_variadic;
zval *return_value;
xdebug_llist *used_vars;
HashTable *symbol_table;
int arg_done;
unsigned int varc;
xdebug_var_name *var;
int is_variadic;
zval *return_value;
xdebug_llist *declared_vars;
HashTable *symbol_table;
zend_execute_data *execute_data;
zval *This;
zval *This;
/* filter properties */
long filtered_tracing;
@@ -232,7 +233,7 @@ typedef struct
} xdebug_trace_handler_t;
xdebug_hash* xdebug_used_var_hash_from_llist(xdebug_llist *list);
xdebug_hash* xdebug_declared_var_hash_from_llist(xdebug_llist *list);
void xdebug_init_debugger(TSRMLS_D);
#endif
Oops, something went wrong.

0 comments on commit 63cd0b7

Please sign in to comment.