GP-4709: post-post-post review

GP-4709: post=post review - test logic in error
GP-4709: post=post review - test logic in error
GP-4709: post-review fixes
GP-4709: going for simplicity
GP-4709: reverting most stuff
GP-4709: fix for replaceValue logic
GP-4709: extensions to HexInteger
This commit is contained in:
d-millar
2024-06-26 09:09:28 -04:00
parent 5ab72bf4f2
commit ae3f6feb70
13 changed files with 1099 additions and 234 deletions

View File

@@ -87,17 +87,41 @@
<p>This view does not support <a href="#EditBytes">editing</a>.</p>
</blockquote>
<h3><a name="Add_Byteviewer_HexInteger_Panel"></a><a name="HexInteger"></a>HexInteger </h3>
<h3><a name="Add_Byteviewer_HexShortPanel"></a><a name="HexShort"></a>Hex Short</h3>
<blockquote>
<p>This format shows four byte numbers represented as an eight digit hex number.&nbsp;</p>
<p>This format shows two-byte numbers represented as an four-digit hex number.&nbsp;</p>
<p> This view supports <a href="#EditBytes">editing</a>. When a byte
is changed, both bytes associated with this address are rendered in
<font color="#ff0000"> red</font> to denote the change.</p>
</blockquote>
<h3><a name="Add_Byteviewer_HexInteger_Panel"></a><a name="HexInteger"></a>Hex Integer</h3>
<blockquote>
<p>This format shows four-byte numbers represented as an eight-digit hex number.&nbsp;</p>
<p> This view supports <a href="#EditBytes">editing</a>. When a byte
is changed, all four bytes associated with this address are rendered in
<font color="#ff0000"> red</font> to denote the change.</p>
</blockquote>
<h3><a name="Add_Byteviewer_HexLong_Panel"></a><a name="HexLongr"></a>Hex Long</h3>
<blockquote>
<p>This format shows eight-byte numbers represented as an 16-digit hex number.&nbsp;</p>
<p> This view supports <a href="#EditBytes">editing</a>. When a byte
is changed, all eight bytes associated with this address are rendered in
<font color="#ff0000"> red</font> to denote the change.</p>
</blockquote>
<h3><a name="Add_Byteviewer_HexLongLong_Panel"></a><a name="HexLongLong"></a>Hex Long Long</h3>
<blockquote>
<p>This format shows 16-byte numbers represented as an 32-digit hex number.&nbsp;</p>
<p> This view supports <a href="#EditBytes">editing</a>. When a byte
is changed, all 16 bytes associated with this address are rendered in
<font color="#ff0000"> red</font> to denote the change.</p>
</blockquote>
<h3><a name="Add_Byteviewer_Integer_Panel"></a><a name="Integer"></a>Integer&nbsp; </h3>
<blockquote>
<p>This view shows four byte numbers represented in decimal format.&nbsp;</p>
<p>This view shows four-byte numbers represented in decimal format.&nbsp;</p>
<p> This view does not support <a href="#EditBytes">editing</a>.</p>
</blockquote>

View File

@@ -912,9 +912,8 @@ public class ByteViewerComponent extends FieldPanel implements FieldMouseListene
ByteField getField(BigInteger index, int fieldNum) {
if (indexMap != null) {
int fieldOffset = indexMap.getFieldOffset(index, fieldNum, fieldFactories);
if (fieldNum < fieldFactories.length) {
return (ByteField) fieldFactories[fieldOffset].getField(index);
return (ByteField) fieldFactories[fieldNum].getField(index);
}
}
return null;

View File

@@ -78,6 +78,19 @@ class FileByteBlock implements ByteBlock {
return 0;
}
/* (non-Javadoc)
* @see ghidra.app.plugin.core.format.ByteBlock#getShort(int)
*/
public short getShort(BigInteger bigIndex) throws ByteBlockAccessException {
int index = bigIndex.intValue();
if (index < buf.length) {
byte[] b = new byte[2];
System.arraycopy(buf, index, b, 0, b.length);
return converter.getShort(b);
}
return 0;
}
/* (non-Javadoc)
* @see ghidra.app.plugin.core.format.ByteBlock#getInt(int)
*/
@@ -114,6 +127,18 @@ class FileByteBlock implements ByteBlock {
}
}
/* (non-Javadoc)
* @see ghidra.app.plugin.core.format.ByteBlock#setShort(int, short)
*/
public void setShort(BigInteger bigIndex, short value) throws ByteBlockAccessException {
int index = bigIndex.intValue();
if (index < buf.length) {
byte[] b = new byte[2];
converter.putShort(b, 0, value);
System.arraycopy(b, 0, buf, index, b.length);
}
}
/* (non-Javadoc)
* @see ghidra.app.plugin.core.format.ByteBlock#setInt(int, int)
*/

View File

@@ -225,6 +225,44 @@ public class MemoryByteBlock implements ByteBlock {
}
}
/**
* Get the short value at the given index.
*
* @param index byte index
* @throws ByteBlockAccessException if the block cannot be read
* @throws IndexOutOfBoundsException if the given index is not in this block.
*/
@Override
public short getShort(BigInteger index) throws ByteBlockAccessException {
Address addr = getAddress(index);
try {
return memory.getShort(addr, bigEndian);
}
catch (MemoryAccessException e) {
throw new ByteBlockAccessException(e.getMessage());
}
}
/**
* Set the short at the given index.
*
* @param index byte index
* @param value value to set
* @throws ByteBlockAccessException if the block cannot be updated
* @throws IndexOutOfBoundsException if the given index is not in this block.
*/
@Override
public void setShort(BigInteger index, short value) throws ByteBlockAccessException {
Address addr = getAddress(index);
checkEditsAllowed(addr, 2);
try {
memory.setShort(addr, value, bigEndian);
}
catch (MemoryAccessException e) {
throw new ByteBlockAccessException(e.getMessage());
}
}
/**
* Return true if this block can be modified.
*/

View File

