From b7249e7d9ea853ed1154b02c312d4906dacf4d17 Mon Sep 17 00:00:00 2001 From: LatvianModder Date: Fri, 20 Oct 2023 17:13:41 +0300 Subject: [PATCH] Added invalid file name detector for assets and data folders --- .../java/dev/latvian/mods/kubejs/KubeJS.java | 4 ++ .../script/data/GeneratedResourcePack.java | 40 +++++++++++++++++++ 2 files changed, 44 insertions(+) diff --git a/common/src/main/java/dev/latvian/mods/kubejs/KubeJS.java b/common/src/main/java/dev/latvian/mods/kubejs/KubeJS.java index d6e6610c5..8a7b04f45 100644 --- a/common/src/main/java/dev/latvian/mods/kubejs/KubeJS.java +++ b/common/src/main/java/dev/latvian/mods/kubejs/KubeJS.java @@ -28,6 +28,7 @@ import dev.latvian.mods.kubejs.script.ScriptPack; import dev.latvian.mods.kubejs.script.ScriptType; import dev.latvian.mods.kubejs.script.ScriptsLoadedEvent; +import dev.latvian.mods.kubejs.script.data.GeneratedResourcePack; import dev.latvian.mods.kubejs.server.KubeJSServerEventHandler; import dev.latvian.mods.kubejs.util.ConsoleJS; import dev.latvian.mods.kubejs.util.KubeJSBackgroundThread; @@ -166,6 +167,9 @@ public KubeJS() throws Throwable { event.created.forEach(BuilderBase::createAdditionalObjects); } } + + GeneratedResourcePack.scanForInvalidFiles("kubejs/assets/", KubeJSPaths.ASSETS); + GeneratedResourcePack.scanForInvalidFiles("kubejs/data/", KubeJSPaths.DATA); } public static void loadScripts(ScriptPack pack, Path dir, String path) { diff --git a/common/src/main/java/dev/latvian/mods/kubejs/script/data/GeneratedResourcePack.java b/common/src/main/java/dev/latvian/mods/kubejs/script/data/GeneratedResourcePack.java index 675554da4..521436cb4 100644 --- a/common/src/main/java/dev/latvian/mods/kubejs/script/data/GeneratedResourcePack.java +++ b/common/src/main/java/dev/latvian/mods/kubejs/script/data/GeneratedResourcePack.java @@ -3,6 +3,7 @@ import dev.latvian.mods.kubejs.DevProperties; import dev.latvian.mods.kubejs.KubeJS; import dev.latvian.mods.kubejs.KubeJSPaths; +import dev.latvian.mods.kubejs.util.ConsoleJS; import dev.latvian.mods.kubejs.util.Lazy; import net.minecraft.resources.ResourceLocation; import net.minecraft.server.packs.AbstractPackResources; @@ -23,8 +24,47 @@ import java.util.Map; import java.util.Set; import java.util.function.Predicate; +import java.util.stream.Stream; public abstract class GeneratedResourcePack implements ExportablePackResources { + private static Stream tryWalk(Path path) { + try { + return Files.walk(path); + } catch (Exception ignore) { + } + + return Stream.empty(); + } + + public static void scanForInvalidFiles(String pathName, Path path) throws IOException { + for (var p : Files.list(path).filter(Files::isDirectory).flatMap(GeneratedResourcePack::tryWalk).filter(Files::isRegularFile).filter(Files::isReadable).toList()) { + try { + var fileName = p.getFileName().toString(); + + if (fileName.endsWith(".zip") || fileName.equals(".ds_store") || fileName.equals("thumbs.db") || fileName.equals("desktop.ini")) { + return; + } else if (Files.isHidden(path)) { + ConsoleJS.STARTUP.error("Invisible file found: " + pathName + path.relativize(p).toString().replace('\\', '/')); + return; + } + + var chars = fileName.toCharArray(); + + for (char c : chars) { + if (c >= 'A' && c <= 'Z') { + ConsoleJS.STARTUP.error("Invalid file name: Uppercase '" + c + "' in " + pathName + path.relativize(p).toString().replace('\\', '/')); + return; + } else if (c != '_' && c != '-' && (c < 'a' || c > 'z') && (c < '0' || c > '9') && c != '/' && c != '.') { + ConsoleJS.STARTUP.error("Invalid file name: Invalid character '" + c + "' in " + pathName + path.relativize(p).toString().replace('\\', '/')); + return; + } + } + } catch (Exception ex) { + ConsoleJS.STARTUP.error("Invalid file name: " + pathName + path.relativize(p).toString().replace('\\', '/')); + } + } + } + private final PackType packType; private Map generated; private Set generatedNamespaces;