Author: cnauroth Date: Fri May 16 05:59:18 2014 New Revision: 1595110 URL: http://svn.apache.org/r1595110 Log: HDFS-6413. xattr names erroneously handled as case-insensitive. Contributed by Charles Lamb.
Modified: hadoop/common/branches/HDFS-2006/hadoop-hdfs-project/hadoop-hdfs/CHANGES-HDFS-2006.txt hadoop/common/branches/HDFS-2006/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/XAttrHelper.java hadoop/common/branches/HDFS-2006/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/FSDirectory.java hadoop/common/branches/HDFS-2006/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/TestDFSShell.java Modified: hadoop/common/branches/HDFS-2006/hadoop-hdfs-project/hadoop-hdfs/CHANGES-HDFS-2006.txt URL: http://svn.apache.org/viewvc/hadoop/common/branches/HDFS-2006/hadoop-hdfs-project/hadoop-hdfs/CHANGES-HDFS-2006.txt?rev=1595110&r1=1595109&r2=1595110&view=diff ============================================================================== --- hadoop/common/branches/HDFS-2006/hadoop-hdfs-project/hadoop-hdfs/CHANGES-HDFS-2006.txt (original) +++ hadoop/common/branches/HDFS-2006/hadoop-hdfs-project/hadoop-hdfs/CHANGES-HDFS-2006.txt Fri May 16 05:59:18 2014 @@ -61,3 +61,6 @@ HDFS-2006 (Unreleased) HDFS-6410. DFSClient unwraps AclException in xattr methods, but those methods cannot throw AclException. (wang) + + HDFS-6413. xattr names erroneously handled as case-insensitive. + (Charles Lamb via cnauroth) Modified: hadoop/common/branches/HDFS-2006/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/XAttrHelper.java URL: http://svn.apache.org/viewvc/hadoop/common/branches/HDFS-2006/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/XAttrHelper.java?rev=1595110&r1=1595109&r2=1595110&view=diff ============================================================================== --- hadoop/common/branches/HDFS-2006/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/XAttrHelper.java (original) +++ hadoop/common/branches/HDFS-2006/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/XAttrHelper.java Fri May 16 05:59:18 2014 @@ -57,7 +57,7 @@ public class XAttrHelper { } NameSpace ns; - final String prefix = name.substring(0, prefixIndex); + final String prefix = name.substring(0, prefixIndex).toLowerCase(); if (prefix.equals(NameSpace.USER.toString().toLowerCase())) { ns = NameSpace.USER; } else if (prefix.equals(NameSpace.TRUSTED.toString().toLowerCase())) { Modified: hadoop/common/branches/HDFS-2006/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/FSDirectory.java URL: http://svn.apache.org/viewvc/hadoop/common/branches/HDFS-2006/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/FSDirectory.java?rev=1595110&r1=1595109&r2=1595110&view=diff ============================================================================== --- hadoop/common/branches/HDFS-2006/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/FSDirectory.java (original) +++ hadoop/common/branches/HDFS-2006/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/FSDirectory.java Fri May 16 05:59:18 2014 @@ -2909,7 +2909,7 @@ public class FSDirectory implements Clos List<XAttr> xAttrs = Lists.newArrayListWithCapacity(existingXAttrs.size()); for (XAttr a : existingXAttrs) { if (!(a.getNameSpace() == xAttr.getNameSpace() - && a.getName().equalsIgnoreCase(xAttr.getName()))) { + && a.getName().equals(xAttr.getName()))) { xAttrs.add(a); } } @@ -2947,7 +2947,7 @@ public class FSDirectory implements Clos if (existingXAttrs != null) { for (XAttr a: existingXAttrs) { if ((a.getNameSpace() == xAttr.getNameSpace() - && a.getName().equalsIgnoreCase(xAttr.getName()))) { + && a.getName().equals(xAttr.getName()))) { exist = true; } else { xAttrs.add(a); Modified: hadoop/common/branches/HDFS-2006/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/TestDFSShell.java URL: http://svn.apache.org/viewvc/hadoop/common/branches/HDFS-2006/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/TestDFSShell.java?rev=1595110&r1=1595109&r2=1595110&view=diff ============================================================================== --- hadoop/common/branches/HDFS-2006/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/TestDFSShell.java (original) +++ hadoop/common/branches/HDFS-2006/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/TestDFSShell.java Fri May 16 05:59:18 2014 @@ -1950,6 +1950,108 @@ public class TestDFSShell { } } + /* HDFS-6413 xattr names erroneously handled as case-insensitive */ + @Test (timeout = 30000) + public void testSetXAttrCaseSensitivity() throws Exception { + UserGroupInformation user = UserGroupInformation. + createUserForTesting("user", new String[] {"mygroup"}); + MiniDFSCluster cluster = null; + PrintStream bak = null; + try { + final Configuration conf = new HdfsConfiguration(); + cluster = new MiniDFSCluster.Builder(conf).numDataNodes(1).build(); + cluster.waitActive(); + + FileSystem fs = cluster.getFileSystem(); + Path p = new Path("/mydir"); + fs.mkdirs(p); + bak = System.err; + + final FsShell fshell = new FsShell(conf); + final ByteArrayOutputStream out = new ByteArrayOutputStream(); + System.setOut(new PrintStream(out)); + + doSetXattr(out, fshell, + new String[] {"-setfattr", "-n", "User.Foo", "/mydir"}, + new String[] {"-getfattr", "-d", "/mydir"}, + new String[] {"user.Foo"}, + new String[] {}); + + doSetXattr(out, fshell, + new String[] {"-setfattr", "-n", "user.FOO", "/mydir"}, + new String[] {"-getfattr", "-d", "/mydir"}, + new String[] {"user.Foo", "user.FOO"}, + new String[] {}); + + doSetXattr(out, fshell, + new String[] {"-setfattr", "-n", "USER.foo", "/mydir"}, + new String[] {"-getfattr", "-d", "/mydir"}, + new String[] {"user.Foo", "user.FOO", "user.foo"}, + new String[] {}); + + doSetXattr(out, fshell, + new String[] {"-setfattr", "-n", "USER.fOo", "-v", "myval", "/mydir"}, + new String[] {"-getfattr", "-d", "/mydir"}, + new String[] {"user.Foo", "user.FOO", "user.foo", "user.fOo=\"myval\""}, + new String[] {"user.Foo=", "user.FOO=", "user.foo="}); + + doSetXattr(out, fshell, + new String[] {"-setfattr", "-x", "useR.foo", "/mydir"}, + new String[] {"-getfattr", "-d", "/mydir"}, + new String[] {"user.Foo", "user.FOO"}, + new String[] {"foo"}); + + doSetXattr(out, fshell, + new String[] {"-setfattr", "-x", "USER.FOO", "/mydir"}, + new String[] {"-getfattr", "-d", "/mydir"}, + new String[] {"user.Foo"}, + new String[] {"FOO"}); + + doSetXattr(out, fshell, + new String[] {"-setfattr", "-x", "useR.Foo", "/mydir"}, + new String[] {"-getfattr", "-n", "User.Foo", "/mydir"}, + new String[] {}, + new String[] {"Foo"}); + + } finally { + if (bak != null) { + System.setOut(bak); + } + if (cluster != null) { + cluster.shutdown(); + } + } + } + + private void doSetXattr(ByteArrayOutputStream out, FsShell fshell, + String[] setOp, String[] getOp, String[] expectArr, + String[] dontExpectArr) throws Exception { + int ret = ToolRunner.run(fshell, setOp); + out.reset(); + ret = ToolRunner.run(fshell, getOp); + final String str = out.toString(); + for (int i = 0; i < expectArr.length; i++) { + final String expect = expectArr[i]; + final StringBuilder sb = new StringBuilder + ("Incorrect results from getfattr. Expected: "); + sb.append(expect).append(" Full Result: "); + sb.append(str); + assertTrue(sb.toString(), + str.indexOf(expect) != -1); + } + + for (int i = 0; i < dontExpectArr.length; i++) { + String dontExpect = dontExpectArr[i]; + final StringBuilder sb = new StringBuilder + ("Incorrect results from getfattr. Didn't Expect: "); + sb.append(dontExpect).append(" Full Result: "); + sb.append(str); + assertTrue(sb.toString(), + str.indexOf(dontExpect) == -1); + } + out.reset(); + } + /** * Test that the server trash configuration is respected when * the client configuration is not set.