diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 9bc4bc073..518a26c70 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -6,6 +6,12 @@ updates: interval: daily time: "10:00" open-pull-requests-limit: 10 + ignore: + #only allow patch updates for locale-data - this has to be updated manually due to codegen + - dependency-name: pocketmine/locale-data + update-types: + - "version-update:semver-major" + - "version-update:semver-minor" - package-ecosystem: gitsubmodule directory: "/" diff --git a/.github/workflows/discord-release-notify.yml b/.github/workflows/discord-release-notify.yml index a1ef20982..595b7374a 100644 --- a/.github/workflows/discord-release-notify.yml +++ b/.github/workflows/discord-release-notify.yml @@ -13,7 +13,7 @@ jobs: - uses: actions/checkout@v3 - name: Setup PHP and tools - uses: shivammathur/setup-php@2.22.0 + uses: shivammathur/setup-php@2.23.0 with: php-version: 8.0 diff --git a/.github/workflows/draft-release.yml b/.github/workflows/draft-release.yml index c8cc68bf7..f73bc5f28 100644 --- a/.github/workflows/draft-release.yml +++ b/.github/workflows/draft-release.yml @@ -18,7 +18,7 @@ jobs: submodules: true - name: Setup PHP - uses: shivammathur/setup-php@2.22.0 + uses: shivammathur/setup-php@2.23.0 with: php-version: 8.0 diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 653a56496..a24e3db20 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -195,7 +195,7 @@ jobs: - uses: actions/checkout@v3 - name: Setup PHP and tools - uses: shivammathur/setup-php@2.22.0 + uses: shivammathur/setup-php@2.23.0 with: php-version: 8.0 tools: php-cs-fixer:3.11 diff --git a/changelogs/4.12.md b/changelogs/4.12.md index 066a5ec0b..16e23dc6a 100644 --- a/changelogs/4.12.md +++ b/changelogs/4.12.md @@ -43,4 +43,10 @@ Released 28th December 2022. Released 3rd January 2023. ## Fixes -- Added workarounds for an active exploit being used to deny service to servers. \ No newline at end of file +- Added workarounds for an active exploit being used to deny service to servers. + +# 4.12.5 +Released 6th January 2023. + +## Fixes +- Removed a workaround for an old client bug in custom form responses. The code contained a denial-of-service vulnerability. diff --git a/composer.json b/composer.json index 90c838f18..68a22e7f1 100644 --- a/composer.json +++ b/composer.json @@ -54,7 +54,7 @@ "webmozart/path-util": "^2.3" }, "require-dev": { - "phpstan/phpstan": "1.9.4", + "phpstan/phpstan": "1.9.7", "phpstan/phpstan-phpunit": "^1.1.0", "phpstan/phpstan-strict-rules": "^1.2.0", "phpunit/phpunit": "^9.2" diff --git a/composer.lock b/composer.lock index fd1325531..a2f6c207e 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "393c7921d03d080d3ef3b836f90b4415", + "content-hash": "76c6b5521d8f88d9070e8dec1c0ae144", "packages": [ { "name": "adhocore/json-comment", @@ -1821,16 +1821,16 @@ }, { "name": "phpstan/phpstan", - "version": "1.9.4", + "version": "1.9.7", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan.git", - "reference": "d03bccee595e2146b7c9d174486b84f4dc61b0f2" + "reference": "0501435cd342eac7664bd62155b1ef907fc60b6f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/d03bccee595e2146b7c9d174486b84f4dc61b0f2", - "reference": "d03bccee595e2146b7c9d174486b84f4dc61b0f2", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/0501435cd342eac7664bd62155b1ef907fc60b6f", + "reference": "0501435cd342eac7664bd62155b1ef907fc60b6f", "shasum": "" }, "require": { @@ -1860,7 +1860,7 @@ ], "support": { "issues": "https://github.com/phpstan/phpstan/issues", - "source": "https://github.com/phpstan/phpstan/tree/1.9.4" + "source": "https://github.com/phpstan/phpstan/tree/1.9.7" }, "funding": [ { @@ -1876,7 +1876,7 @@ "type": "tidelift" } ], - "time": "2022-12-17T13:33:52+00:00" + "time": "2023-01-04T21:59:57+00:00" }, { "name": "phpstan/phpstan-phpunit", diff --git a/src/VersionInfo.php b/src/VersionInfo.php index 95668c9d2..384a63ae7 100644 --- a/src/VersionInfo.php +++ b/src/VersionInfo.php @@ -31,7 +31,7 @@ use function str_repeat; final class VersionInfo{ public const NAME = "PocketMine-MP"; - public const BASE_VERSION = "4.12.5"; + public const BASE_VERSION = "4.12.6"; public const IS_DEVELOPMENT_BUILD = true; public const BUILD_CHANNEL = "stable"; diff --git a/src/network/mcpe/handler/InGamePacketHandler.php b/src/network/mcpe/handler/InGamePacketHandler.php index 80a0f2015..8016b797b 100644 --- a/src/network/mcpe/handler/InGamePacketHandler.php +++ b/src/network/mcpe/handler/InGamePacketHandler.php @@ -115,7 +115,6 @@ use function array_push; use function base64_encode; use function count; use function fmod; -use function implode; use function in_array; use function is_bool; use function is_infinite; @@ -124,12 +123,9 @@ use function json_decode; use function max; use function mb_strlen; use function microtime; -use function preg_match; use function sprintf; use function strlen; use function strpos; -use function substr; -use function trim; use const JSON_THROW_ON_ERROR; /** @@ -890,60 +886,17 @@ class InGamePacketHandler extends PacketHandler{ //TODO: make APIs for this to allow plugins to use this information return $this->player->onFormSubmit($packet->formId, null); }elseif($packet->formData !== null){ - return $this->player->onFormSubmit($packet->formId, self::stupid_json_decode($packet->formData, true)); + try{ + $responseData = json_decode($packet->formData, true, self::MAX_FORM_RESPONSE_DEPTH, JSON_THROW_ON_ERROR); + }catch(\JsonException $e){ + throw PacketHandlingException::wrap($e, "Failed to decode form response data"); + } + return $this->player->onFormSubmit($packet->formId, $responseData); }else{ throw new PacketHandlingException("Expected either formData or cancelReason to be set in ModalFormResponsePacket"); } } - /** - * Hack to work around a stupid bug in Minecraft W10 which causes empty strings to be sent unquoted in form responses. - * - * @return mixed - * @throws PacketHandlingException - */ - private static function stupid_json_decode(string $json, bool $assoc = false){ - if(preg_match('/^\[(.+)\]$/s', $json, $matches) > 0){ - $raw = $matches[1]; - $lastComma = -1; - $newParts = []; - $inQuotes = false; - for($i = 0, $len = strlen($raw); $i <= $len; ++$i){ - if($i === $len || ($raw[$i] === "," && !$inQuotes)){ - $part = substr($raw, $lastComma + 1, $i - ($lastComma + 1)); - if(trim($part) === ""){ //regular parts will have quotes or something else that makes them non-empty - $part = '""'; - } - $newParts[] = $part; - $lastComma = $i; - }elseif($raw[$i] === '"'){ - if(!$inQuotes){ - $inQuotes = true; - }else{ - $backslashes = 0; - for(; $backslashes < $i && $raw[$i - $backslashes - 1] === "\\"; ++$backslashes){} - if(($backslashes % 2) === 0){ //unescaped quote - $inQuotes = false; - } - } - } - } - - $fixed = "[" . implode(",", $newParts) . "]"; - try{ - return json_decode($fixed, $assoc, self::MAX_FORM_RESPONSE_DEPTH, JSON_THROW_ON_ERROR); - }catch(\JsonException $e){ - throw PacketHandlingException::wrap($e, "Failed to fix JSON (original: $json, modified: $fixed)"); - } - } - - try{ - return json_decode($json, $assoc, self::MAX_FORM_RESPONSE_DEPTH, JSON_THROW_ON_ERROR); - }catch(\JsonException $e){ - throw PacketHandlingException::wrap($e); - } - } - public function handleServerSettingsRequest(ServerSettingsRequestPacket $packet) : bool{ return false; //TODO: GUI stuff } diff --git a/src/world/World.php b/src/world/World.php index 54fd7863b..09795fd2f 100644 --- a/src/world/World.php +++ b/src/world/World.php @@ -1321,7 +1321,9 @@ class World implements ChunkManager{ /** * Notify the blocks at and around the position that the block at the position may have changed. - * This will cause onNeighbourBlockUpdate() to be called for these blocks. + * This will cause onNearbyBlockChange() to be called for these blocks. + * + * @see Block::onNearbyBlockChange() */ public function notifyNeighbourBlockUpdate(Vector3 $pos) : void{ $this->tryAddToNeighbourUpdateQueue($pos); diff --git a/tests/phpunit/network/mcpe/handler/StupidJsonDecodeTest.php b/tests/phpunit/network/mcpe/handler/StupidJsonDecodeTest.php deleted file mode 100644 index 6a48bd1ba..000000000 --- a/tests/phpunit/network/mcpe/handler/StupidJsonDecodeTest.php +++ /dev/null @@ -1,68 +0,0 @@ -stupidJsonDecodeFunc = (new \ReflectionMethod(InGamePacketHandler::class, 'stupid_json_decode'))->getClosure(); - } - - /** - * @return mixed[][] - * @phpstan-return list - */ - public function stupidJsonDecodeProvider() : array{ - return [ - ["[\n \"a\",\"b,c,d,e\\\" \",,0,1,2, false, 0.001]", ['a', 'b,c,d,e" ', '', 0, 1, 2, false, 0.001]], - ["0", 0], - ["false", false], - ["null", null], - ['["\",,\"word","a\",,\"word2",]', ['",,"word', 'a",,"word2', '']], - ['["\",,\"word","a\",,\"word2",""]', ['",,"word', 'a",,"word2', '']], - ['["Hello,, PocketMine"]', ['Hello,, PocketMine']], - ['[,]', ['', '']], - ['[]', []] - ]; - } - - /** - * @dataProvider stupidJsonDecodeProvider - * - * @param mixed $expect - * - * @throws \ReflectionException - */ - public function testStupidJsonDecode(string $brokenJson, $expect) : void{ - $decoded = ($this->stupidJsonDecodeFunc)($brokenJson, true); - self::assertEquals($expect, $decoded); - } -}