From 1192781a78e7fcfcbf01b15de5d5a1f22d982e0d Mon Sep 17 00:00:00 2001 From: Chris Douglas Date: Thu, 8 Sep 2016 17:46:12 -0700 Subject: [PATCH] HADOOP-13519. Make Path Serializable. Contributed by Steve Loughran --- .../main/java/org/apache/hadoop/fs/Path.java | 20 ++++++++++++++++++- .../java/org/apache/hadoop/fs/TestPath.java | 20 +++++++++++++++++++ 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/Path.java b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/Path.java index f18a675d1e7..252b3cca79a 100644 --- a/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/Path.java +++ b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/Path.java @@ -19,6 +19,9 @@ package org.apache.hadoop.fs; import java.io.IOException; +import java.io.InvalidObjectException; +import java.io.ObjectInputValidation; +import java.io.Serializable; import java.net.URI; import java.net.URISyntaxException; import java.util.regex.Pattern; @@ -37,7 +40,7 @@ @Stringable @InterfaceAudience.Public @InterfaceStability.Stable -public class Path implements Comparable { +public class Path implements Comparable, Serializable, ObjectInputValidation { /** * The directory separator, a slash. @@ -66,6 +69,8 @@ public class Path implements Comparable { private static final Pattern HAS_DRIVE_LETTER_SPECIFIER = Pattern.compile("^/?[a-zA-Z]:"); + private static final long serialVersionUID = 0xad00f; + private URI uri; // a hierarchical uri /** @@ -565,4 +570,17 @@ public Path makeQualified(URI defaultUri, Path workingDir ) { } return new Path(newUri); } + + /** + * Validate the contents of a deserialized Path, so as + * to defend against malicious object streams. + * @throws InvalidObjectException if there's no URI + */ + @Override + public void validateObject() throws InvalidObjectException { + if (uri == null) { + throw new InvalidObjectException("No URI in deserialized Path"); + } + + } } diff --git a/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/fs/TestPath.java b/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/fs/TestPath.java index dc48a103430..5123526e6ed 100644 --- a/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/fs/TestPath.java +++ b/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/fs/TestPath.java @@ -17,9 +17,14 @@ */ package org.apache.hadoop.fs; +import org.junit.Assert; import org.junit.Test; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; import java.net.URI; import java.net.URISyntaxException; import java.util.Arrays; @@ -506,4 +511,19 @@ public void testIsWindowsAbsolutePath() { assertFalse(Path.isWindowsAbsolutePath("C:test", false)); assertFalse(Path.isWindowsAbsolutePath("/C:test", true)); } + + @Test(timeout = 30000) + public void testSerDeser() throws Throwable { + Path source = new Path("hdfs://localhost:4040/scratch"); + ByteArrayOutputStream baos = new ByteArrayOutputStream(256); + try(ObjectOutputStream oos = new ObjectOutputStream(baos)) { + oos.writeObject(source); + } + ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); + try (ObjectInputStream ois = new ObjectInputStream(bais)) { + Path deser = (Path) ois.readObject(); + Assert.assertEquals(source, deser); + } + + } }