mirror of
				https://github.com/SquidDev-CC/CC-Tweaked
				synced 2025-10-31 21:52:59 +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
	 SquidDev
					SquidDev