Merge mozilla-central to fx-team

This commit is contained in:
Carsten "Tomcat" Book 2016-06-30 12:51:35 +02:00
Родитель 43a3ab0728 3a42c363cc
Коммит dd4e976e4a
340 изменённых файлов: 8449 добавлений и 3246 удалений

Просмотреть файл

@ -1,3 +1,3 @@
[flake8]
max-line-length = 99
filename = *.py, *.lint
filename = *.py, +.lint

Просмотреть файл

@ -22,4 +22,4 @@
# changes to stick? As of bug 928195, this shouldn't be necessary! Please
# don't change CLOBBER for WebIDL changes any more.
Bug 1276696 - New Android dependencies
Bug 1267887 - Build skew after updating rust mp4parse

Просмотреть файл

@ -45,7 +45,7 @@
"gecko_l10n_root": "https://hg.mozilla.org/l10n-central",
"gaia": {
"l10n": {
"vcs": "hgtool",
"vcs": "hg",
"root": "https://hg.mozilla.org/gaia-l10n"
}
}

Просмотреть файл

@ -1,5 +1,22 @@
[
{
"version": "Android NDK r11b for B2G",
"algorithm": "sha512",
"visibility": "internal",
"filename": "android-ndk-b2g.tar.xz",
"unpack": true,
"digest": "bc37c6b2e38f4ff19e3326786312d8f893600e155d35dfba45163bd909e022db852b9c6920863cb498bbe7da8b86a6a387fa024bc9444ce3a8d1715cf2c24b21",
"size": 292442020
},
{
"algorithm": "sha512",
"visibility": "internal",
"filename": "backup-aries_23.0.1.A.5.77.tar.xz",
"unpack": true,
"digest": "79c8e390e88cc4765ff7f5f29f3d5337c9037b7eb9414006947d38d34acefdbcf7090c18a366948c682b1c2c9d9ef51012e7be44daa28fdde7b837ade647c257",
"size": 227555180
},
{
"version": "gcc 4.8.5 + PR64905",
"size": 80160264,
"digest": "c1a9dc9da289b8528874d16300b9d13a997cec99195bb0bc46ff665216d8535d6d6cb5af6b4b1f2749af6815dab12e703fdb3849014e5c23a70eff351a0baf4e",

Просмотреть файл

@ -6,23 +6,21 @@
<remote fetch="https://git.mozilla.org/external/aosp" name="aosp"/>
<!--original fetch url was git://github.com/apitrace/-->
<remote fetch="https://git.mozilla.org/external/apitrace" name="apitrace"/>
<!--original fetch url was git://github.com/mozilla-b2g/-->
<remote fetch="https://git.mozilla.org/b2g" name="b2g"/>
<remote fetch="git://github.com/mozilla-b2g/" name="b2g"/>
<!--original fetch url was https://git.mozilla.org/b2g-->
<remote fetch="https://git.mozilla.org/b2g" name="b2gmozilla"/>
<!--original fetch url was git://codeaurora.org/-->
<remote fetch="https://git.mozilla.org/external/caf" name="caf"/>
<!--original fetch url was http://android.git.linaro.org/git-ro/-->
<remote fetch="https://git.mozilla.org/external/linaro" name="linaro"/>
<!--original fetch url was git://github.com/mozilla/-->
<remote fetch="https://git.mozilla.org/b2g" name="mozilla"/>
<remote fetch="git://github.com/mozilla/" name="mozilla"/>
<!--original fetch url was https://git.mozilla.org/releases-->
<remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
<!--
B2G repositories for all targets
-->
<project name="gaia" path="gaia" remote="mozillaorg" revision="a954bd2954c422b7d24d92cfd73000cb455dce44"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="19150d320e6802ec211ccc5e74c254ae9992312d"/>
<project name="gaia" path="gaia" remote="b2g" revision="99c01f5646b2d8aa5ebf1968114ab2f5db5ac6a8"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="31f2fbb02035c18b84f3387317aab75adf65da87"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="99c333dab00ed79baff9e1cf76b320aee8e1c123"/>
<project name="platform_hardware_libhardware_moz" path="hardware/libhardware_moz" remote="b2g" revision="fdf3a143dc777e5f9d33a88373af7ea161d3b440"/>
<project name="platform_system_libfdio" path="system/libfdio" remote="b2g" revision="34adfb400e031f3dd3353d92413572db5e3a7376"/>

Просмотреть файл

@ -48,7 +48,7 @@
"gecko_l10n_root": "https://hg.mozilla.org/l10n-central",
"gaia": {
"l10n": {
"vcs": "hgtool",
"vcs": "hg",
"root": "https://hg.mozilla.org/gaia-l10n"
}
}

Просмотреть файл

@ -1,8 +1,19 @@
[{
[
{
"version": "Android NDK r11b for B2G",
"algorithm": "sha512",
"visibility": "internal",
"filename": "android-ndk-b2g.tar.xz",
"unpack": true,
"digest": "bc37c6b2e38f4ff19e3326786312d8f893600e155d35dfba45163bd909e022db852b9c6920863cb498bbe7da8b86a6a387fa024bc9444ce3a8d1715cf2c24b21",
"size": 292442020
},
{
"version": "gcc 4.8.5 + PR64905",
"size": 80160264,
"digest": "c1a9dc9da289b8528874d16300b9d13a997cec99195bb0bc46ff665216d8535d6d6cb5af6b4b1f2749af6815dab12e703fdb3849014e5c23a70eff351a0baf4e",
"algorithm": "sha512",
"filename": "gcc.tar.xz",
"unpack": "True"
}]
}
]

Просмотреть файл

@ -6,23 +6,21 @@
<remote fetch="https://git.mozilla.org/external/aosp" name="aosp"/>
<!--original fetch url was git://github.com/apitrace/-->
<remote fetch="https://git.mozilla.org/external/apitrace" name="apitrace"/>
<!--original fetch url was git://github.com/mozilla-b2g/-->
<remote fetch="https://git.mozilla.org/b2g" name="b2g"/>
<remote fetch="git://github.com/mozilla-b2g/" name="b2g"/>
<!--original fetch url was https://git.mozilla.org/b2g-->
<remote fetch="https://git.mozilla.org/b2g" name="b2gmozilla"/>
<!--original fetch url was git://codeaurora.org/-->
<remote fetch="https://git.mozilla.org/external/caf" name="caf"/>
<!--original fetch url was http://android.git.linaro.org/git-ro/-->
<remote fetch="https://git.mozilla.org/external/linaro" name="linaro"/>
<!--original fetch url was git://github.com/mozilla/-->
<remote fetch="https://git.mozilla.org/b2g" name="mozilla"/>
<remote fetch="git://github.com/mozilla/" name="mozilla"/>
<!--original fetch url was https://git.mozilla.org/releases-->
<remote fetch="https://git.mozilla.org/releases" name="mozillaorg"/>
<!--
B2G repositories for all targets
-->
<project name="gaia" path="gaia" remote="mozillaorg" revision="a954bd2954c422b7d24d92cfd73000cb455dce44"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="19150d320e6802ec211ccc5e74c254ae9992312d"/>
<project name="gaia" path="gaia" remote="b2g" revision="99c01f5646b2d8aa5ebf1968114ab2f5db5ac6a8"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="31f2fbb02035c18b84f3387317aab75adf65da87"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="99c333dab00ed79baff9e1cf76b320aee8e1c123"/>
<project name="platform_hardware_libhardware_moz" path="hardware/libhardware_moz" remote="b2g" revision="fdf3a143dc777e5f9d33a88373af7ea161d3b440"/>
<project name="platform_system_libfdio" path="system/libfdio" remote="b2g" revision="34adfb400e031f3dd3353d92413572db5e3a7376"/>

Просмотреть файл

@ -611,7 +611,6 @@ if (Services.appinfo.processType == Services.appinfo.PROCESS_TYPE_CONTENT) {
var DOMFullscreenHandler = {
_fullscreenDoc: null,
init: function() {
addMessageListener("DOMFullscreen:Entered", this);
@ -646,11 +645,14 @@ var DOMFullscreenHandler = {
break;
}
case "DOMFullscreen:CleanUp": {
if (windowUtils) {
// If we've exited fullscreen at this point, no need to record
// transaction id or call exit fullscreen. This is especially
// important for non-e10s, since in that case, it is possible
// that no more paint would be triggered after this point.
if (content.document.fullscreenElement && windowUtils) {
this._lastTransactionId = windowUtils.lastTransactionId;
windowUtils.exitFullscreen();
}
this._fullscreenDoc = null;
break;
}
}
@ -663,9 +665,8 @@ var DOMFullscreenHandler = {
break;
}
case "MozDOMFullscreen:NewOrigin": {
this._fullscreenDoc = aEvent.target;
sendAsyncMessage("DOMFullscreen:NewOrigin", {
originNoSuffix: this._fullscreenDoc.nodePrincipal.originNoSuffix,
originNoSuffix: aEvent.target.nodePrincipal.originNoSuffix,
});
break;
}
@ -687,7 +688,10 @@ var DOMFullscreenHandler = {
case "MozAfterPaint": {
// Only send Painted signal after we actually finish painting
// the transition for the fullscreen change.
if (aEvent.transactionId > this._lastTransactionId) {
// Note that this._lastTransactionId is not set when in non-e10s
// mode, so we need to check that explicitly.
if (!this._lastTransactionId ||
aEvent.transactionId > this._lastTransactionId) {
removeEventListener("MozAfterPaint", this);
sendAsyncMessage("DOMFullscreen:Painted");
}

Просмотреть файл

@ -56,13 +56,16 @@ const AutoMigrate = {
}
Services.obs.removeObserver(migrationObserver, "Migration:Ended");
Services.obs.removeObserver(migrationObserver, "Migration:ItemError");
Services.prefs.setCharPref(kAutoMigrateStartedPref, startTime.toString());
Services.prefs.setCharPref(kAutoMigrateFinishedPref, Date.now().toString());
}
};
Services.obs.addObserver(migrationObserver, "Migration:Ended", false);
Services.obs.addObserver(migrationObserver, "Migration:ItemError", false);
Services.prefs.setCharPref(kAutoMigrateStartedPref, Date.now().toString());
// We'll save this when the migration has finished, at which point the pref
// service will be available.
let startTime = Date.now();
migrator.migrate(this.resourceTypesToUse, profileStartup, profileToMigrate);
histogram.add(20);
},

Просмотреть файл

@ -529,6 +529,7 @@ this.MigrationUtils = Object.freeze({
// Canary uses the same description as Chrome so we can't distinguish them.
const APP_DESC_TO_KEY = {
"Internet Explorer": "ie",
"Microsoft Edge": "edge",
"Safari": "safari",
"Firefox": "firefox",
"Google Chrome": "chrome", // Windows, Linux

Просмотреть файл

@ -53,6 +53,8 @@ PluginContent.prototype = {
global.addMessageListener("BrowserPlugins:NPAPIPluginProcessCrashed", this);
global.addMessageListener("BrowserPlugins:CrashReportSubmitted", this);
global.addMessageListener("BrowserPlugins:Test:ClearCrashData", this);
Services.obs.addObserver(this, "Plugin::HiddenPluginTouched", false);
},
uninit: function() {
@ -75,6 +77,8 @@ PluginContent.prototype = {
global.removeMessageListener("BrowserPlugins:Test:ClearCrashData", this);
delete this.global;
delete this.content;
Services.obs.removeObserver(this, "Plugin::HiddenPluginTouched");
},
receiveMessage: function (msg) {
@ -116,6 +120,15 @@ PluginContent.prototype = {
}
},
observe: function observe(aSubject, aTopic, aData) {
let pluginTag = aSubject.QueryInterface(Ci.nsIPluginTag);
if (aTopic == "Plugin::HiddenPluginTouched") {
this._showClickToPlayNotification(pluginTag, false);
} else {
Cu.reportError("unknown topic observed: " + aTopic);
}
},
onPageShow: function (event) {
// Ignore events that aren't from the main document.
if (!this.content || event.target != this.content.document) {
@ -194,6 +207,45 @@ PluginContent.prototype = {
};
},
_getPluginInfoForTag: function (pluginTag, tagMimetype) {
let pluginHost = Cc["@mozilla.org/plugin/host;1"].getService(Ci.nsIPluginHost);
let pluginName = gNavigatorBundle.GetStringFromName("pluginInfo.unknownPlugin");
let permissionString = null;
let blocklistState = null;
if (pluginTag) {
pluginName = BrowserUtils.makeNicePluginName(pluginTag.name);
permissionString = pluginHost.getPermissionStringForTag(pluginTag);
blocklistState = pluginTag.blocklistState;
// Convert this from nsIPluginTag so it can be serialized.
let properties = ["name", "description", "filename", "version", "enabledState", "niceName"];
let pluginTagCopy = {};
for (let prop of properties) {
pluginTagCopy[prop] = pluginTag[prop];
}
pluginTag = pluginTagCopy;
// Make state-softblocked == state-notblocked for our purposes,
// they have the same UI. STATE_OUTDATED should not exist for plugin
// items, but let's alias it anyway, just in case.
if (blocklistState == Ci.nsIBlocklistService.STATE_SOFTBLOCKED ||
blocklistState == Ci.nsIBlocklistService.STATE_OUTDATED) {
blocklistState = Ci.nsIBlocklistService.STATE_NOT_BLOCKED;
}
}
return { mimetype: tagMimetype,
pluginName: pluginName,
pluginTag: pluginTag,
permissionString: permissionString,
fallbackType: null,
blocklistState: blocklistState,
};
},
/**
* Update the visibility of the plugin overlay.
*/
@ -710,7 +762,13 @@ PluginContent.prototype = {
let location = this.content.document.location.href;
for (let p of plugins) {
let pluginInfo = this._getPluginInfo(p);
let pluginInfo;
if (p instanceof Ci.nsIPluginTag) {
let mimeType = p.getMimeTypes() > 0 ? p.getMimeTypes()[0] : null;
pluginInfo = this._getPluginInfoForTag(p, mimeType);
} else {
pluginInfo = this._getPluginInfo(p);
}
if (pluginInfo.permissionString === null) {
Cu.reportError("No permission string for active plugin.");
continue;

Просмотреть файл

@ -27,6 +27,7 @@ public class GeneratableElementIterator implements Iterator<AnnotatableEntity> {
private final Member[] mObjects;
private AnnotatableEntity mNextReturnValue;
private int mElementIndex;
private AnnotationInfo mClassInfo;
private boolean mIterateEveryEntry;
@ -55,8 +56,8 @@ public class GeneratableElementIterator implements Iterator<AnnotatableEntity> {
// Check for "Wrap ALL the things" flag.
for (Annotation annotation : aClass.getDeclaredAnnotations()) {
final String annotationTypeName = annotation.annotationType().getName();
if (annotationTypeName.equals("org.mozilla.gecko.annotation.WrapForJNI")) {
mClassInfo = buildAnnotationInfo(aClass, annotation);
if (mClassInfo != null) {
mIterateEveryEntry = true;
break;
}
@ -115,6 +116,73 @@ public class GeneratableElementIterator implements Iterator<AnnotatableEntity> {
return ret;
}
private AnnotationInfo buildAnnotationInfo(AnnotatedElement element, Annotation annotation) {
Class<? extends Annotation> annotationType = annotation.annotationType();
final String annotationTypeName = annotationType.getName();
if (!annotationTypeName.equals("org.mozilla.gecko.annotation.WrapForJNI")) {
return null;
}
String stubName = null;
boolean isMultithreadedStub = false;
boolean noThrow = false;
boolean narrowChars = false;
boolean catchException = false;
try {
// Determine the explicitly-given name of the stub to generate, if any.
final Method stubNameMethod = annotationType.getDeclaredMethod("stubName");
stubNameMethod.setAccessible(true);
stubName = (String) stubNameMethod.invoke(annotation);
if (element instanceof Class<?>) {
// Make @WrapForJNI always allow multithread by default, individual methods can then
// override with their own annotation
isMultithreadedStub = true;
} else {
// Determine if the generated stub is to allow calls from multiple threads.
final Method multithreadedStubMethod = annotationType.getDeclaredMethod("allowMultithread");
multithreadedStubMethod.setAccessible(true);
isMultithreadedStub = (Boolean) multithreadedStubMethod.invoke(annotation);
}
// Determine if ignoring exceptions
final Method noThrowMethod = annotationType.getDeclaredMethod("noThrow");
noThrowMethod.setAccessible(true);
noThrow = (Boolean) noThrowMethod.invoke(annotation);
// Determine if strings should be wide or narrow
final Method narrowCharsMethod = annotationType.getDeclaredMethod("narrowChars");
narrowCharsMethod.setAccessible(true);
narrowChars = (Boolean) narrowCharsMethod.invoke(annotation);
// Determine if we should catch exceptions
final Method catchExceptionMethod = annotationType.getDeclaredMethod("catchException");
catchExceptionMethod.setAccessible(true);
catchException = (Boolean) catchExceptionMethod.invoke(annotation);
} catch (NoSuchMethodException e) {
System.err.println("Unable to find expected field on WrapForJNI annotation. Did the signature change?");
e.printStackTrace(System.err);
System.exit(3);
} catch (IllegalAccessException e) {
System.err.println("IllegalAccessException reading fields on WrapForJNI annotation. Seems the semantics of Reflection have changed...");
e.printStackTrace(System.err);
System.exit(4);
} catch (InvocationTargetException e) {
System.err.println("InvocationTargetException reading fields on WrapForJNI annotation. This really shouldn't happen.");
e.printStackTrace(System.err);
System.exit(5);
}
// If the method name was not explicitly given in the annotation generate one...
if (stubName.isEmpty()) {
stubName = Utils.getNativeName(element);
}
return new AnnotationInfo(
stubName, isMultithreadedStub, noThrow, narrowChars, catchException);
}
/**
* Find and cache the next appropriately annotated method, plus the annotation parameter, if
* one exists. Otherwise cache null, so hasNext returns false.
@ -124,63 +192,9 @@ public class GeneratableElementIterator implements Iterator<AnnotatableEntity> {
Member candidateElement = mObjects[mElementIndex];
mElementIndex++;
for (Annotation annotation : ((AnnotatedElement) candidateElement).getDeclaredAnnotations()) {
// WrappedJNIMethod has parameters. Use Reflection to obtain them.
Class<? extends Annotation> annotationType = annotation.annotationType();
final String annotationTypeName = annotationType.getName();
if (annotationTypeName.equals("org.mozilla.gecko.annotation.WrapForJNI")) {
String stubName = null;
boolean isMultithreadedStub = false;
boolean noThrow = false;
boolean narrowChars = false;
boolean catchException = false;
try {
// Determine the explicitly-given name of the stub to generate, if any.
final Method stubNameMethod = annotationType.getDeclaredMethod("stubName");
stubNameMethod.setAccessible(true);
stubName = (String) stubNameMethod.invoke(annotation);
// Determine if the generated stub is to allow calls from multiple threads.
final Method multithreadedStubMethod = annotationType.getDeclaredMethod("allowMultithread");
multithreadedStubMethod.setAccessible(true);
isMultithreadedStub = (Boolean) multithreadedStubMethod.invoke(annotation);
// Determine if ignoring exceptions
final Method noThrowMethod = annotationType.getDeclaredMethod("noThrow");
noThrowMethod.setAccessible(true);
noThrow = (Boolean) noThrowMethod.invoke(annotation);
// Determine if strings should be wide or narrow
final Method narrowCharsMethod = annotationType.getDeclaredMethod("narrowChars");
narrowCharsMethod.setAccessible(true);
narrowChars = (Boolean) narrowCharsMethod.invoke(annotation);
// Determine if we should catch exceptions
final Method catchExceptionMethod = annotationType.getDeclaredMethod("catchException");
catchExceptionMethod.setAccessible(true);
catchException = (Boolean) catchExceptionMethod.invoke(annotation);
} catch (NoSuchMethodException e) {
System.err.println("Unable to find expected field on WrapForJNI annotation. Did the signature change?");
e.printStackTrace(System.err);
System.exit(3);
} catch (IllegalAccessException e) {
System.err.println("IllegalAccessException reading fields on WrapForJNI annotation. Seems the semantics of Reflection have changed...");
e.printStackTrace(System.err);
System.exit(4);
} catch (InvocationTargetException e) {
System.err.println("InvocationTargetException reading fields on WrapForJNI annotation. This really shouldn't happen.");
e.printStackTrace(System.err);
System.exit(5);
}
// If the method name was not explicitly given in the annotation generate one...
if (stubName.isEmpty()) {
stubName = Utils.getNativeName(candidateElement);
}
AnnotationInfo annotationInfo = new AnnotationInfo(
stubName, isMultithreadedStub, noThrow, narrowChars, catchException);
mNextReturnValue = new AnnotatableEntity(candidateElement, annotationInfo);
AnnotationInfo info = buildAnnotationInfo((AnnotatedElement)candidateElement, annotation);
if (info != null) {
mNextReturnValue = new AnnotatableEntity(candidateElement, info);
return;
}
}
@ -190,10 +204,10 @@ public class GeneratableElementIterator implements Iterator<AnnotatableEntity> {
if (mIterateEveryEntry) {
AnnotationInfo annotationInfo = new AnnotationInfo(
Utils.getNativeName(candidateElement),
/* multithreaded */ true,
/* noThrow */ false,
/* narrowChars */ false,
/* catchException */ false);
mClassInfo.isMultithreaded,
mClassInfo.noThrow,
mClassInfo.narrowChars,
mClassInfo.catchException);
mNextReturnValue = new AnnotatableEntity(candidateElement, annotationInfo);
return;
}

Просмотреть файл

@ -6,6 +6,7 @@ package org.mozilla.gecko.annotationProcessors.utils;
import org.mozilla.gecko.annotationProcessors.AnnotationInfo;
import java.lang.reflect.AnnotatedElement;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Member;
@ -212,6 +213,33 @@ public class Utils {
return name.substring(0, 1).toUpperCase() + name.substring(1);
}
/**
* Get the C++ name for a member.
*
* @param member Member to get the name for.
* @return JNI name as a string
*/
public static String getNativeName(Class<?> clz) {
final String name = clz.getName();
return name.substring(0, 1).toUpperCase() + name.substring(1);
}
/**
* Get the C++ name for a member.
*
* @param member Member to get the name for.
* @return JNI name as a string
*/
public static String getNativeName(AnnotatedElement element) {
if (element instanceof Class<?>) {
return getNativeName((Class<?>)element);
} else if (element instanceof Member) {
return getNativeName((Member)element);
} else {
return null;
}
}
/**
* Get the JNI name for a member.
*

1
config/external/nss/nss.symbols поставляемый
Просмотреть файл

@ -557,7 +557,6 @@ SECMOD_DeleteInternalModule
SECMOD_DeleteModule
SECMOD_DestroyModule
SECMOD_FindModule
SECMOD_FindSlot
SECMOD_GetDeadModuleList
SECMOD_GetDefaultModuleList
SECMOD_GetDefaultModuleListLock

Просмотреть файл

@ -7,6 +7,7 @@ import unittest
import inspect
from StringIO import StringIO
import os
import sys
'''Helper to make python unit tests report the way that the Mozilla
unit test infrastructure expects tests to report.
@ -107,6 +108,17 @@ class MockedFile(StringIO):
def __exit__(self, type, value, traceback):
self.close()
def normcase(path):
'''
Normalize the case of `path`.
Don't use `os.path.normcase` because that also normalizes forward slashes
to backslashes on Windows.
'''
if sys.platform.startswith('win'):
return path.lower()
return path
class MockedOpen(object):
'''
Context manager diverting the open builtin such that opening files
@ -129,10 +141,10 @@ class MockedOpen(object):
def __init__(self, files = {}):
self.files = {}
for name, content in files.iteritems():
self.files[os.path.abspath(name)] = content
self.files[normcase(os.path.abspath(name))] = content
def __call__(self, name, mode = 'r'):
absname = os.path.abspath(name)
absname = normcase(os.path.abspath(name))
if 'w' in mode:
file = MockedFile(self, absname)
elif absname in self.files:
@ -169,6 +181,7 @@ class MockedOpen(object):
self._orig_path_exists(p))
def _wrapped_isfile(self, p):
p = normcase(p)
if p in self.files:
return True
@ -179,6 +192,7 @@ class MockedOpen(object):
return self._orig_path_isfile(p)
def _wrapped_isdir(self, p):
p = normcase(p)
p = p if p.endswith(('/', '\\')) else p + os.sep
if any(f.startswith(p) for f in self.files):
return True

Просмотреть файл

@ -86,6 +86,7 @@
#include "nsWhitespaceTokenizer.h"
#include "nsICookieService.h"
#include "nsIConsoleReportCollector.h"
#include "nsObjectLoadingContent.h"
// we want to explore making the document own the load group
// so we can associate the document URI with the load group.
@ -2524,15 +2525,35 @@ nsDocShell::GetFullscreenAllowed(bool* aFullscreenAllowed)
if (frameElement && !frameElement->IsXULElement()) {
// We do not allow document inside any containing element other
// than iframe to enter fullscreen.
if (!frameElement->IsHTMLElement(nsGkAtoms::iframe)) {
return NS_OK;
}
// If any ancestor iframe does not have allowfullscreen attribute
// set, then fullscreen is not allowed.
if (!frameElement->HasAttr(kNameSpaceID_None,
nsGkAtoms::allowfullscreen) &&
!frameElement->HasAttr(kNameSpaceID_None,
nsGkAtoms::mozallowfullscreen)) {
if (frameElement->IsHTMLElement(nsGkAtoms::iframe)) {
// If any ancestor iframe does not have allowfullscreen attribute
// set, then fullscreen is not allowed.
if (!frameElement->HasAttr(kNameSpaceID_None,
nsGkAtoms::allowfullscreen) &&
!frameElement->HasAttr(kNameSpaceID_None,
nsGkAtoms::mozallowfullscreen)) {
return NS_OK;
}
} else if (frameElement->IsHTMLElement(nsGkAtoms::embed)) {
// Respect allowfullscreen only if this is a rewritten YouTube embed.
nsCOMPtr<nsIObjectLoadingContent> objectLoadingContent =
do_QueryInterface(frameElement);
if (!objectLoadingContent) {
return NS_OK;
}
nsObjectLoadingContent* olc =
static_cast<nsObjectLoadingContent*>(objectLoadingContent.get());
if (!olc->IsRewrittenYoutubeEmbed()) {
return NS_OK;
}
// We don't have to check prefixed attributes because Flash does not
// support them.
if (!frameElement->HasAttr(kNameSpaceID_None,
nsGkAtoms::allowfullscreen)) {
return NS_OK;
}
} else {
// neither iframe nor embed
return NS_OK;
}
nsIDocument* doc = frameElement->GetUncomposedDoc();

Просмотреть файл

@ -1733,18 +1733,17 @@ Element::UnbindFromTree(bool aDeep, bool aNullParent)
if (HasPointerLock()) {
nsIDocument::UnlockPointer();
}
if (mState.HasState(NS_EVENT_STATE_FULL_SCREEN)) {
// The element being removed is an ancestor of the full-screen element,
// exit full-screen state.
nsContentUtils::ReportToConsole(nsIScriptError::warningFlag,
NS_LITERAL_CSTRING("DOM"), OwnerDoc(),
nsContentUtils::eDOM_PROPERTIES,
"RemovedFullscreenElement");
// Fully exit full-screen.
nsIDocument::ExitFullscreenInDocTree(OwnerDoc());
}
if (aNullParent) {
if (IsFullScreenAncestor()) {
// The element being removed is an ancestor of the full-screen element,
// exit full-screen state.
nsContentUtils::ReportToConsole(nsIScriptError::warningFlag,
NS_LITERAL_CSTRING("DOM"), OwnerDoc(),
nsContentUtils::eDOM_PROPERTIES,
"RemovedFullscreenElement");
// Fully exit full-screen.
nsIDocument::ExitFullscreenInDocTree(OwnerDoc());
}
if (GetParent() && GetParent()->IsInUncomposedDoc()) {
// Update the editable descendant count in the ancestors before we
// lose the reference to the parent.

Просмотреть файл

@ -192,15 +192,6 @@ public:
*/
void UpdateLinkState(EventStates aState);
/**
* Returns true if this element is either a full-screen element or an
* ancestor of the full-screen element.
*/
bool IsFullScreenAncestor() const {
return mState.HasAtLeastOneOfStates(NS_EVENT_STATE_FULL_SCREEN_ANCESTOR |
NS_EVENT_STATE_FULL_SCREEN);
}
/**
* The style state of this element. This is the real state of the element
* with any style locks applied for pseudo-class inspecting.

Просмотреть файл

@ -1846,6 +1846,12 @@ WebSocketImpl::InitializeConnection(nsIPrincipal* aPrincipal)
// are not thread-safe.
mOriginDocument = nullptr;
// The TriggeringPrincipal for websockets must always be a script.
// Let's make sure that the doc's principal (if a doc exists)
// and aPrincipal are same origin.
MOZ_ASSERT(!doc || doc->NodePrincipal()->Equals(aPrincipal));
wsChannel->InitLoadInfo(doc ? doc->AsDOMNode() : nullptr,
doc ? doc->NodePrincipal() : aPrincipal,
aPrincipal,

Просмотреть файл

@ -1344,6 +1344,80 @@ nsContentUtils::GetParserService()
return sParserService;
}
/**
* A helper function that parses a sandbox attribute (of an <iframe> or a CSP
* directive) and converts it to the set of flags used internally.
*
* @param aSandboxAttr the sandbox attribute
* @return the set of flags (SANDBOXED_NONE if aSandboxAttr is
* null)
*/
uint32_t
nsContentUtils::ParseSandboxAttributeToFlags(const nsAttrValue* aSandboxAttr)
{
if (!aSandboxAttr) {
return SANDBOXED_NONE;
}
uint32_t out = SANDBOX_ALL_FLAGS;
#define SANDBOX_KEYWORD(string, atom, flags) \
if (aSandboxAttr->Contains(nsGkAtoms::atom, eIgnoreCase)) { \
out &= ~(flags); \
}
#include "IframeSandboxKeywordList.h"
#undef SANDBOX_KEYWORD
return out;
}
/**
* A helper function that checks if a string matches a valid sandbox flag.
*
* @param aFlag the potential sandbox flag.
* @return true if the flag is a sandbox flag.
*/
bool
nsContentUtils::IsValidSandboxFlag(const nsAString& aFlag)
{
#define SANDBOX_KEYWORD(string, atom, flags) \
if (EqualsIgnoreASCIICase(nsDependentAtomString(nsGkAtoms::atom), aFlag)) { \
return true; \
}
#include "IframeSandboxKeywordList.h"
#undef SANDBOX_KEYWORD
return false;
}
/**
* A helper function that returns a string attribute corresponding to the
* sandbox flags.
*
* @param aFlags the sandbox flags
* @param aString the attribute corresponding to the flags (null if aFlags
* is zero)
*/
void
nsContentUtils::SandboxFlagsToString(uint32_t aFlags, nsAString& aString)
{
if (!aFlags) {
SetDOMStringToNull(aString);
return;
}
aString.Truncate();
#define SANDBOX_KEYWORD(string, atom, flags) \
if (!(aFlags & (flags))) { \
if (!aString.IsEmpty()) { \
aString.Append(NS_LITERAL_STRING(" ")); \
} \
aString.Append(nsDependentAtomString(nsGkAtoms::atom)); \
}
#include "IframeSandboxKeywordList.h"
#undef SANDBOX_KEYWORD
}
nsIBidiKeyboard*
nsContentUtils::GetBidiKeyboard()
{

Просмотреть файл

@ -917,6 +917,34 @@ public:
const char* aKey,
nsXPIDLString& aResult);
/**
* A helper function that parses a sandbox attribute (of an <iframe> or a CSP
* directive) and converts it to the set of flags used internally.
*
* @param aSandboxAttr the sandbox attribute
* @return the set of flags (SANDBOXED_NONE if aSandboxAttr is
* null)
*/
static uint32_t ParseSandboxAttributeToFlags(const nsAttrValue* aSandboxAttr);
/**
* A helper function that checks if a string matches a valid sandbox flag.
*
* @param aFlag the potential sandbox flag.
* @return true if the flag is a sandbox flag.
*/
static bool IsValidSandboxFlag(const nsAString& aFlag);
/**
* A helper function that returns a string attribute corresponding to the
* sandbox flags.
*
* @param aFlags the sandbox flags
* @param aString the attribute corresponding to the flags (null if aFlags
* is zero)
*/
static void SandboxFlagsToString(uint32_t aFlags, nsAString& aString);
/**
* Helper function that generates a UUID.
*/

Просмотреть файл

@ -3214,6 +3214,10 @@ PrepareForFullscreenChange(nsIPresShell* aPresShell, const nsSize& aSize,
}
if (nsRefreshDriver* rd = aPresShell->GetRefreshDriver()) {
rd->SetIsResizeSuppressed();
// Since we are suppressing the resize reflow which would originally
// be triggered by view manager, we need to ensure that the refresh
// driver actually schedules a flush, otherwise it may get stuck.
rd->ScheduleViewManagerFlush();
}
if (!aSize.IsEmpty()) {
if (nsViewManager* viewManager = aPresShell->GetViewManager()) {

Просмотреть файл

@ -1579,8 +1579,6 @@ nsDocument::~nsDocument()
}
Accumulate(Telemetry::MIXED_CONTENT_PAGE_LOAD, mixedContentLevel);
Accumulate(Telemetry::SCROLL_LINKED_EFFECT_FOUND, mHasScrollLinkedEffect);
// record mixed object subrequest telemetry
if (mHasMixedContentObjectSubrequest) {
/* mixed object subrequest loaded on page*/
@ -2760,6 +2758,8 @@ nsDocument::ApplySettingsFromCSP(bool aSpeculative)
nsresult
nsDocument::InitCSP(nsIChannel* aChannel)
{
MOZ_ASSERT(!mScriptGlobalObject,
"CSP must be initialized before mScriptGlobalObject is set!");
if (!CSPService::sCSPEnabled) {
MOZ_LOG(gCspPRLog, LogLevel::Debug,
("CSP is disabled, skipping CSP init for document %p", this));
@ -2792,7 +2792,7 @@ nsDocument::InitCSP(nsIChannel* aChannel)
NS_ConvertASCIItoUTF16 cspROHeaderValue(tCspROHeaderValue);
// Figure out if we need to apply an app default CSP or a CSP from an app manifest
nsIPrincipal* principal = NodePrincipal();
nsCOMPtr<nsIPrincipal> principal = NodePrincipal();
uint16_t appStatus = principal->GetAppStatus();
bool applyAppDefaultCSP = false;
@ -2941,6 +2941,24 @@ nsDocument::InitCSP(nsIChannel* aChannel)
NS_ENSURE_SUCCESS(rv, rv);
}
// ----- Enforce sandbox policy if supplied in CSP header
// The document may already have some sandbox flags set (e.g. if the document
// is an iframe with the sandbox attribute set). If we have a CSP sandbox
// directive, intersect the CSP sandbox flags with the existing flags. This
// corresponds to the _least_ permissive policy.
uint32_t cspSandboxFlags = SANDBOXED_NONE;
rv = csp->GetCSPSandboxFlags(&cspSandboxFlags);
NS_ENSURE_SUCCESS(rv, rv);
mSandboxFlags |= cspSandboxFlags;
if (cspSandboxFlags & SANDBOXED_ORIGIN) {
// If the new CSP sandbox flags do not have the allow-same-origin flag
// reset the document principal to a null principal
principal = do_CreateInstance("@mozilla.org/nullprincipal;1");
SetPrincipal(principal);
}
// ----- Enforce frame-ancestor policy on any applied policies
nsCOMPtr<nsIDocShell> docShell(mDocumentContainer);
if (docShell) {
@ -3672,6 +3690,12 @@ nsDocument::RemoveCharSetObserver(nsIObserver* aObserver)
mCharSetObservers.RemoveElement(aObserver);
}
void
nsIDocument::GetSandboxFlagsAsString(nsAString& aFlags)
{
nsContentUtils::SandboxFlagsToString(mSandboxFlags, aFlags);
}
void
nsDocument::GetHeaderData(nsIAtom* aHeaderField, nsAString& aData) const
{
@ -4773,7 +4797,9 @@ nsDocument::SetScriptGlobalObject(nsIScriptGlobalObject *aScriptGlobalObject)
}
MaybeRescheduleAnimationFrameNotifications();
mRegistry = new Registry();
if (Preferences::GetBool("dom.webcomponents.enabled")) {
mRegistry = new Registry();
}
}
// Remember the pointer to our window (or lack there of), to avoid
@ -5669,8 +5695,10 @@ nsDocument::CreateElement(const nsAString& aTagName,
return nullptr;
}
if (!aTagName.Equals(aTypeExtension)) {
// Custom element type can not extend itself.
if (!aTypeExtension.IsVoid() &&
!aTagName.Equals(aTypeExtension)) {
// do not process 'is' if it is null or the extended type is the same as
// the localName
SetupCustomElement(elem, GetDefaultNamespaceID(), &aTypeExtension);
}
@ -5727,6 +5755,13 @@ nsDocument::CreateElementNS(const nsAString& aNamespaceURI,
return nullptr;
}
if (aTypeExtension.IsVoid() ||
aQualifiedName.Equals(aTypeExtension)) {
// do not process 'is' if it is null or the extended type is the same as
// the localName
return elem.forget();
}
int32_t nameSpaceId = kNameSpaceID_Wildcard;
if (!aNamespaceURI.EqualsLiteral("*")) {
rv = nsContentUtils::NameSpaceManager()->RegisterNameSpace(aNamespaceURI,
@ -5736,10 +5771,7 @@ nsDocument::CreateElementNS(const nsAString& aNamespaceURI,
}
}
if (!aQualifiedName.Equals(aTypeExtension)) {
// A custom element type can not extend itself.
SetupCustomElement(elem, nameSpaceId, &aTypeExtension);
}
SetupCustomElement(elem, nameSpaceId, &aTypeExtension);
return elem.forget();
}
@ -11652,7 +11684,7 @@ nsDocument::FullScreenStackPop()
while (!mFullScreenStack.IsEmpty()) {
Element* element = FullScreenStackTop();
if (!element || !element->IsInUncomposedDoc() || element->OwnerDoc() != this) {
NS_ASSERTION(!element->IsFullScreenAncestor(),
NS_ASSERTION(!element->State().HasState(NS_EVENT_STATE_FULL_SCREEN),
"Should have already removed full-screen styles");
uint32_t last = mFullScreenStack.Length() - 1;
mFullScreenStack.RemoveElementAt(last);
@ -12214,7 +12246,7 @@ nsDocument::GetFullscreenElement()
{
Element* element = FullScreenStackTop();
NS_ASSERTION(!element ||
element->IsFullScreenAncestor(),
element->State().HasState(NS_EVENT_STATE_FULL_SCREEN),
"Fullscreen element should have fullscreen styles applied");
return element;
}

Просмотреть файл

@ -696,6 +696,11 @@ public:
return mSandboxFlags;
}
/**
* Get string representation of sandbox flags (null if no flags are set)
*/
void GetSandboxFlagsAsString(nsAString& aFlags);
/**
* Set the sandbox flags for this document.
* @see nsSandboxFlags.h for the possible flags

Просмотреть файл

@ -721,7 +721,8 @@ nsObjectLoadingContent::nsObjectLoadingContent()
, mActivated(false)
, mIsStopping(false)
, mIsLoading(false)
, mScriptRequested(false) {}
, mScriptRequested(false)
, mRewrittenYoutubeEmbed(false) {}
nsObjectLoadingContent::~nsObjectLoadingContent()
{
@ -1843,6 +1844,7 @@ nsObjectLoadingContent::UpdateObjectParameters(bool aJavaURI)
NS_NOTREACHED("Unrecognized plugin-loading tag");
}
mRewrittenYoutubeEmbed = false;
// Note that the baseURI changing could affect the newURI, even if uriStr did
// not change.
if (!uriStr.IsEmpty()) {
@ -1856,6 +1858,7 @@ nsObjectLoadingContent::UpdateObjectParameters(bool aJavaURI)
getter_AddRefs(rewrittenURI));
if (rewrittenURI) {
newURI = rewrittenURI;
mRewrittenYoutubeEmbed = true;
newMime = NS_LITERAL_CSTRING("text/html");
}

Просмотреть файл

@ -250,6 +250,11 @@ class nsObjectLoadingContent : public nsImageLoadingContent
return runID;
}
bool IsRewrittenYoutubeEmbed() const
{
return mRewrittenYoutubeEmbed;
}
protected:
/**
* Begins loading the object when called
@ -628,7 +633,7 @@ class nsObjectLoadingContent : public nsImageLoadingContent
FallbackType mFallbackType : 8;
uint32_t mRunID;
bool mHasRunID;
bool mHasRunID : 1;
// If true, we have opened a channel as the listener and it has reached
// OnStartRequest. Does not get set for channels that are passed directly to
@ -658,6 +663,12 @@ class nsObjectLoadingContent : public nsImageLoadingContent
// whether content js has tried to access the plugin script object.
bool mScriptRequested : 1;
// True if object represents an object/embed tag pointing to a flash embed
// for a youtube video. When possible (see IsRewritableYoutubeEmbed function
// comments for details), we change these to try to load HTML5 versions of
// videos.
bool mRewrittenYoutubeEmbed : 1;
nsWeakFrame mPrintFrame;
RefPtr<nsPluginInstanceOwner> mInstanceOwner;

Просмотреть файл

@ -19,6 +19,8 @@
#include "nsIWeakReference.h"
#include "mozilla/Services.h"
#include "nsIInterfaceRequestorUtils.h"
#include "nsIPermissionManager.h"
#include "nsIDocument.h"
using namespace mozilla;
using namespace mozilla::dom;
@ -66,7 +68,8 @@ NS_INTERFACE_MAP_END
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(nsPluginArray,
mWindow,
mPlugins)
mPlugins,
mCTPPlugins)
static void
GetPluginMimeTypes(const nsTArray<RefPtr<nsPluginElement> >& aPlugins,
@ -146,6 +149,7 @@ nsPluginArray::Refresh(bool aReloadDocuments)
}
mPlugins.Clear();
mCTPPlugins.Clear();
nsCOMPtr<nsIDOMNavigator> navigator = mWindow->GetNavigator();
@ -221,6 +225,13 @@ nsPluginArray::NamedGetter(const nsAString& aName, bool &aFound)
nsPluginElement* plugin = FindPlugin(mPlugins, aName);
aFound = (plugin != nullptr);
if (!aFound) {
nsPluginElement* hiddenPlugin = FindPlugin(mCTPPlugins, aName);
if (hiddenPlugin) {
nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
obs->NotifyObservers(hiddenPlugin->PluginTag(), "Plugin::HiddenPluginTouched", nsString(aName).get());
}
}
return plugin;
}
@ -282,7 +293,7 @@ operator<(const RefPtr<nsPluginElement>& lhs,
void
nsPluginArray::EnsurePlugins()
{
if (!mPlugins.IsEmpty()) {
if (!mPlugins.IsEmpty() || !mCTPPlugins.IsEmpty()) {
// We already have an array of plugin elements.
return;
}
@ -299,7 +310,31 @@ nsPluginArray::EnsurePlugins()
// need to wrap each of these with a nsPluginElement, which is
// scriptable.
for (uint32_t i = 0; i < pluginTags.Length(); ++i) {
mPlugins.AppendElement(new nsPluginElement(mWindow, pluginTags[i]));
nsCOMPtr<nsPluginTag> pluginTag = do_QueryInterface(pluginTags[i]);
if (!pluginTag) {
mPlugins.AppendElement(new nsPluginElement(mWindow, pluginTags[i]));
} else if (pluginTag->IsActive()) {
uint32_t permission = nsIPermissionManager::ALLOW_ACTION;
if (pluginTag->IsClicktoplay()) {
nsCString name;
pluginTag->GetName(name);
if (NS_LITERAL_CSTRING("Shockwave Flash").Equals(name)) {
RefPtr<nsPluginHost> pluginHost = nsPluginHost::GetInst();
nsCString permString;
nsresult rv = pluginHost->GetPermissionStringForTag(pluginTag, 0, permString);
if (rv == NS_OK) {
nsIPrincipal* principal = mWindow->GetExtantDoc()->NodePrincipal();
nsCOMPtr<nsIPermissionManager> permMgr = services::GetPermissionManager();
permMgr->TestPermissionFromPrincipal(principal, permString.get(), &permission);
}
}
}
if (permission == nsIPermissionManager::ALLOW_ACTION) {
mPlugins.AppendElement(new nsPluginElement(mWindow, pluginTags[i]));
} else {
mCTPPlugins.AppendElement(new nsPluginElement(mWindow, pluginTags[i]));
}
}
}
// Alphabetize the enumeration order of non-hidden plugins to reduce

Просмотреть файл

@ -60,6 +60,10 @@ private:
nsCOMPtr<nsPIDOMWindowInner> mWindow;
nsTArray<RefPtr<nsPluginElement> > mPlugins;
/* A separate list of click-to-play plugins that we don't tell content
* about but keep track of so we can still prompt the user to click to play.
*/
nsTArray<RefPtr<nsPluginElement> > mCTPPlugins;
};
class nsPluginElement final : public nsISupports,

Просмотреть файл

@ -12,6 +12,11 @@
#ifndef nsSandboxFlags_h___
#define nsSandboxFlags_h___
/**
* This constant denotes the lack of a sandbox attribute/directive.
*/
const unsigned long SANDBOXED_NONE = 0x0;
/**
* This flag prevents content from navigating browsing contexts other than
* itself, browsing contexts nested inside it, the top-level browsing context

Просмотреть файл

@ -0,0 +1,65 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=1240471
-->
<head>
<meta charset="utf-8">
<title>Test for Bug 1240471</title>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<script type="application/javascript">
let SimpleTest = {
finish: function() {
parent.postMessage(JSON.stringify({fn: "finish"}), "*");
}
};
["ok", "is", "info"].forEach(fn => {
self[fn] = function (...args) {
parent.postMessage(JSON.stringify({fn: fn, args: args}), "*");
}
});
"use strict";
function onLoad() {
let youtube_changed_url_query = "https://mochitest.youtube.com/embed/Xm5i5kbIXzc?start=10&end=20";
function testEmbed(embed, expected_url, expected_fullscreen) {
ok (!!embed, "Embed node exists");
// getSVGDocument will return HTMLDocument if the content is HTML
let doc = embed.getSVGDocument();
// doc must be unprivileged because privileged doc will always be
// allowed to use fullscreen.
is (doc.fullscreenEnabled, expected_fullscreen,
"fullscreen should be " + (expected_fullscreen ? "enabled" : "disabled"));
embed = SpecialPowers.wrap(embed);
is (embed.srcURI.spec, expected_url, "Should have src uri of " + expected_url);
}
info("Running youtube rewrite query test");
testEmbed(document.getElementById("testembed-correct"), youtube_changed_url_query, false);
testEmbed(document.getElementById("testembed-correct-fs"), youtube_changed_url_query, true);
testEmbed(document.getElementById("testembed-wrong"), youtube_changed_url_query, false);
testEmbed(document.getElementById("testembed-whywouldyouevendothat"), youtube_changed_url_query, true);
SimpleTest.finish();
}
</script>
</head>
<body onload="onLoad()">
<embed id="testembed-correct"
src="https://mochitest.youtube.com/v/Xm5i5kbIXzc?start=10&end=20"
type="application/x-shockwave-flash"
allowscriptaccess="always"></embed>
<embed id="testembed-correct-fs"
src="https://mochitest.youtube.com/v/Xm5i5kbIXzc?start=10&end=20"
type="application/x-shockwave-flash"
allowfullscreen
allowscriptaccess="always"></embed>
<embed id="testembed-wrong"
src="https://mochitest.youtube.com/v/Xm5i5kbIXzc&start=10&end=20"
type="application/x-shockwave-flash"
allowscriptaccess="always"></embed>
<embed id="testembed-whywouldyouevendothat"
src="https://mochitest.youtube.com/v/Xm5i5kbIXzc&start=10?end=20"
type="application/x-shockwave-flash"
allowfullscreen
allowscriptaccess="always"></embed>
</body>
</html>

Просмотреть файл

@ -189,6 +189,7 @@ support-files =
file_xhtmlserializer_2_enthtml.xhtml
file_xhtmlserializer_2_entw3c.xhtml
file_xhtmlserializer_2_latin1.xhtml
file_youtube_flash_embed.html
fileapi_chromeScript.js
fileutils.js
forRemoval.resource

Просмотреть файл

@ -10,35 +10,23 @@
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<script type="application/javascript">
SimpleTest.waitForExplicitFinish();
"use strict";
function onLoad () {
let youtube_changed_url_query = "https://mochitest.youtube.com/embed/Xm5i5kbIXzc?start=10&end=20";
function testEmbed(embed, expected_url) {
ok (embed, "Embed node exists");
embed = SpecialPowers.wrap(embed);
is (embed.srcURI.spec, expected_url, "Should have src uri of " + expected_url);
let path = location.pathname.substring(0, location.pathname.lastIndexOf('/')) + '/file_youtube_flash_embed.html';
onmessage = function(e) {
let msg = JSON.parse(e.data);
if (msg.fn == "finish") {
SimpleTest.finish();
return;
}
info("Running youtube rewrite query test");
testEmbed(document.getElementById("testembed-correct"), youtube_changed_url_query);
testEmbed(document.getElementById("testembed-wrong"), youtube_changed_url_query);
testEmbed(document.getElementById("testembed-whywouldyouevendothat"), youtube_changed_url_query);
SimpleTest.finish();
self[msg.fn].apply(null, msg.args);
}
function onLoad() {
// The test file must be loaded into youtube.com domain
// because it needs unprivileged access to fullscreenEnabled.
ifr.src = "https://mochitest.youtube.com" + path;
}
</script>
</head>
<body onload="onLoad()">
<embed id="testembed-correct"
src="https://mochitest.youtube.com/v/Xm5i5kbIXzc?start=10&end=20"
type="application/x-shockwave-flash"
allowscriptaccess="always"></embed>
<embed id="testembed-wrong"
src="https://mochitest.youtube.com/v/Xm5i5kbIXzc&start=10&end=20"
type="application/x-shockwave-flash"
allowscriptaccess="always"></embed>
<embed id="testembed-whywouldyouevendothat"
src="https://mochitest.youtube.com/v/Xm5i5kbIXzc&start=10?end=20"
type="application/x-shockwave-flash"
allowscriptaccess="always"></embed>
<iframe id="ifr" allowfullscreen></iframe>
</body>
</html>

Просмотреть файл

@ -241,12 +241,12 @@ IsNotDateOrRegExp(JSContext* cx, JS::Handle<JSObject*> obj,
{
MOZ_ASSERT(obj);
js::ESClassValue cls;
js::ESClass cls;
if (!js::GetBuiltinClass(cx, obj, &cls)) {
return false;
}
*notDateOrRegExp = cls != js::ESClass_Date && cls != js::ESClass_RegExp;
*notDateOrRegExp = cls != js::ESClass::Date && cls != js::ESClass::RegExp;
return true;
}

Просмотреть файл

@ -249,15 +249,7 @@ class TestWebIDLCodegenManager(unittest.TestCase):
args = self._get_manager_args()
m1 = WebIDLCodegenManager(**args)
with MockedOpen({fake_path: '# Original content'}):
old_exists = os.path.exists
try:
def exists(p):
if p == fake_path:
return True
return old_exists(p)
os.path.exists = exists
result = m1.generate_build_files()
l = len(result.inputs)
@ -271,7 +263,6 @@ class TestWebIDLCodegenManager(unittest.TestCase):
result = m2.generate_build_files()
self.assertEqual(len(result.inputs), 0)
finally:
os.path.exists = old_exists
del sys.modules['mozwebidlcodegen.fakemodule']
def test_copy_input(self):

Просмотреть файл

@ -55,12 +55,6 @@
namespace mozilla {
namespace dom {
namespace workers {
extern bool IsCurrentThreadRunningChromeWorker();
} // namespace workers
} // namespace dom
using namespace dom;
using namespace hal;
@ -1344,24 +1338,6 @@ EventListenerManager::Disconnect()
RemoveAllListeners();
}
static EventListenerFlags
GetEventListenerFlagsFromOptions(const EventListenerOptions& aOptions,
bool aIsMainThread)
{
EventListenerFlags flags;
flags.mCapture = aOptions.mCapture;
if (aOptions.mMozSystemGroup) {
if (aIsMainThread) {
JSContext* cx = nsContentUtils::GetCurrentJSContext();
MOZ_ASSERT(cx, "Not being called from JS?");
flags.mInSystemGroup = IsChromeOrXBL(cx, nullptr);
} else {
flags.mInSystemGroup = workers::IsCurrentThreadRunningChromeWorker();
}
}
return flags;
}
void
EventListenerManager::AddEventListener(
const nsAString& aType,
@ -1387,7 +1363,8 @@ EventListenerManager::AddEventListener(
flags.mCapture = aOptions.GetAsBoolean();
} else {
const auto& options = aOptions.GetAsAddEventListenerOptions();
flags = GetEventListenerFlagsFromOptions(options, mIsMainThreadELM);
flags.mCapture = options.mCapture;
flags.mInSystemGroup = options.mMozSystemGroup;
flags.mPassive = options.mPassive;
}
flags.mAllowUntrustedEvents = aWantsUntrusted;
@ -1416,7 +1393,8 @@ EventListenerManager::RemoveEventListener(
flags.mCapture = aOptions.GetAsBoolean();
} else {
const auto& options = aOptions.GetAsEventListenerOptions();
flags = GetEventListenerFlagsFromOptions(options, mIsMainThreadELM);
flags.mCapture = options.mCapture;
flags.mInSystemGroup = options.mMozSystemGroup;
}
RemoveEventListenerByType(aListenerHolder, aType, flags);
}

Просмотреть файл

@ -4817,26 +4817,11 @@ static nsIContent* FindCommonAncestor(nsIContent *aNode1, nsIContent *aNode2)
return nullptr;
}
static Element*
GetParentElement(Element* aElement)
{
nsIContent* p = aElement->GetParent();
return (p && p->IsElement()) ? p->AsElement() : nullptr;
}
/* static */
void
EventStateManager::SetFullScreenState(Element* aElement, bool aIsFullScreen)
{
DoStateChange(aElement, NS_EVENT_STATE_FULL_SCREEN, aIsFullScreen);
Element* ancestor = aElement;
while ((ancestor = GetParentElement(ancestor))) {
DoStateChange(ancestor, NS_EVENT_STATE_FULL_SCREEN_ANCESTOR, aIsFullScreen);
if (ancestor->State().HasState(NS_EVENT_STATE_FULL_SCREEN)) {
// If we meet another fullscreen element, stop here.
break;
}
}
}
/* static */

Просмотреть файл

@ -262,8 +262,8 @@ private:
// Content is the full screen element, or a frame containing the
// current full-screen element.
#define NS_EVENT_STATE_FULL_SCREEN NS_DEFINE_EVENT_STATE_MACRO(33)
// Content is an ancestor of the DOM full-screen element.
#define NS_EVENT_STATE_FULL_SCREEN_ANCESTOR NS_DEFINE_EVENT_STATE_MACRO(34)
// This bit is currently free.
// #define NS_EVENT_STATE_?????????? NS_DEFINE_EVENT_STATE_MACRO(34)
// Handler for click to play plugin
#define NS_EVENT_STATE_TYPE_CLICK_TO_PLAY NS_DEFINE_EVENT_STATE_MACRO(35)
// Content is in the optimum region.
@ -299,8 +299,7 @@ private:
#define ESM_MANAGED_STATES (NS_EVENT_STATE_ACTIVE | NS_EVENT_STATE_FOCUS | \
NS_EVENT_STATE_HOVER | NS_EVENT_STATE_DRAGOVER | \
NS_EVENT_STATE_URLTARGET | NS_EVENT_STATE_FOCUSRING | \
NS_EVENT_STATE_FULL_SCREEN | NS_EVENT_STATE_FULL_SCREEN_ANCESTOR | \
NS_EVENT_STATE_UNRESOLVED)
NS_EVENT_STATE_FULL_SCREEN | NS_EVENT_STATE_UNRESOLVED)
#define INTRINSIC_STATES (~ESM_MANAGED_STATES)

Просмотреть файл

@ -57,7 +57,8 @@ HttpServer::Init(int32_t aPort, bool aHttps, HttpServerListener* aListener)
if (mHttps) {
nsCOMPtr<nsILocalCertService> lcs =
do_CreateInstance("@mozilla.org/security/local-cert-service;1");
nsresult rv = lcs->GetOrCreateCert(NS_LITERAL_CSTRING("flyweb"), this);
nsresult rv = lcs->GetOrCreateCert(NS_LITERAL_CSTRING("flyweb"), this,
nsILocalCertService::KEY_TYPE_EC);
if (NS_FAILED(rv)) {
NotifyStarted(rv);
}

Просмотреть файл

@ -4,56 +4,6 @@
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
EXPORTS.mozilla.dom += [
'Gamepad.h',
'GamepadButton.h',
'GamepadManager.h',
'GamepadMonitoring.h',
'GamepadPlatformService.h',
'GamepadServiceTest.h',
'ipc/GamepadEventChannelChild.h',
'ipc/GamepadEventChannelParent.h',
'ipc/GamepadTestChannelChild.h',
'ipc/GamepadTestChannelParent.h'
]
UNIFIED_SOURCES = [
'Gamepad.cpp',
'GamepadButton.cpp',
'GamepadManager.cpp',
'GamepadMonitoring.cpp',
'GamepadPlatformService.cpp',
'GamepadServiceTest.cpp',
'ipc/GamepadEventChannelChild.cpp',
'ipc/GamepadEventChannelParent.cpp',
'ipc/GamepadTestChannelChild.cpp',
'ipc/GamepadTestChannelParent.cpp'
]
if CONFIG['MOZ_GAMEPAD_BACKEND'] == 'stub':
UNIFIED_SOURCES += [
'fallback/FallbackGamepad.cpp'
]
elif CONFIG['MOZ_GAMEPAD_BACKEND'] == 'cocoa':
UNIFIED_SOURCES += [
'cocoa/CocoaGamepad.cpp'
]
elif CONFIG['MOZ_GAMEPAD_BACKEND'] == 'windows':
UNIFIED_SOURCES += [
'windows/WindowsGamepad.cpp'
]
elif CONFIG['MOZ_GAMEPAD_BACKEND'] == 'linux':
UNIFIED_SOURCES += [
'linux/LinuxGamepad.cpp'
]
elif CONFIG['MOZ_GAMEPAD_BACKEND'] == 'android':
UNIFIED_SOURCES += [
'android/AndroidGamepad.cpp'
]
LOCAL_INCLUDES += [
'ipc',
]
IPDL_SOURCES += [
'ipc/GamepadEventTypes.ipdlh',
@ -61,14 +11,66 @@ IPDL_SOURCES += [
'ipc/PGamepadTestChannel.ipdl'
]
include('/ipc/chromium/chromium-config.mozbuild')
if CONFIG['MOZ_GAMEPAD']:
EXPORTS.mozilla.dom += [
'Gamepad.h',
'GamepadButton.h',
'GamepadManager.h',
'GamepadMonitoring.h',
'GamepadPlatformService.h',
'GamepadServiceTest.h',
'ipc/GamepadEventChannelChild.h',
'ipc/GamepadEventChannelParent.h',
'ipc/GamepadTestChannelChild.h',
'ipc/GamepadTestChannelParent.h'
]
FINAL_LIBRARY = 'xul'
LOCAL_INCLUDES += [
'/dom/base',
]
UNIFIED_SOURCES = [
'Gamepad.cpp',
'GamepadButton.cpp',
'GamepadManager.cpp',
'GamepadMonitoring.cpp',
'GamepadPlatformService.cpp',
'GamepadServiceTest.cpp',
'ipc/GamepadEventChannelChild.cpp',
'ipc/GamepadEventChannelParent.cpp',
'ipc/GamepadTestChannelChild.cpp',
'ipc/GamepadTestChannelParent.cpp'
]
CFLAGS += CONFIG['GLIB_CFLAGS']
CFLAGS += CONFIG['MOZ_DBUS_GLIB_CFLAGS']
CXXFLAGS += CONFIG['GLIB_CFLAGS']
CXXFLAGS += CONFIG['MOZ_DBUS_GLIB_CFLAGS']
if CONFIG['MOZ_GAMEPAD_BACKEND'] == 'stub':
UNIFIED_SOURCES += [
'fallback/FallbackGamepad.cpp'
]
elif CONFIG['MOZ_GAMEPAD_BACKEND'] == 'cocoa':
UNIFIED_SOURCES += [
'cocoa/CocoaGamepad.cpp'
]
elif CONFIG['MOZ_GAMEPAD_BACKEND'] == 'windows':
UNIFIED_SOURCES += [
'windows/WindowsGamepad.cpp'
]
elif CONFIG['MOZ_GAMEPAD_BACKEND'] == 'linux':
UNIFIED_SOURCES += [
'linux/LinuxGamepad.cpp'
]
elif CONFIG['MOZ_GAMEPAD_BACKEND'] == 'android':
UNIFIED_SOURCES += [
'android/AndroidGamepad.cpp'
]
LOCAL_INCLUDES += [
'ipc',
]
include('/ipc/chromium/chromium-config.mozbuild')
FINAL_LIBRARY = 'xul'
LOCAL_INCLUDES += [
'/dom/base',
]
CFLAGS += CONFIG['GLIB_CFLAGS']
CFLAGS += CONFIG['MOZ_DBUS_GLIB_CFLAGS']
CXXFLAGS += CONFIG['GLIB_CFLAGS']
CXXFLAGS += CONFIG['MOZ_DBUS_GLIB_CFLAGS']

Просмотреть файл

@ -242,17 +242,10 @@ HTMLIFrameElement::GetSandboxFlags()
const nsAttrValue* sandboxAttr = GetParsedAttr(nsGkAtoms::sandbox);
// No sandbox attribute, no sandbox flags.
if (!sandboxAttr) {
return 0;
return SANDBOXED_NONE;
}
// Start off by setting all the restriction flags.
uint32_t out = SANDBOX_ALL_FLAGS;
// Macro for updating the flag according to the keywords
#define SANDBOX_KEYWORD(string, atom, flags) \
if (sandboxAttr->Contains(nsGkAtoms::atom, eIgnoreCase)) { out &= ~(flags); }
#include "IframeSandboxKeywordList.h"
#undef SANDBOX_KEYWORD
uint32_t out = nsContentUtils::ParseSandboxAttributeToFlags(sandboxAttr);
if (GetParsedAttr(nsGkAtoms::allowfullscreen) ||
GetParsedAttr(nsGkAtoms::mozallowfullscreen)) {

Просмотреть файл

@ -3165,7 +3165,13 @@ HTMLInputElement::GetDisplayFileName(nsAString& aValue) const
nsXPIDLString value;
if (mFilesOrDirectories.IsEmpty()) {
if (HasAttr(kNameSpaceID_None, nsGkAtoms::multiple)) {
if ((Preferences::GetBool("dom.input.dirpicker", false) &&
HasAttr(kNameSpaceID_None, nsGkAtoms::directory)) ||
(Preferences::GetBool("dom.webkitBlink.dirPicker.enabled", false) &&
HasAttr(kNameSpaceID_None, nsGkAtoms::webkitdirectory))) {
nsContentUtils::GetLocalizedString(nsContentUtils::eFORMS_PROPERTIES,
"NoDirSelected", value);
} else if (HasAttr(kNameSpaceID_None, nsGkAtoms::multiple)) {
nsContentUtils::GetLocalizedString(nsContentUtils::eFORMS_PROPERTIES,
"NoFilesSelected", value);
} else {
@ -4405,12 +4411,10 @@ HTMLInputElement::MaybeInitPickers(EventChainPostVisitor& aVisitor)
if (target &&
target->GetParent() == this &&
target->IsRootOfNativeAnonymousSubtree() &&
(target->HasAttr(kNameSpaceID_None, nsGkAtoms::directory) ||
target->HasAttr(kNameSpaceID_None, nsGkAtoms::webkitdirectory))) {
MOZ_ASSERT(Preferences::GetBool("dom.input.dirpicker", false) ||
Preferences::GetBool("dom.webkitBlink.dirPicker.enabled", false),
"No API or UI should have been exposed to allow this code to "
"be reached");
((Preferences::GetBool("dom.input.dirpicker", false) &&
HasAttr(kNameSpaceID_None, nsGkAtoms::directory)) ||
(Preferences::GetBool("dom.webkitBlink.dirPicker.enabled", false) &&
HasAttr(kNameSpaceID_None, nsGkAtoms::webkitdirectory)))) {
type = FILE_PICKER_DIRECTORY;
}
return InitFilePicker(type);

Просмотреть файл

@ -304,7 +304,7 @@ public:
private:
RefPtr<HTMLMediaElement> mElement;
nsCOMPtr<nsIStreamListener> mNextListener;
uint32_t mLoadID;
const uint32_t mLoadID;
};
NS_IMPL_ISUPPORTS(HTMLMediaElement::MediaLoadListener, nsIRequestObserver,
@ -313,7 +313,8 @@ NS_IMPL_ISUPPORTS(HTMLMediaElement::MediaLoadListener, nsIRequestObserver,
NS_IMETHODIMP
HTMLMediaElement::MediaLoadListener::Observe(nsISupports* aSubject,
const char* aTopic, const char16_t* aData)
const char* aTopic,
const char16_t* aData)
{
nsContentUtils::UnregisterShutdownObserver(this);
@ -322,21 +323,9 @@ HTMLMediaElement::MediaLoadListener::Observe(nsISupports* aSubject,
return NS_OK;
}
void HTMLMediaElement::ReportLoadError(const char* aMsg,
const char16_t** aParams,
uint32_t aParamCount)
{
nsContentUtils::ReportToConsole(nsIScriptError::warningFlag,
NS_LITERAL_CSTRING("Media"),
OwnerDoc(),
nsContentUtils::eDOM_PROPERTIES,
aMsg,
aParams,
aParamCount);
}
NS_IMETHODIMP HTMLMediaElement::MediaLoadListener::OnStartRequest(nsIRequest* aRequest, nsISupports* aContext)
NS_IMETHODIMP
HTMLMediaElement::MediaLoadListener::OnStartRequest(nsIRequest* aRequest,
nsISupports* aContext)
{
nsContentUtils::UnregisterShutdownObserver(this);
@ -394,14 +383,12 @@ NS_IMETHODIMP HTMLMediaElement::MediaLoadListener::OnStartRequest(nsIRequest* aR
nsCOMPtr<nsIChannel> channel = do_QueryInterface(aRequest);
if (channel &&
element &&
NS_SUCCEEDED(rv = element->InitializeDecoderForChannel(channel, getter_AddRefs(mNextListener))) &&
mNextListener) {
rv = mNextListener->OnStartRequest(aRequest, aContext);
} else {
// If InitializeDecoderForChannel() returned an error, fire a network
// error.
if (NS_FAILED(rv) && !mNextListener && element) {
// If InitializeDecoderForChannel() returned an error, fire a network error.
if (NS_FAILED(rv) && !mNextListener) {
// Load failed, attempt to load the next candidate resource. If there
// are none, this will trigger a MEDIA_ERR_SRC_NOT_SUPPORTED error.
element->NotifyLoadError();
@ -415,8 +402,10 @@ NS_IMETHODIMP HTMLMediaElement::MediaLoadListener::OnStartRequest(nsIRequest* aR
return rv;
}
NS_IMETHODIMP HTMLMediaElement::MediaLoadListener::OnStopRequest(nsIRequest* aRequest, nsISupports* aContext,
nsresult aStatus)
NS_IMETHODIMP
HTMLMediaElement::MediaLoadListener::OnStopRequest(nsIRequest* aRequest,
nsISupports* aContext,
nsresult aStatus)
{
if (mNextListener) {
return mNextListener->OnStopRequest(aRequest, aContext, aStatus);
@ -438,27 +427,210 @@ HTMLMediaElement::MediaLoadListener::OnDataAvailable(nsIRequest* aRequest,
return mNextListener->OnDataAvailable(aRequest, aContext, aStream, aOffset, aCount);
}
NS_IMETHODIMP HTMLMediaElement::MediaLoadListener::AsyncOnChannelRedirect(nsIChannel* aOldChannel,
nsIChannel* aNewChannel,
uint32_t aFlags,
nsIAsyncVerifyRedirectCallback* cb)
NS_IMETHODIMP
HTMLMediaElement::MediaLoadListener::AsyncOnChannelRedirect(nsIChannel* aOldChannel,
nsIChannel* aNewChannel,
uint32_t aFlags,
nsIAsyncVerifyRedirectCallback* cb)
{
// TODO is this really correct?? See bug #579329.
if (mElement)
if (mElement) {
mElement->OnChannelRedirect(aOldChannel, aNewChannel, aFlags);
}
nsCOMPtr<nsIChannelEventSink> sink = do_QueryInterface(mNextListener);
if (sink)
if (sink) {
return sink->AsyncOnChannelRedirect(aOldChannel, aNewChannel, aFlags, cb);
}
cb->OnRedirectVerifyCallback(NS_OK);
return NS_OK;
}
NS_IMETHODIMP HTMLMediaElement::MediaLoadListener::GetInterface(const nsIID & aIID, void **aResult)
NS_IMETHODIMP
HTMLMediaElement::MediaLoadListener::GetInterface(const nsIID& aIID,
void** aResult)
{
return QueryInterface(aIID, aResult);
}
void HTMLMediaElement::ReportLoadError(const char* aMsg,
const char16_t** aParams,
uint32_t aParamCount)
{
nsContentUtils::ReportToConsole(nsIScriptError::warningFlag,
NS_LITERAL_CSTRING("Media"),
OwnerDoc(),
nsContentUtils::eDOM_PROPERTIES,
aMsg,
aParams,
aParamCount);
}
class HTMLMediaElement::ChannelLoader final {
public:
NS_INLINE_DECL_REFCOUNTING(ChannelLoader);
void LoadInternal(HTMLMediaElement* aElement)
{
if (mCancelled) {
return;
}
// determine what security checks need to be performed in AsyncOpen2().
nsSecurityFlags securityFlags = aElement->ShouldCheckAllowOrigin()
? nsILoadInfo::SEC_REQUIRE_CORS_DATA_INHERITS :
nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_INHERITS;
if (aElement->GetCORSMode() == CORS_USE_CREDENTIALS) {
securityFlags |= nsILoadInfo::SEC_COOKIES_INCLUDE;
}
MOZ_ASSERT(aElement->IsAnyOfHTMLElements(nsGkAtoms::audio, nsGkAtoms::video));
nsContentPolicyType contentPolicyType = aElement->IsHTMLElement(nsGkAtoms::audio)
? nsIContentPolicy::TYPE_INTERNAL_AUDIO :
nsIContentPolicy::TYPE_INTERNAL_VIDEO;
nsCOMPtr<nsIDocShell> docShell = aElement->OwnerDoc()->GetDocShell();
if (docShell) {
nsDocShell* docShellPtr = nsDocShell::Cast(docShell);
bool privateBrowsing;
docShellPtr->GetUsePrivateBrowsing(&privateBrowsing);
if (privateBrowsing) {
securityFlags |= nsILoadInfo::SEC_FORCE_PRIVATE_BROWSING;
}
}
nsCOMPtr<nsILoadGroup> loadGroup = aElement->GetDocumentLoadGroup();
nsCOMPtr<nsIChannel> channel;
nsresult rv = NS_NewChannel(getter_AddRefs(channel),
aElement->mLoadingSrc,
static_cast<Element*>(aElement),
securityFlags,
contentPolicyType,
loadGroup,
nullptr, // aCallbacks
nsICachingChannel::LOAD_BYPASS_LOCAL_CACHE_IF_BUSY |
nsIChannel::LOAD_MEDIA_SNIFFER_OVERRIDES_CONTENT_TYPE |
nsIChannel::LOAD_CLASSIFY_URI |
nsIChannel::LOAD_CALL_CONTENT_SNIFFERS);
if (NS_FAILED(rv)) {
// Notify load error so the element will try next resource candidate.
aElement->NotifyLoadError();
return;
}
// This is a workaround and it will be fix in bug 1264230.
nsCOMPtr<nsILoadInfo> loadInfo = channel->GetLoadInfo();
if (loadInfo) {
NeckoOriginAttributes originAttrs;
NS_GetOriginAttributes(channel, originAttrs);
loadInfo->SetOriginAttributes(originAttrs);
}
// The listener holds a strong reference to us. This creates a
// reference cycle, once we've set mChannel, which is manually broken
// in the listener's OnStartRequest method after it is finished with
// the element. The cycle will also be broken if we get a shutdown
// notification before OnStartRequest fires. Necko guarantees that
// OnStartRequest will eventually fire if we don't shut down first.
RefPtr<MediaLoadListener> loadListener = new MediaLoadListener(aElement);
channel->SetNotificationCallbacks(loadListener);
nsCOMPtr<nsIHttpChannel> hc = do_QueryInterface(channel);
if (hc) {
// Use a byte range request from the start of the resource.
// This enables us to detect if the stream supports byte range
// requests, and therefore seeking, early.
hc->SetRequestHeader(NS_LITERAL_CSTRING("Range"),
NS_LITERAL_CSTRING("bytes=0-"),
false);
aElement->SetRequestHeaders(hc);
}
rv = channel->AsyncOpen2(loadListener);
if (NS_FAILED(rv)) {
// Notify load error so the element will try next resource candidate.
aElement->NotifyLoadError();
return;
}
// Else the channel must be open and starting to download. If it encounters
// a non-catastrophic failure, it will set a new task to continue loading
// another candidate. It's safe to set it as mChannel now.
mChannel = channel;
// loadListener will be unregistered either on shutdown or when
// OnStartRequest for the channel we just opened fires.
nsContentUtils::RegisterShutdownObserver(loadListener);
}
nsresult Load(HTMLMediaElement* aElement)
{
// Per bug 1235183 comment 8, we can't spin the event loop from stable
// state. Defer NS_NewChannel() to a new regular runnable.
return NS_DispatchToMainThread(NewRunnableMethod<HTMLMediaElement*>(
this, &ChannelLoader::LoadInternal, aElement));
}
void Cancel()
{
mCancelled = true;
if (mChannel) {
mChannel->Cancel(NS_BINDING_ABORTED);
mChannel = nullptr;
}
}
void Done() {
MOZ_ASSERT(mChannel);
// Decoder successfully created, the decoder now owns the MediaResource
// which owns the channel.
mChannel = nullptr;
}
nsresult Redirect(nsIChannel* aChannel,
nsIChannel* aNewChannel,
uint32_t aFlags)
{
NS_ASSERTION(aChannel == mChannel, "Channels should match!");
mChannel = aNewChannel;
// Handle forwarding of Range header so that the intial detection
// of seeking support (via result code 206) works across redirects.
nsCOMPtr<nsIHttpChannel> http = do_QueryInterface(aChannel);
NS_ENSURE_STATE(http);
NS_NAMED_LITERAL_CSTRING(rangeHdr, "Range");
nsAutoCString rangeVal;
if (NS_SUCCEEDED(http->GetRequestHeader(rangeHdr, rangeVal))) {
NS_ENSURE_STATE(!rangeVal.IsEmpty());
http = do_QueryInterface(aNewChannel);
NS_ENSURE_STATE(http);
nsresult rv = http->SetRequestHeader(rangeHdr, rangeVal, false);
NS_ENSURE_SUCCESS(rv, rv);
}
return NS_OK;
}
private:
~ChannelLoader()
{
MOZ_ASSERT(!mChannel);
}
// Holds a reference to the first channel we open to the media resource.
// Once the decoder is created, control over the channel passes to the
// decoder, and we null out this reference. We must store this in case
// we need to cancel the channel before control of it passes to the decoder.
nsCOMPtr<nsIChannel> mChannel;
bool mCancelled = false;
};
NS_IMPL_ADDREF_INHERITED(HTMLMediaElement, nsGenericHTMLElement)
NS_IMPL_RELEASE_INHERITED(HTMLMediaElement, nsGenericHTMLElement)
@ -672,28 +844,8 @@ HTMLMediaElement::OnChannelRedirect(nsIChannel* aChannel,
nsIChannel* aNewChannel,
uint32_t aFlags)
{
NS_ASSERTION(aChannel == mChannel, "Channels should match!");
mChannel = aNewChannel;
// Handle forwarding of Range header so that the intial detection
// of seeking support (via result code 206) works across redirects.
nsCOMPtr<nsIHttpChannel> http = do_QueryInterface(aChannel);
NS_ENSURE_STATE(http);
NS_NAMED_LITERAL_CSTRING(rangeHdr, "Range");
nsAutoCString rangeVal;
if (NS_SUCCEEDED(http->GetRequestHeader(rangeHdr, rangeVal))) {
NS_ENSURE_STATE(!rangeVal.IsEmpty());
http = do_QueryInterface(aNewChannel);
NS_ENSURE_STATE(http);
nsresult rv = http->SetRequestHeader(rangeHdr, rangeVal, false);
NS_ENSURE_SUCCESS(rv, rv);
}
return NS_OK;
MOZ_ASSERT(mChannelLoader);
return mChannelLoader->Redirect(aChannel, aNewChannel, aFlags);
}
void HTMLMediaElement::ShutdownDecoder()
@ -721,6 +873,11 @@ void HTMLMediaElement::AbortExistingLoads()
// with a different load ID to silently be cancelled.
mCurrentLoadID++;
if (mChannelLoader) {
mChannelLoader->Cancel();
mChannelLoader = nullptr;
}
bool fireTimeUpdate = false;
// When aborting the existing loads, empty the objects in audio track list and
@ -1250,9 +1407,9 @@ nsresult HTMLMediaElement::LoadResource()
NS_ASSERTION(mDelayingLoadEvent,
"Should delay load event (if in document) during load");
if (mChannel) {
mChannel->Cancel(NS_BINDING_ABORTED);
mChannel = nullptr;
if (mChannelLoader) {
mChannelLoader->Cancel();
mChannelLoader = nullptr;
}
// Check if media is allowed for the docshell.
@ -1308,87 +1465,12 @@ nsresult HTMLMediaElement::LoadResource()
return FinishDecoderSetup(decoder, resource, nullptr);
}
// determine what security checks need to be performed in AsyncOpen2().
nsSecurityFlags securityFlags =
ShouldCheckAllowOrigin() ? nsILoadInfo::SEC_REQUIRE_CORS_DATA_INHERITS :
nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_INHERITS;
if (GetCORSMode() == CORS_USE_CREDENTIALS) {
securityFlags |= nsILoadInfo::SEC_COOKIES_INCLUDE;
RefPtr<ChannelLoader> loader = new ChannelLoader;
nsresult rv = loader->Load(this);
if (NS_SUCCEEDED(rv)) {
mChannelLoader = loader.forget();
}
MOZ_ASSERT(IsAnyOfHTMLElements(nsGkAtoms::audio, nsGkAtoms::video));
nsContentPolicyType contentPolicyType = IsHTMLElement(nsGkAtoms::audio) ?
nsIContentPolicy::TYPE_INTERNAL_AUDIO : nsIContentPolicy::TYPE_INTERNAL_VIDEO;
nsDocShell* docShellPtr;
if (docShell) {
docShellPtr = nsDocShell::Cast(docShell);
bool privateBrowsing;
docShellPtr->GetUsePrivateBrowsing(&privateBrowsing);
if (privateBrowsing) {
securityFlags |= nsILoadInfo::SEC_FORCE_PRIVATE_BROWSING;
}
}
nsCOMPtr<nsILoadGroup> loadGroup = GetDocumentLoadGroup();
nsCOMPtr<nsIChannel> channel;
nsresult rv = NS_NewChannel(getter_AddRefs(channel),
mLoadingSrc,
static_cast<Element*>(this),
securityFlags,
contentPolicyType,
loadGroup,
nullptr, // aCallbacks
nsICachingChannel::LOAD_BYPASS_LOCAL_CACHE_IF_BUSY |
nsIChannel::LOAD_MEDIA_SNIFFER_OVERRIDES_CONTENT_TYPE |
nsIChannel::LOAD_CLASSIFY_URI |
nsIChannel::LOAD_CALL_CONTENT_SNIFFERS);
NS_ENSURE_SUCCESS(rv,rv);
// This is a workaround and it will be fix in bug 1264230.
nsCOMPtr<nsILoadInfo> loadInfo = channel->GetLoadInfo();
if (loadInfo) {
NeckoOriginAttributes originAttrs;
NS_GetOriginAttributes(channel, originAttrs);
loadInfo->SetOriginAttributes(originAttrs);
}
// The listener holds a strong reference to us. This creates a
// reference cycle, once we've set mChannel, which is manually broken
// in the listener's OnStartRequest method after it is finished with
// the element. The cycle will also be broken if we get a shutdown
// notification before OnStartRequest fires. Necko guarantees that
// OnStartRequest will eventually fire if we don't shut down first.
RefPtr<MediaLoadListener> loadListener = new MediaLoadListener(this);
channel->SetNotificationCallbacks(loadListener);
nsCOMPtr<nsIHttpChannel> hc = do_QueryInterface(channel);
if (hc) {
// Use a byte range request from the start of the resource.
// This enables us to detect if the stream supports byte range
// requests, and therefore seeking, early.
hc->SetRequestHeader(NS_LITERAL_CSTRING("Range"),
NS_LITERAL_CSTRING("bytes=0-"),
false);
SetRequestHeaders(hc);
}
rv = channel->AsyncOpen2(loadListener);
NS_ENSURE_SUCCESS(rv, rv);
// Else the channel must be open and starting to download. If it encounters
// a non-catastrophic failure, it will set a new task to continue loading
// another candidate. It's safe to set it as mChannel now.
mChannel = channel;
// loadListener will be unregistered either on shutdown or when
// OnStartRequest for the channel we just opened fires.
nsContentUtils::RegisterShutdownObserver(loadListener);
return NS_OK;
return rv;
}
nsresult HTMLMediaElement::LoadWithChannel(nsIChannel* aChannel,
@ -2400,8 +2482,8 @@ HTMLMediaElement::~HTMLMediaElement()
NS_ASSERTION(MediaElementTableCount(this, mLoadingSrc) == 0,
"Destroyed media element should no longer be in element table");
if (mChannel) {
mChannel->Cancel(NS_BINDING_ABORTED);
if (mChannelLoader) {
mChannelLoader->Cancel();
}
WakeLockRelease();
@ -3056,8 +3138,10 @@ nsresult HTMLMediaElement::InitializeDecoderForChannel(nsIChannel* aChannel,
if (!resource)
return NS_ERROR_OUT_OF_MEMORY;
// stream successfully created, the stream now owns the channel.
mChannel = nullptr;
if (mChannelLoader) {
mChannelLoader->Done();
mChannelLoader = nullptr;
}
// We postpone the |FinishDecoderSetup| function call until we get
// |OnConnected| signal from MediaStreamController which is held by
@ -3121,13 +3205,20 @@ nsresult HTMLMediaElement::FinishDecoderSetup(MediaDecoder* aDecoder,
#ifdef MOZ_EME
if (mMediaKeys) {
mDecoder->SetCDMProxy(mMediaKeys->GetCDMProxy());
if (mMediaKeys->GetCDMProxy()) {
mDecoder->SetCDMProxy(mMediaKeys->GetCDMProxy());
} else {
// CDM must have crashed.
ShutdownDecoder();
return NS_ERROR_FAILURE;
}
}
#endif
// Decoder successfully created, the decoder now owns the MediaResource
// which owns the channel.
mChannel = nullptr;
if (mChannelLoader) {
mChannelLoader->Done();
mChannelLoader = nullptr;
}
AddMediaElementToURITable();
@ -5411,6 +5502,12 @@ HTMLMediaElement::SetMediaKeys(mozilla::dom::MediaKeys* aMediaKeys,
// 5.3. If mediaKeys is not null, run the following steps:
if (aMediaKeys) {
if (!aMediaKeys->GetCDMProxy()) {
promise->MaybeReject(NS_ERROR_DOM_INVALID_STATE_ERR,
NS_LITERAL_CSTRING("CDM crashed before binding MediaKeys object to HTMLMediaElement"));
return promise.forget();
}
// 5.3.1 Associate the CDM instance represented by mediaKeys with the
// media element for decrypting media data.
if (NS_FAILED(aMediaKeys->Bind(this))) {

Просмотреть файл

@ -732,6 +732,7 @@ public:
protected:
virtual ~HTMLMediaElement();
class ChannelLoader;
class MediaLoadListener;
class MediaStreamTracksAvailableCallback;
class MediaStreamTrackListener;
@ -1255,11 +1256,7 @@ protected:
// that resolved to a MediaSource.
RefPtr<MediaSource> mMediaSource;
// Holds a reference to the first channel we open to the media resource.
// Once the decoder is created, control over the channel passes to the
// decoder, and we null out this reference. We must store this in case
// we need to cancel the channel before control of it passes to the decoder.
nsCOMPtr<nsIChannel> mChannel;
RefPtr<ChannelLoader> mChannelLoader;
// Error attribute
RefPtr<MediaError> mError;

Просмотреть файл

@ -155,12 +155,6 @@ function enter4(event) {
is(event.target, document, "Event target should be full-screen document #5");
is(document.fullscreenElement, inDocElement, "FSE should be inDocElement.");
var n = container;
do {
ok(n.matches(":-moz-full-screen-ancestor"), "Ancestor " + n + " should match :-moz-full-screen-ancestor")
n = n.parentNode;
} while (n && n.matches);
// Remove full-screen ancestor element from document, verify it stops being reported as current FSE.
addFullscreenChangeContinuation("exit", exit_to_arg_test_1);
container.parentNode.removeChild(container);

Просмотреть файл

@ -0,0 +1,17 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Test for Bug 671389</title>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
I am
<ul>
<li>sandboxed but with "allow-forms", "allow-pointer-lock", "allow-popups", "allow-same-origin", "allow-scripts", and "allow-top-navigation", </li>
<li>sandboxed but with "allow-same-origin", "allow-scripts", </li>
<li>sandboxed, or </li>
<li>not sandboxed.</li>
</ul>
</body>
</html>

Просмотреть файл

@ -98,6 +98,7 @@ support-files =
file_iframe_sandbox_c_if6.html
file_iframe_sandbox_c_if7.html
file_iframe_sandbox_c_if8.html
file_iframe_sandbox_c_if9.html
file_iframe_sandbox_close.html
file_iframe_sandbox_d_if1.html
file_iframe_sandbox_d_if10.html

Просмотреть файл

@ -41,7 +41,7 @@ function ok_wrapper(result, desc) {
passedTests++;
}
if (completedTests == 27) {
if (completedTests == 33) {
is(passedTests, completedTests, "There are " + completedTests + " general tests that should pass");
SimpleTest.finish();
}
@ -180,6 +180,14 @@ function doTest() {
// This is done via file_iframe_sandbox_c_if4.html which is sandboxed with "allow-scripts" and "allow-same-origin"
// the window it attempts to open calls window.opener.ok(false, ...) and file_iframe_c_if4.html has an ok()
// function that calls window.parent.ok_wrapper.
// passes twice if good
// 29-32) Test that sandboxFlagsAsString returns the set flags.
// see if_14 and if_15
// passes once if good
// 33) Test that sandboxFlagsAsString returns null if iframe does not have sandbox flag set.
// see if_16
}
addLoadEvent(doTest);
@ -212,6 +220,36 @@ function do_if_10() {
var if_10 = document.getElementById('if_10');
if_10.src = 'javascript:"<html><script>window.parent.ok_wrapper(true, \'an iframe sandboxed with allow-scripts should execute script in a javascript URL in a newly set src attribute\');<\/script><\/html>"';
}
function eqFlags(a, b) {
// both a and b should be either null or have the array same flags
if (a === null && b === null) { return true; }
if (a === null || b === null) { return false; }
if (a.length !== b.length) { return false; }
var a_sorted = a.sort();
var b_sorted = b.sort();
for (var i in a_sorted) {
if (a_sorted[i] !== b_sorted[i]) { return false; }
}
return true;
}
function getSandboxFlags(doc) {
var flags = doc.sandboxFlagsAsString;
if (flags === null) { return null; }
return flags? flags.split(" "):[];
}
function test_sandboxFlagsAsString(name, expected) {
var ifr = document.getElementById(name);
try {
var flags = getSandboxFlags(SpecialPowers.wrap(ifr).contentDocument);
ok_wrapper(eqFlags(flags, expected), name + ' expected: "' + expected + '", got: "' + flags + '"');
} catch (e) {
ok_wrapper(false, name + ' expected "' + expected + ', but failed with ' + e);
}
}
</script>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=341604">Mozilla Bug 341604</a> - Implement HTML5 sandbox attribute for IFRAMEs
@ -234,6 +272,10 @@ function do_if_10() {
<iframe sandbox="allow-same-origin allow-scripts" onload='start_if_10()' id='if_10' src="about:blank" height="10" width="10"></iframe>
<iframe sandbox="allow-scripts" id='if_11' src="file_iframe_sandbox_c_if7.html" height="10" width="10"></iframe>
<iframe sandbox="allow-same-origin allow-scripts" id='if_12' src="file_iframe_sandbox_c_if8.html" height="10" width="10"></iframe>
<iframe sandbox="allow-forms allow-pointer-lock allow-popups allow-same-origin allow-scripts allow-top-navigation " id='if_13' src="file_iframe_sandbox_c_if9.html" height="10" width="10" onload='test_sandboxFlagsAsString("if_13",["allow-forms", "allow-pointer-lock", "allow-popups", "allow-same-origin", "allow-scripts", "allow-top-navigation"])'></iframe>
<iframe sandbox="&#x09;allow-same-origin&#x09;allow-scripts&#x09;" id="if_14" src="file_iframe_sandbox_c_if6.html" height="10" width="10" onload='test_sandboxFlagsAsString("if_14",["allow-same-origin","allow-scripts"])'></iframe>
<iframe sandbox="" id="if_15" src="file_iframe_sandbox_c_if9.html" height="10" width="10" onload='test_sandboxFlagsAsString("if_15",[])'></iframe>
<iframe id="if_16" src="file_iframe_sandbox_c_if9.html" height="10" width="10" onload='test_sandboxFlagsAsString("if_16",null)'></iframe>
<input type='button' id="a_button" onclick='do_if_9()'>
<input type='button' id="a_button2" onclick='do_if_10()'>
</div>

Просмотреть файл

@ -111,11 +111,11 @@ IDBKeyRange::FromJSVal(JSContext* aCx,
JS::Rooted<JSObject*> obj(aCx, aVal.isObject() ? &aVal.toObject() : nullptr);
bool isValidKey = aVal.isPrimitive();
if (!isValidKey) {
js::ESClassValue cls;
js::ESClass cls;
if (!js::GetBuiltinClass(aCx, obj, &cls)) {
return NS_ERROR_UNEXPECTED;
}
isValidKey = cls == js::ESClass_Array || cls == js::ESClass_Date;
isValidKey = cls == js::ESClass::Array || cls == js::ESClass::Date;
}
if (isValidKey) {
// A valid key returns an 'only' IDBKeyRange.

Просмотреть файл

@ -232,12 +232,12 @@ Key::EncodeJSValInternal(JSContext* aCx, JS::Handle<JS::Value> aVal,
if (aVal.isObject()) {
JS::Rooted<JSObject*> obj(aCx, &aVal.toObject());
js::ESClassValue cls;
js::ESClass cls;
if (!js::GetBuiltinClass(aCx, obj, &cls)) {
IDB_REPORT_INTERNAL_ERR();
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
}
if (cls == js::ESClass_Array) {
if (cls == js::ESClass::Array) {
aTypeOffset += eMaxType;
if (aTypeOffset == eMaxType * kMaxArrayCollapse) {
@ -275,7 +275,7 @@ Key::EncodeJSValInternal(JSContext* aCx, JS::Handle<JS::Value> aVal,
return NS_OK;
}
if (cls == js::ESClass_Date) {
if (cls == js::ESClass::Date) {
bool valid;
if (!js::DateIsValid(aCx, obj, &valid)) {
IDB_REPORT_INTERNAL_ERR();

Просмотреть файл

@ -60,6 +60,7 @@ interface nsIContentSecurityPolicy : nsISerializable
const unsigned short CHILD_SRC_DIRECTIVE = 18;
const unsigned short BLOCK_ALL_MIXED_CONTENT = 19;
const unsigned short REQUIRE_SRI_FOR = 20;
const unsigned short SANDBOX_DIRECTIVE = 21;
/**
* Accessor method for a read-only string version of the policy at a given
@ -157,6 +158,17 @@ interface nsIContentSecurityPolicy : nsISerializable
*/
boolean getAllowsEval(out boolean shouldReportViolations);
/**
* Delegate method called by the service when the protected document is loaded.
* Returns the union of all the sandbox flags contained in CSP policies. This is the most
* restrictive interpretation of flags set in multiple policies.
* See nsSandboxFlags.h for the possible flags.
*
* @return
* sandbox flags or SANDBOXED_NONE if no sandbox directive exists
*/
uint32_t getCSPSandboxFlags();
/**
* For each violated policy (of type violationType), log policy violation on
* the Error Console and send a report to report-uris present in the violated

Просмотреть файл

@ -5,8 +5,6 @@
Reset=Reset
Submit=Submit Query
Browse=Browse…
ChooseFiles=Choose files…
ChooseDirs=Choose folder…
FileUpload=File Upload
# LOCALIZATION NOTE (IsIndexPromptWithSpace): The last character of the string
# should be a space (U+0020) in most locales. The prompt is followed by an
@ -25,6 +23,10 @@ NoFileSelected=No file selected.
# LOCALIZATION NOTE (NoFilesSelected): this string is shown on a
# <input type='file' multiple> when there is no file selected yet.
NoFilesSelected=No files selected.
# LOCALIZATION NOTE (NoDirSelected): this string is shown on a
# <input type='file' directory/webkitdirectory> when there is no directory
# selected yet.
NoDirSelected=No directory selected.
# LOCALIZATION NOTE (XFilesSelected): this string is shown on a
# <input type='file' multiple> when there are more than one selected file.
# %S will be a number greater or equal to 2.

Просмотреть файл

@ -74,6 +74,9 @@ blockAllMixedContent = Blocking insecure request %1$S.
# LOCALIZATION NOTE (ignoringDirectiveWithNoValues):
# %1$S is the name of a CSP directive that requires additional values (e.g., 'require-sri-for')
ignoringDirectiveWithNoValues = Ignoring %1$S since it does not contain any parameters.
# LOCALIZATION NOTE (ignoringReportOnlyDirective):
# %1$S is the directive that is ignored in report-only mode.
ignoringReportOnlyDirective = Ignoring sandbox directive when delivered in a report-only policy %1$S
# CSP Errors:
# LOCALIZATION NOTE (couldntParseInvalidSource):
@ -94,3 +97,6 @@ duplicateDirective = Duplicate %1$S directives detected. All but the first inst
# LOCALIZATION NOTE (deprecatedDirective):
# %1$S is the name of the deprecated directive, %2$S is the name of the replacement.
deprecatedDirective = Directive %1$S has been deprecated. Please use directive %2$S instead.
# LOCALIZATION NOTE (couldntParseInvalidSandboxFlag):
# %1$S is the option that could not be understood
couldntParseInvalidSandboxFlag = Couldnt parse invalid sandbox flag %1$S

Просмотреть файл

@ -1,5 +1,5 @@
//Used by JSHint:
/*global Cu, BrowserTestUtils, ok, add_task, PromiseMessage, gBrowser */
/*global Cu, BrowserTestUtils, ok, add_task, gBrowser */
"use strict";
const { PromiseMessage } = Cu.import("resource://gre/modules/PromiseMessage.jsm", {});
const testPath = "/browser/dom/manifest/test/file_reg_install_event.html";
@ -7,21 +7,35 @@ const defaultURL = new URL("http://example.org/browser/dom/manifest/test/file_te
const testURL = new URL(defaultURL);
testURL.searchParams.append("file", testPath);
// Enable window.oninstall, so we can fire events at it.
function enableOnInstallPref() {
const ops = {
"set": [
["dom.manifest.oninstall", true],
],
};
return SpecialPowers.pushPrefEnv(ops);
}
// Send a message for the even to be fired.
// This cause file_reg_install_event.html to be dynamically change.
function* theTest(aBrowser) {
aBrowser.allowEvents = true;
// Resolves when we get a custom event with the correct name
const responsePromise = new Promise((resolve) => {
aBrowser.contentDocument.addEventListener("dom.manifest.oninstall", resolve);
});
const mm = aBrowser.messageManager;
const msgKey = "DOM:Manifest:FireInstallEvent";
const initialText = aBrowser.contentWindowAsCPOW.document.body.innerHTML.trim()
is(initialText, '<h1 id="output">waiting for event</h1>', "should be waiting for event");
const { data: { success } } = yield PromiseMessage.send(mm, msgKey);
ok(success, "message sent and received successfully.");
const eventText = aBrowser.contentWindowAsCPOW.document.body.innerHTML.trim();
is(eventText, '<h1 id="output">event received!</h1>', "text of the page should have changed.");
};
const { detail: { result } } = yield responsePromise;
ok(result, "the page sent us an acknowledgment as a custom event");
}
// Open a tab and run the test
add_task(function*() {
yield enableOnInstallPref();
let tabOptions = {
gBrowser: gBrowser,
url: testURL.href,

Просмотреть файл

@ -1,9 +1,15 @@
<meta charset=utf-8>
<script>
window.addEventListener("install", (ev) => {
"use strict";
window.addEventListener("install", () => {
document
.querySelector("#output")
.innerHTML = "event received!"
.innerHTML = "event received!";
// Send a custom event back to the browser
// to acknowledge that we got this
const detail = { result: true }
const ev = new CustomEvent("dom.manifest.oninstall", { detail });
document.dispatchEvent(ev);
});
</script>
<link rel="manifest" href="file_manifest.json">
<h1 id=output>waiting for event</h1>

Просмотреть файл

@ -3,42 +3,96 @@
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=1265279
-->
<head>
<meta charset="utf-8">
<title>Test for Bug 1265279 - Web Manifest: Implement window.oninstall</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css">
<script>
"use strict";
SimpleTest.waitForExplicitFinish();
is(window.hasOwnProperty("oninstall"), true, "window has own oninstall property");
is(window.oninstall, null, "window install is initially set to null");
"use strict";
SimpleTest.waitForExplicitFinish();
const finish = SimpleTest.finish.bind(SimpleTest);
enableOnInstallPref()
.then(createIframe)
.then(checkImplementation)
.then(checkOnInstallEventFires)
.then(checkAddEventListenerFires)
.then(finish)
.catch(err => {
dump(`${err}: ${err.stack}`);
finish();
});
// Check that enumerable, configurable, and has a getter and setter
const objDescriptor = Object.getOwnPropertyDescriptor(window, "oninstall");
is(objDescriptor.enumerable, true, "is enumerable");
is(objDescriptor.configurable, true, "is configurable");
is(objDescriptor.hasOwnProperty("get"), true, "has getter");
is(objDescriptor.hasOwnProperty("set"), true, "has setter");
function enableOnInstallPref() {
const ops = {
"set": [
["dom.manifest.oninstall", true],
],
};
return SpecialPowers.pushPrefEnv(ops);
}
// Test is we receive the event on window.install
const customEv = new CustomEvent("install");
window.oninstall = function handler(ev){
window.oninstall = null;
is(ev, customEv, "The events should be the same");
testAddEventListener();
};
window.dispatchEvent(customEv);
// WebIDL conditional annotations for an interface are evaluate once per
// global, so we need to create an iframe to see the effects of calling
// enableOnInstallPref().
function createIframe() {
return new Promise((resolve) => {
const iframe = document.createElement("iframe");
iframe.src = "about:blank";
iframe.onload = () => resolve(iframe.contentWindow);
document.body.appendChild(iframe);
});
}
// Test that it works with .addEventListener("install", f);
function testAddEventListener(){
const customEv2 = new CustomEvent("install");
window.addEventListener("install", function handler2(ev2) {
window.removeEventListener("install", handler2);
is(ev2, customEv2, "The events should be the same");
SimpleTest.finish();
});
window.dispatchEvent(customEv2);
}
// Check that the WebIDL is as expected.
function checkImplementation(ifrWindow) {
return new Promise((resolve, reject) => {
const hasOnInstallProp = ifrWindow.hasOwnProperty("oninstall");
ok(hasOnInstallProp, "window has own oninstall property");
// no point in continuing
if (!hasOnInstallProp) {
const err = new Error("No 'oninstall' IDL attribute. Aborting early.");
return reject(err);
}
is(ifrWindow.oninstall, null, "window install is initially set to null");
// Check that enumerable, configurable, and has a getter and setter.
const objDescriptor = Object.getOwnPropertyDescriptor(window, "oninstall");
ok(objDescriptor.enumerable, "is enumerable");
ok(objDescriptor.configurable, "is configurable");
ok(objDescriptor.hasOwnProperty("get"), "has getter");
ok(objDescriptor.hasOwnProperty("set"), "has setter");
resolve(ifrWindow);
});
}
// Checks that .oninstall receives an event.
function checkOnInstallEventFires(ifrWindow) {
const customEv = new CustomEvent("install");
return new Promise((resolve) => {
// Test is we receive the event on `oninstall`
ifrWindow.oninstall = ev => {
ifrWindow.oninstall = null;
is(ev, customEv, "The events should be the same event object");
resolve(ifrWindow);
};
ifrWindow.dispatchEvent(customEv);
});
}
// Checks that .addEventListener("install") receives an event.
function checkAddEventListenerFires(ifrWindow) {
const customEv = new CustomEvent("install");
return new Promise((resolve) => {
ifrWindow.addEventListener("install", function handler(ev) {
ifrWindow.removeEventListener("install", handler);
is(ev, customEv, "The events should be the same");
resolve(ifrWindow);
});
ifrWindow.dispatchEvent(customEv);
});
}
</script>
</head>

Просмотреть файл

@ -1713,6 +1713,7 @@ void
MediaDecoder::SetCDMProxy(CDMProxy* aProxy)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(aProxy);
mCDMProxyPromiseHolder.ResolveIfExists(aProxy, __func__);
}

Просмотреть файл

@ -93,7 +93,8 @@ MP4Decoder::CanHandleMediaType(const nsACString& aMIMETypeExcludingCodecs,
// the web, as opposed to what we use internally (i.e. what our demuxers
// etc output).
const bool isMP4Audio = aMIMETypeExcludingCodecs.EqualsASCII("audio/mp4") ||
aMIMETypeExcludingCodecs.EqualsASCII("audio/x-m4a");
aMIMETypeExcludingCodecs.EqualsASCII("audio/x-m4a") ||
aMIMETypeExcludingCodecs.EqualsASCII("audio/opus");
const bool isMP4Video =
// On B2G, treat 3GPP as MP4 when Gonk PDM is available.
#ifdef MOZ_GONK_MEDIACODEC

Просмотреть файл

@ -5,6 +5,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "AgnosticDecoderModule.h"
#include "mozilla/Logging.h"
#include "OpusDecoder.h"
#include "VorbisDecoder.h"
#include "VPXDecoder.h"
@ -16,10 +17,14 @@ bool
AgnosticDecoderModule::SupportsMimeType(const nsACString& aMimeType,
DecoderDoctorDiagnostics* aDiagnostics) const
{
return VPXDecoder::IsVPX(aMimeType) ||
bool supports =
VPXDecoder::IsVPX(aMimeType) ||
OpusDataDecoder::IsOpus(aMimeType) ||
VorbisDataDecoder::IsVorbis(aMimeType) ||
WaveDataDecoder::IsWave(aMimeType);
MOZ_LOG(sPDMLog, LogLevel::Debug, ("Agnostic decoder %s requested type",
supports ? "supports" : "rejects"));
return supports;
}
already_AddRefed<MediaDataDecoder>

Просмотреть файл

@ -47,18 +47,28 @@ OpusDataDecoder::Shutdown()
return NS_OK;
}
void
OpusDataDecoder::AppendCodecDelay(MediaByteBuffer* config, uint64_t codecDelayUS)
{
uint8_t buffer[sizeof(uint64_t)];
BigEndian::writeUint64(buffer, codecDelayUS);
config->AppendElements(buffer, sizeof(uint64_t));
}
RefPtr<MediaDataDecoder::InitPromise>
OpusDataDecoder::Init()
{
size_t length = mInfo.mCodecSpecificConfig->Length();
uint8_t *p = mInfo.mCodecSpecificConfig->Elements();
if (length < sizeof(uint64_t)) {
OPUS_DEBUG("CodecSpecificConfig too short to read codecDelay!");
return InitPromise::CreateAndReject(DecoderFailureReason::INIT_ERROR, __func__);
}
int64_t codecDelay = BigEndian::readUint64(p);
length -= sizeof(uint64_t);
p += sizeof(uint64_t);
if (NS_FAILED(DecodeHeader(p, length))) {
OPUS_DEBUG("Error decoding header!");
return InitPromise::CreateAndReject(DecoderFailureReason::INIT_ERROR, __func__);
}
@ -348,7 +358,9 @@ bool
OpusDataDecoder::IsOpus(const nsACString& aMimeType)
{
return aMimeType.EqualsLiteral("audio/webm; codecs=opus") ||
aMimeType.EqualsLiteral("audio/ogg; codecs=opus");
aMimeType.EqualsLiteral("audio/ogg; codecs=opus") ||
aMimeType.EqualsLiteral("audio/mp4; codecs=opus") ||
aMimeType.EqualsLiteral("audio/opus");
}
} // namespace mozilla

Просмотреть файл

@ -33,6 +33,13 @@ public:
// Return true if mimetype is Opus
static bool IsOpus(const nsACString& aMimeType);
// Pack pre-skip/CodecDelay, given in microseconds, into a
// MediaByteBuffer. The decoder expects this value to come
// from the container (if any) and to precede the OpusHead
// block in the CodecSpecificConfig buffer to verify the
// values match.
static void AppendCodecDelay(MediaByteBuffer* config, uint64_t codecDelayUS);
private:
enum DecodeError {
DECODE_SUCCESS,

Просмотреть файл

@ -22,8 +22,8 @@ already_AddRefed<MediaDataDecoder>
GonkDecoderModule::CreateVideoDecoder(const CreateDecoderParams& aParams)
{
RefPtr<MediaDataDecoder> decoder =
new GonkMediaDataDecoder(new GonkVideoDecoderManager(aImageContainer, aConfig),
aCallback);
new GonkMediaDataDecoder(new GonkVideoDecoderManager(aParams.mImageContainer, aParams.VideoConfig()),
aParams.mCallback);
return decoder.forget();
}
@ -31,8 +31,8 @@ already_AddRefed<MediaDataDecoder>
GonkDecoderModule::CreateAudioDecoder(const CreateDecoderParams& aParams)
{
RefPtr<MediaDataDecoder> decoder =
new GonkMediaDataDecoder(new GonkAudioDecoderManager(aConfig),
aCallback);
new GonkMediaDataDecoder(new GonkAudioDecoderManager(aParams.AudioConfig()),
aParams.mCallback);
return decoder.forget();
}

Просмотреть файл

@ -8,6 +8,7 @@
#include "MediaDecoderStateMachine.h"
#include "AbstractMediaDecoder.h"
#include "MediaResource.h"
#include "OpusDecoder.h"
#include "WebMDemuxer.h"
#include "WebMBufferedParser.h"
#include "gfx2DGlue.h"
@ -396,15 +397,13 @@ WebMDemuxer::ReadMetadata()
mAudioTrack = track;
mHasAudio = true;
mCodecDelay = media::TimeUnit::FromNanoseconds(params.codec_delay).ToMicroseconds();
mAudioCodec = nestegg_track_codec_id(context, track);
if (mAudioCodec == NESTEGG_CODEC_VORBIS) {
mInfo.mAudio.mMimeType = "audio/webm; codecs=vorbis";
} else if (mAudioCodec == NESTEGG_CODEC_OPUS) {
mInfo.mAudio.mMimeType = "audio/webm; codecs=opus";
uint8_t c[sizeof(uint64_t)];
BigEndian::writeUint64(&c[0], mCodecDelay);
mInfo.mAudio.mCodecSpecificConfig->AppendElements(&c[0], sizeof(uint64_t));
OpusDataDecoder::AppendCodecDelay(mInfo.mAudio.mCodecSpecificConfig,
media::TimeUnit::FromNanoseconds(params.codec_delay).ToMicroseconds());
}
mSeekPreroll = params.seek_preroll;
mInfo.mAudio.mRate = params.rate;

Просмотреть файл

@ -213,9 +213,6 @@ private:
uint32_t mVideoTrack;
uint32_t mAudioTrack;
// Number of microseconds that must be discarded from the start of the Stream.
uint64_t mCodecDelay;
// Nanoseconds to discard after seeking.
uint64_t mSeekPreroll;

Просмотреть файл

@ -61,6 +61,7 @@ DIRS += [
'filesystem',
'flyweb',
'fmradio',
'gamepad',
'geolocation',
'html',
'icc',
@ -135,9 +136,6 @@ if CONFIG['MOZ_B2G_RIL']:
if CONFIG['MOZ_PAY']:
DIRS += ['payment']
if CONFIG['MOZ_GAMEPAD']:
DIRS += ['gamepad']
if CONFIG['MOZ_NFC']:
DIRS += ['nfc']

Просмотреть файл

@ -99,6 +99,18 @@ interface nsIPluginHost : nsISupports
ACString getPermissionStringForType(in AUTF8String mimeType,
[optional] in uint32_t excludeFlags);
/**
* Get the "permission string" for the plugin. This is a string that can be
* passed to the permission manager to see whether the plugin is allowed to
* run, for example. This will typically be based on the plugin's "nice name"
* and its blocklist state.
*
* @tag The tage we're interested in
* @excludeFlags Set of the EXCLUDE_* flags above, defaulting to EXCLUDE_NONE.
*/
ACString getPermissionStringForTag(in nsIPluginTag tag,
[optional] in uint32_t excludeFlags);
/**
* Get the nsIPluginTag for this MIME type. This method works with both
* enabled and disabled/blocklisted plugins, but an enabled plugin will

Просмотреть файл

@ -1110,11 +1110,19 @@ nsPluginHost::GetPermissionStringForType(const nsACString &aMimeType,
nsresult rv = GetPluginTagForType(aMimeType, aExcludeFlags,
getter_AddRefs(tag));
NS_ENSURE_SUCCESS(rv, rv);
NS_ENSURE_TRUE(tag, NS_ERROR_FAILURE);
return GetPermissionStringForTag(tag, aExcludeFlags, aPermissionString);
}
NS_IMETHODIMP
nsPluginHost::GetPermissionStringForTag(nsIPluginTag* aTag,
uint32_t aExcludeFlags,
nsACString &aPermissionString)
{
NS_ENSURE_TRUE(aTag, NS_ERROR_FAILURE);
aPermissionString.Truncate();
uint32_t blocklistState;
rv = tag->GetBlocklistState(&blocklistState);
nsresult rv = aTag->GetBlocklistState(&blocklistState);
NS_ENSURE_SUCCESS(rv, rv);
if (blocklistState == nsIBlocklistService::STATE_VULNERABLE_UPDATE_AVAILABLE ||
@ -1126,7 +1134,7 @@ nsPluginHost::GetPermissionStringForType(const nsACString &aMimeType,
}
nsCString niceName;
rv = tag->GetNiceName(niceName);
rv = aTag->GetNiceName(niceName);
NS_ENSURE_SUCCESS(rv, rv);
NS_ENSURE_TRUE(!niceName.IsEmpty(), NS_ERROR_FAILURE);

Просмотреть файл

@ -323,7 +323,7 @@ nsPluginTag::~nsPluginTag()
NS_ASSERTION(!mNext, "Risk of exhausting the stack space, bug 486349");
}
NS_IMPL_ISUPPORTS(nsPluginTag, nsIPluginTag, nsIInternalPluginTag)
NS_IMPL_ISUPPORTS(nsPluginTag, nsPluginTag, nsIInternalPluginTag, nsIPluginTag)
void nsPluginTag::InitMime(const char* const* aMimeTypes,
const char* const* aMimeDescriptions,

Просмотреть файл

@ -30,6 +30,9 @@ struct FakePluginTagInit;
{ 0xe8fdd227, 0x27da, 0x46ee, \
{ 0xbe, 0xf3, 0x1a, 0xef, 0x5a, 0x8f, 0xc5, 0xb4 } }
#define NS_PLUGINTAG_IID \
{ 0xcce2e8b9, 0x9702, 0x4d4b, \
{ 0xbe, 0xa4, 0x7c, 0x1e, 0x13, 0x1f, 0xaf, 0x78 } }
class nsIInternalPluginTag : public nsIPluginTag
{
public:
@ -90,6 +93,8 @@ NS_DEFINE_STATIC_IID_ACCESSOR(nsIInternalPluginTag, NS_IINTERNALPLUGINTAG_IID)
class nsPluginTag final : public nsIInternalPluginTag
{
public:
NS_DECLARE_STATIC_IID_ACCESSOR(NS_PLUGINTAG_IID)
NS_DECL_ISUPPORTS
NS_DECL_NSIPLUGINTAG
@ -192,6 +197,7 @@ private:
static uint32_t sNextId;
};
NS_DEFINE_STATIC_IID_ACCESSOR(nsPluginTag, NS_PLUGINTAG_IID)
// A class representing "fake" plugin tags; that is plugin tags not
// corresponding to actual NPAPI plugins. In practice these are all

Просмотреть файл

@ -42,6 +42,7 @@
#include "mozilla/dom/CSPDictionariesBinding.h"
#include "mozilla/net/ReferrerPolicy.h"
#include "nsINetworkInterceptController.h"
#include "nsSandboxFlags.h"
using namespace mozilla;
@ -1323,6 +1324,45 @@ nsCSPContext::ToJSON(nsAString& outCSPinJSON)
return NS_OK;
}
NS_IMETHODIMP
nsCSPContext::GetCSPSandboxFlags(uint32_t* aOutSandboxFlags)
{
if (!aOutSandboxFlags) {
return NS_ERROR_FAILURE;
}
*aOutSandboxFlags = SANDBOXED_NONE;
for (uint32_t i = 0; i < mPolicies.Length(); i++) {
uint32_t flags = mPolicies[i]->getSandboxFlags();
// current policy doesn't have sandbox flag, check next policy
if (!flags) {
continue;
}
// current policy has sandbox flags, if the policy is in enforcement-mode
// (i.e. not report-only) set these flags and check for policies with more
// restrictions
if (!mPolicies[i]->getReportOnlyFlag()) {
*aOutSandboxFlags |= flags;
} else {
// sandbox directive is ignored in report-only mode, warn about it and
// continue the loop checking for an enforcement policy.
nsAutoString policy;
mPolicies[i]->toString(policy);
CSPCONTEXTLOG(("nsCSPContext::GetCSPSandboxFlags, report only policy, ignoring sandbox in: %s",
policy.get()));
const char16_t* params[] = { policy.get() };
logToConsole(MOZ_UTF16("ignoringReportOnlyDirective"), params, ArrayLength(params),
EmptyString(), EmptyString(), 0, 0, nsIScriptError::warningFlag);
}
}
return NS_OK;
}
/* ========== CSPViolationReportListener implementation ========== */
NS_IMPL_ISUPPORTS(CSPViolationReportListener, nsIStreamListener, nsIRequestObserver, nsISupports);

Просмотреть файл

@ -7,6 +7,7 @@
#include "mozilla/ArrayUtils.h"
#include "mozilla/Preferences.h"
#include "nsCOMPtr.h"
#include "nsContentUtils.h"
#include "nsCSPParser.h"
#include "nsCSPUtils.h"
#include "nsIConsoleService.h"
@ -993,6 +994,41 @@ nsCSPParser::reportURIList(nsTArray<nsCSPBaseSrc*>& outSrcs)
}
}
/* Helper function for parsing sandbox flags. This function solely concatenates
* all the source list tokens (the sandbox flags) so the attribute parser
* (nsContentUtils::ParseSandboxAttributeToFlags) can parse them.
*/
void
nsCSPParser::sandboxFlagList(nsTArray<nsCSPBaseSrc*>& outSrcs)
{
nsAutoString flags;
// remember, srcs start at index 1
for (uint32_t i = 1; i < mCurDir.Length(); i++) {
mCurToken = mCurDir[i];
CSPPARSERLOG(("nsCSPParser::sandboxFlagList, mCurToken: %s, mCurValue: %s",
NS_ConvertUTF16toUTF8(mCurToken).get(),
NS_ConvertUTF16toUTF8(mCurValue).get()));
if (!nsContentUtils::IsValidSandboxFlag(mCurToken)) {
const char16_t* params[] = { mCurToken.get() };
logWarningErrorToConsole(nsIScriptError::warningFlag,
"couldntParseInvalidSandboxFlag",
params, ArrayLength(params));
continue;
}
flags.Append(mCurToken);
if (i != mCurDir.Length() - 1) {
flags.AppendASCII(" ");
}
}
nsCSPSandboxFlags* sandboxFlags = new nsCSPSandboxFlags(flags);
outSrcs.AppendElement(sandboxFlags);
}
// directive-value = *( WSP / <VCHAR except ";" and ","> )
void
nsCSPParser::directiveValue(nsTArray<nsCSPBaseSrc*>& outSrcs)
@ -1014,6 +1050,13 @@ nsCSPParser::directiveValue(nsTArray<nsCSPBaseSrc*>& outSrcs)
return;
}
// For the sandbox flag the source list is a list of flags, so we're special
// casing this directive
if (CSP_IsDirective(mCurDir[0], nsIContentSecurityPolicy::SANDBOX_DIRECTIVE)) {
sandboxFlagList(outSrcs);
return;
}
// Otherwise just forward to sourceList
sourceList(outSrcs);
}
@ -1061,7 +1104,8 @@ nsCSPParser::directiveName()
// http://www.w3.org/TR/CSP11/#delivery-html-meta-element
if (mDeliveredViaMetaTag &&
((CSP_IsDirective(mCurToken, nsIContentSecurityPolicy::REPORT_URI_DIRECTIVE)) ||
(CSP_IsDirective(mCurToken, nsIContentSecurityPolicy::FRAME_ANCESTORS_DIRECTIVE)))) {
(CSP_IsDirective(mCurToken, nsIContentSecurityPolicy::FRAME_ANCESTORS_DIRECTIVE)) ||
(CSP_IsDirective(mCurToken, nsIContentSecurityPolicy::SANDBOX_DIRECTIVE)))) {
// log to the console to indicate that meta CSP is ignoring the directive
const char16_t* params[] = { mCurToken.get() };
logWarningErrorToConsole(nsIScriptError::warningFlag,

Просмотреть файл

@ -137,14 +137,15 @@ class nsCSPParser {
bool port();
bool path(nsCSPHostSrc* aCspHost);
bool subHost(); // helper function to parse subDomains
bool atValidUnreservedChar(); // helper function to parse unreserved
bool atValidSubDelimChar(); // helper function to parse sub-delims
bool atValidPctEncodedChar(); // helper function to parse pct-encoded
bool subPath(nsCSPHostSrc* aCspHost); // helper function to parse paths
void reportURIList(nsTArray<nsCSPBaseSrc*>& outSrcs); // helper function to parse report-uris
void percentDecodeStr(const nsAString& aEncStr, // helper function to percent-decode
bool subHost(); // helper function to parse subDomains
bool atValidUnreservedChar(); // helper function to parse unreserved
bool atValidSubDelimChar(); // helper function to parse sub-delims
bool atValidPctEncodedChar(); // helper function to parse pct-encoded
bool subPath(nsCSPHostSrc* aCspHost); // helper function to parse paths
void reportURIList(nsTArray<nsCSPBaseSrc*>& outSrcs); // helper function to parse report-uris
void percentDecodeStr(const nsAString& aEncStr, // helper function to percent-decode
nsAString& outDecStr);
void sandboxFlagList(nsTArray<nsCSPBaseSrc*>& outSrcs); // helper function to parse sandbox flags
inline bool atEnd()
{

Просмотреть файл

@ -4,6 +4,8 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "nsAttrValue.h"
#include "nsContentUtils.h"
#include "nsCSPUtils.h"
#include "nsDebug.h"
#include "nsIConsoleService.h"
@ -13,6 +15,7 @@
#include "nsIStringBundle.h"
#include "nsIURL.h"
#include "nsReadableUtils.h"
#include "nsSandboxFlags.h"
static mozilla::LogModule*
GetCspUtilsLog()
@ -792,6 +795,29 @@ nsCSPReportURI::toString(nsAString& outStr) const
outStr.AppendASCII(spec.get());
}
/* ===== nsCSPSandboxFlags ===================== */
nsCSPSandboxFlags::nsCSPSandboxFlags(const nsAString& aFlags)
: mFlags(aFlags)
{
}
nsCSPSandboxFlags::~nsCSPSandboxFlags()
{
}
bool
nsCSPSandboxFlags::visit(nsCSPSrcVisitor* aVisitor) const
{
return false;
}
void
nsCSPSandboxFlags::toString(nsAString& outStr) const
{
outStr.Append(mFlags);
}
/* ===== nsCSPDirective ====================== */
nsCSPDirective::nsCSPDirective(CSPDirective aDirective)
@ -953,6 +979,11 @@ nsCSPDirective::toDomCSPStruct(mozilla::dom::CSP& outCSP) const
outCSP.mChild_src.Value() = mozilla::Move(srcs);
return;
case nsIContentSecurityPolicy::SANDBOX_DIRECTIVE:
outCSP.mSandbox.Construct();
outCSP.mSandbox.Value() = mozilla::Move(srcs);
return;
// REFERRER_DIRECTIVE and REQUIRE_SRI_FOR are handled in nsCSPPolicy::toDomCSPStruct()
default:
@ -1344,6 +1375,33 @@ nsCSPPolicy::getDirectiveAsString(CSPDirective aDir, nsAString& outDirective) co
}
}
/*
* Helper function that returns the underlying bit representation of sandbox
* flags. The function returns SANDBOXED_NONE if there are no sandbox
* directives.
*/
uint32_t
nsCSPPolicy::getSandboxFlags() const
{
for (uint32_t i = 0; i < mDirectives.Length(); i++) {
if (mDirectives[i]->equals(nsIContentSecurityPolicy::SANDBOX_DIRECTIVE)) {
nsAutoString flags;
mDirectives[i]->toString(flags);
if (flags.IsEmpty()) {
return SANDBOX_ALL_FLAGS;
}
nsAttrValue attr;
attr.ParseAtomArray(flags);
return nsContentUtils::ParseSandboxAttributeToFlags(&attr);
}
}
return SANDBOXED_NONE;
}
void
nsCSPPolicy::getReportURIs(nsTArray<nsString>& outReportURIs) const
{

Просмотреть файл

@ -92,8 +92,8 @@ static const char* CSPStrDirectives[] = {
"upgrade-insecure-requests", // UPGRADE_IF_INSECURE_DIRECTIVE
"child-src", // CHILD_SRC_DIRECTIVE
"block-all-mixed-content", // BLOCK_ALL_MIXED_CONTENT
"require-sri-for" // REQUIRE_SRI_FOR
"require-sri-for", // REQUIRE_SRI_FOR
"sandbox" // SANDBOX_DIRECTIVE
};
inline const char* CSP_CSPDirectiveToString(CSPDirective aDir)
@ -334,6 +334,20 @@ class nsCSPReportURI : public nsCSPBaseSrc {
nsCOMPtr<nsIURI> mReportURI;
};
/* =============== nsCSPSandboxFlags ================== */
class nsCSPSandboxFlags : public nsCSPBaseSrc {
public:
explicit nsCSPSandboxFlags(const nsAString& aFlags);
virtual ~nsCSPSandboxFlags();
bool visit(nsCSPSrcVisitor* aVisitor) const;
void toString(nsAString& outStr) const;
private:
nsString mFlags;
};
/* =============== nsCSPSrcVisitor ================== */
class nsCSPSrcVisitor {
@ -558,6 +572,8 @@ class nsCSPPolicy {
void getDirectiveAsString(CSPDirective aDir, nsAString& outDirective) const;
uint32_t getSandboxFlags() const;
bool requireSRIForType(nsContentPolicyType aContentType);
inline uint32_t getNumDirectives() const

Просмотреть файл

@ -175,6 +175,13 @@ DoContentSecurityChecks(nsIChannel* aChannel, nsILoadInfo* aLoadInfo)
nsCString mimeTypeGuess;
nsCOMPtr<nsINode> requestingContext = nullptr;
#ifdef DEBUG
// Don't enforce TYPE_DOCUMENT assertions for loads
// initiated by javascript tests.
bool skipContentTypeCheck = false;
skipContentTypeCheck = Preferences::GetBool("network.loadinfo.skip_type_assertion");
#endif
switch(contentPolicyType) {
case nsIContentPolicy::TYPE_OTHER: {
mimeTypeGuess = EmptyCString();
@ -207,7 +214,7 @@ DoContentSecurityChecks(nsIChannel* aChannel, nsILoadInfo* aLoadInfo)
}
case nsIContentPolicy::TYPE_DOCUMENT: {
MOZ_ASSERT(false, "contentPolicyType not supported yet");
MOZ_ASSERT(skipContentTypeCheck || false, "contentPolicyType not supported yet");
break;
}

Просмотреть файл

@ -0,0 +1,21 @@
<!DOCTYPE HTML>
<html>
<head> <meta charset="utf-8"> </head>
<script type="text/javascript">
function ok(result, desc) {
window.parent.postMessage({ok: result, desc: desc}, "*");
}
function doStuff() {
var beforePrincipal = SpecialPowers.wrap(document).nodePrincipal;
document.open();
document.write("rewritten sandboxed document");
document.close();
var afterPrincipal = SpecialPowers.wrap(document).nodePrincipal;
ok(beforePrincipal.equals(afterPrincipal),
"document.write() does not change underlying principal");
}
</script>
<body onLoad='doStuff();'>
sandboxed with allow-scripts
</body>
</html>

Просмотреть файл

@ -0,0 +1,16 @@
<html>
<head> <meta charset="utf-8"> </head>
<body>
<!-- sandbox="allow-same-origin" -->
<!-- Content-Security-Policy: default-src 'self' -->
<!-- these should be stopped by CSP -->
<img src="http://example.org/tests/dom/security/test/csp/file_CSP.sjs?testid=img1_bad&type=img/png"> </img>
<!-- these should load ok -->
<img src="/tests/dom/security/test/csp/file_CSP.sjs?testid=img1a_good&type=img/png" />
<!-- should not execute script -->
<script src='/tests/dom/security/test/csp/file_sandbox_fail.js'></script>
</body>
</html>

Просмотреть файл

@ -0,0 +1,12 @@
<html>
<head> <meta charset="utf-8"> </head>
<body>
<!-- Content-Security-Policy: default-src 'none'; sandbox -->
<!-- these should be stopped by CSP -->
<img src="http://example.org/tests/dom/security/test/csp/file_CSP.sjs?testid=img10_bad&type=img/png"> </img>
<img src="/tests/dom/security/test/csp/file_CSP.sjs?testid=img10a_bad&type=img/png" />
<script src='/tests/dom/security/test/csp/file_sandbox_fail.js'></script>
</body>
</html>

Просмотреть файл

@ -0,0 +1,25 @@
<!DOCTYPE HTML>
<html>
<head> <meta charset="utf-8"> </head>
<script type="text/javascript">
function ok(result, desc) {
window.parent.postMessage({ok: result, desc: desc}, "*");
}
function doStuff() {
ok(true, "documents sandboxed with allow-scripts should be able to run inline scripts");
}
</script>
<script src='file_sandbox_fail.js'></script>
<body onLoad='ok(true, "documents sandboxed with allow-scripts should be able to run script from event listeners");doStuff();'>
I am sandboxed but with only inline "allow-scripts"
<!-- Content-Security-Policy: default-src 'none'; script-src 'unsafe-inline'; sandbox allow-scripts -->
<!-- these should be stopped by CSP -->
<img src="/tests/dom/security/test/csp/file_CSP.sjs?testid=img11_bad&type=img/png" />
<img src="http://example.org/tests/dom/security/test/csp/file_CSP.sjs?testid=img11a_bad&type=img/png"> </img>
<script src='/tests/dom/security/test/csp/file_CSP.sjs?testid=script11_bad&type=text/javascript'></script>
<script src='http://example.org/tests/dom/security/test/csp/file_CSP.sjs?testid=script11a_bad&type=text/javascript'></script>
</body>
</html>

Просмотреть файл

@ -0,0 +1,40 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
</head>
<script type="text/javascript">
function ok(result, desc) {
window.parent.postMessage({ok: result, desc: desc}, "*");
}
function doStuff() {
ok(true, "documents sandboxed with allow-scripts should be able to run inline scripts");
document.getElementById('a_form').submit();
// trigger the javascript: url test
sendMouseEvent({type:'click'}, 'a_link');
}
</script>
<script src='file_sandbox_pass.js'></script>
<body onLoad='ok(true, "documents sandboxed with allow-scripts should be able to run script from event listeners");doStuff();'>
I am sandboxed but with "allow-same-origin" and allow-scripts"
<!-- Content-Security-Policy: sandbox allow-same-origin allow-scripts; default-src 'self' 'unsafe-inline'; -->
<!-- these should be stopped by CSP -->
<img src="http://example.org/tests/dom/security/test/csp/file_CSP.sjs?testid=img12_bad&type=img/png"> </img>
<script src='http://example.org/tests/dom/security/test/csp/file_CSP.sjs?testid=script12_bad&type=text/javascript'></script>
<form method="get" action="/tests/content/html/content/test/file_iframe_sandbox_form_fail.html" id="a_form">
First name: <input type="text" name="firstname">
Last name: <input type="text" name="lastname">
<input type="submit" onclick="doSubmit()" id="a_button">
</form>
<a href = 'javascript:ok(true, "documents sandboxed with allow-scripts should be able to run script from javascript: URLs");' id='a_link'>click me</a>
</body>
</html>

Просмотреть файл

@ -0,0 +1,16 @@
<html>
<head> <meta charset="utf-8"> </head>
<body>
<!-- sandbox -->
<!-- Content-Security-Policy: default-src 'self' -->
<!-- these should be stopped by CSP -->
<img src="http://example.org/tests/dom/security/test/csp/file_CSP.sjs?testid=img2_bad&type=img/png"> </img>
<!-- these should load ok -->
<img src="/tests/dom/security/test/csp/file_CSP.sjs?testid=img2a_good&type=img/png" />
<!-- should not execute script -->
<script src='/tests/dom/security/test/csp/file_sandbox_fail.js'></script>
</body>
</html>

Просмотреть файл

@ -0,0 +1,13 @@
<html>
<head> <meta charset="utf-8"> </head>
<body>
<!-- sandbox="allow-same-origin" -->
<!-- Content-Security-Policy: default-src 'none' -->
<!-- these should be stopped by CSP -->
<img src="http://example.org/tests/dom/security/test/csp/file_CSP.sjs?testid=img3_bad&type=img/png"> </img>
<img src="/tests/dom/security/test/csp/file_CSP.sjs?testid=img3a_bad&type=img/png" />
<script src='/tests/dom/security/test/csp/file_sandbox_fail.js'></script>
</body>
</html>

Просмотреть файл

@ -0,0 +1,13 @@
<html>
<head> <meta charset="utf-8"> </head>
<body>
<!-- sandbox -->
<!-- Content-Security-Policy: default-src 'none' -->
<!-- these should be stopped by CSP -->
<img src="http://example.org/tests/dom/base/test/csp/file_CSP.sjs?testid=img4_bad&type=img/png"> </img>
<img src="/tests/dom/base/test/csp/file_CSP.sjs?testid=img4a_bad&type=img/png" />
<script src='/tests/dom/base/test/csp/file_sandbox_fail.js'></script>
</body>
</html>

Просмотреть файл

@ -0,0 +1,26 @@
<!DOCTYPE HTML>
<html>
<head> <meta charset="utf-8"> </head>
<script type="text/javascript">
function ok(result, desc) {
window.parent.postMessage({ok: result, desc: desc}, "*");
}
function doStuff() {
ok(true, "documents sandboxed with allow-scripts should be able to run inline scripts");
}
</script>
<script src='file_sandbox_fail.js'></script>
<body onLoad='ok(true, "documents sandboxed with allow-scripts should be able to run script from event listeners");doStuff();'>
I am sandboxed but with only inline "allow-scripts"
<!-- sandbox="allow-scripts" -->
<!-- Content-Security-Policy: default-src 'none'; script-src 'unsafe-inline' -->
<!-- these should be stopped by CSP -->
<img src="/tests/dom/security/test/csp/file_CSP.sjs?testid=img5_bad&type=img/png" />
<img src="http://example.org/tests/dom/security/test/csp/file_CSP.sjs?testid=img5a_bad&type=img/png"> </img>
<script src='/tests/dom/security/test/csp/file_CSP.sjs?testid=script5_bad&type=text/javascript'></script>
<script src='http://example.org/tests/dom/security/test/csp/file_CSP.sjs?testid=script5a_bad&type=text/javascript'></script>
</body>
</html>

Просмотреть файл

@ -0,0 +1,35 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
</head>
<script type="text/javascript">
function ok(result, desc) {
window.parent.postMessage({ok: result, desc: desc}, "*");
}
function doStuff() {
ok(true, "documents sandboxed with allow-scripts should be able to run inline scripts");
document.getElementById('a_form').submit();
// trigger the javascript: url test
sendMouseEvent({type:'click'}, 'a_link');
}
</script>
<script src='file_sandbox_pass.js'></script>
<body onLoad='ok(true, "documents sandboxed with allow-scripts should be able to run script from event listeners");doStuff();'>
I am sandboxed but with "allow-same-origin" and allow-scripts"
<img src="http://example.org/tests/dom/security/test/csp/file_CSP.sjs?testid=img6_bad&type=img/png"> </img>
<script src='http://example.org/tests/dom/security/test/csp/file_CSP.sjs?testid=script6_bad&type=text/javascript'></script>
<form method="get" action="/tests/content/html/content/test/file_iframe_sandbox_form_fail.html" id="a_form">
First name: <input type="text" name="firstname">
Last name: <input type="text" name="lastname">
<input type="submit" onclick="doSubmit()" id="a_button">
</form>
<a href = 'javascript:ok(true, "documents sandboxed with allow-scripts should be able to run script from javascript: URLs");' id='a_link'>click me</a>
</body>
</html>

Просмотреть файл

@ -0,0 +1,15 @@
<html>
<head> <meta charset="utf-8"> </head>
<body>
<!-- Content-Security-Policy: default-src 'self'; sandbox allow-same-origin -->
<!-- these should be stopped by CSP -->
<img src="http://example.org/tests/dom/security/test/csp/file_CSP.sjs?testid=img7_bad&type=img/png"> </img>
<!-- these should load ok -->
<img src="/tests/dom/security/test/csp/file_CSP.sjs?testid=img7a_good&type=img/png" />
<!-- should not execute script -->
<script src='/tests/dom/security/test/csp/file_sandbox_fail.js'></script>
</body>
</html>

Просмотреть файл

@ -0,0 +1,15 @@
<html>
<head> <meta charset="utf-8"> </head>
<body>
<!-- Content-Security-Policy: sandbox; default-src 'self' -->
<!-- these should be stopped by CSP -->
<img src="http://example.org/tests/dom/security/test/csp/file_CSP.sjs?testid=img8_bad&type=img/png"> </img>
<!-- these should load ok -->
<img src="/tests/dom/security/test/csp/file_CSP.sjs?testid=img8a_good&type=img/png" />
<!-- should not execute script -->
<script src='/tests/dom/security/test/csp/file_sandbox_fail.js'></script>
</body>
</html>

Просмотреть файл

@ -0,0 +1,12 @@
<html>
<head> <meta charset="utf-8"> </head>
<body>
<!-- Content-Security-Policy: default-src 'none'; sandbox allow-same-origin -->
<!-- these should be stopped by CSP -->
<img src="http://example.org/tests/dom/security/test/csp/file_CSP.sjs?testid=img9_bad&type=img/png"> </img>
<img src="/tests/dom/security/test/csp/file_CSP.sjs?testid=img9a_bad&type=img/png" />
<script src='/tests/dom/security/test/csp/file_sandbox_fail.js'></script>
</body>
</html>

Просмотреть файл

@ -0,0 +1,4 @@
function ok(result, desc) {
window.parent.postMessage({ok: result, desc: desc}, "*");
}
ok(false, "documents sandboxed with allow-scripts should NOT be able to run <script src=...>");

Просмотреть файл

@ -0,0 +1,4 @@
function ok(result, desc) {
window.parent.postMessage({ok: result, desc: desc}, "*");
}
ok(true, "documents sandboxed with allow-scripts should be able to run <script src=...>");

Просмотреть файл

@ -39,6 +39,11 @@ function handleRequest(request, response) {
response.setHeader("Content-Security-Policy", query.get("csp"), false);
}
// Deliver the CSP report-only policy encoded in the URI
if(query.has("cspRO")){
response.setHeader("Content-Security-Policy-Report-Only", query.get("cspRO"), false);
}
// Deliver the CORS header in the URL
if(query.has("cors")){
response.setHeader("Access-Control-Allow-Origin", query.get("cors"), false);
@ -46,5 +51,7 @@ function handleRequest(request, response) {
// Send HTML to test allowed/blocked behaviors
response.setHeader("Content-Type", "text/html", false);
response.write(loadHTMLFromFile(query.get("file")));
if(query.has("file")){
response.write(loadHTMLFromFile(query.get("file")));
}
}

Просмотреть файл

@ -163,6 +163,22 @@ support-files =
!/image/test/mochitest/blue.png
file_meta_whitespace_skipping.html
file_ping.html
test_iframe_sandbox_top_1.html^headers^
file_iframe_sandbox_document_write.html
file_sandbox_pass.js
file_sandbox_fail.js
file_sandbox_1.html
file_sandbox_2.html
file_sandbox_3.html
file_sandbox_4.html
file_sandbox_5.html
file_sandbox_6.html
file_sandbox_7.html
file_sandbox_8.html
file_sandbox_9.html
file_sandbox_10.html
file_sandbox_11.html
file_sandbox_12.html
[test_base-uri.html]
[test_blob_data_schemes.html]
@ -249,4 +265,7 @@ tags = mcb
tags = mcb
[test_form_action_blocks_url.html]
[test_meta_whitespace_skipping.html]
[test_iframe_sandbox.html]
[test_iframe_sandbox_top_1.html]
[test_sandbox.html]
[test_ping.html]

Просмотреть файл

@ -0,0 +1,239 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=671389
Bug 671389 - Implement CSP sandbox directive
-->
<head>
<meta charset="utf-8">
<title>Tests for Bug 671389</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<script type="application/javascript">
SimpleTest.waitForExplicitFinish();
// Check if two sandbox flags are the same, ignoring case-sensitivity.
// getSandboxFlags returns a list of sandbox flags (if any) or
// null if the flag is not set.
// This function checks if two flags are the same, i.e., they're
// either not set or have the same flags.
function eqFlags(a, b) {
if (a === null && b === null) { return true; }
if (a === null || b === null) { return false; }
if (a.length !== b.length) { return false; }
var a_sorted = a.map(function(e) { return e.toLowerCase(); }).sort();
var b_sorted = b.map(function(e) { return e.toLowerCase(); }).sort();
for (var i in a_sorted) {
if (a_sorted[i] !== b_sorted[i]) {
return false;
}
}
return true;
}
// Get the sandbox flags of document doc.
// If the flag is not set sandboxFlagsAsString returns null,
// this function also returns null.
// If the flag is set it may have some flags; in this case
// this function returns the (potentially empty) list of flags.
function getSandboxFlags(doc) {
var flags = doc.sandboxFlagsAsString;
if (flags === null) { return null; }
return flags? flags.split(" "):[];
}
// Constructor for a CSP sandbox flags test. The constructor
// expectes a description 'desc' and set of options 'opts':
// - sandboxAttribute: [null] or string corresponding to the iframe sandbox attributes
// - csp: [null] or string corresponding to the CSP sandbox flags
// - cspReportOnly: [null] or string corresponding to the CSP report-only sandbox flags
// - file: [null] or string corresponding to file the server should serve
// Above, we use [brackets] to denote default values.
function CSPFlagsTest(desc, opts) {
function ifundef(x, v) {
return (x !== undefined) ? x : v;
}
function intersect(as, bs) { // Intersect two csp attributes:
as = as === null ? null
: as.split(' ').filter(function(x) { return !!x; });
bs = bs === null ? null
: bs.split(' ').filter(function(x) { return !!x; });
if (as === null) { return bs; }
if (bs === null) { return as; }
var cs = [];
as.forEach(function(a) {
if (a && bs.indexOf(a) != -1)
cs.push(a);
});
return cs;
}
this.desc = desc || "Untitled test";
this.attr = ifundef(opts.sandboxAttribute, null);
this.csp = ifundef(opts.csp, null);
this.cspRO = ifundef(opts.cspReportOnly, null);
this.file = ifundef(opts.file, null);
this.expected = intersect(this.attr, this.csp);
}
// Return function that checks that the actual flags are the same as the
// expected flags
CSPFlagsTest.prototype.checkFlags = function(iframe) {
var this_ = this;
return function() {
try {
var actual = getSandboxFlags(SpecialPowers.wrap(iframe).contentDocument);
ok(eqFlags(actual, this_.expected),
this_.desc, 'expected: "' + this_.expected + '", got: "' + actual + '"');
} catch (e) {
ok(false, this_.desc, 'expected: "' + this_.expected + '", failed with: "' + e + '"');
}
runNextTest();
};
};
// Set the iframe src and sandbox attribute
CSPFlagsTest.prototype.runTest = function () {
var iframe = document.createElement('iframe');
document.getElementById("content").appendChild(iframe);
iframe.onload = this.checkFlags(iframe);
// set sandbox attribute
if (this.attr === null) {
iframe.removeAttribute('sandbox');
} else {
iframe.sandbox = this.attr;
}
// set query string
var src = 'http://mochi.test:8888/tests/dom/security/test/csp/file_testserver.sjs';
var delim = '?';
if (this.csp !== null) {
src += delim + 'csp=' + escape('sandbox ' + this.csp);
delim = '&';
}
if (this.cspRO !== null) {
src += delim + 'cspRO=' + escape('sandbox ' + this.cspRO);
delim = '&';
}
if (this.file !== null) {
src += delim + 'file=' + escape(this.file);
delim = '&';
}
iframe.src = src;
iframe.width = iframe.height = 10;
}
testCases = [
{
desc: "Test 1: Header should not override attribute",
sandboxAttribute: "",
csp: "allow-forms aLLOw-POinter-lock alLOW-popups aLLOW-SAME-ORIGin ALLOW-SCRIPTS allow-top-navigation"
},
{
desc: "Test 2: Attribute should not override header",
sandboxAttribute: "sandbox allow-forms allow-pointer-lock allow-popups allow-same-origin allow-scripts allow-top-navigation",
csp: ""
},
{
desc: "Test 3: Header and attribute intersect",
sandboxAttribute: "allow-same-origin allow-scripts",
csp: "allow-forms allow-same-origin allow-scripts"
},
{
desc: "Test 4: CSP sandbox sets the right flags (pt 1)",
csp: "alLOW-FORms ALLOW-pointer-lock allow-popups allow-same-origin allow-scripts ALLOW-TOP-NAVIGation"
},
{
desc: "Test 5: CSP sandbox sets the right flags (pt 2)",
csp: "allow-same-origin allow-TOP-navigation"
},
{
desc: "Test 6: CSP sandbox sets the right flags (pt 3)",
csp: "allow-FORMS ALLOW-scripts"
},
{
desc: "Test 7: CSP sandbox sets the right flags (pt 4)",
csp: ""
},
{
desc: "Test 8: CSP sandbox sets the right flags (pt 5)",
csp: null
},
{
desc: "Test 9: Read-only header should not override attribute",
sandboxAttribute: "",
cspReportOnly: "allow-forms ALLOW-pointer-lock allow-POPUPS allow-same-origin ALLOW-scripts allow-top-NAVIGATION"
},
{
desc: "Test 10: Read-only header should not override CSP header",
csp: "allow-forms allow-scripts",
cspReportOnly: "allow-forms aLlOw-PoInTeR-lOcK aLLow-pOPupS aLLoW-SaME-oRIgIN alLow-scripts allow-tOp-navigation"
},
{
desc: "Test 11: Read-only header should not override attribute or CSP header",
sandboxAttribute: "allow-same-origin allow-scripts",
csp: "allow-forms allow-same-origin allow-scripts",
cspReportOnly: "allow-forms allow-pointer-lock allow-popups allow-same-origin allow-scripts allow-top-navigation"
},
{
desc: "Test 12: CSP sandbox not affected by document.write()",
csp: "allow-scripts",
file: 'tests/dom/security/test/csp/file_iframe_sandbox_document_write.html'
},
].map(function(t) { return (new CSPFlagsTest(t.desc,t)); });
var testCaseIndex = 0;
// Track ok messages from iframes
var childMessages = 0;
var totalChildMessages = 1;
// Check to see if we ran all the tests and received all messges
// from child iframes. If so, finish.
function tryFinish() {
if (testCaseIndex === testCases.length && childMessages === totalChildMessages){
SimpleTest.finish();
}
}
function runNextTest() {
tryFinish();
if (testCaseIndex < testCases.length) {
testCases[testCaseIndex].runTest();
testCaseIndex++;
}
}
function receiveMessage(event) {
ok(event.data.ok, event.data.desc);
childMessages++;
tryFinish();
}
window.addEventListener("message", receiveMessage, false);
addLoadEvent(runNextTest);
</script>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=671389">Mozilla Bug 671389</a> - Implement CSP sandbox directive
<p id="display"></p>
<div id="content">
</div>
</body>
</html>

Просмотреть файл

@ -0,0 +1,80 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=671389
Bug 671389 - Implement CSP sandbox directive
Tests CSP sandbox attribute on top-level page.
Minimal flags: allow-same-origin allow-scripts:
Since we need to load the SimpleTest files, we have to set the
allow-same-origin flag. Additionally, we set the allow-scripts flag
since we need JS to check the flags.
Though not necessary, for this test we also set the allow-forms flag.
We may later wish to extend the testing suite with sandbox_csp_top_*
tests that set different permutations of the flags.
CSP header: Content-Security-Policy: sandbox allow-forms allow-scripts allow-same-origin
-->
<head>
<meta charset="utf-8">
<title>Tests for Bug 671389</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<script type="application/javascript">
SimpleTest.waitForExplicitFinish();
// Check if two sandbox flags are the same.
// getSandboxFlags returns a list of sandbox flags (if any) or
// null if the flag is not set.
// This function checks if two flags are the same, i.e., they're
// either not set or have the same flags.
function eqFlags(a, b) {
if (a === null && b === null) { return true; }
if (a === null || b === null) { return false; }
if (a.length !== b.length) { return false; }
var a_sorted = a.sort();
var b_sorted = b.sort();
for (var i in a_sorted) {
if (a_sorted[i] !== b_sorted[i]) {
return false;
}
}
return true;
}
// Get the sandbox flags of document doc.
// If the flag is not set sandboxFlagsAsString returns null,
// this function also returns null.
// If the flag is set it may have some flags; in this case
// this function returns the (potentially empty) list of flags.
function getSandboxFlags(doc) {
var flags = doc.sandboxFlagsAsString;
if (flags === null) { return null; }
return flags? flags.split(" "):[];
}
function checkFlags(expected) {
try {
var flags = getSandboxFlags(SpecialPowers.wrap(document));
ok(eqFlags(flags, expected), name + ' expected: "' + expected + '", got: "' + flags + '"');
} catch (e) {
ok(false, name + ' expected "' + expected + ', but failed with ' + e);
}
SimpleTest.finish();
}
</script>
<body onLoad='checkFlags(["allow-forms", "allow-scripts", "allow-same-origin"]);'>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=671389">Mozilla Bug 671389</a> - Implement CSP sandbox directive
<p id="display"></p>
<div id="content">
I am a top-level page sandboxed with "allow-scripts allow-forms
allow-same-origin".
</div>
</body>
</html>

Просмотреть файл

@ -0,0 +1 @@
Content-Security-Policy: sAnDbOx aLLow-FOrms aLlOw-ScRiPtS ALLOW-same-origin

Просмотреть файл

@ -67,7 +67,7 @@ var tests = [
},
{
policy1: "default-src 'unsafe-inline' 'sha256-uJXAPKP5NZxnVMZMUkDofh6a9P3UMRc1CRTevVPS/rI=' 'nonce-FooNonce' ",
policy2: "sandbox allow-forms",
policy2: "sandbox allow-scripts allow-same-origin",
description: "unsafe-inline should *not* be ignored within default-src even if hash or nonce is specified",
file: "file_ignore_unsafe_inline.html",
result: "abcd",

Просмотреть файл

@ -0,0 +1,240 @@
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title>Tests for bugs 886164 and 671389</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<p id="display"></p>
<div id="content">
</div>
<script class="testbody" type="text/javascript">
var testCases = [
{
// Test 1: don't load image from non-same-origin; allow loading
// images from same-same origin
sandboxAttribute: "allow-same-origin",
csp: "default-src 'self'",
file: "file_sandbox_1.html",
results: { img1a_good: -1, img1_bad: -1 }
// fails if scripts execute
},
{
// Test 2: don't load image from non-same-origin; allow loading
// images from same-same origin, even without allow-same-origin
// flag
sandboxAttribute: "",
csp: "default-src 'self'",
file: "file_sandbox_2.html",
results: { img2_bad: -1, img2a_good: -1 }
// fails if scripts execute
},
{
// Test 3: disallow loading images from any host, even with
// allow-same-origin flag set
sandboxAttribute: "allow-same-origin",
csp: "default-src 'none'",
file: "file_sandbox_3.html",
results: { img3_bad: -1, img3a_bad: -1 },
// fails if scripts execute
},
{
// Test 4: disallow loading images from any host
sandboxAttribute: "",
csp: "default-src 'none'",
file: "file_sandbox_4.html",
results: { img4_bad: -1, img4a_bad: -1 }
// fails if scripts execute
},
{
// Test 5: disallow loading images or scripts, allow inline scripts
sandboxAttribute: "allow-scripts",
csp: "default-src 'none'; script-src 'unsafe-inline';",
file: "file_sandbox_5.html",
results: { img5_bad: -1, img5a_bad: -1, script5_bad: -1, script5a_bad: -1 },
nrOKmessages: 2 // sends 2 ok message
// fails if scripts execute
},
{
// Test 6: disallow non-same-origin images, allow inline and same origin scripts
sandboxAttribute: "allow-same-origin allow-scripts",
csp: "default-src 'self' 'unsafe-inline';",
file: "file_sandbox_6.html",
results: { img6_bad: -1, script6_bad: -1 },
nrOKmessages: 4 // sends 4 ok message
// fails if forms are not disallowed
},
{
// Test 7: same as Test 1
csp: "default-src 'self'; sandbox allow-same-origin",
file: "file_sandbox_7.html",
results: { img7a_good: -1, img7_bad: -1 }
},
{
// Test 8: same as Test 2
csp: "sandbox allow-same-origin; default-src 'self'",
file: "file_sandbox_8.html",
results: { img8_bad: -1, img8a_good: -1 }
},
{
// Test 9: same as Test 3
csp: "default-src 'none'; sandbox allow-same-origin",
file: "file_sandbox_9.html",
results: { img9_bad: -1, img9a_bad: -1 }
},
{
// Test 10: same as Test 4
csp: "default-src 'none'; sandbox allow-same-origin",
file: "file_sandbox_10.html",
results: { img10_bad: -1, img10a_bad: -1 }
},
{
// Test 11: same as Test 5
csp: "default-src 'none'; script-src 'unsafe-inline'; sandbox allow-scripts allow-same-origin",
file: "file_sandbox_11.html",
results: { img11_bad: -1, img11a_bad: -1, script11_bad: -1, script11a_bad: -1 },
nrOKmessages: 2 // sends 2 ok message
},
{
// Test 12: same as Test 6
csp: "sandbox allow-same-origin allow-scripts; default-src 'self' 'unsafe-inline';",
file: "file_sandbox_12.html",
results: { img12_bad: -1, script12_bad: -1 },
nrOKmessages: 4 // sends 4 ok message
},
];
// a postMessage handler that is used by sandboxed iframes without
// 'allow-same-origin' to communicate pass/fail back to this main page.
// it expects to be called with an object like:
// { ok: true/false,
// desc: <description of the test> which it then forwards to ok() }
window.addEventListener("message", receiveMessage, false);
function receiveMessage(event) {
ok_wrapper(event.data.ok, event.data.desc);
}
var completedTests = 0;
var passedTests = 0;
var totalTests = (function() {
var nrCSPloadTests = 0;
for(var i = 0; i < testCases.length; i++) {
nrCSPloadTests += Object.keys(testCases[i].results).length;
if (testCases[i].nrOKmessages) {
// + number of expected postMessages from iframe
nrCSPloadTests += testCases[i].nrOKmessages;
}
}
return nrCSPloadTests;
})();
function ok_wrapper(result, desc) {
ok(result, desc);
completedTests++;
if (result) {
passedTests++;
}
if (completedTests === totalTests) {
window.examiner.remove();
SimpleTest.finish();
}
}
// Set the iframe src and sandbox attribute
function runTest(test) {
var iframe = document.createElement('iframe');
document.getElementById('content').appendChild(iframe);
// set sandbox attribute
if (test.sandboxAttribute !== undefined) {
iframe.sandbox = test.sandboxAttribute;
}
// set query string
var src = 'file_testserver.sjs';
// path where the files are
var path = '/tests/dom/security/test/csp/';
src += '?file=' + escape(path+test.file);
if (test.csp !== undefined) {
src += '&csp=' + escape(test.csp);
}
iframe.src = src;
iframe.width = iframe.height = 10;
}
// Examiner related
// This is used to watch the blocked data bounce off CSP and allowed data
// get sent out to the wire.
function examiner() {
SpecialPowers.addObserver(this, "csp-on-violate-policy", false);
SpecialPowers.addObserver(this, "specialpowers-http-notify-request", false);
}
examiner.prototype = {
observe: function(subject, topic, data) {
var testpat = new RegExp("testid=([a-z0-9_]+)");
//_good things better be allowed!
//_bad things better be stopped!
if (topic === "specialpowers-http-notify-request") {
//these things were allowed by CSP
var uri = data;
if (!testpat.test(uri)) return;
var testid = testpat.exec(uri)[1];
if(/_good/.test(testid)) {
ok_wrapper(true, uri + " is allowed by csp");
} else {
ok_wrapper(false, uri + " should not be allowed by csp");
}
}
if(topic === "csp-on-violate-policy") {
//these were blocked... record that they were blocked
var asciiSpec = SpecialPowers.getPrivilegedProps(SpecialPowers.do_QueryInterface(subject, "nsIURI"), "asciiSpec");
if (!testpat.test(asciiSpec)) return;
var testid = testpat.exec(asciiSpec)[1];
if(/_bad/.test(testid)) {
ok_wrapper(true, asciiSpec + " was blocked by \"" + data + "\"");
} else {
ok_wrapper(false, asciiSpec + " should have been blocked by \"" + data + "\"");
}
}
},
// must eventually call this to remove the listener,
// or mochitests might get borked.
remove: function() {
SpecialPowers.removeObserver(this, "csp-on-violate-policy");
SpecialPowers.removeObserver(this, "specialpowers-http-notify-request");
}
}
window.examiner = new examiner();
SimpleTest.waitForExplicitFinish();
(function() { // Run tests:
for(var i = 0; i < testCases.length; i++) {
runTest(testCases[i]);
}
})();
</script>
</body>
</html>

Просмотреть файл

@ -93,7 +93,7 @@ function run_next_test() {
return;
}
channel = setupChannel(curTest.contentType);
channel.asyncOpen(new ChannelListener(), null);
channel.asyncOpen2(new ChannelListener());
}
function run_test() {

Просмотреть файл

@ -5,6 +5,7 @@ support-files =
[test_bug900724.html]
[test_bug1017896.html]
[test_bug1176757.html]
[test_bug1276240.html]
[test_content_element.html]
[test_custom_element_adopt_callbacks.html]
[test_custom_element_callback_innerhtml.html]

Просмотреть файл

@ -0,0 +1,55 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=1276240
-->
<head>
<title>Test for Bug 1276240</title>
<script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<a target="_blank"
href="https://bugzilla.mozilla.org/show_bug.cgi?id=1276240">Mozilla Bug 1276240</a>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
<script class="testbody" type="text/javascript">
/** Test for Bug 1276240 **/
// when passing null for the second argument, it would be ignored
function test() {
var e = document.createElement("p", null);
is(e.getAttribute("is"), null);
e = document.createElement("p", undefined);
is(e.getAttribute("is"), null);
e = document.createElementNS("http://www.w3.org/1999/xhtml", "p", null);
is(e.getAttribute("is"), null);
e = document.createElementNS("http://www.w3.org/1999/xhtml", "p", undefined);
is(e.getAttribute("is"), null);
}
function runTest() {
test();
SimpleTest.finish();
}
// test with webcomponents enabled
test();
// test with webcomponents disabled
SimpleTest.waitForExplicitFinish();
SpecialPowers.pushPrefEnv(
{ 'set': [["dom.webcomponents.enabled", false]]}, runTest);
</script>
</pre>
</body>
</html>

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше