Merge m-c to fx-team. a=merge

This commit is contained in:
Ryan VanderMeulen 2014-09-25 16:57:55 -04:00
commit dbd4755917
409 changed files with 47787 additions and 2844 deletions

View File

@ -104,7 +104,7 @@ var gSimpleMatchFunc = function gSimpleMatchFunc(aAccessible) {
// or has a flat subtree.
function isSingleLineage(acc) {
for (let child = acc; child; child = child.firstChild) {
if (child.childCount > 1) {
if (Utils.visibleChildCount(child) > 1) {
return false;
}
}
@ -118,7 +118,7 @@ var gSimpleMatchFunc = function gSimpleMatchFunc(aAccessible) {
if ([Roles.TEXT_LEAF, Roles.STATICTEXT].indexOf(child.role) >= 0) {
continue;
}
if (child.childCount > 0 || child.actionCount > 0) {
if (Utils.visibleChildCount(child) > 0 || child.actionCount > 0) {
return false;
}
}

View File

@ -360,6 +360,16 @@ this.Utils = { // jshint ignore:line
return hidden && hidden === 'true';
},
visibleChildCount: function visibleChildCount(aAccessible) {
let count = 0;
for (let child = aAccessible.firstChild; child; child = child.nextSibling) {
if (!this.isHidden(child)) {
++count;
}
}
return count;
},
inHiddenSubtree: function inHiddenSubtree(aAccessible) {
for (let acc=aAccessible; acc; acc=acc.parent) {
if (this.isHidden(acc)) {

View File

@ -3,6 +3,11 @@
<head>
<title>Traversal Rule test document</title>
<meta charset="utf-8" />
<style>
.content:before {
content: "Content";
}
</style>
</head>
<body>
<h3 id="heading-1">A small first heading</h3>
@ -96,6 +101,25 @@
<td>1</td>
</tr>
</table>
<section id="grid" role="grid">
<ol role="row">
<li role="presentation"></li>
<li role="columnheader" aria-label="Sunday">S</li>
<li role="columnheader">M</li>
</ol>
<ol role="row">
<li role="rowheader" aria-label="Week 1">1</li>
<li role="gridcell"><span>3</span><div></div></li>
<li role="gridcell"><span>4</span><div>7</div></li>
</ol>
<ol role="row">
<li role="rowheader">2</li>
<li role="gridcell"><span>5</span><div role="presentation">8</div></li>
<li id="gridcell4" role="gridcell">
<span>6</span><div aria-hidden="true"><div class="content"></div></div>
</li>
</ol>
</section>
<div id="separator-2" role="separator">Just an innocuous separator</div>
<table id="table-2">
<thead>

View File

@ -94,7 +94,7 @@
['separator-1', 'separator-2']);
queueTraversalSequence(gQueue, docAcc, TraversalRules.Table, null,
['table-1', 'table-2']);
['table-1', 'grid', 'table-2']);
queueTraversalSequence(gQueue, docAcc, TraversalRules.Simple, null,
['heading-1', 'Name:', 'input-1-1', 'label-1-2',
@ -114,13 +114,15 @@
' power is unfathomable.',
'• Lists of Programming Languages', 'Lisp ',
'1. Scheme', '2. Racket', '3. Clojure',
'4. Standard Lisp', 'link-0', ' Lisp', 'checkbox-1-5',
' LeLisp', '• JavaScript', 'heading-5',
'image-2', 'image-3', 'Not actually an image',
'link-1', 'anchor-1', 'link-2', 'anchor-2', 'link-3',
'3', '1', '4', '1', 'Just an innocuous separator',
'Dirty Words', 'Meaning', 'Mud', 'Wet Dirt',
'Dirt', 'Messy Stuff']);
'4. Standard Lisp', 'link-0', ' Lisp',
'checkbox-1-5', ' LeLisp', '• JavaScript',
'heading-5', 'image-2', 'image-3',
'Not actually an image', 'link-1', 'anchor-1',
'link-2', 'anchor-2', 'link-3', '3', '1', '4',
'1', 'S', 'M', '1', '3', '4', '7', '2', '5', '8',
'6', 'Just an innocuous separator', 'Dirty Words',
'Meaning', 'Mud', 'Wet Dirt', 'Dirt',
'Messy Stuff']);
gQueue.invoke();
}

View File

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="3a2947df41a480de1457a6dcdbf46ad0af70d8e0">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="c5d2e2f4ebf5f370d6003517057dcd47493dec90"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="a06714c555ca7068545f10b4437a16c14cd8e7f5"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="5883a99b6528ced9dafaed8d3ca2405fb285537e"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>

View File

@ -19,7 +19,7 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="c5d2e2f4ebf5f370d6003517057dcd47493dec90"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="a06714c555ca7068545f10b4437a16c14cd8e7f5"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="5883a99b6528ced9dafaed8d3ca2405fb285537e"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="cd88d860656c31c7da7bb310d6a160d0011b0961"/>

View File

@ -17,7 +17,7 @@
</project>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="c5d2e2f4ebf5f370d6003517057dcd47493dec90"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="a06714c555ca7068545f10b4437a16c14cd8e7f5"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="5883a99b6528ced9dafaed8d3ca2405fb285537e"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="20a1521efdac44c8219f00c2414de031891fb464"/>

View File

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="3a2947df41a480de1457a6dcdbf46ad0af70d8e0">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="c5d2e2f4ebf5f370d6003517057dcd47493dec90"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="a06714c555ca7068545f10b4437a16c14cd8e7f5"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="5883a99b6528ced9dafaed8d3ca2405fb285537e"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>

View File

@ -19,7 +19,7 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="c5d2e2f4ebf5f370d6003517057dcd47493dec90"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="a06714c555ca7068545f10b4437a16c14cd8e7f5"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="5883a99b6528ced9dafaed8d3ca2405fb285537e"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="platform_hardware_ril" path="hardware/ril" remote="b2g" revision="cd88d860656c31c7da7bb310d6a160d0011b0961"/>

View File

@ -15,7 +15,7 @@
<project name="platform_build" path="build" remote="b2g" revision="3a2947df41a480de1457a6dcdbf46ad0af70d8e0">
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="gaia" path="gaia" remote="mozillaorg" revision="c5d2e2f4ebf5f370d6003517057dcd47493dec90"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="a06714c555ca7068545f10b4437a16c14cd8e7f5"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="5883a99b6528ced9dafaed8d3ca2405fb285537e"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>

View File

@ -17,7 +17,7 @@
</project>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="c5d2e2f4ebf5f370d6003517057dcd47493dec90"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="a06714c555ca7068545f10b4437a16c14cd8e7f5"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="5883a99b6528ced9dafaed8d3ca2405fb285537e"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="20a1521efdac44c8219f00c2414de031891fb464"/>

View File

@ -4,6 +4,6 @@
"remote": "",
"branch": ""
},
"revision": "15291949ab37f96d1d1e30bb890a2604b4454894",
"revision": "253fcdd727387f6ad023de9aed30a20e7b8bd72d",
"repo_path": "/integration/gaia-central"
}

View File

@ -17,7 +17,7 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="c5d2e2f4ebf5f370d6003517057dcd47493dec90"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="a06714c555ca7068545f10b4437a16c14cd8e7f5"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="5883a99b6528ced9dafaed8d3ca2405fb285537e"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>

View File

@ -15,7 +15,7 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="c5d2e2f4ebf5f370d6003517057dcd47493dec90"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="a06714c555ca7068545f10b4437a16c14cd8e7f5"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="5883a99b6528ced9dafaed8d3ca2405fb285537e"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>

View File

@ -17,7 +17,7 @@
</project>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="fake-libdvm" path="dalvik" remote="b2g" revision="d50ae982b19f42f0b66d08b9eb306be81687869f"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="c5d2e2f4ebf5f370d6003517057dcd47493dec90"/>
<project name="gaia" path="gaia" remote="mozillaorg" revision="a06714c555ca7068545f10b4437a16c14cd8e7f5"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="5883a99b6528ced9dafaed8d3ca2405fb285537e"/>
<project name="moztt" path="external/moztt" remote="b2g" revision="562d357b72279a9e35d4af5aeecc8e1ffa2f44f1"/>
<project name="apitrace" path="external/apitrace" remote="apitrace" revision="20a1521efdac44c8219f00c2414de031891fb464"/>

View File

@ -17,7 +17,7 @@
<copyfile dest="Makefile" src="core/root.mk"/>
</project>
<project name="fake-dalvik" path="dalvik" remote="b2g" revision="ca1f327d5acc198bb4be62fa51db2c039032c9ce"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="c5d2e2f4ebf5f370d6003517057dcd47493dec90"/>
<project name="gaia.git" path="gaia" remote="mozillaorg" revision="a06714c555ca7068545f10b4437a16c14cd8e7f5"/>
<project name="gonk-misc" path="gonk-misc" remote="b2g" revision="5883a99b6528ced9dafaed8d3ca2405fb285537e"/>
<project name="rilproxy" path="rilproxy" remote="b2g" revision="827214fcf38d6569aeb5c6d6f31cb296d1f09272"/>
<project name="librecovery" path="librecovery" remote="b2g" revision="891e5069c0ad330d8191bf8c7b879c814258c89f"/>

View File

@ -207,6 +207,7 @@
@BINPATH@/components/dom_xpath.xpt
@BINPATH@/components/dom_xul.xpt
@BINPATH@/components/dom_time.xpt
@BINPATH@/components/dom_engineeringmode.xpt
@BINPATH@/components/downloads.xpt
@BINPATH@/components/editor.xpt
@BINPATH@/components/embed_base.xpt
@ -595,6 +596,10 @@
@BINPATH@/components/MozKeyboard.js
@BINPATH@/components/InputMethod.manifest
@BINPATH@/components/EngineeringMode.manifest
@BINPATH@/components/EngineeringModeAPI.js
@BINPATH@/components/EngineeringModeService.js
#ifdef MOZ_DEBUG
@BINPATH@/components/TestInterfaceJS.js
@BINPATH@/components/TestInterfaceJS.manifest

View File

