From 76025fc10d402f09e82affba317f8810bcb34c1b Mon Sep 17 00:00:00 2001 From: Matthew McClure Date: Tue, 17 Mar 2015 11:21:36 -0700 Subject: [PATCH] hard coded callbacks to avoid XSS. Closes #142 --- src/VideoJS.as | 107 ++++++++++++++++++++++++++----------------------- 1 file changed, 57 insertions(+), 50 deletions(-) diff --git a/src/VideoJS.as b/src/VideoJS.as index ba160ca0..59c740e5 100644 --- a/src/VideoJS.as +++ b/src/VideoJS.as @@ -1,5 +1,5 @@ package{ - + import com.videojs.VideoJSApp; import com.videojs.events.VideoJSEvent; import com.videojs.structs.ExternalEventName; @@ -20,21 +20,21 @@ package{ import flash.utils.ByteArray; import flash.utils.Timer; import flash.utils.setTimeout; - + [SWF(backgroundColor="#000000", frameRate="60", width="480", height="270")] public class VideoJS extends Sprite{ public const VERSION:String = CONFIG::version; - + private var _app:VideoJSApp; private var _stageSizeTimer:Timer; - + public function VideoJS(){ _stageSizeTimer = new Timer(250); _stageSizeTimer.addEventListener(TimerEvent.TIMER, onStageSizeTimerTick); addEventListener(Event.ADDED_TO_STAGE, onAddedToStage); } - + private function init():void{ // Allow JS calls from other domains Security.allowDomain("*"); @@ -44,11 +44,11 @@ package{ // we'll want to suppress ANY uncaught debug errors in production (for the sake of ux) // IEventDispatcher(loaderInfo["uncaughtErrorEvents"]).addEventListener("uncaughtError", onUncaughtError); } - + if(ExternalInterface.available){ registerExternalMethods(); } - + _app = new VideoJSApp(); addChild(_app); @@ -64,9 +64,9 @@ package{ this.contextMenu = _ctxMenu; } - + private function registerExternalMethods():void{ - + try{ ExternalInterface.addCallback("vjs_appendBuffer", onAppendBufferCalled); ExternalInterface.addCallback("vjs_echo", onEchoCalled); @@ -94,39 +94,43 @@ package{ } } finally{} - - - + + + setTimeout(finish, 50); } - + private function finish():void{ - + if(loaderInfo.parameters.mode != undefined){ _app.model.mode = loaderInfo.parameters.mode; } - - if(loaderInfo.parameters.eventProxyFunction != undefined){ + + // Hard coding these in for now until we can come up with a better solution for 5.0 to avoid XSS. + _app.model.jsEventProxyName = 'videojs.Flash.onEvent'; + _app.model.jsErrorEventProxyName = 'videojs.Flash.onError'; + + /*if(loaderInfo.parameters.eventProxyFunction != undefined){ _app.model.jsEventProxyName = loaderInfo.parameters.eventProxyFunction; } - + if(loaderInfo.parameters.errorEventProxyFunction != undefined){ _app.model.jsErrorEventProxyName = loaderInfo.parameters.errorEventProxyFunction; - } - + }*/ + if(loaderInfo.parameters.autoplay != undefined && loaderInfo.parameters.autoplay == "true"){ _app.model.autoplay = true; } - + if(loaderInfo.parameters.preload === "none"){ _app.model.preload = false; } - + if(loaderInfo.parameters.poster != undefined && loaderInfo.parameters.poster != ""){ _app.model.poster = String(loaderInfo.parameters.poster); } - + if(loaderInfo.parameters.src != undefined && loaderInfo.parameters.src != ""){ if (isExternalMSObjectURL(loaderInfo.parameters.src)) { _app.model.srcFromFlashvars = null; @@ -143,19 +147,22 @@ package{ _app.model.rtmpStream = loaderInfo.parameters.rtmpStream; } } - - if(loaderInfo.parameters.readyFunction != undefined){ - try{ - ExternalInterface.call(_app.model.cleanEIString(loaderInfo.parameters.readyFunction), ExternalInterface.objectID); - } - catch(e:Error){ - if (loaderInfo.parameters.debug != undefined && loaderInfo.parameters.debug == "true") { - throw new Error(e.message); - } + + // Hard coding this in for now until we can come up with a better solution for 5.0 to avoid XSS. + ExternalInterface.call('videojs.Flash.onReady', ExternalInterface.objectID); + + /*if(loaderInfo.parameters.readyFunction != undefined){ + try{ + ExternalInterface.call(_app.model.cleanEIString(loaderInfo.parameters.readyFunction), ExternalInterface.objectID); + } + catch(e:Error){ + if (loaderInfo.parameters.debug != undefined && loaderInfo.parameters.debug == "true") { + throw new Error(e.message); } - } + } + }*/ } - + private function onAddedToStage(e:Event):void{ stage.addEventListener(MouseEvent.CLICK, onStageClick); stage.addEventListener(Event.RESIZE, onStageResize); @@ -163,7 +170,7 @@ package{ stage.align = StageAlign.TOP_LEFT; _stageSizeTimer.start(); } - + private function onStageSizeTimerTick(e:TimerEvent):void{ if(stage.stageWidth > 0 && stage.stageHeight > 0){ _stageSizeTimer.stop(); @@ -171,7 +178,7 @@ package{ init(); } } - + private function onStageResize(e:Event):void{ if(_app != null){ _app.model.stageRect = new Rectangle(0, 0, stage.stageWidth, stage.stageHeight); @@ -185,7 +192,7 @@ package{ // write the bytes to the provider _app.model.appendBuffer(bytes); } - + private function onEchoCalled(pResponse:* = null):*{ return pResponse; } @@ -197,7 +204,7 @@ package{ private function onAbortCalled():*{ _app.model.abort(); } - + private function onGetPropertyCalled(pPropertyName:String = ""):*{ switch(pPropertyName){ @@ -208,7 +215,7 @@ package{ case "loop": return _app.model.loop; case "preload": - return _app.model.preload; + return _app.model.preload; break; case "metadata": return _app.model.metadata; @@ -278,14 +285,14 @@ package{ break; case "rtmpConnection": return _app.model.rtmpConnectionURL; - break; + break; case "rtmpStream": return _app.model.rtmpStream; - break; + break; } return null; } - + private function onSetPropertyCalled(pPropertyName:String = "", pValue:* = null):void{ switch(pPropertyName){ case "duration": @@ -342,7 +349,7 @@ package{ break; } } - + private function onAutoplayCalled(pAutoplay:* = false):void{ _app.model.autoplay = _app.model.humanToBoolean(pAutoplay); } @@ -360,7 +367,7 @@ package{ } ExternalInterface.call('videojs.MediaSource.open', cleanSrc, ExternalInterface.objectID); } - + private function onSrcCalled(pSrc:* = ""):void{ // check if an external media source object will provide the video data if (isExternalMSObjectURL(pSrc)) { @@ -375,27 +382,27 @@ package{ _app.model.src = String(pSrc); } } - + private function onLoadCalled():void{ _app.model.load(); } - + private function onPlayCalled():void{ _app.model.play(); } - + private function onPauseCalled():void{ _app.model.pause(); } - + private function onResumeCalled():void{ _app.model.resume(); } - + private function onStopCalled():void{ _app.model.stop(); } - + private function onUncaughtError(e:Event):void{ e.preventDefault(); } @@ -403,6 +410,6 @@ package{ private function onStageClick(e:MouseEvent):void{ _app.model.broadcastEventExternally(ExternalEventName.ON_STAGE_CLICK); } - + } }