HADOOP-15860. ABFS: Throw exception when directory / file name ends with a period (.).
Contributed by Shweta Yakkali.
(cherry picked from commit 13f0ee21f2
)
Change-Id: Ibd010d2e6adc15f53a9c5357482e57313bf84d2e
This commit is contained in:
parent
3593b66693
commit
57c6060c3a
|
@ -176,6 +176,8 @@ public class AzureBlobFileSystem extends FileSystem {
|
||||||
overwrite,
|
overwrite,
|
||||||
blockSize);
|
blockSize);
|
||||||
|
|
||||||
|
trailingPeriodCheck(f);
|
||||||
|
|
||||||
Path qualifiedPath = makeQualified(f);
|
Path qualifiedPath = makeQualified(f);
|
||||||
performAbfsAuthCheck(FsAction.WRITE, qualifiedPath);
|
performAbfsAuthCheck(FsAction.WRITE, qualifiedPath);
|
||||||
|
|
||||||
|
@ -255,6 +257,8 @@ public class AzureBlobFileSystem extends FileSystem {
|
||||||
LOG.debug(
|
LOG.debug(
|
||||||
"AzureBlobFileSystem.rename src: {} dst: {}", src.toString(), dst.toString());
|
"AzureBlobFileSystem.rename src: {} dst: {}", src.toString(), dst.toString());
|
||||||
|
|
||||||
|
trailingPeriodCheck(dst);
|
||||||
|
|
||||||
Path parentFolder = src.getParent();
|
Path parentFolder = src.getParent();
|
||||||
if (parentFolder == null) {
|
if (parentFolder == null) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -359,11 +363,38 @@ public class AzureBlobFileSystem extends FileSystem {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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
|
@Override
|
||||||
public boolean mkdirs(final Path f, final FsPermission permission) throws IOException {
|
public boolean mkdirs(final Path f, final FsPermission permission) throws IOException {
|
||||||
LOG.debug(
|
LOG.debug(
|
||||||
"AzureBlobFileSystem.mkdirs path: {} permissions: {}", f, permission);
|
"AzureBlobFileSystem.mkdirs path: {} permissions: {}", f, permission);
|
||||||
|
|
||||||
|
trailingPeriodCheck(f);
|
||||||
|
|
||||||
final Path parentFolder = f.getParent();
|
final Path parentFolder = f.getParent();
|
||||||
if (parentFolder == null) {
|
if (parentFolder == null) {
|
||||||
// Cannot create root
|
// Cannot create root
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
package org.apache.hadoop.fs.azurebfs;
|
package org.apache.hadoop.fs.azurebfs;
|
||||||
|
|
||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.Callable;
|
import java.util.concurrent.Callable;
|
||||||
|
@ -34,6 +35,11 @@ import org.apache.hadoop.fs.LocatedFileStatus;
|
||||||
import org.apache.hadoop.fs.Path;
|
import org.apache.hadoop.fs.Path;
|
||||||
import org.apache.hadoop.fs.contract.ContractTestUtils;
|
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;
|
import static org.apache.hadoop.test.LambdaTestUtils.intercept;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -169,4 +175,65 @@ public class ITestAzureBlobFileSystemListStatus extends
|
||||||
assertFalse("Not a file: " + status, status.isDirectory());
|
assertFalse("Not a file: " + status, status.isDirectory());
|
||||||
assertTrue("Not a file: " + status, status.isFile());
|
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