Skip to content

Commit

Permalink
GP-4751 Corrected typedef duplicate name resolve
Browse files Browse the repository at this point in the history
  • Loading branch information
ghidra1 committed Jul 5, 2024
1 parent 0e2588b commit 7bc0443
Show file tree
Hide file tree
Showing 3 changed files with 122 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,6 @@ public CParserTest() {
super();
}

/**
* This method just tries to parse a bunch o'
* data types just checking for stack traces.
*/
@Test
public void testSimple() throws Exception {
CParser parser = new CParser();
Expand Down Expand Up @@ -68,10 +64,6 @@ public void testSimple() throws Exception {
assertEquals(comp.getDataType().getName(),"char");
}

/**
* This method just tries to parse a bunch o'
* data types just checking for stack traces.
*/
@Test
public void testLongLong() throws Exception {
CParser parser;
Expand All @@ -96,6 +88,27 @@ public void testLongLong() throws Exception {
assertEquals(8, pdt32.getLength());
}

@Test
public void testTypedef() throws Exception {
CParser parser;

parser = new CParser();
DataType tdDt = parser.parse("typedef struct foo * foo;");

assertTrue(tdDt != null);
assertTrue(tdDt instanceof TypeDef);
System.out.println(tdDt.getPathName());
System.out.println(((TypeDef)tdDt).getDataType().getPathName());
assertEquals("foo", tdDt.getName());
assertEquals("foo.conflict *", ((TypeDef)tdDt).getDataType().getName());
assertEquals(4, tdDt.getLength());

DataType dt = parser.getDataTypeManager().getDataType("/foo");
assertTrue(dt != null);
assertTrue(dt instanceof TypeDef);

}

@Test
public void testWcharT() throws Exception {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1445,23 +1445,48 @@ public String getUnusedConflictName(DataType dt) {
* <br>
* NOTE: The original datatype name will be returned unchanged for pointers and arrays since
* they cannot be renamed.
* <br>
* NOTE: Otherwise, if category does not exist the non-conflict name will be returned.
*
* @param path the category path of the category where the new data type live in
* the data type manager.
* @param dt datatype who name is used to establish non-conflict base name
* @return the unused conflict name
*/
public String getUnusedConflictName(CategoryPath path, DataType dt) {
String name = dt.getName();
if ((dt instanceof Array) || (dt instanceof Pointer) || (dt instanceof BuiltInDataType)) {
// name not used - anything will do
return name;
return dt.getName();
}
return getUnusedConflictName(getCategory(path), dt);
}

/**
* This method gets a ".conflict" name that is not currently used by any data
* types in the indicated category within this data type manager. If the baseName without
* conflict suffix is not used that name will be returned.
* <br>
* NOTE: The original datatype name will be returned unchanged for pointers and arrays since
* they cannot be renamed.
* <br>
* NOTE: Otherwise, if category does not exist the non-conflict name will be returned.
*
* @param cat the existing category to check.
* @param dt datatype who name is used to establish non-conflict base name
* @return the unused conflict name
*/
private String getUnusedConflictName(Category cat, DataType dt) {
if ((dt instanceof Array) || (dt instanceof Pointer) || (dt instanceof BuiltInDataType)) {
// name not used - anything will do
return dt.getName();
}
String baseName = DataTypeUtilities.getNameWithoutConflict(dt);
if (cat == null) {
return baseName;
}
String testName = baseName;
int count = 0;
while (getDataType(path, testName) != null) {
while (cat.getDataType(testName) != null) {
testName = baseName + DataType.CONFLICT_SUFFIX;
if (count > 0) {
testName += Integer.toString(count);
Expand Down Expand Up @@ -3116,6 +3141,10 @@ private TypeDef createTypeDef(TypeDef typedef, String name, Category cat,
flags = (short) TypedefDBAdapter.TYPEDEF_FLAG_AUTONAME;
cat = getCategory(dataType.getCategoryPath()); // force category
}
else if (cat.getDataType(name) != null) {
// force use of conflict name if needed
name = getUnusedConflictName(cat, typedef);
}
DBRecord record = typedefAdapter.createRecord(getID(dataType), name, flags, cat.getID(),
sourceArchiveIdValue, universalIdValue, typedef.getLastChangeTime());
TypedefDB typedefDB = new TypedefDB(this, dtCache, typedefAdapter, record);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
/* ###
* 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.program.database.data;

import static org.junit.Assert.*;

import org.junit.*;

import generic.test.AbstractGenericTest;
import ghidra.program.model.data.*;

public class TypedefDBTest extends AbstractGenericTest {

private final String NAME = "Test";

private DataTypeManagerDB dataMgr;
private int txId;

@Before
public void setUp() throws Exception {
dataMgr = new StandAloneDataTypeManager("dummyDTM");
txId = dataMgr.startTransaction("Test");
}

@After
public void tearDown() {
if (txId > 0) {
dataMgr.endTransaction(txId, true);
dataMgr.close();
}
}

@Test
public void testDuplicateNameResolve() throws Exception {

Structure struct = new StructureDataType(NAME, 0);
struct.add(new ByteDataType(), "field1", "Comment1");
struct.add(new WordDataType(), null, "Comment2");
struct.add(new DWordDataType(), "field3", null);
struct.add(new ByteDataType(), "field4", "Comment4");

Pointer structPtr = new PointerDataType(struct);

TypeDef typeDef = new TypedefDataType(NAME, structPtr);

TypeDef td = (TypeDef) dataMgr.resolve(typeDef, null);
assertNotNull(td);
assertEquals(NAME + ".conflict", td.getName());

assertTrue(td.isEquivalent(typeDef));

assertEquals("typedef Test.conflict Test *", td.toString());

}

}

0 comments on commit 7bc0443

Please sign in to comment.