From 85781a71587d9ed4ab74aa8a1b87cd5c66611951 Mon Sep 17 00:00:00 2001 From: Derek DeMoro Date: Thu, 14 Sep 2006 15:19:39 +0000 Subject: [PATCH] 1) SMACK-170 - Added JID escaping capabilities to SMACK. 2) Escaping form field values to prevent bad xml. git-svn-id: http://svn.igniterealtime.org/svn/repos/smack/trunk@5363 b35dd754-fafc-0310-a699-88a17e54d16e --- .../jivesoftware/smack/XMPPConnection.java | 1 + .../org/jivesoftware/smack/packet/Packet.java | 4 +- .../smack/packet/RosterPacket.java | 2 +- .../jivesoftware/smack/util/StringUtils.java | 55 +++++++++++++++---- source/org/jivesoftware/smackx/FormField.java | 4 +- .../smackx/RemoteRosterEntry.java | 4 +- .../jivesoftware/smackx/packet/MUCUser.java | 25 +++++---- .../smackx/search/UserSearchManager.java | 23 +++++--- 8 files changed, 83 insertions(+), 35 deletions(-) diff --git a/source/org/jivesoftware/smack/XMPPConnection.java b/source/org/jivesoftware/smack/XMPPConnection.java index c0c4f8cd6..fdbd705f1 100644 --- a/source/org/jivesoftware/smack/XMPPConnection.java +++ b/source/org/jivesoftware/smack/XMPPConnection.java @@ -425,6 +425,7 @@ public class XMPPConnection { } // Do partial version of nameprep on the username. username = username.toLowerCase().trim(); + username = StringUtils.escapeNode(username); String response; if (configuration.isSASLAuthenticationEnabled() && diff --git a/source/org/jivesoftware/smack/packet/Packet.java b/source/org/jivesoftware/smack/packet/Packet.java index 62b8e3efc..1be71c8a3 100644 --- a/source/org/jivesoftware/smack/packet/Packet.java +++ b/source/org/jivesoftware/smack/packet/Packet.java @@ -112,7 +112,7 @@ public abstract class Packet { * value has not been set. */ public String getTo() { - return to; + return StringUtils.escapeJID(to); } /** @@ -134,7 +134,7 @@ public abstract class Packet { * valud has not been set. */ public String getFrom() { - return from; + return StringUtils.escapeJID(from); } /** diff --git a/source/org/jivesoftware/smack/packet/RosterPacket.java b/source/org/jivesoftware/smack/packet/RosterPacket.java index fff1c9946..32fd72ff1 100644 --- a/source/org/jivesoftware/smack/packet/RosterPacket.java +++ b/source/org/jivesoftware/smack/packet/RosterPacket.java @@ -198,7 +198,7 @@ public class RosterPacket extends IQ { public String toXML() { StringBuilder buf = new StringBuilder(); - buf.append(" XMPPAddress.length()) { return ""; @@ -127,6 +127,8 @@ public class StringUtils { } } + + /** * Escapes the node portion of a JID according to "JID Escaping" (JEP-0106). * Escaping replaces characters prohibited by node-prep with escape sequences, @@ -166,15 +168,9 @@ public class StringUtils { for (int i=0, n=node.length(); i': buf.append("\\3e"); break; + case '@': buf.append("\\40"); break; - case '\\': buf.append("\\5c"); break; + default: { if (Character.isWhitespace(c)) { buf.append("\\20"); @@ -188,6 +184,43 @@ public class StringUtils { return buf.toString(); } + /** + * Escapes a complete JID by examing the Node itself and escaping + * when neccessary. + * @param jid the users JID + * @return the escaped JID. + */ + public static String escapeJID(String jid){ + if(jid == null){ + return null; + } + + final StringBuilder builder = new StringBuilder(); + String node = parseName(jid); + String restOfJID = jid.substring(node.length()); + builder.append(escapeNode(node)); + builder.append(restOfJID); + return builder.toString(); + } + + /** + * Unescapes a complete JID by examing the node itself and unescaping when necessary. + * @param jid the users jid. + * @return the unescaped JID. + */ + public static String unescapeJID(String jid){ + if(jid == null){ + return null; + } + + final StringBuilder builder = new StringBuilder(); + String node = parseName(jid); + String restOfJID = jid.substring(node.length()); + builder.append(unescapeNode(node)); + builder.append(restOfJID); + return builder.toString(); + } + /** * Un-escapes the node portion of a JID according to "JID Escaping" (JEP-0106).

