Merge remote-tracking branch 'origin/patch'

This commit is contained in:
ghidra1
2025-03-24 09:57:16 -04:00
9 changed files with 95 additions and 38 deletions
@@ -4,9 +4,9 @@
* 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.
@@ -80,8 +80,9 @@ public class RepositoryFile {
pathname += "/";
}
pathname += name;
RepositoryManager.log(repository.getName(), pathname, "file is corrupt", null);
throw new FileNotFoundException(pathname + " is corrupt");
RepositoryManager.log(repository.getName(), pathname,
"file is corrupt or unsupported", null);
throw new FileNotFoundException(pathname + " is corrupt or unsupported");
}
this.databaseItem = (LocalDatabaseItem) folderItem;
}
@@ -4,9 +4,9 @@
* 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.
@@ -154,9 +154,11 @@ public abstract class LocalFolderItem implements FolderItem {
}
/**
* Returns hidden database directory
* Returns hidden data directory.
* NOTE: Even if a data directory is not required this method will still return one to
* allow removal of an unknown item type that may or may not use it.
*/
File getDataDir() {
final File getDataDir() {
synchronized (fileSystem) {
// Use hidden DB directory
return new File(propertyFile.getFolder(),
@@ -356,7 +358,7 @@ public abstract class LocalFolderItem implements FolderItem {
* Files are restored to there original state if unable to remove
* all files.
*/
void deleteContent(String user) throws IOException {
final void deleteContent(String user) throws IOException {
synchronized (fileSystem) {
File dataDir = getDataDir();
File chkDir = new File(dataDir.getParentFile(), dataDir.getName() + ".delete");
@@ -457,7 +459,7 @@ public abstract class LocalFolderItem implements FolderItem {
*/
@Override
public String getContentType() {
return propertyFile.getString(CONTENT_TYPE, null);
return propertyFile.getString(CONTENT_TYPE, UnknownFolderItem.UNKNOWN_CONTENT_TYPE);
}
/**
@@ -809,17 +811,21 @@ public abstract class LocalFolderItem implements FolderItem {
else if (fileType == DATABASE_FILE_TYPE) {
return new LocalDatabaseItem(fileSystem, propertyFile);
}
else if (fileType == UNKNOWN_FILE_TYPE) {
log.error("Folder item has unspecified file type: " +
new File(propertyFile.getFolder(), propertyFile.getStorageName()));
}
else {
log.error("Item has unknown content type: " +
log.error("Folder item has unsupported file type (" + fileType + "): " +
new File(propertyFile.getFolder(), propertyFile.getStorageName()));
}
}
catch (FileNotFoundException e) {
log.error("Item may be corrupt due to missing file: " +
log.error("Folder item may be corrupt due to missing file: " +
new File(propertyFile.getFolder(), propertyFile.getStorageName()), e);
}
catch (IOException e) {
log.error("Item may be corrupt: " +
log.error("Folder item may be corrupt: " +
new File(propertyFile.getFolder(), propertyFile.getStorageName()), e);
}
return new UnknownFolderItem(fileSystem, propertyFile);
@@ -4,9 +4,9 @@
* 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.
@@ -28,7 +28,9 @@ import ghidra.util.task.TaskMonitor;
*/
public class UnknownFolderItem extends LocalFolderItem {
public static final String UNKNOWN_CONTENT_TYPE = "Unknown";
public static final String UNKNOWN_CONTENT_TYPE = "Unknown-File";
private final int fileType;
/**
* Constructor.
@@ -37,6 +39,15 @@ public class UnknownFolderItem extends LocalFolderItem {
*/
UnknownFolderItem(LocalFileSystem fileSystem, PropertyFile propertyFile) {
super(fileSystem, propertyFile);
fileType = propertyFile.getInt(FILE_TYPE, UNKNOWN_FILE_TYPE);
}
/**
* Get the file type
* @return file type or -1 if unspecified
*/
public int getFileType() {
return fileType;
}
@Override
@@ -4,9 +4,9 @@
* 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.
@@ -24,6 +24,7 @@ import ghidra.framework.remote.RepositoryItem;
import ghidra.framework.store.*;
import ghidra.framework.store.FileSystem;
import ghidra.util.InvalidNameException;
import ghidra.util.Msg;
import ghidra.util.exception.CancelledException;
import ghidra.util.task.TaskMonitor;
@@ -111,12 +112,19 @@ public class RemoteFileSystem implements FileSystem, RemoteAdapterListener {
@Override
public FolderItem[] getItems(String folderPath) throws IOException {
RepositoryItem[] items = repository.getItemList(folderPath);
if (!folderPath.endsWith(FileSystem.SEPARATOR)) {
folderPath += FileSystem.SEPARATOR;
}
FolderItem[] folderItems = new FolderItem[items.length];
for (int i = 0; i < items.length; i++) {
if (items[i].getItemType() != RepositoryItem.DATABASE) {
throw new IOException("Unsupported file type");
if (items[i].getItemType() == RepositoryItem.DATABASE) {
folderItems[i] = new RemoteDatabaseItem(repository, items[i]);
}
else {
Msg.error(this,
"Unsupported respository item encountered (" + items[i].getItemType() + "): " +
folderPath + items[i].getName());
}
folderItems[i] = new RemoteDatabaseItem(repository, items[i]);
}
return folderItems;
}
@@ -130,7 +138,7 @@ public class RemoteFileSystem implements FileSystem, RemoteAdapterListener {
if (item.getItemType() == RepositoryItem.DATABASE) {
return new RemoteDatabaseItem(repository, item);
}
throw new IOException("Unsupported file type");
throw new IOException("Unsupported repository item type (" + item.getItemType() + ")");
}
@Override
@@ -142,7 +150,7 @@ public class RemoteFileSystem implements FileSystem, RemoteAdapterListener {
if (item.getItemType() == RepositoryItem.DATABASE) {
return new RemoteDatabaseItem(repository, item);
}
throw new IOException("Unsupported file type");
throw new IOException("Unsupported repository item type (" + item.getItemType() + ")");
}
@Override
@@ -4,9 +4,9 @@
* 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.
@@ -20,6 +20,7 @@ import java.io.IOException;
import ghidra.framework.client.RepositoryAdapter;
import ghidra.framework.remote.RepositoryItem;
import ghidra.framework.store.*;
import ghidra.framework.store.local.UnknownFolderItem;
/**
* <code>RemoteFolderItem</code> provides an abstract FolderItem implementation
@@ -46,7 +47,11 @@ public abstract class RemoteFolderItem implements FolderItem {
this.repository = repository;
parentPath = item.getParentPath();
itemName = item.getName();
contentType = item.getContentType();
String ct = item.getContentType();
if (ct == null) {
ct = UnknownFolderItem.UNKNOWN_CONTENT_TYPE;
}
contentType = ct;
fileID = item.getFileID();
version = item.getVersion();
@@ -4,9 +4,9 @@
* 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.
@@ -23,6 +23,7 @@ import javax.swing.Icon;
import ghidra.framework.model.*;
import ghidra.framework.store.FileSystem;
import ghidra.framework.store.FolderItem;
import ghidra.framework.store.local.UnknownFolderItem;
import ghidra.util.InvalidNameException;
import ghidra.util.classfinder.ExtensionPoint;
import ghidra.util.exception.CancelledException;
@@ -42,7 +43,7 @@ import ghidra.util.task.TaskMonitor;
*/
public interface ContentHandler<T extends DomainObjectAdapter> extends ExtensionPoint {
public static final String UNKNOWN_CONTENT = "Unknown-File";
public static final String UNKNOWN_CONTENT = UnknownFolderItem.UNKNOWN_CONTENT_TYPE;
public static final String MISSING_CONTENT = "Missing-File";
/**
@@ -4,9 +4,9 @@
* 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.
@@ -616,8 +616,9 @@ class GhidraFolderData {
Map<String, T> map = new HashMap<>();
int badItemCount = 0;
int nullNameCount = 0;
int unknownItemCount = 0;
for (T item : items) {
if (item == null || item instanceof UnknownFolderItem) {
if (item == null) {
++badItemCount;
continue;
}
@@ -626,6 +627,16 @@ class GhidraFolderData {
++nullNameCount;
continue;
}
if (item instanceof UnknownFolderItem unk) {
if (unk.getFileType() == FolderItem.UNKNOWN_FILE_TYPE) {
++badItemCount;
continue;
}
Msg.error(this,
"Unsupported folder item encountered (" + unk.getFileType() + "): " +
getPathname(item.getName()));
++unknownItemCount;
}
map.put(itemName, item);
}
if (badItemCount != 0) {
@@ -636,6 +647,11 @@ class GhidraFolderData {
Msg.error(this,
"Project folder contains " + nullNameCount + " null items: " + getPathname());
}
if (badItemCount != 0) {
Msg.error(this,
"Project folder contains " + unknownItemCount + " unsupported items: " +
getPathname());
}
return map;
}
@@ -41,8 +41,7 @@ import generic.theme.GIcon;
import ghidra.app.plugin.PluginCategoryNames;
import ghidra.framework.GenericRunInfo;
import ghidra.framework.client.*;
import ghidra.framework.data.FolderLinkContentHandler;
import ghidra.framework.data.LinkedGhidraFolder;
import ghidra.framework.data.*;
import ghidra.framework.main.datatable.ProjectDataTablePanel;
import ghidra.framework.main.datatree.*;
import ghidra.framework.main.projectdata.actions.*;
@@ -1082,8 +1081,17 @@ public class FrontEndPlugin extends Plugin
}
public void openDomainFile(DomainFile domainFile) {
String contentType = domainFile.getContentType();
if (ContentHandler.UNKNOWN_CONTENT.equals(contentType)) {
Msg.showInfo(this, tool.getToolFrame(), "Cannot Find Tool",
"<html>File type is unrecognized: <b>" +
HTMLUtilities.escapeHTML(domainFile.getName()) +
"</b>.<br><br>File may have been created with a neer version of Ghidra.");
return;
}
if (FolderLinkContentHandler.FOLDER_LINK_CONTENT_TYPE.equals(domainFile.getContentType())) {
if (FolderLinkContentHandler.FOLDER_LINK_CONTENT_TYPE.equals(contentType)) {
showLinkedFolderInViewedProject(domainFile);
return;
}
@@ -4,9 +4,9 @@
* 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.
@@ -17,6 +17,7 @@ package ghidra.framework.protocol.ghidra;
import java.net.URL;
import ghidra.framework.data.ContentHandler;
import ghidra.framework.model.DomainFile;
import ghidra.util.task.TaskMonitor;
@@ -25,7 +26,7 @@ import ghidra.util.task.TaskMonitor;
*/
public class ContentTypeQueryTask extends GhidraURLQueryTask {
private String contentType = "Unknown";
private String contentType = ContentHandler.UNKNOWN_CONTENT;
/**
* Construct a Ghidra URL content type query task