GT-2845 - Checksums - fix for potential concurrent mod exception

This commit is contained in:
dragonmacher 2019-05-08 14:02:41 -04:00
parent 538cbc1226
commit 61b1f7b5ed
4 changed files with 28 additions and 74 deletions

View file

@ -25,8 +25,7 @@ import ghidra.framework.plugintool.ServiceProvider;
/** /**
* This class is used to model the table in the ComputeChecksumsProvider. * This class is used to model the table in the ComputeChecksumsProvider.
*/ */
public class ChecksumTableModel public class ChecksumTableModel extends GDynamicColumnTableModel<ChecksumAlgorithm, Object> {
extends GDynamicColumnTableModel<ChecksumAlgorithm, List<ChecksumAlgorithm>> {
final public static int NAME_COL = 0; final public static int NAME_COL = 0;
final public static int VALUE_COL = 1; final public static int VALUE_COL = 1;
@ -49,10 +48,6 @@ public class ChecksumTableModel
return "Checksum"; return "Checksum";
} }
/**
* Returns a list of all of the checksums in this table model.
* @return a list of all of the checksums in this table model.
*/
@Override @Override
public List<ChecksumAlgorithm> getModelData() { public List<ChecksumAlgorithm> getModelData() {
return checksumList; return checksumList;
@ -62,7 +57,7 @@ public class ChecksumTableModel
* Method used to update the display options for the applicable checksums. * Method used to update the display options for the applicable checksums.
* @param asHex True if the applicable checksums should be displayed in hex, otherwise false. * @param asHex True if the applicable checksums should be displayed in hex, otherwise false.
*/ */
public void formatOptions(boolean asHex) { void setFormatOptions(boolean asHex) {
this.isHex = asHex; this.isHex = asHex;
} }
@ -71,7 +66,7 @@ public class ChecksumTableModel
* @param checksumName the name of the checksum to get. * @param checksumName the name of the checksum to get.
* @return the checksum with the given name, or null if there isn't one. * @return the checksum with the given name, or null if there isn't one.
*/ */
public ChecksumAlgorithm getChecksumFor(String checksumName) { ChecksumAlgorithm getChecksumFor(String checksumName) {
for (ChecksumAlgorithm res : checksumList) { for (ChecksumAlgorithm res : checksumList) {
if (res.getName().equals(checksumName)) { if (res.getName().equals(checksumName)) {
return res; return res;
@ -90,13 +85,9 @@ public class ChecksumTableModel
return descriptor; return descriptor;
} }
/**
* Returns a list of the checksums.
* @return a list of the checksums.
*/
@Override @Override
public List<ChecksumAlgorithm> getDataSource() { public Object getDataSource() {
return checksumList; return null;
} }
private class ChecksumNameColumn private class ChecksumNameColumn

View file

@ -59,7 +59,7 @@ public class ComputeChecksumTask extends Task {
@Override @Override
public void run(TaskMonitor monitor) { public void run(TaskMonitor monitor) {
AddressSet addrs = new AddressSet(set != null ? set : memory); //null ok here AddressSet addrs = new AddressSet(set != null ? set : memory);
for (MemoryBlock block : memory.getBlocks()) { for (MemoryBlock block : memory.getBlocks()) {
if (!block.isInitialized()) { if (!block.isInitialized()) {
addrs.deleteRange(block.getStart(), block.getEnd()); addrs.deleteRange(block.getStart(), block.getEnd());

View file

@ -107,33 +107,22 @@ public class ComputeChecksumsPlugin extends ProgramPlugin {
*/ */
@Override @Override
protected void selectionChanged(ProgramSelection selection) { protected void selectionChanged(ProgramSelection selection) {
super.selectionChanged(selection); provider.setSelection(hasSelection());
if (provider != null) {
provider.setSelection(hasSelection());
}
} }
/** /**
* Get's the provider associated with this plugin. * Returns the current program selection
* @return the provider associated with this plugin. * @return the current program selection
*/ */
public ComputeChecksumsProvider getProvider() { ProgramSelection getSelection() {
return provider;
}
/**
* Returns the current program selection.
* @return the current program selection.
*/
public ProgramSelection getSelection() {
return currentSelection; return currentSelection;
} }
/** /**
* Returns true if the current program has a selection. * Returns true if the current program has a selection
* @return true if the current program has a selection. * @return true if the current program has a selection
*/ */
public boolean hasSelection() { boolean hasSelection() {
ProgramSelection selection = getSelection(); ProgramSelection selection = getSelection();
return selection != null && !selection.isEmpty(); return selection != null && !selection.isEmpty();
} }

View file

@ -17,8 +17,7 @@ package ghidra.app.plugin.core.checksums;
import java.awt.BorderLayout; import java.awt.BorderLayout;
import java.awt.Color; import java.awt.Color;
import java.util.ArrayList; import java.util.*;
import java.util.List;
import javax.swing.*; import javax.swing.*;
@ -64,15 +63,16 @@ public class ComputeChecksumsProvider extends ComponentProviderAdapter {
super(plugin.getTool(), "Checksum Generator", plugin.getName(), ProgramContextAction.class); super(plugin.getTool(), "Checksum Generator", plugin.getName(), ProgramContextAction.class);
setHelpLocation(new HelpLocation("ComputeChecksumsPlugin", "Generate_Checksum_Help")); setHelpLocation(new HelpLocation("ComputeChecksumsPlugin", "Generate_Checksum_Help"));
ClassSearcher.getInstances(ChecksumAlgorithm.class).forEach( Set<ChecksumAlgorithm> algorithms = ClassSearcher.getInstances(ChecksumAlgorithm.class);
alg -> addChecksumAlgorithm(alg)); checksums.addAll(algorithms);
this.plugin = plugin; this.plugin = plugin;
this.mainPanel = createWorkPanel(); this.mainPanel = createWorkPanel();
setSelection(false);
addToTool(); addToTool();
createActions(); createActions();
setSelection(false);
} }
@Override @Override
@ -135,9 +135,7 @@ public class ComputeChecksumsProvider extends ComponentProviderAdapter {
*/ */
void setSelection(boolean state) { void setSelection(boolean state) {
setErrorMessage(""); setErrorMessage("");
if (selectionAction == null) {
return;
}
selectionAction.setSelected(state); selectionAction.setSelected(state);
selectionAction.setEnabled(state); selectionAction.setEnabled(state);
if (state) { if (state) {
@ -184,39 +182,17 @@ public class ComputeChecksumsProvider extends ComponentProviderAdapter {
return carryAction.isSelected(); return carryAction.isSelected();
} }
/** ChecksumTableModel getModel() {
* Returns the model that's being used by the table.
* @return the model that's being used by the table.
*/
public ChecksumTableModel getModel() {
return model; return model;
} }
/** /**
* Returns the checksum algorithm table that's being used in the provider. * Returns a list of the checksums currently being used by the table model
* @return the checksums algorithm table that's being used in the provider. * @return a list of the checksums currently being used by the table model
*/ */
public GhidraTable getTable() { List<ChecksumAlgorithm> getChecksums() {
return table; // send out a copy so that nobody can modify the list while it is being used
} return new ArrayList<>(checksums);
/**
* Returns a list of the checksums currently being used by the table model.
* @return a list of the checksums currently being used by the table model.
*/
public List<ChecksumAlgorithm> getChecksums() {
return checksums;
}
/**
* Adds a checksum algorithm to the table model.
* @param checksumAlgorithm the algorithm to add to the table model.
*/
public void addChecksumAlgorithm(ChecksumAlgorithm checksumAlgorithm) {
checksums.add(checksumAlgorithm);
if (model != null) {
model.fireTableDataChanged();
}
} }
/** /**
@ -228,19 +204,17 @@ public class ComputeChecksumsProvider extends ComponentProviderAdapter {
table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
} }
void updateFields() { private void updateFields() {
if (!hasResults) { if (!hasResults) {
return; return;
} }
model.formatOptions(showHexAction.isSelected()); model.setFormatOptions(showHexAction.isSelected());
model.fireTableDataChanged(); model.fireTableDataChanged();
} }
private void clearFields() { private void clearFields() {
if (checksums != null) { checksums.forEach(checkResult -> checkResult.reset());
checksums.stream().forEach(checkResult -> checkResult.reset());
}
model.fireTableDataChanged(); model.fireTableDataChanged();
} }