From 152598ae8511eafcd1534139aea320e0a8f5d7c4 Mon Sep 17 00:00:00 2001 From: Scott Andrews Date: Fri, 2 Sep 2016 10:07:08 -0700 Subject: [PATCH] Guard property access to __raven_wrapper__ Accessing the `__raven_wrapper__` property in Firefox 48 when run under Selenium results in the following error: Uncaught WebDriverError: Permission denied to access property "__raven_wrapper__" (WARNING: The server did not provide any stacktrace information) Command duration or timeout: 10 milliseconds Build info: version: '3.0.0-beta2', revision: '2aa21c1', time: '2016-08-02 15:03:28 -0700' System info: host: '199-7-164-50', ip: '199.7.164.50', os.name: 'windows', os.arch: 'x86', os.version: '6.2', java.version: '1.8.0_91' Driver info: org.openqa.selenium.firefox.FirefoxDriver Capabilities [{browserstack.localIdentifier=travis-3840.1, raisesAccessibilityExceptions=false, browserstack.tunnelIdentifier=travis-3840.1, browserstack.selenium.jar.version=3.0.0-beta2, appBuildId=20160726073904, platform=XP, specificationLevel=0, acceptSslCerts=false, browserstack.key=GpeJcf7DBqk3pHnB3PkZ, browser=firefox, browserVersion=48.0, platformVersion=6.2, acceptSslCert=false, XULappId={ec8030f7-c20a-464f-9b0e-13a3a9e97384}, browserName=Firefox, takesScreenshot=true, browser_version=48.0, platformName=Windows_NT, 64bit=true, browserstack.debug=false, rotatable=false, browserstack.ie.noFlash=false, browserstack.user=dhcole, version=48.0, proxy={}, command_id=1, firefox_binary=c:\Program Files (x86)\firefox 48.0\firefox.exe, browserstack.video=true, orig_os=win8, takesElementScreenshot=true, device=desktop, proxy_type=privoxy}] Session ID: 8ad81e9d-f345-48a9-b1fe-def338169a10 at WebDriverError (node_modules/selenium-webdriver/lib/error.js:27:10) at Object.checkLegacyResponse (node_modules/selenium-webdriver/lib/error.js:639:15) at parseHttpResponse (node_modules/selenium-webdriver/http/index.js:538:13) at node_modules/selenium-webdriver/http/index.js:472:11 at ManagedPromise.invokeCallback_ (node_modules/selenium-webdriver/lib/promise.js:1379:14) at TaskQueue.execute_ (node_modules/selenium-webdriver/lib/promise.js:2913:14) at TaskQueue.executeNext_ (node_modules/selenium-webdriver/lib/promise.js:2896:21) at node_modules/selenium-webdriver/lib/promise.js:2820:25 at node_modules/selenium-webdriver/lib/promise.js:639:7 From: Task: WebDriver.executeScript() at WebDriver.schedule (node_modules/selenium-webdriver/lib/webdriver.js:377:17) at WebDriver.executeScript (node_modules/selenium-webdriver/lib/webdriver.js:526:16) at WebDriver.driver.load (test/suites/selenium/_init.js:180:14) at test/suites/selenium/_init.js:100:14 at initDriver (test/suites/selenium/_init.js:192:5) at test/suites/selenium/_init.js:147:9 at node_modules/browserstack-local/lib/Local.js:46:11 at ChildProcess.exithandler (child_process.js:204:7) at maybeClose (internal/child_process.js:829:16) at Process.ChildProcess._handle.onexit (internal/child_process.js:211:5) By wrapping the access, we can avoid the error. Relates to #495 --- src/raven.js | 18 +++++++++++------- test/raven.test.js | 13 +++++++++++++ 2 files changed, 24 insertions(+), 7 deletions(-) diff --git a/src/raven.js b/src/raven.js index 8e818c76719f..892461e61255 100644 --- a/src/raven.js +++ b/src/raven.js @@ -258,18 +258,18 @@ Raven.prototype = { if (func.__raven__) { return func; } + + // If this has already been wrapped in the past, return that + if (func.__raven_wrapper__ ){ + return func.__raven_wrapper__ ; + } } catch (e) { - // Just accessing the __raven__ prop in some Selenium environments + // Just accessing custom props in some Selenium environments // can cause a "Permission denied" exception (see raven-js#495). // Bail on wrapping and return the function as-is (defers to window.onerror). return func; } - // If this has already been wrapped in the past, return that - if (func.__raven_wrapper__ ){ - return func.__raven_wrapper__ ; - } - function wrapped() { var args = [], i = arguments.length, deep = !options || options && options.deep !== false; @@ -864,7 +864,11 @@ Raven.prototype = { }, wrappedBuiltIns); fill(proto, 'removeEventListener', function (orig) { return function (evt, fn, capture, secure) { - fn = fn && (fn.__raven_wrapper__ ? fn.__raven_wrapper__ : fn); + try { + fn = fn && (fn.__raven_wrapper__ ? fn.__raven_wrapper__ : fn); + } catch (e) { + // ignore, accessing __raven_wrapper__ will throw in some Selenium environments + } return orig.call(this, evt, fn, capture, secure); }; }, wrappedBuiltIns); diff --git a/test/raven.test.js b/test/raven.test.js index 3881e433e1de..f5c1cc573bfc 100644 --- a/test/raven.test.js +++ b/test/raven.test.js @@ -1735,6 +1735,19 @@ describe('Raven (public API)', function() { assert.equal(fn, wrapped); }); + it('should return input funciton as-is if accessing __raven_wrapper__ prop throws exception', function (){ + // see raven-js#495 + var fn = function () {}; + Object.defineProperty(fn, '__raven_wrapper__', { + get: function () { + throw new Error('Permission denied') + } + }); + assert.throw(function () { fn.__raven_wrapper__; }, 'Permission denied'); + var wrapped = Raven.wrap(fn); + assert.equal(fn, wrapped); + }); + }); describe('.context', function() {