Bugs in Escaping and Unescaping JIDs

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:

RosterItem.as

/**
           * 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.