swftools-common
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Swftools-common] possible bug in lib/action/compile.c


From: Jason Christopher Reed
Subject: [Swftools-common] possible bug in lib/action/compile.c
Date: Fri, 24 Jul 2009 21:24:53 -0400 (EDT)

Executive summary: Under some circumstances I notice Jump actions being generated that jump incorrectly into the middle of a PushData action containing many individual pushes. Arguably this is a bug in bufferWriteDataAndPush and the various other bufferWrite* functions in compile.c, which very agressively coalesce all adjacent pushes together. Yet if I understand the SWF spec correctly, one cannot coalesce coalesce a push that is the target of a jump.

A minimal counterexampe .sc file is the following:

.flash filename="minimal.swf" bbox=500x200 version=8 background=white
.action:
function debug(txt) {
   debugTxt.text = debugTxt.text + "\n" + txt;
}
  this.createTextField("debugTxt", 1, 0, 0, 500, 200);
  debug("Text field created. The bug is a failure of any `xxx' to appear 
below.");
  debug(false ? "xxx" : "xxx");
  debug ("xxx");
.end
.end

It should (and after compiling the same actionscript with an old copy of Macromedia's Flash 8 I had lying around did) produce a text field with the text

Text field created. The bug is a failure of any `xxx' to appear below.
xxx
xxx

but in the most recent git checkout it produces only

Text field created. The bug is a failure of any `xxx' to appear below.

Using swfdump -a on swfc's output reveals that the line
    debug(false ? "xxx" : "xxx"); is being compiled into

...
(2 bytes) action: Push bool:false
(2 bytes) action: If 10
(2 bytes) action: Push Lookup:8 ("xxx")
(2 bytes) action: Jump 5
(9 bytes) action: Push Lookup:8 ("xxx") int:1 Lookup:7 ("debug")
(0 bytes) action: CallFunction
(0 bytes) action: Pop
(9 bytes) action: Push Lookup:8 ("xxx") int:1 Lookup:7 ("debug")
(0 bytes) action: CallFunction
(0 bytes) action: Pop
...

where the Jump 5 action is attempting to jump onto the sequence of bytes that start encoding the first push of the integer 1 onto the stack. This makes some kind of sense, because that's the next thing we want to do, namely push the number of arguments (having already pushed the argument "xxx"), and then call the function "debug". However, the action header the flash interpreter expects to be there is totally absent, and (I presume) it goes off into the weeds and fails to execute any of the following instructions.

I was able to fix the above counterexample by completely disabling all
coalescing of pushes

(replacing in compile.c occurrences of
b->buffer[0] == SWFACTION_PUSHDATA with 0 in  bufferWriteDataAndPush
out->pushloc == NULL               with 1 in  bufferWrite*)

but this seems very crude, and results in blatantly suboptimal generated code size.

---Jason




reply via email to

[Prev in Thread] Current Thread [Next in Thread]