mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2026-06-01 14:54:29 +08:00
Merge remote-tracking branch 'origin/GP-6536_ghidragon_null_ptr_exception_in_lising--SQUASHED' into Ghidra_12.1
This commit is contained in:
+22
-16
@@ -38,6 +38,7 @@ import ghidra.program.model.listing.*;
|
|||||||
import ghidra.program.model.symbol.Reference;
|
import ghidra.program.model.symbol.Reference;
|
||||||
import ghidra.util.datastruct.LRUMap;
|
import ghidra.util.datastruct.LRUMap;
|
||||||
import ghidra.util.task.TaskMonitor;
|
import ghidra.util.task.TaskMonitor;
|
||||||
|
import util.CollectionUtils;
|
||||||
|
|
||||||
public class ProgramBigListingModel implements ListingModel, FormatModelListener,
|
public class ProgramBigListingModel implements ListingModel, FormatModelListener,
|
||||||
DomainObjectListener, ChangeListener, OptionsChangeListener {
|
DomainObjectListener, ChangeListener, OptionsChangeListener {
|
||||||
@@ -454,21 +455,7 @@ public class ProgramBigListingModel implements ListingModel, FormatModelListener
|
|||||||
if (parent.getAddress().equals(addr)) {
|
if (parent.getAddress().equals(addr)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
Data data;
|
Data data = getOpenDataAtAddress(parent, addr);
|
||||||
if (parent.getBaseDataType() instanceof Union) {
|
|
||||||
int index =
|
|
||||||
openCloseMgr.getOpenDataIndex(parent);
|
|
||||||
if (index < 0) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
data = parent.getComponent(index);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
int offset = (int) addr.subtract(parent.getMinAddress());
|
|
||||||
List<Data> componentsContaining = parent.getComponentsContaining(offset - 1);
|
|
||||||
data = componentsContaining.isEmpty() ? null
|
|
||||||
: componentsContaining.get(componentsContaining.size() - 1);
|
|
||||||
}
|
|
||||||
if (data == null) {
|
if (data == null) {
|
||||||
return addr.previous();
|
return addr.previous();
|
||||||
}
|
}
|
||||||
@@ -487,11 +474,30 @@ public class ProgramBigListingModel implements ListingModel, FormatModelListener
|
|||||||
|
|
||||||
int index = data.getComponentIndex();
|
int index = data.getComponentIndex();
|
||||||
if (index > 0) {
|
if (index > 0) {
|
||||||
return parent.getComponent(index - 1).getAddress();
|
Address previous = parent.getComponent(index - 1).getAddress();
|
||||||
|
if (!previous.equals(addr)) {
|
||||||
|
return previous;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Data getOpenDataAtAddress(Data parent, Address address) {
|
||||||
|
if (parent.getBaseDataType() instanceof Union) {
|
||||||
|
int index = openCloseMgr.getOpenDataIndex(parent);
|
||||||
|
if (index < 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return parent.getComponent(index);
|
||||||
|
}
|
||||||
|
int offset = (int) address.subtract(parent.getMinAddress());
|
||||||
|
List<Data> components = parent.getComponentsContaining(offset - 1);
|
||||||
|
if (CollectionUtils.isBlank(components)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return components.get(components.size() - 1);
|
||||||
|
}
|
||||||
|
|
||||||
private void addOpenData(List<Data> list, Data data, Address addr) {
|
private void addOpenData(List<Data> list, Data data, Address addr) {
|
||||||
Address dataAddr = data.getMinAddress();
|
Address dataAddr = data.getMinAddress();
|
||||||
if (openCloseMgr.isDataOpen(data)) {
|
if (openCloseMgr.isDataOpen(data)) {
|
||||||
|
|||||||
+87
@@ -0,0 +1,87 @@
|
|||||||
|
/* ###
|
||||||
|
* 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.listingpanel;
|
||||||
|
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import generic.test.AbstractGenericTest;
|
||||||
|
import ghidra.app.util.viewer.format.FormatManager;
|
||||||
|
import ghidra.framework.options.SaveState;
|
||||||
|
import ghidra.framework.options.ToolOptions;
|
||||||
|
import ghidra.program.database.ProgramBuilder;
|
||||||
|
import ghidra.program.database.ProgramDB;
|
||||||
|
import ghidra.program.database.function.OverlappingFunctionException;
|
||||||
|
import ghidra.program.model.address.*;
|
||||||
|
import ghidra.program.model.data.StructureDataType;
|
||||||
|
import ghidra.program.model.data.UnionDataType;
|
||||||
|
import ghidra.program.model.listing.Data;
|
||||||
|
import ghidra.program.model.listing.Function;
|
||||||
|
import ghidra.program.model.listing.Listing;
|
||||||
|
|
||||||
|
public class ProgramBigListingModelOpenDataTest extends AbstractGenericTest {
|
||||||
|
|
||||||
|
private ProgramDB program;
|
||||||
|
private ProgramBigListingModel model;
|
||||||
|
private AddressSpace space;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() throws Exception {
|
||||||
|
ProgramBuilder builder = new ProgramBuilder("Test", ProgramBuilder._X86);
|
||||||
|
program = builder.getProgram();
|
||||||
|
space = program.getAddressFactory().getDefaultAddressSpace();
|
||||||
|
builder.createMemory("block1", "0", 100);
|
||||||
|
|
||||||
|
FormatManager formatManager =
|
||||||
|
new FormatManager(new ToolOptions("display"), new ToolOptions("Listing Fields"));
|
||||||
|
formatManager.readState(new SaveState()); // this will use default format
|
||||||
|
model = new ProgramBigListingModel(program, formatManager);
|
||||||
|
|
||||||
|
StructureDataType struct1 = new StructureDataType("aaa", 4);
|
||||||
|
StructureDataType struct2 = new StructureDataType("bbb", 2);
|
||||||
|
UnionDataType union = new UnionDataType("uuu");
|
||||||
|
union.add(struct1);
|
||||||
|
union.add(struct2);
|
||||||
|
builder.applyDataType("0", union);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private Address addr(long offset) {
|
||||||
|
return space.getAddress(offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetPreviousAddressWithLargerUnionComponentOpen() {
|
||||||
|
Listing listing = program.getListing();
|
||||||
|
Data data = listing.getDataAt(addr(0));
|
||||||
|
Data component = data.getComponent(0);
|
||||||
|
model.openData(component);
|
||||||
|
assertEquals(addr(2), model.getAddressBefore(addr(3)));
|
||||||
|
}
|
||||||
|
@Test
|
||||||
|
public void testGetPreviousAddressWithSmallerUnionComponentOpen() {
|
||||||
|
Listing listing = program.getListing();
|
||||||
|
Data data = listing.getDataAt(addr(0));
|
||||||
|
Data component = data.getComponent(1);
|
||||||
|
model.openData(component);
|
||||||
|
assertEquals(addr(2), model.getAddressBefore(addr(3)));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user