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

5.22 crash on scan: Uncaught RuntimeException: PHP Error: Uninitialized string offset 0 #10707

Closed
aszenz opened this issue Feb 15, 2024 · 7 comments · Fixed by #10713
Closed

Comments

@aszenz
Copy link
Contributor

aszenz commented Feb 15, 2024

Uncaught RuntimeException: PHP Error: Uninitialized string offset 0 in /home/runner/work/app/vendor/vimeo/psalm/src/Psalm/Internal/Type/TypeTokenizer.php:380 for command with CLI args "/home/runner/work/app/vendor/bin/psalm --output-format=github --no-cache" in /home/runner/work/app/vendor/vimeo/psalm/src/Psalm/Internal/ErrorHandler.php:75
Stack trace:
#0 /home/runner/work/app/vendor/vimeo/psalm/src/Psalm/Internal/Type/TypeTokenizer.php(380): Psalm\Internal\ErrorHandler::Psalm\Internal\{closure}()
#1 /home/runner/work/app/vendor/vimeo/psalm/src/Psalm/Internal/PhpVisitor/Reflector/ClassLikeNodeScanner.php(1964): Psalm\Internal\Type\TypeTokenizer::getFullyQualifiedTokens()
#2 /home/runner/work/app/vendor/vimeo/psalm/src/Psalm/Internal/PhpVisitor/Reflector/ClassLikeNodeScanner.php(1894): Psalm\Internal\PhpVisitor\Reflector\ClassLikeNodeScanner::getTypeAliasesFromCommentLines()
#3 /home/runner/work/app/vendor/vimeo/psalm/src/Psalm/Internal/PhpVisitor/Reflector/ClassLikeNodeScanner.php(386): Psalm\Internal\PhpVisitor\Reflector\ClassLikeNodeScanner::getTypeAliasesFromComment()
#4 /home/runner/work/app/vendor/vimeo/psalm/src/Psalm/Internal/PhpVisitor/ReflectorVisitor.php(155): Psalm\Internal\PhpVisitor\Reflector\ClassLikeNodeScanner->start()
#5 /home/runner/work/app/vendor/nikic/php-parser/lib/PhpParser/NodeTraverser.php(200): Psalm\Internal\PhpVisitor\ReflectorVisitor->enterNode()
#6 /home/runner/work/app/vendor/nikic/php-parser/lib/PhpParser/NodeTraverser.php(114): PhpParser\NodeTraverser->traverseArray()
#7 /home/runner/work/app/vendor/nikic/php-parser/lib/PhpParser/NodeTraverser.php(223): PhpParser\NodeTraverser->traverseNode()
#8 /home/runner/work/app/vendor/nikic/php-parser/lib/PhpParser/NodeTraverser.php(91): PhpParser\NodeTraverser->traverseArray()
#9 /home/runner/work/app/vendor/vimeo/psalm/src/Psalm/Internal/Scanner/FileScanner.php(79): PhpParser\NodeTraverser->traverse()
#10 /home/runner/work/app/vendor/vimeo/psalm/src/Psalm/Internal/Codebase/Scanner.php(554): Psalm\Internal\Scanner\FileScanner->scan()
#11 /home/runner/work/app/vendor/vimeo/psalm/src/Psalm/Internal/Codebase/Scanner.php(782): Psalm\Internal\Codebase\Scanner->scanFile()
#12 /home/runner/work/app/vendor/vimeo/psalm/src/Psalm/Internal/Codebase/Scanner.php(428): Psalm\Internal\Codebase\Scanner->scanAPath()
#13 /home/runner/work/app/vendor/vimeo/psalm/src/Psalm/Internal/Codebase/Scanner.php(280): Psalm\Internal\Codebase\Scanner->scanFilePaths()
#14 /home/runner/work/app/vendor/vimeo/psalm/src/Psalm/Config.php(2576): Psalm\Internal\Codebase\Scanner->scanFiles()
#15 /home/runner/work/app/vendor/vimeo/psalm/src/Psalm/Internal/Analyzer/ProjectAnalyzer.php(372): Psalm\Config->visitComposerAutoloadFiles()
#16 /home/runner/work/app/vendor/vimeo/psalm/src/Psalm/Internal/Analyzer/ProjectAnalyzer.php(502): Psalm\Internal\Analyzer\ProjectAnalyzer->visitAutoloadFiles()
#17 /home/runner/work/app/vendor/vimeo/psalm/src/Psalm/Internal/Cli/Psalm.php(374): Psalm\Internal\Analyzer\ProjectAnalyzer->check()
#18 /home/runner/work/app/vendor/vimeo/psalm/psalm(9): Psalm\Internal\Cli\Psalm::run()
#19 /home/runner/work/app/vendor/bin/psalm(119): include('...')
#20 {main}
(Psalm 5.22.0@fe2c67ec89f358940f90db05efd2d663388b45a6 crashed due to an uncaught Throwable)
@aszenz
Copy link
Contributor Author

aszenz commented Feb 15, 2024

Was working fine on 5.21

@weirdan
Copy link
Collaborator

weirdan commented Feb 15, 2024

