Changeset 225963 in webkit


Ignore:
Timestamp:
Dec 14, 2017 9:32:53 PM (6 years ago)
Author:
commit-queue@webkit.org
Message:

Implement <iframe allow="camera; microphone">
https://bugs.webkit.org/show_bug.cgi?id=167430
LayoutTests/imported/w3c:

Patch by Youenn Fablet <youenn@apple.com> on 2017-12-14
Reviewed by Eric Carlson.

  • resources/import-expectations.json:
  • web-platform-tests/feature-policy/resources/: Added as this is used for some mediacapture-streams tests.
  • web-platform-tests/mediacapture-streams/: Added.

Source/WebCore:

Patch by Youenn Fablet <youenn@apple.com> on 2017-12-14
Reviewed by Eric Carlson.

Tests: imported/w3c/web-platform-tests/mediacapture-streams/MediaStream-default-feature-policy.https.sub.html

Adding allow attribute to HTMLIFrameElement as per https://wicg.github.io/feature-policy/#iframe-allow-attribute.
Cross-origin iframes will get access to camera/microphone based on this attribute value.
Same-origin iframes do not need any attribute.
In case getUserMedia requests both camera and microphone, and allow attribute is only one of these,
getUserMedia access is denied. This goes against the tests but is not very clear from the specification.

  • Modules/mediastream/UserMediaRequest.cpp:

(WebCore::isSecure):
(WebCore::isAllowedToUse):
(WebCore::canCallGetUserMedia):
(WebCore::UserMediaRequest::start):

  • html/HTMLAttributeNames.in:
  • html/HTMLIFrameElement.cpp:

(WebCore::HTMLIFrameElement::parseAttribute):

  • html/HTMLIFrameElement.h:
  • html/HTMLIFrameElement.idl:

LayoutTests:

<rdar://problem/34887226>

Patch by Youenn Fablet <youenn@apple.com> on 2017-12-14
Reviewed by Eric Carlson.

Skipping mediastream tests for wpe.
Updating expectations based on new error message.

  • TestExpectations: Skipping sync XHR test using allow attribute.
  • http/tests/ssl/media-stream/get-user-media-different-host-expected.txt:
  • http/tests/ssl/media-stream/get-user-media-nested-expected.txt:
  • platform/mac-wk1/imported/w3c/web-platform-tests/XMLHttpRequest/xmlhttprequest-sync-default-feature-policy.sub-expected.txt:
  • platform/wpe/TestExpectations:
