mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-07-09 11:31:49 +00:00
event: harden APIs that accept arrays
plugin devs can't be relied on to pass the proper types to these APIs, and when the wrong types get passed it makes type errors appear from inside the internals.
This commit is contained in:
parent
8ce0022de6
commit
a34f3261cb
@ -26,6 +26,7 @@ namespace pocketmine\event\block;
|
|||||||
use pocketmine\block\Block;
|
use pocketmine\block\Block;
|
||||||
use pocketmine\event\Cancellable;
|
use pocketmine\event\Cancellable;
|
||||||
use pocketmine\Player;
|
use pocketmine\Player;
|
||||||
|
use pocketmine\utils\Utils;
|
||||||
use function count;
|
use function count;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -79,6 +80,7 @@ class SignChangeEvent extends BlockEvent implements Cancellable{
|
|||||||
if(count($lines) !== 4){
|
if(count($lines) !== 4){
|
||||||
throw new \InvalidArgumentException("Array size must be 4!");
|
throw new \InvalidArgumentException("Array size must be 4!");
|
||||||
}
|
}
|
||||||
|
Utils::validateArrayValueType($lines, function(string $_) : void{});
|
||||||
$this->lines = $lines;
|
$this->lines = $lines;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,6 +25,7 @@ namespace pocketmine\event\entity;
|
|||||||
|
|
||||||
use pocketmine\entity\Living;
|
use pocketmine\entity\Living;
|
||||||
use pocketmine\item\Item;
|
use pocketmine\item\Item;
|
||||||
|
use pocketmine\utils\Utils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @phpstan-extends EntityEvent<Living>
|
* @phpstan-extends EntityEvent<Living>
|
||||||
@ -62,6 +63,7 @@ class EntityDeathEvent extends EntityEvent{
|
|||||||
* @param Item[] $drops
|
* @param Item[] $drops
|
||||||
*/
|
*/
|
||||||
public function setDrops(array $drops) : void{
|
public function setDrops(array $drops) : void{
|
||||||
|
Utils::validateArrayValueType($drops, function(Item $_) : void{});
|
||||||
$this->drops = $drops;
|
$this->drops = $drops;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,6 +27,7 @@ use pocketmine\block\Block;
|
|||||||
use pocketmine\entity\Entity;
|
use pocketmine\entity\Entity;
|
||||||
use pocketmine\event\Cancellable;
|
use pocketmine\event\Cancellable;
|
||||||
use pocketmine\level\Position;
|
use pocketmine\level\Position;
|
||||||
|
use pocketmine\utils\Utils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called when a entity explodes
|
* Called when a entity explodes
|
||||||
@ -67,6 +68,7 @@ class EntityExplodeEvent extends EntityEvent implements Cancellable{
|
|||||||
* @param Block[] $blocks
|
* @param Block[] $blocks
|
||||||
*/
|
*/
|
||||||
public function setBlockList(array $blocks) : void{
|
public function setBlockList(array $blocks) : void{
|
||||||
|
Utils::validateArrayValueType($blocks, function(Block $_) : void{});
|
||||||
$this->blocks = $blocks;
|
$this->blocks = $blocks;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,6 +28,8 @@ use pocketmine\event\Cancellable;
|
|||||||
use pocketmine\permission\PermissionManager;
|
use pocketmine\permission\PermissionManager;
|
||||||
use pocketmine\Player;
|
use pocketmine\Player;
|
||||||
use pocketmine\Server;
|
use pocketmine\Server;
|
||||||
|
use pocketmine\utils\Utils;
|
||||||
|
use function array_values;
|
||||||
use function spl_object_id;
|
use function spl_object_id;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -97,6 +99,7 @@ class PlayerChatEvent extends PlayerEvent implements Cancellable{
|
|||||||
* @param CommandSender[] $recipients
|
* @param CommandSender[] $recipients
|
||||||
*/
|
*/
|
||||||
public function setRecipients(array $recipients) : void{
|
public function setRecipients(array $recipients) : void{
|
||||||
|
Utils::validateArrayValueType($recipients, function(CommandSender $_) : void{});
|
||||||
$this->recipients = $recipients;
|
$this->recipients = $recipients;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -27,6 +27,7 @@ use pocketmine\Player;
|
|||||||
use pocketmine\plugin\Plugin;
|
use pocketmine\plugin\Plugin;
|
||||||
use pocketmine\Server;
|
use pocketmine\Server;
|
||||||
use pocketmine\utils\Binary;
|
use pocketmine\utils\Binary;
|
||||||
|
use pocketmine\utils\Utils;
|
||||||
use function chr;
|
use function chr;
|
||||||
use function count;
|
use function count;
|
||||||
use function str_replace;
|
use function str_replace;
|
||||||
@ -145,6 +146,7 @@ class QueryRegenerateEvent extends ServerEvent{
|
|||||||
* @param Plugin[] $plugins
|
* @param Plugin[] $plugins
|
||||||
*/
|
*/
|
||||||
public function setPlugins(array $plugins) : void{
|
public function setPlugins(array $plugins) : void{
|
||||||
|
Utils::validateArrayValueType($plugins, function(Plugin $_) : void{});
|
||||||
$this->plugins = $plugins;
|
$this->plugins = $plugins;
|
||||||
$this->destroyCache();
|
$this->destroyCache();
|
||||||
}
|
}
|
||||||
@ -160,6 +162,7 @@ class QueryRegenerateEvent extends ServerEvent{
|
|||||||
* @param Player[] $players
|
* @param Player[] $players
|
||||||
*/
|
*/
|
||||||
public function setPlayerList(array $players) : void{
|
public function setPlayerList(array $players) : void{
|
||||||
|
Utils::validateArrayValueType($players, function(Player $_) : void{});
|
||||||
$this->players = $players;
|
$this->players = $players;
|
||||||
$this->destroyCache();
|
$this->destroyCache();
|
||||||
}
|
}
|
||||||
|
@ -685,6 +685,21 @@ class Utils{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @phpstan-template TMemberType
|
||||||
|
* @phpstan-param array<mixed, TMemberType> $array
|
||||||
|
* @phpstan-param \Closure(TMemberType) : void $validator
|
||||||
|
*/
|
||||||
|
public static function validateArrayValueType(array $array, \Closure $validator) : void{
|
||||||
|
foreach($array as $k => $v){
|
||||||
|
try{
|
||||||
|
$validator($v);
|
||||||
|
}catch(\TypeError $e){
|
||||||
|
throw new \TypeError("Incorrect type of element at \"$k\": " . $e->getMessage(), 0, $e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static function recursiveUnlink(string $dir) : void{
|
public static function recursiveUnlink(string $dir) : void{
|
||||||
if(is_dir($dir)){
|
if(is_dir($dir)){
|
||||||
$objects = scandir($dir, SCANDIR_SORT_NONE);
|
$objects = scandir($dir, SCANDIR_SORT_NONE);
|
||||||
|
@ -35,6 +35,11 @@ parameters:
|
|||||||
count: 1
|
count: 1
|
||||||
path: ../../../src/pocketmine/utils/Utils.php
|
path: ../../../src/pocketmine/utils/Utils.php
|
||||||
|
|
||||||
|
-
|
||||||
|
message: "#^Parameter \\#1 \\$ of closure expects TMemberType, TMemberType given\\.$#"
|
||||||
|
count: 1
|
||||||
|
path: ../../../src/pocketmine/utils/Utils.php
|
||||||
|
|
||||||
-
|
-
|
||||||
message: "#^Call to static method PHPUnit\\\\Framework\\\\Assert\\:\\:assertNotNull\\(\\) with int and string will always evaluate to true\\.$#"
|
message: "#^Call to static method PHPUnit\\\\Framework\\\\Assert\\:\\:assertNotNull\\(\\) with int and string will always evaluate to true\\.$#"
|
||||||
count: 1
|
count: 1
|
||||||
|
Loading…
x
Reference in New Issue
Block a user