HADOOP-15860. ABFS: Throw exception when directory / file name ends with a period (.). Contributed by Shweta Yakkali.
This commit is contained in:
parent
4d50ad030c
commit
13f0ee21f2
@ -193,6 +193,8 @@ public FSDataOutputStream create(final Path f, final FsPermission permission, fi
|
||||
overwrite,
|
||||
blockSize);
|
||||
|
||||
trailingPeriodCheck(f);
|
||||
|
||||
Path qualifiedPath = makeQualified(f);
|
||||
performAbfsAuthCheck(FsAction.WRITE, qualifiedPath);
|
||||
|
||||
@ -272,6 +274,8 @@ public boolean rename(final Path src, final Path dst) throws IOException {
|
||||
LOG.debug(
|
||||
"AzureBlobFileSystem.rename src: {} dst: {}", src.toString(), dst.toString());
|
||||
|
||||
trailingPeriodCheck(dst);
|
||||
|
||||
Path parentFolder = src.getParent();
|
||||
if (parentFolder == null) {
|
||||
return false;
|
||||
@ -376,11 +380,38 @@ public FileStatus[] listStatus(final Path f) throws IOException {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs a check for (.) until root in the path to throw an exception.
|
||||
* The purpose is to differentiate between dir/dir1 and dir/dir1.
|
||||
* Without the exception the behavior seen is dir1. will appear
|
||||
* to be present without it's actual creation as dir/dir1 and dir/dir1. are
|
||||
* treated as identical.
|
||||
* @param path the path to be checked for trailing period (.)
|
||||
* @throws IllegalArgumentException if the path has a trailing period (.)
|
||||
*/
|
||||
private void trailingPeriodCheck(Path path) throws IllegalArgumentException {
|
||||
while (!path.isRoot()){
|
||||
String pathToString = path.toString();
|
||||
if (pathToString.length() != 0) {
|
||||
if (pathToString.charAt(pathToString.length() - 1) == '.') {
|
||||
throw new IllegalArgumentException(
|
||||
"ABFS does not allow files or directories to end with a dot.");
|
||||
}
|
||||
path = path.getParent();
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean mkdirs(final Path f, final FsPermission permission) throws IOException {
|
||||
LOG.debug(
|
||||
"AzureBlobFileSystem.mkdirs path: {} permissions: {}", f, permission);
|
||||
|
||||
trailingPeriodCheck(f);
|
||||
|
||||
final Path parentFolder = f.getParent();
|
||||
if (parentFolder == null) {
|
||||
// Cannot create root
|
||||
|
@ -19,6 +19,7 @@
|
||||
package org.apache.hadoop.fs.azurebfs;
|
||||
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Callable;
|
||||
@ -34,6 +35,11 @@
|
||||
import org.apache.hadoop.fs.Path;
|
||||
import org.apache.hadoop.fs.contract.ContractTestUtils;
|
||||
|
||||
import static org.apache.hadoop.fs.contract.ContractTestUtils.assertMkdirs;
|
||||
import static org.apache.hadoop.fs.contract.ContractTestUtils.createFile;
|
||||
import static org.apache.hadoop.fs.contract.ContractTestUtils.assertPathExists;
|
||||
import static org.apache.hadoop.fs.contract.ContractTestUtils.rename;
|
||||
|
||||
import static org.apache.hadoop.test.LambdaTestUtils.intercept;
|
||||
|
||||
/**
|
||||
@ -169,4 +175,65 @@ private void assertIsFileReference(FileStatus status) {
|
||||
assertFalse("Not a file: " + status, status.isDirectory());
|
||||
assertTrue("Not a file: " + status, status.isFile());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMkdirTrailingPeriodDirName() throws IOException {
|
||||
boolean exceptionThrown = false;
|
||||
final AzureBlobFileSystem fs = getFileSystem();
|
||||
|
||||
Path nontrailingPeriodDir = path("testTrailingDir/dir");
|
||||
Path trailingPeriodDir = path("testTrailingDir/dir.");
|
||||
|
||||
assertMkdirs(fs, nontrailingPeriodDir);
|
||||
|
||||
try {
|
||||
fs.mkdirs(trailingPeriodDir);
|
||||
}
|
||||
catch(IllegalArgumentException e) {
|
||||
exceptionThrown = true;
|
||||
}
|
||||
assertTrue("Attempt to create file that ended with a dot should"
|
||||
+ " throw IllegalArgumentException", exceptionThrown);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateTrailingPeriodFileName() throws IOException {
|
||||
boolean exceptionThrown = false;
|
||||
final AzureBlobFileSystem fs = getFileSystem();
|
||||
|
||||
Path trailingPeriodFile = path("testTrailingDir/file.");
|
||||
Path nontrailingPeriodFile = path("testTrailingDir/file");
|
||||
|
||||
createFile(fs, nontrailingPeriodFile, false, new byte[0]);
|
||||
assertPathExists(fs, "Trailing period file does not exist",
|
||||
nontrailingPeriodFile);
|
||||
|
||||
try {
|
||||
createFile(fs, trailingPeriodFile, false, new byte[0]);
|
||||
}
|
||||
catch(IllegalArgumentException e) {
|
||||
exceptionThrown = true;
|
||||
}
|
||||
assertTrue("Attempt to create file that ended with a dot should"
|
||||
+ " throw IllegalArgumentException", exceptionThrown);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRenameTrailingPeriodFile() throws IOException {
|
||||
boolean exceptionThrown = false;
|
||||
final AzureBlobFileSystem fs = getFileSystem();
|
||||
|
||||
Path nonTrailingPeriodFile = path("testTrailingDir/file");
|
||||
Path trailingPeriodFile = path("testTrailingDir/file.");
|
||||
|
||||
createFile(fs, nonTrailingPeriodFile, false, new byte[0]);
|
||||
try {
|
||||
rename(fs, nonTrailingPeriodFile, trailingPeriodFile);
|
||||
}
|
||||
catch(IllegalArgumentException e) {
|
||||
exceptionThrown = true;
|
||||
}
|
||||
assertTrue("Attempt to create file that ended with a dot should"
|
||||
+ " throw IllegalArgumentException", exceptionThrown);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user