powered by Jive Software

"Bad" message extension causes disconnect and reconnect fails


#1

I’m using Smack 4.3.3 on Android.

The issue: if I try to send a message with extension that has missing data (null for id) then Smack closes connection. Following re-connections (by ReconnectionManager) try to re-send the same stanza and fail. So basically one bad message breaks the application and restart is needed.

I’m not sure - perhaps this somehow is intended behavior.

Code example:

XMPPTCPConnectionConfiguration.Builder config = XMPPTCPConnectionConfiguration.builder()
        .setUsernameAndPassword("test1", "pwd")
        .setXmppDomain("jabber.org")
        .setHost("jabber.org");

config.enableDefaultDebugger();
config.setConnectTimeout(5 * 1000);

AbstractXMPPConnection con = new XMPPTCPConnection(config.build());
ReconnectionManager reconnectionManager = ReconnectionManager.getInstanceFor(con);
reconnectionManager.setReconnectionPolicy(ReconnectionManager.ReconnectionPolicy.FIXED_DELAY);
reconnectionManager.setFixedDelay(5);
reconnectionManager.enableAutomaticReconnection();

con.connect();
con.login();

Message messageBad = new Message();
messageBad.setTo(JidCreate.entityBareFrom("test2@jabber.org"));
messageBad.addExtension(new ChatMarkersElements.ReceivedExtension(null));
con.sendStanza(messageBad);

Note how ReceivedExtension has null in parameter. This is what causes first disconnect.

The logcat:

D/SMACK: SENT (0): <stream:stream xmlns='jabber:client' to='jabber.org' xmlns:stream='http://etherx.jabber.org/streams' version='1.0' from='test@jabber.org' xml:lang='en'>
...
D/SMACK: User logged (0): test1@jabber.org:5222/9114273216672297917426133
D/SMACK: SENT (0): <iq id='e4VGH-8' type='get'><query xmlns='jabber:iq:roster'></query></iq>
...
D/SMACK: RECV (0): <r xmlns='urn:xmpp:sm:3'/>
D/SMACK: SENT (0): <a xmlns='urn:xmpp:sm:3' h='8'/>
D/SMACK: XMPPConnection authenticated (XMPPTCPConnection[test1@jabber.org/911427321667229798517426133] (0))
W/AbstractXMPPConnection: Connection XMPPTCPConnection[test1@jabber.org/911427321667229798517426133] (0) closed with error
    java.lang.NullPointerException: Attempt to invoke interface method 'java.lang.String java.lang.CharSequence.toString()' on a null object reference
        at org.jivesoftware.smack.util.XmlStringBuilder.write(XmlStringBuilder.java:570)
        at org.jivesoftware.smack.util.XmlStringBuilder.write(XmlStringBuilder.java:560)
        at org.jivesoftware.smack.tcp.XMPPTCPConnection$PacketWriter.writePackets(XMPPTCPConnection.java:1526)
        at org.jivesoftware.smack.tcp.XMPPTCPConnection$PacketWriter.access$4000(XMPPTCPConnection.java:1335)
        at org.jivesoftware.smack.tcp.XMPPTCPConnection$PacketWriter$1.run(XMPPTCPConnection.java:1384)
        at java.lang.Thread.run(Thread.java:818)
D/SMACK: XMPPConnection closed due to an exception (XMPPTCPConnection[test1@jabber.org/911427321667229798517426133] (0))
    java.lang.NullPointerException: Attempt to invoke interface method 'java.lang.String java.lang.CharSequence.toString()' on a null object reference
        at org.jivesoftware.smack.util.XmlStringBuilder.write(XmlStringBuilder.java:570)
        at org.jivesoftware.smack.util.XmlStringBuilder.write(XmlStringBuilder.java:560)
        at org.jivesoftware.smack.tcp.XMPPTCPConnection$PacketWriter.writePackets(XMPPTCPConnection.java:1526)
        at org.jivesoftware.smack.tcp.XMPPTCPConnection$PacketWriter.access$4000(XMPPTCPConnection.java:1335)
        at org.jivesoftware.smack.tcp.XMPPTCPConnection$PacketWriter$1.run(XMPPTCPConnection.java:1384)
        at java.lang.Thread.run(Thread.java:818)