@ -105,7 +105,7 @@ function test() {
function test1(aCallback) {
gDebugger.once(gDebugger.EVENTS.FETCHED_WATCH_EXPRESSIONS, () => {
checkWatchExpressions(26, {
a: "ReferenceError: a is not defined, did you mean 'z'?",
a: "ReferenceError: a is not defined",
this: { type: "object", class: "Object" },
prop: { type: "object", class: "String" },
args: { type: "undefined" }

View File

@ -173,6 +173,9 @@ nsCSPContext::ShouldLoad(nsContentPolicyType aContentType,
if (!mPolicies[p]->permits(aContentType,
aContentLocation,
nonce,
// aExtra is only non-null if
// the channel got redirected.
(aExtra != nullptr),
violatedDirective)) {
// If the policy is violated and not report-only, reject the load and
// report to the console
@ -792,7 +795,8 @@ class CSPReportSenderRunnable MOZ_FINAL : public nsRunnable
uint64_t aInnerWindowID,
nsCSPContext* aCSPContext)
: mBlockedContentSource(aBlockedContentSource)
, mOriginalURI(aOriginalURI) , mViolatedPolicyIndex(aViolatedPolicyIndex)
, mOriginalURI(aOriginalURI)
, mViolatedPolicyIndex(aViolatedPolicyIndex)
, mReportOnlyFlag(aReportOnlyFlag)
, mViolatedDirective(aViolatedDirective)
, mSourceFile(aSourceFile)
@ -1024,6 +1028,7 @@ nsCSPContext::PermitsAncestry(nsIDocShell* aDocShell, bool* outPermitsAncestry)
if (!mPolicies[i]->permits(nsIContentPolicy::TYPE_DOCUMENT,
ancestorsArray[a],
EmptyString(), // no nonce
false, // no redirect
violatedDirective)) {
// Policy is violated
// Send reports, but omit the ancestor URI if cross-origin as per spec

View File

@ -30,18 +30,21 @@ GetCspParserLog()
#define CSPPARSERLOG(args) PR_LOG(GetCspParserLog(), 4, args)
static const char16_t COLON = ':';
static const char16_t SEMICOLON = ';';
static const char16_t SLASH = '/';
static const char16_t PLUS = '+';
static const char16_t DASH = '-';
static const char16_t DOT = '.';
static const char16_t UNDERLINE = '_';
static const char16_t WILDCARD = '*';
static const char16_t WHITESPACE = ' ';
static const char16_t SINGLEQUOTE = '\'';
static const char16_t OPEN_CURL = '{';
static const char16_t CLOSE_CURL = '}';
static const char16_t COLON = ':';
static const char16_t SEMICOLON = ';';
static const char16_t SLASH = '/';
static const char16_t PLUS = '+';
static const char16_t DASH = '-';
static const char16_t DOT = '.';
static const char16_t UNDERLINE = '_';
static const char16_t TILDE = '~';
static const char16_t WILDCARD = '*';
static const char16_t WHITESPACE = ' ';
static const char16_t SINGLEQUOTE = '\'';
static const char16_t OPEN_CURL = '{';
static const char16_t CLOSE_CURL = '}';
static const char16_t NUMBER_SIGN = '#';
static const char16_t QUESTIONMARK = '?';
static uint32_t kSubHostPathCharacterCutoff = 512;
@ -145,6 +148,23 @@ nsCSPParser::resetCurChar(const nsAString& aToken)
resetCurValue();
}
// The path is terminated by the first question mark ("?") or
// number sign ("#") character, or by the end of the URI.
// http://tools.ietf.org/html/rfc3986#section-3.3
bool
nsCSPParser::atEndOfPath()
{
return (atEnd() || peek(QUESTIONMARK) || peek(NUMBER_SIGN));
}
bool
nsCSPParser::atValidPathChar()
{
return (peek(isCharacterToken) || peek(isNumberToken) ||
peek(DASH) || peek(DOT) ||
peek(UNDERLINE) || peek(TILDE));
}
void
nsCSPParser::logWarningErrorToConsole(uint32_t aSeverityFlag,
const char* aProperty,
@ -189,25 +209,6 @@ nsCSPParser::schemeChar()
accept(DOT);
}
bool
nsCSPParser::fileAndArguments()
{
CSPPARSERLOG(("nsCSPParser::fileAndArguments, mCurToken: %s, mCurValue: %s",
NS_ConvertUTF16toUTF8(mCurToken).get(),
NS_ConvertUTF16toUTF8(mCurValue).get()));
// Possibly we already parsed part of the file in path(), therefore accepting "."
if (accept(DOT) && !accept(isCharacterToken)) {
return false;
}
// From now on, accept pretty much anything to avoid unnecessary errors
while (!atEnd()) {
advance();
}
return true;
}
// port = ":" ( 1*DIGIT / "*" )
bool
nsCSPParser::port()
@ -253,24 +254,23 @@ nsCSPParser::subPath(nsCSPHostSrc* aCspHost)
// in case we are parsing unrecognized characters in the following loop.
uint32_t charCounter = 0;
while (!atEnd() && !peek(DOT)) {
++charCounter;
while (hostChar() || accept(UNDERLINE)) {
/* consume */
++charCounter;
}
if (accept(SLASH)) {
++charCounter;
while (!atEndOfPath()) {
if (peek(SLASH)) {
aCspHost->appendPath(mCurValue);
// Resetting current value since we are appending parts of the path
// to aCspHost, e.g; "http://www.example.com/path1/path2" then the
// first part is "/path1", second part "/path2"
resetCurValue();
}
if (atEnd()) {
return true;
else if (!atValidPathChar()) {
const char16_t* params[] = { mCurToken.get() };
logWarningErrorToConsole(nsIScriptError::warningFlag,
"couldntParseInvalidSource",
params, ArrayLength(params));
return false;
}
if (charCounter > kSubHostPathCharacterCutoff) {
advance();
if (++charCounter > kSubHostPathCharacterCutoff) {
return false;
}
}
@ -298,7 +298,10 @@ nsCSPParser::path(nsCSPHostSrc* aCspHost)
params, ArrayLength(params));
return false;
}
if (atEnd()) {
if (atEndOfPath()) {
// one slash right after host [port] is also considered a path, e.g.
// www.example.com/ should result in www.example.com/
aCspHost->appendPath(mCurValue);
return true;
}
// path can begin with "/" but not "//"
@ -324,7 +327,7 @@ nsCSPParser::subHost()
// in case we are parsing unrecognized characters in the following loop.
uint32_t charCounter = 0;
while (!atEnd() && !peek(COLON) && !peek(SLASH)) {
while (!atEndOfPath() && !peek(COLON) && !peek(SLASH)) {
++charCounter;
while (hostChar()) {
/* consume */
@ -468,7 +471,7 @@ nsCSPParser::hostSource()
cspHost->setPort(mCurValue);
}
if (atEnd()) {
if (atEndOfPath()) {
return cspHost;
}
@ -482,14 +485,6 @@ nsCSPParser::hostSource()
delete cspHost;
return nullptr;
}
// Calling fileAndArguments to see if there are any files to parse;
// if an error occurs, fileAndArguments() reports the error; if
// fileAndArguments returns true, we have a valid file, so we add it.
if (fileAndArguments()) {
cspHost->setFileAndArguments(mCurValue);
}
return cspHost;
}

View File

@ -126,7 +126,6 @@ class nsCSPParser {
bool schemeChar();
bool port();
bool path(nsCSPHostSrc* aCspHost);
bool fileAndArguments();
bool subHost(); // helper function to parse subDomains
bool subPath(nsCSPHostSrc* aCspHost); // helper function to parse paths
@ -173,6 +172,9 @@ class nsCSPParser {
mCurValue.Truncate();
}
bool atEndOfPath();
bool atValidPathChar();
void resetCurChar(const nsAString& aToken);
void logWarningErrorToConsole(uint32_t aSeverityFlag,

View File

@ -214,7 +214,7 @@ nsCSPBaseSrc::~nsCSPBaseSrc()
// nsCSPKeywordSrc and nsCSPHashSource fall back to this base class
// implementation which will never allow the load.
bool
nsCSPBaseSrc::permits(nsIURI* aUri, const nsAString& aNonce) const
nsCSPBaseSrc::permits(nsIURI* aUri, const nsAString& aNonce, bool aWasRedirected) const
{
#ifdef PR_LOGGING
{
@ -251,7 +251,7 @@ nsCSPSchemeSrc::~nsCSPSchemeSrc()
}
bool
nsCSPSchemeSrc::permits(nsIURI* aUri, const nsAString& aNonce) const
nsCSPSchemeSrc::permits(nsIURI* aUri, const nsAString& aNonce, bool aWasRedirected) const
{
#ifdef PR_LOGGING
{
@ -288,7 +288,7 @@ nsCSPHostSrc::~nsCSPHostSrc()
}
bool
nsCSPHostSrc::permits(nsIURI* aUri, const nsAString& aNonce) const
nsCSPHostSrc::permits(nsIURI* aUri, const nsAString& aNonce, bool aWasRedirected) const
{
#ifdef PR_LOGGING
{
@ -342,6 +342,34 @@ nsCSPHostSrc::permits(nsIURI* aUri, const nsAString& aNonce) const
return false;
}
// If there is a path, we have to enforce path-level matching,
// unless the channel got redirected, see:
// http://www.w3.org/TR/CSP11/#source-list-paths-and-redirects
if (!aWasRedirected && !mPath.IsEmpty()) {
// cloning uri so we can ignore the ref
nsCOMPtr<nsIURI> uri;
aUri->CloneIgnoringRef(getter_AddRefs(uri));
nsAutoCString uriPath;
rv = uri->GetPath(uriPath);
NS_ENSURE_SUCCESS(rv, false);
// check if the last character of mPath is '/'; if so
// we just have to check loading resource is within
// the allowed path.
if (mPath.Last() == '/') {
if (!StringBeginsWith(NS_ConvertUTF8toUTF16(uriPath), mPath)) {
return false;
}
}
// otherwise mPath whitelists a specific file, and we have to
// check if the loading resource matches that whitelisted file.
else {
if (!mPath.Equals(NS_ConvertUTF8toUTF16(uriPath))) {
return false;
}
}
}
// If port uses wildcard, allow the load.
if (mPort.EqualsASCII("*")) {
return true;
@ -369,7 +397,7 @@ nsCSPHostSrc::permits(nsIURI* aUri, const nsAString& aNonce) const
}
}
// At the end: scheme, host, port, match; allow the load.
// At the end: scheme, host, path, and port match -> allow the load.
return true;
}
@ -397,9 +425,8 @@ nsCSPHostSrc::toString(nsAString& outStr) const
outStr.Append(mPort);
}
// in CSP 1.1, paths are ignoed
// outStr.Append(mPath);
// outStr.Append(mFileAndArguments);
// append path
outStr.Append(mPath);
}
void
@ -423,13 +450,6 @@ nsCSPHostSrc::appendPath(const nsAString& aPath)
ToLowerCase(mPath);
}
void
nsCSPHostSrc::setFileAndArguments(const nsAString& aFile)
{
mFileAndArguments = aFile;
ToLowerCase(mFileAndArguments);
}
/* ===== nsCSPKeywordSrc ===================== */
nsCSPKeywordSrc::nsCSPKeywordSrc(CSPKeyword aKeyword)
@ -469,7 +489,7 @@ nsCSPNonceSrc::~nsCSPNonceSrc()
}
bool
nsCSPNonceSrc::permits(nsIURI* aUri, const nsAString& aNonce) const
nsCSPNonceSrc::permits(nsIURI* aUri, const nsAString& aNonce, bool aWasRedirected) const
{
#ifdef PR_LOGGING
{
@ -599,7 +619,7 @@ nsCSPDirective::~nsCSPDirective()
}
bool
nsCSPDirective::permits(nsIURI* aUri, const nsAString& aNonce) const
nsCSPDirective::permits(nsIURI* aUri, const nsAString& aNonce, bool aWasRedirected) const
{
#ifdef PR_LOGGING
{
@ -610,7 +630,7 @@ nsCSPDirective::permits(nsIURI* aUri, const nsAString& aNonce) const
#endif
for (uint32_t i = 0; i < mSrcs.Length(); i++) {
if (mSrcs[i]->permits(aUri, aNonce)) {
if (mSrcs[i]->permits(aUri, aNonce, aWasRedirected)) {
return true;
}
}
@ -621,7 +641,7 @@ bool
nsCSPDirective::permits(nsIURI* aUri) const
{
nsString dummyNonce;
return permits(aUri, dummyNonce);
return permits(aUri, dummyNonce, false);
}
bool
@ -754,6 +774,7 @@ bool
nsCSPPolicy::permits(nsContentPolicyType aContentType,
nsIURI* aUri,
const nsAString& aNonce,
bool aWasRedirected,
nsAString& outViolatedDirective) const
{
#ifdef PR_LOGGING
@ -774,7 +795,7 @@ nsCSPPolicy::permits(nsContentPolicyType aContentType,
for (uint32_t i = 0; i < mDirectives.Length(); i++) {
// Check if the directive name matches
if (mDirectives[i]->restrictsContentType(aContentType)) {
if (!mDirectives[i]->permits(aUri, aNonce)) {
if (!mDirectives[i]->permits(aUri, aNonce, aWasRedirected)) {
mDirectives[i]->toString(outViolatedDirective);
return false;
}
@ -795,7 +816,7 @@ nsCSPPolicy::permits(nsContentPolicyType aContentType,
// If the above loop runs through, we haven't found a matching directive.
// Avoid relooping, just store the result of default-src while looping.
if (defaultDir) {
if (!defaultDir->permits(aUri, aNonce)) {
if (!defaultDir->permits(aUri, aNonce, aWasRedirected)) {
defaultDir->toString(outViolatedDirective);
return false;
}

View File

@ -191,7 +191,7 @@ class nsCSPBaseSrc {
nsCSPBaseSrc();
virtual ~nsCSPBaseSrc();
virtual bool permits(nsIURI* aUri, const nsAString& aNonce) const;
virtual bool permits(nsIURI* aUri, const nsAString& aNonce, bool aWasRedirected) const;
virtual bool allows(enum CSPKeyword aKeyword, const nsAString& aHashOrNonce) const;
virtual void toString(nsAString& outStr) const = 0;
};
@ -203,7 +203,7 @@ class nsCSPSchemeSrc : public nsCSPBaseSrc {
explicit nsCSPSchemeSrc(const nsAString& aScheme);
virtual ~nsCSPSchemeSrc();
bool permits(nsIURI* aUri, const nsAString& aNonce) const;
bool permits(nsIURI* aUri, const nsAString& aNonce, bool aWasRedirected) const;
void toString(nsAString& outStr) const;
private:
@ -217,20 +217,18 @@ class nsCSPHostSrc : public nsCSPBaseSrc {
explicit nsCSPHostSrc(const nsAString& aHost);
virtual ~nsCSPHostSrc();
bool permits(nsIURI* aUri, const nsAString& aNonce) const;
bool permits(nsIURI* aUri, const nsAString& aNonce, bool aWasRedirected) const;
void toString(nsAString& outStr) const;
void setScheme(const nsAString& aScheme);
void setPort(const nsAString& aPort);
void appendPath(const nsAString &aPath);
void setFileAndArguments(const nsAString& aFile);
private:
nsString mScheme;
nsString mHost;
nsString mPort;
nsString mPath;
nsString mFileAndArguments;
};
/* =============== nsCSPKeywordSrc ============ */
@ -254,7 +252,7 @@ class nsCSPNonceSrc : public nsCSPBaseSrc {
explicit nsCSPNonceSrc(const nsAString& aNonce);
virtual ~nsCSPNonceSrc();
bool permits(nsIURI* aUri, const nsAString& aNonce) const;
bool permits(nsIURI* aUri, const nsAString& aNonce, bool aWasRedirected) const;
bool allows(enum CSPKeyword aKeyword, const nsAString& aHashOrNonce) const;
void toString(nsAString& outStr) const;
@ -298,7 +296,7 @@ class nsCSPDirective {
explicit nsCSPDirective(enum CSPDirective aDirective);
virtual ~nsCSPDirective();
bool permits(nsIURI* aUri, const nsAString& aNonce) const;
bool permits(nsIURI* aUri, const nsAString& aNonce, bool aWasRedirected) const;
bool permits(nsIURI* aUri) const;
bool allows(enum CSPKeyword aKeyword, const nsAString& aHashOrNonce) const;
void toString(nsAString& outStr) const;
@ -331,6 +329,7 @@ class nsCSPPolicy {
bool permits(nsContentPolicyType aContentType,
nsIURI* aUri,
const nsAString& aNonce,
bool aWasRedirected,
nsAString& outViolatedDirective) const;
bool permitsBaseURI(nsIURI* aUri) const;
bool allows(nsContentPolicyType aContentType,

View File

@ -1033,7 +1033,7 @@ nsFrameMessageManager::ReceiveMessage(nsISupports* aTarget,
JS::Rooted<JS::Value> thisValue(cx, JS::UndefinedValue());
JS::Rooted<JS::Value> funval(cx);
if (JS_ObjectIsCallable(cx, object)) {
if (JS::IsCallable(object)) {
// If the listener is a JS function:
funval.setObject(*object);
@ -1055,7 +1055,7 @@ nsFrameMessageManager::ReceiveMessage(nsISupports* aTarget,
return NS_ERROR_UNEXPECTED;
// Check if the object is even callable.
NS_ENSURE_STATE(JS_ObjectIsCallable(cx, &funval.toObject()));
NS_ENSURE_STATE(JS::IsCallable(&funval.toObject()));
thisValue.setObject(*object);
}

View File

@ -3980,7 +3980,7 @@ ArrayBufferBuilder::setCapacity(uint32_t aNewCap)
{
MOZ_ASSERT(!mMapPtr);
uint8_t *newdata = (uint8_t *) realloc(mDataPtr, aNewCap);
uint8_t *newdata = (uint8_t *) js_realloc(mDataPtr, aNewCap);
if (!newdata) {
return false;
}

View File

@ -287,52 +287,70 @@ nsresult TestIgnorePaths() {
{ "script-src http://www.example.com",
"script-src http://www.example.com" },
{ "script-src http://www.example.com/",
"script-src http://www.example.com" },
"script-src http://www.example.com/" },
{ "script-src http://www.example.com/path-1",
"script-src http://www.example.com" },
"script-src http://www.example.com/path-1" },
{ "script-src http://www.example.com/path-1/",
"script-src http://www.example.com" },
"script-src http://www.example.com/path-1/" },
{ "script-src http://www.example.com/path-1/path_2",
"script-src http://www.example.com" },
"script-src http://www.example.com/path-1/path_2" },
{ "script-src http://www.example.com/path-1/path_2/",
"script-src http://www.example.com" },
"script-src http://www.example.com/path-1/path_2/" },
{ "script-src http://www.example.com/path-1/path_2/file.js",
"script-src http://www.example.com" },
"script-src http://www.example.com/path-1/path_2/file.js" },
{ "script-src http://www.example.com/path-1/path_2/file_1.js",
"script-src http://www.example.com" },
"script-src http://www.example.com/path-1/path_2/file_1.js" },
{ "script-src http://www.example.com/path-1/path_2/file-2.js",
"script-src http://www.example.com" },
"script-src http://www.example.com/path-1/path_2/file-2.js" },
{ "script-src http://www.example.com/path-1/path_2/f.js",
"script-src http://www.example.com" },
"script-src http://www.example.com/path-1/path_2/f.js" },
{ "script-src http://www.example.com:88",
"script-src http://www.example.com:88" },
{ "script-src http://www.example.com:88/",
"script-src http://www.example.com:88" },
"script-src http://www.example.com:88/" },
{ "script-src http://www.example.com:88/path-1",
"script-src http://www.example.com:88" },
"script-src http://www.example.com:88/path-1" },
{ "script-src http://www.example.com:88/path-1/",
"script-src http://www.example.com:88" },
"script-src http://www.example.com:88/path-1/" },
{ "script-src http://www.example.com:88/path-1/path_2",
"script-src http://www.example.com:88" },
"script-src http://www.example.com:88/path-1/path_2" },
{ "script-src http://www.example.com:88/path-1/path_2/",
"script-src http://www.example.com:88" },
"script-src http://www.example.com:88/path-1/path_2/" },
{ "script-src http://www.example.com:88/path-1/path_2/file.js",
"script-src http://www.example.com:88" },
"script-src http://www.example.com:88/path-1/path_2/file.js" },
{ "script-src http://www.example.com:*",
"script-src http://www.example.com:*" },
{ "script-src http://www.example.com:*/",
"script-src http://www.example.com:*" },
"script-src http://www.example.com:*/" },
{ "script-src http://www.example.com:*/path-1",
"script-src http://www.example.com:*" },
"script-src http://www.example.com:*/path-1" },
{ "script-src http://www.example.com:*/path-1/",
"script-src http://www.example.com:*" },
"script-src http://www.example.com:*/path-1/" },
{ "script-src http://www.example.com:*/path-1/path_2",
"script-src http://www.example.com:*" },
"script-src http://www.example.com:*/path-1/path_2" },
{ "script-src http://www.example.com:*/path-1/path_2/",
"script-src http://www.example.com:*" },
"script-src http://www.example.com:*/path-1/path_2/" },
{ "script-src http://www.example.com:*/path-1/path_2/file.js",
"script-src http://www.example.com:*" },
{ "report-uri http://www.example.com",
"script-src http://www.example.com:*/path-1/path_2/file.js" },
{ "script-src http://www.example.com#foo",
"script-src http://www.example.com" },
{ "script-src http://www.example.com?foo=bar",
"script-src http://www.example.com" },
{ "script-src http://www.example.com:8888#foo",
"script-src http://www.example.com:8888" },
{ "script-src http://www.example.com:8888?foo",
"script-src http://www.example.com:8888" },
{ "script-src http://www.example.com/#foo",
"script-src http://www.example.com/" },
{ "script-src http://www.example.com/?foo",
"script-src http://www.example.com/" },
{ "script-src http://www.example.com/path-1/file.js#foo",
"script-src http://www.example.com/path-1/file.js" },
{ "script-src http://www.example.com/path-1/file.js?foo",
"script-src http://www.example.com/path-1/file.js" },
{ "script-src http://www.example.com/path-1/file.js?foo#bar",
"script-src http://www.example.com/path-1/file.js" },
{ "report-uri http://www.example.com/",
"report-uri http://www.example.com/" },
{ "report-uri http://www.example.com:8888/asdf",
"report-uri http://www.example.com:8888/asdf" },
@ -401,9 +419,9 @@ nsresult TestSimplePolicies() {
{ "script-src 'none' 'none' 'none';",
"script-src 'none'" },
{ "script-src http://www.example.com/path-1//",
"script-src http://www.example.com" },
"script-src http://www.example.com/path-1//" },
{ "script-src http://www.example.com/path-1//path_2",
"script-src http://www.example.com" },
"script-src http://www.example.com/path-1//path_2" },
{ "default-src 127.0.0.1",
"default-src http://127.0.0.1" },
{ "default-src 127.0.0.1:*",
@ -619,21 +637,21 @@ nsresult TestGoodGeneratedPolicies() {
{ "connect-src https://three:81",
"connect-src https://three:81" },
{ "script-src http://self.com:80/foo",
"script-src http://self.com:80" },
"script-src http://self.com:80/foo" },
{ "object-src http://self.com/foo",
"object-src http://self.com" },
"object-src http://self.com/foo" },
{ "report-uri /report.py",
"report-uri http://www.selfuri.com/report.py"},
{ "img-src http://foo.org:34/report.py",
"img-src http://foo.org:34" },
"img-src http://foo.org:34/report.py" },
{ "media-src foo/bar/report.py",
"media-src http://foo" },
"media-src http://foo/bar/report.py" },
{ "report-uri /",
"report-uri http://www.selfuri.com/"},
{ "font-src https://self.com/report.py",
"font-src https://self.com" },
"font-src https://self.com/report.py" },
{ "connect-src https://foo.com/report.py",
"connect-src https://foo.com" },
"connect-src https://foo.com/report.py" },
{ "default-src *; report-uri http://www.reporturi.com/",
"default-src *; report-uri http://www.reporturi.com/" },
{ "default-src http://first.com",
@ -651,15 +669,15 @@ nsresult TestGoodGeneratedPolicies() {
{ "frame-src http://bar.com",
"frame-src http://bar.com" },
{ "font-src http://self.com/",
"font-src http://self.com" },
"font-src http://self.com/" },
{ "script-src 'self'",
"script-src http://www.selfuri.com" },
{ "default-src http://self.com/foo.png",
"default-src http://self.com" },
"default-src http://self.com/foo.png" },
{ "script-src http://self.com/foo.js",
"script-src http://self.com" },
"script-src http://self.com/foo.js" },
{ "object-src http://bar.com/foo.js",
"object-src http://bar.com" },
"object-src http://bar.com/foo.js" },
{ "style-src http://FOO.COM",
"style-src http://foo.com" },
{ "img-src HTTP",
@ -697,11 +715,11 @@ nsresult TestGoodGeneratedPolicies() {
{ "frame-ancestors http://self:80",
"frame-ancestors http://self:80" },
{ "frame-ancestors http://self.com/bar",
"frame-ancestors http://self.com" },
"frame-ancestors http://self.com/bar" },
{ "default-src 'self'; frame-ancestors 'self'",
"default-src http://www.selfuri.com; frame-ancestors http://www.selfuri.com" },
{ "frame-ancestors http://bar.com/foo.png",
"frame-ancestors http://bar.com" },
"frame-ancestors http://bar.com/foo.png" },
};
uint32_t policyCount = sizeof(policies) / sizeof(PolicyTest);
@ -747,111 +765,111 @@ nsresult TestGoodGeneratedPoliciesForPathHandling() {
{ "img-src http://test1.example.com",
"img-src http://test1.example.com" },
{ "img-src http://test1.example.com/",
"img-src http://test1.example.com" },
"img-src http://test1.example.com/" },
{ "img-src http://test1.example.com/path-1",
"img-src http://test1.example.com" },
"img-src http://test1.example.com/path-1" },
{ "img-src http://test1.example.com/path-1/",
"img-src http://test1.example.com" },
"img-src http://test1.example.com/path-1/" },
{ "img-src http://test1.example.com/path-1/path_2/",
"img-src http://test1.example.com" },
"img-src http://test1.example.com/path-1/path_2/" },
{ "img-src http://test1.example.com/path-1/path_2/file.js",
"img-src http://test1.example.com" },
"img-src http://test1.example.com/path-1/path_2/file.js" },
{ "img-src http://test1.example.com/path-1/path_2/file_1.js",
"img-src http://test1.example.com" },
"img-src http://test1.example.com/path-1/path_2/file_1.js" },
{ "img-src http://test1.example.com/path-1/path_2/file-2.js",
"img-src http://test1.example.com" },
"img-src http://test1.example.com/path-1/path_2/file-2.js" },
{ "img-src http://test1.example.com/path-1/path_2/f.js",
"img-src http://test1.example.com" },
"img-src http://test1.example.com/path-1/path_2/f.js" },
{ "img-src http://test1.example.com/path-1/path_2/f.oo.js",
"img-src http://test1.example.com" },
"img-src http://test1.example.com/path-1/path_2/f.oo.js" },
{ "img-src test1.example.com",
"img-src http://test1.example.com" },
{ "img-src test1.example.com/",
"img-src http://test1.example.com" },
"img-src http://test1.example.com/" },
{ "img-src test1.example.com/path-1",
"img-src http://test1.example.com" },
"img-src http://test1.example.com/path-1" },
{ "img-src test1.example.com/path-1/",
"img-src http://test1.example.com" },
"img-src http://test1.example.com/path-1/" },
{ "img-src test1.example.com/path-1/path_2/",
"img-src http://test1.example.com" },
"img-src http://test1.example.com/path-1/path_2/" },
{ "img-src test1.example.com/path-1/path_2/file.js",
"img-src http://test1.example.com" },
"img-src http://test1.example.com/path-1/path_2/file.js" },
{ "img-src test1.example.com/path-1/path_2/file_1.js",
"img-src http://test1.example.com" },
"img-src http://test1.example.com/path-1/path_2/file_1.js" },
{ "img-src test1.example.com/path-1/path_2/file-2.js",
"img-src http://test1.example.com" },
"img-src http://test1.example.com/path-1/path_2/file-2.js" },
{ "img-src test1.example.com/path-1/path_2/f.js",
"img-src http://test1.example.com" },
"img-src http://test1.example.com/path-1/path_2/f.js" },
{ "img-src test1.example.com/path-1/path_2/f.oo.js",
"img-src http://test1.example.com" },
"img-src http://test1.example.com/path-1/path_2/f.oo.js" },
{ "img-src *.example.com",
"img-src http://*.example.com" },
{ "img-src *.example.com/",
"img-src http://*.example.com" },
"img-src http://*.example.com/" },
{ "img-src *.example.com/path-1",
"img-src http://*.example.com" },
"img-src http://*.example.com/path-1" },
{ "img-src *.example.com/path-1/",
"img-src http://*.example.com" },
"img-src http://*.example.com/path-1/" },
{ "img-src *.example.com/path-1/path_2/",
"img-src http://*.example.com" },
"img-src http://*.example.com/path-1/path_2/" },
{ "img-src *.example.com/path-1/path_2/file.js",
"img-src http://*.example.com" },
"img-src http://*.example.com/path-1/path_2/file.js" },
{ "img-src *.example.com/path-1/path_2/file_1.js",
"img-src http://*.example.com" },
"img-src http://*.example.com/path-1/path_2/file_1.js" },
{ "img-src *.example.com/path-1/path_2/file-2.js",
"img-src http://*.example.com" },
"img-src http://*.example.com/path-1/path_2/file-2.js" },
{ "img-src *.example.com/path-1/path_2/f.js",
"img-src http://*.example.com" },
"img-src http://*.example.com/path-1/path_2/f.js" },
{ "img-src *.example.com/path-1/path_2/f.oo.js",
"img-src http://*.example.com" },
"img-src http://*.example.com/path-1/path_2/f.oo.js" },
{ "img-src test1.example.com:80",
"img-src http://test1.example.com:80" },
{ "img-src test1.example.com:80/",
"img-src http://test1.example.com:80" },
"img-src http://test1.example.com:80/" },
{ "img-src test1.example.com:80/path-1",
"img-src http://test1.example.com:80" },
"img-src http://test1.example.com:80/path-1" },
{ "img-src test1.example.com:80/path-1/",
"img-src http://test1.example.com:80" },
"img-src http://test1.example.com:80/path-1/" },
{ "img-src test1.example.com:80/path-1/path_2",
"img-src http://test1.example.com:80" },
"img-src http://test1.example.com:80/path-1/path_2" },
{ "img-src test1.example.com:80/path-1/path_2/",
"img-src http://test1.example.com:80" },
"img-src http://test1.example.com:80/path-1/path_2/" },
{ "img-src test1.example.com:80/path-1/path_2/file.js",
"img-src http://test1.example.com:80" },
"img-src http://test1.example.com:80/path-1/path_2/file.js" },
{ "img-src test1.example.com:80/path-1/path_2/f.ile.js",
"img-src http://test1.example.com:80" },
"img-src http://test1.example.com:80/path-1/path_2/f.ile.js" },
{ "img-src test1.example.com:*",
"img-src http://test1.example.com:*" },
{ "img-src test1.example.com:*/",
"img-src http://test1.example.com:*" },
"img-src http://test1.example.com:*/" },
{ "img-src test1.example.com:*/path-1",
"img-src http://test1.example.com:*" },
"img-src http://test1.example.com:*/path-1" },
{ "img-src test1.example.com:*/path-1/",
"img-src http://test1.example.com:*" },
"img-src http://test1.example.com:*/path-1/" },
{ "img-src test1.example.com:*/path-1/path_2",
"img-src http://test1.example.com:*" },
"img-src http://test1.example.com:*/path-1/path_2" },
{ "img-src test1.example.com:*/path-1/path_2/",
"img-src http://test1.example.com:*" },
"img-src http://test1.example.com:*/path-1/path_2/" },
{ "img-src test1.example.com:*/path-1/path_2/file.js",
"img-src http://test1.example.com:*" },
"img-src http://test1.example.com:*/path-1/path_2/file.js" },
{ "img-src test1.example.com:*/path-1/path_2/f.ile.js",
"img-src http://test1.example.com:*" },
"img-src http://test1.example.com:*/path-1/path_2/f.ile.js" },
{ "img-src http://test1.example.com/abc//",
"img-src http://test1.example.com" },
"img-src http://test1.example.com/abc//" },
{ "img-src https://test1.example.com/abc/def//",
"img-src https://test1.example.com" },
"img-src https://test1.example.com/abc/def//" },
{ "img-src https://test1.example.com/abc/def/ghi//",
"img-src https://test1.example.com" },
"img-src https://test1.example.com/abc/def/ghi//" },
{ "img-src http://test1.example.com:80/abc//",
"img-src http://test1.example.com:80" },
"img-src http://test1.example.com:80/abc//" },
{ "img-src https://test1.example.com:80/abc/def//",
"img-src https://test1.example.com:80" },
"img-src https://test1.example.com:80/abc/def//" },
{ "img-src https://test1.example.com:80/abc/def/ghi//",
"img-src https://test1.example.com:80" },
"img-src https://test1.example.com:80/abc/def/ghi//" },
{ "img-src https://test1.example.com/abc////////////def/",
"img-src https://test1.example.com" },
"img-src https://test1.example.com/abc////////////def/" },
{ "img-src https://test1.example.com/abc////////////",
"img-src https://test1.example.com" },
"img-src https://test1.example.com/abc////////////" },
};
uint32_t policyCount = sizeof(policies) / sizeof(PolicyTest);

