jenkins-bot has submitted this change and it was merged. Change subject: Added validation to QueryEntityDeserializer ......................................................................
Added validation to QueryEntityDeserializer Change-Id: I169aab35421eff5278bfdc826b39eb6ce6e62ed0 --- M Tests/Phpunit/Wikibase/Query/QueryEntityDeserializerTest.php M src/Wikibase/Query/QueryEntityDeserializer.php 2 files changed, 269 insertions(+), 16 deletions(-) Approvals: Denny Vrandecic: Looks good to me, approved jenkins-bot: Verified diff --git a/Tests/Phpunit/Wikibase/Query/QueryEntityDeserializerTest.php b/Tests/Phpunit/Wikibase/Query/QueryEntityDeserializerTest.php index 1044646..70662e1 100644 --- a/Tests/Phpunit/Wikibase/Query/QueryEntityDeserializerTest.php +++ b/Tests/Phpunit/Wikibase/Query/QueryEntityDeserializerTest.php @@ -251,4 +251,204 @@ ); } + /** + * @dataProvider invalidIdProvider + */ + public function testCannotDeserializeWithInvalidId( $invalidIdSerialization ) { + $serialization = $this->newQueryEntitySerialization(); + $serialization['entity'] = $invalidIdSerialization; + + $this->setExpectedException( 'Deserializers\Exceptions\DeserializationException' ); + $this->newQueryEntityDeserializer()->deserialize( $serialization ); + } + + public function invalidIdProvider() { + $argLists = array(); + + $argLists[] = array( + 'foo' + ); + + $argLists[] = array( + array() + ); + + $argLists[] = array( + array( 'item' ) + ); + + $argLists[] = array( + array( 'item', '42' ) + ); + + $argLists[] = array( + array( 42, 42 ) + ); + + $argLists[] = array( + array( 'item', 42, 'foo' ) + ); + + $argLists[] = array( + array( array(), false ) + ); + + return $argLists; + } + + /** + * @dataProvider invalidLabelsProvider + */ + public function testCannotDeserializeWithInvalidLabels( $invalidLabelsSerialization ) { + $serialization = $this->newQueryEntitySerialization(); + $serialization['label'] = $invalidLabelsSerialization; + + $this->setExpectedException( 'Deserializers\Exceptions\DeserializationException' ); + $this->newQueryEntityDeserializer()->deserialize( $serialization ); + } + + public function invalidLabelsProvider() { + $argLists = array(); + + $argLists[] = array( + 'foo' + ); + + $argLists[] = array( + array( array() ) + ); + + $argLists[] = array( + array( 'de' => array( 'foo' ) ) + ); + + $argLists[] = array( + 42 => 'foo' + ); + + $argLists[] = array( + 'en' => 'foo', + 'bar' + ); + + $argLists[] = array( + 'en' => 'foo', + 'de' => false + ); + + return $argLists; + } + + /** + * @dataProvider invalidLabelsProvider + */ + public function testCannotDeserializeWithInvalidDescriptions( $invalidDescriptionsSerialization ) { + $serialization = $this->newQueryEntitySerialization(); + $serialization['description'] = $invalidDescriptionsSerialization; + + $this->setExpectedException( 'Deserializers\Exceptions\DeserializationException' ); + $this->newQueryEntityDeserializer()->deserialize( $serialization ); + } + + /** + * @dataProvider invalidAliasesProvider + */ + public function testCannotDeserializeWithInvalidAliases( $invalidAliasesSerialization ) { + $serialization = $this->newQueryEntitySerialization(); + $serialization['aliases'] = $invalidAliasesSerialization; + + $this->setExpectedException( 'Deserializers\Exceptions\DeserializationException' ); + $this->newQueryEntityDeserializer()->deserialize( $serialization ); + } + + public function invalidAliasesProvider() { + $argLists = array(); + + $argLists[] = array( + 'foo' + ); + + $argLists[] = array( + array( array() ) + ); + + $argLists[] = array( + array( 'de' => 'foo' ) + ); + + $argLists[] = array( + array( 'foo' ) + ); + + $argLists[] = array( + 'en' => array( 'foo' ), + 'bar' + ); + + $argLists[] = array( + 'en' => array( 'foo' ), + 'de' => 'bar' + ); + + return $argLists; + } + + /** + * @dataProvider invalidClaimsProvider + */ + public function testCannotDeserializeWithInvalidClaims( $invalidClaimsSerialization ) { + $serialization = $this->newQueryEntitySerialization(); + $serialization['claim'] = $invalidClaimsSerialization; + + $this->setExpectedException( 'Deserializers\Exceptions\DeserializationException' ); + $this->newQueryEntityDeserializer()->deserialize( $serialization ); + } + + public function invalidClaimsProvider() { + $argLists = array(); + + $argLists[] = array( + 'foo' + ); + + $argLists[] = array( + null + ); + + $argLists[] = array( + array( + 'foo' + ) + ); + + $argLists[] = array( + array( + array( + 'm' => array( 'somevalue', 42 ), + 'q' => array(), + 'g' => null, + ), + 'foo' + ) + ); + +// $argLists[] = array( +// array( +// array( +// ), +// ) +// ); +// +// $argLists[] = array( +// array( +// array( +// 'q' => array(), +// 'g' => null, +// ), +// ) +// ); + + return $argLists; + } + } diff --git a/src/Wikibase/Query/QueryEntityDeserializer.php b/src/Wikibase/Query/QueryEntityDeserializer.php index 1a05fcc..56df911 100644 --- a/src/Wikibase/Query/QueryEntityDeserializer.php +++ b/src/Wikibase/Query/QueryEntityDeserializer.php @@ -4,6 +4,7 @@ use Deserializers\Deserializer; use Deserializers\Exceptions\DeserializationException; +use Deserializers\Exceptions\MissingAttributeException; use Wikibase\Claim; use Wikibase\EntityId; @@ -62,52 +63,104 @@ } protected function deserializeId() { - // TODO: verify key exists - // TODO: value validation $idSerialization = $this->serialization['entity']; + + if ( !is_array( $idSerialization ) || count( $idSerialization ) !== 2 + || !is_string( $idSerialization[0] ) || !is_int( $idSerialization[1] ) ) { + throw new DeserializationException( 'Invalid entity id provided' ); + } + $this->queryEntity->setId( new EntityId( $idSerialization[0], $idSerialization[1] ) ); } protected function deserializeLabels() { - // TODO: verify key exists - // TODO: value validation - foreach ( $this->serialization['label'] as $languageCode => $labelText ) { + $labels = $this->serialization['label']; + + if ( !is_array( $labels ) ) { + throw new DeserializationException( 'Invalid labels provided' ); + } + + foreach ( $labels as $languageCode => $labelText ) { + if ( !is_string( $languageCode ) || !is_string( $labelText ) ) { + throw new DeserializationException( 'Invalid labels provided' ); + } + $this->queryEntity->setLabel( $languageCode, $labelText ); } } protected function deserializeDescriptions() { - // TODO: verify key exists - // TODO: value validation + $descriptions = $this->serialization['description']; + + if ( !is_array( $descriptions ) ) { + throw new DeserializationException( 'Invalid descriptions provided' ); + } + foreach ( $this->serialization['description'] as $languageCode => $descriptionText ) { + if ( !is_string( $languageCode ) || !is_string( $descriptionText ) ) { + throw new DeserializationException( 'Invalid descriptions provided' ); + } + $this->queryEntity->setDescription( $languageCode, $descriptionText ); } } protected function deserializeAliases() { - // TODO: verify key exists - // TODO: value validation - foreach ( $this->serialization['aliases'] as $languageCode => $aliases ) { + $aliasLists = $this->serialization['aliases']; + + if ( !is_array( $aliasLists ) ) { + throw new DeserializationException( 'Invalid aliases provided' ); + } + + foreach ( $aliasLists as $languageCode => $aliases ) { + if ( !is_string( $languageCode ) || !is_array( $aliases ) ) { + // TODO: each alias should be a string + throw new DeserializationException( 'Invalid aliases provided' ); + } + $this->queryEntity->setAliases( $languageCode, $aliases ); } } protected function deserializeClaims() { - // TODO: verify key exists - // TODO: value validation - foreach ( $this->serialization['claim'] as $claimSerialization ) { - $this->queryEntity->addClaim( Claim::newFromArray( $claimSerialization ) ); + $claims = $this->serialization['claim']; + + if ( !is_array( $claims ) ) { + throw new DeserializationException( 'Invalid claims provided' ); + } + + foreach ( $claims as $claimSerialization ) { + if ( !is_array( $claimSerialization ) ) { + throw new DeserializationException( 'Invalid claims provided' ); + } + + $claim = Claim::newFromArray( $claimSerialization ); + $this->queryEntity->addClaim( $claim ); + + // TODO: try catch around Claim::newFromArray as soon as it actually throws exceptions } } public function canDeserialize( $serialization ) { - if( !is_array( $serialization ) || !array_key_exists( 'query', $serialization ) ) { + if( !is_array( $serialization ) ) { return false; + } + + foreach ( array( 'query', 'entity', 'label', 'description', 'aliases', 'claim' ) as $requiredKey ) { + if ( !array_key_exists( $requiredKey, $serialization ) ) { + return false; + } } return $this->queryDeserializer->canDeserialize( $serialization['query'] ); } - // TODO: finish implementation + protected function requireAttribute( $attributeName ) { + if ( !array_key_exists( $attributeName, $this->serialization ) ) { + throw new MissingAttributeException( + $attributeName + ); + } + } } -- To view, visit https://gerrit.wikimedia.org/r/80016 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: merged Gerrit-Change-Id: I169aab35421eff5278bfdc826b39eb6ce6e62ed0 Gerrit-PatchSet: 2 Gerrit-Project: mediawiki/extensions/WikibaseQuery Gerrit-Branch: master Gerrit-Owner: Jeroen De Dauw <jeroended...@gmail.com> Gerrit-Reviewer: Addshore <addshorew...@gmail.com> Gerrit-Reviewer: Aude <aude.w...@gmail.com> Gerrit-Reviewer: Denny Vrandecic <denny.vrande...@wikimedia.de> Gerrit-Reviewer: Jeroen De Dauw <jeroended...@gmail.com> Gerrit-Reviewer: Tobias Gritschacher <tobias.gritschac...@wikimedia.de> Gerrit-Reviewer: jenkins-bot _______________________________________________ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits