I found some actionscript code like that:
var s:Sound = new Sound();
s.addEventListener(Event.COMPLETE, onSoundLoaded);
var req:URLRequest = new URLRequest(XX_EXTERNAL_URL);
s.load(req);
In which case the attacker can control the XX_EXTERNAL_URL, is that vulnerable?
Most likely it will just generate a sound conversion error or garbage sound, without any extra impact on SWF player or the system. One needs to have a bug in sound code that's causing a code injection or data corruption to make this attack successful. But, with predefined code of Sound object, it's either there or not, so it won't be more vulnerable if you load a Sound from elsewhere.
Related
First, I want to mention, I understand how the Firebase onDisconnect method works in JavaScript. It tells the server what to do once the user is disconnected, in advance.
Now, I am using AS3. How should I tell the server the same thing as achieved by the 'onDisconnect' method?
When I tried debugging the code in JavaScript, it doesn't seem to send something to the server.(or maybe i am wrong).
Sample code in JavaScript:
userRef.on('value', function(snapshot) {
if (snapshot.val()) {
userRef.onDisconnect().remove(); //this line does the magic
}
});
What is being done by the onDisconnect method which tells the server what to do? What is the equivalent code if written in AS3?
EDITED:
The code in AS3, as reference by here, it works for Realtime Database.
private var myStream:URLStream;
private function loadLiveFeed():void
{
var header:URLRequestHeader = new URLRequestHeader("Accept", "text/event-stream");
var request:URLRequest = new URLRequest("https://<YOUR-PROJECT-ID>.firebaseio.com/breakingnews.json");
request.requestHeaders.push(header);
myStream:URLStream = new URLStream();
myStream.addEventListener(ProgressEvent.PROGRESS, progress);
myStream.load(request);
}
private function progress(event:ProgressEvent):void
{
var message:String = myStream.readUTFBytes(myStream.bytesAvailable);
trace(message);
}
The code you shared accesses the Firebase Database through its REST API:
new URLRequest("https://<YOUR-PROJECT-ID>.firebaseio.com/breakingnews.json");
This means that it is using a connectionless method to interact with the database. Unfortunately that also means that there is no way to register an onDisconnect() handler, since it would essentially have to fire between any two HTTP calls that you make.
No time to answer this, but you'd have to reverse engineer the communication. Under the hood, it's all just HTTP (or similar) as can be seen in the As3 code. To know what's going on exactly, get a working example code in JavaScript that contains the magic line you are curious about, then execute it in the browser. All requests can be monitored in the developer tools of the browser. You should be able to identify what's being sent.
Also, it's JavaScript, which means you have to have the source code which you can simply read. It might be minified and/or obfuscated, but maybe you can find a readable one.
With the knowledge of what the bare requests look like, you can then implement an API of your own in any language that's capable of performing the necessary network communication.
I'm a c++ programmer who's been forced to do some tweaks to an existing AS3 game to use the kongregate api for monetization and whatnot.
I've had no big trouble with the AS3 syntax, but now in the kongregate docs it refers to "server-side" calls which use a strange http POST syntax. Something like this: http://developers.kongregate.com/docs/rest/use-item
Can anyone point me to what it's doing (not the actual effect, that's pretty well covered by the docs)? Is it using some other language? A part of AS3 that I don't know about (that doesn't look much like a high level OO language). And what does it mean server-side? How can I write server code for an app that I build into a SWF file and upload to the server?
I feel there is a big chunk of something I'm missing to be able to research what is going on, but everyone in the comments I've seen talks about "server-side" as a given, without giving me any pointers to the basics I should know to actually use it.
Thanks,
Jaime
My understanding is that the docs are showing you what the api is expecting (in terms of HTTP request) and it's up to you to implement it in Actionscript.
If that's the case, you could use the URLLoader class.
Basically, you'd do something like this:
var url:String = "http://www.kongregate.com/api/use_item.json";
var request:URLRequest = new URLRequest();
request.url = url;
request.method = URLRequestMethod.POST
request.data = new URLVariables();
request.data.api_key = "MyApiKey";
// etc...
var loader:URLLoader = new URLLoader();
loader.dataFormat = URLLoaderDataFormat.TEXT;
loader.addEventListener(Event.COMPLETE,handleComplete);
loader.load(request);
function handleComplete(e:Event):void {
var loader:URLLoader = e.currentTarget as URLLoader;
trace(loader.data); // a string containing the service response
}
You should also handle async errors (which I ommited in this sample). Another thing you should do is decode the JSON string into an Object to make working with the data easier. I suggest you google around for some library, there are a couple out there (off the top of my head, as3corelib, which was sponsered by adobe, had a JSON parser).
I have a preloader that loads a swf, the swf creates a bunch of listeners, objects, and movie clips. I want all of these to be destroyed and recreated.
Simplified version of my preloader:
var request:URLRequest = new URLRequest("myfile.swf");
var myLoader:Loader = new Loader();
var urlLoader:URLLoader = new URLLoader();
urlLoader.addEventListener(Event.COMPLETE, function(event){
stage.addChild(myLoader);
myLoader.loadBytes(urlLoader.data);
});
urlLoader.dataFormat = URLLoaderDataFormat.BINARY;
urlLoader.load(request);
When I try to remove it, I do this:
stage.removeChild(myLoader);
var child = loader.myLoader.content as Object;
SoundMixer.stopAll();
while(stage.numChildren > 0){
stage.removeChildAt(0);
}
child.stop();
while(stage.numChildren > 0){
stage.removeChildAt(0);
}
child=null;
System.gc();
myLoader.unloadAndStop(true);
System.gc();
myLoader.unload();
System.gc();
myLoader.loadBytes(urlLoader.data);
stage.addChild(loader.myLoader);
In your loaded SWF you may create a method 'destroy' which would remove all listeners, destroy all objects and reset all data.
You can call this method either from the parent object (if the method is public) or you can call destroy when you remove the SWF from stage (Event.REMOVED_FROM_STAGE)
You can reload swf with js, this is the easy way to do this. you can check this answer.
Or you have to do a good object and listener managment and reset game in swf file. This might be complex as project get bigger. You need release methods that removes all references and listener.
first you should load your swf using the Loader Class like this :
var movie:MovieClip
var loader:Loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, loadComplete);
loader.load( new URLRequest("myfile.swf"));
function loadComplete(event:Event):void
{
movie = loader.content as MovieCLip;
addChild(movie);
}
//when reloading just remove the movie object from the stage
removeChild(movie);
SoundMixer.stopAll();
//......
//.
//.
I know this is old, but I stumbled on it for reference and see some things that I think should be mentioned.
System.gc() - while it's a function you have access to, everything I've seen suggests that the garbage collector should never be called by your code unless you've used a considerable amount of memory and need it back immediately. The garbage collector usually has a better idea of when it should run than you do (Force Garbage Collection in AS3?). It can impact performance for not just your application but all flash applications running in that browser or container.
There's also a good bit of people struggling to make effective use of unloadAndStop(), as it seems to be rather unreliable in various contexts (Unloading swf using the unloadAndStop() method, but video sounds remain audible).
To be thorough, I'd strongly suggest putting the effort into simply eliminating everything as it would be in any other language from within the loaded flash object first before removing the flash object itself, not expecting the container to take care of it for you. This is why Flash has a reputation for memory leaks to begin with.
Inside the loaded swf, add code that fires on unload.
One way is to add this to the swf:
this.addEventListener(Event.REMOVED_FROM_STAGE, doUnload)
Then have the doUnload functon perform the following:
Use removeEventListener to effectively terminate the event handlers. You could either recall all the addEventListeners you created, or cook up a routine to walk through and remove them all by traversing the objects in play. The first option is more efficient since it's exclusive, but the second option would theoretically be something you could memorize and copy between applications.
Use delete() on variables to make them removable by the garbage collector. NOTE: Unlike many languages, a referenced variable will not be removable unless the reference is also removed. For example:
var a:int = 0;
var b:int = a;
delete(a); // b still exists and equals 0, a is not available to GC.
delete(b); // now both variables can be removed by GC.
There's also still confusion as to whether it's a good idea to use removeChildAt(0) or remove the child objects individually. The first has the benefit of being distinctly simple and straight-forward, but that also gives it the caveat of not being entirely understood by the coder, and possibly missing something similarly to unloadAndStop(). Not as much as walking your object tree with removeChild and eliminating things explicitly without question or uncertainty.
After this is set, adding a function to unload the flash object will trigger its self-removal, so the loader will remain simple and neat, and reload the flash cleanly.
I've done it this way, but Adobe Air hangs for several seconds.
private function test():void
{
fileStream = new FileStream();
fileStream.addEventListener(IOErrorEvent.IO_ERROR, fileError);
fileStream.addEventListener(Event.COMPLETE, opened);
fileStream.openAsync(filePath, FileMode.READ);
}
protected function opened(event:Event):void
{
var bytes:ByteArray = new ByteArray();
fileStream.readBytes(bytes);
fileStream.close();
// MD5Stream from package com.adobe.crypto.MD5Stream https://github.com/mikechambers/as3corelib/blob/master/src/com/adobe/crypto/MD5Stream.as
var md5stream:MD5Stream = new MD5Stream;
trace(md5stream.complete(bytes)); // md5
}
How to make the process of getting md5 without hanging?
Try using Bloody's MD5 implementation. It's apparently a lot faster.
While it will speed up the hash calculation, perhaps even adequately, you're not really solving the underlying problem, which is that you want a non-blocking operation in a single threaded application model. In Flash/AIR, this is generally done by breaking the work up into smaller chunks, and doing only one chunk's worth of processing each frame, instead of all at once during one frame. There's even a cool framework to simplify this!
I noticed that the library you're currently using, MD5Stream, is built for incremental updates -- so you can easily feed it little chunks of the file each frame until the entire file is processed. This will allow the frame rate to stay relatively constant while the hash is computed.
In Actionscript 3 / Flash 10, is it possible to programmatically reference a sound object that exists on the timeline? I've found lots of examples for referencing DisplayObjects via the following sytax:
var m:MovieClip = stage.getChildByName("SomeMovieClipClass");
var n:MovieClip = stage.getChildByIndex(1);
But this doesn't seem to include sound objects. Similarly, it seems straightforward to instantiate and play a sound that exists in the Library via Actionscript:
var s:SoundClip1 = new SoundClip1(); // exported in first frame via properties
s.play();
For my purposes, though, I'd like to reference sound clips (ideally in a specific layer, although that seems to be a design-time element) that designers have adjusted and arranged on the timeline, so that I can inspect their waveforms via code, at runtime. Something like this:
// Imaginary Code
sc = timeline.getSoundClipByName("SoundClip1");
sc.extract(waveform,sc.length/1000 * bitrate);
Is this possible? Thanks!
As of this date, no it is not possible to access the soundChannel generated by a timeline sound. It's a feature I would love to see implemented.
I was going to try to test the feasibility of using computeSpectrum to get the waveform of a timeline sound but I'm having problems importing mp3s right now. In absence of firsthand proof of concept, I searched around and found this thread:
http://www.kirupa.com/forum/showthread.php?t=329632
Which links to this solution
http://www.mail-archive.com/flashcoders#chattyfig.figleaf.com/msg43157.html
But of course this doesn't allow you to disambiguate between different timeline sounds. I'm pretty sure you won't be able to do that at all.
I have not ever used Sound.extract(), but if the sounds exist in the fla library this indicates to me that you can simply give them a Class name and at runtime use extract() to gather the waveform for your own purposes, yes? Then whenever the appropriate timeline sound plays, you can tap into the waveform from the Sound object. Perhaps a timeline callback or event would suffice for this?