View File

@ -223,7 +223,7 @@
// (the privileged junk scope, but we don't have a good way to test for that
// specifically).
is(unprivilegedObject.expando, undefined, "parent->child references should get Xrays");
todo_is(unprivilegedObject.wrappedJSObject.expando, 42, "parent->child references should get waivable Xrays - see bug 1065811");
is(unprivilegedObject.wrappedJSObject.expando, 42, "parent->child references should get waivable Xrays");
// Send an object to the child to let it verify invariants in the other direction.
function passMe() { return 42; };

View File

@ -1,10 +1,10 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Bug 916054 - URLs with path are ignored by FF's CSP parser</title>
<title>Bug 808292 - Implement path-level host-source matching to CSP</title>
</head>
<body>
<div id="testdiv">blocked</div>
<script src="http://test1.example.com/tests/content/base/test/csp/file_csp_regexp_parsing.js"></script>
<script src="http://test1.example.com/tests/content/base/test/csp/file_csp_path_matching.js#foo"></script>
</body>
</html>

View File

@ -0,0 +1,10 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Bug 808292 - Implement path-level host-source matching to CSP</title>
</head>
<body>
<div id="testdiv">blocked</div>
<script src="http://example.com/tests/content/base/test/csp/file_csp_path_matching_redirect_server.sjs"></script>
</body>
</html>

View File

@ -0,0 +1,13 @@
// Redirect server specifically to handle redirects
// for path-level host-source matching
// see https://bugzilla.mozilla.org/show_bug.cgi?id=808292
function handleRequest(request, response)
{
var newLocation = "http://test1.example.com/tests/content/base/test/csp/file_csp_path_matching.js";
response.setStatusLine("1.1", 302, "Found");
response.setHeader("Cache-Control", "no-cache", false);
response.setHeader("Location", newLocation, false);
}

View File

@ -81,9 +81,11 @@ support-files =
file_hash_source.html^headers^
file_self_none_as_hostname_confusion.html
file_self_none_as_hostname_confusion.html^headers^
file_csp_path_matching.html
file_csp_path_matching.js
file_csp_path_matching_redirect.html
file_csp_path_matching_redirect_server.sjs
file_csp_testserver.sjs
file_csp_regexp_parsing.html
file_csp_regexp_parsing.js
file_report_uri_missing_in_report_only_header.html
file_report_uri_missing_in_report_only_header.html^headers^
file_csp_report.html
@ -121,7 +123,8 @@ skip-if = (buildapp == 'b2g' && (toolkit != 'gonk' || debug)) || toolkit == 'and
skip-if = e10s || buildapp == 'b2g' # can't compute hashes in child process (bug 958702)
[test_self_none_as_hostname_confusion.html]
[test_bug949549.html]
[test_csp_regexp_parsing.html]
[test_csp_path_matching.html]
[test_csp_path_matching_redirect.html]
[test_report_uri_missing_in_report_only_header.html]
[test_csp_report.html]
skip-if = e10s || buildapp == 'b2g' # http-on-opening-request observer not supported in child process (bug 1009632)

View File

