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

Malformed JSON output due to erroneous UTF-8 character splitting #11072

Closed
maximal opened this issue Aug 13, 2024 · 1 comment · Fixed by #11092
Closed

Malformed JSON output due to erroneous UTF-8 character splitting #11072

maximal opened this issue Aug 13, 2024 · 1 comment · Fixed by #11092
Labels

Comments

@maximal
Copy link
Contributor

maximal commented Aug 13, 2024

This code breaks JSON formatter entirely (and the overall output slightly):

<?php

$message = sprintf(
	// Note the erroneous `ы` instead of `s` -----------------↓
	"[%s][Some string with erroneous unicode specifier] %s = %ы",
	(new \DateTimeImmutable())->format("d.m.Y H:i:s.v"),
	'topic',
	'message'
);

echo $message, PHP_EOL;

JSON formatter exception:

$ ./vendor/bin/psalm --output-format=json

Target PHP version: 8.3 (inferred from composer.json).
Scanning files...
Analyzing files...

E
Uncaught RuntimeException: Cannot create JSON string: Malformed UTF-8 characters, possibly incorrectly encoded in /path/to/project/vendor/vimeo/psalm/src/Psalm/Internal/Json/Json.php:41
Stack trace:
#0 /path/to/project/vendor/vimeo/psalm/src/Psalm/Report/JsonReport.php(27): Psalm\Internal\Json\Json::encode(Array, 0)
#1 /path/to/project/vendor/vimeo/psalm/src/Psalm/IssueBuffer.php(945): Psalm\Report\JsonReport->create()
#2 /path/to/project/vendor/vimeo/psalm/src/Psalm/IssueBuffer.php(653): Psalm\IssueBuffer::getOutput(Array, Object(Psalm\Report\ReportOptions), Array)
#3 /path/to/project/vendor/vimeo/psalm/src/Psalm/Internal/Cli/Psalm.php(399): Psalm\IssueBuffer::finish(Object(Psalm\Internal\Analyzer\ProjectAnalyzer), true, 1723569466.044, false, Array)
#4 /path/to/project/vendor/vimeo/psalm/psalm(9): Psalm\Internal\Cli\Psalm::run(Array)
#5 /path/to/project/vendor/bin/psalm(119): include('/path/to/projec...')
#6 {main}
(Psalm 5.25.0@01a8eb06b9e9cc6cfb6a320bf9fb14331919d505 crashed due to an uncaught Throwable)

GitHub formatter works without exceptions, although Psalm erroneously calculates the character (cuts two bytes of UTF-8 encoded ы in half getting ):

$ ./vendor/bin/psalm --output-format=github

Target PHP version: 8.3 (inferred from composer.json).
Scanning files...
Analyzing files...


::error file=test.php,line=3,col=12,title=InvalidArgument::test.php:3:12: InvalidArgument: Argument 1 of sprintf is invalid - Unknown format specifier "�" (see https://psalm.dev/004)
------------------------------
1 errors found
------------------------------

Checks took 0.01 seconds and used 1.692MB of memory
No files analyzed
Psalm was able to infer types for 100% of the codebase

The web service at https://psalm.dev/ gives empty response for this code, because it cannot build the JSON output for it.

@maximal maximal changed the title Malformed JSON string due to erroneous UTF-8 character splitting Malformed JSON output due to erroneous UTF-8 character splitting Aug 13, 2024
@weirdan
Copy link
Collaborator

weirdan commented Sep 8, 2024

although Psalm erroneously calculates the character (cuts two bytes of UTF-8 encoded ы in half getting �):

Actually, that's kinda correct. sprintf() takes one byte after the % character (if we ignore width specification for the sake of simplicity) as a specifier.

Now of course this shouldn't break output formatters.

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

Successfully merging a pull request may close this issue.

2 participants