Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Parsing Xdebug Engine's XML Response sometimes fails #77

Closed
jbeales opened this issue May 3, 2014 · 10 comments

Comments

Projects
None yet
3 participants
@jbeales
Copy link

commented May 3, 2014

Debugging WordPress issues, sometimes the XML that the Xdebug engine sends back to SublimeTextXdebug isn't valid, so parsing fails.

The invalid XML fragment looks like this:

<property name="&#0;lambda_13" fullname="$wp_filter[&#39;widgets_init&#39;][10][&#39;&#0;lambda_13&#39;]" address="4579437104" type="array" children="1" numchildren="2"></property>

The problem is the &#0.

This seems to be acknowledged in Xdebug issue 924, but it seems their "solution" might be to not use XML, if I understand properly. Is there a way we can follow the recommendation?

@martomo

This comment has been minimized.

Copy link
Owner

commented May 4, 2014

@jbeales When does this exactly happen upon retrieving context, or evaluating a watch expression.
Please provide steps to reproduce and include your system configuration with any other issue related data as described in the README.

@jbeales

This comment has been minimized.

Copy link
Author

commented May 4, 2014

It looks like it happens when retrieving the context, but when the error occurs the stack doesn't get properly populated either, (I don't know the internals, both windows might get their info from the context-get operation).

This is the console output:

Exception in thread Thread-4612:
Traceback (most recent call last):
  File "./threading.py", line 901, in _bootstrap_inner
  File "xdebug.session in /Users/John/Library/Application Support/Sublime Text 3/Installed Packages/Xdebug Client.sublime-package", line 148, in run
  File "xdebug.session in /Users/John/Library/Application Support/Sublime Text 3/Installed Packages/Xdebug Client.sublime-package", line 242, in execute
  File "xdebug.session in /Users/John/Library/Application Support/Sublime Text 3/Installed Packages/Xdebug Client.sublime-package", line 279, in get_context_values
  File "xdebug.protocol in /Users/John/Library/Application Support/Sublime Text 3/Installed Packages/Xdebug Client.sublime-package", line 129, in read
  File "./xml/etree/ElementTree.py", line 1356, in XML
  File "<string>", line None
xml.etree.ElementTree.ParseError: reference to invalid character number: line 2, column 161659

The thread number & column number change each time it happens, the rest stays the same.

Here's the XML output for the context_get operation of a test case where the problem occurs:

<?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="36" context="0"><property name="$false" fullname="$false" type="uninitialized"></property><property name="$php_errormsg" fullname="$php_errormsg" address="4546419944" type="string" size="29" encoding="base64"><![CDATA[VW5kZWZpbmVkIHZhcmlhYmxlOiB3cF9maWx0ZXI=]]></property><property name="$test" fullname="$test" address="4546419896" type="array" children="1" numchildren="1" page="0" pagesize="1000"><property name="&#0;" fullname="$test[&#39;&#0;&#39;]" address="4546422504" type="string" size="0" encoding="base64"><![CDATA[]]></property></property><property name="$true" fullname="$true" address="4546422552" type="bool"><![CDATA[0]]></property></response>

Here's the PHP file got me the XML above. The error occurs setting the $test variable:

<?php

echo 'hi';
$true = false;


$test = array("\0" => '');

echo ' there ';

$false = true;

echo 'dude.';

This is a contrived example, but it seems to happen when dealing with semi-anonymous functions, especially in WordPress's apply_filters() function.

Project Settings file:

{
    "folders":
    [
        {
            "follow_symlinks": true,
            "path": "serverfiles",
            "folder_exclude_patterns": [ "node_modules", ".sass-cache" ],
            "file_exclude_patterns": [ "*.cache" ]
        }
    ],

    "settings":
    {
        "xdebug":
        {
            "url": "http://testsite.loc",
            "close_on_stop": true,
            "super_globals": true,
            "max_children": 1000 ,
            "max_depth": 3,
            "debug": true
        }
    }
}

