GP-1860 fixed duplicate 'ask to analyze' dialogs when opening unanalyzed program with connected tools

This commit is contained in:
ghidravore
2022-04-06 14:07:04 -04:00
parent 0bfb9ae84a
commit ebb2b5eb9e
2 changed files with 15 additions and 28 deletions
@@ -1099,24 +1099,17 @@ public class AutoAnalysisManager implements DomainObjectListener, DomainObjectCl
} }
boolean askToAnalyze(PluginTool tool) { boolean askToAnalyze(PluginTool tool) {
if (program == null) { // This code relies on being called in the swing thread to avoid a race condition
return false; // where multiple threads check the flag before either thread has a chance to set it.
} Swing.assertSwingThread("Asking to analyze must be on the swing thread!");
//if program has just been instantiated, then we can analyze it.
if (!program.canSave() && !program.isChanged()) {
return false;
}
if (GhidraProgramUtilities.shouldAskToAnalyze(program)) { if (GhidraProgramUtilities.shouldAskToAnalyze(program)) {
// initialize the analyzed flag to a non-null value to indicate we at least asked
GhidraProgramUtilities.setAnalyzedFlag(program, false);
int answer = OptionDialog.showYesNoDialog(tool.getToolFrame(), "Analyze", int answer = OptionDialog.showYesNoDialog(tool.getToolFrame(), "Analyze",
"<html>" + HTMLUtilities.escapeHTML(program.getDomainFile().getName()) + "<html>" + HTMLUtilities.escapeHTML(program.getDomainFile().getName()) +
" has not been analyzed. Would you like to analyze it now?"); " has not been analyzed. Would you like to analyze it now?");
//Set to false for now. ANALYZED is a tri-valued variable:
// null means not asked.
// false means asked but could still turn true when analysis happens.
// true means analysis has started.
//Setting false here only works due to this code only being reachable
// because of the behavior of GhidraProgramUtilities.shouldAskToAnalyze(program) above.
GhidraProgramUtilities.setAnalyzedFlag(program, false);
return answer == OptionDialog.OPTION_ONE; //Analyze return answer == OptionDialog.OPTION_ONE; //Analyze
} }
return false; return false;
@@ -20,10 +20,6 @@ import ghidra.framework.options.Options;
import ghidra.framework.plugintool.PluginTool; import ghidra.framework.plugintool.PluginTool;
import ghidra.program.model.listing.Program; import ghidra.program.model.listing.Program;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class GhidraProgramUtilities { public class GhidraProgramUtilities {
private GhidraProgramUtilities() { private GhidraProgramUtilities() {
} }
@@ -38,21 +34,19 @@ public class GhidraProgramUtilities {
} }
/** /**
* Returns true if the program does not contain the analyzed flag. * Returns true if the program does not contain the analyzed flag. The assumption is that a
* non-null value means that the user has already made a decision about analyzing.
*
* @param program the program to check for the property * @param program the program to check for the property
* @return true if the program does not contain the analyzed flag * @return true if the program does not contain the analyzed flag
*/ */
public static boolean shouldAskToAnalyze(Program program) { public static boolean shouldAskToAnalyze(Program program) {
try {
SimpleDateFormat format = new SimpleDateFormat(Program.ANALYSIS_START_DATE_FORMAT); // no need to ask if the program can't be saved (i.e. read-only)
Date analysisStartDate = format.parse(Program.ANALYSIS_START_DATE); if (program == null || !program.canSave()) {
Date creationDate = program.getCreationDate();
if (creationDate.compareTo(analysisStartDate) < 0) {
return false; return false;
} }
}
catch (ParseException e) {
}
Options options = program.getOptions(Program.PROGRAM_INFO); Options options = program.getOptions(Program.PROGRAM_INFO);
return !options.contains(Program.ANALYZED); return !options.contains(Program.ANALYZED);
} }