|
20 | 20 | import net.minecraft.server.level.ServerPlayer; |
21 | 21 | import me.lucko.fabric.api.permissions.v0.Permissions; |
22 | 22 | import net.minecraft.world.item.ItemStack; |
| 23 | +import org.jetbrains.annotations.NotNull; |
23 | 24 |
|
24 | | -import java.io.File; |
25 | | -import java.io.FileInputStream; |
26 | | -import java.io.FileOutputStream; |
27 | | -import java.io.IOException; |
| 25 | +import javax.imageio.ImageIO; |
| 26 | +import java.io.*; |
28 | 27 | import java.net.URI; |
29 | 28 | import java.nio.charset.StandardCharsets; |
30 | 29 | import java.nio.file.Files; |
|
33 | 32 | import java.security.MessageDigest; |
34 | 33 | import java.security.NoSuchAlgorithmException; |
35 | 34 | import java.security.SecureRandom; |
36 | | -import java.util.Arrays; |
37 | 35 | import java.util.Optional; |
38 | 36 | import java.util.UUID; |
39 | 37 | import java.util.zip.ZipEntry; |
@@ -147,6 +145,12 @@ public void upload_file(UUID uploader, AssetType type, String name, byte[] conte |
147 | 145 | var ext = split_name[split_name.length-1]; |
148 | 146 | if(!type.is_valid_extension(ext)) throw new IOException("Invalid extension for upload type!"); |
149 | 147 |
|
| 148 | + if(ext.equals("png")) { |
| 149 | + if(!png_is_mipmap_safe(contents)) { |
| 150 | + throw new IOException("Image resolution must be a power of 2!"); |
| 151 | + } |
| 152 | + } |
| 153 | + |
150 | 154 | // Replace packer_id |
151 | 155 | if(ext.equals("json")) { |
152 | 156 | var str = new String(contents, StandardCharsets.UTF_8); |
@@ -384,4 +388,30 @@ public static String getSHA1(File file) throws IOException { |
384 | 388 | } |
385 | 389 | return sb.toString(); |
386 | 390 | } |
| 391 | + |
| 392 | + private boolean png_is_mipmap_safe(byte @NotNull [] contents) throws IOException { |
| 393 | + if(contents.length == 0) return false; |
| 394 | + var bais = new ByteArrayInputStream(contents); |
| 395 | + var iis = ImageIO.createImageInputStream(bais); |
| 396 | + |
| 397 | + var readers = ImageIO.getImageReaders(iis); |
| 398 | + if(!readers.hasNext()) { |
| 399 | + return false; |
| 400 | + } |
| 401 | + |
| 402 | + var reader = readers.next(); |
| 403 | + try { |
| 404 | + reader.setInput(iis); |
| 405 | + int width = reader.getWidth(0); |
| 406 | + int height = reader.getHeight(0); |
| 407 | + |
| 408 | + return is_power_of_two(width) && is_power_of_two(height); |
| 409 | + } finally { |
| 410 | + reader.dispose(); |
| 411 | + } |
| 412 | + } |
| 413 | + |
| 414 | + private boolean is_power_of_two(int n) { |
| 415 | + return (n > 0) && ((n & (n - 1)) == 0); |
| 416 | + } |
387 | 417 | } |
0 commit comments