D/SMACK: XMPPConnection (XMPPTCPConnection[test1@jabber.org/911427321667229798517426133] (0)) will reconnect in 4
D/SMACK: XMPPConnection (XMPPTCPConnection[test1@jabber.org/911427321667229798517426133] (0)) will reconnect in 3
D/SMACK: XMPPConnection (XMPPTCPConnection[test1@jabber.org/911427321667229798517426133] (0)) will reconnect in 2
D/SMACK: XMPPConnection (XMPPTCPConnection[test1@jabber.org/911427321667229798517426133] (0)) will reconnect in 1
D/SMACK: XMPPConnection (XMPPTCPConnection[test1@jabber.org/911427321667229798517426133] (0)) will reconnect in 0
D/SMACK: XMPPConnection (XMPPTCPConnection[test1@jabber.org/911427321667229798517426133] (0)) will reconnect in 0
D/SMACK: SENT (0): <stream:stream xmlns='jabber:client' to='jabber.org' xmlns:stream='http://etherx.jabber.org/streams' version='1.0' from='test1@jabber.org' xml:lang='en'>
...
D/SMACK: XMPPConnection connected (XMPPTCPConnection[test1@jabber.org/911427321667229798517426133] (0))
D/SMACK: SENT (0): <auth xmlns='urn:ietf:params:xml:ns:xmpp-sasl' mechanism='SCRAM-SHA-1'>biwsbj1qYXR0N0MSxyPSY5Pl5dKEg/d3JDS2pEW2ZrtENkp5YFg8QUQyOiZ4</auth>
...
D/SMACK: RECV (0): <resumed previd='g2gCbQAAABs5MTE0MjczMjE2NjcyMjk3OTg1MTc0MjYxMzNoA2IAAAYVYgAOYLhiAEI2iA==' h='9' xmlns='urn:xmpp:sm:3'/>
D/SMACK: User logged (0): test1@jabber.org:5222/911427321667229798517426133
D/SMACK: XMPPConnection authenticated (XMPPTCPConnection[test1@jabber.org/911427321667229798517426133] (0)) and resumed
D/SMACK: RECV (0): <r xmlns='urn:xmpp:sm:3'/>
W/AbstractXMPPConnection: Connection XMPPTCPConnection[test1@jabber.org/911427321667229798517426133] (0) closed with error
    java.lang.NullPointerException: Attempt to invoke interface method 'java.lang.String java.lang.CharSequence.toString()' on a null object reference
        at org.jivesoftware.smack.util.XmlStringBuilder.write(XmlStringBuilder.java:570)
        at org.jivesoftware.smack.util.XmlStringBuilder.write(XmlStringBuilder.java:560)
        at org.jivesoftware.smack.tcp.XMPPTCPConnection$PacketWriter.writePackets(XMPPTCPConnection.java:1526)
        at org.jivesoftware.smack.tcp.XMPPTCPConnection$PacketWriter.access$4000(XMPPTCPConnection.java:1335)
        at org.jivesoftware.smack.tcp.XMPPTCPConnection$PacketWriter$1.run(XMPPTCPConnection.java:1384)
        at java.lang.Thread.run(Thread.java:818)
D/SMACK: XMPPConnection closed due to an exception (XMPPTCPConnection[test1@jabber.org/911427321667229798517426133] (0))
    java.lang.NullPointerException: Attempt to invoke interface method 'java.lang.String java.lang.CharSequence.toString()' on a null object reference
        at org.jivesoftware.smack.util.XmlStringBuilder.write(XmlStringBuilder.java:570)
        at org.jivesoftware.smack.util.XmlStringBuilder.write(XmlStringBuilder.java:560)
        at org.jivesoftware.smack.tcp.XMPPTCPConnection$PacketWriter.writePackets(XMPPTCPConnection.java:1526)
        at org.jivesoftware.smack.tcp.XMPPTCPConnection$PacketWriter.access$4000(XMPPTCPConnection.java:1335)
        at org.jivesoftware.smack.tcp.XMPPTCPConnection$PacketWriter$1.run(XMPPTCPConnection.java:1384)
        at java.lang.Thread.run(Thread.java:818)
D/SMACK: XMPPConnection (XMPPTCPConnection[test1@jabber.org/911427321667229798517426133] (0)) will reconnect in 4
D/SMACK: XMPPConnection (XMPPTCPConnection[test1@jabber.org/911427321667229798517426133] (0)) will reconnect in 3
D/SMACK: XMPPConnection (XMPPTCPConnection[test1@jabber.org/911427321667229798517426133] (0)) will reconnect in 2
D/SMACK: XMPPConnection (XMPPTCPConnection[test1@jabber.org/911427321667229798517426133] (0)) will reconnect in 1
D/SMACK: XMPPConnection (XMPPTCPConnection[test1@jabber.org/911427321667229798517426133] (0)) will reconnect in 0
D/SMACK: XMPPConnection (XMPPTCPConnection[test1@jabber.org/911427321667229798517426133] (0)) will reconnect in 0
...

The ‘bad’ message is sent right after “XMPPConnection authenticated” in the log. You can see how then reconnection manager takes over and looks like it’s trying to re-send this ‘bad’ message again which causes disconnect and so on.


#2

Every chat marker must have an ‘id’. From XEP-0333:

The Chat Marker MUST have an ‘id’ which is the ‘id’ of the message being marked.


#3

Not arguing with this. Just want to understand the architecture of Smack. So, if there is any violation, like this, Smack is designed to disconnect?

Also - why does it try to resend that bad stanza? Is it by design too?


#4

No. Smack is designed so that the constructor will throw an IllegalArgumentException if you construct an invalid XML element. Unfortunately the constructor of the ReceivedExtension in Smack 4.3 does not perform the required check and allows null values. This has been fixed in the master branch, which will become Smack 4.4. a while ago.


#5

Understood. Thanks!