fix leaks

- Files.list and Files.walk streams must be closed
- JavaFileManager used by compiler needs closing
This commit is contained in:
Jason P. Leasure 2020-07-09 16:05:24 -04:00
parent 6060888ce6
commit cc4e8a6fee
5 changed files with 88 additions and 77 deletions

View file

@ -404,9 +404,10 @@ public class GhidraSourceBundle extends GhidraBundle {
protected static boolean wipeContents(Path path) throws IOException {
if (Files.exists(path)) {
boolean anythingDeleted = false;
for (Path p : (Iterable<Path>) Files.walk(path)
.sorted(Comparator.reverseOrder())::iterator) {
anythingDeleted |= Files.deleteIfExists(p);
try (Stream<Path> walk = Files.walk(path)) {
for (Path p : (Iterable<Path>) walk.sorted(Comparator.reverseOrder())::iterator) {
anythingDeleted |= Files.deleteIfExists(p);
}
}
return anythingDeleted;
}
@ -859,44 +860,46 @@ public class GhidraSourceBundle extends GhidraBundle {
System.getProperty("java.class.path") + File.pathSeparator + binaryDir.toString());
options.add("-proc:none");
BundleJavaManager bundleJavaManager = createBundleJavaManager(writer, summary, options);
try (BundleJavaManager bundleJavaManager =
createBundleJavaManager(writer, summary, options)) {
final List<ResourceFileJavaFileObject> sourceFiles = newSources.stream()
.map(sf -> new ResourceFileJavaFileObject(sf.getParentFile(), sf, Kind.SOURCE))
.collect(Collectors.toList());
final List<ResourceFileJavaFileObject> sourceFiles = newSources.stream()
.map(sf -> new ResourceFileJavaFileObject(sf.getParentFile(), sf, Kind.SOURCE))
.collect(Collectors.toList());
Path binaryManifest = getBinaryManifestPath();
if (Files.exists(binaryManifest)) {
Files.delete(binaryManifest);
}
// try to compile, if we fail, avoid offenders and try again
while (!sourceFiles.isEmpty()) {
if (tryBuild(writer, bundleJavaManager, sourceFiles, options)) {
break;
Path binaryManifest = getBinaryManifestPath();
if (Files.exists(binaryManifest)) {
Files.delete(binaryManifest);
}
}
// mark the successful compilations
for (ResourceFileJavaFileObject sourceFile : sourceFiles) {
buildSuccess(sourceFile.getFile());
}
// buildErrors is now up to date, set status
if (getBuildErrorCount() > 0) {
int count = getBuildErrorCount();
summary.printf("%d source file%s with errors", count, count > 1 ? "s" : "");
}
ResourceFile sourceManifest = getSourceManifestFile();
if (sourceManifest.exists()) {
Files.createDirectories(binaryManifest.getParent());
try (InputStream inStream = sourceManifest.getInputStream()) {
Files.copy(inStream, binaryManifest, StandardCopyOption.REPLACE_EXISTING);
// try to compile, if we fail, avoid offenders and try again
while (!sourceFiles.isEmpty()) {
if (tryBuild(writer, bundleJavaManager, sourceFiles, options)) {
break;
}
}
return summary.getValue();
}
return generateManifest(writer, summary, binaryManifest);
// mark the successful compilations
for (ResourceFileJavaFileObject sourceFile : sourceFiles) {
buildSuccess(sourceFile.getFile());
}
// buildErrors is now up to date, set status
if (getBuildErrorCount() > 0) {
int count = getBuildErrorCount();
summary.printf("%d source file%s with errors", count, count > 1 ? "s" : "");
}
ResourceFile sourceManifest = getSourceManifestFile();
if (sourceManifest.exists()) {
Files.createDirectories(binaryManifest.getParent());
try (InputStream inStream = sourceManifest.getInputStream()) {
Files.copy(inStream, binaryManifest, StandardCopyOption.REPLACE_EXISTING);
}
return summary.getValue();
}
return generateManifest(writer, summary, binaryManifest);
}
}
protected static class Compilation {

View file

@ -160,8 +160,8 @@ public class OSGiUtils {
}
static void collectPackagesFromDirectory(Path dirPath, Set<String> packages) {
try {
Files.walk(dirPath).filter(p -> p.toString().endsWith(".class")).forEach(path -> {
try (Stream<Path> walk = Files.walk(dirPath)) {
walk.filter(p -> p.toString().endsWith(".class")).forEach(path -> {
String relativePath = dirPath.relativize(path).toString();
int lastSlash = relativePath.lastIndexOf(File.separatorChar);
packages.add(lastSlash > 0

View file

@ -20,8 +20,10 @@ import java.awt.event.KeyEvent;
import java.io.*;
import java.net.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.*;
import java.util.function.Predicate;
import java.util.stream.Stream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
@ -176,29 +178,30 @@ class GhidraScriptActionManager {
private DockingAction createScriptAction(String name, String menuEntry, String description,
Icon icon, String toolBarGroup, Runnable runnable) {
return new ActionBuilder(name, plugin.getName()).popupMenuPath(menuEntry)
.popupMenuIcon(icon)
.toolBarIcon(icon)
.toolBarGroup(toolBarGroup)
.description(description)
.enabled(false)
.enabledWhen(context -> context.getContextObject() instanceof ResourceFile)
.onAction(context -> runnable.run())
.buildAndInstallLocal(provider);
.popupMenuIcon(icon)
.toolBarIcon(icon)
.toolBarGroup(toolBarGroup)
.description(description)
.enabled(false)
.enabledWhen(context -> context.getContextObject() instanceof ResourceFile)
.onAction(context -> runnable.run())
.buildAndInstallLocal(provider);
}
private DockingAction createScriptTableAction(String name, String description, Icon icon,
Runnable runnable) {
return new ActionBuilder(name, plugin.getName()).popupMenuPath(name)
.popupMenuIcon(icon)
.toolBarIcon(icon)
.toolBarGroup(null)
.description(description)
.enabledWhen(context -> {
Object contextObject = context.getContextObject();
return (contextObject instanceof GTable) || (contextObject instanceof ResourceFile);
})
.onAction(context -> runnable.run())
.buildAndInstallLocal(provider);
.popupMenuIcon(icon)
.toolBarIcon(icon)
.toolBarGroup(null)
.description(description)
.enabledWhen(context -> {
Object contextObject = context.getContextObject();
return (contextObject instanceof GTable) ||
(contextObject instanceof ResourceFile);
})
.onAction(context -> runnable.run())
.buildAndInstallLocal(provider);
}
private void createActions() {
@ -246,15 +249,15 @@ class GhidraScriptActionManager {
};
new ActionBuilder("Ghidra API Help", plugin.getName()).popupMenuPath("Ghidra API Help")
.popupMenuIcon(icon)
.popupWhen(test)
.toolBarIcon(icon)
.toolBarGroup(null)
.description("Help")
.helpLocation(new HelpLocation(plugin.getName(), "Help"))
.enabledWhen(test)
.onAction(context -> showGhidraScriptJavadoc())
.buildAndInstallLocal(provider);
.popupMenuIcon(icon)
.popupWhen(test)
.toolBarIcon(icon)
.toolBarGroup(null)
.description("Help")
.helpLocation(new HelpLocation(plugin.getName(), "Help"))
.enabledWhen(test)
.onAction(context -> showGhidraScriptJavadoc())
.buildAndInstallLocal(provider);
// XXX In order to override a method of the new DockingAction and use the builder, we
// need to override the build method of the ActionBuilder. When the ActionBuilder is
@ -279,10 +282,10 @@ class GhidraScriptActionManager {
return action;
}
}.menuGroup(ToolConstants.HELP_CONTENTS_MENU_GROUP)
.menuPath(ToolConstants.MENU_HELP, "Ghidra API Help")
.helpLocation(new HelpLocation("Misc", "Welcome_to_Ghidra_Help"))
.onAction(context -> showGhidraScriptJavadoc())
.buildAndInstall(plugin.getTool());
.menuPath(ToolConstants.MENU_HELP, "Ghidra API Help")
.helpLocation(new HelpLocation("Misc", "Welcome_to_Ghidra_Help"))
.onAction(context -> showGhidraScriptJavadoc())
.buildAndInstall(plugin.getTool());
}
private void showGhidraScriptJavadoc() {
@ -397,9 +400,11 @@ class GhidraScriptActionManager {
if (versionedExtractDir.exists()) {
// Open Javadoc if all the files are present
if (zf.size() + 1 == Files.walk(versionedExtractDir.toPath()).count()) {
launchJavadoc();
return;
try (Stream<Path> walk = Files.walk(versionedExtractDir.toPath())) {
if (zf.size() + 1 == walk.count()) {
launchJavadoc();
return;
}
}
// Delete corrupted directory and continue

View file

@ -181,9 +181,10 @@ public abstract class AbstractGhidraScriptMgrPluginTest
protected static void wipe(Path path) throws IOException {
if (Files.exists(path)) {
for (Path p : (Iterable<Path>) Files.walk(path)
.sorted(Comparator.reverseOrder())::iterator) {
Files.deleteIfExists(p);
try (Stream<Path> walk = Files.walk(path)) {
for (Path p : (Iterable<Path>) walk.sorted(Comparator.reverseOrder())::iterator) {
Files.deleteIfExists(p);
}
}
}
}

View file

@ -23,6 +23,7 @@ import java.nio.file.Path;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Stream;
import org.junit.*;
import org.osgi.framework.Bundle;
@ -41,9 +42,10 @@ public class BundleHostTest extends AbstractGhidraHeadlessIntegrationTest {
protected static void wipe(Path path) throws IOException {
if (Files.exists(path)) {
for (Path p : (Iterable<Path>) Files.walk(path)
.sorted(Comparator.reverseOrder())::iterator) {
Files.deleteIfExists(p);
try (Stream<Path> walk = Files.walk(path)) {
for (Path p : (Iterable<Path>) walk.sorted(Comparator.reverseOrder())::iterator) {
Files.deleteIfExists(p);
}
}
}
}