@@ -61,6 +61,15 @@ public interface ByteBlock {
return true;
}
/**
* Get the short value at the given index.
* @param index byte index
* @throws ByteBlockAccessException if the block cannot be read
* @throws IndexOutOfBoundsException if the given index is not in this
* block.
*/
public short getShort(BigInteger index) throws ByteBlockAccessException;
/**
* Get the int value at the given index.
* @param index byte index
@@ -89,6 +98,16 @@ public interface ByteBlock {
*/
public void setByte(BigInteger index, byte value) throws ByteBlockAccessException;
/**
* Set the short at the given index.
* @param index byte index
* @param value value to set
* @throws ByteBlockAccessException if the block cannot be updated
* @throws IndexOutOfBoundsException if the given index is not in this
* block.
*/
public void setShort(BigInteger index, short value) throws ByteBlockAccessException;
/**
* Set the int at the given index.
* @param index byte index

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.
@@ -16,236 +15,22 @@
*/
package ghidra.app.plugin.core.format;
import ghidra.util.HelpLocation;
import java.math.BigInteger;
/**
* Converts byte values to Integer represented as an 8 digit hex number.
* Converts byte values to Integer represented as an 4-byte/8-digit hex number.
*/
public class HexIntegerFormatModel implements UniversalDataFormatModel {
private int symbolSize;
public class HexIntegerFormatModel extends HexValueFormatModel {
public HexIntegerFormatModel() {
symbolSize = 8;
super("Hex Integer", 4);
}
/**
* Get the name of this formatter.
*/
public String getName() {
return "HexInteger";
}
/**
* Get the number of bytes to make a unit; in this case,
* returns 4.
*/
public int getUnitByteSize() {
return 4;
}
/**
* Returns the byte used to generate the character at a given
* position.
* @param position number in the range 0 to 7
*/
public int getByteOffset(ByteBlock block, int position) {
int o = position / 2;
if (block.isBigEndian()) {
return o;
}
return 3 - o;
}
/**
* Given the byte offset into a unit, get the column position.
*/
public int getColumnPosition(ByteBlock block, int byteOffset) {
if (byteOffset > 3) {
throw new IllegalArgumentException("invalid byteOffset: " + byteOffset);
}
if (block.isBigEndian()) {
return byteOffset * 2;
}
return (3 - byteOffset) * 2;
}
/**
* Gets the number of characters required to display a
* unit.
* @return 4 for number of characters in the integer representation.
*/
public int getDataUnitSymbolSize() {
return symbolSize;
}
/**
* Gets the string representation at the given index in the block.
* @param block block to change
* @param index byte index into the block
* @throws ByteBlockAccessException if the block cannot be read
* @throws IndexOutOfBoundsException if index is not valid for the
* block
*/
@Override
public String getDataRepresentation(ByteBlock block, BigInteger index)
throws ByteBlockAccessException {
int i = block.getInt(index);
String str = Integer.toHexString(i);
return pad(str);
}
/**
* Returns true to allow values to be changed.
*/
public boolean isEditable() {
return true;
}
/**
* Overwrite a value in a ByteBlock.
* @param block block to change
* @param index byte index into the block
* @param pos The position within the unit where c will be the
* new character.
* @param c new character to put at pos param
* @return true if the replacement is legal, false if the
* replacement value would not make sense for this format, e.g.
* attempt to put a 'z' in a hex unit.
* @throws ByteBlockAccessException if the block cannot be updated
* @throws IndexOutOfBoundsException if index is not valid for the
* block
*/
public boolean replaceValue(ByteBlock block, BigInteger index, int charPosition, char c)
throws ByteBlockAccessException {
if (charPosition < 0 || charPosition > symbolSize - 1) {
return false;
}
char[] charArray = { c };
String s = new String(charArray);
try {
Integer.parseInt(s, 16);
}
catch (Exception e) {
return false;
}
byte cb = Byte.parseByte(new String(charArray), 16);
// get the correct byte offset based on position
int byteOffset = getByteOffset(block, charPosition);
BigInteger saveIndex = index;
index = index.add(BigInteger.valueOf(byteOffset));
byte b = block.getByte(index);
b = adjustByte(b, cb, charPosition);
int intValue = getInt(block, saveIndex, b, byteOffset);
block.setInt(saveIndex, intValue);
return true;
}
/**
* Get number of units in a group. A group may represent
* multiple units shown as one entity. This format does not
* support groups.
*/
public int getGroupSize() {
return 1;
}
/**
* Set the number of units in a group. This format does not
* support groups.
* @throws UnsupportedOperationException
*/
public void setGroupSize(int groupSize) {
throw new UnsupportedOperationException("groups are not supported");
}
/**
* Get the number of characters separating units.
*/
public int getUnitDelimiterSize() {
return 1;
}
/**
* @see ghidra.app.plugin.core.format.DataFormatModel#validateBytesPerLine(int)
*/
public boolean validateBytesPerLine(int bytesPerLine) {
return bytesPerLine % 4 == 0;
}
/////////////////////////////////////////////////////////////////
// *** private methods ***
/////////////////////////////////////////////////////////////////
/**
* Returns value with leading zeros.
*/
private String pad(String value) {
StringBuffer sb = new StringBuffer();
int len = symbolSize - value.length();
for (int i = 0; i < len; i++) {
sb.append("0");
}
sb.append(value);
return sb.toString();
}
/**
* adjust byte b to use either the upper 4 bits or
* the lower 4 bits of newb according to charPosition.
*/
private byte adjustByte(byte b, byte newb, int charPosition) {
if (charPosition % 2 == 0) {
// its the high order byte
b &= 0x0f;
newb <<= 4;
}
else {
b &= 0xf0;
}
b += newb;
return b;
}
private int getInt(ByteBlock block, BigInteger offset, byte newb, int byteOffset) {
byte[] b = new byte[4];
try {
for (int i = 0; i < b.length; i++) {
b[i] = block.getByte(offset.add(BigInteger.valueOf(i)));
}
b[byteOffset] = newb;
if (block.isBigEndian()) {
return (b[0] << 24) | ((b[1] << 16) & 0x00FF0000) | ((b[2] << 8) & 0x0000FF00) |
(b[3] & 0x000000FF);
}
return (b[3] << 24) | ((b[2] << 16) & 0x00FF0000) | ((b[1] << 8) & 0x0000FF00) |
(b[0] & 0x000000FF);
}
catch (ByteBlockAccessException e) {
}
return 0;
}
/* (non-Javadoc)
* @see ghidra.app.plugin.format.DataFormatModel#getHelpLocation()
*/
public HelpLocation getHelpLocation() {
return new HelpLocation("ByteViewerPlugin", "HexInteger");
}
public void dispose() {
}
}

View File

@@ -0,0 +1,36 @@
/* ###
* 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.plugin.core.format;
import java.math.BigInteger;
/**
* Converts byte values to Long represented as an 8-byte/16--digit hex number.
*/
public class HexLongFormatModel extends HexValueFormatModel {
public HexLongFormatModel() {
super("Hex Long", 8);
}
@Override
public String getDataRepresentation(ByteBlock block, BigInteger index)
throws ByteBlockAccessException {
long l = block.getLong(index);
String str = Long.toHexString(l);
return pad(str);
}
}

View File

@@ -0,0 +1,39 @@
/* ###
* 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.plugin.core.format;
import java.math.BigInteger;
/**
* Converts byte values to LongLong represented as an 16-byte/32-digit hex number.
*/
public class HexLongLongFormatModel extends HexValueFormatModel {
public HexLongLongFormatModel() {
super("Hex Long Long", 16);
}
@Override
public String getDataRepresentation(ByteBlock block, BigInteger index)
throws ByteBlockAccessException {
long l0 = block.getLong(index);
String str0 = pad(Long.toHexString(l0));
long l1 = block.getLong(index.add(BigInteger.valueOf(8)));
String str1 = pad(Long.toHexString(l1));
String str = str1.substring(16) + str0.substring(16);
return pad(str);
}
}

View File

@@ -0,0 +1,36 @@
/* ###
* 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.plugin.core.format;
import java.math.BigInteger;
/**
* Converts byte values to Short represented as an 2-byte/4-digit hex number.
*/
public class HexShortFormatModel extends HexValueFormatModel {
public HexShortFormatModel() {
super("Hex Short", 2);
}
@Override
public String getDataRepresentation(ByteBlock block, BigInteger index)
throws ByteBlockAccessException {
short s = block.getShort(index);
String str = Integer.toHexString(s & 0xFFFF);
return pad(str);
}
}

View File

@@ -0,0 +1,167 @@
/* ###
* 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.plugin.core.format;
import java.math.BigInteger;
import ghidra.util.HelpLocation;
/**
* Converts byte values to value represented as a 2, 4, 8, or 16-byte hex number.
*/
public abstract class HexValueFormatModel implements UniversalDataFormatModel {
protected String name;
private int symbolSize;
protected int nbytes;
public HexValueFormatModel(String name, int nbytes) {
this.name = name;
this.nbytes = nbytes;
symbolSize = nbytes * 2;
}
@Override
public String getName() {
return name;
}
@Override
public int getUnitByteSize() {
return nbytes;
}
@Override
public int getByteOffset(ByteBlock block, int position) {
int o = position / 2;
if (block.isBigEndian()) {
return o;
}
return nbytes - 1 - o;
}
@Override
public int getColumnPosition(ByteBlock block, int byteOffset) {
if (byteOffset > nbytes - 1) {
throw new IllegalArgumentException("invalid byteOffset: " + byteOffset);
}
if (block.isBigEndian()) {
return byteOffset * 2;
}
return (nbytes - 1 - byteOffset) * 2;
}
@Override
public int getDataUnitSymbolSize() {
return symbolSize;
}
@Override
public abstract String getDataRepresentation(ByteBlock block, BigInteger index)
throws ByteBlockAccessException;
@Override
public boolean isEditable() {
return true;
}
@Override
public boolean replaceValue(ByteBlock block, BigInteger index, int charPosition, char c)
throws ByteBlockAccessException {
if (charPosition < 0 || charPosition > symbolSize - 1) {
// Not sure how this is possible, but...
return false;
}
char[] charArray = { c };
byte cb = Byte.parseByte(new String(charArray), 16);
// get the correct byte offset based on position
int byteOffset = getByteOffset(block, charPosition);
index = index.add(BigInteger.valueOf(byteOffset));
byte b = block.getByte(index);
b = adjustByte(b, cb, charPosition);
block.setByte(index, b);
return true;
}
@Override
public int getGroupSize() {
return 1;
}
/**
* Set the number of units in a group. This format does not
* support groups.
*/
@Override
public void setGroupSize(int groupSize) {
throw new UnsupportedOperationException("groups are not supported");
}
@Override
public int getUnitDelimiterSize() {
return 1;
}
@Override
public boolean validateBytesPerLine(int bytesPerLine) {
return bytesPerLine % nbytes == 0;
}
/**
* Returns value with leading zeros.
*/
protected String pad(String value) {
StringBuffer sb = new StringBuffer();
int len = symbolSize - value.length();
for (int i = 0; i < len; i++) {
sb.append("0");
}
sb.append(value);
return sb.toString();
}
/**
* adjust byte b to use either the upper 4 bits or
* the lower 4 bits of newb according to charPosition.
*/
private byte adjustByte(byte b, byte newb, int charPosition) {
if (charPosition % 2 == 0) {
// its the high order byte
b &= 0x0f;
newb <<= 4;
}
else {
b &= 0xf0;
}
b += newb;
return b;
}
@Override
public HelpLocation getHelpLocation() {
return new HelpLocation("ByteViewerPlugin", "HexValue");
}
@Override
public void dispose() {
}
}

View File

@@ -305,7 +305,7 @@ public class ByteViewerPlugin2Test extends AbstractGhidraHeadedIntegrationTest {
field = asciiC.getField(loc.getIndex(), loc.getFieldNum());
assertEquals(ByteViewerComponentProvider.CHANGED_VALUE_COLOR, field.getForeground());
final ByteViewerComponent hexIntC = findComponent(panel, "HexInteger");
final ByteViewerComponent hexIntC = findComponent(panel, "Hex Integer");
SwingUtilities.invokeAndWait(() -> panel.setCurrentView(hexIntC));
loc = getFieldLocation(addr);
@@ -456,14 +456,14 @@ public class ByteViewerPlugin2Test extends AbstractGhidraHeadedIntegrationTest {
}
@Test
public void testUndoRedoHexInteger() throws Exception {
public void testUndoRedoHexShort() throws Exception {
env.showTool();
addViews();
final Address addr = getAddr(0x01001003);
final ToggleDockingAction action =
(ToggleDockingAction) getAction(plugin, "Enable/Disable Byteviewer Editing");
ByteViewerComponent c = findComponent(panel, "HexInteger");
ByteViewerComponent c = findComponent(panel, "Hex Short");
panel.setCurrentView(c);
SwingUtilities.invokeAndWait(() -> {
@@ -504,6 +504,228 @@ public class ByteViewerPlugin2Test extends AbstractGhidraHeadedIntegrationTest {
}
@Test
public void testUndoRedoHexInteger() throws Exception {
env.showTool();
addViews();
final Address addr = getAddr(0x01001003);
final ToggleDockingAction action =
(ToggleDockingAction) getAction(plugin, "Enable/Disable Byteviewer Editing");
ByteViewerComponent c = findComponent(panel, "Hex Integer");
panel.setCurrentView(c);
SwingUtilities.invokeAndWait(() -> {
FieldLocation loc = getFieldLocation(addr);
ByteViewerComponent currentComponent = panel.getCurrentComponent();
currentComponent.setCursorPosition(loc.getIndex(), loc.getFieldNum(), loc.getRow(),
loc.getCol());
action.setSelected(true);
action.actionPerformed(new DefaultActionContext());
});
byte value = program.getMemory().getByte(addr);
SwingUtilities.invokeAndWait(() -> {
ByteViewerComponent currentComponent = panel.getCurrentComponent();
FieldLocation loc = getFieldLocation(addr);
KeyEvent ev =
new KeyEvent(currentComponent, 0, new Date().getTime(), 0, KeyEvent.VK_A, 'a');
currentComponent.keyPressed(ev, loc.getIndex(), loc.getFieldNum(), loc.getRow(),
loc.getCol(), currentComponent.getCurrentField());
});
program.flushEvents();
assertEquals((byte) 0xa0, memory.getByte(addr));
undo(program);
assertEquals(value, memory.getByte(addr));
FieldLocation loc = getFieldLocation(addr);
ByteField field = c.getField(loc.getIndex(), loc.getFieldNum());
Color fg = field.getForeground();
assertTrue(fg == null ||
ByteViewerComponentProvider.CURSOR_NON_ACTIVE_COLOR == field.getForeground());
redo(program);
// field color should show edit color
loc = getFieldLocation(addr);
field = c.getField(loc.getIndex(), loc.getFieldNum());
assertEquals(ByteViewerComponentProvider.CHANGED_VALUE_COLOR, field.getForeground());
}
@Test
public void testUndoRedoHexLong() throws Exception {
env.showTool();
addViews();
final Address addr = getAddr(0x01001003);
final ToggleDockingAction action =
(ToggleDockingAction) getAction(plugin, "Enable/Disable Byteviewer Editing");
ByteViewerComponent c = findComponent(panel, "Hex Long");
panel.setCurrentView(c);
SwingUtilities.invokeAndWait(() -> {
FieldLocation loc = getFieldLocation(addr);
ByteViewerComponent currentComponent = panel.getCurrentComponent();
currentComponent.setCursorPosition(loc.getIndex(), loc.getFieldNum(), loc.getRow(),
loc.getCol());
action.setSelected(true);
action.actionPerformed(new DefaultActionContext());
});
byte value = program.getMemory().getByte(addr);
SwingUtilities.invokeAndWait(() -> {
ByteViewerComponent currentComponent = panel.getCurrentComponent();
FieldLocation loc = getFieldLocation(addr);
KeyEvent ev =
new KeyEvent(currentComponent, 0, new Date().getTime(), 0, KeyEvent.VK_A, 'a');
currentComponent.keyPressed(ev, loc.getIndex(), loc.getFieldNum(), loc.getRow(),
loc.getCol(), currentComponent.getCurrentField());
});
program.flushEvents();
assertEquals((byte) 0xa0, memory.getByte(addr));
undo(program);
assertEquals(value, memory.getByte(addr));
FieldLocation loc = getFieldLocation(addr);
ByteField field = c.getField(loc.getIndex(), loc.getFieldNum());
Color fg = field.getForeground();
assertTrue(fg == null ||
ByteViewerComponentProvider.CURSOR_NON_ACTIVE_COLOR == field.getForeground());
redo(program);
// field color should show edit color
loc = getFieldLocation(addr);
field = c.getField(loc.getIndex(), loc.getFieldNum());
assertEquals(ByteViewerComponentProvider.CHANGED_VALUE_COLOR, field.getForeground());
}
@Test
public void testUndoRedoHexLongLong() throws Exception {
env.showTool();
addViews();
final Address addr = getAddr(0x01001003);
final ToggleDockingAction action =
(ToggleDockingAction) getAction(plugin, "Enable/Disable Byteviewer Editing");
ByteViewerComponent c = findComponent(panel, "Hex Long Long");
panel.setCurrentView(c);
SwingUtilities.invokeAndWait(() -> {
FieldLocation loc = getFieldLocation(addr);
ByteViewerComponent currentComponent = panel.getCurrentComponent();
currentComponent.setCursorPosition(loc.getIndex(), loc.getFieldNum(), loc.getRow(),
loc.getCol());
action.setSelected(true);
action.actionPerformed(new DefaultActionContext());
});
byte value = program.getMemory().getByte(addr);
SwingUtilities.invokeAndWait(() -> {
ByteViewerComponent currentComponent = panel.getCurrentComponent();
FieldLocation loc = getFieldLocation(addr);
KeyEvent ev =
new KeyEvent(currentComponent, 0, new Date().getTime(), 0, KeyEvent.VK_A, 'a');
currentComponent.keyPressed(ev, loc.getIndex(), loc.getFieldNum(), loc.getRow(),
loc.getCol(), currentComponent.getCurrentField());
});
program.flushEvents();
assertEquals((byte) 0xa0, memory.getByte(addr));
undo(program);
assertEquals(value, memory.getByte(addr));
FieldLocation loc = getFieldLocation(addr);
ByteField field = c.getField(loc.getIndex(), loc.getFieldNum());
Color fg = field.getForeground();
assertTrue(fg == null ||
ByteViewerComponentProvider.CURSOR_NON_ACTIVE_COLOR == field.getForeground());
redo(program);
// field color should show edit color
loc = getFieldLocation(addr);
field = c.getField(loc.getIndex(), loc.getFieldNum());
assertEquals(ByteViewerComponentProvider.CHANGED_VALUE_COLOR, field.getForeground());
}
@Test
public void testUndoRedoHexShort2() throws Exception {
// remove code browser plugin so the cursor position does not
// get changed because of location events that the code browser
// generates.
tool.removePlugins(new Plugin[] { cbPlugin });
env.showTool();
addViews();
ByteViewerComponent c = findComponent(panel, "Hex Short");
panel.setCurrentView(c);
// make 3 changes
// verify that the Undo button is enabled and undo can be done 5 times
final ToggleDockingAction action =
(ToggleDockingAction) getAction(plugin, "Enable/Disable Byteviewer Editing");
SwingUtilities.invokeAndWait(() -> {
Address addr = getAddr(0x01001003);
FieldLocation loc = getFieldLocation(addr);
ByteViewerComponent currentComponent = panel.getCurrentComponent();
currentComponent.setCursorPosition(loc.getIndex(), loc.getFieldNum(), 0, 0);
action.setSelected(true);
action.actionPerformed(new DefaultActionContext());
});
SwingUtilities.invokeAndWait(() -> {
char[] values = { 'a', '1', '2' };
int[] keyCodes =
{ KeyEvent.VK_P, KeyEvent.VK_1, KeyEvent.VK_2, KeyEvent.VK_B, KeyEvent.VK_3 };
ByteViewerComponent currentComponent = panel.getCurrentComponent();
for (int i = 0; i < 3; i++) {
FieldLocation loc = currentComponent.getCursorLocation();
KeyEvent ev = new KeyEvent(currentComponent, 0, new Date().getTime(), 0,
keyCodes[i], values[i]);
currentComponent.keyPressed(ev, loc.getIndex(), loc.getFieldNum(), loc.getRow(),
loc.getCol(), currentComponent.getCurrentField());
}
});
program.flushEvents();
waitForSwing();
for (int i = 0; i < 3; i++) {
assertTrue(program.canUndo());
undo(program);
FieldLocation loc = c.getCursorLocation();
ByteField field = c.getField(loc.getIndex(), loc.getFieldNum());
Color fg = field.getForeground();
if (i == 2) {
assertTrue(fg == null ||
ByteViewerComponentProvider.CURSOR_NON_ACTIVE_COLOR == field.getForeground());
}
else {
assertEquals(fg, ByteViewerComponentProvider.CHANGED_VALUE_COLOR);
}
}
assertTrue(!program.canUndo());
for (int i = 0; i < 3; i++) {
redo(program);
FieldLocation loc = c.getCursorLocation();
ByteField field = c.getField(loc.getIndex(), loc.getFieldNum());
Color fg = field.getForeground();
assertEquals(fg, ByteViewerComponentProvider.CHANGED_VALUE_COLOR);
}
assertTrue(program.canUndo());
}
@Test
public void testUndoRedoHexInteger2() throws Exception {
// remove code browser plugin so the cursor position does not
@@ -514,7 +736,7 @@ public class ByteViewerPlugin2Test extends AbstractGhidraHeadedIntegrationTest {
env.showTool();
addViews();
ByteViewerComponent c = findComponent(panel, "HexInteger");
ByteViewerComponent c = findComponent(panel, "Hex Integer");
panel.setCurrentView(c);
// make 5 changes
// verify that the Undo button is enabled and undo can be done 5 times
@@ -579,6 +801,160 @@ public class ByteViewerPlugin2Test extends AbstractGhidraHeadedIntegrationTest {
assertTrue(program.canUndo());
}
@Test
public void testUndoRedoHexLong2() throws Exception {
// remove code browser plugin so the cursor position does not
// get changed because of location events that the code browser
// generates.
tool.removePlugins(new Plugin[] { cbPlugin });
env.showTool();
addViews();
ByteViewerComponent c = findComponent(panel, "Hex Long");
panel.setCurrentView(c);
// make 9 changes
// verify that the Undo button is enabled and undo can be done 5 times
final ToggleDockingAction action =
(ToggleDockingAction) getAction(plugin, "Enable/Disable Byteviewer Editing");
SwingUtilities.invokeAndWait(() -> {
Address addr = getAddr(0x01001003);
FieldLocation loc = getFieldLocation(addr);
ByteViewerComponent currentComponent = panel.getCurrentComponent();
currentComponent.setCursorPosition(loc.getIndex(), loc.getFieldNum(), 0, 0);
action.setSelected(true);
action.actionPerformed(new DefaultActionContext());
});
SwingUtilities.invokeAndWait(() -> {
char[] values = { 'a', '1', '2', 'b', '3', 'c', '4', 'd', '5' };
int[] keyCodes =
{ KeyEvent.VK_P, KeyEvent.VK_1, KeyEvent.VK_2, KeyEvent.VK_B, KeyEvent.VK_3,
KeyEvent.VK_C, KeyEvent.VK_4, KeyEvent.VK_D, KeyEvent.VK_5 };
ByteViewerComponent currentComponent = panel.getCurrentComponent();
for (int i = 0; i < 9; i++) {
FieldLocation loc = currentComponent.getCursorLocation();
KeyEvent ev = new KeyEvent(currentComponent, 0, new Date().getTime(), 0,
keyCodes[i], values[i]);
currentComponent.keyPressed(ev, loc.getIndex(), loc.getFieldNum(), loc.getRow(),
loc.getCol(), currentComponent.getCurrentField());
}
});
program.flushEvents();
waitForSwing();
for (int i = 0; i < 9; i++) {
assertTrue(program.canUndo());
undo(program);
FieldLocation loc = c.getCursorLocation();
ByteField field = c.getField(loc.getIndex(), loc.getFieldNum());
Color fg = field.getForeground();
if (i == 8) {
assertTrue(fg == null ||
ByteViewerComponentProvider.CURSOR_NON_ACTIVE_COLOR == field.getForeground());
}
else {
assertEquals(fg, ByteViewerComponentProvider.CHANGED_VALUE_COLOR);
}
}
assertTrue(!program.canUndo());
for (int i = 0; i < 9; i++) {
redo(program);
FieldLocation loc = c.getCursorLocation();
ByteField field = c.getField(loc.getIndex(), loc.getFieldNum());
Color fg = field.getForeground();
assertEquals(fg, ByteViewerComponentProvider.CHANGED_VALUE_COLOR);
}
assertTrue(program.canUndo());
}
@Test
public void testUndoRedoHexLongLong2() throws Exception {
// remove code browser plugin so the cursor position does not
// get changed because of location events that the code browser
// generates.
tool.removePlugins(new Plugin[] { cbPlugin });
env.showTool();
addViews();
ByteViewerComponent c = findComponent(panel, "Hex Long Long");
panel.setCurrentView(c);
// make 9 changes
// verify that the Undo button is enabled and undo can be done 5 times
final ToggleDockingAction action =
(ToggleDockingAction) getAction(plugin, "Enable/Disable Byteviewer Editing");
SwingUtilities.invokeAndWait(() -> {
Address addr = getAddr(0x01001003);
FieldLocation loc = getFieldLocation(addr);
ByteViewerComponent currentComponent = panel.getCurrentComponent();
currentComponent.setCursorPosition(loc.getIndex(), loc.getFieldNum(), 0, 0);
action.setSelected(true);
action.actionPerformed(new DefaultActionContext());
});
SwingUtilities.invokeAndWait(() -> {
char[] values = { 'a', '1', '2', 'b', '3', 'c', '4', 'd', '5', 'e', '6', 'f', '7', 'a',
'8', 'b', '9' };
int[] keyCodes =
{ KeyEvent.VK_P, KeyEvent.VK_1, KeyEvent.VK_2, KeyEvent.VK_B, KeyEvent.VK_3,
KeyEvent.VK_C, KeyEvent.VK_4, KeyEvent.VK_D, KeyEvent.VK_5, KeyEvent.VK_E, KeyEvent.VK_6,
KeyEvent.VK_F, KeyEvent.VK_7, KeyEvent.VK_G, KeyEvent.VK_8, KeyEvent.VK_H, KeyEvent.VK_9 };
ByteViewerComponent currentComponent = panel.getCurrentComponent();
for (int i = 0; i < 17; i++) {
FieldLocation loc = currentComponent.getCursorLocation();
KeyEvent ev = new KeyEvent(currentComponent, 0, new Date().getTime(), 0,
keyCodes[i], values[i]);
currentComponent.keyPressed(ev, loc.getIndex(), loc.getFieldNum(), loc.getRow(),
loc.getCol(), currentComponent.getCurrentField());
}
});
program.flushEvents();
waitForSwing();
for (int i = 0; i < 17; i++) {
assertTrue(program.canUndo());
undo(program);
FieldLocation loc = c.getCursorLocation();
ByteField field = c.getField(loc.getIndex(), loc.getFieldNum());
Color fg = field.getForeground();
if (i == 16) {
assertTrue(fg == null ||
ByteViewerComponentProvider.CURSOR_NON_ACTIVE_COLOR == field.getForeground());
}
else {
assertEquals(fg, ByteViewerComponentProvider.CHANGED_VALUE_COLOR);
}
}
assertTrue(!program.canUndo());
for (int i = 0; i < 17; i++) {
redo(program);
FieldLocation loc = c.getCursorLocation();
ByteField field = c.getField(loc.getIndex(), loc.getFieldNum());
Color fg = field.getForeground();
assertEquals(fg, ByteViewerComponentProvider.CHANGED_VALUE_COLOR);
}
assertTrue(program.canUndo());
}
@Test
public void testEditInputHex() throws Exception {
env.showTool();
@@ -717,12 +1093,129 @@ public class ByteViewerPlugin2Test extends AbstractGhidraHeadedIntegrationTest {
assertEquals(value, program.getMemory().getByte(getAddr(0x01001000)));
}
@Test
public void testEditModeHexShort() throws Exception {
env.showTool();
addViews();
final ByteViewerComponent c = findComponent(panel, "Hex Short");
panel.setCurrentView(c);
final ToggleDockingAction action =
(ToggleDockingAction) getAction(plugin, "Enable/Disable Byteviewer Editing");
final FieldLocation loc = getFieldLocation(getAddr(0x01001003));
SwingUtilities.invokeAndWait(() -> {
ByteViewerComponent currentComponent = panel.getCurrentComponent();
currentComponent.setCursorPosition(loc.getIndex(), loc.getFieldNum(), 0, 0);
action.setSelected(true);
action.actionPerformed(new DefaultActionContext());
});
assertTrue(action.isSelected());
assertEquals(ByteViewerComponentProvider.CHANGED_VALUE_COLOR, c.getFocusedCursorColor());
SwingUtilities.invokeAndWait(() -> {
KeyEvent ev = new KeyEvent(c, 0, new Date().getTime(), 0, KeyEvent.VK_1, '1');
c.keyPressed(ev, loc.getIndex(), loc.getFieldNum(), loc.getRow(), loc.getCol(),
c.getCurrentField());
});
program.flushEvents();
assertEquals((byte) 0x10, program.getMemory().getByte(getAddr(0x01001003)));
assertEquals(ByteViewerComponentProvider.CHANGED_VALUE_COLOR,
((ByteField) c.getCurrentField()).getForeground());
SwingUtilities.invokeAndWait(() -> {
action.setSelected(false);
action.actionPerformed(new DefaultActionContext());
});
assertTrue(!action.isSelected());
assertEquals(ByteViewerComponentProvider.CURSOR_ACTIVE_COLOR,
c.getFocusedCursorColor());
}
@Test
public void testEditModeHexInteger() throws Exception {
env.showTool();
addViews();
final ByteViewerComponent c = findComponent(panel, "HexInteger");
final ByteViewerComponent c = findComponent(panel, "Hex Integer");
panel.setCurrentView(c);
final ToggleDockingAction action =
(ToggleDockingAction) getAction(plugin, "Enable/Disable Byteviewer Editing");
final FieldLocation loc = getFieldLocation(getAddr(0x01001003));
SwingUtilities.invokeAndWait(() -> {
ByteViewerComponent currentComponent = panel.getCurrentComponent();
currentComponent.setCursorPosition(loc.getIndex(), loc.getFieldNum(), 0, 0);
action.setSelected(true);
action.actionPerformed(new DefaultActionContext());
});
assertTrue(action.isSelected());
assertEquals(ByteViewerComponentProvider.CHANGED_VALUE_COLOR, c.getFocusedCursorColor());
SwingUtilities.invokeAndWait(() -> {
KeyEvent ev = new KeyEvent(c, 0, new Date().getTime(), 0, KeyEvent.VK_1, '1');
c.keyPressed(ev, loc.getIndex(), loc.getFieldNum(), loc.getRow(), loc.getCol(),
c.getCurrentField());
});
program.flushEvents();
assertEquals((byte) 0x10, program.getMemory().getByte(getAddr(0x01001003)));
assertEquals(ByteViewerComponentProvider.CHANGED_VALUE_COLOR,
((ByteField) c.getCurrentField()).getForeground());
SwingUtilities.invokeAndWait(() -> {
action.setSelected(false);
action.actionPerformed(new DefaultActionContext());
});
assertTrue(!action.isSelected());
assertEquals(ByteViewerComponentProvider.CURSOR_ACTIVE_COLOR,
c.getFocusedCursorColor());
}
@Test
public void testEditModeHexLong() throws Exception {
env.showTool();
addViews();
final ByteViewerComponent c = findComponent(panel, "Hex Long");
panel.setCurrentView(c);
final ToggleDockingAction action =
(ToggleDockingAction) getAction(plugin, "Enable/Disable Byteviewer Editing");
final FieldLocation loc = getFieldLocation(getAddr(0x01001003));
SwingUtilities.invokeAndWait(() -> {
ByteViewerComponent currentComponent = panel.getCurrentComponent();
currentComponent.setCursorPosition(loc.getIndex(), loc.getFieldNum(), 0, 0);
action.setSelected(true);
action.actionPerformed(new DefaultActionContext());
});
assertTrue(action.isSelected());
assertEquals(ByteViewerComponentProvider.CHANGED_VALUE_COLOR, c.getFocusedCursorColor());
SwingUtilities.invokeAndWait(() -> {
KeyEvent ev = new KeyEvent(c, 0, new Date().getTime(), 0, KeyEvent.VK_1, '1');
c.keyPressed(ev, loc.getIndex(), loc.getFieldNum(), loc.getRow(), loc.getCol(),
c.getCurrentField());
});
program.flushEvents();
assertEquals((byte) 0x10, program.getMemory().getByte(getAddr(0x01001003)));
assertEquals(ByteViewerComponentProvider.CHANGED_VALUE_COLOR,
((ByteField) c.getCurrentField()).getForeground());
SwingUtilities.invokeAndWait(() -> {
action.setSelected(false);
action.actionPerformed(new DefaultActionContext());
});
assertTrue(!action.isSelected());
assertEquals(ByteViewerComponentProvider.CURSOR_ACTIVE_COLOR,
c.getFocusedCursorColor());
}
@Test
public void testEditModeHexLongLong() throws Exception {
env.showTool();
addViews();
final ByteViewerComponent c = findComponent(panel, "Hex Long Long");
panel.setCurrentView(c);
final ToggleDockingAction action =
@@ -1563,7 +2056,10 @@ public class ByteViewerPlugin2Test extends AbstractGhidraHeadedIntegrationTest {
ByteViewerOptionsDialog dialog = launchByteViewerOptions();
setViewSelected(dialog, "Ascii", true);
setViewSelected(dialog, "Octal", true);
setViewSelected(dialog, "HexInteger", true);
setViewSelected(dialog, "Hex Short", true);
setViewSelected(dialog, "Hex Integer", true);
setViewSelected(dialog, "Hex Long", true);
setViewSelected(dialog, "Hex Long Long", true);
pressButtonByText(dialog.getComponent(), "OK");
}

View File

@@ -237,13 +237,72 @@ public class ByteViewerPluginFormatsTest extends AbstractGhidraHeadedIntegration
assertEquals(insertionStr, findLabelStr(panel, "Insertion"));
}
@Test
public void testHexShortView() throws Exception {
env.showTool();
addViews();
final ByteViewerComponent c = findComponent(panel, "Hex Short");
panel.setCurrentView(c);
assertEquals(8, c.getNumberOfFields());
assertEquals(2, c.getDataModel().getUnitByteSize());
final FieldLocation loc = getFieldLocation(getAddr(0x01001000));
runSwing(() -> {
ByteViewerComponent currentComponent = panel.getCurrentComponent();
currentComponent.setCursorPosition(loc.getIndex(), loc.getFieldNum(), 0, 0);
});
// verify that the 2 bytes are represented as an 4 digit hex number
assertEquals(4, c.getCurrentField().getNumCols(loc.getRow()));
}
@Test
public void testOtherEditsHexShort() throws Exception {
// verify that the 4 byte string is rendered in red when a byte
// is changed from another view, e.g. Ascii or Hex
env.showTool();
addViews();
final ByteViewerComponent c = findComponent(panel, "Ascii");
panel.setCurrentView(c);
final ToggleDockingAction action =
(ToggleDockingAction) getAction(plugin, "Enable/Disable Byteviewer Editing");
final FieldLocation loc = getFieldLocation(getAddr(0x01001000));
runSwing(() -> {
ByteViewerComponent currentComponent = panel.getCurrentComponent();
currentComponent.setCursorPosition(loc.getIndex(), loc.getFieldNum(), 0, 0);
action.setSelected(true);
action.actionPerformed(new DefaultActionContext());
KeyEvent ev =
new KeyEvent(currentComponent, 0, new Date().getTime(), 0, KeyEvent.VK_1, '1');
currentComponent.keyPressed(ev, loc.getIndex(), loc.getFieldNum(), loc.getRow(),
loc.getCol(), currentComponent.getCurrentField());
});
program.flushEvents();
final ByteViewerComponent hexComp = findComponent(panel, "Hex Short");
runSwing(() -> {
ProgramByteBlockSet blockset =
(ProgramByteBlockSet) plugin.getProvider().getByteBlockSet();
ByteBlockInfo bbInfo = blockset.getByteBlockInfo(getAddr(0x01001000));
FieldLocation l = hexComp.getFieldLocation(bbInfo.getBlock(), bbInfo.getOffset());
hexComp.setCursorPosition(l.getIndex(), l.getFieldNum(), 0, 0);
});
assertEquals(ByteViewerComponentProvider.CHANGED_VALUE_COLOR,
((ByteField) hexComp.getCurrentField()).getForeground());
}
@Test
public void testHexIntegerView() throws Exception {
env.showTool();
addViews();
final ByteViewerComponent c = findComponent(panel, "HexInteger");
final ByteViewerComponent c = findComponent(panel, "Hex Integer");
panel.setCurrentView(c);
assertEquals(4, c.getNumberOfFields());
assertEquals(4, c.getDataModel().getUnitByteSize());
@@ -282,7 +341,125 @@ public class ByteViewerPluginFormatsTest extends AbstractGhidraHeadedIntegration
});
program.flushEvents();
final ByteViewerComponent hexComp = findComponent(panel, "HexInteger");
final ByteViewerComponent hexComp = findComponent(panel, "Hex Integer");
runSwing(() -> {
ProgramByteBlockSet blockset =
(ProgramByteBlockSet) plugin.getProvider().getByteBlockSet();
ByteBlockInfo bbInfo = blockset.getByteBlockInfo(getAddr(0x01001000));
FieldLocation l = hexComp.getFieldLocation(bbInfo.getBlock(), bbInfo.getOffset());
hexComp.setCursorPosition(l.getIndex(), l.getFieldNum(), 0, 0);
});
assertEquals(ByteViewerComponentProvider.CHANGED_VALUE_COLOR,
((ByteField) hexComp.getCurrentField()).getForeground());
}
@Test
public void testHexLongView() throws Exception {
env.showTool();
addViews();
final ByteViewerComponent c = findComponent(panel, "Hex Long");
panel.setCurrentView(c);
assertEquals(2, c.getNumberOfFields());
assertEquals(8, c.getDataModel().getUnitByteSize());
final FieldLocation loc = getFieldLocation(getAddr(0x01001000));
runSwing(() -> {
ByteViewerComponent currentComponent = panel.getCurrentComponent();
currentComponent.setCursorPosition(loc.getIndex(), loc.getFieldNum(), 0, 0);
});
// verify that the 8 bytes are represented as an 8 digit hex number
assertEquals(16, c.getCurrentField().getNumCols(loc.getRow()));
}
@Test
public void testOtherEditsHexLong() throws Exception {
// verify that the 4 byte string is rendered in red when a byte
// is changed from another view, e.g. Ascii or Hex
env.showTool();
addViews();
final ByteViewerComponent c = findComponent(panel, "Ascii");
panel.setCurrentView(c);
final ToggleDockingAction action =
(ToggleDockingAction) getAction(plugin, "Enable/Disable Byteviewer Editing");
final FieldLocation loc = getFieldLocation(getAddr(0x01001000));
runSwing(() -> {
ByteViewerComponent currentComponent = panel.getCurrentComponent();
currentComponent.setCursorPosition(loc.getIndex(), loc.getFieldNum(), 0, 0);
action.setSelected(true);
action.actionPerformed(new DefaultActionContext());
KeyEvent ev =
new KeyEvent(currentComponent, 0, new Date().getTime(), 0, KeyEvent.VK_1, '1');
currentComponent.keyPressed(ev, loc.getIndex(), loc.getFieldNum(), loc.getRow(),
loc.getCol(), currentComponent.getCurrentField());
});
program.flushEvents();
final ByteViewerComponent hexComp = findComponent(panel, "Hex Long");
runSwing(() -> {
ProgramByteBlockSet blockset =
(ProgramByteBlockSet) plugin.getProvider().getByteBlockSet();
ByteBlockInfo bbInfo = blockset.getByteBlockInfo(getAddr(0x01001000));
FieldLocation l = hexComp.getFieldLocation(bbInfo.getBlock(), bbInfo.getOffset());
hexComp.setCursorPosition(l.getIndex(), l.getFieldNum(), 0, 0);
});
assertEquals(ByteViewerComponentProvider.CHANGED_VALUE_COLOR,
((ByteField) hexComp.getCurrentField()).getForeground());
}
@Test
public void testHexLongLongView() throws Exception {
env.showTool();
addViews();
final ByteViewerComponent c = findComponent(panel, "Hex Long Long");
panel.setCurrentView(c);
assertEquals(1, c.getNumberOfFields());
assertEquals(16, c.getDataModel().getUnitByteSize());
final FieldLocation loc = getFieldLocation(getAddr(0x01001000));
runSwing(() -> {
ByteViewerComponent currentComponent = panel.getCurrentComponent();
currentComponent.setCursorPosition(loc.getIndex(), loc.getFieldNum(), 0, 0);
});
// verify that the 16 bytes are represented as an 32 digit hex number
assertEquals(32, c.getCurrentField().getNumCols(loc.getRow()));
}
@Test
public void testOtherEditsHexLongLong() throws Exception {
// verify that the 4 byte string is rendered in red when a byte
// is changed from another view, e.g. Ascii or Hex
env.showTool();
addViews();
final ByteViewerComponent c = findComponent(panel, "Ascii");
panel.setCurrentView(c);
final ToggleDockingAction action =
(ToggleDockingAction) getAction(plugin, "Enable/Disable Byteviewer Editing");
final FieldLocation loc = getFieldLocation(getAddr(0x01001000));
runSwing(() -> {
ByteViewerComponent currentComponent = panel.getCurrentComponent();
currentComponent.setCursorPosition(loc.getIndex(), loc.getFieldNum(), 0, 0);
action.setSelected(true);
action.actionPerformed(new DefaultActionContext());
KeyEvent ev =
new KeyEvent(currentComponent, 0, new Date().getTime(), 0, KeyEvent.VK_1, '1');
currentComponent.keyPressed(ev, loc.getIndex(), loc.getFieldNum(), loc.getRow(),
loc.getCol(), currentComponent.getCurrentField());
});
program.flushEvents();
final ByteViewerComponent hexComp = findComponent(panel, "Hex Long Long");
runSwing(() -> {
ProgramByteBlockSet blockset =
@@ -402,7 +579,7 @@ public class ByteViewerPluginFormatsTest extends AbstractGhidraHeadedIntegration
ByteViewerOptionsDialog dialog = launchByteViewerOptions();
setViewSelected(dialog, "Ascii", true);
setViewSelected(dialog, "Octal", true);
setViewSelected(dialog, "HexInteger", true);
setViewSelected(dialog, "Hex Integer", true);
setViewSelected(dialog, "Integer", true);
pressButtonByText(dialog.getComponent(), "OK");
waitForSwing();
@@ -805,7 +982,10 @@ public class ByteViewerPluginFormatsTest extends AbstractGhidraHeadedIntegration
ByteViewerOptionsDialog dialog = launchByteViewerOptions();
setViewSelected(dialog, "Ascii", true);
setViewSelected(dialog, "Octal", true);
setViewSelected(dialog, "HexInteger", true);
setViewSelected(dialog, "Hex Short", true);
setViewSelected(dialog, "Hex Integer", true);
setViewSelected(dialog, "Hex Long", true);
setViewSelected(dialog, "Hex Long Long", true);
pressButtonByText(dialog.getComponent(), "OK");
waitForSwing();
}