From ec949840b275a249d68cbb3ee5247997e75aa0fe Mon Sep 17 00:00:00 2001 From: "Dylan K. Taylor" Date: Wed, 1 Apr 2020 21:30:25 +0100 Subject: [PATCH] Do not crash on failure to decompress region chunks this could happen when a chunk was partially overwritten with one of the same sector size. --- src/pocketmine/level/format/io/region/Anvil.php | 7 ++++++- src/pocketmine/level/format/io/region/McRegion.php | 7 ++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/pocketmine/level/format/io/region/Anvil.php b/src/pocketmine/level/format/io/region/Anvil.php index d602fd8a2..6464269cf 100644 --- a/src/pocketmine/level/format/io/region/Anvil.php +++ b/src/pocketmine/level/format/io/region/Anvil.php @@ -33,6 +33,7 @@ use pocketmine\nbt\tag\ByteArrayTag; use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\IntArrayTag; use pocketmine\nbt\tag\ListTag; +use function zlib_decode; class Anvil extends McRegion{ @@ -96,8 +97,12 @@ class Anvil extends McRegion{ } protected function nbtDeserialize(string $data) : Chunk{ + $data = @zlib_decode($data); + if($data === false){ + throw new CorruptedChunkException("Failed to decompress chunk data"); + } $nbt = new BigEndianNBTStream(); - $chunk = $nbt->readCompressed($data); + $chunk = $nbt->read($data); if(!($chunk instanceof CompoundTag) or !$chunk->hasTag("Level")){ throw new CorruptedChunkException("'Level' key is missing from chunk NBT"); } diff --git a/src/pocketmine/level/format/io/region/McRegion.php b/src/pocketmine/level/format/io/region/McRegion.php index 3516fc598..946ee5170 100644 --- a/src/pocketmine/level/format/io/region/McRegion.php +++ b/src/pocketmine/level/format/io/region/McRegion.php @@ -58,6 +58,7 @@ use function strrpos; use function substr; use function time; use function unpack; +use function zlib_decode; use const SCANDIR_SORT_NONE; class McRegion extends BaseLevelProvider{ @@ -125,8 +126,12 @@ class McRegion extends BaseLevelProvider{ * @throws CorruptedChunkException */ protected function nbtDeserialize(string $data) : Chunk{ + $data = @zlib_decode($data); + if($data === false){ + throw new CorruptedChunkException("Failed to decompress chunk data"); + } $nbt = new BigEndianNBTStream(); - $chunk = $nbt->readCompressed($data); + $chunk = $nbt->read($data); if(!($chunk instanceof CompoundTag) or !$chunk->hasTag("Level")){ throw new CorruptedChunkException("'Level' key is missing from chunk NBT"); }