Monthly Archives: December 2007

ExternalInterface bug can mangle data from JavaScript

While developing the YUI Charts, I discovered a nasty bug with ExternalInterface that affects many versions of Flash Player 9. Basically, it involves overwriting parts of the data passed from JavaScript somewhere in the encoding or decoding process. The best way to describe this error is to explain with an example.

Consider the following Flex application. Once it is initialized, the application calls a function named flashReady() in the hosting page’s JavaScript. The function returns a complex object to display in the Flex app’s Tree control.

Screenshot of working Flex application. Click image to run the application.

Source code for the Flex app:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical" applicationComplete="getDataFromJavaScript()">
	<mx:HBox>
		<mx:Tree id="tree" width="250" height="300"/>
		<mx:TextArea id="parsedData" fontFamily="Courier New" fontSize="12" width="250" height="300"/>
	</mx:HBox>
	<mx:Label id="status" text="Loading Data..."/>
	<mx:Script>
		<![CDATA[
			import com.adobe.serialization.json.JSON;

			private function getDataFromJavaScript():void
			{
				if(ExternalInterface.available)
				{
					var result:Object = ExternalInterface.call("flashReady", []);
					this.tree.dataProvider = result;

					//we're only encoding to JSON to view the result in the TextArea
					this.parsedData.text = JSON.encode(result);

					//version displayed for easy identification
					this.status.text = "Flash Player Version: " + Capabilities.version;
				}
				else
				{
					this.status.text = "ExternalInterface is not available!";
				}
			}

		]]>
	</mx:Script>
</mx:Application>

The following structure is passed from JavaScript to ActionScript.

var dataToPass =
{
	label: "Level 1-A",
	children:
	[
		{ label: "Level 2-A" },
		{
			label: "Level 2-B",
			children:
			[
				{ label: "Level 3-A" },
				{ label: "Level 3-B" }
			]
		},
		{
			label: "Level 2-C",
			children:
			[
				{
					label: "Level 3-C",
					children:
					[
						{ label: "Level 4-A" }
					]
				},
				{ label: "Level 3-D" }
			]
		}
	]
};

As you can see, the data passed through ExternalInterface has a complex hierarchy. Many of the objects have a label variable and many have children to specify branches in the Tree.

With Flash Player 9.0.28 (it affects other builds, but that one is commonly installed), the parsed data displayed in the TextArea control looks like the following code block. I’ve manually formatted it for readability.

{
	"0" : { "label" : "Level 4-A" },
	"children" :
	[
		{ "label" : "Level 4-A" }
	],
	"1" : {"label" : "Level 3-D"},
	"2" :
	{
		"0": { "label" : "Level 4-A" },
		"children" :
		[
			{ "label" : "Level 4-A" }
		],
		"1" : { "label" : "Level 3-D" },
		"label" : "Level 3-D"
	},
	"label" : "Level 3-D"
}

You’ll notice that the label property is overwritten on many of the more shallow levels. The strange numeric variables come from the indexes of the various children Arrays. Clearly, much of the data gets completely lost. You can see the very nearly empty Tree control in the following screenshot.

Screenshot of the Flex application when in a buggy Flash Player.

Thankfully, Flash Player 9 Update 3 (build 9.0.115) properly handles this type of ExternalInterface data. However, one can hardly expect everyone to install the very newest version that isn’t even a month old yet.

For the YUI Charts, I needed to find a way to get around this problem in older versions of Flash Player 9. Using the YUI JSON Utility, I encoded the data provider and various other complex properties to simple strings before passing them through ExternalInterface from JavaScript to ActionScript. On the ActionScript side, the JSON data can be decoded with AS3 corelib to turn it back into native objects.

For public releases of Flash Player (official releases and those appearing on Adobe Labs), this bug seems to affect builds below 9.0.60 (the beta version of Update 3, mentioned above). It shouldn’t affect too many applications out there as ExternalInterface isn’t widely used, in my experience. For those out there that do make heavy use of this API, it’s definitely a concern, and you will either need to resort to encoding the data somehow or requiring FP 9.0.115 as the minimum version if you discover that you’re affected.

By the way, if you ever need to test older versions of Flash Player, Adobe provides nice zipped downloads of each major version (with multiple builds of each) back to Flash Player 2.

Thoughts on Essential ActionScript 3.0

Widely considered the ultimate books on programming in Flash, Colin Moock’s Essential ActionScript series recently got updated for AS3. The first thing you’ll notice when you see it on the shelf, or pick it up off a fellow developer’s desk, is that Moock’s been doing a lot of writing. Essential ActionScript 3.0 appears to be about a third bigger than the last version. With the index, it surpasses 900 pages. The size difference between this book and its predecessor is strong evidence of how much ActionScript has grown and changed in recent years.

Let me start my review with a bit of a warning. It’s possible that this book may not contain the information you’d expect in its pages. It’s a book purely about ActionScript, the language. You won’t learn about Flash’s visual drawing tools, the library, components like a List or a RadioButton, and certainly not about anything specific to Flex. The author’s intent is to show you how to use the language itself, regardless of the IDE or type of project in which you use it. Moock shows the reader how to build classes, create functions, use inheritance, and work with many of Flash Player’s native APIs. The information is applicable to both the classic Flash authoring environment and in Flex Builder.

Although the back of the book states, “if you have no prior programming knowledge, this book gently guides you on your journey toward ActionScript proficiency”, I believe that it is more suited for intermediate to advanced developers. Folks coming from AS2 with a little knowledge of OOP should have no trouble, and developers coming from another language will easily transition into AS3. People less experienced in programming may get frustrated by a lack of step-by-step guidance. I’ve heard many people complain that Moock didn’t include enough examples. Personally, I felt the “Virtual Zoo” example that was referenced throughout much of the book felt out of place. Either he should have left it out or he should have built a larger variety of examples.

Reading through Essential ActionScript 3.0 reminded me of the textbooks I had in my college computer science classes. It’s the kind of no-nonsense book a software engineer would use as a stepping stone for a new language before moving entirely to the online documentation, which I think fits well with O’Reilly‘s typical audience. While I very much enjoy the Friends of ED Flash books for their tendency to be lighter reading and more guided, EAS3 was an odd breath of fresh air for me, and I can’t quite explain it. Regardless, know that while it’s a bit more technical, it’s not boring either.

One of the ultimate tests of a programming book, for me, is whether it teaches me anything new. As the guy who always seems to have an answer when my coworkers run into something strange, that can be a bit of a challenge. Generally, it’s some little function on a core class that I simply passed over a million times while reading the documentation. For EAS3, my moment of learning was a little more obscure, but I found the chapter that covers ApplicationDomains and communication betweens SWFs very interesting and I picked up a couple tidbits that I know I will need someday.

Though not for everybody, Essential ActionScript 3.0 is a good manual for development with Flash Player’s primary programming language, ActionScript. At nearly one thousand pages, a lot of information will be at your fingertips, and I imagine this book will sit very close to many developer’s desks. Beginners may find its information a little hard to follow, but experienced developers should feel right at home.