From b83bb8d018153259dc3d856a9b2dee5b984b97d7 Mon Sep 17 00:00:00 2001 From: Guus der Kinderen Date: Tue, 25 Jun 2024 17:14:24 +0200 Subject: [PATCH] SMACK-944: Ensure dataforms are ordered prior to ver calculation --- .../smackx/caps/EntityCapsManager.java | 28 +++++++++++++++---- 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/caps/EntityCapsManager.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/caps/EntityCapsManager.java index 8bd738fa27..7cd40188e4 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/caps/EntityCapsManager.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/caps/EntityCapsManager.java @@ -23,6 +23,7 @@ import java.util.Comparator; import java.util.HashMap; import java.util.HashSet; +import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.Locale; @@ -69,6 +70,7 @@ import org.jivesoftware.smackx.disco.packet.DiscoverInfoBuilder; import org.jivesoftware.smackx.disco.packet.DiscoverInfoView; import org.jivesoftware.smackx.xdata.FormField; +import org.jivesoftware.smackx.xdata.TextSingleFormField; import org.jivesoftware.smackx.xdata.packet.DataForm; import org.jxmpp.jid.DomainBareJid; @@ -701,16 +703,30 @@ static CapsVersionAndHash generateVerificationString(DiscoverInfoView discoverIn } List extendedInfos = discoverInfo.getExtensions(DataForm.class); - for (DataForm extendedInfo : extendedInfos) { - if (!extendedInfo.hasHiddenFormTypeField()) { + final Iterator iter = extendedInfos.iterator(); + while (iter.hasNext()) { + if (!iter.next().hasHiddenFormTypeField()) { // Only use the data form for calculation is it has a hidden FORM_TYPE field. // See XEP-0115 5.4 step 3.f - continue; + iter.remove(); + } + } + + // 6. If the service discovery information response includes + // XEP-0128 data forms, sort the forms by the FORM_TYPE (i.e., + // by the XML character data of the element). + Collections.sort(extendedInfos, new Comparator() { + @Override + public int compare(DataForm d1, DataForm d2) { + final TextSingleFormField hft1 = d1.getHiddenFormTypeField(); + assert hft1 != null; // ensured by the previous step. + final TextSingleFormField hft2 = d2.getHiddenFormTypeField(); + assert hft2 != null; // ensured by the previous step. + return hft1.getFirstValue().compareTo(hft2.getFirstValue()); } + }); - // 6. If the service discovery information response includes - // XEP-0128 data forms, sort the forms by the FORM_TYPE (i.e., - // by the XML character data of the element). + for (DataForm extendedInfo : extendedInfos) { SortedSet fs = new TreeSet<>(new Comparator() { @Override public int compare(FormField f1, FormField f2) {