All Downloads are FREE. Search and download functionalities are using the official Maven repository.

bt.data.file.FileSystemStorage Maven / Gradle / Ivy

There is a newer version: 1.10
Show newest version
package bt.data.file;

import bt.data.StorageUnit;
import bt.data.Storage;
import bt.metainfo.Torrent;
import bt.metainfo.TorrentFile;

import java.io.File;
import java.nio.file.Path;

/**
 * Provides file-system based storage for torrent files.
 *
 * 

Information about the collection of files in a torrent is stored as a list of strings in the torrent metainfo. * This makes it possible for malicious parties to create torrents with malformed pathnames, * e.g. by using relative paths (. and ..), empty and invalid directory and file names, etc. * In the worst case this can lead to loss and corruption of user data and execution of arbitrary code. * *

This storage implementation performs normalization of file paths, ensuring that: *

    *
  • all torrent files are stored inside the root directory of this storage (see {@link #FileSystemStorage(File)})
  • *
  • all individual paths are checked for potential issues and fixed in a consistent way (see below)
  • *
* *

Algorithm for resolving paths:
* 1) The following transformations are applied to each individual path element: *

    *
  • trimming whitespaces,
  • *
  • truncating trailing dots and whitespaces recursively,
  • *
  • substituting empty names with an underscore character * (this also includes names that became empty after the truncation of whitespaces and dots),
  • *
  • in case there is a leading or trailing file separator, * it is assumed that the path starts or ends with an empty name, respectively.
  • *

* 2) Normalized path elements are concatenated together using {@link File#separator} as the delimiter. * *

Examples:
* {@code "a/b/c" => "a/b/c"}
* {@code " a/ b /c" => "a/b/c"}
* {@code ".a/.b" => ".a/.b"}
* {@code "a./.b." => "a/.b"}
* {@code "" => "_"}
* {@code "a//b" => "a/_/b"}
* {@code "." => "_"}
* {@code ".." => "_"}
* {@code "/" => "_/_"}
* {@code "/a/b/c" => "_/a/b/c"}
* * @since 1.0 */ public class FileSystemStorage implements Storage { private final Path rootDirectory; private final PathNormalizer pathNormalizer; /** * Create a file-system based storage inside a given directory. * * @param rootDirectory Root directory for this storage. All torrent files will be stored inside this directory. * @since 1.0 * @deprecated since 1.3 in favor of more generic {@link #FileSystemStorage(Path)} */ @Deprecated public FileSystemStorage(File rootDirectory) { this(rootDirectory.toPath()); } public FileSystemStorage(Path rootDirectory) { this.rootDirectory = rootDirectory; this.pathNormalizer = new PathNormalizer(); } @Override public StorageUnit getUnit(Torrent torrent, TorrentFile torrentFile) { Path torrentDirectory; if (torrent.getFiles().size() == 1) { torrentDirectory = rootDirectory; } else { String normalizedName = pathNormalizer.normalize(torrent.getName()); torrentDirectory = rootDirectory.resolve(normalizedName); } String normalizedPath = pathNormalizer.normalize(torrentFile.getPathElements()); return new FileSystemStorageUnit(torrentDirectory, normalizedPath, torrentFile.getSize()); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy