swfmill not properly processsing fonts and colour transforms in some SWFs generated by CS4
RP reports (as bug #496426 on Launchpad):
See attached swf (from Open Source Flashdevelopment book) intended to be a simple example of using external swf assets with actionscript. When you run swfmill (from bzr) swf2xml it generates perfectly valid xml, which swfmill will compile back to a swf that immediately crashes the flashplayer if you attempt to run it (on adobe flashplayer 10 debug on both Linux and Windows). When I turn on debug output it appears that the seemingly fine swf is setting under the
DefineFont3tag thewideMapattribute, which is being parsed, but not written out anywhere in the XML representation. In this case, it is settingwideMapto 1, instead of zero.I additionally noticed that in some of the
FontAlignZonesit is improperly setting the reserved bit to 3, rather than zero as specified.ColorTransform2tags with no Offset or Factor also differed in that the size of bits were being left at zero, instead of 1 like the properly working swf.Once I made all of the changes and re-milled the swf, it loaded without a hitch on both Windows and Linux.
The other difference that I noted is that in the original file, it reported the length of the font name “Arial” as
6, which is including the nul character, against the specification. It seems that other programs are expecting the font name length to include the nul character (primarily FlashDevelop, I haven’t been able to confirm it with any other programs). If I can do anything else to help in this just let me know.I’ve made some quick and dirty hacks to fix the things I’ve mentioned if you want the diffs.
RP comments:
I located the .fla file that generated the swf and loaded it into CS4 to attempt to determine the version number of the fla file, the only thing I could discern is that it was generated in a version earlier than CS4, per the warning messages given.
Anyways, I published it myself using CS4 - no errors generated that I could tell, I'm not an expert in CS4, same results, sets WideMaps in the font, 1 bits in the ColorTransform that isn't there, and in the ZoneData it puts the naughty 3 in the reserved fields.
Again, turning it to xml with swfmill looks fine, the resultant xml to swf immediately crashes the flashplayer.
On further examination of the code, my diffs were all against the generated code (gSWFparser, etc...), and I'm not familiar enough with the xsl wizardry going on to comfortably change that.
Here’s an attachment of the full debug output of the swf (
swfmill -V swf2xml test.swf test.xml 2> db.txt)If there’s anything else I can do to help, let me know.
RP comments:
I forgot to mention that CS4 did properly account for the size of the name field in
DefineFont, setting it to size5, rather than size6.Screenshot of hex dumped files
Sorry for the multiple reports, but apparently even though CS4 did in fact report the correct length of the font name, it still appended an extra nul character just for fun. That's what it appears through the attached screenshot, the top file is the just published by me CS4 version reporting five characters and adds the
00before reporting theNumGlyphsas 16 bit.The bottom is the swfmill generated swf.
The only thing that I have noticed that this affects is the improper display in Flashdevelop, it doesn't appear to affect anything that I can tell.
Daniel Cassidy (that’s me) comments:
Confirmed in swfmill 0.3.0.
RP comments:
Patch to add support in DefineFont3 for Widemaps, zonealign reserved settings
Here’s a quick patch for a temp fix on the problem. Per Daniel [Turing] the WideMaps settings should be set automatically.
Daniel Cassidy comments:
In the next few days I will very belatedly release a new version of swfmill that correctly includes the
wideMapattribute in XML for bothDefineFont3andDefineFont2.I’m going to leave swfmill’s handling of reserved fields as it is (i.e. reserved fields will always get written with zeroes), unless there is some compelling reason to do otherwise (for example, if the SWF spec is wrong and Flash Player actually does something with those bits). However, swfmill should really warn if it reads a swf with non-zero reserved bits. I will add a bug to fix that.
I don’t see any reason why writing
ColorTransform2size as0should cause problems if neither offset nor factor are present, but I will change it if there is some compelling reason.In any case Flash Player has become more robust and the broken SWF doesn’t seem to crash it any more, even if it is incorrect.
I’m moving swfmill development to GitHub so the wideMap change is at https://github.com/djcsdy/swfmill