GP-7239 limit max number of files in a filesystem

This commit is contained in:
dev747368
2026-09-21 21:52:54 +00:00
committed by Ryan Kurtz
parent b81eb22750
commit 061ec06a79
4 changed files with 122 additions and 7 deletions

View File

@@ -35,6 +35,8 @@ import ghidra.util.Msg;
public class FileSystemIndexHelper<METADATATYPE> {
private static final int MAX_SYMLINK_RECURSE_DEPTH = 10;
public static final int MAX_FILEENTRY_COUNT = 500_000;
private FileData<METADATATYPE> rootDir;
static class FileData<METADATATYPE> {
@@ -336,9 +338,10 @@ public class FileSystemIndexHelper<METADATATYPE> {
* @param metadata opaque blob that will be stored and associated with the new
* GFile instance
* @return new GFile instance
* @throws IOException if error adding files (too many files)
*/
public synchronized GFile storeFile(String path, long fileIndex, boolean isDirectory,
long length, METADATATYPE metadata) {
long length, METADATATYPE metadata) throws IOException {
String[] nameparts = FSUtilities.splitPath(path);
if (nameparts.length == 0) {
@@ -370,9 +373,10 @@ public class FileSystemIndexHelper<METADATATYPE> {
* @param metadata opaque blob that will be stored and associated with the new
* GFile instance
* @return new GFile instance
* @throws IOException if error adding files (too many files)
*/
public synchronized GFile storeFileWithParent(String filename, GFile parent, long fileIndex,
boolean isDirectory, long length, METADATATYPE metadata) {
boolean isDirectory, long length, METADATATYPE metadata) throws IOException {
FileData<METADATATYPE> fileData =
doStoreFile(filename, parent, fileIndex, isDirectory, length, null, metadata);
return fileData.file;
@@ -397,9 +401,10 @@ public class FileSystemIndexHelper<METADATATYPE> {
* @param metadata opaque blob that will be stored and associated with the new
* GFile instance
* @return new GFile instance
* @throws IOException if error adding files (too many files)
*/
public synchronized GFile storeSymlink(String path, long fileIndex, String symlinkPath,
long length, METADATATYPE metadata) {
long length, METADATATYPE metadata) throws IOException {
String[] nameparts = FSUtilities.splitPath(path);
if (nameparts.length == 0) {
Msg.warn(this,
@@ -434,9 +439,10 @@ public class FileSystemIndexHelper<METADATATYPE> {
* @param metadata opaque blob that will be stored and associated with the new
* GFile instance
* @return new GFile instance
* @throws IOException if error adding files (too many files)
*/
public synchronized GFile storeSymlinkWithParent(String filename, GFile parent, long fileIndex,
String symlinkPath, long length, METADATATYPE metadata) {
String symlinkPath, long length, METADATATYPE metadata) throws IOException {
length = length != 0 ? length : symlinkPath.length();
FileData<METADATATYPE> fileData =
doStoreFile(filename, parent, fileIndex, false, length, symlinkPath, metadata);
@@ -458,7 +464,13 @@ public class FileSystemIndexHelper<METADATATYPE> {
}
private FileData<METADATATYPE> doStoreFile(String filename, GFile parent, long fileIndex,
boolean isDirectory, long length, String symlinkPath, METADATATYPE metadata) {
boolean isDirectory, long length, String symlinkPath, METADATATYPE metadata)
throws IOException {
if (fileToEntryMap.size() > MAX_FILEENTRY_COUNT) {
throw new IOException("Too many file entries: " + fileToEntryMap.size());
}
parent = (parent == null) ? rootDir.file : parent;
long fileNum = (fileIndex != -1) ? fileIndex : fileToEntryMap.size();
if (fileIndexToEntryMap.containsKey(fileNum)) {

View File

@@ -0,0 +1,102 @@
/* ###
* 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.formats.gfilesystem;
import static org.junit.Assert.*;
import java.io.IOException;
import java.util.List;
import org.junit.Test;
import ghidra.app.util.bin.ByteProvider;
import ghidra.util.exception.CancelledException;
import ghidra.util.task.TaskMonitor;
public class FileSystemIndexHelperTest {
@Test
public void testMaxFiles() throws IOException {
FSRLRoot fsFSRL = FSRLRoot.makeRoot("dummy");
FileSystemIndexHelper<Object> fsih =
new FileSystemIndexHelper<Object>(new DummyFileSystem(), fsFSRL);
for (int i = 0; i < FileSystemIndexHelper.MAX_FILEENTRY_COUNT; i++) {
fsih.storeFile("file" + i, -1, false, 1, null);
}
try {
fsih.storeFile("toomuch", -1, false, 1, null);
fail("Should not get here");
}
catch (IOException e) {
// good
}
}
private static class DummyFileSystem implements GFileSystem {
@Override
public void close() throws IOException {
// empty dummy
}
@Override
public GFile lookup(String path) throws IOException {
// empty dummy
return null;
}
@Override
public boolean isClosed() {
// empty dummy
return false;
}
@Override
public FileSystemRefManager getRefManager() {
// empty dummy
return null;
}
@Override
public String getName() {
// empty dummy
return null;
}
@Override
public List<GFile> getListing(GFile directory) throws IOException {
// empty dummy
return null;
}
@Override
public FSRLRoot getFSRL() {
// empty dummy
return null;
}
@Override
public ByteProvider getByteProvider(GFile file, TaskMonitor monitor)
throws IOException, CancelledException {
// empty dummy
return null;
}
}
}