Skip to content

Commit

Permalink
Fix JSON reports with long UTF8 strings (#5300)
Browse files Browse the repository at this point in the history
* Fix JSON reports with long UTF8 strings

* CS fix

* UTF8-safe snippets
  • Loading branch information
danog authored Mar 1, 2021
1 parent ad8c04c commit 404db2b
Show file tree
Hide file tree
Showing 4 changed files with 24 additions and 12 deletions.
12 changes: 6 additions & 6 deletions src/Psalm/CodeLocation.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@
use function strlen;
use function strpos;
use function strrpos;
use function substr;
use function substr_count;
use function mb_strcut;
use function trim;

class CodeLocation
Expand Down Expand Up @@ -183,7 +183,7 @@ private function calculateRealLocation(): void
) {
$preview_lines = explode(
"\n",
substr(
mb_strcut(
$file_contents,
$this->preview_start,
$this->selection_start - $this->preview_start - 1
Expand All @@ -206,7 +206,7 @@ private function calculateRealLocation(): void

$indentation = (int)strpos($key_line, '@');

$key_line = trim(preg_replace('@\**/\s*@', '', substr($key_line, $indentation)));
$key_line = trim(preg_replace('@\**/\s*@', '', mb_strcut($key_line, $indentation)));

$this->selection_start = $preview_offset + $indentation + $this->preview_start;
$this->selection_end = $this->selection_start + strlen($key_line);
Expand Down Expand Up @@ -258,7 +258,7 @@ private function calculateRealLocation(): void
throw new \UnexpectedValueException('Unrecognised regex type ' . $this->regex_type);
}

$preview_snippet = substr(
$preview_snippet = mb_strcut(
$file_contents,
$this->selection_start,
$this->selection_end - $this->selection_start
Expand Down Expand Up @@ -298,8 +298,8 @@ private function calculateRealLocation(): void
}
}

$this->snippet = substr($file_contents, $this->preview_start, $this->preview_end - $this->preview_start);
$this->text = substr($file_contents, $this->selection_start, $this->selection_end - $this->selection_start);
$this->snippet = mb_strcut($file_contents, $this->preview_start, $this->preview_end - $this->preview_start);
$this->text = mb_strcut($file_contents, $this->selection_start, $this->selection_end - $this->selection_start);

// reset preview start to beginning of line
$this->column_from = $this->selection_start -
Expand Down
4 changes: 3 additions & 1 deletion src/Psalm/Internal/Json/Json.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
use RuntimeException;

use function json_encode;
use function json_last_error_msg;
use const JSON_PRETTY_PRINT;
use const JSON_UNESCAPED_SLASHES;
use const JSON_UNESCAPED_UNICODE;
Expand Down Expand Up @@ -34,7 +35,8 @@ public static function encode($data, ?int $options = null): string

$result = json_encode($data, $options);
if ($result === false) {
throw new RuntimeException('Cannot create JSON string.');
/** @psalm-suppress ImpureFunctionCall */
throw new RuntimeException('Cannot create JSON string: '.json_last_error_msg());
}

return $result;
Expand Down
8 changes: 4 additions & 4 deletions src/Psalm/Type/Atomic/TLiteralString.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
namespace Psalm\Type\Atomic;

use function preg_replace;
use function strlen;
use function substr;
use function mb_strlen;
use function mb_substr;

/**
* Denotes a string whose value is known.
Expand Down Expand Up @@ -31,8 +31,8 @@ public function __toString(): string
public function getId(bool $nested = false): string
{
$no_newline_value = preg_replace("/\n/m", '\n', $this->value);
if (strlen($this->value) > 80) {
return '"' . substr($no_newline_value, 0, 80) . '...' . '"';
if (mb_strlen($this->value) > 80) {
return '"' . mb_substr($no_newline_value, 0, 80) . '...' . '"';
}

return '"' . $no_newline_value . '"';
Expand Down
12 changes: 11 additions & 1 deletion tests/TypeParseTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@

use function function_exists;
use function print_r;
use function mb_substr;
use function stripos;

use Psalm\Internal\RuntimeCaches;
use Psalm\Type;
use function stripos;

class TypeParseTest extends TestCase
{
Expand Down Expand Up @@ -860,6 +861,15 @@ public function testEnumWithoutSpaces(): void
$this->assertSame($resolved_type->getId(), $docblock_type->getId());
}

public function testLongUtf8LiteralString(): void
{
$string = "АаБбВвГгДдЕеЁёЖжЗзИиЙйКкЛлМмНнОоПпРрСсТтУуФфХхЦцЧчШшЩщЪъЫыЬьЭэЮюЯя";
$string .= $string;
$expected = mb_substr($string, 0, 80);
$this->assertSame("\"$expected...\"", Type:: parseString("'$string'")->getId());
$this->assertSame("\"$expected...\"", Type:: parseString("\"$string\"")->getId());
}

public function testSingleLiteralString(): void
{
$this->assertSame(
Expand Down

0 comments on commit 404db2b

Please sign in to comment.