diff --git a/src/main/java/land/chipmunk/chipmunkmod/mixin/TextSerializerMixin.java b/src/main/java/land/chipmunk/chipmunkmod/mixin/TextSerializerMixin.java index 8c168b2..1ec8529 100644 --- a/src/main/java/land/chipmunk/chipmunkmod/mixin/TextSerializerMixin.java +++ b/src/main/java/land/chipmunk/chipmunkmod/mixin/TextSerializerMixin.java @@ -3,10 +3,12 @@ package land.chipmunk.chipmunkmod.mixin; import com.google.gson.JsonArray; import com.google.gson.JsonDeserializationContext; import com.google.gson.JsonElement; +import com.google.gson.JsonObject; import net.minecraft.text.MutableText; import net.minecraft.text.Text; import net.minecraft.util.Formatting; import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Unique; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; @@ -15,34 +17,46 @@ import java.lang.reflect.Type; @Mixin(Text.Serializer.class) public class TextSerializerMixin { + @Unique private static final int LIMIT = 128; + + @Unique private int i; + + @Unique + private boolean checkDepth (JsonElement element) { + if (element.isJsonPrimitive()) return false; + else if (i >= LIMIT) return true; + + if (element.isJsonArray()) { + i++; + + for (JsonElement item : element.getAsJsonArray()) if (checkDepth(item)) return true; + } else if (element.isJsonObject()) { + final JsonObject object = element.getAsJsonObject(); + + JsonArray array; + + if (object.has("extra")) array = object.get("extra").getAsJsonArray(); + else if (object.has("with")) array = object.get("with").getAsJsonArray(); + else return false; + + i++; + + for (JsonElement member : array) if (checkDepth(member)) return true; + } + + return false; + } + @Inject(method = "deserialize(Lcom/google/gson/JsonElement;Ljava/lang/reflect/Type;Lcom/google/gson/JsonDeserializationContext;)Lnet/minecraft/text/MutableText;", at = @At("HEAD"), cancellable = true) private void deserialize (JsonElement jsonElement, Type type, JsonDeserializationContext jsonDeserializationContext, CallbackInfoReturnable cir) { - try { - if (!jsonElement.isJsonArray()) return; + i = 0; // better way to do this? - final JsonArray array = jsonElement.getAsJsonArray(); + final boolean overLimit = checkDepth(jsonElement); - if (array.size() == 0) return; + if (!overLimit) return; - JsonElement item = array.get(0); + cir.setReturnValue(Text.literal("Component is too big").formatted(Formatting.RED)); - int depth = 0; - - while (item != null && item.isJsonArray() && depth < 512) { - if (item.getAsJsonArray().size() == 0 && item.getAsJsonArray().get(0) == null) continue; - - depth++; - - item = item.getAsJsonArray().get(0); - } - - if (depth >= 512) { - cir.setReturnValue(Text.literal("Component is too big").formatted(Formatting.RED)); - - cir.cancel(); - } - } catch (Exception e) { - e.printStackTrace(); - } + cir.cancel(); } }