Fix path handling

This commit is contained in:
Paul Fulham 2020-11-21 21:19:38 -08:00
parent fe8c3d4e73
commit 6e131583dd
3 changed files with 67 additions and 65 deletions

View file

@ -91,10 +91,8 @@ public class ServerSchematicLoader {
}
public void handleNewUpload(ServerPlayerEntity player, String schematic, long size, BlockPos pos) {
String playerPath = getSchematicPath() + "/" + player.getName()
.getFormattedText();
String playerSchematicId = player.getName()
.getFormattedText() + "/" + schematic;
String playerPath = getSchematicPath() + "/" + player.getGameProfile().getName();
String playerSchematicId = player.getGameProfile().getName() + "/" + schematic;
FilesHelper.createFolderIfMissing(playerPath);
// Unsupported Format
@ -103,6 +101,14 @@ public class ServerSchematicLoader {
return;
}
Path schematicPath = Paths.get(getSchematicPath()).toAbsolutePath();
Path uploadPath = schematicPath.resolve(playerSchematicId).normalize();
if (!uploadPath.startsWith(schematicPath)) {
Create.logger.warn("Attempted Schematic Upload with directory escape: {}", playerSchematicId);
return;
}
// Too big
if (!validateSchematicSizeOnServer(player, size))
return;
@ -117,12 +123,13 @@ public class ServerSchematicLoader {
if (table == null)
return;
// Delete schematic with same name
Files.deleteIfExists(Paths.get(getSchematicPath(), playerSchematicId));
// Too many Schematics
Stream<Path> list = Files.list(Paths.get(playerPath));
if (list.count() >= getConfig().maxSchematics.get()) {
long count;
try (Stream<Path> list = Files.list(Paths.get(playerPath))) {
count = list.count();
}
if (count >= getConfig().maxSchematics.get()) {
Stream<Path> list2 = Files.list(Paths.get(playerPath));
Optional<Path> lastFilePath = list2.filter(f -> !Files.isDirectory(f))
.min(Comparator.comparingLong(f -> f.toFile()
@ -132,11 +139,9 @@ public class ServerSchematicLoader {
Files.deleteIfExists(lastFilePath.get());
}
}
list.close();
// Open Stream
OutputStream writer =
Files.newOutputStream(Paths.get(getSchematicPath(), playerSchematicId), StandardOpenOption.CREATE_NEW);
OutputStream writer = Files.newOutputStream(uploadPath);
activeUploads.put(playerSchematicId, new SchematicUploadEntry(writer, size, player.getServerWorld(), pos));
// Notify Tile Entity
@ -165,8 +170,7 @@ public class ServerSchematicLoader {
}
public void handleWriteRequest(ServerPlayerEntity player, String schematic, byte[] data) {
String playerSchematicId = player.getName()
.getFormattedText() + "/" + schematic;
String playerSchematicId = player.getGameProfile().getName() + "/" + schematic;
if (activeUploads.containsKey(playerSchematicId)) {
SchematicUploadEntry entry = activeUploads.get(playerSchematicId);
@ -236,8 +240,7 @@ public class ServerSchematicLoader {
}
public void handleFinishedUpload(ServerPlayerEntity player, String schematic) {
String playerSchematicId = player.getName()
.getFormattedText() + "/" + schematic;
String playerSchematicId = player.getGameProfile().getName() + "/" + schematic;
if (activeUploads.containsKey(playerSchematicId)) {
try {
@ -258,8 +261,7 @@ public class ServerSchematicLoader {
if (table == null)
return;
table.finishUpload();
table.inventory.setStackInSlot(1, SchematicItem.create(schematic, player.getName()
.getFormattedText()));
table.inventory.setStackInSlot(1, SchematicItem.create(schematic, player.getGameProfile().getName()));
} catch (IOException e) {
Create.logger.error("Exception Thrown when finishing Upload: " + playerSchematicId);
@ -270,15 +272,21 @@ public class ServerSchematicLoader {
public void handleInstantSchematic(ServerPlayerEntity player, String schematic, World world, BlockPos pos,
BlockPos bounds) {
String playerPath = getSchematicPath() + "/" + player.getName()
.getFormattedText();
String playerSchematicId = player.getName()
.getFormattedText() + "/" + schematic;
String playerPath = getSchematicPath() + "/" + player.getGameProfile().getName();
String playerSchematicId = player.getGameProfile().getName() + "/" + schematic;
FilesHelper.createFolderIfMissing(playerPath);
// Unsupported Format
if (!schematic.endsWith(".nbt")) {
Create.logger.warn("Attempted Schematic Upload with non-supported Format: " + playerSchematicId);
Create.logger.warn("Attempted Schematic Upload with non-supported Format: {}", playerSchematicId);
return;
}
Path schematicPath = Paths.get(getSchematicPath()).toAbsolutePath();
Path path = schematicPath.resolve(playerSchematicId).normalize();
if (!path.startsWith(schematicPath)) {
Create.logger.warn("Attempted Schematic Upload with directory escape: {}", playerSchematicId);
return;
}
@ -287,39 +295,32 @@ public class ServerSchematicLoader {
return;
try {
// Delete schematic with same name
Path path = Paths.get(getSchematicPath(), playerSchematicId);
Files.deleteIfExists(path);
// Too many Schematics
Stream<Path> list = Files.list(Paths.get(playerPath));
if (list.count() >= getConfig().maxSchematics.get()) {
long count;
try (Stream<Path> list = Files.list(Paths.get(playerPath))) {
count = list.count();
}
if (count >= getConfig().maxSchematics.get()) {
Stream<Path> list2 = Files.list(Paths.get(playerPath));
Optional<Path> lastFilePath = list2.filter(f -> !Files.isDirectory(f))
.min(Comparator.comparingLong(f -> f.toFile()
.lastModified()));
list2.close();
if (lastFilePath.isPresent())
if (lastFilePath.isPresent())
Files.deleteIfExists(lastFilePath.get());
}
list.close();
Template t = new Template();
t.takeBlocksFromWorld(world, pos, bounds, true, Blocks.AIR);
OutputStream outputStream = null;
try {
outputStream = Files.newOutputStream(path, StandardOpenOption.CREATE);
try (OutputStream outputStream = Files.newOutputStream(path)) {
CompoundNBT nbttagcompound = t.writeToNBT(new CompoundNBT());
CompressedStreamTools.writeCompressed(nbttagcompound, outputStream);
player.setHeldItem(Hand.MAIN_HAND, SchematicItem.create(schematic, player.getName()
.getFormattedText()));
player.setHeldItem(Hand.MAIN_HAND, SchematicItem.create(schematic, player.getGameProfile().getName()));
} catch (IOException e) {
e.printStackTrace();
} finally {
if (outputStream != null)
IOUtils.closeQuietly(outputStream);
}
} catch (IOException e) {
Create.logger.error("Exception Thrown in direct Schematic Upload: " + playerSchematicId);

View file

@ -3,13 +3,15 @@ package com.simibubi.create.content.schematics.item;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.util.List;
import javax.annotation.Nonnull;
import org.apache.commons.io.IOUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import com.simibubi.create.AllItems;
import com.simibubi.create.content.schematics.SchematicProcessor;
@ -46,6 +48,8 @@ import net.minecraftforge.fml.common.thread.SidedThreadGroups;
public class SchematicItem extends Item {
private static final Logger LOGGER = LogManager.getLogger();
public SchematicItem(Properties properties) {
super(properties.maxStackSize(1));
}
@ -106,25 +110,29 @@ public class SchematicItem extends Item {
String schematic = blueprint.getTag()
.getString("File");
String filepath = "";
if (!schematic.endsWith(".nbt"))
return t;
if (Thread.currentThread()
.getThreadGroup() == SidedThreadGroups.SERVER)
filepath = "schematics/uploaded/" + owner + "/" + schematic;
else
filepath = "schematics/" + schematic;
Path dir;
Path file;
InputStream stream = null;
try {
stream = Files.newInputStream(Paths.get(filepath), StandardOpenOption.READ);
if (Thread.currentThread().getThreadGroup() == SidedThreadGroups.SERVER) {
dir = Paths.get("schematics", "uploaded").toAbsolutePath();
file = Paths.get(owner, schematic);
} else {
dir = Paths.get("schematics").toAbsolutePath();
file = Paths.get(schematic);
}
Path path = dir.resolve(file).normalize();
if (!path.startsWith(dir))
return t;
try (InputStream stream = Files.newInputStream(path, StandardOpenOption.READ)) {
CompoundNBT nbt = CompressedStreamTools.readCompressed(stream);
t.read(nbt);
} catch (IOException e) {
// Player/Server doesnt have schematic saved
} finally {
if (stream != null)
IOUtils.closeQuietly(stream);
LOGGER.warn("Failed to read schematic", e);
}
return t;

View file

@ -21,17 +21,10 @@ import net.minecraft.nbt.CompoundNBT;
public class FilesHelper {
public static void createFolderIfMissing(String name) {
Path path = Paths.get(name);
if (path.getParent() != null)
createFolderIfMissing(path.getParent()
.toString());
if (!Files.isDirectory(path)) {
try {
Files.createDirectory(path);
} catch (IOException e) {
Create.logger.warn("Could not create Folder: " + name);
}
try {
Files.createDirectories(Paths.get(name));
} catch (IOException e) {
Create.logger.warn("Could not create Folder: {}", name);
}
}