diff options
-rwxr-xr-x | browser/base/content/browser.js | 2 | ||||
-rw-r--r-- | browser/base/content/urlbarBindings.xml | 53 | ||||
-rw-r--r-- | gfx/layers/basic/BasicImages.cpp | 9 | ||||
-rw-r--r-- | js/moz.configure | 24 | ||||
-rw-r--r-- | js/src/gc/Nursery.cpp | 14 | ||||
-rw-r--r-- | js/src/jit/MoveResolver.cpp | 99 | ||||
-rw-r--r-- | js/src/jit/MoveResolver.h | 11 | ||||
-rw-r--r-- | js/src/jsapi-tests/testJitMoveEmitterCycles.cpp | 94 | ||||
-rw-r--r-- | mfbt/Vector.h | 4 | ||||
-rw-r--r-- | mfbt/tests/TestVector.cpp | 52 | ||||
-rw-r--r-- | mobile/android/base/java/org/mozilla/gecko/IntentHelper.java | 6 | ||||
-rw-r--r-- | toolkit/components/feeds/FeedProcessor.js | 3 | ||||
-rw-r--r-- | toolkit/moz.configure | 24 |
13 files changed, 338 insertions, 57 deletions
diff --git a/browser/base/content/browser.js b/browser/base/content/browser.js index 7aaaa09aa..5a54dcc58 100755 --- a/browser/base/content/browser.js +++ b/browser/base/content/browser.js @@ -5688,7 +5688,7 @@ function middleMousePaste(event) { function stripUnsafeProtocolOnPaste(pasteData) { // Don't allow pasting javascript URIs since we don't support // LOAD_FLAGS_DISALLOW_INHERIT_PRINCIPAL for those. - return pasteData.replace(/^(?:\s*javascript:)+/i, ""); + return pasteData.replace(/\r?\n/g, "").replace(/^(?:\s*javascript:)+/i, ""); } // handleDroppedLink has the following 2 overloads: diff --git a/browser/base/content/urlbarBindings.xml b/browser/base/content/urlbarBindings.xml index 84ed693ff..689c7c5a7 100644 --- a/browser/base/content/urlbarBindings.xml +++ b/browser/base/content/urlbarBindings.xml @@ -701,38 +701,51 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/. ]]></body> </method> - <method name="onDragOver"> - <parameter name="aEvent"/> - <body> - var types = aEvent.dataTransfer.types; - if (types.includes("application/x-moz-file") || - types.includes("text/x-moz-url") || - types.includes("text/uri-list") || - types.includes("text/unicode")) - aEvent.preventDefault(); - </body> - </method> - - <method name="onDrop"> + <method name="_getDroppableLink"> <parameter name="aEvent"/> <body><![CDATA[ let links = browserDragAndDrop.dropLinks(aEvent); - // The URL bar automatically handles inputs with newline characters, // so we can get away with treating text/x-moz-url flavours as text/plain. if (links.length > 0 && links[0].url) { - let url = links[0].url; aEvent.preventDefault(); - this.value = url; - SetPageProxyState("invalid"); - this.focus(); + let url = links[0].url; + let strippedURL = stripUnsafeProtocolOnPaste(url); + if (strippedURL != url) { + aEvent.stopImmediatePropagation(); + return null; + } try { urlSecurityCheck(url, gBrowser.contentPrincipal, Ci.nsIScriptSecurityManager.DISALLOW_INHERIT_PRINCIPAL); } catch (ex) { - return; + return null; } + return url; + } + return null; + ]]></body> + </method> + + <method name="onDragOver"> + <parameter name="aEvent"/> + <body><![CDATA[ + // We don't need the link here, so we ignore the return value. + if (!this._getDroppableLink(aEvent)) { + aEvent.dataTransfer.dropEffect = "none"; + } + ]]></body> + </method> + + <method name="onDrop"> + <parameter name="aEvent"/> + <body><![CDATA[ + let url = this._getDroppableLink(aEvent); + if (url) { + this.value = url; + SetPageProxyState("invalid"); + this.focus(); this.handleCommand(); // Force not showing the dropped URI immediately. gBrowser.userTypedValue = null; @@ -932,7 +945,7 @@ file, You can obtain one at http://mozilla.org/MPL/2.0/. // Unfortunately we're not allowed to set the bits being pasted // so cancel this event: aEvent.preventDefault(); - aEvent.stopPropagation(); + aEvent.stopImmediatePropagation(); this.inputField.value = oldStart + pasteData + oldEnd; // Fix up cursor/selection: diff --git a/gfx/layers/basic/BasicImages.cpp b/gfx/layers/basic/BasicImages.cpp index ed9447207..fc1be6e9a 100644 --- a/gfx/layers/basic/BasicImages.cpp +++ b/gfx/layers/basic/BasicImages.cpp @@ -11,6 +11,7 @@ #include "gfxASurface.h" // for gfxASurface, etc #include "gfxPlatform.h" // for gfxPlatform, gfxImageFormat #include "gfxUtils.h" // for gfxUtils +#include "mozilla/CheckedInt.h" #include "mozilla/mozalloc.h" // for operator delete[], etc #include "mozilla/RefPtr.h" #include "mozilla/UniquePtr.h" @@ -111,7 +112,13 @@ BasicPlanarYCbCrImage::CopyData(const Data& aData) gfxImageFormat iFormat = gfx::SurfaceFormatToImageFormat(format); mStride = gfxASurface::FormatStrideForWidth(iFormat, size.width); - mDecodedBuffer = AllocateBuffer(size.height * mStride); + mozilla::CheckedInt32 requiredBytes = + mozilla::CheckedInt32(size.height) * mozilla::CheckedInt32(mStride); + if (!requiredBytes.isValid()) { + // invalid size + return false; + } + mDecodedBuffer = AllocateBuffer(requiredBytes.value()); if (!mDecodedBuffer) { // out of memory return false; diff --git a/js/moz.configure b/js/moz.configure index 0eeb2fc52..eadd0e9ab 100644 --- a/js/moz.configure +++ b/js/moz.configure @@ -236,3 +236,27 @@ def ctypes_and_compile_environment(ctypes, compile_environment, _): return ctypes and compile_environment include('ffi.configure', when=ctypes_and_compile_environment) + +# Support various fuzzing options +# ============================================================== +with only_when('--enable-compile-environment'): + option('--enable-fuzzing', help='Enable fuzzing support') + + @depends('--enable-fuzzing') + def enable_fuzzing(value): + if value: + return True + + @depends(enable_fuzzing, + try_compile(body='__AFL_COMPILER;', + check_msg='for AFL compiler', + when='--enable-fuzzing')) + def enable_libfuzzer(fuzzing, afl): + if fuzzing and not afl: + return True + + set_config('FUZZING', enable_fuzzing) + set_define('FUZZING', enable_fuzzing) + + set_config('LIBFUZZER', enable_libfuzzer) + set_define('LIBFUZZER', enable_libfuzzer) diff --git a/js/src/gc/Nursery.cpp b/js/src/gc/Nursery.cpp index bce2b74aa..aa50bf29e 100644 --- a/js/src/gc/Nursery.cpp +++ b/js/src/gc/Nursery.cpp @@ -121,6 +121,13 @@ js::Nursery::Nursery(JSRuntime* rt) bool js::Nursery::init(uint32_t maxNurseryBytes, AutoLockGC& lock) { + if (!mallocedBuffers.init()) + return false; + + freeMallocedBuffersTask = js_new<FreeMallocedBuffersTask>(runtime()->defaultFreeOp()); + if (!freeMallocedBuffersTask || !freeMallocedBuffersTask->init()) + return false; + /* maxNurseryBytes parameter is rounded down to a multiple of chunk size. */ maxNurseryChunks_ = maxNurseryBytes >> ChunkShift; @@ -128,16 +135,9 @@ js::Nursery::init(uint32_t maxNurseryBytes, AutoLockGC& lock) if (maxNurseryChunks_ == 0) return true; - if (!mallocedBuffers.init()) - return false; - if (!cellsWithUid_.init()) return false; - freeMallocedBuffersTask = js_new<FreeMallocedBuffersTask>(runtime()->defaultFreeOp()); - if (!freeMallocedBuffersTask || !freeMallocedBuffersTask->init()) - return false; - AutoMaybeStartBackgroundAllocation maybeBgAlloc; updateNumChunksLocked(1, maybeBgAlloc, lock); if (numChunks() == 0) diff --git a/js/src/jit/MoveResolver.cpp b/js/src/jit/MoveResolver.cpp index 5fd6c7bd5..383b45073 100644 --- a/js/src/jit/MoveResolver.cpp +++ b/js/src/jit/MoveResolver.cpp @@ -106,12 +106,111 @@ MoveResolver::findCycledMove(PendingMoveIterator* iter, PendingMoveIterator end, return nullptr; } +#ifdef JS_CODEGEN_ARM +static inline bool +MoveIsDouble(const MoveOperand& move) +{ + if (!move.isFloatReg()) + return false; + return move.floatReg().isDouble(); +} +#endif + +#ifdef JS_CODEGEN_ARM +static inline bool +MoveIsSingle(const MoveOperand& move) +{ + if (!move.isFloatReg()) + return false; + return move.floatReg().isSingle(); +} +#endif + +#ifdef JS_CODEGEN_ARM +bool +MoveResolver::isDoubleAliasedAsSingle(const MoveOperand& move) +{ + if (!MoveIsDouble(move)) + return false; + + for (auto iter = pending_.begin(); iter != pending_.end(); ++iter) { + PendingMove* other = *iter; + if (other->from().aliases(move) && MoveIsSingle(other->from())) + return true; + if (other->to().aliases(move) && MoveIsSingle(other->to())) + return true; + } + return false; +} +#endif + +#ifdef JS_CODEGEN_ARM +static MoveOperand +SplitIntoLowerHalf(const MoveOperand& move) +{ + if (MoveIsDouble(move)) { + FloatRegister lowerSingle = move.floatReg().asSingle(); + return MoveOperand(lowerSingle); + } + + MOZ_ASSERT(move.isMemoryOrEffectiveAddress()); + return move; +} +#endif + +#ifdef JS_CODEGEN_ARM +static MoveOperand +SplitIntoUpperHalf(const MoveOperand& move) +{ + if (MoveIsDouble(move)) { + FloatRegister lowerSingle = move.floatReg().asSingle(); + FloatRegister upperSingle = VFPRegister(lowerSingle.code() + 1, VFPRegister::Single); + return MoveOperand(upperSingle); + } + + MOZ_ASSERT(move.isMemoryOrEffectiveAddress()); + return MoveOperand(move.base(), move.disp() + sizeof(float)); +} +#endif + bool MoveResolver::resolve() { resetState(); orderedMoves_.clear(); +#ifdef JS_CODEGEN_ARM + // Some of ARM's double registers alias two of its single registers, + // but the algorithm below assumes that every register can participate + // in at most one cycle. To satisfy the algorithm, any double registers + // that may conflict are split into their single-register halves. + // + // This logic is only applicable because ARM only uses registers d0-d15, + // all of which alias s0-s31. Double registers d16-d31 are unused. + // Therefore there is never a double move that cannot be split. + // If this changes in the future, the algorithm will have to be fixed. + for (auto iter = pending_.begin(); iter != pending_.end(); ++iter) { + PendingMove* pm = *iter; + + if (isDoubleAliasedAsSingle(pm->from()) || isDoubleAliasedAsSingle(pm->to())) { + PendingMove* lower = movePool_.allocate(); + if (!lower) + return false; + + // Insert the new node before the current position to not affect iteration. + MoveOperand fromLower = SplitIntoLowerHalf(pm->from()); + MoveOperand toLower = SplitIntoLowerHalf(pm->to()); + new (lower) PendingMove(fromLower, toLower, MoveOp::FLOAT32); + pending_.insertBefore(pm, lower); + + // Overwrite pm in place for the upper move. Iteration proceeds as normal. + MoveOperand fromUpper = SplitIntoUpperHalf(pm->from()); + MoveOperand toUpper = SplitIntoUpperHalf(pm->to()); + pm->overwrite(fromUpper, toUpper, MoveOp::FLOAT32); + } + } +#endif + InlineList<PendingMove> stack; // This is a depth-first-search without recursion, which tries to find diff --git a/js/src/jit/MoveResolver.h b/js/src/jit/MoveResolver.h index fad2ba9e3..db045cfcf 100644 --- a/js/src/jit/MoveResolver.h +++ b/js/src/jit/MoveResolver.h @@ -252,6 +252,13 @@ class MoveOp bool aliases(const MoveOp& other) const { return aliases(other.from()) || aliases(other.to()); } +#ifdef JS_CODEGEN_ARM + void overwrite(MoveOperand& from, MoveOperand& to, Type type) { + from_ = from; + to_ = to; + type_ = type; + } +#endif }; class MoveResolver @@ -299,6 +306,10 @@ class MoveResolver // Internal reset function. Does not clear lists. void resetState(); +#ifdef JS_CODEGEN_ARM + bool isDoubleAliasedAsSingle(const MoveOperand& move); +#endif + public: MoveResolver(); diff --git a/js/src/jsapi-tests/testJitMoveEmitterCycles.cpp b/js/src/jsapi-tests/testJitMoveEmitterCycles.cpp index 416587293..c1c2baddd 100644 --- a/js/src/jsapi-tests/testJitMoveEmitterCycles.cpp +++ b/js/src/jsapi-tests/testJitMoveEmitterCycles.cpp @@ -6,6 +6,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #if defined(JS_SIMULATOR_ARM) + #include "jit/arm/Assembler-arm.h" #include "jit/arm/MoveEmitter-arm.h" #include "jit/arm/Simulator-arm.h" @@ -528,5 +529,96 @@ BEGIN_TEST(testJitMoveEmitterCycles_autogen3) return true; } END_TEST(testJitMoveEmitterCycles_autogen3) +BEGIN_TEST(testJitMoveEmitterCycles_bug1299147_1) +{ + using namespace js; + using namespace js::jit; + LifoAlloc lifo(LIFO_ALLOC_PRIMARY_CHUNK_SIZE); + TempAllocator alloc(&lifo); + JitContext jc(cx, &alloc); + cx->runtime()->getJitRuntime(cx); + MacroAssembler masm; + MoveEmitter mover(masm); + MoveResolver mr; + mr.setAllocator(alloc); + Simulator* sim = Simulator::Current(); + // S2 -> S0 + // S2 -> S6 + // S3 -> S1 + // S3 -> S7 + // D0 -> D1 + // D0 -> D2 + TRY(mr.addMove(MoveOperand(s2), MoveOperand(s0), MoveOp::FLOAT32)); + TRY(mr.addMove(MoveOperand(s2), MoveOperand(s6), MoveOp::FLOAT32)); + sim->set_s_register_from_float(2, 2); + TRY(mr.addMove(MoveOperand(s3), MoveOperand(s1), MoveOp::FLOAT32)); + TRY(mr.addMove(MoveOperand(s3), MoveOperand(s7), MoveOp::FLOAT32)); + sim->set_s_register_from_float(3, 4); + TRY(mr.addMove(MoveOperand(d0), MoveOperand(d1), MoveOp::FLOAT32)); + TRY(mr.addMove(MoveOperand(d0), MoveOperand(d2), MoveOp::FLOAT32)); + sim->set_d_register_from_double(0, 1); + // don't explode! + TRY(mr.resolve()); + mover.emit(mr); + mover.finish(); + masm.abiret(); + JitCode* code = linkAndAllocate(cx, &masm); + sim->call(code->raw(), 1, 1); + float f; + double d; + sim->get_double_from_d_register(1, &d); + CHECK(d == 1); + sim->get_double_from_d_register(2, &d); + CHECK(d == 1); + sim->get_float_from_s_register(0, &f); + CHECK(int(f) == 2); + sim->get_float_from_s_register(6, &f); + CHECK(int(f) == 2); + sim->get_float_from_s_register(1, &f); + CHECK(int(f) == 4); + sim->get_float_from_s_register(7, &f); + CHECK(int(f) == 4); + return true; +} +END_TEST(testJitMoveEmitterCycles_bug1299147_1) +BEGIN_TEST(testJitMoveEmitterCycles_bug1299147) +{ + using namespace js; + using namespace js::jit; + LifoAlloc lifo(LIFO_ALLOC_PRIMARY_CHUNK_SIZE); + TempAllocator alloc(&lifo); + JitContext jc(cx, &alloc); + cx->runtime()->getJitRuntime(cx); + MacroAssembler masm; + MoveEmitter mover(masm); + MoveResolver mr; + mr.setAllocator(alloc); + Simulator* sim = Simulator::Current(); + // S2 -> S5 + // S2 -> S6 + // D0 -> D1 + TRY(mr.addMove(MoveOperand(s2), MoveOperand(s5), MoveOp::FLOAT32)); + TRY(mr.addMove(MoveOperand(s2), MoveOperand(s6), MoveOp::FLOAT32)); + sim->set_s_register_from_float(2, 2); + TRY(mr.addMove(MoveOperand(d0), MoveOperand(d1), MoveOp::FLOAT32)); + sim->set_d_register_from_double(0, 1); + // don't explode! + TRY(mr.resolve()); + mover.emit(mr); + mover.finish(); + masm.abiret(); + JitCode* code = linkAndAllocate(cx, &masm); + sim->call(code->raw(), 1, 1); + float f; + double d; + sim->get_double_from_d_register(1, &d); + CHECK(d == 1); + sim->get_float_from_s_register(5, &f); + CHECK(int(f) == 2); + sim->get_float_from_s_register(6, &f); + CHECK(int(f) == 2); + return true; +} +END_TEST(testJitMoveEmitterCycles_bug1299147) -#endif +#endif // JS_SIMULATOR_ARM diff --git a/mfbt/Vector.h b/mfbt/Vector.h index fc43afcf1..07e370426 100644 --- a/mfbt/Vector.h +++ b/mfbt/Vector.h @@ -1232,10 +1232,10 @@ Vector<T, N, AP>::insert(T* aP, U&& aVal) } } else { T oldBack = Move(back()); - if (!append(Move(oldBack))) { /* Dup the last element. */ + if (!append(Move(oldBack))) { return nullptr; } - for (size_t i = oldLength; i > pos; --i) { + for (size_t i = oldLength - 1; i > pos; --i) { (*this)[i] = Move((*this)[i - 1]); } (*this)[pos] = Forward<U>(aVal); diff --git a/mfbt/tests/TestVector.cpp b/mfbt/tests/TestVector.cpp index d969bcbc2..e28b432d6 100644 --- a/mfbt/tests/TestVector.cpp +++ b/mfbt/tests/TestVector.cpp @@ -22,6 +22,7 @@ struct mozilla::detail::VectorTesting static void testReverse(); static void testExtractRawBuffer(); static void testExtractOrCopyRawBuffer(); + static void testInsert(); }; void @@ -141,6 +142,15 @@ struct S destructCount++; } + S& operator=(S&& rhs) { + j = rhs.j; + rhs.j = 0; + k = Move(rhs.k); + rhs.k.reset(); + moveCount++; + return *this; + } + S(const S&) = delete; S& operator=(const S&) = delete; }; @@ -346,6 +356,47 @@ mozilla::detail::VectorTesting::testExtractOrCopyRawBuffer() free(buf); } +void +mozilla::detail::VectorTesting::testInsert() +{ + S::resetCounts(); + + Vector<S, 8> vec; + MOZ_RELEASE_ASSERT(vec.reserve(8)); + for (size_t i = 0; i < 7; i++) { + vec.infallibleEmplaceBack(i, i * i); + } + + MOZ_RELEASE_ASSERT(vec.length() == 7); + MOZ_ASSERT(vec.reserved() == 8); + MOZ_RELEASE_ASSERT(S::constructCount == 7); + MOZ_RELEASE_ASSERT(S::moveCount == 0); + MOZ_RELEASE_ASSERT(S::destructCount == 0); + + S s(42, 43); + MOZ_RELEASE_ASSERT(vec.insert(vec.begin() + 4, Move(s))); + + for (size_t i = 0; i < vec.length(); i++) { + const S& s = vec[i]; + MOZ_RELEASE_ASSERT(s.k); + if (i < 4) { + MOZ_RELEASE_ASSERT(s.j == i && *s.k == i * i); + } else if (i == 4) { + MOZ_RELEASE_ASSERT(s.j == 42 && *s.k == 43); + } else { + MOZ_RELEASE_ASSERT(s.j == i - 1 && *s.k == (i - 1) * (i - 1)); + } + } + + MOZ_RELEASE_ASSERT(vec.length() == 8); + MOZ_ASSERT(vec.reserved() == 8); + MOZ_RELEASE_ASSERT(S::constructCount == 8); + MOZ_RELEASE_ASSERT(S::moveCount == 1 /* move in insert() call */ + + 1 /* move the back() element */ + + 3 /* elements to shift */); + MOZ_RELEASE_ASSERT(S::destructCount == 1); +} + int main() { @@ -355,4 +406,5 @@ main() VectorTesting::testReverse(); VectorTesting::testExtractRawBuffer(); VectorTesting::testExtractOrCopyRawBuffer(); + VectorTesting::testInsert(); } diff --git a/mobile/android/base/java/org/mozilla/gecko/IntentHelper.java b/mobile/android/base/java/org/mozilla/gecko/IntentHelper.java index efe9576d7..e2f34f926 100644 --- a/mobile/android/base/java/org/mozilla/gecko/IntentHelper.java +++ b/mobile/android/base/java/org/mozilla/gecko/IntentHelper.java @@ -287,6 +287,12 @@ public final class IntentHelper implements GeckoEventListener, return null; } + final Uri data = intent.getData(); + if (data != null && "file".equals(data.normalizeScheme().getScheme())) { + Log.w(LOGTAG, "Blocked intent with \"file://\" data scheme."); + return null; + } + // Only open applications which can accept arbitrary data from a browser. intent.addCategory(Intent.CATEGORY_BROWSABLE); diff --git a/toolkit/components/feeds/FeedProcessor.js b/toolkit/components/feeds/FeedProcessor.js index 88d0ad6ed..51b6b13c9 100644 --- a/toolkit/components/feeds/FeedProcessor.js +++ b/toolkit/components/feeds/FeedProcessor.js @@ -637,7 +637,8 @@ TextConstruct.prototype = { else return null; - return this.parserUtils.parseFragment(this.text, 0, isXML, + let flags = Ci.nsIParserUtils.SanitizerDropForms; + return this.parserUtils.parseFragment(this.text, flags, isXML, this.base, element); }, diff --git a/toolkit/moz.configure b/toolkit/moz.configure index 1a8c5b1bb..85a01e658 100644 --- a/toolkit/moz.configure +++ b/toolkit/moz.configure @@ -825,27 +825,3 @@ def skia_includes(skia, skia_gpu): return includes set_config('SKIA_INCLUDES', skia_includes) - -# Support various fuzzing options -# ============================================================== -with only_when('--enable-compile-environment'): - option('--enable-fuzzing', help='Enable fuzzing support') - - @depends('--enable-fuzzing') - def enable_fuzzing(value): - if value: - return True - - @depends(enable_fuzzing, - try_compile(body='__AFL_COMPILER;', - check_msg='for AFL compiler', - when='--enable-fuzzing')) - def enable_libfuzzer(fuzzing, afl): - if fuzzing and not afl: - return True - - set_config('FUZZING', enable_fuzzing) - set_define('FUZZING', enable_fuzzing) - - set_config('LIBFUZZER', enable_libfuzzer) - set_define('LIBFUZZER', enable_libfuzzer) |