mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2026-01-08 21:47:59 -05:00
Merge remote-tracking branch 'origin/patch'
This commit is contained in:
@@ -1226,14 +1226,159 @@ public class ExtendedFlatProgramAPI extends FlatProgramAPI {
|
||||
public void createShortenedTemplateNamesForClasses(List<RecoveredClass> recoveredClasses)
|
||||
throws CancelledException {
|
||||
|
||||
// update recovered classes variable that stores shortened names such that all templated
|
||||
// class names get generic classname<...> shortened name to start with
|
||||
// also create a map of all same classname<> templates separated into unique parent namespaces
|
||||
// and the list of recovered class objects in that namespace with the same generic
|
||||
// classname<...> shortened name
|
||||
Map<String, Map<Namespace, List<RecoveredClass>>> templateClassesMap =
|
||||
mapTemplateClasses(recoveredClasses);
|
||||
|
||||
// now loop through them to make sure all in a particular namespace have unique shortened
|
||||
// names or if unable to do that, remove the shortened name and use the full template name
|
||||
Set<String> shortenedNames = templateClassesMap.keySet();
|
||||
for (String shortenedName : shortenedNames) {
|
||||
|
||||
monitor.checkCancelled();
|
||||
|
||||
Map<Namespace, List<RecoveredClass>> namespaceMap =
|
||||
templateClassesMap.get(shortenedName);
|
||||
for (Namespace parentNamespace : namespaceMap.keySet()) {
|
||||
|
||||
monitor.checkCancelled();
|
||||
|
||||
// if only one, keep empty template
|
||||
List<RecoveredClass> sameNameClassesInNamespace = namespaceMap.get(parentNamespace);
|
||||
if (sameNameClassesInNamespace.size() == 1) {
|
||||
continue;
|
||||
}
|
||||
processDuplicateTemplates(sameNameClassesInNamespace, shortenedName,
|
||||
parentNamespace);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to create unique shortened names for those blank templates that are dupes in a
|
||||
* particular namespace
|
||||
* @param sameNameClassesInNamespace the list of same name dupes in the given namespace
|
||||
* @param shortenedName the duplicated shortened name
|
||||
* @throws CancelledException if cancelled
|
||||
*/
|
||||
private void processDuplicateTemplates(List<RecoveredClass> sameNameClassesInNamespace,
|
||||
String shortenedName, Namespace parentNamespace) throws CancelledException {
|
||||
|
||||
// first verify that all are in the same parent namespace
|
||||
for (RecoveredClass recoveredClass : sameNameClassesInNamespace) {
|
||||
if (!recoveredClass.getClassNamespace().getParentNamespace().equals(parentNamespace)) {
|
||||
throw new IllegalArgumentException(
|
||||
"This method is meant to dedupe shortened class names in the same parent namespace");
|
||||
}
|
||||
}
|
||||
|
||||
List<RecoveredClass> classesToProcess =
|
||||
new ArrayList<RecoveredClass>(sameNameClassesInNamespace);
|
||||
|
||||
// First, check for a simple internal to the template (ie just one item in it
|
||||
// if that is the case then just keep the original name
|
||||
for (RecoveredClass classWithSameShortName : sameNameClassesInNamespace) {
|
||||
monitor.checkCancelled();
|
||||
|
||||
if (containsSimpleTemplate(classWithSameShortName.getName())) {
|
||||
//reset shortened name variable to empty to indicate no shortened name
|
||||
classWithSameShortName.addShortenedTemplatedName(new String());
|
||||
classesToProcess.remove(classWithSameShortName);
|
||||
}
|
||||
}
|
||||
|
||||
// if none left after removing simple ones then continue processing next namespace
|
||||
if (classesToProcess.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// if only one left after removing the simple templates then use it with first part of
|
||||
// template internal (ie up to the first comma)
|
||||
if (classesToProcess.size() == 1) {
|
||||
RecoveredClass classWithSameShortName = classesToProcess.get(0);
|
||||
String newName = getNewShortenedTemplateName(classWithSameShortName, 1);
|
||||
classWithSameShortName.addShortenedTemplatedName(newName);
|
||||
return;
|
||||
}
|
||||
|
||||
// if more than one complex left over after all the removals above, then keep trying to
|
||||
// get unique name
|
||||
int commaIndex = 1;
|
||||
while (!classesToProcess.isEmpty()) {
|
||||
|
||||
List<RecoveredClass> leftoversWithSameShortName =
|
||||
new ArrayList<RecoveredClass>(classesToProcess);
|
||||
|
||||
// update these classes so their short names include up to the n'th comma
|
||||
for (RecoveredClass currentClass : leftoversWithSameShortName) {
|
||||
monitor.checkCancelled();
|
||||
String newShortenedTemplateName =
|
||||
getNewShortenedTemplateName(currentClass, commaIndex);
|
||||
|
||||
// check to see if the new name is equal to the original class name
|
||||
// if so, remove the shortened name and just use full name for that class
|
||||
// also remove from list to process
|
||||
if (newShortenedTemplateName.equals(currentClass.getName())) {
|
||||
currentClass.addShortenedTemplatedName(new String());
|
||||
classesToProcess.remove(currentClass);
|
||||
continue;
|
||||
}
|
||||
// else update with new shortened name
|
||||
currentClass.addShortenedTemplatedName(newShortenedTemplateName);
|
||||
}
|
||||
|
||||
// if only one left then we are done
|
||||
if (classesToProcess.size() == 1) {
|
||||
classesToProcess.remove(0);
|
||||
continue;
|
||||
}
|
||||
|
||||
// otherwise see if any are unique and if so remove from list
|
||||
List<RecoveredClass> classesWithUpdatedNames =
|
||||
new ArrayList<RecoveredClass>(classesToProcess);
|
||||
|
||||
for (RecoveredClass currentClass : classesWithUpdatedNames) {
|
||||
monitor.checkCancelled();
|
||||
|
||||
String shortenedTemplateName = currentClass.getShortenedTemplateName();
|
||||
|
||||
List<RecoveredClass> classesWithSameShortName = getClassesWithSameShortenedName(
|
||||
classesWithUpdatedNames, shortenedTemplateName);
|
||||
|
||||
if (classesWithSameShortName.size() == 1) {
|
||||
classesToProcess.remove(classesWithSameShortName.get(0));
|
||||
}
|
||||
}
|
||||
|
||||
// at this point either the classesToProcess will be empty and we are done
|
||||
// OR there are still some with same (now with more of the template internal included)
|
||||
// name so update commaIndex so that on next pass the internal will add more text up
|
||||
// to this new comma index and so on until all are unique or back to their original
|
||||
// full template name
|
||||
commaIndex++;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private List<RecoveredClass> getClassesWithTemplateNames(List<RecoveredClass> recoveredClasses)
|
||||
throws CancelledException {
|
||||
|
||||
List<RecoveredClass> classesWithTemplates = new ArrayList<RecoveredClass>();
|
||||
|
||||
// create list with only classes that have templates in name and add completely stripped
|
||||
// template name to class var
|
||||
Iterator<RecoveredClass> recoveredClassesIterator = recoveredClasses.iterator();
|
||||
while (recoveredClassesIterator.hasNext()) {
|
||||
for (RecoveredClass recoveredClass : recoveredClasses) {
|
||||
monitor.checkCancelled();
|
||||
RecoveredClass recoveredClass = recoveredClassesIterator.next();
|
||||
|
||||
if (!recoveredClass.getShortenedTemplateName().isEmpty()) {
|
||||
classesWithTemplates.add(recoveredClass);
|
||||
continue;
|
||||
}
|
||||
|
||||
String className = recoveredClass.getName();
|
||||
|
||||
@@ -1243,115 +1388,7 @@ public class ExtendedFlatProgramAPI extends FlatProgramAPI {
|
||||
classesWithTemplates.add(recoveredClass);
|
||||
}
|
||||
}
|
||||
|
||||
// iterate over map and remove entries that already have unique shortened names on map and
|
||||
// add those unique names to class as shorted name
|
||||
// for those with non-unique names, process them as a group of matched names
|
||||
List<RecoveredClass> classesToProcess = new ArrayList<RecoveredClass>(classesWithTemplates);
|
||||
|
||||
Iterator<RecoveredClass> classWithTemplatesIterator = classesWithTemplates.iterator();
|
||||
|
||||
while (classWithTemplatesIterator.hasNext()) {
|
||||
monitor.checkCancelled();
|
||||
RecoveredClass currentClass = classWithTemplatesIterator.next();
|
||||
|
||||
// skip if already processed
|
||||
if (!classesToProcess.contains(currentClass)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
String currentShortenedName = currentClass.getShortenedTemplateName();
|
||||
|
||||
// if removing the middle of template results in unique name then keep that name and
|
||||
// remove class from list to process
|
||||
List<RecoveredClass> classesWithSameShortenedName =
|
||||
getClassesWithSameShortenedName(classesToProcess, currentShortenedName);
|
||||
|
||||
if (classesWithSameShortenedName.size() == 1) {
|
||||
classesToProcess.remove(currentClass);
|
||||
continue;
|
||||
}
|
||||
|
||||
Iterator<RecoveredClass> classesWithSameShortnameIterator =
|
||||
classesWithSameShortenedName.iterator();
|
||||
while (classesWithSameShortnameIterator.hasNext()) {
|
||||
monitor.checkCancelled();
|
||||
|
||||
RecoveredClass classWithSameShortName = classesWithSameShortnameIterator.next();
|
||||
|
||||
// if removing the middle of template results in duplicate names then
|
||||
// check for a simple internal to the template (ie just one item in it
|
||||
// if that is the case then just keep the original name
|
||||
if (containsSimpleTemplate(classWithSameShortName.getName())) {
|
||||
classWithSameShortName.addShortenedTemplatedName(new String());
|
||||
classesWithSameShortnameIterator.remove();
|
||||
classesToProcess.remove(classWithSameShortName);
|
||||
}
|
||||
}
|
||||
|
||||
// if none left after removing simple ones then continue processing next class
|
||||
if (classesWithSameShortenedName.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// if only one left after removing the simple templates then use it with first part of
|
||||
// template internal
|
||||
if (classesWithSameShortenedName.size() == 1) {
|
||||
RecoveredClass classWithSameShortName = classesWithSameShortenedName.get(0);
|
||||
String newName = getNewShortenedTemplateName(classWithSameShortName, 1);
|
||||
classWithSameShortName.addShortenedTemplatedName(newName);
|
||||
classesToProcess.remove(classWithSameShortName);
|
||||
continue;
|
||||
}
|
||||
|
||||
// if more than one complex left over after all the removals above, then keep trying to
|
||||
// get unique name
|
||||
int commaIndex = 1;
|
||||
while (!classesWithSameShortenedName.isEmpty()) {
|
||||
|
||||
List<RecoveredClass> leftoversWithSameShortName =
|
||||
new ArrayList<RecoveredClass>(classesWithSameShortenedName);
|
||||
|
||||
// update all their shorted names to include up to the n'th comma
|
||||
Iterator<RecoveredClass> leftoversIterator = leftoversWithSameShortName.iterator();
|
||||
|
||||
while (leftoversIterator.hasNext()) {
|
||||
|
||||
monitor.checkCancelled();
|
||||
RecoveredClass currentClassWithSameShortName = leftoversIterator.next();
|
||||
currentClassWithSameShortName.addShortenedTemplatedName(
|
||||
getNewShortenedTemplateName(currentClassWithSameShortName, commaIndex));
|
||||
}
|
||||
|
||||
// now iterate and see if any are unique and if so remove from list
|
||||
// if not, add up to next comma and so on until all are unique
|
||||
List<RecoveredClass> leftovers2WithSameShortName =
|
||||
new ArrayList<RecoveredClass>(classesWithSameShortenedName);
|
||||
Iterator<RecoveredClass> leftovers2Iterator =
|
||||
leftovers2WithSameShortName.iterator();
|
||||
|
||||
while (leftovers2Iterator.hasNext()) {
|
||||
|
||||
monitor.checkCancelled();
|
||||
RecoveredClass currentClassWithSameShortName = leftovers2Iterator.next();
|
||||
|
||||
String shortenedTemplateName =
|
||||
currentClassWithSameShortName.getShortenedTemplateName();
|
||||
|
||||
List<RecoveredClass> classesWithSameShortName =
|
||||
getClassesWithSameShortenedName(classesToProcess, shortenedTemplateName);
|
||||
|
||||
if (classesWithSameShortName.size() == 1) {
|
||||
classesToProcess.remove(classesWithSameShortName.get(0));
|
||||
classesWithSameShortenedName.remove(classesWithSameShortName.get(0));
|
||||
}
|
||||
}
|
||||
|
||||
commaIndex++;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return classesWithTemplates;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1372,7 +1409,7 @@ public class ExtendedFlatProgramAPI extends FlatProgramAPI {
|
||||
return nameWithoutTemplates;
|
||||
}
|
||||
|
||||
public String getNewShortenedTemplateName(RecoveredClass recoveredClass, int commaIndex) {
|
||||
private String getNewShortenedTemplateName(RecoveredClass recoveredClass, int commaIndex) {
|
||||
|
||||
String className = recoveredClass.getName();
|
||||
|
||||
@@ -1393,21 +1430,62 @@ public class ExtendedFlatProgramAPI extends FlatProgramAPI {
|
||||
return shortenedName;
|
||||
}
|
||||
|
||||
public List<RecoveredClass> getClassesWithSameShortenedName(
|
||||
private Map<Namespace, List<RecoveredClass>> mapClassesWithSameShortenedName(
|
||||
List<RecoveredClass> templateClasses, String shortenedName) throws CancelledException {
|
||||
|
||||
List<RecoveredClass> classesWithSameShortenedName = new ArrayList<RecoveredClass>();
|
||||
Map<Namespace, List<RecoveredClass>> sameNamespaceMap = new HashMap<>();
|
||||
|
||||
Iterator<RecoveredClass> classIterator = templateClasses.iterator();
|
||||
while (classIterator.hasNext()) {
|
||||
for (RecoveredClass currentClass : templateClasses) {
|
||||
monitor.checkCancelled();
|
||||
RecoveredClass currentClass = classIterator.next();
|
||||
|
||||
if (currentClass.getShortenedTemplateName().equals(shortenedName)) {
|
||||
classesWithSameShortenedName.add(currentClass);
|
||||
Namespace parentNamespace = currentClass.getClassNamespace().getParentNamespace();
|
||||
List<RecoveredClass> sameShortNameClasses = sameNamespaceMap.get(parentNamespace);
|
||||
if (sameShortNameClasses == null) {
|
||||
sameShortNameClasses = new ArrayList<>();
|
||||
}
|
||||
sameShortNameClasses.add(currentClass);
|
||||
sameNamespaceMap.put(parentNamespace, sameShortNameClasses);
|
||||
}
|
||||
}
|
||||
return classesWithSameShortenedName;
|
||||
return sameNamespaceMap;
|
||||
|
||||
}
|
||||
|
||||
private List<RecoveredClass> getClassesWithSameShortenedName(
|
||||
List<RecoveredClass> templateClasses, String shortenedName) throws CancelledException {
|
||||
|
||||
List<RecoveredClass> sameShortNameClasses = new ArrayList<>();
|
||||
|
||||
for (RecoveredClass currentClass : templateClasses) {
|
||||
monitor.checkCancelled();
|
||||
if (currentClass.getShortenedTemplateName().equals(shortenedName)) {
|
||||
|
||||
sameShortNameClasses.add(currentClass);
|
||||
|
||||
}
|
||||
}
|
||||
return sameShortNameClasses;
|
||||
|
||||
}
|
||||
|
||||
private Map<String, Map<Namespace, List<RecoveredClass>>> mapTemplateClasses(
|
||||
List<RecoveredClass> recoveredClasses) throws CancelledException {
|
||||
|
||||
List<RecoveredClass> templateClasses = getClassesWithTemplateNames(recoveredClasses);
|
||||
|
||||
Map<String, Map<Namespace, List<RecoveredClass>>> sameNameMap = new HashMap<>();
|
||||
|
||||
for (RecoveredClass currentClass : templateClasses) {
|
||||
monitor.checkCancelled();
|
||||
|
||||
String shortenedName = currentClass.getShortenedTemplateName();
|
||||
Map<Namespace, List<RecoveredClass>> sameShortNamesMap = sameNameMap.get(shortenedName);
|
||||
if (sameShortNamesMap == null) {
|
||||
sameNameMap.put(shortenedName,
|
||||
mapClassesWithSameShortenedName(templateClasses, shortenedName));
|
||||
}
|
||||
}
|
||||
return sameNameMap;
|
||||
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user