Merge mozilla-inbound in mozilla-central.

This commit is contained in:
Mounir Lamouri 2012-09-26 11:57:25 +01:00
Родитель 9ead2559d1 8c8368ef8b
Коммит 25a3db2998
258 изменённых файлов: 8169 добавлений и 4729 удалений

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

@ -29,8 +29,8 @@
function testTabRelations()
{
this.eventSeq = [
new invokerChecker(EVENT_DOCUMENT_LOAD_COMPLETE, tabDocumentAt, 0),
new invokerChecker(EVENT_DOCUMENT_LOAD_COMPLETE, tabDocumentAt, 1)
new asyncInvokerChecker(EVENT_DOCUMENT_LOAD_COMPLETE, tabDocumentAt, 0),
new asyncInvokerChecker(EVENT_DOCUMENT_LOAD_COMPLETE, tabDocumentAt, 1)
];
this.invoke = function testTabRelations_invoke()
@ -61,8 +61,10 @@
////////////////////////////////////////////////////////////////////////////
// Test
//gA11yEventDumpToConsole = true; // debug stuff
var gQueue = null;
gA11yEventDumpToConsole = true;
function doTest()
{
// Load documents into tabs and wait for DocLoadComplete events caused by

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

@ -28,8 +28,8 @@
function testTabHierarchy()
{
this.eventSeq = [
new invokerChecker(EVENT_DOCUMENT_LOAD_COMPLETE, tabDocumentAt, 0),
new invokerChecker(EVENT_DOCUMENT_LOAD_COMPLETE, tabDocumentAt, 1)
new asyncInvokerChecker(EVENT_DOCUMENT_LOAD_COMPLETE, tabDocumentAt, 0),
new asyncInvokerChecker(EVENT_DOCUMENT_LOAD_COMPLETE, tabDocumentAt, 1)
];
this.invoke = function testTabHierarchy_invoke()

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

@ -354,6 +354,10 @@ pref("browser.dom.window.dump.enabled", false);
// installable apps or wifi support.
pref("security.fileuri.strict_origin_policy", false);
// Default Content Security Policy to apply to privileged and certified apps
pref("security.apps.privileged.CSP.default", "default-src *; script-src 'self'; object-src 'none'; style-src 'self' 'unsafe-inline'");
pref("security.apps.certified.CSP.default", "options inline-script eval-script; default-src *; script-src 'self'; object-src 'none'; style-src 'self'");
// Temporarily force-enable GL compositing. This is default-disabled
// deep within the bowels of the widgetry system. Remove me when GL
// compositing isn't default disabled in widget/android.

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

@ -1,5 +1,5 @@
{
"tooltool_manifest": "releng-pandaboard.tt",
"mock_target": "mozilla-centos6-i386",
"mock_packages": ["ccache", "make", "bison", "flex", "gcc", "g++", "mpfr", "zlib-devel", "ncurses-devel", "zip", "autoconf213", "glibc-static", "java-1.6.0-openjdk-devel"]
"mock_packages": ["ccache", "make", "bison", "flex", "gcc", "g++", "mpfr", "zlib-devel", "ncurses-devel", "zip", "autoconf213", "glibc-static", "perl-Digest-SHA"]
}

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

@ -73,100 +73,103 @@ var stringBundle;
function saveCanvas(canvas) {
const nsIFilePicker = Components.interfaces.nsIFilePicker;
let filePicker = Components.classes["@mozilla.org/filepicker;1"].
createInstance(nsIFilePicker);
filePicker.init(window, null, nsIFilePicker.modeSave);
filePicker.appendFilters(
nsIFilePicker.filterImages | nsIFilePicker.filterAll);
filePicker.defaultString = "canvas.png";
let fp = Components.classes["@mozilla.org/filepicker;1"].
createInstance(nsIFilePicker);
let fpCallback = function fpCallback_done(aResult) {
if (aResult == nsIFilePicker.returnOK ||
aResult == nsIFilePicker.returnReplace) {
const nsIWebBrowserPersist =
Components.interfaces.nsIWebBrowserPersist;
let file = fp.file;
let response = filePicker.show();
if (response == nsIFilePicker.returnOK ||
response == nsIFilePicker.returnReplace) {
const nsIWebBrowserPersist = Components.interfaces.nsIWebBrowserPersist;
let file = filePicker.file;
// create a data url from the canvas and then create URIs of the
// source and targets
let io = Components.classes["@mozilla.org/network/io-service;1"].
getService(Components.interfaces.nsIIOService);
let source = io.newURI(canvas.toDataURL("image/png"), "UTF8", null);
let target = io.newFileURI(file);
// create a data url from the canvas and then create URIs of the source
// and targets
let io = Components.classes["@mozilla.org/network/io-service;1"].
getService(Components.interfaces.nsIIOService);
let source = io.newURI(canvas.toDataURL("image/png"), "UTF8", null);
let target = io.newFileURI(file);
// prepare to save the canvas data
let persist = Components.classes[
"@mozilla.org/embedding/browser/nsWebBrowserPersist;1"].
createInstance(nsIWebBrowserPersist);
persist.persistFlags = nsIWebBrowserPersist.
PERSIST_FLAGS_REPLACE_EXISTING_FILES;
persist.persistFlags |= nsIWebBrowserPersist.
PERSIST_FLAGS_AUTODETECT_APPLY_CONVERSION;
// prepare to save the canvas data
let persist = Components.classes[
"@mozilla.org/embedding/browser/nsWebBrowserPersist;1"].
createInstance(nsIWebBrowserPersist);
persist.persistFlags = nsIWebBrowserPersist.
PERSIST_FLAGS_REPLACE_EXISTING_FILES;
persist.persistFlags |= nsIWebBrowserPersist.
PERSIST_FLAGS_AUTODETECT_APPLY_CONVERSION;
// displays a download dialog (remove these 3 lines for silent download)
let xfer = Components.classes["@mozilla.org/transfer;1"].
createInstance(Components.interfaces.nsITransfer);
xfer.init(source, target, "", null, null, null, persist);
persist.progressListener = xfer;
// displays a download dialog (remove these 3 lines for silent download)
let xfer = Components.classes["@mozilla.org/transfer;1"].
createInstance(Components.interfaces.nsITransfer);
xfer.init(source, target, "", null, null, null, persist);
persist.progressListener = xfer;
// save the canvas data to the file
persist.saveURI(source, null, null, null, null, file);
}
};
// save the canvas data to the file
persist.saveURI(source, null, null, null, null, file);
}
fp.init(window, null, nsIFilePicker.modeSave);
fp.appendFilters(nsIFilePicker.filterImages | nsIFilePicker.filterAll);
fp.defaultString = "canvas.png";
fp.open(fpCallback);
}
function exportData() {
const nsIFilePicker = Components.interfaces.nsIFilePicker;
let filePicker = Components.classes["@mozilla.org/filepicker;1"].
createInstance(nsIFilePicker);
let eid = getUrlParam("eid");
let task = TestPilotSetup.getTaskById(eid);
let fp = Components.classes["@mozilla.org/filepicker;1"].
createInstance(nsIFilePicker);
let fpCallback = function fpCallback_done(aResult) {
if (aResult == nsIFilePicker.returnOK ||
aResult == nsIFilePicker.returnReplace) {
const nsIWebBrowserPersist =
Components.interfaces.nsIWebBrowserPersist;
let foStream =
Components.classes["@mozilla.org/network/file-output-stream;1"].
createInstance(Components.interfaces.nsIFileOutputStream);
let converter =
Components.classes["@mozilla.org/intl/converter-output-stream;1"].
createInstance(Components.interfaces.nsIConverterOutputStream);
let file = fp.file;
let dataStore = task.dataStore;
let columnNames = dataStore.getHumanReadableColumnNames();
let propertyNames = dataStore.getPropertyNames();
let csvString = "";
filePicker.init(window, null, nsIFilePicker.modeSave);
filePicker.appendFilters(
nsIFilePicker.filterImages | nsIFilePicker.filterAll);
filePicker.defaultString = task.title + ".csv";
let response = filePicker.show();
if (response == nsIFilePicker.returnOK ||
response == nsIFilePicker.returnReplace) {
const nsIWebBrowserPersist = Components.interfaces.nsIWebBrowserPersist;
let foStream =
Components.classes["@mozilla.org/network/file-output-stream;1"].
createInstance(Components.interfaces.nsIFileOutputStream);
let converter =
Components.classes["@mozilla.org/intl/converter-output-stream;1"].
createInstance(Components.interfaces.nsIConverterOutputStream);
let file = filePicker.file;
let dataStore = task.dataStore;
let columnNames = dataStore.getHumanReadableColumnNames();
let propertyNames = dataStore.getPropertyNames();
let csvString = "";
// titles
for (let i = 0; i < columnNames.length; i++) {
csvString += "\"" + columnNames[i] + "\",";
}
if (csvString.length > 0) {
csvString = csvString.substring(0, (csvString.length - 1));
csvString += "\n";
}
dataStore.getAllDataAsJSON(true, function(rawData) {
// data
for (let i = 0; i < rawData.length; i++) {
for (let j = 0; j < columnNames.length; j++) {
csvString += "\"" + rawData[i][propertyNames[j]] + "\",";
}
csvString = csvString.substring(0, (csvString.length - 1));
// titles
for (let i = 0; i < columnNames.length; i++) {
csvString += "\"" + columnNames[i] + "\",";
}
if (csvString.length > 0) {
csvString = csvString.substring(0, (csvString.length - 1));
csvString += "\n";
}
// write, create, truncate
foStream.init(file, 0x02 | 0x08 | 0x20, 0664, 0);
converter.init(foStream, "UTF-8", 0, 0);
converter.writeString(csvString);
converter.close();
});
}
dataStore.getAllDataAsJSON(true, function(rawData) {
// data
for (let i = 0; i < rawData.length; i++) {
for (let j = 0; j < columnNames.length; j++) {
csvString += "\"" + rawData[i][propertyNames[j]] + "\",";
}
csvString = csvString.substring(0, (csvString.length - 1));
csvString += "\n";
}
// write, create, truncate
foStream.init(file, 0x02 | 0x08 | 0x20, 0664, 0);
converter.init(foStream, "UTF-8", 0, 0);
converter.writeString(csvString);
converter.close();
});
}
};
fp.init(window, null, nsIFilePicker.modeSave);
fp.appendFilters(nsIFilePicker.filterImages | nsIFilePicker.filterAll);
fp.defaultString = task.title + ".csv";
fp.open(fpCallback);
}
function openLink(url) {

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

@ -191,7 +191,6 @@ let SocialChatBar = {
function sizeSocialPanelToContent(iframe) {
// FIXME: bug 764787: Maybe we can use nsIDOMWindowUtils.getRootBounds() here?
// Need to handle dynamic sizing
let doc = iframe.contentDocument;
if (!doc) {
return;
@ -199,15 +198,38 @@ function sizeSocialPanelToContent(iframe) {
// "notif" is an implementation detail that we should get rid of
// eventually
let body = doc.getElementById("notif") || doc.body;
if (!body || !body.firstChild) {
if (!body) {
return;
}
let [height, width] = [body.firstChild.offsetHeight || 300, 330];
iframe.style.width = width + "px";
// XXX - do we want a max for width and height here?
// The 300 and 330 defaults also seem arbitrary, so should be revisited.
// BUT - for at least one provider, the scrollWidth/offsetWidth/css width
// isn't set appropriately, so the 330 is "fixed" for now...
iframe.style.width = "330px";
// offsetHeight doesn't include margins, so account for that.
let cs = doc.defaultView.getComputedStyle(body);
let computedHeight = parseInt(cs.marginTop) + body.offsetHeight + parseInt(cs.marginBottom);
let height = computedHeight || 300;
iframe.style.height = height + "px";
}
function setupDynamicPanelResizer(iframe) {
let doc = iframe.contentDocument;
let mo = new iframe.contentWindow.MutationObserver(function(mutations) {
sizeSocialPanelToContent(iframe);
});
// Observe anything that causes the size to change.
let config = {attributes: true, characterData: true, childList: true, subtree: true};
mo.observe(doc, config);
doc.addEventListener("unload", function() {
if (mo) {
mo.disconnect();
mo = null;
}
}, false);
sizeSocialPanelToContent(iframe);
}
let SocialFlyout = {
get panel() {
return document.getElementById("social-flyout-panel");
@ -235,6 +257,7 @@ let SocialFlyout = {
unload: function() {
let panel = this.panel;
panel.hidePopup();
if (!panel.firstChild)
return
panel.removeChild(panel.firstChild);
@ -275,7 +298,7 @@ let SocialFlyout = {
if (src != aURL) {
iframe.addEventListener("load", function documentLoaded() {
iframe.removeEventListener("load", documentLoaded, true);
sizeSocialPanelToContent(iframe);
setupDynamicPanelResizer(iframe);
if (aCallback) {
try {
aCallback(iframe.contentWindow);
@ -332,7 +355,7 @@ let SocialShareButton = {
if (profile && profile.displayName) {
profileRow.hidden = false;
let portrait = document.getElementById("socialUserPortrait");
portrait.setAttribute("src", profile.portrait || "chrome://browser/skin/social/social.png");
portrait.setAttribute("src", profile.portrait || "chrome://global/skin/icons/information-32.png");
let displayName = document.getElementById("socialUserDisplayName");
displayName.setAttribute("label", profile.displayName);
} else {
@ -540,7 +563,7 @@ var SocialToolbar = {
// response. In that case we'll be called again when it's available, via
// social:profile-changed
let profile = Social.provider.profile || {};
let userPortrait = profile.portrait || "chrome://browser/skin/social/social.png";
let userPortrait = profile.portrait || "chrome://global/skin/icons/information-32.png";
document.getElementById("social-statusarea-user-portrait").setAttribute("src", userPortrait);
let notLoggedInLabel = document.getElementById("social-statusarea-notloggedin");
@ -650,13 +673,13 @@ var SocialToolbar = {
notificationFrame.docShell.isActive = true;
notificationFrame.docShell.isAppTab = true;
if (notificationFrame.contentDocument.readyState == "complete") {
sizeSocialPanelToContent(notificationFrame);
setupDynamicPanelResizer(notificationFrame);
dispatchPanelEvent("socialFrameShow");
} else {
// first time load, wait for load and dispatch after load
notificationFrame.addEventListener("load", function panelBrowserOnload(e) {
notificationFrame.removeEventListener("load", panelBrowserOnload, true);
sizeSocialPanelToContent(notificationFrame);
setupDynamicPanelResizer(notificationFrame);
setTimeout(function() {
dispatchPanelEvent("socialFrameShow");
}, 0);

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

@ -8,7 +8,7 @@
<binding id="chatbox">
<content orient="vertical" mousethrough="never">
<xul:hbox class="chat-titlebar" xbl:inherits="minimized,selected"
onclick="document.getBindingParent(this).toggle();">
onclick="document.getBindingParent(this).toggle();" align="baseline">
<xul:image class="chat-status-icon" xbl:inherits="src=image"/>
<xul:label class="chat-title" flex="1" xbl:inherits="value=label,crop"/>
<xul:toolbarbutton class="chat-close-button chat-toolbarbutton"

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

@ -115,5 +115,24 @@ var tests = {
}
}
port.postMessage({topic: "test-worker-chat", data: chatUrl});
},
testCloseOnLogout: function(next) {
const chatUrl = "https://example.com/browser/browser/base/content/test/social_chat.html";
let port = Social.provider.getWorkerPort();
ok(port, "provider has a port");
port.postMessage({topic: "test-init"});
port.onmessage = function (e) {
let topic = e.data.topic;
switch (topic) {
case "got-chatbox-message":
ok(true, "got a chat window opened");
port.postMessage({topic: "test-logout"});
waitForCondition(function() document.getElementById("pinnedchats").firstChild == null,
next,
"chat windows didn't close");
break;
}
}
port.postMessage({topic: "test-worker-chat", data: chatUrl});
}
}

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

@ -31,11 +31,12 @@ var tests = {
case "got-flyout-visibility":
if (e.data.result == "hidden") {
ok(true, "flyout visibility is 'hidden'");
is(panel.state, "closed", "panel really is closed");
port.close();
next();
} else if (e.data.result == "shown") {
ok(true, "flyout visibility is 'shown");
panel.hidePopup();
port.postMessage({topic: "test-flyout-close"});
}
break;
case "got-flyout-message":
@ -44,6 +45,35 @@ var tests = {
}
}
port.postMessage({topic: "test-init"});
},
testResizeFlyout: function(next) {
let panel = document.getElementById("social-flyout-panel");
let port = Social.provider.getWorkerPort();
ok(port, "provider has a port");
port.onmessage = function (e) {
let topic = e.data.topic;
switch (topic) {
case "test-init-done":
port.postMessage({topic: "test-flyout-open"});
break;
case "got-flyout-visibility":
// The width of the flyout should be 250px
let iframe = panel.firstChild;
let cs = iframe.contentWindow.getComputedStyle(iframe.contentDocument.body);
is(cs.width, "250px", "should be 250px wide");
iframe.contentDocument.addEventListener("SocialTest-DoneMakeWider", function _doneHandler() {
iframe.contentDocument.removeEventListener("SocialTest-DoneMakeWider", _doneHandler, false);
cs = iframe.contentWindow.getComputedStyle(iframe.contentDocument.body);
is(cs.width, "500px", "should now be 500px wide");
panel.hidePopup();
next();
}, false);
SocialFlyout.dispatchPanelEvent("socialTest-MakeWider");
break;
}
}
port.postMessage({topic: "test-init"});
}
}

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

@ -56,8 +56,6 @@ var tests = {
testProfileUnset: function(next) {
Social.provider.updateUserProfile({});
// check dom values
let portrait = document.getElementById("social-statusarea-user-portrait").getAttribute("src");
is(portrait, "chrome://browser/skin/social/social.png", "portrait is generic");
let userButton = document.getElementById("social-statusarea-username");
ok(userButton.hidden, "username is not visible");
let ambience = document.getElementById("social-status-iconbox").firstChild;

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

@ -14,9 +14,16 @@
var port = navigator.mozSocial.getWorker().port;
port.postMessage({topic: "flyout-visibility", result: "hidden"});
}, false);
window.addEventListener("socialTest-MakeWider", function(e) {
document.body.setAttribute("style", "width: 500px;");
document.body.offsetWidth; // force a layout flush
var evt = document.createEvent("CustomEvent");
evt.initCustomEvent("SocialTest-DoneMakeWider", true, true, {});
document.documentElement.dispatchEvent(evt);
}, false);
</script>
</head>
<body onload="pingWorker();">
<body style="max-width: 250px;" onload="pingWorker();">
<p>This is a test social flyout panel.</p>
</body>
</html>

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

@ -11,6 +11,9 @@
case "test-flyout-open":
navigator.mozSocial.openPanel("social_flyout.html");
break;
case "test-flyout-close":
navigator.mozSocial.closePanel();
break;
case "test-chatbox-open":
var url = "social_chat.html";
var data = e.data.data;

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

@ -13,6 +13,9 @@ onconnect = function(e) {
testPort = port;
port.postMessage({topic: "test-init-done"});
break;
case "test-logout":
apiPort.postMessage({topic: "social.user-profile", data: {}});
break;
case "sidebar-message":
sidebarPort = port;
if (testPort && event.data.result == "ok")
@ -64,6 +67,9 @@ onconnect = function(e) {
case "flyout-visibility":
testPort.postMessage({topic:"got-flyout-visibility", result: event.data.result});
break;
case "test-flyout-close":
sidebarPort.postMessage({topic:"test-flyout-close"});
break;
case "test-worker-chat":
apiPort.postMessage({topic: "social.request-chat", data: event.data.data });
break;

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

@ -1,4 +1,4 @@
This is the pdf.js project output, https://github.com/mozilla/pdf.js
Current extension version is: 0.5.22
Current extension version is: 0.5.184

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

@ -539,8 +539,8 @@ PdfStreamConverter.prototype = {
.getService(Ci.nsIScriptSecurityManager);
var uri = ioService.newURI(PDF_VIEWER_WEB_PAGE, null, null);
// FF16 and below had getCodebasePrincipal (bug 774585)
var resourcePrincipal = 'getSimpleCodebasePrincipal' in securityManager ?
securityManager.getSimpleCodebasePrincipal(uri) :
var resourcePrincipal = 'getNoAppCodebasePrincipal' in securityManager ?
securityManager.getNoAppCodebasePrincipal(uri) :
securityManager.getCodebasePrincipal(uri);
channel.owner = resourcePrincipal;
}

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

@ -121,7 +121,7 @@ html[dir='rtl'] .innerCenter {
-o-transition-timing-function: ease;
transition-duration: 200ms;
transition-timing-function: ease;
}
html[dir='ltr'] #sidebarContainer {
-webkit-transition-property: left;
@ -629,7 +629,7 @@ html[dir='rtl'] .toolbarButton:first-child {
display: inline-block;
content: url(images/toolbarButton-sidebarToggle.png);
}
html[dir='ltr'] .toolbarButton.pageUp::before {
display: inline-block;
content: url(images/toolbarButton-pageUp.png);
@ -639,7 +639,7 @@ html[dir='rtl'] .toolbarButton.pageUp::before {
display: inline-block;
content: url(images/toolbarButton-pageUp-rtl.png);
}
html[dir='ltr'] .toolbarButton.pageDown::before {
display: inline-block;
content: url(images/toolbarButton-pageDown.png);
@ -654,7 +654,7 @@ html[dir='rtl'] .toolbarButton.pageDown::before {
display: inline-block;
content: url(images/toolbarButton-zoomOut.png);
}
.toolbarButton.zoomIn::before {
display: inline-block;
content: url(images/toolbarButton-zoomIn.png);
@ -691,12 +691,12 @@ html[dir='rtl'] .toolbarButton.pageDown::before {
.toolbarButton.bookmark::before {
content: url(images/toolbarButton-bookmark.png);
}
#viewThumbnail.toolbarButton::before {
display: inline-block;
content: url(images/toolbarButton-viewThumbnail.png);
}
#viewOutline.toolbarButton::before {
display: inline-block;
content: url(images/toolbarButton-viewOutline.png);
@ -797,7 +797,7 @@ html[dir='rtl'] .toolbarButton.pageDown::before {
padding: 7px;
-moz-transition-duration: 150ms;
}
a:focus > .thumbnail > .thumbnailSelectionRing > .thumbnailImage,
.thumbnail:hover > .thumbnailSelectionRing > .thumbnailImage {
opacity: .9;
@ -1016,7 +1016,7 @@ canvas {
background: -moz-linear-gradient(top, #b2b2b2 0%,#898989 100%);
background: -ms-linear-gradient(top, #b2b2b2 0%,#898989 100%);
background: -o-linear-gradient(top, #b2b2b2 0%,#898989 100%);
background: linear-gradient(top, #b2b2b2 0%,#898989 100%);
background: linear-gradient(top, #b2b2b2 0%,#898989 100%);
border-top-left-radius: 2px;
border-bottom-left-radius: 2px;
@ -1066,6 +1066,7 @@ canvas {
color: transparent;
position: absolute;
line-height:1.3;
white-space:pre;
}
/* TODO: file FF bug to support ::-moz-selection:window-inactive
@ -1202,7 +1203,7 @@ canvas {
@page {
margin: 0;
}
}
#printContainer {
display: none;

Разница между файлами не показана из-за своего большого размера Загрузить разницу

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

@ -35,7 +35,6 @@ var RenderingStates = {
FINISHED: 3
};
PDFJS.workerSrc = '../build/pdf.js';
var mozL10n = document.mozL10n || document.webL10n;
@ -286,9 +285,11 @@ var PDFView = {
isFullscreen: false,
previousScale: null,
pageRotation: 0,
lastScroll: 0,
// called once when the document is loaded
initialize: function pdfViewInitialize() {
var self = this;
var container = this.container = document.getElementById('viewerContainer');
this.pageViewScroll = {};
this.watchScroll(container, this.pageViewScroll, updateViewarea);
@ -300,6 +301,9 @@ var PDFView = {
this.renderHighestPriority.bind(this));
this.initialized = true;
container.addEventListener('scroll', function() {
self.lastScroll = Date.now();
}, false);
},
// Helper function to keep track whether a div was scrolled up or down and
@ -437,7 +441,7 @@ var PDFView = {
get supportsFullscreen() {
var doc = document.documentElement;
var support = doc.requestFullScreen || doc.mozRequestFullScreen ||
var support = doc.requestFullscreen || doc.mozRequestFullScreen ||
doc.webkitRequestFullScreen;
Object.defineProperty(this, 'supportsFullScreen', { value: support,
enumerable: true,
@ -537,7 +541,6 @@ var PDFView = {
function noData() {
FirefoxCom.request('download', { originalUrl: url });
}
var url = this.url.split('#')[0];
// Document isn't ready just try to download with the url.
if (!this.pdfDocument) {
@ -546,10 +549,8 @@ var PDFView = {
}
this.pdfDocument.getData().then(
function getDataSuccess(data) {
var bb = new MozBlobBuilder();
bb.append(data.buffer);
var blobUrl = window.URL.createObjectURL(
bb.getBlob('application/pdf'));
var blob = PDFJS.createBlob(data.buffer, 'application/pdf');
var blobUrl = window.URL.createObjectURL(blob);
FirefoxCom.request('download', { blobUrl: blobUrl, originalUrl: url },
function response(err) {
@ -1052,7 +1053,7 @@ var PDFView = {
function extractPageText(pageIndex) {
self.pages[pageIndex].pdfPage.getTextContent().then(
function textContentResolved(textContent) {
self.pageText[pageIndex] = textContent;
self.pageText[pageIndex] = textContent.join('');
self.search();
if ((pageIndex + 1) < self.pages.length)
extractPageText(pageIndex + 1);
@ -1164,7 +1165,7 @@ var PDFView = {
},
fullscreen: function pdfViewFullscreen() {
var isFullscreen = document.fullscreen || document.mozFullScreen ||
var isFullscreen = document.fullscreenElement || document.mozFullScreen ||
document.webkitIsFullScreen;
if (isFullscreen) {
@ -1172,8 +1173,8 @@ var PDFView = {
}
var wrapper = document.getElementById('viewerContainer');
if (document.documentElement.requestFullScreen) {
wrapper.requestFullScreen();
if (document.documentElement.requestFullscreen) {
wrapper.requestFullscreen();
} else if (document.documentElement.mozRequestFullScreen) {
wrapper.mozRequestFullScreen();
} else if (document.documentElement.webkitRequestFullScreen) {
@ -1217,9 +1218,7 @@ var PDFView = {
var currentPage = this.pages[this.page - 1];
if (this.isFullscreen) {
this.parseScale('page-fit', true);
}
this.parseScale(this.currentScaleValue, true);
this.renderHighestPriority();
@ -1242,6 +1241,8 @@ var PageView = function pageView(container, pdfPage, id, scale,
this.renderingState = RenderingStates.INITIAL;
this.resume = null;
this.textContent = null;
var anchor = document.createElement('a');
anchor.name = '' + this.id;
@ -1462,6 +1463,13 @@ var PageView = function pageView(container, pdfPage, id, scale,
}, 0);
};
this.getTextContent = function pageviewGetTextContent() {
if (!this.textContent) {
this.textContent = this.pdfPage.getTextContent();
}
return this.textContent;
};
this.draw = function pageviewDraw(callback) {
if (this.renderingState !== RenderingStates.INITIAL)
error('Must be in new state before drawing');
@ -1542,6 +1550,14 @@ var PageView = function pageView(container, pdfPage, id, scale,
}
);
if (textLayer) {
this.getTextContent().then(
function textContentResolved(textContent) {
textLayer.setTextContent(textContent);
}
);
}
setupAnnotations(this.pdfPage, this.viewport);
div.setAttribute('data-loaded', true);
};
@ -1832,7 +1848,10 @@ var CustomStyle = (function CustomStyleClosure() {
})();
var TextLayerBuilder = function textLayerBuilder(textLayerDiv) {
var textLayerFrag = document.createDocumentFragment();
this.textLayerDiv = textLayerDiv;
this.layoutDone = false;
this.divContentDone = false;
this.beginLayout = function textLayerBuilderBeginLayout() {
this.textDivs = [];
@ -1840,84 +1859,104 @@ var TextLayerBuilder = function textLayerBuilder(textLayerDiv) {
};
this.endLayout = function textLayerBuilderEndLayout() {
this.layoutDone = true;
this.insertDivContent();
},
this.renderLayer = function textLayerBuilderRenderLayer() {
var self = this;
var textDivs = this.textDivs;
var textLayerDiv = this.textLayerDiv;
var renderTimer = null;
var renderingDone = false;
var renderInterval = 0;
var resumeInterval = 500; // in ms
var canvas = document.createElement('canvas');
var ctx = canvas.getContext('2d');
// Render the text layer, one div at a time
function renderTextLayer() {
if (textDivs.length === 0) {
clearInterval(renderTimer);
renderingDone = true;
self.textLayerDiv = textLayerDiv = canvas = ctx = null;
return;
}
// No point in rendering so many divs as it'd make the browser unusable
// even after the divs are rendered
if (textDivs.length > 100000)
return;
while (textDivs.length > 0) {
var textDiv = textDivs.shift();
if (textDiv.dataset.textLength > 0) {
textLayerDiv.appendChild(textDiv);
textLayerFrag.appendChild(textDiv);
if (textDiv.dataset.textLength > 1) { // avoid div by zero
// Adjust div width to match canvas text
ctx.font = textDiv.style.fontSize + ' ' + textDiv.style.fontFamily;
var width = ctx.measureText(textDiv.textContent).width;
ctx.font = textDiv.style.fontSize + ' sans-serif';
var width = ctx.measureText(textDiv.textContent).width;
if (width > 0) {
var textScale = textDiv.dataset.canvasWidth / width;
var textScale = textDiv.dataset.canvasWidth / width;
CustomStyle.setProp('transform' , textDiv,
'scale(' + textScale + ', 1)');
CustomStyle.setProp('transformOrigin' , textDiv, '0% 0%');
}
} // textLength > 0
}
renderTimer = setInterval(renderTextLayer, renderInterval);
// Stop rendering when user scrolls. Resume after XXX milliseconds
// of no scroll events
var scrollTimer = null;
function textLayerOnScroll() {
if (renderingDone) {
window.removeEventListener('scroll', textLayerOnScroll, false);
return;
CustomStyle.setProp('transform' , textDiv,
'scale(' + textScale + ', 1)');
CustomStyle.setProp('transformOrigin' , textDiv, '0% 0%');
}
}
// Immediately pause rendering
clearInterval(renderTimer);
textLayerDiv.appendChild(textLayerFrag);
};
clearTimeout(scrollTimer);
scrollTimer = setTimeout(function textLayerScrollTimer() {
// Resume rendering
renderTimer = setInterval(renderTextLayer, renderInterval);
}, resumeInterval);
} // textLayerOnScroll
this.setupRenderLayoutTimer = function textLayerSetupRenderLayoutTimer() {
// Schedule renderLayout() if user has been scrolling, otherwise
// run it right away
var kRenderDelay = 200; // in ms
var self = this;
if (Date.now() - PDFView.lastScroll > kRenderDelay) {
// Render right away
this.renderLayer();
} else {
// Schedule
if (this.renderTimer)
clearTimeout(this.renderTimer);
this.renderTimer = setTimeout(function() {
self.setupRenderLayoutTimer();
}, kRenderDelay);
}
};
window.addEventListener('scroll', textLayerOnScroll, false);
}; // endLayout
this.appendText = function textLayerBuilderAppendText(text,
fontName, fontSize) {
this.appendText = function textLayerBuilderAppendText(fontName, fontSize,
geom) {
var textDiv = document.createElement('div');
// vScale and hScale already contain the scaling to pixel units
var fontHeight = fontSize * text.geom.vScale;
textDiv.dataset.canvasWidth = text.canvasWidth * text.geom.hScale;
var fontHeight = fontSize * geom.vScale;
textDiv.dataset.canvasWidth = geom.canvasWidth * geom.hScale;
textDiv.dataset.fontName = fontName;
textDiv.style.fontSize = fontHeight + 'px';
textDiv.style.left = text.geom.x + 'px';
textDiv.style.top = (text.geom.y - fontHeight) + 'px';
textDiv.textContent = PDFJS.bidi(text, -1);
textDiv.dir = text.direction;
textDiv.dataset.textLength = text.length;
textDiv.style.fontFamily = fontName;
textDiv.style.left = geom.x + 'px';
textDiv.style.top = (geom.y - fontHeight) + 'px';
// The content of the div is set in the `setTextContent` function.
this.textDivs.push(textDiv);
};
this.insertDivContent = function textLayerUpdateTextContent() {
// Only set the content of the divs once layout has finished, the content
// for the divs is available and content is not yet set on the divs.
if (!this.layoutDone || this.divContentDone || !this.textContent)
return;
this.divContentDone = true;
var textDivs = this.textDivs;
var bidiTexts = this.textContent.bidiTexts;
for (var i = 0; i < bidiTexts.length; i++) {
var bidiText = bidiTexts[i];
var textDiv = textDivs[i];
textDiv.textContent = bidiText.str;
textDiv.dir = bidiText.ltr ? 'ltr' : 'rtl';
}
this.setupRenderLayoutTimer();
};
this.setTextContent = function textLayerBuilderSetTextContent(textContent) {
this.textContent = textContent;
this.insertDivContent();
};
};
document.addEventListener('DOMContentLoaded', function webViewerLoad(evt) {
@ -2059,7 +2098,7 @@ document.addEventListener('DOMContentLoaded', function webViewerLoad(evt) {
});
document.getElementById('searchTermsInput').addEventListener('keydown',
function() {
function(event) {
if (event.keyCode == 13) {
PDFView.search();
}
@ -2282,6 +2321,7 @@ window.addEventListener('keydown', function keydown(evt) {
PDFView.zoomIn();
handled = true;
break;
case 173: // FF/Mac '-'
case 109: // FF '-'
case 189: // Chrome '-'
PDFView.zoomOut();
@ -2362,7 +2402,7 @@ window.addEventListener('afterprint', function afterPrint(evt) {
(function fullscreenClosure() {
function fullscreenChange(e) {
var isFullscreen = document.fullscreen || document.mozFullScreen ||
var isFullscreen = document.fullscreenElement || document.mozFullScreen ||
document.webkitIsFullScreen;
if (!isFullscreen) {

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

@ -398,17 +398,18 @@ social.error.closeSidebar.accesskey=C
# Identity notifications popups
identity.termsOfService = Terms of Service
identity.privacyPolicy = Privacy Policy
# LOCALIZATION NOTE (identity.chooseIdentity.description): %S is the website origin (e.g. https://www.mozilla.org) shown in popup notifications.
identity.chooseIdentity.description = Sign in to %S
identity.chooseIdentity.label = Use an existing email
identity.newIdentity.label = Use a different email
identity.newIdentity.accessKey = e
identity.newIdentity.email.placeholder = Email
# LOCALIZATION NOTE (identity.newIdentity.description, identity.chooseIdentity.description): %S is the website origin (ie. https://www.mozilla.org) shown in popup notifications.
# LOCALIZATION NOTE (identity.newIdentity.description): %S is the website origin (e.g. https://www.mozilla.org) shown in popup notifications.
identity.newIdentity.description = Enter your email address to sign in to %S
identity.next.label = Next
identity.next.accessKey = n
# LOCALIZATION NOTE: shown in the popup notification when a user successfully logs into a website
# LOCALIZATION NOTE (identity.loggedIn.description): %S is the website origin (ie. https://www.mozilla.org)
# LOCALIZATION NOTE (identity.loggedIn.description): %S is the user's identity (e.g. user@example.com)
identity.loggedIn.description = Signed in as: %S
identity.loggedIn.signOut.label = Sign Out
identity.loggedIn.signOut.accessKey = O

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

@ -18,8 +18,8 @@ zoom_in_label=Zoom In
zoom.title=Zoom
print.title=Print
print_label=Print
fullscreen.title=Fullscreen
fullscreen_label=Fullscreen
presentation_mode.title=Switch to Presentation Mode
presentation_mode_label=Presentation Mode
open_file.title=Open File
open_file_label=Open
download.title=Download
@ -51,8 +51,8 @@ thumb_page_title=Page {{page}}
thumb_page_canvas=Thumbnail of Page {{page}}
# Context menu
page_rotate_cw=Rotate Clockwise
page_rotate_ccw=Rotate Counter-Clockwise
page_rotate_cw.label=Rotate Clockwise
page_rotate_ccw.label=Rotate Counter-Clockwise
# Search panel button title and messages
search=Find

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

@ -2702,7 +2702,6 @@ html|*#gcli-output-frame {
height: 32px;
border-radius: 2px;
margin: 10px;
list-style-image: url("chrome://browser/skin/social/social.png");
}
#social-statusarea-username {
@ -2713,6 +2712,7 @@ html|*#gcli-output-frame {
cursor: pointer;
min-width: 0;
margin: 0 6px;
list-style-image: none;
}
#social-statusarea-username:hover {
text-decoration: underline;
@ -2766,6 +2766,7 @@ html|*#gcli-output-frame {
width: 100%;
margin: 0;
padding: 2px;
-moz-padding-start: 6px;
border: none;
border-bottom: 1px solid gray;
cursor: pointer;

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

@ -3382,7 +3382,6 @@ html|*#gcli-output-frame {
width: 32px;
height: 32px;
margin: 10px;
list-style-image: url("chrome://browser/skin/social/social.png");
}
#social-statusarea-username {
@ -3391,6 +3390,7 @@ html|*#gcli-output-frame {
cursor: pointer;
min-width: 0;
margin: 0 6px;
list-style-image: none;
}
#social-statusarea-username:hover {
@ -3452,6 +3452,7 @@ html|*#gcli-output-frame {
width: 100%;
margin: 0;
padding: 2px;
-moz-padding-start: 6px;
border: none;
border-bottom: 1px solid #404040;
cursor: pointer;

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

@ -83,7 +83,6 @@ browser.jar:
skin/classic/browser/places/minus-active.png (places/minus-active.png)
skin/classic/browser/places/plus.png (places/plus.png)
skin/classic/browser/places/plus-active.png (places/plus-active.png)
skin/classic/browser/places/starPage.png (places/starPage.png)
skin/classic/browser/places/starred48.png (places/starred48.png)
skin/classic/browser/places/unstarred48.png (places/unstarred48.png)
skin/classic/browser/places/unfiledBookmarks.png (places/unfiledBookmarks.png)

Двоичные данные
browser/themes/pinstripe/places/starPage.png

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 653 B

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

@ -3401,7 +3401,6 @@ html|*#gcli-output-frame {
height: 32px;
border-radius: 2px;
margin: 10px;
list-style-image: url("chrome://browser/skin/social/social.png");
}
#social-statusarea-username {
@ -3412,6 +3411,7 @@ html|*#gcli-output-frame {
cursor: pointer;
min-width: 0;
margin: 0 6px;
list-style-image: none;
}
#social-statusarea-username:hover {
text-decoration: underline;
@ -3470,6 +3470,7 @@ html|*#gcli-output-frame {
width: 100%;
margin: 0;
padding: 2px;
-moz-padding-start: 6px;
border: none;
border-bottom: 1px solid gray;
cursor: pointer;

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

@ -29,6 +29,12 @@ _DEFAULT_HTTP_PORT = 8888
_DEFAULT_SSL_PORT = 4443
_DEFAULT_WEBSOCKET_PORT = 9988
# from nsIPrincipal.idl
_APP_STATUS_NOT_INSTALLED = 0
_APP_STATUS_INSTALLED = 1
_APP_STATUS_PRIVILEGED = 2
_APP_STATUS_CERTIFIED = 3
#expand _DIST_BIN = __XPC_BIN_PATH__
#expand _IS_WIN32 = len("__WIN32__") != 0
#expand _IS_MAC = __IS_MAC__ != 0
@ -297,7 +303,8 @@ class Automation(object):
"receipt": null,
"installTime": 132333986000,
"manifestURL": "$manifestURL",
"localId": $localId
"localId": $localId,
"appStatus": $appStatus
}""")
manifestTemplate = Template("""{
@ -520,31 +527,50 @@ user_pref("camino.use_system_proxy_settings", false); // Camino-only, harmless t
'name': 'http_example_org',
'origin': 'http://example.org',
'manifestURL': 'http://example.org/manifest.webapp',
'description': 'http://example.org App'
'description': 'http://example.org App',
'appStatus': _APP_STATUS_INSTALLED
},
{
'name': 'https_example_com',
'origin': 'https://example.com',
'manifestURL': 'https://example.com/manifest.webapp',
'description': 'https://example.com App'
'description': 'https://example.com App',
'appStatus': _APP_STATUS_INSTALLED
},
{
'name': 'http_test1_example_org',
'origin': 'http://test1.example.org',
'manifestURL': 'http://test1.example.org/manifest.webapp',
'description': 'http://test1.example.org App'
'description': 'http://test1.example.org App',
'appStatus': _APP_STATUS_INSTALLED
},
{
'name': 'http_test1_example_org_8000',
'origin': 'http://test1.example.org:8000',
'manifestURL': 'http://test1.example.org:8000/manifest.webapp',
'description': 'http://test1.example.org:8000 App'
'description': 'http://test1.example.org:8000 App',
'appStatus': _APP_STATUS_INSTALLED
},
{
'name': 'http_sub1_test1_example_org',
'origin': 'http://sub1.test1.example.org',
'manifestURL': 'http://sub1.test1.example.org/manifest.webapp',
'description': 'http://sub1.test1.example.org App'
'description': 'http://sub1.test1.example.org App',
'appStatus': _APP_STATUS_INSTALLED
},
{
'name': 'https_example_com_privileged',
'origin': 'https://example.com',
'manifestURL': 'https://example.com/manifest_priv.webapp',
'description': 'https://example.com Privileged App',
'appStatus': _APP_STATUS_PRIVILEGED
},
{
'name': 'https_example_com_certified',
'origin': 'https://example.com',
'manifestURL': 'https://example.com/manifest_cert.webapp',
'description': 'https://example.com Certified App',
'appStatus': _APP_STATUS_CERTIFIED
},
];
self.setupTestApps(profileDir, apps)

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

@ -46,7 +46,5 @@ if __name__ == '__main__':
url = "http://localhost:%d/bloatcycle.html" % PORT
appPath = os.path.join(SCRIPT_DIR, automation.DEFAULT_APP)
status = automation.runApp(url, browserEnv, appPath, PROFILE_DIRECTORY,
# leaktest builds are slow, give up and
# don't use a timeout.
extraArgs, timeout=None)
extraArgs, timeout=1800)
sys.exit(status)

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

@ -21,7 +21,7 @@ interface nsIContentSecurityPolicy;
[ptr] native JSPrincipals(JSPrincipals);
[ptr] native PrincipalArray(nsTArray<nsCOMPtr<nsIPrincipal> >);
[scriptable, uuid(825ffce8-962d-11e1-aef3-8f2b6188709b)]
[scriptable, uuid(115d1081-373e-4837-8d12-d0f4874f3467)]
interface nsIPrincipal : nsISerializable
{
/**
@ -273,6 +273,13 @@ interface nsIPrincipal : nsISerializable
* Returns true iif the principal is inside a browser element.
*/
readonly attribute boolean isInBrowserElement;
/**
* Returns true if this principal has an unknown appId. This shouldn't
* generally be used. We only expose it due to not providing the correct
* appId everywhere where we construct principals.
*/
readonly attribute boolean unknownAppId;
};
/**

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

@ -131,6 +131,7 @@ public:
NS_IMETHOD GetAppStatus(uint16_t* aAppStatus);
NS_IMETHOD GetAppId(uint32_t* aAppStatus);
NS_IMETHOD GetIsInBrowserElement(bool* aIsInBrowserElement);
NS_IMETHOD GetUnknownAppId(bool* aUnknownAppId);
#ifdef DEBUG
virtual void dumpImpl();
#endif
@ -227,6 +228,7 @@ public:
NS_IMETHOD GetAppStatus(uint16_t* aAppStatus);
NS_IMETHOD GetAppId(uint32_t* aAppStatus);
NS_IMETHOD GetIsInBrowserElement(bool* aIsInBrowserElement);
NS_IMETHOD GetUnknownAppId(bool* aUnknownAppId);
#ifdef DEBUG
virtual void dumpImpl();
#endif

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

@ -360,6 +360,13 @@ nsNullPrincipal::GetIsInBrowserElement(bool* aIsInBrowserElement)
return NS_OK;
}
NS_IMETHODIMP
nsNullPrincipal::GetUnknownAppId(bool* aUnknownAppId)
{
*aUnknownAppId = false;
return NS_OK;
}
/**
* nsISerializable implementation
*/

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

@ -1111,6 +1111,13 @@ nsPrincipal::GetIsInBrowserElement(bool* aIsInBrowserElement)
return NS_OK;
}
NS_IMETHODIMP
nsPrincipal::GetUnknownAppId(bool* aUnknownAppId)
{
*aUnknownAppId = mAppId == nsIScriptSecurityManager::UNKNOWN_APP_ID;
return NS_OK;
}
NS_IMETHODIMP
nsPrincipal::Read(nsIObjectInputStream* aStream)
{
@ -1535,6 +1542,13 @@ nsExpandedPrincipal::GetIsInBrowserElement(bool* aIsInBrowserElement)
return NS_ERROR_NOT_AVAILABLE;
}
NS_IMETHODIMP
nsExpandedPrincipal::GetUnknownAppId(bool* aUnknownAppId)
{
*aUnknownAppId = false;
return NS_OK;
}
void
nsExpandedPrincipal::GetScriptLocation(nsACString& aStr)
{

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

@ -61,6 +61,10 @@
#include "mozilla/StandardInteger.h"
#include "mozilla/ClearOnShutdown.h"
#include "mozilla/StaticPtr.h"
#include "nsContentUtils.h"
// This should be probably defined on some other place... but I couldn't find it
#define WEBAPPS_PERM_NAME "webapps-manage"
using namespace mozilla;
using namespace mozilla::dom;
@ -1403,7 +1407,25 @@ nsScriptSecurityManager::CheckLoadURIWithPrincipal(nsIPrincipal* aPrincipal,
nsCaseInsensitiveCStringComparator()))
{
// every scheme can access another URI from the same scheme,
// as long as they don't represent null principals.
// as long as they don't represent null principals...
// Or they don't require an special permission to do so
// See bug#773886
bool hasFlags;
rv = NS_URIChainHasFlags(targetBaseURI,
nsIProtocolHandler::URI_CROSS_ORIGIN_NEEDS_WEBAPPS_PERM,
&hasFlags);
NS_ENSURE_SUCCESS(rv, rv);
if (hasFlags) {
// In this case, we allow opening only if the source and target URIS
// are on the same domain, or the opening URI has the webapps
// permision granted
if (!SecurityCompareURIs(sourceBaseURI,targetBaseURI) &&
!nsContentUtils::IsExactSitePermAllow(aPrincipal,WEBAPPS_PERM_NAME)){
return NS_ERROR_DOM_BAD_URI;
}
}
return NS_OK;
}

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

@ -265,6 +265,13 @@ nsSystemPrincipal::GetIsInBrowserElement(bool* aIsInBrowserElement)
return NS_OK;
}
NS_IMETHODIMP
nsSystemPrincipal::GetUnknownAppId(bool* aUnknownAppId)
{
*aUnknownAppId = false;
return NS_OK;
}
//////////////////////////////////////////
// Methods implementing nsISerializable //
//////////////////////////////////////////

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

@ -2298,7 +2298,6 @@ ia64*-hpux*)
DSO_LDOPTS="$DSO_LDOPTS -MACHINE:X86"
fi
MOZ_CHECK_HEADERS(mmintrin.h)
AC_DEFINE(_X86_)
;;
x86_64-*)
@ -2977,11 +2976,6 @@ dnl Quota support
MOZ_CHECK_HEADERS(sys/quota.h sys/sysmacros.h)
MOZ_CHECK_HEADERS(linux/quota.h)
dnl Try for MMX support
dnl NB - later gcc versions require -mmmx for this header to be successfully
dnl included (or another option which implies it, such as -march=pentium-mmx)
MOZ_CHECK_HEADERS(mmintrin.h)
MOZ_CHECK_HEADERS(sys/types.h netinet/in.h byteswap.h)
dnl Check whether the compiler supports the new-style C++ standard

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

@ -570,6 +570,22 @@ public:
// system principal, and true for a null principal.
static bool IsSitePermDeny(nsIPrincipal* aPrincipal, const char* aType);
// Get a permission-manager setting for the given principal and type.
// If the pref doesn't exist or if it isn't ALLOW_ACTION, false is
// returned, otherwise true is returned. Always returns true for the
// system principal, and false for a null principal.
// This version checks the permission for an exact host match on
// the principal
static bool IsExactSitePermAllow(nsIPrincipal* aPrincipal, const char* aType);
// Get a permission-manager setting for the given principal and type.
// If the pref doesn't exist or if it isn't DENY_ACTION, false is
// returned, otherwise true is returned. Always returns false for the
// system principal, and true for a null principal.
// This version checks the permission for an exact host match on
// the principal
static bool IsExactSitePermDeny(nsIPrincipal* aPrincipal, const char* aType);
// Returns true if aDoc1 and aDoc2 have equal NodePrincipal()s.
static bool HaveEqualPrincipals(nsIDocument* aDoc1, nsIDocument* aDoc2);

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

@ -886,12 +886,8 @@ nsContentSink::SelectDocAppCache(nsIApplicationCache *aLoadApplicationCache,
"mDocument must implement nsIApplicationCacheContainer.");
if (aLoadApplicationCache) {
nsAutoCString groupID;
rv = aLoadApplicationCache->GetGroupID(groupID);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIURI> groupURI;
rv = NS_NewURI(getter_AddRefs(groupURI), groupID);
rv = aLoadApplicationCache->GetManifestURI(getter_AddRefs(groupURI));
NS_ENSURE_SUCCESS(rv, rv);
bool equal = false;
@ -975,11 +971,7 @@ nsContentSink::SelectDocAppCacheNoManifest(nsIApplicationCache *aLoadApplication
// Return the uri and invoke the update process for the selected
// application cache.
nsAutoCString groupID;
rv = aLoadApplicationCache->GetGroupID(groupID);
NS_ENSURE_SUCCESS(rv, rv);
rv = NS_NewURI(aManifestURI, groupID);
rv = aLoadApplicationCache->GetManifestURI(aManifestURI);
NS_ENSURE_SUCCESS(rv, rv);
*aAction = CACHE_SELECTION_UPDATE;

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

@ -2877,7 +2877,7 @@ nsContentUtils::IsDraggableLink(const nsIContent* aContent) {
}
static bool
TestSitePerm(nsIPrincipal* aPrincipal, const char* aType, uint32_t aPerm)
TestSitePerm(nsIPrincipal* aPrincipal, const char* aType, uint32_t aPerm, bool aExactHostMatch)
{
if (!aPrincipal) {
// We always deny (i.e. don't allow) the permission if we don't have a
@ -2890,7 +2890,12 @@ TestSitePerm(nsIPrincipal* aPrincipal, const char* aType, uint32_t aPerm)
NS_ENSURE_TRUE(permMgr, false);
uint32_t perm;
nsresult rv = permMgr->TestPermissionFromPrincipal(aPrincipal, aType, &perm);
nsresult rv;
if (aExactHostMatch) {
rv = permMgr->TestExactPermissionFromPrincipal(aPrincipal, aType, &perm);
} else {
rv = permMgr->TestPermissionFromPrincipal(aPrincipal, aType, &perm);
}
NS_ENSURE_SUCCESS(rv, false);
return perm == aPerm;
@ -2899,13 +2904,25 @@ TestSitePerm(nsIPrincipal* aPrincipal, const char* aType, uint32_t aPerm)
bool
nsContentUtils::IsSitePermAllow(nsIPrincipal* aPrincipal, const char* aType)
{
return TestSitePerm(aPrincipal, aType, nsIPermissionManager::ALLOW_ACTION);
return TestSitePerm(aPrincipal, aType, nsIPermissionManager::ALLOW_ACTION, false);
}
bool
nsContentUtils::IsSitePermDeny(nsIPrincipal* aPrincipal, const char* aType)
{
return TestSitePerm(aPrincipal, aType, nsIPermissionManager::DENY_ACTION);
return TestSitePerm(aPrincipal, aType, nsIPermissionManager::DENY_ACTION, false);
}
bool
nsContentUtils::IsExactSitePermAllow(nsIPrincipal* aPrincipal, const char* aType)
{
return TestSitePerm(aPrincipal, aType, nsIPermissionManager::ALLOW_ACTION, true);
}
bool
nsContentUtils::IsExactSitePermDeny(nsIPrincipal* aPrincipal, const char* aType)
{
return TestSitePerm(aPrincipal, aType, nsIPermissionManager::DENY_ACTION, true);
}
static const char *gEventNames[] = {"event"};

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

@ -2394,9 +2394,6 @@ nsDocument::StartDocumentLoad(const char* aCommand, nsIChannel* aChannel,
mMayStartLayout = false;
mHaveInputEncoding = true;
nsCOMPtr<nsIContentSecurityPolicy> csp;
nsresult rv = InitCSP(aChannel, getter_AddRefs(csp));
NS_ENSURE_SUCCESS(rv, rv);
if (aReset) {
Reset(aChannel, aLoadGroup);
@ -2426,30 +2423,27 @@ nsDocument::StartDocumentLoad(const char* aCommand, nsIChannel* aChannel,
NS_ENSURE_SUCCESS(rv, rv);
}
if (csp) {
// Copy into principal
nsIPrincipal* principal = GetPrincipal();
principal->SetCsp(csp);
#ifdef PR_LOGGING
PR_LOG(gCspPRLog, PR_LOG_DEBUG,
("Inserted CSP into principal %p", principal));
#endif
}
nsresult rv = InitCSP(aChannel);
NS_ENSURE_SUCCESS(rv, rv);
return NS_OK;
}
nsresult
nsDocument::InitCSP(nsIChannel* aChannel, nsIContentSecurityPolicy **aCSP)
nsDocument::InitCSP(nsIChannel* aChannel)
{
*aCSP = nullptr;
if (CSPService::sCSPEnabled) {
nsAutoCString tCspHeaderValue, tCspROHeaderValue;
nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(aChannel);
if (!httpChannel) {
// no CSP for non http channels
return NS_OK;
}
nsCOMPtr<nsIContentSecurityPolicy> csp;
if (!CSPService::sCSPEnabled) {
#ifdef PR_LOGGING
PR_LOG(gCspPRLog, PR_LOG_DEBUG,
("CSP is disabled, skipping CSP init for document %p", this));
#endif
return NS_OK;
}
nsAutoCString tCspHeaderValue, tCspROHeaderValue;
nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(aChannel);
if (httpChannel) {
httpChannel->GetResponseHeader(
NS_LITERAL_CSTRING("x-content-security-policy"),
tCspHeaderValue);
@ -2457,45 +2451,115 @@ nsDocument::InitCSP(nsIChannel* aChannel, nsIContentSecurityPolicy **aCSP)
httpChannel->GetResponseHeader(
NS_LITERAL_CSTRING("x-content-security-policy-report-only"),
tCspROHeaderValue);
NS_ConvertASCIItoUTF16 cspHeaderValue(tCspHeaderValue);
NS_ConvertASCIItoUTF16 cspROHeaderValue(tCspROHeaderValue);
if (cspHeaderValue.IsEmpty() && cspROHeaderValue.IsEmpty()) {
// no CSP header present, stop processing
return NS_OK;
}
}
NS_ConvertASCIItoUTF16 cspHeaderValue(tCspHeaderValue);
NS_ConvertASCIItoUTF16 cspROHeaderValue(tCspROHeaderValue);
// ----- Figure out if we need to apply an app default CSP
bool applyAppDefaultCSP = false;
nsIPrincipal* principal = NodePrincipal();
PRUint16 appStatus = nsIPrincipal::APP_STATUS_NOT_INSTALLED;
bool unknownAppId;
if (NS_SUCCEEDED(principal->GetUnknownAppId(&unknownAppId)) &&
!unknownAppId &&
NS_SUCCEEDED(principal->GetAppStatus(&appStatus))) {
applyAppDefaultCSP = ( appStatus == nsIPrincipal::APP_STATUS_PRIVILEGED ||
appStatus == nsIPrincipal::APP_STATUS_CERTIFIED);
}
#ifdef PR_LOGGING
PR_LOG(gCspPRLog, PR_LOG_DEBUG, ("CSP header specified for document %p", this));
else
PR_LOG(gCspPRLog, PR_LOG_DEBUG, ("Failed to get app status from principal"));
#endif
nsresult rv;
nsCOMPtr<nsIContentSecurityPolicy> csp;
csp = do_CreateInstance("@mozilla.org/contentsecuritypolicy;1", &rv);
if (NS_FAILED(rv)) {
// If there's no CSP to apply go ahead and return early
if (!applyAppDefaultCSP &&
cspHeaderValue.IsEmpty() &&
cspROHeaderValue.IsEmpty()) {
#ifdef PR_LOGGING
PR_LOG(gCspPRLog, PR_LOG_DEBUG, ("Failed to create CSP object: %x", rv));
#endif
return rv;
}
// Store the request context for violation reports
csp->ScanRequestData(httpChannel);
// Start parsing the policy
nsCOMPtr<nsIURI> chanURI;
aChannel->GetURI(getter_AddRefs(chanURI));
nsAutoCString aspec;
chanURI->GetAsciiSpec(aspec);
PR_LOG(gCspPRLog, PR_LOG_DEBUG,
("no CSP for document, %s, %s",
aspec.get(),
applyAppDefaultCSP ? "is app" : "not an app"));
#endif
return NS_OK;
}
#ifdef PR_LOGGING
PR_LOG(gCspPRLog, PR_LOG_DEBUG, ("CSP Loaded"));
PR_LOG(gCspPRLog, PR_LOG_DEBUG, ("Document is an app or CSP header specified %p", this));
#endif
// ReportOnly mode is enabled *only* if there are no regular-strength CSP
// headers present. If there are, then we ignore the ReportOnly mode and
// toss a warning into the error console, proceeding with enforcing the
// regular-strength CSP.
if (cspHeaderValue.IsEmpty()) {
nsresult rv;
csp = do_CreateInstance("@mozilla.org/contentsecuritypolicy;1", &rv);
if (NS_FAILED(rv)) {
#ifdef PR_LOGGING
PR_LOG(gCspPRLog, PR_LOG_DEBUG, ("Failed to create CSP object: %x", rv));
#endif
return rv;
}
// used as a "self" identifier for the CSP.
nsCOMPtr<nsIURI> chanURI;
aChannel->GetURI(getter_AddRefs(chanURI));
// Store the request context for violation reports
csp->ScanRequestData(httpChannel);
// ----- process the app default policy, if necessary
if (applyAppDefaultCSP) {
nsAdoptingString appCSP;
if (appStatus == nsIPrincipal::APP_STATUS_PRIVILEGED) {
appCSP = Preferences::GetString("security.apps.privileged.CSP.default");
NS_ASSERTION(appCSP, "App, but no default CSP in security.apps.privileged.CSP.default");
} else if (appStatus == nsIPrincipal::APP_STATUS_CERTIFIED) {
appCSP = Preferences::GetString("security.apps.certified.CSP.default");
NS_ASSERTION(appCSP, "App, but no default CSP in security.apps.certified.CSP.default");
}
if (appCSP)
csp->RefinePolicy(appCSP, chanURI);
}
// ----- if there's a full-strength CSP header, apply it.
if (!cspHeaderValue.IsEmpty()) {
// Need to tokenize the header value since multiple headers could be
// concatenated into one comma-separated list of policies.
// See RFC2616 section 4.2 (last paragraph)
nsCharSeparatedTokenizer tokenizer(cspHeaderValue, ',');
while (tokenizer.hasMoreTokens()) {
const nsSubstring& policy = tokenizer.nextToken();
csp->RefinePolicy(policy, chanURI);
#ifdef PR_LOGGING
{
PR_LOG(gCspPRLog, PR_LOG_DEBUG,
("CSP refined with policy: \"%s\"",
NS_ConvertUTF16toUTF8(policy).get()));
}
#endif
}
}
// ----- if there's a report-only CSP header, apply it
if (!cspROHeaderValue.IsEmpty()) {
// post a warning and skip report-only CSP when both read only and regular
// CSP policies are present since CSP only allows one policy and it can't
// be partially report-only.
if (applyAppDefaultCSP || !cspHeaderValue.IsEmpty()) {
nsContentUtils::ReportToConsole(nsIScriptError::warningFlag,
"CSP", this,
nsContentUtils::eDOM_PROPERTIES,
"ReportOnlyCSPIgnored");
#ifdef PR_LOGGING
PR_LOG(gCspPRLog, PR_LOG_DEBUG,
("Skipped report-only CSP init for document %p because another, enforced policy is set", this));
#endif
} else {
// we can apply the report-only policy because there's no other CSP
// applied.
csp->SetReportOnlyMode(true);
// Need to tokenize the header value since multiple headers could be
@ -2508,58 +2572,43 @@ nsDocument::InitCSP(nsIChannel* aChannel, nsIContentSecurityPolicy **aCSP)
#ifdef PR_LOGGING
{
PR_LOG(gCspPRLog, PR_LOG_DEBUG,
("CSP (report only) refined with policy: \"%s\"",
("CSP (report-only) refined with policy: \"%s\"",
NS_ConvertUTF16toUTF8(policy).get()));
}
#endif
}
} else {
//XXX(sstamm): maybe we should post a warning when both read only and regular
// CSP headers are present.
// Need to tokenize the header value since multiple headers could be
// concatenated into one comma-separated list of policies.
// See RFC2616 section 4.2 (last paragraph)
nsCharSeparatedTokenizer tokenizer(cspHeaderValue, ',');
while (tokenizer.hasMoreTokens()) {
const nsSubstring& policy = tokenizer.nextToken();
csp->RefinePolicy(policy, chanURI);
#ifdef PR_LOGGING
{
PR_LOG(gCspPRLog, PR_LOG_DEBUG,
("CSP refined with policy: \"%s\"",
NS_ConvertUTF16toUTF8(policy).get()));
}
#endif
}
}
// Check for frame-ancestor violation
nsCOMPtr<nsIDocShell> docShell = do_QueryReferent(mDocumentContainer);
if (docShell) {
bool safeAncestry = false;
// PermitsAncestry sends violation reports when necessary
rv = csp->PermitsAncestry(docShell, &safeAncestry);
NS_ENSURE_SUCCESS(rv, rv);
if (!safeAncestry) {
#ifdef PR_LOGGING
PR_LOG(gCspPRLog, PR_LOG_DEBUG,
("CSP doesn't like frame's ancestry, not loading."));
#endif
// stop! ERROR page!
aChannel->Cancel(NS_ERROR_CSP_FRAME_ANCESTOR_VIOLATION);
}
}
csp.forget(aCSP);
}
// ----- Enforce frame-ancestor policy on any applied policies
nsCOMPtr<nsIDocShell> docShell = do_QueryReferent(mDocumentContainer);
if (docShell) {
bool safeAncestry = false;
// PermitsAncestry sends violation reports when necessary
rv = csp->PermitsAncestry(docShell, &safeAncestry);
NS_ENSURE_SUCCESS(rv, rv);
if (!safeAncestry) {
#ifdef PR_LOGGING
PR_LOG(gCspPRLog, PR_LOG_DEBUG,
("CSP doesn't like frame's ancestry, not loading."));
#endif
// stop! ERROR page!
aChannel->Cancel(NS_ERROR_CSP_FRAME_ANCESTOR_VIOLATION);
}
}
if (csp) {
// Copy into principal
nsIPrincipal* principal = GetPrincipal();
principal->SetCsp(csp);
#ifdef PR_LOGGING
else { //CSP was not enabled!
PR_LOG(gCspPRLog, PR_LOG_DEBUG,
("CSP is disabled, skipping CSP init for document %p", this));
}
("Inserted CSP into principal %p", principal));
#endif
}
return NS_OK;
}

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

@ -1274,7 +1274,7 @@ private:
void DoUnblockOnload();
nsresult CheckFrameOptions();
nsresult InitCSP(nsIChannel* aChannel, nsIContentSecurityPolicy **aCSP);
nsresult InitCSP(nsIChannel* aChannel);
// Sets aElement to be the pending pointer lock element. Once this document's
// node principal's URI is granted the "fullscreen" permission, the pointer

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

@ -658,6 +658,7 @@ GK_ATOM(oncontextmenu, "oncontextmenu")
GK_ATOM(oncopy, "oncopy")
GK_ATOM(oncut, "oncut")
GK_ATOM(ondatachange, "ondatachange")
GK_ATOM(ondataerror, "ondataerror")
GK_ATOM(ondblclick, "ondblclick")
GK_ATOM(ondelivered, "ondelivered")
GK_ATOM(ondevicecreated, "ondevicecreated")

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

@ -195,6 +195,15 @@ nsMixedContentBlocker::ShouldProcess(PRUint32 aContentType,
nsIPrincipal* aRequestPrincipal,
PRInt16* aDecision)
{
if(!aContentLocation) {
// aContentLocation may be null when a plugin is loading without an associated URI resource
if(aContentType == TYPE_OBJECT) {
return NS_OK;
} else {
return NS_ERROR_FAILURE;
}
}
return ShouldLoad(aContentType, aContentLocation, aRequestingLocation,
aRequestingContext, aMimeGuess, aExtra, aRequestPrincipal,
aDecision);

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

@ -367,6 +367,8 @@ MOCHITEST_FILES_B = \
file_CSP_evalscript_main.html \
file_CSP_evalscript_main.html^headers^ \
file_CSP_evalscript_main.js \
file_csp_bug768029.html \
file_csp_bug768029.sjs \
test_bug540854.html \
bug540854.sjs \
test_bug548463.html \

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

@ -46,6 +46,7 @@ MOCHITEST_CHROME_FILES = \
test_bug682305.html \
test_bug780199.xul \
test_bug780529.xul \
test_csp_bug768029.html \
$(NULL)
include $(topsrcdir)/config/rules.mk

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

@ -0,0 +1,221 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=768029
-->
<head>
<meta charset="utf-8">
<title>Test for CSP on trusted/certified apps -- bug 768029</title>
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"/>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=768029">Mozilla Bug 768029</a>
<p id="display"></p>
<div id="content">
</div>
<pre id="test">
<script type="application/javascript;version=1.7">
Components.utils.import("resource://gre/modules/Services.jsm");
/** Test for Bug 768029 **/
// Note: we don't have to inspect all the different operations of CSP,
// we're just looking for specific differences in behavior that indicate
// a default CSP got applied.
const DEFAULT_CSP_PRIV = "default-src *; script-src 'self'; style-src 'self' 'unsafe-inline'; object-src 'none'";
const DEFAULT_CSP_CERT = "default-src *; script-src 'self'; style-src 'self'; object-src 'none'";
SimpleTest.waitForExplicitFinish();
var gData = [
{
app: "https://example.com/manifest.webapp",
appStatus: Components.interfaces.nsIPrincipal.APP_STATUS_INSTALLED,
origin: "https://example.com",
uri: "https://example.com/tests/content/base/test/file_csp_bug768029.html",
statusString: "installed app",
expectedTestResults: {
max_tests: 7, /* number of bools below plus one for the status check */
cross_origin: { img: true, script: true, style: true },
same_origin: { img: true, script: true, style: true },
},
},
{
app: "https://example.com/manifest_priv.webapp",
appStatus: Components.interfaces.nsIPrincipal.APP_STATUS_PRIVILEGED,
origin: "https://example.com",
uri: "https://example.com/tests/content/base/test/file_csp_bug768029.html",
statusString: "privileged app",
expectedTestResults: {
max_tests: 7, /* number of bools below plus one for the status check */
cross_origin: { img: true, script: false, style: false },
same_origin: { img: true, script: true, style: true },
},
},
{
app: "https://example.com/manifest_cert.webapp",
appStatus: Components.interfaces.nsIPrincipal.APP_STATUS_CERTIFIED,
origin: "https://example.com",
uri: "https://example.com/tests/content/base/test/file_csp_bug768029.html",
statusString: "certified app",
expectedTestResults: {
max_tests: 7, /* number of bools below plus one for the status check */
cross_origin: { img: true, script: false, style: false },
same_origin: { img: true, script: true, style: true },
},
},
];
// Observer for watching allowed loads and blocked attempts
function ThingyListener(app, iframe) {
Services.obs.addObserver(this, "csp-on-violate-policy", false);
Services.obs.addObserver(this, "http-on-modify-request", false);
dump("added observers\n");
// keep track of which app ID this test is monitoring.
this._testData = app;
this._expectedResults = app.expectedTestResults;
this._resultsRecorded = { cross_origin: {}, same_origin: {}};
this._iframe = iframe;
this._countedTests = 0;
}
ThingyListener.prototype = {
observe: function(subject, topic, data) {
// make sure to only observe app-generated calls to the helper for this test.
var testpat = new RegExp("file_csp_bug768029\\.sjs");
// used to extract which kind of load this is (img, script, etc).
var typepat = new RegExp("type=([\\_a-z0-9]+)");
// used to identify whether it's cross-origin or same-origin loads
// (the applied CSP allows same-origin loads).
var originpat = new RegExp("origin=([\\_a-z0-9]+)");
if (topic === "http-on-modify-request") {
// Matching requests on this topic were allowed by the csp
var chan = subject.QueryInterface(Components.interfaces.nsIHttpChannel);
var uri = chan.URI;
// ignore irrelevent URIs
if (!testpat.test(uri.asciiSpec)) return;
var loadType = typepat.exec(uri.asciiSpec)[1];
var originType = originpat.exec(uri.asciiSpec)[1];
// skip duplicate hits to this topic (potentially document loads
// may generate duplicate loads.
if (this._resultsRecorded[originType] &&
this._resultsRecorded[originType][loadType]) {
return;
}
var message = originType + " : " + loadType + " should be " +
(this._expectedResults[originType][loadType] ? "allowed" : "blocked");
ok(this._expectedResults[originType][loadType] == true, message);
this._resultsRecorded[originType][loadType] = true;
this._countedTests++;
}
else if (topic === "csp-on-violate-policy") {
// Matching hits on this topic were blocked by the csp
var uri = subject.QueryInterface(Components.interfaces.nsIURI);
// ignore irrelevent URIs
if (!testpat.test(uri.asciiSpec)) return;
var loadType = typepat.exec(uri.asciiSpec)[1];
var originType = originpat.exec(uri.asciiSpec)[1];
// skip duplicate hits to this topic (potentially document loads
// may generate duplicate loads.
if (this._resultsRecorded[originType] &&
this._resultsRecorded[originType][loadType]) {
return;
}
var message = originType + " : " + loadType + " should be " +
(this._expectedResults[originType][loadType] ? "allowed" : "blocked");
ok(this._expectedResults[originType][loadType] == false, message);
this._resultsRecorded[originType][loadType] = true;
this._countedTests++;
}
else {
// wrong topic! Nothing to do.
return;
}
this._checkForFinish();
},
_checkForFinish: function() {
// check to see if there are load tests still pending.
// (All requests triggered by the app should hit one of the
// two observer topics.)
if (this._countedTests == this._expectedResults.max_tests) {
Services.obs.removeObserver(this, "csp-on-violate-policy");
Services.obs.removeObserver(this, "http-on-modify-request");
dump("removed observers\n");
checkedCount++;
if (checkedCount == checksTodo) {
SpecialPowers.removePermission("browser", "https://example.com");
SimpleTest.finish();
} else {
gTestRunner.next();
}
}
},
// verify the status of the app
checkAppStatus: function() {
var principal = this._iframe.contentDocument.nodePrincipal;
if (this._testData.app) {
is(principal.appStatus, this._testData.appStatus,
"iframe principal's app status doesn't match the expected app status.");
this._countedTests++;
this._checkForFinish();
}
}
}
var content = document.getElementById('content');
var checkedCount = 0; // number of apps checked
var checksTodo = gData.length;
// quick check to make sure we can test apps:
is('appStatus' in document.nodePrincipal, true,
'appStatus should be present in nsIPrincipal, if not the rest of this test will fail');
function runTest() {
for (var i = 0; i < gData.length; i++) {
let data = gData[i];
var iframe = document.createElement('iframe');
// watch for successes and failures
var examiner = new ThingyListener(data, iframe);
iframe.setAttribute('mozapp', data.app);
iframe.setAttribute('mozbrowser', 'true');
iframe.addEventListener('load', examiner.checkAppStatus.bind(examiner));
iframe.src = data.uri;
content.appendChild(iframe);
yield;
}
}
var gTestRunner = runTest();
// load the default CSP and pref it on
SpecialPowers.addPermission("browser", true, "https://example.com");
SpecialPowers.pushPrefEnv({'set': [["dom.mozBrowserFramesEnabled", true],
["security.apps.privileged.CSP.default", DEFAULT_CSP_PRIV],
["security.apps.certified.CSP.default", DEFAULT_CSP_CERT]]},
function() { gTestRunner.next(); });
</script>
</pre>
</body>
</html>

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

@ -0,0 +1,25 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=768029
-->
<head>
<meta charset="utf-8">
<title>This is an app for testing</title>
<link rel="stylesheet" type="text/css"
href="file_csp_bug768029.sjs?type=style&origin=same_origin" />
<link rel="stylesheet" type="text/css"
href="http://example.com/tests/content/base/test/file_csp_bug768029.sjs?type=style&origin=cross_origin" />
</head>
<body>
<script src="file_csp_bug768029.sjs?type=script&origin=same_origin"></script>
<script src="http://example.com/tests/content/base/test/file_csp_bug768029.sjs?type=script&origin=cross_origin"></script>
<img src="file_csp_bug768029.sjs?type=img&origin=same_origin" />
<img src="http://example.com/tests/content/base/test/file_csp_bug768029.sjs?type=img&origin=cross_origin" />
Test for CSP applied to (simulated) app.
</body>
</html>

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

@ -0,0 +1,29 @@
function handleRequest(request, response) {
var query = {};
request.queryString.split('&').forEach(function(val) {
var [name, value] = val.split('=');
query[name] = unescape(value);
});
response.setHeader("Cache-Control", "no-cache", false);
if ("type" in query) {
switch (query.type) {
case "script":
response.setHeader("Content-Type", "application/javascript");
response.write("\n\ndocument.write('<pre>script loaded\\n</pre>');\n\n");
return;
case "style":
response.setHeader("Content-Type", "text/css");
response.write("\n\n.cspfoo { color:red; }\n\n");
return;
case "img":
response.setHeader("Content-Type", "image/png");
return;
}
}
response.setHeader("Content-Type", "text/plain");
response.write("ohnoes!");
}

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

@ -0,0 +1,101 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* 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 "AudioBuffer.h"
#include "mozilla/dom/AudioBufferBinding.h"
#include "nsContentUtils.h"
#include "AudioContext.h"
#include "jsfriendapi.h"
#include "mozilla/ErrorResult.h"
namespace mozilla {
namespace dom {
NS_IMPL_CYCLE_COLLECTION_CLASS(AudioBuffer)
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(AudioBuffer)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mContext)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMARRAY(mChannels)
NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
NS_DROP_JS_OBJECTS(tmp, AudioBuffer);
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(AudioBuffer)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mContext)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(AudioBuffer)
NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER
for (uint32_t i = 0; i < tmp->mChannels.Length(); ++i) {
NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mChannels[i])
}
NS_IMPL_CYCLE_COLLECTION_TRACE_END
NS_IMPL_CYCLE_COLLECTING_ADDREF(AudioBuffer)
NS_IMPL_CYCLE_COLLECTING_RELEASE(AudioBuffer)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(AudioBuffer)
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_INTERFACE_MAP_END
AudioBuffer::AudioBuffer(AudioContext* aContext, uint32_t aLength,
uint32_t aSampleRate)
: mContext(aContext),
mLength(aLength),
mSampleRate(aSampleRate)
{
SetIsDOMBinding();
}
AudioBuffer::~AudioBuffer()
{
// Drop the JS object reference if we're still holding to the channels
if (mChannels.Length()) {
NS_DROP_JS_OBJECTS(this, AudioBuffer);
}
}
bool
AudioBuffer::InitializeBuffers(uint32_t aNumberOfChannels, JSContext* aJSContext)
{
if (!mChannels.SetCapacity(aNumberOfChannels)) {
return false;
}
for (uint32_t i = 0; i < aNumberOfChannels; ++i) {
JSObject* array = JS_NewFloat32Array(aJSContext, mLength);
if (!array) {
return false;
}
mChannels.AppendElement(array);
}
NS_HOLD_JS_OBJECTS(this, AudioBuffer);
return true;
}
JSObject*
AudioBuffer::WrapObject(JSContext* aCx, JSObject* aScope,
bool* aTriedToWrap)
{
return AudioBufferBinding::Wrap(aCx, aScope, this, aTriedToWrap);
}
JSObject*
AudioBuffer::GetChannelData(JSContext* aJSContext, uint32_t aChannel,
ErrorResult& aRv) const
{
if (aChannel >= mChannels.Length()) {
aRv.Throw(NS_ERROR_DOM_SYNTAX_ERR);
return nullptr;
}
return mChannels[aChannel];
}
}
}

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

@ -0,0 +1,83 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* 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/. */
#pragma once
#include "nsWrapperCache.h"
#include "nsCycleCollectionParticipant.h"
#include "mozilla/Attributes.h"
#include "EnableWebAudioCheck.h"
#include "nsAutoPtr.h"
#include "nsTArray.h"
#include "AudioContext.h"
struct JSContext;
struct JSObject;
namespace mozilla {
class ErrorResult;
namespace dom {
class AudioBuffer MOZ_FINAL : public nsISupports,
public nsWrapperCache,
public EnableWebAudioCheck
{
public:
AudioBuffer(AudioContext* aContext, uint32_t aLength,
uint32_t aSampleRate);
~AudioBuffer();
// This function needs to be called in order to allocate
// all of the channels. It is fallible!
bool InitializeBuffers(uint32_t aNumberOfChannels,
JSContext* aJSContext);
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(AudioBuffer)
AudioContext* GetParentObject() const
{
return mContext;
}
virtual JSObject* WrapObject(JSContext* aCx, JSObject* aScope,
bool* aTriedToWrap);
float SampleRate() const
{
return mSampleRate;
}
uint32_t Length() const
{
return mLength;
}
float Duration() const
{
return mLength / mSampleRate;
}
uint32_t NumberOfChannels() const
{
return mChannels.Length();
}
JSObject* GetChannelData(JSContext* aJSContext, uint32_t aChannel,
ErrorResult& aRv) const;
private:
nsRefPtr<AudioContext> mContext;
FallibleTArray<JSObject*> mChannels;
uint32_t mLength;
float mSampleRate;
};
}
}

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

@ -11,6 +11,7 @@
#include "mozilla/dom/AudioContextBinding.h"
#include "AudioDestinationNode.h"
#include "AudioBufferSourceNode.h"
#include "AudioBuffer.h"
namespace mozilla {
namespace dom {
@ -63,6 +64,19 @@ AudioContext::CreateBufferSource()
return bufferNode.forget();
}
already_AddRefed<AudioBuffer>
AudioContext::CreateBuffer(JSContext* aJSContext, uint32_t aNumberOfChannels,
uint32_t aLength, float aSampleRate,
ErrorResult& aRv)
{
nsRefPtr<AudioBuffer> buffer = new AudioBuffer(this, aLength, aSampleRate);
if (!buffer->InitializeBuffers(aNumberOfChannels, aJSContext)) {
aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
return nullptr;
}
return buffer.forget();
}
}
}

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

@ -24,6 +24,7 @@ namespace dom {
class AudioDestinationNode;
class AudioBufferSourceNode;
class AudioBuffer;
class AudioContext MOZ_FINAL : public nsISupports,
public nsWrapperCache,
@ -55,6 +56,11 @@ public:
already_AddRefed<AudioBufferSourceNode> CreateBufferSource();
already_AddRefed<AudioBuffer>
CreateBuffer(JSContext* aJSContext, uint32_t aNumberOfChannels,
uint32_t aLength, float aSampleRate,
ErrorResult& aRv);
private:
nsCOMPtr<nsIDOMWindow> mWindow;
nsRefPtr<AudioDestinationNode> mDestination;

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

@ -15,6 +15,7 @@ LIBRARY_NAME := gkconwebaudio_s
LIBXUL_LIBRARY := 1
CPPSRCS := \
AudioBuffer.cpp \
AudioBufferSourceNode.cpp \
AudioContext.cpp \
AudioDestinationNode.cpp \
@ -25,6 +26,7 @@ CPPSRCS := \
EXPORTS_NAMESPACES := mozilla/dom
EXPORTS_mozilla/dom := \
AudioBuffer.h \
AudioBufferSourceNode.h \
AudioDestinationNode.h \
AudioNode.h \

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

@ -11,6 +11,7 @@ relativesrcdir := @relativesrcdir@
include $(DEPTH)/config/autoconf.mk
MOCHITEST_FILES := \
test_AudioBuffer.html \
test_AudioContext.html \
$(NULL)

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

@ -0,0 +1,44 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Test whether we can create an AudioContext interface</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<pre id="test">
<script class="testbody" type="text/javascript">
SimpleTest.waitForExplicitFinish();
addLoadEvent(function() {
SpecialPowers.setBoolPref("media.webaudio.enabled", true);
var ac = new mozAudioContext();
var buffer = ac.createBuffer(2, 2048, 44100);
SpecialPowers.gc(); // Make sure that our channels are accessible after GC
ok(buffer, "Buffer was allocated successfully");
is(buffer.sampleRate, 44100, "Correct sample rate");
is(buffer.length, 2048, "Correct length");
ok(Math.abs(buffer.duration - 2048 / 44100) < 0.0001, "Correct duration");
is(buffer.numberOfChannels, 2, "Correct number of channels");
for (var i = 0; i < buffer.numberOfChannels; ++i) {
var buf = buffer.getChannelData(i);
ok(buf, "Buffer index " + i + " exists");
ok(buf instanceof Float32Array, "Result is a typed array");
is(buf.length, buffer.length, "Correct length");
var foundNonZero = false;
for (var j = 0; j < buf.length; ++j) {
if (buf[j] != 0) {
foundNonZero = true;
break;
}
}
ok(!foundNonZero, "Buffer " + i + " should be initialized to 0");
}
SpecialPowers.clearUserPref("media.webaudio.enabled");
SimpleTest.finish();
});
</script>
</pre>
</body>
</html>

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

@ -32,23 +32,22 @@
SimpleTest.is(getDocShellType(typeContentFrame), Ci.nsIDocShellTreeItem.typeContent,
"iframe with mozFrameType='content' in chrome document is typeContent");
// avoid closing the window from within the onload event handler to see
// whether that fixes the intermittent orange in bug 772823
SimpleTest.executeSoon(function () {
// Wait for the window to be closed before finishing the test
let ww = Components.classes["@mozilla.org/embedcomp/window-watcher;1"]
.getService(Components.interfaces.nsIWindowWatcher);
ww.registerNotification(function windowObs(subject, topic, data) {
if (topic == "domwindowclosed") {
ww.unregisterNotification(windowObs);
// Wait for the window to be closed before finishing the test
let ww = Components.classes["@mozilla.org/embedcomp/window-watcher;1"]
.getService(Components.interfaces.nsIWindowWatcher);
ww.registerNotification(function windowObs(subject, topic, data) {
if (topic == "domwindowclosed") {
ww.unregisterNotification(windowObs);
SimpleTest.executeSoon(function () {
SimpleTest.waitForFocus(function() {
SimpleTest.finish();
}, opener);
}
});
window.close();
});
}
});
window.close();
}
]]></script>
</window>

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

@ -505,6 +505,7 @@ using mozilla::dom::indexedDB::IDBWrapperCache;
#include "nsIDOMMobileConnection.h"
#endif
#include "USSDReceivedEvent.h"
#include "DataErrorEvent.h"
#include "mozilla/dom/network/Utils.h"
#ifdef MOZ_B2G_RIL
@ -1507,6 +1508,9 @@ static nsDOMClassInfoData sClassInfoData[] = {
NS_DEFINE_CLASSINFO_DATA(USSDReceivedEvent, nsDOMGenericSH,
DOM_DEFAULT_SCRIPTABLE_FLAGS)
NS_DEFINE_CLASSINFO_DATA(DataErrorEvent, nsDOMGenericSH,
DOM_DEFAULT_SCRIPTABLE_FLAGS)
NS_DEFINE_CLASSINFO_DATA(CSSFontFaceRule, nsDOMGenericSH,
DOM_DEFAULT_SCRIPTABLE_FLAGS)
NS_DEFINE_CLASSINFO_DATA(CSSFontFaceStyleDecl, nsCSSStyleDeclSH,
@ -4158,6 +4162,11 @@ nsDOMClassInfo::Init()
DOM_CLASSINFO_MAP_ENTRY(nsIDOMEvent)
DOM_CLASSINFO_MAP_END
DOM_CLASSINFO_MAP_BEGIN(DataErrorEvent, nsIDOMDataErrorEvent)
DOM_CLASSINFO_MAP_ENTRY(nsIDOMDataErrorEvent)
DOM_CLASSINFO_MAP_ENTRY(nsIDOMEvent)
DOM_CLASSINFO_MAP_END
DOM_CLASSINFO_MAP_BEGIN(CSSFontFaceRule, nsIDOMCSSFontFaceRule)
DOM_CLASSINFO_MAP_ENTRY(nsIDOMCSSFontFaceRule)
DOM_CLASSINFO_MAP_END

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

@ -413,6 +413,8 @@ DOMCI_CLASS(MozMobileConnection)
DOMCI_CLASS(USSDReceivedEvent)
DOMCI_CLASS(DataErrorEvent)
// @font-face in CSS
DOMCI_CLASS(CSSFontFaceRule)
DOMCI_CLASS(CSSFontFaceStyleDecl)

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

@ -66,8 +66,12 @@
DOMInterfaces = {
'AudioBuffer' : {
},
'mozAudioContext': {
'nativeType': 'AudioContext',
'implicitJSContext': [ 'createBuffer' ],
},
'AudioNode' : {

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

@ -6,6 +6,7 @@
#include "Skeleton.h"
#include "mozilla/dom/SkeletonBinding.h"
#include "nsContentUtils.h"
namespace mozilla {
namespace dom {

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

@ -61,6 +61,17 @@ BluetoothDevice::BluetoothDevice(nsPIDOMWindow* aOwner,
aValue.get_ArrayOfBluetoothNamedValue();
for (uint32_t i = 0; i < values.Length(); ++i) {
SetPropertyByValue(values[i]);
if (values[i].name().EqualsLiteral("Path")) {
// Since this is our signal handler string, set it as we set the property
// in the object. Odd place to do it, but makes more sense than in
// SetPropertyByValue.
BluetoothService* bs = BluetoothService::Get();
if (!bs) {
NS_WARNING("BluetoothService not available!");
} else {
bs->RegisterBluetoothSignalHandler(mPath, this);
}
}
}
}
@ -100,14 +111,8 @@ BluetoothDevice::SetPropertyByValue(const BluetoothNamedValue& aValue)
if (name.EqualsLiteral("Name")) {
mName = value.get_nsString();
} else if (name.EqualsLiteral("Path")) {
MOZ_ASSERT(value.get_nsString().Length() > 0);
mPath = value.get_nsString();
NS_WARNING(NS_ConvertUTF16toUTF8(mPath).get());
BluetoothService* bs = BluetoothService::Get();
if (!bs) {
NS_WARNING("BluetoothService not available!");
} else {
bs->RegisterBluetoothSignalHandler(mPath, this);
}
} else if (name.EqualsLiteral("Address")) {
mAddress = value.get_nsString();
} else if (name.EqualsLiteral("Class")) {

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

@ -65,11 +65,11 @@ NS_IMETHODIMP
BluetoothReplyRunnable::Run()
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(mDOMRequest);
MOZ_ASSERT(mReply);
nsresult rv;
MOZ_ASSERT(mDOMRequest);
if (mReply->type() != BluetoothReply::TBluetoothReplySuccess) {
rv = FireReply(JSVAL_VOID);
} else {

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

@ -20,6 +20,7 @@
#include "mozilla/Util.h"
#include "mozilla/dom/ContentParent.h"
#include "mozilla/dom/bluetooth/BluetoothTypes.h"
#include "mozilla/ipc/UnixSocket.h"
#include "nsContentUtils.h"
#include "nsIDOMDOMRequest.h"
#include "nsIObserverService.h"
@ -242,10 +243,9 @@ BluetoothService::Create()
return new BluetoothGonkService();
#elif defined(MOZ_BLUETOOTH_DBUS)
return new BluetoothDBusService();
#else
#endif
NS_WARNING("No platform support for bluetooth!");
return nullptr;
#endif
}
bool
@ -269,8 +269,6 @@ BluetoothService::Init()
return false;
}
RegisterBluetoothSignalHandler(NS_LITERAL_STRING(LOCAL_AGENT_PATH), this);
RegisterBluetoothSignalHandler(NS_LITERAL_STRING(REMOTE_AGENT_PATH), this);
mRegisteredForLocalAgent = true;
return true;
@ -360,16 +358,6 @@ BluetoothService::StartStopBluetooth(bool aStart)
{
MOZ_ASSERT(NS_IsMainThread());
#ifdef DEBUG
if (aStart && mLastRequestedEnable) {
MOZ_ASSERT(false, "Calling Start twice in a row!");
}
else if (!aStart && !mLastRequestedEnable) {
MOZ_ASSERT(false, "Calling Stop twice in a row!");
}
mLastRequestedEnable = aStart;
#endif
if (gInShutdown) {
if (aStart) {
// Don't try to start if we're already shutting down.
@ -394,6 +382,16 @@ BluetoothService::StartStopBluetooth(bool aStart)
NS_ENSURE_SUCCESS(rv, rv);
}
if (aStart) {
RegisterBluetoothSignalHandler(NS_LITERAL_STRING(LOCAL_AGENT_PATH), this);
RegisterBluetoothSignalHandler(NS_LITERAL_STRING(REMOTE_AGENT_PATH), this);
BluetoothManagerList::ForwardIterator iter(mLiveManagers);
while (iter.HasMore()) {
RegisterBluetoothSignalHandler(NS_LITERAL_STRING("/"), (BluetoothSignalObserver*)iter.GetNext());
}
}
nsCOMPtr<nsIRunnable> runnable = new ToggleBtTask(aStart);
rv = mBluetoothCommandThread->Dispatch(runnable, NS_DISPATCH_NORMAL);
NS_ENSURE_SUCCESS(rv, rv);
@ -697,7 +695,7 @@ SetJsObject(JSContext* aContext,
JSObject* aObj,
const InfallibleTArray<BluetoothNamedValue>& aData)
{
for (int i = 0; i < aData.Length(); i++) {
for (uint32_t i = 0; i < aData.Length(); i++) {
jsval v;
if (aData[i].value().type() == BluetoothValue::TnsString) {
nsString data = aData[i].value().get_nsString();

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

@ -14,6 +14,12 @@
#include "nsIThread.h"
#include "nsTObserverArray.h"
namespace mozilla {
namespace ipc {
class UnixSocketConsumer;
}
}
BEGIN_BLUETOOTH_NAMESPACE
class BluetoothManager;
@ -226,14 +232,12 @@ public:
virtual nsresult
GetSocketViaService(const nsAString& aObjectPath,
const nsAString& aService,
int aType,
BluetoothSocketType aType,
bool aAuth,
bool aEncrypt,
mozilla::ipc::UnixSocketConsumer* aSocketConsumer,
BluetoothReplyRunnable* aRunnable) = 0;
virtual bool
CloseSocket(int aFd, BluetoothReplyRunnable* aRunnable) = 0;
virtual bool
SetPinCodeInternal(const nsAString& aDeviceAddress, const nsAString& aPinCode,
BluetoothReplyRunnable* aRunnable) = 0;

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

@ -0,0 +1,175 @@
/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/*
* Copyright 2009, The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* NOTE: Due to being based on the dbus compatibility layer for
* android's bluetooth implementation, this file is licensed under the
* apache license instead of MPL.
*
*/
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/socket.h>
#include <bluetooth/bluetooth.h>
#include <bluetooth/sco.h>
#include <bluetooth/rfcomm.h>
#include <bluetooth/l2cap.h>
#include "BluetoothUnixSocketConnector.h"
#include "nsThreadUtils.h"
USING_BLUETOOTH_NAMESPACE
static const int RFCOMM_SO_SNDBUF = 70 * 1024; // 70 KB send buffer
static
int get_bdaddr(const char *str, bdaddr_t *ba)
{
char *d = ((char*)ba) + 5, *endp;
for (int i = 0; i < 6; i++) {
*d-- = strtol(str, &endp, 16);
MOZ_ASSERT(!(*endp != ':' && i != 5));
str = endp + 1;
}
return 0;
}
BluetoothUnixSocketConnector::BluetoothUnixSocketConnector(
BluetoothSocketType aType,
int aChannel,
bool aAuth,
bool aEncrypt) : mType(aType)
, mChannel(aChannel)
, mAuth(aAuth)
, mEncrypt(aEncrypt)
{
}
int
BluetoothUnixSocketConnector::Create()
{
MOZ_ASSERT(!NS_IsMainThread());
int lm = 0;
int fd = -1;
int sndbuf;
switch (mType) {
case BluetoothSocketType::RFCOMM:
fd = socket(PF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
break;
case BluetoothSocketType::SCO:
fd = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_SCO);
break;
case BluetoothSocketType::L2CAP:
fd = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP);
break;
default:
return -1;
}
if (fd < 0) {
NS_WARNING("Could not open bluetooth socket!");
return -1;
}
/* kernel does not yet support LM for SCO */
switch (mType) {
case BluetoothSocketType::RFCOMM:
lm |= mAuth ? RFCOMM_LM_AUTH : 0;
lm |= mEncrypt ? RFCOMM_LM_ENCRYPT : 0;
lm |= (mAuth && mEncrypt) ? RFCOMM_LM_SECURE : 0;
break;
case BluetoothSocketType::L2CAP:
lm |= mAuth ? L2CAP_LM_AUTH : 0;
lm |= mEncrypt ? L2CAP_LM_ENCRYPT : 0;
lm |= (mAuth && mEncrypt) ? L2CAP_LM_SECURE : 0;
break;
}
if (lm) {
if (setsockopt(fd, SOL_RFCOMM, RFCOMM_LM, &lm, sizeof(lm))) {
NS_WARNING("setsockopt(RFCOMM_LM) failed, throwing");
return -1;
}
}
if (mType == BluetoothSocketType::RFCOMM) {
sndbuf = RFCOMM_SO_SNDBUF;
if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &sndbuf, sizeof(sndbuf))) {
NS_WARNING("setsockopt(SO_SNDBUF) failed, throwing");
return -1;
}
}
return fd;
}
bool
BluetoothUnixSocketConnector::ConnectInternal(int aFd, const char* aAddress)
{
int n = 1;
setsockopt(aFd, SOL_SOCKET, SO_REUSEADDR, &n, sizeof(n));
socklen_t addr_sz;
struct sockaddr *addr;
bdaddr_t bd_address_obj;
if (get_bdaddr(aAddress, &bd_address_obj)) {
NS_WARNING("Can't get bluetooth address!");
return false;
}
switch (mType) {
case BluetoothSocketType::RFCOMM:
struct sockaddr_rc addr_rc;
addr = (struct sockaddr *)&addr_rc;
addr_sz = sizeof(addr_rc);
memset(addr, 0, addr_sz);
addr_rc.rc_family = AF_BLUETOOTH;
addr_rc.rc_channel = mChannel;
memcpy(&addr_rc.rc_bdaddr, &bd_address_obj, sizeof(bdaddr_t));
break;
case BluetoothSocketType::SCO:
struct sockaddr_sco addr_sco;
addr = (struct sockaddr *)&addr_sco;
addr_sz = sizeof(addr_sco);
memset(addr, 0, addr_sz);
addr_sco.sco_family = AF_BLUETOOTH;
memcpy(&addr_sco.sco_bdaddr, &bd_address_obj, sizeof(bdaddr_t));
break;
default:
NS_WARNING("Socket type unknown!");
return false;
}
int ret = connect(aFd, addr, addr_sz);
if (ret) {
#if DEBUG
//LOG("Socket connect errno=%d\n", errno);
#endif
NS_WARNING("Socket connect error!");
return false;
}
return true;
}

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

@ -0,0 +1,34 @@
/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/* 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/. */
#ifndef mozilla_dom_bluetooth_BluetoothUnixSocketConnector_h
#define mozilla_dom_bluetooth_BluetoothUnixSocketConnector_h
#include "BluetoothCommon.h"
#include <mozilla/ipc/UnixSocket.h>
BEGIN_BLUETOOTH_NAMESPACE
class BluetoothUnixSocketConnector : public mozilla::ipc::UnixSocketConnector
{
public:
BluetoothUnixSocketConnector(BluetoothSocketType aType, int aChannel,
bool aAuth, bool aEncrypt);
virtual ~BluetoothUnixSocketConnector()
{}
virtual int Create() MOZ_OVERRIDE;
virtual bool ConnectInternal(int aFd, const char* aAddress) MOZ_OVERRIDE;
private:
BluetoothSocketType mType;
int mChannel;
bool mAuth;
bool mEncrypt;
};
END_BLUETOOTH_NAMESPACE
#endif

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

@ -51,6 +51,7 @@ CPPSRCS += \
BluetoothChild.cpp \
BluetoothParent.cpp \
BluetoothServiceChildProcess.cpp \
BluetoothUnixSocketConnector.cpp \
$(NULL)
XPIDLSRCS = \

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

@ -203,23 +203,16 @@ BluetoothServiceChildProcess::RemoveDeviceInternal(
nsresult
BluetoothServiceChildProcess::GetSocketViaService(
const nsAString& aObjectPath,
const nsAString& aService,
int aType,
bool aAuth,
bool aEncrypt,
BluetoothReplyRunnable* aRunnable)
const nsAString& aObjectPath,
const nsAString& aService,
BluetoothSocketType aType,
bool aAuth,
bool aEncrypt,
mozilla::ipc::UnixSocketConsumer* aConsumer,
BluetoothReplyRunnable* aRunnable)
{
MOZ_NOT_REACHED("Implement me!");
return NS_ERROR_NOT_IMPLEMENTED;
}
bool
BluetoothServiceChildProcess::CloseSocket(int aFd,
BluetoothReplyRunnable* aRunnable)
{
MOZ_NOT_REACHED("Implement me!");
return false;
MOZ_NOT_REACHED("This should never be called!");
return NS_ERROR_FAILURE;
}
bool

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

@ -10,6 +10,9 @@
#include "BluetoothService.h"
namespace mozilla {
namespace ipc {
class UnixSocketConsumer;
}
namespace dom {
namespace bluetooth {
@ -86,14 +89,12 @@ public:
virtual nsresult
GetSocketViaService(const nsAString& aObjectPath,
const nsAString& aService,
int aType,
BluetoothSocketType aType,
bool aAuth,
bool aEncrypt,
mozilla::ipc::UnixSocketConsumer* aConsumer,
BluetoothReplyRunnable* aRunnable) MOZ_OVERRIDE;
virtual bool
CloseSocket(int aFd, BluetoothReplyRunnable* aRunnable) MOZ_OVERRIDE;
virtual bool
SetPinCodeInternal(const nsAString& aDeviceAddress,
const nsAString& aPinCode,
@ -108,7 +109,7 @@ public:
SetPairingConfirmationInternal(const nsAString& aDeviceAddress,
bool aConfirm,
BluetoothReplyRunnable* aRunnable)
MOZ_OVERRIDE;
MOZ_OVERRIDE;
virtual bool
SetAuthorizationInternal(const nsAString& aDeviceAddress,

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

@ -20,6 +20,7 @@
#include "BluetoothDBusService.h"
#include "BluetoothServiceUuid.h"
#include "BluetoothReplyRunnable.h"
#include "BluetoothUnixSocketConnector.h"
#include <cstdio>
#include <dbus/dbus.h>
@ -29,7 +30,7 @@
#include "nsThreadUtils.h"
#include "nsDebug.h"
#include "nsDataHashtable.h"
#include "mozilla/ipc/Socket.h"
#include "mozilla/ipc/UnixSocket.h"
#include "mozilla/ipc/DBusThread.h"
#include "mozilla/ipc/DBusUtils.h"
#include "mozilla/ipc/RawDBusConnection.h"
@ -1156,9 +1157,19 @@ EventFilter(DBusConnection* aConn, DBusMessage* aMsg, void* aData)
// a dict value. After we parse out the properties, we need to go back
// and add the address to the ipdl dict we've created to make sure we
// have all of the information to correctly build the device.
nsString addrstr = NS_ConvertUTF8toUTF16(addr);
nsString path = GetObjectPathFromAddress(signalPath, addrstr);
v.get_ArrayOfBluetoothNamedValue()
.AppendElement(BluetoothNamedValue(NS_LITERAL_STRING("Address"),
NS_ConvertUTF8toUTF16(addr)));
addrstr));
// We also need to create a path for the device, to make sure we know
// where to access it later.
v.get_ArrayOfBluetoothNamedValue()
.AppendElement(BluetoothNamedValue(NS_LITERAL_STRING("Path"),
path));
}
} else {
errorStr.AssignLiteral("DBus device found message structure not as expected!");
@ -1571,8 +1582,15 @@ public:
// for agent events "RequestConfirmation", "RequestPinCode", and "RequestPasskey"
InfallibleTArray<BluetoothNamedValue> parameters = v.get_ArrayOfBluetoothNamedValue();
// For consistency, append path
nsString path = parameters[0].value();
BluetoothNamedValue pathprop;
pathprop.name().AssignLiteral("Path");
pathprop.value() = path;
parameters.AppendElement(pathprop);
// Replace object path with device address
nsString address = GetAddressFromObjectPath(parameters[0].value());
nsString address = GetAddressFromObjectPath(path);
parameters[0].value() = address;
uint8_t i;
@ -1833,6 +1851,9 @@ GetDeviceServiceChannel(const nsAString& aObjectPath,
// This is a blocking call, should not be run on main thread.
MOZ_ASSERT(!NS_IsMainThread());
#ifdef MOZ_WIDGET_GONK
// GetServiceAttributeValue only exists in android's bluez dbus binding
// implementation
nsCString tempPattern = NS_ConvertUTF16toUTF8(aPattern);
const char* pattern = tempPattern.get();
@ -1845,6 +1866,11 @@ GetDeviceServiceChannel(const nsAString& aObjectPath,
DBUS_TYPE_INVALID);
return reply ? dbus_returns_int32(reply) : -1;
#else
// FIXME/Bug 793977 qdot: Just return something for desktop, until we have a
// parser for the GetServiceAttributes xml block
return 1;
#endif
}
// static
@ -2146,12 +2172,14 @@ class CreateBluetoothSocketRunnable : public nsRunnable
{
public:
CreateBluetoothSocketRunnable(BluetoothReplyRunnable* aRunnable,
UnixSocketConsumer* aConsumer,
const nsAString& aObjectPath,
const nsAString& aServiceUUID,
int aType,
BluetoothSocketType aType,
bool aAuth,
bool aEncrypt)
: mRunnable(dont_AddRef(aRunnable)),
mConsumer(aConsumer),
mObjectPath(aObjectPath),
mServiceUUID(aServiceUUID),
mType(aType),
@ -2168,18 +2196,16 @@ public:
nsString address = GetAddressFromObjectPath(mObjectPath);
int channel = GetDeviceServiceChannel(mObjectPath, mServiceUUID, 0x0004);
int fd = mozilla::ipc::GetNewSocket(mType, NS_ConvertUTF16toUTF8(address).get(),
channel, mAuth, mEncrypt);
BluetoothValue v;
nsString replyError;
if (fd < 0) {
BluetoothUnixSocketConnector c(mType, channel, mAuth, mEncrypt);
if (!mConsumer->ConnectSocket(c, NS_ConvertUTF16toUTF8(address).get())) {
replyError.AssignLiteral("SocketConnectionError");
DispatchBluetoothReply(mRunnable, v, replyError);
return NS_ERROR_FAILURE;
}
v = (uint32_t)fd;
// Bluetooth value needs to be set to something to succeed.
v = true;
DispatchBluetoothReply(mRunnable, v, replyError);
return NS_OK;
@ -2187,9 +2213,10 @@ public:
private:
nsRefPtr<BluetoothReplyRunnable> mRunnable;
nsRefPtr<UnixSocketConsumer> mConsumer;
nsString mObjectPath;
nsString mServiceUUID;
int mType;
BluetoothSocketType mType;
bool mAuth;
bool mEncrypt;
};
@ -2197,9 +2224,10 @@ private:
nsresult
BluetoothDBusService::GetSocketViaService(const nsAString& aObjectPath,
const nsAString& aService,
int aType,
BluetoothSocketType aType,
bool aAuth,
bool aEncrypt,
mozilla::ipc::UnixSocketConsumer* aConsumer,
BluetoothReplyRunnable* aRunnable)
{
NS_ASSERTION(NS_IsMainThread(), "Must be called from main thread!");
@ -2209,7 +2237,9 @@ BluetoothDBusService::GetSocketViaService(const nsAString& aObjectPath,
}
nsRefPtr<BluetoothReplyRunnable> runnable = aRunnable;
nsRefPtr<nsRunnable> func(new CreateBluetoothSocketRunnable(runnable, aObjectPath,
nsRefPtr<nsRunnable> func(new CreateBluetoothSocketRunnable(runnable,
aConsumer,
aObjectPath,
aService, aType,
aAuth, aEncrypt));
if (NS_FAILED(mBluetoothCommandThread->Dispatch(func, NS_DISPATCH_NORMAL))) {
@ -2221,53 +2251,3 @@ BluetoothDBusService::GetSocketViaService(const nsAString& aObjectPath,
return NS_OK;
}
class CloseBluetoothSocketRunnable : public nsRunnable
{
public:
CloseBluetoothSocketRunnable(BluetoothReplyRunnable* aRunnable,
int aFd)
: mRunnable(dont_AddRef(aRunnable)),
mFd(aFd)
{
}
nsresult
Run()
{
BluetoothValue v;
nsString replyError;
if (mozilla::ipc::CloseSocket(mFd) != 0) {
replyError.AssignLiteral("SocketConnectionError");
DispatchBluetoothReply(mRunnable, v, replyError);
return NS_ERROR_FAILURE;
}
DispatchBluetoothReply(mRunnable, v, replyError);
return NS_OK;
}
private:
nsRefPtr<BluetoothReplyRunnable> mRunnable;
int mFd;
};
bool
BluetoothDBusService::CloseSocket(int aFd, BluetoothReplyRunnable* aRunnable)
{
NS_ASSERTION(NS_IsMainThread(), "Must be called from main thread!");
if (!mConnection || !gThreadConnection) {
NS_ERROR("Bluetooth service not started yet!");
return false;
}
nsRefPtr<BluetoothReplyRunnable> runnable = aRunnable;
nsRefPtr<nsRunnable> func(new CloseBluetoothSocketRunnable(runnable, aFd));
if (NS_FAILED(mBluetoothCommandThread->Dispatch(func, NS_DISPATCH_NORMAL))) {
NS_WARNING("Cannot dispatch firmware loading task!");
return false;
}
runnable.forget();
return true;
}

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

@ -70,13 +70,12 @@ public:
virtual nsresult
GetSocketViaService(const nsAString& aObjectPath,
const nsAString& aService,
int aType,
BluetoothSocketType aType,
bool aAuth,
bool aEncrypt,
mozilla::ipc::UnixSocketConsumer* aConsumer,
BluetoothReplyRunnable* aRunnable);
virtual bool CloseSocket(int aFd, BluetoothReplyRunnable* aRunnable);
virtual nsresult
CreatePairedDeviceInternal(const nsAString& aAdapterPath,
const nsAString& aDeviceAddress,

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

@ -19,7 +19,7 @@ using namespace mozilla::services;
namespace mozilla {
bool
AppProcessHasPermission(PBrowserParent* aActor, const char* aPermission)
AssertAppProcessPermission(PBrowserParent* aActor, const char* aPermission)
{
if (!aActor) {
NS_WARNING("Testing permissions for null actor");
@ -46,12 +46,12 @@ AppProcessHasPermission(PBrowserParent* aActor, const char* aPermission)
}
bool
AppProcessHasPermission(PContentParent* aActor, const char* aPermission)
AssertAppProcessPermission(PContentParent* aActor, const char* aPermission)
{
const InfallibleTArray<PBrowserParent*>& browsers =
aActor->ManagedPBrowserParent();
for (uint32_t i = 0; i < browsers.Length(); ++i) {
if (AppProcessHasPermission(browsers[i], aPermission)) {
if (AssertAppProcessPermission(browsers[i], aPermission)) {
return true;
}
}
@ -59,9 +59,9 @@ AppProcessHasPermission(PContentParent* aActor, const char* aPermission)
}
bool
AppProcessHasPermission(PHalParent* aActor, const char* aPermission)
AssertAppProcessPermission(PHalParent* aActor, const char* aPermission)
{
return AppProcessHasPermission(aActor->Manager(), aPermission);
return AssertAppProcessPermission(aActor->Manager(), aPermission);
}
} // namespace mozilla

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

@ -5,8 +5,8 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef mozilla_Capabilities_h
#define mozilla_Capabilities_h
#ifndef mozilla_AppProcessPermissions_h
#define mozilla_AppProcessPermissions_h
namespace mozilla {
@ -21,31 +21,34 @@ class PHalParent;
/**
* Return true iff the specified browser has the specified capability.
* If this returns false, the browser didn't have the permission and
* will be killed.
*/
bool
AppProcessHasPermissions(mozilla::dom::PBrowserParent* aActor,
const char* aPermission);
AssertAppProcessPermission(mozilla::dom::PBrowserParent* aActor,
const char* aPermission);
/**
* Return true iff any of the PBrowsers loaded in this content process
* has the specified capability.
* has the specified capability. If this returns false, the process
* didn't have the permission and will be killed.
*/
bool
AppProcessHasPermission(mozilla::dom::PContentParent* aActor,
const char* aPermission);
AssertAppProcessPermission(mozilla::dom::PContentParent* aActor,
const char* aPermission);
bool
AppProcessHasPermission(mozilla::hal_sandbox::PHalParent* aActor,
const char* aPermission);
AssertAppProcessPermission(mozilla::hal_sandbox::PHalParent* aActor,
const char* aPermission);
// NB: when adding capability checks for other IPDL actors, please add
// them to this file and have them delegate to the two functions above
// as appropriate. For example,
//
// bool AppProcessHasCapability(PNeckoParent* aActor) {
// return AppProcessHasCapability(aActor->Manager());
// return AssertAppProcessPermission(aActor->Manager());
// }
} // namespace mozilla
#endif // mozilla_Capabilities_h
#endif // mozilla_AppProcessPermissions_h

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

@ -1450,7 +1450,7 @@ ContentParent::DeallocPExternalHelperApp(PExternalHelperAppParent* aService)
PSmsParent*
ContentParent::AllocPSms()
{
if (!AppProcessHasPermission(this, "sms")) {
if (!AssertAppProcessPermission(this, "sms")) {
return nullptr;
}
return new SmsParent();
@ -1480,7 +1480,7 @@ PBluetoothParent*
ContentParent::AllocPBluetooth()
{
#ifdef MOZ_B2G_BT
if (!AppProcessHasPermission(this, "bluetooth")) {
if (!AssertAppProcessPermission(this, "bluetooth")) {
return nullptr;
}
return new mozilla::dom::bluetooth::BluetoothParent();

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

@ -230,7 +230,8 @@ parent:
* has already been cached (stickDocument=false).
*/
POfflineCacheUpdate(URIParams manifestURI, URIParams documentURI,
nsCString clientID, bool stickDocument);
bool isInBrowserElement, uint32_t appId,
bool stickDocument);
sync PIndexedDB(nsCString asciiOrigin)
returns (bool allowed);

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

@ -1177,9 +1177,10 @@ TabChild::RecvActivateFrameEvent(const nsString& aType, const bool& capture)
POfflineCacheUpdateChild*
TabChild::AllocPOfflineCacheUpdate(const URIParams& manifestURI,
const URIParams& documentURI,
const nsCString& clientID,
const bool& stickDocument)
const URIParams& documentURI,
const bool& isInBrowserElement,
const uint32_t& appId,
const bool& stickDocument)
{
NS_RUNTIMEABORT("unused");
return nullptr;

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

@ -253,9 +253,11 @@ public:
virtual PContentPermissionRequestChild* AllocPContentPermissionRequest(const nsCString& aType, const IPC::Principal& aPrincipal);
virtual bool DeallocPContentPermissionRequest(PContentPermissionRequestChild* actor);
virtual POfflineCacheUpdateChild* AllocPOfflineCacheUpdate(const URIParams& manifestURI,
virtual POfflineCacheUpdateChild* AllocPOfflineCacheUpdate(
const URIParams& manifestURI,
const URIParams& documentURI,
const nsCString& clientID,
const bool& isInBrowserElement,
const uint32_t& appId,
const bool& stickDocument);
virtual bool DeallocPOfflineCacheUpdate(POfflineCacheUpdateChild* offlineCacheUpdate);

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

@ -1028,14 +1028,15 @@ TabParent::DeallocPRenderFrame(PRenderFrameParent* aFrame)
mozilla::docshell::POfflineCacheUpdateParent*
TabParent::AllocPOfflineCacheUpdate(const URIParams& aManifestURI,
const URIParams& aDocumentURI,
const nsCString& aClientID,
const bool& isInBrowserElement,
const uint32_t& appId,
const bool& stickDocument)
{
nsRefPtr<mozilla::docshell::OfflineCacheUpdateParent> update =
new mozilla::docshell::OfflineCacheUpdateParent();
nsresult rv = update->Schedule(aManifestURI, aDocumentURI, aClientID,
stickDocument);
nsresult rv = update->Schedule(aManifestURI, aDocumentURI,
isInBrowserElement, appId, stickDocument);
if (NS_FAILED(rv))
return nullptr;

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

@ -181,7 +181,8 @@ public:
virtual POfflineCacheUpdateParent* AllocPOfflineCacheUpdate(
const URIParams& aManifestURI,
const URIParams& aDocumentURI,
const nsCString& aClientID,
const bool& isInBrowserElement,
const uint32_t& appId,
const bool& stickDocument);
virtual bool DeallocPOfflineCacheUpdate(POfflineCacheUpdateParent* actor);

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

@ -105,6 +105,7 @@ FocusedWindowedPluginWhileFullScreen=Exited full-screen because windowed plugin
HTMLMultipartXHRWarning=HTML parsing in XMLHttpRequest is not supported for multipart responses.
HTMLSyncXHRWarning=HTML parsing in XMLHttpRequest is not supported in the synchronous mode.
InvalidRedirectChannelWarning=Unable to redirect to %S because the channel doesn't implement nsIWritablePropertyBag2.
ReportOnlyCSPIgnored=Report-only CSP policy will be ignored because there are other non-report-only CSP policies applied.
ResponseTypeSyncXHRWarning=Use of XMLHttpRequest's responseType attribute is no longer supported in the synchronous mode in window context.
WithCredentialsSyncXHRWarning=Use of XMLHttpRequest's withCredentials attribute is no longer supported in the synchronous mode in window context.
TimeoutSyncXHRWarning=Use of XMLHttpRequest's timeout attribute is not supported in the synchronous mode in window context.

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

@ -18,6 +18,7 @@ XPIDLSRCS = \
nsIDOMConnection.idl \
nsIDOMUSSDReceivedEvent.idl \
nsIDOMTCPSocket.idl \
nsIDOMDataErrorEvent.idl \
$(NULL)
ifdef MOZ_B2G_RIL

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

@ -0,0 +1,11 @@
/* 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 "nsIDOMEvent.idl"
[scriptable, builtinclass, uuid(1cfc45ba-c5d4-11e1-b4c3-00265511db39)]
interface nsIDOMDataErrorEvent : nsIDOMEvent
{
readonly attribute DOMString message;
};

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

@ -12,7 +12,7 @@ interface nsIDOMMozMobileNetworkInfo;
interface nsIDOMMozMobileCellInfo;
interface nsIDOMMozIccManager;
[scriptable, builtinclass, uuid(d9009d90-a4b3-44fd-a592-42b09f330fe5)]
[scriptable, builtinclass, uuid(c07309ee-a424-11e1-a75c-00265511db39)]
interface nsIDOMMozMobileConnection : nsIDOMEventTarget
{
/**
@ -239,6 +239,12 @@ interface nsIDOMMozMobileConnection : nsIDOMEventTarget
* received.
*/
[implicit_jscontext] attribute jsval onussdreceived;
/**
* The 'dataerror' event is notified whenever the data connection object
* receives an error from the RIL
*/
[implicit_jscontext] attribute jsval ondataerror;
};
[scriptable, uuid(5ea0e4a9-4684-40da-9930-8ebb61d187f3)]

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

@ -0,0 +1,43 @@
/* 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 "DataErrorEvent.h"
#include "nsIDOMClassInfo.h"
DOMCI_DATA(DataErrorEvent, mozilla::dom::network::DataErrorEvent)
namespace mozilla {
namespace dom {
namespace network {
already_AddRefed<DataErrorEvent>
DataErrorEvent::Create(nsAString& aMessage)
{
NS_ASSERTION(!aMessage.IsEmpty(), "Empty message!");
nsRefPtr<DataErrorEvent> event = new DataErrorEvent();
event->mMessage = aMessage;
return event.forget();
}
NS_IMPL_ADDREF_INHERITED(DataErrorEvent, nsDOMEvent)
NS_IMPL_RELEASE_INHERITED(DataErrorEvent, nsDOMEvent)
NS_INTERFACE_MAP_BEGIN(DataErrorEvent)
NS_INTERFACE_MAP_ENTRY(nsIDOMDataErrorEvent)
NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(DataErrorEvent)
NS_INTERFACE_MAP_END_INHERITING(nsDOMEvent)
NS_IMETHODIMP
DataErrorEvent::GetMessage(nsAString& aMessage)
{
aMessage.Assign(mMessage);
return NS_OK;
}
}
}
}

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

@ -0,0 +1,63 @@
/* 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/. */
#ifndef mozilla_dom_network_dataerrorevent_h
#define mozilla_dom_network_dataerrorevent_h
#include "nsIDOMDataErrorEvent.h"
#include "nsDOMEvent.h"
namespace mozilla {
namespace dom {
namespace network {
class DataErrorEvent : public nsDOMEvent,
public nsIDOMDataErrorEvent
{
nsString mMessage;
public:
NS_DECL_ISUPPORTS_INHERITED
NS_FORWARD_TO_NSDOMEVENT
NS_DECL_NSIDOMDATAERROREVENT
static already_AddRefed<DataErrorEvent>
Create(nsAString& aMessage);
nsresult
Dispatch(nsIDOMEventTarget* aTarget, const nsAString& aEventType)
{
NS_ASSERTION(aTarget, "Null pointer!");
NS_ASSERTION(!aEventType.IsEmpty(), "Empty event type!");
nsresult rv = InitEvent(aEventType, false, false);
NS_ENSURE_SUCCESS(rv, rv);
rv = SetTrusted(true);
NS_ENSURE_SUCCESS(rv, rv);
nsIDOMEvent* thisEvent =
static_cast<nsDOMEvent*>(const_cast<DataErrorEvent*>(this));
bool dummy;
rv = aTarget->DispatchEvent(thisEvent, &dummy);
NS_ENSURE_SUCCESS(rv, rv);
return NS_OK;
}
private:
DataErrorEvent()
: nsDOMEvent(nullptr, nullptr)
{ }
~DataErrorEvent()
{ }
};
}
}
}
#endif // mozilla_dom_network_dataerrorevent_h

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

@ -33,6 +33,7 @@ CPPSRCS = \
Connection.cpp \
Utils.cpp \
USSDReceivedEvent.cpp \
DataErrorEvent.cpp \
$(NULL)
ifdef MOZ_B2G_RIL

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

@ -8,6 +8,7 @@
#include "nsDOMEvent.h"
#include "nsIObserverService.h"
#include "USSDReceivedEvent.h"
#include "DataErrorEvent.h"
#include "mozilla/Services.h"
#include "IccManager.h"
@ -18,6 +19,7 @@
#define CARDSTATECHANGE_EVENTNAME NS_LITERAL_STRING("cardstatechange")
#define ICCINFOCHANGE_EVENTNAME NS_LITERAL_STRING("iccinfochange")
#define USSDRECEIVED_EVENTNAME NS_LITERAL_STRING("ussdreceived")
#define DATAERROR_EVENTNAME NS_LITERAL_STRING("dataerror")
DOMCI_DATA(MozMobileConnection, mozilla::dom::network::MobileConnection)
@ -30,6 +32,7 @@ const char* kDataChangedTopic = "mobile-connection-data-changed";
const char* kCardStateChangedTopic = "mobile-connection-cardstate-changed";
const char* kIccInfoChangedTopic = "mobile-connection-iccinfo-changed";
const char* kUssdReceivedTopic = "mobile-connection-ussd-received";
const char* kDataErrorTopic = "mobile-connection-data-error";
NS_IMPL_CYCLE_COLLECTION_CLASS(MobileConnection)
@ -57,6 +60,7 @@ NS_IMPL_EVENT_HANDLER(MobileConnection, iccinfochange)
NS_IMPL_EVENT_HANDLER(MobileConnection, voicechange)
NS_IMPL_EVENT_HANDLER(MobileConnection, datachange)
NS_IMPL_EVENT_HANDLER(MobileConnection, ussdreceived)
NS_IMPL_EVENT_HANDLER(MobileConnection, dataerror)
MobileConnection::MobileConnection()
{
@ -85,6 +89,7 @@ MobileConnection::Init(nsPIDOMWindow* aWindow)
obs->AddObserver(this, kCardStateChangedTopic, false);
obs->AddObserver(this, kIccInfoChangedTopic, false);
obs->AddObserver(this, kUssdReceivedTopic, false);
obs->AddObserver(this, kDataErrorTopic, false);
mIccManager = new icc::IccManager();
mIccManager->Init(aWindow);
@ -104,6 +109,7 @@ MobileConnection::Shutdown()
obs->RemoveObserver(this, kCardStateChangedTopic);
obs->RemoveObserver(this, kIccInfoChangedTopic);
obs->RemoveObserver(this, kUssdReceivedTopic);
obs->RemoveObserver(this, kDataErrorTopic);
if (mIccManager) {
mIccManager->Shutdown();
@ -147,7 +153,18 @@ MobileConnection::Observe(nsISupports* aSubject,
nsresult rv =
event->Dispatch(ToIDOMEventTarget(), USSDRECEIVED_EVENTNAME);
NS_ENSURE_SUCCESS(rv, rv);
return NS_OK;
}
if (!strcmp(aTopic, kDataErrorTopic)) {
nsString dataerror;
dataerror.Assign(aData);
nsRefPtr<DataErrorEvent> event = DataErrorEvent::Create(dataerror);
NS_ASSERTION(event, "This should never fail!");
nsresult rv =
event->Dispatch(ToIDOMEventTarget(), DATAERROR_EVENTNAME);
NS_ENSURE_SUCCESS(rv, rv);
return NS_OK;
}

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

@ -773,8 +773,16 @@ nsDOMOfflineResourceList::CacheKeys()
if (mCachedKeys)
return NS_OK;
nsCOMPtr<nsIDOMWindow> window = do_QueryInterface(GetOwner());
nsCOMPtr<nsIWebNavigation> webNav = do_GetInterface(window);
nsCOMPtr<nsILoadContext> loadContext = do_QueryInterface(webNav);
nsAutoCString groupID;
mApplicationCacheService->BuildGroupID(
mManifestURI, loadContext, groupID);
nsCOMPtr<nsIApplicationCache> appCache;
mApplicationCacheService->GetActiveCache(mManifestSpec,
mApplicationCacheService->GetActiveCache(groupID,
getter_AddRefs(appCache));
if (!appCache) {

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

@ -36,8 +36,7 @@ parent:
__delete__();
Init(bool useDB, bool sessionOnly, bool isPrivate,
nsCString domain, nsCString scopeDBKey,
nsCString quotaDBKey, uint32_t storageType);
nsCString scopeDBKey, nsCString quotaDBKey, uint32_t storageType);
sync GetKeys(bool callerSecure)
returns (nsString[] keys);

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

@ -83,21 +83,21 @@ StorageChild::InitRemote()
ContentChild* child = ContentChild::GetSingleton();
AddIPDLReference();
child->SendPStorageConstructor(this, null_t());
SendInit(mUseDB, mSessionOnly, mInPrivateBrowsing, mDomain, mScopeDBKey,
SendInit(mUseDB, mSessionOnly, mInPrivateBrowsing, mScopeDBKey,
mQuotaDBKey, mStorageType);
}
void
StorageChild::InitAsSessionStorage(nsIURI* aDomainURI, bool aPrivate)
StorageChild::InitAsSessionStorage(nsIPrincipal* aPrincipal, bool aPrivate)
{
DOMStorageBase::InitAsSessionStorage(aDomainURI, aPrivate);
DOMStorageBase::InitAsSessionStorage(aPrincipal, aPrivate);
InitRemote();
}
void
StorageChild::InitAsLocalStorage(nsIURI* aDomainURI, bool aPrivate)
StorageChild::InitAsLocalStorage(nsIPrincipal* aPrincipal, bool aPrivate)
{
DOMStorageBase::InitAsLocalStorage(aDomainURI, aPrivate);
DOMStorageBase::InitAsLocalStorage(aPrincipal, aPrivate);
InitRemote();
}
@ -233,7 +233,7 @@ StorageChild::CloneFrom(bool aCallerSecure, DOMStorageBase* aThat)
StorageClone clone(nullptr, other, aCallerSecure);
AddIPDLReference();
child->SendPStorageConstructor(this, clone);
SendInit(mUseDB, mSessionOnly, mInPrivateBrowsing, mDomain,
SendInit(mUseDB, mSessionOnly, mInPrivateBrowsing,
mScopeDBKey, mQuotaDBKey, mStorageType);
return NS_OK;
}

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

@ -26,8 +26,8 @@ public:
StorageChild(nsDOMStorage* aOwner);
StorageChild(nsDOMStorage* aOwner, StorageChild& aOther);
virtual void InitAsSessionStorage(nsIURI* aDomainURI, bool aPrivate);
virtual void InitAsLocalStorage(nsIURI* aDomainURI, bool aPrivate);
virtual void InitAsSessionStorage(nsIPrincipal* aPrincipal, bool aPrivate);
virtual void InitAsLocalStorage(nsIPrincipal* aPrincipal, bool aPrivate);
virtual bool CacheStoragePermissions();

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

@ -30,12 +30,11 @@ bool
StorageParent::RecvInit(const bool& aUseDB,
const bool& aSessionOnly,
const bool& aPrivate,
const nsCString& aDomain,
const nsCString& aScopeDBKey,
const nsCString& aQuotaDBKey,
const uint32_t& aStorageType)
{
mStorage->InitFromChild(aUseDB, aSessionOnly, aPrivate, aDomain,
mStorage->InitFromChild(aUseDB, aSessionOnly, aPrivate,
aScopeDBKey, aQuotaDBKey,
aStorageType);
return true;

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

@ -45,7 +45,6 @@ private:
bool RecvInit(const bool& aUseDB,
const bool& aSessionOnly,
const bool& aPrivate,
const nsCString& aDomain,
const nsCString& aScopeDBKey,
const nsCString& aQuotaDBKey,
const uint32_t& aStorageType);

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

@ -59,38 +59,6 @@ static const char kStorageEnabled[] = "dom.storage.enabled";
static const char kCookiesBehavior[] = "network.cookie.cookieBehavior";
static const char kCookiesLifetimePolicy[] = "network.cookie.lifetimePolicy";
// The URI returned is the innermost URI that should be used for
// security-check-like stuff. aHost is its hostname, correctly canonicalized.
static nsresult
GetPrincipalURIAndHost(nsIPrincipal* aPrincipal, nsIURI** aURI, nsCString& aHost)
{
nsresult rv = aPrincipal->GetDomain(aURI);
NS_ENSURE_SUCCESS(rv, rv);
if (!*aURI) {
rv = aPrincipal->GetURI(aURI);
NS_ENSURE_SUCCESS(rv, rv);
}
if (!*aURI) {
return NS_OK;
}
nsCOMPtr<nsIURI> innerURI = NS_GetInnermostURI(*aURI);
if (!innerURI) {
return NS_ERROR_UNEXPECTED;
}
rv = innerURI->GetAsciiHost(aHost);
if (NS_FAILED(rv)) {
return NS_ERROR_DOM_SECURITY_ERR;
}
innerURI.swap(*aURI);
return NS_OK;
}
//
// Helper that tells us whether the caller is secure or not.
//
@ -459,7 +427,6 @@ DOMStorageBase::DOMStorageBase(DOMStorageBase& aThat)
: mStorageType(aThat.mStorageType)
, mUseDB(false) // Clones don't use the DB
, mSessionOnly(true)
, mDomain(aThat.mDomain)
, mScopeDBKey(aThat.mScopeDBKey)
, mQuotaDBKey(aThat.mQuotaDBKey)
, mInPrivateBrowsing(aThat.mInPrivateBrowsing)
@ -467,15 +434,9 @@ DOMStorageBase::DOMStorageBase(DOMStorageBase& aThat)
}
void
DOMStorageBase::InitAsSessionStorage(nsIURI* aDomainURI, bool aPrivate)
DOMStorageBase::InitAsSessionStorage(nsIPrincipal* aPrincipal, bool aPrivate)
{
// No need to check for a return value. If this would fail we would not get
// here as we call GetPrincipalURIAndHost (nsDOMStorage.cpp:88) from
// nsDOMStorage::CanUseStorage before we query the storage manager for a new
// sessionStorage. It calls GetAsciiHost on innermost URI. If it fails, we
// won't get to InitAsSessionStorage.
aDomainURI->GetAsciiHost(mDomain);
MOZ_ASSERT(mQuotaDBKey.IsEmpty());
mUseDB = false;
mScopeDBKey.Truncate();
mStorageType = nsPIDOMStorage::SessionStorage;
@ -483,18 +444,9 @@ DOMStorageBase::InitAsSessionStorage(nsIURI* aDomainURI, bool aPrivate)
}
void
DOMStorageBase::InitAsLocalStorage(nsIURI* aDomainURI,
bool aPrivate)
DOMStorageBase::InitAsLocalStorage(nsIPrincipal* aPrincipal, bool aPrivate)
{
// No need to check for a return value. If this would fail we would not get
// here as we call GetPrincipalURIAndHost (nsDOMStorage.cpp:88) from
// nsDOMStorage::CanUseStorage before we query the storage manager for a new
// localStorage. It calls GetAsciiHost on innermost URI. If it fails, we won't
// get to InitAsLocalStorage. Actually, mDomain will get replaced with
// mPrincipal in bug 455070. It is not even used for localStorage.
aDomainURI->GetAsciiHost(mDomain);
nsDOMStorageDBWrapper::CreateScopeDBKey(aDomainURI, mScopeDBKey);
nsDOMStorageDBWrapper::CreateScopeDBKey(aPrincipal, mScopeDBKey);
// XXX Bug 357323, we have to solve the issue how to define
// origin for file URLs. In that case CreateOriginScopeDBKey
@ -502,7 +454,7 @@ DOMStorageBase::InitAsLocalStorage(nsIURI* aDomainURI,
// in that case because it produces broken entries w/o owner.
mUseDB = !mScopeDBKey.IsEmpty();
nsDOMStorageDBWrapper::CreateQuotaDBKey(mDomain, mQuotaDBKey);
nsDOMStorageDBWrapper::CreateQuotaDBKey(aPrincipal, mQuotaDBKey);
mStorageType = nsPIDOMStorage::LocalStorage;
mInPrivateBrowsing = aPrivate;
}
@ -589,7 +541,6 @@ DOMStorageImpl::InitDB()
void
DOMStorageImpl::InitFromChild(bool aUseDB,
bool aSessionOnly, bool aPrivate,
const nsACString& aDomain,
const nsACString& aScopeDBKey,
const nsACString& aQuotaDBKey,
uint32_t aStorageType)
@ -597,7 +548,6 @@ DOMStorageImpl::InitFromChild(bool aUseDB,
mUseDB = aUseDB;
mSessionOnly = aSessionOnly;
mInPrivateBrowsing = aPrivate;
mDomain = aDomain;
mScopeDBKey = aScopeDBKey;
mQuotaDBKey = aQuotaDBKey;
mStorageType = static_cast<nsPIDOMStorage::nsDOMStorageType>(aStorageType);
@ -609,19 +559,6 @@ DOMStorageImpl::SetSessionOnly(bool aSessionOnly)
mSessionOnly = aSessionOnly;
}
void
DOMStorageImpl::InitAsSessionStorage(nsIURI* aDomainURI, bool aPrivate)
{
DOMStorageBase::InitAsSessionStorage(aDomainURI, aPrivate);
}
void
DOMStorageImpl::InitAsLocalStorage(nsIURI* aDomainURI,
bool aPrivate)
{
DOMStorageBase::InitAsLocalStorage(aDomainURI, aPrivate);
}
bool
DOMStorageImpl::CacheStoragePermissions()
{
@ -1122,49 +1059,24 @@ nsDOMStorage::~nsDOMStorage()
{
}
static
nsresult
GetDomainURI(nsIPrincipal *aPrincipal, bool aIncludeDomain, nsIURI **_domain)
{
nsCOMPtr<nsIURI> uri;
if (aIncludeDomain) {
nsresult rv = aPrincipal->GetDomain(getter_AddRefs(uri));
NS_ENSURE_SUCCESS(rv, rv);
}
if (!uri) {
nsresult rv = aPrincipal->GetURI(getter_AddRefs(uri));
NS_ENSURE_SUCCESS(rv, rv);
}
// Check if we really got any URI. System principal doesn't return a URI
// instance and we would crash in NS_GetInnermostURI below.
if (!uri)
return NS_ERROR_NOT_AVAILABLE;
nsCOMPtr<nsIURI> innerURI = NS_GetInnermostURI(uri);
if (!innerURI)
return NS_ERROR_UNEXPECTED;
innerURI.forget(_domain);
return NS_OK;
}
nsresult
nsDOMStorage::InitAsSessionStorage(nsIPrincipal *aPrincipal, const nsSubstring &aDocumentURI,
bool aPrivate)
{
nsCOMPtr<nsIURI> domainURI;
nsresult rv = GetDomainURI(aPrincipal, true, getter_AddRefs(domainURI));
nsCOMPtr<nsIURI> uri;
nsresult rv = aPrincipal->GetURI(getter_AddRefs(uri));
NS_ENSURE_SUCCESS(rv, rv);
if (!uri) {
return NS_ERROR_NOT_AVAILABLE;
}
mDocumentURI = aDocumentURI;
mPrincipal = aPrincipal;
mStorageType = SessionStorage;
mStorageImpl->InitAsSessionStorage(domainURI, aPrivate);
mStorageImpl->InitAsSessionStorage(mPrincipal, aPrivate);
return NS_OK;
}
@ -1172,16 +1084,20 @@ nsresult
nsDOMStorage::InitAsLocalStorage(nsIPrincipal *aPrincipal, const nsSubstring &aDocumentURI,
bool aPrivate)
{
nsCOMPtr<nsIURI> domainURI;
nsresult rv = GetDomainURI(aPrincipal, false, getter_AddRefs(domainURI));
nsCOMPtr<nsIURI> uri;
nsresult rv = aPrincipal->GetURI(getter_AddRefs(uri));
NS_ENSURE_SUCCESS(rv, rv);
if (!uri) {
return NS_ERROR_NOT_AVAILABLE;
}
mDocumentURI = aDocumentURI;
mPrincipal = aPrincipal;
mStorageType = LocalStorage;
mStorageImpl->InitAsLocalStorage(domainURI, aPrivate);
mStorageImpl->InitAsLocalStorage(aPrincipal, aPrivate);
return NS_OK;
}
@ -1217,21 +1133,14 @@ nsDOMStorage::CanUseStorage(DOMStorageBase* aStorage /* = NULL */)
// if subjectPrincipal were null we'd have returned after
// IsCallerChrome().
nsCOMPtr<nsIURI> subjectURI;
nsAutoCString unused;
if (NS_FAILED(GetPrincipalURIAndHost(subjectPrincipal,
getter_AddRefs(subjectURI),
unused))) {
return false;
}
nsCOMPtr<nsIPermissionManager> permissionManager =
do_GetService(NS_PERMISSIONMANAGER_CONTRACTID);
if (!permissionManager)
return false;
uint32_t perm;
permissionManager->TestPermission(subjectURI, kPermissionType, &perm);
permissionManager->TestPermissionFromPrincipal(subjectPrincipal,
kPermissionType, &perm);
if (perm == nsIPermissionManager::DENY_ACTION)
return false;

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

@ -109,8 +109,8 @@ public:
DOMStorageBase();
DOMStorageBase(DOMStorageBase&);
virtual void InitAsSessionStorage(nsIURI* aDomainURI, bool aPrivate);
virtual void InitAsLocalStorage(nsIURI* aDomainURI, bool aPrivate);
virtual void InitAsSessionStorage(nsIPrincipal* aPrincipal, bool aPrivate);
virtual void InitAsLocalStorage(nsIPrincipal* aPrincipal, bool aPrivate);
virtual nsTArray<nsString>* GetKeys(bool aCallerSecure) = 0;
virtual nsresult GetLength(bool aCallerSecure, uint32_t* aLength) = 0;
@ -190,9 +190,6 @@ protected:
// make sure this stays up to date.
bool mSessionOnly;
// domain this store is associated with
nsCString mDomain;
// keys are used for database queries.
// see comments of the getters bellow.
nsCString mScopeDBKey;
@ -213,9 +210,6 @@ public:
DOMStorageImpl(nsDOMStorage*, DOMStorageImpl&);
~DOMStorageImpl();
virtual void InitAsSessionStorage(nsIURI* aDomainURI, bool aPrivate);
virtual void InitAsLocalStorage(nsIURI* aDomainURI, bool aPrivate);
bool SessionOnly() {
return mSessionOnly;
}
@ -281,7 +275,7 @@ private:
// Cross-process storage implementations never have InitAs(Session|Local|Global)Storage
// called, so the appropriate initialization needs to happen from the child.
void InitFromChild(bool aUseDB, bool aSessionOnly,
bool aPrivate, const nsACString& aDomain,
bool aPrivate,
const nsACString& aScopeDBKey,
const nsACString& aQuotaDBKey,
uint32_t aStorageType);

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

@ -11,6 +11,7 @@
#include "nsIURL.h"
#include "nsIVariant.h"
#include "nsIEffectiveTLDService.h"
#include "nsIScriptSecurityManager.h"
#include "nsAppDirectoryServiceDefs.h"
#include "mozStorageCID.h"
#include "mozStorageHelper.h"
@ -19,6 +20,7 @@
#include "mozIStorageFunction.h"
#include "nsPrintfCString.h"
#include "nsNetUtil.h"
#include "nsIPrincipal.h"
void ReverseString(const nsCSubstring& source, nsCSubstring& result)
{
@ -226,37 +228,16 @@ nsDOMStorageDBWrapper::GetUsage(const nsACString& aDomain,
}
nsresult
nsDOMStorageDBWrapper::CreateScopeDBKey(nsIURI* aUri, nsACString& aKey)
nsDOMStorageDBWrapper::CreateScopeDBKey(nsIPrincipal* aPrincipal,
nsACString& aKey)
{
nsresult rv;
rv = CreateReversedDomain(aUri, aKey);
if (NS_FAILED(rv))
return rv;
nsAutoCString scheme;
rv = aUri->GetScheme(scheme);
nsCOMPtr<nsIURI> uri;
nsresult rv = aPrincipal->GetURI(getter_AddRefs(uri));
NS_ENSURE_SUCCESS(rv, rv);
aKey.AppendLiteral(":");
aKey.Append(scheme);
int32_t port = NS_GetRealPort(aUri);
if (port != -1) {
aKey.AppendLiteral(":");
aKey.Append(nsPrintfCString("%d", port));
}
return NS_OK;
}
nsresult
nsDOMStorageDBWrapper::CreateReversedDomain(nsIURI* aUri, nsACString& aKey)
{
nsresult rv;
NS_ENSURE_TRUE(uri, NS_ERROR_UNEXPECTED);
nsAutoCString domainScope;
rv = aUri->GetAsciiHost(domainScope);
rv = uri->GetAsciiHost(domainScope);
NS_ENSURE_SUCCESS(rv, rv);
if (domainScope.IsEmpty()) {
@ -264,25 +245,57 @@ nsDOMStorageDBWrapper::CreateReversedDomain(nsIURI* aUri, nsACString& aKey)
// internally by our own redirector, we can trust them and use path as key.
// if file:/// protocol, let's make the exact directory the domain
bool isScheme = false;
if ((NS_SUCCEEDED(aUri->SchemeIs("about", &isScheme)) && isScheme) ||
(NS_SUCCEEDED(aUri->SchemeIs("moz-safe-about", &isScheme)) && isScheme)) {
rv = aUri->GetPath(domainScope);
if ((NS_SUCCEEDED(uri->SchemeIs("about", &isScheme)) && isScheme) ||
(NS_SUCCEEDED(uri->SchemeIs("moz-safe-about", &isScheme)) && isScheme)) {
rv = uri->GetPath(domainScope);
NS_ENSURE_SUCCESS(rv, rv);
// While the host is always canonicalized to lowercase, the path is not,
// thus need to force the casing.
ToLowerCase(domainScope);
}
else if (NS_SUCCEEDED(aUri->SchemeIs("file", &isScheme)) && isScheme) {
nsCOMPtr<nsIURL> url = do_QueryInterface(aUri, &rv);
else if (NS_SUCCEEDED(uri->SchemeIs("file", &isScheme)) && isScheme) {
nsCOMPtr<nsIURL> url = do_QueryInterface(uri, &rv);
NS_ENSURE_SUCCESS(rv, rv);
rv = url->GetDirectory(domainScope);
NS_ENSURE_SUCCESS(rv, rv);
}
}
rv = CreateReversedDomain(domainScope, aKey);
nsAutoCString key;
rv = CreateReversedDomain(domainScope, key);
NS_ENSURE_SUCCESS(rv, rv);
nsAutoCString scheme;
rv = uri->GetScheme(scheme);
NS_ENSURE_SUCCESS(rv, rv);
key.Append(NS_LITERAL_CSTRING(":") + scheme);
int32_t port = NS_GetRealPort(uri);
if (port != -1) {
key.Append(nsPrintfCString(":%d", port));
}
uint32_t appId;
rv = aPrincipal->GetAppId(&appId);
NS_ENSURE_SUCCESS(rv, rv);
bool isInBrowserElement;
rv = aPrincipal->GetIsInBrowserElement(&isInBrowserElement);
NS_ENSURE_SUCCESS(rv, rv);
if (appId == nsIScriptSecurityManager::NO_APP_ID && !isInBrowserElement) {
aKey.Assign(key);
return NS_OK;
}
aKey.Truncate();
aKey.AppendInt(appId);
aKey.Append(NS_LITERAL_CSTRING(":") + (isInBrowserElement ?
NS_LITERAL_CSTRING("t") : NS_LITERAL_CSTRING("f")) +
NS_LITERAL_CSTRING(":") + key);
return NS_OK;
}
@ -300,7 +313,7 @@ nsDOMStorageDBWrapper::CreateReversedDomain(const nsACString& aAsciiDomain,
}
nsresult
nsDOMStorageDBWrapper::CreateQuotaDBKey(const nsACString& aAsciiDomain,
nsDOMStorageDBWrapper::CreateQuotaDBKey(nsIPrincipal* aPrincipal,
nsACString& aKey)
{
nsresult rv;
@ -311,33 +324,39 @@ nsDOMStorageDBWrapper::CreateQuotaDBKey(const nsACString& aAsciiDomain,
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIURI> uri;
rv = NS_NewURI(getter_AddRefs(uri), NS_LITERAL_CSTRING("http://") + aAsciiDomain);
rv = aPrincipal->GetURI(getter_AddRefs(uri));
NS_ENSURE_SUCCESS(rv, rv);
NS_ENSURE_TRUE(uri, NS_ERROR_UNEXPECTED);
nsAutoCString eTLDplusOne;
rv = eTLDService->GetBaseDomain(uri, 0, eTLDplusOne);
if (NS_ERROR_INSUFFICIENT_DOMAIN_LEVELS == rv) {
// XXX bug 357323 - what to do for localhost/file exactly?
eTLDplusOne = aAsciiDomain;
rv = NS_OK;
rv = uri->GetAsciiHost(eTLDplusOne);
}
NS_ENSURE_SUCCESS(rv, rv);
CreateReversedDomain(eTLDplusOne, subdomainsDBKey);
aKey.Assign(subdomainsDBKey);
return NS_OK;
}
uint32_t appId;
rv = aPrincipal->GetAppId(&appId);
NS_ENSURE_SUCCESS(rv, rv);
nsresult
nsDOMStorageDBWrapper::GetDomainFromScopeKey(const nsACString& aScope,
nsACString& aDomain)
{
nsAutoCString reverseDomain, scope;
scope = aScope;
scope.Left(reverseDomain, scope.FindChar(':')-1);
bool isInBrowserElement;
rv = aPrincipal->GetIsInBrowserElement(&isInBrowserElement);
NS_ENSURE_SUCCESS(rv, rv);
if (appId == nsIScriptSecurityManager::NO_APP_ID && !isInBrowserElement) {
aKey.Assign(subdomainsDBKey);
return NS_OK;
}
aKey.Truncate();
aKey.AppendInt(appId);
aKey.Append(NS_LITERAL_CSTRING(":") + (isInBrowserElement ?
NS_LITERAL_CSTRING("t") : NS_LITERAL_CSTRING("f")) +
NS_LITERAL_CSTRING(":") + subdomainsDBKey);
ReverseString(reverseDomain, aDomain);
return NS_OK;
}

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

@ -173,7 +173,7 @@ public:
* i.e. reverses the host, appends a dot, appends the schema
* and a port number.
*/
static nsresult CreateScopeDBKey(nsIURI* aUri, nsACString& aKey);
static nsresult CreateScopeDBKey(nsIPrincipal* aPrincipal, nsACString& aKey);
/**
* Turns "http://foo.bar.com" to "moc.rab.oof.",
@ -187,11 +187,19 @@ public:
* i.e. extracts eTLD+1 from the host, reverses the result
* and appends a dot.
*/
static nsresult CreateQuotaDBKey(const nsACString& aAsciiDomain,
static nsresult CreateQuotaDBKey(nsIPrincipal* aPrincipal,
nsACString& aKey);
static nsresult GetDomainFromScopeKey(const nsACString& aScope,
nsACString& aDomain);
/**
* Turns "foo.bar.com" to "moc.rab.",
* i.e. extracts eTLD+1 from the host, reverses the result
* and appends a dot.
*/
static nsresult CreateQuotaDBKey(const nsACString& aDomain,
nsACString& aKey)
{
return CreateReversedDomain(aDomain, aKey);
}
/**
* Ensures the temp table flush timer is running. This is called when we add

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

@ -61,7 +61,8 @@ const RIL_IPC_MSG_NAMES = [
"RIL:CancelUssd:Return:OK",
"RIL:CancelUssd:Return:KO",
"RIL:StkCommand",
"RIL:StkSessionEnd"
"RIL:StkSessionEnd",
"RIL:DataError"
];
const kVoiceChangedTopic = "mobile-connection-voice-changed";
@ -71,6 +72,7 @@ const kIccInfoChangedTopic = "mobile-connection-iccinfo-changed";
const kUssdReceivedTopic = "mobile-connection-ussd-received";
const kStkCommandTopic = "icc-manager-stk-command";
const kStkSessionEndTopic = "icc-manager-stk-session-end";
const kDataErrorTopic = "mobile-connection-data-error";
XPCOMUtils.defineLazyServiceGetter(this, "cpmm",
"@mozilla.org/childprocessmessagemanager;1",
@ -714,7 +716,11 @@ RILContentHelper.prototype = {
break;
case "RIL:StkSessionEnd":
Services.obs.notifyObservers(null, kStkSessionEndTopic, null);
break;
break;
case "RIL:DataError":
this.updateConnectionInfo(msg.json, this.dataConnectionInfo);
Services.obs.notifyObservers(null, kDataErrorTopic, msg.json.error);
break;
}
},

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

@ -381,10 +381,7 @@ RadioInterfaceLayer.prototype = {
this.updateDataConnection(message);
break;
case "datacallerror":
// 3G Network revoked the data connection, possible unavailable APN
debug("Received data registration error message. Failed APN " +
this.dataCallSettings["apn"]);
RILNetworkInterface.reset();
this.handleDataCallError(message);
break;
case "signalstrengthchange":
this.handleSignalStrengthChange(message);
@ -645,6 +642,20 @@ RadioInterfaceLayer.prototype = {
this.updateRILNetworkInterface();
},
/**
* Handle data errors
*/
handleDataCallError: function handleDataCallError(message) {
if (message.apn != this.dataCallSettings["apn"]) {
return;
}
// 3G Network revoked the data connection, possible unavailable APN
RILNetworkInterface.reset();
// Notify datacall error
ppmm.broadcastAsyncMessage("RIL:DataError", message);
},
handleSignalStrengthChange: function handleSignalStrengthChange(message) {
let voiceInfo = this.rilContext.voice;
// TODO CDMA, EVDO, LTE, etc. (see bug 726098)

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

@ -1719,6 +1719,53 @@ RIL_CALL_FAILCAUSE_TO_GECKO_CALL_ERROR[CALL_FAIL_IMSI_UNKNOWN_IN_VLR] = GECKO_CA
RIL_CALL_FAILCAUSE_TO_GECKO_CALL_ERROR[CALL_FAIL_IMEI_NOT_ACCEPTED] = GECKO_CALL_ERROR_DEVICE_NOT_ACCEPTED;
RIL_CALL_FAILCAUSE_TO_GECKO_CALL_ERROR[CALL_FAIL_ERROR_UNSPECIFIED] = GECKO_CALL_ERROR_UNSPECIFIED;
const GECKO_DATACALL_ERROR_OPERATOR_BARRED = "OperatorBarredError";
const GECKO_DATACALL_ERROR_INSUFFICIENT_RESOURCES = "InsufficientResourcesError";
const GECKO_DATACALL_ERROR_MISSING_UKNOWN_APN = "MissingUnknownAPNError";
const GECKO_DATACALL_ERROR_UNKNOWN_PDP_ADDRESS_TYPE = "UnknownPDPAddressTypeError";
const GECKO_DATACALL_ERROR_USER_AUTHENTICATION = "UserAuthenticationError";
const GECKO_DATACALL_ERROR_ACTIVATION_REJECT_GGSN = "ActivationRejectGGSNError";
const GECKO_DATACALL_ERROR_ACTIVATION_REJECT_UNSPECIFIED = "ActivationRejectUnspecifiedError";
const GECKO_DATACALL_ERROR_SERVICE_OPTION_NOT_SUPPORTED = "ServiceOptionNotSupportedError";
const GECKO_DATACALL_ERROR_SERVICE_OPTION_NOT_SUBSCRIBED = "ServiceOptionNotSubscribedError";
const GECKO_DATACALL_ERROR_SERVICE_OPTION_OUT_OF_ORDER = "ServiceOptionOutOfOrderError";
const GECKO_DATACALL_ERROR_NSAPI_IN_USE = "NSAPIInUseError";
const GECKO_DATACALL_ERROR_ONLY_IPV4_ALLOWED = "OnlyIPv4Error";
const GECKO_DATACALL_ERROR_ONLY_IPV6_ALLOWED = "OnlyIPv6Error";
const GECKO_DATACALL_ERROR_ONLY_SINGLE_BEARER_ALLOWED = "OnlySingleBearerAllowedError";
const GECKO_DATACALL_ERROR_PROTOCOL_ERRORS = "ProtocolErrorsError";
const GECKO_DATACALL_ERROR_VOICE_REGISTRATION_FAIL = "VoiceRegistrationFailError";
const GECKO_DATACALL_ERROR_DATA_REGISTRATION_FAIL = "DataRegistrationFailError";
const GECKO_DATACALL_ERROR_SIGNAL_LOST = "SignalLostError";
const GECKO_DATACALL_ERROR_PREF_RADIO_TECH_CHANGED = "PrefRadioTechChangedError";
const GECKO_DATACALL_ERROR_RADIO_POWER_OFF = "RadioPowerOffError";
const GECKO_DATACALL_ERROR_TETHERED_CALL_ACTIVE = "TetheredCallActiveError";
const GECKO_DATACALL_ERROR_UNSPECIFIED = "UnspecifiedError";
const RIL_DATACALL_FAILCAUSE_TO_GECKO_DATACALL_ERROR = {};
RIL_DATACALL_FAILCAUSE_TO_GECKO_DATACALL_ERROR[DATACALL_FAIL_OPERATOR_BARRED] = GECKO_DATACALL_ERROR_OPERATOR_BARRED;
RIL_DATACALL_FAILCAUSE_TO_GECKO_DATACALL_ERROR[DATACALL_FAIL_INSUFFICIENT_RESOURCES] = GECKO_DATACALL_ERROR_INSUFFICIENT_RESOURCES;
RIL_DATACALL_FAILCAUSE_TO_GECKO_DATACALL_ERROR[DATACALL_FAIL_MISSING_UKNOWN_APN] = GECKO_DATACALL_ERROR_MISSING_UKNOWN_APN;
RIL_DATACALL_FAILCAUSE_TO_GECKO_DATACALL_ERROR[DATACALL_FAIL_UNKNOWN_PDP_ADDRESS_TYPE] = GECKO_DATACALL_ERROR_UNKNOWN_PDP_ADDRESS_TYPE;
RIL_DATACALL_FAILCAUSE_TO_GECKO_DATACALL_ERROR[DATACALL_FAIL_USER_AUTHENTICATION] = GECKO_DATACALL_ERROR_USER_AUTHENTICATION;
RIL_DATACALL_FAILCAUSE_TO_GECKO_DATACALL_ERROR[DATACALL_FAIL_ACTIVATION_REJECT_GGSN] = GECKO_DATACALL_ERROR_ACTIVATION_REJECT_GGSN;
RIL_DATACALL_FAILCAUSE_TO_GECKO_DATACALL_ERROR[DATACALL_FAIL_ACTIVATION_REJECT_UNSPECIFIED] = GECKO_DATACALL_ERROR_ACTIVATION_REJECT_UNSPECIFIED;
RIL_DATACALL_FAILCAUSE_TO_GECKO_DATACALL_ERROR[DATACALL_FAIL_SERVICE_OPTION_NOT_SUPPORTED] = GECKO_DATACALL_ERROR_SERVICE_OPTION_NOT_SUPPORTED;
RIL_DATACALL_FAILCAUSE_TO_GECKO_DATACALL_ERROR[DATACALL_FAIL_SERVICE_OPTION_NOT_SUBSCRIBED] = GECKO_DATACALL_ERROR_SERVICE_OPTION_NOT_SUBSCRIBED;
RIL_DATACALL_FAILCAUSE_TO_GECKO_DATACALL_ERROR[DATACALL_FAIL_SERVICE_OPTION_OUT_OF_ORDER] = GECKO_DATACALL_ERROR_SERVICE_OPTION_OUT_OF_ORDER;
RIL_DATACALL_FAILCAUSE_TO_GECKO_DATACALL_ERROR[DATACALL_FAIL_NSAPI_IN_USE] = GECKO_DATACALL_ERROR_NSAPI_IN_USE;
RIL_DATACALL_FAILCAUSE_TO_GECKO_DATACALL_ERROR[DATACALL_FAIL_ONLY_IPV4_ALLOWED] = GECKO_DATACALL_ERROR_ONLY_IPV4_ALLOWED;
RIL_DATACALL_FAILCAUSE_TO_GECKO_DATACALL_ERROR[DATACALL_FAIL_ONLY_IPV6_ALLOWED] = GECKO_DATACALL_ERROR_ONLY_IPV6_ALLOWED;
RIL_DATACALL_FAILCAUSE_TO_GECKO_DATACALL_ERROR[DATACALL_FAIL_ONLY_SINGLE_BEARER_ALLOWED] = GECKO_DATACALL_ERROR_ONLY_SINGLE_BEARER_ALLOWED;
RIL_DATACALL_FAILCAUSE_TO_GECKO_DATACALL_ERROR[DATACALL_FAIL_PROTOCOL_ERRORS] = GECKO_DATACALL_ERROR_PROTOCOL_ERRORS;
RIL_DATACALL_FAILCAUSE_TO_GECKO_DATACALL_ERROR[DATACALL_FAIL_VOICE_REGISTRATION_FAIL] = GECKO_DATACALL_ERROR_VOICE_REGISTRATION_FAIL;
RIL_DATACALL_FAILCAUSE_TO_GECKO_DATACALL_ERROR[DATACALL_FAIL_DATA_REGISTRATION_FAIL] = GECKO_DATACALL_ERROR_DATA_REGISTRATION_FAIL;
RIL_DATACALL_FAILCAUSE_TO_GECKO_DATACALL_ERROR[DATACALL_FAIL_SIGNAL_LOST] = GECKO_DATACALL_ERROR_SIGNAL_LOST;
RIL_DATACALL_FAILCAUSE_TO_GECKO_DATACALL_ERROR[DATACALL_FAIL_PREF_RADIO_TECH_CHANGED] = GECKO_DATACALL_ERROR_PREF_RADIO_TECH_CHANGED;
RIL_DATACALL_FAILCAUSE_TO_GECKO_DATACALL_ERROR[DATACALL_FAIL_RADIO_POWER_OFF] = GECKO_DATACALL_ERROR_RADIO_POWER_OFF;
RIL_DATACALL_FAILCAUSE_TO_GECKO_DATACALL_ERROR[DATACALL_FAIL_TETHERED_CALL_ACTIVE] = GECKO_DATACALL_ERROR_TETHERED_CALL_ACTIVE;
RIL_DATACALL_FAILCAUSE_TO_GECKO_DATACALL_ERROR[DATACALL_FAIL_ERROR_UNSPECIFIED] = GECKO_DATACALL_ERROR_UNSPECIFIED;
const GECKO_RADIO_TECH = [
null,
"gprs",

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

@ -2900,7 +2900,26 @@ let RIL = {
}
},
_sendDataCallError: function _sendDataCallError(message, errorCode) {
message.rilMessageType = "datacallerror";
if (errorCode == ERROR_GENERIC_FAILURE) {
message.error = RIL_ERROR_TO_GECKO_ERROR[errorCode];
} else {
message.error = RIL_DATACALL_FAILCAUSE_TO_GECKO_DATACALL_ERROR[errorCode];
}
this.sendDOMMessage(message);
},
_processDataCallList: function _processDataCallList(datacalls, newDataCallOptions) {
// Check for possible PDP errors: We check earlier because the datacall
// can be removed if is the same as the current one.
for each (let newDataCall in datacalls) {
if (newDataCall.status != DATACALL_FAIL_NONE) {
newDataCall.apn = newDataCallOptions.apn;
this._sendDataCallError(newDataCall, newDataCall.status);
}
}
for each (let currentDataCall in this.currentDataCalls) {
let updatedDataCall;
if (datacalls) {
@ -3705,8 +3724,8 @@ RIL.readSetupDataCall_v5 = function readSetupDataCall_v5(options) {
RIL[REQUEST_SETUP_DATA_CALL] = function REQUEST_SETUP_DATA_CALL(length, options) {
if (options.rilRequestError) {
options.rilMessageType = "datacallerror";
this.sendDOMMessage(options);
// On Data Call generic errors, we shall notify caller
this._sendDataCallError(options, options.rilRequestError);
return;
}

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

@ -14,12 +14,12 @@ function manifestUpdated()
.getService(SpecialPowers.Ci.nsIApplicationCacheService);
var foreign2cache = appCacheService.chooseApplicationCache(
"http://mochi.test:8888/tests/dom/tests/mochitest/ajax/offline/foreign2.html");
"http://mochi.test:8888/tests/dom/tests/mochitest/ajax/offline/foreign2.html", OfflineTest.loadContext());
OfflineTest.ok(foreign2cache, "Foreign 2 cache present, chosen for foreign2.html");
OfflineTest.is(foreign2cache.groupID, "http://mochi.test:8888/tests/dom/tests/mochitest/ajax/offline/foreign2.cacheManifest")
OfflineTest.is(foreign2cache.manifestURI.asciiSpec, "http://mochi.test:8888/tests/dom/tests/mochitest/ajax/offline/foreign2.cacheManifest")
var foreign1cache = appCacheService.getActiveCache(
var foreign1cache = OfflineTest.getActiveCache(
"http://mochi.test:8888/tests/dom/tests/mochitest/ajax/offline/foreign1.cacheManifest");
OfflineTest.ok(foreign1cache, "Foreign 1 cache loaded");
foreign1cache.discard();
@ -33,16 +33,16 @@ function onLoaded()
var appCacheService = SpecialPowers.Components.classes["@mozilla.org/network/application-cache-service;1"]
.getService(SpecialPowers.Ci.nsIApplicationCacheService);
var foreign1cache = appCacheService.getActiveCache(
var foreign1cache = OfflineTest.getActiveCache(
"http://mochi.test:8888/tests/dom/tests/mochitest/ajax/offline/foreign1.cacheManifest");
OfflineTest.ok(foreign1cache, "Foreign 1 cache loaded");
var foreign2cache = appCacheService.getActiveCache(
var foreign2cache = OfflineTest.getActiveCache(
"http://mochi.test:8888/tests/dom/tests/mochitest/ajax/offline/foreign2.cacheManifest");
OfflineTest.ok(!foreign2cache, "Foreign 2 cache not present");
foreign1cache = appCacheService.chooseApplicationCache(
"http://mochi.test:8888/tests/dom/tests/mochitest/ajax/offline/foreign2.html");
"http://mochi.test:8888/tests/dom/tests/mochitest/ajax/offline/foreign2.html", OfflineTest.loadContext());
OfflineTest.ok(!foreign1cache, "foreign2.html not chosen from foreign1 cache");
try

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