Skip to content

Commit

Permalink
Merge pull request #87 from localheinz/fix/object
Browse files Browse the repository at this point in the history
Fix: Do not attempt to fetch and modify properties of something that isn't an object
  • Loading branch information
localheinz authored Oct 9, 2018
2 parents c28f2e9 + b3c12a3 commit 3c81b21
Show file tree
Hide file tree
Showing 7 changed files with 70 additions and 5 deletions.
4 changes: 4 additions & 0 deletions phpstan.neon
Original file line number Diff line number Diff line change
@@ -1,2 +1,6 @@
includes:
- vendor/phpstan/phpstan-strict-rules/rules.neon

parameters:
ignoreErrors:
- '#Access to an undefined property object::\$bin.#'
5 changes: 4 additions & 1 deletion src/Normalizer/BinNormalizer.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,10 @@ public function normalize(string $json): string
));
}

if (!\property_exists($decoded, 'bin') || !\is_array($decoded->bin)) {
if (!\is_object($decoded)
|| !\property_exists($decoded, 'bin')
|| !\is_array($decoded->bin)
) {
return $json;
}

Expand Down
8 changes: 7 additions & 1 deletion src/Normalizer/ComposerJsonNormalizer.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,19 @@ public function __construct(string $schemaUri = 'https://getcomposer.org/schema.

public function normalize(string $json): string
{
if (null === \json_decode($json) && \JSON_ERROR_NONE !== \json_last_error()) {
$decoded = \json_decode($json);

if (null === $decoded && \JSON_ERROR_NONE !== \json_last_error()) {
throw new \InvalidArgumentException(\sprintf(
'"%s" is not valid JSON.',
$json
));
}

if (!\is_object($decoded)) {
return $json;
}

return $this->normalizer->normalize($json);
}
}
4 changes: 4 additions & 0 deletions src/Normalizer/ConfigHashNormalizer.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@ public function normalize(string $json): string
));
}

if (!\is_object($decoded)) {
return $json;
}

$objectProperties = \array_intersect_key(
\get_object_vars($decoded),
\array_flip(self::$properties)
Expand Down
4 changes: 4 additions & 0 deletions src/Normalizer/PackageHashNormalizer.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@ public function normalize(string $json): string
));
}

if (!\is_object($decoded)) {
return $json;
}

$objectProperties = \array_intersect_key(
\get_object_vars($decoded),
\array_flip(self::$properties)
Expand Down
4 changes: 4 additions & 0 deletions src/Normalizer/VersionConstraintNormalizer.php
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,10 @@ public function normalize(string $json): string
));
}

if (!\is_object($decoded)) {
return $json;
}

$objectProperties = \array_intersect_key(
\get_object_vars($decoded),
\array_flip(self::$properties)
Expand Down
46 changes: 43 additions & 3 deletions test/Unit/Normalizer/AbstractNormalizerTestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,7 @@ final public function testNormalizeRejectsInvalidJson(): void
{
$json = $this->faker()->realText();

$reflection = new \ReflectionClass($this->className());

$normalizer = $reflection->newInstanceWithoutConstructor();
$normalizer = $this->createNormalizer();

$this->expectException(\InvalidArgumentException::class);
$this->expectExceptionMessage(\sprintf(
Expand All @@ -46,6 +44,41 @@ final public function testNormalizeRejectsInvalidJson(): void
$normalizer->normalize($json);
}

/**
* @dataProvider providerJsonNotDecodingToObject
*
* @param string $json
*/
final public function testNormalizeDoesNotModifyWhenJsonDecodedIsNotAnObject(string $json): void
{
$normalizer = $this->createNormalizer();

$normalized = $normalizer->normalize($json);

$this->assertSame($json, $normalized);
}

public function providerJsonNotDecodingToObject(): \Generator
{
$faker = $this->faker();

$values = [
'array' => $faker->words,
'bool-false' => false,
'bool-true' => true,
'float' => $faker->randomFloat(),
'int' => $faker->randomNumber(),
'null' => null,
'string' => $faker->sentence,
];

foreach ($values as $key => $value) {
yield $key => [
\json_encode($value),
];
}
}

final protected function className(): string
{
return \preg_replace(
Expand All @@ -58,4 +91,11 @@ final protected function className(): string
)
);
}

private function createNormalizer(): Normalizer\NormalizerInterface
{
$reflection = new \ReflectionClass($this->className());

return $reflection->newInstanceWithoutConstructor();
}
}

0 comments on commit 3c81b21

Please sign in to comment.