diff --git a/source/org/jivesoftware/smack/util/StringUtils.java b/source/org/jivesoftware/smack/util/StringUtils.java index d0d685788..7e9e1aa69 100644 --- a/source/org/jivesoftware/smack/util/StringUtils.java +++ b/source/org/jivesoftware/smack/util/StringUtils.java @@ -127,6 +127,147 @@ 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, + * as follows:

+ * + * + * + * + * + * + * + * + * + * + * + * + * + *
Unescaped CharacterEncoded Sequence
<space>\20
"\22
&\26
'\27
/\2f
:\3a
<\3c
>\3e
@\40
\\5c

+ * + * This process is useful when the node comes from an external source that doesn't + * conform to nodeprep. For example, a username in LDAP may be "Joe Smith". Because + * the <space> character isn't a valid part of a node, the username should + * be escaped to "Joe\20Smith" before being made into a JID (e.g. "joe\20smith@example.com" + * after case-folding, etc. has been applied).

+ * + * All node escaping and un-escaping must be performed manually at the appropriate + * time; the JID class will not escape or un-escape automatically. + * + * @param node the node. + * @return the escaped version of the node. + */ + public static String escapeNode(String node) { + if (node == null) { + return null; + } + StringBuilder buf = new StringBuilder(node.length() + 8); + 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"); + } + else { + buf.append(c); + } + } + } + } + return buf.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, + * as follows:

+ * + * + * + * + * + * + * + * + * + * + * + * + * + *
Unescaped CharacterEncoded Sequence
<space>\20
"\22
&\26
'\27
/\2f
:\3a
<\3c
>\3e
@\40
\\5c

+ * + * This process is useful when the node comes from an external source that doesn't + * conform to nodeprep. For example, a username in LDAP may be "Joe Smith". Because + * the <space> character isn't a valid part of a node, the username should + * be escaped to "Joe\20Smith" before being made into a JID (e.g. "joe\20smith@example.com" + * after case-folding, etc. has been applied).

+ * + * All node escaping and un-escaping must be performed manually at the appropriate + * time; the JID class will not escape or un-escape automatically. + * + * @param node the escaped version of the node. + * @return the un-escaped version of the node. + */ + public static String unescapeNode(String node) { + if (node == null) { + return null; + } + char [] nodeChars = node.toCharArray(); + StringBuilder buf = new StringBuilder(nodeChars.length); + for (int i=0, n=nodeChars.length; i'); i+=2; break compare; + } + } + else if (c2 == '4') { + if (c3 == '0') { + buf.append("@"); + i+=2; + break compare; + } + } + else if (c2 == '5') { + if (c3 == 'c') { + buf.append("\\"); + i+=2; + break compare; + } + } + } + buf.append(c); + } + } + return buf.toString(); + } + /** * Escapes all necessary characters in the String so that it can be used * in an XML doc.