HADOOP-18136. Verify FileUtils.unTar() handling of missing .tar files.

Contributed by Steve Loughran

Change-Id: I73af19d2e2e41f4ba686c470726a80c3903a1950
This commit is contained in:
Steve Loughran 2022-02-21 17:08:22 +00:00
parent 007c2011ef
commit cae749b076
No known key found for this signature in database
GPG Key ID: D22CF846DBB162A0
2 changed files with 43 additions and 5 deletions

View File

@ -888,10 +888,13 @@ private static void unTarUsingTar(InputStream inputStream, File untarDir,
private static void unTarUsingTar(File inFile, File untarDir, private static void unTarUsingTar(File inFile, File untarDir,
boolean gzipped) throws IOException { boolean gzipped) throws IOException {
StringBuffer untarCommand = new StringBuffer(); StringBuffer untarCommand = new StringBuffer();
// not using canonical path here; this postpones relative path
// resolution until bash is executed.
final String source = "'" + FileUtil.makeSecureShellPath(inFile) + "'";
if (gzipped) { if (gzipped) {
untarCommand.append(" gzip -dc '") untarCommand.append(" gzip -dc ")
.append(FileUtil.makeSecureShellPath(inFile)) .append(source)
.append("' | ("); .append(" | (");
} }
untarCommand.append("cd '") untarCommand.append("cd '")
.append(FileUtil.makeSecureShellPath(untarDir)) .append(FileUtil.makeSecureShellPath(untarDir))
@ -901,15 +904,17 @@ private static void unTarUsingTar(File inFile, File untarDir,
if (gzipped) { if (gzipped) {
untarCommand.append(" -)"); untarCommand.append(" -)");
} else { } else {
untarCommand.append(FileUtil.makeSecureShellPath(inFile)); untarCommand.append(source);
} }
LOG.debug("executing [{}]", untarCommand);
String[] shellCmd = { "bash", "-c", untarCommand.toString() }; String[] shellCmd = { "bash", "-c", untarCommand.toString() };
ShellCommandExecutor shexec = new ShellCommandExecutor(shellCmd); ShellCommandExecutor shexec = new ShellCommandExecutor(shellCmd);
shexec.execute(); shexec.execute();
int exitcode = shexec.getExitCode(); int exitcode = shexec.getExitCode();
if (exitcode != 0) { if (exitcode != 0) {
throw new IOException("Error untarring file " + inFile + throw new IOException("Error untarring file " + inFile +
". Tar process exited with exit code " + exitcode); ". Tar process exited with exit code " + exitcode
+ " from command " + untarCommand);
} }
} }

View File

@ -17,6 +17,7 @@
*/ */
package org.apache.hadoop.fs; package org.apache.hadoop.fs;
import static org.apache.hadoop.test.LambdaTestUtils.intercept;
import static org.apache.hadoop.test.PlatformAssumptions.assumeNotWindows; import static org.apache.hadoop.test.PlatformAssumptions.assumeNotWindows;
import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
@ -1135,6 +1136,38 @@ public void testUntar() throws IOException {
doUntarAndVerify(new File(tarFileName), untarDir); doUntarAndVerify(new File(tarFileName), untarDir);
} }
/**
* Verify we can't unTar a file which isn't there.
* This will test different codepaths on Windows from unix,
* but both MUST throw an IOE of some kind.
*/
@Test(timeout = 30000)
public void testUntarMissingFile() throws Throwable {
File dataDir = GenericTestUtils.getTestDir();
File tarFile = new File(dataDir, "missing; true");
File untarDir = new File(dataDir, "untarDir");
intercept(IOException.class, () ->
FileUtil.unTar(tarFile, untarDir));
}
/**
* Verify we can't unTar a file which isn't there
* through the java untar code.
* This is how {@code FileUtil.unTar(File, File}
* will behave on Windows,
*/
@Test(timeout = 30000)
public void testUntarMissingFileThroughJava() throws Throwable {
File dataDir = GenericTestUtils.getTestDir();
File tarFile = new File(dataDir, "missing; true");
File untarDir = new File(dataDir, "untarDir");
// java8 on unix throws java.nio.file.NoSuchFileException here;
// leaving as an IOE intercept in case windows throws something
// else.
intercept(IOException.class, () ->
FileUtil.unTarUsingJava(tarFile, untarDir, false));
}
@Test (timeout = 30000) @Test (timeout = 30000)
public void testCreateJarWithClassPath() throws Exception { public void testCreateJarWithClassPath() throws Exception {
// create files expected to match a wildcard // create files expected to match a wildcard