GP-4223: Fix case-insenstive search in Terminal window.

This commit is contained in:
Dan 2024-01-19 15:46:59 -05:00
parent 1e0145401b
commit fb9cbdf7ed
2 changed files with 103 additions and 11 deletions

View file

@ -73,11 +73,7 @@ public abstract class TerminalFinder {
this.wholeWord = options.contains(FindOptions.WHOLE_WORD); this.wholeWord = options.contains(FindOptions.WHOLE_WORD);
} }
protected void lowerBuf(StringBuilder sb) { protected abstract void caseBuf(StringBuilder sb);
for (int i = 0; i < sb.length(); i++) {
sb.setCharAt(i, Character.toLowerCase(sb.charAt(i)));
}
}
protected boolean isWholeWord(int i, String match) { protected boolean isWholeWord(int i, String match) {
if (i > 0 && VtLine.isWordChar(sb.charAt(i - 1))) { if (i > 0 && VtLine.isWordChar(sb.charAt(i - 1))) {
@ -113,9 +109,7 @@ public abstract class TerminalFinder {
VtLine line = layout.line; VtLine line = layout.line;
sb.delete(0, sb.length()); sb.delete(0, sb.length());
line.gatherText(sb, 0, line.length()); line.gatherText(sb, 0, line.length());
if (!caseSensitive) { caseBuf(sb);
lowerBuf(sb);
}
int s; int s;
if (index.equals(cur.getIndex())) { if (index.equals(cur.getIndex())) {
s = cur.getCol(); s = cur.getCol();
@ -166,8 +160,13 @@ public abstract class TerminalFinder {
if (text.isEmpty()) { if (text.isEmpty()) {
throw new IllegalArgumentException("Empty text"); throw new IllegalArgumentException("Empty text");
} }
if (!caseSensitive) {
this.text = text.toLowerCase();
}
else {
this.text = text; this.text = text;
} }
}
@Override @Override
protected FieldRange findInLine(int start, BigInteger index) { protected FieldRange findInLine(int start, BigInteger index) {
@ -188,6 +187,19 @@ public abstract class TerminalFinder {
} }
return null; return null;
} }
protected void lowerBuf(StringBuilder sb) {
for (int i = 0; i < sb.length(); i++) {
sb.setCharAt(i, Character.toLowerCase(sb.charAt(i)));
}
}
@Override
protected void caseBuf(StringBuilder sb) {
if (!caseSensitive) {
lowerBuf(sb);
}
}
} }
/** /**
@ -205,8 +217,13 @@ public abstract class TerminalFinder {
if (pattern.isEmpty()) { if (pattern.isEmpty()) {
throw new IllegalArgumentException("Empty pattern"); throw new IllegalArgumentException("Empty pattern");
} }
if (!caseSensitive) {
this.pattern = Pattern.compile(pattern, Pattern.CASE_INSENSITIVE);
}
else {
this.pattern = Pattern.compile(pattern); this.pattern = Pattern.compile(pattern);
} }
}
@Override @Override
protected FieldRange findInLine(int start, BigInteger index) { protected FieldRange findInLine(int start, BigInteger index) {
@ -246,5 +263,10 @@ public abstract class TerminalFinder {
new FieldLocation(index, 0, 0, lastStart), new FieldLocation(index, 0, 0, lastStart),
new FieldLocation(index, 0, 0, lastEnd)); new FieldLocation(index, 0, 0, lastEnd));
} }
@Override
protected void caseBuf(StringBuilder sb) {
// Nothing. Pattern handles it.
}
} }
} }

View file

@ -150,7 +150,7 @@ public class TerminalProviderTest extends AbstractGhidraHeadedDebuggerTest {
@Test @Test
@SuppressWarnings("resource") @SuppressWarnings("resource")
public void testFindSimple() throws Exception { public void testFindText() throws Exception {
terminalService = addPlugin(tool, TerminalPlugin.class); terminalService = addPlugin(tool, TerminalPlugin.class);
try (DefaultTerminal term = (DefaultTerminal) terminalService try (DefaultTerminal term = (DefaultTerminal) terminalService
@ -180,6 +180,38 @@ public class TerminalProviderTest extends AbstractGhidraHeadedDebuggerTest {
} }
} }
@Test
@SuppressWarnings("resource")
public void testFindTextCaps() throws Exception {
terminalService = addPlugin(tool, TerminalPlugin.class);
try (DefaultTerminal term = (DefaultTerminal) terminalService
.createNullTerminal(Charset.forName("UTF-8"), buf -> {
})) {
term.setFixedSize(80, 25);
term.injectDisplayOutput(TEST_CONTENTS);
term.provider.findDialog.txtFind.setText("TERM");
performAction(term.provider.actionFindNext, false);
waitForPass(() -> assertSingleSelection(0, 0, 4,
term.provider.panel.fieldPanel.getSelection()));
performAction(term.provider.actionFindNext, false);
waitForPass(() -> assertSingleSelection(0, 5, 9,
term.provider.panel.fieldPanel.getSelection()));
performAction(term.provider.actionFindNext, false);
waitForPass(() -> assertSingleSelection(1, 2, 6,
term.provider.panel.fieldPanel.getSelection()));
performAction(term.provider.actionFindNext, false);
OkDialog dialog = waitForInfoDialog();
assertEquals("String not found", dialog.getMessage());
dialog.close();
}
}
@Test @Test
@SuppressWarnings("resource") @SuppressWarnings("resource")
public void testFindCaseSensitive() throws Exception { public void testFindCaseSensitive() throws Exception {
@ -308,6 +340,44 @@ public class TerminalProviderTest extends AbstractGhidraHeadedDebuggerTest {
} }
} }
@Test
@SuppressWarnings("resource")
public void testFindRegexCaps() throws Exception {
terminalService = addPlugin(tool, TerminalPlugin.class);
try (DefaultTerminal term = (DefaultTerminal) terminalService
.createNullTerminal(Charset.forName("UTF-8"), buf -> {
})) {
term.setFixedSize(80, 25);
term.injectDisplayOutput(TEST_CONTENTS);
term.provider.findDialog.txtFind.setText("o?TERM");
term.provider.findDialog.cbRegex.setSelected(true);
performAction(term.provider.actionFindNext, false);
waitForPass(() -> assertSingleSelection(0, 0, 4,
term.provider.panel.fieldPanel.getSelection()));
performAction(term.provider.actionFindNext, false);
waitForPass(() -> assertSingleSelection(0, 5, 9,
term.provider.panel.fieldPanel.getSelection()));
performAction(term.provider.actionFindNext, false);
waitForPass(() -> assertSingleSelection(1, 1, 6,
term.provider.panel.fieldPanel.getSelection()));
// NB. the o is optional, so it finds a subrange of the previous result
performAction(term.provider.actionFindNext, false);
waitForPass(() -> assertSingleSelection(1, 2, 6,
term.provider.panel.fieldPanel.getSelection()));
performAction(term.provider.actionFindNext, false);
OkDialog dialog = waitForInfoDialog();
assertEquals("String not found", dialog.getMessage());
dialog.close();
}
}
@Test @Test
@SuppressWarnings("resource") @SuppressWarnings("resource")
public void testFindPrevious() throws Exception { public void testFindPrevious() throws Exception {