From 5ead24e416634a47b31b9d88bebbc38301bd4b31 Mon Sep 17 00:00:00 2001
From: Florian Schmaus
Date: Sun, 27 Jul 2014 23:45:19 +0200
Subject: [PATCH 1/9] Smack 4.0.3-SNAPSHOT
---
build.gradle | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/build.gradle b/build.gradle
index 8cf025fe6..04e1875c7 100644
--- a/build.gradle
+++ b/build.gradle
@@ -5,8 +5,8 @@ allprojects {
apply plugin: 'eclipse'
ext {
- shortVersion = '4.0.2'
- isSnapshot = false
+ shortVersion = '4.0.3'
+ isSnapshot = true
gitCommit = getGitCommit()
javadocAllDir = new File(buildDir, 'javadoc')
documentationDir = new File(projectDir, 'documentation')
From 0b6069d75f3e513f13ccf837b16da8cb38644e69 Mon Sep 17 00:00:00 2001
From: Florian Schmaus
Date: Wed, 30 Jul 2014 21:58:10 +0200
Subject: [PATCH 2/9] Fix FormField.Option.toXML() to use correct element
Fixes SMACK-589
---
.../main/java/org/jivesoftware/smackx/xdata/FormField.java | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
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 1e7ba1bd8..5b8172f5c 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
@@ -313,7 +313,7 @@ public class FormField {
*/
public static class Option {
- public static final String ELEMNT = "option";
+ public static final String ELEMENT = "option";
private final String value;
private String label;
@@ -352,7 +352,7 @@ public class FormField {
public XmlStringBuilder toXML() {
XmlStringBuilder xml = new XmlStringBuilder();
- xml.halfOpenElement(ELEMNT);
+ xml.halfOpenElement(ELEMENT);
// Add attribute
xml.optAttribute("label", getLabel());
xml.rightAngelBracket();
From 1935039432113a7437c19066d8129164bb73c7f2 Mon Sep 17 00:00:00 2001
From: Florian Schmaus
Date: Thu, 31 Jul 2014 19:45:00 +0200
Subject: [PATCH 3/9] Improve documentation (targetCompatibility, XPP3)
---
build.gradle | 3 ++-
documentation/gettingstarted.html | 6 ++----
resources/releasedocs/README.html | 19 ++++++++++++++-----
3 files changed, 18 insertions(+), 10 deletions(-)
diff --git a/build.gradle b/build.gradle
index 04e1875c7..79b7392da 100644
--- a/build.gradle
+++ b/build.gradle
@@ -23,6 +23,7 @@ allprojects {
}
group = 'org.igniterealtime.smack'
sourceCompatibility = 1.7
+ targetCompatibility = sourceCompatibility
version = shortVersion
if (isSnapshot) {
version += '-SNAPSHOT'
@@ -81,7 +82,7 @@ import org.apache.tools.ant.filters.ReplaceTokens
task prepareReleasedocs(type: Copy) {
from 'resources/releasedocs'
into releasedocsDir
- filter(ReplaceTokens, tokens: [version: version, releasedate: buildDate])
+ filter(ReplaceTokens, tokens: [version: version, releasedate: buildDate, targetCompatibility: targetCompatibility.toString()])
}
task distributionZip(type: Zip, dependsOn: [javadocAll, prepareReleasedocs]) {
diff --git a/documentation/gettingstarted.html b/documentation/gettingstarted.html
index ee5c35273..de817b244 100644
--- a/documentation/gettingstarted.html
+++ b/documentation/gettingstarted.html
@@ -23,10 +23,8 @@ important classes and concepts.
JAR Files and Requirements
-Smack is meant to be easily embedded into any existing JDK 1.5 or later Java application.
-It has no external dependencies (except for the Jingle voice chat functionality) and is optimized
-to be as small as possible. The library ships as several JAR files to provide more flexibility
-over which features applications require:
+Smack is meant to be easily embedded into any existing Java application.
+The library ships as several JAR files to provide more flexibility over which features applications require:
- smack-core.jar -- provides core XMPP functionality. All XMPP features that are
diff --git a/resources/releasedocs/README.html b/resources/releasedocs/README.html
index d1a220e4c..962c43fbc 100644
--- a/resources/releasedocs/README.html
+++ b/resources/releasedocs/README.html
@@ -154,18 +154,27 @@ hr {
-Thank you for downloading Smack!
-
+Thank you for downloading Smack! This version of Smack is compatible
+with JVMs @targetCompatibility@ or higher. If you dont' use a
+dependency resolution system, like gradle or maven, then you will need
+to download at least
+the Xml
+Pull Parser 3rd Edition (XPP3) library or any other library that
+implements the XmlPullParser interface
+(like kXML).
+
+
Start off by viewing the documentation
that can be found in the "documentation" directory included with this distribution.
-
+
Further information can be found on the
Smack website. If you need help using or would like to make contributions or
fixes to the code, please visit the
online forum.
-
-About the Distribution
+
+
+About the Distribution
The smack-core.jar file in the main distribution folder. The optional
smack-extensions.jar contains the Smack extensions
From 66da4dfa91cc4cadfa0170a3c9e04f25c6bcf282 Mon Sep 17 00:00:00 2001
From: Florian Schmaus
Date: Fri, 1 Aug 2014 23:15:46 +0200
Subject: [PATCH 4/9] Fix Typo: s/isSubscibe/isSubscribe/ in ConfigureForm
Fixes SMACK-588
---
.../jivesoftware/smackx/pubsub/ConfigureForm.java | 13 ++++++++++++-
1 file changed, 12 insertions(+), 1 deletion(-)
diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/ConfigureForm.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/ConfigureForm.java
index f6f6cb76a..297557daf 100644
--- a/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/ConfigureForm.java
+++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/pubsub/ConfigureForm.java
@@ -577,12 +577,23 @@ public class ConfigureForm extends Form
* Determines if subscriptions are allowed.
*
* @return true if subscriptions are allowed, false otherwise
+ * @deprecated use {@link #isSubscribe()} instead
*/
+ @Deprecated
public boolean isSubscibe()
{
- return parseBoolean(getFieldValue(ConfigureNodeFields.subscribe));
+ return isSubscribe();
}
+ /**
+ * Determines if subscriptions are allowed.
+ *
+ * @return true if subscriptions are allowed, false otherwise
+ */
+ public boolean isSubscribe() {
+ return parseBoolean(getFieldValue(ConfigureNodeFields.subscribe));
+ }
+
/**
* Sets whether subscriptions are allowed.
*
From a574e1d56d5530c6b836f14b5f70e12cce119fbb Mon Sep 17 00:00:00 2001
From: Florian Schmaus
Date: Fri, 1 Aug 2014 23:20:35 +0200
Subject: [PATCH 5/9] Verify ConnectionConfiguration parameters
also fix javadoc error for StringUtils.isNullOrEmpty()
Fixes SMACK-539
---
.../smack/ConnectionConfiguration.java | 7 +++++++
.../org/jivesoftware/smack/util/StringUtils.java | 16 +++++++++++++---
2 files changed, 20 insertions(+), 3 deletions(-)
diff --git a/smack-core/src/main/java/org/jivesoftware/smack/ConnectionConfiguration.java b/smack-core/src/main/java/org/jivesoftware/smack/ConnectionConfiguration.java
index f8e69533c..544f3ac48 100644
--- a/smack-core/src/main/java/org/jivesoftware/smack/ConnectionConfiguration.java
+++ b/smack-core/src/main/java/org/jivesoftware/smack/ConnectionConfiguration.java
@@ -20,6 +20,7 @@ package org.jivesoftware.smack;
import org.jivesoftware.smack.packet.Session;
import org.jivesoftware.smack.proxy.ProxyInfo;
import org.jivesoftware.smack.util.DNSUtil;
+import org.jivesoftware.smack.util.StringUtils;
import org.jivesoftware.smack.util.dns.HostAddress;
import javax.net.SocketFactory;
@@ -180,6 +181,9 @@ public class ConnectionConfiguration implements Cloneable {
}
protected void init(String serviceName, ProxyInfo proxy) {
+ if (StringUtils.isEmpty(serviceName)) {
+ throw new IllegalArgumentException("serviceName must not be the empty String");
+ }
this.serviceName = serviceName;
this.proxy = proxy;
@@ -597,6 +601,9 @@ public class ConnectionConfiguration implements Cloneable {
}
private void initHostAddresses(String host, int port) {
+ if (StringUtils.isEmpty(host)) {
+ throw new IllegalArgumentException("host must not be the empty String");
+ }
hostAddresses = new ArrayList(1);
HostAddress hostAddress;
hostAddress = new HostAddress(host, port);
diff --git a/smack-core/src/main/java/org/jivesoftware/smack/util/StringUtils.java b/smack-core/src/main/java/org/jivesoftware/smack/util/StringUtils.java
index 132e1d340..796b7ff1f 100644
--- a/smack-core/src/main/java/org/jivesoftware/smack/util/StringUtils.java
+++ b/smack-core/src/main/java/org/jivesoftware/smack/util/StringUtils.java
@@ -528,12 +528,22 @@ public class StringUtils {
}
/**
- * Returns true if the given CharSequence is not null or empty.
+ * Returns true if the given CharSequence is null or empty.
*
* @param cs
- * @return true if the given CharSequence is not null or empty
+ * @return true if the given CharSequence is null or empty
*/
public static boolean isNullOrEmpty(CharSequence cs) {
- return cs == null || cs.length() == 0;
+ return cs == null || isEmpty(cs);
+ }
+
+ /**
+ * Returns true if the given CharSequence is empty
+ *
+ * @param cs
+ * @return true if the given CharSequence is empty
+ */
+ public static boolean isEmpty(CharSequence cs) {
+ return cs.length() == 0;
}
}
From d65d239550812b0dd5bc2897b3fe9576b59bb578 Mon Sep 17 00:00:00 2001
From: Florian Schmaus
Date: Mon, 4 Aug 2014 12:19:58 +0200
Subject: [PATCH 6/9] Make getMessages() set up collector *before* sending the
request
Similar flaw was also fixed in 2c7f1efe80b988.
Also ensure that OfflineMessagesManager doesn't leak collector by using
a try/finally block.
Fixes SMACK-592
---
.../smackx/offline/OfflineMessageManager.java | 43 +++++++++++--------
1 file changed, 26 insertions(+), 17 deletions(-)
diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/offline/OfflineMessageManager.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/offline/OfflineMessageManager.java
index 8c7bfb75d..3d7d13b88 100644
--- a/smack-extensions/src/main/java/org/jivesoftware/smackx/offline/OfflineMessageManager.java
+++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/offline/OfflineMessageManager.java
@@ -156,20 +156,24 @@ public class OfflineMessageManager {
}
});
PacketCollector messageCollector = connection.createPacketCollector(messageFilter);
- connection.createPacketCollectorAndSend(request).nextResultOrThrow();
- // Collect the received offline messages
- Message message = (Message) messageCollector.nextResult();
- while (message != null) {
- messages.add(message);
- message = (Message) messageCollector.nextResult();
+ try {
+ connection.createPacketCollectorAndSend(request).nextResultOrThrow();
+ // Collect the received offline messages
+ Message message = (Message) messageCollector.nextResult();
+ while (message != null) {
+ messages.add(message);
+ message = (Message) messageCollector.nextResult();
+ }
+ }
+ finally {
+ // Stop queuing offline messages
+ messageCollector.cancel();
}
- // Stop queuing offline messages
- messageCollector.cancel();
return messages;
}
/**
- * Returns an Iterator with all the offline Messages of the user. The returned offline
+ * Returns a List of Messages with all the offline Messages of the user. The returned offline
* messages will not be deleted from the server. Use {@link #deleteMessages(java.util.List)}
* to delete the messages.
*
@@ -183,17 +187,22 @@ public class OfflineMessageManager {
List messages = new ArrayList();
OfflineMessageRequest request = new OfflineMessageRequest();
request.setFetch(true);
- connection.createPacketCollectorAndSend(request).nextResultOrThrow();
PacketCollector messageCollector = connection.createPacketCollector(packetFilter);
- // Collect the received offline messages
- Message message = (Message) messageCollector.nextResult();
- while (message != null) {
- messages.add(message);
- message = (Message) messageCollector.nextResult();
+ try {
+ connection.createPacketCollectorAndSend(request).nextResultOrThrow();
+
+ // Collect the received offline messages
+ Message message = (Message) messageCollector.nextResult();
+ while (message != null) {
+ messages.add(message);
+ message = (Message) messageCollector.nextResult();
+ }
+ }
+ finally {
+ // Stop queuing offline messages
+ messageCollector.cancel();
}
- // Stop queuing offline messages
- messageCollector.cancel();
return messages;
}
From 5c2f051c1ce6d4a4e1ac3529ea984f20018347c1 Mon Sep 17 00:00:00 2001
From: Florian Schmaus
Date: Tue, 5 Aug 2014 09:32:13 +0200
Subject: [PATCH 7/9] Make Socks5Proxy try other ports if 7777 is already in
use
by setting the default value to '-7777' (negative values mean that the
next port number will be tried if the current one is in use).
---
.../smackx/bytestreams/socks5/Socks5Proxy.java | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/bytestreams/socks5/Socks5Proxy.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/bytestreams/socks5/Socks5Proxy.java
index 08a0abfff..1728347aa 100644
--- a/smack-extensions/src/main/java/org/jivesoftware/smackx/bytestreams/socks5/Socks5Proxy.java
+++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/bytestreams/socks5/Socks5Proxy.java
@@ -73,7 +73,12 @@ public class Socks5Proxy {
private static Socks5Proxy socks5Server;
private static boolean localSocks5ProxyEnabled = true;
- private static int localSocks5ProxyPort = 7777;
+
+ /**
+ * The port of the local Socks5 Proxy. If this value is negative, the next ports will be tried
+ * until a unused is found.
+ */
+ private static int localSocks5ProxyPort = -7777;
/* reusable implementation of a SOCKS5 proxy server process */
private Socks5ServerProcess serverProcess;
From 4e588f7908d2fc5a8952828a53e58fed97c395e2 Mon Sep 17 00:00:00 2001
From: Florian Schmaus
Date: Tue, 5 Aug 2014 09:33:20 +0200
Subject: [PATCH 8/9] Throw IAE if invalid port number is given for Socks5Proxy
---
.../jivesoftware/smackx/bytestreams/socks5/Socks5Proxy.java | 3 +++
1 file changed, 3 insertions(+)
diff --git a/smack-extensions/src/main/java/org/jivesoftware/smackx/bytestreams/socks5/Socks5Proxy.java b/smack-extensions/src/main/java/org/jivesoftware/smackx/bytestreams/socks5/Socks5Proxy.java
index 1728347aa..855cba222 100644
--- a/smack-extensions/src/main/java/org/jivesoftware/smackx/bytestreams/socks5/Socks5Proxy.java
+++ b/smack-extensions/src/main/java/org/jivesoftware/smackx/bytestreams/socks5/Socks5Proxy.java
@@ -147,6 +147,9 @@ public class Socks5Proxy {
* @param localSocks5ProxyPort the port of the local Socks5 proxy to set
*/
public static void setLocalSocks5ProxyPort(int localSocks5ProxyPort) {
+ if (Math.abs(localSocks5ProxyPort) > 65535) {
+ throw new IllegalArgumentException("localSocks5ProxyPort must be within (-65535,65535)");
+ }
Socks5Proxy.localSocks5ProxyPort = localSocks5ProxyPort;
}
From c3f6c51d0ea3735877e2854e0b5b352a27230c91 Mon Sep 17 00:00:00 2001
From: Florian Schmaus
Date: Thu, 7 Aug 2014 14:42:30 +0200
Subject: [PATCH 9/9] Add a setting for the used flush mode when compressing
data
Fixes SMACK-593
---
.../jzlib/JzlibInputOutputStream.java | 4 +++-
.../Java7ZlibInputOutputStream.java | 23 ++++++++++---------
.../compression/XMPPInputOutputStream.java | 20 ++++++++++++++++
3 files changed, 35 insertions(+), 12 deletions(-)
diff --git a/smack-compression-jzlib/src/main/java/org/jivesoftware/smack/compression/jzlib/JzlibInputOutputStream.java b/smack-compression-jzlib/src/main/java/org/jivesoftware/smack/compression/jzlib/JzlibInputOutputStream.java
index 356eef8a0..68e4d16d5 100644
--- a/smack-compression-jzlib/src/main/java/org/jivesoftware/smack/compression/jzlib/JzlibInputOutputStream.java
+++ b/smack-compression-jzlib/src/main/java/org/jivesoftware/smack/compression/jzlib/JzlibInputOutputStream.java
@@ -58,7 +58,9 @@ public class JzlibInputOutputStream extends XMPPInputOutputStream {
@Override
public OutputStream getOutputStream(OutputStream outputStream) throws IOException {
final DeflaterOutputStream os = new DeflaterOutputStream(outputStream);
- os.setSyncFlush(true);
+ if (flushMethod == FlushMethod.SYNC_FLUSH) {
+ os.setSyncFlush(true);
+ }
return os;
}
diff --git a/smack-core/src/main/java/org/jivesoftware/smack/compression/Java7ZlibInputOutputStream.java b/smack-core/src/main/java/org/jivesoftware/smack/compression/Java7ZlibInputOutputStream.java
index 906a8e1f0..0f7933faa 100644
--- a/smack-core/src/main/java/org/jivesoftware/smack/compression/Java7ZlibInputOutputStream.java
+++ b/smack-core/src/main/java/org/jivesoftware/smack/compression/Java7ZlibInputOutputStream.java
@@ -48,6 +48,9 @@ public class Java7ZlibInputOutputStream extends XMPPInputOutputStream {
private final static boolean supported;
private final static int compressionLevel = Deflater.DEFAULT_COMPRESSION;
+ private static final int SYNC_FLUSH_INT = 2;
+ private static final int FULL_FLUSH_INT = 3;
+
static {
Method m = null;
try {
@@ -100,25 +103,23 @@ public class Java7ZlibInputOutputStream extends XMPPInputOutputStream {
@Override
public OutputStream getOutputStream(OutputStream outputStream) {
+ final int flushMethodInt;
+ if (flushMethod == FlushMethod.SYNC_FLUSH) {
+ flushMethodInt = SYNC_FLUSH_INT;
+ } else {
+ flushMethodInt = FULL_FLUSH_INT;
+ }
return new DeflaterOutputStream(outputStream, new Deflater(compressionLevel)) {
public void flush() throws IOException {
if (!supported) {
super.flush();
return;
}
- int count = 0;
- if (!def.needsInput()) {
- do {
- count = def.deflate(buf, 0, buf.length);
- out.write(buf, 0, count);
- } while (count > 0);
- out.flush();
- }
try {
- do {
- count = (Integer) method.invoke(def, buf, 0, buf.length, 2);
+ int count;
+ while ((count = (Integer) method.invoke(def, buf, 0, buf.length, flushMethodInt)) != 0) {
out.write(buf, 0, count);
- } while (count > 0);
+ }
} catch (IllegalArgumentException e) {
throw new IOException("Can't flush");
} catch (IllegalAccessException e) {
diff --git a/smack-core/src/main/java/org/jivesoftware/smack/compression/XMPPInputOutputStream.java b/smack-core/src/main/java/org/jivesoftware/smack/compression/XMPPInputOutputStream.java
index 41308243f..6fd289325 100644
--- a/smack-core/src/main/java/org/jivesoftware/smack/compression/XMPPInputOutputStream.java
+++ b/smack-core/src/main/java/org/jivesoftware/smack/compression/XMPPInputOutputStream.java
@@ -20,6 +20,21 @@ import java.io.InputStream;
import java.io.OutputStream;
public abstract class XMPPInputOutputStream {
+
+ protected static FlushMethod flushMethod;
+
+ /**
+ * Set the used flushed method when compressing data. The default is full flush which may not
+ * achieve the best compression ratio, but provides better security against certain attacks.
+ * Only use sync flush if you fully understand the implications.
+ *
+ * @see Attacks against XMPP when using compression
+ * @param flushMethod
+ */
+ public static void setFlushMethod(FlushMethod flushMethod) {
+ XMPPInputOutputStream.flushMethod = flushMethod;
+ }
+
protected String compressionMethod;
public String getCompressionMethod() {
@@ -31,4 +46,9 @@ public abstract class XMPPInputOutputStream {
public abstract InputStream getInputStream(InputStream inputStream) throws Exception;
public abstract OutputStream getOutputStream(OutputStream outputStream) throws Exception;
+
+ public enum FlushMethod {
+ FULL_FLUSH,
+ SYNC_FLUSH,
+ }
}