parser: Gracefully handle invalid ParsoidRenderID keys
Why: - ParsoidRenderID::newFromKey() validates incoming keys and throws an InvalidArgumentException if a required key component was missing. - It does so by eagerly destructuring the return value of explode(), which causes a PHP Notice for invalid inputs as the expected offsets won't exist then. What: - Check the count of key parts before destructuring. - Add unit tests. Bug: T385567 Change-Id: I1d936ae038f85ffa2e5d1d3d8a75fdc75e4c8ef8 (cherry picked from commit eec130925c081c2da1c475f9a9ce719e6838ca51)
This commit is contained in:
parent
e751026153
commit
b99dcc23bc
2 changed files with 36 additions and 2 deletions
|
|
@ -5,6 +5,7 @@ namespace MediaWiki\Edit;
|
|||
use InvalidArgumentException;
|
||||
use MediaWiki\Parser\ParserOutput;
|
||||
use Stringable;
|
||||
use function count;
|
||||
|
||||
/**
|
||||
* Represents the identity of a specific rendering of a specific revision
|
||||
|
|
@ -37,12 +38,14 @@ class ParsoidRenderID implements Stringable {
|
|||
*
|
||||
*/
|
||||
public static function newFromKey( string $key ): self {
|
||||
[ $revisionID, $uniqueID ] = explode( '/', $key, 2 );
|
||||
$parts = explode( '/', $key, 2 );
|
||||
|
||||
if ( $revisionID === null || $uniqueID === null ) {
|
||||
if ( count( $parts ) < 2 ) {
|
||||
throw new InvalidArgumentException( 'Bad key: ' . $key );
|
||||
}
|
||||
|
||||
[ $revisionID, $uniqueID ] = $parts;
|
||||
|
||||
return new self( (int)$revisionID, $uniqueID );
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
namespace MediaWiki\Tests\Unit\Edit;
|
||||
|
||||
use InvalidArgumentException;
|
||||
use MediaWiki\Edit\ParsoidRenderID;
|
||||
use MediaWikiUnitTestCase;
|
||||
|
||||
|
|
@ -68,4 +69,34 @@ class ParsoidRenderIdTest extends MediaWikiUnitTestCase {
|
|||
yield [ '"1/foo"XXX' ];
|
||||
yield [ 'XXX"1/foo"' ];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideNewFromKey
|
||||
* @covers \MediaWiki\Edit\ParsoidRenderID::newFromKey
|
||||
*/
|
||||
public function testNewFromKey( string $key, ParsoidRenderID $expected ): void {
|
||||
$actual = ParsoidRenderID::newFromKey( $key );
|
||||
$this->assertSame( $expected->getKey(), $actual->getKey() );
|
||||
}
|
||||
|
||||
public static function provideNewFromKey(): iterable {
|
||||
yield [ '1/abc', new ParsoidRenderID( 1, 'abc' ) ];
|
||||
yield [ '2/bar', new ParsoidRenderID( 2, 'bar' ) ];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider provideBadKeys
|
||||
* @covers \MediaWiki\Edit\ParsoidRenderID::newFromKey
|
||||
*/
|
||||
public function testBadNewFromKey( $key ): void {
|
||||
$this->expectException( InvalidArgumentException::class );
|
||||
$this->expectExceptionMessage( "Bad key: $key" );
|
||||
|
||||
ParsoidRenderID::newFromKey( $key );
|
||||
}
|
||||
|
||||
public static function provideBadKeys(): iterable {
|
||||
yield [ '' ];
|
||||
yield [ '1' ];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue