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.
This commit is contained in:
Dylan K. Taylor 2020-04-01 21:30:25 +01:00
parent e45e84b236
commit ec949840b2
2 changed files with 12 additions and 2 deletions

View File

@ -33,6 +33,7 @@ use pocketmine\nbt\tag\ByteArrayTag;
use pocketmine\nbt\tag\CompoundTag; use pocketmine\nbt\tag\CompoundTag;
use pocketmine\nbt\tag\IntArrayTag; use pocketmine\nbt\tag\IntArrayTag;
use pocketmine\nbt\tag\ListTag; use pocketmine\nbt\tag\ListTag;
use function zlib_decode;
class Anvil extends McRegion{ class Anvil extends McRegion{
@ -96,8 +97,12 @@ class Anvil extends McRegion{
} }
protected function nbtDeserialize(string $data) : Chunk{ protected function nbtDeserialize(string $data) : Chunk{
$data = @zlib_decode($data);
if($data === false){
throw new CorruptedChunkException("Failed to decompress chunk data");
}
$nbt = new BigEndianNBTStream(); $nbt = new BigEndianNBTStream();
$chunk = $nbt->readCompressed($data); $chunk = $nbt->read($data);
if(!($chunk instanceof CompoundTag) or !$chunk->hasTag("Level")){ if(!($chunk instanceof CompoundTag) or !$chunk->hasTag("Level")){
throw new CorruptedChunkException("'Level' key is missing from chunk NBT"); throw new CorruptedChunkException("'Level' key is missing from chunk NBT");
} }

View File

@ -58,6 +58,7 @@ use function strrpos;
use function substr; use function substr;
use function time; use function time;
use function unpack; use function unpack;
use function zlib_decode;
use const SCANDIR_SORT_NONE; use const SCANDIR_SORT_NONE;
class McRegion extends BaseLevelProvider{ class McRegion extends BaseLevelProvider{
@ -125,8 +126,12 @@ class McRegion extends BaseLevelProvider{
* @throws CorruptedChunkException * @throws CorruptedChunkException
*/ */
protected function nbtDeserialize(string $data) : Chunk{ protected function nbtDeserialize(string $data) : Chunk{
$data = @zlib_decode($data);
if($data === false){
throw new CorruptedChunkException("Failed to decompress chunk data");
}
$nbt = new BigEndianNBTStream(); $nbt = new BigEndianNBTStream();
$chunk = $nbt->readCompressed($data); $chunk = $nbt->read($data);
if(!($chunk instanceof CompoundTag) or !$chunk->hasTag("Level")){ if(!($chunk instanceof CompoundTag) or !$chunk->hasTag("Level")){
throw new CorruptedChunkException("'Level' key is missing from chunk NBT"); throw new CorruptedChunkException("'Level' key is missing from chunk NBT");
} }