mirror of
https://github.com/SquidDev-CC/CC-Tweaked
synced 2025-10-30 13:13:00 +00:00
Prevent copying folders inside themselves
- contains now performs a case-insensitive comparison. While this is a little dubious, it's required for systems like Windows, where foo and Foo are the same folder. - Impose a depth limit on copyRecursive. If there are any other cases where we may try to copy a folder into itself, this should prevent the computer entirely crashing.
This commit is contained in:
@@ -27,7 +27,7 @@ public class FileOperationException extends IOException
|
|||||||
this.filename = filename;
|
this.filename = filename;
|
||||||
}
|
}
|
||||||
|
|
||||||
public FileOperationException( String message )
|
public FileOperationException( @Nonnull String message )
|
||||||
{
|
{
|
||||||
super( Objects.requireNonNull( message, "message cannot be null" ) );
|
super( Objects.requireNonNull( message, "message cannot be null" ) );
|
||||||
this.filename = null;
|
this.filename = null;
|
||||||
|
|||||||
@@ -29,6 +29,14 @@ import java.util.regex.Pattern;
|
|||||||
|
|
||||||
public class FileSystem
|
public class FileSystem
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* Maximum depth that {@link #copyRecursive(String, MountWrapper, String, MountWrapper, int)} will descend into.
|
||||||
|
*
|
||||||
|
* This is a pretty arbitrary value, though hopefully it is large enough that it'll never be normally hit. This
|
||||||
|
* exists to prevent it overflowing if it ever gets into an infinite loop.
|
||||||
|
*/
|
||||||
|
private static final int MAX_COPY_DEPTH = 128;
|
||||||
|
|
||||||
private static class MountWrapper
|
private static class MountWrapper
|
||||||
{
|
{
|
||||||
private String m_label;
|
private String m_label;
|
||||||
@@ -611,15 +619,13 @@ public class FileSystem
|
|||||||
{
|
{
|
||||||
throw new FileSystemException( "/" + sourcePath + ": Can't copy a directory inside itself" );
|
throw new FileSystemException( "/" + sourcePath + ": Can't copy a directory inside itself" );
|
||||||
}
|
}
|
||||||
copyRecursive( sourcePath, getMount( sourcePath ), destPath, getMount( destPath ) );
|
copyRecursive( sourcePath, getMount( sourcePath ), destPath, getMount( destPath ), 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
private synchronized void copyRecursive( String sourcePath, MountWrapper sourceMount, String destinationPath, MountWrapper destinationMount ) throws FileSystemException
|
private synchronized void copyRecursive( String sourcePath, MountWrapper sourceMount, String destinationPath, MountWrapper destinationMount, int depth ) throws FileSystemException
|
||||||
{
|
{
|
||||||
if( !sourceMount.exists( sourcePath ) )
|
if( !sourceMount.exists( sourcePath ) ) return;
|
||||||
{
|
if( depth >= MAX_COPY_DEPTH ) throw new FileSystemException( "Too many directories to copy" );
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( sourceMount.isDirectory( sourcePath ) )
|
if( sourceMount.isDirectory( sourcePath ) )
|
||||||
{
|
{
|
||||||
@@ -634,7 +640,8 @@ public class FileSystem
|
|||||||
{
|
{
|
||||||
copyRecursive(
|
copyRecursive(
|
||||||
combine( sourcePath, child ), sourceMount,
|
combine( sourcePath, child ), sourceMount,
|
||||||
combine( destinationPath, child ), destinationMount
|
combine( destinationPath, child ), destinationMount,
|
||||||
|
depth + 1
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -854,8 +861,8 @@ public class FileSystem
|
|||||||
|
|
||||||
public static boolean contains( String pathA, String pathB )
|
public static boolean contains( String pathA, String pathB )
|
||||||
{
|
{
|
||||||
pathA = sanitizePath( pathA );
|
pathA = sanitizePath( pathA ).toLowerCase( Locale.ROOT );
|
||||||
pathB = sanitizePath( pathB );
|
pathB = sanitizePath( pathB ).toLowerCase( Locale.ROOT );
|
||||||
|
|
||||||
if( pathB.equals( ".." ) )
|
if( pathB.equals( ".." ) )
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -116,7 +116,7 @@ public class BasicEnvironment implements IComputerEnvironment
|
|||||||
while( baseFile != null && !wholeFile.exists() )
|
while( baseFile != null && !wholeFile.exists() )
|
||||||
{
|
{
|
||||||
baseFile = baseFile.getParentFile();
|
baseFile = baseFile.getParentFile();
|
||||||
wholeFile = new File( baseFile, "resources/" + fallback + "/" + path );
|
wholeFile = new File( baseFile, "src/" + fallback + "/resources/" + path );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( !wholeFile.exists() ) throw new IllegalStateException( "Cannot find ROM mount at " + file );
|
if( !wholeFile.exists() ) throw new IllegalStateException( "Cannot find ROM mount at " + file );
|
||||||
|
|||||||
@@ -125,6 +125,21 @@ describe("The fs library", function()
|
|||||||
it("fails on read-only mounts", function()
|
it("fails on read-only mounts", function()
|
||||||
expect.error(fs.copy, "rom", "rom/startup"):eq("/rom/startup: Access denied")
|
expect.error(fs.copy, "rom", "rom/startup"):eq("/rom/startup: Access denied")
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
it("fails to copy a folder inside itself", function()
|
||||||
|
fs.makeDir("some-folder")
|
||||||
|
expect.error(fs.copy, "some-folder", "some-folder/x"):eq("/some-folder: Can't copy a directory inside itself")
|
||||||
|
expect.error(fs.copy, "some-folder", "Some-Folder/x"):eq("/some-folder: Can't copy a directory inside itself")
|
||||||
|
end)
|
||||||
|
|
||||||
|
it("copies folders", function()
|
||||||
|
fs.delete("some-folder")
|
||||||
|
fs.delete("another-folder")
|
||||||
|
|
||||||
|
fs.makeDir("some-folder")
|
||||||
|
fs.copy("some-folder", "another-folder")
|
||||||
|
expect(fs.isDir("another-folder")):eq(true)
|
||||||
|
end)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
describe("fs.move", function()
|
describe("fs.move", function()
|
||||||
|
|||||||
Reference in New Issue
Block a user