From 3a62514e60b16873cd87a36119db7fbeb60eedc2 Mon Sep 17 00:00:00 2001 From: Ben Staddon Date: Fri, 2 Aug 2019 21:32:08 +0100 Subject: [PATCH] Fix various unclosed I/O resources (#5766) --- .../ResourcePackRepository.java.patch | 22 +++++ .../text/translation/LanguageMap.java.patch | 24 +++-- .../chunk/storage/AnvilChunkLoader.java.patch | 23 +++-- .../common/ForgeModContainer.java | 14 ++- .../minecraftforge/fml/client/GuiModList.java | 4 +- .../net/minecraftforge/fml/common/Loader.java | 27 +++++- .../fml/common/patcher/ClassPatchManager.java | 92 +++++++++++-------- 7 files changed, 138 insertions(+), 68 deletions(-) create mode 100644 patches/minecraft/net/minecraft/client/resources/ResourcePackRepository.java.patch diff --git a/patches/minecraft/net/minecraft/client/resources/ResourcePackRepository.java.patch b/patches/minecraft/net/minecraft/client/resources/ResourcePackRepository.java.patch new file mode 100644 index 0000000000..49e15808c2 --- /dev/null +++ b/patches/minecraft/net/minecraft/client/resources/ResourcePackRepository.java.patch @@ -0,0 +1,22 @@ +--- ../src-base/minecraft/net/minecraft/client/resources/ResourcePackRepository.java ++++ ../src-work/minecraft/net/minecraft/client/resources/ResourcePackRepository.java +@@ -310,9 +310,10 @@ + + private boolean func_190113_a(String p_190113_1_, File p_190113_2_) + { ++ InputStream is = null; + try + { +- String s = DigestUtils.sha1Hex((InputStream)(new FileInputStream(p_190113_2_))); ++ String s = DigestUtils.sha1Hex(is = (InputStream)(new FileInputStream(p_190113_2_))); + + if (p_190113_1_.isEmpty()) + { +@@ -332,6 +333,7 @@ + { + field_177320_c.warn("File {} couldn't be hashed.", p_190113_2_, ioexception); + } ++ finally { IOUtils.closeQuietly(is); } // Forge: close stream after use + + return false; + } diff --git a/patches/minecraft/net/minecraft/util/text/translation/LanguageMap.java.patch b/patches/minecraft/net/minecraft/util/text/translation/LanguageMap.java.patch index 8417282478..d34a6609f8 100644 --- a/patches/minecraft/net/minecraft/util/text/translation/LanguageMap.java.patch +++ b/patches/minecraft/net/minecraft/util/text/translation/LanguageMap.java.patch @@ -1,13 +1,21 @@ --- ../src-base/minecraft/net/minecraft/util/text/translation/LanguageMap.java +++ ../src-work/minecraft/net/minecraft/util/text/translation/LanguageMap.java -@@ -23,9 +23,29 @@ +@@ -23,10 +23,37 @@ public LanguageMap() { + InputStream inputstream = LanguageMap.class.getResourceAsStream("/assets/minecraft/lang/en_us.lang"); -+ inject(this, inputstream); + try + { +- InputStream inputstream = LanguageMap.class.getResourceAsStream("/assets/minecraft/lang/en_us.lang"); ++ inject(this, inputstream); ++ } ++ finally ++ { ++ IOUtils.closeQuietly(inputstream); // Forge: close stream after use (MC-153470) ++ } + } -+ + + public static void inject(InputStream inputstream) + { + inject(field_74817_a, inputstream); @@ -23,15 +31,15 @@ + public static Map parseLangFile(InputStream inputstream) + { + Map table = Maps.newHashMap(); - try - { -- InputStream inputstream = LanguageMap.class.getResourceAsStream("/assets/minecraft/lang/en_us.lang"); ++ try ++ { + inputstream = net.minecraftforge.fml.common.FMLCommonHandler.instance().loadLanguage(table, inputstream); + if (inputstream == null) return table; - ++ for (String s : IOUtils.readLines(inputstream, StandardCharsets.UTF_8)) { -@@ -37,17 +57,18 @@ + if (!s.isEmpty() && s.charAt(0) != '#') +@@ -37,17 +64,18 @@ { String s1 = astring[0]; String s2 = field_111053_a.matcher(astring[1]).replaceAll("%$1s"); diff --git a/patches/minecraft/net/minecraft/world/chunk/storage/AnvilChunkLoader.java.patch b/patches/minecraft/net/minecraft/world/chunk/storage/AnvilChunkLoader.java.patch index 2d4bf100d3..7024e6387d 100644 --- a/patches/minecraft/net/minecraft/world/chunk/storage/AnvilChunkLoader.java.patch +++ b/patches/minecraft/net/minecraft/world/chunk/storage/AnvilChunkLoader.java.patch @@ -32,8 +32,11 @@ ChunkPos chunkpos = new ChunkPos(p_75815_2_, p_75815_3_); NBTTagCompound nbttagcompound = this.field_75828_a.get(chunkpos); -@@ -67,7 +89,7 @@ +@@ -65,9 +87,10 @@ + } + nbttagcompound = this.field_193416_e.func_188257_a(FixTypes.CHUNK, CompressedStreamTools.func_74794_a(datainputstream)); ++ datainputstream.close(); // Forge: close stream after use } - return this.func_75822_a(p_75815_1_, p_75815_2_, p_75815_3_, nbttagcompound); @@ -41,7 +44,7 @@ } public boolean func_191063_a(int p_191063_1_, int p_191063_2_) -@@ -80,6 +102,13 @@ +@@ -80,6 +103,13 @@ @Nullable protected Chunk func_75822_a(World p_75822_1_, int p_75822_2_, int p_75822_3_, NBTTagCompound p_75822_4_) { @@ -55,7 +58,7 @@ if (!p_75822_4_.func_150297_b("Level", 10)) { field_151505_a.error("Chunk file at {},{} is missing level data, skipping", Integer.valueOf(p_75822_2_), Integer.valueOf(p_75822_3_)); -@@ -103,10 +132,29 @@ +@@ -103,10 +133,29 @@ field_151505_a.error("Chunk file at {},{} is in the wrong location; relocating. (Expected {}, {}, got {}, {})", Integer.valueOf(p_75822_2_), Integer.valueOf(p_75822_3_), Integer.valueOf(p_75822_2_), Integer.valueOf(p_75822_3_), Integer.valueOf(chunk.field_76635_g), Integer.valueOf(chunk.field_76647_h)); nbttagcompound.func_74768_a("xPos", p_75822_2_); nbttagcompound.func_74768_a("zPos", p_75822_3_); @@ -86,7 +89,7 @@ } } } -@@ -121,7 +169,10 @@ +@@ -121,7 +170,10 @@ NBTTagCompound nbttagcompound1 = new NBTTagCompound(); nbttagcompound.func_74782_a("Level", nbttagcompound1); nbttagcompound.func_74768_a("DataVersion", 1343); @@ -97,7 +100,7 @@ this.func_75824_a(p_75816_2_.func_76632_l(), nbttagcompound); } catch (Exception exception) -@@ -305,11 +356,19 @@ +@@ -305,11 +357,19 @@ { NBTTagCompound nbttagcompound2 = new NBTTagCompound(); @@ -117,7 +120,7 @@ } } -@@ -318,8 +377,16 @@ +@@ -318,8 +378,16 @@ for (TileEntity tileentity : p_75820_1_.func_177434_r().values()) { @@ -134,7 +137,7 @@ } p_75820_3_.func_74782_a("TileEntities", nbttaglist2); -@@ -345,6 +412,18 @@ +@@ -345,6 +413,18 @@ p_75820_3_.func_74782_a("TileTicks", nbttaglist3); } @@ -153,7 +156,7 @@ } private Chunk func_75823_a(World p_75823_1_, NBTTagCompound p_75823_2_) -@@ -388,6 +467,16 @@ +@@ -388,6 +468,16 @@ chunk.func_76616_a(p_75823_2_.func_74770_j("Biomes")); } @@ -170,7 +173,7 @@ NBTTagList nbttaglist1 = p_75823_2_.func_150295_c("Entities", 10); for (int j1 = 0; j1 < nbttaglist1.func_74745_c(); ++j1) -@@ -431,8 +520,6 @@ +@@ -431,8 +521,6 @@ p_75823_1_.func_180497_b(new BlockPos(nbttagcompound3.func_74762_e("x"), nbttagcompound3.func_74762_e("y"), nbttagcompound3.func_74762_e("z")), block, nbttagcompound3.func_74762_e("t"), nbttagcompound3.func_74762_e("p")); } } @@ -179,7 +182,7 @@ } @Nullable -@@ -563,4 +650,9 @@ +@@ -563,4 +651,9 @@ return entity; } } diff --git a/src/main/java/net/minecraftforge/common/ForgeModContainer.java b/src/main/java/net/minecraftforge/common/ForgeModContainer.java index a01883ec24..9ef4c8d76b 100644 --- a/src/main/java/net/minecraftforge/common/ForgeModContainer.java +++ b/src/main/java/net/minecraftforge/common/ForgeModContainer.java @@ -35,6 +35,7 @@ import java.util.Collections; import java.util.List; import java.util.Map; +import org.apache.commons.io.IOUtils; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -439,9 +440,16 @@ public class ForgeModContainer extends DummyModContainer implements WorldAccessC public void modConstruction(FMLConstructionEvent evt) { InputStream is = ForgeModContainer.class.getResourceAsStream("/META-INF/vanilla_annotations.json"); - if (is != null) - JsonAnnotationLoader.loadJson(is, null, evt.getASMHarvestedData()); - log.debug("Loading Vanilla annotations: " + is); + try + { + if (is != null) + JsonAnnotationLoader.loadJson(is, null, evt.getASMHarvestedData()); + log.debug("Loading Vanilla annotations: " + is); + } + finally + { + IOUtils.closeQuietly(is); + } List all = Lists.newArrayList(); for (ASMData asm : evt.getASMHarvestedData().getAll(ICrashReportDetail.class.getName().replace('.', '/'))) diff --git a/src/main/java/net/minecraftforge/fml/client/GuiModList.java b/src/main/java/net/minecraftforge/fml/client/GuiModList.java index ff8799f0ac..96b01a0813 100644 --- a/src/main/java/net/minecraftforge/fml/client/GuiModList.java +++ b/src/main/java/net/minecraftforge/fml/client/GuiModList.java @@ -30,7 +30,6 @@ import java.util.List; import java.util.Map.Entry; import javax.annotation.Nullable; -import javax.imageio.ImageIO; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.FontRenderer; @@ -43,6 +42,7 @@ import net.minecraft.client.renderer.Tessellator; import net.minecraft.client.renderer.BufferBuilder; import net.minecraft.client.renderer.texture.DynamicTexture; import net.minecraft.client.renderer.texture.TextureManager; +import net.minecraft.client.renderer.texture.TextureUtil; import net.minecraft.client.renderer.vertex.DefaultVertexFormats; import net.minecraft.client.resources.I18n; import net.minecraft.client.resources.IResourcePack; @@ -387,7 +387,7 @@ public class GuiModList extends GuiScreen { InputStream logoResource = getClass().getResourceAsStream(logoFile); if (logoResource != null) - logo = ImageIO.read(logoResource); + logo = TextureUtil.readBufferedImage(logoResource); } if (logo != null) { diff --git a/src/main/java/net/minecraftforge/fml/common/Loader.java b/src/main/java/net/minecraftforge/fml/common/Loader.java index 2f98fa348d..b9170971eb 100644 --- a/src/main/java/net/minecraftforge/fml/common/Loader.java +++ b/src/main/java/net/minecraftforge/fml/common/Loader.java @@ -26,6 +26,8 @@ import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStreamWriter; +import java.io.Reader; +import java.io.Writer; import java.net.MalformedURLException; import java.nio.charset.StandardCharsets; import java.util.ArrayList; @@ -650,7 +652,10 @@ public class Loader FMLLog.log.trace("Found a mod state file {}", forcedModFile.getName()); try { - forcedModListProperties.load(new InputStreamReader(new FileInputStream(forcedModFile), StandardCharsets.UTF_8)); + try (Reader reader = new InputStreamReader(new FileInputStream(forcedModFile), StandardCharsets.UTF_8)) + { + forcedModListProperties.load(reader); + } FMLLog.log.trace("Loaded states for {} mods from file", forcedModListProperties.size()); } catch (Exception e) @@ -863,7 +868,10 @@ public class Loader Properties loaded = new Properties(); try { - loaded.load(getClass().getClassLoader().getResourceAsStream("fmlbranding.properties")); + try (InputStream stream = getClass().getClassLoader().getResourceAsStream("fmlbranding.properties")) + { + loaded.load(stream); + } } catch (Exception e) { @@ -935,9 +943,15 @@ public class Loader try { Properties props = new Properties(); - props.load(new InputStreamReader(new FileInputStream(forcedModFile), StandardCharsets.UTF_8)); + try (Reader reader = new InputStreamReader(new FileInputStream(forcedModFile), StandardCharsets.UTF_8)) + { + props.load(reader); + } props.put(modId, "false"); - props.store(new OutputStreamWriter(new FileOutputStream(forcedModFile), StandardCharsets.UTF_8), null); + try (Writer writer = new OutputStreamWriter(new FileOutputStream(forcedModFile), StandardCharsets.UTF_8)) + { + props.store(writer, null); + } } catch (Exception e) { @@ -966,7 +980,10 @@ public class Loader JsonElement injectedDeps; try { - injectedDeps = parser.parse(new InputStreamReader(new FileInputStream(injectedDepFile), StandardCharsets.UTF_8)); + try (Reader reader = new InputStreamReader(new FileInputStream(injectedDepFile), StandardCharsets.UTF_8)) + { + injectedDeps = parser.parse(reader); + } for (JsonElement el : injectedDeps.getAsJsonArray()) { JsonObject jo = el.getAsJsonObject(); diff --git a/src/main/java/net/minecraftforge/fml/common/patcher/ClassPatchManager.java b/src/main/java/net/minecraftforge/fml/common/patcher/ClassPatchManager.java index 68e6467707..201de291e7 100644 --- a/src/main/java/net/minecraftforge/fml/common/patcher/ClassPatchManager.java +++ b/src/main/java/net/minecraftforge/fml/common/patcher/ClassPatchManager.java @@ -48,6 +48,7 @@ import com.google.common.hash.Hashing; import com.google.common.io.ByteArrayDataInput; import com.google.common.io.ByteStreams; import com.google.common.io.Files; +import org.apache.commons.io.IOUtils; public class ClassPatchManager { //Must be ABOVE INSTANCE so they get set in time for the constructor. @@ -166,57 +167,68 @@ public class ClassPatchManager { public void setup(Side side) { Pattern binpatchMatcher = Pattern.compile(String.format("binpatch/%s/.*.binpatch", side.toString().toLowerCase(Locale.ENGLISH))); - JarInputStream jis; + JarInputStream jis = null; try - { - InputStream binpatchesCompressed = getClass().getResourceAsStream("/binpatches.pack.lzma"); - if (binpatchesCompressed==null) - { - if (!FMLLaunchHandler.isDeobfuscatedEnvironment()) - { - FMLLog.log.fatal("The binary patch set is missing, things are not going to work!"); - } - return; - } - LzmaInputStream binpatchesDecompressed = new LzmaInputStream(binpatchesCompressed); - ByteArrayOutputStream jarBytes = new ByteArrayOutputStream(); - JarOutputStream jos = new JarOutputStream(jarBytes); - Pack200.newUnpacker().unpack(binpatchesDecompressed, jos); - jis = new JarInputStream(new ByteArrayInputStream(jarBytes.toByteArray())); - } - catch (Exception e) - { - throw new RuntimeException("Error occurred reading binary patches. Expect severe problems!", e); - } - - patches = ArrayListMultimap.create(); - - do { try { - JarEntry entry = jis.getNextJarEntry(); - if (entry == null) + InputStream binpatchesCompressed = getClass().getResourceAsStream("/binpatches.pack.lzma"); + if (binpatchesCompressed==null) { - break; - } - if (binpatchMatcher.matcher(entry.getName()).matches()) - { - ClassPatch cp = readPatch(entry, jis); - if (cp != null) + if (!FMLLaunchHandler.isDeobfuscatedEnvironment()) { - patches.put(cp.sourceClassName, cp); + FMLLog.log.fatal("The binary patch set is missing, things are not going to work!"); + } + return; + } + try (LzmaInputStream binpatchesDecompressed = new LzmaInputStream(binpatchesCompressed)) + { + ByteArrayOutputStream jarBytes = new ByteArrayOutputStream(); + try (JarOutputStream jos = new JarOutputStream(jarBytes)) + { + Pack200.newUnpacker().unpack(binpatchesDecompressed, jos); + jis = new JarInputStream(new ByteArrayInputStream(jarBytes.toByteArray())); } } - else - { - jis.closeEntry(); - } } - catch (IOException e) + catch (Exception e) { + throw new RuntimeException("Error occurred reading binary patches. Expect severe problems!", e); } - } while (true); + + patches = ArrayListMultimap.create(); + + do + { + try + { + JarEntry entry = jis.getNextJarEntry(); + if (entry == null) + { + break; + } + if (binpatchMatcher.matcher(entry.getName()).matches()) + { + ClassPatch cp = readPatch(entry, jis); + if (cp != null) + { + patches.put(cp.sourceClassName, cp); + } + } + else + { + jis.closeEntry(); + } + } + catch (IOException e) + { + } + } while (true); + } + finally + { + IOUtils.closeQuietly(jis); + } FMLLog.log.debug("Read {} binary patches", patches.size()); if (DEBUG) FMLLog.log.debug("Patch list :\n\t{}", Joiner.on("\t\n").join(patches.asMap().entrySet()));