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

Uncaught TypeError: Argument 1 passed to PhpParser\NodeTraverser::traverseNode() must implement interface PhpParser\Node, string given #687

Closed
williamdes opened this issue Jul 19, 2020 · 12 comments

Comments

@williamdes
Copy link

williamdes commented Jul 19, 2020

Using Doctum I have this issue, I tried to switch to PHP 7.4 just in case but it does not solve the issue.
Doctum 5.0.1 uses "nikic/php-parser": "~4.5",
https://travis-ci.org/github/phpmyadmin/phpmyadmin/jobs/709689913#L350

PHP Fatal error:  Uncaught TypeError: Argument 1 passed to PhpParser\NodeTraverser::traverseNode() must implement interface PhpParser\Node, string given, called in /home/travis/.composer/vendor/nikic/php-parser/lib/PhpParser/NodeTraverser.php on line 223 and defined in /home/travis/.composer/vendor/nikic/php-parser/lib/PhpParser/NodeTraverser.php:109
Stack trace:
#0 /home/travis/.composer/vendor/nikic/php-parser/lib/PhpParser/NodeTraverser.php(223): PhpParser\NodeTraverser->traverseNode('object(PhpParse...')
#1 /home/travis/.composer/vendor/nikic/php-parser/lib/PhpParser/NodeTraverser.php(114): PhpParser\NodeTraverser->traverseArray(Array)
#2 /home/travis/.composer/vendor/nikic/php-parser/lib/PhpParser/NodeTraverser.php(223): PhpParser\NodeTraverser->traverseNode(Object(PhpParser\Node\Stmt\Class_))
#3 /home/travis/.composer/vendor/nikic/php-parser/lib/PhpParser/NodeTraverser.php(114): PhpParser\NodeTraverser->traverseArray(Array)
#4 /home/travis/.composer/vendor/nikic/php-parser/lib/PhpParser/NodeTraverser.php(223): PhpParser\ in /home/travis/.composer/vendor/nikic/php-parser/lib/PhpParser/NodeTraverser.php on line 109
Fatal error: Uncaught TypeError: Argument 1 passed to PhpParser\NodeTraverser::traverseNode() must implement interface PhpParser\Node, string given, called in /home/travis/.composer/vendor/nikic/php-parser/lib/PhpParser/NodeTraverser.php on line 223 and defined in /home/travis/.composer/vendor/nikic/php-parser/lib/PhpParser/NodeTraverser.php:109
Stack trace:
#0 /home/travis/.composer/vendor/nikic/php-parser/lib/PhpParser/NodeTraverser.php(223): PhpParser\NodeTraverser->traverseNode('object(PhpParse...')
#1 /home/travis/.composer/vendor/nikic/php-parser/lib/PhpParser/NodeTraverser.php(114): PhpParser\NodeTraverser->traverseArray(Array)
#2 /home/travis/.composer/vendor/nikic/php-parser/lib/PhpParser/NodeTraverser.php(223): PhpParser\NodeTraverser->traverseNode(Object(PhpParser\Node\Stmt\Class_))
#3 /home/travis/.composer/vendor/nikic/php-parser/lib/PhpParser/NodeTraverser.php(114): PhpParser\NodeTraverser->traverseArray(Array)
#4 /home/travis/.composer/vendor/nikic/php-parser/lib/PhpParser/NodeTraverser.php(223): PhpParser\ in /home/travis/.composer/vendor/nikic/php-parser/lib/PhpParser/NodeTraverser.php on line 109
@williamdes
Copy link
Author

williamdes commented Jul 19, 2020

@williamdes
Copy link
Author

Same at laravel/laravel.com#124

@nikic
Copy link
Owner

nikic commented Jul 20, 2020

Please provide a minimal reproduction.

@williamdes
Copy link
Author

williamdes commented Jul 21, 2020

@nikic I would like some help because for now I struggle reproducing this issue on any of my workstations and versions of PHP, with docker or not

Could you please help me ?

The php version does not seem to have something to do with this issue, TravisCI has the error. Using docker on the same Ubuntu version I could not reproduce it.

Here is another trace: https://user-images.githubusercontent.com/463230/87959570-ba609700-ca78-11ea-980a-481af7988ce6.png

@nikic
Copy link
Owner

nikic commented Jul 23, 2020

@williamdes Based on the trace, the best guess I have is that you have an enterNode() handler that returns a string somewhere.

@nikic
Copy link
Owner

nikic commented Jul 23, 2020

Maybe

private function ensureReplacementReasonable($old, $new) {
could be extended with more sanity checks, to catch this closer to the source (if it's indeed the issue).

@nikic
Copy link
Owner

nikic commented Jul 23, 2020

No, that's not it, returning a string from enterNode() would already throw. I don't really see how this can happen, as we check that $node instanceof Node and the replacement also only happens if $return instanceof Node, so by rights this method can only be called with $node being a Node.

Maybe this is a PHP bug?

@nikic
Copy link
Owner

nikic commented Jul 23, 2020

Do you have some instructions on how to run Doctum on an affected codebase (even if it does not reproduce for you)?

@williamdes
Copy link
Author

Do you have some instructions on how to run Doctum on an affected codebase (even if it does not reproduce for you)?

Yes, basically you can do is:

  • Clone an affected repo (git@github.com:phpmyadmin/phpmyadmin.git) branch: QA_5_0
  • Follow the script:
      install: curl -O https://doctum.long-term.support/releases/latest/doctum.phar
      script:
        - chmod +x ./doctum.phar
        - php ./doctum.phar --version
        - php ./doctum.phar --no-interaction update ./test/doctum-config.php

My PR should show you how to setup Doctum (phpmyadmin/phpmyadmin#16273)

I hope you will be able to reproduce this issue, anyway thanks a lot for the above comments. Let me know if you expect me to do something :)

@nikic
Copy link
Owner

nikic commented Jul 23, 2020

I've managed to track this down to this genius piece of code: https://github.com/phpDocumentor/ReflectionDocBlock/blob/1ac416df3f66c542f2d3688925105b539f064b64/src/DocBlock/Tags/InvalidTag.php#L78

NodeTraverser iterates over the array by-reference, the reference gets captured by the exception trace and that code ends up converting the node into a string :(

This needs to be fixed in phpDocumentor/ReflectionDocBlock, and I will also fix https://bugs.php.net/bug.php?id=79108 for PHP 8.0, to ensure this kind of interference is impossible in the future.

@nikic
Copy link
Owner

nikic commented Jul 25, 2020

I've fixed the issue on the PHP side for PHP 8, and reported phpDocumentor/ReflectionDocBlock#249 for ReflectionDocBlock. Closing here as the rest is outside the scope of PhpParser.

@nikic nikic closed this as completed Jul 25, 2020
@williamdes
Copy link
Author

Thank you so much!!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants