Skip to content

Commit

Permalink
Merge pull request #558 from erayd/backport-528
Browse files Browse the repository at this point in the history
Backports for 5.2.8
  • Loading branch information
bighappyface authored Jan 14, 2019
2 parents 8560d43 + 86dfb04 commit dcb6e10
Show file tree
Hide file tree
Showing 10 changed files with 119 additions and 85 deletions.
3 changes: 0 additions & 3 deletions .php_cs.dist
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,9 @@ $config
'@PSR2' => true,
'@Symfony' => true,
// additionally
'align_multiline_comment' => array('comment_type' => 'phpdocs_like'),
'array_syntax' => array('syntax' => 'long'),
'binary_operator_spaces' => false,
'concat_space' => array('spacing' => 'one'),
'increment_style' => false,
'no_useless_else' => true,
'no_useless_return' => true,
'ordered_imports' => true,
Expand All @@ -25,7 +23,6 @@ $config
'pre_increment' => false,
'simplified_null_return' => false,
'trailing_comma_in_multiline_array' => false,
'yoda_style' => null,
))
->setFinder($finder)
;
Expand Down
1 change: 1 addition & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ matrix:
dist: trusty
allow_failures:
- php: 'nightly'
- php: hhvm

before_install:
- if [[ "$WITH_COVERAGE" != "true" && "$TRAVIS_PHP_VERSION" != "hhvm" && "$TRAVIS_PHP_VERSION" != "nightly" && "$TRAVIS_PHP_VERSION" != "7.1" ]]; then phpenv config-rm xdebug.ini; fi
Expand Down
2 changes: 1 addition & 1 deletion bin/validate-json
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ function parseHeaderValue($headerValue)
/**
* Send a string to the output stream, but only if --quiet is not enabled
*
* @param $str A string output
* @param $str string A string output
*/
function output($str) {
global $arOptions;
Expand Down
65 changes: 38 additions & 27 deletions composer.json
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
{
"name": "justinrainbow/json-schema",
"type": "library",
"description": "A library to validate a json schema.",
"keywords": ["json", "schema"],
"keywords": [
"json",
"schema"
],
"homepage": "https://github.com/justinrainbow/json-schema",
"type": "library",
"license": "MIT",
"authors": [
{
Expand All @@ -23,43 +26,51 @@
"email": "[email protected]"
}
],
"repositories": [{
"type": "package",
"package": {
"name": "json-schema/JSON-Schema-Test-Suite",
"version": "1.2.0",
"source": {
"url": "https://github.com/json-schema/JSON-Schema-Test-Suite",
"type": "git",
"reference": "1.2.0"
}
}
}],
"require": {
"php": ">=5.3.3"
},
"require-dev": {
"friendsofphp/php-cs-fixer": "~2.2.20",
"json-schema/JSON-Schema-Test-Suite": "1.2.0",
"friendsofphp/php-cs-fixer": "^2.1",
"phpunit/phpunit": "^4.8.35"
},
"autoload": {
"psr-4": { "JsonSchema\\": "src/JsonSchema/" }
},
"autoload-dev": {
"psr-4": { "JsonSchema\\Tests\\": "tests/" }
},
"bin": ["bin/validate-json"],
"extra": {
"branch-alias": {
"dev-master": "5.0.x-dev"
}
},
"autoload": {
"psr-4": {
"JsonSchema\\": "src/JsonSchema/"
}
},
"autoload-dev": {
"psr-4": {
"JsonSchema\\Tests\\": "tests/"
}
},
"repositories": [
{
"type": "package",
"package": {
"name": "json-schema/JSON-Schema-Test-Suite",
"version": "1.2.0",
"source": {
"type": "git",
"url": "https://github.com/json-schema/JSON-Schema-Test-Suite",
"reference": "1.2.0"
}
}
}
],
"bin": [
"bin/validate-json"
],
"scripts": {
"test" : "phpunit",
"testOnly" : "phpunit --colors --filter",
"coverage" : "phpunit --coverage-text",
"style-check" : "php-cs-fixer fix --dry-run --verbose --diff",
"style-fix" : "php-cs-fixer fix --verbose"
"coverage": "phpunit --coverage-text",
"style-check": "php-cs-fixer fix --dry-run --verbose --diff",
"style-fix": "php-cs-fixer fix --verbose",
"test": "phpunit",
"testOnly": "phpunit --colors --filter"
}
}
56 changes: 15 additions & 41 deletions src/JsonSchema/Constraints/CollectionConstraint.php
Original file line number Diff line number Diff line change
Expand Up @@ -65,53 +65,27 @@ protected function validateItems(&$value, $schema = null, JsonPointer $path = nu
{
if (is_object($schema->items)) {
// just one type definition for the whole array
foreach ($value as $k => &$v) {
$initErrors = $this->getErrors();

if (isset($schema->items->type)
&& (
$schema->items->type == 'string'
|| $schema->items->type == 'number'
|| $schema->items->type == 'integer'
)
&& !isset($schema->additionalItems)
) {
// performance optimization
$type = $schema->items->type;
$typeValidator = $this->factory->createInstanceFor('type');
$validator = $this->factory->createInstanceFor($type === 'integer' ? 'number' : $type);

foreach ($value as $k => &$v) {
$k_path = $this->incrementPath($path, $k);
$typeValidator->check($v, $schema->items, $k_path, $i);
// First check if its defined in "items"
$this->checkUndefined($v, $schema->items, $path, $k);

$validator->check($v, $schema->items, $k_path, $i);
// Recheck with "additionalItems" if the first test fails
if (count($initErrors) < count($this->getErrors()) && (isset($schema->additionalItems) && $schema->additionalItems !== false)) {
$secondErrors = $this->getErrors();
$this->checkUndefined($v, $schema->additionalItems, $path, $k);
}
unset($v); /* remove dangling reference to prevent any future bugs
* caused by accidentally using $v elsewhere */
$this->addErrors($typeValidator->getErrors());
$this->addErrors($validator->getErrors());
} else {
foreach ($value as $k => &$v) {
$initErrors = $this->getErrors();

// First check if its defined in "items"
$this->checkUndefined($v, $schema->items, $path, $k);

// Recheck with "additionalItems" if the first test fails
if (count($initErrors) < count($this->getErrors()) && (isset($schema->additionalItems) && $schema->additionalItems !== false)) {
$secondErrors = $this->getErrors();
$this->checkUndefined($v, $schema->additionalItems, $path, $k);
}

// Reset errors if needed
if (isset($secondErrors) && count($secondErrors) < count($this->getErrors())) {
$this->errors = $secondErrors;
} elseif (isset($secondErrors) && count($secondErrors) === count($this->getErrors())) {
$this->errors = $initErrors;
}
// Reset errors if needed
if (isset($secondErrors) && count($secondErrors) < count($this->getErrors())) {
$this->errors = $secondErrors;
} elseif (isset($secondErrors) && count($secondErrors) === count($this->getErrors())) {
$this->errors = $initErrors;
}
unset($v); /* remove dangling reference to prevent any future bugs
* caused by accidentally using $v elsewhere */
}
unset($v); /* remove dangling reference to prevent any future bugs
* caused by accidentally using $v elsewhere */
} else {
// Defined item type definitions
foreach ($value as $k => &$v) {
Expand Down
13 changes: 4 additions & 9 deletions src/JsonSchema/Constraints/NumberConstraint.php
Original file line number Diff line number Diff line change
Expand Up @@ -69,18 +69,13 @@ public function check(&$element, $schema = null, JsonPointer $path = null, $i =

private function fmod($number1, $number2)
{
$number1 = abs($number1);
$modulus = fmod($number1, $number2);
$precision = abs(0.0000000001);
$diff = (float) ($modulus - $number2);
$modulus = ($number1 - round($number1 / $number2) * $number2);
$precision = 0.0000000001;

if (-$precision < $diff && $diff < $precision) {
if (-$precision < $modulus && $modulus < $precision) {
return 0.0;
}

$decimals1 = mb_strpos($number1, '.') ? mb_strlen($number1) - mb_strpos($number1, '.') - 1 : 0;
$decimals2 = mb_strpos($number2, '.') ? mb_strlen($number2) - mb_strpos($number2, '.') - 1 : 0;

return (float) round($modulus, max($decimals1, $decimals2));
return $modulus;
}
}
4 changes: 4 additions & 0 deletions src/JsonSchema/Constraints/TypeCheck/StrictTypeCheck.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ public static function propertyExists($value, $property)

public static function propertyCount($value)
{
if (!is_object($value)) {
return 0;
}

return count(get_object_vars($value));
}
}
25 changes: 22 additions & 3 deletions src/JsonSchema/Uri/UriRetriever.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,14 @@ class UriRetriever implements BaseUriRetrieverInterface
'|^https?://json-schema.org/draft-(0[34])/schema#?|' => 'package://dist/schema/json-schema-draft-$1.json'
);

/**
* @var array A list of endpoints for media type check exclusion
*/
protected $allowedInvalidContentTypeEndpoints = array(
'http://json-schema.org/',
'https://json-schema.org/'
);

/**
* @var null|UriRetrieverInterface
*/
Expand All @@ -44,6 +52,16 @@ class UriRetriever implements BaseUriRetrieverInterface
*/
private $schemaCache = array();

/**
* Adds an endpoint to the media type validation exclusion list
*
* @param string $endpoint
*/
public function addInvalidContentTypeEndpoint($endpoint)
{
$this->allowedInvalidContentTypeEndpoints[] = $endpoint;
}

/**
* Guarantee the correct media type was encountered
*
Expand All @@ -65,9 +83,10 @@ public function confirmMediaType($uriRetriever, $uri)
return;
}

if (substr($uri, 0, 23) == 'http://json-schema.org/') {
//HACK; they deliver broken content types
return true;
foreach ($this->allowedInvalidContentTypeEndpoints as $endpoint) {
if (strpos($uri, $endpoint) === 0) {
return true;
}
}

throw new InvalidSchemaMediaTypeException(sprintf('Media type %s expected', Validator::SCHEMA_MEDIA_TYPE));
Expand Down
10 changes: 10 additions & 0 deletions tests/Constraints/MinMaxPropertiesTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,16 @@ public function getInvalidTests()
}
}'
),
array(
'{
"value": []
}',
'{
"properties": {
"value": {"minProperties": 1,"maxProperties": 2}
}
}'
),
);
}
}
25 changes: 24 additions & 1 deletion tests/Uri/UriRetrieverTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -330,13 +330,36 @@ public function testRetrieveSchemaFromPackage()
$this->assertEquals('454f423bd7edddf0bc77af4130ed9161', md5(json_encode($schema)));
}

public function testJsonSchemaOrgMediaTypeHack()
public function testInvalidContentTypeEndpointsDefault()
{
$mock = $this->getMock('JsonSchema\Uri\UriRetriever', array('getContentType'));
$mock->method('getContentType')->willReturn('Application/X-Fake-Type');
$retriever = new UriRetriever();

$this->assertTrue($retriever->confirmMediaType($mock, 'http://json-schema.org/'));
$this->assertTrue($retriever->confirmMediaType($mock, 'https://json-schema.org/'));
}

/**
* @expectedException \JsonSchema\Exception\InvalidSchemaMediaTypeException
*/
public function testInvalidContentTypeEndpointsUnknown()
{
$mock = $this->getMock('JsonSchema\Uri\UriRetriever', array('getContentType'));
$mock->method('getContentType')->willReturn('Application/X-Fake-Type');
$retriever = new UriRetriever();

$retriever->confirmMediaType($mock, 'http://example.com');
}

public function testInvalidContentTypeEndpointsAdded()
{
$mock = $this->getMock('JsonSchema\Uri\UriRetriever', array('getContentType'));
$mock->method('getContentType')->willReturn('Application/X-Fake-Type');
$retriever = new UriRetriever();
$retriever->addInvalidContentTypeEndpoint('http://example.com');

$retriever->confirmMediaType($mock, 'http://example.com');
}

public function testSchemaCache()
Expand Down

0 comments on commit dcb6e10

Please sign in to comment.