Bug 414512

Summary: Firefox KDE Plasma Integration sets window.Audio.prototype to undefined
Product: [Plasma] plasma-browser-integration Reporter: Craig Leinoff <craig.leinoff>
Component: FirefoxAssignee: Kai Uwe Broulik <kde>
Status: RESOLVED FIXED    
Severity: normal CC: bugs.kde.org.facelift226, simon
Priority: HI    
Version First Reported In: unspecified   
Target Milestone: ---   
Platform: Manjaro   
OS: Linux   
Latest Commit: Version Fixed In:
Sentry Crash Report:

Description Craig Leinoff 2019-11-25 22:25:13 UTC
SUMMARY


STEPS TO REPRODUCE
1. Install "Plasma Integration" Firefox extension.
2. Open any tab and go to a website (e.g. browse somewhere that isn't the default Firefox "New Tab" page)
3. Open console.
4. Type `window.Audio.prototype` (or even just `Audio.prototype`) and hit enter.

OBSERVED RESULT
Firefox console will report `undefined` as the value. Things relying on checking the prototype of the Audio  class (such as Twilio's JavaScript client) will not work.

EXPECTED RESULT
Firefox console should report the `HTMLAudioElementPrototype` class as its value.


SOFTWARE/OS VERSIONS
Extension version 1.6.1

ADDITIONAL INFORMATION
When redefining something with a proxy, the developer should inject the original proxy. (Presumably this is the issue.)
Comment 1 Kai Uwe Broulik 2019-11-25 22:30:29 UTC
Can you check wheter this [1] helps? What kind of issues does this cause?
If you know how to fix it I'd be grateful, I am somewhat lost in this HTML JavaScript mess.

[1] https://cgit.kde.org/plasma-browser-integration.git/commit/?id=c1d7ea7346074e1912d56b9aed8d5ec47957e3a2
Comment 2 Kai Uwe Broulik 2019-11-25 22:33:25 UTC
Would a "window.Audio.prototype = oldAudio.prototype" call fix this?
Comment 3 Craig Leinoff 2019-11-26 15:58:25 UTC
Hello! Thanks for the quick reply and I apologize for my own delay.

I am not 100% positive -- but am pretty confident that this (the solution you identified) might actually be all you need to do! :)
Comment 4 Synthetic451 2020-03-12 00:02:38 UTC
I believe this is also what's causing PlayCanvas WebGL apps to fail in Firefox.

Here are some test cases:
https://robostorm.io/
https://playcanv.as/p/44MRmJRU/

Disabling the addon makes the above sites work.
Comment 5 Kai Uwe Broulik 2020-03-12 07:50:32 UTC
The issue is that with Firefox I can't manipulate the JS environment directly, so I have to override window Audio from what I can tell. In Chrome playcanvas works because here I can manipulate the prototype.

Thanks for showing me a website that actually excerts the bug in Firefox :) This should make fixing it a lot easier.
Comment 6 Kai Uwe Broulik 2020-04-09 16:32:25 UTC
At last I found a solution for the problem!
If you could try https://phabricator.kde.org/D28706 this would be highly appreciated
Comment 7 Synthetic451 2020-04-10 18:41:09 UTC
Thanks for working on this! What's the easiest way to test this out? Is there a prebuilt package somewhere or can I get the old extension and replace that file in there?
Comment 8 Kai Uwe Broulik 2020-04-10 18:45:41 UTC
Pretty much just clone https://cgit.kde.org/plasma-browser-integration.git/, apply the patch (we tried a different approach from the one I linked here but it didn't work out). Then in Firefox go to about:debugging → "this firefox" and "temporarily load" the extension folder in the repo you just cloned. There's some more guides on our wiki: https://community.kde.org/Plasma/Browser_Integration
Comment 9 Kai Uwe Broulik 2020-04-14 09:20:21 UTC
Git commit 08468773f1fefecbe27bab89e64f8df80254315a by Kai Uwe Broulik.
Committed on 14/04/2020 at 09:19.
Pushed by broulik into branch 'master'.

Restore old Audio prototype after exportFunction

exportFunction doesn't carry over a prototype, nor can I assign a non-function with it afterwards.
However, Firefox exports the "unsafe" stuff in wrappedJSObject, so I can actually get the original untrusted prototype,
exportFunction my new function, and then set it back.

I can't just use the prototype in content-script since it wouldn't be accessible from the webpage.
Interestingly enough, I have to use window.Audio rather than window.wrappedJSObject.Audio for creating the player as the
wrapped one doesn't appear to be working when used from this function. This one then still passes onto the website like
normal and plays sound.

Differential Revision: https://phabricator.kde.org/D28706

M  +13   -3    extension/content-script.js

https://commits.kde.org/plasma-browser-integration/08468773f1fefecbe27bab89e64f8df80254315a