Location:
trunk
Files:
23 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r225960 r225963  
     12017-12-14  Youenn Fablet  <youenn@apple.com>
     2
     3        Implement <iframe allow="camera; microphone">
     4        https://bugs.webkit.org/show_bug.cgi?id=167430
     5        <rdar://problem/34887226>
     6
     7        Reviewed by Eric Carlson.
     8
     9        Skipping mediastream tests for wpe.
     10        Updating expectations based on new error message.
     11
     12        * TestExpectations: Skipping sync XHR test using allow attribute.
     13        * http/tests/ssl/media-stream/get-user-media-different-host-expected.txt:
     14        * http/tests/ssl/media-stream/get-user-media-nested-expected.txt:
     15        * platform/mac-wk1/imported/w3c/web-platform-tests/XMLHttpRequest/xmlhttprequest-sync-default-feature-policy.sub-expected.txt:
     16        * platform/wpe/TestExpectations:
     17
    1182017-12-14  Zalan Bujtas  <zalan@apple.com>
    219
  • trunk/LayoutTests/TestExpectations

    r225909 r225963  
    223223
    224224imported/w3c/web-platform-tests/2dcontext/transformations/canvas_transformations_reset_001.html [ ImageOnlyFailure ]
     225imported/w3c/web-platform-tests/XMLHttpRequest/xmlhttprequest-sync-default-feature-policy.sub.html [ Skip ]
    225226webkit.org/b/179607 imported/w3c/web-platform-tests/XMLHttpRequest/access-control-and-redirects-async.htm [ Pass Failure ]
    226227webkit.org/b/179607 imported/w3c/web-platform-tests/XMLHttpRequest/access-control-and-redirects-async-same-origin.htm [ Pass Failure ]
  • trunk/LayoutTests/http/tests/ssl/media-stream/get-user-media-different-host-expected.txt

    r219663 r225963  
    1 CONSOLE MESSAGE: line 52: Trying to call getUserMedia from a document with a different security origin than its top-level frame.
     1CONSOLE MESSAGE: line 52: The top-level frame has prevented a document with a different security origin to call getUserMedia.
    22Tests that getUserMedia fails when the top level document and iframe do not have the same domain.
    33
  • trunk/LayoutTests/http/tests/ssl/media-stream/get-user-media-nested-expected.txt

    r219663 r225963  
    1 CONSOLE MESSAGE: line 52: Trying to call getUserMedia from a document with a different security origin than its top-level frame.
     1CONSOLE MESSAGE: line 52: The top-level frame has prevented a document with a different security origin to call getUserMedia.
    22Tests that getUserMedia fails when the top level document and iframe do not have the same domain.
    33
  • trunk/LayoutTests/imported/w3c/ChangeLog

    r225961 r225963  
     12017-12-14  Youenn Fablet  <youenn@apple.com>
     2
     3        Implement <iframe allow="camera; microphone">
     4        https://bugs.webkit.org/show_bug.cgi?id=167430
     5
     6        Reviewed by Eric Carlson.
     7
     8        * resources/import-expectations.json:
     9        * web-platform-tests/feature-policy/resources/: Added as this is used for some mediacapture-streams tests.
     10        * web-platform-tests/mediacapture-streams/: Added.
     11
    1122017-12-14  Chris Dumez  <cdumez@apple.com>
    213
  • trunk/LayoutTests/imported/w3c/resources/import-expectations.json

    r225593 r225963  
    135135    "web-platform-tests/feature-policy": "skip",
    136136    "web-platform-tests/feature-policy/resources": "import",
     137    "web-platform-tests/feature-policy/resources/": "import",
    137138    "web-platform-tests/fetch": "import",
    138139    "web-platform-tests/fullscreen": "skip",
  • trunk/LayoutTests/imported/w3c/web-platform-tests/XMLHttpRequest/xmlhttprequest-sync-default-feature-policy.sub-expected.txt

    r224156 r225963  
     1Blocked access to external URL http://www.localhost:8800/XMLHttpRequest/xmlhttprequest-sync-default-feature-policy.sub.html#iframe#sync-xhr
    12Blocked access to external URL http://www.localhost:8800/XMLHttpRequest/xmlhttprequest-sync-default-feature-policy.sub.html#iframe#sync-xhr
    23
     
    78PASS Default "sync-xhr" feature policy ["*"] allows same-origin iframes.
    89TIMEOUT Default "sync-xhr" feature policy ["*"] allows cross-origin iframes. Test timed out
    9 FAIL Feature policy "sync-xhr" can be disabled in cross-origin iframes using "allow" attribute. undefined is not an object (evaluating 'frame.allow.concat')
     10TIMEOUT Feature policy "sync-xhr" can be disabled in cross-origin iframes using "allow" attribute. Test timed out
    1011
  • trunk/LayoutTests/imported/w3c/web-platform-tests/feature-policy/resources/featurepolicy.js

    r224156 r225963  
    8282    feature_promise_factory().then(
    8383        () => window.parent.postMessage('#OK', '*'),
    84         (e) => window.parent.postMessage('#' + e.toString(), '*'));
     84        (e) => window.parent.postMessage('#' + e.name, '*'));
    8585  }
    8686}
  • trunk/LayoutTests/imported/w3c/web-platform-tests/feature-policy/resources/w3c-import.log

    r223189 r225963  
    1515------------------------------------------------------------------------
    1616List of files:
     17/LayoutTests/imported/w3c/web-platform-tests/feature-policy/resources/autoplay.js
     18/LayoutTests/imported/w3c/web-platform-tests/feature-policy/resources/feature-policy-autoplay.html
     19/LayoutTests/imported/w3c/web-platform-tests/feature-policy/resources/feature-policy-generic-sensor.html
    1720/LayoutTests/imported/w3c/web-platform-tests/feature-policy/resources/feature-policy-payment.html
    1821/LayoutTests/imported/w3c/web-platform-tests/feature-policy/resources/feature-policy-usb.html
     22/LayoutTests/imported/w3c/web-platform-tests/feature-policy/resources/feature-policy-wakelock.html
    1923/LayoutTests/imported/w3c/web-platform-tests/feature-policy/resources/feature-policy-webvr.html
    2024/LayoutTests/imported/w3c/web-platform-tests/feature-policy/resources/featurepolicy.js
  • trunk/LayoutTests/imported/w3c/web-platform-tests/mediacapture-streams/MediaStream-default-feature-policy.https-expected.txt

    r224156 r225963  
    1 CONSOLE MESSAGE: line 1: Trying to call getUserMedia from a document with a different security origin than its top-level frame.
    2 CONSOLE MESSAGE: line 1: Trying to call getUserMedia from a document with a different security origin than its top-level frame.
    3 CONSOLE MESSAGE: line 1: Trying to call getUserMedia from a document with a different security origin than its top-level frame.
    4 CONSOLE MESSAGE: line 1: Trying to call getUserMedia from a document with a different security origin than its top-level frame.
    5 CONSOLE MESSAGE: line 1: Trying to call getUserMedia from a document with a different security origin than its top-level frame.
     1CONSOLE MESSAGE: line 1: The top-level frame has prevented a document with a different security origin to call getUserMedia.
     2CONSOLE MESSAGE: line 1: The top-level frame has prevented a document with a different security origin to call getUserMedia.
     3CONSOLE MESSAGE: line 1: The top-level frame has prevented a document with a different security origin to call getUserMedia.
     4CONSOLE MESSAGE: line 1: The top-level frame has prevented a document with a different security origin to call getUserMedia.
     5CONSOLE MESSAGE: line 1: The top-level frame has prevented a document with a different security origin to call getUserMedia.
     6CONSOLE MESSAGE: line 1: The top-level frame has prevented a document with a different security origin to call getUserMedia.
     7CONSOLE MESSAGE: line 1: The top-level frame has prevented a document with a different security origin to call getUserMedia.
    68
    79
    810PASS Default "microphone" feature policy ["self"] allows the top-level document.
    911PASS Default "microphone" feature policy ["self"] allows same-origin iframes.
    10 FAIL Default "microphone" feature policy ["self"] disallows cross-origin iframes. assert_equals: expected "#[object NavigatorUserMediaError]" but got "#NotAllowedError: The request is not allowed by the user agent or the platform in the current context, possibly because the user denied permission."
    11 FAIL Feature policy "microphone" can be enabled in cross-origin iframes using "allow" attribute. undefined is not an object (evaluating 'frame.allow.concat')
     12PASS Default "microphone" feature policy ["self"] disallows cross-origin iframes.
     13FAIL Feature policy "microphone" can be enabled in cross-origin iframes using "allow" attribute. assert_equals: expected "#OK" but got "#NotAllowedError"
    1214PASS Default "camera" feature policy ["self"] allows the top-level document.
    1315PASS Default "camera" feature policy ["self"] allows same-origin iframes.
    14 FAIL Default "camera" feature policy ["self"] disallows cross-origin iframes. assert_equals: expected "#[object NavigatorUserMediaError]" but got "#NotAllowedError: The request is not allowed by the user agent or the platform in the current context, possibly because the user denied permission."
    15 FAIL Feature policy "camera" can be enabled in cross-origin iframes using "allow" attribute. undefined is not an object (evaluating 'frame.allow.concat')
     16PASS Default "camera" feature policy ["self"] disallows cross-origin iframes.
     17FAIL Feature policy "camera" can be enabled in cross-origin iframes using "allow" attribute. assert_equals: expected "#OK" but got "#NotAllowedError"
    1618PASS Default "camera; microphone" feature policy ["self"] allows the top-level document.
    1719PASS Default "camera; microphone" feature policy ["self"] allows same-origin iframes.
    18 FAIL Default "camera; microphone" feature policy ["self"] disallows cross-origin iframes. assert_equals: expected "#[object NavigatorUserMediaError]" but got "#NotAllowedError: The request is not allowed by the user agent or the platform in the current context, possibly because the user denied permission."
    19 FAIL Feature policy "camera; microphone" can be enabled in cross-origin iframes using "allow" attribute. undefined is not an object (evaluating 'frame.allow.concat')
     20PASS Default "camera; microphone" feature policy ["self"] disallows cross-origin iframes.
     21PASS Feature policy "camera; microphone" can be enabled in cross-origin iframes using "allow" attribute.
    2022
  • trunk/LayoutTests/imported/w3c/web-platform-tests/mediacapture-streams/MediaStream-default-feature-policy.https.html

    r224156 r225963  
    3838      cross_domain,
    3939      'microphone',
    40       '[object NavigatorUserMediaError]',
     40      'NotAllowedError',
    4141      function() {
    4242        return promise_factory('microphone');
     
    4646      cross_domain,
    4747      'camera',
    48       '[object NavigatorUserMediaError]',
     48      'NotAllowedError',
    4949      function() {
    5050        return promise_factory('camera');
     
    5454    cross_domain,
    5555    'camera; microphone',
    56     '[object NavigatorUserMediaError]',
     56    'NotAllowedError',
    5757    function() {
    5858      return promise_factory('camera; microphone');
  • trunk/LayoutTests/imported/w3c/web-platform-tests/mediacapture-streams/MediaStreamTrack-init.https-expected.txt

    r223189 r225963  
    66
    77
    8 PASS Tests that the video MediaStreamTrack objects are properly initialized
    9 PASS EventTarget interface: existence and properties of interface object
    10 PASS EventTarget interface object length
    11 PASS EventTarget interface object name
    12 PASS EventTarget interface: existence and properties of interface prototype object
    13 PASS EventTarget interface: existence and properties of interface prototype object's "constructor" property
    14 PASS EventTarget interface: operation addEventListener(DOMString, EventListener, boolean)
    15 PASS EventTarget interface: operation removeEventListener(DOMString, EventListener, boolean)
    16 PASS EventTarget interface: operation dispatchEvent(Event)
    17 PASS MediaStreamTrack interface: existence and properties of interface object
    18 PASS MediaStreamTrack interface object length
    19 PASS MediaStreamTrack interface object name
    20 PASS MediaStreamTrack interface: existence and properties of interface prototype object
    21 PASS MediaStreamTrack interface: existence and properties of interface prototype object's "constructor" property
    22 PASS MediaStreamTrack interface: attribute kind
    23 PASS MediaStreamTrack interface: attribute id
    24 PASS MediaStreamTrack interface: attribute label
    25 PASS MediaStreamTrack interface: attribute enabled
    26 PASS MediaStreamTrack interface: attribute muted
    27 PASS MediaStreamTrack interface: attribute onmute
    28 PASS MediaStreamTrack interface: attribute onunmute
    29 PASS MediaStreamTrack interface: attribute readyState
    30 PASS MediaStreamTrack interface: attribute onended
    31 PASS MediaStreamTrack interface: attribute onoverconstrained
    32 PASS MediaStreamTrack interface: operation clone()
    33 PASS MediaStreamTrack interface: operation stop()
    34 PASS MediaStreamTrack interface: operation getCapabilities()
    35 PASS MediaStreamTrack interface: operation getConstraints()
    36 PASS MediaStreamTrack interface: operation getSettings()
    37 PASS MediaStreamTrack interface: operation applyConstraints(MediaTrackConstraints)
    38 PASS MediaStreamTrack must be primary interface of track
    39 PASS Stringification of track
    40 PASS MediaStreamTrack interface: track must inherit property "kind" with the proper type
    41 PASS MediaStreamTrack interface: track must inherit property "id" with the proper type
    42 PASS MediaStreamTrack interface: track must inherit property "label" with the proper type
    43 PASS MediaStreamTrack interface: track must inherit property "enabled" with the proper type
    44 PASS MediaStreamTrack interface: track must inherit property "muted" with the proper type
    45 FAIL MediaStreamTrack interface: track must inherit property "onmute" with the proper type Unrecognized type EventHandler
    46 FAIL MediaStreamTrack interface: track must inherit property "onunmute" with the proper type Unrecognized type EventHandler
    47 FAIL MediaStreamTrack interface: track must inherit property "readyState" with the proper type Unrecognized type MediaStreamTrackState
    48 FAIL MediaStreamTrack interface: track must inherit property "onended" with the proper type Unrecognized type EventHandler
    49 FAIL MediaStreamTrack interface: track must inherit property "onoverconstrained" with the proper type Unrecognized type EventHandler
    50 PASS MediaStreamTrack interface: track must inherit property "clone()" with the proper type
    51 PASS MediaStreamTrack interface: track must inherit property "stop()" with the proper type
    52 PASS MediaStreamTrack interface: track must inherit property "getCapabilities()" with the proper type
    53 PASS MediaStreamTrack interface: track must inherit property "getConstraints()" with the proper type
    54 PASS MediaStreamTrack interface: track must inherit property "getSettings()" with the proper type
    55 PASS MediaStreamTrack interface: track must inherit property "applyConstraints(MediaTrackConstraints)" with the proper type
    56 PASS MediaStreamTrack interface: calling applyConstraints(MediaTrackConstraints) on track with too few arguments must throw TypeError
    57 PASS EventTarget interface: track must inherit property "addEventListener(DOMString, EventListener, boolean)" with the proper type
    58 PASS EventTarget interface: calling addEventListener(DOMString, EventListener, boolean) on track with too few arguments must throw TypeError
    59 PASS EventTarget interface: track must inherit property "removeEventListener(DOMString, EventListener, boolean)" with the proper type
    60 PASS EventTarget interface: calling removeEventListener(DOMString, EventListener, boolean) on track with too few arguments must throw TypeError
    61 PASS EventTarget interface: track must inherit property "dispatchEvent(Event)" with the proper type
    62 PASS EventTarget interface: calling dispatchEvent(Event) on track with too few arguments must throw TypeError
     8PASS getUserMedia({video:true}) creates a stream with a properly initialized video track
    639
  • trunk/LayoutTests/imported/w3c/web-platform-tests/mediacapture-streams/MediaStreamTrack-init.https.html

    r223189 r225963  
    1919<script src=/resources/testharness.js></script>
    2020<script src=/resources/testharnessreport.js></script>
    21 <script src=/resources/WebIDLParser.js></script>
    22 <script src=/resources/idlharness.js></script>
    2321<script>
    24 var t = async_test("Tests that the video MediaStreamTrack objects are properly initialized", {timeout:10000});
    25 var track = null
    26 var idl_array = new IdlArray();
    27 
    28 idl_array.add_idls("interface EventTarget {\
    29   void addEventListener(DOMString type, EventListener? callback, optional boolean capture = false);\
    30   void removeEventListener(DOMString type, EventListener? callback, optional boolean capture = false);\
    31   boolean dispatchEvent(Event event);\
    32 };");
    33 
    34 idl_array.add_idls("interface MediaStreamTrack : EventTarget {\
    35     readonly    attribute DOMString             kind;\
    36     readonly    attribute DOMString             id;\
    37     readonly    attribute DOMString             label;\
    38                 attribute boolean               enabled;\
    39     readonly    attribute boolean               muted;\
    40                 attribute EventHandler          onmute;\
    41                 attribute EventHandler          onunmute;\
    42     readonly    attribute MediaStreamTrackState readyState;\
    43                 attribute EventHandler          onended;\
    44                 attribute EventHandler          onoverconstrained;\
    45     MediaStreamTrack       clone ();\
    46     void                   stop ();\
    47     MediaTrackCapabilities getCapabilities ();\
    48     MediaTrackConstraints  getConstraints ();\
    49     MediaTrackSettings     getSettings ();\
    50     Promise<void>          applyConstraints (optional MediaTrackConstraints constraints);\
    51 };");
    52 
    53 t.step(function () {
    54   navigator.mediaDevices.getUserMedia({video: true})
    55     .then(t.step_func(function (stream) {
     22promise_test(() => {
     23  return navigator.mediaDevices.getUserMedia({video: true})
     24    .then(stream => {
    5625      var videoTracks = stream.getVideoTracks();
    5726      assert_equals(videoTracks.length, 1, "There is exactly one video track in the media stream");
    5827      track = videoTracks[0];
    59       idl_array.add_objects({MediaStreamTrack: ["track"]});
    60       idl_array.test();
    6128      assert_equals(track.readyState, "live", "The track object is in live state");
    6229      assert_equals(track.kind, "video", "The track object is of video kind");
     
    6431      // see https://www.w3.org/Bugs/Public/show_bug.cgi?id=22212
    6532      assert_true(track.enabled, "The track object is enabed");
    66       t.done();
    67     }));
     33    });
    6834});
    6935</script>
  • trunk/LayoutTests/imported/w3c/web-platform-tests/mediacapture-streams/OWNERS

    r224156 r225963  
    22@alvestrand
    33@dontcallmedom
     4@eric-carlson
    45@youennf
  • trunk/LayoutTests/imported/w3c/web-platform-tests/mediacapture-streams/w3c-import.log

    r224156 r225963  
    4242/LayoutTests/imported/w3c/web-platform-tests/mediacapture-streams/MediaStreamTrack-getSettings.https.html
    4343/LayoutTests/imported/w3c/web-platform-tests/mediacapture-streams/MediaStreamTrack-id.https.html
     44/LayoutTests/imported/w3c/web-platform-tests/mediacapture-streams/MediaStreamTrack-idl.https.html
    4445/LayoutTests/imported/w3c/web-platform-tests/mediacapture-streams/MediaStreamTrack-init.https.html
    4546/LayoutTests/imported/w3c/web-platform-tests/mediacapture-streams/MediaStreamTrackEvent-constructor.https.html
  • trunk/LayoutTests/platform/mac-wk1/imported/w3c/web-platform-tests/XMLHttpRequest/xmlhttprequest-sync-default-feature-policy.sub-expected.txt

    r224156 r225963  
     1Blocked access to external URL http://www.localhost:8800/XMLHttpRequest/xmlhttprequest-sync-default-feature-policy.sub.html#iframe%23sync-xhr
    12Blocked access to external URL http://www.localhost:8800/XMLHttpRequest/xmlhttprequest-sync-default-feature-policy.sub.html#iframe%23sync-xhr
    23
     
    78PASS Default "sync-xhr" feature policy ["*"] allows same-origin iframes.
    89TIMEOUT Default "sync-xhr" feature policy ["*"] allows cross-origin iframes. Test timed out
    9 FAIL Feature policy "sync-xhr" can be disabled in cross-origin iframes using "allow" attribute. undefined is not an object (evaluating 'frame.allow.concat')
     10TIMEOUT Feature policy "sync-xhr" can be disabled in cross-origin iframes using "allow" attribute. Test timed out
    1011
  • trunk/LayoutTests/platform/wpe/TestExpectations

    r225899 r225963  
    425425Bug(WPE) fast/mediacapturefromelement [ Skip ]
    426426Bug(WPE) fast/mediastream [ Skip ]
     427imported/w3c/web-platform-tests/mediacapture-streams [ Skip ]
    427428Bug(WPE) fast/multicol [ Skip ]
    428429Bug(WPE) fast/overflow [ Skip ]
  • trunk/Source/WebCore/ChangeLog

    r225960 r225963  
     12017-12-14  Youenn Fablet  <youenn@apple.com>
     2
     3        Implement <iframe allow="camera; microphone">
     4        https://bugs.webkit.org/show_bug.cgi?id=167430
     5
     6        Reviewed by Eric Carlson.
     7
     8        Tests: imported/w3c/web-platform-tests/mediacapture-streams/MediaStream-default-feature-policy.https.sub.html
     9
     10        Adding allow attribute to HTMLIFrameElement as per https://wicg.github.io/feature-policy/#iframe-allow-attribute.
     11        Cross-origin iframes will get access to camera/microphone based on this attribute value.
     12        Same-origin iframes do not need any attribute.
     13        In case getUserMedia requests both camera and microphone, and allow attribute is only one of these,
     14        getUserMedia access is denied. This goes against the tests but is not very clear from the specification.
     15
     16        * Modules/mediastream/UserMediaRequest.cpp:
     17        (WebCore::isSecure):
     18        (WebCore::isAllowedToUse):
     19        (WebCore::canCallGetUserMedia):
     20        (WebCore::UserMediaRequest::start):
     21        * html/HTMLAttributeNames.in:
     22        * html/HTMLIFrameElement.cpp:
     23        (WebCore::HTMLIFrameElement::parseAttribute):
     24        * html/HTMLIFrameElement.h:
     25        * html/HTMLIFrameElement.idl:
     26
    1272017-12-14  Zalan Bujtas  <zalan@apple.com>
    228
  • trunk/Source/WebCore/Modules/mediastream/UserMediaRequest.cpp

    r225828 r225963  
    4141#include "Document.h"
    4242#include "DocumentLoader.h"
     43#include "HTMLIFrameElement.h"
     44#include "HTMLParserIdioms.h"
    4345#include "JSMediaStream.h"
    4446#include "JSOverconstrainedError.h"
     
    9698{
    9799    auto& response = documentLoader.response();
     100    if (SecurityOrigin::isLocalHostOrLoopbackIPAddress(documentLoader.response().url()))
     101        return true;
    98102    return SchemeRegistry::shouldTreatURLSchemeAsSecure(response.url().protocol().toStringWithoutCopying())
    99103        && response.certificateInfo()
     
    101105}
    102106
    103 static bool canCallGetUserMedia(Document& document, String& errorMessage)
     107static bool isAllowedToUse(Document& document, Document& topDocument, bool requiresAudio, bool requiresVideo)
     108{
     109    if (&document == &topDocument)
     110        return true;
     111
     112    auto* parentDocument = document.parentDocument();
     113    if (!parentDocument)
     114        return false;
     115
     116    if (document.securityOrigin().isSameSchemeHostPort(parentDocument->securityOrigin()))
     117        return true;
     118
     119    auto* element = document.ownerElement();
     120    ASSERT(element);
     121    if (!element)
     122        return false;
     123
     124    if (!is<HTMLIFrameElement>(*element))
     125        return false;
     126    auto& allow = downcast<HTMLIFrameElement>(*element).allow();
     127
     128    bool allowCameraAccess = false;
     129    bool allowMicrophoneAccess = false;
     130    for (auto allowItem : StringView { allow }.split(';')) {
     131        auto item = allowItem.stripLeadingAndTrailingMatchedCharacters(isHTMLSpace<UChar>);
     132        if (!allowCameraAccess && item == "camera")
     133            allowCameraAccess = true;
     134        else if (!allowMicrophoneAccess && item == "microphone")
     135            allowMicrophoneAccess = true;
     136    }
     137    return (allowCameraAccess || !requiresVideo) && (allowMicrophoneAccess || !requiresAudio);
     138}
     139
     140static bool canCallGetUserMedia(Document& document, bool wantsAudio, bool wantsVideo, String& errorMessage)
    104141{
    105142    bool requiresSecureConnection = DeprecatedGlobalSettings::mediaCaptureRequiresSecureConnection();
    106143    auto& documentLoader = *document.loader();
    107     if (requiresSecureConnection && !isSecure(documentLoader) && !SecurityOrigin::isLocalHostOrLoopbackIPAddress(documentLoader.response().url())) {
     144    if (requiresSecureConnection && !isSecure(documentLoader)) {
    108145        errorMessage = "Trying to call getUserMedia from an insecure document.";
    109146        return false;
     
    112149    auto& topDocument = document.topDocument();
    113150    if (&document != &topDocument) {
    114         auto& topOrigin = topDocument.topOrigin();
    115 
    116         if (!document.securityOrigin().isSameSchemeHostPort(topOrigin)) {
    117             errorMessage = "Trying to call getUserMedia from a document with a different security origin than its top-level frame.";
    118             return false;
    119         }
    120 
    121         for (auto* ancestorDocument = document.parentDocument(); ancestorDocument != &topDocument; ancestorDocument = ancestorDocument->parentDocument()) {
     151        for (auto* ancestorDocument = &document; ancestorDocument != &topDocument; ancestorDocument = ancestorDocument->parentDocument()) {
    122152            if (requiresSecureConnection && !isSecure(*ancestorDocument->loader())) {
    123153                errorMessage = "Trying to call getUserMedia from a document with an insecure parent frame.";
     
    125155            }
    126156
    127             if (!ancestorDocument->securityOrigin().isSameSchemeHostPort(topOrigin)) {
    128                 errorMessage = "Trying to call getUserMedia from a document with a different security origin than its top-level frame.";
     157            if (!isAllowedToUse(*ancestorDocument, topDocument, wantsAudio, wantsVideo)) {
     158                errorMessage = "The top-level frame has prevented a document with a different security origin to call getUserMedia.";
    129159                return false;
    130160            }
     
    147177    // or due to platform limitations, jump to the step labeled Permission Failure below.
    148178    String errorMessage;
    149     if (!canCallGetUserMedia(document, errorMessage)) {
     179    if (!canCallGetUserMedia(document, m_audioConstraints.isValid, m_videoConstraints.isValid, errorMessage)) {
    150180        deny(MediaAccessDenialReason::PermissionDenied, emptyString());
    151181        document.domWindow()->printErrorMessage(errorMessage);
  • trunk/Source/WebCore/html/HTMLAttributeNames.in

    r225616 r225963  
    1111align
    1212alink
     13allow
    1314allowfullscreen
    1415alt
  • trunk/Source/WebCore/html/HTMLIFrameElement.cpp

    r222613 r225963  
    9494        if (!invalidTokens.isNull())
    9595            document().addConsoleMessage(MessageSource::Other, MessageLevel::Error, "Error while parsing the 'sandbox' attribute: " + invalidTokens);
    96     } else
     96    } else if (name == allowAttr)
     97        m_allow = value;
     98    else
    9799        HTMLFrameElementBase::parseAttribute(name, value);
    98100}
  • trunk/Source/WebCore/html/HTMLIFrameElement.h

    r205249 r225963  
    3838
    3939    RenderIFrame* renderer() const;
     40    const String& allow() const { return m_allow; }
    4041
    4142private:
     
    5455
    5556    std::unique_ptr<DOMTokenList> m_sandbox;
     57    String m_allow;
    5658};
    5759
  • trunk/Source/WebCore/html/HTMLIFrameElement.idl

    r215330 r225963  
    3030    [PutForwards=value] readonly attribute DOMTokenList sandbox;
    3131    [Reflect] attribute boolean allowFullscreen;
     32    [CEReactions, Reflect] attribute DOMString allow;
    3233
    3334    [Reflect] attribute DOMString scrolling;
Note: See TracChangeset for help on using the changeset viewer.