GT-2824 - Comments - fixed infinite loop when editing comments

This commit is contained in:
dragonmacher 2019-04-24 18:16:14 -04:00
parent 8f9a8dd1b1
commit d33ffc2855
17 changed files with 853 additions and 516 deletions

View file

@ -1,6 +1,5 @@
/* ###
* IP: GHIDRA
* REVIEWED: YES
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -27,6 +26,7 @@ import javax.swing.text.*;
import ghidra.program.model.address.Address;
import ghidra.program.model.listing.CommentHistory;
import ghidra.program.model.listing.Program;
import ghidra.util.Msg;
/**
* Panel that shows comment history for a particular comment type; uses
@ -34,13 +34,13 @@ import ghidra.program.model.listing.Program;
* readability.
*/
class CommentHistoryPanel extends JPanel {
private final static String NO_HISTORY = "No History Found";
private SimpleAttributeSet userAttrSet;
private SimpleAttributeSet dateAttrSet;
private SimpleAttributeSet textAttrSet;
private SimpleAttributeSet tabAttrSet;
private StyledDocument doc;
private JTextPane textPane;
@ -52,87 +52,87 @@ class CommentHistoryPanel extends JPanel {
* @param commentType comment type
*/
CommentHistoryPanel(int commentType) {
super(new BorderLayout());
setUpAttributes();
this.commentType = commentType;
formatter = new SimpleDateFormat("yyyy MMM dd hh:mm aaa");
create();
}
/**
* Show the comment history
* @param program program
* @param addr address of comment history
*/
void showCommentHistory(Program program, Address addr) {
textPane.setText("");
CommentHistory[] historyItems =
program.getListing().getCommentHistory(addr, commentType);
CommentHistory[] historyItems = program.getListing().getCommentHistory(addr, commentType);
try {
if (historyItems.length == 0) {
doc.insertString(0, NO_HISTORY, null);
doc.setCharacterAttributes(0, NO_HISTORY.length(), textAttrSet, true);
return;
}
for (int i=0; i<historyItems.length; i++) {
formatHistory(historyItems[i]);
for (CommentHistory historyItem : historyItems) {
formatHistory(historyItem);
}
} catch (BadLocationException e) {
}
catch (BadLocationException e) {
// shouldn't happen
Msg.debug(this, "Error setting comment text field text", e);
}
textPane.setCaretPosition(0);
}
private void create() {
textPane = new JTextPane();
textPane.setEditable(false);
add(textPane, BorderLayout.CENTER);
doc = textPane.getStyledDocument();
doc = textPane.getStyledDocument();
}
private void formatHistory(CommentHistory history)
throws BadLocationException {
private void formatHistory(CommentHistory history) throws BadLocationException {
int offset = doc.getLength();
String userName = history.getUserName();
if (offset > 0) {
userName = "\n" + userName;
}
doc.insertString(offset, userName, userAttrSet);
offset = doc.getLength();
doc.insertString(offset, "\t" + formatter.format(history.getModificationDate()),
dateAttrSet);
doc.insertString(offset, "\t" + formatter.format(history.getModificationDate()),
dateAttrSet);
doc.setParagraphAttributes(offset, 1, tabAttrSet, false);
offset = doc.getLength();
doc.insertString(offset, "\n"+ history.getComments()+"\n", textAttrSet);
doc.insertString(offset, "\n" + history.getComments() + "\n", textAttrSet);
}
private void setUpAttributes() {
textAttrSet = new SimpleAttributeSet();
textAttrSet.addAttribute(StyleConstants.FontFamily, "Monospaced");
textAttrSet.addAttribute(StyleConstants.FontSize, new Integer(12));
textAttrSet.addAttribute(StyleConstants.FontSize, Integer.valueOf(12));
textAttrSet.addAttribute(StyleConstants.Foreground, Color.BLUE);
userAttrSet = new SimpleAttributeSet();
userAttrSet.addAttribute(StyleConstants.FontFamily, "Tahoma");
userAttrSet.addAttribute(StyleConstants.FontSize, new Integer(12));
userAttrSet.addAttribute(StyleConstants.FontSize, Integer.valueOf(12));
userAttrSet.addAttribute(StyleConstants.Bold, Boolean.TRUE);
dateAttrSet = new SimpleAttributeSet();
dateAttrSet.addAttribute(StyleConstants.FontFamily, "Tahoma");
dateAttrSet.addAttribute(StyleConstants.FontSize, new Integer(11));
dateAttrSet.addAttribute(StyleConstants.FontSize, Integer.valueOf(11));
dateAttrSet.addAttribute(StyleConstants.Bold, Boolean.TRUE);
dateAttrSet.addAttribute(StyleConstants.Foreground,
new Color(124,37,18));
dateAttrSet.addAttribute(StyleConstants.Foreground, new Color(124, 37, 18));
tabAttrSet = new SimpleAttributeSet();
TabStop tabs = new TabStop(100, StyleConstants.ALIGN_LEFT, TabStop.LEAD_NONE);
StyleConstants.setTabSet(tabAttrSet, new TabSet(new TabStop[]{tabs}));
StyleConstants.setTabSet(tabAttrSet, new TabSet(new TabStop[] { tabs }));
}
}

View file

@ -27,6 +27,8 @@ import javax.swing.text.html.HTMLEditorKit;
import javax.swing.tree.TreePath;
import javax.swing.tree.TreeSelectionModel;
import org.apache.commons.lang3.StringUtils;
import docking.ActionContext;
import docking.action.KeyBindingData;
import docking.event.mouse.GMouseListenerAdapter;
@ -44,7 +46,8 @@ import ghidra.app.services.ConsoleService;
import ghidra.framework.options.SaveState;
import ghidra.framework.plugintool.ComponentProviderAdapter;
import ghidra.program.model.listing.Program;
import ghidra.util.*;
import ghidra.util.HelpLocation;
import ghidra.util.Msg;
import ghidra.util.datastruct.WeakDataStructureFactory;
import ghidra.util.datastruct.WeakSet;
import ghidra.util.table.GhidraTableFilterPanel;
@ -226,7 +229,7 @@ public class GhidraScriptComponentProvider extends ComponentProviderAdapter {
reader.close();
writer.close();
FileUtilities.copyFile(temp, renameFile, TaskMonitorAdapter.DUMMY_MONITOR);
FileUtilities.copyFile(temp, renameFile, TaskMonitor.DUMMY);
if (!renameFile.exists()) {
Msg.showWarn(getClass(), getComponent(), "Unable to rename script",
@ -378,8 +381,7 @@ public class GhidraScriptComponentProvider extends ComponentProviderAdapter {
checkNewScriptDirectoryEnablement(newFile);
String category = StringUtilities.convertStringArray(getSelectedCategoryPath(),
ScriptInfo.DELIMITTER);
String category = StringUtils.join(getSelectedCategoryPath(), ScriptInfo.DELIMITTER);
provider.createNewScript(newFile, category);
GhidraScriptEditorComponentProvider editor =
@ -477,7 +479,7 @@ public class GhidraScriptComponentProvider extends ComponentProviderAdapter {
tableModel.fireTableDataChanged();
}
/**
/*
* is more than just root node selected?
*/
boolean isSelectedCategory() {

View file

@ -15,7 +15,8 @@
*/
package ghidra.app.script;
import static ghidra.util.HTMLUtilities.*;
import static ghidra.util.HTMLUtilities.HTML_NEW_LINE;
import static ghidra.util.HTMLUtilities.HTML_SPACE;
import java.io.*;
import java.util.List;
@ -25,9 +26,12 @@ import java.util.regex.Pattern;
import javax.swing.ImageIcon;
import javax.swing.KeyStroke;
import org.apache.commons.lang3.StringUtils;
import docking.DockingKeyBindingAction;
import generic.jar.ResourceFile;
import ghidra.util.*;
import ghidra.util.HTMLUtilities;
import ghidra.util.Msg;
import resources.ResourceManager;
/**
@ -77,8 +81,8 @@ public class ScriptInfo {
this.sourceFile = sourceFile;
if (!sourceFile.exists()) {
throw new IllegalArgumentException("Source file for script does not exist!: " +
sourceFile);
throw new IllegalArgumentException(
"Source file for script does not exist!: " + sourceFile);
}
}
@ -92,7 +96,7 @@ public class ScriptInfo {
toolbarImage = null;
keybindingErrorMessage = null;
}
/**
* Setting the toolbar image to null forces it to be reloaded on the next request.
*/
@ -402,7 +406,7 @@ public class ScriptInfo {
* @return the script tool bar icon
*/
public ImageIcon getToolBarImage(boolean scaled) {
parseHeader();
if (toolbar == null) {
return null;
@ -432,18 +436,15 @@ public class ScriptInfo {
* @return a string designed to be used as a tool tip
*/
public String getToolTipText() {
String htmlDescription =
description == null ? "No Description" : description.replaceAll("\n", HTML_NEW_LINE +
HTML_SPACE);
String htmlDescription = description == null ? "No Description"
: description.replaceAll("\n", HTML_NEW_LINE + HTML_SPACE);
String htmlAuthor = HTMLUtilities.bold("Author:") + HTML_SPACE + (toToolTip(author));
String htmlCategory =
HTMLUtilities.bold("Category:") + HTML_SPACE +
toToolTip(StringUtilities.convertStringArray(category, "."));
String htmlCategory = HTMLUtilities.bold("Category:") + HTML_SPACE +
toToolTip(StringUtils.join(category, DELIMITTER));
String htmlKeyBinding =
HTMLUtilities.bold("Key Binding:") + HTML_SPACE + getKeybindingToolTip();
String htmlMenuPath =
HTMLUtilities.bold("Menu Path:") + HTML_SPACE +
toToolTip(StringUtilities.convertStringArray(menupath, "."));
String htmlMenuPath = HTMLUtilities.bold("Menu Path:") + HTML_SPACE +
toToolTip(StringUtils.join(menupath, DELIMITTER));
StringBuffer buffer = new StringBuffer();
buffer.append("<h3>").append(HTML_SPACE).append(getName()).append("</h3>");

View file

@ -32,6 +32,8 @@ import javax.swing.JTree;
import javax.swing.tree.DefaultTreeCellEditor;
import javax.swing.tree.TreePath;
import org.apache.commons.lang3.StringUtils;
import docking.ActionContext;
import docking.action.DockingActionIf;
import docking.action.ToggleDockingAction;
@ -46,7 +48,6 @@ import ghidra.program.model.data.Undefined1DataType;
import ghidra.program.model.listing.*;
import ghidra.program.model.symbol.*;
import ghidra.test.ToyProgramBuilder;
import ghidra.util.StringUtilities;
/**
* Utility class that has common methods needed by the Junit tests.
@ -410,8 +411,7 @@ class SymbolTreeTestUtils {
if (!rootNode.getName().equals(rootName)) {
throw new RuntimeException(
"When selecting paths by name the first path element must be the " +
"name of the root node - path: " +
StringUtilities.convertStringArray(path, "."));
"name of the root node - path: " + StringUtils.join(path, '.'));
}
GTreeNode node = rootNode;
for (int i = 1; i < path.length; i++) {