fix-polyfill WebRTC-events-when-proto-is-non-writable-but-configurable#1194
Conversation
|
so #1177 again... but the only usage affected should be shimSendThrowTypeError which is on its way out in M149? |
|
but the first should be inert due to in all browsers (since 2018 for Chrome). Firefox still seems to need the second shim but that is not polyfillable so inert too. Safari... hey @youennf, would you mind reducing the need for adapter? Gets you two points here |
|
Does checking |
Hi @fippo, no, you cannot get the addEventListener descriptor from RTCPeerConnection because that property is not in the RTCPeerConnection prototype, is inherit from EventTarget.
Direct assignment to RTCPeerConnection.prototype.addEventListener will fail because the inherited property is non-writable, while Object.defineProperty can still create a new own property on RTCPeerConnection.prototype with writeable and configurable as true. |

Summary
Fix
wrapPeerConnectionEventso it does not skip event polyfilling whenRTCPeerConnection.prototypeevent listener methods are non-writable but still configurable through Object.defineProperty.Background
I found this issue while testing a WebRTC application embedded in Wix.
The current implementation checks the descriptor of
EventTarget.prototype.addEventListener, but the polyfill actually patches methods onRTCPeerConnection.prototype:In some browsers or environments, these properties can behave as read-only, so direct assignment throws a
TypeError:The latest adapter version avoids the crash by checking whether
EventTarget.prototype.addEventListeneris writable before applying the polyfill. However, that check is not enough to determine whetherRTCPeerConnection.prototypecan actually be patched.This is a known issue that has been reported in other contexts as well:
Reproduction
This can be reproduced with this Wix test page:
By default, the page loads with the polyfill fix applied. To disable the fix and reproduce the original error, run this in the browser console:
Then reload the page. You will see the crash in the console.
Important: Because the test page uses an old version that does not have the
EventTarget.prototypedescriptor check, the issue was loud and visible. The latest version of adapter does not crash, but it also does not apply the polyfill.A minimal code example to illustrate the underlying JavaScript behavior:
However, even when a property is non-writable, it can still be redefined:
Root Cause
The old guard checked
EventTarget.prototype.addEventListener.writableglobally:The main issue is that the
EventTarget.prototype.addEventListeneris not writeable, cannot be assigned... but the targetRTCPeerConnection.prototypecan still define its ownaddEventListenerFix
Introduce
tryMakePropertyWritable, which attempts to redefine the target property as writable before applying the polyfill.Instead of relying on direct assignment, it uses
Object.defineProperty:If the property can be redefined, the helper returns
true. If the property is truly locked, it catches the error and returnsfalse.The polyfill now only proceeds when both required methods can be prepared:
This makes the check more accurate because it validates the actual prototype being patched.
Behavior Before
The polyfill could be skipped based on the descriptor of
EventTarget.prototype, even though the actual patch target wasRTCPeerConnection.prototype.Behavior After
The polyfill now checks whether the actual target can be patched before replacing the event listener methods.
Test Plan
Added unit tests for
wrapPeerConnectionEventcovering:Configurable properties
addEventListenerandremoveEventListenercan be redefined.Non-configurable properties