From 4643d07ef410c91f0fa31333541d7419876b6b0c Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Sun, 18 Jul 2021 17:20:50 +0200 Subject: [PATCH 1/3] [xdata] Add missing ensureAtMostSingleValue() to parseBooleanFormField --- .../org/jivesoftware/smackx/xdata/provider/DataFormProvider.java | 1 + 1 file changed, 1 insertion(+) 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 6465efacb..d858ee666 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 @@ -300,6 +300,7 @@ public class DataFormProvider extends ExtensionElementProvider { private static FormField.Builder parseBooleanFormField(String fieldName, List values) throws SmackParsingException { BooleanFormField.Builder builder = FormField.booleanBuilder(fieldName); + ensureAtMostSingleValue(builder.getType(), values); if (values.size() == 1) { String value = values.get(0).getValue().toString(); builder.setValue(value); From 097d2453582f32729be1f00dd421e399c52dbc4d Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Sun, 18 Jul 2021 17:21:50 +0200 Subject: [PATCH 2/3] [xdata] Safe the raw character data of form field values --- .../smack/util/CollectionUtil.java | 9 +++- .../smackx/xdata/AbstractMultiFormField.java | 19 +++++++-- .../AbstractSingleStringValueFormField.java | 13 +++--- .../smackx/xdata/BooleanFormField.java | 9 ++-- .../jivesoftware/smackx/xdata/FormField.java | 4 +- .../smackx/xdata/JidMultiFormField.java | 28 ++++++++++++- .../smackx/xdata/JidSingleFormField.java | 14 ++++++- .../smackx/xdata/SingleValueFormField.java | 42 ++++++++++++++++--- .../xdata/provider/DataFormProvider.java | 14 ++++--- 9 files changed, 121 insertions(+), 31 deletions(-) diff --git a/smack-core/src/main/java/org/jivesoftware/smack/util/CollectionUtil.java b/smack-core/src/main/java/org/jivesoftware/smack/util/CollectionUtil.java index b35dfb4a0..24b73b8b0 100644 --- a/smack-core/src/main/java/org/jivesoftware/smack/util/CollectionUtil.java +++ b/smack-core/src/main/java/org/jivesoftware/smack/util/CollectionUtil.java @@ -1,6 +1,6 @@ /** * - * Copyright 2015-2020 Florian Schmaus + * Copyright 2015-2021 Florian Schmaus * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -82,4 +82,11 @@ public class CollectionUtil { } return new HashSet<>(collection); } + + public static List emptyOrSingletonListFrom(T element) { + if (element == null) { + return Collections.emptyList(); + } + return Collections.singletonList(element); + } } diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/xdata/AbstractMultiFormField.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/xdata/AbstractMultiFormField.java index 31c778a87..4b1c092b3 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/xdata/AbstractMultiFormField.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/xdata/AbstractMultiFormField.java @@ -1,6 +1,6 @@ /** * - * Copyright 2020 Florian Schmaus + * Copyright 2020-2021 Florian Schmaus * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -29,9 +29,12 @@ public class AbstractMultiFormField extends FormField { private final List values; + private final List rawValues; + protected AbstractMultiFormField(Builder builder) { super(builder); values = CollectionUtil.cloneAndSeal(builder.values); + rawValues = CollectionUtil.cloneAndSeal(builder.rawValues); } @Override @@ -39,11 +42,16 @@ public class AbstractMultiFormField extends FormField { return values; } + @Override + public final List getRawValues() { + return rawValues; + } - public abstract static class Builder> + public abstract static class Builder> extends FormField.Builder { private List values; + private List rawValues; protected Builder(AbstractMultiFormField formField) { super(formField); @@ -57,6 +65,7 @@ public class AbstractMultiFormField extends FormField { private void ensureValuesAreInitialized() { if (values == null) { values = new ArrayList<>(); + rawValues = new ArrayList<>(); } } @@ -70,7 +79,9 @@ public class AbstractMultiFormField extends FormField { public B addValueVerbatim(CharSequence value) { ensureValuesAreInitialized(); - values.add(value.toString()); + String valueString = value.toString(); + values.add(valueString); + rawValues.add(valueString); return getThis(); } @@ -83,7 +94,7 @@ public class AbstractMultiFormField extends FormField { ensureValuesAreInitialized(); for (CharSequence value : values) { - this.values.add(value.toString()); + addValueVerbatim(value); } return getThis(); diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/xdata/AbstractSingleStringValueFormField.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/xdata/AbstractSingleStringValueFormField.java index 27fca4cde..4530d3968 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/xdata/AbstractSingleStringValueFormField.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/xdata/AbstractSingleStringValueFormField.java @@ -1,6 +1,6 @@ /** * - * Copyright 2020 Florian Schmaus. + * Copyright 2020-2021 Florian Schmaus. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -42,7 +42,8 @@ public class AbstractSingleStringValueFormField extends SingleValueFormField { return Integer.valueOf(value); } - public abstract static class Builder> extends FormField.Builder { + public abstract static class Builder> + extends SingleValueFormField.Builder { private String value; @@ -74,18 +75,16 @@ public class AbstractSingleStringValueFormField extends SingleValueFormField { } public B setValue(CharSequence value) { - this.value = value.toString(); + this.rawValue = this.value = value.toString(); return getThis(); } public B setValue(Enum value) { - this.value = value.toString(); - return getThis(); + return setValue(value.toString()); } public B setValue(int value) { - this.value = Integer.toString(value); - return getThis(); + return setValue(Integer.toString(value)); } public B setValue(URL value) { diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/xdata/BooleanFormField.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/xdata/BooleanFormField.java index 2b036b162..e87278ae9 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/xdata/BooleanFormField.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/xdata/BooleanFormField.java @@ -1,6 +1,6 @@ /** * - * Copyright 2020 Florian Schmaus. + * Copyright 2020-2021 Florian Schmaus. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -43,7 +43,7 @@ public class BooleanFormField extends SingleValueFormField { return new Builder(this); } - public static final class Builder extends FormField.Builder { + public static final class Builder extends SingleValueFormField.Builder { private Boolean value; private Builder(BooleanFormField booleanFormField) { @@ -57,6 +57,7 @@ public class BooleanFormField extends SingleValueFormField { @Override protected void resetInternal() { + super.resetInternal(); value = null; } @@ -74,11 +75,13 @@ public class BooleanFormField extends SingleValueFormField { } public Builder setValue(CharSequence value) { - boolean valueBoolean = ParserUtils.parseXmlBoolean(value.toString()); + rawValue = value.toString(); + boolean valueBoolean = ParserUtils.parseXmlBoolean(rawValue); return setValue(valueBoolean); } public Builder setValue(boolean value) { + rawValue = Boolean.toString(value); this.value = value; return this; } diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/xdata/FormField.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/xdata/FormField.java index 4bc28a7ef..545083eee 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/xdata/FormField.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/xdata/FormField.java @@ -1,6 +1,6 @@ /** * - * Copyright 2003-2007 Jive Software, 2019-2020 Florian Schmaus. + * Copyright 2003-2007 Jive Software, 2019-2021 Florian Schmaus. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -271,6 +271,8 @@ public abstract class FormField implements FullyQualifiedElement { */ public abstract List getValues(); + public abstract List getRawValues(); + public boolean hasValueSet() { List values = getValues(); return !values.isEmpty(); diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/xdata/JidMultiFormField.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/xdata/JidMultiFormField.java index e1e93c0d3..bfb405b97 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/xdata/JidMultiFormField.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/xdata/JidMultiFormField.java @@ -1,6 +1,6 @@ /** * - * Copyright 2020 Florian Schmaus. + * Copyright 2020-2021 Florian Schmaus. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,14 +23,18 @@ import java.util.List; import org.jivesoftware.smack.util.CollectionUtil; import org.jxmpp.jid.Jid; +import org.jxmpp.jid.util.JidUtil; -public class JidMultiFormField extends FormField { +public final class JidMultiFormField extends FormField { private final List values; + private final List rawValues; + protected JidMultiFormField(Builder builder) { super(builder); values = CollectionUtil.cloneAndSeal(builder.values); + rawValues = CollectionUtil.cloneAndSeal(builder.rawValues); } @Override @@ -38,6 +42,11 @@ public class JidMultiFormField extends FormField { return values; } + @Override + public List getRawValues() { + return rawValues; + } + public Builder asBuilder() { return new Builder(this); } @@ -45,6 +54,8 @@ public class JidMultiFormField extends FormField { public static final class Builder extends FormField.Builder { private List values; + private List rawValues; + private Builder(JidMultiFormField jidMultiFormField) { super(jidMultiFormField); values = CollectionUtil.newListWith(jidMultiFormField.getValues()); @@ -57,18 +68,30 @@ public class JidMultiFormField extends FormField { private void ensureValuesAreInitialized() { if (values == null) { values = new ArrayList<>(); + rawValues = new ArrayList<>(); } } @Override protected void resetInternal() { values = null; + rawValues = null; } public Builder addValue(Jid jid) { + return addValue(jid, null); + } + + public Builder addValue(Jid jid, String rawValue) { + if (rawValue == null) { + rawValue = jid.toString(); + } + ensureValuesAreInitialized(); values.add(jid); + rawValues.add(rawValue); + return this; } @@ -76,6 +99,7 @@ public class JidMultiFormField extends FormField { ensureValuesAreInitialized(); values.addAll(jids); + rawValues.addAll(JidUtil.toStringList(jids)); return this; } diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/xdata/JidSingleFormField.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/xdata/JidSingleFormField.java index d1b0237de..7948971a3 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/xdata/JidSingleFormField.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/xdata/JidSingleFormField.java @@ -1,6 +1,6 @@ /** * - * Copyright 2020 Florian Schmaus. + * Copyright 2020-2021 Florian Schmaus. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -36,7 +36,7 @@ public class JidSingleFormField extends SingleValueFormField { return new Builder(this); } - public static final class Builder extends FormField.Builder { + public static final class Builder extends SingleValueFormField.Builder { private Jid value; private Builder(JidSingleFormField jidSingleFormField) { @@ -50,11 +50,21 @@ public class JidSingleFormField extends SingleValueFormField { @Override protected void resetInternal() { + super.resetInternal(); value = null; } public Builder setValue(Jid value) { + return setValue(value, null); + } + + public Builder setValue(Jid value, String rawValue) { this.value = value; + if (rawValue != null) { + this.rawValue = rawValue; + } else { + this.rawValue = value.toString(); + } return this; } diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/xdata/SingleValueFormField.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/xdata/SingleValueFormField.java index 2c039f1ab..796abd654 100644 --- a/smack-extensions/src/main/java/org/jivesoftware/smackx/xdata/SingleValueFormField.java +++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/xdata/SingleValueFormField.java @@ -1,6 +1,6 @@ /** * - * Copyright 2020 Florian Schmaus. + * Copyright 2020-2021 Florian Schmaus. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,23 +19,35 @@ package org.jivesoftware.smackx.xdata; import java.util.Collections; import java.util.List; +import org.jivesoftware.smack.util.CollectionUtil; + public abstract class SingleValueFormField extends FormField { + private final String rawValue; + protected SingleValueFormField(Builder builder) { super(builder); + rawValue = builder.rawValue; } @Override public final List getValues() { CharSequence value = getValue(); - if (value == null) { - return Collections.emptyList(); - } - return Collections.singletonList(value); + return CollectionUtil.emptyOrSingletonListFrom(value); } public abstract CharSequence getValue(); + public final String getRawValue() { + return rawValue; + } + + @Override + public final List getRawValues() { + String rawValue = getRawValue(); + return CollectionUtil.emptyOrSingletonListFrom(rawValue); + } + @Override protected void populateExtraXmlChildElements() { CharSequence value = getValue(); @@ -45,4 +57,24 @@ public abstract class SingleValueFormField extends FormField { extraXmlChildElements = Collections.singletonList(new Value(value)); } + + public abstract static class Builder> + extends FormField.Builder { + + protected Builder(String fieldName, Type type) { + super(fieldName, type); + } + + protected Builder(FormField formField) { + super(formField); + } + + protected String rawValue; + + @Override + protected void resetInternal() { + rawValue = null; + }; + + } } 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 d858ee666..f6362660c 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 @@ -237,8 +237,9 @@ public class DataFormProvider extends ExtensionElementProvider { case jid_multi: JidMultiFormField.Builder jidMultiBuilder = FormField.jidMultiBuilder(fieldName); for (FormField.Value value : values) { - Jid jid = JidCreate.from(value.getValue()); - jidMultiBuilder.addValue(jid); + String rawValue = value.getValue().toString(); + Jid jid = JidCreate.from(rawValue); + jidMultiBuilder.addValue(jid, rawValue); } builder = jidMultiBuilder; break; @@ -246,9 +247,9 @@ public class DataFormProvider extends ExtensionElementProvider { ensureAtMostSingleValue(type, values); JidSingleFormField.Builder jidSingleBuilder = FormField.jidSingleBuilder(fieldName); if (!values.isEmpty()) { - CharSequence jidCharSequence = values.get(0).getValue(); - Jid jid = JidCreate.from(jidCharSequence); - jidSingleBuilder.setValue(jid); + String rawValue = values.get(0).getValue().toString(); + Jid jid = JidCreate.from(rawValue); + jidSingleBuilder.setValue(jid, rawValue); } builder = jidSingleBuilder; break; @@ -322,7 +323,8 @@ public class DataFormProvider extends ExtensionElementProvider { private static AbstractMultiFormField.Builder parseMultiKindFormField(AbstractMultiFormField.Builder builder, List values) { for (FormField.Value value : values) { - builder.addValue(value.getValue()); + String rawValue = value.getValue().toString(); + builder.addValue(rawValue); } return builder; } From b47225c2c1048290d0d5712c357e7b46732eb025 Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Sun, 18 Jul 2021 17:22:06 +0200 Subject: [PATCH 3/3] [caps] Use the raw character data of form fields when caclulating the hash --- .../java/org/jivesoftware/smackx/caps/EntityCapsManager.java | 4 ++-- 1 file changed, 2 insertions(+), 2 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 523213513..36429ca5a 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 @@ -1,6 +1,6 @@ /** * - * Copyright © 2009 Jonas Ådahl, 2011-2020 Florian Schmaus + * Copyright © 2009 Jonas Ådahl, 2011-2021 Florian Schmaus * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -700,7 +700,7 @@ public final class EntityCapsManager extends Manager { for (FormField f : fs) { sb.append(f.getFieldName()); sb.append('<'); - formFieldValuesToCaps(f.getValues(), sb); + formFieldValuesToCaps(f.getRawValues(), sb); } }