From 5c2afb21e71eccf3119b2da96681c750ddf657c3 Mon Sep 17 00:00:00 2001 From: Mike Hommey Date: Thu, 26 Sep 2013 16:43:52 +0900 Subject: [PATCH 01/84] Bug 919832 - Remove EXPORTS related rules from rules.mk. r=gps --- config/rules.mk | 23 ----------------------- js/src/config/rules.mk | 23 ----------------------- mfbt/exported_headers.mk | 7 ++++--- 3 files changed, 4 insertions(+), 49 deletions(-) diff --git a/config/rules.mk b/config/rules.mk index 1144c3928e7..c7a6bd65423 100644 --- a/config/rules.mk +++ b/config/rules.mk @@ -1254,9 +1254,6 @@ $(DEPTH)/config/autoconf.mk: $(topsrcdir)/config/autoconf.mk.in # Bunch of things that extend the 'export' rule (in order): ############################################################################### -################################################################################ -# Copy each element of EXPORTS to $(DIST)/include - ifneq ($(XPI_NAME),) $(FINAL_TARGET): $(NSINSTALL) -D $@ @@ -1264,26 +1261,6 @@ $(FINAL_TARGET): export:: $(FINAL_TARGET) endif -ifndef NO_DIST_INSTALL -ifneq (,$(EXPORTS)) -EXPORTS_FILES := $(EXPORTS) -EXPORTS_DEST := $(DIST)/include -EXPORTS_TARGET := export -INSTALL_TARGETS += EXPORTS -endif -endif # NO_DIST_INSTALL - -define EXPORT_NAMESPACE_RULE -ifndef NO_DIST_INSTALL -EXPORTS_$(namespace)_FILES := $$(EXPORTS_$(namespace)) -EXPORTS_$(namespace)_DEST := $$(DIST)/include/$(namespace) -EXPORTS_$(namespace)_TARGET := export -INSTALL_TARGETS += EXPORTS_$(namespace) -endif # NO_DIST_INSTALL -endef - -$(foreach namespace,$(EXPORTS_NAMESPACES),$(eval $(EXPORT_NAMESPACE_RULE))) - ################################################################################ # Copy each element of PREF_JS_EXPORTS diff --git a/js/src/config/rules.mk b/js/src/config/rules.mk index 1144c3928e7..c7a6bd65423 100644 --- a/js/src/config/rules.mk +++ b/js/src/config/rules.mk @@ -1254,9 +1254,6 @@ $(DEPTH)/config/autoconf.mk: $(topsrcdir)/config/autoconf.mk.in # Bunch of things that extend the 'export' rule (in order): ############################################################################### -################################################################################ -# Copy each element of EXPORTS to $(DIST)/include - ifneq ($(XPI_NAME),) $(FINAL_TARGET): $(NSINSTALL) -D $@ @@ -1264,26 +1261,6 @@ $(FINAL_TARGET): export:: $(FINAL_TARGET) endif -ifndef NO_DIST_INSTALL -ifneq (,$(EXPORTS)) -EXPORTS_FILES := $(EXPORTS) -EXPORTS_DEST := $(DIST)/include -EXPORTS_TARGET := export -INSTALL_TARGETS += EXPORTS -endif -endif # NO_DIST_INSTALL - -define EXPORT_NAMESPACE_RULE -ifndef NO_DIST_INSTALL -EXPORTS_$(namespace)_FILES := $$(EXPORTS_$(namespace)) -EXPORTS_$(namespace)_DEST := $$(DIST)/include/$(namespace) -EXPORTS_$(namespace)_TARGET := export -INSTALL_TARGETS += EXPORTS_$(namespace) -endif # NO_DIST_INSTALL -endef - -$(foreach namespace,$(EXPORTS_NAMESPACES),$(eval $(EXPORT_NAMESPACE_RULE))) - ################################################################################ # Copy each element of PREF_JS_EXPORTS diff --git a/mfbt/exported_headers.mk b/mfbt/exported_headers.mk index 295297a85fe..4fa701320f3 100644 --- a/mfbt/exported_headers.mk +++ b/mfbt/exported_headers.mk @@ -6,9 +6,10 @@ # itself and by the JS engine, which, when built standalone, must install # mfbt's exported headers itself. -EXPORTS_NAMESPACES += mozilla - -EXPORTS_mozilla += \ +EXPORTS_mozilla_DEST := $(DIST)/include/mozilla +EXPORTS_mozilla_TARGET := export +INSTALL_TARGETS += EXPORTS_mozilla +EXPORTS_mozilla_FILES += \ Alignment.h \ AllocPolicy.h \ Array.h \ From efc297fb0e8d76962b9bebf96cb17d8994d491c0 Mon Sep 17 00:00:00 2001 From: Mike Hommey Date: Thu, 26 Sep 2013 16:43:53 +0900 Subject: [PATCH 02/84] Bug 920353 - Use PYCOMMANDPATH paths as site packages in pymake, and set it to the virtualenv site packages instead of $(topsrcdir)/config. r=gps --- build/autoconf/python-virtualenv.m4 | 7 +++++ build/pymake/pymake/process.py | 32 ++++++++-------------- config/config.mk | 2 +- js/src/build/autoconf/python-virtualenv.m4 | 7 +++++ js/src/config/config.mk | 2 +- 5 files changed, 28 insertions(+), 22 deletions(-) diff --git a/build/autoconf/python-virtualenv.m4 b/build/autoconf/python-virtualenv.m4 index dbc8a21cf0d..e7dd990585c 100644 --- a/build/autoconf/python-virtualenv.m4 +++ b/build/autoconf/python-virtualenv.m4 @@ -74,5 +74,12 @@ if test "$?" != 0; then AC_MSG_ERROR([Python environment does not appear to be sane.]) fi AC_MSG_RESULT([yes]) + +PYTHON_SITE_PACKAGES=`$PYTHON -c "import distutils.sysconfig; print distutils.sysconfig.get_python_lib()"` +if test -z "$PYTHON_SITE_PACKAGES"; then + AC_MSG_ERROR([Could not determine python site packages directory.]) +fi +AC_SUBST([PYTHON_SITE_PACKAGES]) + ]) diff --git a/build/pymake/pymake/process.py b/build/pymake/pymake/process.py index 95e658b92c9..d6b39b2fba2 100644 --- a/build/pymake/pymake/process.py +++ b/build/pymake/pymake/process.py @@ -6,6 +6,7 @@ parsing command lines into argv and making sure that no shell magic is being use #TODO: ship pyprocessing? import multiprocessing import subprocess, shlex, re, logging, sys, traceback, os, imp, glob +import site from collections import deque # XXXkhuey Work around http://bugs.python.org/issue1731717 subprocess._cleanup = lambda: None @@ -347,28 +348,19 @@ class PythonException(Exception): def load_module_recursive(module, path): """ - Emulate the behavior of __import__, but allow - passing a custom path to search for modules. + Like __import__, but allow passing a custom path to search for modules. """ - bits = module.split('.') oldsyspath = sys.path - for i, bit in enumerate(bits): - dotname = '.'.join(bits[:i+1]) - try: - f, path, desc = imp.find_module(bit, path) - # Add the directory the module was found in to sys.path - if path != '': - abspath = os.path.abspath(path) - if not os.path.isdir(abspath): - abspath = os.path.dirname(path) - sys.path = [abspath] + sys.path - m = imp.load_module(dotname, f, path, desc) - if f is None: - path = m.__path__ - except ImportError: - return - finally: - sys.path = oldsyspath + sys.path = [] + for p in path: + site.addsitedir(p) + sys.path.extend(oldsyspath) + try: + __import__(module) + except ImportError: + return + finally: + sys.path = oldsyspath class PythonJob(Job): """ diff --git a/config/config.mk b/config/config.mk index b41602cba3a..ffd6dfcdf7c 100644 --- a/config/config.mk +++ b/config/config.mk @@ -132,7 +132,7 @@ SLEEP ?= sleep TOUCH ?= touch ifdef .PYMAKE -PYCOMMANDPATH += $(topsrcdir)/config +PYCOMMANDPATH += $(PYTHON_SITE_PACKAGES) endif PYTHON_PATH = $(PYTHON) $(topsrcdir)/config/pythonpath.py diff --git a/js/src/build/autoconf/python-virtualenv.m4 b/js/src/build/autoconf/python-virtualenv.m4 index dbc8a21cf0d..e7dd990585c 100644 --- a/js/src/build/autoconf/python-virtualenv.m4 +++ b/js/src/build/autoconf/python-virtualenv.m4 @@ -74,5 +74,12 @@ if test "$?" != 0; then AC_MSG_ERROR([Python environment does not appear to be sane.]) fi AC_MSG_RESULT([yes]) + +PYTHON_SITE_PACKAGES=`$PYTHON -c "import distutils.sysconfig; print distutils.sysconfig.get_python_lib()"` +if test -z "$PYTHON_SITE_PACKAGES"; then + AC_MSG_ERROR([Could not determine python site packages directory.]) +fi +AC_SUBST([PYTHON_SITE_PACKAGES]) + ]) diff --git a/js/src/config/config.mk b/js/src/config/config.mk index b41602cba3a..ffd6dfcdf7c 100644 --- a/js/src/config/config.mk +++ b/js/src/config/config.mk @@ -132,7 +132,7 @@ SLEEP ?= sleep TOUCH ?= touch ifdef .PYMAKE -PYCOMMANDPATH += $(topsrcdir)/config +PYCOMMANDPATH += $(PYTHON_SITE_PACKAGES) endif PYTHON_PATH = $(PYTHON) $(topsrcdir)/config/pythonpath.py From ed1ecb4aff9e2ed037cf8f47b18819a65b601543 Mon Sep 17 00:00:00 2001 From: Mike Hommey Date: Thu, 26 Sep 2013 16:43:53 +0900 Subject: [PATCH 03/84] Bug 920891 - Fix installation of bug 677930 css file after bug 917622. r=gps --- browser/devtools/styleinspector/test/Makefile.in | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/browser/devtools/styleinspector/test/Makefile.in b/browser/devtools/styleinspector/test/Makefile.in index 06a7355c68d..444bef7d1d9 100644 --- a/browser/devtools/styleinspector/test/Makefile.in +++ b/browser/devtools/styleinspector/test/Makefile.in @@ -52,8 +52,12 @@ MOCHITEST_BROWSER_FILES += \ browser_bug705707_is_content_stylesheet_xul.css \ browser_bug722196_identify_media_queries.html \ browser_styleinspector_bug_677930_urls_clickable.html \ - browser_styleinspector_bug_677930_urls_clickable \ - browser_styleinspector_bug_677930_urls_clickable/browser_styleinspector_bug_677930_urls_clickable.css \ test-image.png \ browser_ruleview_pseudoelement.html \ $(NULL) + +MOCHITEST_BUG_677940_DATA_FILES = \ + browser_styleinspector_bug_677930_urls_clickable/browser_styleinspector_bug_677930_urls_clickable.css \ + $(NULL) +MOCHITEST_BUG_677940_DATA_DEST = $(MOCHITEST_BROWSER_DEST)/browser_styleinspector_bug_677930_urls_clickable +INSTALL_TARGETS += MOCHITEST_BUG_677940_DATA From 520a763515c26dfbc10efae825fbcd0796ce7d20 Mon Sep 17 00:00:00 2001 From: Mike Hommey Date: Thu, 26 Sep 2013 16:43:53 +0900 Subject: [PATCH 04/84] Bug 920896 - Strip ./ from targets and dependencies in includedeps files. r=gps --- build/pymake/pymake/parserdata.py | 4 ++-- build/pymake/tests/includedeps-stripdotslash.deps | 1 + build/pymake/tests/includedeps-stripdotslash.mk | 8 ++++++++ 3 files changed, 11 insertions(+), 2 deletions(-) create mode 100644 build/pymake/tests/includedeps-stripdotslash.deps create mode 100644 build/pymake/tests/includedeps-stripdotslash.mk diff --git a/build/pymake/pymake/parserdata.py b/build/pymake/pymake/parserdata.py index 4df1e12ff10..7b2e5443d58 100644 --- a/build/pymake/pymake/parserdata.py +++ b/build/pymake/pymake/parserdata.py @@ -171,8 +171,8 @@ class Rule(Statement): # Skip targets with no rules and no dependencies if not deps: return - targets = self.targetexp.resolvesplit(makefile, makefile.variables) - rule = data.Rule(deps, self.doublecolon, loc=self.targetexp.loc, weakdeps=True) + targets = data.stripdotslashes(self.targetexp.resolvesplit(makefile, makefile.variables)) + rule = data.Rule(list(data.stripdotslashes(deps)), self.doublecolon, loc=self.targetexp.loc, weakdeps=True) for target in targets: makefile.gettarget(target).addrule(rule) makefile.foundtarget(target) diff --git a/build/pymake/tests/includedeps-stripdotslash.deps b/build/pymake/tests/includedeps-stripdotslash.deps new file mode 100644 index 00000000000..352fca1bb94 --- /dev/null +++ b/build/pymake/tests/includedeps-stripdotslash.deps @@ -0,0 +1 @@ +./test: TEST-PASS diff --git a/build/pymake/tests/includedeps-stripdotslash.mk b/build/pymake/tests/includedeps-stripdotslash.mk new file mode 100644 index 00000000000..ee942e6dbb9 --- /dev/null +++ b/build/pymake/tests/includedeps-stripdotslash.mk @@ -0,0 +1,8 @@ +#T gmake skip + +test: + @echo $< + +includedeps $(TESTPATH)/includedeps-stripdotslash.deps + +TEST-PASS: From 3057e0d19cf7fce431afdcbbd31d0db5f89a55e6 Mon Sep 17 00:00:00 2001 From: Georg Fritzsche Date: Thu, 26 Sep 2013 10:12:51 +0200 Subject: [PATCH 05/84] Bug 916542 - Guard against non-plugin elements in DOMWindowUtils.plugins. r=jaws --- browser/base/content/browser-plugins.js | 4 +- browser/base/content/test/general/Makefile.in | 1 + .../test/general/browser_CTP_nonplugins.js | 160 ++++++++++++++++++ 3 files changed, 164 insertions(+), 1 deletion(-) create mode 100644 browser/base/content/test/general/browser_CTP_nonplugins.js diff --git a/browser/base/content/browser-plugins.js b/browser/base/content/browser-plugins.js index 3716a1ac209..989ce986972 100644 --- a/browser/base/content/browser-plugins.js +++ b/browser/base/content/browser-plugins.js @@ -804,7 +804,9 @@ var gPluginHandler = { let contentDoc = aBrowser.contentDocument; let cwu = contentWindow.QueryInterface(Ci.nsIInterfaceRequestor) .getInterface(Ci.nsIDOMWindowUtils); - let plugins = cwu.plugins; + // cwu.plugins may contain non-plugin s, filter them out + let plugins = cwu.plugins.filter((plugin) => + plugin.getContentTypeForMIMEType(plugin.actualType) == Ci.nsIObjectLoadingContent.TYPE_PLUGIN); if (plugins.length == 0) { if (notification) { PopupNotifications.remove(notification); diff --git a/browser/base/content/test/general/Makefile.in b/browser/base/content/test/general/Makefile.in index b0b2e357a9a..bdbc8cce1a2 100644 --- a/browser/base/content/test/general/Makefile.in +++ b/browser/base/content/test/general/Makefile.in @@ -192,6 +192,7 @@ MOCHITEST_BROWSER_FILES = \ browser_contextSearchTabPosition.js \ browser_CTP_drag_drop.js \ browser_CTP_data_urls.js \ + browser_CTP_nonplugins.js \ browser_CTP_resize.js \ browser_ctrlTab.js \ browser_customize_popupNotification.js \ diff --git a/browser/base/content/test/general/browser_CTP_nonplugins.js b/browser/base/content/test/general/browser_CTP_nonplugins.js new file mode 100644 index 00000000000..4cf5c3c9850 --- /dev/null +++ b/browser/base/content/test/general/browser_CTP_nonplugins.js @@ -0,0 +1,160 @@ +var rootDir = getRootDirectory(gTestPath); +const gTestRoot = rootDir; +const gHttpTestRoot = rootDir.replace("chrome://mochitests/content/", "http://127.0.0.1:8888/"); + +var gTestBrowser = null; +var gNextTest = null; +var gPluginHost = Components.classes["@mozilla.org/plugin/host;1"].getService(Components.interfaces.nsIPluginHost); +var gRunNextTestAfterPluginRemoved = false; + +Components.utils.import("resource://gre/modules/Services.jsm"); + +// This listens for the next opened tab and checks it is of the right url. +// opencallback is called when the new tab is fully loaded +// closecallback is called when the tab is closed +function TabOpenListener(url, opencallback, closecallback) { + this.url = url; + this.opencallback = opencallback; + this.closecallback = closecallback; + + gBrowser.tabContainer.addEventListener("TabOpen", this, false); +} + +TabOpenListener.prototype = { + url: null, + opencallback: null, + closecallback: null, + tab: null, + browser: null, + + handleEvent: function(event) { + if (event.type == "TabOpen") { + gBrowser.tabContainer.removeEventListener("TabOpen", this, false); + this.tab = event.originalTarget; + this.browser = this.tab.linkedBrowser; + gBrowser.addEventListener("pageshow", this, false); + } else if (event.type == "pageshow") { + if (event.target.location.href != this.url) + return; + gBrowser.removeEventListener("pageshow", this, false); + this.tab.addEventListener("TabClose", this, false); + var url = this.browser.contentDocument.location.href; + is(url, this.url, "Should have opened the correct tab"); + this.opencallback(this.tab, this.browser.contentWindow); + } else if (event.type == "TabClose") { + if (event.originalTarget != this.tab) + return; + this.tab.removeEventListener("TabClose", this, false); + this.opencallback = null; + this.tab = null; + this.browser = null; + // Let the window close complete + executeSoon(this.closecallback); + this.closecallback = null; + } + } +}; + +function test() { + waitForExplicitFinish(); + registerCleanupFunction(function() { + clearAllPluginPermissions(); + Services.prefs.clearUserPref("extensions.blocklist.suppressUI"); + gTestBrowser.removeEventListener("PluginRemoved", handlePluginRemoved, true, true); + }); + Services.prefs.setBoolPref("extensions.blocklist.suppressUI", true); + + var newTab = gBrowser.addTab(); + gBrowser.selectedTab = newTab; + gTestBrowser = gBrowser.selectedBrowser; + gTestBrowser.addEventListener("load", pageLoad, true); + gTestBrowser.addEventListener("PluginRemoved", handlePluginRemoved, true, true); + + Services.prefs.setBoolPref("plugins.click_to_play", true); + setTestPluginEnabledState(Ci.nsIPluginTag.STATE_CLICKTOPLAY); + + prepareTest(runAfterPluginBindingAttached(test1), gHttpTestRoot + "plugin_two_types.html"); +} + +function finishTest() { + clearAllPluginPermissions(); + gTestBrowser.removeEventListener("load", pageLoad, true); + gBrowser.removeCurrentTab(); + window.focus(); + finish(); +} + +function pageLoad() { + // The plugin events are async dispatched and can come after the load event + // This just allows the events to fire before we then go on to test the states + executeSoon(gNextTest); +} + +function prepareTest(nextTest, url) { + gNextTest = nextTest; + gTestBrowser.contentWindow.location = url; +} + +// Due to layout being async, "PluginBindAttached" may trigger later. +// This wraps a function to force a layout flush, thus triggering it, +// and schedules the function execution so they're definitely executed +// afterwards. +function runAfterPluginBindingAttached(func) { + return function() { + let doc = gTestBrowser.contentDocument; + let elems = doc.getElementsByTagName('embed'); + if (elems.length < 1) { + elems = doc.getElementsByTagName('object'); + } + elems[0].clientTop; + executeSoon(func); + }; +} + +function handlePluginRemoved() { + if (gRunNextTestAfterPluginRemoved) { + executeSoon(gNextTest); + gRunNextTestAfterPluginRemoved = false; + } +} + +function runAfterPluginRemoved(func) { + gNextTest = func; + gRunNextTestAfterPluginRemoved = true; +} + +// Test that the click-to-play notification is not shown for non-plugin object elements + +function test1() { + let popupNotification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser); + ok(popupNotification, "Test 1, Should have a click-to-play notification"); + + let plugin = gTestBrowser.contentDocument.getElementById("secondtestA"); + plugin.parentNode.removeChild(plugin); + plugin = gTestBrowser.contentDocument.getElementById("secondtestB"); + plugin.parentNode.removeChild(plugin); + + let image = gTestBrowser.contentDocument.createElement("object"); + image.type = "image/png"; + image.data = "moz.png"; + gTestBrowser.contentDocument.body.appendChild(image); + + runAfterPluginRemoved(test2); +} + +function test2() { + let popupNotification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser); + ok(popupNotification, "Test 2, Should have a click-to-play notification"); + + let plugin = gTestBrowser.contentDocument.getElementById("test"); + plugin.parentNode.removeChild(plugin); + + runAfterPluginRemoved(() => executeSoon(test3)); +} + +function test3() { + let popupNotification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser); + ok(!popupNotification, "Test 3, Should not have a click-to-play notification"); + + finishTest(); +} From 44ae0315e3d31577edf85f4b5b436454353f362e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kan-Ru=20Chen=20=28=E9=99=B3=E4=BE=83=E5=A6=82=29?= Date: Thu, 26 Sep 2013 17:13:41 +0800 Subject: [PATCH 06/84] Bug 914026 - Check mDocShell before use. r=khuey --- dom/base/nsGlobalWindow.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dom/base/nsGlobalWindow.cpp b/dom/base/nsGlobalWindow.cpp index ca01e8f6198..c10458bf0f1 100644 --- a/dom/base/nsGlobalWindow.cpp +++ b/dom/base/nsGlobalWindow.cpp @@ -5999,7 +5999,7 @@ nsGlobalWindow::ResizeTo(int32_t aWidth, int32_t aHeight) * If caller is a browser-element then dispatch a resize event to * the embedder. */ - if (mDocShell->GetIsBrowserOrApp()) { + if (mDocShell && mDocShell->GetIsBrowserOrApp()) { nsIntSize size(aWidth, aHeight); if (!DispatchResizeEvent(size)) { // The embedder chose to prevent the default action for this @@ -6039,7 +6039,7 @@ nsGlobalWindow::ResizeBy(int32_t aWidthDif, int32_t aHeightDif) * If caller is a browser-element then dispatch a resize event to * parent. */ - if (mDocShell->GetIsBrowserOrApp()) { + if (mDocShell && mDocShell->GetIsBrowserOrApp()) { CSSIntSize size; nsresult rv = GetInnerSize(size); NS_ENSURE_SUCCESS(rv, NS_OK); From bf6062b284df9e3796756d69d0b5033d73442705 Mon Sep 17 00:00:00 2001 From: Blake Kaplan Date: Tue, 24 Sep 2013 11:01:15 +0200 Subject: [PATCH 07/84] Fix bug 916404. r=mccr8 --- .../html/content/src/HTMLTemplateElement.cpp | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/content/html/content/src/HTMLTemplateElement.cpp b/content/html/content/src/HTMLTemplateElement.cpp index eb48b4b0e9c..e7f85311e90 100644 --- a/content/html/content/src/HTMLTemplateElement.cpp +++ b/content/html/content/src/HTMLTemplateElement.cpp @@ -65,9 +65,20 @@ HTMLTemplateElement::~HTMLTemplateElement() NS_IMPL_ADDREF_INHERITED(HTMLTemplateElement, Element) NS_IMPL_RELEASE_INHERITED(HTMLTemplateElement, Element) -NS_IMPL_CYCLE_COLLECTION_INHERITED_1(HTMLTemplateElement, - nsGenericHTMLElement, - mContent) +NS_IMPL_CYCLE_COLLECTION_CLASS(HTMLTemplateElement) + +NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(HTMLTemplateElement, + nsGenericHTMLElement) + if (tmp->mContent) { + tmp->mContent->SetHost(nullptr); + tmp->mContent = nullptr; + } +NS_IMPL_CYCLE_COLLECTION_UNLINK_END + +NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(HTMLTemplateElement, + nsGenericHTMLElement) + NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mContent) +NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END // QueryInterface implementation for HTMLTemplateElement NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(HTMLTemplateElement) From aac3f11145c7404603608cac4f336d99c4acef4d Mon Sep 17 00:00:00 2001 From: Ed Morley Date: Thu, 26 Sep 2013 13:36:50 +0100 Subject: [PATCH 08/84] Bug 909937 - Output more useful error messages for |mach mercurial-setup| parsing exceptions; r=gps --- tools/mercurial/hgsetup/wizard.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/tools/mercurial/hgsetup/wizard.py b/tools/mercurial/hgsetup/wizard.py index cb42d82dd10..a465eff4870 100644 --- a/tools/mercurial/hgsetup/wizard.py +++ b/tools/mercurial/hgsetup/wizard.py @@ -10,6 +10,7 @@ import os import sys import which +from configobj import ConfigObjError from StringIO import StringIO from mozversioncontrol.repoupdate import ( @@ -105,7 +106,13 @@ class MercurialSetupWizard(object): 'up to date.') return 1 - c = MercurialConfig(config_paths) + try: + c = MercurialConfig(config_paths) + except ConfigObjError as e: + print('Error importing existing Mercurial config!\n' + '%s\n' + 'If using quotes, they must wrap the entire string.' % e) + return 1 print(INITIAL_MESSAGE) raw_input() From 878714ba073ac2f1f15b598b2d125ceeffa84964 Mon Sep 17 00:00:00 2001 From: Robert Longson Date: Thu, 26 Sep 2013 13:42:15 +0100 Subject: [PATCH 09/84] Bug 919900 - Correct bounding box calculations for empty text elements with svg.text.css-frames.enabled. r=heycam --- content/svg/content/test/bbox-helper.svg | 2 + content/svg/content/test/bounds-helper.svg | 5 ++ content/svg/content/test/test_bounds.html | 12 ++++ layout/svg/nsSVGTextFrame2.cpp | 78 +++++++++++++--------- 4 files changed, 65 insertions(+), 32 deletions(-) diff --git a/content/svg/content/test/bbox-helper.svg b/content/svg/content/test/bbox-helper.svg index 6aa2798129e..6ec055a53a3 100644 --- a/content/svg/content/test/bbox-helper.svg +++ b/content/svg/content/test/bbox-helper.svg @@ -21,6 +21,8 @@ + + diff --git a/content/svg/content/test/bounds-helper.svg b/content/svg/content/test/bounds-helper.svg index 599918dbf99..1fe00b9d1a5 100644 --- a/content/svg/content/test/bounds-helper.svg +++ b/content/svg/content/test/bounds-helper.svg @@ -27,5 +27,10 @@ text { font: 20px monospace; } + + + + + diff --git a/content/svg/content/test/test_bounds.html b/content/svg/content/test/test_bounds.html index a742f4b6890..fcd43ef36a4 100644 --- a/content/svg/content/test/test_bounds.html +++ b/content/svg/content/test/test_bounds.html @@ -141,6 +141,18 @@ function runTest() is(iBounds.width, 200, "i.getBoundingClientRect().width"); is(iBounds.height, 200, "i.getBoundingClientRect().height"); + var text4Bounds = doc.getElementById("text4").getBoundingClientRect(); + is(text4Bounds.left, 0, "text4.getBoundingClientRect().left"); + is(text4Bounds.top, 0, "text4.getBoundingClientRect().top"); + is(text4Bounds.width, 0, "text4.getBoundingClientRect().width"); + is(text4Bounds.height, 0, "text4.getBoundingClientRect().height"); + + var gBounds = doc.getElementById("g2").getBoundingClientRect(); + is(gBounds.left, 100, "g2.getBoundingClientRect().left"); + is(gBounds.top, 100, "g2.getBoundingClientRect().top"); + is(gBounds.width, 50, "g2.getBoundingClientRect().width"); + is(gBounds.height, 50, "g2.getBoundingClientRect().height"); + SimpleTest.finish(); } diff --git a/layout/svg/nsSVGTextFrame2.cpp b/layout/svg/nsSVGTextFrame2.cpp index dad4e14fe57..50d0f1bbd60 100644 --- a/layout/svg/nsSVGTextFrame2.cpp +++ b/layout/svg/nsSVGTextFrame2.cpp @@ -645,7 +645,7 @@ struct TextRenderedRun * eIncludeStroke) indicating what parts of the text to include in * the rectangle. */ - gfxRect GetRunUserSpaceRect(nsPresContext* aContext, uint32_t aFlags) const; + SVGBBox GetRunUserSpaceRect(nsPresContext* aContext, uint32_t aFlags) const; /** * Returns a rectangle that covers the fill and/or stroke of the rendered run @@ -682,7 +682,7 @@ struct TextRenderedRun * eIncludeStroke) indicating what parts of the text to include in * the rectangle. */ - gfxRect GetFrameUserSpaceRect(nsPresContext* aContext, uint32_t aFlags) const; + SVGBBox GetFrameUserSpaceRect(nsPresContext* aContext, uint32_t aFlags) const; /** * Returns a rectangle that covers the fill and/or stroke of the rendered run @@ -695,7 +695,7 @@ struct TextRenderedRun * frame user space rectangle before its bounds are transformed into * user space. */ - gfxRect GetUserSpaceRect(nsPresContext* aContext, uint32_t aFlags, + SVGBBox GetUserSpaceRect(nsPresContext* aContext, uint32_t aFlags, const gfxMatrix* aAdditionalTransform = nullptr) const; /** @@ -865,11 +865,11 @@ TextRenderedRun::GetTransformFromRunUserSpaceToFrameUserSpace( 0)); } -gfxRect +SVGBBox TextRenderedRun::GetRunUserSpaceRect(nsPresContext* aContext, uint32_t aFlags) const { - gfxRect r; + SVGBBox r; if (!mFrame) { return r; } @@ -930,28 +930,34 @@ TextRenderedRun::GetRunUserSpaceRect(nsPresContext* aContext, // Include the stroke if requested. if ((aFlags & eIncludeStroke) && nsSVGUtils::GetStrokeWidth(mFrame) > 0) { - r = r.Union(nsSVGUtils::PathExtentsToMaxStrokeExtents(fill, mFrame, - gfxMatrix())); + r.UnionEdges(nsSVGUtils::PathExtentsToMaxStrokeExtents(fill, mFrame, + gfxMatrix())); } return r; } -gfxRect +SVGBBox TextRenderedRun::GetFrameUserSpaceRect(nsPresContext* aContext, uint32_t aFlags) const { - gfxRect r = GetRunUserSpaceRect(aContext, aFlags); + SVGBBox r = GetRunUserSpaceRect(aContext, aFlags); + if (r.IsEmpty()) { + return r; + } gfxMatrix m = GetTransformFromRunUserSpaceToFrameUserSpace(aContext); return m.TransformBounds(r); } -gfxRect +SVGBBox TextRenderedRun::GetUserSpaceRect(nsPresContext* aContext, uint32_t aFlags, const gfxMatrix* aAdditionalTransform) const { - gfxRect r = GetRunUserSpaceRect(aContext, aFlags); + SVGBBox r = GetRunUserSpaceRect(aContext, aFlags); + if (r.IsEmpty()) { + return r; + } gfxMatrix m = GetTransformFromRunUserSpaceToUserSpace(aContext); if (aAdditionalTransform) { m.Multiply(*aAdditionalTransform); @@ -3307,16 +3313,17 @@ nsSVGTextFrame2::FindCloserFrameForSelection( uint32_t flags = TextRenderedRun::eIncludeFill | TextRenderedRun::eIncludeStroke | TextRenderedRun::eNoHorizontalOverflow; - gfxRect userRect = run.GetUserSpaceRect(presContext, flags); + SVGBBox userRect = run.GetUserSpaceRect(presContext, flags); + if (!userRect.IsEmpty()) { + nsRect rect = nsSVGUtils::ToCanvasBounds(userRect, + GetCanvasTM(FOR_HIT_TESTING), + presContext); - nsRect rect = nsSVGUtils::ToCanvasBounds(userRect, - GetCanvasTM(FOR_HIT_TESTING), - presContext); - - if (nsLayoutUtils::PointIsCloserToRect(aPoint, rect, - aCurrentBestFrame->mXDistance, - aCurrentBestFrame->mYDistance)) { - aCurrentBestFrame->mFrame = run.mFrame; + if (nsLayoutUtils::PointIsCloserToRect(aPoint, rect, + aCurrentBestFrame->mXDistance, + aCurrentBestFrame->mYDistance)) { + aCurrentBestFrame->mFrame = run.mFrame; + } } } } @@ -3640,7 +3647,7 @@ nsSVGTextFrame2::ReflowSVG() nsPresContext* presContext = PresContext(); - gfxRect r; + SVGBBox r; TextRenderedRunIterator it(this, TextRenderedRunIterator::eAllFrames); for (TextRenderedRun run = it.Current(); run.mFrame; run = it.Next()) { uint32_t runFlags = 0; @@ -3656,17 +3663,21 @@ nsSVGTextFrame2::ReflowSVG() } if (runFlags) { - r = r.Union(run.GetUserSpaceRect(presContext, runFlags)); + r.UnionEdges(run.GetUserSpaceRect(presContext, runFlags)); } } - mRect = - nsLayoutUtils::RoundGfxRectToAppRect(r, presContext->AppUnitsPerCSSPixel()); - // Due to rounding issues when we have a transform applied, we sometimes - // don't include an additional row of pixels. For now, just inflate our - // covered region. - mRect.Inflate(presContext->AppUnitsPerDevPixel()); + if (r.IsEmpty()) { + mRect.SetEmpty(); + } else { + mRect = + nsLayoutUtils::RoundGfxRectToAppRect(r, presContext->AppUnitsPerCSSPixel()); + // Due to rounding issues when we have a transform applied, we sometimes + // don't include an additional row of pixels. For now, just inflate our + // covered region. + mRect.Inflate(presContext->AppUnitsPerDevPixel()); + } if (mState & NS_FRAME_FIRST_REFLOW) { // Make sure we have our filter property (if any) before calling @@ -3719,15 +3730,15 @@ nsSVGTextFrame2::GetBBoxContribution(const gfxMatrix &aToBBoxUserspace, UpdateGlyphPositioning(); - gfxRect bbox; + SVGBBox bbox; nsPresContext* presContext = PresContext(); TextRenderedRunIterator it(this); for (TextRenderedRun run = it.Current(); run.mFrame; run = it.Next()) { uint32_t flags = TextRenderedRunFlagsForBBoxContribution(run, aFlags); - gfxRect bboxForRun = + SVGBBox bboxForRun = run.GetUserSpaceRect(presContext, flags, &aToBBoxUserspace); - bbox = bbox.Union(bboxForRun); + bbox.UnionEdges(bboxForRun); } return bbox; @@ -5304,7 +5315,10 @@ nsSVGTextFrame2::TransformFrameRectToTextChild(const gfxRect& aRect, // Intersect it with this run's rectangle. uint32_t flags = TextRenderedRun::eIncludeFill | TextRenderedRun::eIncludeStroke; - gfxRect runRectInFrameUserSpace = run.GetFrameUserSpaceRect(presContext, flags); + SVGBBox runRectInFrameUserSpace = run.GetFrameUserSpaceRect(presContext, flags); + if (runRectInFrameUserSpace.IsEmpty()) { + continue; + } gfxRect runIntersectionInFrameUserSpace = incomingRectInFrameUserSpace.Intersect(runRectInFrameUserSpace); From a1caaa978ab1ce628285ee53e1a3d0f06cb44e89 Mon Sep 17 00:00:00 2001 From: Monica Chew Date: Thu, 26 Sep 2013 06:51:59 -0700 Subject: [PATCH 10/84] Bug 842828: Clean up urlclassifier.gethashtables preferences (r=gcp) * * * Bug 842828: Mark attributes of nsIApplicationReputationQuery as readonly, remove unused field (r=mossop) * * * Bug 842828: Check local list to suppress remote lookups (r=paolo) --- b2g/app/b2g.js | 3 - browser/app/profile/firefox.js | 3 - browser/metro/profile/metro.js | 3 - mobile/android/app/mobile.js | 3 - modules/libpref/src/init/all.js | 6 + toolkit/components/build/nsToolkitCompsCID.h | 6 - .../components/build/nsToolkitCompsModule.cpp | 16 +- .../downloads/ApplicationReputation.cpp | 365 ++++++++++-------- .../downloads/ApplicationReputation.h | 66 +--- toolkit/components/downloads/moz.build | 8 +- .../downloads/nsIApplicationReputation.idl | 15 +- .../downloads/test/unit/data/digest.chunk | 2 + .../downloads/test/unit/test_app_rep.js | 180 +++++++-- .../downloads/test/unit/xpcshell.ini | 1 + .../url-classifier/SafeBrowsing.jsm | 10 +- toolkit/components/url-classifier/moz.build | 7 +- .../nsUrlClassifierDBService.cpp | 105 ++--- .../url-classifier/nsUrlClassifierDBService.h | 2 +- 18 files changed, 456 insertions(+), 345 deletions(-) create mode 100644 toolkit/components/downloads/test/unit/data/digest.chunk diff --git a/b2g/app/b2g.js b/b2g/app/b2g.js index 42e4c19149c..f0a99c76805 100644 --- a/b2g/app/b2g.js +++ b/b2g/app/b2g.js @@ -330,9 +330,6 @@ pref("urlclassifier.alternate_error_page", "blocked"); // The number of random entries to send with a gethash request. pref("urlclassifier.gethashnoise", 4); -// The list of tables that use the gethash request to confirm partial results. -pref("urlclassifier.gethashtables", "goog-phish-shavar,goog-malware-shavar"); - // If an urlclassifier table has not been updated in this number of seconds, // a gethash request will be forced to check that the result is still in // the database. diff --git a/browser/app/profile/firefox.js b/browser/app/profile/firefox.js index 4b9ebbc6ac3..f13caa8e32f 100644 --- a/browser/app/profile/firefox.js +++ b/browser/app/profile/firefox.js @@ -803,9 +803,6 @@ pref("urlclassifier.alternate_error_page", "blocked"); // The number of random entries to send with a gethash request. pref("urlclassifier.gethashnoise", 4); -// The list of tables that use the gethash request to confirm partial results. -pref("urlclassifier.gethashtables", "goog-phish-shavar,goog-malware-shavar"); - // If an urlclassifier table has not been updated in this number of seconds, // a gethash request will be forced to check that the result is still in // the database. diff --git a/browser/metro/profile/metro.js b/browser/metro/profile/metro.js index c87617f0ca2..346f8a3ef7d 100644 --- a/browser/metro/profile/metro.js +++ b/browser/metro/profile/metro.js @@ -607,9 +607,6 @@ pref("urlclassifier.alternate_error_page", "blocked"); // The number of random entries to send with a gethash request. pref("urlclassifier.gethashnoise", 4); -// The list of tables that use the gethash request to confirm partial results. -pref("urlclassifier.gethashtables", "goog-phish-shavar,goog-malware-shavar"); - // If an urlclassifier table has not been updated in this number of seconds, // a gethash request will be forced to check that the result is still in // the database. diff --git a/mobile/android/app/mobile.js b/mobile/android/app/mobile.js index 000e442e88d..c68a7f9eb4f 100644 --- a/mobile/android/app/mobile.js +++ b/mobile/android/app/mobile.js @@ -600,9 +600,6 @@ pref("urlclassifier.alternate_error_page", "blocked"); // The number of random entries to send with a gethash request. pref("urlclassifier.gethashnoise", 4); -// The list of tables that use the gethash request to confirm partial results. -pref("urlclassifier.gethashtables", "goog-phish-shavar,goog-malware-shavar"); - // If an urlclassifier table has not been updated in this number of seconds, // a gethash request will be forced to check that the result is still in // the database. diff --git a/modules/libpref/src/init/all.js b/modules/libpref/src/init/all.js index 89d2ecc8276..430f9f24024 100644 --- a/modules/libpref/src/init/all.js +++ b/modules/libpref/src/init/all.js @@ -4429,3 +4429,9 @@ pref("dom.telephony.enabled", false); // DOM Inter-App Communication API. pref("dom.inter-app-communication-api.enabled", false); + +// The tables used for Safebrowsing phishing and malware checks. +pref("urlclassifier.malware_table", "goog-malware-shavar"); +pref("urlclassifier.phish_table", "goog-phish-shavar"); +pref("urlclassifier.download_block_table", "goog-badbinurl-shavar"); +pref("urlclassifier.download_allow_table", "goog-downloadwhite-digest256"); diff --git a/toolkit/components/build/nsToolkitCompsCID.h b/toolkit/components/build/nsToolkitCompsCID.h index 9b25877e58f..b0b12f44f97 100644 --- a/toolkit/components/build/nsToolkitCompsCID.h +++ b/toolkit/components/build/nsToolkitCompsCID.h @@ -175,12 +175,6 @@ { 0xf3dcf644, 0x79e8, 0x4f59, { 0xa1, 0xbb, 0x87, 0x84, 0x54, 0x48, 0x8e, 0xf9 } } #endif -#define NS_APPLICATION_REPUTATION_QUERY_CONTRACTID \ - "@mozilla.org/downloads/application-reputation-query;1" - -#define NS_APPLICATION_REPUTATION_QUERY_CID \ -{ 0x857da2c0, 0xcfe5, 0x11e2, { 0x8b, 0x8b, 0x08, 0x00, 0x20, 0x0c, 0x9a, 0x66 } } - #define NS_APPLICATION_REPUTATION_SERVICE_CONTRACTID \ "@mozilla.org/downloads/application-reputation-service;1" diff --git a/toolkit/components/build/nsToolkitCompsModule.cpp b/toolkit/components/build/nsToolkitCompsModule.cpp index eb77441573f..991c3f07ccf 100644 --- a/toolkit/components/build/nsToolkitCompsModule.cpp +++ b/toolkit/components/build/nsToolkitCompsModule.cpp @@ -26,6 +26,7 @@ #include "nsTypeAheadFind.h" #ifdef MOZ_URL_CLASSIFIER +#include "ApplicationReputation.h" #include "nsUrlClassifierDBService.h" #include "nsUrlClassifierStreamUpdater.h" #include "nsUrlClassifierUtils.h" @@ -33,7 +34,6 @@ #endif #include "nsBrowserStatusFilter.h" -#include "ApplicationReputation.h" ///////////////////////////////////////////////////////////////////////////// @@ -55,6 +55,8 @@ NS_GENERIC_FACTORY_CONSTRUCTOR(nsDownloadProxy) NS_GENERIC_FACTORY_CONSTRUCTOR(nsTypeAheadFind) #ifdef MOZ_URL_CLASSIFIER +NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(ApplicationReputationService, + ApplicationReputationService::GetSingleton) NS_GENERIC_FACTORY_CONSTRUCTOR(nsUrlClassifierPrefixSet) NS_GENERIC_FACTORY_CONSTRUCTOR(nsUrlClassifierStreamUpdater) NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsUrlClassifierUtils, Init) @@ -79,16 +81,11 @@ nsUrlClassifierDBServiceConstructor(nsISupports *aOuter, REFNSIID aIID, } #endif -NS_GENERIC_FACTORY_CONSTRUCTOR(ApplicationReputationQuery) -NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(ApplicationReputationService, - ApplicationReputationService::GetSingleton) NS_GENERIC_FACTORY_CONSTRUCTOR(nsBrowserStatusFilter) #if defined(USE_MOZ_UPDATER) NS_GENERIC_FACTORY_CONSTRUCTOR(nsUpdateProcessor) #endif -NS_DEFINE_NAMED_CID(NS_APPLICATION_REPUTATION_QUERY_CID); -NS_DEFINE_NAMED_CID(NS_APPLICATION_REPUTATION_SERVICE_CID); NS_DEFINE_NAMED_CID(NS_TOOLKIT_APPSTARTUP_CID); NS_DEFINE_NAMED_CID(NS_USERINFO_CID); NS_DEFINE_NAMED_CID(NS_ALERTSSERVICE_CID); @@ -101,6 +98,7 @@ NS_DEFINE_NAMED_CID(NS_DOWNLOAD_CID); NS_DEFINE_NAMED_CID(NS_FIND_SERVICE_CID); NS_DEFINE_NAMED_CID(NS_TYPEAHEADFIND_CID); #ifdef MOZ_URL_CLASSIFIER +NS_DEFINE_NAMED_CID(NS_APPLICATION_REPUTATION_SERVICE_CID); NS_DEFINE_NAMED_CID(NS_URLCLASSIFIERPREFIXSET_CID); NS_DEFINE_NAMED_CID(NS_URLCLASSIFIERDBSERVICE_CID); NS_DEFINE_NAMED_CID(NS_URLCLASSIFIERSTREAMUPDATER_CID); @@ -113,8 +111,6 @@ NS_DEFINE_NAMED_CID(NS_UPDATEPROCESSOR_CID); #endif static const mozilla::Module::CIDEntry kToolkitCIDs[] = { - { &kNS_APPLICATION_REPUTATION_QUERY_CID, false, NULL, ApplicationReputationQueryConstructor }, - { &kNS_APPLICATION_REPUTATION_SERVICE_CID, false, NULL, ApplicationReputationServiceConstructor }, { &kNS_TOOLKIT_APPSTARTUP_CID, false, NULL, nsAppStartupConstructor }, { &kNS_USERINFO_CID, false, NULL, nsUserInfoConstructor }, { &kNS_ALERTSSERVICE_CID, false, NULL, nsAlertsServiceConstructor }, @@ -127,6 +123,7 @@ static const mozilla::Module::CIDEntry kToolkitCIDs[] = { { &kNS_FIND_SERVICE_CID, false, NULL, nsFindServiceConstructor }, { &kNS_TYPEAHEADFIND_CID, false, NULL, nsTypeAheadFindConstructor }, #ifdef MOZ_URL_CLASSIFIER + { &kNS_APPLICATION_REPUTATION_SERVICE_CID, false, NULL, ApplicationReputationServiceConstructor }, { &kNS_URLCLASSIFIERPREFIXSET_CID, false, NULL, nsUrlClassifierPrefixSetConstructor }, { &kNS_URLCLASSIFIERDBSERVICE_CID, false, NULL, nsUrlClassifierDBServiceConstructor }, { &kNS_URLCLASSIFIERSTREAMUPDATER_CID, false, NULL, nsUrlClassifierStreamUpdaterConstructor }, @@ -141,8 +138,6 @@ static const mozilla::Module::CIDEntry kToolkitCIDs[] = { }; static const mozilla::Module::ContractIDEntry kToolkitContracts[] = { - { NS_APPLICATION_REPUTATION_QUERY_CONTRACTID, &kNS_APPLICATION_REPUTATION_QUERY_CID }, - { NS_APPLICATION_REPUTATION_SERVICE_CONTRACTID, &kNS_APPLICATION_REPUTATION_SERVICE_CID }, { NS_APPSTARTUP_CONTRACTID, &kNS_TOOLKIT_APPSTARTUP_CID }, { NS_USERINFO_CONTRACTID, &kNS_USERINFO_CID }, { NS_ALERTSERVICE_CONTRACTID, &kNS_ALERTSSERVICE_CID }, @@ -155,6 +150,7 @@ static const mozilla::Module::ContractIDEntry kToolkitContracts[] = { { NS_FIND_SERVICE_CONTRACTID, &kNS_FIND_SERVICE_CID }, { NS_TYPEAHEADFIND_CONTRACTID, &kNS_TYPEAHEADFIND_CID }, #ifdef MOZ_URL_CLASSIFIER + { NS_APPLICATION_REPUTATION_SERVICE_CONTRACTID, &kNS_APPLICATION_REPUTATION_SERVICE_CID }, { NS_URLCLASSIFIERPREFIXSET_CONTRACTID, &kNS_URLCLASSIFIERPREFIXSET_CID }, { NS_URLCLASSIFIERDBSERVICE_CONTRACTID, &kNS_URLCLASSIFIERDBSERVICE_CID }, { NS_URICLASSIFIERSERVICE_CONTRACTID, &kNS_URLCLASSIFIERDBSERVICE_CID }, diff --git a/toolkit/components/downloads/ApplicationReputation.cpp b/toolkit/components/downloads/ApplicationReputation.cpp index 99c743f9ea7..9260e7715f5 100644 --- a/toolkit/components/downloads/ApplicationReputation.cpp +++ b/toolkit/components/downloads/ApplicationReputation.cpp @@ -11,12 +11,13 @@ #include "nsIChannel.h" #include "nsIHttpChannel.h" #include "nsIIOService.h" -#include "nsIObserverService.h" #include "nsIPrefService.h" +#include "nsIScriptSecurityManager.h" #include "nsIStreamListener.h" #include "nsIStringStream.h" #include "nsIUploadChannel2.h" #include "nsIURI.h" +#include "nsIUrlClassifierDBService.h" #include "mozilla/Preferences.h" #include "mozilla/Services.h" @@ -25,6 +26,7 @@ #include "nsDebug.h" #include "nsError.h" #include "nsNetCID.h" +#include "nsReadableUtils.h" #include "nsServiceManagerUtils.h" #include "nsString.h" #include "nsThreadUtils.h" @@ -38,79 +40,117 @@ using mozilla::Preferences; #define PREF_SB_APP_REP_URL "browser.safebrowsing.appRepURL" #define PREF_SB_MALWARE_ENABLED "browser.safebrowsing.malware.enabled" #define PREF_GENERAL_LOCALE "general.useragent.locale" +#define PREF_DOWNLOAD_BLOCK_TABLE "urlclassifier.download_block_table" +#define PREF_DOWNLOAD_ALLOW_TABLE "urlclassifier.download_allow_table" -NS_IMPL_ISUPPORTS1(ApplicationReputationService, nsIApplicationReputationService) +/** + * Keep track of pending lookups. Once the ApplicationReputationService creates + * this, it is guaranteed to call mCallback. This class is private to + * ApplicationReputationService. + */ +class PendingLookup MOZ_FINAL : + public nsIStreamListener, + public nsIUrlClassifierCallback { +public: + NS_DECL_ISUPPORTS + NS_DECL_NSIREQUESTOBSERVER + NS_DECL_NSISTREAMLISTENER + NS_DECL_NSIURLCLASSIFIERCALLBACK + PendingLookup(nsIApplicationReputationQuery* aQuery, + nsIApplicationReputationCallback* aCallback); + ~PendingLookup(); -ApplicationReputationService* ApplicationReputationService::gApplicationReputationService = nullptr; +private: + nsCOMPtr mQuery; + nsCOMPtr mCallback; + /** + * The response from the application reputation query. This is read in chunks + * as part of our nsIStreamListener implementation and may contain embedded + * NULLs. + */ + nsCString mResponse; + /** + * Clean up and call the callback. PendingLookup must not be used after this + * function is called. + */ + nsresult OnComplete(bool shouldBlock, nsresult rv); + /** + * Wrapper function for nsIStreamListener.onStopRequest to make it easy to + * guarantee calling the callback + */ + nsresult OnStopRequestInternal(nsIRequest *aRequest, + nsISupports *aContext, + nsresult aResult, + bool* aShouldBlock); + /** + * Sends a query to the remote application reputation service. Returns NS_OK + * on success. + */ + nsresult SendRemoteQuery(); +}; -ApplicationReputationService * -ApplicationReputationService::GetSingleton() -{ - if (gApplicationReputationService) { - NS_ADDREF(gApplicationReputationService); - return gApplicationReputationService; - } +NS_IMPL_ISUPPORTS3(PendingLookup, + nsIStreamListener, + nsIRequestObserver, + nsIUrlClassifierCallback) - gApplicationReputationService = new ApplicationReputationService(); - if (gApplicationReputationService) { - NS_ADDREF(gApplicationReputationService); - } - - return gApplicationReputationService; +PendingLookup::PendingLookup(nsIApplicationReputationQuery* aQuery, + nsIApplicationReputationCallback* aCallback) : + mQuery(aQuery), + mCallback(aCallback) { } -ApplicationReputationService::ApplicationReputationService() { } -ApplicationReputationService::~ApplicationReputationService() { } +PendingLookup::~PendingLookup() { +} +nsresult +PendingLookup::OnComplete(bool shouldBlock, nsresult rv) { + nsresult res = mCallback->OnComplete(shouldBlock, rv); + return res; +} + +//////////////////////////////////////////////////////////////////////////////// +//// nsIUrlClassifierCallback NS_IMETHODIMP -ApplicationReputationService::QueryReputation( - nsIApplicationReputationQuery* aQuery, - nsIApplicationReputationCallback* aCallback) { - NS_ENSURE_ARG_POINTER(aQuery); - NS_ENSURE_ARG_POINTER(aCallback); +PendingLookup::HandleEvent(const nsACString& tables) { + // HandleEvent is guaranteed to call the callback if either the URL can be + // classified locally, or if there is an error sending the remote lookup. + // Allow listing trumps block listing. + nsCString allow_list; + Preferences::GetCString(PREF_DOWNLOAD_ALLOW_TABLE, &allow_list); + if (FindInReadable(tables, allow_list)) { + return OnComplete(false, NS_OK); + } - nsresult rv = QueryReputationInternal(aQuery, aCallback); + nsCString block_list; + Preferences::GetCString(PREF_DOWNLOAD_BLOCK_TABLE, &block_list); + if (FindInReadable(tables, block_list)) { + return OnComplete(true, NS_OK); + } + + nsresult rv = SendRemoteQuery(); if (NS_FAILED(rv)) { - aCallback->OnComplete(false, rv); - aCallback = nullptr; + return OnComplete(false, rv); } return NS_OK; } nsresult -ApplicationReputationService::QueryReputationInternal( - nsIApplicationReputationQuery* aQuery, - nsIApplicationReputationCallback* aCallback) { - nsresult rv; - aQuery->SetCallback(aCallback); - - // If malware checks aren't enabled, don't query application reputation. - if (!Preferences::GetBool(PREF_SB_MALWARE_ENABLED, false)) { - return NS_ERROR_NOT_AVAILABLE; - } - - // If there is no service URL for querying application reputation, abort. - nsCString serviceUrl; - NS_ENSURE_SUCCESS(Preferences::GetCString(PREF_SB_APP_REP_URL, &serviceUrl), - NS_ERROR_NOT_AVAILABLE); - if (serviceUrl.EqualsLiteral("")) { - return NS_ERROR_NOT_AVAILABLE; - } - +PendingLookup::SendRemoteQuery() { + // We did not find a local result, so fire off the query to the application + // reputation service. safe_browsing::ClientDownloadRequest req; - + nsCOMPtr uri; + nsresult rv; + rv = mQuery->GetSourceURI(getter_AddRefs(uri)); + NS_ENSURE_SUCCESS(rv, rv); nsCString spec; - nsCOMPtr aURI; - rv = aQuery->GetSourceURI(getter_AddRefs(aURI)); + rv = uri->GetSpec(spec); NS_ENSURE_SUCCESS(rv, rv); - // If the URI hasn't been set, bail - NS_ENSURE_STATE(aURI); - rv = aURI->GetSpec(spec); - NS_ENSURE_SUCCESS(rv, rv); - req.set_url(spec.get()); + uint32_t fileSize; - rv = aQuery->GetFileSize(&fileSize); + rv = mQuery->GetFileSize(&fileSize); NS_ENSURE_SUCCESS(rv, rv); req.set_length(fileSize); // We have no way of knowing whether or not a user initiated the download. @@ -121,11 +161,11 @@ ApplicationReputationService::QueryReputationInternal( NS_ERROR_NOT_AVAILABLE); req.set_locale(locale.get()); nsCString sha256Hash; - rv = aQuery->GetSha256Hash(sha256Hash); + rv = mQuery->GetSha256Hash(sha256Hash); NS_ENSURE_SUCCESS(rv, rv); req.mutable_digests()->set_sha256(sha256Hash.Data()); nsString fileName; - rv = aQuery->GetSuggestedFileName(fileName); + rv = mQuery->GetSuggestedFileName(fileName); NS_ENSURE_SUCCESS(rv, rv); req.set_file_basename(NS_ConvertUTF16toUTF8(fileName).get()); @@ -150,6 +190,9 @@ ApplicationReputationService::QueryReputationInternal( // Set up the channel to transmit the request to the service. nsCOMPtr channel; + nsCString serviceUrl; + NS_ENSURE_SUCCESS(Preferences::GetCString(PREF_SB_APP_REP_URL, &serviceUrl), + NS_ERROR_NOT_AVAILABLE); rv = ios->NewChannel(serviceUrl, nullptr, nullptr, getter_AddRefs(channel)); NS_ENSURE_SUCCESS(rv, rv); @@ -171,96 +214,14 @@ ApplicationReputationService::QueryReputationInternal( NS_LITERAL_CSTRING("POST"), false); NS_ENSURE_SUCCESS(rv, rv); - nsCOMPtr listener = do_QueryInterface(aQuery, &rv); - NS_ENSURE_SUCCESS(rv, rv); - rv = channel->AsyncOpen(listener, nullptr); + rv = channel->AsyncOpen(this, nullptr); NS_ENSURE_SUCCESS(rv, rv); return NS_OK; } -NS_IMPL_ISUPPORTS3(ApplicationReputationQuery, - nsIApplicationReputationQuery, - nsIStreamListener, - nsIRequestObserver) - -ApplicationReputationQuery::ApplicationReputationQuery() : - mURI(nullptr), - mFileSize(0), - mCallback(nullptr) { -} - -ApplicationReputationQuery::~ApplicationReputationQuery() { -} - -NS_IMETHODIMP -ApplicationReputationQuery::GetSourceURI(nsIURI** aURI) { - *aURI = mURI; - NS_IF_ADDREF(*aURI); - return NS_OK; -} - -NS_IMETHODIMP -ApplicationReputationQuery::SetSourceURI(nsIURI* aURI) { - mURI = aURI; - return NS_OK; -} - -NS_IMETHODIMP -ApplicationReputationQuery::GetSuggestedFileName( - nsAString& aSuggestedFileName) { - aSuggestedFileName = mSuggestedFileName; - return NS_OK; -} - -NS_IMETHODIMP -ApplicationReputationQuery::SetSuggestedFileName( - const nsAString& aSuggestedFileName) { - mSuggestedFileName = aSuggestedFileName; - return NS_OK; -} - -NS_IMETHODIMP -ApplicationReputationQuery::GetFileSize(uint32_t* aFileSize) { - *aFileSize = mFileSize; - return NS_OK; -} - -NS_IMETHODIMP -ApplicationReputationQuery::SetFileSize(uint32_t aFileSize) { - mFileSize = aFileSize; - return NS_OK; -} - -NS_IMETHODIMP -ApplicationReputationQuery::GetSha256Hash(nsACString& aSha256Hash) { - aSha256Hash = mSha256Hash; - return NS_OK; -} - -NS_IMETHODIMP -ApplicationReputationQuery::SetSha256Hash(const nsACString& aSha256Hash) { - mSha256Hash = aSha256Hash; - return NS_OK; -} - -NS_IMETHODIMP -ApplicationReputationQuery::GetCallback( - nsIApplicationReputationCallback** aCallback) { - *aCallback = mCallback; - return NS_OK; -} - -NS_IMETHODIMP -ApplicationReputationQuery::SetCallback( - nsIApplicationReputationCallback* aCallback) { - mCallback = aCallback; - return NS_OK; -} - //////////////////////////////////////////////////////////////////////////////// //// nsIStreamListener - static NS_METHOD AppendSegmentToString(nsIInputStream* inputStream, void *closure, @@ -275,40 +236,39 @@ AppendSegmentToString(nsIInputStream* inputStream, } NS_IMETHODIMP -ApplicationReputationQuery::OnDataAvailable(nsIRequest *aRequest, - nsISupports *aContext, - nsIInputStream *aStream, - uint64_t offset, - uint32_t count) { +PendingLookup::OnDataAvailable(nsIRequest *aRequest, + nsISupports *aContext, + nsIInputStream *aStream, + uint64_t offset, + uint32_t count) { uint32_t read; return aStream->ReadSegments(AppendSegmentToString, &mResponse, count, &read); } NS_IMETHODIMP -ApplicationReputationQuery::OnStartRequest(nsIRequest *aRequest, - nsISupports *aContext) { +PendingLookup::OnStartRequest(nsIRequest *aRequest, + nsISupports *aContext) { return NS_OK; } NS_IMETHODIMP -ApplicationReputationQuery::OnStopRequest(nsIRequest *aRequest, - nsISupports *aContext, - nsresult aResult) { +PendingLookup::OnStopRequest(nsIRequest *aRequest, + nsISupports *aContext, + nsresult aResult) { NS_ENSURE_STATE(mCallback); bool shouldBlock = false; nsresult rv = OnStopRequestInternal(aRequest, aContext, aResult, &shouldBlock); - mCallback->OnComplete(shouldBlock, rv); - mCallback = nullptr; + OnComplete(shouldBlock, rv); return rv; } nsresult -ApplicationReputationQuery::OnStopRequestInternal(nsIRequest *aRequest, - nsISupports *aContext, - nsresult aResult, - bool* aShouldBlock) { +PendingLookup::OnStopRequestInternal(nsIRequest *aRequest, + nsISupports *aContext, + nsresult aResult, + bool* aShouldBlock) { *aShouldBlock = false; nsresult rv; nsCOMPtr channel = do_QueryInterface(aRequest, &rv); @@ -337,3 +297,98 @@ ApplicationReputationQuery::OnStopRequestInternal(nsIRequest *aRequest, return NS_OK; } + +NS_IMPL_ISUPPORTS1(ApplicationReputationService, + nsIApplicationReputationService) + +ApplicationReputationService* + ApplicationReputationService::gApplicationReputationService = nullptr; + +ApplicationReputationService* +ApplicationReputationService::GetSingleton() +{ + if (gApplicationReputationService) { + NS_ADDREF(gApplicationReputationService); + return gApplicationReputationService; + } + + // We're not initialized yet. + gApplicationReputationService = new ApplicationReputationService(); + if (gApplicationReputationService) { + NS_ADDREF(gApplicationReputationService); + } + + return gApplicationReputationService; +} + +ApplicationReputationService::ApplicationReputationService() : + mDBService(nullptr), + mSecurityManager(nullptr) { +} + +ApplicationReputationService::~ApplicationReputationService() { +} + +NS_IMETHODIMP +ApplicationReputationService::QueryReputation( + nsIApplicationReputationQuery* aQuery, + nsIApplicationReputationCallback* aCallback) { + NS_ENSURE_ARG_POINTER(aQuery); + NS_ENSURE_ARG_POINTER(aCallback); + + nsresult rv = QueryReputationInternal(aQuery, aCallback); + if (NS_FAILED(rv)) { + aCallback->OnComplete(false, rv); + } + return NS_OK; +} + +nsresult ApplicationReputationService::QueryReputationInternal( + nsIApplicationReputationQuery* aQuery, + nsIApplicationReputationCallback* aCallback) { + // Lazily instantiate mDBService and mSecurityManager + nsresult rv; + if (!mDBService) { + mDBService = do_GetService(NS_URLCLASSIFIERDBSERVICE_CONTRACTID, &rv); + NS_ENSURE_SUCCESS(rv, rv); + } + if (!mSecurityManager) { + mSecurityManager = do_GetService("@mozilla.org/scriptsecuritymanager;1", + &rv); + NS_ENSURE_SUCCESS(rv, rv); + } + // If malware checks aren't enabled, don't query application reputation. + if (!Preferences::GetBool(PREF_SB_MALWARE_ENABLED, false)) { + return NS_ERROR_NOT_AVAILABLE; + } + + // If there is no service URL for querying application reputation, abort. + nsCString serviceUrl; + NS_ENSURE_SUCCESS(Preferences::GetCString(PREF_SB_APP_REP_URL, &serviceUrl), + NS_ERROR_NOT_AVAILABLE); + if (serviceUrl.EqualsLiteral("")) { + return NS_ERROR_NOT_AVAILABLE; + } + + // Create a new pending lookup. + nsRefPtr lookup(new PendingLookup(aQuery, aCallback)); + NS_ENSURE_STATE(lookup); + + nsCOMPtr uri; + rv = aQuery->GetSourceURI(getter_AddRefs(uri)); + NS_ENSURE_SUCCESS(rv, rv); + // If the URI hasn't been set, bail + NS_ENSURE_STATE(uri); + nsCOMPtr principal; + // In nsIUrlClassifierDBService.lookup, the only use of the principal is to + // wrap the URI. nsISecurityManager.getNoAppCodebasePrincipal is the easiest + // way to wrap a URI inside a principal, since principals can't be + // constructed. + rv = mSecurityManager->GetNoAppCodebasePrincipal(uri, + getter_AddRefs(principal)); + NS_ENSURE_SUCCESS(rv, rv); + + // Check local lists to see if the URI has already been whitelisted or + // blacklisted. + return mDBService->Lookup(principal, lookup); +} diff --git a/toolkit/components/downloads/ApplicationReputation.h b/toolkit/components/downloads/ApplicationReputation.h index 775cf2fcda2..08c32f40773 100644 --- a/toolkit/components/downloads/ApplicationReputation.h +++ b/toolkit/components/downloads/ApplicationReputation.h @@ -15,11 +15,10 @@ #include "nsCOMPtr.h" #include "nsString.h" -class nsIApplicationReputationListener; -class nsIChannel; -class nsIObserverService; class nsIRequest; -class PRLogModuleInfo; +class nsIUrlClassifierDBService; +class nsIScriptSecurityManager; +class PendingLookup; class ApplicationReputationService MOZ_FINAL : public nsIApplicationReputationService { @@ -35,10 +34,16 @@ private: * Global singleton object for holding this factory service. */ static ApplicationReputationService* gApplicationReputationService; - + /** + * Keeps track of services used to query the local database of URLs. + */ + nsCOMPtr mDBService; + nsCOMPtr mSecurityManager; + /** + * This is a singleton, so disallow construction. + */ ApplicationReputationService(); ~ApplicationReputationService(); - /** * Wrapper function for QueryReputation that makes it easier to ensure the * callback is called. @@ -46,53 +51,4 @@ private: nsresult QueryReputationInternal(nsIApplicationReputationQuery* aQuery, nsIApplicationReputationCallback* aCallback); }; - -/** - * This class implements nsIApplicationReputation. See the - * nsIApplicationReputation.idl for details. ApplicationReputation also - * implements nsIStreamListener because it calls nsIChannel->AsyncOpen. - */ -class ApplicationReputationQuery MOZ_FINAL : - public nsIApplicationReputationQuery, - public nsIStreamListener { -public: - NS_DECL_ISUPPORTS - NS_DECL_NSIREQUESTOBSERVER - NS_DECL_NSISTREAMLISTENER - NS_DECL_NSIAPPLICATIONREPUTATIONQUERY - - ApplicationReputationQuery(); - ~ApplicationReputationQuery(); - -private: - /** - * Corresponding member variables for the attributes in the IDL. - */ - nsString mSuggestedFileName; - nsCOMPtr mURI; - uint32_t mFileSize; - nsCString mSha256Hash; - - /** - * The callback for the request. - */ - nsCOMPtr mCallback; - - /** - * The response from the application reputation query. This is read in chunks - * as part of our nsIStreamListener implementation and may contain embedded - * NULLs. - */ - nsCString mResponse; - - /** - * Wrapper function for nsIStreamListener.onStopRequest to make it easy to - * guarantee calling the callback - */ - nsresult OnStopRequestInternal(nsIRequest *aRequest, - nsISupports *aContext, - nsresult aResult, - bool* aShouldBlock); -}; - #endif /* ApplicationReputation_h__ */ diff --git a/toolkit/components/downloads/moz.build b/toolkit/components/downloads/moz.build index 5d7a8c10a9e..d540af9fce6 100644 --- a/toolkit/components/downloads/moz.build +++ b/toolkit/components/downloads/moz.build @@ -19,10 +19,14 @@ MODULE = 'downloads' CPP_SOURCES += [ 'SQLFunctions.cpp', 'nsDownloadManager.cpp', - 'ApplicationReputation.cpp', - 'csd.pb.cc' ] +if CONFIG['MOZ_URL_CLASSIFIER']: + CPP_SOURCES += [ + 'ApplicationReputation.cpp', + 'csd.pb.cc' + ] + if CONFIG['OS_ARCH'] == 'WINNT': CPP_SOURCES += [ 'nsDownloadScanner.cpp', diff --git a/toolkit/components/downloads/nsIApplicationReputation.idl b/toolkit/components/downloads/nsIApplicationReputation.idl index b947de9fecb..b346a8f4941 100644 --- a/toolkit/components/downloads/nsIApplicationReputation.idl +++ b/toolkit/components/downloads/nsIApplicationReputation.idl @@ -43,12 +43,12 @@ interface nsIApplicationReputationService : nsISupports { * downloaded file. nsIApplicationReputationService.Start() may only be called * once with a single query. */ -[scriptable, uuid(857da2c0-cfe5-11e2-8b8b-0800200c9a66)] +[scriptable, uuid(5a054991-e489-4a1c-a0aa-ea7c69b20e3d)] interface nsIApplicationReputationQuery : nsISupports { /* * The nsIURI from which the file was downloaded. This may not be null. */ - attribute nsIURI sourceURI; + readonly attribute nsIURI sourceURI; /* * The target filename for the downloaded file, as inferred from the source @@ -56,24 +56,19 @@ interface nsIApplicationReputationQuery : nsISupports { * is not set by the caller, it will be passed as an empty string but the * query won't produce any useful information. */ - attribute AString suggestedFileName; + readonly attribute AString suggestedFileName; /* * The size of the downloaded file in bytes. */ - attribute unsigned long fileSize; + readonly attribute unsigned long fileSize; /* * The SHA256 hash of the downloaded file in raw bytes. If this is not set by * the caller, it will be passed as an empty string but the query won't * produce any useful information. */ - attribute ACString sha256Hash; - - /** - * The callback object listening to this query. - */ - attribute nsIApplicationReputationCallback callback; + readonly attribute ACString sha256Hash; }; [scriptable, function, uuid(9a228470-cfe5-11e2-8b8b-0800200c9a66)] diff --git a/toolkit/components/downloads/test/unit/data/digest.chunk b/toolkit/components/downloads/test/unit/data/digest.chunk new file mode 100644 index 00000000000..738c96f6ba1 --- /dev/null +++ b/toolkit/components/downloads/test/unit/data/digest.chunk @@ -0,0 +1,2 @@ +a:5:32:32 +“Ê_Há^˜aÍ7ÂÙ]´=#ÌnmåÃøún‹æo—ÌQ‰ \ No newline at end of file diff --git a/toolkit/components/downloads/test/unit/test_app_rep.js b/toolkit/components/downloads/test/unit/test_app_rep.js index a77a75202e1..c7155c339bf 100644 --- a/toolkit/components/downloads/test/unit/test_app_rep.js +++ b/toolkit/components/downloads/test/unit/test_app_rep.js @@ -7,13 +7,47 @@ Cu.import('resource://gre/modules/NetUtil.jsm'); Cu.import("resource://gre/modules/XPCOMUtils.jsm"); -const ApplicationReputationQuery = Components.Constructor( - "@mozilla.org/downloads/application-reputation-query;1", - "nsIApplicationReputationQuery"); - const gAppRep = Cc["@mozilla.org/downloads/application-reputation-service;1"]. getService(Ci.nsIApplicationReputationService); let gHttpServ = null; +let gTables = {}; + +function readFileToString(aFilename) { + let f = do_get_file(aFilename); + let stream = Cc["@mozilla.org/network/file-input-stream;1"] + .createInstance(Ci.nsIFileInputStream); + stream.init(f, -1, 0, 0); + let buf = NetUtil.readInputStreamToString(stream, stream.available()); + return buf; +} + +// Registers a table for which to serve update chunks. Returns a promise that +// resolves when that chunk has been downloaded. +function registerTableUpdate(aTable, aFilename) { + // If we haven't been given an update for this table yet, add it to the map + if (!(aTable in gTables)) { + gTables[aTable] = []; + } + + // The number of chunks associated with this table. + let numChunks = gTables[aTable].length + 1; + let redirectPath = "/" + aTable + "-" + numChunks; + let redirectUrl = "localhost:4444" + redirectPath; + + // Store redirect url for that table so we can return it later when we + // process an update request. + gTables[aTable].push(redirectUrl); + + gHttpServ.registerPathHandler(redirectPath, function(request, response) { + do_print("Mock safebrowsing server handling request for " + redirectPath); + let contents = readFileToString(aFilename); + do_print("Length of " + aFilename + ": " + contents.length); + response.setHeader("Content-Type", + "application/vnd.google.safebrowsing-update", false); + response.setStatusLine(request.httpVersion, 200, "OK"); + response.bodyOutputStream.write(contents, contents.length); + }); +} function run_test() { // Set up a local HTTP server to return bad verdicts. @@ -49,13 +83,16 @@ function run_test() { request.bodyInputStream, request.bodyInputStream.available()); do_print("Request length: " + buf.length); - // A garbage response. + // A garbage response. By default this produces NS_CANNOT_CONVERT_DATA as + // the callback status. let blob = "this is not a serialized protocol buffer"; // We can't actually parse the protocol buffer here, so just switch on the // length instead of inspecting the contents. if (buf.length == 35) { + // evil.com blob = createVerdict(true); } else if (buf.length == 38) { + // mozilla.com blob = createVerdict(false); } response.bodyOutputStream.write(blob, blob.length); @@ -67,11 +104,10 @@ function run_test() { } add_test(function test_shouldBlock() { - let query = new ApplicationReputationQuery(); - query.sourceURI = createURI("http://evil.com"); - query.fileSize = 12; - - gAppRep.queryReputation(query, function onComplete(aShouldBlock, aStatus) { + gAppRep.queryReputation({ + sourceURI: createURI("http://evil.com"), + fileSize: 12, + }, function onComplete(aShouldBlock, aStatus) { do_check_true(aShouldBlock); do_check_eq(Cr.NS_OK, aStatus); run_next_test(); @@ -79,35 +115,21 @@ add_test(function test_shouldBlock() { }); add_test(function test_shouldNotBlock() { - let query = new ApplicationReputationQuery(); - query.sourceURI = createURI("http://mozilla.com"); - query.fileSize = 12; - - gAppRep.queryReputation(query, function onComplete(aShouldBlock, aStatus) { + gAppRep.queryReputation({ + sourceURI: createURI("http://mozilla.com"), + fileSize: 12, + }, function onComplete(aShouldBlock, aStatus) { do_check_eq(Cr.NS_OK, aStatus); do_check_false(aShouldBlock); run_next_test(); }); }); -add_test(function test_garbage() { - let query = new ApplicationReputationQuery(); - query.sourceURI = createURI("http://thisisagarbageurl.com"); - query.fileSize = 12; - - gAppRep.queryReputation(query, function onComplete(aShouldBlock, aStatus) { - // We should be getting the garbage response. - do_check_eq(Cr.NS_ERROR_CANNOT_CONVERT_DATA, aStatus); - do_check_false(aShouldBlock); - run_next_test(); - }); -}); - add_test(function test_nullSourceURI() { - let query = new ApplicationReputationQuery(); - query.fileSize = 12; - // No source URI - gAppRep.queryReputation(query, function onComplete(aShouldBlock, aStatus) { + gAppRep.queryReputation({ + // No source URI + fileSize: 12, + }, function onComplete(aShouldBlock, aStatus) { do_check_eq(Cr.NS_ERROR_UNEXPECTED, aStatus); do_check_false(aShouldBlock); run_next_test(); @@ -115,10 +137,11 @@ add_test(function test_nullSourceURI() { }); add_test(function test_nullCallback() { - let query = new ApplicationReputationQuery(); - query.fileSize = 12; try { - gAppRep.queryReputation(query, null); + gAppRep.queryReputation({ + sourceURI: createURI("http://example.com"), + fileSize: 12, + }, null); do_throw("Callback cannot be null"); } catch (ex if ex.result == Cr.NS_ERROR_INVALID_POINTER) { run_next_test(); @@ -127,13 +150,92 @@ add_test(function test_nullCallback() { add_test(function test_disabled() { Services.prefs.setCharPref("browser.safebrowsing.appRepURL", ""); - let query = new ApplicationReputationQuery(); - query.sourceURI = createURI("http://example.com"); - query.fileSize = 12; - gAppRep.queryReputation(query, function onComplete(aShouldBlock, aStatus) { + gAppRep.queryReputation({ + sourceURI: createURI("http://example.com"), + fileSize: 12, + }, function onComplete(aShouldBlock, aStatus) { // We should be getting NS_ERROR_NOT_AVAILABLE if the service is disabled do_check_eq(Cr.NS_ERROR_NOT_AVAILABLE, aStatus); do_check_false(aShouldBlock); run_next_test(); }); }); + +add_test(function test_garbage() { + Services.prefs.setCharPref("browser.safebrowsing.appRepURL", + "http://localhost:4444/download"); + gAppRep.queryReputation({ + sourceURI: createURI("http://whitelisted.com"), + fileSize: 12, + }, function onComplete(aShouldBlock, aStatus) { + // We should be getting the garbage response. + do_check_eq(Cr.NS_ERROR_CANNOT_CONVERT_DATA, aStatus); + do_check_false(aShouldBlock); + run_next_test(); + }); +}); + +// Set up the local whitelist. +add_test(function test_local_list() { + // Construct a response with redirect urls. + function processUpdateRequest() { + let response = "n:1000\n"; + for (let table in gTables) { + response += "i:" + table + "\n"; + for (let i = 0; i < gTables[table].length; ++i) { + response += "u:" + gTables[table][i] + "\n"; + } + } + do_print("Returning update response: " + response); + return response; + } + gHttpServ.registerPathHandler("/downloads", function(request, response) { + let buf = NetUtil.readInputStreamToString(request.bodyInputStream, + request.bodyInputStream.available()); + let blob = processUpdateRequest(); + response.setHeader("Content-Type", + "application/vnd.google.safebrowsing-update", false); + response.setStatusLine(request.httpVersion, 200, "OK"); + response.bodyOutputStream.write(blob, blob.length); + }); + + let streamUpdater = Cc["@mozilla.org/url-classifier/streamupdater;1"] + .getService(Ci.nsIUrlClassifierStreamUpdater); + streamUpdater.updateUrl = "http://localhost:4444/downloads"; + + // Load up some update chunks for the safebrowsing server to serve. This + // particular chunk contains the hash of whitelisted.com/. + registerTableUpdate("goog-downloadwhite-digest256", "data/digest.chunk"); + + // Download some updates, and don't continue until the downloads are done. + function updateSuccess(aEvent) { + // Timeout of n:1000 is constructed in processUpdateRequest above and + // passed back in the callback in nsIUrlClassifierStreamUpdater on success. + do_check_eq("1000", aEvent); + do_print("All data processed"); + run_next_test(); + } + // Just throw if we ever get an update or download error. + function handleError(aEvent) { + do_throw("We didn't download or update correctly: " + aEvent); + } + streamUpdater.downloadUpdates( + "goog-downloadwhite-digest256", + "goog-downloadwhite-digest256;\n", "", + updateSuccess, handleError, handleError); +}); + +// After being whitelisted, we shouldn't throw. +add_test(function test_local_whitelist() { + Services.prefs.setCharPref("browser.safebrowsing.appRepURL", + "http://localhost:4444/download"); + gAppRep.queryReputation({ + sourceURI: createURI("http://whitelisted.com"), + fileSize: 12, + }, function onComplete(aShouldBlock, aStatus) { + // We would get garbage if this query made it to the remote server. + do_check_eq(Cr.NS_OK, aStatus); + do_check_false(aShouldBlock); + run_next_test(); + }); +}); diff --git a/toolkit/components/downloads/test/unit/xpcshell.ini b/toolkit/components/downloads/test/unit/xpcshell.ini index 07d8c7c1820..5ce9a32c5b4 100644 --- a/toolkit/components/downloads/test/unit/xpcshell.ini +++ b/toolkit/components/downloads/test/unit/xpcshell.ini @@ -8,6 +8,7 @@ support-files = downloads_manifest.js empty_downloads.rdf test_downloads.manifest + data/digest.chunk [test_app_rep.js] [test_bug_382825.js] diff --git a/toolkit/components/url-classifier/SafeBrowsing.jsm b/toolkit/components/url-classifier/SafeBrowsing.jsm index 099d38da0f6..5f6df334eeb 100644 --- a/toolkit/components/url-classifier/SafeBrowsing.jsm +++ b/toolkit/components/url-classifier/SafeBrowsing.jsm @@ -10,8 +10,12 @@ const Cu = Components.utils; Cu.import("resource://gre/modules/Services.jsm"); -const [phishingList, malwareList] = - Services.prefs.getCharPref("urlclassifier.gethashtables").split(",").map(function(value) value.trim()); +const phishingList = Services.prefs.getCharPref("urlclassifier.phish_table"); +const malwareList = Services.prefs.getCharPref("urlclassifier.malware_table"); +const downloadBlockList = + Services.prefs.getCharPref("urlclassifier.download_block_table"); +const downloadAllowList = + Services.prefs.getCharPref("urlclassifier.download_allow_table"); var debug = false; function log(...stuff) { @@ -39,6 +43,8 @@ this.SafeBrowsing = { getService(Ci.nsIUrlListManager); listManager.registerTable(phishingList, false); listManager.registerTable(malwareList, false); + listManager.registerTable(downloadBlockList, false); + listManager.registerTable(downloadAllowList, false); this.addMozEntries(); this.controlUpdateChecking(); diff --git a/toolkit/components/url-classifier/moz.build b/toolkit/components/url-classifier/moz.build index 4112828827f..251006acf45 100644 --- a/toolkit/components/url-classifier/moz.build +++ b/toolkit/components/url-classifier/moz.build @@ -48,9 +48,14 @@ EXTRA_JS_MODULES += [ 'SafeBrowsing.jsm', ] +EXPORTS += [ + 'Entries.h', + 'LookupCache.h', + 'nsUrlClassifierPrefixSet.h', +] + FAIL_ON_WARNINGS = True LIBXUL_LIBRARY = True MSVC_ENABLE_PGO = True - diff --git a/toolkit/components/url-classifier/nsUrlClassifierDBService.cpp b/toolkit/components/url-classifier/nsUrlClassifierDBService.cpp index fbda1291ff1..e970a9b6284 100644 --- a/toolkit/components/url-classifier/nsUrlClassifierDBService.cpp +++ b/toolkit/components/url-classifier/nsUrlClassifierDBService.cpp @@ -33,6 +33,7 @@ #include "mozilla/Atomics.h" #include "mozilla/DebugOnly.h" #include "mozilla/Mutex.h" +#include "mozilla/Preferences.h" #include "mozilla/TimeStamp.h" #include "mozilla/Telemetry.h" #include "prlog.h" @@ -68,7 +69,10 @@ PRLogModuleInfo *gUrlClassifierDbServiceLog = nullptr; #define GETHASH_NOISE_PREF "urlclassifier.gethashnoise" #define GETHASH_NOISE_DEFAULT 4 -#define GETHASH_TABLES_PREF "urlclassifier.gethashtables" +#define MALWARE_TABLE_PREF "urlclassifier.malware_table" +#define PHISH_TABLE_PREF "urlclassifier.phish_table" +#define DOWNLOAD_BLOCK_TABLE_PREF "urlclassifier.download_block_table" +#define DOWNLOAD_ALLOW_TABLE_PREF "urlclassifier.download_allow_table" #define CONFIRM_AGE_PREF "urlclassifier.max-complete-age" #define CONFIRM_AGE_DEFAULT_SEC (45 * 60) @@ -1115,43 +1119,34 @@ nsUrlClassifierDBService::Init() gUrlClassifierDbServiceLog = PR_NewLogModule("UrlClassifierDbService"); #endif - nsresult rv; + // Retrieve all the preferences. + mCheckMalware = Preferences::GetBool(CHECK_MALWARE_PREF, + CHECK_MALWARE_DEFAULT); + mCheckPhishing = Preferences::GetBool(CHECK_PHISHING_PREF, + CHECK_PHISHING_DEFAULT); + uint32_t gethashNoise = Preferences::GetUint(GETHASH_NOISE_PREF, + GETHASH_NOISE_DEFAULT); + gFreshnessGuarantee = Preferences::GetInt(CONFIRM_AGE_PREF, + CONFIRM_AGE_DEFAULT_SEC); + mGethashTables.AppendElement(Preferences::GetCString(PHISH_TABLE_PREF)); + mGethashTables.AppendElement(Preferences::GetCString(MALWARE_TABLE_PREF)); + mGethashTables.AppendElement(Preferences::GetCString( + DOWNLOAD_BLOCK_TABLE_PREF)); + mGethashTables.AppendElement(Preferences::GetCString( + DOWNLOAD_ALLOW_TABLE_PREF)); - // Should we check document loads for malware URIs? - nsCOMPtr prefs = do_GetService(NS_PREFSERVICE_CONTRACTID); - - uint32_t gethashNoise = 0; - if (prefs) { - bool tmpbool; - rv = prefs->GetBoolPref(CHECK_MALWARE_PREF, &tmpbool); - mCheckMalware = NS_SUCCEEDED(rv) ? tmpbool : CHECK_MALWARE_DEFAULT; - - prefs->AddObserver(CHECK_MALWARE_PREF, this, false); - - rv = prefs->GetBoolPref(CHECK_PHISHING_PREF, &tmpbool); - mCheckPhishing = NS_SUCCEEDED(rv) ? tmpbool : CHECK_PHISHING_DEFAULT; - - prefs->AddObserver(CHECK_PHISHING_PREF, this, false); - - int32_t tmpint; - rv = prefs->GetIntPref(GETHASH_NOISE_PREF, &tmpint); - gethashNoise = (NS_SUCCEEDED(rv) && tmpint >= 0) ? - static_cast(tmpint) : GETHASH_NOISE_DEFAULT; - - nsXPIDLCString tmpstr; - if (NS_SUCCEEDED(prefs->GetCharPref(GETHASH_TABLES_PREF, getter_Copies(tmpstr)))) { - SplitTables(tmpstr, mGethashWhitelist); - } - - prefs->AddObserver(GETHASH_TABLES_PREF, this, false); - - rv = prefs->GetIntPref(CONFIRM_AGE_PREF, &tmpint); - gFreshnessGuarantee = NS_SUCCEEDED(rv) ? tmpint : CONFIRM_AGE_DEFAULT_SEC; - - prefs->AddObserver(CONFIRM_AGE_PREF, this, false); - } + // Do we *really* need to be able to change all of these at runtime? + Preferences::AddStrongObserver(this, CHECK_MALWARE_PREF); + Preferences::AddStrongObserver(this, CHECK_PHISHING_PREF); + Preferences::AddStrongObserver(this, GETHASH_NOISE_PREF); + Preferences::AddStrongObserver(this, CONFIRM_AGE_PREF); + Preferences::AddStrongObserver(this, PHISH_TABLE_PREF); + Preferences::AddStrongObserver(this, MALWARE_TABLE_PREF); + Preferences::AddStrongObserver(this, DOWNLOAD_BLOCK_TABLE_PREF); + Preferences::AddStrongObserver(this, DOWNLOAD_ALLOW_TABLE_PREF); // Force PSM loading on main thread + nsresult rv; nsCOMPtr acryptoHash = do_CreateInstance(NS_CRYPTO_HASH_CONTRACTID, &rv); NS_ENSURE_SUCCESS(rv, rv); @@ -1429,7 +1424,7 @@ nsUrlClassifierDBService::GetCompleter(const nsACString &tableName, return true; } - if (!mGethashWhitelist.Contains(tableName)) { + if (!mGethashTables.Contains(tableName)) { return false; } @@ -1446,23 +1441,26 @@ nsUrlClassifierDBService::Observe(nsISupports *aSubject, const char *aTopic, nsCOMPtr prefs(do_QueryInterface(aSubject, &rv)); NS_ENSURE_SUCCESS(rv, rv); if (NS_LITERAL_STRING(CHECK_MALWARE_PREF).Equals(aData)) { - bool tmpbool; - rv = prefs->GetBoolPref(CHECK_MALWARE_PREF, &tmpbool); - mCheckMalware = NS_SUCCEEDED(rv) ? tmpbool : CHECK_MALWARE_DEFAULT; + mCheckMalware = Preferences::GetBool(CHECK_MALWARE_PREF, + CHECK_MALWARE_DEFAULT); } else if (NS_LITERAL_STRING(CHECK_PHISHING_PREF).Equals(aData)) { - bool tmpbool; - rv = prefs->GetBoolPref(CHECK_PHISHING_PREF, &tmpbool); - mCheckPhishing = NS_SUCCEEDED(rv) ? tmpbool : CHECK_PHISHING_DEFAULT; - } else if (NS_LITERAL_STRING(GETHASH_TABLES_PREF).Equals(aData)) { - mGethashWhitelist.Clear(); - nsXPIDLCString val; - if (NS_SUCCEEDED(prefs->GetCharPref(GETHASH_TABLES_PREF, getter_Copies(val)))) { - SplitTables(val, mGethashWhitelist); - } + mCheckPhishing = Preferences::GetBool(CHECK_PHISHING_PREF, + CHECK_PHISHING_DEFAULT); + } else if (NS_LITERAL_STRING(PHISH_TABLE_PREF).Equals(aData) || + NS_LITERAL_STRING(MALWARE_TABLE_PREF).Equals(aData) || + NS_LITERAL_STRING(DOWNLOAD_BLOCK_TABLE_PREF).Equals(aData) || + NS_LITERAL_STRING(DOWNLOAD_ALLOW_TABLE_PREF).Equals(aData)) { + // Just read everything again. + mGethashTables.Clear(); + mGethashTables.AppendElement(Preferences::GetCString(PHISH_TABLE_PREF)); + mGethashTables.AppendElement(Preferences::GetCString(MALWARE_TABLE_PREF)); + mGethashTables.AppendElement(Preferences::GetCString( + DOWNLOAD_BLOCK_TABLE_PREF)); + mGethashTables.AppendElement(Preferences::GetCString( + DOWNLOAD_ALLOW_TABLE_PREF)); } else if (NS_LITERAL_STRING(CONFIRM_AGE_PREF).Equals(aData)) { - int32_t tmpint; - rv = prefs->GetIntPref(CONFIRM_AGE_PREF, &tmpint); - gFreshnessGuarantee = NS_SUCCEEDED(rv) ? tmpint : CONFIRM_AGE_DEFAULT_SEC; + gFreshnessGuarantee = Preferences::GetInt(CONFIRM_AGE_PREF, + CONFIRM_AGE_DEFAULT_SEC); } } else if (!strcmp(aTopic, "profile-before-change") || !strcmp(aTopic, "xpcom-shutdown-threads")) { @@ -1489,7 +1487,10 @@ nsUrlClassifierDBService::Shutdown() if (prefs) { prefs->RemoveObserver(CHECK_MALWARE_PREF, this); prefs->RemoveObserver(CHECK_PHISHING_PREF, this); - prefs->RemoveObserver(GETHASH_TABLES_PREF, this); + prefs->RemoveObserver(PHISH_TABLE_PREF, this); + prefs->RemoveObserver(MALWARE_TABLE_PREF, this); + prefs->RemoveObserver(DOWNLOAD_BLOCK_TABLE_PREF, this); + prefs->RemoveObserver(DOWNLOAD_ALLOW_TABLE_PREF, this); prefs->RemoveObserver(CONFIRM_AGE_PREF, this); } diff --git a/toolkit/components/url-classifier/nsUrlClassifierDBService.h b/toolkit/components/url-classifier/nsUrlClassifierDBService.h index f3f6a63cda4..a951b2ee4d9 100644 --- a/toolkit/components/url-classifier/nsUrlClassifierDBService.h +++ b/toolkit/components/url-classifier/nsUrlClassifierDBService.h @@ -101,7 +101,7 @@ private: bool mInUpdate; // The list of tables that can use the default hash completer object. - nsTArray mGethashWhitelist; + nsTArray mGethashTables; // Thread that we do the updates on. static nsIThread* gDbBackgroundThread; From b5c3752a03b7068309332201b8d00da2aeb00799 Mon Sep 17 00:00:00 2001 From: "Brian R. Bondy" Date: Thu, 26 Sep 2013 09:54:45 -0400 Subject: [PATCH 11/84] Bug 911158 - Removal of URL Protocol from FirefoxURL causes problems for some users. r=jimm --- browser/installer/windows/nsis/installer.nsi | 2 +- browser/installer/windows/nsis/shared.nsh | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/browser/installer/windows/nsis/installer.nsi b/browser/installer/windows/nsis/installer.nsi index b292b7ad224..7b83e8f5714 100755 --- a/browser/installer/windows/nsis/installer.nsi +++ b/browser/installer/windows/nsis/installer.nsi @@ -341,7 +341,7 @@ Section "-Application" APP_IDX ${AddDisabledDDEHandlerValues} "FirefoxHTML" "$2" "$8,1" \ "${AppRegName} Document" "" ${AddDisabledDDEHandlerValues} "FirefoxURL" "$2" "$8,1" "${AppRegName} URL" \ - "delete" + "true" ; For pre win8, the following keys should only be set if we can write to HKLM. ; For post win8, the keys below get set in both HKLM and HKCU. diff --git a/browser/installer/windows/nsis/shared.nsh b/browser/installer/windows/nsis/shared.nsh index 958ea545006..1c38bfb8f13 100755 --- a/browser/installer/windows/nsis/shared.nsh +++ b/browser/installer/windows/nsis/shared.nsh @@ -415,7 +415,7 @@ FunctionEnd "${AppRegName} HTML Document" "" ${AddDisabledDDEHandlerValues} "FirefoxURL" "$2" "$8,1" "${AppRegName} URL" \ - "delete" + "true" Call RegisterCEH ; An empty string is used for the 4th & 5th params because the following @@ -653,7 +653,7 @@ FunctionEnd ${IsHandlerForInstallDir} "FirefoxURL" $R9 ${If} "$R9" == "true" ${AddDisabledDDEHandlerValues} "FirefoxURL" "$2" "$8,1" \ - "${AppRegName} URL" "delete" + "${AppRegName} URL" "true" ${EndIf} ; An empty string is used for the 4th & 5th params because the following From 0e2ea5ca69ba5a2cee92df36325249578298ade0 Mon Sep 17 00:00:00 2001 From: Milan Sreckovic Date: Wed, 25 Sep 2013 13:06:22 -0400 Subject: [PATCH 12/84] Bug 856616 - Post size in the global header, rather than continuing with the processing, if all we need is a size decode. r=seth --- image/decoders/nsGIFDecoder2.cpp | 6 ++++++ image/test/crashtests/856616.gif | Bin 0 -> 27 bytes image/test/crashtests/crashtests.list | 4 ++++ 3 files changed, 10 insertions(+) create mode 100644 image/test/crashtests/856616.gif diff --git a/image/decoders/nsGIFDecoder2.cpp b/image/decoders/nsGIFDecoder2.cpp index 6aecbe69187..5f4d1a2709d 100644 --- a/image/decoders/nsGIFDecoder2.cpp +++ b/image/decoders/nsGIFDecoder2.cpp @@ -665,6 +665,12 @@ nsGIFDecoder2::WriteInternal(const char *aBuffer, uint32_t aCount) mGIFStruct.screen_height = GETINT16(q + 2); mGIFStruct.global_colormap_depth = (q[4]&0x07) + 1; + if (IsSizeDecode()) { + MOZ_ASSERT(!mGIFOpen, "Gif should not be open at this point"); + PostSize(mGIFStruct.screen_width, mGIFStruct.screen_height); + return; + } + // screen_bgcolor is not used //mGIFStruct.screen_bgcolor = q[5]; // q[6] = Pixel Aspect Ratio diff --git a/image/test/crashtests/856616.gif b/image/test/crashtests/856616.gif new file mode 100644 index 0000000000000000000000000000000000000000..0fac8110141961ae786a92de70b15edb8592c189 GIT binary patch literal 27 icmZ?wbhEHbWMp7uXkcK_d05ZDz+k;HU*QwOF&_X_PX{gl literal 0 HcmV?d00001 diff --git a/image/test/crashtests/crashtests.list b/image/test/crashtests/crashtests.list index dc021f15762..74caaba7860 100644 --- a/image/test/crashtests/crashtests.list +++ b/image/test/crashtests/crashtests.list @@ -41,3 +41,7 @@ load truncated-second-frame.png # bug 863975 # This icon's size is such that it leads to multiple writes to the PNG decoder # after we've gotten our size. load multiple-png-hassize.ico + +# Bug 856615 +# Asserts in the debug build +load 856616.gif From 497ad25dd0f560f1acc1f724fa2aad6cbbd51421 Mon Sep 17 00:00:00 2001 From: David Major Date: Thu, 26 Sep 2013 10:11:37 -0400 Subject: [PATCH 13/84] Bug 919069 - Set -env win32 for x86 targets regardless of MIDL version. r=ted --- configure.in | 20 ++------------------ 1 file changed, 2 insertions(+), 18 deletions(-) diff --git a/configure.in b/configure.in index 0642272757d..6b0a227731d 100644 --- a/configure.in +++ b/configure.in @@ -490,30 +490,14 @@ case "$target" in INCREMENTAL_LINKER=1 - # Check midl version - _MIDL_FULL_VERSION=`"${MIDL}" -v 2>&1 | sed -nre "$_MSVC_VER_FILTER"` - _MIDL_MAJOR_VERSION=`echo ${_MIDL_FULL_VERSION} | $AWK -F\. '{ print $1 }'` - _MIDL_MINOR_VERSION=`echo ${_MIDL_FULL_VERSION} | $AWK -F\. '{ print $2 }'` - _MIDL_REV_VERSION=`echo ${_MIDL_FULL_VERSION} | $AWK -F\. '{ print $3 }'` - # Add flags if necessary - AC_MSG_CHECKING([for midl flags]) + # Set midl environment case "$target" in i*86-*) - if test \( "$_MIDL_MAJOR_VERSION" = "7" -a "$_MIDL_MINOR_VERSION" = "00" -a "$_MIDL_REV_VERSION" = "0499" \); then - # MIDL version 7.00.0499 defaults /env win64 on x64 platforms. - # MIDL version 7.00.0500 or later has no problem. - MIDL_FLAGS="${MIDL_FLAGS} -env win32" - AC_MSG_RESULT([need -env win32]) - else - AC_MSG_RESULT([none needed]) - fi + MIDL_FLAGS="${MIDL_FLAGS} -env win32" ;; x86_64-*) MIDL_FLAGS="${MIDL_FLAGS} -env x64" ;; - *) - AC_MSG_RESULT([none needed]) - ;; esac unset _MSVC_VER_FILTER From f6240d199e2b080cf33bad9818e503cc1ec91d2c Mon Sep 17 00:00:00 2001 From: Rick Eyre Date: Mon, 23 Sep 2013 13:59:49 -0400 Subject: [PATCH 14/84] Bug 919265 - Part 1: Fix TextTrackCue() crashtests to use VTTCue(). r=bz --- content/media/test/crashtests/882549.html | 4 ++-- content/media/test/crashtests/894104.html | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/content/media/test/crashtests/882549.html b/content/media/test/crashtests/882549.html index 8711cd1fbdd..8a720c3e119 100644 --- a/content/media/test/crashtests/882549.html +++ b/content/media/test/crashtests/882549.html @@ -2,8 +2,8 @@ diff --git a/content/media/test/crashtests/894104.html b/content/media/test/crashtests/894104.html index c550b9ea49b..cb2429ae26a 100644 --- a/content/media/test/crashtests/894104.html +++ b/content/media/test/crashtests/894104.html @@ -8,9 +8,9 @@ function boom() { var frame = document.getElementById("f"); var frameWin = frame.contentWindow; - frameWin.TextTrackCue; + frameWin.VTTCue; document.body.removeChild(frame); - frameWin.TextTrackCue(0, 1, "Bug 894104").getCueAsHTML(); + frameWin.VTTCue(0, 1, "Bug 894104").getCueAsHTML(); } From a35055b353f107d966003b3b5e0ae1122145af8d Mon Sep 17 00:00:00 2001 From: Rick Eyre Date: Tue, 24 Sep 2013 15:17:15 -0400 Subject: [PATCH 15/84] Bug 919265 - Part 2: Add ClearOnShutdown() call on the static WebVTTParserWrapper. r=bz --- content/media/TextTrackCue.cpp | 2 ++ content/media/test/Makefile.in | 11 +++++---- content/media/test/test_bug919265.html | 32 ++++++++++++++++++++++++++ 3 files changed, 40 insertions(+), 5 deletions(-) create mode 100644 content/media/test/test_bug919265.html diff --git a/content/media/TextTrackCue.cpp b/content/media/TextTrackCue.cpp index 0f60d79d1c6..41c0f3189ff 100644 --- a/content/media/TextTrackCue.cpp +++ b/content/media/TextTrackCue.cpp @@ -8,6 +8,7 @@ #include "nsIFrame.h" #include "nsVideoFrame.h" #include "nsComponentManagerUtils.h" +#include "mozilla/ClearOnShutdown.h" // Alternate value for the 'auto' keyword. #define WEBVTT_AUTO -1 @@ -162,6 +163,7 @@ TextTrackCue::GetCueAsHTML() return mDocument->CreateDocumentFragment(); } sParserWrapper = parserWrapper; + ClearOnShutdown(&sParserWrapper); } nsPIDOMWindow* window = mDocument->GetWindow(); diff --git a/content/media/test/Makefile.in b/content/media/test/Makefile.in index d507d2df3b6..cf06adc3b24 100644 --- a/content/media/test/Makefile.in +++ b/content/media/test/Makefile.in @@ -64,10 +64,16 @@ MOCHITEST_FILES = \ test_audio1.html \ test_audio2.html \ test_autoplay.html \ + test_bug448534.html \ + test_bug463162.xhtml \ test_bug495145.html \ test_bug495300.html \ test_bug654550.html \ test_bug686942.html \ + test_bug883173.html \ + test_bug895305.html \ + test_bug895091.html \ + test_bug919265.html \ test_can_play_type.html \ test_can_play_type_mpeg.html \ test_closing_connections.html \ @@ -118,8 +124,6 @@ MOCHITEST_FILES = \ test_mozHasAudio.html \ test_source_media.html \ test_autoplay_contentEditable.html \ - test_bug448534.html \ - test_bug463162.xhtml \ test_decoder_disable.html \ test_mediarecorder_record_no_timeslice.html \ test_mediarecorder_reload_crash.html \ @@ -146,9 +150,6 @@ MOCHITEST_FILES = \ test_VideoPlaybackQuality.html \ test_VideoPlaybackQuality_disabled.html \ test_webvtt_disabled.html \ - test_bug895305.html \ - test_bug895091.html \ - test_bug883173.html \ $(NULL) # Don't run in suite diff --git a/content/media/test/test_bug919265.html b/content/media/test/test_bug919265.html new file mode 100644 index 00000000000..76433419da2 --- /dev/null +++ b/content/media/test/test_bug919265.html @@ -0,0 +1,32 @@ + + + + + + Regression test for bug 919265 - Leak on VTTCue::GetCueAsHTML() + + + + + +

+ +
+
+
+ + From 5634f0f7529e087a6c7d671052e59d50049d02c6 Mon Sep 17 00:00:00 2001 From: Jan Beich Date: Thu, 26 Sep 2013 10:11:37 -0400 Subject: [PATCH 16/84] Bug 920112 - Make sure nsCOMPtr is defined before using. r=ehsan --- extensions/spellcheck/hunspell/src/mozHunspellDirProvider.h | 1 + 1 file changed, 1 insertion(+) diff --git a/extensions/spellcheck/hunspell/src/mozHunspellDirProvider.h b/extensions/spellcheck/hunspell/src/mozHunspellDirProvider.h index acbc6ace7e0..d4d81791428 100644 --- a/extensions/spellcheck/hunspell/src/mozHunspellDirProvider.h +++ b/extensions/spellcheck/hunspell/src/mozHunspellDirProvider.h @@ -37,6 +37,7 @@ #define mozHunspellDirProvider_h__ #include "nsIDirectoryService.h" +#include "nsIFile.h" #include "nsISimpleEnumerator.h" #include "mozilla/Attributes.h" From aef016cc4a26715fd821f37da991b9a1d1a4c5ed Mon Sep 17 00:00:00 2001 From: Andy Wingo Date: Thu, 26 Sep 2013 10:11:38 -0400 Subject: [PATCH 17/84] Bug 920433 - Improve API support for self-hosted functions. r=till, r=bz --- dom/bindings/BindingUtils.cpp | 20 +++++++++---- dom/bindings/Codegen.py | 22 +++++++++----- js/src/builtin/Intl.cpp | 12 ++++---- js/src/builtin/MapObject.cpp | 4 +-- js/src/builtin/ParallelArray.cpp | 18 ++++++------ js/src/jsapi.cpp | 34 ++++++++++++++++++---- js/src/jsapi.h | 25 ++++++++++++---- js/src/jsarray.cpp | 50 ++++++++++++++++---------------- js/src/jsdate.cpp | 6 ++-- js/src/jsfun.cpp | 3 +- js/src/jsnum.cpp | 2 +- js/src/jsstr.cpp | 6 ++-- js/src/vm/GlobalObject.cpp | 16 ++++------ js/src/vm/GlobalObject.h | 5 ++-- 14 files changed, 136 insertions(+), 87 deletions(-) diff --git a/dom/bindings/BindingUtils.cpp b/dom/bindings/BindingUtils.cpp index 49aefd24d4b..043332062bd 100644 --- a/dom/bindings/BindingUtils.cpp +++ b/dom/bindings/BindingUtils.cpp @@ -1019,13 +1019,21 @@ XrayResolveProperty(JSContext* cx, JS::Handle wrapper, for ( ; methodIds[i] != JSID_VOID; ++i) { if (id == methodIds[i]) { const JSFunctionSpec& methodSpec = methodsSpecs[i]; - JSFunction *fun = JS_NewFunctionById(cx, methodSpec.call.op, - methodSpec.nargs, 0, - wrapper, id); - if (!fun) { - return false; + JSFunction *fun; + if (methodSpec.selfHostedName) { + fun = JS::GetSelfHostedFunction(cx, methodSpec.selfHostedName, id, methodSpec.nargs); + if (!fun) { + return false; + } + MOZ_ASSERT(!methodSpec.call.op, "Bad FunctionSpec declaration: non-null native"); + MOZ_ASSERT(!methodSpec.call.info, "Bad FunctionSpec declaration: non-null jitinfo"); + } else { + fun = JS_NewFunctionById(cx, methodSpec.call.op, methodSpec.nargs, 0, wrapper, id); + if (!fun) { + return false; + } + SET_JITINFO(fun, methodSpec.call.info); } - SET_JITINFO(fun, methodSpec.call.info); JSObject *funobj = JS_GetFunctionObject(fun); desc.value().setObject(*funobj); desc.setAttributes(methodSpec.flags); diff --git a/dom/bindings/Codegen.py b/dom/bindings/Codegen.py index 8554f67854f..1c0c878eeb8 100644 --- a/dom/bindings/Codegen.py +++ b/dom/bindings/Codegen.py @@ -1571,17 +1571,25 @@ class MethodDefiner(PropertyDefiner): return m["condition"] def specData(m): - accessor = m.get("nativeName", m["name"]) - if m.get("methodInfo", True): - jitinfo = ("&%s_methodinfo" % accessor) - accessor = "genericMethod" - else: + if "selfHostedName" in m: + selfHostedName = '"%s"' % m["selfHostedName"] + assert not m.get("methodInfo", True) + accessor = "nullptr" jitinfo = "nullptr" - return (m["name"], accessor, jitinfo, m["length"], m["flags"]) + else: + selfHostedName = "nullptr"; + accessor = m.get("nativeName", m["name"]) + if m.get("methodInfo", True): + jitinfo = ("&%s_methodinfo" % accessor) + accessor = "genericMethod" + else: + jitinfo = "nullptr" + + return (m["name"], accessor, jitinfo, m["length"], m["flags"], selfHostedName) return self.generatePrefableArray( array, name, - ' JS_FNINFO("%s", %s, %s, %s, %s)', + ' JS_FNSPEC("%s", %s, %s, %s, %s, %s)', ' JS_FS_END', 'JSFunctionSpec', condition, specData, doIdArrays) diff --git a/js/src/builtin/Intl.cpp b/js/src/builtin/Intl.cpp index 746fc577846..c3123c6e054 100644 --- a/js/src/builtin/Intl.cpp +++ b/js/src/builtin/Intl.cpp @@ -570,12 +570,12 @@ collator_toSource(JSContext *cx, unsigned argc, Value *vp) #endif static const JSFunctionSpec collator_static_methods[] = { - {"supportedLocalesOf", JSOP_NULLWRAPPER, 1, JSFunction::INTERPRETED, "Intl_Collator_supportedLocalesOf"}, + JS_SELF_HOSTED_FN("supportedLocalesOf", "Intl_Collator_supportedLocalesOf", 1, 0), JS_FS_END }; static const JSFunctionSpec collator_methods[] = { - {"resolvedOptions", JSOP_NULLWRAPPER, 0, JSFunction::INTERPRETED, "Intl_Collator_resolvedOptions"}, + JS_SELF_HOSTED_FN("resolvedOptions", "Intl_Collator_resolvedOptions", 0, 0), #if JS_HAS_TOSOURCE JS_FN(js_toSource_str, collator_toSource, 0, 0), #endif @@ -1053,12 +1053,12 @@ numberFormat_toSource(JSContext *cx, unsigned argc, Value *vp) #endif static const JSFunctionSpec numberFormat_static_methods[] = { - {"supportedLocalesOf", JSOP_NULLWRAPPER, 1, JSFunction::INTERPRETED, "Intl_NumberFormat_supportedLocalesOf"}, + JS_SELF_HOSTED_FN("supportedLocalesOf", "Intl_NumberFormat_supportedLocalesOf", 1, 0), JS_FS_END }; static const JSFunctionSpec numberFormat_methods[] = { - {"resolvedOptions", JSOP_NULLWRAPPER, 0, JSFunction::INTERPRETED, "Intl_NumberFormat_resolvedOptions"}, + JS_SELF_HOSTED_FN("resolvedOptions", "Intl_NumberFormat_resolvedOptions", 0, 0), #if JS_HAS_TOSOURCE JS_FN(js_toSource_str, numberFormat_toSource, 0, 0), #endif @@ -1510,12 +1510,12 @@ dateTimeFormat_toSource(JSContext *cx, unsigned argc, Value *vp) #endif static const JSFunctionSpec dateTimeFormat_static_methods[] = { - {"supportedLocalesOf", JSOP_NULLWRAPPER, 1, JSFunction::INTERPRETED, "Intl_DateTimeFormat_supportedLocalesOf"}, + JS_SELF_HOSTED_FN("supportedLocalesOf", "Intl_DateTimeFormat_supportedLocalesOf", 1, 0), JS_FS_END }; static const JSFunctionSpec dateTimeFormat_methods[] = { - {"resolvedOptions", JSOP_NULLWRAPPER, 0, JSFunction::INTERPRETED, "Intl_DateTimeFormat_resolvedOptions"}, + JS_SELF_HOSTED_FN("resolvedOptions", "Intl_DateTimeFormat_resolvedOptions", 0, 0), #if JS_HAS_TOSOURCE JS_FN(js_toSource_str, dateTimeFormat_toSource, 0, 0), #endif diff --git a/js/src/builtin/MapObject.cpp b/js/src/builtin/MapObject.cpp index 8364f92550b..dc2dd92fce0 100644 --- a/js/src/builtin/MapObject.cpp +++ b/js/src/builtin/MapObject.cpp @@ -1039,7 +1039,7 @@ const JSFunctionSpec MapObject::methods[] = { JS_FN("keys", keys, 0, 0), JS_FN("values", values, 0, 0), JS_FN("clear", clear, 0, 0), - {"forEach", {nullptr, nullptr}, 2, 0, "MapForEach"}, + JS_SELF_HOSTED_FN("forEach", "MapForEach", 2, 0), JS_FS_END }; @@ -1600,7 +1600,7 @@ const JSFunctionSpec SetObject::methods[] = { JS_FN("delete", delete_, 1, 0), JS_FN("entries", entries, 0, 0), JS_FN("clear", clear, 0, 0), - {"forEach", {nullptr, nullptr}, 2, 0, "SetForEach"}, + JS_SELF_HOSTED_FN("forEach", "SetForEach", 2, 0), JS_FS_END }; diff --git a/js/src/builtin/ParallelArray.cpp b/js/src/builtin/ParallelArray.cpp index 981505298fb..5185b6edc69 100644 --- a/js/src/builtin/ParallelArray.cpp +++ b/js/src/builtin/ParallelArray.cpp @@ -23,13 +23,13 @@ using namespace js; FixedHeapPtr ParallelArrayObject::ctorNames[NumCtors]; const JSFunctionSpec ParallelArrayObject::methods[] = { - { "map", JSOP_NULLWRAPPER, 2, 0, "ParallelArrayMap" }, - { "reduce", JSOP_NULLWRAPPER, 2, 0, "ParallelArrayReduce" }, - { "scan", JSOP_NULLWRAPPER, 2, 0, "ParallelArrayScan" }, - { "scatter", JSOP_NULLWRAPPER, 5, 0, "ParallelArrayScatter" }, - { "filter", JSOP_NULLWRAPPER, 2, 0, "ParallelArrayFilter" }, - { "partition", JSOP_NULLWRAPPER, 1, 0, "ParallelArrayPartition" }, - { "flatten", JSOP_NULLWRAPPER, 0, 0, "ParallelArrayFlatten" }, + JS_SELF_HOSTED_FN("map", "ParallelArrayMap", 2, 0), + JS_SELF_HOSTED_FN("reduce", "ParallelArrayReduce", 2, 0), + JS_SELF_HOSTED_FN("scan", "ParallelArrayScan", 2, 0), + JS_SELF_HOSTED_FN("scatter", "ParallelArrayScatter", 5, 0), + JS_SELF_HOSTED_FN("filter", "ParallelArrayFilter", 2, 0), + JS_SELF_HOSTED_FN("partition", "ParallelArrayPartition", 1, 0), + JS_SELF_HOSTED_FN("flatten", "ParallelArrayFlatten", 0, 0), // FIXME #838906. Note that `get()` is not currently defined on this table but // rather is assigned to each instance of ParallelArray as an own @@ -38,9 +38,9 @@ const JSFunctionSpec ParallelArrayObject::methods[] = { // receiver. In the future we can improve this by (1) extending // TI to track the dimensionality of the receiver and (2) using a // hint to aggressively inline calls to get(). - // { "get", JSOP_NULLWRAPPER, 1, 0, "ParallelArrayGet" }, + // JS_SELF_HOSTED_FN("get", "ParallelArrayGet", 1, 0), - { "toString", JSOP_NULLWRAPPER, 0, 0, "ParallelArrayToString" }, + JS_SELF_HOSTED_FN("toString", "ParallelArrayToString", 0, 0), JS_FS_END }; diff --git a/js/src/jsapi.cpp b/js/src/jsapi.cpp index c57d0c198d5..4f50197d1fb 100644 --- a/js/src/jsapi.cpp +++ b/js/src/jsapi.cpp @@ -4034,13 +4034,32 @@ JS_NewFunctionById(JSContext *cx, JSNative native, unsigned nargs, unsigned flag RootedObject parent(cx, parentArg); JS_ASSERT(JSID_IS_STRING(id)); JS_ASSERT(!cx->runtime()->isAtomsCompartment(cx->compartment())); + JS_ASSERT(native); AssertHeapIsIdle(cx); CHECK_REQUEST(cx); assertSameCompartment(cx, parent); - RootedAtom atom(cx, JSID_TO_ATOM(id)); + RootedAtom name(cx, JSID_TO_ATOM(id)); JSFunction::Flags funFlags = JSAPIToJSFunctionFlags(flags); - return NewFunction(cx, NullPtr(), native, nargs, funFlags, parent, atom); + return NewFunction(cx, NullPtr(), native, nargs, funFlags, parent, name); +} + +JS_PUBLIC_API(JSFunction *) +JS::GetSelfHostedFunction(JSContext *cx, const char *selfHostedName, jsid id, unsigned nargs) +{ + JS_ASSERT(JSID_IS_STRING(id)); + JS_ASSERT(!cx->runtime()->isAtomsCompartment(cx->compartment())); + AssertHeapIsIdle(cx); + CHECK_REQUEST(cx); + + RootedAtom name(cx, JSID_TO_ATOM(id)); + RootedAtom shName(cx, Atomize(cx, selfHostedName, strlen(selfHostedName))); + if (!shName) + return nullptr; + RootedValue funVal(cx); + if (!cx->global()->getSelfHostedFunction(cx, shName, name, nargs, &funVal)) + return nullptr; + return &funVal.toObject().as(); } JS_PUBLIC_API(JSObject *) @@ -4238,13 +4257,18 @@ JS_DefineFunctions(JSContext *cx, JSObject *objArg, const JSFunctionSpec *fs) * in. Self-hosted functions can access each other via their names, * but not via the builtin classes they get installed into. */ + JS_ASSERT(!fs->call.op); + JS_ASSERT(!fs->call.info); if (cx->runtime()->isSelfHostingGlobal(cx->global())) continue; - RootedValue funVal(cx); - if (!cx->global()->getSelfHostedFunction(cx, fs, atom, &funVal)) + RootedAtom shName(cx, Atomize(cx, fs->selfHostedName, strlen(fs->selfHostedName))); + if (!shName) return false; - if (!JSObject::defineGeneric(cx, obj, id, funVal, NULL, NULL, 0)) + RootedValue funVal(cx); + if (!cx->global()->getSelfHostedFunction(cx, shName, atom, fs->nargs, &funVal)) + return false; + if (!JSObject::defineGeneric(cx, obj, id, funVal, NULL, NULL, flags)) return false; } else { JSFunction *fun = DefineFunction(cx, obj, id, fs->call.op, fs->nargs, flags); diff --git a/js/src/jsapi.h b/js/src/jsapi.h index 36032d4b87b..cb6f2a5e6d9 100644 --- a/js/src/jsapi.h +++ b/js/src/jsapi.h @@ -2383,16 +2383,22 @@ struct JSFunctionSpec { #define JS_FS_END JS_FS(NULL,NULL,0,0) /* - * Initializer macros for a JSFunctionSpec array element. JS_FN (whose name - * pays homage to the old JSNative/JSFastNative split) simply adds the flag - * JSFUN_STUB_GSOPS. JS_FNINFO allows the simple adding of JSJitInfos. + * Initializer macros for a JSFunctionSpec array element. JS_FN (whose name pays + * homage to the old JSNative/JSFastNative split) simply adds the flag + * JSFUN_STUB_GSOPS. JS_FNINFO allows the simple adding of + * JSJitInfos. JS_SELF_HOSTED_FN declares a self-hosted function. Finally + * JS_FNSPEC has slots for all the fields. */ #define JS_FS(name,call,nargs,flags) \ - {name, JSOP_WRAPPER(call), nargs, flags} + JS_FNSPEC(name, call, nullptr, nargs, flags, nullptr) #define JS_FN(name,call,nargs,flags) \ - {name, JSOP_WRAPPER(call), nargs, (flags) | JSFUN_STUB_GSOPS} + JS_FNSPEC(name, call, nullptr, nargs, (flags) | JSFUN_STUB_GSOPS, nullptr) #define JS_FNINFO(name,call,info,nargs,flags) \ - {name,{call,info},nargs,flags} + JS_FNSPEC(name, call, info, nargs, flags, nullptr) +#define JS_SELF_HOSTED_FN(name,selfHostedName,nargs,flags) \ + JS_FNSPEC(name, nullptr, nullptr, nargs, flags, selfHostedName) +#define JS_FNSPEC(name,call,info,nargs,flags,selfHostedName) \ + {name, {call, info}, nargs, flags, selfHostedName} extern JS_PUBLIC_API(JSObject *) JS_InitClass(JSContext *cx, JSObject *obj, JSObject *parent_proto, @@ -3101,6 +3107,13 @@ extern JS_PUBLIC_API(JSFunction *) JS_NewFunctionById(JSContext *cx, JSNative call, unsigned nargs, unsigned flags, JSObject *parent, jsid id); +namespace JS { + +extern JS_PUBLIC_API(JSFunction *) +GetSelfHostedFunction(JSContext *cx, const char *selfHostedName, jsid id, unsigned nargs); + +} /* namespace JS */ + extern JS_PUBLIC_API(JSObject *) JS_GetFunctionObject(JSFunction *fun); diff --git a/js/src/jsarray.cpp b/js/src/jsarray.cpp index 06b99cca479..eed907e4d04 100644 --- a/js/src/jsarray.cpp +++ b/js/src/jsarray.cpp @@ -2869,28 +2869,28 @@ static const JSFunctionSpec array_methods[] = { JS_FN("concat", array_concat, 1,JSFUN_GENERIC_NATIVE), JS_FN("slice", array_slice, 2,JSFUN_GENERIC_NATIVE), - {"lastIndexOf", {NULL, NULL}, 1,0, "ArrayLastIndexOf"}, - {"indexOf", {NULL, NULL}, 1,0, "ArrayIndexOf"}, - {"forEach", {NULL, NULL}, 1,0, "ArrayForEach"}, - {"map", {NULL, NULL}, 1,0, "ArrayMap"}, - {"reduce", {NULL, NULL}, 1,0, "ArrayReduce"}, - {"reduceRight", {NULL, NULL}, 1,0, "ArrayReduceRight"}, + JS_SELF_HOSTED_FN("lastIndexOf", "ArrayLastIndexOf", 1,0), + JS_SELF_HOSTED_FN("indexOf", "ArrayIndexOf", 1,0), + JS_SELF_HOSTED_FN("forEach", "ArrayForEach", 1,0), + JS_SELF_HOSTED_FN("map", "ArrayMap", 1,0), + JS_SELF_HOSTED_FN("reduce", "ArrayReduce", 1,0), + JS_SELF_HOSTED_FN("reduceRight", "ArrayReduceRight", 1,0), JS_FN("filter", array_filter, 1,JSFUN_GENERIC_NATIVE), - {"some", {NULL, NULL}, 1,0, "ArraySome"}, - {"every", {NULL, NULL}, 1,0, "ArrayEvery"}, + JS_SELF_HOSTED_FN("some", "ArraySome", 1,0), + JS_SELF_HOSTED_FN("every", "ArrayEvery", 1,0), #ifdef ENABLE_PARALLEL_JS /* Parallelizable and pure methods. */ - {"mapPar", {NULL, NULL}, 2,0, "ArrayMapPar"}, - {"reducePar", {NULL, NULL}, 2,0, "ArrayReducePar"}, - {"scanPar", {NULL, NULL}, 2,0, "ArrayScanPar"}, - {"scatterPar", {NULL, NULL}, 5,0, "ArrayScatterPar"}, - {"filterPar", {NULL, NULL}, 2,0, "ArrayFilterPar"}, + JS_SELF_HOSTED_FN("mapPar", "ArrayMapPar", 2,0), + JS_SELF_HOSTED_FN("reducePar", "ArrayReducePar", 2,0), + JS_SELF_HOSTED_FN("scanPar", "ArrayScanPar", 2,0), + JS_SELF_HOSTED_FN("scatterPar", "ArrayScatterPar", 5,0), + JS_SELF_HOSTED_FN("filterPar", "ArrayFilterPar", 2,0), #endif /* ES6 additions */ - {"find", {NULL, NULL}, 1,0, "ArrayFind"}, - {"findIndex", {NULL, NULL}, 1,0, "ArrayFindIndex"}, + JS_SELF_HOSTED_FN("find", "ArrayFind", 1,0), + JS_SELF_HOSTED_FN("findIndex", "ArrayFindIndex", 1,0), JS_FN("iterator", JS_ArrayIterator, 0,0), JS_FS_END @@ -2898,20 +2898,20 @@ static const JSFunctionSpec array_methods[] = { static const JSFunctionSpec array_static_methods[] = { JS_FN("isArray", array_isArray, 1,0), - {"lastIndexOf", {NULL, NULL}, 2,0, "ArrayStaticLastIndexOf"}, - {"indexOf", {NULL, NULL}, 2,0, "ArrayStaticIndexOf"}, - {"forEach", {NULL, NULL}, 2,0, "ArrayStaticForEach"}, - {"map", {NULL, NULL}, 2,0, "ArrayStaticMap"}, - {"every", {NULL, NULL}, 2,0, "ArrayStaticEvery"}, - {"some", {NULL, NULL}, 2,0, "ArrayStaticSome"}, - {"reduce", {NULL, NULL}, 2,0, "ArrayStaticReduce"}, - {"reduceRight", {NULL, NULL}, 2,0, "ArrayStaticReduceRight"}, + JS_SELF_HOSTED_FN("lastIndexOf", "ArrayStaticLastIndexOf", 2,0), + JS_SELF_HOSTED_FN("indexOf", "ArrayStaticIndexOf", 2,0), + JS_SELF_HOSTED_FN("forEach", "ArrayStaticForEach", 2,0), + JS_SELF_HOSTED_FN("map", "ArrayStaticMap", 2,0), + JS_SELF_HOSTED_FN("every", "ArrayStaticEvery", 2,0), + JS_SELF_HOSTED_FN("some", "ArrayStaticSome", 2,0), + JS_SELF_HOSTED_FN("reduce", "ArrayStaticReduce", 2,0), + JS_SELF_HOSTED_FN("reduceRight", "ArrayStaticReduceRight", 2,0), JS_FN("of", array_of, 0,0), #ifdef ENABLE_PARALLEL_JS - {"build", {NULL, NULL}, 2,0, "ArrayStaticBuild"}, + JS_SELF_HOSTED_FN("build", "ArrayStaticBuild", 2,0), /* Parallelizable and pure static methods. */ - {"buildPar", {NULL, NULL}, 3,0, "ArrayStaticBuildPar"}, + JS_SELF_HOSTED_FN("buildPar", "ArrayStaticBuildPar", 3,0), #endif JS_FS_END diff --git a/js/src/jsdate.cpp b/js/src/jsdate.cpp index e6d3728d368..3571291d2d2 100644 --- a/js/src/jsdate.cpp +++ b/js/src/jsdate.cpp @@ -2946,9 +2946,9 @@ static const JSFunctionSpec date_methods[] = { JS_FN("toUTCString", date_toGMTString, 0,0), JS_FN("toLocaleFormat", date_toLocaleFormat, 0,0), #if EXPOSE_INTL_API - {js_toLocaleString_str, {NULL, NULL}, 0,0, "Date_toLocaleString"}, - {"toLocaleDateString", {NULL, NULL}, 0,0, "Date_toLocaleDateString"}, - {"toLocaleTimeString", {NULL, NULL}, 0,0, "Date_toLocaleTimeString"}, + JS_SELF_HOSTED_FN(js_toLocaleString_str, "Date_toLocaleString", 0,0), + JS_SELF_HOSTED_FN("toLocaleDateString", "Date_toLocaleDateString", 0,0), + JS_SELF_HOSTED_FN("toLocaleTimeString", "Date_toLocaleTimeString", 0,0), #else JS_FN(js_toLocaleString_str, date_toLocaleString, 0,0), JS_FN("toLocaleDateString", date_toLocaleDateString, 0,0), diff --git a/js/src/jsfun.cpp b/js/src/jsfun.cpp index 0e5b5918638..fdbd9058ceb 100644 --- a/js/src/jsfun.cpp +++ b/js/src/jsfun.cpp @@ -1197,8 +1197,7 @@ JSFunction::createScriptForLazilyInterpretedFunction(JSContext *cx, HandleFuncti } /* Lazily cloned self hosted script. */ - JSFunctionSpec *fs = static_cast(fun->getExtendedSlot(0).toPrivate()); - RootedAtom funAtom(cx, Atomize(cx, fs->selfHostedName, strlen(fs->selfHostedName))); + RootedAtom funAtom(cx, &fun->getExtendedSlot(0).toString()->asAtom()); if (!funAtom) return false; Rooted funName(cx, funAtom->asPropertyName()); diff --git a/js/src/jsnum.cpp b/js/src/jsnum.cpp index 38c1d1fb2f4..6557ce7c672 100644 --- a/js/src/jsnum.cpp +++ b/js/src/jsnum.cpp @@ -1009,7 +1009,7 @@ static const JSFunctionSpec number_methods[] = { #endif JS_FN(js_toString_str, js_num_toString, 1, 0), #if EXPOSE_INTL_API - {js_toLocaleString_str, {NULL, NULL}, 0,0, "Number_toLocaleString"}, + JS_SELF_HOSTED_FN(js_toLocaleString_str, "Number_toLocaleString", 0,0), #else JS_FN(js_toLocaleString_str, num_toLocaleString, 0,0), #endif diff --git a/js/src/jsstr.cpp b/js/src/jsstr.cpp index 879bf065cae..8a5db3c0478 100644 --- a/js/src/jsstr.cpp +++ b/js/src/jsstr.cpp @@ -3624,11 +3624,11 @@ static const JSFunctionSpec string_methods[] = { JS_FN("toLocaleLowerCase", str_toLocaleLowerCase, 0,JSFUN_GENERIC_NATIVE), JS_FN("toLocaleUpperCase", str_toLocaleUpperCase, 0,JSFUN_GENERIC_NATIVE), #if EXPOSE_INTL_API - {"localeCompare", {NULL, NULL}, 1,0, "String_localeCompare"}, + JS_SELF_HOSTED_FN("localeCompare", "String_localeCompare", 1,0), #else JS_FN("localeCompare", str_localeCompare, 1,JSFUN_GENERIC_NATIVE), #endif - {"repeat", {NULL, NULL}, 1,0, "String_repeat"}, + JS_SELF_HOSTED_FN("repeat", "String_repeat", 1,0), /* Perl-ish methods (search is actually Python-esque). */ JS_FN("match", str_match, 1,JSFUN_GENERIC_NATIVE), @@ -3732,7 +3732,7 @@ static const JSFunctionSpec string_static_methods[] = { // This must be at the end because of bug 853075: functions listed after // self-hosted methods aren't available in self-hosted code. #if EXPOSE_INTL_API - {"localeCompare", {NULL, NULL}, 2,0, "String_static_localeCompare"}, + JS_SELF_HOSTED_FN("localeCompare", "String_static_localeCompare", 2,0), #endif JS_FS_END }; diff --git a/js/src/vm/GlobalObject.cpp b/js/src/vm/GlobalObject.cpp index 6a4b8e16617..f9b702230e7 100644 --- a/js/src/vm/GlobalObject.cpp +++ b/js/src/vm/GlobalObject.cpp @@ -631,14 +631,10 @@ GlobalObject::addDebugger(JSContext *cx, Handle global, Debugger } bool -GlobalObject::getSelfHostedFunction(JSContext *cx, const JSFunctionSpec *fs, HandleAtom atom, - MutableHandleValue funVal) +GlobalObject::getSelfHostedFunction(JSContext *cx, HandleAtom selfHostedName, HandleAtom name, + unsigned nargs, MutableHandleValue funVal) { - JS_ASSERT(fs->selfHostedName); - RootedAtom shAtom(cx, Atomize(cx, fs->selfHostedName, strlen(fs->selfHostedName))); - if (!shAtom) - return false; - RootedId shId(cx, AtomToId(shAtom)); + RootedId shId(cx, AtomToId(selfHostedName)); RootedObject holder(cx, cx->global()->intrinsicsHolder()); if (HasDataProperty(cx, holder, shId, funVal.address())) @@ -649,12 +645,12 @@ GlobalObject::getSelfHostedFunction(JSContext *cx, const JSFunctionSpec *fs, Han if (!funVal.isUndefined()) return true; - JSFunction *fun = NewFunction(cx, NullPtr(), NULL, fs->nargs, JSFunction::INTERPRETED_LAZY, - holder, atom, JSFunction::ExtendedFinalizeKind, SingletonObject); + JSFunction *fun = NewFunction(cx, NullPtr(), NULL, nargs, JSFunction::INTERPRETED_LAZY, + holder, name, JSFunction::ExtendedFinalizeKind, SingletonObject); if (!fun) return false; fun->setIsSelfHostedBuiltin(); - fun->setExtendedSlot(0, PrivateValue(const_cast(fs))); + fun->setExtendedSlot(0, StringValue(selfHostedName)); funVal.setObject(*fun); return JSObject::defineGeneric(cx, holder, shId, funVal, NULL, NULL, 0); diff --git a/js/src/vm/GlobalObject.h b/js/src/vm/GlobalObject.h index a286c712a07..e008ebcee32 100644 --- a/js/src/vm/GlobalObject.h +++ b/js/src/vm/GlobalObject.h @@ -456,8 +456,9 @@ class GlobalObject : public JSObject RootedValue valCopy(cx, value); return JSObject::setProperty(cx, holder, holder, name, &valCopy, false); } - bool getSelfHostedFunction(JSContext *cx, const JSFunctionSpec *fs, HandleAtom atom, - MutableHandleValue funVal); + + bool getSelfHostedFunction(JSContext *cx, HandleAtom selfHostedName, HandleAtom name, + unsigned nargs, MutableHandleValue funVal); RegExpStatics *getRegExpStatics() const { JSObject &resObj = getSlot(REGEXP_STATICS).toObject(); From 694bab7fc413083ad46091e27b843d793278a90c Mon Sep 17 00:00:00 2001 From: Douglas Crosher Date: Thu, 26 Sep 2013 11:01:24 +1000 Subject: [PATCH 18/84] Bug 920452 - Odinmonkey: Constant global variables have no alias dependencies. r=bbouvier --- js/src/jit/MIR.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/js/src/jit/MIR.h b/js/src/jit/MIR.h index add22dae73c..798006597eb 100644 --- a/js/src/jit/MIR.h +++ b/js/src/jit/MIR.h @@ -8629,7 +8629,7 @@ class MAsmJSStoreHeap : public MBinaryInstruction, public MAsmJSHeapAccess class MAsmJSLoadGlobalVar : public MNullaryInstruction { MAsmJSLoadGlobalVar(MIRType type, unsigned globalDataOffset, bool isConstant) - : globalDataOffset_(globalDataOffset) + : globalDataOffset_(globalDataOffset), isConstant_(isConstant) { JS_ASSERT(type == MIRType_Int32 || type == MIRType_Double); setResultType(type); @@ -8637,6 +8637,7 @@ class MAsmJSLoadGlobalVar : public MNullaryInstruction } unsigned globalDataOffset_; + bool isConstant_; public: INSTRUCTION_HEADER(AsmJSLoadGlobalVar); @@ -8650,7 +8651,7 @@ class MAsmJSLoadGlobalVar : public MNullaryInstruction bool congruentTo(MDefinition *ins) const; AliasSet getAliasSet() const { - return AliasSet::Load(AliasSet::AsmJSGlobalVar); + return isConstant_ ? AliasSet::None() : AliasSet::Load(AliasSet::AsmJSGlobalVar); } bool mightAlias(MDefinition *def); From 34afbf8b40ae16b2db8ac926767570b2df297198 Mon Sep 17 00:00:00 2001 From: Chris Jones Date: Thu, 26 Sep 2013 10:11:38 -0400 Subject: [PATCH 19/84] Bug 920703 - Give an informative error message when expandlibs_exec fails. r=glandium --- config/expandlibs_exec.py | 6 +++++- js/src/config/expandlibs_exec.py | 6 +++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/config/expandlibs_exec.py b/config/expandlibs_exec.py index 770dce4b58f..89dab4d6719 100644 --- a/config/expandlibs_exec.py +++ b/config/expandlibs_exec.py @@ -318,7 +318,11 @@ def main(): if options.verbose: print_command(sys.stderr, args) - proc = subprocess.Popen(args, stdout = subprocess.PIPE, stderr = subprocess.STDOUT) + try: + proc = subprocess.Popen(args, stdout = subprocess.PIPE, stderr = subprocess.STDOUT) + except Exception, e: + print >>sys.stderr, 'error: Launching', args, ':', e + raise e (stdout, stderr) = proc.communicate() if proc.returncode and not options.verbose: print_command(sys.stderr, args) diff --git a/js/src/config/expandlibs_exec.py b/js/src/config/expandlibs_exec.py index 770dce4b58f..89dab4d6719 100644 --- a/js/src/config/expandlibs_exec.py +++ b/js/src/config/expandlibs_exec.py @@ -318,7 +318,11 @@ def main(): if options.verbose: print_command(sys.stderr, args) - proc = subprocess.Popen(args, stdout = subprocess.PIPE, stderr = subprocess.STDOUT) + try: + proc = subprocess.Popen(args, stdout = subprocess.PIPE, stderr = subprocess.STDOUT) + except Exception, e: + print >>sys.stderr, 'error: Launching', args, ':', e + raise e (stdout, stderr) = proc.communicate() if proc.returncode and not options.verbose: print_command(sys.stderr, args) From 92809f7d9835f016bc00889fa4212f5d704d994c Mon Sep 17 00:00:00 2001 From: Robert Longson Date: Thu, 26 Sep 2013 15:22:13 +0100 Subject: [PATCH 20/84] Bug 919900 - Mark reftest fuzzy on windows 7 --- layout/reftests/svg/reftest.list | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/layout/reftests/svg/reftest.list b/layout/reftests/svg/reftest.list index 1f204925e70..460a91ba25a 100644 --- a/layout/reftests/svg/reftest.list +++ b/layout/reftests/svg/reftest.list @@ -106,7 +106,7 @@ skip-if(B2G) == dynamic-pattern-contents-02.svg pass.svg == dynamic-text-01.svg dynamic-text-01-ref.svg fuzzy-if(d2d&&layersGPUAccelerated,2,12739) == dynamic-text-02.svg dynamic-text-02-ref.svg # bug 776038 for Win7 fuzzy-if(d2d&&layersGPUAccelerated,2,10539) == dynamic-text-03.svg dynamic-text-03-ref.svg # bug 776038 for Win7 -random-if(/^Windows\x20NT\x205\.1/.test(http.oscpu)) == dynamic-text-04.svg dynamic-text-04-ref.svg # bug 421587 for WinXP +random-if(/^Windows\x20NT\x205\.1/.test(http.oscpu)) fuzzy-if(d2d&&layersGPUAccelerated,47,89) == dynamic-text-04.svg dynamic-text-04-ref.svg # bug 421587 for WinXP, bug 776038 for Win7 skip-if(B2G) == dynamic-text-05.svg pass.svg skip-if(B2G) == dynamic-text-06.svg pass.svg == dynamic-text-07.svg dynamic-text-07-ref.svg From 65256398656b3bba75ec517391fc7482103ee80e Mon Sep 17 00:00:00 2001 From: Robert Longson Date: Thu, 26 Sep 2013 15:29:09 +0100 Subject: [PATCH 21/84] Bug 919900 - Mark reftest fuzzy on windows 7 --- layout/reftests/svg/reftest.list | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/layout/reftests/svg/reftest.list b/layout/reftests/svg/reftest.list index 460a91ba25a..f5c0f743d73 100644 --- a/layout/reftests/svg/reftest.list +++ b/layout/reftests/svg/reftest.list @@ -106,7 +106,7 @@ skip-if(B2G) == dynamic-pattern-contents-02.svg pass.svg == dynamic-text-01.svg dynamic-text-01-ref.svg fuzzy-if(d2d&&layersGPUAccelerated,2,12739) == dynamic-text-02.svg dynamic-text-02-ref.svg # bug 776038 for Win7 fuzzy-if(d2d&&layersGPUAccelerated,2,10539) == dynamic-text-03.svg dynamic-text-03-ref.svg # bug 776038 for Win7 -random-if(/^Windows\x20NT\x205\.1/.test(http.oscpu)) fuzzy-if(d2d&&layersGPUAccelerated,47,89) == dynamic-text-04.svg dynamic-text-04-ref.svg # bug 421587 for WinXP, bug 776038 for Win7 +random-if(/^Windows\x20NT\x205\.1/.test(http.oscpu)) fuzzy-if(/^Windows\x20NT\x206\.1/.test(http.oscpu),47,89) == dynamic-text-04.svg dynamic-text-04-ref.svg # bug 421587 for WinXP, bug 776038 for Win7 skip-if(B2G) == dynamic-text-05.svg pass.svg skip-if(B2G) == dynamic-text-06.svg pass.svg == dynamic-text-07.svg dynamic-text-07-ref.svg From c3664e6ae659c67d67d866b3dda91c048f5331d0 Mon Sep 17 00:00:00 2001 From: Jan de Mooij Date: Thu, 26 Sep 2013 16:27:18 +0200 Subject: [PATCH 22/84] Bug 811122 - Use double addition in AddOperation to avoid signed integer overflow. r=bhackett --HG-- extra : rebase_source : 16bbb1470021c1e26730cdd329a528467827ec12 --- js/src/vm/Interpreter.cpp | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/js/src/vm/Interpreter.cpp b/js/src/vm/Interpreter.cpp index 322fec0f830..e78d59398a2 100644 --- a/js/src/vm/Interpreter.cpp +++ b/js/src/vm/Interpreter.cpp @@ -1079,13 +1079,9 @@ AddOperation(JSContext *cx, HandleScript script, jsbytecode *pc, { if (lhs.isInt32() && rhs.isInt32()) { int32_t l = lhs.toInt32(), r = rhs.toInt32(); - int32_t sum = l + r; - if (JS_UNLIKELY(bool((l ^ sum) & (r ^ sum) & 0x80000000))) { - res->setDouble(double(l) + double(r)); + double d = double(l) + double(r); + if (!res->setNumber(d)) types::TypeScript::MonitorOverflow(cx, script, pc); - } else { - res->setInt32(sum); - } return true; } From 93a7d8cfd36dc1744601044b8c502063ce2f8907 Mon Sep 17 00:00:00 2001 From: Alexander Surkov Date: Thu, 26 Sep 2013 10:37:40 -0400 Subject: [PATCH 23/84] Bug 920547 - create generic accessibles for mathml elements, r=tbsaunde --- accessible/src/base/nsAccessibilityService.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/accessible/src/base/nsAccessibilityService.cpp b/accessible/src/base/nsAccessibilityService.cpp index e3032e28ea4..da6d5b45f28 100644 --- a/accessible/src/base/nsAccessibilityService.cpp +++ b/accessible/src/base/nsAccessibilityService.cpp @@ -1022,8 +1022,11 @@ nsAccessibilityService::GetOrCreateAccessible(nsINode* aNode, } else if (content->Tag() == nsGkAtoms::svg) { newAcc = new EnumRoleAccessible(content, document, roles::DIAGRAM); } - } else if (content->IsMathML(nsGkAtoms::math)) { - newAcc = new EnumRoleAccessible(content, document, roles::EQUATION); + } else if (content->IsMathML()){ + if (content->Tag() == nsGkAtoms::math) + newAcc = new EnumRoleAccessible(content, document, roles::EQUATION); + else + newAcc = new HyperTextAccessible(content, document); } } From 5ca8abdaf0f5de4b8a285892bc2f5c9559f83b29 Mon Sep 17 00:00:00 2001 From: Nathan Froyd Date: Fri, 13 Sep 2013 14:57:32 -0400 Subject: [PATCH 24/84] Bug 916257 - part 1 - convert ipdlsrcs.mk writing to use mozbuild.makeutil; r=gps --- python/mozbuild/mozbuild/backend/recursivemake.py | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/python/mozbuild/mozbuild/backend/recursivemake.py b/python/mozbuild/mozbuild/backend/recursivemake.py index 150aa72c51f..f10385bcc2f 100644 --- a/python/mozbuild/mozbuild/backend/recursivemake.py +++ b/python/mozbuild/mozbuild/backend/recursivemake.py @@ -11,6 +11,7 @@ import types from collections import namedtuple +import mozbuild.makeutil as mozmakeutil from mozpack.copier import FilePurger from mozpack.manifests import ( InstallManifest, @@ -554,21 +555,25 @@ class RecursiveMakeBackend(CommonBackend): # Write out a master list of all IPDL source files. ipdls = FileAvoidWrite(os.path.join(self.environment.topobjdir, 'ipc', 'ipdl', 'ipdlsrcs.mk')) + mk = mozmakeutil.Makefile() + for p in sorted(self._ipdl_sources): - ipdls.write('ALL_IPDLSRCS += %s\n' % p) + mk.add_statement('ALL_IPDLSRCS += %s\n' % p) base = os.path.basename(p) root, ext = os.path.splitext(base) # Both .ipdl and .ipdlh become .cpp files - ipdls.write('CPPSRCS += %s.cpp\n' % root) + mk.add_statement('CPPSRCS += %s.cpp\n' % root) if ext == '.ipdl': # .ipdl also becomes Child/Parent.cpp files - ipdls.write('CPPSRCS += %sChild.cpp\n' % root) - ipdls.write('CPPSRCS += %sParent.cpp\n' % root) + mk.add_statement('CPPSRCS += %sChild.cpp\n' % root) + mk.add_statement('CPPSRCS += %sParent.cpp\n' % root) - ipdls.write('IPDLDIRS := %s\n' % ' '.join(sorted(set(os.path.dirname(p) + mk.add_statement('IPDLDIRS := %s\n' % ' '.join(sorted(set(os.path.dirname(p) for p in self._ipdl_sources)))) + mk.dump(ipdls) + self._update_from_avoid_write(ipdls.close()) self.summary.managed_count += 1 From e73b29def538b32dd9a9f40e5387513c10c07840 Mon Sep 17 00:00:00 2001 From: Nathan Froyd Date: Fri, 13 Sep 2013 15:03:15 -0400 Subject: [PATCH 25/84] Bug 916257 - part 2 - separate out files-from-this-ipdl logic from writing CPPSRCS; r=gps --- .../mozbuild/backend/recursivemake.py | 20 +++++++++++-------- .../test/backend/test_recursivemake.py | 17 ++++++++++------ 2 files changed, 23 insertions(+), 14 deletions(-) diff --git a/python/mozbuild/mozbuild/backend/recursivemake.py b/python/mozbuild/mozbuild/backend/recursivemake.py index f10385bcc2f..067f1b9b348 100644 --- a/python/mozbuild/mozbuild/backend/recursivemake.py +++ b/python/mozbuild/mozbuild/backend/recursivemake.py @@ -559,15 +559,19 @@ class RecursiveMakeBackend(CommonBackend): for p in sorted(self._ipdl_sources): mk.add_statement('ALL_IPDLSRCS += %s\n' % p) - base = os.path.basename(p) - root, ext = os.path.splitext(base) + def files_from(ipdl): + base = os.path.basename(ipdl) + root, ext = os.path.splitext(base) - # Both .ipdl and .ipdlh become .cpp files - mk.add_statement('CPPSRCS += %s.cpp\n' % root) - if ext == '.ipdl': - # .ipdl also becomes Child/Parent.cpp files - mk.add_statement('CPPSRCS += %sChild.cpp\n' % root) - mk.add_statement('CPPSRCS += %sParent.cpp\n' % root) + # Both .ipdl and .ipdlh become .cpp files + files = ['%s.cpp' % root] + if ext == '.ipdl': + # .ipdl also becomes Child/Parent.cpp files + files.extend(['%sChild.cpp' % root, + '%sParent.cpp' % root]) + return files + + mk.add_statement('CPPSRCS += %s\n' % ' '.join(files_from(p))) mk.add_statement('IPDLDIRS := %s\n' % ' '.join(sorted(set(os.path.dirname(p) for p in self._ipdl_sources)))) diff --git a/python/mozbuild/mozbuild/test/backend/test_recursivemake.py b/python/mozbuild/mozbuild/test/backend/test_recursivemake.py index 3adadee9271..1e54de507c3 100644 --- a/python/mozbuild/mozbuild/test/backend/test_recursivemake.py +++ b/python/mozbuild/mozbuild/test/backend/test_recursivemake.py @@ -468,18 +468,23 @@ class TestRecursiveMakeBackend(BackendTester): expected = [ "ALL_IPDLSRCS += %s/bar/bar.ipdl" % topsrcdir, - "CPPSRCS += bar.cpp", - "CPPSRCS += barChild.cpp", - "CPPSRCS += barParent.cpp", + "", + "CPPSRCS += bar.cpp barChild.cpp barParent.cpp", + "", "ALL_IPDLSRCS += %s/bar/bar2.ipdlh" % topsrcdir, + "", "CPPSRCS += bar2.cpp", + "", "ALL_IPDLSRCS += %s/foo/foo.ipdl" % topsrcdir, - "CPPSRCS += foo.cpp", - "CPPSRCS += fooChild.cpp", - "CPPSRCS += fooParent.cpp", + "", + "CPPSRCS += foo.cpp fooChild.cpp fooParent.cpp", + "", "ALL_IPDLSRCS += %s/foo/foo2.ipdlh" % topsrcdir, + "", "CPPSRCS += foo2.cpp", + "", "IPDLDIRS := %s/bar %s/foo" % (topsrcdir, topsrcdir), + "", ] self.assertEqual(lines, expected) From 10b7e36077bed2db6d1de485e7ac6b7cd4bbfd4d Mon Sep 17 00:00:00 2001 From: Nathan Froyd Date: Mon, 23 Sep 2013 10:21:41 -0400 Subject: [PATCH 26/84] Bug 916257 - part 3 - write ALL_IPDLSRCS and CPPSRCS in one go; r=gps --- .../mozbuild/backend/recursivemake.py | 29 ++++++++++--------- .../test/backend/test_recursivemake.py | 19 ++++-------- 2 files changed, 21 insertions(+), 27 deletions(-) diff --git a/python/mozbuild/mozbuild/backend/recursivemake.py b/python/mozbuild/mozbuild/backend/recursivemake.py index 067f1b9b348..7c730bc86ab 100644 --- a/python/mozbuild/mozbuild/backend/recursivemake.py +++ b/python/mozbuild/mozbuild/backend/recursivemake.py @@ -5,6 +5,7 @@ from __future__ import unicode_literals import errno +import itertools import logging import os import types @@ -557,21 +558,23 @@ class RecursiveMakeBackend(CommonBackend): 'ipc', 'ipdl', 'ipdlsrcs.mk')) mk = mozmakeutil.Makefile() - for p in sorted(self._ipdl_sources): - mk.add_statement('ALL_IPDLSRCS += %s\n' % p) - def files_from(ipdl): - base = os.path.basename(ipdl) - root, ext = os.path.splitext(base) + sorted_ipdl_sources = list(sorted(self._ipdl_sources)) + mk.add_statement('ALL_IPDLSRCS := %s\n' % ' '.join(sorted_ipdl_sources)) - # Both .ipdl and .ipdlh become .cpp files - files = ['%s.cpp' % root] - if ext == '.ipdl': - # .ipdl also becomes Child/Parent.cpp files - files.extend(['%sChild.cpp' % root, - '%sParent.cpp' % root]) - return files + def files_from(ipdl): + base = os.path.basename(ipdl) + root, ext = os.path.splitext(base) - mk.add_statement('CPPSRCS += %s\n' % ' '.join(files_from(p))) + # Both .ipdl and .ipdlh become .cpp files + files = ['%s.cpp' % root] + if ext == '.ipdl': + # .ipdl also becomes Child/Parent.cpp files + files.extend(['%sChild.cpp' % root, + '%sParent.cpp' % root]) + return files + + ipdl_cppsrcs = itertools.chain(*[files_from(p) for p in sorted_ipdl_sources]) + mk.add_statement('CPPSRCS := %s\n' % ' '.join(ipdl_cppsrcs)) mk.add_statement('IPDLDIRS := %s\n' % ' '.join(sorted(set(os.path.dirname(p) for p in self._ipdl_sources)))) diff --git a/python/mozbuild/mozbuild/test/backend/test_recursivemake.py b/python/mozbuild/mozbuild/test/backend/test_recursivemake.py index 1e54de507c3..685c298a2f4 100644 --- a/python/mozbuild/mozbuild/test/backend/test_recursivemake.py +++ b/python/mozbuild/mozbuild/test/backend/test_recursivemake.py @@ -467,21 +467,12 @@ class TestRecursiveMakeBackend(BackendTester): topsrcdir = env.topsrcdir.replace(os.sep, '/') expected = [ - "ALL_IPDLSRCS += %s/bar/bar.ipdl" % topsrcdir, + "ALL_IPDLSRCS := %s/bar/bar.ipdl %s/bar/bar2.ipdlh %s/foo/foo.ipdl %s/foo/foo2.ipdlh" % tuple([topsrcdir] * 4), "", - "CPPSRCS += bar.cpp barChild.cpp barParent.cpp", - "", - "ALL_IPDLSRCS += %s/bar/bar2.ipdlh" % topsrcdir, - "", - "CPPSRCS += bar2.cpp", - "", - "ALL_IPDLSRCS += %s/foo/foo.ipdl" % topsrcdir, - "", - "CPPSRCS += foo.cpp fooChild.cpp fooParent.cpp", - "", - "ALL_IPDLSRCS += %s/foo/foo2.ipdlh" % topsrcdir, - "", - "CPPSRCS += foo2.cpp", + "CPPSRCS := bar.cpp barChild.cpp barParent.cpp" + + " bar2.cpp" + + " foo.cpp fooChild.cpp fooParent.cpp" + + " foo2.cpp", "", "IPDLDIRS := %s/bar %s/foo" % (topsrcdir, topsrcdir), "", From 8f7b83cf9417505b27007864d4525e64740091ce Mon Sep 17 00:00:00 2001 From: Nathan Froyd Date: Wed, 11 Sep 2013 08:21:14 -0400 Subject: [PATCH 27/84] Bug 907789 - part 1 - write out webidl file lists as one big list; r=gps --- .../mozbuild/backend/recursivemake.py | 21 ++++++++----------- 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/python/mozbuild/mozbuild/backend/recursivemake.py b/python/mozbuild/mozbuild/backend/recursivemake.py index 7c730bc86ab..0c1ac4da78f 100644 --- a/python/mozbuild/mozbuild/backend/recursivemake.py +++ b/python/mozbuild/mozbuild/backend/recursivemake.py @@ -588,18 +588,15 @@ class RecursiveMakeBackend(CommonBackend): webidls = FileAvoidWrite(os.path.join(self.environment.topobjdir, 'dom', 'bindings', 'webidlsrcs.mk')) - for webidl in sorted(self._webidl_sources): - webidls.write('webidl_files += %s\n' % os.path.basename(webidl)) - for webidl in sorted(self._generated_events_webidl_sources): - webidls.write('generated_events_webidl_files += %s\n' % os.path.basename(webidl)) - for webidl in sorted(self._test_webidl_sources): - webidls.write('test_webidl_files += %s\n' % os.path.basename(webidl)) - for webidl in sorted(self._preprocessed_test_webidl_sources): - webidls.write('preprocessed_test_webidl_files += %s\n' % os.path.basename(webidl)) - for webidl in sorted(self._generated_webidl_sources): - webidls.write('generated_webidl_files += %s\n' % os.path.basename(webidl)) - for webidl in sorted(self._preprocessed_webidl_sources): - webidls.write('preprocessed_webidl_files += %s\n' % os.path.basename(webidl)) + def write_var(variable, sources): + files = [os.path.basename(f) for f in sorted(sources)] + webidls.write('%s += %s\n' % (variable, ' '.join(files))) + write_var('webidl_files', self._webidl_sources) + write_var('generated_events_webidl_files', self._generated_events_webidl_sources) + write_var('test_webidl_files', self._test_webidl_sources) + write_var('preprocessed_test_webidl_files', self._preprocessed_test_webidl_sources) + write_var('generated_webidl_files', self._generated_webidl_sources) + write_var('preprocessed_webidl_files', self._preprocessed_webidl_sources) self._update_from_avoid_write(webidls.close()) self.summary.managed_count += 1 From 980030dae478cbd5bf5e2bbc862bda9a4db3dfd2 Mon Sep 17 00:00:00 2001 From: Nathan Froyd Date: Fri, 13 Sep 2013 20:21:05 -0400 Subject: [PATCH 28/84] Bug 907789 - part 2 - use mozbuild.makeutil to write webidl file lists; r=gps --- python/mozbuild/mozbuild/backend/recursivemake.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/python/mozbuild/mozbuild/backend/recursivemake.py b/python/mozbuild/mozbuild/backend/recursivemake.py index 0c1ac4da78f..d7269e60188 100644 --- a/python/mozbuild/mozbuild/backend/recursivemake.py +++ b/python/mozbuild/mozbuild/backend/recursivemake.py @@ -588,9 +588,11 @@ class RecursiveMakeBackend(CommonBackend): webidls = FileAvoidWrite(os.path.join(self.environment.topobjdir, 'dom', 'bindings', 'webidlsrcs.mk')) + mk = mozmakeutil.Makefile() + def write_var(variable, sources): files = [os.path.basename(f) for f in sorted(sources)] - webidls.write('%s += %s\n' % (variable, ' '.join(files))) + mk.add_statement('%s += %s\n' % (variable, ' '.join(files))) write_var('webidl_files', self._webidl_sources) write_var('generated_events_webidl_files', self._generated_events_webidl_sources) write_var('test_webidl_files', self._test_webidl_sources) @@ -598,6 +600,8 @@ class RecursiveMakeBackend(CommonBackend): write_var('generated_webidl_files', self._generated_webidl_sources) write_var('preprocessed_webidl_files', self._preprocessed_webidl_sources) + mk.dump(webidls) + self._update_from_avoid_write(webidls.close()) self.summary.managed_count += 1 From d94c4d06d8ae01183ceac3deea30358285933ce2 Mon Sep 17 00:00:00 2001 From: Nathan Froyd Date: Mon, 23 Sep 2013 13:17:41 -0400 Subject: [PATCH 29/84] Bug 907789 - part 3 - build dom/bindings/ in "unified" mode; r=gps --- dom/bindings/Makefile.in | 3 +- .../mozbuild/backend/recursivemake.py | 84 ++++++++++++++++++- 2 files changed, 83 insertions(+), 4 deletions(-) diff --git a/dom/bindings/Makefile.in b/dom/bindings/Makefile.in index e9cf828115a..0bd7a036924 100644 --- a/dom/bindings/Makefile.in +++ b/dom/bindings/Makefile.in @@ -60,7 +60,7 @@ globalgen_targets := \ # would break |make FooBinding.o(bj)|. Ah, well. ifneq (export TestExampleInterface-example TestExampleProxyInterface-example,$(MAKECMDGOALS)) CPPSRCS = \ - $(linked_binding_cpp_files) \ + $(unified_binding_cpp_files) \ $(linked_generated_events_cpp_files) \ $(filter %.cpp, $(globalgen_targets)) \ BindingUtils.cpp \ @@ -258,6 +258,7 @@ GARBAGE += \ parser.out \ $(wildcard *-example.h) \ $(wildcard *-example.cpp) \ + $(unified_binding_cpp_files) \ .BindingGen \ .all-webidl-file-list \ .generated-events-webidl-files \ diff --git a/python/mozbuild/mozbuild/backend/recursivemake.py b/python/mozbuild/mozbuild/backend/recursivemake.py index d7269e60188..de48c155767 100644 --- a/python/mozbuild/mozbuild/backend/recursivemake.py +++ b/python/mozbuild/mozbuild/backend/recursivemake.py @@ -8,6 +8,7 @@ import errno import itertools import logging import os +import re import types from collections import namedtuple @@ -510,6 +511,69 @@ class RecursiveMakeBackend(CommonBackend): self._update_from_avoid_write(root.close()) self._update_from_avoid_write(root_deps.close()) + def _add_unified_build_rules(self, makefile, files, output_directory, + unified_prefix='Unified', + extra_dependencies=[], + unified_files_makefile_variable='unified_files', + include_curdir_build_rules=True): + files_per_unified_file = 16 + + explanation = "\n" \ + "# We build files in 'unified' mode by including several files\n" \ + "# together into a single source file. This cuts down on\n" \ + "# compilation times and debug information size. %d was chosen as\n" \ + "# a reasonable compromise between clobber rebuild time, incremental\n" \ + "# rebuild time, and compiler memory usage.\n" % files_per_unified_file + makefile.add_statement(explanation) + + def unified_files(): + "Return an iterator of (unified_filename, source_filenames) tuples." + # Our last returned list of source filenames may be short, and we + # don't want the fill value inserted by izip_longest to be an + # issue. So we do a little dance to filter it out ourselves. + dummy_fill_value = ("dummy",) + def filter_out_dummy(iterable): + return itertools.ifilter(lambda x: x != dummy_fill_value, + iterable) + + # From the itertools documentation, slightly modified: + def grouper(n, iterable): + "grouper(3, 'ABCDEFG', 'x') --> ABC DEF Gxx" + args = [iter(iterable)] * n + return itertools.izip_longest(fillvalue=dummy_fill_value, *args) + + for i, unified_group in enumerate(grouper(files_per_unified_file, + sorted(files))): + just_the_filenames = list(filter_out_dummy(unified_group)) + yield '%s%d.cpp' % (unified_prefix, i), just_the_filenames + + all_sources = ' '.join(source for source, _ in unified_files()) + makefile.add_statement('%s := %s\n' % (unified_files_makefile_variable, + all_sources)) + + regen_cmds = ['for f in $(filter %.cpp,$^); do echo "#include \\"$$f\\""; done > $@'] + for unified_file, source_filenames in unified_files(): + rule = makefile.create_rule([unified_file]) + rule.add_dependencies(extra_dependencies + source_filenames) + rule.add_commands(regen_cmds) + + # The rule we just defined is only for cases where the cpp files get + # blown away and we need to regenerate them. The rule doesn't correctly + # handle source files being added/removed/renamed. Therefore, we + # generate them here also to make sure everything's up-to-date. + with FileAvoidWrite(os.path.join(output_directory, unified_file)) as f: + f.write('\n'.join(['#include "%s"' % s for s in source_filenames])) + + if include_curdir_build_rules: + makefile.add_statement('\n' + '# Make sometimes gets confused between "foo" and "$(CURDIR)/foo".\n' + '# Help it out by explicitly specifiying dependencies.') + makefile.add_statement('all_absolute_unified_files := \\\n' + ' $(addprefix $(CURDIR)/,$(%s))' + % unified_files_makefile_variable) + rule = makefile.create_rule(['$(all_absolute_unified_files)']) + rule.add_dependencies(['$(CURDIR)/%: %']) + def consume_finished(self): CommonBackend.consume_finished(self) @@ -585,8 +649,8 @@ class RecursiveMakeBackend(CommonBackend): self.summary.managed_count += 1 # Write out master lists of WebIDL source files. - webidls = FileAvoidWrite(os.path.join(self.environment.topobjdir, - 'dom', 'bindings', 'webidlsrcs.mk')) + bindings_dir = os.path.join(self.environment.topobjdir, 'dom', 'bindings') + webidls = FileAvoidWrite(os.path.join(bindings_dir, 'webidlsrcs.mk')) mk = mozmakeutil.Makefile() @@ -600,7 +664,21 @@ class RecursiveMakeBackend(CommonBackend): write_var('generated_webidl_files', self._generated_webidl_sources) write_var('preprocessed_webidl_files', self._preprocessed_webidl_sources) - mk.dump(webidls) + all_webidl_files = itertools.chain(iter(self._webidl_sources), + iter(self._generated_events_webidl_sources), + iter(self._generated_webidl_sources), + iter(self._preprocessed_webidl_sources)) + all_webidl_files = [os.path.basename(x) for x in all_webidl_files] + all_webidl_sources = [re.sub(r'\.webidl$', 'Binding.cpp', x) for x in all_webidl_files] + + self._add_unified_build_rules(mk, all_webidl_sources, + bindings_dir, + unified_prefix='UnifiedBindings', + unified_files_makefile_variable='unified_binding_cpp_files') + + # Assume that Somebody Else has responsibility for correctly + # specifying removal dependencies for |all_webidl_sources|. + mk.dump(webidls, removal_guard=False) self._update_from_avoid_write(webidls.close()) self.summary.managed_count += 1 From b6409bb295b5dfcef02746757bce7c978d0fe688 Mon Sep 17 00:00:00 2001 From: Martijn Wargers Date: Wed, 25 Sep 2013 20:03:38 +0200 Subject: [PATCH 30/84] Bug 917061 - Fix the last 2 crashtests that use enablePrivilege. r=dholbert --- accessible/tests/crashtests/471493.xul | 6 ++-- accessible/tests/crashtests/crashtests.list | 3 +- layout/mathml/crashtests/400157.xhtml | 33 +++++++++++---------- testing/crashtest/crashtests.list | 2 ++ 4 files changed, 24 insertions(+), 20 deletions(-) diff --git a/accessible/tests/crashtests/471493.xul b/accessible/tests/crashtests/471493.xul index 2a34778e95c..9536e2813a8 100644 --- a/accessible/tests/crashtests/471493.xul +++ b/accessible/tests/crashtests/471493.xul @@ -9,10 +9,8 @@ + \ No newline at end of file diff --git a/testing/crashtest/crashtests.list b/testing/crashtest/crashtests.list index 455ad32a856..01739ab7bd5 100644 --- a/testing/crashtest/crashtests.list +++ b/testing/crashtest/crashtests.list @@ -3,6 +3,8 @@ include ../../testing/crashtest/sanity/crashtests.list +include ../../accessible/tests/crashtests/crashtests.list + include ../../content/base/crashtests/crashtests.list include ../../content/canvas/crashtests/crashtests.list include ../../content/events/crashtests/crashtests.list From ecd60b0dd9159a56ee1c92320337ad764cdf4107 Mon Sep 17 00:00:00 2001 From: Niv Yahel Date: Thu, 26 Sep 2013 09:53:22 -0400 Subject: [PATCH 31/84] Bug 848772 - Remove the abouthome.title reference from config.dtd, create anaboutHome.dtd, and add it to jar.mn. r=mleibovic --- mobile/android/chrome/content/aboutHome.xhtml | 11 +++++++++-- .../android/chrome/content/aboutPrivateBrowsing.xhtml | 1 + mobile/android/locales/en-US/chrome/aboutHome.dtd | 5 +++++ mobile/android/locales/jar.mn | 1 + 4 files changed, 16 insertions(+), 2 deletions(-) create mode 100644 mobile/android/locales/en-US/chrome/aboutHome.dtd diff --git a/mobile/android/chrome/content/aboutHome.xhtml b/mobile/android/chrome/content/aboutHome.xhtml index 3d9c76ef832..6d0224a1e4f 100644 --- a/mobile/android/chrome/content/aboutHome.xhtml +++ b/mobile/android/chrome/content/aboutHome.xhtml @@ -1,7 +1,13 @@ - + + %htmlDTD; + + %brandDTD; + + %abouthomeDTD; +]> + + diff --git a/mobile/android/locales/jar.mn b/mobile/android/locales/jar.mn index 7e71e059cb5..07623ecf994 100644 --- a/mobile/android/locales/jar.mn +++ b/mobile/android/locales/jar.mn @@ -14,6 +14,7 @@ locale/@AB_CD@/browser/aboutDownloads.dtd (%chrome/aboutDownloads.dtd) locale/@AB_CD@/browser/aboutDownloads.properties (%chrome/aboutDownloads.properties) locale/@AB_CD@/browser/aboutFeedback.dtd (%chrome/aboutFeedback.dtd) + locale/@AB_CD@/browser/aboutHome.dtd (%chrome/aboutHome.dtd) locale/@AB_CD@/browser/aboutPrivateBrowsing.dtd (%chrome/aboutPrivateBrowsing.dtd) locale/@AB_CD@/browser/aboutReader.properties (%chrome/aboutReader.properties) #ifdef MOZ_SERVICES_HEALTHREPORT From 6caee84ef104fbd98ab67049476039ac26488676 Mon Sep 17 00:00:00 2001 From: Paul Rouget Date: Thu, 26 Sep 2013 09:53:22 -0400 Subject: [PATCH 32/84] Bug 919496 - [app manager] Once an app has been installed, it doesn't show up in the 'installed app' tab. r=apoirot --- browser/devtools/app-manager/webapps-store.js | 68 ++++++++++++++++++- .../apps/tests/unit/test_webappsActor.js | 19 ++++++ toolkit/devtools/apps/tests/unit/xpcshell.ini | 1 - toolkit/devtools/server/actors/webapps.js | 27 ++++++++ 4 files changed, 111 insertions(+), 4 deletions(-) diff --git a/browser/devtools/app-manager/webapps-store.js b/browser/devtools/app-manager/webapps-store.js index ded3fac6c7a..34d35ec738b 100644 --- a/browser/devtools/app-manager/webapps-store.js +++ b/browser/devtools/app-manager/webapps-store.js @@ -8,9 +8,6 @@ const {Connection} = require("devtools/client/connection-manager"); const {Cu} = require("chrome"); const dbgClient = Cu.import("resource://gre/modules/devtools/dbg-client.jsm"); -dbgClient.UnsolicitedNotifications.appOpen = "appOpen"; -dbgClient.UnsolicitedNotifications.appClose = "appClose" - const _knownWebappsStores = new WeakMap(); let WebappsStore; @@ -103,6 +100,14 @@ WebappsStore.prototype = { this._onAppClose(manifestURL); }); + client.addListener("appInstall", (type, { manifestURL }) => { + this._onAppInstall(manifestURL); + }); + + client.addListener("appUninstall", (type, { manifestURL }) => { + this._onAppUninstall(manifestURL); + }); + return deferred.resolve(); }) return deferred.promise; @@ -177,6 +182,10 @@ WebappsStore.prototype = { let a = allApps[idx++]; request.manifestURL = a.manifestURL; return client.request(request, (res) => { + if (res.error) { + Cu.reportError(res.message || res.error); + } + if (res.url) { a.iconURL = res.url; } @@ -204,4 +213,57 @@ WebappsStore.prototype = { return m != manifest; }); }, + + _onAppInstall: function(manifest) { + let client = this._connection.client; + let request = { + to: this._webAppsActor, + type: "getApp", + manifestURL: manifest + }; + + client.request(request, (res) => { + if (res.error) { + if (res.error == "forbidden") { + // We got a notification for an app we don't have access to. + // Ignore. + return; + } + Cu.reportError(res.message || res.error); + return; + } + + let app = res.app; + app.running = false; + + let notFound = true; + let proxifiedApp; + for (let i = 0; i < this.object.all.length; i++) { + let storedApp = this.object.all[i]; + if (storedApp.manifestURL == app.manifestURL) { + this.object.all[i] = app; + proxifiedApp = this.object.all[i]; + notFound = false; + break; + } + } + if (notFound) { + this.object.all.push(app); + proxifiedApp = this.object.all[this.object.all.length - 1]; + } + + request.type = "getIconAsDataURL"; + client.request(request, (res) => { + if (res.url) { + proxifiedApp.iconURL = res.url; + } + }); + }); + }, + + _onAppUninstall: function(manifest) { + this.object.all = this.object.all.filter((app) => { + return (app.manifestURL != manifest); + }); + }, } diff --git a/toolkit/devtools/apps/tests/unit/test_webappsActor.js b/toolkit/devtools/apps/tests/unit/test_webappsActor.js index 09699f6ceb1..724b3efa5ea 100644 --- a/toolkit/devtools/apps/tests/unit/test_webappsActor.js +++ b/toolkit/devtools/apps/tests/unit/test_webappsActor.js @@ -57,6 +57,23 @@ add_test(function testGetAll() { }); }); +add_test(function testGetApp() { + let manifestURL = APP_ORIGIN + "/manifest.webapp"; + let request = {type: "getApp", manifestURL: manifestURL}; + webappActorRequest(request, function (aResponse) { + do_check_true("app" in aResponse); + let app = aResponse.app; + do_check_eq(app.id, gAppId); + do_check_eq(app.name, "Test app"); + do_check_eq(app.manifest.description, "Testing webapps actor"); + do_check_eq(app.manifest.launch_path, "/index.html"); + do_check_eq(app.origin, APP_ORIGIN); + do_check_eq(app.installOrigin, app.origin); + do_check_eq(app.manifestURL, app.origin + "/manifest.webapp"); + run_next_test(); + }); +}); + add_test(function testLaunchApp() { let manifestURL = APP_ORIGIN + "/manifest.webapp"; let startPoint = "/index.html"; @@ -103,6 +120,7 @@ add_test(function testCloseApp() { let red1px = "data:application/xml;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAADElEQVQI12P4z8AAAAMBAQAY3Y2wAAAAAElFTkSuQmCC"; let blue1px = "data:application/xml;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAADElEQVQI12MwZDgHAAFlAQBDpjhLAAAAAElFTkSuQmCC"; +/* testGetIcon and testGetIconWithCustomSize disabled: bug 920981 add_test(function testGetIcon() { let manifestURL = APP_ORIGIN + "/manifest.webapp"; let request = { @@ -134,6 +152,7 @@ add_test(function testGetIconWithCustomSize() { run_next_test(); }); }); +*/ add_test(function testUninstall() { let manifestURL = APP_ORIGIN + "/manifest.webapp"; diff --git a/toolkit/devtools/apps/tests/unit/xpcshell.ini b/toolkit/devtools/apps/tests/unit/xpcshell.ini index c29025792bd..dc0119a6ecc 100644 --- a/toolkit/devtools/apps/tests/unit/xpcshell.ini +++ b/toolkit/devtools/apps/tests/unit/xpcshell.ini @@ -4,4 +4,3 @@ tail = tail_apps.js support-files = data/app.zip [test_webappsActor.js] -skip-if = (os == "win" || "linux" || "mac") diff --git a/toolkit/devtools/server/actors/webapps.js b/toolkit/devtools/server/actors/webapps.js index f2c0256de49..bf5cf9f15f0 100644 --- a/toolkit/devtools/server/actors/webapps.js +++ b/toolkit/devtools/server/actors/webapps.js @@ -541,6 +541,32 @@ WebappsActor.prototype = { return deferred.promise; }, + getApp: function wa_actorGetApp(aRequest) { + debug("getAll"); + + let manifestURL = aRequest.manifestURL; + if (!manifestURL) { + return { error: "missingParameter", + message: "missing parameter manifestURL" }; + } + + let reg = DOMApplicationRegistry; + let app = reg.getAppByManifestURL(manifestURL); + if (!app) { + return { error: "appNotFound" }; + } + + if (this._isAppAllowedForManifest(app.manifestURL)) { + let deferred = promise.defer(); + reg.getManifestFor(manifestURL, function (manifest) { + app.manifest = manifest; + deferred.resolve({app: app}); + }); + return deferred.promise; + } + return { error: "forbidden" }; + }, + _areCertifiedAppsAllowed: function wa__areCertifiedAppsAllowed() { let pref = "devtools.debugger.forbid-certified-apps"; return !Services.prefs.getBoolPref(pref); @@ -928,6 +954,7 @@ if (Services.prefs.getBoolPref("devtools.debugger.enable-content-actors")) { let requestTypes = WebappsActor.prototype.requestTypes; requestTypes.uploadPackage = WebappsActor.prototype.uploadPackage; requestTypes.getAll = WebappsActor.prototype.getAll; + requestTypes.getApp = WebappsActor.prototype.getApp; requestTypes.launch = WebappsActor.prototype.launch; requestTypes.close = WebappsActor.prototype.close; requestTypes.uninstall = WebappsActor.prototype.uninstall; From 0e9424a8dc0b66c60f4d33f5ebb535d1afce4560 Mon Sep 17 00:00:00 2001 From: Paul Rouget Date: Thu, 26 Sep 2013 09:53:22 -0400 Subject: [PATCH 33/84] Bug 920984 - In the inspector, when a node is highlighted, we should scroll to show the node. r=mratcliffe --- toolkit/devtools/server/actors/inspector.js | 1 - 1 file changed, 1 deletion(-) diff --git a/toolkit/devtools/server/actors/inspector.js b/toolkit/devtools/server/actors/inspector.js index 7d278488acc..a59b879c9ea 100644 --- a/toolkit/devtools/server/actors/inspector.js +++ b/toolkit/devtools/server/actors/inspector.js @@ -934,7 +934,6 @@ var WalkerActor = protocol.ActorClass({ } this._installHelperSheet(node); - this.layoutHelpers.scrollIntoViewIfNeeded(node.rawNode); DOMUtils.addPseudoClassLock(node.rawNode, HIGHLIGHTED_PSEUDO_CLASS); this._highlightTimeout = setTimeout(this._unhighlight.bind(this), HIGHLIGHTED_TIMEOUT); From b2979ad58483c4b934ac5926db9cfd5b0b9f6d10 Mon Sep 17 00:00:00 2001 From: Ryan VanderMeulen Date: Thu, 26 Sep 2013 10:00:44 -0400 Subject: [PATCH 34/84] Backed out changeset 3786755b89c0 (bug 920495) for landing with the wrong bug # in the commit message. --- toolkit/devtools/server/actors/inspector.js | 1 + 1 file changed, 1 insertion(+) diff --git a/toolkit/devtools/server/actors/inspector.js b/toolkit/devtools/server/actors/inspector.js index a59b879c9ea..7d278488acc 100644 --- a/toolkit/devtools/server/actors/inspector.js +++ b/toolkit/devtools/server/actors/inspector.js @@ -934,6 +934,7 @@ var WalkerActor = protocol.ActorClass({ } this._installHelperSheet(node); + this.layoutHelpers.scrollIntoViewIfNeeded(node.rawNode); DOMUtils.addPseudoClassLock(node.rawNode, HIGHLIGHTED_PSEUDO_CLASS); this._highlightTimeout = setTimeout(this._unhighlight.bind(this), HIGHLIGHTED_TIMEOUT); From 24a22323ae5cabbf42428db4b574d3cbdd22df8d Mon Sep 17 00:00:00 2001 From: Paul Rouget Date: Thu, 26 Sep 2013 09:53:22 -0400 Subject: [PATCH 35/84] Bug 920495 - In the inspector, when a node is highlighted, we should scroll to show the node. r=mratcliffe --- toolkit/devtools/server/actors/inspector.js | 1 - 1 file changed, 1 deletion(-) diff --git a/toolkit/devtools/server/actors/inspector.js b/toolkit/devtools/server/actors/inspector.js index 7d278488acc..a59b879c9ea 100644 --- a/toolkit/devtools/server/actors/inspector.js +++ b/toolkit/devtools/server/actors/inspector.js @@ -934,7 +934,6 @@ var WalkerActor = protocol.ActorClass({ } this._installHelperSheet(node); - this.layoutHelpers.scrollIntoViewIfNeeded(node.rawNode); DOMUtils.addPseudoClassLock(node.rawNode, HIGHLIGHTED_PSEUDO_CLASS); this._highlightTimeout = setTimeout(this._unhighlight.bind(this), HIGHLIGHTED_TIMEOUT); From 8c189eec3240bde573ffbca7adc31be8f2c07e54 Mon Sep 17 00:00:00 2001 From: Neil Deakin Date: Thu, 26 Sep 2013 10:58:19 -0400 Subject: [PATCH 36/84] Bug 908260, pass properties to DownloadError constructor, r=paolo --- .../jsdownloads/src/DownloadCore.jsm | 79 ++++++++++++------- .../test/unit/test_DownloadCore.js | 71 +++++++++++++++++ 2 files changed, 122 insertions(+), 28 deletions(-) diff --git a/toolkit/components/jsdownloads/src/DownloadCore.jsm b/toolkit/components/jsdownloads/src/DownloadCore.jsm index 877ab496736..51e81b6d504 100644 --- a/toolkit/components/jsdownloads/src/DownloadCore.jsm +++ b/toolkit/components/jsdownloads/src/DownloadCore.jsm @@ -338,8 +338,8 @@ Download.prototype = { // While shutting down or disposing of this object, we prevent the download // from returning to be in progress. if (this._finalized) { - return Promise.reject(new DownloadError(Cr.NS_ERROR_FAILURE, - "Cannot start after finalization.")); + return Promise.reject(new DownloadError({ + message: "Cannot start after finalization."})); } // Initialize all the status properties for a new or restarted download. @@ -410,10 +410,7 @@ Download.prototype = { // Disallow download if parental controls service restricts it. if (yield DownloadIntegration.shouldBlockForParentalControls(this)) { - let error = new DownloadError(Cr.NS_ERROR_FAILURE, "Download blocked."); - error.becauseBlocked = true; - error.becauseBlockedByParentalControls = true; - throw error; + throw new DownloadError({ becauseBlockedByParentalControls: true }); } try { @@ -430,7 +427,7 @@ Download.prototype = { // is forced to actually check the status properties to see if the // download was canceled or failed because of other reasons. if (this._promiseCanceled) { - throw new DownloadError(Cr.NS_ERROR_FAILURE, "Download canceled."); + throw new DownloadError({ message: "Download canceled." }); } // Update the download error, unless a new attempt already started. The @@ -1152,18 +1149,22 @@ DownloadTarget.fromSerializable = function (aSerializable) { /** * Provides detailed information about a download failure. * - * @param aResult - * The result code associated with the error. - * @param aMessage - * The message to be displayed, or null to use the message associated - * with the result code. - * @param aInferCause - * If true, attempts to determine if the cause of the download is a - * network failure or a local file failure, based on a set of known - * values of the result code. This is useful when the error is received - * by a component that handles both aspects of the download. + * @param aProperties + * Object which may contain any of the following properties: + * { + * result: Result error code, defaulting to Cr.NS_ERROR_FAILURE + * message: String error message to be displayed, or null to use the + * message associated with the result code. + * inferCause: If true, attempts to determine if the cause of the + * download is a network failure or a local file failure, + * based on a set of known values of the result code. + * This is useful when the error is received by a + * component that handles both aspects of the download. + * } + * The properties object may also contain any of the DownloadError's + * because properties, which will be set accordingly in the error object. */ -function DownloadError(aResult, aMessage, aInferCause) +function DownloadError(aProperties) { const NS_ERROR_MODULE_BASE_OFFSET = 0x45; const NS_ERROR_MODULE_NETWORK = 6; @@ -1171,18 +1172,39 @@ function DownloadError(aResult, aMessage, aInferCause) // Set the error name used by the Error object prototype first. this.name = "DownloadError"; - this.result = aResult || Cr.NS_ERROR_FAILURE; - if (aMessage) { - this.message = aMessage; + this.result = aProperties.result || Cr.NS_ERROR_FAILURE; + if (aProperties.message) { + this.message = aProperties.message; + } else if (aProperties.becauseBlocked || + aProperties.becauseBlockedByParentalControls) { + this.message = "Download blocked."; } else { let exception = new Components.Exception("", this.result); this.message = exception.toString(); } - if (aInferCause) { - let module = ((aResult & 0x7FFF0000) >> 16) - NS_ERROR_MODULE_BASE_OFFSET; + if (aProperties.inferCause) { + let module = ((this.result & 0x7FFF0000) >> 16) - + NS_ERROR_MODULE_BASE_OFFSET; this.becauseSourceFailed = (module == NS_ERROR_MODULE_NETWORK); this.becauseTargetFailed = (module == NS_ERROR_MODULE_FILES); } + else { + if (aProperties.becauseSourceFailed) { + this.becauseSourceFailed = true; + } + if (aProperties.becauseTargetFailed) { + this.becauseTargetFailed = true; + } + } + + if (aProperties.becauseBlockedByParentalControls) { + this.becauseBlocked = true; + this.becauseBlockedByParentalControls = true; + } + else if (aProperties.becauseBlocked) { + this.becauseBlocked = true; + } + this.stack = new Error().stack; } @@ -1420,7 +1442,7 @@ DownloadCopySaver.prototype = { // Throw a DownloadError indicating that the operation failed because of // the target file. We cannot translate this into a specific result // code, but we preserve the original message using the toString method. - let error = new DownloadError(Cr.NS_ERROR_FAILURE, ex.toString()); + let error = new DownloadError({ message: ex.toString() }); error.becauseTargetFailed = true; throw error; } @@ -1431,7 +1453,7 @@ DownloadCopySaver.prototype = { if (this._canceled) { // Don't create the BackgroundFileSaver object if we have been // canceled meanwhile. - throw new DownloadError(Cr.NS_ERROR_FAILURE, "Saver canceled."); + throw new DownloadError({ message: "Saver canceled." }); } // Create the object that will save the file in a background thread. @@ -1453,8 +1475,8 @@ DownloadCopySaver.prototype = { } else { // Infer the origin of the error from the failure code, because // BackgroundFileSaver does not provide more specific data. - deferSaveComplete.reject(new DownloadError(aStatus, null, - true)); + let properties = { result: aStatus, inferCause: true }; + deferSaveComplete.reject(new DownloadError(properties)); } }, }; @@ -1805,7 +1827,8 @@ DownloadLegacySaver.prototype = { } else { // Infer the origin of the error from the failure code, because more // specific data is not available through the nsITransfer implementation. - this.deferExecuted.reject(new DownloadError(aStatus, null, true)); + let properties = { result: aStatus, inferCause: true }; + this.deferExecuted.reject(new DownloadError(properties)); } }, diff --git a/toolkit/components/jsdownloads/test/unit/test_DownloadCore.js b/toolkit/components/jsdownloads/test/unit/test_DownloadCore.js index a316522150a..0301b76ec69 100644 --- a/toolkit/components/jsdownloads/test/unit/test_DownloadCore.js +++ b/toolkit/components/jsdownloads/test/unit/test_DownloadCore.js @@ -9,6 +9,9 @@ "use strict"; +XPCOMUtils.defineLazyModuleGetter(this, "DownloadError", + "resource://gre/modules/DownloadCore.jsm"); + //////////////////////////////////////////////////////////////////////////////// //// Execution of common tests @@ -17,6 +20,74 @@ let gUseLegacySaver = false; let scriptFile = do_get_file("common_test_Download.js"); Services.scriptloader.loadSubScript(NetUtil.newURI(scriptFile).spec); +//////////////////////////////////////////////////////////////////////////////// +//// Tests + +/** + * Tests the DownloadError object. + */ +add_task(function test_DownloadError() +{ + let error = new DownloadError({ result: Cr.NS_ERROR_NOT_RESUMABLE, + message: "Not resumable."}); + do_check_eq(error.result, Cr.NS_ERROR_NOT_RESUMABLE); + do_check_eq(error.message, "Not resumable."); + do_check_false(error.becauseSourceFailed); + do_check_false(error.becauseTargetFailed); + do_check_false(error.becauseBlocked); + do_check_false(error.becauseBlockedByParentalControls); + + error = new DownloadError({ message: "Unknown error."}); + do_check_eq(error.result, Cr.NS_ERROR_FAILURE); + do_check_eq(error.message, "Unknown error."); + + error = new DownloadError({ result: Cr.NS_ERROR_NOT_RESUMABLE }); + do_check_eq(error.result, Cr.NS_ERROR_NOT_RESUMABLE); + do_check_true(error.message.indexOf("Exception") > 0); + + // becauseSourceFailed will be set, but not the unknown property. + error = new DownloadError({ message: "Unknown error.", + becauseSourceFailed: true, + becauseUnknown: true }); + do_check_true(error.becauseSourceFailed); + do_check_false("becauseUnknown" in error); + + error = new DownloadError({ result: Cr.NS_ERROR_MALFORMED_URI, + inferCause: true }); + do_check_eq(error.result, Cr.NS_ERROR_MALFORMED_URI); + do_check_true(error.becauseSourceFailed); + do_check_false(error.becauseTargetFailed); + do_check_false(error.becauseBlocked); + do_check_false(error.becauseBlockedByParentalControls); + + // This test does not set inferCause, so becauseSourceFailed will not be set. + error = new DownloadError({ result: Cr.NS_ERROR_MALFORMED_URI }); + do_check_eq(error.result, Cr.NS_ERROR_MALFORMED_URI); + do_check_false(error.becauseSourceFailed); + + error = new DownloadError({ result: Cr.NS_ERROR_FILE_INVALID_PATH, + inferCause: true }); + do_check_eq(error.result, Cr.NS_ERROR_FILE_INVALID_PATH); + do_check_false(error.becauseSourceFailed); + do_check_true(error.becauseTargetFailed); + do_check_false(error.becauseBlocked); + do_check_false(error.becauseBlockedByParentalControls); + + error = new DownloadError({ becauseBlocked: true }); + do_check_eq(error.message, "Download blocked."); + do_check_false(error.becauseSourceFailed); + do_check_false(error.becauseTargetFailed); + do_check_true(error.becauseBlocked); + do_check_false(error.becauseBlockedByParentalControls); + + error = new DownloadError({ becauseBlockedByParentalControls: true }); + do_check_eq(error.message, "Download blocked."); + do_check_false(error.becauseSourceFailed); + do_check_false(error.becauseTargetFailed); + do_check_true(error.becauseBlocked); + do_check_true(error.becauseBlockedByParentalControls); +}); + //////////////////////////////////////////////////////////////////////////////// //// Termination From 2215468ce628817cc1981ebf294cd5235095a09d Mon Sep 17 00:00:00 2001 From: Neil Deakin Date: Thu, 26 Sep 2013 10:58:21 -0400 Subject: [PATCH 37/84] Bug 908260, support 450 error for windows parental controls in new download api, r=paolo --- .../jsdownloads/src/DownloadCore.jsm | 54 ++++++++++++++++--- .../test/unit/common_test_Download.js | 27 ++++++++++ .../components/jsdownloads/test/unit/head.js | 7 +++ 3 files changed, 82 insertions(+), 6 deletions(-) diff --git a/toolkit/components/jsdownloads/src/DownloadCore.jsm b/toolkit/components/jsdownloads/src/DownloadCore.jsm index 51e81b6d504..43c294b3b82 100644 --- a/toolkit/components/jsdownloads/src/DownloadCore.jsm +++ b/toolkit/components/jsdownloads/src/DownloadCore.jsm @@ -408,12 +408,12 @@ Download.prototype = { } } - // Disallow download if parental controls service restricts it. - if (yield DownloadIntegration.shouldBlockForParentalControls(this)) { - throw new DownloadError({ becauseBlockedByParentalControls: true }); - } - try { + // Disallow download if parental controls service restricts it. + if (yield DownloadIntegration.shouldBlockForParentalControls(this)) { + throw new DownloadError({ becauseBlockedByParentalControls: true }); + } + // Execute the actual download through the saver object. yield this.saver.execute(DS_setProgressBytes.bind(this), DS_setProperties.bind(this)); @@ -430,6 +430,15 @@ Download.prototype = { throw new DownloadError({ message: "Download canceled." }); } + // An HTTP 450 error code is used by Windows to indicate that a uri is + // blocked by parental controls. This will prevent the download from + // occuring, so an error needs to be raised. This is not performed + // during the parental controls check above as it requires the request + // to start. + if (this._blockedByParentalControls) { + ex = new DownloadError({ becauseBlockedByParentalControls: true }); + } + // Update the download error, unless a new attempt already started. The // change in the status property is notified in the finally block. if (this._currentAttempt == currentAttempt || !this._currentAttempt) { @@ -472,7 +481,7 @@ Download.prototype = { // Notify the new download state before returning. this._notifyChange(); - return this._currentAttempt; + return currentAttempt; }, /* @@ -1331,6 +1340,31 @@ DownloadSaver.prototype = { targetUri); }, + /** + * Return true if the request's response has been blocked by Windows parental + * controls with an HTTP 450 error code. + * + * @param aRequest + * nsIRequest object + * @return True if the response is blocked. + */ + isResponseParentalBlocked: function(aRequest) + { + // If the HTTP status is 450, then Windows Parental Controls have + // blocked this download. + if (aRequest instanceof Ci.nsIHttpChannel && + aRequest.responseStatus == 450) { + // Cancel the request, but set a flag on the download that can be + // retrieved later when handling the cancellation so that the proper + // blocked by parental controls error can be thrown. + this.download._blockedByParentalControls = true; + aRequest.cancel(Cr.NS_BINDING_ABORTED); + return true; + } + + return false; + }, + /** * Returns a static representation of the current object state. * @@ -1528,6 +1562,10 @@ DownloadCopySaver.prototype = { onStartRequest: function (aRequest, aContext) { backgroundFileSaver.onStartRequest(aRequest, aContext); + if (this.isResponseParentalBlocked(aRequest)) { + return; + } + aSetPropertiesFn({ contentType: channel.contentType }); // Ensure we report the value of "Content-Length", if available, @@ -1799,6 +1837,10 @@ DownloadLegacySaver.prototype = { ex.result == Cr.NS_ERROR_NOT_RESUMABLE) { } } + if (this.isResponseParentalBlocked(aRequest)) { + return; + } + // For legacy downloads, we must update the referrer at this time. if (aRequest instanceof Ci.nsIHttpChannel && aRequest.referrer) { this.download.source.referrer = aRequest.referrer.spec; diff --git a/toolkit/components/jsdownloads/test/unit/common_test_Download.js b/toolkit/components/jsdownloads/test/unit/common_test_Download.js index ac98af189b0..da89be8af81 100644 --- a/toolkit/components/jsdownloads/test/unit/common_test_Download.js +++ b/toolkit/components/jsdownloads/test/unit/common_test_Download.js @@ -1355,6 +1355,7 @@ add_task(function test_blocked_parental_controls() do_throw("The download should have blocked."); } catch (ex if ex instanceof Downloads.Error && ex.becauseBlocked) { do_check_true(ex.becauseBlockedByParentalControls); + do_check_true(download.error.becauseBlockedByParentalControls); } // Now that the download stopped, the target file should not exist. @@ -1363,6 +1364,32 @@ add_task(function test_blocked_parental_controls() cleanup(); }); +/** + * Test a download that will be blocked by Windows parental controls by + * resulting in an HTTP status code of 450. + */ +add_task(function test_blocked_parental_controls_httpstatus450() +{ + let download; + try { + if (!gUseLegacySaver) { + download = yield promiseNewDownload(httpUrl("parentalblocked.zip")); + yield download.start(); + } + else { + download = yield promiseStartLegacyDownload(httpUrl("parentalblocked.zip")); + yield promiseDownloadStopped(download); + } + do_throw("The download should have blocked."); + } catch (ex if ex instanceof Downloads.Error && ex.becauseBlocked) { + do_check_true(ex.becauseBlockedByParentalControls); + do_check_true(download.error.becauseBlockedByParentalControls); + do_check_true(download.stopped); + } + + do_check_false(yield OS.File.exists(download.target.path)); +}); + /** * download.showContainingDirectory() action */ diff --git a/toolkit/components/jsdownloads/test/unit/head.js b/toolkit/components/jsdownloads/test/unit/head.js index 10e02393ee9..b338d6f1b3f 100644 --- a/toolkit/components/jsdownloads/test/unit/head.js +++ b/toolkit/components/jsdownloads/test/unit/head.js @@ -773,6 +773,13 @@ add_task(function test_common_initialize() TEST_DATA_SHORT_GZIP_ENCODED_SECOND.length); }); + // This URL will emulate being blocked by Windows Parental controls + gHttpServer.registerPathHandler("/parentalblocked.zip", + function (aRequest, aResponse) { + aResponse.setStatusLine(aRequest.httpVersion, 450, + "Blocked by Windows Parental Controls"); + }); + // Disable integration with the host application requiring profile access. DownloadIntegration.dontLoadList = true; DownloadIntegration.dontLoadObservers = true; From 0ce8c586592205fe91fee986d5c6aa04e1a0f558 Mon Sep 17 00:00:00 2001 From: Ed Morley Date: Thu, 26 Sep 2013 16:22:26 +0100 Subject: [PATCH 38/84] Backed out changeset a2601d3f3214 (bug 919496) for xpcshell assertions during test_webappsActor.js --- browser/devtools/app-manager/webapps-store.js | 68 +------------------ .../apps/tests/unit/test_webappsActor.js | 19 ------ toolkit/devtools/apps/tests/unit/xpcshell.ini | 1 + toolkit/devtools/server/actors/webapps.js | 27 -------- 4 files changed, 4 insertions(+), 111 deletions(-) diff --git a/browser/devtools/app-manager/webapps-store.js b/browser/devtools/app-manager/webapps-store.js index 34d35ec738b..ded3fac6c7a 100644 --- a/browser/devtools/app-manager/webapps-store.js +++ b/browser/devtools/app-manager/webapps-store.js @@ -8,6 +8,9 @@ const {Connection} = require("devtools/client/connection-manager"); const {Cu} = require("chrome"); const dbgClient = Cu.import("resource://gre/modules/devtools/dbg-client.jsm"); +dbgClient.UnsolicitedNotifications.appOpen = "appOpen"; +dbgClient.UnsolicitedNotifications.appClose = "appClose" + const _knownWebappsStores = new WeakMap(); let WebappsStore; @@ -100,14 +103,6 @@ WebappsStore.prototype = { this._onAppClose(manifestURL); }); - client.addListener("appInstall", (type, { manifestURL }) => { - this._onAppInstall(manifestURL); - }); - - client.addListener("appUninstall", (type, { manifestURL }) => { - this._onAppUninstall(manifestURL); - }); - return deferred.resolve(); }) return deferred.promise; @@ -182,10 +177,6 @@ WebappsStore.prototype = { let a = allApps[idx++]; request.manifestURL = a.manifestURL; return client.request(request, (res) => { - if (res.error) { - Cu.reportError(res.message || res.error); - } - if (res.url) { a.iconURL = res.url; } @@ -213,57 +204,4 @@ WebappsStore.prototype = { return m != manifest; }); }, - - _onAppInstall: function(manifest) { - let client = this._connection.client; - let request = { - to: this._webAppsActor, - type: "getApp", - manifestURL: manifest - }; - - client.request(request, (res) => { - if (res.error) { - if (res.error == "forbidden") { - // We got a notification for an app we don't have access to. - // Ignore. - return; - } - Cu.reportError(res.message || res.error); - return; - } - - let app = res.app; - app.running = false; - - let notFound = true; - let proxifiedApp; - for (let i = 0; i < this.object.all.length; i++) { - let storedApp = this.object.all[i]; - if (storedApp.manifestURL == app.manifestURL) { - this.object.all[i] = app; - proxifiedApp = this.object.all[i]; - notFound = false; - break; - } - } - if (notFound) { - this.object.all.push(app); - proxifiedApp = this.object.all[this.object.all.length - 1]; - } - - request.type = "getIconAsDataURL"; - client.request(request, (res) => { - if (res.url) { - proxifiedApp.iconURL = res.url; - } - }); - }); - }, - - _onAppUninstall: function(manifest) { - this.object.all = this.object.all.filter((app) => { - return (app.manifestURL != manifest); - }); - }, } diff --git a/toolkit/devtools/apps/tests/unit/test_webappsActor.js b/toolkit/devtools/apps/tests/unit/test_webappsActor.js index 724b3efa5ea..09699f6ceb1 100644 --- a/toolkit/devtools/apps/tests/unit/test_webappsActor.js +++ b/toolkit/devtools/apps/tests/unit/test_webappsActor.js @@ -57,23 +57,6 @@ add_test(function testGetAll() { }); }); -add_test(function testGetApp() { - let manifestURL = APP_ORIGIN + "/manifest.webapp"; - let request = {type: "getApp", manifestURL: manifestURL}; - webappActorRequest(request, function (aResponse) { - do_check_true("app" in aResponse); - let app = aResponse.app; - do_check_eq(app.id, gAppId); - do_check_eq(app.name, "Test app"); - do_check_eq(app.manifest.description, "Testing webapps actor"); - do_check_eq(app.manifest.launch_path, "/index.html"); - do_check_eq(app.origin, APP_ORIGIN); - do_check_eq(app.installOrigin, app.origin); - do_check_eq(app.manifestURL, app.origin + "/manifest.webapp"); - run_next_test(); - }); -}); - add_test(function testLaunchApp() { let manifestURL = APP_ORIGIN + "/manifest.webapp"; let startPoint = "/index.html"; @@ -120,7 +103,6 @@ add_test(function testCloseApp() { let red1px = "data:application/xml;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAADElEQVQI12P4z8AAAAMBAQAY3Y2wAAAAAElFTkSuQmCC"; let blue1px = "data:application/xml;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAIAAACQd1PeAAAADElEQVQI12MwZDgHAAFlAQBDpjhLAAAAAElFTkSuQmCC"; -/* testGetIcon and testGetIconWithCustomSize disabled: bug 920981 add_test(function testGetIcon() { let manifestURL = APP_ORIGIN + "/manifest.webapp"; let request = { @@ -152,7 +134,6 @@ add_test(function testGetIconWithCustomSize() { run_next_test(); }); }); -*/ add_test(function testUninstall() { let manifestURL = APP_ORIGIN + "/manifest.webapp"; diff --git a/toolkit/devtools/apps/tests/unit/xpcshell.ini b/toolkit/devtools/apps/tests/unit/xpcshell.ini index dc0119a6ecc..c29025792bd 100644 --- a/toolkit/devtools/apps/tests/unit/xpcshell.ini +++ b/toolkit/devtools/apps/tests/unit/xpcshell.ini @@ -4,3 +4,4 @@ tail = tail_apps.js support-files = data/app.zip [test_webappsActor.js] +skip-if = (os == "win" || "linux" || "mac") diff --git a/toolkit/devtools/server/actors/webapps.js b/toolkit/devtools/server/actors/webapps.js index bf5cf9f15f0..f2c0256de49 100644 --- a/toolkit/devtools/server/actors/webapps.js +++ b/toolkit/devtools/server/actors/webapps.js @@ -541,32 +541,6 @@ WebappsActor.prototype = { return deferred.promise; }, - getApp: function wa_actorGetApp(aRequest) { - debug("getAll"); - - let manifestURL = aRequest.manifestURL; - if (!manifestURL) { - return { error: "missingParameter", - message: "missing parameter manifestURL" }; - } - - let reg = DOMApplicationRegistry; - let app = reg.getAppByManifestURL(manifestURL); - if (!app) { - return { error: "appNotFound" }; - } - - if (this._isAppAllowedForManifest(app.manifestURL)) { - let deferred = promise.defer(); - reg.getManifestFor(manifestURL, function (manifest) { - app.manifest = manifest; - deferred.resolve({app: app}); - }); - return deferred.promise; - } - return { error: "forbidden" }; - }, - _areCertifiedAppsAllowed: function wa__areCertifiedAppsAllowed() { let pref = "devtools.debugger.forbid-certified-apps"; return !Services.prefs.getBoolPref(pref); @@ -954,7 +928,6 @@ if (Services.prefs.getBoolPref("devtools.debugger.enable-content-actors")) { let requestTypes = WebappsActor.prototype.requestTypes; requestTypes.uploadPackage = WebappsActor.prototype.uploadPackage; requestTypes.getAll = WebappsActor.prototype.getAll; - requestTypes.getApp = WebappsActor.prototype.getApp; requestTypes.launch = WebappsActor.prototype.launch; requestTypes.close = WebappsActor.prototype.close; requestTypes.uninstall = WebappsActor.prototype.uninstall; From 4a1b1983318f19847ed9d00f3a8f4c167b48e329 Mon Sep 17 00:00:00 2001 From: Chenxia Liu Date: Thu, 26 Sep 2013 10:47:23 -0700 Subject: [PATCH 39/84] Bug 919704 - Remove empty screen for "Top Sites". r=sriram --- mobile/android/base/Makefile.in | 3 --- mobile/android/base/home/TopSitesPage.java | 21 ------------------ .../base/locales/en-US/android_strings.dtd | 2 -- .../drawable-hdpi/icon_most_visited_empty.png | Bin 1294 -> 0 bytes .../drawable-mdpi/icon_most_visited_empty.png | Bin 808 -> 0 bytes .../icon_most_visited_empty.png | Bin 1783 -> 0 bytes .../resources/layout/home_top_sites_page.xml | 5 ----- mobile/android/base/strings.xml.in | 2 -- 8 files changed, 33 deletions(-) delete mode 100644 mobile/android/base/resources/drawable-hdpi/icon_most_visited_empty.png delete mode 100644 mobile/android/base/resources/drawable-mdpi/icon_most_visited_empty.png delete mode 100644 mobile/android/base/resources/drawable-xhdpi/icon_most_visited_empty.png diff --git a/mobile/android/base/Makefile.in b/mobile/android/base/Makefile.in index 40cc6a92ea9..7c6c27b5c36 100644 --- a/mobile/android/base/Makefile.in +++ b/mobile/android/base/Makefile.in @@ -666,7 +666,6 @@ RES_DRAWABLE_MDPI = \ res/drawable-mdpi/icon_most_recent.png \ res/drawable-mdpi/icon_most_recent_empty.png \ res/drawable-mdpi/icon_most_visited.png \ - res/drawable-mdpi/icon_most_visited_empty.png \ res/drawable-mdpi/icon_openinapp.png \ res/drawable-mdpi/icon_pageaction.png \ res/drawable-mdpi/icon_reading_list_empty.png \ @@ -782,7 +781,6 @@ RES_DRAWABLE_HDPI = \ res/drawable-hdpi/icon_most_recent.png \ res/drawable-hdpi/icon_most_recent_empty.png \ res/drawable-hdpi/icon_most_visited.png \ - res/drawable-hdpi/icon_most_visited_empty.png \ res/drawable-hdpi/icon_openinapp.png \ res/drawable-hdpi/icon_pageaction.png \ res/drawable-hdpi/icon_reading_list_empty.png \ @@ -884,7 +882,6 @@ RES_DRAWABLE_XHDPI = \ res/drawable-xhdpi/icon_most_recent.png \ res/drawable-xhdpi/icon_most_recent_empty.png \ res/drawable-xhdpi/icon_most_visited.png \ - res/drawable-xhdpi/icon_most_visited_empty.png \ res/drawable-xhdpi/icon_openinapp.png \ res/drawable-xhdpi/icon_pageaction.png \ res/drawable-xhdpi/icon_reading_list_empty.png \ diff --git a/mobile/android/base/home/TopSitesPage.java b/mobile/android/base/home/TopSitesPage.java index 1bbc674161d..a9a8dcb2ca6 100644 --- a/mobile/android/base/home/TopSitesPage.java +++ b/mobile/android/base/home/TopSitesPage.java @@ -47,11 +47,8 @@ import android.view.MotionEvent; import android.view.View; import android.view.View.OnTouchListener; import android.view.ViewGroup; -import android.view.ViewStub; import android.widget.AdapterView; -import android.widget.ImageView; import android.widget.ListView; -import android.widget.TextView; import android.widget.Toast; import java.util.EnumSet; @@ -87,9 +84,6 @@ public class TopSitesPage extends HomeFragment { // Grid of top sites private TopSitesGridView mGrid; - // Reference to the View to display when there are no results. - private View mEmptyView; - // Banner to show snippets. private HomeBanner mBanner; @@ -224,7 +218,6 @@ public class TopSitesPage extends HomeFragment { super.onDestroyView(); mList = null; mGrid = null; - mEmptyView = null; mListAdapter = null; mGridAdapter = null; } @@ -466,20 +459,6 @@ public class TopSitesPage extends HomeFragment { if (c != null && c.getCount() > 0) { return; } - - if (mEmptyView == null) { - // Set empty page view. We delay this so that the empty view won't flash. - ViewStub emptyViewStub = (ViewStub) getView().findViewById(R.id.home_empty_view_stub); - mEmptyView = emptyViewStub.inflate(); - - final ImageView emptyIcon = (ImageView) mEmptyView.findViewById(R.id.home_empty_image); - emptyIcon.setImageResource(R.drawable.icon_most_visited_empty); - - final TextView emptyText = (TextView) mEmptyView.findViewById(R.id.home_empty_text); - emptyText.setText(R.string.home_most_visited_empty); - - mList.setEmptyView(mEmptyView); - } } private static class TopSitesLoader extends SimpleCursorLoader { diff --git a/mobile/android/base/locales/en-US/android_strings.dtd b/mobile/android/base/locales/en-US/android_strings.dtd index c8151c21fb8..547ce6f7b1b 100644 --- a/mobile/android/base/locales/en-US/android_strings.dtd +++ b/mobile/android/base/locales/en-US/android_strings.dtd @@ -280,7 +280,6 @@ size. --> - as alternate text for accessibility. It is not visible in the UI. --> - diff --git a/mobile/android/base/resources/drawable-hdpi/icon_most_visited_empty.png b/mobile/android/base/resources/drawable-hdpi/icon_most_visited_empty.png deleted file mode 100644 index 93f5bf2d0ddb74d232252088c59837e6dc682216..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1294 zcmah}YfMuI7_EZTRay}cO1)4XibZUpP~^f0S}0bYQgNA5L<>4}b`2MWRViw%_LhgY zEDJssreGIvj1UI(1&Bop7j@8rIEDr8M;IO8Zs2po^6xZZxTmi~EmV7_18x3_G(kp6;7gj&+Vtd+px}L@rJ5 zk6Kv0=k$wrSm7R)y(7wCmK}6qGMR}#k*0~hmP)7>+zy0Myx@xX9zP2sanf*A&B+N- z<`XU-zG4lsGNj&r^)7a3ut2lleHaGYqfFvO8zQ4qrmtsklm2vmhE+*F!)BB(f zMGQu|VF_f3=4z;GLrih%`avj*o7L@uMIX?40o;&GK_0M#%KzjA?U6aH>c}g?33jR5 zkh+LN<&%=Ay+Tlasf<~316;KliPZ))6`&QGFo<_aFbe&m830$fp;T;ztrOZ9h+N$5 zi)@``#oak%$H^8*TmY0aEf%h}4d zOtmExBaGt2FK}iL z`e(9^g3m>?0BQHIW8^C2>kN}{pU0ITR;IT;HA@F72josK{6;#!z*|Gnws~y=`X8(9 zw{ie-!U6kvRnU`{Db{#{7)Z!=w*@0LQLnkMJ8G|&jpb8{M5weCIWwkQx(QvuJNuHa<++c)K&8-_iEU z6Y`}%s(1i%fkD0BKkLv+1f`2&zJGVOOj9nD;h;whMQP#KcF2BKt?|DLs zKIp)*N_-*SZPY!tx= z%AKY&H6wA7u2YCoP#fzd<A% z>yO=Q=S48;wK#B$Xm>Oc12h6 z3zlo2S$;FDKQZkCpYw~Ol_m-=vtD>rRLUFk|IVQ(Q{t>J+S-5$qG zzt~kUW_4$09FA#N*#20iO696F7fMP=jDt8aZ?U|@_1-rWzZ3PTUsijLEJF%%r7;Am-6*Tyw2@hA0XCtLI0s; zmS|>#gp+-lMTxwQ&cfd^y>lFud=~DO>Dkj_6*0qUezCz9(TE#P^GkF-DMv^+%NJ^V z%2qifW%btMiDk&aLsGvMFi#W@;N~uVF{{J<+#?O0Hw*c9h(%_XI7}?P9%wUvLYu2* zN%9e;{qCkZSqsm*yh&8y>`r>IT99K;Q<;Ro*$aCW`~S$4Zg6_}|HawVLfKRUai{&9 z4~+`hHK&`UpWY}l>A-0ThppYaAAEJ4wOZPh|5iZ%U4!`Qd9T$AnKh?Bw^}E<3q6mEna|%x|J@4&M%C-0Fg*G*vL#IDVt~F@YbIVvD7W|9t<3b=&*f0LYQ%lgU&}eWTE6GiJ-h9B?%(&1bI$j3&Uwx`|DBRU zk!(8@4h4h3>>~Ct4zEVtnpq=PJ@p^RKo|^pCxStbIc=O6S=m4GA-?lf#*QaNH`7!R zADPA&=Rf7ewh&UvJ&xg@8;Zb+u6^qUkjU<+NL7jhSacQqTKGb$#H(Lel}}G zNj=x{)BP8>+7iRYH3Rncm?dPT&wzS-de^wykkRNUESe3F5V;NrziNPq)%~RuQs+N% z`L@QT>EBm=B^5GH5@?PYuJ$*+5L!*U3VX~6hJnUZvF5Jh*ei660MX%cFHOTh-%>$w8Ir06mTg6-wERV<6-=%sJA zaXp?1`gdIFXjYhAR;gKbg=M0c%3TU5dLq#0MuWviq=?1bF4K=Xc%!+W;X z=whtSjjqqc3K}T_bev%QW|MV7UD7?fISj|;LvZ*#hLLCp-y+x)-J+z=n1jpAnDl97 zPT1wXlF(!A*-K44tFt$y$O@Izw-Rf(q1-ZjKfeOun{wUkAjR9hyy%s8ZEw}kN!K70 z&Q;5b8k{)39If!RTvh4e^?3D53aW#(i5ml|GlEJxSmOBNQJ!D4aBwW-8|+LkJsnj5&Er@@1pMf#}VWOB)N#BDZc{PANsqCdU!{RH~-E(CU~ z4LJ=R`|vL$rz$92&hDbxr~~B{EOm}}qYt!R3vB-_%Z&p7 z$AyvOpAxzEuLDk^!H*4H5!Y-MTB44ns6S#Cqz&~V(lmWTIZRaiZvBq!@&q@-kp&=( zQrgf@5ro&OD}123D8V(I)Y+}}=p8^$Ds7B8%arvN`}09B*0b{V;BT@`XXa&PuJ_{( z{2dywd0UPS$;2i%4eveAIvhiRo~puqi|XrsQIug+%rNtxt64%Cz49Z8`JJheTU>1?S^c$M`i<6ln*X` z?*%QgewrLh6>$yCRQdpc*LQVk-6Y3dpN!~o++#jt#}2wRdIxxF{o%DB~#LvqKc;SM-FL zzf(j1Oq-ow9DO=;ah%9)lQp)df7vMJCt=t>=r>e&LLc;);Krta#XKk7ZhG?>&(34_4P}I2ZgW;fw`|E^wIQ{&e7XiGM1U_5)@9u z(kI~3aw);=jXjTbjwMif?@GQ>KX`PcBmi@Lg5l{U+&4*JTF*Ul+OspyDKYDx=Y(Cm zY`m?Y`Y`FR%Gh@@=MZgWGc;cp_p0=zNBqMwYbcP$SI=oRTCP|6iB3zA1;D;F)~e3Q z{~FdB12)vn$}C5Px=Eg`=mjvVpZ}Q?aJjq863UfivJPHdk`I2;-%|#M79^9b%Ds>M z@&A_i!$i+}wdE5qNn;pP%ne$cqN%N*j5t0`{Yw>T(L}TK0}7l$8k!3rbP{CzUu - - &home_last_tabs_empty; &home_most_recent_title; &home_most_recent_empty; - &home_most_visited_title; - &home_most_visited_empty; &home_reading_list_empty; &home_reading_list_hint; &home_reading_list_hint_accessible; From 504fa94de06d57e3ea7260cb030b02cd216b3d2c Mon Sep 17 00:00:00 2001 From: Shane Caraveo Date: Thu, 26 Sep 2013 10:55:08 -0700 Subject: [PATCH 40/84] bug 919803 fix panel sizing by not removing panel iframe unecessarily, r=markh --- browser/base/content/browser-social.js | 27 +++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/browser/base/content/browser-social.js b/browser/base/content/browser-social.js index e118535887a..304c8d61d09 100644 --- a/browser/base/content/browser-social.js +++ b/browser/base/content/browser-social.js @@ -874,18 +874,27 @@ SocialToolbar = { let toggleNotificationsCommand = document.getElementById("Social:ToggleNotifications"); toggleNotificationsCommand.setAttribute("hidden", !socialEnabled); - let parent = document.getElementById("social-notification-panel"); - while (parent.hasChildNodes()) { - let frame = parent.firstChild; - SharedFrame.forgetGroup(frame.id); - parent.removeChild(frame); - } - + // we need to remove buttons and frames if !socialEnabled or the provider + // has changed (frame origin does not match current provider). We only + // remove frames that are "attached" to buttons in this toolbar button since + // other buttons may also be using grouped frames. let tbi = document.getElementById("social-provider-button"); if (tbi) { // buttons after social-provider-button are ambient icons - while (tbi.nextSibling) { - tbi.parentNode.removeChild(tbi.nextSibling); + let next = tbi.nextSibling; + let currentOrigin = Social.provider ? Social.provider.origin : null; + + while (next) { + let button = next; + next = next.nextSibling; + // get the frame for this button + let frameId = button.getAttribute("notificationFrameId"); + let frame = document.getElementById(frameId); + if (!socialEnabled || frame.getAttribute("origin") != currentOrigin) { + SharedFrame.forgetGroup(frame.id); + frame.parentNode.removeChild(frame); + button.parentNode.removeChild(button); + } } } }, From 51843f850ddf8302e2a647d479f70d754e466f24 Mon Sep 17 00:00:00 2001 From: "patilkr24@gmail.com" Date: Thu, 26 Sep 2013 14:07:29 -0400 Subject: [PATCH 41/84] Bug 898712 - Add an error category to SSL errors in the browser console. r=bsmith --- browser/devtools/webconsole/webconsole.js | 1 + content/base/public/nsContentUtils.h | 8 ++++++++ content/base/src/nsContentUtils.cpp | 18 ++++++++++++++++++ .../ssl/src/SSLServerCertVerification.cpp | 8 ++------ security/manager/ssl/src/nsNSSCallbacks.cpp | 18 ++++++++---------- security/manager/ssl/src/nsNSSIOLayer.cpp | 7 ++----- 6 files changed, 39 insertions(+), 21 deletions(-) diff --git a/browser/devtools/webconsole/webconsole.js b/browser/devtools/webconsole/webconsole.js index f330dcce38b..54936299586 100644 --- a/browser/devtools/webconsole/webconsole.js +++ b/browser/devtools/webconsole/webconsole.js @@ -4522,6 +4522,7 @@ var Utils = { case "CSP": case "Invalid HSTS Headers": case "Insecure Password Field": + case "SSL": return CATEGORY_SECURITY; default: diff --git a/content/base/public/nsContentUtils.h b/content/base/public/nsContentUtils.h index 5e590a7c7a0..c59c5f8f1be 100644 --- a/content/base/public/nsContentUtils.h +++ b/content/base/public/nsContentUtils.h @@ -737,6 +737,14 @@ public: return sXPConnect; } + /** + * Report simple error message to the browser console + * @param aErrorText the error message + * @param classification Name of the module reporting error + */ + static void LogSimpleConsoleError(const nsAString& aErrorText, + const char * classification); + /** * Report a non-localized error message to the error console. * @param aErrorText the error message diff --git a/content/base/src/nsContentUtils.cpp b/content/base/src/nsContentUtils.cpp index 93794eea10d..d7b18d8c6ba 100644 --- a/content/base/src/nsContentUtils.cpp +++ b/content/base/src/nsContentUtils.cpp @@ -3014,6 +3014,24 @@ nsresult nsContentUtils::FormatLocalizedString(PropertiesFile aFile, getter_Copies(aResult)); } +/* static */ void +nsContentUtils::LogSimpleConsoleError(const nsAString& aErrorText, + const char * classification) +{ + nsCOMPtr scriptError = + do_CreateInstance(NS_SCRIPTERROR_CONTRACTID); + if (scriptError) { + nsCOMPtr console = + do_GetService(NS_CONSOLESERVICE_CONTRACTID); + if (console && NS_SUCCEEDED(scriptError->Init(aErrorText, EmptyString(), + EmptyString(), 0, 0, + nsIScriptError::errorFlag, + classification))) { + console->LogMessage(scriptError); + } + } +} + /* static */ nsresult nsContentUtils::ReportToConsole(uint32_t aErrorFlags, const nsACString& aCategory, diff --git a/security/manager/ssl/src/SSLServerCertVerification.cpp b/security/manager/ssl/src/SSLServerCertVerification.cpp index af129538ede..76456203458 100644 --- a/security/manager/ssl/src/SSLServerCertVerification.cpp +++ b/security/manager/ssl/src/SSLServerCertVerification.cpp @@ -113,9 +113,9 @@ #include "nsXPCOMCIDInternal.h" #include "nsComponentManagerUtils.h" #include "nsServiceManagerUtils.h" -#include "nsIConsoleService.h" #include "PSMRunnable.h" #include "SharedSSLState.h" +#include "nsContentUtils.h" #include "ssl.h" #include "secerr.h" @@ -213,11 +213,7 @@ LogInvalidCertError(TransportSecurityInfo *socketInfo, socketInfo->GetErrorLogMessage(errorCode, errorMessageType, message); if (!message.IsEmpty()) { - nsCOMPtr console; - console = do_GetService(NS_CONSOLESERVICE_CONTRACTID); - if (console) { - console->LogStringMessage(message.get()); - } + nsContentUtils::LogSimpleConsoleError(message, "SSL"); } } diff --git a/security/manager/ssl/src/nsNSSCallbacks.cpp b/security/manager/ssl/src/nsNSSCallbacks.cpp index 633719c9ff3..732b4ae8226 100644 --- a/security/manager/ssl/src/nsNSSCallbacks.cpp +++ b/security/manager/ssl/src/nsNSSCallbacks.cpp @@ -18,7 +18,7 @@ #include "nsProxyRelease.h" #include "PSMRunnable.h" #include "ScopedNSSTypes.h" -#include "nsIConsoleService.h" +#include "nsContentUtils.h" #include "nsIHttpChannelInternal.h" #include "nsNetUtil.h" #include "SharedSSLState.h" @@ -1042,16 +1042,14 @@ void HandshakeCallback(PRFileDesc* fd, void* client_data) { // localized. if (!siteSupportsSafeRenego && ioLayerHelpers.getWarnLevelMissingRFC5746() > 0) { - nsCOMPtr console = do_GetService(NS_CONSOLESERVICE_CONTRACTID); - if (console) { - nsXPIDLCString hostName; - infoObject->GetHostName(getter_Copies(hostName)); + nsXPIDLCString hostName; + infoObject->GetHostName(getter_Copies(hostName)); - nsAutoString msg; - msg.Append(NS_ConvertASCIItoUTF16(hostName)); - msg.Append(NS_LITERAL_STRING(" : server does not support RFC 5746, see CVE-2009-3555")); - console->LogStringMessage(msg.get()); - } + nsAutoString msg; + msg.Append(NS_ConvertASCIItoUTF16(hostName)); + msg.Append(NS_LITERAL_STRING(" : server does not support RFC 5746, see CVE-2009-3555")); + + nsContentUtils::LogSimpleConsoleError(msg, "SSL"); } ScopedCERTCertificate serverCert(SSL_PeerCertificate(fd)); diff --git a/security/manager/ssl/src/nsNSSIOLayer.cpp b/security/manager/ssl/src/nsNSSIOLayer.cpp index ede8fbdb725..c40914289f2 100644 --- a/security/manager/ssl/src/nsNSSIOLayer.cpp +++ b/security/manager/ssl/src/nsNSSIOLayer.cpp @@ -37,6 +37,7 @@ #include "ScopedNSSTypes.h" #include "SharedSSLState.h" #include "mozilla/Preferences.h" +#include "nsContentUtils.h" #include "ssl.h" #include "secerr.h" @@ -668,11 +669,7 @@ nsHandleSSLError(nsNSSSocketInfo *socketInfo, socketInfo->GetErrorLogMessage(err, errtype, errorString); if (!errorString.IsEmpty()) { - nsCOMPtr console; - console = do_GetService(NS_CONSOLESERVICE_CONTRACTID); - if (console) { - console->LogStringMessage(errorString.get()); - } + nsContentUtils::LogSimpleConsoleError(errorString, "SSL"); } } From 09833f2c82a221e8b46b23a2cc21b561bd33ccb6 Mon Sep 17 00:00:00 2001 From: Alexandre Poirot Date: Thu, 26 Sep 2013 14:07:44 -0400 Subject: [PATCH 42/84] Bug 919831 - Fix support of packaged apps with custom origin. r=paul --- browser/devtools/app-manager/app-projects.js | 27 +++++++++++++++++++ .../devtools/app-manager/content/projects.js | 13 ++++++--- 2 files changed, 36 insertions(+), 4 deletions(-) diff --git a/browser/devtools/app-manager/app-projects.js b/browser/devtools/app-manager/app-projects.js index 78349f0ce76..bf89a379425 100644 --- a/browser/devtools/app-manager/app-projects.js +++ b/browser/devtools/app-manager/app-projects.js @@ -68,6 +68,23 @@ const IDB = { return deferred.promise; }, + update: function(project) { + let deferred = promise.defer(); + + var transaction = IDB._db.transaction(["projects"], "readwrite"); + var objectStore = transaction.objectStore("projects"); + var request = objectStore.put(project); + request.onerror = function(event) { + deferred.reject("Unable to update project to the AppProjects indexedDB: " + + this.error.name + " - " + this.error.message ); + }; + request.onsuccess = function() { + deferred.resolve(); + }; + + return deferred.promise; + }, + remove: function(location) { let deferred = promise.defer(); @@ -110,6 +127,8 @@ const AppProjects = { // The packaged app local path is a valid id, but only on the client. // This origin will be used to generate the true id of an app: // its manifest URL. + // If the app ends up specifying an explicit origin in its manifest, + // we will override this random UUID on app install. packagedAppOrigin: generateUUID().toString().slice(1, -1) }; return IDB.add(project).then(function () { @@ -131,6 +150,14 @@ const AppProjects = { }); }, + update: function (project) { + return IDB.update({ + type: project.type, + location: project.location, + packagedAppOrigin: project.packagedAppOrigin + }).then(() => project); + }, + remove: function(location) { return IDB.remove(location).then(function () { let projects = store.object.projects; diff --git a/browser/devtools/app-manager/content/projects.js b/browser/devtools/app-manager/content/projects.js index ed3ed1a3a40..f3ec4ca7aad 100644 --- a/browser/devtools/app-manager/content/projects.js +++ b/browser/devtools/app-manager/content/projects.js @@ -208,9 +208,15 @@ let UI = { }, install: function(project) { - let install; if (project.type == "packaged") { - install = installPackaged(this.connection.client, this.listTabsResponse.webappsActor, project.location, project.packagedAppOrigin); + return installPackaged(this.connection.client, this.listTabsResponse.webappsActor, project.location, project.packagedAppOrigin) + .then(({ appId }) => { + // If the packaged app specified a custom origin override, + // we need to update the local project origin + project.packagedAppOrigin = appId; + // And ensure the indexed db on disk is also updated + AppProjects.update(project); + }); } else { let manifestURLObject = Services.io.newURI(project.location, null, null); let origin = Services.io.newURI(manifestURLObject.prePath, null, null); @@ -219,9 +225,8 @@ let UI = { origin: origin.spec, manifestURL: project.location }; - install = installHosted(this.connection.client, this.listTabsResponse.webappsActor, appId, metadata, project.manifest); + return installHosted(this.connection.client, this.listTabsResponse.webappsActor, appId, metadata, project.manifest); } - return install; }, start: function(project) { From f2b90586221a00de01088412fb5a294aeabba0a9 Mon Sep 17 00:00:00 2001 From: Sankha Narayan Guria Date: Thu, 26 Sep 2013 14:36:59 +0530 Subject: [PATCH 43/84] Bug 920943 - Unprefix -moz-grab from browser chrome CSS. r=dao --- browser/base/content/browser.css | 2 +- browser/base/content/sanitizeDialog.css | 2 +- toolkit/themes/linux/global/toolbar.css | 2 +- toolkit/themes/os2/global/toolbar.css | 2 +- toolkit/themes/osx/global/toolbar.css | 2 +- toolkit/themes/windows/global/toolbar.css | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/browser/base/content/browser.css b/browser/base/content/browser.css index 055aa3a396a..2dc90a3261e 100644 --- a/browser/base/content/browser.css +++ b/browser/base/content/browser.css @@ -259,7 +259,7 @@ panel[noactions] > richlistbox > richlistitem[type~="action"] > .ac-url-box > .a #wrapper-urlbar-container > #urlbar-container > #urlbar { -moz-user-input: disabled; - cursor: -moz-grab; + cursor: grab; } #PopupAutoComplete { diff --git a/browser/base/content/sanitizeDialog.css b/browser/base/content/sanitizeDialog.css index 27c3c086666..a7c17f094ac 100644 --- a/browser/base/content/sanitizeDialog.css +++ b/browser/base/content/sanitizeDialog.css @@ -11,7 +11,7 @@ #placesTreechildren::-moz-tree-cell(grippyRow), #placesTreechildren::-moz-tree-cell-text(grippyRow), #placesTreechildren::-moz-tree-image(grippyRow) { - cursor: -moz-grab; + cursor: grab; } diff --git a/toolkit/themes/linux/global/toolbar.css b/toolkit/themes/linux/global/toolbar.css index 03655895917..e8e082f15ac 100644 --- a/toolkit/themes/linux/global/toolbar.css +++ b/toolkit/themes/linux/global/toolbar.css @@ -56,7 +56,7 @@ toolbarspacer { /* ::::: toolbarpaletteitem ::::: */ toolbarpaletteitem { - cursor: -moz-grab; + cursor: grab; } .toolbarpaletteitem-box[type="spacer"], diff --git a/toolkit/themes/os2/global/toolbar.css b/toolkit/themes/os2/global/toolbar.css index 1ef43111504..0200fc6d8a7 100644 --- a/toolkit/themes/os2/global/toolbar.css +++ b/toolkit/themes/os2/global/toolbar.css @@ -74,7 +74,7 @@ toolbarspacer { /* ::::: toolbarpaletteitem ::::: */ toolbarpaletteitem { - cursor: -moz-grab; + cursor: grab; } .toolbarpaletteitem-box[type="spacer"], diff --git a/toolkit/themes/osx/global/toolbar.css b/toolkit/themes/osx/global/toolbar.css index 6298dbd0ee6..0d0ad6b7789 100644 --- a/toolkit/themes/osx/global/toolbar.css +++ b/toolkit/themes/osx/global/toolbar.css @@ -41,7 +41,7 @@ toolbarseparator { /* ::::: toolbarpaletteitem ::::: */ toolbarpaletteitem { - cursor: -moz-grab; + cursor: grab; } toolbar[iconsize="small"] toolbarpaletteitem[type="spacer"] { diff --git a/toolkit/themes/windows/global/toolbar.css b/toolkit/themes/windows/global/toolbar.css index 40f6aedd606..991592d2ab2 100644 --- a/toolkit/themes/windows/global/toolbar.css +++ b/toolkit/themes/windows/global/toolbar.css @@ -65,7 +65,7 @@ toolbarspacer { /* ::::: toolbarpaletteitem ::::: */ toolbarpaletteitem { - cursor: -moz-grab; + cursor: grab; } .toolbarpaletteitem-box[type="spacer"], From 78a172c4af48714268443b7f2d4c79b2b5c210cc Mon Sep 17 00:00:00 2001 From: Jared Wein Date: Thu, 26 Sep 2013 15:18:25 -0400 Subject: [PATCH 44/84] Bug 920803 - Blocked plug-in click-to-activate doorhanger is too narrow for some locales. r=dao --- browser/base/content/urlbarBindings.xml | 2 +- browser/locales/en-US/chrome/browser/browser.dtd | 7 +++++++ browser/themes/shared/plugin-doorhanger.inc.css | 4 ---- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/browser/base/content/urlbarBindings.xml b/browser/base/content/urlbarBindings.xml index faea2189dd8..e9aa1b1626a 100644 --- a/browser/base/content/urlbarBindings.xml +++ b/browser/base/content/urlbarBindings.xml @@ -1499,7 +1499,7 @@ - + diff --git a/browser/locales/en-US/chrome/browser/browser.dtd b/browser/locales/en-US/chrome/browser/browser.dtd index e4a76067440..36a781a5f7d 100644 --- a/browser/locales/en-US/chrome/browser/browser.dtd +++ b/browser/locales/en-US/chrome/browser/browser.dtd @@ -672,6 +672,13 @@ just addresses the organization to follow, e.g. "This site is run by " --> + + + diff --git a/browser/themes/shared/plugin-doorhanger.inc.css b/browser/themes/shared/plugin-doorhanger.inc.css index bda08e4f61e..f427eed0644 100644 --- a/browser/themes/shared/plugin-doorhanger.inc.css +++ b/browser/themes/shared/plugin-doorhanger.inc.css @@ -2,10 +2,6 @@ padding: 0px; } -.click-to-play-plugins-notification-content { - width: 28em; -} - .click-to-play-plugins-notification-center-box { border: 1px solid ThreeDShadow; margin: 10px; From c0bfd4f1a748a1041198dcb4af2045679fd753e6 Mon Sep 17 00:00:00 2001 From: Brandon Benvie Date: Thu, 26 Sep 2013 10:51:51 -0700 Subject: [PATCH 45/84] Bug 843019 - Add VariablesViewController#setSingleVariable. r=vp, r=msucan --- .../netmonitor/netmonitor-controller.js | 1 + .../devtools/netmonitor/netmonitor-view.js | 7 ++-- .../widgets/VariablesViewController.jsm | 36 +++++++++++++++++-- browser/devtools/webconsole/webconsole.js | 15 +++----- 4 files changed, 44 insertions(+), 15 deletions(-) diff --git a/browser/devtools/netmonitor/netmonitor-controller.js b/browser/devtools/netmonitor/netmonitor-controller.js index c49d0b37df8..8ff53a2d409 100644 --- a/browser/devtools/netmonitor/netmonitor-controller.js +++ b/browser/devtools/netmonitor/netmonitor-controller.js @@ -65,6 +65,7 @@ Cu.import("resource:///modules/devtools/sourceeditor/source-editor.jsm"); Cu.import("resource:///modules/devtools/shared/event-emitter.js"); Cu.import("resource:///modules/devtools/SideMenuWidget.jsm"); Cu.import("resource:///modules/devtools/VariablesView.jsm"); +Cu.import("resource:///modules/devtools/VariablesViewController.jsm"); Cu.import("resource:///modules/devtools/ViewHelpers.jsm"); XPCOMUtils.defineLazyModuleGetter(this, "PluralForm", diff --git a/browser/devtools/netmonitor/netmonitor-view.js b/browser/devtools/netmonitor/netmonitor-view.js index 40887523f1b..b852baa51e2 100644 --- a/browser/devtools/netmonitor/netmonitor-view.js +++ b/browser/devtools/netmonitor/netmonitor-view.js @@ -1889,9 +1889,10 @@ NetworkDetailsView.prototype = { ? L10N.getFormatStr("jsonpScopeName", callbackPadding[0].slice(0, -1)) : L10N.getStr("jsonScopeName"); - let jsonScope = this._json.addScope(jsonScopeName); - jsonScope.addItem().populate(jsonObject, { expanded: true }); - jsonScope.expanded = true; + this._json.controller.setSingleVariable({ + label: jsonScopeName, + rawObject: jsonObject, + }); } // Malformed JSON. else { diff --git a/browser/devtools/shared/widgets/VariablesViewController.jsm b/browser/devtools/shared/widgets/VariablesViewController.jsm index 97c1a5b5c91..0f42bfcb45d 100644 --- a/browser/devtools/shared/widgets/VariablesViewController.jsm +++ b/browser/devtools/shared/widgets/VariablesViewController.jsm @@ -40,7 +40,7 @@ this.EXPORTED_SYMBOLS = ["VariablesViewController"]; * * @param VariablesView aView * The view to attach to. - * @param object aOptions + * @param object aOptions [optional] * Options for configuring the controller. Supported options: * - getObjectClient: callback for creating an object grip client * - getLongStringClient: callback for creating a long string grip client @@ -49,7 +49,7 @@ this.EXPORTED_SYMBOLS = ["VariablesViewController"]; * - getterOrSetterEvalMacro: callback for creating a getter/setter eval macro * - simpleValueEvalMacro: callback for creating a simple value eval macro */ -function VariablesViewController(aView, aOptions) { +function VariablesViewController(aView, aOptions = {}) { this.addExpander = this.addExpander.bind(this); this._getObjectClient = aOptions.getObjectClient; @@ -341,6 +341,38 @@ VariablesViewController.prototype = { } } }, + + /** + * Helper function for setting up a single Scope with a single Variable + * contained within it. + * + * @param object aOptions + * Options for the contents of the view: + * - objectActor: the grip of the new ObjectActor to show. + * - rawObject: the new raw object to show. + * - label: the new label for the inspected object. + * @return Object + * - variable: the created Variable. + * - expanded: the Promise that resolves when the variable expands. + */ + setSingleVariable: function(aOptions) { + this.view.empty(); + let scope = this.view.addScope(aOptions.label); + scope.expanded = true; + scope.locked = true; + + let variable = scope.addItem(); + let expanded; + + if (aOptions.objectActor) { + expanded = this.expand(variable, aOptions.objectActor); + } else if (aOptions.rawObject) { + variable.populate(aOptions.rawObject, { expanded: true }); + expanded = promise.resolve(); + } + + return { variable: variable, expanded: expanded }; + }, }; diff --git a/browser/devtools/webconsole/webconsole.js b/browser/devtools/webconsole/webconsole.js index 54936299586..5b509727d53 100644 --- a/browser/devtools/webconsole/webconsole.js +++ b/browser/devtools/webconsole/webconsole.js @@ -3481,20 +3481,13 @@ JSTerm.prototype = { view.delete = null; } - let scope = view.addScope(aOptions.label); - scope.expanded = true; - scope.locked = true; - - let container = scope.addItem(); - container.evaluationMacro = simpleValueEvalMacro; + let { variable, expanded } = view.controller.setSingleVariable(aOptions); + variable.evaluationMacro = simpleValueEvalMacro; if (aOptions.objectActor) { - view.controller.expand(container, aOptions.objectActor); view._consoleLastObjectActor = aOptions.objectActor.actor; } else if (aOptions.rawObject) { - container.populate(aOptions.rawObject); - view.commitHierarchy(); view._consoleLastObjectActor = null; } else { @@ -3502,7 +3495,9 @@ JSTerm.prototype = { "display."); } - this.emit("variablesview-updated", view, aOptions); + expanded.then(() => { + this.emit("variablesview-updated", view, aOptions); + }); }, /** From 4593bfa05d6f6b66fb5e0600630c01ade06b5e2d Mon Sep 17 00:00:00 2001 From: Ryan VanderMeulen Date: Thu, 26 Sep 2013 17:29:37 -0400 Subject: [PATCH 46/84] Backed out changeset 3732f69b6d81 (bug 843019) for mochitest-bc failures. --- .../netmonitor/netmonitor-controller.js | 1 - .../devtools/netmonitor/netmonitor-view.js | 7 ++-- .../widgets/VariablesViewController.jsm | 36 ++----------------- browser/devtools/webconsole/webconsole.js | 15 +++++--- 4 files changed, 15 insertions(+), 44 deletions(-) diff --git a/browser/devtools/netmonitor/netmonitor-controller.js b/browser/devtools/netmonitor/netmonitor-controller.js index 8ff53a2d409..c49d0b37df8 100644 --- a/browser/devtools/netmonitor/netmonitor-controller.js +++ b/browser/devtools/netmonitor/netmonitor-controller.js @@ -65,7 +65,6 @@ Cu.import("resource:///modules/devtools/sourceeditor/source-editor.jsm"); Cu.import("resource:///modules/devtools/shared/event-emitter.js"); Cu.import("resource:///modules/devtools/SideMenuWidget.jsm"); Cu.import("resource:///modules/devtools/VariablesView.jsm"); -Cu.import("resource:///modules/devtools/VariablesViewController.jsm"); Cu.import("resource:///modules/devtools/ViewHelpers.jsm"); XPCOMUtils.defineLazyModuleGetter(this, "PluralForm", diff --git a/browser/devtools/netmonitor/netmonitor-view.js b/browser/devtools/netmonitor/netmonitor-view.js index b852baa51e2..40887523f1b 100644 --- a/browser/devtools/netmonitor/netmonitor-view.js +++ b/browser/devtools/netmonitor/netmonitor-view.js @@ -1889,10 +1889,9 @@ NetworkDetailsView.prototype = { ? L10N.getFormatStr("jsonpScopeName", callbackPadding[0].slice(0, -1)) : L10N.getStr("jsonScopeName"); - this._json.controller.setSingleVariable({ - label: jsonScopeName, - rawObject: jsonObject, - }); + let jsonScope = this._json.addScope(jsonScopeName); + jsonScope.addItem().populate(jsonObject, { expanded: true }); + jsonScope.expanded = true; } // Malformed JSON. else { diff --git a/browser/devtools/shared/widgets/VariablesViewController.jsm b/browser/devtools/shared/widgets/VariablesViewController.jsm index 0f42bfcb45d..97c1a5b5c91 100644 --- a/browser/devtools/shared/widgets/VariablesViewController.jsm +++ b/browser/devtools/shared/widgets/VariablesViewController.jsm @@ -40,7 +40,7 @@ this.EXPORTED_SYMBOLS = ["VariablesViewController"]; * * @param VariablesView aView * The view to attach to. - * @param object aOptions [optional] + * @param object aOptions * Options for configuring the controller. Supported options: * - getObjectClient: callback for creating an object grip client * - getLongStringClient: callback for creating a long string grip client @@ -49,7 +49,7 @@ this.EXPORTED_SYMBOLS = ["VariablesViewController"]; * - getterOrSetterEvalMacro: callback for creating a getter/setter eval macro * - simpleValueEvalMacro: callback for creating a simple value eval macro */ -function VariablesViewController(aView, aOptions = {}) { +function VariablesViewController(aView, aOptions) { this.addExpander = this.addExpander.bind(this); this._getObjectClient = aOptions.getObjectClient; @@ -341,38 +341,6 @@ VariablesViewController.prototype = { } } }, - - /** - * Helper function for setting up a single Scope with a single Variable - * contained within it. - * - * @param object aOptions - * Options for the contents of the view: - * - objectActor: the grip of the new ObjectActor to show. - * - rawObject: the new raw object to show. - * - label: the new label for the inspected object. - * @return Object - * - variable: the created Variable. - * - expanded: the Promise that resolves when the variable expands. - */ - setSingleVariable: function(aOptions) { - this.view.empty(); - let scope = this.view.addScope(aOptions.label); - scope.expanded = true; - scope.locked = true; - - let variable = scope.addItem(); - let expanded; - - if (aOptions.objectActor) { - expanded = this.expand(variable, aOptions.objectActor); - } else if (aOptions.rawObject) { - variable.populate(aOptions.rawObject, { expanded: true }); - expanded = promise.resolve(); - } - - return { variable: variable, expanded: expanded }; - }, }; diff --git a/browser/devtools/webconsole/webconsole.js b/browser/devtools/webconsole/webconsole.js index 5b509727d53..54936299586 100644 --- a/browser/devtools/webconsole/webconsole.js +++ b/browser/devtools/webconsole/webconsole.js @@ -3481,13 +3481,20 @@ JSTerm.prototype = { view.delete = null; } - let { variable, expanded } = view.controller.setSingleVariable(aOptions); - variable.evaluationMacro = simpleValueEvalMacro; + let scope = view.addScope(aOptions.label); + scope.expanded = true; + scope.locked = true; + + let container = scope.addItem(); + container.evaluationMacro = simpleValueEvalMacro; if (aOptions.objectActor) { + view.controller.expand(container, aOptions.objectActor); view._consoleLastObjectActor = aOptions.objectActor.actor; } else if (aOptions.rawObject) { + container.populate(aOptions.rawObject); + view.commitHierarchy(); view._consoleLastObjectActor = null; } else { @@ -3495,9 +3502,7 @@ JSTerm.prototype = { "display."); } - expanded.then(() => { - this.emit("variablesview-updated", view, aOptions); - }); + this.emit("variablesview-updated", view, aOptions); }, /** From 11d4551f4bf0bc819471fed8d1bb539d294f1c07 Mon Sep 17 00:00:00 2001 From: Sriram Ramasubramanian Date: Mon, 23 Sep 2013 16:35:46 -0700 Subject: [PATCH 47/84] Bug 906227: Last tabs with switch-to-tab should not create new tabs. [r=margaret] --HG-- extra : rebase_source : 929416c50248094fb3164b3b34a48486ac70f668 --- mobile/android/base/BrowserApp.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/mobile/android/base/BrowserApp.java b/mobile/android/base/BrowserApp.java index b6cac4ee1e0..486a5bb088c 100644 --- a/mobile/android/base/BrowserApp.java +++ b/mobile/android/base/BrowserApp.java @@ -2268,8 +2268,12 @@ abstract public class BrowserApp extends GeckoApp // HomePager.OnNewTabsListener @Override public void onNewTabs(String[] urls) { + final EnumSet flags = EnumSet.of(OnUrlOpenListener.Flags.ALLOW_SWITCH_TO_TAB); + for (String url : urls) { - openUrl(url, true); + if (!maybeSwitchToTab(url, flags)) { + openUrl(url, true); + } } } From cf010d389fed2b2c13930ea1c6588132ef88591b Mon Sep 17 00:00:00 2001 From: Jon Coppeard Date: Thu, 26 Sep 2013 16:02:16 +0100 Subject: [PATCH 48/84] Bug 919781 - Fix use of uninitialized cx introduced by bug 917798 r=sfink --- js/jsd/jsd_stak.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/js/jsd/jsd_stak.cpp b/js/jsd/jsd_stak.cpp index 50e10fbe776..ad4089ffe94 100644 --- a/js/jsd/jsd_stak.cpp +++ b/js/jsd/jsd_stak.cpp @@ -544,11 +544,10 @@ JSDValue* jsd_GetException(JSDContext* jsdc, JSDThreadState* jsdthreadstate) { JSContext* cx; - JS::RootedValue val(cx); - if(!(cx = _getContextForThreadState(jsdc, jsdthreadstate))) return nullptr; + JS::RootedValue val(cx); if(JS_GetPendingException(cx, &val)) return jsd_NewValue(jsdc, val); return nullptr; From 1b1a321533e261296f9661aad1b5468d5e6a963b Mon Sep 17 00:00:00 2001 From: Jon Coppeard Date: Thu, 26 Sep 2013 16:02:16 +0100 Subject: [PATCH 49/84] Bug 919536 - Post barrier array write in SetElementIC r=bhackett --- js/src/jit-test/tests/gc/bug-919536.js | 17 ++++++++++ js/src/jit/IonCaches.cpp | 5 +++ js/src/jit/IonMacroAssembler.cpp | 47 ++++++++++++++++++++++++++ js/src/jit/IonMacroAssembler.h | 8 +++++ 4 files changed, 77 insertions(+) create mode 100644 js/src/jit-test/tests/gc/bug-919536.js diff --git a/js/src/jit-test/tests/gc/bug-919536.js b/js/src/jit-test/tests/gc/bug-919536.js new file mode 100644 index 00000000000..0c07b4b5988 --- /dev/null +++ b/js/src/jit-test/tests/gc/bug-919536.js @@ -0,0 +1,17 @@ +if ("gczeal" in this) { + gczeal(2, 1000); + + var a = new Array(10 * 1000); + + var i = a.length; + while (i-- != 0) { + switch (i % 3) { + case 0: + a[i] = { }; + break; + } + } + + gc(); +} + diff --git a/js/src/jit/IonCaches.cpp b/js/src/jit/IonCaches.cpp index cf12836ee57..1ea5e4e8c1b 100644 --- a/js/src/jit/IonCaches.cpp +++ b/js/src/jit/IonCaches.cpp @@ -3341,6 +3341,11 @@ SetElementIC::attachDenseElement(JSContext *cx, IonScript *ion, JSObject *obj, c masm.callPreBarrier(target, MIRType_Value); } + // Call post barrier if necessary, and recalculate elements pointer if it got cobbered. + Register postBarrierScratch = elements; + if (masm.maybeCallPostBarrier(object(), value(), postBarrierScratch)) + masm.loadPtr(Address(object(), JSObject::offsetOfElements()), elements); + // Store the value. masm.bind(&storeElem); masm.storeConstantOrRegister(value(), target); diff --git a/js/src/jit/IonMacroAssembler.cpp b/js/src/jit/IonMacroAssembler.cpp index 482cd517649..3c602f3a635 100644 --- a/js/src/jit/IonMacroAssembler.cpp +++ b/js/src/jit/IonMacroAssembler.cpp @@ -338,6 +338,53 @@ MacroAssembler::PopRegsInMaskIgnore(RegisterSet set, RegisterSet ignore) JS_ASSERT(diffG == 0); } +bool MacroAssembler::maybeCallPostBarrier(Register object, ConstantOrRegister value, + Register maybeScratch) { + bool usedMaybeScratch = false; + +#ifdef JSGC_GENERATIONAL + JSRuntime *runtime = GetIonContext()->runtime; + if (value.constant()) { + JS_ASSERT_IF(value.value().isGCThing(), + !gc::IsInsideNursery(runtime, value.value().toGCThing())); + return false; + } + + TypedOrValueRegister valReg = value.reg(); + if (valReg.hasTyped() && valReg.type() != MIRType_Object) + return false; + + Label done; + Label tenured; + branchPtr(Assembler::Below, object, ImmWord(runtime->gcNurseryStart_), &tenured); + branchPtr(Assembler::Below, object, ImmWord(runtime->gcNurseryEnd_), &done); + + bind(&tenured); + if (valReg.hasValue()) { + branchTestObject(Assembler::NotEqual, valReg.valueReg(), &done); + extractObject(valReg, maybeScratch); + usedMaybeScratch = true; + } + Register valObj = valReg.hasValue() ? maybeScratch : valReg.typedReg().gpr(); + branchPtr(Assembler::Below, valObj, ImmWord(runtime->gcNurseryStart_), &done); + branchPtr(Assembler::AboveOrEqual, valObj, ImmWord(runtime->gcNurseryEnd_), &done); + + GeneralRegisterSet saveRegs = GeneralRegisterSet::Volatile(); + PushRegsInMask(saveRegs); + Register callScratch = saveRegs.getAny(); + setupUnalignedABICall(2, callScratch); + movePtr(ImmPtr(runtime), callScratch); + passABIArg(callScratch); + passABIArg(object); + callWithABI(JS_FUNC_TO_DATA_PTR(void *, PostWriteBarrier)); + PopRegsInMask(saveRegs); + + bind(&done); +#endif + + return usedMaybeScratch; +} + void MacroAssembler::branchNurseryPtr(Condition cond, const Address &ptr1, const ImmMaybeNurseryPtr &ptr2, Label *label) diff --git a/js/src/jit/IonMacroAssembler.h b/js/src/jit/IonMacroAssembler.h index d81d07db4d3..6586d3da3b0 100644 --- a/js/src/jit/IonMacroAssembler.h +++ b/js/src/jit/IonMacroAssembler.h @@ -662,6 +662,14 @@ class MacroAssembler : public MacroAssemblerSpecific bind(&done); } + /* + * Call the post barrier if necessary when writing value to a slot or + * element of object. + * + * Returns whether the maybeScratch register was used. + */ + bool maybeCallPostBarrier(Register object, ConstantOrRegister value, Register maybeScratch); + void branchNurseryPtr(Condition cond, const Address &ptr1, const ImmMaybeNurseryPtr &ptr2, Label *label); void moveNurseryPtr(const ImmMaybeNurseryPtr &ptr, const Register ®); From f3eed0a7def5e3aa65589a62548c2bee87d7760f Mon Sep 17 00:00:00 2001 From: Ted Mielczarek Date: Thu, 26 Sep 2013 11:19:04 -0400 Subject: [PATCH 50/84] bug 920640 - fix crashreporter key in mozinfo.json when --enable-crashreporter is specified. r=gps --- python/mozbuild/mozbuild/mozinfo.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/mozbuild/mozbuild/mozinfo.py b/python/mozbuild/mozbuild/mozinfo.py index f4b24bcb468..b9ec5ca6fcf 100755 --- a/python/mozbuild/mozbuild/mozinfo.py +++ b/python/mozbuild/mozbuild/mozinfo.py @@ -73,7 +73,7 @@ def build_dict(config, env=os.environ): # other CPUs will wind up with unknown bits d['debug'] = substs.get('MOZ_DEBUG') == '1' - d['crashreporter'] = substs.get('MOZ_CRASHREPORTER') == '1' + d['crashreporter'] = bool(substs.get('MOZ_CRASHREPORTER')) d['asan'] = substs.get('MOZ_ASAN') == '1' d['tests_enabled'] = substs.get('ENABLE_TESTS') == "1" d['bin_suffix'] = substs.get('BIN_SUFFIX', '') From fc4cbf926ee210caec61e5551dc54ae2097edf0e Mon Sep 17 00:00:00 2001 From: Luke Wagner Date: Thu, 26 Sep 2013 04:52:58 -0500 Subject: [PATCH 51/84] Bug 917991 - Revert unintentional change in AsmJSPassStackArg (r=jandem) --HG-- extra : rebase_source : d1510625b0d430bd8df05edaeac6071f46ee984f --- js/src/jit/shared/CodeGenerator-x86-shared.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/src/jit/shared/CodeGenerator-x86-shared.cpp b/js/src/jit/shared/CodeGenerator-x86-shared.cpp index b0e0d14fb31..d15937d850c 100644 --- a/js/src/jit/shared/CodeGenerator-x86-shared.cpp +++ b/js/src/jit/shared/CodeGenerator-x86-shared.cpp @@ -226,7 +226,7 @@ CodeGeneratorX86Shared::visitAsmJSPassStackArg(LAsmJSPassStackArg *ins) const MAsmJSPassStackArg *mir = ins->mir(); Address dst(StackPointer, mir->spOffset()); if (ins->arg()->isConstant()) { - masm.store32(Imm32(ToInt32(ins->arg())), dst); + masm.storePtr(ImmWord(ToInt32(ins->arg())), dst); } else { if (ins->arg()->isGeneralReg()) masm.storePtr(ToRegister(ins->arg()), dst); From 52d857e0024773e6a7945a3700285ed5ab9b2767 Mon Sep 17 00:00:00 2001 From: Tom Schuster Date: Thu, 26 Sep 2013 11:21:02 -0400 Subject: [PATCH 52/84] Bug 919344 - Avoid accessing dead objects in Finder.jsm after a page change. r=mikedeboer,dao --- toolkit/modules/Finder.jsm | 32 +++++++++++++++++++++++--------- 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/toolkit/modules/Finder.jsm b/toolkit/modules/Finder.jsm index d0cad951d85..05b961b5c22 100644 --- a/toolkit/modules/Finder.jsm +++ b/toolkit/modules/Finder.jsm @@ -16,14 +16,14 @@ function Finder(docShell) { this._fastFind.init(docShell); this._docShell = docShell; - this._document = docShell.QueryInterface(Ci.nsIInterfaceRequestor) - .getInterface(Ci.nsIDOMWindow).document; this._listeners = []; - this._previousLink = null; this._drewOutline = false; - this._searchString = null; + + docShell.QueryInterface(Ci.nsIInterfaceRequestor) + .getInterface(Ci.nsIWebProgress) + .addProgressListener(this, Ci.nsIWebProgress.NOTIFY_LOCATION); } Finder.prototype = { @@ -125,10 +125,11 @@ Finder.prototype = { this._fastFind.foundLink.click(); break; case Ci.nsIDOMKeyEvent.DOM_VK_TAB: - if (aEvent.shiftKey) - this._document.commandDispatcher.rewindFocus(); - else - this._document.commandDispatcher.advanceFocus(); + let direction = Services.focus.MOVEFOCUS_FORWARD; + if (aEvent.shiftKey) { + direction = Services.focus.MOVEFOCUS_BACKWARD; + } + Services.focus.moveFocus(this._getWindow(), null, direction, 0); break; case Ci.nsIDOMKeyEvent.DOM_VK_PAGE_UP: controller.scrollPage(false); @@ -420,6 +421,16 @@ Finder.prototype = { return null; }, + // Start of nsIWebProgressListener implementation. + + onLocationChange: function(aWebProgress, aRequest, aLocation, aFlags) { + if (!aWebProgress.isTopLevel) + return; + + // Avoid leaking if we change the page. + this._previousLink = null; + }, + // Start of nsIEditActionListener implementations WillDeleteText: function (aTextNode, aOffset, aLength) { @@ -588,5 +599,8 @@ Finder.prototype = { notifyDocumentCreated: function() {}, notifyDocumentStateChanged: function(aDirty) {} }; - } + }, + + QueryInterface: XPCOMUtils.generateQI([Ci.nsIWebProgressListener, + Ci.nsISupportsWeakReference]) }; From 0b09fb049449bc04801e987441363b84e194cfe8 Mon Sep 17 00:00:00 2001 From: Tom Schuster Date: Thu, 26 Sep 2013 11:21:02 -0400 Subject: [PATCH 53/84] Bug 919340 - Always draw outline around links when using quickfind. r=mikedeboer --- toolkit/content/widgets/findbar.xml | 8 ++-- toolkit/modules/Finder.jsm | 65 ++++++++++++++++++----------- 2 files changed, 46 insertions(+), 27 deletions(-) diff --git a/toolkit/content/widgets/findbar.xml b/toolkit/content/widgets/findbar.xml index 49ddc8b73e5..79ab577bcdd 100644 --- a/toolkit/content/widgets/findbar.xml +++ b/toolkit/content/widgets/findbar.xml @@ -44,7 +44,7 @@ } this.findbar.onFindAgainCommand(aEvent.shiftKey); - } else if (this.findbar._findMode == this.findbar.FIND_LINKS) { + } else { this.findbar._finishFAYT(aEvent); } ]]> @@ -870,7 +870,8 @@ this._updateCaseSensitivity(val); - this.browser.finder.fastFind(val, this._findMode == this.FIND_LINKS); + this.browser.finder.fastFind(val, this._findMode == this.FIND_LINKS, + this._findMode != this.FIND_NORMAL); } if (this._findMode != this.FIND_NORMAL) @@ -923,7 +924,8 @@ diff --git a/toolkit/modules/Finder.jsm b/toolkit/modules/Finder.jsm index 05b961b5c22..507f32a07a0 100644 --- a/toolkit/modules/Finder.jsm +++ b/toolkit/modules/Finder.jsm @@ -18,7 +18,6 @@ function Finder(docShell) { this._docShell = docShell; this._listeners = []; this._previousLink = null; - this._drewOutline = false; this._searchString = null; docShell.QueryInterface(Ci.nsIInterfaceRequestor) @@ -36,12 +35,12 @@ Finder.prototype = { this._listeners = this._listeners.filter(l => l != aListener); }, - _notify: function (aResult, aFindBackwards, aLinksOnly) { - this._outlineLink(aLinksOnly); + _notify: function (aResult, aFindBackwards, aDrawOutline) { + this._outlineLink(aDrawOutline); let foundLink = this._fastFind.foundLink; let linkURL = null; - if (aLinksOnly && foundLink) { + if (foundLink) { let docCharset = null; let ownerDoc = foundLink.ownerDocument; if (ownerDoc) @@ -68,14 +67,30 @@ Finder.prototype = { this._fastFind.caseSensitive = aSensitive; }, - fastFind: function (aSearchString, aLinksOnly) { + /** + * Used for normal search operations, highlights the first match. + * + * @param aSearchString String to search for. + * @param aLinksOnly Only consider nodes that are links for the search. + * @param aDrawOutline Puts an outline around matched links. + */ + fastFind: function (aSearchString, aLinksOnly, aDrawOutline) { let result = this._fastFind.find(aSearchString, aLinksOnly); - this._notify(result, false, aLinksOnly); + this._notify(result, false, aDrawOutline); }, - findAgain: function (aFindBackwards, aLinksOnly) { + /** + * Repeat the previous search. Should only be called after a previous + * call to Finder.fastFind. + * + * @param aFindBackwards Controls the search direction: + * true: before current match, false: after current match. + * @param aLinksOnly Only consider nodes that are links for the search. + * @param aDrawOutline Puts an outline around matched links. + */ + findAgain: function (aFindBackwards, aLinksOnly, aDrawOutline) { let result = this._fastFind.findAgain(aFindBackwards, aLinksOnly); - this._notify(result, aFindBackwards, aLinksOnly); + this._notify(result, aFindBackwards, aDrawOutline); }, highlight: function (aHighlight, aWord) { @@ -93,11 +108,7 @@ Finder.prototype = { fastFind.collapseSelection(); fastFind.setSelectionModeAndRepaint(Ci.nsISelectionController.SELECTION_ON); - // We also drew our own outline, remove that as well. - if (this._previousLink && this._drewOutline) { - this._previousLink.style.outline = this._tmpOutline; - this._previousLink.style.outlineOffset = this._tmpOutlineOffset; - } + this._restoreOriginalOutline(); }, focusContent: function() { @@ -150,20 +161,17 @@ Finder.prototype = { return this._docShell.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindow); }, - _outlineLink: function (aLinksOnly) { + _outlineLink: function (aDrawOutline) { let foundLink = this._fastFind.foundLink; - if (foundLink == this._previousLink) + // Optimization: We are drawing outlines and we matched + // the same link before, so don't duplicate work. + if (foundLink == this._previousLink && aDrawOutline) return; - if (this._previousLink && this._drewOutline) { - // restore original outline - this._previousLink.style.outline = this._tmpOutline; - this._previousLink.style.outlineOffset = this._tmpOutlineOffset; - } + this._restoreOriginalOutline(); - this._drewOutline = (foundLink && aLinksOnly); - if (this._drewOutline) { + if (foundLink && aDrawOutline) { // Backup original outline this._tmpOutline = foundLink.style.outline; this._tmpOutlineOffset = foundLink.style.outlineOffset; @@ -175,9 +183,18 @@ Finder.prototype = { // Don't set the outline-color, we should always use initial value. foundLink.style.outline = "1px dotted"; foundLink.style.outlineOffset = "0"; - } - this._previousLink = foundLink; + this._previousLink = foundLink; + } + }, + + _restoreOriginalOutline: function () { + // Removes the outline around the last found link. + if (this._previousLink) { + this._previousLink.style.outline = this._tmpOutline; + this._previousLink.style.outlineOffset = this._tmpOutlineOffset; + this._previousLink = null; + } }, _highlight: function (aHighlight, aWord, aWindow) { From 099a37905e2dc9864eb9e5fbec91f87e0a1b2994 Mon Sep 17 00:00:00 2001 From: Tom Schuster Date: Thu, 26 Sep 2013 11:21:02 -0400 Subject: [PATCH 54/84] Bug 919340 - Test. r=mikedeboer --- .../modules/tests/browser/browser_Finder.js | 30 +++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/toolkit/modules/tests/browser/browser_Finder.js b/toolkit/modules/tests/browser/browser_Finder.js index e6205e0747c..30ca884df8e 100644 --- a/toolkit/modules/tests/browser/browser_Finder.js +++ b/toolkit/modules/tests/browser/browser_Finder.js @@ -9,13 +9,19 @@ let tab, browser; function test () { waitForExplicitFinish(); - tab = gBrowser.addTab("data:text/html," + + "test link")); browser = gBrowser.getBrowserForTab(tab); gBrowser.selectedTab = tab; browser.addEventListener("load", startTests, true); } +var outlineTest = "sendAsyncMessage(\"OutlineTest\", " + + "{ ok : !!content.document." + + "getElementsByTagName(\"a\")[0].style.outline }" + + ");"; + function startTests () { browser.removeEventListener("load", startTests, true); @@ -33,7 +40,28 @@ function startTests () { listener.onFindResult = function (result) { ok(result == Ci.nsITypeAheadFind.FIND_NOTFOUND, "should not find string"); - cleanup(); + let first = true; + listener.onFindResult = function (result) { + ok(result == Ci.nsITypeAheadFind.FIND_FOUND, "should find link"); + + browser.messageManager.addMessageListener("OutlineTest", function f(aMessage) { + browser.messageManager.removeMessageListener("OutlineTest", f); + + + if (first) { + ok(aMessage.data.ok, "content script should send okay"); + first = false; + } else { + ok(!aMessage.data.ok, "content script should not send okay"); + cleanup(); + } + }) + browser.messageManager.loadFrameScript("data:," + outlineTest, false) + } + // Search only for links and draw outlines. + finder.fastFind("test link", true, true); + // Just a simple search for "test link". + finder.fastFind("test link", false, false); } finder.highlight(true, "Bla"); } From 98c63c456ec56b78ef289bb35282a567b50e199a Mon Sep 17 00:00:00 2001 From: Gregory Szorc Date: Thu, 26 Sep 2013 09:18:08 -0700 Subject: [PATCH 59/84] Bug 920781 - Invoke pymake with calling python, not $PATH python; r=glandium --- python/mozbuild/mozbuild/base.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/python/mozbuild/mozbuild/base.py b/python/mozbuild/mozbuild/base.py index 44c182472c2..42a87b70de3 100644 --- a/python/mozbuild/mozbuild/base.py +++ b/python/mozbuild/mozbuild/base.py @@ -394,7 +394,7 @@ class MozbuildObject(ProcessExecutionMixin): """ self._ensure_objdir_exists() - args = [self._make_path(force_pymake=force_pymake)] + args = self._make_path(force_pymake=force_pymake) if directory: args.extend(['-C', directory]) @@ -457,12 +457,17 @@ class MozbuildObject(ProcessExecutionMixin): def _make_path(self, force_pymake=False): if self._is_windows() or force_pymake: - return os.path.join(self.topsrcdir, 'build', 'pymake', + make_py = os.path.join(self.topsrcdir, 'build', 'pymake', 'make.py').replace(os.sep, '/') + # We might want to consider invoking with the virtualenv's Python + # some day. But, there is a chicken-and-egg problem w.r.t. when the + # virtualenv is created. + return [sys.executable, make_py] + for test in ['gmake', 'make']: try: - return which.which(test) + return [which.which(test)] except which.WhichError: continue From 31c9411d9117e6756d5de66d3f31e948d20d383b Mon Sep 17 00:00:00 2001 From: Gregory Szorc Date: Thu, 26 Sep 2013 09:18:19 -0700 Subject: [PATCH 60/84] Bug 917988 - Fix licensing of in-tree documentation; r=gerv DONTBUILD (NPOTB) --- build/docs/conf.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/docs/conf.py b/build/docs/conf.py index 58fcf287326..600c4e62451 100644 --- a/build/docs/conf.py +++ b/build/docs/conf.py @@ -26,7 +26,7 @@ source_suffix = '.rst' master_doc = 'index' project = u'Mozilla Build System' year = datetime.now().year -copyright = u'%s, Mozilla Foundation, CC BY-SA 3.0' % year +copyright = u'%s, Mozilla Foundation, CC BY-SA 3.0 or any later version' % year # Grab the version from the source tree's milestone. with open(os.path.join(mozilla_dir, 'config', 'milestone.txt'), 'rt') as fh: From fd5567445b17bc6634354e53915ae73ea77c726a Mon Sep 17 00:00:00 2001 From: Gregory Szorc Date: Thu, 26 Sep 2013 09:19:05 -0700 Subject: [PATCH 61/84] Bug 914563 - Temporarily disable build resource recording on Windows; r=mshal --- python/mozbuild/mozbuild/controller/building.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/python/mozbuild/mozbuild/controller/building.py b/python/mozbuild/mozbuild/controller/building.py index 60ea1beacaf..d17387cc8a9 100644 --- a/python/mozbuild/mozbuild/controller/building.py +++ b/python/mozbuild/mozbuild/controller/building.py @@ -297,6 +297,12 @@ class BuildMonitor(MozbuildObject): def start_resource_recording(self): # This should be merged into start() once bug 892342 lands. + + # Resource monitoring on Windows is currently busted because of + # multiprocessing issues. Bug 914563. + if self._is_windows(): + return + self.resources.start() self._resources_started = True From 3be319951b3fd0653a44a12c81982bf8db138a57 Mon Sep 17 00:00:00 2001 From: Gregory Szorc Date: Thu, 26 Sep 2013 09:21:20 -0700 Subject: [PATCH 62/84] NO BUG - Increase memory allocation for documentation VM --- build/docs/Vagrantfile | 3 +++ 1 file changed, 3 insertions(+) diff --git a/build/docs/Vagrantfile b/build/docs/Vagrantfile index 4d435d9a525..bc1265766c7 100644 --- a/build/docs/Vagrantfile +++ b/build/docs/Vagrantfile @@ -7,4 +7,7 @@ Vagrant::Config.run do |config| config.vm.box = "precise64" config.vm.box_url = "http://files.vagrantup.com/precise64.box" config.vm.share_folder("gecko", "/gecko", "../..") + # Doxygen needs more than the default memory or it will swap and be + # extremely slow. + config.vm.customize ["modifyvm", :id, "--memory", 1024] end From 5445873afd2e5a61c3df4babdc921c7a89185990 Mon Sep 17 00:00:00 2001 From: Ben Turner Date: Wed, 25 Sep 2013 16:10:57 -0700 Subject: [PATCH 63/84] Bug 920179 - 'Add resolve hook for IndexedDB constructors on non-window globals'. r=bholley. --HG-- extra : transplant_source : 77%C6F%3FlL%0F%C2%DE36.%5DA%0D%F6H%0B%24 --- dom/indexedDB/IndexedDatabaseManager.cpp | 85 ++++++++++++++++++++++++ dom/indexedDB/IndexedDatabaseManager.h | 5 ++ js/xpconnect/src/XPCRuntimeService.cpp | 30 +++++++-- js/xpconnect/src/nsXPConnect.cpp | 18 ++--- 4 files changed, 118 insertions(+), 20 deletions(-) diff --git a/dom/indexedDB/IndexedDatabaseManager.cpp b/dom/indexedDB/IndexedDatabaseManager.cpp index 1a5c6202c30..ebaaf6a561b 100644 --- a/dom/indexedDB/IndexedDatabaseManager.cpp +++ b/dom/indexedDB/IndexedDatabaseManager.cpp @@ -13,6 +13,7 @@ #include "nsIObserverService.h" #include "nsIScriptError.h" +#include "jsapi.h" #include "mozilla/ClearOnShutdown.h" #include "mozilla/CondVar.h" #include "mozilla/ContentEvents.h" @@ -22,6 +23,7 @@ #include "mozilla/dom/TabContext.h" #include "mozilla/Services.h" #include "mozilla/storage.h" +#include "mozilla/Util.h" #include "nsContentUtils.h" #include "nsEventDispatcher.h" #include "nsThreadUtils.h" @@ -31,6 +33,17 @@ #include "IDBKeyRange.h" #include "IDBRequest.h" +// Bindings for ResolveConstructors +#include "mozilla/dom/IDBCursorBinding.h" +#include "mozilla/dom/IDBDatabaseBinding.h" +#include "mozilla/dom/IDBFactoryBinding.h" +#include "mozilla/dom/IDBIndexBinding.h" +#include "mozilla/dom/IDBObjectStoreBinding.h" +#include "mozilla/dom/IDBOpenDBRequestBinding.h" +#include "mozilla/dom/IDBRequestBinding.h" +#include "mozilla/dom/IDBTransactionBinding.h" +#include "mozilla/dom/IDBVersionChangeEventBinding.h" + // The two possible values for the data argument when receiving the disk space // observer notification. #define LOW_DISK_SPACE_DATA_FULL "full" @@ -94,6 +107,33 @@ mozilla::StaticRefPtr gInstance; mozilla::Atomic gInitialized(0); mozilla::Atomic gClosed(0); +// See ResolveConstructors below. +struct ConstructorInfo { + const char* name; + JS::Handle (*resolve)(JSContext*, JS::Handle, bool); + mutable jsid id; +}; + +const ConstructorInfo gConstructorInfo[] = { + +#define BINDING_ENTRY(_name) \ + { #_name, _name##Binding::GetConstructorObject, JSID_VOID }, + + BINDING_ENTRY(IDBFactory) + BINDING_ENTRY(IDBDatabase) + BINDING_ENTRY(IDBTransaction) + BINDING_ENTRY(IDBObjectStore) + BINDING_ENTRY(IDBIndex) + BINDING_ENTRY(IDBCursor) + BINDING_ENTRY(IDBRequest) + BINDING_ENTRY(IDBOpenDBRequest) + BINDING_ENTRY(IDBVersionChangeEvent) + +#undef BINDING_ENTRY +}; + +const uint32_t gConstructorCount = mozilla::ArrayLength(gConstructorInfo); + class AsyncDeleteFileRunnable MOZ_FINAL : public nsIRunnable { public: @@ -884,3 +924,48 @@ GetFileReferencesHelper::Run() return NS_OK; } + +BEGIN_INDEXEDDB_NAMESPACE + +bool +ResolveConstructors(JSContext* aCx, JS::HandleObject aObj, JS::HandleId aId, + JS::MutableHandleObject aObjp) +{ + MOZ_ASSERT(NS_IsMainThread()); + + // The first time this function is called we need to intern all the strings we + // care about. + if (JSID_IS_VOID(gConstructorInfo[0].id)) { + for (uint32_t i = 0; i < gConstructorCount; i++) { + JS::RootedString str(aCx, JS_InternString(aCx, gConstructorInfo[i].name)); + if (!str) { + NS_WARNING("Failed to intern string!"); + while (i) { + gConstructorInfo[--i].id = JSID_VOID; + } + return false; + } + gConstructorInfo[i].id = INTERNED_STRING_TO_JSID(aCx, str); + } + } + + // Now resolve. + for (uint32_t i = 0; i < gConstructorCount; i++) { + if (gConstructorInfo[i].id == aId) { + JS::RootedObject constructor(aCx, + gConstructorInfo[i].resolve(aCx, aObj, true)); + if (!constructor) { + return false; + } + + aObjp.set(aObj); + return true; + } + } + + // Not resolved. + aObjp.set(nullptr); + return true; +} + +END_INDEXEDDB_NAMESPACE diff --git a/dom/indexedDB/IndexedDatabaseManager.h b/dom/indexedDB/IndexedDatabaseManager.h index 8598cee3b2e..2e87eac9adb 100644 --- a/dom/indexedDB/IndexedDatabaseManager.h +++ b/dom/indexedDB/IndexedDatabaseManager.h @@ -12,6 +12,7 @@ #include "nsIIndexedDatabaseManager.h" #include "nsIObserver.h" +#include "js/TypeDecls.h" #include "mozilla/Atomics.h" #include "mozilla/dom/quota/PersistenceType.h" #include "mozilla/Mutex.h" @@ -166,6 +167,10 @@ private: static mozilla::Atomic sLowDiskSpaceMode; }; +bool +ResolveConstructors(JSContext* aCx, JS::HandleObject aObj, JS::HandleId aId, + JS::MutableHandleObject aObjp); + END_INDEXEDDB_NAMESPACE #endif /* mozilla_dom_indexeddb_indexeddatabasemanager_h__ */ diff --git a/js/xpconnect/src/XPCRuntimeService.cpp b/js/xpconnect/src/XPCRuntimeService.cpp index e1d405f209c..188a15c98aa 100644 --- a/js/xpconnect/src/XPCRuntimeService.cpp +++ b/js/xpconnect/src/XPCRuntimeService.cpp @@ -4,14 +4,17 @@ * 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 "mozilla/dom/workers/Workers.h" #include "nsContentUtils.h" #include "BackstagePass.h" #include "nsIProgrammingLanguage.h" #include "nsDOMClassInfo.h" #include "nsIPrincipal.h" +#include "mozilla/dom/indexedDB/IndexedDatabaseManager.h" +#include "mozilla/dom/workers/Workers.h" + using mozilla::dom::workers::ResolveWorkerClasses; +namespace indexedDB = mozilla::dom::indexedDB; NS_INTERFACE_MAP_BEGIN(BackstagePass) NS_INTERFACE_MAP_ENTRY(nsIGlobalObject) @@ -52,12 +55,10 @@ BackstagePass::NewResolve(nsIXPConnectWrappedNative *wrapper, JS::RootedId id(cx, idArg); bool resolved; + *objpArg = nullptr; *_retval = !!JS_ResolveStandardClass(cx, obj, id, &resolved); - if (!*_retval) { - *objpArg = nullptr; - return NS_OK; - } + NS_ENSURE_TRUE(*_retval, NS_ERROR_FAILURE); if (resolved) { *objpArg = obj; @@ -65,8 +66,23 @@ BackstagePass::NewResolve(nsIXPConnectWrappedNative *wrapper, } JS::RootedObject objp(cx, *objpArg); - *_retval = !!ResolveWorkerClasses(cx, obj, id, flags, &objp); - *objpArg = objp; + + *_retval = ResolveWorkerClasses(cx, obj, id, flags, &objp); + NS_ENSURE_TRUE(*_retval, NS_ERROR_FAILURE); + + if (objp) { + *objpArg = objp; + return NS_OK; + } + + *_retval = indexedDB::ResolveConstructors(cx, obj, id, &objp); + NS_ENSURE_TRUE(*_retval, NS_ERROR_FAILURE); + + if (objp) { + *objpArg = objp; + return NS_OK; + } + return NS_OK; } diff --git a/js/xpconnect/src/nsXPConnect.cpp b/js/xpconnect/src/nsXPConnect.cpp index b76ff311e2b..644fc7fe320 100644 --- a/js/xpconnect/src/nsXPConnect.cpp +++ b/js/xpconnect/src/nsXPConnect.cpp @@ -30,12 +30,6 @@ #include "mozilla/dom/BindingUtils.h" #include "mozilla/dom/Exceptions.h" -#include "mozilla/dom/IDBIndexBinding.h" -#include "mozilla/dom/IDBObjectStoreBinding.h" -#include "mozilla/dom/IDBOpenDBRequestBinding.h" -#include "mozilla/dom/IDBRequestBinding.h" -#include "mozilla/dom/IDBTransactionBinding.h" -#include "mozilla/dom/IDBVersionChangeEventBinding.h" #include "mozilla/dom/TextDecoderBinding.h" #include "mozilla/dom/TextEncoderBinding.h" #include "mozilla/dom/DOMErrorBinding.h" @@ -530,13 +524,11 @@ nsXPConnect::InitClassesWithNewWrappedGlobal(JSContext * aJSContext, MOZ_ASSERT(js::GetObjectClass(global)->flags & JSCLASS_DOM_GLOBAL); // Init WebIDL binding constructors wanted on all XPConnect globals. - if (!IDBIndexBinding::GetConstructorObject(aJSContext, global) || - !IDBObjectStoreBinding::GetConstructorObject(aJSContext, global) || - !IDBOpenDBRequestBinding::GetConstructorObject(aJSContext, global) || - !IDBRequestBinding::GetConstructorObject(aJSContext, global) || - !IDBTransactionBinding::GetConstructorObject(aJSContext, global) || - !IDBVersionChangeEventBinding::GetConstructorObject(aJSContext, global) || - !TextDecoderBinding::GetConstructorObject(aJSContext, global) || + // Additional bindings may be created lazily, see BackstagePass::NewResolve. + // + // XXX Please do not add any additional classes here without the approval of + // the XPConnect module owner. + if (!TextDecoderBinding::GetConstructorObject(aJSContext, global) || !TextEncoderBinding::GetConstructorObject(aJSContext, global) || !DOMErrorBinding::GetConstructorObject(aJSContext, global)) { return UnexpectedFailure(NS_ERROR_FAILURE); From 13044eee98700d394f1f53b8780d92435b4b0533 Mon Sep 17 00:00:00 2001 From: Blake Kaplan Date: Thu, 26 Sep 2013 18:42:53 +0200 Subject: [PATCH 64/84] Bug 917515 - Check for null before checking the document. r=ehsan --- layout/generic/nsSelection.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/layout/generic/nsSelection.cpp b/layout/generic/nsSelection.cpp index 8c6407bfb33..0fc063cc607 100644 --- a/layout/generic/nsSelection.cpp +++ b/layout/generic/nsSelection.cpp @@ -4383,7 +4383,7 @@ Selection::Collapse(nsINode* aParentNode, int32_t aOffset) nsresult result; nsRefPtr presContext = GetPresContext(); - if (presContext->Document() != aParentNode->OwnerDoc()) + if (!presContext || presContext->Document() != aParentNode->OwnerDoc()) return NS_ERROR_FAILURE; // Delete all of the current ranges @@ -4624,7 +4624,7 @@ Selection::Extend(nsINode* aParentNode, int32_t aOffset) return NS_ERROR_FAILURE; nsRefPtr presContext = GetPresContext(); - if (presContext->Document() != aParentNode->OwnerDoc()) + if (!presContext || presContext->Document() != aParentNode->OwnerDoc()) return NS_ERROR_FAILURE; //mFrameSelection->InvalidateDesiredX(); From 508853154574aa3dc3ddd7c053b1107a01c816e0 Mon Sep 17 00:00:00 2001 From: Nicolas Silva Date: Thu, 26 Sep 2013 19:06:12 +0200 Subject: [PATCH 65/84] Bug 916118 - Backed out changeset bafb8bf3b279 on a CLOSED TREE --- gfx/layers/CompositorTypes.h | 12 +++++++----- gfx/layers/GrallocImages.cpp | 3 ++- gfx/layers/LayersLogging.cpp | 1 + gfx/layers/client/CanvasClient.cpp | 4 ++-- gfx/layers/client/ClientCanvasLayer.cpp | 8 ++++---- gfx/layers/client/CompositableClient.cpp | 2 +- gfx/layers/client/ContentClient.cpp | 2 +- gfx/layers/client/ContentClient.h | 2 +- gfx/layers/client/ImageClient.cpp | 4 ++-- gfx/layers/client/TextureClient.cpp | 2 +- gfx/layers/client/TextureClient.h | 7 +++++++ gfx/layers/composite/CompositableHost.cpp | 2 +- gfx/layers/ipc/CompositableTransactionParent.cpp | 4 ++-- gfx/layers/ipc/ImageBridgeChild.cpp | 12 ++++++------ gfx/layers/ipc/ShadowLayers.cpp | 2 +- gfx/layers/opengl/TextureClientOGL.cpp | 4 ++-- 16 files changed, 41 insertions(+), 30 deletions(-) diff --git a/gfx/layers/CompositorTypes.h b/gfx/layers/CompositorTypes.h index 532233e5d01..227f541dd2e 100644 --- a/gfx/layers/CompositorTypes.h +++ b/gfx/layers/CompositorTypes.h @@ -60,11 +60,12 @@ const TextureFlags TEXTURE_TILE = 1 << 15; // from the previous texture. const TextureFlags TEXTURE_COPY_PREVIOUS = 1 << 24; // Who is responsible for deallocating the shared data. -// if TEXTURE_DEALLOCATE_CLIENT is set, the shared data is deallocated on the -// client side and requires some extra synchronizaion to ensure race-free -// deallocation. -// The default behaviour is to deallocate on the host side. +// if none of the following two flags is set, the shared data will not be +// deallocated by the layers system. It is not necessarily a leak, it could +// be a choice from another part of gecko that wants to keep the data alive +// for some reason. The default behaviour is to deallocate on the host side. const TextureFlags TEXTURE_DEALLOCATE_CLIENT = 1 << 25; +const TextureFlags TEXTURE_DEALLOCATE_HOST = 1 << 26; // After being shared ith the compositor side, an immutable texture is never // modified, it can only be read. It is safe to not Lock/Unlock immutable // textures. @@ -79,7 +80,8 @@ const TextureFlags TEXTURE_IMMEDIATE_UPLOAD = 1 << 28; const TextureFlags TEXTURE_DOUBLE_BUFFERED = 1 << 29; // the default flags -const TextureFlags TEXTURE_FLAGS_DEFAULT = TEXTURE_FRONT; +const TextureFlags TEXTURE_FLAGS_DEFAULT = TEXTURE_DEALLOCATE_HOST + | TEXTURE_FRONT; static inline bool TextureRequiresLocking(TextureFlags aFlags) diff --git a/gfx/layers/GrallocImages.cpp b/gfx/layers/GrallocImages.cpp index 856d80ba79b..80fc628736b 100644 --- a/gfx/layers/GrallocImages.cpp +++ b/gfx/layers/GrallocImages.cpp @@ -290,7 +290,8 @@ GrallocImage::GetTextureClient() return nullptr; } const SurfaceDescriptorGralloc& desc = sd.get_SurfaceDescriptorGralloc(); - TextureFlags flags = desc.external() ? TEXTURE_DEALLOCATE_CLIENT : 0; + TextureFlags flags = desc.external() ? TEXTURE_DEALLOCATE_CLIENT + : TEXTURE_DEALLOCATE_HOST; if (desc.isRBSwapped()) { flags |= TEXTURE_RB_SWAPPED; } diff --git a/gfx/layers/LayersLogging.cpp b/gfx/layers/LayersLogging.cpp index fa2c244d20d..1e8de0739ef 100644 --- a/gfx/layers/LayersLogging.cpp +++ b/gfx/layers/LayersLogging.cpp @@ -225,6 +225,7 @@ AppendToString(nsACString& s, TextureFlags flags, AppendFlag(TEXTURE_DISALLOW_BIGIMAGE); AppendFlag(TEXTURE_ALLOW_REPEAT); AppendFlag(TEXTURE_NEW_TILE); + AppendFlag(TEXTURE_DEALLOCATE_HOST); #undef AppendFlag } diff --git a/gfx/layers/client/CanvasClient.cpp b/gfx/layers/client/CanvasClient.cpp index 67aa9911da3..3ea30b797aa 100644 --- a/gfx/layers/client/CanvasClient.cpp +++ b/gfx/layers/client/CanvasClient.cpp @@ -42,11 +42,11 @@ CanvasClient::CreateCanvasClient(CanvasClientType aType, { if (aType == CanvasClientGLContext && aForwarder->GetCompositorBackendType() == LAYERS_OPENGL) { - aFlags &= TEXTURE_DEALLOCATE_CLIENT; + aFlags &= ~TEXTURE_DEALLOCATE_HOST; return new DeprecatedCanvasClientSurfaceStream(aForwarder, aFlags); } if (gfxPlatform::GetPlatform()->UseDeprecatedTextures()) { - aFlags &= TEXTURE_DEALLOCATE_CLIENT; + aFlags &= ~TEXTURE_DEALLOCATE_HOST; return new DeprecatedCanvasClient2D(aForwarder, aFlags); } return new CanvasClient2D(aForwarder, aFlags); diff --git a/gfx/layers/client/ClientCanvasLayer.cpp b/gfx/layers/client/ClientCanvasLayer.cpp index a8cdc39d839..50377179196 100644 --- a/gfx/layers/client/ClientCanvasLayer.cpp +++ b/gfx/layers/client/ClientCanvasLayer.cpp @@ -98,12 +98,12 @@ ClientCanvasLayer::RenderLayer() } if (!mGLContext) { - // We don't support locking for buffer surfaces currently - flags |= TEXTURE_IMMEDIATE_UPLOAD; - } else { // GLContext's SurfaceStream handles ownership itself, // and doesn't require layers to do any deallocation. - flags |= TEXTURE_DEALLOCATE_CLIENT; + flags |= TEXTURE_DEALLOCATE_HOST; + + // We don't support locking for buffer surfaces currently + flags |= TEXTURE_IMMEDIATE_UPLOAD; } mCanvasClient = CanvasClient::CreateCanvasClient(GetCanvasClientType(), ClientManager(), flags); diff --git a/gfx/layers/client/CompositableClient.cpp b/gfx/layers/client/CompositableClient.cpp index 0b9be8b5372..1681bf42118 100644 --- a/gfx/layers/client/CompositableClient.cpp +++ b/gfx/layers/client/CompositableClient.cpp @@ -231,7 +231,7 @@ CompositableClient::RemoveTextureClient(TextureClient* aClient) MOZ_ASSERT(aClient); mTexturesToRemove.AppendElement(TextureIDAndFlags(aClient->GetID(), aClient->GetFlags())); - if (aClient->GetFlags() & TEXTURE_DEALLOCATE_CLIENT) { + if (!(aClient->GetFlags() & TEXTURE_DEALLOCATE_HOST)) { TextureClientData* data = aClient->DropTextureData(); if (data) { mTexturesToRemoveCallbacks[aClient->GetID()] = data; diff --git a/gfx/layers/client/ContentClient.cpp b/gfx/layers/client/ContentClient.cpp index 60e31458ed3..d30d0287a7d 100644 --- a/gfx/layers/client/ContentClient.cpp +++ b/gfx/layers/client/ContentClient.cpp @@ -201,7 +201,7 @@ ContentClientRemoteBuffer::BuildDeprecatedTextureClients(ContentType aType, mContentType = aType; mSize = gfx::IntSize(aRect.width, aRect.height); - mTextureInfo.mTextureFlags = aFlags & ~TEXTURE_DEALLOCATE_CLIENT; + mTextureInfo.mTextureFlags = aFlags | TEXTURE_DEALLOCATE_HOST; if (!CreateAndAllocateDeprecatedTextureClient(mDeprecatedTextureClient)) { return; diff --git a/gfx/layers/client/ContentClient.h b/gfx/layers/client/ContentClient.h index 619f370247b..5951bf556ec 100644 --- a/gfx/layers/client/ContentClient.h +++ b/gfx/layers/client/ContentClient.h @@ -404,7 +404,7 @@ private: void NotifyBufferCreated(ContentType aType, uint32_t aFlags) { - mTextureInfo.mTextureFlags = aFlags & ~TEXTURE_DEALLOCATE_CLIENT; + mTextureInfo.mTextureFlags = aFlags | TEXTURE_DEALLOCATE_HOST; mContentType = aType; mForwarder->CreatedIncrementalBuffer(this, diff --git a/gfx/layers/client/ImageClient.cpp b/gfx/layers/client/ImageClient.cpp index 1cd71658f21..d2db40d9932 100644 --- a/gfx/layers/client/ImageClient.cpp +++ b/gfx/layers/client/ImageClient.cpp @@ -165,7 +165,7 @@ ImageClientSingle::UpdateImage(ImageContainer* aContainer, bool bufferCreated = false; if (!mFrontBuffer) { - mFrontBuffer = CreateBufferTextureClient(gfx::FORMAT_YUV, TEXTURE_FLAGS_DEFAULT); + mFrontBuffer = CreateBufferTextureClient(gfx::FORMAT_YUV, TEXTURE_DEALLOCATE_HOST); gfx::IntSize ySize(data->mYSize.width, data->mYSize.height); gfx::IntSize cbCrSize(data->mCbCrSize.width, data->mCbCrSize.height); if (!mFrontBuffer->AsTextureClientYCbCr()->AllocateForYCbCr(ySize, cbCrSize, data->mStereoMode)) { @@ -226,7 +226,7 @@ ImageClientSingle::UpdateImage(ImageContainer* aContainer, gfxImageFormat format = gfxPlatform::GetPlatform()->OptimalFormatForContent(surface->GetContentType()); mFrontBuffer = CreateBufferTextureClient(gfx::ImageFormatToSurfaceFormat(format), - TEXTURE_FLAGS_DEFAULT); + TEXTURE_DEALLOCATE_HOST); MOZ_ASSERT(mFrontBuffer->AsTextureClientSurface()); mFrontBuffer->AsTextureClientSurface()->AllocateForSurface(size); diff --git a/gfx/layers/client/TextureClient.cpp b/gfx/layers/client/TextureClient.cpp index 509bd0fa41a..4c2c0e56972 100644 --- a/gfx/layers/client/TextureClient.cpp +++ b/gfx/layers/client/TextureClient.cpp @@ -398,7 +398,7 @@ DeprecatedTextureClientShmem::ReleaseResources() ShadowLayerForwarder::CloseDescriptor(mDescriptor); } - if (!(mTextureInfo.mTextureFlags & TEXTURE_DEALLOCATE_CLIENT)) { + if (mTextureInfo.mTextureFlags & TEXTURE_DEALLOCATE_HOST) { mDescriptor = SurfaceDescriptor(); return; } diff --git a/gfx/layers/client/TextureClient.h b/gfx/layers/client/TextureClient.h index 294839238dc..1c6b798f23c 100644 --- a/gfx/layers/client/TextureClient.h +++ b/gfx/layers/client/TextureClient.h @@ -195,6 +195,13 @@ protected: void AddFlags(TextureFlags aFlags) { MOZ_ASSERT(!IsSharedWithCompositor()); + // make sure we don't deallocate on both client and host; + MOZ_ASSERT(!(aFlags & TEXTURE_DEALLOCATE_CLIENT && aFlags & TEXTURE_DEALLOCATE_HOST)); + if (aFlags & TEXTURE_DEALLOCATE_CLIENT) { + mFlags &= ~TEXTURE_DEALLOCATE_HOST; + } else if (aFlags & TEXTURE_DEALLOCATE_HOST) { + mFlags &= ~TEXTURE_DEALLOCATE_CLIENT; + } mFlags |= aFlags; } diff --git a/gfx/layers/composite/CompositableHost.cpp b/gfx/layers/composite/CompositableHost.cpp index 29bfcf91860..282988aed8d 100644 --- a/gfx/layers/composite/CompositableHost.cpp +++ b/gfx/layers/composite/CompositableHost.cpp @@ -39,7 +39,7 @@ CompositableHost::~CompositableHost() RefPtr it = mFirstTexture; while (it) { - if (!(it->GetFlags() & TEXTURE_DEALLOCATE_CLIENT)) { + if (it->GetFlags() & TEXTURE_DEALLOCATE_HOST) { it->DeallocateSharedData(); } it = it->GetNextSibling(); diff --git a/gfx/layers/ipc/CompositableTransactionParent.cpp b/gfx/layers/ipc/CompositableTransactionParent.cpp index e6814310db2..1841642e3dc 100644 --- a/gfx/layers/ipc/CompositableTransactionParent.cpp +++ b/gfx/layers/ipc/CompositableTransactionParent.cpp @@ -260,7 +260,7 @@ CompositableParentManager::ReceiveCompositableUpdate(const CompositableOperation TextureFlags flags = texture->GetFlags(); - if (!(flags & TEXTURE_DEALLOCATE_CLIENT)) { + if (flags & TEXTURE_DEALLOCATE_HOST) { texture->DeallocateSharedData(); } @@ -269,7 +269,7 @@ CompositableParentManager::ReceiveCompositableUpdate(const CompositableOperation // if it is not the host that deallocates the shared data, then we need // to notfy the client side to tell when it is safe to deallocate or // reuse it. - if (flags & TEXTURE_DEALLOCATE_CLIENT) { + if (!(flags & TEXTURE_DEALLOCATE_HOST)) { replyv.push_back(ReplyTextureRemoved(op.compositableParent(), nullptr, op.textureID())); } diff --git a/gfx/layers/ipc/ImageBridgeChild.cpp b/gfx/layers/ipc/ImageBridgeChild.cpp index 01b345b6409..53a0e8628a0 100644 --- a/gfx/layers/ipc/ImageBridgeChild.cpp +++ b/gfx/layers/ipc/ImageBridgeChild.cpp @@ -122,16 +122,16 @@ ImageBridgeChild::RemoveTexture(CompositableClient* aCompositable, uint64_t aTexture, TextureFlags aFlags) { - if (aFlags & TEXTURE_DEALLOCATE_CLIENT) { - // if deallocation happens on the host side, we need the transaction + if (aFlags & TEXTURE_DEALLOCATE_HOST) { + // if deallocation happens on the host side, we don't need the transaction // to be synchronous. - mTxn->AddEdit(OpRemoveTexture(nullptr, aCompositable->GetIPDLActor(), - aTexture, - aFlags)); - } else { mTxn->AddNoSwapEdit(OpRemoveTexture(nullptr, aCompositable->GetIPDLActor(), aTexture, aFlags)); + } else { + mTxn->AddEdit(OpRemoveTexture(nullptr, aCompositable->GetIPDLActor(), + aTexture, + aFlags)); } } diff --git a/gfx/layers/ipc/ShadowLayers.cpp b/gfx/layers/ipc/ShadowLayers.cpp index 07c0450a524..10630305060 100644 --- a/gfx/layers/ipc/ShadowLayers.cpp +++ b/gfx/layers/ipc/ShadowLayers.cpp @@ -411,7 +411,7 @@ ShadowLayerForwarder::RemoveTexture(CompositableClient* aCompositable, mTxn->AddEdit(OpRemoveTexture(nullptr, aCompositable->GetIPDLActor(), aTexture, aFlags)); - if (aFlags & TEXTURE_DEALLOCATE_CLIENT) { + if (!(aFlags & TEXTURE_DEALLOCATE_HOST)) { mTxn->MarkSyncTransaction(); } } diff --git a/gfx/layers/opengl/TextureClientOGL.cpp b/gfx/layers/opengl/TextureClientOGL.cpp index 2af0753056e..135719b5a60 100644 --- a/gfx/layers/opengl/TextureClientOGL.cpp +++ b/gfx/layers/opengl/TextureClientOGL.cpp @@ -21,8 +21,8 @@ SharedTextureClientOGL::SharedTextureClientOGL(TextureFlags aFlags) , mHandle(0) , mInverted(false) { - MOZ_ASSERT(aFlags & TEXTURE_DEALLOCATE_CLIENT, - "SharedTextureClientOGL is always owned externally"); + MOZ_ASSERT(!(aFlags & (TEXTURE_DEALLOCATE_CLIENT|TEXTURE_DEALLOCATE_HOST)), + "SharedTextureClientOGL doesn't know how to release textures!"); } SharedTextureClientOGL::~SharedTextureClientOGL() From aa9a8c2b48f67aa74ebfbc6a6a706c647172022f Mon Sep 17 00:00:00 2001 From: Drew Willcoxon Date: Thu, 26 Sep 2013 11:04:46 -0700 Subject: [PATCH 66/84] Bug 920299 - Make Mach logger colorize TEST-START and TEST-INFO. r=gps --- python/mach/mach/logging.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/python/mach/mach/logging.py b/python/mach/mach/logging.py index 4573d872027..c28f39ce7b5 100644 --- a/python/mach/mach/logging.py +++ b/python/mach/mach/logging.py @@ -114,6 +114,10 @@ class StructuredTerminalFormatter(StructuredHumanFormatter): result = self.terminal.green(s[0:9]) + s[9:] elif s.startswith('TEST-UNEXPECTED'): result = self.terminal.red(s[0:20]) + s[20:] + elif s.startswith('TEST-START'): + result = self.terminal.yellow(s[0:10]) + s[10:] + elif s.startswith('TEST-INFO'): + result = self.terminal.yellow(s[0:9]) + s[9:] return result From c3dc99499b053b0d83c39c2cc65082f402b7d8d5 Mon Sep 17 00:00:00 2001 From: Ben Turner Date: Tue, 24 Sep 2013 10:14:16 -0700 Subject: [PATCH 67/84] Bug 920633 - 'Add getAllKeys() to IDBObjectStore'. r=janv. --- dom/indexedDB/IDBIndex.cpp | 37 ++- dom/indexedDB/IDBObjectStore.cpp | 297 ++++++++++++++++++ dom/indexedDB/IDBObjectStore.h | 17 +- dom/indexedDB/ipc/IndexedDBChild.cpp | 3 + dom/indexedDB/ipc/IndexedDBParams.ipdlh | 6 + dom/indexedDB/ipc/IndexedDBParent.cpp | 41 +++ dom/indexedDB/ipc/IndexedDBParent.h | 4 + dom/indexedDB/ipc/PIndexedDBIndex.ipdl | 6 - dom/indexedDB/ipc/PIndexedDBObjectStore.ipdl | 1 + dom/indexedDB/ipc/unit/xpcshell.ini | 1 + dom/indexedDB/test/Makefile.in | 1 + .../test/test_objectStore_getAllKeys.html | 19 ++ dom/indexedDB/test/unit/Makefile.in | 1 + .../test/unit/test_objectStore_getAllKeys.js | 123 ++++++++ dom/indexedDB/test/unit/xpcshell.ini | 1 + dom/webidl/IDBObjectStore.webidl | 6 + 16 files changed, 542 insertions(+), 22 deletions(-) create mode 100644 dom/indexedDB/test/test_objectStore_getAllKeys.html create mode 100644 dom/indexedDB/test/unit/test_objectStore_getAllKeys.js diff --git a/dom/indexedDB/IDBIndex.cpp b/dom/indexedDB/IDBIndex.cpp index 0418c236191..f5274455a48 100644 --- a/dom/indexedDB/IDBIndex.cpp +++ b/dom/indexedDB/IDBIndex.cpp @@ -10,6 +10,7 @@ #include "nsIIDBKeyRange.h" +#include #include "mozilla/dom/ContentChild.h" #include "mozilla/dom/ContentParent.h" #include "mozilla/dom/ipc/Blob.h" @@ -563,6 +564,7 @@ IDBIndex::GetAllKeysInternal(IDBKeyRange* aKeyRange, uint32_t aLimit, IDBTransaction* transaction = mObjectStore->Transaction(); if (!transaction->IsOpen()) { aRv.Throw(NS_ERROR_DOM_INDEXEDDB_TRANSACTION_INACTIVE_ERR); + return nullptr; } nsRefPtr request = GenerateRequest(this); @@ -1367,10 +1369,11 @@ GetHelper::UnpackResponseFromParentProcess(const ResponseValue& aResponseValue) nsresult GetAllKeysHelper::DoDatabaseWork(mozIStorageConnection* /* aConnection */) { - NS_ASSERTION(!NS_IsMainThread(), "Wrong thread!"); - NS_ASSERTION(IndexedDatabaseManager::IsMainProcess(), "Wrong process!"); + MOZ_ASSERT(!NS_IsMainThread()); + MOZ_ASSERT(IndexedDatabaseManager::IsMainProcess()); - PROFILER_LABEL("IndexedDB", "GetAllKeysHelper::DoDatabaseWork"); + PROFILER_LABEL("IndexedDB", + "GetAllKeysHelper::DoDatabaseWork [IDBIndex.cpp]"); nsCString tableName; if (mIndex->IsUnique()) { @@ -1410,7 +1413,7 @@ GetAllKeysHelper::DoDatabaseWork(mozIStorageConnection* /* aConnection */) NS_ENSURE_SUCCESS(rv, rv); } - mKeys.SetCapacity(50); + mKeys.SetCapacity(std::min(50, mLimit)); bool hasResult; while(NS_SUCCEEDED((rv = stmt->ExecuteStep(&hasResult))) && hasResult) { @@ -1433,7 +1436,12 @@ nsresult GetAllKeysHelper::GetSuccessResult(JSContext* aCx, JS::MutableHandle aVal) { - NS_ASSERTION(mKeys.Length() <= mLimit, "Too many results!"); + MOZ_ASSERT(NS_IsMainThread()); + MOZ_ASSERT(mKeys.Length() <= mLimit); + + PROFILER_MAIN_THREAD_LABEL("IndexedDB", + "GetAllKeysHelper::GetSuccessResult " + "[IDBIndex.cpp]"); nsTArray keys; mKeys.SwapElements(keys); @@ -1475,11 +1483,12 @@ GetAllKeysHelper::GetSuccessResult(JSContext* aCx, nsresult GetAllKeysHelper::PackArgumentsForParentProcess(IndexRequestParams& aParams) { - NS_ASSERTION(NS_IsMainThread(), "Wrong thread!"); - NS_ASSERTION(!IndexedDatabaseManager::IsMainProcess(), "Wrong process!"); + MOZ_ASSERT(NS_IsMainThread()); + MOZ_ASSERT(!IndexedDatabaseManager::IsMainProcess()); PROFILER_MAIN_THREAD_LABEL("IndexedDB", - "GetAllKeysHelper::PackArgumentsForParentProcess"); + "GetAllKeysHelper::PackArgumentsForParentProcess " + "[IDBIndex.cpp]"); GetAllKeysParams params; @@ -1501,11 +1510,12 @@ GetAllKeysHelper::PackArgumentsForParentProcess(IndexRequestParams& aParams) AsyncConnectionHelper::ChildProcessSendResult GetAllKeysHelper::SendResponseToChildProcess(nsresult aResultCode) { - NS_ASSERTION(NS_IsMainThread(), "Wrong thread!"); - NS_ASSERTION(IndexedDatabaseManager::IsMainProcess(), "Wrong process!"); + MOZ_ASSERT(NS_IsMainThread()); + MOZ_ASSERT(IndexedDatabaseManager::IsMainProcess()); PROFILER_MAIN_THREAD_LABEL("IndexedDB", - "GetAllKeysHelper::SendResponseToChildProcess"); + "GetAllKeysHelper::SendResponseToChildProcess " + "[IDBIndex.cpp]"); IndexedDBRequestParentBase* actor = mRequest->GetActorParent(); NS_ASSERTION(actor, "How did we get this far without an actor?"); @@ -1531,8 +1541,9 @@ nsresult GetAllKeysHelper::UnpackResponseFromParentProcess( const ResponseValue& aResponseValue) { - NS_ASSERTION(aResponseValue.type() == ResponseValue::TGetAllKeysResponse, - "Bad response type!"); + MOZ_ASSERT(NS_IsMainThread()); + MOZ_ASSERT(!IndexedDatabaseManager::IsMainProcess()); + MOZ_ASSERT(aResponseValue.type() == ResponseValue::TGetAllKeysResponse); mKeys.AppendElements(aResponseValue.get_GetAllKeysResponse().keys()); return NS_OK; diff --git a/dom/indexedDB/IDBObjectStore.cpp b/dom/indexedDB/IDBObjectStore.cpp index bf168099037..ca488fc7b46 100644 --- a/dom/indexedDB/IDBObjectStore.cpp +++ b/dom/indexedDB/IDBObjectStore.cpp @@ -11,6 +11,7 @@ #include "mozilla/dom/ipc/nsIRemoteBlob.h" #include "nsIOutputStream.h" +#include #include "jsfriendapi.h" #include "mozilla/dom/ContentChild.h" #include "mozilla/dom/ContentParent.h" @@ -441,6 +442,46 @@ private: nsTArray mCloneReadInfos; }; +class GetAllKeysHelper MOZ_FINAL : public ObjectStoreHelper +{ +public: + GetAllKeysHelper(IDBTransaction* aTransaction, + IDBRequest* aRequest, + IDBObjectStore* aObjectStore, + IDBKeyRange* aKeyRange, + const uint32_t aLimit) + : ObjectStoreHelper(aTransaction, aRequest, aObjectStore), + mKeyRange(aKeyRange), mLimit(aLimit) + { } + + virtual nsresult + DoDatabaseWork(mozIStorageConnection* aConnection) MOZ_OVERRIDE; + + virtual nsresult + GetSuccessResult(JSContext* aCx, JS::MutableHandleValue aVal) MOZ_OVERRIDE; + + virtual void + ReleaseMainThreadObjects() MOZ_OVERRIDE; + + virtual nsresult + PackArgumentsForParentProcess(ObjectStoreRequestParams& aParams) MOZ_OVERRIDE; + + virtual ChildProcessSendResult + SendResponseToChildProcess(nsresult aResultCode) MOZ_OVERRIDE; + + virtual nsresult + UnpackResponseFromParentProcess(const ResponseValue& aResponseValue) + MOZ_OVERRIDE; + +private: + ~GetAllKeysHelper() + { } + + nsRefPtr mKeyRange; + const uint32_t mLimit; + nsTArray mKeys; +}; + class CountHelper : public ObjectStoreHelper { public: @@ -2081,6 +2122,47 @@ IDBObjectStore::GetAllInternal(IDBKeyRange* aKeyRange, return request.forget(); } +already_AddRefed +IDBObjectStore::GetAllKeysInternal(IDBKeyRange* aKeyRange, uint32_t aLimit, + ErrorResult& aRv) +{ + MOZ_ASSERT(NS_IsMainThread()); + + if (!mTransaction->IsOpen()) { + aRv.Throw(NS_ERROR_DOM_INDEXEDDB_TRANSACTION_INACTIVE_ERR); + return nullptr; + } + + nsRefPtr request = GenerateRequest(this); + if (!request) { + NS_WARNING("Failed to generate request!"); + aRv.Throw(NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR); + return nullptr; + } + + nsRefPtr helper = + new GetAllKeysHelper(mTransaction, request, this, aKeyRange, aLimit); + + nsresult rv = helper->DispatchToTransactionPool(); + if (NS_FAILED(rv)) { + NS_WARNING("Failed to dispatch!"); + aRv.Throw(NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR); + return nullptr; + } + + IDB_PROFILER_MARK("IndexedDB Request %llu: " + "database(%s).transaction(%s).objectStore(%s)." + "getAllKeys(%s, %lu)", + "IDBRequest[%llu] MT IDBObjectStore.getAllKeys()", + request->GetSerialNumber(), + IDB_PROFILER_STRING(Transaction()->Database()), + IDB_PROFILER_STRING(Transaction()), + IDB_PROFILER_STRING(this), IDB_PROFILER_STRING(aKeyRange), + aLimit); + + return request.forget(); +} + already_AddRefed IDBObjectStore::DeleteInternal(IDBKeyRange* aKeyRange, ErrorResult& aRv) @@ -2767,6 +2849,32 @@ IDBObjectStore::Count(JSContext* aCx, return CountInternal(keyRange, aRv); } +already_AddRefed +IDBObjectStore::GetAllKeys(JSContext* aCx, + const Optional& aKey, + const Optional& aLimit, ErrorResult& aRv) +{ + MOZ_ASSERT(NS_IsMainThread()); + + if (!mTransaction->IsOpen()) { + aRv.Throw(NS_ERROR_DOM_INDEXEDDB_TRANSACTION_INACTIVE_ERR); + return nullptr; + } + + nsRefPtr keyRange; + if (aKey.WasPassed()) { + aRv = IDBKeyRange::FromJSVal(aCx, aKey.Value(), getter_AddRefs(keyRange)); + ENSURE_SUCCESS(aRv, nullptr); + } + + uint32_t limit = UINT32_MAX; + if (aLimit.WasPassed() && aLimit.Value() != 0) { + limit = aLimit.Value(); + } + + return GetAllKeysInternal(keyRange, limit, aRv); +} + inline nsresult CopyData(nsIInputStream* aInputStream, nsIOutputStream* aOutputStream) { @@ -4297,6 +4405,195 @@ GetAllHelper::UnpackResponseFromParentProcess( return NS_OK; } +nsresult +GetAllKeysHelper::DoDatabaseWork(mozIStorageConnection* /* aConnection */) +{ + MOZ_ASSERT(!NS_IsMainThread()); + MOZ_ASSERT(IndexedDatabaseManager::IsMainProcess()); + + PROFILER_LABEL("IndexedDB", + "GetAllKeysHelper::DoDatabaseWork [IDObjectStore.cpp]"); + + NS_NAMED_LITERAL_CSTRING(keyValue, "key_value"); + + nsAutoCString keyRangeClause; + if (mKeyRange) { + mKeyRange->GetBindingClause(keyValue, keyRangeClause); + } + + nsAutoCString limitClause; + if (mLimit != UINT32_MAX) { + limitClause = NS_LITERAL_CSTRING(" LIMIT "); + limitClause.AppendInt(mLimit); + } + + NS_NAMED_LITERAL_CSTRING(osid, "osid"); + + nsCString query = NS_LITERAL_CSTRING("SELECT ") + keyValue + + NS_LITERAL_CSTRING(" FROM object_data WHERE " + "object_store_id = :") + + osid + keyRangeClause + + NS_LITERAL_CSTRING(" ORDER BY key_value ASC") + + limitClause; + + nsCOMPtr stmt = mTransaction->GetCachedStatement(query); + NS_ENSURE_TRUE(stmt, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR); + + mozStorageStatementScoper scoper(stmt); + + nsresult rv = stmt->BindInt64ByName(osid, mObjectStore->Id()); + NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR); + + if (mKeyRange) { + rv = mKeyRange->BindToStatement(stmt); + NS_ENSURE_SUCCESS(rv, rv); + } + + mKeys.SetCapacity(std::min(50, mLimit)); + + bool hasResult; + while(NS_SUCCEEDED((rv = stmt->ExecuteStep(&hasResult))) && hasResult) { + if (mKeys.Capacity() == mKeys.Length()) { + mKeys.SetCapacity(mKeys.Capacity() * 2); + } + + Key* key = mKeys.AppendElement(); + NS_ASSERTION(key, "This shouldn't fail!"); + + rv = key->SetFromStatement(stmt, 0); + NS_ENSURE_SUCCESS(rv, rv); + } + NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR); + + return NS_OK; +} + +nsresult +GetAllKeysHelper::GetSuccessResult(JSContext* aCx, JS::MutableHandleValue aVal) +{ + MOZ_ASSERT(NS_IsMainThread()); + MOZ_ASSERT(mKeys.Length() <= mLimit); + + PROFILER_MAIN_THREAD_LABEL("IndexedDB", + "GetAllKeysHelper::GetSuccessResult " + "[IDBObjectStore.cpp]"); + + nsTArray keys; + mKeys.SwapElements(keys); + + JS::RootedObject array(aCx, JS_NewArrayObject(aCx, 0, NULL)); + if (!array) { + NS_WARNING("Failed to make array!"); + return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR; + } + + if (!keys.IsEmpty()) { + if (!JS_SetArrayLength(aCx, array, keys.Length())) { + NS_WARNING("Failed to set array length!"); + return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR; + } + + for (uint32_t index = 0, count = keys.Length(); index < count; index++) { + const Key& key = keys[index]; + MOZ_ASSERT(!key.IsUnset()); + + JS::RootedValue value(aCx); + nsresult rv = key.ToJSVal(aCx, &value); + if (NS_FAILED(rv)) { + NS_WARNING("Failed to get jsval for key!"); + return rv; + } + + if (!JS_SetElement(aCx, array, index, &value)) { + NS_WARNING("Failed to set array element!"); + return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR; + } + } + } + + aVal.setObject(*array); + return NS_OK; +} + +void +GetAllKeysHelper::ReleaseMainThreadObjects() +{ + MOZ_ASSERT(NS_IsMainThread()); + + mKeyRange = nullptr; + + ObjectStoreHelper::ReleaseMainThreadObjects(); +} + +nsresult +GetAllKeysHelper::PackArgumentsForParentProcess( + ObjectStoreRequestParams& aParams) +{ + MOZ_ASSERT(NS_IsMainThread()); + MOZ_ASSERT(!IndexedDatabaseManager::IsMainProcess()); + + PROFILER_MAIN_THREAD_LABEL("IndexedDB", + "GetAllKeysHelper::PackArgumentsForParentProcess " + "[IDBObjectStore.cpp]"); + + GetAllKeysParams params; + + if (mKeyRange) { + KeyRange keyRange; + mKeyRange->ToSerializedKeyRange(keyRange); + params.optionalKeyRange() = keyRange; + } else { + params.optionalKeyRange() = mozilla::void_t(); + } + + params.limit() = mLimit; + + aParams = params; + return NS_OK; +} + +AsyncConnectionHelper::ChildProcessSendResult +GetAllKeysHelper::SendResponseToChildProcess(nsresult aResultCode) +{ + MOZ_ASSERT(NS_IsMainThread()); + MOZ_ASSERT(IndexedDatabaseManager::IsMainProcess()); + + PROFILER_MAIN_THREAD_LABEL("IndexedDB", + "GetAllKeysHelper::SendResponseToChildProcess " + "[IDBObjectStore.cpp]"); + + IndexedDBRequestParentBase* actor = mRequest->GetActorParent(); + MOZ_ASSERT(actor); + + ResponseValue response; + if (NS_FAILED(aResultCode)) { + response = aResultCode; + } + else { + GetAllKeysResponse getAllKeysResponse; + getAllKeysResponse.keys().AppendElements(mKeys); + response = getAllKeysResponse; + } + + if (!actor->SendResponse(response)) { + return Error; + } + + return Success_Sent; +} + +nsresult +GetAllKeysHelper::UnpackResponseFromParentProcess( + const ResponseValue& aResponseValue) +{ + MOZ_ASSERT(NS_IsMainThread()); + MOZ_ASSERT(!IndexedDatabaseManager::IsMainProcess()); + MOZ_ASSERT(aResponseValue.type() == ResponseValue::TGetAllKeysResponse); + + mKeys.AppendElements(aResponseValue.get_GetAllKeysResponse().keys()); + return NS_OK; +} + nsresult CountHelper::DoDatabaseWork(mozIStorageConnection* aConnection) { diff --git a/dom/indexedDB/IDBObjectStore.h b/dom/indexedDB/IDBObjectStore.h index 86f225f8422..dfad748f7fd 100644 --- a/dom/indexedDB/IDBObjectStore.h +++ b/dom/indexedDB/IDBObjectStore.h @@ -9,6 +9,7 @@ #include "mozilla/dom/indexedDB/IndexedDatabase.h" +#include "js/TypeDecls.h" #include "mozilla/dom/IDBCursorBinding.h" #include "mozilla/dom/IDBIndexBinding.h" #include "mozilla/dom/IDBObjectStoreBinding.h" @@ -220,6 +221,11 @@ public: uint32_t aLimit, ErrorResult& aRv); + already_AddRefed + GetAllKeysInternal(IDBKeyRange* aKeyRange, + uint32_t aLimit, + ErrorResult& aRv); + already_AddRefed DeleteInternal(IDBKeyRange* aKeyRange, ErrorResult& aRv); @@ -233,7 +239,8 @@ public: size_t aDirection, ErrorResult& aRv); - nsresult OpenCursorFromChildProcess( + nsresult + OpenCursorFromChildProcess( IDBRequest* aRequest, size_t aDirection, const Key& aKey, @@ -319,7 +326,7 @@ public: already_AddRefed CreateIndex(JSContext* aCx, const nsAString& aName, - const Sequence& aKeyPath, + const Sequence& aKeyPath, const IDBIndexParameters& aOptionalParameters, ErrorResult& aRv); already_AddRefed @@ -334,7 +341,11 @@ public: already_AddRefed GetAll(JSContext* aCx, const Optional >& aKey, - const Optional& aLimit, ErrorResult& aRv); + const Optional& aLimit, ErrorResult& aRv); + + already_AddRefed + GetAllKeys(JSContext* aCx, const Optional& aKey, + const Optional& aLimit, ErrorResult& aRv); protected: IDBObjectStore(); diff --git a/dom/indexedDB/ipc/IndexedDBChild.cpp b/dom/indexedDB/ipc/IndexedDBChild.cpp index 3b7e9e98293..038d42978b2 100644 --- a/dom/indexedDB/ipc/IndexedDBChild.cpp +++ b/dom/indexedDB/ipc/IndexedDBChild.cpp @@ -1069,6 +1069,9 @@ IndexedDBObjectStoreRequestChild::Recv__delete__(const ResponseValue& aResponse) case ResponseValue::TGetAllResponse: MOZ_ASSERT(mRequestType == ParamsUnionType::TGetAllParams); break; + case ResponseValue::TGetAllKeysResponse: + MOZ_ASSERT(mRequestType == ParamsUnionType::TGetAllKeysParams); + break; case ResponseValue::TAddResponse: MOZ_ASSERT(mRequestType == ParamsUnionType::TAddParams); break; diff --git a/dom/indexedDB/ipc/IndexedDBParams.ipdlh b/dom/indexedDB/ipc/IndexedDBParams.ipdlh index a3b2e0224e5..d3e3d2d8bba 100644 --- a/dom/indexedDB/ipc/IndexedDBParams.ipdlh +++ b/dom/indexedDB/ipc/IndexedDBParams.ipdlh @@ -40,6 +40,12 @@ struct GetAllParams uint32_t limit; }; +struct GetAllKeysParams +{ + OptionalKeyRange optionalKeyRange; + uint32_t limit; +}; + struct CountParams { OptionalKeyRange optionalKeyRange; diff --git a/dom/indexedDB/ipc/IndexedDBParent.cpp b/dom/indexedDB/ipc/IndexedDBParent.cpp index 0630b23338b..419cd12716c 100644 --- a/dom/indexedDB/ipc/IndexedDBParent.cpp +++ b/dom/indexedDB/ipc/IndexedDBParent.cpp @@ -1097,6 +1097,9 @@ IndexedDBObjectStoreParent::RecvPIndexedDBRequestConstructor( case ObjectStoreRequestParams::TGetAllParams: return actor->GetAll(aParams.get_GetAllParams()); + case ObjectStoreRequestParams::TGetAllKeysParams: + return actor->GetAllKeys(aParams.get_GetAllKeysParams()); + case ObjectStoreRequestParams::TAddParams: return actor->Add(aParams.get_AddParams()); @@ -1554,6 +1557,44 @@ IndexedDBObjectStoreRequestParent::GetAll(const GetAllParams& aParams) return true; } +bool +IndexedDBObjectStoreRequestParent::GetAllKeys(const GetAllKeysParams& aParams) +{ + MOZ_ASSERT(mRequestType == ParamsUnionType::TGetAllKeysParams); + MOZ_ASSERT(mObjectStore); + + nsRefPtr request; + + const ipc::OptionalKeyRange keyRangeUnion = aParams.optionalKeyRange(); + + nsRefPtr keyRange; + + switch (keyRangeUnion.type()) { + case ipc::OptionalKeyRange::TKeyRange: + keyRange = + IDBKeyRange::FromSerializedKeyRange(keyRangeUnion.get_KeyRange()); + break; + + case ipc::OptionalKeyRange::Tvoid_t: + break; + + default: + MOZ_CRASH("Unknown param type!"); + } + + { + AutoSetCurrentTransaction asct(mObjectStore->Transaction()); + + ErrorResult rv; + request = mObjectStore->GetAllKeysInternal(keyRange, aParams.limit(), rv); + ENSURE_SUCCESS(rv, false); + } + + request->SetActor(this); + mRequest.swap(request); + return true; +} + bool IndexedDBObjectStoreRequestParent::Add(const AddParams& aParams) { diff --git a/dom/indexedDB/ipc/IndexedDBParent.h b/dom/indexedDB/ipc/IndexedDBParent.h index ee212a594c6..092f3f87de2 100644 --- a/dom/indexedDB/ipc/IndexedDBParent.h +++ b/dom/indexedDB/ipc/IndexedDBParent.h @@ -707,6 +707,7 @@ class IndexedDBObjectStoreRequestParent : public IndexedDBRequestParentBase typedef ipc::DeleteParams DeleteParams; typedef ipc::GetParams GetParams; typedef ipc::GetAllParams GetAllParams; + typedef ipc::GetAllKeysParams GetAllKeysParams; typedef ipc::CountParams CountParams; typedef ipc::OpenCursorParams OpenCursorParams; @@ -721,6 +722,9 @@ public: bool GetAll(const GetAllParams& aParams); + bool + GetAllKeys(const GetAllKeysParams& aParams); + bool Add(const AddParams& aParams); diff --git a/dom/indexedDB/ipc/PIndexedDBIndex.ipdl b/dom/indexedDB/ipc/PIndexedDBIndex.ipdl index 88d0022c821..21ff8d89b40 100644 --- a/dom/indexedDB/ipc/PIndexedDBIndex.ipdl +++ b/dom/indexedDB/ipc/PIndexedDBIndex.ipdl @@ -22,12 +22,6 @@ struct GetKeyParams KeyRange keyRange; }; -struct GetAllKeysParams -{ - OptionalKeyRange optionalKeyRange; - uint32_t limit; -}; - struct OpenKeyCursorParams { OptionalKeyRange optionalKeyRange; diff --git a/dom/indexedDB/ipc/PIndexedDBObjectStore.ipdl b/dom/indexedDB/ipc/PIndexedDBObjectStore.ipdl index f79bd81a5b4..e3483c346c6 100644 --- a/dom/indexedDB/ipc/PIndexedDBObjectStore.ipdl +++ b/dom/indexedDB/ipc/PIndexedDBObjectStore.ipdl @@ -52,6 +52,7 @@ union ObjectStoreRequestParams { GetParams; GetAllParams; + GetAllKeysParams; AddParams; PutParams; DeleteParams; diff --git a/dom/indexedDB/ipc/unit/xpcshell.ini b/dom/indexedDB/ipc/unit/xpcshell.ini index f04d1723477..78254e31dc1 100644 --- a/dom/indexedDB/ipc/unit/xpcshell.ini +++ b/dom/indexedDB/ipc/unit/xpcshell.ini @@ -36,6 +36,7 @@ tail = [test_names_sorted.js] [test_object_identity.js] [test_objectCursors.js] +[test_objectStore_getAllKeys.js] [test_objectStore_inline_autoincrement_key_added_on_put.js] [test_objectStore_remove_values.js] [test_odd_result_order.js] diff --git a/dom/indexedDB/test/Makefile.in b/dom/indexedDB/test/Makefile.in index f92ae0159b1..18e51ca022e 100644 --- a/dom/indexedDB/test/Makefile.in +++ b/dom/indexedDB/test/Makefile.in @@ -70,6 +70,7 @@ MOCHITEST_FILES = \ test_multientry.html \ test_names_sorted.html \ test_objectCursors.html \ + test_objectStore_getAllKeys.html \ test_objectStore_inline_autoincrement_key_added_on_put.html \ test_objectStore_remove_values.html \ test_object_identity.html \ diff --git a/dom/indexedDB/test/test_objectStore_getAllKeys.html b/dom/indexedDB/test/test_objectStore_getAllKeys.html new file mode 100644 index 00000000000..7ae98882d08 --- /dev/null +++ b/dom/indexedDB/test/test_objectStore_getAllKeys.html @@ -0,0 +1,19 @@ + + + + Indexed Database Property Test + + + + + + + + + + + + diff --git a/dom/indexedDB/test/unit/Makefile.in b/dom/indexedDB/test/unit/Makefile.in index 1e69218ca20..8761a2f5e90 100644 --- a/dom/indexedDB/test/unit/Makefile.in +++ b/dom/indexedDB/test/unit/Makefile.in @@ -38,6 +38,7 @@ MOCHITEST_FILES = \ test_names_sorted.js \ test_object_identity.js \ test_objectCursors.js \ + test_objectStore_getAllKeys.js \ test_objectStore_inline_autoincrement_key_added_on_put.js \ test_objectStore_remove_values.js \ test_odd_result_order.js \ diff --git a/dom/indexedDB/test/unit/test_objectStore_getAllKeys.js b/dom/indexedDB/test/unit/test_objectStore_getAllKeys.js new file mode 100644 index 00000000000..8e078cc6114 --- /dev/null +++ b/dom/indexedDB/test/unit/test_objectStore_getAllKeys.js @@ -0,0 +1,123 @@ +/** + * Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ + */ + +let testGenerator = testSteps(); + +function testSteps() { + const dbName = this.window ? + window.location.pathname : + "test_objectStore_getAllKeys"; + const dbVersion = 1; + const objectStoreName = "foo"; + const keyCount = 200; + + let request = indexedDB.open(dbName, dbVersion); + request.onerror = errorHandler; + request.onupgradeneeded = grabEventAndContinueHandler; + request.onsuccess = unexpectedSuccessHandler; + + let event = yield undefined; + + info("Creating database"); + + let db = event.target.result; + let objectStore = db.createObjectStore(objectStoreName); + for (let i = 0; i < keyCount; i++) { + objectStore.add(true, i); + } + + request.onupgradeneeded = unexpectedSuccessHandler; + request.onsuccess = grabEventAndContinueHandler; + + event = yield undefined; + + db = event.target.result; + objectStore = db.transaction(objectStoreName).objectStore(objectStoreName); + + info("Getting all keys"); + objectStore.getAllKeys().onsuccess = grabEventAndContinueHandler; + event = yield undefined; + + ok(Array.isArray(event.target.result), "Got an array result"); + is(event.target.result.length, keyCount, "Got correct array length"); + + let match = true; + for (let i = 0; i < keyCount; i++) { + if (event.target.result[i] != i) { + match = false; + break; + } + } + ok(match, "Got correct keys"); + + info("Getting all keys with key range"); + let keyRange = IDBKeyRange.bound(10, 20, false, true); + objectStore.getAllKeys(keyRange).onsuccess = grabEventAndContinueHandler; + event = yield undefined; + + ok(Array.isArray(event.target.result), "Got an array result"); + is(event.target.result.length, 10, "Got correct array length"); + + match = true; + for (let i = 10; i < 20; i++) { + if (event.target.result[i - 10] != i) { + match = false; + break; + } + } + ok(match, "Got correct keys"); + + info("Getting all keys with unmatched key range"); + keyRange = IDBKeyRange.bound(10000, 200000); + objectStore.getAllKeys(keyRange).onsuccess = grabEventAndContinueHandler; + event = yield undefined; + + ok(Array.isArray(event.target.result), "Got an array result"); + is(event.target.result.length, 0, "Got correct array length"); + + info("Getting all keys with limit"); + objectStore.getAllKeys(null, 5).onsuccess = grabEventAndContinueHandler; + event = yield undefined; + + ok(Array.isArray(event.target.result), "Got an array result"); + is(event.target.result.length, 5, "Got correct array length"); + + match = true; + for (let i = 0; i < 5; i++) { + if (event.target.result[i] != i) { + match = false; + break; + } + } + ok(match, "Got correct keys"); + + info("Getting all keys with key range and limit"); + keyRange = IDBKeyRange.bound(10, 20, false, true); + objectStore.getAllKeys(keyRange, 5).onsuccess = grabEventAndContinueHandler; + event = yield undefined; + + ok(Array.isArray(event.target.result), "Got an array result"); + is(event.target.result.length, 5, "Got correct array length"); + + match = true; + for (let i = 10; i < 15; i++) { + if (event.target.result[i - 10] != i) { + match = false; + break; + } + } + ok(match, "Got correct keys"); + + info("Getting all keys with unmatched key range and limit"); + keyRange = IDBKeyRange.bound(10000, 200000); + objectStore.getAllKeys(keyRange, 5).onsuccess = grabEventAndContinueHandler; + event = yield undefined; + + ok(Array.isArray(event.target.result), "Got an array result"); + is(event.target.result.length, 0, "Got correct array length"); + + finishTest(); + yield undefined; +} diff --git a/dom/indexedDB/test/unit/xpcshell.ini b/dom/indexedDB/test/unit/xpcshell.ini index a2adfc1556f..c098bd9df31 100644 --- a/dom/indexedDB/test/unit/xpcshell.ini +++ b/dom/indexedDB/test/unit/xpcshell.ini @@ -39,6 +39,7 @@ tail = [test_names_sorted.js] [test_object_identity.js] [test_objectCursors.js] +[test_objectStore_getAllKeys.js] [test_objectStore_inline_autoincrement_key_added_on_put.js] [test_objectStore_remove_values.js] [test_odd_result_order.js] diff --git a/dom/webidl/IDBObjectStore.webidl b/dom/webidl/IDBObjectStore.webidl index a323b80d9c3..0607f832037 100644 --- a/dom/webidl/IDBObjectStore.webidl +++ b/dom/webidl/IDBObjectStore.webidl @@ -65,4 +65,10 @@ partial interface IDBObjectStore { // Success fires IDBTransactionEvent, result == array of values for given keys [Throws] IDBRequest mozGetAll (optional any key, optional unsigned long limit); + + [Pref="dom.indexedDB.experimental", Throws] + IDBRequest getAll (optional any key, optional unsigned long limit); + + [Pref="dom.indexedDB.experimental", Throws] + IDBRequest getAllKeys (optional any key, optional unsigned long limit); }; From 083c2958642c753b95ab88ce4e9bd970845c0f43 Mon Sep 17 00:00:00 2001 From: Sriram Ramasubramanian Date: Tue, 24 Sep 2013 11:54:16 -0700 Subject: [PATCH 68/84] Bug 910882: Change search suggestions background to a lighter blue. [r=margaret] --HG-- extra : rebase_source : cd4b8ab06669bc856bded04392d71abc6e8961ac --- .../base/resources/layout/home_suggestion_prompt.xml | 11 +++++------ mobile/android/base/resources/values/styles.xml | 4 ++++ 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/mobile/android/base/resources/layout/home_suggestion_prompt.xml b/mobile/android/base/resources/layout/home_suggestion_prompt.xml index ed9ae66dccb..51ea012bb5f 100644 --- a/mobile/android/base/resources/layout/home_suggestion_prompt.xml +++ b/mobile/android/base/resources/layout/home_suggestion_prompt.xml @@ -6,7 +6,7 @@ + android:background="@color/background_light"> + android:layout_weight="1" + android:textAppearance="@style/TextAppearance.Widget.SuggestionsPrompt"/> ?android:attr/textColorSecondary + +