1
0
mirror of https://github.com/danog/psalm.git synced 2024-11-26 20:34:47 +01:00

Fix #1518 - add escaping of object-like keys

This commit is contained in:
Brown 2020-04-26 17:36:02 -04:00
parent ebcb0b8cc4
commit 5e2af1d7f6
4 changed files with 40 additions and 18 deletions

View File

@ -648,6 +648,10 @@ abstract class Type
);
}
if ($property_key[0] === '\'' || $property_key[0] === '"') {
$property_key = \stripslashes(substr($property_key, 1, -1));
}
if (!$property_type instanceof Union) {
$property_type = new Union([$property_type]);
}

View File

@ -75,13 +75,11 @@ class ObjectLike extends \Psalm\Type\Atomic
public function __toString()
{
$union_type_parts = array_map(
/**
* @param string|int $name
* @param Union $type
*
* @return string
*/
function ($name, Union $type) {
if (\is_string($name) && \preg_match('/[ "\'\\\\.\n]/', $name)) {
$name = '\'' . \str_replace("\n", '\n', \addslashes($name)) . '\'';
}
return $name . ($type->possibly_undefined ? '?' : '') . ': ' . $type;
},
array_keys($this->properties),
@ -95,13 +93,11 @@ class ObjectLike extends \Psalm\Type\Atomic
public function getId(bool $nested = false)
{
$union_type_parts = array_map(
/**
* @param string|int $name
* @param Union $type
*
* @return string
*/
function ($name, Union $type) {
if (\is_string($name) && \preg_match('/[ "\'\\\\.\n]/', $name)) {
$name = '\'' . \str_replace("\n", '\n', \addslashes($name)) . '\'';
}
return $name . ($type->possibly_undefined ? '?' : '') . ': ' . $type->getId();
},
array_keys($this->properties),
@ -143,12 +139,6 @@ class ObjectLike extends \Psalm\Type\Atomic
implode(
', ',
array_map(
/**
* @param string|int $name
* @param Union $type
*
* @return string
*/
function (
$name,
Union $type
@ -158,6 +148,10 @@ class ObjectLike extends \Psalm\Type\Atomic
$this_class,
$use_phpdoc_format
) {
if (\is_string($name) && \preg_match('/[ "\'\\\\.\n]/', $name)) {
$name = '\'' . \str_replace("\n", '\n', \addslashes($name)) . '\'';
}
return $name . ($type->possibly_undefined ? '?' : '') . ': ' . $type->toNamespacedString(
$namespace,
$aliased_classes,

View File

@ -1129,6 +1129,13 @@ class AnnotationTest extends TestCase
[],
'7.4'
],
'arrayWithKeySlashesAndNewline' => [
'<?php
$arr = ["foo\\bar\nbaz" => "literal"];',
[
'$arr' => 'array{\'foo\\\\bar\nbaz\': string}'
]
],
];
}

View File

@ -398,6 +398,23 @@ class TypeParseTest extends TestCase
$this->assertSame('array{a: int, b: string}', (string) Type:: parseString('array{a: int, b: string}'));
}
/**
* @return void
*/
public function testObjectLikeWithSpace()
{
$this->assertSame('array{\'a \': int, \'b \': string}', (string) Type:: parseString('array{\'a \': int, \'b \': string}'));
}
/**
* @return void
*/
public function testObjectLikeWithQuotedKeys()
{
$this->assertSame('array{\'\\"\': int, \'\\\'\': string}', (string) Type:: parseString('array{\'"\': int, \'\\\'\': string}'));
$this->assertSame('array{\'\\"\': int, \'\\\'\': string}', (string) Type:: parseString('array{"\\"": int, "\\\'": string}'));
}
/**
* @return void
*/