Make MapCacheLRU throw errors for bad $field arguments
authorAaron Schulz <aschulz@wikimedia.org>
Thu, 19 Jul 2018 09:50:28 +0000 (10:50 +0100)
committerAaron Schulz <aschulz@wikimedia.org>
Tue, 14 Aug 2018 00:41:33 +0000 (00:41 +0000)
Change-Id: Ibde33e0ff671d3428b73c66766478f58763726e1

includes/libs/MapCacheLRU.php
tests/phpunit/includes/libs/MapCacheLRUTest.php

index ad5e58d..a0381de 100644 (file)
@@ -141,7 +141,7 @@ class MapCacheLRU implements IExpiringStore, Serializable {
        public function has( $key, $maxAge = 0.0 ) {
                if ( !is_int( $key ) && !is_string( $key ) ) {
                        throw new UnexpectedValueException(
-                               __METHOD__ . ' called with invalid key. Must be string or integer.' );
+                               __METHOD__ . ': invalid key; must be string or integer.' );
                }
 
                if ( !array_key_exists( $key, $this->cache ) ) {
@@ -183,6 +183,11 @@ class MapCacheLRU implements IExpiringStore, Serializable {
                        $this->set( $key, [], $initRank );
                }
 
+               if ( !is_int( $field ) && !is_string( $field ) ) {
+                       throw new UnexpectedValueException(
+                               __METHOD__ . ": invalid field for '$key'; must be string or integer." );
+               }
+
                if ( !is_array( $this->cache[$key] ) ) {
                        throw new UnexpectedValueException( "The value of '$key' is not an array." );
                }
@@ -199,6 +204,12 @@ class MapCacheLRU implements IExpiringStore, Serializable {
         */
        public function hasField( $key, $field, $maxAge = 0.0 ) {
                $value = $this->get( $key );
+
+               if ( !is_int( $field ) && !is_string( $field ) ) {
+                       throw new UnexpectedValueException(
+                               __METHOD__ . ": invalid field for '$key'; must be string or integer." );
+               }
+
                if ( !is_array( $value ) || !array_key_exists( $field, $value ) ) {
                        return false;
                }
index a06ef62..7147c6f 100644 (file)
@@ -214,4 +214,54 @@ class MapCacheLRUTest extends PHPUnit\Framework\TestCase {
                $this->assertEquals( 1983, $cache->getField( 'MPs', 'Edwina Currie' ) );
                $this->assertEquals( 1970, $cache->getField( 'MPs', 'Neil Kinnock' ) );
        }
+
+       /**
+        * @covers MapCacheLRU::has()
+        * @covers MapCacheLRU::get()
+        * @covers MapCacheLRU::set()
+        * @covers MapCacheLRU::hasField()
+        * @covers MapCacheLRU::getField()
+        * @covers MapCacheLRU::setField()
+        */
+       public function testInvalidKeys() {
+               $cache = MapCacheLRU::newFromArray( [], 3 );
+
+               try {
+                       $cache->has( 3.4 );
+                       $this->fail( "No exception" );
+               } catch ( UnexpectedValueException $e ) {
+                       $this->assertRegExp( '/must be string or integer/', $e->getMessage() );
+               }
+               try {
+                       $cache->get( false );
+                       $this->fail( "No exception" );
+               } catch ( UnexpectedValueException $e ) {
+                       $this->assertRegExp( '/must be string or integer/', $e->getMessage() );
+               }
+               try {
+                       $cache->set( 3.4, 'x' );
+                       $this->fail( "No exception" );
+               } catch ( UnexpectedValueException $e ) {
+                       $this->assertRegExp( '/must be string or integer/', $e->getMessage() );
+               }
+
+               try {
+                       $cache->hasField( 'x', 3.4 );
+                       $this->fail( "No exception" );
+               } catch ( UnexpectedValueException $e ) {
+                       $this->assertRegExp( '/must be string or integer/', $e->getMessage() );
+               }
+               try {
+                       $cache->getField( 'x', false );
+                       $this->fail( "No exception" );
+               } catch ( UnexpectedValueException $e ) {
+                       $this->assertRegExp( '/must be string or integer/', $e->getMessage() );
+               }
+               try {
+                       $cache->setField( 'x', 3.4, 'x' );
+                       $this->fail( "No exception" );
+               } catch ( UnexpectedValueException $e ) {
+                       $this->assertRegExp( '/must be string or integer/', $e->getMessage() );
+               }
+       }
 }