We would need to see the docblock it crashes on. You can try locating it by running psalm --debug --debug-by-line - it would be the class-level docblock in the file pointed to by the last few lines of debug output before the crash.

@aszenz
Copy link
Contributor Author

aszenz commented Feb 15, 2024

This is the doc block of the last class it is trying to scan vendor/composer/composer/src/Composer/Package/PackageInterface:

/**
 * Defines the essential information a package has that is used during solving/installation
 *
 * PackageInterface & derivatives are considered internal, you may use them in type hints but extending/implementing them is not recommended and not supported. Things may change without notice.
 *
 * @author Jordi Boggiano <j.boggiano@seld.be>
 *
 * @phpstan-type AutoloadRules    array{psr-0?: array<string, string|string[]>, psr-4?: array<string, string|string[]>, classmap?: list<string>, files?: list<string>, exclude-from-classmap?: list<string>}
 * @phpstan-type DevAutoloadRules array{psr-0?: array<string, string|string[]>, psr-4?: array<string, string|string[]>, classmap?: list<string>, files?: list<string>}
 */

Here's the last few lines of the output using the debug flag :

Using reflection to get metadata for mysqli
Using composer to locate file for Doctrine\DBAL\Driver\PgSQL\Statement
Using composer to locate file for Doctrine\DBAL\Driver\PgSQL\Result
Using reflection to get metadata for SQLite3
Using composer to locate file for Doctrine\DBAL\Driver\SQLite3\Statement
Using composer to locate file for Doctrine\DBAL\Driver\SQLite3\Result
Using composer to locate file for Doctrine\DBAL\Query\Limit
Using composer to locate file for Doctrine\DBAL\Query\ForUpdate
Using composer to locate file for PHPUnit\Metadata\Api\Groups
Using composer to locate file for Symfony\Component\DependencyInjection\Exception\RuntimeException
Using composer to locate file for Symfony\Component\DependencyInjection\Exception\InvalidArgumentException
Parsing /home/user/Desktop/app/vendor/composer/composer/src/Composer/Package/PackageInterface.php
Scanning /home/user/Desktop/app/vendor/composer/composer/src/Composer/Package/PackageInterface.php
Uncaught RuntimeException: PHP Error: Uninitialized string offset 0 in /home/user/Desktop/app/vendor/vimeo/psalm/src/Psalm/Internal/Type/TypeTokenizer.php:380 for command with CLI args "/home/user/Desktop/app/vendor/bin/psalm --debug --debug-by-line" in /home/user/Desktop/app/vendor/vimeo/psalm/src/Psalm/Internal/ErrorHandler.php:75
Stack trace:
#0 /home/user/Desktop/app/vendor/vimeo/psalm/src/Psalm/Internal/Type/TypeTokenizer.php(380): Psalm\Internal\ErrorHandler::Psalm\Internal\{closure}(2, 'Uninitialized s...', '/home/user/Des...', 380)
#1 /home/user/Desktop/app/vendor/vimeo/psalm/src/Psalm/Internal/PhpVisitor/Reflector/ClassLikeNodeScanner.php(1964): Psalm\Internal\Type\TypeTokenizer::getFullyQualifiedTokens('', Object(Psalm\Aliases), NULL, Array, 'Composer\\Packag...')
#2 /home/user/Desktop/app/vendor/vimeo/psalm/src/Psalm/Internal/PhpVisitor/Reflector/ClassLikeNodeScanner.php(1894): Psalm\Internal\PhpVisitor\Reflector\ClassLikeNodeScanner::getTypeAliasesFromCommentLines(Array, Object(Psalm\Aliases), Array, 'Composer\\Packag...')
#3 /home/user/Desktop/app/vendor/vimeo/psalm/src/Psalm/Internal/PhpVisitor/Reflector/ClassLikeNodeScanner.php(386): Psalm\Internal\PhpVisitor\Reflector\ClassLikeNodeScanner::getTypeAliasesFromComment(Object(PhpParser\Comment\Doc), Object(Psalm\Aliases), Array, 'Composer\\Packag...')
#4 /home/user/Desktop/app/vendor/vimeo/psalm/src/Psalm/Internal/PhpVisitor/ReflectorVisitor.php(155): Psalm\Internal\PhpVisitor\Reflector\ClassLikeNodeScanner->start(Object(PhpParser\Node\Stmt\Interface_))
#5 /home/user/Desktop/app/vendor/nikic/php-parser/lib/PhpParser/NodeTraverser.php(200): Psalm\Internal\PhpVisitor\ReflectorVisitor->enterNode(Object(PhpParser\Node\Stmt\Interface_))
#6 /home/user/Desktop/app/vendor/nikic/php-parser/lib/PhpParser/NodeTraverser.php(114): PhpParser\NodeTraverser->traverseArray(Array)
#7 /home/user/Desktop/app/vendor/nikic/php-parser/lib/PhpParser/NodeTraverser.php(223): PhpParser\
NodeTraverser->traverseNode(Object(PhpParser\Node\Stmt\Namespace_))
#8 /home/user/Desktop/app/vendor/nikic/php-parser/lib/PhpParser/NodeTraverser.php(91): PhpParser\NodeTraverser->traverseArray(Array)
#9 /home/user/Desktop/app/vendor/vimeo/psalm/src/Psalm/Internal/Scanner/FileScanner.php(79): PhpParser\NodeTraverser->traverse(Array)
#10 /home/user/Desktop/app/vendor/vimeo/psalm/src/Psalm/Internal/Codebase/Scanner.php(554): Psalm\Internal\Scanner\FileScanner->scan(Object(Psalm\Codebase), Object(Psalm\Storage\FileStorage), false, Object(Psalm\Progress\DebugProgress))
#11 /home/user/Desktop/app/vendor/vimeo/psalm/src/Psalm/Internal/Codebase/Scanner.php(782): Psalm\Internal\Codebase\Scanner->scanFile('/home/user/Des...', Array, false)
#12 /home/user/Desktop/app/vendor/vimeo/psalm/src/Psalm/Internal/Codebase/Scanner.php(428): Psalm\Internal\Codebase\Scanner->scanAPath(263, '/home/user/Des...')
#13 /home/user/Desktop/app/vendor/vimeo/psalm/src/Psalm/Internal/Codebase/Scanner.php(280): Psalm\Internal\Codebase\Scanner->scanFilePaths(1)
#14 /home/user/Desktop/app/vendor/vimeo/psalm/src/Psalm/Config.php(2576): Psalm\Internal\Codebase\Scanner->scanFiles(Object(Psalm\Internal\Codebase\ClassLikes))
#15 /home/user/Desktop/app/vendor/vimeo/psalm/src/Psalm/Internal/Analyzer/ProjectAnalyzer.php(372): Psalm\Config->visitComposerAutoloadFiles(Object(Psalm\Internal\Analyzer\ProjectAnalyzer), Object(Psalm\Progress\DebugProgress))
#16 /home/user/Desktop/app/vendor/vimeo/psalm/src/Psalm/Internal/Analyzer/ProjectAnalyzer.php(502): Psalm\Internal\Analyzer\ProjectAnalyzer->visitAutoloadFiles()
#17 /home/user/Desktop/app/vendor/vimeo/psalm/src/Psalm/Internal/Cli/Psalm.php(374): Psalm\Internal\Analyzer\ProjectAnalyzer->check('/home/user/Des...', true)
#18 /home/user/Desktop/app/vendor/vimeo/psalm/psalm(9): Psalm\Internal\Cli\Psalm::run(Array)
#19 /home/user/Desktop/app/vendor/bin/psalm(119): include('/home/user/Des...')
#20 {main}
(Psalm 5.22.0@fe2c67ec89f358940f90db05efd2d663388b45a6 crashed due to an uncaught Throwable)