* Escaping replaces characters prohibited by node-prep with escape sequences, @@ -308,7 +341,7 @@ public class StringUtils { if (i > last) { out.append(input, last, i - last); } - // Do nothing if the string is of the form ë (unicode value) + // Do nothing if the string is of the form ë (unicode value) if (!(len > i + 5 && input[i + 1] == '#' && Character.isDigit(input[i + 2]) diff --git a/source/org/jivesoftware/smackx/FormField.java b/source/org/jivesoftware/smackx/FormField.java index 643ca7a91..2a58c278c 100644 --- a/source/org/jivesoftware/smackx/FormField.java +++ b/source/org/jivesoftware/smackx/FormField.java @@ -20,6 +20,8 @@ package org.jivesoftware.smackx; +import org.jivesoftware.smack.util.StringUtils; + import java.util.ArrayList; import java.util.Collections; import java.util.Iterator; @@ -288,7 +290,7 @@ public class FormField { } // Loop through all the values and append them to the string buffer for (Iterator i = getValues(); i.hasNext();) { - buf.append("").append(i.next()).append(""); + buf.append("").append(StringUtils.escapeForXML(i.next())).append(""); } // Loop through all the values and append them to the string buffer for (Iterator i = getOptions(); i.hasNext();) { diff --git a/source/org/jivesoftware/smackx/RemoteRosterEntry.java b/source/org/jivesoftware/smackx/RemoteRosterEntry.java index fe329e2c2..8039b4d19 100644 --- a/source/org/jivesoftware/smackx/RemoteRosterEntry.java +++ b/source/org/jivesoftware/smackx/RemoteRosterEntry.java @@ -20,6 +20,8 @@ package org.jivesoftware.smackx; +import org.jivesoftware.smack.util.StringUtils; + import java.util.*; /** @@ -100,7 +102,7 @@ public class RemoteRosterEntry { public String toXML() { StringBuilder buf = new StringBuilder(); - buf.append("").append(getReason()).append(""); } if (getActor() != null) { - buf.append(""); + buf.append(""); } buf.append(""); } @@ -528,7 +529,7 @@ public class MUCUser implements PacketExtension { * @author Gaston Dombiak */ public static class Status { - private String code; + private String code; /** * Creates a new instance of Status with the specified code. @@ -538,7 +539,7 @@ public class MUCUser implements PacketExtension { public Status(String code) { this.code = code; } - + /** * Returns the code that uniquely identifies the reason of the error. The code * assists in presenting notification messages. @@ -566,8 +567,8 @@ public class MUCUser implements PacketExtension { public static class Destroy { private String reason; private String jid; - - + + /** * Returns the JID of an alternate location since the current room is being destroyed. * @@ -608,7 +609,7 @@ public class MUCUser implements PacketExtension { StringBuilder buf = new StringBuilder(); buf.append(""); diff --git a/source/org/jivesoftware/smackx/search/UserSearchManager.java b/source/org/jivesoftware/smackx/search/UserSearchManager.java index 945eadd84..9358d1fe5 100644 --- a/source/org/jivesoftware/smackx/search/UserSearchManager.java +++ b/source/org/jivesoftware/smackx/search/UserSearchManager.java @@ -49,7 +49,7 @@ public class UserSearchManager { /** * Creates a new UserSearchManager. * - * @param con the XMPPConnection to use. + * @param con the XMPPConnection to use. */ public UserSearchManager(XMPPConnection con) { this.con = con; @@ -71,7 +71,7 @@ public class UserSearchManager { * Submits a search form to the server and returns the resulting information * in the form of ReportedData * - * @param searchForm the Form to submit for searching. + * @param searchForm the Form to submit for searching. * @param searchService the name of the search service to use. * @return the ReportedData returned by the server. * @throws XMPPException thrown if a server error has occurred. @@ -88,18 +88,27 @@ public class UserSearchManager { * @throws XMPPException thrown if a server error has occurred. */ public Collection getSearchServices() throws XMPPException { - List searchServices = new ArrayList(); + final List searchServices = new ArrayList(); ServiceDiscoveryManager discoManager = ServiceDiscoveryManager.getInstanceFor(con); DiscoverItems items = discoManager.discoverItems(con.getServiceName()); - for (Iterator it = items.getItems(); it.hasNext();) { - DiscoverItems.Item item = (DiscoverItems.Item) it.next(); + Iterator iter = items.getItems(); + while (iter.hasNext()) { + DiscoverItems.Item item = (DiscoverItems.Item) iter.next(); try { - DiscoverInfo info = discoManager.discoverInfo(item.getEntityID()); + DiscoverInfo info = null; + try { + info = discoManager.discoverInfo(item.getEntityID()); + } + catch (XMPPException e) { + // Ignore Case + continue; + } + if (info.containsFeature("jabber:iq:search")) { searchServices.add(item.getEntityID()); } } - catch (XMPPException e) { + catch (Exception e) { // No info found. break; }