@ -1,7 +1,7 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Bug 916054 - URLs with path are ignored by FF's CSP parser</title>
<title>Bug 808292 - Implement path-level host-source matching to CSP</title>
<!-- Including SimpleTest.js so we can use waitForExplicitFinish !-->
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
@ -16,49 +16,51 @@
SimpleTest.waitForExplicitFinish();
/* Description of the test:
* We are loading the following url (including a fragment portion):
* http://test1.example.com/tests/content/base/test/csp/file_csp_path_matching.js#foo
* using different policies and verify that the applied policy is accurately enforced.
*/
var policies = [
["allowed", "*"],
["allowed", "test1.example.com"],
["allowed", "test1.example.com/"],
["allowed", "test1.example.com/path-1"],
["allowed", "test1.example.com/path-1/"],
["allowed", "test1.example.com/path-1/path_2/"],
["allowed", "test1.example.com/path-1/path_2/file.js"],
["allowed", "test1.example.com/path-1/path_2/file_1.js"],
["allowed", "test1.example.com/path-1/path_2/file-2.js"],
["allowed", "test1.example.com/path-1/path_2/f.js"],
["allowed", "test1.example.com/path-1/path_2/f.oo.js"],
["allowed", "test1.example.com/tests/content/base/test/csp/"],
["allowed", "test1.example.com/tests/content/base/test/csp/file_csp_path_matching.js"],
["allowed", "test1.example.com?foo=val"],
["allowed", "test1.example.com/?foo=val"],
["allowed", "test1.example.com/tests/content/base/test/csp/?foo=val"],
["allowed", "test1.example.com/tests/content/base/test/csp/file_csp_path_matching.js?foo=val"],
["allowed", "test1.example.com#foo"],
["allowed", "test1.example.com/#foo"],
["allowed", "test1.example.com/tests/content/base/test/csp/#foo"],
["allowed", "test1.example.com/tests/content/base/test/csp/file_csp_path_matching.js#foo"],
["allowed", "*.example.com"],
["allowed", "*.example.com/"],
["allowed", "*.example.com/path-1"],
["allowed", "*.example.com/path-1/"],
["allowed", "*.example.com/path-1/path_2/"],
["allowed", "*.example.com/path-1/path_2/file.js"],
["allowed", "*.example.com/path-1/path_2/file_1.js"],
["allowed", "*.example.com/path-1/path_2/file-2.js"],
["allowed", "*.example.com/path-1/path_2/f.js"],
["allowed", "*.example.com/path-1/path_2/f.oo.js"],
["allowed", "*.example.com/tests/content/base/test/csp/"],
["allowed", "*.example.com/tests/content/base/test/csp/file_csp_path_matching.js"],
["allowed", "test1.example.com:80"],
["allowed", "test1.example.com:80/"],
["allowed", "test1.example.com:80/path-1"],
["allowed", "test1.example.com:80/path-1/"],
["allowed", "test1.example.com:80/path-1/path_2"],
["allowed", "test1.example.com:80/path-1/path_2/"],
["allowed", "test1.example.com:80/path-1/path_2/file.js"],
["allowed", "test1.example.com:80/path-1/path_2/f.ile.js"],
["allowed", "test1.example.com:80/tests/content/base/test/csp/"],
["allowed", "test1.example.com:80/tests/content/base/test/csp/file_csp_path_matching.js"],
["allowed", "test1.example.com:*"],
["allowed", "test1.example.com:*/"],
["allowed", "test1.example.com:*/path-1"],
["allowed", "test1.example.com:*/path-1/"],
["allowed", "test1.example.com:*/path-1/path_2"],
["allowed", "test1.example.com:*/path-1/path_2/"],
["allowed", "test1.example.com:*/path-1/path_2/file.js"],
["allowed", "test1.example.com:*/path-1/path_2/f.ile.js"],
// the following tests should fail
["blocked", "test1.example.com:88path-1/"],
["blocked", "test1.example.com:80.js"],
["blocked", "test1.example.com:*.js"],
["blocked", "test1.example.com:*."]
["allowed", "test1.example.com:*/tests/content/base/test/csp/"],
["allowed", "test1.example.com:*/tests/content/base/test/csp/file_csp_path_matching.js"],
["blocked", "test1.example.com/tests"],
["blocked", "test1.example.com/tests/content/base/test/csp"],
["blocked", "test1.example.com/tests/content/base/test/csp/file_csp_path_matching.py"],
["blocked", "test1.example.com:8888/tests"],
["blocked", "test1.example.com:8888/tests/content/base/test/csp"],
["blocked", "test1.example.com:8888/tests/content/base/test/csp/file_csp_path_matching.py"],
]
var counter = 0;
@ -72,7 +74,7 @@ function loadNextTest() {
policy = policies[counter++];
var src = "file_csp_testserver.sjs";
// append the file that should be served
src += "?file=" + escape("tests/content/base/test/csp/file_csp_regexp_parsing.html");
src += "?file=" + escape("tests/content/base/test/csp/file_csp_path_matching.html");
// append the CSP that should be used to serve the file
src += "&csp=" + escape("default-src 'none'; script-src " + policy[1]);

View File

@ -0,0 +1,89 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Bug 808292 - Implement path-level host-source matching to CSP (redirects)</title>
<!-- Including SimpleTest.js so we can use waitForExplicitFinish !-->
<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" style="visibility: hidden">
<iframe style="width:100%;" id="testframe"></iframe>
</div>
<script class="testbody" type="text/javascript">
SimpleTest.waitForExplicitFinish();
/* Description of the test:
* First, we try to load a script where the *path* does not match.
* Second, we try to load a script which is allowed by the CSPs
* script-src directive. The script then gets redirected to
* an URL where the host matches, but the path wouldn't.
* Since 'paths' should not be taken into account after redirects,
* that load should succeed. We are using a similar test setup
* as described in the spec, see:
* http://www.w3.org/TR/CSP11/#source-list-paths-and-redirects
*/
var policy = "script-src http://example.com http://test1.example.com/CSPAllowsScriptsInThatFolder";
var tests = [
{
// the script in file_csp_path_matching.html
// <script src="http://test1.example.com/tests/content/base/..">
// is not within the whitelisted path by the csp-policy
// hence the script is 'blocked' by CSP.
expected: "blocked",
uri: "tests/content/base/test/csp/file_csp_path_matching.html"
},
{
// the script in file_csp_path_matching_redirect.html
// <script src="http://example.com/tests/content/..">
// gets redirected to: http://test1.example.com/tests/content
// where after the redirect the path of the policy is not enforced
// anymore and hence execution of the script is 'allowed'.
expected: "allowed",
uri: "tests/content/base/test/csp/file_csp_path_matching_redirect.html"
},
];
var counter = 0;
var curTest;
function checkResult() {
try {
document.getElementById("testframe").removeEventListener('load', checkResult, false);
var testframe = document.getElementById("testframe");
var divcontent = testframe.contentWindow.document.getElementById('testdiv').innerHTML;
is(divcontent, curTest.expected, "should be blocked in test " + (counter - 1) + "!");
}
catch (e) {
ok(false, "ERROR: could not access content in test " + (counter - 1) + "!");
}
loadNextTest();
}
function loadNextTest() {
if (counter == tests.length) {
SimpleTest.finish();
}
else {
curTest = tests[counter++];
var src = "file_csp_testserver.sjs";
// append the file that should be served
src += "?file=" + escape(curTest.uri);
// append the CSP that should be used to serve the file
src += "&csp=" + escape(policy);
document.getElementById("testframe").addEventListener("load", checkResult, false);
document.getElementById("testframe").src = src;
}
}
loadNextTest();
</script>
</body>
</html>

View File

@ -33,8 +33,7 @@ window.onerror = function(message, uri, line) {
</script>
<script type="application/javascript">
window.onerror = function(message, uri, line) {
ok(message.contains("ReferenceError: c is not defined"),
"Should have correct error message");
is(message, "ReferenceError: c is not defined", "Should have correct error message");
is(uri,
"http://mochi.test:8888/tests/content/base/test/bug461735-redirect2.sjs",
"Unexpected error location URI");

View File

@ -38,8 +38,7 @@ window.onerror = function(message, uri, line) {
errorFired = false;
global = "";
window.onerror = function(message, uri, line) {
ok(message.contains("ReferenceError: c is not defined"),
"Should have correct error message");
is(message, "ReferenceError: c is not defined", "Should have correct error message");
is(uri,
"http://example.com/tests/content/base/test/bug696301-script-1.js",
"Should also have correct script URI");

View File

@ -40,8 +40,7 @@ window.onerror = function(message, uri, line) {
errorFired = false;
global = "";
window.onerror = function(message, uri, line) {
ok(message.contains("ReferenceError: c is not defined"),
"Should have correct error message");
is(message, "ReferenceError: c is not defined", "Should have correct error message");
is(uri,
"http://example.com/tests/content/base/test/bug696301-script-1.js",
"Should also have correct script URI");

View File

@ -222,6 +222,14 @@ let Activities = {
startActivity: function activities_startActivity(aMsg) {
debug("StartActivity: " + JSON.stringify(aMsg));
// The caller app will be killed by |assertAppHasStatus| if it doesn't
// fit our permission requirement.
let callerApp = this.callers[aMsg.id].mm;
if (aMsg.options.name === 'internal-system-engineering-mode' &&
!callerApp.assertAppHasStatus(Ci.nsIPrincipal.APP_STATUS_CERTIFIED)) {
return;
}
let self = this;
let successCb = function successCb(aResults) {
debug(JSON.stringify(aResults));
@ -341,6 +349,12 @@ let Activities = {
};
let matchFunc = function matchFunc(aResult) {
let calleeApp = DOMApplicationRegistry.getAppByManifestURL(aResult.manifest);
// Only allow certified apps to handle this special activity
if (aMsg.options.name === 'internal-system-engineering-mode' &&
calleeApp.appStatus !== Ci.nsIPrincipal.APP_STATUS_CERTIFIED) {
return false;
}
return ActivitiesServiceFilter.match(aMsg.options.data,
aResult.description.filters);
};

View File

@ -56,7 +56,15 @@ ActivityProxy.prototype = {
// Only let certified apps enumerate providers for this filter.
if (aOptions.getFilterResults === true &&
principal.appStatus != Ci.nsIPrincipal.APP_STATUS_CERTIFIED) {
Services.DOMRequest.fireError(this.activity, "SecurityError");
Services.DOMRequest.fireErrorAsync(this.activity, "SecurityError");
Services.obs.notifyObservers(null, "Activity:Error", null);
return;
}
// Only let certified app to initiate this activitiy.
if (aOptions.name === 'internal-system-engineering-mode' &&
principal.appStatus != Ci.nsIPrincipal.APP_STATUS_CERTIFIED) {
Services.DOMRequest.fireErrorAsync(this.activity, "SecurityError");
Services.obs.notifyObservers(null, "Activity:Error", null);
return;
}

View File

@ -3,6 +3,9 @@
* 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/. */
#ifndef mozilla_dom_AnimationUtils_h
#define mozilla_dom_AnimationUtils_h
#include "mozilla/TimeStamp.h"
#include "mozilla/dom/Nullable.h"
@ -27,3 +30,5 @@ public:
} // namespace dom
} // namespace mozilla
#endif

View File

@ -14,7 +14,7 @@ EXPORTS.mozilla.dom += [
'AnimationTimeline.h',
]
SOURCES += [
UNIFIED_SOURCES += [
'Animation.cpp',
'AnimationEffect.cpp',
'AnimationPlayer.cpp',

View File

@ -487,6 +487,12 @@ this.PermissionsTable = { geolocation: {
certified: ALLOW_ACTION,
access: ["read", "write"],
additional: ["settings-api"]
},
"engineering-mode": {
app: DENY_ACTION,
trusted: DENY_ACTION,
privileged: DENY_ACTION,
certified: ALLOW_ACTION
}
};

View File

@ -1535,7 +1535,7 @@ BaseStubConstructor(nsIWeakReference* aWeakOwner,
}
// Check if the object is even callable.
NS_ENSURE_STATE(JS_ObjectIsCallable(cx, &funval.toObject()));
NS_ENSURE_STATE(JS::IsCallable(&funval.toObject()));
{
// wrap parameters in the target compartment
// we also pass in the calling window as the first argument

View File

@ -5274,7 +5274,7 @@ nsGlobalWindow::RequestAnimationFrame(JS::Handle<JS::Value> aCallback,
JSContext* cx,
int32_t* aHandle)
{
if (!aCallback.isObject() || !JS_ObjectIsCallable(cx, &aCallback.toObject())) {
if (!aCallback.isObject() || !JS::IsCallable(&aCallback.toObject())) {
return NS_ERROR_INVALID_ARG;
}

View File

@ -1699,7 +1699,7 @@ NativeToString(JSContext* cx, JS::Handle<JSObject*> wrapper,
if (!JS_WrapValue(cx, &toString)) {
return false;
}
MOZ_ASSERT(JS_ObjectIsCallable(cx, &toString.toObject()));
MOZ_ASSERT(JS::IsCallable(&toString.toObject()));
JS::Rooted<JS::Value> toStringResult(cx);
if (JS_CallFunctionValue(cx, obj, toString, JS::HandleValueArray::empty(),
&toStringResult)) {

View File

@ -20,7 +20,7 @@ CallbackInterface::GetCallableProperty(JSContext* cx, JS::Handle<jsid> aPropId,
return false;
}
if (!aCallable.isObject() ||
!JS_ObjectIsCallable(cx, &aCallable.toObject())) {
!JS::IsCallable(&aCallable.toObject())) {
char* propName =
JS_EncodeString(cx, JS_FORGET_STRING_FLATNESS(JSID_TO_FLAT_STRING(aPropId)));
nsPrintfCString description("Property '%s'", propName);

View File

@ -4911,7 +4911,7 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
conversion = indent(CGCallbackTempRoot(name).define())
if allowTreatNonCallableAsNull and type.treatNonCallableAsNull():
haveCallable = "JS_ObjectIsCallable(cx, &${val}.toObject())"
haveCallable = "JS::IsCallable(&${val}.toObject())"
if not isDefinitelyObject:
haveCallable = "${val}.isObject() && " + haveCallable
if defaultValue is not None:
@ -4936,7 +4936,7 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
template = conversion
else:
template = wrapObjectTemplate(
"if (JS_ObjectIsCallable(cx, &${val}.toObject())) {\n" +
"if (JS::IsCallable(&${val}.toObject())) {\n" +
conversion +
"} else {\n" +
indent(onFailureNotCallable(failureCode).define()) +
@ -13417,7 +13417,7 @@ class CGCallback(CGClass):
def getConstructors(self):
if (not self.idlObject.isInterface() and
not self.idlObject._treatNonObjectAsNull):
body = "MOZ_ASSERT(JS_ObjectIsCallable(nullptr, mCallback));\n"
body = "MOZ_ASSERT(JS::IsCallable(mCallback));\n"
else:
# Not much we can assert about it, other than not being null, and
# CallbackObject does that already.
@ -13879,7 +13879,7 @@ class CallCallback(CallbackMethod):
def getCallGuard(self):
if self.callback._treatNonObjectAsNull:
return "JS_ObjectIsCallable(cx, mCallback) && "
return "JS::IsCallable(mCallback) && "
return ""
@ -13927,7 +13927,7 @@ class CallbackOperationBase(CallbackMethod):
return 'JS::Rooted<JS::Value> callable(cx);\n' + getCallableFromProp
return fill(
"""
bool isCallable = JS_ObjectIsCallable(cx, mCallback);
bool isCallable = JS::IsCallable(mCallback);
JS::Rooted<JS::Value> callable(cx);
if (isCallable) {
callable = JS::ObjectValue(*mCallback);

View File

@ -54,6 +54,8 @@ public:
virtual void Accept(int aFd, BluetoothSocketResultHandler* aRes) = 0;
virtual void Close(BluetoothSocketResultHandler* aRes) = 0;
protected:
virtual ~BluetoothSocketInterface();
};

View File

@ -238,7 +238,7 @@ BluetoothA2dpManager::ResetAvrcp()
mMediaNumber = 0;
mTotalMediaCount = 0;
mPosition = 0;
mPlayStatus = ControlPlayStatus::PLAYSTATUS_UNKNOWN;
mPlayStatus = ControlPlayStatus::PLAYSTATUS_STOPPED;
}
/*

View File

@ -395,7 +395,10 @@ public:
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(sBluetoothSocketInterface);
sBluetoothSocketInterface->Accept(mFd, new AcceptResultHandler(GetIO()));
BluetoothSocketResultHandler* res = new AcceptResultHandler(GetIO());
GetIO()->mConsumer->SetCurrentResultHandler(res);
sBluetoothSocketInterface->Accept(mFd, res);
return NS_OK;
}
@ -476,6 +479,7 @@ BluetoothSocket::BluetoothSocket(BluetoothSocketObserver* aObserver,
bool aAuth,
bool aEncrypt)
: mObserver(aObserver)
, mCurrentRes(nullptr)
, mImpl(nullptr)
, mAuth(aAuth)
, mEncrypt(aEncrypt)
@ -527,13 +531,15 @@ BluetoothSocket::ConnectSocket(const nsAString& aDeviceAddress, int aChannel)
mImpl = new DroidSocketImpl(XRE_GetIOMessageLoop(), this);
BluetoothSocketResultHandler* res = new ConnectSocketResultHandler(mImpl);
SetCurrentResultHandler(res);
// TODO: uuid as argument
sBluetoothSocketInterface->Connect(
aDeviceAddress,
BluetoothSocketType::RFCOMM,
UUID_OBEX_OBJECT_PUSH,
aChannel, mEncrypt, mAuth,
new ConnectSocketResultHandler(mImpl));
aChannel, mEncrypt, mAuth, res);
return true;
}
@ -576,12 +582,14 @@ BluetoothSocket::ListenSocket(int aChannel)
mImpl = new DroidSocketImpl(XRE_GetIOMessageLoop(), this);
BluetoothSocketResultHandler* res = new ListenResultHandler(mImpl);
SetCurrentResultHandler(res);
sBluetoothSocketInterface->Listen(
BluetoothSocketType::RFCOMM,
NS_LITERAL_STRING("OBEX Object Push"),
UUID_OBEX_OBJECT_PUSH,
aChannel, mEncrypt, mAuth,
new ListenResultHandler(mImpl));
aChannel, mEncrypt, mAuth, res);
return true;
}
@ -590,10 +598,16 @@ void
BluetoothSocket::CloseSocket()
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(sBluetoothSocketInterface);
if (!mImpl) {
return;
}
// Stop any watching |SocketMessageWatcher|
if (mCurrentRes) {
sBluetoothSocketInterface->Close(mCurrentRes);
}
// From this point on, we consider mImpl as being deleted.
// We sever the relationship here so any future calls to listen or connect
// will create a new implementation.
@ -633,6 +647,8 @@ BluetoothSocket::OnConnectSuccess()
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(mObserver);
SetCurrentResultHandler(nullptr);
mObserver->OnSocketConnectSuccess(this);
}
@ -641,6 +657,8 @@ BluetoothSocket::OnConnectError()
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(mObserver);
SetCurrentResultHandler(nullptr);
mObserver->OnSocketConnectError(this);
}

View File

@ -13,6 +13,7 @@
BEGIN_BLUETOOTH_NAMESPACE
class BluetoothSocketObserver;
class BluetoothSocketResultHandler;
class DroidSocketImpl;
class BluetoothSocket : public mozilla::ipc::SocketConsumerBase
@ -47,8 +48,14 @@ public:
mDeviceAddress = aDeviceAddress;
}
inline void SetCurrentResultHandler(BluetoothSocketResultHandler* aRes)
{
mCurrentRes = aRes;
}
private:
BluetoothSocketObserver* mObserver;
BluetoothSocketResultHandler* mCurrentRes;
DroidSocketImpl* mImpl;
nsString mDeviceAddress;
bool mAuth;

View File

@ -9,24 +9,25 @@
#include <unistd.h>
#include <sys/socket.h>
#include "BluetoothHALHelpers.h"
#include "nsClassHashtable.h"
#include "nsXULAppAPI.h"
BEGIN_BLUETOOTH_NAMESPACE
typedef
BluetoothHALInterfaceRunnable1<BluetoothSocketResultHandler, void,
int, int>
int, int>
BluetoothSocketHALIntResultRunnable;
typedef
BluetoothHALInterfaceRunnable3<BluetoothSocketResultHandler, void,
int, const nsString, int,
int, const nsAString_internal&, int>
int, const nsString, int,
int, const nsAString_internal&, int>
BluetoothSocketHALIntStringIntResultRunnable;
typedef
BluetoothHALInterfaceRunnable1<BluetoothSocketResultHandler, void,
BluetoothStatus, BluetoothStatus>
BluetoothStatus, BluetoothStatus>
BluetoothSocketHALErrorRunnable;
static nsresult
@ -78,11 +79,11 @@ DispatchBluetoothSocketHALResult(
void
BluetoothSocketHALInterface::Listen(BluetoothSocketType aType,
const nsAString& aServiceName,
const uint8_t aServiceUuid[16],
int aChannel, bool aEncrypt,
bool aAuth,
BluetoothSocketResultHandler* aRes)
const nsAString& aServiceName,
const uint8_t aServiceUuid[16],
int aChannel, bool aEncrypt,
bool aAuth,
BluetoothSocketResultHandler* aRes)
{
int fd;
bt_status_t status;
@ -109,6 +110,34 @@ BluetoothSocketHALInterface::Listen(BluetoothSocketType aType,
( ((_cmsghdr)->cmsg_level == SOL_SOCKET) && \
((_cmsghdr)->cmsg_type == SCM_RIGHTS) )
class SocketMessageWatcher;
/* |SocketMessageWatcherWrapper| wraps SocketMessageWatcher to keep it from
* being released by hash table's Remove() method.
*/
class SocketMessageWatcherWrapper
{
public:
SocketMessageWatcherWrapper(SocketMessageWatcher* aSocketMessageWatcher)
: mSocketMessageWatcher(aSocketMessageWatcher)
{
MOZ_ASSERT(mSocketMessageWatcher);
}
SocketMessageWatcher* GetSocketMessageWatcher()
{
return mSocketMessageWatcher;
}
private:
SocketMessageWatcher* mSocketMessageWatcher;
};
/* |sWatcherHashTable| maps result handlers to corresponding watchers */
static nsClassHashtable<nsRefPtrHashKey<BluetoothSocketResultHandler>,
SocketMessageWatcherWrapper>
sWatcherHashtable;
/* |SocketMessageWatcher| receives Bluedroid's socket setup
* messages on the I/O thread. You need to inherit from this
* class to make use of it.
@ -135,11 +164,14 @@ public:
static const unsigned char OFF_CHANNEL2 = 12;
static const unsigned char OFF_STATUS = 16;
SocketMessageWatcher(int aFd)
SocketMessageWatcher(int aFd, BluetoothSocketResultHandler* aRes)
: mFd(aFd)
, mClientFd(-1)
, mLen(0)
{ }
, mRes(aRes)
{
MOZ_ASSERT(mRes);
}
virtual ~SocketMessageWatcher()
{ }
@ -164,7 +196,7 @@ public:
}
if (IsComplete() || status != STATUS_SUCCESS) {
mWatcher.StopWatchingFileDescriptor();
StopWatching();
Proceed(status);
}
}
@ -174,6 +206,9 @@ public:
void Watch()
{
// add this watcher and its result handler to hash table
sWatcherHashtable.Put(mRes, new SocketMessageWatcherWrapper(this));
MessageLoopForIO::current()->WatchFileDescriptor(
mFd,
true,
@ -182,6 +217,14 @@ public:
this);
}
void StopWatching()
{
mWatcher.StopWatchingFileDescriptor();
// remove this watcher and its result handler from hash table
sWatcherHashtable.Remove(mRes);
}
bool IsComplete() const
{
return mLen == (MSG1_SIZE + MSG2_SIZE);
@ -224,6 +267,11 @@ public:
return mClientFd;
}
BluetoothSocketResultHandler* GetResultHandler() const
{
return mRes;
}
private:
BluetoothStatus RecvMsg1()
{
@ -322,6 +370,7 @@ private:
int mClientFd;
unsigned char mLen;
uint8_t mBuf[MSG1_SIZE + MSG2_SIZE];
nsRefPtr<BluetoothSocketResultHandler> mRes;
};
/* |SocketMessageWatcherTask| starts a SocketMessageWatcher
@ -373,32 +422,27 @@ class ConnectWatcher MOZ_FINAL : public SocketMessageWatcher
{
public:
ConnectWatcher(int aFd, BluetoothSocketResultHandler* aRes)
: SocketMessageWatcher(aFd)
, mRes(aRes)
: SocketMessageWatcher(aFd, aRes)
{ }
void Proceed(BluetoothStatus aStatus) MOZ_OVERRIDE
{
if (mRes) {
DispatchBluetoothSocketHALResult(
mRes, &BluetoothSocketResultHandler::Connect, GetFd(),
GetBdAddress(), GetConnectionStatus(), aStatus);
}
DispatchBluetoothSocketHALResult(
GetResultHandler(), &BluetoothSocketResultHandler::Connect,
GetFd(), GetBdAddress(), GetConnectionStatus(), aStatus);
MessageLoopForIO::current()->PostTask(
FROM_HERE, new DeleteTask<ConnectWatcher>(this));
}
private:
nsRefPtr<BluetoothSocketResultHandler> mRes;
};
void
BluetoothSocketHALInterface::Connect(const nsAString& aBdAddr,
BluetoothSocketType aType,
const uint8_t aUuid[16],
int aChannel, bool aEncrypt,
bool aAuth,
BluetoothSocketResultHandler* aRes)
BluetoothSocketType aType,
const uint8_t aUuid[16],
int aChannel, bool aEncrypt,
bool aAuth,
BluetoothSocketResultHandler* aRes)
{
int fd;
bt_status_t status;
@ -425,10 +469,10 @@ BluetoothSocketHALInterface::Connect(const nsAString& aBdAddr,
}
}
/* Specializes SocketMessageWatcher for Accept operations by
* reading the socket messages from Bluedroid and forwarding
* the received client socket to the resource handler. The
* first message is received immediately. When there's a new
/* |AcceptWatcher| specializes SocketMessageWatcher for Accept
* operations by reading the socket messages from Bluedroid and
* forwarding the received client socket to the resource handler.
* The first message is received immediately. When there's a new
* connection, Bluedroid sends the 2nd message with the socket
* info and socket file descriptor.
*/
@ -436,37 +480,69 @@ class AcceptWatcher MOZ_FINAL : public SocketMessageWatcher
{
public:
AcceptWatcher(int aFd, BluetoothSocketResultHandler* aRes)
: SocketMessageWatcher(aFd)
, mRes(aRes)
{
/* not supplying a result handler leaks received file descriptor */
MOZ_ASSERT(mRes);
}
: SocketMessageWatcher(aFd, aRes)
{ }
void Proceed(BluetoothStatus aStatus) MOZ_OVERRIDE
{
if (mRes) {
DispatchBluetoothSocketHALResult(
mRes, &BluetoothSocketResultHandler::Accept, GetClientFd(),
GetBdAddress(), GetConnectionStatus(), aStatus);
}
DispatchBluetoothSocketHALResult(
GetResultHandler(), &BluetoothSocketResultHandler::Accept,
GetClientFd(), GetBdAddress(), GetConnectionStatus(), aStatus);
MessageLoopForIO::current()->PostTask(
FROM_HERE, new DeleteTask<AcceptWatcher>(this));
}
private:
nsRefPtr<BluetoothSocketResultHandler> mRes;
};
void
BluetoothSocketHALInterface::Accept(int aFd,
BluetoothSocketResultHandler* aRes)
BluetoothSocketResultHandler* aRes)
{
/* receive Bluedroid's socket-setup messages and client fd */
Task* t = new SocketMessageWatcherTask(new AcceptWatcher(aFd, aRes));
XRE_GetIOMessageLoop()->PostTask(FROM_HERE, t);
}
/* |DeleteSocketMessageWatcherTask| deletes a watching SocketMessageWatcher
* on the I/O task
*/
class DeleteSocketMessageWatcherTask MOZ_FINAL : public Task
{
public:
DeleteSocketMessageWatcherTask(BluetoothSocketResultHandler* aRes)
: mRes(aRes)
{
MOZ_ASSERT(mRes);
}
void Run() MOZ_OVERRIDE
{
// look up hash table for the watcher corresponding to |mRes|
SocketMessageWatcherWrapper* wrapper = sWatcherHashtable.Get(mRes);
if (!wrapper) {
return;
}
// stop the watcher if it exists
SocketMessageWatcher* watcher = wrapper->GetSocketMessageWatcher();
watcher->StopWatching();
watcher->Proceed(STATUS_DONE);
}
private:
BluetoothSocketResultHandler* mRes;
};
void
BluetoothSocketHALInterface::Close(BluetoothSocketResultHandler* aRes)
{
MOZ_ASSERT(aRes);
/* stop the watcher corresponding to |aRes| */
Task* t = new DeleteSocketMessageWatcherTask(aRes);
XRE_GetIOMessageLoop()->PostTask(FROM_HERE, t);
}
BluetoothSocketHALInterface::BluetoothSocketHALInterface(
const btsock_interface_t* aInterface)
: mInterface(aInterface)

View File

@ -36,6 +36,8 @@ public:
void Accept(int aFd, BluetoothSocketResultHandler* aRes);
void Close(BluetoothSocketResultHandler* aRes);
protected:
BluetoothSocketHALInterface(const btsock_interface_t* aInterface);
~BluetoothSocketHALInterface();

View File

@ -38,5 +38,7 @@
/* CHLD values */
#define BTA_AG_CHLD_VAL "(0,1,2,3)"
/* SDP AVRCP 1.5 feature */
#define SDP_AVRCP_1_5 FALSE
#endif /* B2G_BDROID_BUILDCFG_H */

View File

@ -54,6 +54,8 @@ public:
virtual void Accept(int aFd, BluetoothSocketResultHandler* aRes) = 0;
virtual void Close(BluetoothSocketResultHandler* aRes) = 0;
protected:
virtual ~BluetoothSocketInterface();
};

View File

@ -182,7 +182,7 @@ MobileConnectionListener::Listen(bool aStart)
NS_ENSURE_TRUE(service, false);
nsCOMPtr<nsIMobileConnection> connection;
mcService->GetItemByServiceId(mClientId, getter_AddRefs(connection));
service->GetItemByServiceId(mClientId, getter_AddRefs(connection));
NS_ENSURE_TRUE(connection, false);
nsresult rv;

View File

@ -395,7 +395,10 @@ public:
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(sBluetoothSocketInterface);
sBluetoothSocketInterface->Accept(mFd, new AcceptResultHandler(GetIO()));
BluetoothSocketResultHandler* res = new AcceptResultHandler(GetIO());
GetIO()->mConsumer->SetCurrentResultHandler(res);
sBluetoothSocketInterface->Accept(mFd, res);
return NS_OK;
}
@ -476,6 +479,7 @@ BluetoothSocket::BluetoothSocket(BluetoothSocketObserver* aObserver,
bool aAuth,
bool aEncrypt)
: mObserver(aObserver)
, mCurrentRes(nullptr)
, mImpl(nullptr)
, mAuth(aAuth)
, mEncrypt(aEncrypt)
@ -527,13 +531,15 @@ BluetoothSocket::ConnectSocket(const nsAString& aDeviceAddress, int aChannel)
mImpl = new DroidSocketImpl(XRE_GetIOMessageLoop(), this);
BluetoothSocketResultHandler* res = new ConnectSocketResultHandler(mImpl);
SetCurrentResultHandler(res);
// TODO: uuid as argument
sBluetoothSocketInterface->Connect(
aDeviceAddress,
BluetoothSocketType::RFCOMM,
UUID_OBEX_OBJECT_PUSH,
aChannel, mEncrypt, mAuth,
new ConnectSocketResultHandler(mImpl));
aChannel, mEncrypt, mAuth, res);
return true;
}
@ -576,12 +582,14 @@ BluetoothSocket::ListenSocket(int aChannel)
mImpl = new DroidSocketImpl(XRE_GetIOMessageLoop(), this);
BluetoothSocketResultHandler* res = new ListenResultHandler(mImpl);
SetCurrentResultHandler(res);
sBluetoothSocketInterface->Listen(
BluetoothSocketType::RFCOMM,
NS_LITERAL_STRING("OBEX Object Push"),
UUID_OBEX_OBJECT_PUSH,
aChannel, mEncrypt, mAuth,
new ListenResultHandler(mImpl));
aChannel, mEncrypt, mAuth, res);
return true;
}
@ -590,10 +598,16 @@ void
BluetoothSocket::CloseSocket()
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(sBluetoothSocketInterface);
if (!mImpl) {
return;
}
// Stop any watching |SocketMessageWatcher|
if (mCurrentRes) {
sBluetoothSocketInterface->Close(mCurrentRes);
}
// From this point on, we consider mImpl as being deleted.
// We sever the relationship here so any future calls to listen or connect
// will create a new implementation.
@ -633,6 +647,8 @@ BluetoothSocket::OnConnectSuccess()
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(mObserver);
SetCurrentResultHandler(nullptr);
mObserver->OnSocketConnectSuccess(this);
}
@ -641,6 +657,8 @@ BluetoothSocket::OnConnectError()
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(mObserver);
SetCurrentResultHandler(nullptr);
mObserver->OnSocketConnectError(this);
}

View File

@ -13,6 +13,7 @@
BEGIN_BLUETOOTH_NAMESPACE
class BluetoothSocketObserver;
class BluetoothSocketResultHandler;
class DroidSocketImpl;
class BluetoothSocket : public mozilla::ipc::SocketConsumerBase
@ -47,8 +48,14 @@ public:
mDeviceAddress = aDeviceAddress;
}
inline void SetCurrentResultHandler(BluetoothSocketResultHandler* aRes)
{
mCurrentRes = aRes;
}
private:
BluetoothSocketObserver* mObserver;
BluetoothSocketResultHandler* mCurrentRes;
DroidSocketImpl* mImpl;
nsString mDeviceAddress;
bool mAuth;

View File

@ -9,6 +9,7 @@
#include <sys/socket.h>
#include <unistd.h>
#include "BluetoothHALHelpers.h"
#include "nsClassHashtable.h"
#include "nsXULAppAPI.h"
BEGIN_BLUETOOTH_NAMESPACE
@ -109,6 +110,34 @@ BluetoothSocketHALInterface::Listen(BluetoothSocketType aType,
( ((_cmsghdr)->cmsg_level == SOL_SOCKET) && \
((_cmsghdr)->cmsg_type == SCM_RIGHTS) )
class SocketMessageWatcher;
/* |SocketMessageWatcherWrapper| wraps SocketMessageWatcher to keep it from
* being released by hash table's Remove() method.
*/
class SocketMessageWatcherWrapper
{
public:
SocketMessageWatcherWrapper(SocketMessageWatcher* aSocketMessageWatcher)
: mSocketMessageWatcher(aSocketMessageWatcher)
{
MOZ_ASSERT(mSocketMessageWatcher);
}
SocketMessageWatcher* GetSocketMessageWatcher()
{
return mSocketMessageWatcher;
}
private:
SocketMessageWatcher* mSocketMessageWatcher;
};
/* |sWatcherHashTable| maps result handlers to corresponding watchers */
static nsClassHashtable<nsRefPtrHashKey<BluetoothSocketResultHandler>,
SocketMessageWatcherWrapper>
sWatcherHashtable;
/* |SocketMessageWatcher| receives Bluedroid's socket setup
* messages on the I/O thread. You need to inherit from this
* class to make use of it.
@ -135,11 +164,14 @@ public:
static const unsigned char OFF_CHANNEL2 = 12;
static const unsigned char OFF_STATUS = 16;
SocketMessageWatcher(int aFd)
SocketMessageWatcher(int aFd, BluetoothSocketResultHandler* aRes)
: mFd(aFd)
, mClientFd(-1)
, mLen(0)
{ }
, mRes(aRes)
{
MOZ_ASSERT(mRes);
}
virtual ~SocketMessageWatcher()
{ }
@ -164,7 +196,7 @@ public:
}
if (IsComplete() || status != STATUS_SUCCESS) {
mWatcher.StopWatchingFileDescriptor();
StopWatching();
Proceed(status);
}
}
@ -174,6 +206,9 @@ public:
void Watch()
{
// add this watcher and its result handler to hash table
sWatcherHashtable.Put(mRes, new SocketMessageWatcherWrapper(this));
MessageLoopForIO::current()->WatchFileDescriptor(
mFd,
true,
@ -182,6 +217,14 @@ public:
this);
}
void StopWatching()
{
mWatcher.StopWatchingFileDescriptor();
// remove this watcher and its result handler from hash table
sWatcherHashtable.Remove(mRes);
}
bool IsComplete() const
{
return mLen == (MSG1_SIZE + MSG2_SIZE);
@ -224,6 +267,11 @@ public:
return mClientFd;
}
BluetoothSocketResultHandler* GetResultHandler() const
{
return mRes;
}
private:
BluetoothStatus RecvMsg1()
{
@ -322,6 +370,7 @@ private:
int mClientFd;
unsigned char mLen;
uint8_t mBuf[MSG1_SIZE + MSG2_SIZE];
nsRefPtr<BluetoothSocketResultHandler> mRes;
};
/* |SocketMessageWatcherTask| starts a SocketMessageWatcher
@ -373,23 +422,18 @@ class ConnectWatcher MOZ_FINAL : public SocketMessageWatcher
{
public:
ConnectWatcher(int aFd, BluetoothSocketResultHandler* aRes)
: SocketMessageWatcher(aFd)
, mRes(aRes)
: SocketMessageWatcher(aFd, aRes)
{ }
void Proceed(BluetoothStatus aStatus) MOZ_OVERRIDE
{
if (mRes) {
DispatchBluetoothSocketHALResult(
mRes, &BluetoothSocketResultHandler::Connect, GetFd(),
GetBdAddress(), GetConnectionStatus(), aStatus);
}
DispatchBluetoothSocketHALResult(
GetResultHandler(), &BluetoothSocketResultHandler::Connect,
GetFd(), GetBdAddress(), GetConnectionStatus(), aStatus);
MessageLoopForIO::current()->PostTask(
FROM_HERE, new DeleteTask<ConnectWatcher>(this));
}
private:
nsRefPtr<BluetoothSocketResultHandler> mRes;
};
void
@ -436,26 +480,18 @@ class AcceptWatcher MOZ_FINAL : public SocketMessageWatcher
{
public:
AcceptWatcher(int aFd, BluetoothSocketResultHandler* aRes)
: SocketMessageWatcher(aFd)
, mRes(aRes)
{
/* not supplying a result handler leaks received file descriptor */
MOZ_ASSERT(mRes);
}
: SocketMessageWatcher(aFd, aRes)
{ }
void Proceed(BluetoothStatus aStatus) MOZ_OVERRIDE
{
if (mRes) {
DispatchBluetoothSocketHALResult(
mRes, &BluetoothSocketResultHandler::Accept, GetClientFd(),
GetBdAddress(), GetConnectionStatus(), aStatus);
}
DispatchBluetoothSocketHALResult(
GetResultHandler(), &BluetoothSocketResultHandler::Accept,
GetClientFd(), GetBdAddress(), GetConnectionStatus(), aStatus);
MessageLoopForIO::current()->PostTask(
FROM_HERE, new DeleteTask<AcceptWatcher>(this));
}
private:
nsRefPtr<BluetoothSocketResultHandler> mRes;
};
void
@ -467,6 +503,46 @@ BluetoothSocketHALInterface::Accept(int aFd,
XRE_GetIOMessageLoop()->PostTask(FROM_HERE, t);
}
/* |DeleteSocketMessageWatcherTask| deletes a watching SocketMessageWatcher
* on the I/O task
*/
class DeleteSocketMessageWatcherTask MOZ_FINAL : public Task
{
public:
DeleteSocketMessageWatcherTask(BluetoothSocketResultHandler* aRes)
: mRes(aRes)
{
MOZ_ASSERT(mRes);
}
void Run() MOZ_OVERRIDE
{
// look up hash table for the watcher corresponding to |mRes|
SocketMessageWatcherWrapper* wrapper = sWatcherHashtable.Get(mRes);
if (!wrapper) {
return;
}
// stop the watcher if it exists
SocketMessageWatcher* watcher = wrapper->GetSocketMessageWatcher();
watcher->StopWatching();
watcher->Proceed(STATUS_DONE);
}
private:
BluetoothSocketResultHandler* mRes;
};
void
BluetoothSocketHALInterface::Close(BluetoothSocketResultHandler* aRes)
{
MOZ_ASSERT(aRes);
/* stop the watcher corresponding to |aRes| */
Task* t = new DeleteSocketMessageWatcherTask(aRes);
XRE_GetIOMessageLoop()->PostTask(FROM_HERE, t);
}
BluetoothSocketHALInterface::BluetoothSocketHALInterface(
const btsock_interface_t* aInterface)
: mInterface(aInterface)

View File

@ -36,6 +36,8 @@ public:
void Accept(int aFd, BluetoothSocketResultHandler* aRes);
void Close(BluetoothSocketResultHandler* aRes);
protected:
BluetoothSocketHALInterface(const btsock_interface_t* aInterface);
~BluetoothSocketHALInterface();

View File

@ -1431,7 +1431,7 @@ WebGLContext::PresentScreenBuffer()
void
WebGLContext::DummyFramebufferOperation(const char *info)
{
GLenum status = CheckFramebufferStatus(LOCAL_GL_FRAMEBUFFER);
FBStatus status = CheckFramebufferStatus(LOCAL_GL_FRAMEBUFFER);
if (status != LOCAL_GL_FRAMEBUFFER_COMPLETE)
ErrorInvalidFramebufferOperation("%s: incomplete framebuffer", info);
}

View File

@ -355,6 +355,10 @@ public:
void FramebufferTexture2D(GLenum target, GLenum attachment,
GLenum textarget, WebGLTexture *tobj,
GLint level);
// Framebuffer validation
bool ValidateFramebufferAttachment(GLenum attachment, const char* funcName);
void FrontFace(GLenum mode);
void GenerateMipmap(GLenum target);
already_AddRefed<WebGLActiveInfo> GetActiveAttrib(WebGLProgram *prog,

View File

@ -64,7 +64,7 @@ WebGLContext::CurValidFBRectObject() const
if (mBoundFramebuffer) {
// We don't really need to ask the driver.
// Use 'precheck' to just check that our internal state looks good.
GLenum precheckStatus = mBoundFramebuffer->PrecheckFramebufferStatus();
FBStatus precheckStatus = mBoundFramebuffer->PrecheckFramebufferStatus();
if (precheckStatus == LOCAL_GL_FRAMEBUFFER_COMPLETE)
rect = &mBoundFramebuffer->RectangleObject();
} else {
@ -348,7 +348,7 @@ WebGLContext::CheckFramebufferStatus(GLenum target)
if (!mBoundFramebuffer)
return LOCAL_GL_FRAMEBUFFER_COMPLETE;
return mBoundFramebuffer->CheckFramebufferStatus();
return mBoundFramebuffer->CheckFramebufferStatus().get();
}
void
@ -795,7 +795,16 @@ WebGLContext::FramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum r
if (!mBoundFramebuffer)
return ErrorInvalidOperation("framebufferRenderbuffer: cannot modify framebuffer 0");
return mBoundFramebuffer->FramebufferRenderbuffer(target, attachment, rbtarget, wrb);
if (target != LOCAL_GL_FRAMEBUFFER)
return ErrorInvalidEnumInfo("framebufferRenderbuffer: target", target);
if (rbtarget != LOCAL_GL_RENDERBUFFER)
return ErrorInvalidEnumInfo("framebufferRenderbuffer: renderbuffer target:", rbtarget);
if (!ValidateFramebufferAttachment(attachment, "framebufferRenderbuffer"))
return;
return mBoundFramebuffer->FramebufferRenderbuffer(attachment, rbtarget, wrb);
}
void
@ -811,6 +820,9 @@ WebGLContext::FramebufferTexture2D(GLenum target,
if (!mBoundFramebuffer)
return ErrorInvalidOperation("framebufferRenderbuffer: cannot modify framebuffer 0");
if (target != LOCAL_GL_FRAMEBUFFER)
return ErrorInvalidEnumInfo("framebufferTexture2D: target", target);
if (textarget != LOCAL_GL_TEXTURE_2D &&
(textarget < LOCAL_GL_TEXTURE_CUBE_MAP_POSITIVE_X ||
textarget > LOCAL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Z))
@ -818,7 +830,10 @@ WebGLContext::FramebufferTexture2D(GLenum target,
return ErrorInvalidEnumInfo("framebufferTexture2D: invalid texture target", textarget);
}
return mBoundFramebuffer->FramebufferTexture2D(target, attachment, TexImageTarget(textarget), tobj, level);
if (!ValidateFramebufferAttachment(attachment, "framebufferTexture2D"))
return;
return mBoundFramebuffer->FramebufferTexture2D(attachment, textarget, tobj, level);
}
void
@ -1084,27 +1099,11 @@ WebGLContext::GetFramebufferAttachmentParameter(JSContext* cx,
return JS::NullValue();
}
if (attachment != LOCAL_GL_DEPTH_ATTACHMENT &&
attachment != LOCAL_GL_STENCIL_ATTACHMENT &&
attachment != LOCAL_GL_DEPTH_STENCIL_ATTACHMENT)
{
if (IsExtensionEnabled(WebGLExtensionID::WEBGL_draw_buffers))
{
if (attachment < LOCAL_GL_COLOR_ATTACHMENT0 ||
attachment >= GLenum(LOCAL_GL_COLOR_ATTACHMENT0 + mGLMaxColorAttachments))
{
ErrorInvalidEnumInfo("getFramebufferAttachmentParameter: attachment", attachment);
return JS::NullValue();
}
if (!ValidateFramebufferAttachment(attachment, "getFramebufferAttachmentParameter"))
return JS::NullValue();
mBoundFramebuffer->EnsureColorAttachments(attachment - LOCAL_GL_COLOR_ATTACHMENT0);
}
else if (attachment != LOCAL_GL_COLOR_ATTACHMENT0)
{
ErrorInvalidEnumInfo("getFramebufferAttachmentParameter: attachment", attachment);
return JS::NullValue();
}
}
if (IsExtensionEnabled(WebGLExtensionID::WEBGL_draw_buffers))
mBoundFramebuffer->EnsureColorAttachments(attachment - LOCAL_GL_COLOR_ATTACHMENT0);
MakeContextCurrent();

View File

@ -520,6 +520,34 @@ bool WebGLContext::ValidateGLSLString(const nsAString& string, const char *info)
return true;
}
/**
* Return true if the framebuffer attachment is valid. Attachment must
* be one of depth/stencil/depth_stencil/color attachment.
*/
bool
WebGLContext::ValidateFramebufferAttachment(GLenum attachment, const char* funcName)
{
if (attachment == LOCAL_GL_DEPTH_ATTACHMENT ||
attachment == LOCAL_GL_STENCIL_ATTACHMENT ||
attachment == LOCAL_GL_DEPTH_STENCIL_ATTACHMENT)
{
return true;
}
GLenum colorAttachCount = 1;
if (IsExtensionEnabled(WebGLExtensionID::WEBGL_draw_buffers))
colorAttachCount = mGLMaxColorAttachments;
if (attachment >= LOCAL_GL_COLOR_ATTACHMENT0 &&
attachment < GLenum(LOCAL_GL_COLOR_ATTACHMENT0 + colorAttachCount))
{
return true;
}
ErrorInvalidEnum("%s: attachment: invalid enum value 0x%x.", funcName, attachment);
return false;
}
/**
* Return true if format is a valid texture image format for source,
* taking into account enabled WebGL extensions.

View File

@ -24,7 +24,7 @@ WebGLFramebuffer::WrapObject(JSContext* cx)
}
WebGLFramebuffer::WebGLFramebuffer(WebGLContext* context)
: WebGLBindableName<GLenum>()
: WebGLBindableName<FBTarget>()
, WebGLContextBoundObject(context)
, mStatus(0)
, mDepthAttachment(LOCAL_GL_DEPTH_ATTACHMENT)
@ -40,7 +40,7 @@ WebGLFramebuffer::WebGLFramebuffer(WebGLContext* context)
mColorAttachments[0].mAttachmentPoint = LOCAL_GL_COLOR_ATTACHMENT0;
}
WebGLFramebuffer::Attachment::Attachment(GLenum aAttachmentPoint)
WebGLFramebuffer::Attachment::Attachment(FBAttachment aAttachmentPoint)
: mAttachmentPoint(aAttachmentPoint)
, mTexImageTarget(LOCAL_GL_NONE)
, mNeedsFinalize(false)
@ -341,8 +341,8 @@ WebGLFramebuffer::Attachment::IsComplete() const
}
if (mAttachmentPoint >= LOCAL_GL_COLOR_ATTACHMENT0 &&
mAttachmentPoint < GLenum(LOCAL_GL_COLOR_ATTACHMENT0 +
WebGLContext::kMaxColorAttachments))
mAttachmentPoint <= FBAttachment(LOCAL_GL_COLOR_ATTACHMENT0 - 1 +
WebGLContext::kMaxColorAttachments))
{
return IsValidFBOTextureColorFormat(webGLFormat);
}
@ -363,8 +363,8 @@ WebGLFramebuffer::Attachment::IsComplete() const
return IsValidFBORenderbufferDepthStencilFormat(internalFormat);
if (mAttachmentPoint >= LOCAL_GL_COLOR_ATTACHMENT0 &&
mAttachmentPoint < GLenum(LOCAL_GL_COLOR_ATTACHMENT0 +
WebGLContext::kMaxColorAttachments))
mAttachmentPoint <= FBAttachment(LOCAL_GL_COLOR_ATTACHMENT0 - 1 +
WebGLContext::kMaxColorAttachments))
{
return IsValidFBORenderbufferColorFormat(internalFormat);
}
@ -377,7 +377,7 @@ WebGLFramebuffer::Attachment::IsComplete() const
}
void
WebGLFramebuffer::Attachment::FinalizeAttachment(GLContext* gl, GLenum attachmentLoc) const
WebGLFramebuffer::Attachment::FinalizeAttachment(GLContext* gl, FBAttachment attachmentLoc) const
{
if (!mNeedsFinalize)
return;
@ -391,7 +391,7 @@ WebGLFramebuffer::Attachment::FinalizeAttachment(GLContext* gl, GLenum attachmen
gl->fFramebufferRenderbuffer(LOCAL_GL_FRAMEBUFFER, LOCAL_GL_STENCIL_ATTACHMENT,
LOCAL_GL_RENDERBUFFER, 0);
} else {
gl->fFramebufferRenderbuffer(LOCAL_GL_FRAMEBUFFER, attachmentLoc,
gl->fFramebufferRenderbuffer(LOCAL_GL_FRAMEBUFFER, attachmentLoc.get(),
LOCAL_GL_RENDERBUFFER, 0);
}
@ -412,7 +412,7 @@ WebGLFramebuffer::Attachment::FinalizeAttachment(GLContext* gl, GLenum attachmen
gl->fFramebufferTexture2D(LOCAL_GL_FRAMEBUFFER, LOCAL_GL_STENCIL_ATTACHMENT,
imageTarget, glName, mipLevel);
} else {
gl->fFramebufferTexture2D(LOCAL_GL_FRAMEBUFFER, attachmentLoc,
gl->fFramebufferTexture2D(LOCAL_GL_FRAMEBUFFER, attachmentLoc.get(),
imageTarget, glName, mipLevel);
}
return;
@ -464,9 +464,8 @@ WebGLFramebuffer::DetachAllAttachments()
}
void
WebGLFramebuffer::FramebufferRenderbuffer(GLenum target,
GLenum attachment,
GLenum rbtarget,
WebGLFramebuffer::FramebufferRenderbuffer(FBAttachment attachment,
RBTarget rbtarget,
WebGLRenderbuffer* wrb)
{
MOZ_ASSERT(mContext->mBoundFramebuffer == this);
@ -474,12 +473,6 @@ WebGLFramebuffer::FramebufferRenderbuffer(GLenum target,
if (!mContext->ValidateObjectAllowNull("framebufferRenderbuffer: renderbuffer", wrb))
return;
if (target != LOCAL_GL_FRAMEBUFFER)
return mContext->ErrorInvalidEnumInfo("framebufferRenderbuffer: target", target);
if (rbtarget != LOCAL_GL_RENDERBUFFER)
return mContext->ErrorInvalidEnumInfo("framebufferRenderbuffer: renderbuffer target:", rbtarget);
/* Get the requested attachment. If result is NULL, attachment is
* invalid and an error is generated.
*
@ -509,8 +502,7 @@ WebGLFramebuffer::FramebufferRenderbuffer(GLenum target,
}
void
WebGLFramebuffer::FramebufferTexture2D(GLenum target,
GLenum attachment,
WebGLFramebuffer::FramebufferTexture2D(FBAttachment attachment,
TexImageTarget texImageTarget,
WebGLTexture* wtex,
GLint level)
@ -520,9 +512,6 @@ WebGLFramebuffer::FramebufferTexture2D(GLenum target,
if (!mContext->ValidateObjectAllowNull("framebufferTexture2D: texture", wtex))
return;
if (target != LOCAL_GL_FRAMEBUFFER)
return mContext->ErrorInvalidEnumInfo("framebufferTexture2D: target", target);
if (wtex) {
bool isTexture2D = wtex->Target() == LOCAL_GL_TEXTURE_2D;
bool isTexTarget2D = texImageTarget == LOCAL_GL_TEXTURE_2D;
@ -563,7 +552,7 @@ WebGLFramebuffer::FramebufferTexture2D(GLenum target,
}
WebGLFramebuffer::Attachment*
WebGLFramebuffer::GetAttachmentOrNull(GLenum attachment)
WebGLFramebuffer::GetAttachmentOrNull(FBAttachment attachment)
{
if (attachment == LOCAL_GL_DEPTH_STENCIL_ATTACHMENT)
return &mDepthStencilAttachment;
@ -574,17 +563,17 @@ WebGLFramebuffer::GetAttachmentOrNull(GLenum attachment)
if (attachment == LOCAL_GL_STENCIL_ATTACHMENT)
return &mStencilAttachment;
if (!CheckColorAttachmentNumber(attachment, "getAttachmentOrNull"))
if (!mContext->ValidateFramebufferAttachment(attachment.get(), "getAttachmentOrNull"))
return nullptr;
size_t colorAttachmentId = attachment - LOCAL_GL_COLOR_ATTACHMENT0;
size_t colorAttachmentId = attachment.get() - LOCAL_GL_COLOR_ATTACHMENT0;
EnsureColorAttachments(colorAttachmentId);
return &mColorAttachments[colorAttachmentId];
}
const WebGLFramebuffer::Attachment&
WebGLFramebuffer::GetAttachment(GLenum attachment) const
WebGLFramebuffer::GetAttachment(FBAttachment attachment) const
{
if (attachment == LOCAL_GL_DEPTH_STENCIL_ATTACHMENT)
return mDepthStencilAttachment;
@ -593,12 +582,12 @@ WebGLFramebuffer::GetAttachment(GLenum attachment) const
if (attachment == LOCAL_GL_STENCIL_ATTACHMENT)
return mStencilAttachment;
if (!CheckColorAttachmentNumber(attachment, "getAttachment")) {
if (!mContext->ValidateFramebufferAttachment(attachment.get(), "getAttachment")) {
MOZ_ASSERT(false);
return mColorAttachments[0];
}
size_t colorAttachmentId = attachment - LOCAL_GL_COLOR_ATTACHMENT0;
size_t colorAttachmentId = attachment.get() - LOCAL_GL_COLOR_ATTACHMENT0;
if (colorAttachmentId >= mColorAttachments.Length()) {
MOZ_ASSERT(false);
return mColorAttachments[0];
@ -613,17 +602,17 @@ WebGLFramebuffer::DetachTexture(const WebGLTexture* tex)
size_t count = mColorAttachments.Length();
for (size_t i = 0; i < count; i++) {
if (mColorAttachments[i].Texture() == tex) {
FramebufferTexture2D(LOCAL_GL_FRAMEBUFFER, LOCAL_GL_COLOR_ATTACHMENT0+i, LOCAL_GL_TEXTURE_2D, nullptr, 0);
FramebufferTexture2D(LOCAL_GL_COLOR_ATTACHMENT0+i, LOCAL_GL_TEXTURE_2D, nullptr, 0);
// a texture might be attached more that once while editing the framebuffer
}
}
if (mDepthAttachment.Texture() == tex)
FramebufferTexture2D(LOCAL_GL_FRAMEBUFFER, LOCAL_GL_DEPTH_ATTACHMENT, LOCAL_GL_TEXTURE_2D, nullptr, 0);
FramebufferTexture2D(LOCAL_GL_DEPTH_ATTACHMENT, LOCAL_GL_TEXTURE_2D, nullptr, 0);
if (mStencilAttachment.Texture() == tex)
FramebufferTexture2D(LOCAL_GL_FRAMEBUFFER, LOCAL_GL_STENCIL_ATTACHMENT, LOCAL_GL_TEXTURE_2D, nullptr, 0);
FramebufferTexture2D(LOCAL_GL_STENCIL_ATTACHMENT, LOCAL_GL_TEXTURE_2D, nullptr, 0);
if (mDepthStencilAttachment.Texture() == tex)
FramebufferTexture2D(LOCAL_GL_FRAMEBUFFER, LOCAL_GL_DEPTH_STENCIL_ATTACHMENT, LOCAL_GL_TEXTURE_2D, nullptr, 0);
FramebufferTexture2D(LOCAL_GL_DEPTH_STENCIL_ATTACHMENT, LOCAL_GL_TEXTURE_2D, nullptr, 0);
}
void
@ -632,17 +621,17 @@ WebGLFramebuffer::DetachRenderbuffer(const WebGLRenderbuffer* rb)
size_t count = mColorAttachments.Length();
for (size_t i = 0; i < count; i++) {
if (mColorAttachments[i].Renderbuffer() == rb) {
FramebufferRenderbuffer(LOCAL_GL_FRAMEBUFFER, LOCAL_GL_COLOR_ATTACHMENT0+i, LOCAL_GL_RENDERBUFFER, nullptr);
FramebufferRenderbuffer(LOCAL_GL_COLOR_ATTACHMENT0+i, LOCAL_GL_RENDERBUFFER, nullptr);
// a renderbuffer might be attached more that once while editing the framebuffer
}
}
if (mDepthAttachment.Renderbuffer() == rb)
FramebufferRenderbuffer(LOCAL_GL_FRAMEBUFFER, LOCAL_GL_DEPTH_ATTACHMENT, LOCAL_GL_RENDERBUFFER, nullptr);
FramebufferRenderbuffer(LOCAL_GL_DEPTH_ATTACHMENT, LOCAL_GL_RENDERBUFFER, nullptr);
if (mStencilAttachment.Renderbuffer() == rb)
FramebufferRenderbuffer(LOCAL_GL_FRAMEBUFFER, LOCAL_GL_STENCIL_ATTACHMENT, LOCAL_GL_RENDERBUFFER, nullptr);
FramebufferRenderbuffer(LOCAL_GL_STENCIL_ATTACHMENT, LOCAL_GL_RENDERBUFFER, nullptr);
if (mDepthStencilAttachment.Renderbuffer() == rb)
FramebufferRenderbuffer(LOCAL_GL_FRAMEBUFFER, LOCAL_GL_DEPTH_STENCIL_ATTACHMENT, LOCAL_GL_RENDERBUFFER, nullptr);
FramebufferRenderbuffer(LOCAL_GL_DEPTH_STENCIL_ATTACHMENT, LOCAL_GL_RENDERBUFFER, nullptr);
}
bool
@ -757,7 +746,7 @@ WebGLFramebuffer::RectangleObject() const
return GetAnyRectObject();
}
GLenum
FBStatus
WebGLFramebuffer::PrecheckFramebufferStatus() const
{
MOZ_ASSERT(mContext->mBoundFramebuffer == this);
@ -777,13 +766,13 @@ WebGLFramebuffer::PrecheckFramebufferStatus() const
return LOCAL_GL_FRAMEBUFFER_COMPLETE;
}
GLenum
FBStatus
WebGLFramebuffer::CheckFramebufferStatus() const
{
if (mStatus != 0)
return mStatus;
mStatus = PrecheckFramebufferStatus();
mStatus = PrecheckFramebufferStatus().get();
if (mStatus != LOCAL_GL_FRAMEBUFFER_COMPLETE)
return mStatus;
@ -897,33 +886,6 @@ WebGLFramebuffer::CheckAndInitializeAttachments()
return true;
}
bool WebGLFramebuffer::CheckColorAttachmentNumber(GLenum attachment, const char* functionName) const
{
const char* const errorFormating = "%s: attachment: invalid enum value 0x%x";
if (mContext->IsExtensionEnabled(WebGLExtensionID::WEBGL_draw_buffers)) {
if (attachment < LOCAL_GL_COLOR_ATTACHMENT0 ||
attachment >= GLenum(LOCAL_GL_COLOR_ATTACHMENT0 + mContext->mGLMaxColorAttachments))
{
mContext->ErrorInvalidEnum(errorFormating, functionName, attachment);
return false;
}
} else if (attachment != LOCAL_GL_COLOR_ATTACHMENT0) {
if (attachment > LOCAL_GL_COLOR_ATTACHMENT0 &&
attachment <= LOCAL_GL_COLOR_ATTACHMENT15)
{
mContext->ErrorInvalidEnum("%s: attachment: invalid enum value 0x%x. "
"Try the WEBGL_draw_buffers extension if supported.", functionName, attachment);
return false;
} else {
mContext->ErrorInvalidEnum(errorFormating, functionName, attachment);
return false;
}
}
return true;
}
void WebGLFramebuffer::EnsureColorAttachments(size_t colorAttachmentId)
{
MOZ_ASSERT(colorAttachmentId < WebGLContext::kMaxColorAttachments);

View File

@ -25,7 +25,7 @@ namespace gl {
class WebGLFramebuffer MOZ_FINAL
: public nsWrapperCache
, public WebGLBindableName<GLenum>
, public WebGLBindableName<FBTarget>
, public WebGLRefCountedObject<WebGLFramebuffer>
, public LinkedListElement<WebGLFramebuffer>
, public WebGLContextBoundObject
@ -41,12 +41,12 @@ public:
// deleting a texture or renderbuffer immediately detaches it
WebGLRefPtr<WebGLTexture> mTexturePtr;
WebGLRefPtr<WebGLRenderbuffer> mRenderbufferPtr;
GLenum mAttachmentPoint;
FBAttachment mAttachmentPoint;
TexImageTarget mTexImageTarget;
GLint mTexImageLevel;
mutable bool mNeedsFinalize;
explicit Attachment(GLenum aAttachmentPoint = LOCAL_GL_COLOR_ATTACHMENT0);
explicit Attachment(FBAttachment aAttachmentPoint = LOCAL_GL_COLOR_ATTACHMENT0);
~Attachment();
bool IsDefined() const;
@ -88,18 +88,16 @@ public:
bool HasImage() const;
bool IsComplete() const;
void FinalizeAttachment(gl::GLContext* gl, GLenum attachmentLoc) const;
void FinalizeAttachment(gl::GLContext* gl, FBAttachment attachmentLoc) const;
};
void Delete();
void FramebufferRenderbuffer(GLenum target,
GLenum attachment,
GLenum rbtarget,
void FramebufferRenderbuffer(FBAttachment attachment,
RBTarget rbtarget,
WebGLRenderbuffer* wrb);
void FramebufferTexture2D(GLenum target,
GLenum attachment,
void FramebufferTexture2D(FBAttachment attachment,
TexImageTarget texImageTarget,
WebGLTexture* wtex,
GLint level);
@ -108,14 +106,14 @@ private:
void DetachAttachment(WebGLFramebuffer::Attachment& attachment);
void DetachAllAttachments();
const WebGLRectangleObject& GetAnyRectObject() const;
Attachment* GetAttachmentOrNull(GLenum attachment);
Attachment* GetAttachmentOrNull(FBAttachment attachment);
public:
bool HasDefinedAttachments() const;
bool HasIncompleteAttachments() const;
bool AllImageRectsMatch() const;
GLenum PrecheckFramebufferStatus() const;
GLenum CheckFramebufferStatus() const;
FBStatus PrecheckFramebufferStatus() const;
FBStatus CheckFramebufferStatus() const;
GLenum GetFormatForAttachment(const WebGLFramebuffer::Attachment& attachment) const;
bool HasDepthStencilConflict() const {
@ -143,7 +141,7 @@ public:
return mDepthStencilAttachment;
}
const Attachment& GetAttachment(GLenum attachment) const;
const Attachment& GetAttachment(FBAttachment attachment) const;
void DetachTexture(const WebGLTexture* tex);
@ -167,11 +165,10 @@ public:
bool CheckAndInitializeAttachments();
bool CheckColorAttachmentNumber(GLenum attachment, const char* functionName) const;
bool CheckColorAttachmentNumber(FBAttachment attachment, const char* functionName) const;
void EnsureColorAttachments(size_t colorAttachmentId);
Attachment* AttachmentFor(GLenum attachment);
void NotifyAttachableChanged() const;
private:

View File

@ -12,7 +12,7 @@
using namespace mozilla;
void
WebGLFramebufferAttachable::AttachTo(WebGLFramebuffer* fb, GLenum attachment)
WebGLFramebufferAttachable::AttachTo(WebGLFramebuffer* fb, FBAttachment attachment)
{
MOZ_ASSERT(fb);
if (!fb)
@ -25,7 +25,7 @@ WebGLFramebufferAttachable::AttachTo(WebGLFramebuffer* fb, GLenum attachment)
}
void
WebGLFramebufferAttachable::DetachFrom(WebGLFramebuffer* fb, GLenum attachment)
WebGLFramebufferAttachable::DetachFrom(WebGLFramebuffer* fb, FBAttachment attachment)
{
MOZ_ASSERT(fb);
if (!fb)

View File

@ -10,6 +10,7 @@
#include "nsTArray.h"
#include "mozilla/WeakPtr.h"
#include "WebGLFramebuffer.h"
#include "WebGLStrongTypes.h"
namespace mozilla {
@ -17,13 +18,13 @@ class WebGLFramebufferAttachable
{
struct AttachmentPoint
{
AttachmentPoint(const WebGLFramebuffer* fb, GLenum attachment)
AttachmentPoint(const WebGLFramebuffer* fb, FBAttachment attachment)
: mFB(fb)
, mAttachment(attachment)
{}
WeakPtr<const WebGLFramebuffer> mFB;
GLenum mAttachment;
FBAttachment mAttachment;
bool operator==(const AttachmentPoint& o) const {
return mFB == o.mFB && mAttachment == o.mAttachment;
@ -35,8 +36,8 @@ class WebGLFramebufferAttachable
public:
// Track FBO/Attachment combinations
void AttachTo(WebGLFramebuffer* fb, GLenum attachment);
void DetachFrom(WebGLFramebuffer* fb, GLenum attachment);
void AttachTo(WebGLFramebuffer* fb, FBAttachment attachment);
void DetachFrom(WebGLFramebuffer* fb, FBAttachment attachment);
void NotifyFBsStatusChanged();
};

View File

@ -43,7 +43,7 @@ WebGLRenderbuffer::WrapObject(JSContext *cx) {
}
WebGLRenderbuffer::WebGLRenderbuffer(WebGLContext *context)
: WebGLBindableName<GLenum>()
: WebGLBindableName<RBTarget>()
, WebGLContextBoundObject(context)
, mPrimaryRB(0)
, mSecondaryRB(0)
@ -182,10 +182,10 @@ WebGLRenderbuffer::RenderbufferStorage(GLenum internalFormat, GLsizei width, GLs
}
void
WebGLRenderbuffer::FramebufferRenderbuffer(GLenum attachment) const {
WebGLRenderbuffer::FramebufferRenderbuffer(FBAttachment attachment) const {
GLContext* gl = mContext->gl;
if (attachment != LOCAL_GL_DEPTH_STENCIL_ATTACHMENT) {
gl->fFramebufferRenderbuffer(LOCAL_GL_FRAMEBUFFER, attachment, LOCAL_GL_RENDERBUFFER, mPrimaryRB);
gl->fFramebufferRenderbuffer(LOCAL_GL_FRAMEBUFFER, attachment.get(), LOCAL_GL_RENDERBUFFER, mPrimaryRB);
return;
}
@ -200,10 +200,10 @@ WebGLRenderbuffer::FramebufferRenderbuffer(GLenum attachment) const {
}
GLint
WebGLRenderbuffer::GetRenderbufferParameter(GLenum target, GLenum pname) const {
WebGLRenderbuffer::GetRenderbufferParameter(RBTarget target, RBParam pname) const {
GLContext* gl = mContext->gl;
switch (pname) {
switch (pname.get()) {
case LOCAL_GL_RENDERBUFFER_STENCIL_SIZE: {
if (NeedsDepthStencilEmu(mContext->gl, InternalFormatForGL())) {
if (gl->WorkAroundDriverBugs() &&
@ -215,7 +215,7 @@ WebGLRenderbuffer::GetRenderbufferParameter(GLenum target, GLenum pname) const {
ScopedBindRenderbuffer autoRB(gl, mSecondaryRB);
GLint i = 0;
gl->fGetRenderbufferParameteriv(target, pname, &i);
gl->fGetRenderbufferParameteriv(target.get(), pname.get(), &i);
return i;
}
// Fall through otherwise.
@ -228,7 +228,7 @@ WebGLRenderbuffer::GetRenderbufferParameter(GLenum target, GLenum pname) const {
case LOCAL_GL_RENDERBUFFER_ALPHA_SIZE:
case LOCAL_GL_RENDERBUFFER_DEPTH_SIZE: {
GLint i = 0;
gl->fGetRenderbufferParameteriv(target, pname, &i);
gl->fGetRenderbufferParameteriv(target.get(), pname.get(), &i);
return i;
}
}

View File

@ -18,7 +18,7 @@ namespace mozilla {
class WebGLRenderbuffer MOZ_FINAL
: public nsWrapperCache
, public WebGLBindableName<GLenum>
, public WebGLBindableName<RBTarget>
, public WebGLRefCountedObject<WebGLRenderbuffer>
, public LinkedListElement<WebGLRenderbuffer>
, public WebGLRectangleObject
@ -52,9 +52,9 @@ public:
void BindRenderbuffer() const;
void RenderbufferStorage(GLenum internalFormat, GLsizei width, GLsizei height) const;
void FramebufferRenderbuffer(GLenum attachment) const;
void FramebufferRenderbuffer(FBAttachment attachment) const;
// Only handles a subset of `pname`s.
GLint GetRenderbufferParameter(GLenum target, GLenum pname) const;
GLint GetRenderbufferParameter(RBTarget target, RBParam pname) const;
virtual JSObject* WrapObject(JSContext *cx) MOZ_OVERRIDE;

View File

@ -153,6 +153,14 @@ public:
return get() != other.get();
}
bool operator<=(const StrongGLenum& other) const {
return get() <= other.get();
}
bool operator>=(const StrongGLenum& other) const {
return get() >= other.get();
}
static bool IsValueLegal(GLenum value) {
if (value > UINT16_MAX) {
return false;
@ -342,4 +350,59 @@ STRONG_GLENUM_BEGIN(TexInternalFormat)
STRONG_GLENUM_VALUE(RGB10_A2UI),
STRONG_GLENUM_END(TexInternalFormat)
STRONG_GLENUM_BEGIN(FBTarget)
STRONG_GLENUM_VALUE(NONE),
STRONG_GLENUM_VALUE(READ_FRAMEBUFFER),
STRONG_GLENUM_VALUE(DRAW_FRAMEBUFFER),
STRONG_GLENUM_VALUE(FRAMEBUFFER),
STRONG_GLENUM_END(FBTarget)
STRONG_GLENUM_BEGIN(RBTarget)
STRONG_GLENUM_VALUE(NONE),
STRONG_GLENUM_VALUE(RENDERBUFFER),
STRONG_GLENUM_END(RBTarget)
STRONG_GLENUM_BEGIN(FBAttachment)
STRONG_GLENUM_VALUE(DEPTH_STENCIL_ATTACHMENT),
STRONG_GLENUM_VALUE(COLOR_ATTACHMENT0),
STRONG_GLENUM_VALUE(COLOR_ATTACHMENT1),
STRONG_GLENUM_VALUE(COLOR_ATTACHMENT2),
STRONG_GLENUM_VALUE(COLOR_ATTACHMENT3),
STRONG_GLENUM_VALUE(COLOR_ATTACHMENT4),
STRONG_GLENUM_VALUE(COLOR_ATTACHMENT5),
STRONG_GLENUM_VALUE(COLOR_ATTACHMENT6),
STRONG_GLENUM_VALUE(COLOR_ATTACHMENT7),
STRONG_GLENUM_VALUE(COLOR_ATTACHMENT8),
STRONG_GLENUM_VALUE(COLOR_ATTACHMENT9),
STRONG_GLENUM_VALUE(COLOR_ATTACHMENT10),
STRONG_GLENUM_VALUE(COLOR_ATTACHMENT11),
STRONG_GLENUM_VALUE(COLOR_ATTACHMENT12),
STRONG_GLENUM_VALUE(COLOR_ATTACHMENT13),
STRONG_GLENUM_VALUE(COLOR_ATTACHMENT14),
STRONG_GLENUM_VALUE(COLOR_ATTACHMENT15),
STRONG_GLENUM_VALUE(DEPTH_ATTACHMENT),
STRONG_GLENUM_VALUE(STENCIL_ATTACHMENT),
STRONG_GLENUM_END(FBAttachment)
STRONG_GLENUM_BEGIN(FBStatus)
STRONG_GLENUM_VALUE(FRAMEBUFFER_COMPLETE),
STRONG_GLENUM_VALUE(FRAMEBUFFER_INCOMPLETE_ATTACHMENT),
STRONG_GLENUM_VALUE(FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT),
STRONG_GLENUM_VALUE(FRAMEBUFFER_INCOMPLETE_DIMENSIONS),
STRONG_GLENUM_VALUE(FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER),
STRONG_GLENUM_VALUE(FRAMEBUFFER_INCOMPLETE_READ_BUFFER),
STRONG_GLENUM_VALUE(FRAMEBUFFER_UNSUPPORTED),
STRONG_GLENUM_END(FBStatus)
STRONG_GLENUM_BEGIN(RBParam)
STRONG_GLENUM_VALUE(RENDERBUFFER_WIDTH),
STRONG_GLENUM_VALUE(RENDERBUFFER_HEIGHT),
STRONG_GLENUM_VALUE(RENDERBUFFER_RED_SIZE),
STRONG_GLENUM_VALUE(RENDERBUFFER_GREEN_SIZE),
STRONG_GLENUM_VALUE(RENDERBUFFER_BLUE_SIZE),
STRONG_GLENUM_VALUE(RENDERBUFFER_ALPHA_SIZE),
STRONG_GLENUM_VALUE(RENDERBUFFER_DEPTH_SIZE),
STRONG_GLENUM_VALUE(RENDERBUFFER_STENCIL_SIZE),
STRONG_GLENUM_END(RBParam)
#endif

View File

@ -17,7 +17,7 @@ EXPORTS.mozilla.dom += [
'DataStoreService.h',
]
SOURCES += [
UNIFIED_SOURCES += [
'DataStore.cpp',
'DataStoreCursor.cpp',
'DataStoreDB.cpp',

View File

@ -0,0 +1,6 @@
component {27e55b94-fc43-42b3-b0f0-28bebdd804f1} EngineeringModeAPI.js
contract @mozilla.org/dom/engineering-mode-api;1 {27e55b94-fc43-42b3-b0f0-28bebdd804f1}
component {1345a96a-7b8d-4017-a776-07d918f14d84} EngineeringModeService.js
contract @mozilla.org/engineering-mode-service;1 {1345a96a-7b8d-4017-a776-07d918f14d84}
category profile-after-change EngineeringModeService @mozilla.org/engineering-mode-service;1

View File

@ -0,0 +1,135 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* 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/. */
"use strict";
const DEBUG = false;
function debug(s) {
if (DEBUG) dump("-*- EngineeringModeAPI: " + s + "\n");
}
const Cc = Components.classes;
const Ci = Components.interfaces;
const Cu = Components.utils;
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/DOMRequestHelper.jsm");
XPCOMUtils.defineLazyServiceGetter(this, "cpmm",
"@mozilla.org/childprocessmessagemanager;1",
"nsIMessageSender");
function EngineeringModeAPI() {
}
EngineeringModeAPI.prototype = {
__proto__: DOMRequestIpcHelper.prototype,
classDescription: "Engineering Mode API",
classID: Components.ID("{27e55b94-fc43-42b3-b0f0-28bebdd804f1}"),
contractID: "@mozilla.org/dom/engineering-mode-api;1",
// For DOMRequestHelper: must have nsISupportsWeakReference and nsIObserver.
QueryInterface: XPCOMUtils.generateQI([Ci.nsIDOMGlobalPropertyInitializer,
Ci.nsISupportsWeakReference,
Ci.nsIObserver]),
init: function(aWindow) {
this.initDOMRequestHelper(aWindow, ["EngineeringMode:OnMessage",
"EngineeringMode:SetValue:Result:OK",
"EngineeringMode:SetValue:Result:KO",
"EngineeringMode:GetValue:Result:OK",
"EngineeringMode:GetValue:Result:KO"]);
cpmm.sendAsyncMessage("EngineeringMode:Register", null);
},
uninit: function() {
cpmm.sendAsyncMessage("EngineeringMode:Unregister", null);
},
// This returns a Promise<DOMString>
getValue: function getValue(aName) {
debug("getValue " + aName);
let promiseInit = function(resolve, reject) {
debug("promise init called for getValue " + aName);
let resolverId = this.getPromiseResolverId({resolve: resolve,
reject: reject });
debug("promise init " + resolverId);
cpmm.sendAsyncMessage("EngineeringMode:GetValue", {
requestId: resolverId,
name: aName
});
}.bind(this);
return this.createPromise(promiseInit);
},
// This returns a Promise<void>
setValue: function setValue(aName, aValue) {
debug("setValue " + aName + ' as ' + aValue );
let promiseInit = function(resolve, reject) {
debug("promise init called for setValue " + aName);
let resolverId = this.getPromiseResolverId({resolve: resolve,
reject: reject });
debug("promise init " + resolverId);
cpmm.sendAsyncMessage("EngineeringMode:SetValue", {
requestId: resolverId,
name: aName,
value: aValue
});
}.bind(this);
return this.createPromise(promiseInit);
},
set onmessage(aHandler) {
this.__DOM_IMPL__.setEventHandler("onmessage", aHandler);
},
get onmessage() {
return this.__DOM_IMPL__.getEventHandler("onmessage");
},
receiveMessage: function(aMessage) {
debug("receiveMessage: name: " + aMessage.name);
let resolver = null;
let data = aMessage.data;
switch (aMessage.name) {
case "EngineeringMode:OnMessage":
let detail = Cu.cloneInto(data, this._window);
let event = new this._window.CustomEvent("message", {"detail": detail});
this.__DOM_IMPL__.dispatchEvent(event);
break;
case "EngineeringMode:GetValue:Result:OK":
case "EngineeringMode:GetValue:Result:KO":
resolver = this.takePromiseResolver(data.requestId);
if (!resolver) {
return;
}
if (aMessage.name === "EngineeringMode:GetValue:Result:OK") {
resolver.resolve(data.value);
} else {
resolver.reject(data.reason);
}
break;
case "EngineeringMode:SetValue:Result:OK":
case "EngineeringMode:SetValue:Result:KO":
resolver = this.takePromiseResolver(data.requestId);
if (!resolver) {
return;
}
if (aMessage.name === "EngineeringMode:SetValue:Result:OK") {
resolver.resolve();
} else {
resolver.reject(data.reason);
}
break;
}
}
}
this.NSGetFactory = XPCOMUtils.generateNSGetFactory([EngineeringModeAPI]);

View File

@ -0,0 +1,163 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* 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/. */
"use strict";
const DEBUG = false;
function debug(s) {
if (DEBUG) dump("-*- EngineeringModeService: " + s + "\n");
}
const Cc = Components.classes;
const Ci = Components.interfaces;
const Cu = Components.utils;
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm");
XPCOMUtils.defineLazyServiceGetter(this, "ppmm",
"@mozilla.org/parentprocessmessagemanager;1",
"nsIMessageBroadcaster");
XPCOMUtils.defineLazyServiceGetter(this, "EngineeringMode",
"@mozilla.org/b2g/engineering-mode-impl;1",
"nsIEngineeringMode");
function EngineeringModeService() {
}
EngineeringModeService.prototype = {
classID: Components.ID("{1345a96a-7b8d-4017-a776-07d918f14d84}"),
QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver,
Ci.nsIEngineeringModeMessageHandler]),
observe: function(aSubject, aTopic, aData) {
debug("-- init");
switch(aTopic) {
case "profile-after-change":
Services.obs.addObserver(this, "xpcom-shutdown", false);
ppmm.addMessageListener("EngineeringMode:Register", this);
ppmm.addMessageListener("EngineeringMode:Unregister", this);
ppmm.addMessageListener("EngineeringMode:SetValue", this);
ppmm.addMessageListener("EngineeringMode:GetValue", this);
this._clients = [];
break;
case "xpcom-shutdown":
Services.obs.removeObserver(this, "xpcom-shutdown");
ppmm.removeMessageListener("EngineeringMode:Register", this);
ppmm.removeMessageListener("EngineeringMode:Unregister", this);
ppmm.removeMessageListener("EngineeringMode:SetValue", this);
ppmm.removeMessageListener("EngineeringMode:GetValue", this);
if (this._hasEngineeringModeImpl()) {
EngineeringMode.setMessageHandler(function(){});
}
this._clients = null;
break;
}
},
receiveMessage: function(aMessage) {
debug("receiveMessage: name: " + aMessage.name);
if (!aMessage.target.assertPermission("engineering-mode")) {
debug(aMessage.name + " from a content process with no 'engineering-mode' privileges.");
return;
}
switch (aMessage.name) {
case "EngineeringMode:Register":
// Lazy bind message handler until we have first client.
if (this._hasEngineeringModeImpl() && this._clients.length === 0) {
EngineeringMode.setMessageHandler(this.onMessage.bind(this));
}
this._clients.push(aMessage.target);
break;
case "EngineeringMode:Unregister":
let index = this._clients.indexOf(aMessage.target);
if (index > -1) {
this._clients.splice(index, 1);
}
break;
case "EngineeringMode:SetValue":
this.setValue(aMessage.target, aMessage.data);
break;
case "EngineeringMode:GetValue":
this.getValue(aMessage.target, aMessage.data);
break;
}
},
setValue: function(aTarget, aData) {
if (!this._hasEngineeringModeImpl()) {
aTarget.sendAsyncMessage("EngineeringMode:SetValue:Result:KO", {
requestId: aData.requestId,
reason: "No engineering mode implementation"
});
return;
}
EngineeringMode.setValue(aData.name, aData.value, {
onsuccess: function() {
aTarget.sendAsyncMessage("EngineeringMode:SetValue:Result:OK", {
requestId: aData.requestId
});
},
onerror: function(aError) {
aTarget.sendAsyncMessage("EngineeringMode:SetValue:Result:KO", {
requestId: aData.requestId,
reason: "Error: code " + aError
});
}
});
},
getValue: function(aTarget, aData) {
if (!this._hasEngineeringModeImpl()) {
aTarget.sendAsyncMessage("EngineeringMode:GetValue:Result:KO", {
requestId: aData.requestId,
reason: "No engineering mode implementation"
});
return;
}
EngineeringMode.getValue(aData.name, {
onsuccess: function(aValue) {
aTarget.sendAsyncMessage("EngineeringMode:GetValue:Result:OK", {
requestId: aData.requestId,
value: aValue
});
},
onerror: function(aError) {
aTarget.sendAsyncMessage("EngineeringMode:GetValue:Result:KO", {
requestId: aData.requestId,
reason: "Error: code " + aError
});
}
});
},
onMessage: function(aMessage) {
this._clients.forEach(function(aClient) {
aClient.sendAsyncMessage("EngineeringMode:OnMessage", {
data: aMessage
});
});
},
_hasEngineeringModeImpl: function() {
if (typeof Cc["@mozilla.org/b2g/engineering-mode-impl;1"] === "undefined") {
debug("Can not get engineering mode implementation.");
return false;
}
return true;
}
}
this.NSGetFactory = XPCOMUtils.generateNSGetFactory([EngineeringModeService]);

View File

@ -0,0 +1,19 @@
# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
# vim: set filetype=python:
# This Source Code Form is subject to the terms of the Mozilla Public
# 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/.
if CONFIG['MOZ_B2G']:
EXTRA_COMPONENTS += [
'EngineeringMode.manifest',
'EngineeringModeAPI.js',
'EngineeringModeService.js',
]
XPIDL_SOURCES += [
'nsIEngineeringMode.idl',
]
XPIDL_MODULE = 'dom_engineeringmode'

View File

@ -0,0 +1,29 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* 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 "nsISupports.idl"
[scriptable, function, uuid(82e7c515-d174-4e84-9091-e7e89617a6d9)]
interface nsIEngineeringModeMessageHandler : nsISupports
{
void handleMessage(in DOMString message);
};
[scriptable, uuid(fdae21b9-bd8c-4d01-bc6a-6c3a7b5efb27)]
interface nsIEngineeringModeCallback : nsISupports
{
void onsuccess([optional] in DOMString value);
void onerror(in int32_t error);
};
// Implemented by contract id @mozilla.org/b2g/engineering-mode-impl;1
[scriptable, uuid(7251c99b-225f-4e39-8336-a7e2a087aa21)]
interface nsIEngineeringMode : nsISupports
{
void getValue(in DOMString name, in nsIEngineeringModeCallback callback);
void setValue(in DOMString name, in DOMString value,
in nsIEngineeringModeCallback callback);
void setMessageHandler(in nsIEngineeringModeMessageHandler handler);
};

View File

@ -278,8 +278,7 @@ DOMEventTargetHelper::SetEventHandler(nsIAtom* aType,
{
nsRefPtr<EventHandlerNonNull> handler;
JS::Rooted<JSObject*> callable(aCx);
if (aValue.isObject() &&
JS_ObjectIsCallable(aCx, callable = &aValue.toObject())) {
if (aValue.isObject() && JS::IsCallable(callable = &aValue.toObject())) {
handler = new EventHandlerNonNull(callable, dom::GetIncumbentGlobal());
}
SetEventHandler(aType, EmptyString(), handler);

View File

@ -13,7 +13,7 @@ EXPORTS.mozilla.dom += [
'FileSystemUtils.h',
]
SOURCES += [
UNIFIED_SOURCES += [
'CreateDirectoryTask.cpp',
'CreateFileTask.cpp',
'DeviceStorageFileSystem.cpp',

View File

@ -11,7 +11,7 @@ EXPORTS.mozilla.dom += [
'FMRadioRequestParent.h',
]
SOURCES += [
UNIFIED_SOURCES += [
'FMRadioChild.cpp',
'FMRadioParent.cpp',
'FMRadioRequestChild.cpp',

View File

@ -15,7 +15,7 @@ if CONFIG['MOZ_B2G_FM']:
'FMRadioService.h',
]
SOURCES += [
UNIFIED_SOURCES += [
'FMRadio.cpp',
'FMRadioService.cpp',
]

View File

@ -11,7 +11,7 @@ EXPORTS.mozilla.dom += [
'IccManager.h',
]
SOURCES += [
UNIFIED_SOURCES += [
'Icc.cpp',
'IccListener.cpp',
'IccManager.cpp',

View File

@ -217,8 +217,7 @@ nsJSON::EncodeInternal(JSContext* cx, const JS::Value& aValue,
JS::Rooted<JS::Value> val(cx, aValue);
JS::Rooted<JS::Value> toJSON(cx);
if (JS_GetProperty(cx, obj, "toJSON", &toJSON) &&
toJSON.isObject() &&
JS_ObjectIsCallable(cx, &toJSON.toObject())) {
toJSON.isObject() && JS::IsCallable(&toJSON.toObject())) {
// If toJSON is implemented, it must not throw
if (!JS_CallFunctionValue(cx, obj, toJSON, JS::HandleValueArray::empty(), &val)) {
if (JS_IsExceptionPending(cx))

View File

@ -21,6 +21,9 @@
#include "nsJSUtils.h"
#include "nsServiceManagerUtils.h"
#ifdef CONVERT_STRING_TO_NULLABLE_ENUM
#undef CONVERT_STRING_TO_NULLABLE_ENUM
#endif
#define CONVERT_STRING_TO_NULLABLE_ENUM(_string, _enumType, _enum) \
{ \
uint32_t i = 0; \

View File

@ -231,13 +231,15 @@ MobileConnectionCallback::NotifyGetNetworksSuccess(uint32_t aCount,
}
NS_IMETHODIMP
MobileConnectionCallback::NotifySendCancelMmiSuccess(JS::Handle<JS::Value> aResult)
MobileConnectionCallback::NotifySendCancelMmiSuccess(JS::Handle<JS::Value> aResult,
JSContext* aCx)
{
return NotifySuccess(aResult);
}
NS_IMETHODIMP
MobileConnectionCallback::NotifyGetCallForwardingSuccess(JS::Handle<JS::Value> aResults)
MobileConnectionCallback::NotifyGetCallForwardingSuccess(JS::Handle<JS::Value> aResults,
JSContext* aCx)
{
return NotifySuccess(aResults);
}

View File

@ -10,6 +10,9 @@
#include "jsapi.h"
#ifdef CONVERT_STRING_TO_NULLABLE_ENUM
#undef CONVERT_STRING_TO_NULLABLE_ENUM
#endif
#define CONVERT_STRING_TO_NULLABLE_ENUM(_string, _enumType, _enum) \
{ \
_enum.SetNull(); \
@ -117,7 +120,7 @@ MobileConnectionInfo::Update(nsIMobileConnectionInfo* aInfo)
CONVERT_STRING_TO_NULLABLE_ENUM(type, MobileConnectionType, mType);
// Update mSignalStrength
AutoSafeJSContext cx;
AutoJSContext cx;
JS::Rooted<JS::Value> signalStrength(cx, JSVAL_VOID);
aInfo->GetSignalStrength(&signalStrength);
if (signalStrength.isNumber()) {

View File

@ -124,7 +124,7 @@ interface nsIMobileConnectionListener : nsISupports
#define NO_ADDITIONAL_INFORMATION 0
%}
[scriptable, builtinclass, uuid(e9d7c247-34c6-42bf-875b-f99b19db394f)]
[scriptable, builtinclass, uuid(7f2dbbe0-42f2-11e4-916c-0800200c9a66)]
interface nsIMobileConnectionCallback : nsISupports
{
/**
@ -139,8 +139,10 @@ interface nsIMobileConnectionCallback : nsISupports
void notifyGetNetworksSuccess(in uint32_t count,
[array, size_is(count)] in nsIMobileNetworkInfo networks);
[implicit_jscontext]
void notifySendCancelMmiSuccess(in jsval result /* MozMMIResult */);
[implicit_jscontext]
void notifyGetCallForwardingSuccess(in jsval results /* Array of MozCallForwardingOptions */);
void notifyGetCallBarringSuccess(in unsigned short program,

View File

@ -242,7 +242,12 @@ NS_IMETHODIMP
MobileConnectionChild::SetCallForwarding(JS::Handle<JS::Value> aOptions,
nsIMobileConnectionCallback* aCallback)
{
AutoSafeJSContext cx;
AutoJSAPI jsapi;
if (!NS_WARN_IF(jsapi.Init(&aOptions.toObject()))) {
return NS_ERROR_FAILURE;
}
JSContext* cx = jsapi.cx();
IPC::MozCallForwardingOptions options;
if(!options.Init(cx, aOptions)) {
return NS_ERROR_TYPE_ERR;
@ -264,7 +269,12 @@ NS_IMETHODIMP
MobileConnectionChild::SetCallBarring(JS::Handle<JS::Value> aOptions,
nsIMobileConnectionCallback* aCallback)
{
AutoSafeJSContext cx;
AutoJSAPI jsapi;
if (!NS_WARN_IF(jsapi.Init(&aOptions.toObject()))) {
return NS_ERROR_FAILURE;
}
JSContext* cx = jsapi.cx();
IPC::MozCallBarringOptions options;
if(!options.Init(cx, aOptions)) {
return NS_ERROR_TYPE_ERR;
@ -278,7 +288,12 @@ NS_IMETHODIMP
MobileConnectionChild::GetCallBarring(JS::Handle<JS::Value> aOptions,
nsIMobileConnectionCallback* aCallback)
{
AutoSafeJSContext cx;
AutoJSAPI jsapi;
if (!NS_WARN_IF(jsapi.Init(&aOptions.toObject()))) {
return NS_ERROR_FAILURE;
}
JSContext* cx = jsapi.cx();
IPC::MozCallBarringOptions options;
if(!options.Init(cx, aOptions)) {
return NS_ERROR_TYPE_ERR;
@ -292,7 +307,12 @@ NS_IMETHODIMP
MobileConnectionChild::ChangeCallBarringPassword(JS::Handle<JS::Value> aOptions,
nsIMobileConnectionCallback* aCallback)
{
AutoSafeJSContext cx;
AutoJSAPI jsapi;
if (!NS_WARN_IF(jsapi.Init(&aOptions.toObject()))) {
return NS_ERROR_FAILURE;
}
JSContext* cx = jsapi.cx();
IPC::MozCallBarringOptions options;
if(!options.Init(cx, aOptions)) {
return NS_ERROR_TYPE_ERR;

View File

@ -11,7 +11,7 @@
#include "mozilla/dom/MobileNetworkInfo.h"
#include "mozilla/dom/MozMobileConnectionBinding.h"
using mozilla::AutoSafeJSContext;
using mozilla::AutoJSContext;
using mozilla::dom::MobileNetworkInfo;
using mozilla::dom::MobileCellInfo;
using mozilla::dom::MobileConnectionInfo;
@ -261,7 +261,7 @@ struct ParamTraits<nsIMobileConnectionInfo*>
return;
}
AutoSafeJSContext cx;
AutoJSContext cx;
nsString pString;
bool pBool;
nsCOMPtr<nsIMobileNetworkInfo> pNetworkInfo;
@ -330,7 +330,7 @@ struct ParamTraits<nsIMobileConnectionInfo*>
return true;
}
AutoSafeJSContext cx;
AutoJSContext cx;
nsString state;
bool connected;
bool emergencyOnly;

View File

@ -423,7 +423,19 @@ MobileConnectionRequestParent::DoRequest(const SetCallForwardingRequest& aReques
{
NS_ENSURE_TRUE(mMobileConnection, false);
AutoSafeJSContext cx;
// There are cases (bug 1070083) where this is called with no JS on the stack.
// And since mobileConnectionService might be JS-Implemented, so we just
// create it in the System-Principaled Junk Scope. We are going to get rid of
// the "jsval" used in MobileConnection's interface in bug 1047196, after that
// we don't need these things.
// Note that using xpc::PrivilegedJunkScope requires explicit case-by-case
// approval from the XPConnect module owner (bholley).
AutoJSAPI jsapi;
if (NS_WARN_IF(!jsapi.Init(xpc::PrivilegedJunkScope()))) {
return false;
}
JSContext* cx = jsapi.cx();
JS::Rooted<JS::Value> options(cx);
if (!ToJSValue(cx, aRequest.options(), &options)) {
JS_ClearPendingException(cx);
@ -446,7 +458,19 @@ MobileConnectionRequestParent::DoRequest(const SetCallBarringRequest& aRequest)
{
NS_ENSURE_TRUE(mMobileConnection, false);
AutoSafeJSContext cx;
// There are cases (bug 1070083) where this is called with no JS on the stack.
// And since mobileConnectionService might be JS-Implemented, so we just
// create it in the System-Principaled Junk Scope. We are going to get rid of
// the "jsval" used in MobileConnection's interface in bug 1047196, after that
// we don't need these things.
// Note that using xpc::PrivilegedJunkScope requires explicit case-by-case
// approval from the XPConnect module owner (bholley).
AutoJSAPI jsapi;
if (NS_WARN_IF(!jsapi.Init(xpc::PrivilegedJunkScope()))) {
return false;
}
JSContext* cx = jsapi.cx();
JS::Rooted<JS::Value> options(cx);
if (!ToJSValue(cx, aRequest.options(), &options)) {
JS_ClearPendingException(cx);
@ -461,7 +485,19 @@ MobileConnectionRequestParent::DoRequest(const GetCallBarringRequest& aRequest)
{
NS_ENSURE_TRUE(mMobileConnection, false);
AutoSafeJSContext cx;
// There are cases (bug 1070083) where this is called with no JS on the stack.
// And since mobileConnectionService might be JS-Implemented, so we just
// create it in the System-Principaled Junk Scope. We are going to get rid of
// the "jsval" used in MobileConnection's interface in bug 1047196, after that
// we don't need these things.
// Note that using xpc::PrivilegedJunkScope requires explicit case-by-case
// approval from the XPConnect module owner (bholley).
AutoJSAPI jsapi;
if (NS_WARN_IF(!jsapi.Init(xpc::PrivilegedJunkScope()))) {
return false;
}
JSContext* cx = jsapi.cx();
JS::Rooted<JS::Value> options(cx);
if (!ToJSValue(cx, aRequest.options(), &options)) {
JS_ClearPendingException(cx);
@ -476,7 +512,19 @@ MobileConnectionRequestParent::DoRequest(const ChangeCallBarringPasswordRequest&
{
NS_ENSURE_TRUE(mMobileConnection, false);
AutoSafeJSContext cx;
// There are cases (bug 1070083) where this is called with no JS on the stack.
// And since mobileConnectionService might be JS-Implemented, so we just
// create it in the System-Principaled Junk Scope. We are going to get rid of
// the "jsval" used in MobileConnection's interface in bug 1047196, after that
// we don't need these things.
// Note that using xpc::PrivilegedJunkScope requires explicit case-by-case
// approval from the XPConnect module owner (bholley).
AutoJSAPI jsapi;
if (NS_WARN_IF(!jsapi.Init(xpc::PrivilegedJunkScope()))) {
return false;
}
JSContext* cx = jsapi.cx();
JS::Rooted<JS::Value> options(cx);
if (!ToJSValue(cx, aRequest.options(), &options)) {
JS_ClearPendingException(cx);
@ -579,12 +627,12 @@ MobileConnectionRequestParent::NotifyGetNetworksSuccess(uint32_t aCount,
}
NS_IMETHODIMP
MobileConnectionRequestParent::NotifySendCancelMmiSuccess(JS::Handle<JS::Value> aResult)
MobileConnectionRequestParent::NotifySendCancelMmiSuccess(JS::Handle<JS::Value> aResult,
JSContext* aCx)
{
AutoSafeJSContext cx;
RootedDictionary<MozMMIResult> result(cx);
RootedDictionary<MozMMIResult> result(aCx);
if (!result.Init(cx, aResult)) {
if (!result.Init(aCx, aResult)) {
return NS_ERROR_TYPE_ERR;
}
@ -605,13 +653,13 @@ MobileConnectionRequestParent::NotifySendCancelMmiSuccess(JS::Handle<JS::Value>
if (additionInformation.IsObject()) {
uint32_t length;
JS::Rooted<JS::Value> value(cx);
JS::Rooted<JSObject*> object(cx, additionInformation.GetAsObject());
JS::Rooted<JS::Value> value(aCx);
JS::Rooted<JSObject*> object(aCx, additionInformation.GetAsObject());
if (!JS_IsArrayObject(cx, object) ||
!JS_GetArrayLength(cx, object, &length) || length <= 0 ||
if (!JS_IsArrayObject(aCx, object) ||
!JS_GetArrayLength(aCx, object, &length) || length <= 0 ||
// Check first element to decide the format of array.
!JS_GetElement(cx, object, 0, &value)) {
!JS_GetElement(aCx, object, 0, &value)) {
return NS_ERROR_TYPE_ERR;
}
@ -620,12 +668,12 @@ MobileConnectionRequestParent::NotifySendCancelMmiSuccess(JS::Handle<JS::Value>
// String[]
nsTArray<nsString> infos;
for (uint32_t i = 0; i < length; i++) {
if (!JS_GetElement(cx, object, i, &value) || !value.isString()) {
if (!JS_GetElement(aCx, object, i, &value) || !value.isString()) {
return NS_ERROR_TYPE_ERR;
}
nsAutoJSString str;
if (!str.init(cx, value.toString())) {
if (!str.init(aCx, value.toString())) {
return NS_ERROR_FAILURE;
}
infos.AppendElement(str);
@ -639,7 +687,7 @@ MobileConnectionRequestParent::NotifySendCancelMmiSuccess(JS::Handle<JS::Value>
nsTArray<IPC::MozCallForwardingOptions> infos;
for (uint32_t i = 0; i < length; i++) {
IPC::MozCallForwardingOptions info;
if (!JS_GetElement(cx, object, i, &value) || !info.Init(cx, value)) {
if (!JS_GetElement(aCx, object, i, &value) || !info.Init(aCx, value)) {
return NS_ERROR_TYPE_ERR;
}
@ -656,23 +704,23 @@ MobileConnectionRequestParent::NotifySendCancelMmiSuccess(JS::Handle<JS::Value>
}
NS_IMETHODIMP
MobileConnectionRequestParent::NotifyGetCallForwardingSuccess(JS::Handle<JS::Value> aResults)
MobileConnectionRequestParent::NotifyGetCallForwardingSuccess(JS::Handle<JS::Value> aResults,
JSContext* aCx)
{
uint32_t length;
AutoSafeJSContext cx;
JS::Rooted<JSObject*> object(cx, &aResults.toObject());
JS::Rooted<JSObject*> object(aCx, &aResults.toObject());
nsTArray<IPC::MozCallForwardingOptions> results;
if (!JS_IsArrayObject(cx, object) ||
!JS_GetArrayLength(cx, object, &length)) {
if (!JS_IsArrayObject(aCx, object) ||
!JS_GetArrayLength(aCx, object, &length)) {
return NS_ERROR_TYPE_ERR;
}
for (uint32_t i = 0; i < length; i++) {
JS::Rooted<JS::Value> entry(cx);
JS::Rooted<JS::Value> entry(aCx);
IPC::MozCallForwardingOptions info;
if (!JS_GetElement(cx, object, i, &entry) || !info.Init(cx, entry)) {
if (!JS_GetElement(aCx, object, i, &entry) || !info.Init(aCx, entry)) {
return NS_ERROR_TYPE_ERR;
}

View File

@ -30,7 +30,7 @@ XPIDL_SOURCES += [
'interfaces/nsINeighboringCellInfo.idl',
]
SOURCES += [
UNIFIED_SOURCES += [
'DOMMMIError.cpp',
'ipc/MobileConnectionChild.cpp',
'ipc/MobileConnectionIPCService.cpp',

View File

@ -10,16 +10,12 @@
namespace {
const char* kPrefRilNumRadioInterfaces = "ril.numRadioInterfaces";
#define kPrefDefaultServiceId "dom.sms.defaultServiceId"
const char* kObservedPrefs[] = {
kPrefDefaultServiceId,
nullptr
};
uint32_t
getDefaultServiceId()
{
static const char* kPrefRilNumRadioInterfaces = "ril.numRadioInterfaces";
int32_t id = mozilla::Preferences::GetInt(kPrefDefaultServiceId, 0);
int32_t numRil = mozilla::Preferences::GetInt(kPrefRilNumRadioInterfaces, 1);
@ -46,6 +42,10 @@ SmsService::SmsService()
NS_WARN_IF_FALSE(mRil, "This shouldn't fail!");
// Initialize observer.
static const char* kObservedPrefs[] = {
kPrefDefaultServiceId,
nullptr
};
Preferences::AddStrongObservers(this, kObservedPrefs);
mDefaultServiceId = getDefaultServiceId();
}

View File

@ -19,14 +19,8 @@ using namespace mozilla::dom::mobilemessage;
namespace {
const char* kPrefRilNumRadioInterfaces = "ril.numRadioInterfaces";
#define kPrefMmsDefaultServiceId "dom.mms.defaultServiceId"
#define kPrefSmsDefaultServiceId "dom.sms.defaultServiceId"
const char* kObservedPrefs[] = {
kPrefMmsDefaultServiceId,
kPrefSmsDefaultServiceId,
nullptr
};
// TODO: Bug 767082 - WebSMS: sSmsChild leaks at shutdown
PSmsChild* gSmsChild;
@ -86,6 +80,7 @@ SendCursorRequest(const IPCMobileMessageCursor& aRequest,
uint32_t
getDefaultServiceId(const char* aPrefKey)
{
static const char* kPrefRilNumRadioInterfaces = "ril.numRadioInterfaces";
int32_t id = mozilla::Preferences::GetInt(aPrefKey, 0);
int32_t numRil = mozilla::Preferences::GetInt(kPrefRilNumRadioInterfaces, 1);
@ -119,6 +114,11 @@ SmsIPCService::GetSingleton()
SmsIPCService::SmsIPCService()
{
static const char* kObservedPrefs[] = {
kPrefMmsDefaultServiceId,
kPrefSmsDefaultServiceId,
nullptr
};
Preferences::AddStrongObservers(this, kObservedPrefs);
mMmsDefaultServiceId = getDefaultServiceId(kPrefMmsDefaultServiceId);
mSmsDefaultServiceId = getDefaultServiceId(kPrefSmsDefaultServiceId);

View File

@ -35,7 +35,7 @@ elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk' and CONFIG['MOZ_B2G_RIL']:
'gonk/MobileMessageDatabaseService.js',
'gonk/MobileMessageDatabaseService.manifest',
]
SOURCES += [
UNIFIED_SOURCES += [
'gonk/SmsService.cpp',
]

View File

@ -128,7 +128,8 @@ if CONFIG['MOZ_NFC']:
if CONFIG['MOZ_B2G']:
DIRS += [
'downloads',
'mobileid'
'mobileid',
'engineeringmode'
]
if CONFIG['MOZ_B2G_BT_API_V2']:

View File

@ -14,7 +14,7 @@ if CONFIG['MOZ_NFC']:
EXPORTS.mozilla.dom += [
'MozNDEFRecord.h',
]
SOURCES += [
UNIFIED_SOURCES += [
'MozNDEFRecord.cpp',
]
EXTRA_COMPONENTS += [
@ -24,7 +24,7 @@ if CONFIG['MOZ_NFC']:
]
if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk' and CONFIG['MOZ_NFC']:
SOURCES += [
UNIFIED_SOURCES += [
'gonk/NfcMessageHandler.cpp',
'gonk/NfcService.cpp',
]

View File

@ -1609,7 +1609,7 @@ NPObjWrapper_Convert(JSContext *cx, JS::Handle<JSObject*> obj, JSType hint, JS::
JS::Rooted<JS::Value> v(cx, JSVAL_VOID);
if (!JS_GetProperty(cx, obj, "toString", &v))
return false;
if (!v.isPrimitive() && JS_ObjectIsCallable(cx, v.toObjectOrNull())) {
if (!v.isPrimitive() && JS::IsCallable(v.toObjectOrNull())) {
if (!JS_CallFunctionValue(cx, obj, v, JS::HandleValueArray::empty(), vp))
return false;
if (vp.isPrimitive())

View File

@ -1092,7 +1092,7 @@ Promise::ResolveInternal(JSContext* aCx,
return;
}
if (then.isObject() && JS_ObjectIsCallable(aCx, &then.toObject())) {
if (then.isObject() && JS::IsCallable(&then.toObject())) {
// This is the then() function of the thenable aValueObj.
JS::Rooted<JSObject*> thenObj(aCx, &then.toObject());
nsRefPtr<PromiseInit> thenCallback =

View File

@ -12,7 +12,7 @@ EXPORTS += [
'SpeakerManagerServiceChild.h',
]
SOURCES += [
UNIFIED_SOURCES += [
'SpeakerManager.cpp',
'SpeakerManagerService.cpp',
'SpeakerManagerServiceChild.cpp',

View File

@ -378,7 +378,7 @@ Volume::HandleVoldResponse(int aResponseCode, nsCWhitespaceTokenizer& aTokenizer
// The volume name will have already been parsed, and the tokenizer will point
// to the token after the volume name
switch (aResponseCode) {
case ResponseCode::VolumeListResult: {
case ::ResponseCode::VolumeListResult: {
// Each line will look something like:
//
// sdcard /mnt/sdcard 1
@ -397,7 +397,7 @@ Volume::HandleVoldResponse(int aResponseCode, nsCWhitespaceTokenizer& aTokenizer
break;
}
case ResponseCode::VolumeStateChange: {
case ::ResponseCode::VolumeStateChange: {
// Format of the line looks something like:
//
// Volume sdcard /mnt/sdcard state changed from 7 (Shared-Unmounted) to 1 (Idle-Unmounted)
@ -415,12 +415,12 @@ Volume::HandleVoldResponse(int aResponseCode, nsCWhitespaceTokenizer& aTokenizer
break;
}
case ResponseCode::VolumeDiskInserted:
case ::ResponseCode::VolumeDiskInserted:
SetMediaPresent(true);
break;
case ResponseCode::VolumeDiskRemoved: // fall-thru
case ResponseCode::VolumeBadRemoval:
case ::ResponseCode::VolumeDiskRemoved: // fall-thru
case ::ResponseCode::VolumeBadRemoval:
SetMediaPresent(false);
break;

Some files were not shown because too many files have changed in this diff Show More