Xdebug section of my php.ini, (there's another .ini that includes the Xdebug module):

[xdebug]
xdebug.remote_enable = 1

I'm running OSX 10.9.2, Sublime Text 3 (Dev channel, build 3601). SublimeTextXdebug was installed via Package Control, which tells me it's at the latest version, and Xdebug 2.2.5, and PHP 5.5.

I'm debugging locally, running the script through the browser.

I think that's it. If you need any more info let me know.

@martomo

This comment has been minimized.

Copy link
Owner

commented May 4, 2014

I managed to reproduce it, however I think this more in relation to PHP.
In this case the backslash, \, is used inside double quotes therefor trying to escape the numeric value, which is not valid value in this case.

In case it's possible I would change the code in order to use single quotes or make sure you escape it properly within the double quotes.

// Breaks, double quotes with invalid escaped character
$invalid = array("\0" => '');

// Works, properly escaped with double quotes
$escape = array("\\0" => '');

// Works, using single quotes
$single = array('\0' => '');

// Works, but displays a space as key instead of '\040'
$space = array("\040" => '');

@martomo martomo added the pinned label May 4, 2014

@jbeales

This comment has been minimized.

Copy link
Author

commented May 4, 2014

I'll look into my full bunch of code and make sure that there's no issue like that there, and post back with another test case if it still happens.

@jbeales

This comment has been minimized.

Copy link
Author

commented May 4, 2014

Here's an example that doesn't involve directly typing an illegal string:

PHP file:

<pre><?php


$functions = array();

// $func should be a string, see http://ca2.php.net/create_function
$func = create_function('', 'return "hi";');

// check to see if it is a string, (it is)
var_dump( is_string( $func ) );

$functions[ $func ] = array( 'function' => $func );

$true = false;

// put a breakpoint here and try to inspect $functions
var_dump( $functions );


echo " Done.";

XML Output:

<?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="23" context="0"><property name="$filter_id_count" fullname="$filter_id_count" address="4487012088" type="int"><![CDATA[0]]></property><property name="$function" fullname="$function" address="4487003760" type="array" children="1" numchildren="2" page="0" pagesize="1000"><property name="0" fullname="$function[0]" address="4487011760" type="object" classname="DBG_Test_Class" children="0" numchildren="0" page="0" pagesize="1000"></property><property name="1" fullname="$function[1]" address="4487003624" type="string" size="17" encoding="base64"><![CDATA[X3JlZ2lzdGVyX3dpZGdldHM=]]></property></property><property name="$obj_idx" fullname="$obj_idx" type="uninitialized"></property><property name="$priority" fullname="$priority" address="4487003808" type="int"><![CDATA[100]]></property><property name="$tag" fullname="$tag" address="4487025592" type="string" size="12" encoding="base64"><![CDATA[d2lkZ2V0c19pbml0]]></property><property name="$wp_filter" fullname="$wp_filter" address="4487015384" type="array" children="1" numchildren="1" page="0" pagesize="1000"><property name="widgets_init" fullname="$wp_filter[&#39;widgets_init&#39;]" address="4487027928" type="array" children="1" numchildren="1" page="0" pagesize="1000"><property name="10" fullname="$wp_filter[&#39;widgets_init&#39;][10]" address="4487027976" type="array" children="1" numchildren="3" page="0" pagesize="1000"><property name="&#0;lambda_1" fullname="$wp_filter[&#39;widgets_init&#39;][10][&#39;&#0;lambda_1&#39;]" address="4487025544" type="array" children="1" numchildren="2"></property><property name="&#0;lambda_2" fullname="$wp_filter[&#39;widgets_init&#39;][10][&#39;&#0;lambda_2&#39;]" address="4487002104" type="array" children="1" numchildren="2"></property><property name="some_fake_init_action" fullname="$wp_filter[&#39;widgets_init&#39;][10][&#39;some_fake_init_action&#39;]" address="4487002752" type="array" children="1" numchildren="2"></property></property></property></property></response>

I know it seems contrived, but if you try to register a filter or action hook in WordPress that's been generated with create_function() WP uses the string generated by create_function() as an array key, which makes the invalid XML, and therefore makes the XML parser choke.

@martomo

This comment has been minimized.

Copy link
Owner

commented May 4, 2014

I'm not sure how I could provide an solution here, seeing the XML parser is native in Python.
As for Xdebug providing the XML, I guess we have to wait until for the actual implementation of extended_properties.

What I could suggest is to check for a newer version of Wordpress if this isn't the latest, which might use anonymous functions as suggested on the create_function manual page.

Otherwise you could change the current Wordpress by using addslashes, to ensure the string is properly escaped.

@jbeales

This comment has been minimized.

Copy link
Author

commented May 5, 2014

WordPress is the latest. The create_function() call is actually coming from a plugin, but WP's use of the string it generates as an array key is what causes the problem.

The only thing that you could do would be to remove the offending character from the XML string before feeding it to the parser, (I think that NetBeans may be doing that, from something I was when Googling this), but that may open a whole new can of worms.

I'll also open a ticket with WordPress to see if there's interest in filtering the string before it gets used as an array key, and if there is I'll contribute a patch.

@martomo martomo added the bug label May 11, 2014

@jbeales

This comment has been minimized.

Copy link
Author

commented May 11, 2014

WordPress isn't going to create a workaround, (and they shouldn't - this is in a part of code that's used a lot, any bit they add will be called hundreds of times per page load, making this a performance issue).

I've solved my immediate issue by submitting a patch to the plugin that used create_function(), so I don't use create_function() anymore.

At least, because of this thread, if anyone else runs into the problem they'll see how to work around it.

@martomo martomo closed this in 4324974 May 11, 2014

@jbeales

This comment has been minimized.

Copy link
Author

commented May 11, 2014

Thanks!

@brannou

This comment has been minimized.

Copy link

commented Sep 9, 2015

I have the exact same problem with wordpress when I try to use xdebug client. I don't know if it's a dumb suggestion but would it be possible to filter the xml output sent by xdebug before it's shown in client panels ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.