fixed parsing of unescaped jids with @ in local part

Daniel Gultsch created

Change summary

src/main/java/eu/siacs/conversations/xmpp/Jid.java | 32 ++++++++++++++--
1 file changed, 28 insertions(+), 4 deletions(-)

Detailed changes

src/main/java/eu/siacs/conversations/xmpp/Jid.java 🔗

@@ -7,10 +7,21 @@ import org.jxmpp.jid.parts.Resourcepart;
 import org.jxmpp.stringprep.XmppStringprepException;
 
 import java.io.Serializable;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 public interface Jid extends Comparable<Jid>, Serializable, CharSequence {
 
+    Pattern JID = Pattern.compile("^((.*?)@)?([^/@]+)(/(.*))?$");
+
     static Jid of(CharSequence local, CharSequence domain, CharSequence resource) {
+        if (local == null) {
+            if (resource == null) {
+                return ofDomain(domain);
+            } else {
+                return ofDomainAndResource(domain, resource);
+            }
+        }
         if (resource == null) {
             return ofLocalAndDomain(local, domain);
         }
@@ -67,6 +78,18 @@ public interface Jid extends Comparable<Jid>, Serializable, CharSequence {
         }
     }
 
+    static Jid ofDomainAndResource(CharSequence domain, CharSequence resource) {
+        try {
+                return new WrappedJid(
+                        JidCreate.domainFullFrom(
+                                Domainpart.from(domain.toString()),
+                                Resourcepart.from(resource.toString())
+                        ));
+            } catch (XmppStringprepException e) {
+                throw new IllegalArgumentException(e);
+            }
+    }
+
     static Jid ofLocalAndDomainEscaped(CharSequence local, CharSequence domain) {
         try {
             return new WrappedJid(
@@ -84,10 +107,11 @@ public interface Jid extends Comparable<Jid>, Serializable, CharSequence {
         if (jid instanceof Jid) {
             return (Jid) jid;
         }
-        try {
-            return new WrappedJid(JidCreate.fromUnescaped(jid));
-        } catch (XmppStringprepException e) {
-            throw new IllegalArgumentException(e);
+        Matcher matcher = JID.matcher(jid);
+        if (matcher.matches()) {
+            return of(matcher.group(2), matcher.group(3), matcher.group(5));
+        } else {
+            throw new IllegalArgumentException("Could not parse JID: " + jid);
         }
     }