Prechádzať zdrojové kódy

HDFS-8963. Fix incorrect sign extension of xattr length in HDFS-8900. (Colin Patrick McCabe via yliu)

yliu 9 rokov pred
rodič
commit
e166c038c0

+ 3 - 0
hadoop-hdfs-project/hadoop-hdfs/CHANGES.txt

@@ -1243,6 +1243,9 @@ Release 2.8.0 - UNRELEASED
     HDFS-8969. Clean up findbugs warnings for HDFS-8823 and HDFS-8932.
     (Anu Engineer via wheat9)
 
+    HDFS-8963. Fix incorrect sign extension of xattr length in HDFS-8900.
+    (Colin Patrick McCabe via yliu)
+
 Release 2.7.2 - UNRELEASED
 
   INCOMPATIBLE CHANGES

+ 10 - 4
hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/XAttrFormat.java

@@ -61,12 +61,15 @@ class XAttrFormat {
     for (int i = 0; i < attrs.length;) {
       XAttr.Builder builder = new XAttr.Builder();
       // big-endian
-      int v = Ints.fromBytes(attrs[i++], attrs[i++], attrs[i++], attrs[i++]);
+      int v = Ints.fromBytes(attrs[i], attrs[i + 1],
+          attrs[i + 2], attrs[i + 3]);
+      i += 4;
       int ns = (v >> XATTR_NAMESPACE_OFFSET) & XATTR_NAMESPACE_MASK;
       int nid = v & XATTR_NAME_MASK;
       builder.setNameSpace(XATTR_NAMESPACE_VALUES[ns]);
       builder.setName(XAttrStorage.getName(nid));
-      int vlen = (attrs[i++] << 8) | attrs[i++];
+      int vlen = ((0xff & attrs[i]) << 8) | (0xff & attrs[i + 1]);
+      i += 2;
       if (vlen > 0) {
         byte[] value = new byte[vlen];
         System.arraycopy(attrs, i, value, 0, vlen);
@@ -94,12 +97,15 @@ class XAttrFormat {
     XAttr xAttr = XAttrHelper.buildXAttr(prefixedName);
     for (int i = 0; i < attrs.length;) {
       // big-endian
-      int v = Ints.fromBytes(attrs[i++], attrs[i++], attrs[i++], attrs[i++]);
+      int v = Ints.fromBytes(attrs[i], attrs[i + 1],
+          attrs[i + 2], attrs[i + 3]);
+      i += 4;
       int ns = (v >> XATTR_NAMESPACE_OFFSET) & XATTR_NAMESPACE_MASK;
       int nid = v & XATTR_NAME_MASK;
       XAttr.NameSpace namespace = XATTR_NAMESPACE_VALUES[ns];
       String name = XAttrStorage.getName(nid);
-      int vlen = (attrs[i++] << 8) | attrs[i++];
+      int vlen = ((0xff & attrs[i]) << 8) | (0xff & attrs[i + 1]);
+      i += 2;
       if (xAttr.getNameSpace() == namespace &&
           xAttr.getName().equals(name)) {
         if (vlen > 0) {

+ 12 - 0
hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/server/namenode/TestXAttrFeature.java

@@ -43,6 +43,14 @@ public class TestXAttrFeature {
   static final String name7 = "raw.a7";
   static final byte[] value7 = {0x011, 0x012, 0x013};
   static final String name8 = "user.a8";
+  static final String bigXattrKey = "user.big.xattr.key";
+  static final byte[] bigXattrValue = new byte[128];
+
+  static {
+    for (int i = 0; i < bigXattrValue.length; i++) {
+      bigXattrValue[i] = (byte) (i & 0xff);
+    }
+  }
 
   static byte[] randomBytes(int len) {
     Random rand = new Random();
@@ -74,12 +82,14 @@ public class TestXAttrFeature {
     XAttr a5 = XAttrHelper.buildXAttr(name5, value5);
     XAttr a6 = XAttrHelper.buildXAttr(name6, value6);
     XAttr a7 = XAttrHelper.buildXAttr(name7, value7);
+    XAttr bigXattr = XAttrHelper.buildXAttr(bigXattrKey, bigXattrValue);
     xAttrs.add(a2);
     xAttrs.add(a3);
     xAttrs.add(a4);
     xAttrs.add(a5);
     xAttrs.add(a6);
     xAttrs.add(a7);
+    xAttrs.add(bigXattr);
     feature = new XAttrFeature(xAttrs);
 
     XAttr r2 = feature.getXAttr(name2);
@@ -94,6 +104,8 @@ public class TestXAttrFeature {
     assertTrue(a6.equals(r6));
     XAttr r7 = feature.getXAttr(name7);
     assertTrue(a7.equals(r7));
+    XAttr rBigXattr = feature.getXAttr(bigXattrKey);
+    assertTrue(bigXattr.equals(rBigXattr));
     List<XAttr> rs = feature.getXAttrs();
     assertEquals(rs.size(), xAttrs.size());
     for (int i = 0; i < rs.size(); i++) {