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) { public void handleNewUpload(ServerPlayerEntity player, String schematic, long size, BlockPos pos) {
String playerPath = getSchematicPath() + "/" + player.getName() String playerPath = getSchematicPath() + "/" + player.getGameProfile().getName();
.getFormattedText(); String playerSchematicId = player.getGameProfile().getName() + "/" + schematic;
String playerSchematicId = player.getName()
.getFormattedText() + "/" + schematic;
FilesHelper.createFolderIfMissing(playerPath); FilesHelper.createFolderIfMissing(playerPath);
// Unsupported Format // Unsupported Format
@ -103,6 +101,14 @@ public class ServerSchematicLoader {
return; 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 // Too big
if (!validateSchematicSizeOnServer(player, size)) if (!validateSchematicSizeOnServer(player, size))
return; return;
@ -117,12 +123,13 @@ public class ServerSchematicLoader {
if (table == null) if (table == null)
return; return;
// Delete schematic with same name
Files.deleteIfExists(Paths.get(getSchematicPath(), playerSchematicId));
// Too many Schematics // Too many Schematics
Stream<Path> list = Files.list(Paths.get(playerPath)); long count;
if (list.count() >= getConfig().maxSchematics.get()) { 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)); Stream<Path> list2 = Files.list(Paths.get(playerPath));
Optional<Path> lastFilePath = list2.filter(f -> !Files.isDirectory(f)) Optional<Path> lastFilePath = list2.filter(f -> !Files.isDirectory(f))
.min(Comparator.comparingLong(f -> f.toFile() .min(Comparator.comparingLong(f -> f.toFile()
@ -132,11 +139,9 @@ public class ServerSchematicLoader {
Files.deleteIfExists(lastFilePath.get()); Files.deleteIfExists(lastFilePath.get());
} }
} }
list.close();
// Open Stream // Open Stream
OutputStream writer = OutputStream writer = Files.newOutputStream(uploadPath);
Files.newOutputStream(Paths.get(getSchematicPath(), playerSchematicId), StandardOpenOption.CREATE_NEW);
activeUploads.put(playerSchematicId, new SchematicUploadEntry(writer, size, player.getServerWorld(), pos)); activeUploads.put(playerSchematicId, new SchematicUploadEntry(writer, size, player.getServerWorld(), pos));
// Notify Tile Entity // Notify Tile Entity
@ -165,8 +170,7 @@ public class ServerSchematicLoader {
} }
public void handleWriteRequest(ServerPlayerEntity player, String schematic, byte[] data) { public void handleWriteRequest(ServerPlayerEntity player, String schematic, byte[] data) {
String playerSchematicId = player.getName() String playerSchematicId = player.getGameProfile().getName() + "/" + schematic;
.getFormattedText() + "/" + schematic;
if (activeUploads.containsKey(playerSchematicId)) { if (activeUploads.containsKey(playerSchematicId)) {
SchematicUploadEntry entry = activeUploads.get(playerSchematicId); SchematicUploadEntry entry = activeUploads.get(playerSchematicId);
@ -236,8 +240,7 @@ public class ServerSchematicLoader {
} }
public void handleFinishedUpload(ServerPlayerEntity player, String schematic) { public void handleFinishedUpload(ServerPlayerEntity player, String schematic) {
String playerSchematicId = player.getName() String playerSchematicId = player.getGameProfile().getName() + "/" + schematic;
.getFormattedText() + "/" + schematic;
if (activeUploads.containsKey(playerSchematicId)) { if (activeUploads.containsKey(playerSchematicId)) {
try { try {
@ -258,8 +261,7 @@ public class ServerSchematicLoader {
if (table == null) if (table == null)
return; return;
table.finishUpload(); table.finishUpload();
table.inventory.setStackInSlot(1, SchematicItem.create(schematic, player.getName() table.inventory.setStackInSlot(1, SchematicItem.create(schematic, player.getGameProfile().getName()));
.getFormattedText()));
} catch (IOException e) { } catch (IOException e) {
Create.logger.error("Exception Thrown when finishing Upload: " + playerSchematicId); 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, public void handleInstantSchematic(ServerPlayerEntity player, String schematic, World world, BlockPos pos,
BlockPos bounds) { BlockPos bounds) {
String playerPath = getSchematicPath() + "/" + player.getName() String playerPath = getSchematicPath() + "/" + player.getGameProfile().getName();
.getFormattedText(); String playerSchematicId = player.getGameProfile().getName() + "/" + schematic;
String playerSchematicId = player.getName()
.getFormattedText() + "/" + schematic;
FilesHelper.createFolderIfMissing(playerPath); FilesHelper.createFolderIfMissing(playerPath);
// Unsupported Format // Unsupported Format
if (!schematic.endsWith(".nbt")) { 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; return;
} }
@ -287,39 +295,32 @@ public class ServerSchematicLoader {
return; return;
try { try {
// Delete schematic with same name
Path path = Paths.get(getSchematicPath(), playerSchematicId);
Files.deleteIfExists(path);
// Too many Schematics // Too many Schematics
Stream<Path> list = Files.list(Paths.get(playerPath)); long count;
if (list.count() >= getConfig().maxSchematics.get()) { 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)); Stream<Path> list2 = Files.list(Paths.get(playerPath));
Optional<Path> lastFilePath = list2.filter(f -> !Files.isDirectory(f)) Optional<Path> lastFilePath = list2.filter(f -> !Files.isDirectory(f))
.min(Comparator.comparingLong(f -> f.toFile() .min(Comparator.comparingLong(f -> f.toFile()
.lastModified())); .lastModified()));
list2.close(); list2.close();
if (lastFilePath.isPresent()) if (lastFilePath.isPresent())
Files.deleteIfExists(lastFilePath.get()); Files.deleteIfExists(lastFilePath.get());
} }
list.close();
Template t = new Template(); Template t = new Template();
t.takeBlocksFromWorld(world, pos, bounds, true, Blocks.AIR); t.takeBlocksFromWorld(world, pos, bounds, true, Blocks.AIR);
OutputStream outputStream = null; try (OutputStream outputStream = Files.newOutputStream(path)) {
try {
outputStream = Files.newOutputStream(path, StandardOpenOption.CREATE);
CompoundNBT nbttagcompound = t.writeToNBT(new CompoundNBT()); CompoundNBT nbttagcompound = t.writeToNBT(new CompoundNBT());
CompressedStreamTools.writeCompressed(nbttagcompound, outputStream); CompressedStreamTools.writeCompressed(nbttagcompound, outputStream);
player.setHeldItem(Hand.MAIN_HAND, SchematicItem.create(schematic, player.getName() player.setHeldItem(Hand.MAIN_HAND, SchematicItem.create(schematic, player.getGameProfile().getName()));
.getFormattedText()));
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
} finally {
if (outputStream != null)
IOUtils.closeQuietly(outputStream);
} }
} catch (IOException e) { } catch (IOException e) {
Create.logger.error("Exception Thrown in direct Schematic Upload: " + playerSchematicId); 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.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths; import java.nio.file.Paths;
import java.nio.file.StandardOpenOption; import java.nio.file.StandardOpenOption;
import java.util.List; import java.util.List;
import javax.annotation.Nonnull; 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.AllItems;
import com.simibubi.create.content.schematics.SchematicProcessor; import com.simibubi.create.content.schematics.SchematicProcessor;
@ -46,6 +48,8 @@ import net.minecraftforge.fml.common.thread.SidedThreadGroups;
public class SchematicItem extends Item { public class SchematicItem extends Item {
private static final Logger LOGGER = LogManager.getLogger();
public SchematicItem(Properties properties) { public SchematicItem(Properties properties) {
super(properties.maxStackSize(1)); super(properties.maxStackSize(1));
} }
@ -106,25 +110,29 @@ public class SchematicItem extends Item {
String schematic = blueprint.getTag() String schematic = blueprint.getTag()
.getString("File"); .getString("File");
String filepath = ""; if (!schematic.endsWith(".nbt"))
return t;
if (Thread.currentThread() Path dir;
.getThreadGroup() == SidedThreadGroups.SERVER) Path file;
filepath = "schematics/uploaded/" + owner + "/" + schematic;
else
filepath = "schematics/" + schematic;
InputStream stream = null; if (Thread.currentThread().getThreadGroup() == SidedThreadGroups.SERVER) {
try { dir = Paths.get("schematics", "uploaded").toAbsolutePath();
stream = Files.newInputStream(Paths.get(filepath), StandardOpenOption.READ); 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); CompoundNBT nbt = CompressedStreamTools.readCompressed(stream);
t.read(nbt); t.read(nbt);
} catch (IOException e) { } catch (IOException e) {
// Player/Server doesnt have schematic saved LOGGER.warn("Failed to read schematic", e);
} finally {
if (stream != null)
IOUtils.closeQuietly(stream);
} }
return t; return t;

View File

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