@weirdan
Copy link
Collaborator

weirdan commented Feb 15, 2024

Reproduced, seems to depend on the number of spaces between the type name and type definition.

Crashes: https://psalm.dev/r/a6494c8bae
Works: https://psalm.dev/r/902d894ce5

Copy link

I found these snippets:

https://psalm.dev/r/a6494c8bae
<?php
/**
 * @phpstan-type _T   int
 */
interface I {}
Psalm encountered an internal error:

/vendor/vimeo/psalm/src/Psalm/Type.php: $class cannot be empty
https://psalm.dev/r/902d894ce5
<?php
/**
 * @phpstan-type _T  int
 */
interface I {}
Psalm output (using commit 639bed0):

No issues!

@weirdan
Copy link
Collaborator

weirdan commented Feb 15, 2024

The first snippet additionally outputs:

Warning: Uninitialized string offset 0 in /var/www/vhosts/psalm.dev/httpdocs/vendor/vimeo/psalm/src/Psalm/Internal/Type/TypeTokenizer.php on line 362

Warning: Uninitialized string offset 0 in /var/www/vhosts/psalm.dev/httpdocs/vendor/vimeo/psalm/src/Psalm/Internal/Type/TypeTokenizer.php on line 368

Warning: Uninitialized string offset 0 in /var/www/vhosts/psalm.dev/httpdocs/vendor/vimeo/psalm/src/Psalm/Internal/Type/TypeTokenizer.php on line 369

Warning: Uninitialized string offset 0 in /var/www/vhosts/psalm.dev/httpdocs/vendor/vimeo/psalm/src/Psalm/Internal/Type/TypeTokenizer.php on line 370

Warning: Uninitialized string offset 0 in /var/www/vhosts/psalm.dev/httpdocs/vendor/vimeo/psalm/src/Psalm/Internal/Type/TypeTokenizer.php on line 375

Warning: Uninitialized string offset 0 in /var/www/vhosts/psalm.dev/httpdocs/vendor/vimeo/psalm/src/Psalm/Internal/Type/TypeTokenizer.php on line 443

Warning: Uninitialized string offset 0 in /var/www/vhosts/psalm.dev/httpdocs/vendor/vimeo/psalm/src/Psalm/Internal/Type/TypeTokenizer.php on line 443

@weirdan
Copy link
Collaborator

weirdan commented Feb 15, 2024

Fixed in #10711

@weirdan weirdan closed this as completed Feb 15, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants