From 9be498c440e2b10cae4d01b4d0037bfdb90c85cf Mon Sep 17 00:00:00 2001 From: Florian Schmaus Date: Mon, 1 Apr 2019 22:02:36 +0200 Subject: [PATCH] Fix NPE in Roster's presence listeners if 'from' is not set The NPE is caused by an inbound presence stanza without the 'from' attribute set. The stacktrace of the NPE is: FATAL EXCEPTION: Smack Cached Executor Process: de.fhg.ivi.senetz.mobile.android.mbk.debug, PID: 13365 java.lang.NullPointerException: Attempt to invoke virtual method 'int java.lang.Object.hashCode()' on a null object reference at java.util.concurrent.ConcurrentHashMap.get(ConcurrentHashMap.java:944) at org.jivesoftware.smack.roster.Roster.getPresencesInternal(Roster.java:374) at org.jivesoftware.smack.roster.Roster.getOrCreatePresencesInternal(Roster.java:388) at org.jivesoftware.smack.roster.Roster.access$1100(Roster.java:94) at org.jivesoftware.smack.roster.Roster$PresencePacketListener$1.run(Roster.java:1519) at org.jivesoftware.smack.AsyncButOrdered$Handler.run(AsyncButOrdered.java:121) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636) at java.lang.Thread.run(Thread.java:764) Thanks to Marcel Heckel for reporting this. Fixes SMACK-861. --- .../org/jivesoftware/smack/roster/Roster.java | 24 ++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/smack-im/src/main/java/org/jivesoftware/smack/roster/Roster.java b/smack-im/src/main/java/org/jivesoftware/smack/roster/Roster.java index 8e241151d..73486cd12 100644 --- a/smack-im/src/main/java/org/jivesoftware/smack/roster/Roster.java +++ b/smack-im/src/main/java/org/jivesoftware/smack/roster/Roster.java @@ -1471,7 +1471,29 @@ public final class Roster extends Manager { final Presence presence = (Presence) packet; final Jid from = presence.getFrom(); - final BareJid key = from != null ? from.asBareJid() : null; + final BareJid key; + if (from != null) { + key = from.asBareJid(); + } else { + XMPPConnection connection = connection(); + if (connection == null) { + LOGGER.finest("Connection was null while trying to handle exotic presence stanza: " + presence); + return; + } + // Assume the presence come "from the users account on the server" since no from was set (RFC 6120 ยง + // 8.1.2.1 4.). Note that getUser() may return null, but should never return null in this case as where + // connected. + EntityFullJid myJid = connection.getUser(); + if (myJid == null) { + LOGGER.info( + "Connection had no local address in Roster's presence listener." + + " Possibly we received a presence without from before being authenticated." + + " Presence: " + presence); + return; + } + LOGGER.info("Exotic presence stanza without from received: " + presence); + key = myJid.asBareJid(); + } asyncButOrdered.performAsyncButOrdered(key, new Runnable() { @Override