Mike Chambers

code = joy

ExternalInterface Bug with new line chars

with 11 comments

A couple of days ago I ran into a bug with ExternalInterface which caused me quite a hassle (a couple of people ran into it before I did). I finally figured it out, and wanted to post here in case anyone else runs into it.

Basically, if the data being passed from JavaScript to ActionScript or ActionScript to JavaScript via ExternalInterface contains any line returns (\n) then the string is not serialized correctly, and the call will fail (you will probably see a JavaScript error). This affects both Flash Player 8, and the Flash Player 8.5 alpha.

The issue has been logged and is being looked at it. Luckily, there is a simple workaround, which is to manually escape the line returns by replace \n with \\n.

Here is how to do it in ActionScript 3:

var data:String = stringToPass.replace(/\n/g, "\\n" );

and here is how to do it in ActionScript 2:

function escapeLineReturns(s:String):String
{
    trace("a");
    var len:Number = s.length;
    var sb = "";

    var c;
    for(var i:Number = 0; i < len; i++)
    {
        c = s.charAt(i);
        if(c == "\n")
        {
            sb += "\\n";
        }
        else
        {
            sb += c;
        }
    }

    trace("r : " + sb);
    return sb;
}

var data:String = escapeLineReturns(stringToPass);

On the JavaScript side you can basically use the same solution as in ActionScript 3.0:

var data = stringToPass.replace(/\n/g, "\\n" );

Written by mikechambers

January 10th, 2006 at 5:08 pm

Posted in General

11 Responses to 'ExternalInterface Bug with new line chars'

Subscribe to comments with RSS

  1. By the way, when you fix this bug, can you create a unit test on your side that throws alot of other crazy characters through ExternalInterface (including \r, pointy brackets, etc.)? If you are using XML as your internal serialization format, which I suspect, you might incorrectly serialize/deserialize those as well.

    Brad Neuberg

    10 Jan 06 at 5:51 pm

  2. There are some other characters that either cause and ExternalInterface call to fail or are not serialized properly. Here are the ones I’m aware of and their workarounds:

    \r >> \\r
    &amp; >> &amp;amp;
    &apos; >> &amp;apos;
    &lt; >> &amp;lt;
    &gt; >> &amp;gt;
    &quot; >> &amp;quot;

    Cheers

    Wes Carr

    10 Jan 06 at 8:24 pm

  3. Thanks. I just added these to the bug.

    mike chambers

    mesh@adobe.com

    mike chambers

    10 Jan 06 at 8:56 pm

  4. Could you simplify your AS2 replacement function to this:

    [code]
    function escapeLineReturns(s:String):String
    {
    return s.split(”\n”).join(”\\n”);
    }
    [/code]

    ? Not sure if it is less efficient but it seems to work for me…

    Kelvin Luck

    11 Jan 06 at 7:31 am

  5. It sounds like you used XML for your serialization format, but didn’t surround the value sections with CDATA blocks:

    That should help some of these problems, including having XML characters and entities misinterpreted. That is, if you didn’t roll your own XML parser on the other side, which doesn’t correctly handle CDATA sections, or are parsing out the XML with regular expressions….

    Brad Neuberg

    13 Jan 06 at 10:15 am

  6. The replacements in Wes Carr’s comment simplify to just replacing ‘&’ with ‘&’

    If you are just passing strings, you need to escape ‘&’, backslashes, and the line endings when sending from AS to JS, and unescape on the JS side.

    If you are passing objects, there are a host of other encoding issues in the xml serialization. Brad Meuberg has fixed most of these in dojo, so take a look at that code if interested.

    I’m not sure the dojo code does the backslash escaping though, so if you use it and see your literal ‘\t’ turning into a tab, update the encodeData AS function.

    It is disappointing that Adobe/Macromedia would release this interface publicly with so many errors. Adopters will necessarily have to fix it up on their own in in a superficial layer. Which means, if and when Adobe actually fixes it, all the userspace fixes we have had to painfully determine and apply will then be rebroken. Boo. They should consider a rename and rerelease of the working interface to prevent this

    Adam Morton

    4 May 07 at 9:14 am

  7. This issue has been fixed now for some time the public release builds of the player.

    mike chambers

    mesh@adobe.com

    mikechambers

    4 May 07 at 10:01 am

  8. Looks like the newline issue is fixed in 9,X, but not the entities or the backslashes. And I’m not set up to test the xml serialization so I can’t speak to that.

    Adam Morton

    4 May 07 at 2:32 pm

  9. So now if we pass the string containing “\n”, it will be passed correctly for one player and incorrectly for another. So flash code must detect which player is being used, and do the encoding manually if it is not done automatically by the player? And not all the necessary encoding is being done yet? This is broken on top of broken.

    Probably best to avoid passing any strings with any troublesome characters. I.e. strip out newlines, tabs, entities, backslashes, etc. Or force the user to use a specific player, not newer or older. Gack!

    Daniel LaLiberte

    16 Jan 08 at 11:31 am

  10. When passing a string from AS to JS, AS wraps the string in double quote. This creates problem with backslashes.

    Ex: to pass ‘c:\’ to myfunc, AS will call myfunc(”c:\”), thus syntax error will occurs at JS side.

    Ngoc

    24 Mar 08 at 6:18 pm

  11. FYI, there appears to be a new bug in ExternalInterface serialization. Namely,

    \\* is being converted to \* (where * is any character)

    So now you need to do the following (AS3):
    var data:String = stringToPass.replace(/\\/g, “\\\\” );

    Tested in Flash 9 and 10.

    Wes Carr

    6 Nov 08 at 4:01 pm

Leave a Reply