munge-dont.html (3035B)
1 <!doctype html> 2 <meta charset=utf-8> 3 <meta name="timeout" content="long"> 4 <title>SDP munging is a bad idea</title> 5 <script src="/resources/testharness.js"></script> 6 <script src="/resources/testharnessreport.js"></script> 7 <script> 8 'use strict'; 9 10 const sdp = `v=0 11 o=- 0 3 IN IP4 127.0.0.1 12 s=- 13 t=0 0 14 m=video 9 UDP/TLS/RTP/SAVPF 100 15 c=IN IP4 0.0.0.0 16 a=rtcp-mux 17 a=sendonly 18 a=mid:video 19 a=rtpmap:100 VP8/90000 20 a=fmtp:100 max-fr=30;max-fs=3600 21 a=fingerprint:sha-256 A7:24:72:CA:6E:02:55:39:BA:66:DF:6E:CC:4C:D8:B0:1A:BF:1A:56:65:7D:F4:03:AD:7E:77:43:2A:29:EC:93 22 a=ice-ufrag:ETEn 23 a=ice-pwd:OtSK0WpNtpUjkY4+86js7Z/l 24 `; 25 const candidateString = 'candidate:1905690388 1 udp 2113937151 192.168.0.1 58041 typ host generation 0 ufrag thC8'; 26 27 // See https://bugs.chromium.org/p/chromium/issues/detail?id=662898 28 // and https://bugs.chromium.org/p/chromium/issues/detail?id=823036 29 // for why neither of these is feasible to enforce. 30 31 // Note that this does not restrict creating a 32 // new RTCSessionDescription with a modified copy. 33 test(() => { 34 const desc = new RTCSessionDescription({ 35 type: 'offer', 36 sdp, 37 }); 38 assert_throws_js(TypeError, () => { 39 desc.type = 'answer'; 40 }); 41 }, 'RTCSessionDescription.type is read-only'); 42 43 test(() => { 44 const desc = new RTCSessionDescription({ 45 type: 'offer', 46 sdp, 47 }); 48 assert_throws_js(TypeError, () => { 49 desc.sdp += 'a=dont-modify-me\r\n'; 50 }); 51 }, 'RTCSessionDescription.sdp is read-only'); 52 53 test(() => { 54 const candidate = new RTCIceCandidate({ 55 sdpMid: '0', 56 candidate: candidateString, 57 }); 58 assert_throws_js(TypeError, () => { 59 candidate.candidate += ' myattribute value'; 60 }); 61 }, 'RTCIceCandidate.candidate is read-only'); 62 63 // https://w3c.github.io/webrtc-pc/#dom-peerconnection-setlocaldescription 64 // If type is "offer", and sdp is not the empty string and not equal to 65 // connection.[[LastCreatedOffer]], then return a promise rejected with a 66 // newly created InvalidModificationError and abort these steps. 67 promise_test(async t => { 68 const pc = new RTCPeerConnection(); 69 t.add_cleanup(() => pc.close()); 70 pc.addTransceiver('audio'); 71 const offer = await pc.createOffer(); 72 return promise_rejects_dom(t, 'InvalidModificationError', 73 pc.setLocalDescription({type: 'offer', sdp: offer.sdp + 'a=munging-is-not-good\r\n'})); 74 }, 'Rejects SDP munging between createOffer and setLocalDescription'); 75 76 // If type is "answer" or "pranswer", and sdp is not the empty string and not equal to 77 // connection.[[LastCreatedAnswer]], then return a promise rejected with a 78 // newly created InvalidModificationError and abort these steps. 79 promise_test(async t => { 80 const pc = new RTCPeerConnection(); 81 t.add_cleanup(() => pc.close()); 82 await pc.setRemoteDescription({type: 'offer', sdp}); 83 84 const answer = await pc.createAnswer(); 85 return promise_rejects_dom(t, 'InvalidModificationError', 86 pc.setLocalDescription({type: 'answer', sdp: answer.sdp + 'a=munging-is-not-good\r\n'})); 87 }, 'Rejects SDP munging between createAnswer and setLocalDescription'); 88 </script>