mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2024-11-22 12:11:55 +00:00
Merge remote-tracking branch 'origin/GP-3760-dragonmacher-annotations-text--SQUASHED'
This commit is contained in:
commit
2623a95a0d
@ -56,7 +56,7 @@ public class AddressAnnotatedStringHandler implements AnnotatedStringHandler {
|
||||
|
||||
String addressText = address.toString();
|
||||
if (text.length > 2) { // address and display text
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
StringBuilder buffer = new StringBuilder();
|
||||
for (int i = 2; i < text.length; i++) {
|
||||
buffer.append(text[i]).append(" ");
|
||||
}
|
||||
|
@ -16,8 +16,6 @@
|
||||
package ghidra.app.util.viewer.field;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import docking.widgets.fieldpanel.field.AttributedString;
|
||||
import ghidra.app.nav.Navigatable;
|
||||
@ -26,12 +24,8 @@ import ghidra.program.model.listing.Program;
|
||||
import ghidra.util.classfinder.ClassSearcher;
|
||||
|
||||
public class Annotation {
|
||||
/**
|
||||
* A pattern to match text between two quote characters and to capture that text. This
|
||||
* pattern does not match quote characters that are escaped with a '\' character.
|
||||
*/
|
||||
private static final Pattern QUOTATION_PATTERN =
|
||||
Pattern.compile("(?<!\\\\)[\"](.*?)(?<!\\\\)[\"]");
|
||||
|
||||
public static final String ESCAPABLE_CHARS = "{}\"\\";
|
||||
|
||||
private static List<AnnotatedStringHandler> ANNOTATED_STRING_HANDLERS;
|
||||
private static Map<String, AnnotatedStringHandler> ANNOTATED_STRING_MAP;
|
||||
@ -149,55 +143,149 @@ public class Annotation {
|
||||
serviceProvider);
|
||||
}
|
||||
|
||||
private String[] parseAnnotationText(String theAnnotationText) {
|
||||
StringBuffer buffer = new StringBuffer(theAnnotationText);
|
||||
|
||||
// strip off the brackets
|
||||
buffer.delete(0, 2); // remove '{' and '@'
|
||||
buffer.deleteCharAt(buffer.length() - 1);
|
||||
|
||||
// first split out the tokens on '"' so that annotations can have groupings with
|
||||
// whitespace
|
||||
int unqouotedOffset = 0;
|
||||
List<String> tokens = new ArrayList<>();
|
||||
Matcher matcher = QUOTATION_PATTERN.matcher(buffer.toString());
|
||||
while (matcher.find()) {
|
||||
// put all text in the buffer,
|
||||
int quoteStart = matcher.start();
|
||||
String contentBeforeQuote = buffer.substring(unqouotedOffset, quoteStart);
|
||||
grabTokens(tokens, contentBeforeQuote);
|
||||
unqouotedOffset = matcher.end();
|
||||
|
||||
String quotedContent = matcher.group(1); // group 0 is the entire string
|
||||
tokens.add(quotedContent);
|
||||
}
|
||||
|
||||
// handle any remaining part of the text after quoted sections
|
||||
if (unqouotedOffset < buffer.length()) {
|
||||
String remainingString = buffer.substring(unqouotedOffset);
|
||||
grabTokens(tokens, remainingString);
|
||||
}
|
||||
|
||||
// split on whitespace
|
||||
return tokens.toArray(new String[tokens.size()]);
|
||||
}
|
||||
|
||||
private void grabTokens(List<String> tokenContainer, String content) {
|
||||
String[] strings = content.split("\\s");
|
||||
for (String string : strings) {
|
||||
// 0 length strings can happen when 'content' begins with a space
|
||||
if (string.length() > 0) {
|
||||
tokenContainer.add(string);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public String getAnnotationText() {
|
||||
return annotationText;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return annotationText;
|
||||
}
|
||||
|
||||
/*package*/ static Set<String> getAnnotationNames() {
|
||||
return Collections.unmodifiableSet(getAnnotatedStringHandlerMap().keySet());
|
||||
}
|
||||
|
||||
private String[] parseAnnotationText(String text) {
|
||||
|
||||
String trimmed = text.substring(2, text.length() - 1); // remove "{@" and '}'
|
||||
List<String> tokens = new ArrayList<>();
|
||||
List<TextPart> parts = parseText(trimmed);
|
||||
for (TextPart part : parts) {
|
||||
part.grabTokens(tokens);
|
||||
}
|
||||
|
||||
return tokens.toArray(new String[tokens.size()]);
|
||||
}
|
||||
|
||||
private List<TextPart> parseText(String text) {
|
||||
|
||||
List<TextPart> textParts = new ArrayList<>();
|
||||
boolean escaped = false;
|
||||
boolean inQuote = false;
|
||||
int partStart = 0;
|
||||
int n = text.length();
|
||||
for (int i = 0; i < n; i++) {
|
||||
|
||||
boolean wasEscaped = escaped;
|
||||
escaped = false;
|
||||
char prev = '\0';
|
||||
if (i != 0 && !wasEscaped) {
|
||||
prev = text.charAt(i - 1);
|
||||
}
|
||||
|
||||
char c = text.charAt(i);
|
||||
if (prev == '\\') {
|
||||
if (Annotation.ESCAPABLE_CHARS.indexOf(c) != -1) {
|
||||
escaped = true;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (c == '"') {
|
||||
if (inQuote) {
|
||||
// end quote
|
||||
String s = text.substring(partStart, i + 1); // keep the quote
|
||||
textParts.add(new QuotedTextPart(s));
|
||||
partStart = i + 1;
|
||||
}
|
||||
else {
|
||||
// end previous word; start quote
|
||||
if (i != 0) {
|
||||
String s = text.substring(partStart, i);
|
||||
textParts.add(new TextPart(s));
|
||||
partStart = i;
|
||||
}
|
||||
}
|
||||
inQuote = !inQuote;
|
||||
}
|
||||
}
|
||||
|
||||
if (partStart < n) { // grab trailing text
|
||||
String s = text.substring(partStart, n);
|
||||
textParts.add(new TextPart(s));
|
||||
}
|
||||
|
||||
return textParts;
|
||||
}
|
||||
|
||||
// remove any backslashes that escape special annotation characters, like '{' and '}'
|
||||
private static String removeEscapeChars(String text) {
|
||||
boolean escaped = false;
|
||||
StringBuilder buffy = new StringBuilder();
|
||||
for (int i = 0; i < text.length(); i++) {
|
||||
char c = text.charAt(i);
|
||||
boolean wasEscaped = escaped;
|
||||
escaped = false;
|
||||
if (c != '\\') {
|
||||
buffy.append(c);
|
||||
continue;
|
||||
}
|
||||
|
||||
char next = '\0';
|
||||
if (i != text.length() - 1 && !wasEscaped) {
|
||||
next = text.charAt(i + 1);
|
||||
}
|
||||
|
||||
if (ESCAPABLE_CHARS.indexOf(next) != -1) {
|
||||
escaped = true;
|
||||
continue;
|
||||
}
|
||||
buffy.append(c);
|
||||
}
|
||||
|
||||
return buffy.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* A simple class to hold text and extract tokens
|
||||
*/
|
||||
private class TextPart {
|
||||
|
||||
protected String text;
|
||||
|
||||
TextPart(String text) {
|
||||
this.text = text;
|
||||
}
|
||||
|
||||
public void grabTokens(List<String> tokens) {
|
||||
String escaped = removeEscapeChars(text);
|
||||
String[] strings = escaped.split("\\s");
|
||||
for (String string : strings) {
|
||||
// 0 length strings can happen when 'content' begins with a space
|
||||
if (string.length() > 0) {
|
||||
tokens.add(string);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return text;
|
||||
}
|
||||
}
|
||||
|
||||
private class QuotedTextPart extends TextPart {
|
||||
QuotedTextPart(String text) {
|
||||
super(text);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void grabTokens(List<String> tokens) {
|
||||
String unquoted = text.substring(1, text.length() - 1);
|
||||
String escaped = removeEscapeChars(unquoted);
|
||||
tokens.add(escaped); // all quoted text is a 'token'
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,44 @@
|
||||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package ghidra.app.util.viewer.field;
|
||||
|
||||
import docking.widgets.fieldpanel.field.AbstractTextFieldElement;
|
||||
import ghidra.util.bean.field.AnnotatedTextFieldElement;
|
||||
|
||||
public class AnnotationCommentPart extends CommentPart {
|
||||
|
||||
private Annotation annotation;
|
||||
|
||||
AnnotationCommentPart(String displayText, Annotation annotation) {
|
||||
super(displayText);
|
||||
this.annotation = annotation;
|
||||
}
|
||||
|
||||
@Override
|
||||
String getRawText() {
|
||||
return annotation.getAnnotationText();
|
||||
}
|
||||
|
||||
@Override
|
||||
AbstractTextFieldElement createElement(int row, int column) {
|
||||
return new AnnotatedTextFieldElement(annotation, row, column);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return annotation.toString();
|
||||
}
|
||||
}
|
@ -0,0 +1,35 @@
|
||||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package ghidra.app.util.viewer.field;
|
||||
|
||||
import docking.widgets.fieldpanel.field.AbstractTextFieldElement;
|
||||
|
||||
public abstract class CommentPart {
|
||||
|
||||
protected String displayText;
|
||||
|
||||
CommentPart(String displayText) {
|
||||
this.displayText = displayText;
|
||||
}
|
||||
|
||||
abstract AbstractTextFieldElement createElement(int row, int column);
|
||||
|
||||
abstract String getRawText();
|
||||
|
||||
String getDisplayText() {
|
||||
return displayText;
|
||||
}
|
||||
}
|
@ -31,8 +31,6 @@ import generic.theme.Gui;
|
||||
import ghidra.program.model.listing.Program;
|
||||
import ghidra.util.StringUtilities;
|
||||
import ghidra.util.WordLocation;
|
||||
import ghidra.util.bean.field.AnnotatedTextFieldElement;
|
||||
import ghidra.util.exception.AssertException;
|
||||
|
||||
public class CommentUtils {
|
||||
|
||||
@ -75,21 +73,10 @@ public class CommentUtils {
|
||||
};
|
||||
|
||||
StringBuilder buffy = new StringBuilder();
|
||||
List<Object> parts =
|
||||
List<CommentPart> parts =
|
||||
doParseTextIntoTextAndAnnotations(rawCommentText, symbolFixer, program, prototype);
|
||||
for (Object part : parts) {
|
||||
|
||||
if (part instanceof String) {
|
||||
String s = (String) part;
|
||||
buffy.append(s);
|
||||
}
|
||||
else if (part instanceof Annotation) {
|
||||
Annotation a = (Annotation) part;
|
||||
buffy.append(a.getAnnotationText());
|
||||
}
|
||||
else {
|
||||
throw new AssertException("Unhandled annotation piece: " + part);
|
||||
}
|
||||
for (CommentPart part : parts) {
|
||||
buffy.append(part.getRawText());
|
||||
}
|
||||
return buffy.toString();
|
||||
}
|
||||
@ -136,7 +123,7 @@ public class CommentUtils {
|
||||
Function<Annotation, Annotation> noFixing = Function.identity();
|
||||
return doParseTextForAnnotations(text, noFixing, program, prototypeString, row);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sanitizes the given text, removing or replacing illegal characters.
|
||||
* <p>
|
||||
@ -175,25 +162,12 @@ public class CommentUtils {
|
||||
text = StringUtilities.convertTabsToSpaces(text);
|
||||
|
||||
int column = 0;
|
||||
List<Object> parts =
|
||||
List<CommentPart> parts =
|
||||
doParseTextIntoTextAndAnnotations(text, fixerUpper, program, prototype);
|
||||
List<FieldElement> fields = new ArrayList<>();
|
||||
for (Object part : parts) {
|
||||
|
||||
if (part instanceof String) {
|
||||
String s = (String) part;
|
||||
AttributedString as = prototype.deriveAttributedString(s);
|
||||
fields.add(new TextFieldElement(as, row, column));
|
||||
column += s.length();
|
||||
}
|
||||
else if (part instanceof Annotation) {
|
||||
Annotation a = (Annotation) part;
|
||||
fields.add(new AnnotatedTextFieldElement(a, row, column));
|
||||
column += a.getAnnotationText().length();
|
||||
}
|
||||
else {
|
||||
throw new AssertException("Unhandled annotation piece: " + part);
|
||||
}
|
||||
for (CommentPart part : parts) {
|
||||
fields.add(part.createElement(row, column));
|
||||
column += part.getDisplayText().length();
|
||||
}
|
||||
|
||||
return new CompositeFieldElement(fields.toArray(new FieldElement[fields.size()]));
|
||||
@ -204,21 +178,20 @@ public class CommentUtils {
|
||||
* an Annotation
|
||||
*
|
||||
* @param text the text to parse
|
||||
* @param fixerUpper a function that is given a chance to convert an Annotation into a new
|
||||
* one
|
||||
* @param fixerUpper a function that is given a chance to convert an Annotation into a new one
|
||||
* @param program the program
|
||||
* @param prototype the prototype string that contains decoration attributes
|
||||
* @return a list that contains a mixture String or an Annotation entries
|
||||
*/
|
||||
private static List<Object> doParseTextIntoTextAndAnnotations(String text,
|
||||
private static List<CommentPart> doParseTextIntoTextAndAnnotations(String text,
|
||||
Function<Annotation, Annotation> fixerUpper, Program program,
|
||||
AttributedString prototype) {
|
||||
|
||||
List<Object> results = new ArrayList<>();
|
||||
List<CommentPart> results = new ArrayList<>();
|
||||
|
||||
List<WordLocation> annotations = getCommentAnnotations(text);
|
||||
if (annotations.isEmpty()) {
|
||||
results.add(text);
|
||||
results.add(new StringCommentPart(text, prototype));
|
||||
return results;
|
||||
}
|
||||
|
||||
@ -230,19 +203,20 @@ public class CommentUtils {
|
||||
if (offset != start) {
|
||||
// text between annotations
|
||||
String preceeding = text.substring(offset, start);
|
||||
results.add(preceeding);
|
||||
results.add(new StringCommentPart(preceeding, prototype));
|
||||
}
|
||||
|
||||
String annotationText = word.getWord();
|
||||
Annotation annotation = new Annotation(annotationText, prototype, program);
|
||||
annotation = fixerUpper.apply(annotation);
|
||||
results.add(annotation);
|
||||
results.add(new AnnotationCommentPart(annotationText, annotation));
|
||||
|
||||
offset = start + annotationText.length();
|
||||
}
|
||||
|
||||
if (offset != text.length()) { // trailing text
|
||||
results.add(text.substring(offset));
|
||||
String trailing = text.substring(offset);
|
||||
results.add(new StringCommentPart(trailing, prototype));
|
||||
}
|
||||
|
||||
return results;
|
||||
@ -299,26 +273,30 @@ public class CommentUtils {
|
||||
*/
|
||||
private static int findAnnotationEnd(String comment, int start) {
|
||||
|
||||
boolean startQuote = false;
|
||||
int count = 0;
|
||||
boolean escaped = false;
|
||||
boolean inQuote = false;
|
||||
for (int i = start; i < comment.length(); i++) {
|
||||
char prev = i == 0 ? '\0' : comment.charAt(i - 1);
|
||||
if (prev == '\\') {
|
||||
continue; // escaped
|
||||
|
||||
boolean wasEscaped = escaped;
|
||||
escaped = false;
|
||||
char prev = '\0';
|
||||
if (i != 0 && !wasEscaped) {
|
||||
prev = comment.charAt(i - 1);
|
||||
}
|
||||
|
||||
char c = comment.charAt(i);
|
||||
if (prev == '\\') {
|
||||
if (Annotation.ESCAPABLE_CHARS.indexOf(c) != -1) {
|
||||
escaped = true;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (c == '"') {
|
||||
if (startQuote) {
|
||||
--count;
|
||||
}
|
||||
else {
|
||||
++count;
|
||||
}
|
||||
startQuote = !startQuote;
|
||||
inQuote = !inQuote;
|
||||
}
|
||||
else if (c == '}') {
|
||||
if (count == 0) {
|
||||
if (!inQuote) {
|
||||
return i + 1;
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,44 @@
|
||||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package ghidra.app.util.viewer.field;
|
||||
|
||||
import docking.widgets.fieldpanel.field.*;
|
||||
|
||||
public class StringCommentPart extends CommentPart {
|
||||
|
||||
private AttributedString prototype;
|
||||
|
||||
StringCommentPart(String text, AttributedString prototype) {
|
||||
super(text);
|
||||
this.prototype = prototype;
|
||||
}
|
||||
|
||||
@Override
|
||||
String getRawText() {
|
||||
return getDisplayText();
|
||||
}
|
||||
|
||||
@Override
|
||||
AbstractTextFieldElement createElement(int row, int column) {
|
||||
AttributedString as = prototype.deriveAttributedString(displayText);
|
||||
return new TextFieldElement(as, row, column);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return getDisplayText();
|
||||
}
|
||||
}
|
@ -201,14 +201,69 @@ public class AnnotationTest extends AbstractGhidraHeadedIntegrationTest {
|
||||
public void testSymbolAnnotation_WithBracesInName_Escaped() {
|
||||
String rawComment = "This is a symbol {@sym mySym\\{0\\}} annotation";
|
||||
String display = CommentUtils.getDisplayString(rawComment, program);
|
||||
assertEquals("This is a symbol mySym\\{0\\} annotation", display);
|
||||
assertEquals("This is a symbol mySym{0} annotation", display);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSymbolAnnotation_WithEscapedItemsOutsideOfAnnotation() {
|
||||
String rawComment = "This is a foo} symbol {@sym mySym\\{0\\}} annotation {bar";
|
||||
String display = CommentUtils.getDisplayString(rawComment, program);
|
||||
assertEquals("This is a foo} symbol mySym{0} annotation {bar", display);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAddressAnnotation_QuotedQuote() {
|
||||
String rawComment = "Test {@address 0 \"quote\\\"\"} extra}";
|
||||
String display = CommentUtils.getDisplayString(rawComment, program);
|
||||
assertEquals("Test quote\" extra}", display);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAddressAnnotation_EscapedBrace() {
|
||||
String rawComment = "Test {@address 0 \"quote\\}\"} blah";
|
||||
String display = CommentUtils.getDisplayString(rawComment, program);
|
||||
assertEquals("Test quote} blah", display);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAddressAnnotation_BackslashAndEscapedBrace() {
|
||||
String rawComment = "Test {@address 0 \"quote\\\\}\"} blah";
|
||||
String display = CommentUtils.getDisplayString(rawComment, program);
|
||||
assertEquals("Test quote\\} blah", display);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAddressAnnotation_BackslashBackslash() {
|
||||
String rawComment = "Test {@address 0 \"quote\\\\\"} blah";
|
||||
String display = CommentUtils.getDisplayString(rawComment, program);
|
||||
assertEquals("Test quote\\ blah", display);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAddressAnnotation_LonelyBackslash() {
|
||||
String rawComment = "Test {@address 0 bo\\b} some text";
|
||||
String display = CommentUtils.getDisplayString(rawComment, program);
|
||||
assertEquals("Test bo\\b some text", display);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSymbolAnnotation_FullyEscaped() {
|
||||
// We currently don't support rendering escaped annotation characters unless they are
|
||||
// inside of an annotation.
|
||||
String rawComment = "This is a symbol \\{@sym bob\\} annotation";
|
||||
String display = CommentUtils.getDisplayString(rawComment, program);
|
||||
assertEquals(rawComment, display);
|
||||
assertEquals("This is a symbol \\{@sym bob\\} annotation", display);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSymbolAnnotation_LonelyBackslash() {
|
||||
// We currently don't support rendering escaped annotation characters unless they are
|
||||
// inside of an annotation.
|
||||
String rawComment = "This is a symbol {@sym bob jo\\e} annotation";
|
||||
String display = CommentUtils.getDisplayString(rawComment, program);
|
||||
|
||||
// Note: Symbol Annotations ignore display text which means that the symbol name
|
||||
assertEquals("This is a symbol bob annotation", display);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -37,7 +37,7 @@ public class CommentUtilsTest extends AbstractGhidraHeadlessIntegrationTest {
|
||||
@Test
|
||||
public void testGetCommentAnnotations_PlainAnnotation() {
|
||||
|
||||
String comment = "This is an {@symbol symbolName}";
|
||||
String comment = "This is a {@symbol symbolName}";
|
||||
List<WordLocation> annotations = CommentUtils.getCommentAnnotations(comment);
|
||||
assertEquals(1, annotations.size());
|
||||
WordLocation word = annotations.get(0);
|
||||
@ -47,7 +47,7 @@ public class CommentUtilsTest extends AbstractGhidraHeadlessIntegrationTest {
|
||||
@Test
|
||||
public void testGetCommentAnnotations_QuotedAnnotation() {
|
||||
|
||||
String comment = "This is an {@symbol \"symbolName\"}";
|
||||
String comment = "This is a {@symbol \"symbolName\"}";
|
||||
List<WordLocation> annotations = CommentUtils.getCommentAnnotations(comment);
|
||||
assertEquals(1, annotations.size());
|
||||
WordLocation word = annotations.get(0);
|
||||
@ -57,7 +57,7 @@ public class CommentUtilsTest extends AbstractGhidraHeadlessIntegrationTest {
|
||||
@Test
|
||||
public void testGetCommentAnnotations_QuotedAnnotation_WithEscapedQuotes() {
|
||||
|
||||
String comment = "This is an {@symbol \"symbol\\\"Name\\\"\"}";
|
||||
String comment = "This is a {@symbol \"symbol\\\"Name\\\"\"}";
|
||||
List<WordLocation> annotations = CommentUtils.getCommentAnnotations(comment);
|
||||
assertEquals(1, annotations.size());
|
||||
WordLocation word = annotations.get(0);
|
||||
@ -67,7 +67,7 @@ public class CommentUtilsTest extends AbstractGhidraHeadlessIntegrationTest {
|
||||
@Test
|
||||
public void testGetCommentAnnotations_QuotedAnnotationWithBraces() {
|
||||
|
||||
String comment = "This is an {@symbol \"symbol{Name}\"}";
|
||||
String comment = "This is a {@symbol \"symbol{Name}\"}";
|
||||
List<WordLocation> annotations = CommentUtils.getCommentAnnotations(comment);
|
||||
assertEquals(1, annotations.size());
|
||||
WordLocation word = annotations.get(0);
|
||||
@ -79,7 +79,7 @@ public class CommentUtilsTest extends AbstractGhidraHeadlessIntegrationTest {
|
||||
|
||||
// the second brace is ignored (if the first brace is part of the symbol name, then it
|
||||
// needs to be escaped or quoted
|
||||
String comment = "This is an {@symbol symbol{Name}}";
|
||||
String comment = "This is a {@symbol symbol{Name}}";
|
||||
List<WordLocation> annotations = CommentUtils.getCommentAnnotations(comment);
|
||||
assertEquals(1, annotations.size());
|
||||
WordLocation word = annotations.get(0);
|
||||
@ -90,7 +90,7 @@ public class CommentUtilsTest extends AbstractGhidraHeadlessIntegrationTest {
|
||||
public void testGetCommentAnnotations_UnquotedAnnotation_WithUnbalancedBraces() {
|
||||
|
||||
// the second brace is ignored
|
||||
String comment = "This is an {@symbol symbolName}}";
|
||||
String comment = "This is a {@symbol symbolName}}";
|
||||
List<WordLocation> annotations = CommentUtils.getCommentAnnotations(comment);
|
||||
assertEquals(1, annotations.size());
|
||||
WordLocation word = annotations.get(0);
|
||||
@ -101,16 +101,17 @@ public class CommentUtilsTest extends AbstractGhidraHeadlessIntegrationTest {
|
||||
public void testGetCommentAnnotations_UnquotedAnnotation_WithEscapedBraces() {
|
||||
|
||||
// escaped braces get ignored
|
||||
String comment = "This is an {@symbol symbol\\{Name\\}}";
|
||||
String comment = "This is a {@symbol symbol\\{Name\\}}";
|
||||
List<WordLocation> annotations = CommentUtils.getCommentAnnotations(comment);
|
||||
assertEquals(1, annotations.size());
|
||||
WordLocation word = annotations.get(0);
|
||||
assertEquals("{@symbol symbol\\{Name\\}}", word.getWord());
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testSanitize() {
|
||||
|
||||
|
||||
String comment = null;
|
||||
String sanitized = CommentUtils.sanitize(comment);
|
||||
assertNull(sanitized);
|
||||
|
@ -53,12 +53,6 @@ public class FcgComponent extends GraphComponent<FcgVertex, FcgEdge, FunctionCal
|
||||
build();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setGraph(FunctionCallGraph g) {
|
||||
this.fcGraph = g;
|
||||
super.setGraph(g);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected FcgVertex getInitialVertex() {
|
||||
return fcGraph.getSource();
|
||||
|
Loading…
Reference in New Issue
Block a user