diff --git a/README.md b/README.md index afe5d1a6..0332a965 100644 --- a/README.md +++ b/README.md @@ -126,6 +126,7 @@ The library will remain open source and MIT licensed and can still be used, fork ##### Changes in 5.1.1 (not released yet): - Added new Helper class `VariantBuilder` to allow creating Variants which contain Maps or Collections without messing with the required DBus type arguments + - Fixed wrong/missing increment when resolving nested structs or deeply nested objects in `Marshalling.getDBusType` ([#265](https://github.com/hypfvieh/dbus-java/issues/265)) ##### Changes in 5.1.0 (2024-08-01): - Use Junit BOM thanks to [spannm](https://github.com/spannm) ([PR#248](https://github.com/hypfvieh/dbus-java/issues/248)) diff --git a/dbus-java-core/src/main/java/org/freedesktop/dbus/Marshalling.java b/dbus-java-core/src/main/java/org/freedesktop/dbus/Marshalling.java index 30ecbf98..20384381 100644 --- a/dbus-java-core/src/main/java/org/freedesktop/dbus/Marshalling.java +++ b/dbus-java-core/src/main/java/org/freedesktop/dbus/Marshalling.java @@ -22,6 +22,9 @@ * Contains static methods for marshalling values. */ public final class Marshalling { + /** Used as initial and incremental size of StringBuffer array when resolving DBusTypes recursively. */ + private static final int INITIAL_BUFFER_SZ = 10; + private static final String MTH_NAME_DESERIALIZE = "deserialize"; private static final String ERROR_MULTI_VALUED_ARRAY = "Multi-valued array types not permitted"; @@ -177,13 +180,13 @@ public static String[] getDBusType(Type _javaType) throws DBusException { * @throws DBusException If the given type cannot be converted to a DBus type. */ public static String[] getDBusType(Type _dataType, boolean _basic) throws DBusException { - return recursiveGetDBusType(new StringBuffer[10], _dataType, _basic, 0); + return recursiveGetDBusType(new StringBuffer[INITIAL_BUFFER_SZ], _dataType, _basic, 0); } @SuppressWarnings("checkstyle:parameterassignment") private static String[] recursiveGetDBusType(StringBuffer[] _out, Type _dataType, boolean _basic, int _level) throws DBusException { if (_out.length <= _level) { - StringBuffer[] newout = new StringBuffer[_out.length]; + StringBuffer[] newout = new StringBuffer[_level + INITIAL_BUFFER_SZ]; System.arraycopy(_out, 0, newout, 0, _out.length); _out = newout; } diff --git a/dbus-java-tests/src/test/java/sample/issue/Issue265Test.java b/dbus-java-tests/src/test/java/sample/issue/Issue265Test.java new file mode 100644 index 00000000..253a4d17 --- /dev/null +++ b/dbus-java-tests/src/test/java/sample/issue/Issue265Test.java @@ -0,0 +1,146 @@ +package sample.issue; + +import org.freedesktop.dbus.Marshalling; +import org.freedesktop.dbus.Struct; +import org.freedesktop.dbus.annotations.Position; +import org.freedesktop.dbus.exceptions.DBusException; +import org.freedesktop.dbus.test.AbstractBaseTest; +import org.junit.jupiter.api.Test; + +import java.util.Arrays; + +class Issue265Test extends AbstractBaseTest { + + @Test + public void testNestedStruct() throws DBusException { + String[] dBusType = Marshalling.getDBusType(Struct1.class); + + // Every struct has 2 bytes signature: open/closing bracket + // Struct1 has one additional int member + // this test uses nested structs with a depth of 15 + // => 3 * 15 bytes should be in signature string at the end + int expectedSigLen = 3 * 15; + + assertEquals(1, dBusType.length); + assertEquals(expectedSigLen, dBusType[0].length()); + assertEquals("[(i(i(i(i(i(i(i(i(i(i(i(i(i(i(i)))))))))))))))]", Arrays.toString(dBusType)); + } + + public static class Struct1 extends Struct { + @Position(0) + private int foo; + + @Position(1) + private Struct2 inner; + } + + public static class Struct2 extends Struct { + @Position(0) + private int foo; + + @Position(1) + private Struct3 inner; + } + + public static class Struct3 extends Struct { + @Position(0) + private int foo; + + @Position(1) + private Struct4 inner; + } + + public static class Struct4 extends Struct { + @Position(0) + private int foo; + + @Position(1) + private Struct5 inner; + } + + public static class Struct5 extends Struct { + @Position(0) + private int foo; + + @Position(1) + private Struct6 inner; + } + + public static class Struct6 extends Struct { + @Position(0) + private int foo; + + @Position(1) + private Struct7 inner; + } + + public static class Struct7 extends Struct { + @Position(0) + private int foo; + + @Position(1) + private Struct8 inner; + } + + public static class Struct8 extends Struct { + @Position(0) + private int foo; + + @Position(1) + private Struct9 inner; + } + + public static class Struct9 extends Struct { + @Position(0) + private int foo; + + @Position(1) + private Struct10 inner; + } + + public static class Struct10 extends Struct { + @Position(0) + private int foo; + + @Position(1) + private Struct11 inner; + } + + public static class Struct11 extends Struct { + @Position(0) + private int foo; + + @Position(1) + private Struct12 inner; + } + + public static class Struct12 extends Struct { + @Position(0) + private int foo; + + @Position(1) + private Struct13 inner; + } + + public static class Struct13 extends Struct { + @Position(0) + private int foo; + + @Position(1) + private Struct14 inner; + } + + public static class Struct14 extends Struct { + @Position(0) + private int foo; + + @Position(1) + private Struct15 inner; + } + + public static class Struct15 extends Struct { + @Position(0) + private int foo; + + } +}