diff options
21 files changed, 2036 insertions, 1 deletions
diff --git a/gnu-system.am b/gnu-system.am index 946b77eeff..f3ded69a78 100644 --- a/gnu-system.am +++ b/gnu-system.am @@ -500,6 +500,25 @@ dist_patch_DATA = \ gnu/packages/patches/hwloc-gather-topology-lstopo.patch \ gnu/packages/patches/hydra-automake-1.15.patch \ gnu/packages/patches/hydra-disable-darcs-test.patch \ + gnu/packages/patches/icecat-CVE-2015-4513-pt01.patch \ + gnu/packages/patches/icecat-CVE-2015-4513-pt02.patch \ + gnu/packages/patches/icecat-CVE-2015-4513-pt03.patch \ + gnu/packages/patches/icecat-CVE-2015-4513-pt04.patch \ + gnu/packages/patches/icecat-CVE-2015-4513-pt05.patch \ + gnu/packages/patches/icecat-CVE-2015-4513-pt06.patch \ + gnu/packages/patches/icecat-CVE-2015-4513-pt07.patch \ + gnu/packages/patches/icecat-CVE-2015-4513-pt08.patch \ + gnu/packages/patches/icecat-CVE-2015-4513-pt09.patch \ + gnu/packages/patches/icecat-CVE-2015-4513-pt10.patch \ + gnu/packages/patches/icecat-CVE-2015-4513-pt11.patch \ + gnu/packages/patches/icecat-CVE-2015-7188.patch \ + gnu/packages/patches/icecat-CVE-2015-7189.patch \ + gnu/packages/patches/icecat-CVE-2015-7193.patch \ + gnu/packages/patches/icecat-CVE-2015-7194.patch \ + gnu/packages/patches/icecat-CVE-2015-7196.patch \ + gnu/packages/patches/icecat-CVE-2015-7197.patch \ + gnu/packages/patches/icecat-CVE-2015-7198.patch \ + gnu/packages/patches/icecat-CVE-2015-7199.patch \ gnu/packages/patches/icecat-avoid-bundled-includes.patch \ gnu/packages/patches/icecat-freetype-2.6.patch \ gnu/packages/patches/icu4c-CVE-2014-6585.patch \ diff --git a/gnu/packages/gnuzilla.scm b/gnu/packages/gnuzilla.scm index 07453989df..49e3b31537 100644 --- a/gnu/packages/gnuzilla.scm +++ b/gnu/packages/gnuzilla.scm @@ -239,7 +239,26 @@ standards.") (base32 "0vm6f7f1i5vkq2713mgzjdfnm8rpz9l0q8sv4s123vsam0j9gzh8")) (patches (map search-patch '("icecat-avoid-bundled-includes.patch" - "icecat-freetype-2.6.patch"))) + "icecat-freetype-2.6.patch" + "icecat-CVE-2015-4513-pt01.patch" + "icecat-CVE-2015-4513-pt02.patch" + "icecat-CVE-2015-4513-pt03.patch" + "icecat-CVE-2015-4513-pt04.patch" + "icecat-CVE-2015-4513-pt05.patch" + "icecat-CVE-2015-4513-pt06.patch" + "icecat-CVE-2015-4513-pt07.patch" + "icecat-CVE-2015-4513-pt08.patch" + "icecat-CVE-2015-4513-pt09.patch" + "icecat-CVE-2015-4513-pt10.patch" + "icecat-CVE-2015-4513-pt11.patch" + "icecat-CVE-2015-7188.patch" + "icecat-CVE-2015-7189.patch" + "icecat-CVE-2015-7193.patch" + "icecat-CVE-2015-7194.patch" + "icecat-CVE-2015-7196.patch" + "icecat-CVE-2015-7197.patch" + "icecat-CVE-2015-7198.patch" + "icecat-CVE-2015-7199.patch"))) (modules '((guix build utils))) (snippet '(begin diff --git a/gnu/packages/patches/icecat-CVE-2015-4513-pt01.patch b/gnu/packages/patches/icecat-CVE-2015-4513-pt01.patch new file mode 100644 index 0000000000..f003e3cf68 --- /dev/null +++ b/gnu/packages/patches/icecat-CVE-2015-4513-pt01.patch @@ -0,0 +1,36 @@ +From 3df141cb85a530d7ddc3a7555d44235e49341837 Mon Sep 17 00:00:00 2001 +From: Karl Tomlinson <karlt+@karlt.net> +Date: Sat, 19 Sep 2015 00:51:03 +1200 +Subject: [PATCH] Bug 1206564 - skip copying of listeners. r=roc, a=sylvestre + +--HG-- +extra : source : ddd169d6bd65771a6811a3bb223a4a385b101690 +--- + widget/gtk/nsWindow.cpp | 11 +++++------ + 1 file changed, 5 insertions(+), 6 deletions(-) + +diff --git a/widget/gtk/nsWindow.cpp b/widget/gtk/nsWindow.cpp +index dd1895b..d8e8e42 100644 +--- a/widget/gtk/nsWindow.cpp ++++ b/widget/gtk/nsWindow.cpp +@@ -461,12 +461,11 @@ nsWindow::DispatchDeactivateEvent(void) + void + nsWindow::DispatchResized(int32_t aWidth, int32_t aHeight) + { +- nsIWidgetListener *listeners[] = +- { mWidgetListener, mAttachedWidgetListener }; +- for (size_t i = 0; i < ArrayLength(listeners); ++i) { +- if (listeners[i]) { +- listeners[i]->WindowResized(this, aWidth, aHeight); +- } ++ if (mWidgetListener) { ++ mWidgetListener->WindowResized(this, aWidth, aHeight); ++ } ++ if (mAttachedWidgetListener) { ++ mAttachedWidgetListener->WindowResized(this, aWidth, aHeight); + } + } + +-- +2.5.0 + diff --git a/gnu/packages/patches/icecat-CVE-2015-4513-pt02.patch b/gnu/packages/patches/icecat-CVE-2015-4513-pt02.patch new file mode 100644 index 0000000000..9a77ed908b --- /dev/null +++ b/gnu/packages/patches/icecat-CVE-2015-4513-pt02.patch @@ -0,0 +1,103 @@ +From d463cb5f0374bfc7c62ae5f1c89edd3ca35084e5 Mon Sep 17 00:00:00 2001 +From: Olli Pettay <Olli.Pettay@helsinki.fi> +Date: Thu, 24 Sep 2015 03:53:31 +0300 +Subject: [PATCH] Bug 1204669 - optimize out hashtable lookups caused by extra + GetPrototypeBinding call, r=bz,waldo, a=al + +--HG-- +extra : source : 91657db26f49f885f2338cb8c9302cdf18999f1f +--- + dom/xbl/nsXBLPrototypeBinding.h | 9 +++++++-- + dom/xbl/nsXBLService.cpp | 6 +++--- + mfbt/WeakPtr.h | 8 +++++++- + 3 files changed, 17 insertions(+), 6 deletions(-) + +diff --git a/dom/xbl/nsXBLPrototypeBinding.h b/dom/xbl/nsXBLPrototypeBinding.h +index be2cb5a..1aaa07f 100644 +--- a/dom/xbl/nsXBLPrototypeBinding.h ++++ b/dom/xbl/nsXBLPrototypeBinding.h +@@ -17,6 +17,7 @@ + #include "nsXBLProtoImplMethod.h" + #include "nsXBLPrototypeHandler.h" + #include "nsXBLPrototypeResources.h" ++#include "mozilla/WeakPtr.h" + + class nsIAtom; + class nsIContent; +@@ -35,9 +36,12 @@ class CSSStyleSheet; + // Instances of this class are owned by the nsXBLDocumentInfo object returned + // by XBLDocumentInfo(). Consumers who want to refcount things should refcount + // that. +-class nsXBLPrototypeBinding final ++class nsXBLPrototypeBinding final : ++ public mozilla::SupportsWeakPtr<nsXBLPrototypeBinding> + { + public: ++ MOZ_DECLARE_WEAKREFERENCE_TYPENAME(nsXBLPrototypeBinding) ++ + nsIContent* GetBindingElement() const { return mBinding; } + void SetBindingElement(nsIContent* aElement); + +@@ -289,7 +293,8 @@ protected: + nsXBLProtoImpl* mImplementation; // Our prototype implementation (includes methods, properties, fields, + // the constructor, and the destructor). + +- nsXBLPrototypeBinding* mBaseBinding; // Weak. The docinfo will own our base binding. ++ // Weak. The docinfo will own our base binding. ++ mozilla::WeakPtr<nsXBLPrototypeBinding> mBaseBinding; + bool mInheritStyle; + bool mCheckedBaseProto; + bool mKeyHandlersRegistered; +diff --git a/dom/xbl/nsXBLService.cpp b/dom/xbl/nsXBLService.cpp +index 2204520..978c6fc 100644 +--- a/dom/xbl/nsXBLService.cpp ++++ b/dom/xbl/nsXBLService.cpp +@@ -732,7 +732,8 @@ nsXBLService::GetBinding(nsIContent* aBoundElement, nsIURI* aURI, + if (!docInfo) + return NS_ERROR_FAILURE; + +- nsXBLPrototypeBinding* protoBinding = docInfo->GetPrototypeBinding(ref); ++ WeakPtr<nsXBLPrototypeBinding> protoBinding = ++ docInfo->GetPrototypeBinding(ref); + + if (!protoBinding) { + #ifdef DEBUG +@@ -783,7 +784,7 @@ nsXBLService::GetBinding(nsIContent* aBoundElement, nsIURI* aURI, + NS_ENSURE_SUCCESS(rv, rv); + + nsCOMPtr<nsIURI> baseBindingURI; +- nsXBLPrototypeBinding* baseProto = protoBinding->GetBasePrototype(); ++ WeakPtr<nsXBLPrototypeBinding> baseProto = protoBinding->GetBasePrototype(); + if (baseProto) { + baseBindingURI = baseProto->BindingURI(); + } +@@ -828,7 +829,6 @@ nsXBLService::GetBinding(nsIContent* aBoundElement, nsIURI* aURI, + + if (!aPeekOnly) { + // Make a new binding +- protoBinding = docInfo->GetPrototypeBinding(ref); + NS_ENSURE_STATE(protoBinding); + nsXBLBinding *newBinding = new nsXBLBinding(protoBinding); + +diff --git a/mfbt/WeakPtr.h b/mfbt/WeakPtr.h +index 6e5de43..22ba20e 100644 +--- a/mfbt/WeakPtr.h ++++ b/mfbt/WeakPtr.h +@@ -172,7 +172,13 @@ public: + + WeakPtr& operator=(T* aOther) + { +- return *this = aOther->SelfReferencingWeakPtr(); ++ if (aOther) { ++ *this = aOther->SelfReferencingWeakPtr(); ++ } else if (!mRef || mRef->get()) { ++ // Ensure that mRef is dereferenceable in the uninitialized state. ++ mRef = new WeakReference(nullptr); ++ } ++ return *this; + } + + MOZ_IMPLICIT WeakPtr(T* aOther) +-- +2.5.0 + diff --git a/gnu/packages/patches/icecat-CVE-2015-4513-pt03.patch b/gnu/packages/patches/icecat-CVE-2015-4513-pt03.patch new file mode 100644 index 0000000000..4f86629068 --- /dev/null +++ b/gnu/packages/patches/icecat-CVE-2015-4513-pt03.patch @@ -0,0 +1,48 @@ +From 88312d4d167aba886fdbd563afcfd5cc96a9d813 Mon Sep 17 00:00:00 2001 +From: Boris Zbarsky <bzbarsky@mit.edu> +Date: Fri, 11 Sep 2015 21:59:43 -0400 +Subject: [PATCH] Bug 1191942 - Make sure to not schedule + requestAnimationFrame callbacks if animations are paused. r=roc, a=ritu + +--HG-- +extra : source : ed8a6af1508ac68a28d017e26935e7a12dbda864 +extra : intermediate-source : 254e3cb723ed279f68b0c88ad30dc35b6a93ce84 +--- + dom/base/nsDocument.cpp | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +diff --git a/dom/base/nsDocument.cpp b/dom/base/nsDocument.cpp +index 47f611e..087501c 100644 +--- a/dom/base/nsDocument.cpp ++++ b/dom/base/nsDocument.cpp +@@ -3928,7 +3928,7 @@ void + nsDocument::DeleteShell() + { + mExternalResourceMap.HideViewers(); +- if (IsEventHandlingEnabled()) { ++ if (IsEventHandlingEnabled() && !AnimationsPaused()) { + RevokeAnimationFrameNotifications(); + } + +@@ -4687,7 +4687,7 @@ nsDocument::SetScriptGlobalObject(nsIScriptGlobalObject *aScriptGlobalObject) + // our layout history state now. + mLayoutHistoryState = GetLayoutHistoryState(); + +- if (mPresShell && !EventHandlingSuppressed()) { ++ if (mPresShell && !EventHandlingSuppressed() && !AnimationsPaused()) { + RevokeAnimationFrameNotifications(); + } + +@@ -10276,7 +10276,8 @@ nsIDocument::ScheduleFrameRequestCallback(const FrameRequestCallbackHolder& aCal + DebugOnly<FrameRequest*> request = + mFrameRequestCallbacks.AppendElement(FrameRequest(aCallback, newHandle)); + NS_ASSERTION(request, "This is supposed to be infallible!"); +- if (!alreadyRegistered && mPresShell && IsEventHandlingEnabled()) { ++ if (!alreadyRegistered && mPresShell && IsEventHandlingEnabled() && ++ !AnimationsPaused()) { + mPresShell->GetPresContext()->RefreshDriver()-> + ScheduleFrameRequestCallbacks(this); + } +-- +2.5.0 + diff --git a/gnu/packages/patches/icecat-CVE-2015-4513-pt04.patch b/gnu/packages/patches/icecat-CVE-2015-4513-pt04.patch new file mode 100644 index 0000000000..f6f3cd3585 --- /dev/null +++ b/gnu/packages/patches/icecat-CVE-2015-4513-pt04.patch @@ -0,0 +1,50 @@ +From 97bd3ada2a0ac6eff0e03e6eec8d2012af3bb57d Mon Sep 17 00:00:00 2001 +From: Jan de Mooij <jdemooij@mozilla.com> +Date: Mon, 28 Sep 2015 13:30:42 +0200 +Subject: [PATCH] Bug 1205707 part 1 - Clean up some is-TypedArrayObject code + in Ion. r=Waldo, a=sylvestre + +--- + js/src/jit/MCallOptimize.cpp | 19 +++++++++++++++++-- + 1 file changed, 17 insertions(+), 2 deletions(-) + +diff --git a/js/src/jit/MCallOptimize.cpp b/js/src/jit/MCallOptimize.cpp +index 7fdede8..2c6a533 100644 +--- a/js/src/jit/MCallOptimize.cpp ++++ b/js/src/jit/MCallOptimize.cpp +@@ -2122,6 +2122,19 @@ IonBuilder::inlineIsTypedArray(CallInfo& callInfo) + return InliningStatus_Inlined; + } + ++static bool ++IsTypedArrayObject(CompilerConstraintList* constraints, MDefinition* def) ++{ ++ MOZ_ASSERT(def->type() == MIRType_Object); ++ ++ TemporaryTypeSet* types = def->resultTypeSet(); ++ if (!types) ++ return false; ++ ++ return types->forAllClasses(constraints, IsTypedArrayClass) == ++ TemporaryTypeSet::ForAllResult::ALL_TRUE; ++} ++ + IonBuilder::InliningStatus + IonBuilder::inlineTypedArrayLength(CallInfo& callInfo) + { +@@ -2132,8 +2145,10 @@ IonBuilder::inlineTypedArrayLength(CallInfo& callInfo) + if (getInlineReturnType() != MIRType_Int32) + return InliningStatus_NotInlined; + +- // We assume that when calling this function we always +- // have a TypedArray. The native asserts that as well. ++ // Note that the argument we see here is not necessarily a typed array. ++ // If it's not, this call should be unreachable though. ++ if (!IsTypedArrayObject(constraints(), callInfo.getArg(0))) ++ return InliningStatus_NotInlined; + + MInstruction* length = addTypedArrayLength(callInfo.getArg(0)); + current->push(length); +-- +2.5.0 + diff --git a/gnu/packages/patches/icecat-CVE-2015-4513-pt05.patch b/gnu/packages/patches/icecat-CVE-2015-4513-pt05.patch new file mode 100644 index 0000000000..b25f2231a7 --- /dev/null +++ b/gnu/packages/patches/icecat-CVE-2015-4513-pt05.patch @@ -0,0 +1,25 @@ +From d91a58cb0094d0421439a915be0b4879a45d20d4 Mon Sep 17 00:00:00 2001 +From: Brian Hackett <bhackett1024@gmail.com> +Date: Mon, 12 Oct 2015 17:15:12 -0600 +Subject: [PATCH] Bug 1209471 - Fix group used for Array.concat result, + r=jandem. a=al + +--- + js/src/jsarray.cpp | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/js/src/jsarray.cpp b/js/src/jsarray.cpp +index 3d574d5..b4ff057 100644 +--- a/js/src/jsarray.cpp ++++ b/js/src/jsarray.cpp +@@ -2661,6 +2661,7 @@ js::array_concat(JSContext* cx, unsigned argc, Value* vp) + narr = NewDenseEmptyArray(cx); + if (!narr) + return false; ++ TryReuseArrayGroup(aobj, narr); + args.rval().setObject(*narr); + length = 0; + } +-- +2.5.0 + diff --git a/gnu/packages/patches/icecat-CVE-2015-4513-pt06.patch b/gnu/packages/patches/icecat-CVE-2015-4513-pt06.patch new file mode 100644 index 0000000000..33dbf68f2c --- /dev/null +++ b/gnu/packages/patches/icecat-CVE-2015-4513-pt06.patch @@ -0,0 +1,461 @@ +From 13b2b587c183e85618868752e05ec46bd5a0af86 Mon Sep 17 00:00:00 2001 +From: Jon Coppeard <jcoppeard@mozilla.com> +Date: Tue, 13 Oct 2015 11:09:12 +0200 +Subject: [PATCH] Bug 1208665 - r=Waldo a=abillings a=sylvestre + +--- + js/public/Utility.h | 49 +++++++++++++++++++++++++++++++++++++-------- + js/src/ds/LifoAlloc.h | 13 ++++++------ + js/src/jit/FixedList.h | 10 +++++---- + js/src/jit/JitAllocPolicy.h | 19 ++++++++++-------- + js/src/jit/LIR.cpp | 3 +-- + js/src/jit/MIRGenerator.h | 7 ++++--- + js/src/jit/MIRGraph.cpp | 2 +- + js/src/jsalloc.h | 14 ++++++++++--- + js/src/vm/MallocProvider.h | 39 ++++++++++++++++-------------------- + js/src/vm/Runtime.h | 10 +++++---- + 10 files changed, 105 insertions(+), 61 deletions(-) + +diff --git a/js/public/Utility.h b/js/public/Utility.h +index 40b5d90..6b750c3 100644 +--- a/js/public/Utility.h ++++ b/js/public/Utility.h +@@ -217,6 +217,36 @@ static inline char* js_strdup(const char* s) + + JS_DECLARE_NEW_METHODS(js_new, js_malloc, static MOZ_ALWAYS_INLINE) + ++namespace js { ++ ++/* ++ * Calculate the number of bytes needed to allocate |numElems| contiguous ++ * instances of type |T|. Return false if the calculation overflowed. ++ */ ++template <typename T> ++MOZ_WARN_UNUSED_RESULT inline bool ++CalculateAllocSize(size_t numElems, size_t* bytesOut) ++{ ++ *bytesOut = numElems * sizeof(T); ++ return (numElems & mozilla::tl::MulOverflowMask<sizeof(T)>::value) == 0; ++} ++ ++/* ++ * Calculate the number of bytes needed to allocate a single instance of type ++ * |T| followed by |numExtra| contiguous instances of type |Extra|. Return ++ * false if the calculation overflowed. ++ */ ++template <typename T, typename Extra> ++MOZ_WARN_UNUSED_RESULT inline bool ++CalculateAllocSizeWithExtra(size_t numExtra, size_t* bytesOut) ++{ ++ *bytesOut = sizeof(T) + numExtra * sizeof(Extra); ++ return (numExtra & mozilla::tl::MulOverflowMask<sizeof(Extra)>::value) == 0 && ++ *bytesOut >= sizeof(T); ++} ++ ++} /* namespace js */ ++ + template <class T> + static MOZ_ALWAYS_INLINE void + js_delete(T* p) +@@ -242,32 +272,34 @@ template <class T> + static MOZ_ALWAYS_INLINE T* + js_pod_malloc() + { +- return (T*)js_malloc(sizeof(T)); ++ return static_cast<T*>(js_malloc(sizeof(T))); + } + + template <class T> + static MOZ_ALWAYS_INLINE T* + js_pod_calloc() + { +- return (T*)js_calloc(sizeof(T)); ++ return static_cast<T*>(js_calloc(sizeof(T))); + } + + template <class T> + static MOZ_ALWAYS_INLINE T* + js_pod_malloc(size_t numElems) + { +- if (MOZ_UNLIKELY(numElems & mozilla::tl::MulOverflowMask<sizeof(T)>::value)) ++ size_t bytes; ++ if (MOZ_UNLIKELY(!js::CalculateAllocSize<T>(numElems, &bytes))) + return nullptr; +- return (T*)js_malloc(numElems * sizeof(T)); ++ return static_cast<T*>(js_malloc(bytes)); + } + + template <class T> + static MOZ_ALWAYS_INLINE T* + js_pod_calloc(size_t numElems) + { +- if (MOZ_UNLIKELY(numElems & mozilla::tl::MulOverflowMask<sizeof(T)>::value)) ++ size_t bytes; ++ if (MOZ_UNLIKELY(!js::CalculateAllocSize<T>(numElems, &bytes))) + return nullptr; +- return (T*)js_calloc(numElems * sizeof(T)); ++ return static_cast<T*>(js_calloc(bytes)); + } + + template <class T> +@@ -275,9 +307,10 @@ static MOZ_ALWAYS_INLINE T* + js_pod_realloc(T* prior, size_t oldSize, size_t newSize) + { + MOZ_ASSERT(!(oldSize & mozilla::tl::MulOverflowMask<sizeof(T)>::value)); +- if (MOZ_UNLIKELY(newSize & mozilla::tl::MulOverflowMask<sizeof(T)>::value)) ++ size_t bytes; ++ if (MOZ_UNLIKELY(!js::CalculateAllocSize<T>(newSize, &bytes))) + return nullptr; +- return (T*)js_realloc(prior, newSize * sizeof(T)); ++ return static_cast<T*>(js_realloc(prior, bytes)); + } + + namespace js { +diff --git a/js/src/ds/LifoAlloc.h b/js/src/ds/LifoAlloc.h +index 9dc68c1..35cdc72 100644 +--- a/js/src/ds/LifoAlloc.h ++++ b/js/src/ds/LifoAlloc.h +@@ -310,9 +310,10 @@ class LifoAlloc + // The caller is responsible for initialization. + template <typename T> + T* newArrayUninitialized(size_t count) { +- if (MOZ_UNLIKELY(count & mozilla::tl::MulOverflowMask<sizeof(T)>::value)) ++ size_t bytes; ++ if (MOZ_UNLIKELY(!CalculateAllocSize<T>(count, &bytes))) + return nullptr; +- return static_cast<T*>(alloc(sizeof(T) * count)); ++ return static_cast<T*>(alloc(bytes)); + } + + class Mark { +@@ -527,16 +528,16 @@ class LifoAllocPolicy + {} + template <typename T> + T* pod_malloc(size_t numElems) { +- if (MOZ_UNLIKELY(numElems & mozilla::tl::MulOverflowMask<sizeof(T)>::value)) ++ size_t bytes; ++ if (MOZ_UNLIKELY(!CalculateAllocSize<T>(numElems, &bytes))) + return nullptr; +- size_t bytes = numElems * sizeof(T); + void* p = fb == Fallible ? alloc_.alloc(bytes) : alloc_.allocInfallible(bytes); + return static_cast<T*>(p); + } + template <typename T> + T* pod_calloc(size_t numElems) { + T* p = pod_malloc<T>(numElems); +- if (fb == Fallible && !p) ++ if (MOZ_UNLIKELY(!p)) + return nullptr; + memset(p, 0, numElems * sizeof(T)); + return p; +@@ -544,7 +545,7 @@ class LifoAllocPolicy + template <typename T> + T* pod_realloc(T* p, size_t oldSize, size_t newSize) { + T* n = pod_malloc<T>(newSize); +- if (fb == Fallible && !n) ++ if (MOZ_UNLIKELY(!n)) + return nullptr; + MOZ_ASSERT(!(oldSize & mozilla::tl::MulOverflowMask<sizeof(T)>::value)); + memcpy(n, p, Min(oldSize * sizeof(T), newSize * sizeof(T))); +diff --git a/js/src/jit/FixedList.h b/js/src/jit/FixedList.h +index 9cea3a8..b6b37bb 100644 +--- a/js/src/jit/FixedList.h ++++ b/js/src/jit/FixedList.h +@@ -37,9 +37,10 @@ class FixedList + if (length == 0) + return true; + +- if (MOZ_UNLIKELY(length & mozilla::tl::MulOverflowMask<sizeof(T)>::value)) ++ size_t bytes; ++ if (MOZ_UNLIKELY(!CalculateAllocSize<T>(length, &bytes))) + return false; +- list_ = (T*)alloc.allocate(length * sizeof(T)); ++ list_ = (T*)alloc.allocate(bytes); + return list_ != nullptr; + } + +@@ -60,9 +61,10 @@ class FixedList + size_t newlength = length_ + num; + if (newlength < length_) + return false; +- if (MOZ_UNLIKELY(newlength & mozilla::tl::MulOverflowMask<sizeof(T)>::value)) ++ size_t bytes; ++ if (MOZ_UNLIKELY(!CalculateAllocSize<T>(newlength, &bytes))) + return false; +- T* list = (T*)alloc.allocate((length_ + num) * sizeof(T)); ++ T* list = (T*)alloc.allocate(bytes); + if (MOZ_UNLIKELY(!list)) + return false; + +diff --git a/js/src/jit/JitAllocPolicy.h b/js/src/jit/JitAllocPolicy.h +index 4bbd1a3..fca4b3f 100644 +--- a/js/src/jit/JitAllocPolicy.h ++++ b/js/src/jit/JitAllocPolicy.h +@@ -48,12 +48,13 @@ class TempAllocator + return p; + } + +- template <size_t ElemSize> +- void* allocateArray(size_t n) ++ template <typename T> ++ T* allocateArray(size_t n) + { +- if (MOZ_UNLIKELY(n & mozilla::tl::MulOverflowMask<ElemSize>::value)) ++ size_t bytes; ++ if (MOZ_UNLIKELY(!CalculateAllocSize<T>(n, &bytes))) + return nullptr; +- void* p = lifoScope_.alloc().alloc(n * ElemSize); ++ T* p = static_cast<T*>(lifoScope_.alloc().alloc(bytes)); + if (MOZ_UNLIKELY(!ensureBallast())) + return nullptr; + return p; +@@ -79,9 +80,10 @@ class JitAllocPolicy + {} + template <typename T> + T* pod_malloc(size_t numElems) { +- if (MOZ_UNLIKELY(numElems & mozilla::tl::MulOverflowMask<sizeof(T)>::value)) ++ size_t bytes; ++ if (MOZ_UNLIKELY(!CalculateAllocSize<T>(numElems, &bytes))) + return nullptr; +- return static_cast<T*>(alloc_.allocate(numElems * sizeof(T))); ++ return static_cast<T*>(alloc_.allocate(bytes)); + } + template <typename T> + T* pod_calloc(size_t numElems) { +@@ -112,9 +114,10 @@ class OldJitAllocPolicy + {} + template <typename T> + T* pod_malloc(size_t numElems) { +- if (MOZ_UNLIKELY(numElems & mozilla::tl::MulOverflowMask<sizeof(T)>::value)) ++ size_t bytes; ++ if (MOZ_UNLIKELY(!CalculateAllocSize<T>(numElems, &bytes))) + return nullptr; +- return static_cast<T*>(GetJitContext()->temp->allocate(numElems * sizeof(T))); ++ return static_cast<T*>(GetJitContext()->temp->allocate(bytes)); + } + void free_(void* p) { + } +diff --git a/js/src/jit/LIR.cpp b/js/src/jit/LIR.cpp +index 70a3fc0..a76e742 100644 +--- a/js/src/jit/LIR.cpp ++++ b/js/src/jit/LIR.cpp +@@ -105,8 +105,7 @@ LBlock::init(TempAllocator& alloc) + + int numPhis = (phi->type() == MIRType_Value) ? BOX_PIECES : 1; + for (int i = 0; i < numPhis; i++) { +- void* array = alloc.allocateArray<sizeof(LAllocation)>(numPreds); +- LAllocation* inputs = static_cast<LAllocation*>(array); ++ LAllocation* inputs = alloc.allocateArray<LAllocation>(numPreds); + if (!inputs) + return false; + +diff --git a/js/src/jit/MIRGenerator.h b/js/src/jit/MIRGenerator.h +index 01de27d..5e6b9ef 100644 +--- a/js/src/jit/MIRGenerator.h ++++ b/js/src/jit/MIRGenerator.h +@@ -60,10 +60,11 @@ class MIRGenerator + } + + template <typename T> +- T * allocate(size_t count = 1) { +- if (count & mozilla::tl::MulOverflowMask<sizeof(T)>::value) ++ T* allocate(size_t count = 1) { ++ size_t bytes; ++ if (MOZ_UNLIKELY(!CalculateAllocSize<T>(count, &bytes))) + return nullptr; +- return reinterpret_cast<T*>(alloc().allocate(sizeof(T) * count)); ++ return static_cast<T*>(alloc().allocate(bytes)); + } + + // Set an error state and prints a message. Returns false so errors can be +diff --git a/js/src/jit/MIRGraph.cpp b/js/src/jit/MIRGraph.cpp +index 5d000dca..4c5cf8e 100644 +--- a/js/src/jit/MIRGraph.cpp ++++ b/js/src/jit/MIRGraph.cpp +@@ -297,7 +297,7 @@ MBasicBlock::NewAsmJS(MIRGraph& graph, CompileInfo& info, MBasicBlock* pred, Kin + size_t nphis = block->stackPosition_; + + TempAllocator& alloc = graph.alloc(); +- MPhi* phis = (MPhi*)alloc.allocateArray<sizeof(MPhi)>(nphis); ++ MPhi* phis = alloc.allocateArray<MPhi>(nphis); + if (!phis) + return nullptr; + +diff --git a/js/src/jsalloc.h b/js/src/jsalloc.h +index ce11ade..e20fa5f2 100644 +--- a/js/src/jsalloc.h ++++ b/js/src/jsalloc.h +@@ -53,6 +53,14 @@ class TempAllocPolicy + */ + JS_FRIEND_API(void*) onOutOfMemory(void* p, size_t nbytes); + ++ template <typename T> ++ T* onOutOfMemoryTyped(void* p, size_t numElems) { ++ size_t bytes; ++ if (MOZ_UNLIKELY(!CalculateAllocSize<T>(numElems, &bytes))) ++ return nullptr; ++ return static_cast<T*>(onOutOfMemory(p, bytes)); ++ } ++ + public: + MOZ_IMPLICIT TempAllocPolicy(JSContext* cx) : cx_((ContextFriendFields*) cx) {} // :( + MOZ_IMPLICIT TempAllocPolicy(ContextFriendFields* cx) : cx_(cx) {} +@@ -61,7 +69,7 @@ class TempAllocPolicy + T* pod_malloc(size_t numElems) { + T* p = js_pod_malloc<T>(numElems); + if (MOZ_UNLIKELY(!p)) +- p = static_cast<T*>(onOutOfMemory(nullptr, numElems * sizeof(T))); ++ p = onOutOfMemoryTyped<T>(nullptr, numElems); + return p; + } + +@@ -69,7 +77,7 @@ class TempAllocPolicy + T* pod_calloc(size_t numElems) { + T* p = js_pod_calloc<T>(numElems); + if (MOZ_UNLIKELY(!p)) +- p = static_cast<T*>(onOutOfMemory(reinterpret_cast<void*>(1), numElems * sizeof(T))); ++ p = onOutOfMemoryTyped<T>(reinterpret_cast<void*>(1), numElems); + return p; + } + +@@ -77,7 +85,7 @@ class TempAllocPolicy + T* pod_realloc(T* prior, size_t oldSize, size_t newSize) { + T* p2 = js_pod_realloc<T>(prior, oldSize, newSize); + if (MOZ_UNLIKELY(!p2)) +- p2 = static_cast<T*>(onOutOfMemory(p2, newSize * sizeof(T))); ++ p2 = onOutOfMemoryTyped<T>(p2, newSize); + return p2; + } + +diff --git a/js/src/vm/MallocProvider.h b/js/src/vm/MallocProvider.h +index 1ea4ce2..f334eb1 100644 +--- a/js/src/vm/MallocProvider.h ++++ b/js/src/vm/MallocProvider.h +@@ -64,30 +64,27 @@ struct MallocProvider + client()->updateMallocCounter(numElems * sizeof(T)); + return p; + } +- if (numElems & mozilla::tl::MulOverflowMask<sizeof(T)>::value) { ++ size_t bytes; ++ if (MOZ_UNLIKELY(!CalculateAllocSize<T>(numElems, &bytes))) { + client()->reportAllocationOverflow(); + return nullptr; + } +- return (T*)client()->onOutOfMemory(nullptr, numElems * sizeof(T)); ++ return static_cast<T*>(client()->onOutOfMemory(nullptr, bytes)); + } + + template <class T, class U> + T* pod_malloc_with_extra(size_t numExtra) { +- if (MOZ_UNLIKELY(numExtra & mozilla::tl::MulOverflowMask<sizeof(U)>::value)) { ++ size_t bytes; ++ if (MOZ_UNLIKELY((!CalculateAllocSizeWithExtra<T, U>(numExtra, &bytes)))) { + client()->reportAllocationOverflow(); + return nullptr; + } +- size_t bytes = sizeof(T) + numExtra * sizeof(U); +- if (MOZ_UNLIKELY(bytes < sizeof(T))) { +- client()->reportAllocationOverflow(); +- return nullptr; +- } +- T* p = reinterpret_cast<T*>(js_pod_malloc<uint8_t>(bytes)); ++ T* p = static_cast<T*>(js_malloc(bytes)); + if (MOZ_LIKELY(p)) { + client()->updateMallocCounter(bytes); + return p; + } +- return (T*)client()->onOutOfMemory(nullptr, bytes); ++ return static_cast<T*>(client()->onOutOfMemory(nullptr, bytes)); + } + + template <class T> +@@ -108,30 +105,27 @@ struct MallocProvider + client()->updateMallocCounter(numElems * sizeof(T)); + return p; + } +- if (numElems & mozilla::tl::MulOverflowMask<sizeof(T)>::value) { ++ size_t bytes; ++ if (MOZ_UNLIKELY(!CalculateAllocSize<T>(numElems, &bytes))) { + client()->reportAllocationOverflow(); + return nullptr; + } +- return (T*)client()->onOutOfMemory(nullptr, numElems * sizeof(T)); ++ return static_cast<T*>(client()->onOutOfMemory(nullptr, bytes)); + } + + template <class T, class U> + T* pod_calloc_with_extra(size_t numExtra) { +- if (MOZ_UNLIKELY(numExtra & mozilla::tl::MulOverflowMask<sizeof(U)>::value)) { +- client()->reportAllocationOverflow(); +- return nullptr; +- } +- size_t bytes = sizeof(T) + numExtra * sizeof(U); +- if (MOZ_UNLIKELY(bytes < sizeof(T))) { ++ size_t bytes; ++ if (MOZ_UNLIKELY((!CalculateAllocSizeWithExtra<T, U>(numExtra, &bytes)))) { + client()->reportAllocationOverflow(); + return nullptr; + } +- T* p = reinterpret_cast<T*>(js_pod_calloc<uint8_t>(bytes)); ++ T* p = static_cast<T*>(js_calloc(bytes)); + if (MOZ_LIKELY(p)) { + client()->updateMallocCounter(bytes); + return p; + } +- return (T*)client()->onOutOfMemory(nullptr, bytes); ++ return static_cast<T*>(client()->onOutOfMemory(nullptr, bytes)); + } + + template <class T> +@@ -151,11 +145,12 @@ struct MallocProvider + client()->updateMallocCounter((newSize - oldSize) * sizeof(T)); + return p; + } +- if (newSize & mozilla::tl::MulOverflowMask<sizeof(T)>::value) { ++ size_t bytes; ++ if (MOZ_UNLIKELY(!CalculateAllocSize<T>(newSize, &bytes))) { + client()->reportAllocationOverflow(); + return nullptr; + } +- return (T*)client()->onOutOfMemory(prior, newSize * sizeof(T)); ++ return static_cast<T*>(client()->onOutOfMemory(prior, bytes)); + } + + JS_DECLARE_NEW_METHODS(new_, pod_malloc<uint8_t>, MOZ_ALWAYS_INLINE) +diff --git a/js/src/vm/Runtime.h b/js/src/vm/Runtime.h +index 90771d6..24c34d3 100644 +--- a/js/src/vm/Runtime.h ++++ b/js/src/vm/Runtime.h +@@ -1354,11 +1354,12 @@ struct JSRuntime : public JS::shadow::Runtime, + T* p = pod_calloc<T>(numElems); + if (MOZ_LIKELY(!!p)) + return p; +- if (numElems & mozilla::tl::MulOverflowMask<sizeof(T)>::value) { ++ size_t bytes; ++ if (MOZ_UNLIKELY(!js::CalculateAllocSize<T>(numElems, &bytes))) { + reportAllocationOverflow(); + return nullptr; + } +- return (T*)onOutOfMemoryCanGC(reinterpret_cast<void*>(1), numElems * sizeof(T)); ++ return static_cast<T*>(onOutOfMemoryCanGC(reinterpret_cast<void*>(1), bytes)); + } + + template <typename T> +@@ -1366,11 +1367,12 @@ struct JSRuntime : public JS::shadow::Runtime, + T* p2 = pod_realloc<T>(p, oldSize, newSize); + if (MOZ_LIKELY(!!p2)) + return p2; +- if (newSize & mozilla::tl::MulOverflowMask<sizeof(T)>::value) { ++ size_t bytes; ++ if (MOZ_UNLIKELY(!js::CalculateAllocSize<T>(newSize, &bytes))) { + reportAllocationOverflow(); + return nullptr; + } +- return (T*)onOutOfMemoryCanGC(p, newSize * sizeof(T)); ++ return static_cast<T*>(onOutOfMemoryCanGC(p, bytes)); + } + + /* +-- +2.5.0 + diff --git a/gnu/packages/patches/icecat-CVE-2015-4513-pt07.patch b/gnu/packages/patches/icecat-CVE-2015-4513-pt07.patch new file mode 100644 index 0000000000..042188ee9c --- /dev/null +++ b/gnu/packages/patches/icecat-CVE-2015-4513-pt07.patch @@ -0,0 +1,93 @@ +From 182bcb255e28b536e2d2a1208fde3324a994dbc1 Mon Sep 17 00:00:00 2001 +From: Benjamin Bouvier <benj@benj.me> +Date: Tue, 13 Oct 2015 19:22:47 +0200 +Subject: [PATCH] Bug 1107011: Propagate recovered on bailout flags when + converting float32 to doubles; r=nbp, a=ritu, a=abillings + +--HG-- +extra : commitid : 51QGWZ84Mqx +extra : amend_source : 48bf9cd43b37c95d61dd4d11b184c307e84a56b5 +extra : histedit_source : ae510534e698e680103f508e0029d75f03f4e6e0%2C1d8eb51e63dd3a52898892976f50747cc3907e65 +--- + js/src/jit-test/tests/ion/bug1107011-1.js | 17 +++++++++++++++++ + js/src/jit-test/tests/ion/bug1107011-2.js | 12 ++++++++++++ + js/src/jit/TypePolicy.cpp | 2 ++ + js/src/jit/ValueNumbering.cpp | 6 ++++++ + 4 files changed, 37 insertions(+) + create mode 100644 js/src/jit-test/tests/ion/bug1107011-1.js + create mode 100644 js/src/jit-test/tests/ion/bug1107011-2.js + +diff --git a/js/src/jit-test/tests/ion/bug1107011-1.js b/js/src/jit-test/tests/ion/bug1107011-1.js +new file mode 100644 +index 0000000..458d7dd +--- /dev/null ++++ b/js/src/jit-test/tests/ion/bug1107011-1.js +@@ -0,0 +1,17 @@ ++var f32 = new Float32Array(32); ++function f(n) { ++ var x; ++ if (n > 10000) { ++ x = 4.5; ++ } else { ++ x = f32[0]; ++ } ++ f32[0] = (function() { ++ for(var f=0;f<4;++f) { ++ x=1; ++ } ++ })() < x; ++} ++for (var n = 0; n < 100; n++) ++ f(n); ++ +diff --git a/js/src/jit-test/tests/ion/bug1107011-2.js b/js/src/jit-test/tests/ion/bug1107011-2.js +new file mode 100644 +index 0000000..d59685e +--- /dev/null ++++ b/js/src/jit-test/tests/ion/bug1107011-2.js +@@ -0,0 +1,12 @@ ++function foo() { ++ var x = 0, y = 0, a = new Float32Array(1); ++ function bar() { ++ x = y; ++ y = a[0]; ++ } ++ for (var i = 0; i < 1000; i++) { ++ bar(); ++ } ++} ++for (var i=0; i < 50; i++) ++ foo(); +diff --git a/js/src/jit/TypePolicy.cpp b/js/src/jit/TypePolicy.cpp +index 4cea638..2510d50 100644 +--- a/js/src/jit/TypePolicy.cpp ++++ b/js/src/jit/TypePolicy.cpp +@@ -22,6 +22,8 @@ EnsureOperandNotFloat32(TempAllocator& alloc, MInstruction* def, unsigned op) + if (in->type() == MIRType_Float32) { + MToDouble* replace = MToDouble::New(alloc, in); + def->block()->insertBefore(def, replace); ++ if (def->isRecoveredOnBailout()) ++ replace->setRecoveredOnBailout(); + def->replaceOperand(op, replace); + } + } +diff --git a/js/src/jit/ValueNumbering.cpp b/js/src/jit/ValueNumbering.cpp +index da3e692..eb367e1 100644 +--- a/js/src/jit/ValueNumbering.cpp ++++ b/js/src/jit/ValueNumbering.cpp +@@ -726,6 +726,12 @@ ValueNumberer::visitDefinition(MDefinition* def) + return true; + } + ++ // Skip optimizations on instructions which are recovered on bailout, to ++ // avoid mixing instructions which are recovered on bailouts with ++ // instructions which are not. ++ if (def->isRecoveredOnBailout()) ++ return true; ++ + // If this instruction has a dependency() into an unreachable block, we'll + // need to update AliasAnalysis. + MInstruction* dep = def->dependency(); +-- +2.5.0 + diff --git a/gnu/packages/patches/icecat-CVE-2015-4513-pt08.patch b/gnu/packages/patches/icecat-CVE-2015-4513-pt08.patch new file mode 100644 index 0000000000..6a16b07497 --- /dev/null +++ b/gnu/packages/patches/icecat-CVE-2015-4513-pt08.patch @@ -0,0 +1,41 @@ +From 544bc596ac085ee1adc0b3d7ea793bc37d747ce2 Mon Sep 17 00:00:00 2001 +From: Carsten Book <cbook@mozilla.com> +Date: Mon, 19 Oct 2015 08:49:46 +0200 +Subject: [PATCH] Bug 1213979 - h2 paket formats. r=hurley, a=al + +--HG-- +extra : source : 551a28778624d4aff67b698952b1b3e011fc21f7 +extra : intermediate-source : ed67ac61d1c0e4a23888abe3abd3f4636757e038 +--- + netwerk/protocol/http/Http2Stream.cpp | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/netwerk/protocol/http/Http2Stream.cpp b/netwerk/protocol/http/Http2Stream.cpp +index 38fc025..340eccf 100644 +--- a/netwerk/protocol/http/Http2Stream.cpp ++++ b/netwerk/protocol/http/Http2Stream.cpp +@@ -629,9 +629,9 @@ Http2Stream::AdjustInitialWindow() + return; + } + +- uint8_t *packet = mTxInlineFrame.get() + mTxInlineFrameUsed; + EnsureBuffer(mTxInlineFrame, mTxInlineFrameUsed + Http2Session::kFrameHeaderBytes + 4, + mTxInlineFrameUsed, mTxInlineFrameSize); ++ uint8_t *packet = mTxInlineFrame.get() + mTxInlineFrameUsed; + mTxInlineFrameUsed += Http2Session::kFrameHeaderBytes + 4; + + mSession->CreateFrameHeader(packet, 4, +@@ -661,9 +661,9 @@ Http2Stream::AdjustPushedPriority() + if (mPushSource->RecvdFin() || mPushSource->RecvdReset()) + return; + +- uint8_t *packet = mTxInlineFrame.get() + mTxInlineFrameUsed; + EnsureBuffer(mTxInlineFrame, mTxInlineFrameUsed + Http2Session::kFrameHeaderBytes + 5, + mTxInlineFrameUsed, mTxInlineFrameSize); ++ uint8_t *packet = mTxInlineFrame.get() + mTxInlineFrameUsed; + mTxInlineFrameUsed += Http2Session::kFrameHeaderBytes + 5; + + mSession->CreateFrameHeader(packet, 5, +-- +2.5.0 + diff --git a/gnu/packages/patches/icecat-CVE-2015-4513-pt09.patch b/gnu/packages/patches/icecat-CVE-2015-4513-pt09.patch new file mode 100644 index 0000000000..687eb0af76 --- /dev/null +++ b/gnu/packages/patches/icecat-CVE-2015-4513-pt09.patch @@ -0,0 +1,65 @@ +From ef6298177a8390c01f5084ba89a808015a0b9473 Mon Sep 17 00:00:00 2001 +From: Gerald Squelart <gsquelart@mozilla.com> +Date: Thu, 22 Oct 2015 10:00:12 +0200 +Subject: [PATCH] Bug 1204580 - Check box ranges for overflow - r=rillian, a=al + +--- + media/libstagefright/binding/Box.cpp | 21 +++++++++++++++++++-- + 1 file changed, 19 insertions(+), 2 deletions(-) + +diff --git a/media/libstagefright/binding/Box.cpp b/media/libstagefright/binding/Box.cpp +index 71c79ed..2558be0 100644 +--- a/media/libstagefright/binding/Box.cpp ++++ b/media/libstagefright/binding/Box.cpp +@@ -40,6 +40,11 @@ Box::Box(BoxContext* aContext, uint64_t aOffset, const Box* aParent) + : mContext(aContext), mParent(aParent) + { + uint8_t header[8]; ++ ++ if (aOffset > INT64_MAX - sizeof(header)) { ++ return; ++ } ++ + MediaByteRange headerRange(aOffset, aOffset + sizeof(header)); + if (mParent && !mParent->mRange.Contains(headerRange)) { + return; +@@ -67,11 +72,14 @@ Box::Box(BoxContext* aContext, uint64_t aOffset, const Box* aParent) + uint64_t size = BigEndian::readUint32(header); + if (size == 1) { + uint8_t bigLength[8]; ++ if (aOffset > INT64_MAX - sizeof(header) - sizeof(bigLength)) { ++ return; ++ } + MediaByteRange bigLengthRange(headerRange.mEnd, + headerRange.mEnd + sizeof(bigLength)); + if ((mParent && !mParent->mRange.Contains(bigLengthRange)) || + !byteRange->Contains(bigLengthRange) || +- !mContext->mSource->CachedReadAt(aOffset, bigLength, ++ !mContext->mSource->CachedReadAt(aOffset + sizeof(header), bigLength, + sizeof(bigLength), &bytes) || + bytes != sizeof(bigLength)) { + return; +@@ -82,10 +90,19 @@ Box::Box(BoxContext* aContext, uint64_t aOffset, const Box* aParent) + mBodyOffset = headerRange.mEnd; + } + ++ if (size > INT64_MAX) { ++ return; ++ } ++ int64_t end = static_cast<int64_t>(aOffset) + static_cast<int64_t>(size); ++ if (end < static_cast<int64_t>(aOffset)) { ++ // Overflowed. ++ return; ++ } ++ + mType = BigEndian::readUint32(&header[4]); + mChildOffset = mBodyOffset + BoxOffset(mType); + +- MediaByteRange boxRange(aOffset, aOffset + size); ++ MediaByteRange boxRange(aOffset, end); + if (mChildOffset > boxRange.mEnd || + (mParent && !mParent->mRange.Contains(boxRange)) || + !byteRange->Contains(boxRange)) { +-- +2.5.0 + diff --git a/gnu/packages/patches/icecat-CVE-2015-4513-pt10.patch b/gnu/packages/patches/icecat-CVE-2015-4513-pt10.patch new file mode 100644 index 0000000000..43dd17786f --- /dev/null +++ b/gnu/packages/patches/icecat-CVE-2015-4513-pt10.patch @@ -0,0 +1,110 @@ +From 7b6c571182661cfffa0987c1a88a2cb5a3230bcd Mon Sep 17 00:00:00 2001 +From: Georg Fritzsche <georg.fritzsche@googlemail.com> +Date: Tue, 18 Aug 2015 19:21:40 +0200 +Subject: [PATCH] Bug 1193038 - Purposely leak StatisticsReport object and + suppress the leak report. r=glandium,mccr8,njn, a=lizzard + +--HG-- +extra : source : 346b9ee524d1a704ea953ef16237f3d0c7ee56d1 +extra : intermediate-source : 48b17faad125691454ebba9bdef0a5def9128f11 +--- + build/valgrind/cross-architecture.sup | 9 +++++++++ + toolkit/xre/nsAppRunner.cpp | 22 +++++++++++++++------- + 2 files changed, 24 insertions(+), 7 deletions(-) + +diff --git a/build/valgrind/cross-architecture.sup b/build/valgrind/cross-architecture.sup +index 9215d3b..1e9d7ab 100644 +--- a/build/valgrind/cross-architecture.sup ++++ b/build/valgrind/cross-architecture.sup +@@ -34,6 +34,15 @@ + fun:_ZN13CrashReporter14SetupExtraDataEP7nsIFileRK19nsACString_internal + ... + } ++{ ++ We purposely leak the StatisticsReporter object ++ Memcheck:Leak ++ fun:malloc ++ fun:moz_xmalloc ++ fun:operator new ++ fun:_Z21XRE_CreateStatsObjectv ++ ... ++} + + #################################### + # Leaks in third party libraries # +diff --git a/toolkit/xre/nsAppRunner.cpp b/toolkit/xre/nsAppRunner.cpp +index 5334a05..037aeac 100644 +--- a/toolkit/xre/nsAppRunner.cpp ++++ b/toolkit/xre/nsAppRunner.cpp +@@ -20,6 +20,7 @@ + #include "mozilla/Poison.h" + #include "mozilla/Preferences.h" + #include "mozilla/Telemetry.h" ++#include "mozilla/MemoryChecking.h" + + #include "nsAppRunner.h" + #include "mozilla/AppData.h" +@@ -3004,7 +3005,6 @@ public: + + ~XREMain() { + mScopedXPCOM = nullptr; +- mStatisticsRecorder = nullptr; + mAppData = nullptr; + } + +@@ -3023,7 +3023,6 @@ public: + #endif + + UniquePtr<ScopedXPCOMStartup> mScopedXPCOM; +- UniquePtr<base::StatisticsRecorder> mStatisticsRecorder; + nsAutoPtr<mozilla::ScopedAppData> mAppData; + + nsXREDirProvider mDirProvider; +@@ -4268,10 +4267,6 @@ XREMain::XRE_main(int argc, char* argv[], const nsXREAppData* aAppData) + + NS_ENSURE_TRUE(aAppData, 2); + +- // A initializer to initialize histogram collection, a chromium +- // thing used by Telemetry. +- mStatisticsRecorder = MakeUnique<base::StatisticsRecorder>(); +- + mAppData = new ScopedAppData(aAppData); + if (!mAppData) + return 1; +@@ -4345,7 +4340,6 @@ XREMain::XRE_main(int argc, char* argv[], const nsXREAppData* aAppData) + } + + mScopedXPCOM = nullptr; +- mStatisticsRecorder = nullptr; + + // unlock the profile after ScopedXPCOMStartup object (xpcom) + // has gone out of scope. see bug #386739 for more details +@@ -4531,11 +4525,25 @@ XRE_StopLateWriteChecks(void) { + mozilla::StopLateWriteChecks(); + } + ++// Separate stub function to let us specifically suppress it in Valgrind ++void ++XRE_CreateStatsObject() ++{ ++ // A initializer to initialize histogram collection, a chromium ++ // thing used by Telemetry (and effectively a global; it's all static). ++ // Note: purposely leaked ++ base::StatisticsRecorder* statistics_recorder = new base::StatisticsRecorder(); ++ MOZ_LSAN_INTENTIONALLY_LEAK_OBJECT(statistics_recorder); ++ unused << statistics_recorder; ++} ++ + int + XRE_main(int argc, char* argv[], const nsXREAppData* aAppData, uint32_t aFlags) + { + #if !defined(MOZ_METRO) || !defined(XP_WIN) + XREMain main; ++ ++ XRE_CreateStatsObject(); + int result = main.XRE_main(argc, argv, aAppData); + mozilla::RecordShutdownEndTimeStamp(); + return result; +-- +2.5.0 + diff --git a/gnu/packages/patches/icecat-CVE-2015-4513-pt11.patch b/gnu/packages/patches/icecat-CVE-2015-4513-pt11.patch new file mode 100644 index 0000000000..c4b326b9ed --- /dev/null +++ b/gnu/packages/patches/icecat-CVE-2015-4513-pt11.patch @@ -0,0 +1,42 @@ +From 72185a2795d4627203970e3c17fd9b3a6944edc6 Mon Sep 17 00:00:00 2001 +From: "Nicolas B. Pierron" <nicolas.b.pierron@mozilla.com> +Date: Thu, 15 Oct 2015 10:57:39 +0200 +Subject: [PATCH] Bug 1204700 - ARM: Use a different scratch register for + store32. r=sstangl, a=lizzard + +--HG-- +extra : commitid : 8itRSfm5tEh +extra : source : ebafbc7c1a870499159cdd2ee91573f1b52c728a +--- + js/src/jit/arm/MacroAssembler-arm.cpp | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/js/src/jit/arm/MacroAssembler-arm.cpp b/js/src/jit/arm/MacroAssembler-arm.cpp +index 7b8c06e..c8030bb 100644 +--- a/js/src/jit/arm/MacroAssembler-arm.cpp ++++ b/js/src/jit/arm/MacroAssembler-arm.cpp +@@ -2487,8 +2487,8 @@ MacroAssemblerARMCompat::store32(Imm32 src, const Address& address) + void + MacroAssemblerARMCompat::store32(Imm32 imm, const BaseIndex& dest) + { +- ma_mov(imm, secondScratchReg_); +- store32(secondScratchReg_, dest); ++ ma_mov(imm, ScratchRegister); ++ store32(ScratchRegister, dest); + } + + void +@@ -2498,8 +2498,8 @@ MacroAssemblerARMCompat::store32(Register src, const BaseIndex& dest) + uint32_t scale = Imm32::ShiftOf(dest.scale).value; + + if (dest.offset != 0) { +- ma_add(base, Imm32(dest.offset), ScratchRegister); +- base = ScratchRegister; ++ ma_add(base, Imm32(dest.offset), secondScratchReg_); ++ base = secondScratchReg_; + } + ma_str(src, DTRAddr(base, DtrRegImmShift(dest.index, LSL, scale))); + } +-- +2.5.0 + diff --git a/gnu/packages/patches/icecat-CVE-2015-7188.patch b/gnu/packages/patches/icecat-CVE-2015-7188.patch new file mode 100644 index 0000000000..15e26e3a6e --- /dev/null +++ b/gnu/packages/patches/icecat-CVE-2015-7188.patch @@ -0,0 +1,143 @@ +From 23e5bd6ffab4b6fa17a92d0bc58fbd185e9a7e6e Mon Sep 17 00:00:00 2001 +From: Valentin Gosu <valentin.gosu@gmail.com> +Date: Tue, 13 Oct 2015 11:10:26 +0200 +Subject: [PATCH] Bug 1199430 - Reject hostnames containing @. r=mcmanus, a=al + +--- + docshell/test/unit/test_nsDefaultURIFixup_info.js | 16 ++++++------ + netwerk/base/nsStandardURL.cpp | 30 ++++++++++++++--------- + netwerk/base/nsStandardURL.h | 2 +- + 3 files changed, 27 insertions(+), 21 deletions(-) + +diff --git a/docshell/test/unit/test_nsDefaultURIFixup_info.js b/docshell/test/unit/test_nsDefaultURIFixup_info.js +index b178ea9..dbb55c6 100644 +--- a/docshell/test/unit/test_nsDefaultURIFixup_info.js ++++ b/docshell/test/unit/test_nsDefaultURIFixup_info.js +@@ -199,12 +199,10 @@ let testcases = [ { + protocolChange: true + }, { + input: "[::1][100", +- fixedURI: "http://[::1][100/", +- alternateURI: "http://[::1][100/", ++ fixedURI: null, ++ alternateURI: null, + keywordLookup: true, +- protocolChange: true, +- affectedByWhitelist: true, +- affectedByDNSForSingleHosts: true, ++ protocolChange: true + }, { + input: "[::1]]", + keywordLookup: true, +@@ -514,15 +512,15 @@ if (Services.appinfo.OS.toLowerCase().startsWith("win")) { + input: "//mozilla", + fixedURI: "file:////mozilla", + protocolChange: true, +- }); ++ }); // \ is an invalid character in the hostname until bug 652186 is implemented + testcases.push({ + input: "mozilla\\", +- fixedURI: "http://mozilla\\/", +- alternateURI: "http://www.mozilla/", ++ // fixedURI: "http://mozilla\\/", ++ // alternateURI: "http://www.mozilla/", + keywordLookup: true, + protocolChange: true, + affectedByWhitelist: true, +- affectedByDNSForSingleHosts: true, ++ // affectedByDNSForSingleHosts: true, + }); + } + +diff --git a/netwerk/base/nsStandardURL.cpp b/netwerk/base/nsStandardURL.cpp +index f5f516f..cff90fc 100644 +--- a/netwerk/base/nsStandardURL.cpp ++++ b/netwerk/base/nsStandardURL.cpp +@@ -427,14 +427,16 @@ nsStandardURL::NormalizeIDN(const nsCSubstring &host, nsCString &result) + } + + bool +-nsStandardURL::ValidIPv6orHostname(const char *host) ++nsStandardURL::ValidIPv6orHostname(const char *host, uint32_t length) + { +- if (!host || !*host) { +- // Should not be NULL or empty string ++ if (!host) { + return false; + } + +- int32_t length = strlen(host); ++ if (length != strlen(host)) { ++ // Embedded null ++ return false; ++ } + + bool openBracket = host[0] == '['; + bool closeBracket = host[length - 1] == ']'; +@@ -448,8 +450,9 @@ nsStandardURL::ValidIPv6orHostname(const char *host) + return false; + } + +- if (PL_strchr(host, ':')) { +- // Hostnames should not contain a colon ++ const char *end = host + length; ++ if (end != net_FindCharInSet(host, end, "\t\n\v\f\r #/:?@[\\]")) { ++ // % is allowed because we don't do hostname percent decoding yet. + return false; + } + +@@ -587,6 +590,11 @@ nsStandardURL::BuildNormalizedSpec(const char *spec) + approxLen += encHost.Length(); + else + approxLen += mHost.mLen; ++ ++ if ((useEncHost && !ValidIPv6orHostname(encHost.BeginReading(), encHost.Length())) || ++ (!useEncHost && !ValidIPv6orHostname(tempHost.BeginReading(), tempHost.Length()))) { ++ return NS_ERROR_MALFORMED_URI; ++ } + } + + // +@@ -1580,14 +1588,10 @@ nsStandardURL::SetHost(const nsACString &input) + if (strchr(host, ' ')) + return NS_ERROR_MALFORMED_URI; + +- if (!ValidIPv6orHostname(host)) { +- return NS_ERROR_MALFORMED_URI; +- } +- + InvalidateCache(); + mHostEncoding = eEncoding_ASCII; + +- int32_t len; ++ uint32_t len; + nsAutoCString hostBuf; + if (NormalizeIDN(flat, hostBuf)) { + host = hostBuf.get(); +@@ -1596,6 +1600,10 @@ nsStandardURL::SetHost(const nsACString &input) + else + len = flat.Length(); + ++ if (!ValidIPv6orHostname(host, len)) { ++ return NS_ERROR_MALFORMED_URI; ++ } ++ + if (mHost.mLen < 0) { + int port_length = 0; + if (mPort != -1) { +diff --git a/netwerk/base/nsStandardURL.h b/netwerk/base/nsStandardURL.h +index 179a618..c56426e 100644 +--- a/netwerk/base/nsStandardURL.h ++++ b/netwerk/base/nsStandardURL.h +@@ -173,7 +173,7 @@ private: + void Clear(); + void InvalidateCache(bool invalidateCachedFile = true); + +- bool ValidIPv6orHostname(const char *host); ++ bool ValidIPv6orHostname(const char *host, uint32_t aLen); + bool NormalizeIDN(const nsCSubstring &host, nsCString &result); + void CoalescePath(netCoalesceFlags coalesceFlag, char *path); + +-- +2.5.0 + diff --git a/gnu/packages/patches/icecat-CVE-2015-7189.patch b/gnu/packages/patches/icecat-CVE-2015-7189.patch new file mode 100644 index 0000000000..329d1b6f1f --- /dev/null +++ b/gnu/packages/patches/icecat-CVE-2015-7189.patch @@ -0,0 +1,143 @@ +From 377e1cefec0fcf230caafb97b4414c835d27c7fe Mon Sep 17 00:00:00 2001 +From: Milan Sreckovic <milan@mozilla.com> +Date: Fri, 2 Oct 2015 09:18:26 +0200 +Subject: [PATCH] Bug 1205900 - Compare context and canvas element sizes before + extracting the data. r=gwright, a=al + +--HG-- +extra : source : f6c99c8baa9b0b6a34d6791e5d4031a2de8f2087 +--- + dom/canvas/CanvasRenderingContext2D.cpp | 2 -- + dom/canvas/CanvasRenderingContext2D.h | 7 +++---- + dom/canvas/WebGLContext.cpp | 2 -- + dom/canvas/WebGLContext.h | 3 +-- + dom/canvas/nsICanvasRenderingContextInternal.h | 8 +++----- + dom/html/HTMLCanvasElement.cpp | 13 +++++++------ + 6 files changed, 14 insertions(+), 21 deletions(-) + +diff --git a/dom/canvas/CanvasRenderingContext2D.cpp b/dom/canvas/CanvasRenderingContext2D.cpp +index d9eaf99..a06fbce 100644 +--- a/dom/canvas/CanvasRenderingContext2D.cpp ++++ b/dom/canvas/CanvasRenderingContext2D.cpp +@@ -1418,7 +1418,6 @@ CanvasRenderingContext2D::EnsureTarget(RenderingMode aRenderingMode) + return mode; + } + +-#ifdef DEBUG + int32_t + CanvasRenderingContext2D::GetWidth() const + { +@@ -1430,7 +1429,6 @@ CanvasRenderingContext2D::GetHeight() const + { + return mHeight; + } +-#endif + + NS_IMETHODIMP + CanvasRenderingContext2D::SetDimensions(int32_t width, int32_t height) +diff --git a/dom/canvas/CanvasRenderingContext2D.h b/dom/canvas/CanvasRenderingContext2D.h +index af29c78..e853987 100644 +--- a/dom/canvas/CanvasRenderingContext2D.h ++++ b/dom/canvas/CanvasRenderingContext2D.h +@@ -481,10 +481,9 @@ public: + + nsresult Redraw(); + +-#ifdef DEBUG +- virtual int32_t GetWidth() const override; +- virtual int32_t GetHeight() const override; +-#endif ++ virtual int32_t GetWidth() const override; ++ virtual int32_t GetHeight() const override; ++ + // nsICanvasRenderingContextInternal + /** + * Gets the pres shell from either the canvas element or the doc shell +diff --git a/dom/canvas/WebGLContext.cpp b/dom/canvas/WebGLContext.cpp +index 1c22c27..f2a620a 100644 +--- a/dom/canvas/WebGLContext.cpp ++++ b/dom/canvas/WebGLContext.cpp +@@ -463,7 +463,6 @@ WebGLContext::SetContextOptions(JSContext* cx, JS::Handle<JS::Value> options) + return NS_OK; + } + +-#ifdef DEBUG + int32_t + WebGLContext::GetWidth() const + { +@@ -475,7 +474,6 @@ WebGLContext::GetHeight() const + { + return mHeight; + } +-#endif + + /* So there are a number of points of failure here. We might fail based + * on EGL vs. WGL, or we might fail to alloc a too-large size, or we +diff --git a/dom/canvas/WebGLContext.h b/dom/canvas/WebGLContext.h +index 63c4091..210f341 100644 +--- a/dom/canvas/WebGLContext.h ++++ b/dom/canvas/WebGLContext.h +@@ -202,10 +202,9 @@ public: + NS_DECL_NSIDOMWEBGLRENDERINGCONTEXT + + // nsICanvasRenderingContextInternal +-#ifdef DEBUG + virtual int32_t GetWidth() const override; + virtual int32_t GetHeight() const override; +-#endif ++ + NS_IMETHOD SetDimensions(int32_t width, int32_t height) override; + NS_IMETHOD InitializeWithSurface(nsIDocShell*, gfxASurface*, int32_t, + int32_t) override +diff --git a/dom/canvas/nsICanvasRenderingContextInternal.h b/dom/canvas/nsICanvasRenderingContextInternal.h +index 3b1120f..fb1ef7c 100644 +--- a/dom/canvas/nsICanvasRenderingContextInternal.h ++++ b/dom/canvas/nsICanvasRenderingContextInternal.h +@@ -81,11 +81,9 @@ public: + return mCanvasElement; + } + +-#ifdef DEBUG +- // Useful for testing +- virtual int32_t GetWidth() const = 0; +- virtual int32_t GetHeight() const = 0; +-#endif ++ // Dimensions of the canvas, in pixels. ++ virtual int32_t GetWidth() const = 0; ++ virtual int32_t GetHeight() const = 0; + + // Sets the dimensions of the canvas, in pixels. Called + // whenever the size of the element changes. +diff --git a/dom/html/HTMLCanvasElement.cpp b/dom/html/HTMLCanvasElement.cpp +index f326662..68649f5 100644 +--- a/dom/html/HTMLCanvasElement.cpp ++++ b/dom/html/HTMLCanvasElement.cpp +@@ -526,18 +526,19 @@ HTMLCanvasElement::ToBlob(JSContext* aCx, + return; + } + +-#ifdef DEBUG + if (mCurrentContext) { + // We disallow canvases of width or height zero, and set them to 1, so + // we will have a discrepancy with the sizes of the canvas and the context. + // That discrepancy is OK, the rest are not. + nsIntSize elementSize = GetWidthHeight(); +- MOZ_ASSERT(elementSize.width == mCurrentContext->GetWidth() || +- (elementSize.width == 0 && mCurrentContext->GetWidth() == 1)); +- MOZ_ASSERT(elementSize.height == mCurrentContext->GetHeight() || +- (elementSize.height == 0 && mCurrentContext->GetHeight() == 1)); ++ if ((elementSize.width != mCurrentContext->GetWidth() && ++ (elementSize.width != 0 || mCurrentContext->GetWidth() != 1)) || ++ (elementSize.height != mCurrentContext->GetHeight() && ++ (elementSize.height != 0 || mCurrentContext->GetHeight() != 1))) { ++ aRv.Throw(NS_ERROR_FAILURE); ++ return; ++ } + } +-#endif + + uint8_t* imageBuffer = nullptr; + int32_t format = 0; +-- +2.5.0 + diff --git a/gnu/packages/patches/icecat-CVE-2015-7193.patch b/gnu/packages/patches/icecat-CVE-2015-7193.patch new file mode 100644 index 0000000000..798799de9f --- /dev/null +++ b/gnu/packages/patches/icecat-CVE-2015-7193.patch @@ -0,0 +1,397 @@ +From d135e3b3c48811c577e1632a41c5c50bc55c035c Mon Sep 17 00:00:00 2001 +From: Ehsan Akhgari <ehsan@mozilla.com> +Date: Tue, 20 Oct 2015 11:40:12 +0200 +Subject: [PATCH] Bug 1210302 - Add a NS_ParseRequestContentType API; ba=al, + r=mcmanus, r=sicking, a=al + +--HG-- +extra : amend_source : d93021b626709b03f6499029dc3d1813cccba386 +--- + docshell/base/nsDocShell.cpp | 2 +- + dom/base/Navigator.cpp | 4 +-- + dom/base/nsContentUtils.cpp | 2 +- + dom/html/nsHTMLDocument.cpp | 2 +- + dom/manifest/ManifestProcessor.jsm | 6 ++-- + netwerk/base/moz.build | 1 + + netwerk/base/nsINetUtil_ESR_38.idl | 14 +++++++++ + netwerk/base/nsIOService.cpp | 12 ++++++++ + netwerk/base/nsIOService.h | 3 ++ + netwerk/base/nsNetUtil.h | 21 +++++++++++++ + netwerk/base/nsURLHelper.cpp | 60 +++++++++++++++++++++++++++++++++++--- + netwerk/base/nsURLHelper.h | 32 +++++++++++++++----- + 12 files changed, 139 insertions(+), 20 deletions(-) + create mode 100644 netwerk/base/nsINetUtil_ESR_38.idl + +diff --git a/docshell/base/nsDocShell.cpp b/docshell/base/nsDocShell.cpp +index bcc205c..4fc7c34 100644 +--- a/docshell/base/nsDocShell.cpp ++++ b/docshell/base/nsDocShell.cpp +@@ -13519,7 +13519,7 @@ nsDocShell::OnLinkClickSync(nsIContent* aContent, + anchor->GetType(typeHint); + NS_ConvertUTF16toUTF8 utf8Hint(typeHint); + nsAutoCString type, dummy; +- NS_ParseContentType(utf8Hint, type, dummy); ++ NS_ParseRequestContentType(utf8Hint, type, dummy); + CopyUTF8toUTF16(type, typeHint); + } + +diff --git a/dom/base/Navigator.cpp b/dom/base/Navigator.cpp +index f4ea502..7288420 100644 +--- a/dom/base/Navigator.cpp ++++ b/dom/base/Navigator.cpp +@@ -1221,9 +1221,9 @@ Navigator::SendBeacon(const nsAString& aUrl, + rv = secMan->CheckSameOriginURI(documentURI, uri, false); + bool crossOrigin = NS_FAILED(rv); + nsAutoCString contentType, parsedCharset; +- rv = NS_ParseContentType(mimeType, contentType, parsedCharset); ++ rv = NS_ParseRequestContentType(mimeType, contentType, parsedCharset); + if (crossOrigin && +- contentType.Length() > 0 && ++ mimeType.Length() > 0 && + !contentType.Equals(APPLICATION_WWW_FORM_URLENCODED) && + !contentType.Equals(MULTIPART_FORM_DATA) && + !contentType.Equals(TEXT_PLAIN)) { +diff --git a/dom/base/nsContentUtils.cpp b/dom/base/nsContentUtils.cpp +index 5e8dbd6..686f7bf 100644 +--- a/dom/base/nsContentUtils.cpp ++++ b/dom/base/nsContentUtils.cpp +@@ -7001,7 +7001,7 @@ nsContentUtils::IsAllowedNonCorsContentType(const nsACString& aHeaderValue) + nsAutoCString contentType; + nsAutoCString unused; + +- nsresult rv = NS_ParseContentType(aHeaderValue, contentType, unused); ++ nsresult rv = NS_ParseRequestContentType(aHeaderValue, contentType, unused); + if (NS_FAILED(rv)) { + return false; + } +diff --git a/dom/html/nsHTMLDocument.cpp b/dom/html/nsHTMLDocument.cpp +index 7481109..d195792 100644 +--- a/dom/html/nsHTMLDocument.cpp ++++ b/dom/html/nsHTMLDocument.cpp +@@ -1422,7 +1422,7 @@ nsHTMLDocument::Open(JSContext* cx, + nsAutoString type; + nsContentUtils::ASCIIToLower(aType, type); + nsAutoCString actualType, dummy; +- NS_ParseContentType(NS_ConvertUTF16toUTF8(type), actualType, dummy); ++ NS_ParseRequestContentType(NS_ConvertUTF16toUTF8(type), actualType, dummy); + if (!actualType.EqualsLiteral("text/html") && + !type.EqualsLiteral("replace")) { + contentType.AssignLiteral("text/plain"); +diff --git a/dom/manifest/ManifestProcessor.jsm b/dom/manifest/ManifestProcessor.jsm +index b6df920..f16881a 100644 +--- a/dom/manifest/ManifestProcessor.jsm ++++ b/dom/manifest/ManifestProcessor.jsm +@@ -31,7 +31,7 @@ const imports = {}; + Cu.import('resource://gre/modules/Services.jsm', imports); + Cu.importGlobalProperties(['URL']); + const securityManager = imports.Services.scriptSecurityManager; +-const netutil = Cc['@mozilla.org/network/util;1'].getService(Ci.nsINetUtil); ++const netutil = Cc['@mozilla.org/network/util;1'].getService(Ci.nsINetUtil_ESR_38); + const defaultDisplayMode = 'browser'; + const displayModes = new Set([ + 'fullscreen', +@@ -258,7 +258,7 @@ this.ManifestProcessor.prototype.process = function({ + }; + let value = extractValue(obj), + isParsable = (typeof value === 'string' && value.length > 0); +- value = (isParsable) ? netutil.parseContentType(value.trim(), charset, hadCharset) : undefined; ++ value = (isParsable) ? netutil.parseRequestContentType(value.trim(), charset, hadCharset) : undefined; + return (value === '') ? undefined : value; + } + +@@ -354,4 +354,4 @@ this.ManifestProcessor.prototype.process = function({ + }; + processedManifest.scope = processScopeMember(manifest, manifestURL, docURL, processedManifest.start_url); + return processedManifest; +-}; +\ No newline at end of file ++}; +diff --git a/netwerk/base/moz.build b/netwerk/base/moz.build +index 877365b..deedf76 100644 +--- a/netwerk/base/moz.build ++++ b/netwerk/base/moz.build +@@ -59,6 +59,7 @@ XPIDL_SOURCES += [ + 'nsINestedURI.idl', + 'nsINetAddr.idl', + 'nsINetUtil.idl', ++ 'nsINetUtil_ESR_38.idl', + 'nsINetworkInterceptController.idl', + 'nsINetworkLinkService.idl', + 'nsINetworkPredictor.idl', +diff --git a/netwerk/base/nsINetUtil_ESR_38.idl b/netwerk/base/nsINetUtil_ESR_38.idl +new file mode 100644 +index 0000000..7ef40e9 +--- /dev/null ++++ b/netwerk/base/nsINetUtil_ESR_38.idl +@@ -0,0 +1,14 @@ ++/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ ++/* This Source Code Form is subject to the terms of the Mozilla Public ++ * License, v. 2.0. If a copy of the MPL was not distributed with this ++ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ ++ ++#include "nsISupports.idl" ++ ++[scriptable, uuid(e82f2b9d-8bac-48bb-ade7-26a7cd4fb894)] ++interface nsINetUtil_ESR_38 : nsISupports ++{ ++ AUTF8String parseRequestContentType(in AUTF8String aTypeHeader, ++ out AUTF8String aCharset, ++ out boolean aHadCharset); ++}; +diff --git a/netwerk/base/nsIOService.cpp b/netwerk/base/nsIOService.cpp +index 83db86f..9a17e8b 100644 +--- a/netwerk/base/nsIOService.cpp ++++ b/netwerk/base/nsIOService.cpp +@@ -321,6 +321,7 @@ NS_IMPL_ISUPPORTS(nsIOService, + nsIIOService, + nsIIOService2, + nsINetUtil, ++ nsINetUtil_ESR_38, + nsISpeculativeConnect, + nsIObserver, + nsISupportsWeakReference) +@@ -1280,6 +1281,17 @@ nsIOService::Observe(nsISupports *subject, + + // nsINetUtil interface + NS_IMETHODIMP ++nsIOService::ParseRequestContentType(const nsACString &aTypeHeader, ++ nsACString &aCharset, ++ bool *aHadCharset, ++ nsACString &aContentType) ++{ ++ net_ParseRequestContentType(aTypeHeader, aContentType, aCharset, aHadCharset); ++ return NS_OK; ++} ++ ++// nsINetUtil interface ++NS_IMETHODIMP + nsIOService::ParseContentType(const nsACString &aTypeHeader, + nsACString &aCharset, + bool *aHadCharset, +diff --git a/netwerk/base/nsIOService.h b/netwerk/base/nsIOService.h +index acd501c..b125709 100644 +--- a/netwerk/base/nsIOService.h ++++ b/netwerk/base/nsIOService.h +@@ -14,6 +14,7 @@ + #include "nsIObserver.h" + #include "nsWeakReference.h" + #include "nsINetUtil.h" ++#include "nsINetUtil_ESR_38.h" + #include "nsIChannelEventSink.h" + #include "nsCategoryCache.h" + #include "nsISpeculativeConnect.h" +@@ -47,6 +48,7 @@ namespace net { + class nsIOService final : public nsIIOService2 + , public nsIObserver + , public nsINetUtil ++ , public nsINetUtil_ESR_38 + , public nsISpeculativeConnect + , public nsSupportsWeakReference + { +@@ -56,6 +58,7 @@ public: + NS_DECL_NSIIOSERVICE2 + NS_DECL_NSIOBSERVER + NS_DECL_NSINETUTIL ++ NS_DECL_NSINETUTIL_ESR_38 + NS_DECL_NSISPECULATIVECONNECT + + // Gets the singleton instance of the IO Service, creating it as needed +diff --git a/netwerk/base/nsNetUtil.h b/netwerk/base/nsNetUtil.h +index ec69716..df8874c 100644 +--- a/netwerk/base/nsNetUtil.h ++++ b/netwerk/base/nsNetUtil.h +@@ -56,6 +56,7 @@ + #include "nsISyncStreamListener.h" + #include "nsInterfaceRequestorAgg.h" + #include "nsINetUtil.h" ++#include "nsINetUtil_ESR_38.h" + #include "nsIURIWithPrincipal.h" + #include "nsIAuthPrompt.h" + #include "nsIAuthPrompt2.h" +@@ -1228,6 +1229,26 @@ NS_GetReferrerFromChannel(nsIChannel *channel, + } + + inline nsresult ++NS_ParseRequestContentType(const nsACString &rawContentType, ++ nsCString &contentType, ++ nsCString &contentCharset) ++{ ++ // contentCharset is left untouched if not present in rawContentType ++ nsresult rv; ++ nsCOMPtr<nsINetUtil> util = do_GetNetUtil(&rv); ++ NS_ENSURE_SUCCESS(rv, rv); ++ nsCOMPtr<nsINetUtil_ESR_38> utilESR38 = do_QueryInterface(util, &rv); ++ NS_ENSURE_SUCCESS(rv, rv); ++ nsCString charset; ++ bool hadCharset; ++ rv = utilESR38->ParseRequestContentType(rawContentType, charset, &hadCharset, ++ contentType); ++ if (NS_SUCCEEDED(rv) && hadCharset) ++ contentCharset = charset; ++ return rv; ++} ++ ++inline nsresult + NS_ParseContentType(const nsACString &rawContentType, + nsCString &contentType, + nsCString &contentCharset) +diff --git a/netwerk/base/nsURLHelper.cpp b/netwerk/base/nsURLHelper.cpp +index 10ea849..cdb2120 100644 +--- a/netwerk/base/nsURLHelper.cpp ++++ b/netwerk/base/nsURLHelper.cpp +@@ -803,7 +803,8 @@ net_ParseMediaType(const nsACString &aMediaTypeStr, + int32_t aOffset, + bool *aHadCharset, + int32_t *aCharsetStart, +- int32_t *aCharsetEnd) ++ int32_t *aCharsetEnd, ++ bool aStrict) + { + const nsCString& flatStr = PromiseFlatCString(aMediaTypeStr); + const char* start = flatStr.get(); +@@ -820,6 +821,8 @@ net_ParseMediaType(const nsACString &aMediaTypeStr, + int32_t charsetParamStart = 0; + int32_t charsetParamEnd = 0; + ++ uint32_t consumed = typeEnd - type; ++ + // Iterate over parameters + bool typeHasCharset = false; + uint32_t paramStart = flatStr.FindChar(';', typeEnd - start); +@@ -843,6 +846,7 @@ net_ParseMediaType(const nsACString &aMediaTypeStr, + charsetParamEnd = curParamEnd; + } + ++ consumed = curParamEnd; + curParamStart = curParamEnd + 1; + } while (curParamStart < flatStr.Length()); + } +@@ -872,8 +876,10 @@ net_ParseMediaType(const nsACString &aMediaTypeStr, + // some servers give junk after the charset parameter, which may + // include a comma, so this check makes us a bit more tolerant. + +- if (type != typeEnd && strncmp(type, "*/*", typeEnd - type) != 0 && +- memchr(type, '/', typeEnd - type) != nullptr) { ++ if (type != typeEnd && ++ memchr(type, '/', typeEnd - type) != nullptr && ++ (aStrict ? (net_FindCharNotInSet(start + consumed, end, HTTP_LWS) == end) : ++ (strncmp(type, "*/*", typeEnd - type) != 0))) { + // Common case here is that aContentType is empty + bool eq = !aContentType.IsEmpty() && + aContentType.Equals(Substring(type, typeEnd), +@@ -980,13 +986,59 @@ net_ParseContentType(const nsACString &aHeaderStr, + net_ParseMediaType(Substring(flatStr, curTypeStart, + curTypeEnd - curTypeStart), + aContentType, aContentCharset, curTypeStart, +- aHadCharset, aCharsetStart, aCharsetEnd); ++ aHadCharset, aCharsetStart, aCharsetEnd, false); + + // And let's move on to the next media-type + curTypeStart = curTypeEnd + 1; + } while (curTypeStart < flatStr.Length()); + } + ++void ++net_ParseRequestContentType(const nsACString &aHeaderStr, ++ nsACString &aContentType, ++ nsACString &aContentCharset, ++ bool *aHadCharset) ++{ ++ // ++ // Augmented BNF (from RFC 7231 section 3.1.1.1): ++ // ++ // media-type = type "/" subtype *( OWS ";" OWS parameter ) ++ // type = token ++ // subtype = token ++ // parameter = token "=" ( token / quoted-string ) ++ // ++ // Examples: ++ // ++ // text/html ++ // text/html; charset=ISO-8859-1 ++ // text/html; charset="ISO-8859-1" ++ // application/octet-stream ++ // ++ ++ aContentType.Truncate(); ++ aContentCharset.Truncate(); ++ *aHadCharset = false; ++ const nsCString& flatStr = PromiseFlatCString(aHeaderStr); ++ ++ // At this point curTypeEnd points to the spot where the media-type ++ // starting at curTypeEnd ends. Time to parse that! ++ nsAutoCString contentType, contentCharset; ++ bool hadCharset = false; ++ int32_t dummy1, dummy2; ++ uint32_t typeEnd = net_FindMediaDelimiter(flatStr, 0, ','); ++ if (typeEnd != flatStr.Length()) { ++ // We have some stuff left at the end, so this is not a valid ++ // request Content-Type header. ++ return; ++ } ++ net_ParseMediaType(flatStr, contentType, contentCharset, 0, ++ &hadCharset, &dummy1, &dummy2, true); ++ ++ aContentType = contentType; ++ aContentCharset = contentCharset; ++ *aHadCharset = hadCharset; ++} ++ + bool + net_IsValidHostName(const nsCSubstring &host) + { +diff --git a/netwerk/base/nsURLHelper.h b/netwerk/base/nsURLHelper.h +index 816a3c5..21e17be 100644 +--- a/netwerk/base/nsURLHelper.h ++++ b/netwerk/base/nsURLHelper.h +@@ -172,11 +172,27 @@ char * net_RFindCharNotInSet(const char *str, const char *end, const char *set); + * specified), aHadCharset is set to false. Otherwise, it's set to + * true. Note that aContentCharset can be empty even if aHadCharset + * is true. ++ * ++ * This parsing is suitable for HTTP request. Use net_ParseContentType ++ * for parsing this header in HTTP responses. ++ */ ++void net_ParseRequestContentType(const nsACString &aHeaderStr, ++ nsACString &aContentType, ++ nsACString &aContentCharset, ++ bool* aHadCharset); ++ ++/** ++ * Parses a content-type header and returns the content type and ++ * charset (if any). aCharset is not modified if no charset is ++ * specified in anywhere in aHeaderStr. In that case (no charset ++ * specified), aHadCharset is set to false. Otherwise, it's set to ++ * true. Note that aContentCharset can be empty even if aHadCharset ++ * is true. + */ + void net_ParseContentType(const nsACString &aHeaderStr, +- nsACString &aContentType, +- nsACString &aContentCharset, +- bool* aHadCharset); ++ nsACString &aContentType, ++ nsACString &aContentCharset, ++ bool* aHadCharset); + /** + * As above, but also returns the start and end indexes for the charset + * parameter in aHeaderStr. These are indices for the entire parameter, NOT +@@ -187,11 +203,11 @@ void net_ParseContentType(const nsACString &aHeaderStr, + * *aCharsetStart is nonnegative; this corresponds to charset="". + */ + void net_ParseContentType(const nsACString &aHeaderStr, +- nsACString &aContentType, +- nsACString &aContentCharset, +- bool *aHadCharset, +- int32_t *aCharsetStart, +- int32_t *aCharsetEnd); ++ nsACString &aContentType, ++ nsACString &aContentCharset, ++ bool *aHadCharset, ++ int32_t *aCharsetStart, ++ int32_t *aCharsetEnd); + + /* inline versions */ + +-- +2.5.0 + diff --git a/gnu/packages/patches/icecat-CVE-2015-7194.patch b/gnu/packages/patches/icecat-CVE-2015-7194.patch new file mode 100644 index 0000000000..481da06a7f --- /dev/null +++ b/gnu/packages/patches/icecat-CVE-2015-7194.patch @@ -0,0 +1,32 @@ +From 382a08fa0b21d46c44c46af39041324f304a9dfa Mon Sep 17 00:00:00 2001 +From: Aaron Klotz <aklotz@mozilla.com> +Date: Tue, 13 Oct 2015 12:20:25 -0600 +Subject: [PATCH] Bug 1211262: Ensure that STORED entries in ZIP are considered + corrupt if compressed and uncompressed sizes differ; r=mwu, a=ritu + +--HG-- +extra : source : 673d9f45b802f1fd1ffaaeae19d433622fe68a5e +extra : intermediate-source : db9d3e806685d72a2891830ffbc42ef3cde559ae +--- + modules/libjar/nsZipArchive.cpp | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/modules/libjar/nsZipArchive.cpp b/modules/libjar/nsZipArchive.cpp +index bb1e21b..eaf22ac 100644 +--- a/modules/libjar/nsZipArchive.cpp ++++ b/modules/libjar/nsZipArchive.cpp +@@ -828,8 +828,10 @@ MOZ_WIN_MEM_TRY_BEGIN + // -- check if there is enough source data in the file + if (!offset || + mFd->mLen < aItem->Size() || +- offset > mFd->mLen - aItem->Size()) ++ offset > mFd->mLen - aItem->Size() || ++ (aItem->Compression() == STORED && aItem->Size() != aItem->RealSize())) { + return nullptr; ++ } + + return mFd->mFileData + offset; + MOZ_WIN_MEM_TRY_CATCH(return nullptr) +-- +2.5.0 + diff --git a/gnu/packages/patches/icecat-CVE-2015-7196.patch b/gnu/packages/patches/icecat-CVE-2015-7196.patch new file mode 100644 index 0000000000..6114ebf505 --- /dev/null +++ b/gnu/packages/patches/icecat-CVE-2015-7196.patch @@ -0,0 +1,27 @@ +From 3ed5c713015536b49dc88d3d4a36b60833ccd09a Mon Sep 17 00:00:00 2001 +From: Jan de Mooij <jdemooij@mozilla.com> +Date: Tue, 25 Aug 2015 13:11:41 +0200 +Subject: [PATCH] Bug 1140616 - Crash when _releaseobject is called on the + wrong thread. r=bsmedberg, a=sledru, a=lizzard + +--HG-- +extra : source : 6a513309283d06f56cebee8528cfcf134a74f3c4 +--- + dom/plugins/base/nsNPAPIPlugin.cpp | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/dom/plugins/base/nsNPAPIPlugin.cpp b/dom/plugins/base/nsNPAPIPlugin.cpp +index f0d07fa..9cd2e05 100644 +--- a/dom/plugins/base/nsNPAPIPlugin.cpp ++++ b/dom/plugins/base/nsNPAPIPlugin.cpp +@@ -1413,6 +1413,7 @@ _releaseobject(NPObject* npobj) + { + if (!NS_IsMainThread()) { + NPN_PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("NPN_releaseobject called from the wrong thread\n")); ++ MOZ_CRASH("NPN_releaseobject called from the wrong thread"); + } + if (!npobj) + return; +-- +2.5.0 + diff --git a/gnu/packages/patches/icecat-CVE-2015-7197.patch b/gnu/packages/patches/icecat-CVE-2015-7197.patch new file mode 100644 index 0000000000..1763341ff7 --- /dev/null +++ b/gnu/packages/patches/icecat-CVE-2015-7197.patch @@ -0,0 +1,70 @@ +From a522e727bff0fb69cb0d34c2d2ad89168d15158d Mon Sep 17 00:00:00 2001 +From: Ehsan Akhgari <ehsan@mozilla.com> +Date: Sat, 12 Sep 2015 17:38:51 -0400 +Subject: [PATCH] Bug 1204269 - Use the worker private in order to determine + the origin of the entry settings object for workers; r=smaug a=me + +--- + dom/base/WebSocket.cpp | 46 ++++++++++++++++++++++++++-------------------- + 1 file changed, 26 insertions(+), 20 deletions(-) + +diff --git a/dom/base/WebSocket.cpp b/dom/base/WebSocket.cpp +index ea91232..26b94d0 100644 +--- a/dom/base/WebSocket.cpp ++++ b/dom/base/WebSocket.cpp +@@ -1503,26 +1503,32 @@ WebSocketImpl::Init(JSContext* aCx, + !Preferences::GetBool("network.websocket.allowInsecureFromHTTPS", + false)) { + // Confirmed we are opening plain ws:// and want to prevent this from a +- // secure context (e.g. https). Check the principal's uri to determine if +- // we were loaded from https. +- nsCOMPtr<nsIGlobalObject> globalObject(GetEntryGlobal()); +- if (globalObject) { +- nsCOMPtr<nsIPrincipal> principal(globalObject->PrincipalOrNull()); +- if (principal) { +- nsCOMPtr<nsIURI> uri; +- principal->GetURI(getter_AddRefs(uri)); +- if (uri) { +- bool originIsHttps = false; +- aRv = uri->SchemeIs("https", &originIsHttps); +- if (NS_WARN_IF(aRv.Failed())) { +- return; +- } +- +- if (originIsHttps) { +- aRv.Throw(NS_ERROR_DOM_SECURITY_ERR); +- return; +- } +- } ++ // secure context (e.g. https). ++ nsCOMPtr<nsIPrincipal> principal; ++ nsCOMPtr<nsIURI> originURI; ++ if (mWorkerPrivate) { ++ // For workers, retrieve the URI from the WorkerPrivate ++ principal = mWorkerPrivate->GetPrincipal(); ++ } else { ++ // Check the principal's uri to determine if we were loaded from https. ++ nsCOMPtr<nsIGlobalObject> globalObject(GetEntryGlobal()); ++ if (globalObject) { ++ principal = globalObject->PrincipalOrNull(); ++ } ++ } ++ ++ if (principal) { ++ principal->GetURI(getter_AddRefs(originURI)); ++ } ++ if (originURI) { ++ bool originIsHttps = false; ++ aRv = originURI->SchemeIs("https", &originIsHttps); ++ if (NS_WARN_IF(aRv.Failed())) { ++ return; ++ } ++ if (originIsHttps) { ++ aRv.Throw(NS_ERROR_DOM_SECURITY_ERR); ++ return; + } + } + } +-- +2.5.0 + diff --git a/gnu/packages/patches/icecat-CVE-2015-7198.patch b/gnu/packages/patches/icecat-CVE-2015-7198.patch new file mode 100644 index 0000000000..2e127897bc --- /dev/null +++ b/gnu/packages/patches/icecat-CVE-2015-7198.patch @@ -0,0 +1,27 @@ +From cc2a334ee16e99d376fcb49203239abf9eb2c148 Mon Sep 17 00:00:00 2001 +From: Jeff Gilbert <jgilbert@mozilla.com> +Date: Wed, 7 Oct 2015 13:27:37 -0700 +Subject: [PATCH] Bug 1188010 - Use MOZ_RELEASE_ASSERT when failure means + overflow. - r=kamidphish, a=abillings + +--- + dom/canvas/WebGLTexture.cpp | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/dom/canvas/WebGLTexture.cpp b/dom/canvas/WebGLTexture.cpp +index 60afc45..d6a6ccd 100644 +--- a/dom/canvas/WebGLTexture.cpp ++++ b/dom/canvas/WebGLTexture.cpp +@@ -651,8 +651,7 @@ WebGLTexture::EnsureNoUninitializedImageData(TexImageTarget imageTarget, + imageInfo.mDepth, + bytespertexel, + mContext->mPixelStoreUnpackAlignment); +- MOZ_ASSERT(checked_byteLength.isValid()); // Should have been checked +- // earlier. ++ MOZ_RELEASE_ASSERT(checked_byteLength.isValid()); // Should have been checked earlier. + + // Infallible for now. + UniquePtr<uint8_t> zeros((uint8_t*)moz_xcalloc(1, +-- +2.5.0 + diff --git a/gnu/packages/patches/icecat-CVE-2015-7199.patch b/gnu/packages/patches/icecat-CVE-2015-7199.patch new file mode 100644 index 0000000000..d6b830b8a0 --- /dev/null +++ b/gnu/packages/patches/icecat-CVE-2015-7199.patch @@ -0,0 +1,84 @@ +From 04741232fa561a4c299f31a5b5fb4603da79d2c5 Mon Sep 17 00:00:00 2001 +From: Robert Longson <longsonr@gmail.com> +Date: Tue, 6 Oct 2015 13:19:03 +0100 +Subject: [PATCH] Bug 1204061 - check return values from some methods + r=dholbert, a=sylvestre + +--HG-- +extra : source : f4c2f277aeae7bf8b05c6b01d1e140cd51b693b4 +--- + dom/svg/SVGPathSegListSMILType.cpp | 23 +++++++++++------------ + 1 file changed, 11 insertions(+), 12 deletions(-) + +diff --git a/dom/svg/SVGPathSegListSMILType.cpp b/dom/svg/SVGPathSegListSMILType.cpp +index f8b67d0..6df0f53 100644 +--- a/dom/svg/SVGPathSegListSMILType.cpp ++++ b/dom/svg/SVGPathSegListSMILType.cpp +@@ -232,7 +232,7 @@ AddWeightedPathSegs(double aCoeff1, + * identity, in which case we'll grow it to the right + * size. Also allowed to be the same list as aList1. + */ +-static void ++static nsresult + AddWeightedPathSegLists(double aCoeff1, const SVGPathDataAndInfo& aList1, + double aCoeff2, const SVGPathDataAndInfo& aList2, + SVGPathDataAndInfo& aResult) +@@ -263,8 +263,9 @@ AddWeightedPathSegLists(double aCoeff1, const SVGPathDataAndInfo& aList1, + // because in that case, we will have already set iter1 to nullptr above, to + // record that our first operand is an identity value.) + if (aResult.IsIdentity()) { +- DebugOnly<bool> success = aResult.SetLength(aList2.Length()); +- MOZ_ASSERT(success, "infallible nsTArray::SetLength should succeed"); ++ if (!aResult.SetLength(aList2.Length())) { ++ return NS_ERROR_OUT_OF_MEMORY; ++ } + aResult.SetElement(aList2.Element()); // propagate target element info! + } + +@@ -280,6 +281,7 @@ AddWeightedPathSegLists(double aCoeff1, const SVGPathDataAndInfo& aList1, + iter2 == end2 && + resultIter == aResult.end(), + "Very, very bad - path data corrupt"); ++ return NS_OK; + } + + static void +@@ -429,9 +431,7 @@ SVGPathSegListSMILType::Add(nsSMILValue& aDest, + } + } + +- AddWeightedPathSegLists(1.0, dest, aCount, valueToAdd, dest); +- +- return NS_OK; ++ return AddWeightedPathSegLists(1.0, dest, aCount, valueToAdd, dest); + } + + nsresult +@@ -482,8 +482,9 @@ SVGPathSegListSMILType::Interpolate(const nsSMILValue& aStartVal, + if (check == eRequiresConversion) { + // Can't convert |start| in-place, since it's const. Instead, we copy it + // into |result|, converting the types as we go, and use that as our start. +- DebugOnly<bool> success = result.SetLength(end.Length()); +- MOZ_ASSERT(success, "infallible nsTArray::SetLength should succeed"); ++ if (!result.SetLength(end.Length())) { ++ return NS_ERROR_OUT_OF_MEMORY; ++ } + result.SetElement(end.Element()); // propagate target element info! + + ConvertAllPathSegmentData(start.begin(), start.end(), +@@ -492,10 +493,8 @@ SVGPathSegListSMILType::Interpolate(const nsSMILValue& aStartVal, + startListToUse = &result; + } + +- AddWeightedPathSegLists(1.0 - aUnitDistance, *startListToUse, +- aUnitDistance, end, result); +- +- return NS_OK; ++ return AddWeightedPathSegLists(1.0 - aUnitDistance, *startListToUse, ++ aUnitDistance, end, result); + } + + } // namespace mozilla +-- +2.5.0 + |