Sparkweb won’t take spaces in usernames for login, and throught the JavaScript ExternalInterface method.
After checkout out the SparkWeb source it looks like there are a few bugs in handling Escaping of JIDs.
In xiff there is a bug in AbstractJID.
http://svn.igniterealtime.org/svn/repos/xiff/trunk/src/org/jivesoftware/xiff/cor e/AbstractJID.as
The method unescapedNode() looks like:
/**
* Provides functionality to return an escaped JID into a normal String.
*
* @param n The string to unescape.
*
* @return The unescaped string.
*/
public static function unescapedNode(n:String):String
{
if( n && (
n.indexOf("\\40") >= 0 ||
n.indexOf("\\20") >= 0 ||
n.indexOf("\\26")>= 0 ||
n.indexOf("\\3e") >= 0 ||
n.indexOf("\\3c") >= 0 ||
n.indexOf("\\5c") >= 0 ||
n.indexOf('\\3a') >= 0 ||
n.indexOf("\\2f") >= 0 ||
n.indexOf("\\22") >= 0 ||
n.indexOf("\\27") >= 0) )
{
n = n.replace(/\40/g, "@");
n = n.replace(/\20/g, " ");
n = n.replace(/\26/g, "&");
n = n.replace(/\3e/g, ">");
n = n.replace(/\3c/g, "<");
n = n.replace(/\3a/g, ":");
n = n.replace(/\2f/g, "/");
n = n.replace(quoteregex, '"');
n = n.replace(quoteregex2, "'");
n = n.replace(/\5c/g, "\\");
}
return n;
}
It will not unescape the node correctly as /\40/ should be /\40/ etc.
/**
* Provides functionality to return an escaped JID into a normal String.
*
* @param n The string to unescape.
*
* @return The unescaped string.
*/
public static function unescapedNode(n:String):String
{
if( n && (
n.indexOf("\\40") >= 0 ||
n.indexOf("\\20") >= 0 ||
n.indexOf("\\26")>= 0 ||
n.indexOf("\\3e") >= 0 ||
n.indexOf("\\3c") >= 0 ||
n.indexOf("\\5c") >= 0 ||
n.indexOf('\\3a') >= 0 ||
n.indexOf("\\2f") >= 0 ||
n.indexOf("\\22") >= 0 ||
n.indexOf("\\27") >= 0) )
{
n = n.replace(/\\40/g, "@");
n = n.replace(/\\20/g, " ");
n = n.replace(/\\26/g, "&");
n = n.replace(/\\3e/g, ">");
n = n.replace(/\\3c/g, "<");
n = n.replace(/\\3a/g, ":");
n = n.replace(/\\2f/g, "/");
n = n.replace(quoteregex, '"');
n = n.replace(quoteregex2, "'");
n = n.replace(/\\5c/g, "\\");
}
return n;
}
Could someone confirm if this is a bug?
The other issue is during authentication the JID is not escaped.
eg: http://svn.igniterealtime.org/svn/repos/xiff/trunk/src/org/jivesoftware/xiff/aut h/Plain.as
/**
* Creates a new Plain authentication object.
*
* @param connection A reference to the XMPPConnection instance in use.
*/
public function Plain(connection:XMPPConnection)
{
//should probably use the escaped form, but flex/as handles \\ weirdly for unknown reasons
var jid:UnescapedJID = connection.jid;
var authContent:String = jid.bareJID;
authContent += '\u0000';
authContent += jid.node;
authContent += '\u0000';
authContent += connection.password; var b64coder:Base64Encoder = new Base64Encoder();
b64coder.insertNewLines = false;
b64coder.encodeUTFBytes(authContent);
authContent = b64coder.flush(); var attrs:Object = {
mechanism: "PLAIN",
xmlns: "urn:ietf:params:xml:ns:xmpp-sasl"
}; req = new XMLNode(1, "auth");
req.appendChild(new XMLNode(3, authContent));
req.attributes = attrs; stage = 0;
}
The JID should be escaped.
/**
* Creates a new Plain authentication object.
*
* @param connection A reference to the XMPPConnection instance in use.
*/
public function Plain(connection:XMPPConnection)
{
//should probably use the escaped form, but flex/as handles \\ weirdly for unknown reasons
// gabe@fijiwebdesign.com : using escaped jids
var jid:UnescapedJID = connection.jid;
var authContent:String = jid.escaped.bareJID;
authContent += '\u0000';
authContent += jid.escaped.node;
authContent += '\u0000';
authContent += connection.password; var b64coder:Base64Encoder = new Base64Encoder();
b64coder.insertNewLines = false;
b64coder.encodeUTFBytes(authContent);
authContent = b64coder.flush(); var attrs:Object = {
mechanism: "PLAIN",
xmlns: "urn:ietf:params:xml:ns:xmpp-sasl"
}; req = new XMLNode(1, "auth");
req.appendChild(new XMLNode(3, authContent));
req.attributes = attrs; stage = 0;
}
There are a few other places that the JID is double escaped, or double unescaped (thought double unescape doesn’t hurt). eg:
/**
* The JID for this roster item.
*
* @availability Flash Player 7
*/
public function get jid():EscapedJID
{
return new EscapedJID(getNode().attributes.jid);
}
public function set jid( newJID:EscapedJID ):void
{
getNode().attributes.jid = newJID.toString();
}
Shouldn’t that be:
/**
* The JID for this roster item.
*
* @availability Flash Player 7
*/
public function get jid():EscapedJID
{
return new EscapedJID(getNode().attributes.jid);
}
public function set jid( newJID:EscapedJID ):void
{
getNode().attributes.jid = newJID.unescaped.toString();
}
or bypass having to unescape and then escape altogether b receiving an UnescapedJID?
As doing new EscapedJID(EscapedJID.toString()) would duble escape.