From bc228455251dfe76712320668e8e82f848d93265 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matthias=20Bl=C3=A4sing?= Date: Wed, 5 Dec 2018 11:20:16 -0600 Subject: [PATCH] Avoid exception when getting zero-length xattrs Closes: #1041 --- CHANGES.md | 1 + .../com/sun/jna/platform/linux/XAttrUtil.java | 12 +++++++++ .../com/sun/jna/platform/mac/XAttrUtil.java | 3 +++ .../sun/jna/platform/linux/XAttrUtilTest.java | 26 +++++++++++++++++++ .../sun/jna/platform/mac/XAttrUtilTest.java | 6 +++++ 5 files changed, 48 insertions(+) diff --git a/CHANGES.md b/CHANGES.md index c481730753..fb14f675e3 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -14,6 +14,7 @@ Bug Fixes --------- * [#1036](https://github.com/java-native-access/jna/issues/1036): `Advapi32Util.registryValueExists` called on non existing key raises exception instead of returning `false` - [@matthiasblaesing](https://github.com/matthiasblaesing). * [#384](https://github.com/java-native-access/jna/issues/384): Android only supports loading libraries through the JVM `System#loadLibrary` mechanism, defaulting `jna.nosys` to `true` disabled that code path - [@matthiasblaesing](https://github.com/matthiasblaesing). +* [#1041](https://github.com/java-native-access/jna/pull/1041): Avoid IllegalArgumentException when reading xattrs with zero length - [@jrobhoward](https://github.com/jrobhoward). Release 5.1.0 ============= diff --git a/contrib/platform/src/com/sun/jna/platform/linux/XAttrUtil.java b/contrib/platform/src/com/sun/jna/platform/linux/XAttrUtil.java index b9f7f75aeb..3176a4942f 100644 --- a/contrib/platform/src/com/sun/jna/platform/linux/XAttrUtil.java +++ b/contrib/platform/src/com/sun/jna/platform/linux/XAttrUtil.java @@ -255,6 +255,10 @@ public static Memory getXAttrAsMemory(String path, String name) throws IOExcepti throw new IOException("errno: " + eno); } + if (retval.longValue() == 0) { + return null; + } + valueMem = new Memory(retval.longValue()); retval = XAttr.INSTANCE.getxattr(path, name, valueMem, new size_t(valueMem.size())); if (retval.longValue() < 0) { @@ -352,6 +356,10 @@ public static Memory lGetXAttrAsMemory(String path, String name) throws IOExcept throw new IOException("errno: " + eno); } + if (retval.longValue() == 0) { + return null; + } + valueMem = new Memory(retval.longValue()); retval = XAttr.INSTANCE.lgetxattr(path, name, valueMem, new size_t(valueMem.size())); if (retval.longValue() < 0) { @@ -445,6 +453,10 @@ public static Memory fGetXAttrAsMemory(int fd, String name) throws IOException { throw new IOException("errno: " + eno); } + if (retval.longValue() == 0) { + return null; + } + valueMem = new Memory(retval.longValue()); retval = XAttr.INSTANCE.fgetxattr(fd, name, valueMem, new size_t(valueMem.size())); if (retval.longValue() < 0) { diff --git a/contrib/platform/src/com/sun/jna/platform/mac/XAttrUtil.java b/contrib/platform/src/com/sun/jna/platform/mac/XAttrUtil.java index e6a0559a40..150c3d95a4 100644 --- a/contrib/platform/src/com/sun/jna/platform/mac/XAttrUtil.java +++ b/contrib/platform/src/com/sun/jna/platform/mac/XAttrUtil.java @@ -58,6 +58,9 @@ public static String getXAttr(String path, String name) { if (bufferLength < 0) return null; + if (bufferLength == 0) + return ""; + Memory valueBuffer = new Memory(bufferLength); long valueLength = XAttr.INSTANCE.getxattr(path, name, valueBuffer, bufferLength, 0, 0); diff --git a/contrib/platform/test/com/sun/jna/platform/linux/XAttrUtilTest.java b/contrib/platform/test/com/sun/jna/platform/linux/XAttrUtilTest.java index c4a074b6a5..bd1f14f28f 100644 --- a/contrib/platform/test/com/sun/jna/platform/linux/XAttrUtilTest.java +++ b/contrib/platform/test/com/sun/jna/platform/linux/XAttrUtilTest.java @@ -24,6 +24,7 @@ */ package com.sun.jna.platform.linux; +import com.sun.jna.Memory; import java.io.File; import java.io.IOException; import java.util.Collection; @@ -33,12 +34,16 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertNotNull; public class XAttrUtilTest { private static final String TEST_STRING = "Žluťoučký kůň úpěl nebo tak něco."; private static final String TEST_STRING_2 = "Příliš žluťoučký kůň úpěl ďábelské ódy."; + private static final String TEST_EMPTY_STRING = ""; private static final String TEST_ATTRIBUTE = "user.test"; private static final String TEST_ATTRIBUTE_FOO = TEST_ATTRIBUTE + ".foo"; + private static final String TEST_ATTRIBUTE_EMPTY = TEST_ATTRIBUTE + ".empty"; @Test public void setXAttr() throws IOException { @@ -66,5 +71,26 @@ public void setXAttr() throws IOException { xattrs = XAttrUtil.lListXAttr(file.getAbsolutePath()); assertFalse(xattrs.contains(TEST_ATTRIBUTE)); assertTrue(xattrs.contains(TEST_ATTRIBUTE_FOO)); + + file.delete(); + } + + @Test + public void testGetXAttr() throws IOException { + File file = File.createTempFile("xattr", "test"); + file.deleteOnExit(); + + XAttrUtil.setXAttr(file.getAbsolutePath(), TEST_ATTRIBUTE_EMPTY, TEST_EMPTY_STRING); + + Memory memoryReadMissing = XAttrUtil.getXAttrAsMemory(file.getAbsolutePath(), TEST_ATTRIBUTE_EMPTY); + byte[] byteReadMissing = XAttrUtil.getXAttrBytes(file.getAbsolutePath(), TEST_ATTRIBUTE_EMPTY); + String stringReadMissing = XAttrUtil.getXAttr(file.getAbsolutePath(), TEST_ATTRIBUTE_EMPTY); + assertNull(memoryReadMissing); + assertNotNull(byteReadMissing); + assertEquals(0, byteReadMissing.length); + assertNotNull(stringReadMissing); + assertTrue(stringReadMissing.isEmpty()); + + file.delete(); } } \ No newline at end of file diff --git a/contrib/platform/test/com/sun/jna/platform/mac/XAttrUtilTest.java b/contrib/platform/test/com/sun/jna/platform/mac/XAttrUtilTest.java index 6abd401181..53abd3f3ff 100644 --- a/contrib/platform/test/com/sun/jna/platform/mac/XAttrUtilTest.java +++ b/contrib/platform/test/com/sun/jna/platform/mac/XAttrUtilTest.java @@ -12,6 +12,8 @@ */ package com.sun.jna.platform.mac; +import com.sun.jna.Memory; +import com.sun.jna.Pointer; import java.io.File; import java.util.Arrays; import java.util.List; @@ -58,6 +60,10 @@ public void testGetXAttr() { value = XAttrUtil.getXAttr(testPath, "JNA"); assertEquals(Arrays.toString("Java Native Access".getBytes()), Arrays.toString(value.getBytes())); + + XAttr.INSTANCE.setxattr(testPath, "JNA.empty", Pointer.NULL, 0, 0, 0); + value = XAttrUtil.getXAttr(testPath, "JNA.empty"); + assertEquals("", value); } public void testSetXAttr() {