mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-05 02:39:44 +02:00
GT-2824 - Comments - fixed infinite loop when editing comments
This commit is contained in:
parent
8f9a8dd1b1
commit
d33ffc2855
17 changed files with 853 additions and 516 deletions
|
@ -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 }));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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>");
|
||||
|
|
|
@ -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++) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue