aboutsummaryrefslogtreecommitdiffstats
path: root/src/main/java/eu/siacs/conversations/parser/MessageParser.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/eu/siacs/conversations/parser/MessageParser.java')
-rw-r--r--src/main/java/eu/siacs/conversations/parser/MessageParser.java81
1 files changed, 68 insertions, 13 deletions
diff --git a/src/main/java/eu/siacs/conversations/parser/MessageParser.java b/src/main/java/eu/siacs/conversations/parser/MessageParser.java
index c79110c9..57a737ef 100644
--- a/src/main/java/eu/siacs/conversations/parser/MessageParser.java
+++ b/src/main/java/eu/siacs/conversations/parser/MessageParser.java
@@ -1,5 +1,6 @@
package eu.siacs.conversations.parser;
+import android.text.Html;
import android.util.Log;
import android.util.Pair;
@@ -12,6 +13,9 @@ import net.java.otr4j.session.SessionStatus;
import java.net.URL;
import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Locale;
import java.util.Set;
import de.thedevstack.android.logcat.Logging;
@@ -29,6 +33,8 @@ import eu.siacs.conversations.entities.Contact;
import eu.siacs.conversations.entities.Conversation;
import eu.siacs.conversations.entities.Message;
import eu.siacs.conversations.entities.MucOptions;
+import eu.siacs.conversations.entities.Presence;
+import eu.siacs.conversations.entities.ServiceDiscoveryResult;
import eu.siacs.conversations.http.HttpConnectionManager;
import eu.siacs.conversations.services.AvatarService;
import eu.siacs.conversations.services.MessageArchiveService;
@@ -41,8 +47,10 @@ import eu.siacs.conversations.xmpp.jid.Jid;
import eu.siacs.conversations.xmpp.pep.Avatar;
import eu.siacs.conversations.xmpp.stanzas.MessagePacket;
-public class MessageParser extends AbstractParser implements
- OnMessagePacketReceived {
+public class MessageParser extends AbstractParser implements OnMessagePacketReceived {
+
+ private static final List<String> CLIENTS_SENDING_HTML_IN_OTR = Arrays.asList(new String[]{"Pidgin","Adium"});
+
public MessageParser(XmppConnectionService service) {
super(service);
}
@@ -106,6 +114,11 @@ public class MessageParser extends AbstractParser implements
conversation.setSymmetricKey(CryptoHelper.hexToBytes(key));
return null;
}
+ if (clientMightSendHtml(conversation.getAccount(), from)) {
+ Log.d(Config.LOGTAG,conversation.getAccount().getJid().toBareJid()+": received OTR message from bad behaving client. escaping HTML…");
+ body = Html.fromHtml(body).toString();
+ }
+
final OtrService otrService = conversation.getAccount().getOtrService();
Message finishedMessage = new Message(conversation, body, Message.ENCRYPTION_OTR, Message.STATUS_RECEIVED);
finishedMessage.setFingerprint(otrService.getFingerprint(otrSession.getRemotePublicKey()));
@@ -118,6 +131,30 @@ public class MessageParser extends AbstractParser implements
}
}
+ private static boolean clientMightSendHtml(Account account, Jid from) {
+ String resource = from.getResourcepart();
+ if (resource == null) {
+ return false;
+ }
+ Presence presence = account.getRoster().getContact(from).getPresences().getPresences().get(resource);
+ ServiceDiscoveryResult disco = presence == null ? null : presence.getServiceDiscoveryResult();
+ if (disco == null) {
+ return false;
+ }
+ return hasIdentityKnowForSendingHtml(disco.getIdentities());
+ }
+
+ private static boolean hasIdentityKnowForSendingHtml(List<ServiceDiscoveryResult.Identity> identities) {
+ for(ServiceDiscoveryResult.Identity identity : identities) {
+ if (identity.getName() != null) {
+ if (CLIENTS_SENDING_HTML_IN_OTR.contains(identity.getName())) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
private Message parseAxolotlChat(Element axolotlMessage, Jid from, Conversation conversation, int status) {
Message finishedMessage = null;
AxolotlService service = conversation.getAccount().getAxolotlService();
@@ -320,7 +357,7 @@ public class MessageParser extends AbstractParser implements
}
boolean isTypeGroupChat = packet.getType() == MessagePacket.TYPE_GROUPCHAT;
- boolean isProperlyAddressed = (to != null ) && (!to.isBareJid() || account.countPresences() <= 1);
+ boolean isProperlyAddressed = (to != null ) && (!to.isBareJid() || account.countPresences() == 0);
boolean isMucStatusMessage = from.isBareJid() && mucUserElement != null && mucUserElement.hasChild("status");
if (packet.fromAccount(account)) {
status = Message.STATUS_SEND;
@@ -374,7 +411,7 @@ public class MessageParser extends AbstractParser implements
} else if (axolotlEncrypted != null && Config.supportOmemo()) {
Jid origin;
if (conversation.getMode() == Conversation.MODE_MULTI) {
- origin = conversation.getMucOptions().getTrueCounterpart(counterpart.getResourcepart());
+ origin = conversation.getMucOptions().getTrueCounterpart(counterpart);
if (origin == null) {
Log.d(Config.LOGTAG,"axolotl message in non anonymous conference received");
return;
@@ -406,16 +443,13 @@ public class MessageParser extends AbstractParser implements
message.setOob(isOob);
message.markable = packet.hasChild("markable", "urn:xmpp:chat-markers:0");
if (conversation.getMode() == Conversation.MODE_MULTI) {
- Jid trueCounterpart = conversation.getMucOptions().getTrueCounterpart(counterpart.getResourcepart());
+ Jid trueCounterpart = conversation.getMucOptions().getTrueCounterpart(counterpart);
message.setTrueCounterpart(trueCounterpart);
- if (trueCounterpart != null) {
- updateLastseen(timestamp, account, trueCounterpart, false);
- }
if (!isTypeGroupChat) {
message.setType(Message.TYPE_PRIVATE);
}
} else {
- updateLastseen(timestamp, account, packet.getFrom(), true);
+ updateLastseen(timestamp, account, from);
}
boolean checkForDuplicates = query != null
@@ -486,8 +520,11 @@ public class MessageParser extends AbstractParser implements
}
}
} else if (!packet.hasChild("body")){ //no body
- if (isTypeGroupChat) {
+ if (Config.BACKGROUND_STANZA_LOGGING && !mXmppConnectionService.checkListeners()) {
+ Log.d(Config.LOGTAG, account.getJid().toBareJid() + ": " + original);
+ }
Conversation conversation = mXmppConnectionService.find(account, from.toBareJid());
+ if (isTypeGroupChat) {
if (packet.hasChild("subject")) {
if (conversation != null && conversation.getMode() == Conversation.MODE_MULTI) {
conversation.setHasMessagesLeftOnServer(conversation.countMessages() > 0);
@@ -503,17 +540,35 @@ public class MessageParser extends AbstractParser implements
return;
}
}
-
- if (conversation != null && isMucStatusMessage) {
+ }
+ if (conversation != null && mucUserElement != null && from.isBareJid()) {
+ if (mucUserElement.hasChild("status")) {
for (Element child : mucUserElement.getChildren()) {
if (child.getName().equals("status")
&& MucOptions.STATUS_CODE_ROOM_CONFIG_CHANGED.equals(child.getAttribute("code"))) {
mXmppConnectionService.fetchConferenceConfiguration(conversation);
}
}
+ } else if (mucUserElement.hasChild("item")) {
+ for(Element child : mucUserElement.getChildren()) {
+ if ("item".equals(child.getName())) {
+ MucOptions.User user = AbstractParser.parseItem(conversation,child);
+ Log.d(Config.LOGTAG,account.getJid()+": changing affiliation for "
+ +user.getRealJid()+" to "+user.getAffiliation()+" in "
+ +conversation.getJid().toBareJid());
+ if (!user.realJidMatchesAccount()) {
+ conversation.getMucOptions().addUser(user);
+ mXmppConnectionService.getAvatarService().clear(conversation);
+ mXmppConnectionService.updateMucRosterUi();
+ mXmppConnectionService.updateConversationUi();
+ }
+ }
}
}
}
+ }
+
+
Element received = packet.findChild("received", "urn:xmpp:chat-markers:0");
if (received == null) {
@@ -531,7 +586,7 @@ public class MessageParser extends AbstractParser implements
mXmppConnectionService.markRead(conversation);
}
} else {
- updateLastseen(timestamp, account, packet.getFrom(), true);
+ updateLastseen(timestamp, account, from);
final Message displayedMessage = mXmppConnectionService.markMessage(account, from.toBareJid(), displayed.getAttribute("id"), Message.STATUS_SEND_DISPLAYED);
Message message = displayedMessage == null ? null : displayedMessage.prev();
while (message != null