From d3de2d65b93509ac374e573e6bb491c56a2870ef Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Tue, 15 Oct 2024 12:50:59 +0200 Subject: [PATCH] [xdata] Avoid NPE if form field's name is not set Do not throw an NPE if an form field without a name, i.e., the 'var' attribute, is received. Thanks to Peter Kaul for reporting this. --- .../smackx/xdata/provider/DataFormProvider.java | 14 +++++++++++--- .../xdata/provider/DataFormProviderTest.java | 14 ++++++++++++++ 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/xdata/provider/DataFormProvider.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/xdata/provider/DataFormProvider.java index 0b32e3adc..f0fc2c5af 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/xdata/provider/DataFormProvider.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/xdata/provider/DataFormProvider.java @@ -29,6 +29,7 @@ import javax.xml.namespace.QName; import org.jivesoftware.smack.packet.XmlEnvironment; import org.jivesoftware.smack.parsing.SmackParsingException; +import org.jivesoftware.smack.parsing.SmackParsingException.RequiredValueMissingException; import org.jivesoftware.smack.provider.ExtensionElementProvider; import org.jivesoftware.smack.roster.packet.RosterPacket; import org.jivesoftware.smack.roster.provider.RosterPacketProvider; @@ -185,9 +186,8 @@ public class DataFormProvider extends ExtensionElementProvider { FormField.Type type = null; { String fieldTypeString = parser.getAttributeValue("type"); - if (fieldTypeString != null) { - type = FormField.Type.fromString(fieldTypeString); - } + // FormField.Type.fromString() will return null if its input is null. + type = FormField.Type.fromString(fieldTypeString); } List values = new ArrayList<>(); @@ -238,6 +238,14 @@ public class DataFormProvider extends ExtensionElementProvider { } } + if (type != FormField.Type.fixed && fieldName == null) { + String typeString = "unspecified"; + if (type != null) { + typeString = type.toString(); + } + throw new RequiredValueMissingException("The data form field of " + typeString + " type has no 'var' attribute, even though one is required as per XEP-0004 § 3.2"); + } + if (type == null) { // The field name 'FORM_TYPE' is magic. if (fieldName.equals(FormField.FORM_TYPE)) { diff --git a/smack-extensions/src/test/java/org/jivesoftware/smackx/xdata/provider/DataFormProviderTest.java b/smack-extensions/src/test/java/org/jivesoftware/smackx/xdata/provider/DataFormProviderTest.java index 3d901a8fc..b08807d82 100644 --- a/smack-extensions/src/test/java/org/jivesoftware/smackx/xdata/provider/DataFormProviderTest.java +++ b/smack-extensions/src/test/java/org/jivesoftware/smackx/xdata/provider/DataFormProviderTest.java @@ -17,11 +17,13 @@ package org.jivesoftware.smackx.xdata.provider; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; import java.io.IOException; import java.util.List; import org.jivesoftware.smack.parsing.SmackParsingException; +import org.jivesoftware.smack.test.util.SmackTestUtil; import org.jivesoftware.smack.util.PacketParserUtils; import org.jivesoftware.smack.xml.XmlPullParser; import org.jivesoftware.smack.xml.XmlPullParserException; @@ -30,6 +32,8 @@ import org.jivesoftware.smackx.xdata.FormField; import org.jivesoftware.smackx.xdata.packet.DataForm; import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.EnumSource; public class DataFormProviderTest { @@ -144,4 +148,14 @@ public class DataFormProviderTest { assertEquals(FormField.Type.hidden, usernameFormField.getType()); assertEquals("", usernameFormField.getLabel()); } + + @ParameterizedTest + @EnumSource(SmackTestUtil.XmlPullParserKind.class) + public void testShouldThrowSmackParsingException(SmackTestUtil.XmlPullParserKind parserKind) { + String form = "" + + "" + + ""; + SmackParsingException.RequiredValueMissingException exception = assertThrows(SmackParsingException.RequiredValueMissingException.class, () -> SmackTestUtil.parse(form, DataFormProvider.class, parserKind)); + assertEquals("The data form field of unspecified type has no 'var' attribute, even though one is required as per XEP-0004 § 3.2", exception.getMessage()); + } }