From e6ea5984c76d6bf2972a5202ae7f3dce7394d8bd Mon Sep 17 00:00:00 2001 From: apple502j <33279053+apple502j@users.noreply.github.com> Date: Sun, 7 Aug 2022 03:02:42 +0900 Subject: [PATCH] ModResourcePackUtil: Properly handle special chars in mod name (#2407) * ModResourcePackUtil: Properly handle special chars in mod name * Add tests * Fix NPE in testmod --- .../resource/loader/ModResourcePackUtil.java | 27 ++++++++++------- .../loader/BuiltinResourcePackTestMod.java | 30 ++++++++++++++++++- 2 files changed, 46 insertions(+), 11 deletions(-) diff --git a/fabric-resource-loader-v0/src/main/java/net/fabricmc/fabric/impl/resource/loader/ModResourcePackUtil.java b/fabric-resource-loader-v0/src/main/java/net/fabricmc/fabric/impl/resource/loader/ModResourcePackUtil.java index d5866f9c5..ee5b0987b 100644 --- a/fabric-resource-loader-v0/src/main/java/net/fabricmc/fabric/impl/resource/loader/ModResourcePackUtil.java +++ b/fabric-resource-loader-v0/src/main/java/net/fabricmc/fabric/impl/resource/loader/ModResourcePackUtil.java @@ -19,8 +19,11 @@ package net.fabricmc.fabric.impl.resource.loader; import java.io.InputStream; import java.util.ArrayList; import java.util.List; +import java.util.Objects; import com.google.common.base.Charsets; +import com.google.gson.Gson; +import com.google.gson.JsonObject; import org.apache.commons.io.IOUtils; import org.jetbrains.annotations.Nullable; @@ -40,6 +43,8 @@ import net.fabricmc.loader.api.metadata.ModMetadata; * Internal utilities for managing resource packs. */ public final class ModResourcePackUtil { + private static final Gson GSON = new Gson(); + private ModResourcePackUtil() { } @@ -71,21 +76,23 @@ public final class ModResourcePackUtil { public static InputStream openDefault(ModMetadata info, ResourceType type, String filename) { switch (filename) { case "pack.mcmeta": - String description = info.getName(); - - if (description == null) { - description = ""; - } else { - description = description.replaceAll("\"", "\\\""); - } - - String pack = String.format("{\"pack\":{\"pack_format\":" + type.getPackVersion(SharedConstants.getGameVersion()) + ",\"description\":\"%s\"}}", description); - return IOUtils.toInputStream(pack, Charsets.UTF_8); + String description = Objects.requireNonNullElse(info.getName(), ""); + String metadata = serializeMetadata(type.getPackVersion(SharedConstants.getGameVersion()), description); + return IOUtils.toInputStream(metadata, Charsets.UTF_8); default: return null; } } + public static String serializeMetadata(int packVersion, String description) { + JsonObject pack = new JsonObject(); + pack.addProperty("pack_format", packVersion); + pack.addProperty("description", description); + JsonObject metadata = new JsonObject(); + metadata.add("pack", pack); + return GSON.toJson(metadata); + } + public static String getName(ModMetadata info) { if (info.getName() != null) { return info.getName(); diff --git a/fabric-resource-loader-v0/src/testmod/java/net/fabricmc/fabric/test/resource/loader/BuiltinResourcePackTestMod.java b/fabric-resource-loader-v0/src/testmod/java/net/fabricmc/fabric/test/resource/loader/BuiltinResourcePackTestMod.java index 40481fc6e..c5e9ccc4b 100644 --- a/fabric-resource-loader-v0/src/testmod/java/net/fabricmc/fabric/test/resource/loader/BuiltinResourcePackTestMod.java +++ b/fabric-resource-loader-v0/src/testmod/java/net/fabricmc/fabric/test/resource/loader/BuiltinResourcePackTestMod.java @@ -16,14 +16,18 @@ package net.fabricmc.fabric.test.resource.loader; -import org.slf4j.LoggerFactory; +import com.google.gson.Gson; +import com.google.gson.JsonObject; +import com.google.gson.JsonParseException; import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import net.minecraft.util.Identifier; import net.fabricmc.api.ModInitializer; import net.fabricmc.fabric.api.resource.ResourceManagerHelper; import net.fabricmc.fabric.api.resource.ResourcePackActivationType; +import net.fabricmc.fabric.impl.resource.loader.ModResourcePackUtil; import net.fabricmc.loader.api.FabricLoader; public class BuiltinResourcePackTestMod implements ModInitializer { @@ -31,6 +35,8 @@ public class BuiltinResourcePackTestMod implements ModInitializer { private static final Logger LOGGER = LoggerFactory.getLogger(BuiltinResourcePackTestMod.class); + private static final Gson GSON = new Gson(); + @Override public void onInitialize() { // Should always be present as it's **this** mod. @@ -42,5 +48,27 @@ public class BuiltinResourcePackTestMod implements ModInitializer { .map(container -> ResourceManagerHelper.registerBuiltinResourcePack(new Identifier(MODID, "test2"), container, ResourcePackActivationType.NORMAL)) .filter(success -> !success).ifPresent(success -> LOGGER.warn("Could not register built-in resource pack.")); + + // Test various metadata serialization issues (#2407) + testMetadataSerialization(""); + testMetadataSerialization("Quotes: \"\" \""); + testMetadataSerialization("Backslash: \\ \\\\"); + } + + private void testMetadataSerialization(String description) { + String metadata = ModResourcePackUtil.serializeMetadata(1, description); + JsonObject json; + + try { + json = GSON.fromJson(metadata, JsonObject.class); + } catch (JsonParseException exc) { + throw new AssertionError("Metadata parsing test for description \"%s\" failed".formatted(description), exc); + } + + String parsedDescription = json.get("pack").getAsJsonObject().get("description").getAsString(); + + if (!description.equals(parsedDescription)) { + throw new AssertionError("Metadata parsing test for description failed: expected \"%s\", got \"%s\"".formatted(description, parsedDescription)); + } } }