Merge remote-tracking branch 'origin/master' into custom

This commit is contained in:
Roy Tam 2019-03-23 06:56:07 +08:00
commit b186b7ea74
24 changed files with 230 additions and 248 deletions

View file

@ -57,6 +57,9 @@ pref("@GUAO_PREF@.www.amazon.com","Mozilla/5.0 (@OS_SLICE@ rv:45.9) @GK_SLICE@ F
pref("@GUAO_PREF@.soundcloud.com","Mozilla/5.0 (@OS_SLICE@ rv:@GRE_VERSION@) @GRE_DATE_SLICE@ @PM_SLICE@"); pref("@GUAO_PREF@.soundcloud.com","Mozilla/5.0 (@OS_SLICE@ rv:@GRE_VERSION@) @GRE_DATE_SLICE@ @PM_SLICE@");
// Daily motion only likes strict Firefox UAs // Daily motion only likes strict Firefox UAs
pref("@GUAO_PREF@.dailymotion.com","Mozilla/5.0 (@OS_SLICE@ rv:52.0) @GK_SLICE@ Firefox/52.0"); pref("@GUAO_PREF@.dailymotion.com","Mozilla/5.0 (@OS_SLICE@ rv:52.0) @GK_SLICE@ Firefox/52.0");
// Financial Times' polyfill.io breaks horribly on a Pale Moon UA. Send a strict Firefox UA instead.
pref("@GUAO_PREF@.polyfill.io","Mozilla/5.0 (@OS_SLICE@ rv:60.9) @GK_SLICE@ Firefox/60.9");
// The following requires native mode. Or it blocks.. "too old firefox", breakage, etc. // The following requires native mode. Or it blocks.. "too old firefox", breakage, etc.
pref("@GUAO_PREF@.deviantart.com","Mozilla/5.0 (@OS_SLICE@ rv:@GRE_VERSION@) @GRE_DATE_SLICE@ @PM_SLICE@"); pref("@GUAO_PREF@.deviantart.com","Mozilla/5.0 (@OS_SLICE@ rv:@GRE_VERSION@) @GRE_DATE_SLICE@ @PM_SLICE@");

View file

@ -1607,6 +1607,17 @@ richlistitem[type~="action"][actiontype="switchtab"] > .ac-url-box > .ac-action-
background-image: linear-gradient(to top, rgba(0,0,0,.3) 1px, rgba(0,0,0,.05) 1px, transparent 50%); background-image: linear-gradient(to top, rgba(0,0,0,.3) 1px, rgba(0,0,0,.05) 1px, transparent 50%);
} }
/* When the tab bar is collapsed, show a 1px border in its place. */
#TabsToolbar[collapsed="true"] {
visibility: visible;
height: 1px;
border-bottom-width: 1px;
/* !important here to override border-style: none on the toolbar */
border-bottom-style: solid !important;
border-bottom-color: ThreeDShadow;
overflow: hidden;
}
.tabbrowser-tab, .tabbrowser-tab,
.tabs-newtab-button { .tabs-newtab-button {
position: static; position: static;

View file

@ -1630,6 +1630,17 @@ richlistitem[type~="action"][actiontype="switchtab"][selected="true"] > .ac-url-
background-image: linear-gradient(to top, @toolbarShadowColor@ 1px, rgba(0,0,0,.05) 1px, transparent 50%); background-image: linear-gradient(to top, @toolbarShadowColor@ 1px, rgba(0,0,0,.05) 1px, transparent 50%);
} }
/* When the tab bar is collapsed, show a 1px border in its place. */
#TabsToolbar[collapsed="true"] {
visibility: visible;
height: 1px;
border-bottom-width: 1px;
/* !important here to override border-style: none on the toolbar */
border-bottom-style: solid !important;
border-bottom-color: ThreeDShadow;
overflow: hidden;
}
@media (-moz-mac-lion-theme) { @media (-moz-mac-lion-theme) {
#main-window[sizemode=normal] #TabsToolbar { #main-window[sizemode=normal] #TabsToolbar {
padding-left: 2px; padding-left: 2px;

View file

@ -31,6 +31,8 @@
%endif %endif
:root { :root {
--toolbox-after-color: ThreeDShadow;
--toolbar-custom-color: hsl(210,75%,92%); --toolbar-custom-color: hsl(210,75%,92%);
--toolbar-highlight-top: rgba(255,255,255,.5); --toolbar-highlight-top: rgba(255,255,255,.5);
--toolbar-highlight-bottom: transparent; --toolbar-highlight-bottom: transparent;
@ -91,7 +93,7 @@
display: -moz-box; display: -moz-box;
-moz-box-ordinal-group: 101; /* tabs toolbar is 100 */ -moz-box-ordinal-group: 101; /* tabs toolbar is 100 */
height: 1px; height: 1px;
background-color: ThreeDShadow; background-color: var(--toolbox-after-color);
} }
#navigator-toolbox[tabsontop=false]::after, #navigator-toolbox[tabsontop=false]::after,
#main-window[disablechrome] #navigator-toolbox::after { #main-window[disablechrome] #navigator-toolbox::after {
@ -1841,6 +1843,17 @@ richlistitem[type~="action"][actiontype="switchtab"] > .ac-url-box > .ac-action-
background-image: linear-gradient(to top, @toolbarShadowColor@ 1px, rgba(0,0,0,.05) 1px, transparent 50%); background-image: linear-gradient(to top, @toolbarShadowColor@ 1px, rgba(0,0,0,.05) 1px, transparent 50%);
} }
/* When the tab bar is collapsed, show a 1px border in its place. */
#TabsToolbar[collapsed="true"] {
visibility: visible;
height: 1px;
border-bottom-width: 1px;
/* !important here to override border-style: none on the toolbar */
border-bottom-style: solid !important;
border-bottom-color: var(--toolbox-after-color);
overflow: hidden;
}
.tabbrowser-tab, .tabbrowser-tab,
.tabs-newtab-button { .tabs-newtab-button {
-moz-appearance: none; -moz-appearance: none;
@ -3044,8 +3057,8 @@ toolbar[brighttext] #addonbar-closebutton {
@media (-moz-os-version: windows-vista), @media (-moz-os-version: windows-vista),
(-moz-os-version: windows-win7) { (-moz-os-version: windows-win7) {
#navigator-toolbox:not(:-moz-lwtheme)::after { :root:not(:-moz-lwtheme) {
background-color: #aabccf; --toolbox-after-color: #aabccf;
} }
} }
@ -3055,8 +3068,8 @@ toolbar[brighttext] #addonbar-closebutton {
--toolbar-custom-color: hsl(210,0%,92%); --toolbar-custom-color: hsl(210,0%,92%);
} }
#navigator-toolbox:not(:-moz-lwtheme)::after { :root:not(:-moz-lwtheme) {
background-color: #bcbcbc; --toolbox-after-color: #bcbcbc;
} }
} }

View file

@ -6329,6 +6329,13 @@ CanvasRenderingContext2D::ShouldForceInactiveLayer(LayerManager* aManager)
return !aManager->CanUseCanvasLayerForSize(GetSize()); return !aManager->CanUseCanvasLayerForSize(GetSize());
} }
void CanvasRenderingContext2D::SetWriteOnly() {
mWriteOnly = true;
if (mCanvasElement) {
mCanvasElement->SetWriteOnly();
}
}
NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(CanvasPath, AddRef) NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(CanvasPath, AddRef)
NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(CanvasPath, Release) NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(CanvasPath, Release)

View file

@ -1156,9 +1156,7 @@ protected:
// For the origin-clean algorithm (mWriteOnly == !origin-clean) // For the origin-clean algorithm (mWriteOnly == !origin-clean)
// See https://html.spec.whatwg.org/multipage/imagebitmap-and-animations.html // See https://html.spec.whatwg.org/multipage/imagebitmap-and-animations.html
void SetWriteOnly() { void SetWriteOnly();
mWriteOnly = true;
}
bool IsWriteOnly() const { bool IsWriteOnly() const {
return mWriteOnly; return mWriteOnly;

View file

@ -421,11 +421,10 @@ HTMLTableElement::CreateTHead()
void void
HTMLTableElement::DeleteTHead() HTMLTableElement::DeleteTHead()
{ {
HTMLTableSectionElement* tHead = GetTHead(); RefPtr<HTMLTableSectionElement> tHead = GetTHead();
if (tHead) { if (tHead) {
mozilla::ErrorResult rv; mozilla::IgnoredErrorResult rv;
nsINode::RemoveChild(*tHead, rv); nsINode::RemoveChild(*tHead, rv);
MOZ_ASSERT(!rv.Failed());
} }
} }
@ -452,11 +451,10 @@ HTMLTableElement::CreateTFoot()
void void
HTMLTableElement::DeleteTFoot() HTMLTableElement::DeleteTFoot()
{ {
HTMLTableSectionElement* tFoot = GetTFoot(); RefPtr<HTMLTableSectionElement> tFoot = GetTFoot();
if (tFoot) { if (tFoot) {
mozilla::ErrorResult rv; mozilla::IgnoredErrorResult rv;
nsINode::RemoveChild(*tFoot, rv); nsINode::RemoveChild(*tFoot, rv);
MOZ_ASSERT(!rv.Failed());
} }
} }
@ -483,11 +481,10 @@ HTMLTableElement::CreateCaption()
void void
HTMLTableElement::DeleteCaption() HTMLTableElement::DeleteCaption()
{ {
HTMLTableCaptionElement* caption = GetCaption(); RefPtr<HTMLTableCaptionElement> caption = GetCaption();
if (caption) { if (caption) {
mozilla::ErrorResult rv; mozilla::IgnoredErrorResult rv;
nsINode::RemoveChild(*caption, rv); nsINode::RemoveChild(*caption, rv);
MOZ_ASSERT(!rv.Failed());
} }
} }

View file

@ -122,7 +122,7 @@ HTMLTableSectionElement::DeleteRow(int32_t aValue, ErrorResult& aError)
refIndex = (uint32_t)aValue; refIndex = (uint32_t)aValue;
} }
nsINode* row = rows->Item(refIndex); nsCOMPtr<nsINode> row = rows->Item(refIndex);
if (!row) { if (!row) {
aError.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR); aError.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
return; return;

View file

@ -233,7 +233,7 @@ void
nsSMILAnimationController::NotifyRefreshDriverCreated( nsSMILAnimationController::NotifyRefreshDriverCreated(
nsRefreshDriver* aRefreshDriver) nsRefreshDriver* aRefreshDriver)
{ {
if (!mPauseState) { if (!mPauseState && mChildContainerTable.Count()) {
MaybeStartSampling(aRefreshDriver); MaybeStartSampling(aRefreshDriver);
} }
} }

View file

@ -567,8 +567,11 @@ class MOZ_NON_PARAM alignas(8) Value
} }
bool isMagic(JSWhyMagic why) const { bool isMagic(JSWhyMagic why) const {
MOZ_ASSERT_IF(isMagic(), data.s.payload.why == why); if (!isMagic()) {
return isMagic(); return false;
}
MOZ_RELEASE_ASSERT(data.s.payload.why == why);
return true;
} }
JS::TraceKind traceKind() const { JS::TraceKind traceKind() const {

View file

@ -210,6 +210,7 @@ js::Nursery::disable()
return; return;
updateNumChunks(0); updateNumChunks(0);
currentEnd_ = 0; currentEnd_ = 0;
position_ = 0;
runtime()->gc.storeBuffer.disable(); runtime()->gc.storeBuffer.disable();
} }

View file

@ -245,6 +245,7 @@ class Nursery
// Free space remaining, not counting chunk trailers. // Free space remaining, not counting chunk trailers.
MOZ_ALWAYS_INLINE size_t freeSpace() const { MOZ_ALWAYS_INLINE size_t freeSpace() const {
MOZ_ASSERT(isEnabled());
MOZ_ASSERT(currentEnd_ - position_ <= NurseryChunkUsableSize); MOZ_ASSERT(currentEnd_ - position_ <= NurseryChunkUsableSize);
return (currentEnd_ - position_) + return (currentEnd_ - position_) +
(numChunks() - currentChunk_ - 1) * NurseryChunkUsableSize; (numChunks() - currentChunk_ - 1) * NurseryChunkUsableSize;

View file

@ -222,7 +222,7 @@ DefaultJitOptions::DefaultJitOptions()
} }
// Toggles whether unboxed plain objects can be created by the VM. // Toggles whether unboxed plain objects can be created by the VM.
SET_DEFAULT(disableUnboxedObjects, false); SET_DEFAULT(disableUnboxedObjects, true);
// Test whether Atomics are allowed in asm.js code. // Test whether Atomics are allowed in asm.js code.
SET_DEFAULT(asmJSAtomicsEnable, false); SET_DEFAULT(asmJSAtomicsEnable, false);

View file

@ -6410,6 +6410,9 @@ JS_SetGlobalJitCompilerOption(JSContext* cx, JSJitCompilerOption opt, uint32_t v
} }
jit::JitOptions.jumpThreshold = value; jit::JitOptions.jumpThreshold = value;
break; break;
case JSJITCOMPILER_UNBOXED_OBJECTS:
jit::JitOptions.disableUnboxedObjects = !value;
break;
case JSJITCOMPILER_ASMJS_ATOMICS_ENABLE: case JSJITCOMPILER_ASMJS_ATOMICS_ENABLE:
jit::JitOptions.asmJSAtomicsEnable = !!value; jit::JitOptions.asmJSAtomicsEnable = !!value;
break; break;

View file

@ -5783,19 +5783,20 @@ JS_SetParallelParsingEnabled(JSContext* cx, bool enabled);
extern JS_PUBLIC_API(void) extern JS_PUBLIC_API(void)
JS_SetOffthreadIonCompilationEnabled(JSContext* cx, bool enabled); JS_SetOffthreadIonCompilationEnabled(JSContext* cx, bool enabled);
#define JIT_COMPILER_OPTIONS(Register) \ #define JIT_COMPILER_OPTIONS(Register) \
Register(BASELINE_WARMUP_TRIGGER, "baseline.warmup.trigger") \ Register(BASELINE_WARMUP_TRIGGER, "baseline.warmup.trigger") \
Register(ION_WARMUP_TRIGGER, "ion.warmup.trigger") \ Register(ION_WARMUP_TRIGGER, "ion.warmup.trigger") \
Register(ION_GVN_ENABLE, "ion.gvn.enable") \ Register(ION_GVN_ENABLE, "ion.gvn.enable") \
Register(ION_FORCE_IC, "ion.forceinlineCaches") \ Register(ION_FORCE_IC, "ion.forceinlineCaches") \
Register(ION_ENABLE, "ion.enable") \ Register(ION_ENABLE, "ion.enable") \
Register(ION_INTERRUPT_WITHOUT_SIGNAL, "ion.interrupt-without-signals") \ Register(ION_INTERRUPT_WITHOUT_SIGNAL, "ion.interrupt-without-signals") \
Register(ION_CHECK_RANGE_ANALYSIS, "ion.check-range-analysis") \ Register(ION_CHECK_RANGE_ANALYSIS, "ion.check-range-analysis") \
Register(BASELINE_ENABLE, "baseline.enable") \ Register(BASELINE_ENABLE, "baseline.enable") \
Register(OFFTHREAD_COMPILATION_ENABLE, "offthread-compilation.enable") \ Register(OFFTHREAD_COMPILATION_ENABLE, "offthread-compilation.enable") \
Register(JUMP_THRESHOLD, "jump-threshold") \ Register(JUMP_THRESHOLD, "jump-threshold") \
Register(ASMJS_ATOMICS_ENABLE, "asmjs.atomics.enable") \ Register(UNBOXED_OBJECTS, "unboxed_objects") \
Register(WASM_TEST_MODE, "wasm.test-mode") \ Register(ASMJS_ATOMICS_ENABLE, "asmjs.atomics.enable") \
Register(WASM_TEST_MODE, "wasm.test-mode") \
Register(WASM_FOLD_OFFSETS, "wasm.fold-offsets") Register(WASM_FOLD_OFFSETS, "wasm.fold-offsets")
typedef enum JSJitCompilerOption { typedef enum JSJitCompilerOption {

View file

@ -288,6 +288,12 @@ CallerGetterImpl(JSContext* cx, const CallArgs& args)
return true; return true;
} }
if (JS_IsDeadWrapper(callerObj)) {
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
JSMSG_DEAD_OBJECT);
return false;
}
JSFunction* callerFun = &callerObj->as<JSFunction>(); JSFunction* callerFun = &callerObj->as<JSFunction>();
MOZ_ASSERT(!callerFun->isBuiltin(), "non-builtin iterator returned a builtin?"); MOZ_ASSERT(!callerFun->isBuiltin(), "non-builtin iterator returned a builtin?");
@ -314,54 +320,14 @@ CallerSetterImpl(JSContext* cx, const CallArgs& args)
{ {
MOZ_ASSERT(IsFunction(args.thisv())); MOZ_ASSERT(IsFunction(args.thisv()));
// Beware! This function can be invoked on *any* function! It can't // We just have to return |undefined|, but first we call CallerGetterImpl
// assume it'll never be invoked on natives, strict mode functions, bound // because we need the same strict-mode and security checks.
// functions, or anything else that ordinarily has immutable .caller
// defined with [[ThrowTypeError]]. if (!CallerGetterImpl(cx, args)) {
RootedFunction fun(cx, &args.thisv().toObject().as<JSFunction>()); return false;
if (!CallerRestrictions(cx, fun)) }
return false;
// Return |undefined| unless an error must be thrown.
args.rval().setUndefined(); args.rval().setUndefined();
// We can almost just return |undefined| here -- but if the caller function
// was strict mode code, we still have to throw a TypeError. This requires
// computing the caller, checking that no security boundaries are crossed,
// and throwing a TypeError if the resulting caller is strict.
NonBuiltinScriptFrameIter iter(cx);
if (!AdvanceToActiveCallLinear(cx, iter, fun))
return true;
++iter;
while (!iter.done() && iter.isEvalFrame())
++iter;
if (iter.done() || !iter.isFunctionFrame())
return true;
RootedObject caller(cx, iter.callee(cx));
if (!cx->compartment()->wrap(cx, &caller)) {
cx->clearPendingException();
return true;
}
// If we don't have full access to the caller, or the caller is not strict,
// return undefined. Otherwise throw a TypeError.
JSObject* callerObj = CheckedUnwrap(caller);
if (!callerObj)
return true;
JSFunction* callerFun = &callerObj->as<JSFunction>();
MOZ_ASSERT(!callerFun->isBuiltin(), "non-builtin iterator returned a builtin?");
if (callerFun->strict()) {
JS_ReportErrorFlagsAndNumberASCII(cx, JSREPORT_ERROR, GetErrorMessage, nullptr,
JSMSG_CALLER_IS_STRICT);
return false;
}
return true; return true;
} }

View file

@ -1427,6 +1427,8 @@ ReloadPrefsCallback(const char* pref, void* data)
bool extraWarnings = Preferences::GetBool(JS_OPTIONS_DOT_STR "strict"); bool extraWarnings = Preferences::GetBool(JS_OPTIONS_DOT_STR "strict");
bool unboxedObjects = Preferences::GetBool(JS_OPTIONS_DOT_STR "unboxed_objects");
sSharedMemoryEnabled = Preferences::GetBool(JS_OPTIONS_DOT_STR "shared_memory"); sSharedMemoryEnabled = Preferences::GetBool(JS_OPTIONS_DOT_STR "shared_memory");
#ifdef DEBUG #ifdef DEBUG
@ -1455,6 +1457,8 @@ ReloadPrefsCallback(const char* pref, void* data)
useBaselineEager ? 0 : -1); useBaselineEager ? 0 : -1);
JS_SetGlobalJitCompilerOption(cx, JSJITCOMPILER_ION_WARMUP_TRIGGER, JS_SetGlobalJitCompilerOption(cx, JSJITCOMPILER_ION_WARMUP_TRIGGER,
useIonEager ? 0 : -1); useIonEager ? 0 : -1);
JS_SetGlobalJitCompilerOption(cx, JSJITCOMPILER_UNBOXED_OBJECTS,
unboxedObjects);
} }
XPCJSContext::~XPCJSContext() XPCJSContext::~XPCJSContext()

View file

@ -212,7 +212,7 @@ public:
return *this; return *this;
} }
T& operator[](int aIndex) const T& operator[](ptrdiff_t aIndex) const
{ {
MOZ_ASSERT(size_t(aIndex > 0 ? aIndex : -aIndex) <= size_t(-1) / sizeof(T)); MOZ_ASSERT(size_t(aIndex > 0 ? aIndex : -aIndex) <= size_t(-1) / sizeof(T));
return *create(mPtr + aIndex); return *create(mPtr + aIndex);

View file

@ -1264,6 +1264,7 @@ pref("javascript.options.strict", false);
#ifdef DEBUG #ifdef DEBUG
pref("javascript.options.strict.debug", false); pref("javascript.options.strict.debug", false);
#endif #endif
pref("javascript.options.unboxed_objects", false);
pref("javascript.options.baselinejit", true); pref("javascript.options.baselinejit", true);
pref("javascript.options.ion", true); pref("javascript.options.ion", true);
pref("javascript.options.asmjs", true); pref("javascript.options.asmjs", true);

View file

@ -23,6 +23,7 @@
#include "nsNetCID.h" #include "nsNetCID.h"
#include "nsServiceManagerUtils.h" #include "nsServiceManagerUtils.h"
#include "nsComponentManagerUtils.h" #include "nsComponentManagerUtils.h"
#include "nsSocketTransport2.h"
namespace mozilla { namespace mozilla {
namespace net { namespace net {
@ -42,6 +43,7 @@ TLSFilterTransaction::TLSFilterTransaction(nsAHttpTransaction *aWrapped,
, mSegmentReader(aReader) , mSegmentReader(aReader)
, mSegmentWriter(aWriter) , mSegmentWriter(aWriter)
, mForce(false) , mForce(false)
, mReadSegmentReturnValue(NS_OK)
, mNudgeCounter(0) , mNudgeCounter(0)
{ {
MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread); MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
@ -130,6 +132,19 @@ TLSFilterTransaction::Close(nsresult aReason)
} }
mTransaction->Close(aReason); mTransaction->Close(aReason);
mTransaction = nullptr; mTransaction = nullptr;
RefPtr<NullHttpTransaction> baseTrans(do_QueryReferent(mWeakTrans));
SpdyConnectTransaction *trans = baseTrans
? baseTrans->QuerySpdyConnectTransaction()
: nullptr;
LOG(("TLSFilterTransaction::Close %p aReason=%" PRIx32 " trans=%p\n",
this, static_cast<uint32_t>(aReason), trans));
if (trans) {
trans->Close(aReason);
trans = nullptr;
}
} }
nsresult nsresult
@ -140,7 +155,7 @@ TLSFilterTransaction::OnReadSegment(const char *aData,
LOG(("TLSFilterTransaction %p OnReadSegment %d (buffered %d)\n", LOG(("TLSFilterTransaction %p OnReadSegment %d (buffered %d)\n",
this, aCount, mEncryptedTextUsed)); this, aCount, mEncryptedTextUsed));
mReadSegmentBlocked = false; mReadSegmentReturnValue = NS_OK;
MOZ_ASSERT(mSegmentReader); MOZ_ASSERT(mSegmentReader);
if (!mSecInfo) { if (!mSecInfo) {
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
@ -188,10 +203,12 @@ TLSFilterTransaction::OnReadSegment(const char *aData,
return NS_OK; return NS_OK;
} }
// mTransaction ReadSegments actually obscures this code, so // mTransaction ReadSegments actually obscures this code, so
// keep it in a member var for this::ReadSegments to insepct. Similar // keep it in a member var for this::ReadSegments to inspect. Similar
// to nsHttpConnection::mSocketOutCondition // to nsHttpConnection::mSocketOutCondition
mReadSegmentBlocked = (PR_GetError() == PR_WOULD_BLOCK_ERROR); PRErrorCode code = PR_GetError();
return mReadSegmentBlocked ? NS_BASE_STREAM_WOULD_BLOCK : NS_ERROR_FAILURE; mReadSegmentReturnValue = ErrorAccordingToNSPR(code);
return mReadSegmentReturnValue;
} }
aCount -= written; aCount -= written;
aData += written; aData += written;
@ -273,10 +290,18 @@ TLSFilterTransaction::OnWriteSegment(char *aData,
mFilterReadCode = NS_OK; mFilterReadCode = NS_OK;
int32_t bytesRead = PR_Read(mFD, aData, aCount); int32_t bytesRead = PR_Read(mFD, aData, aCount);
if (bytesRead == -1) { if (bytesRead == -1) {
if (PR_GetError() == PR_WOULD_BLOCK_ERROR) { PRErrorCode code = PR_GetError();
if (code == PR_WOULD_BLOCK_ERROR) {
return NS_BASE_STREAM_WOULD_BLOCK; return NS_BASE_STREAM_WOULD_BLOCK;
} }
return NS_ERROR_FAILURE; // If reading from the socket succeeded (NS_SUCCEEDED(mFilterReadCode)),
// but the nss layer encountered an error remember the error.
if (NS_SUCCEEDED(mFilterReadCode)) {
mFilterReadCode = ErrorAccordingToNSPR(code);
LOG(("TLSFilterTransaction::OnWriteSegment %p nss error %" PRIx32 ".\n",
this, static_cast<uint32_t>(mFilterReadCode)));
}
return mFilterReadCode;
} }
*outCountRead = bytesRead; *outCountRead = bytesRead;
@ -303,7 +328,7 @@ TLSFilterTransaction::FilterInput(char *aBuf, int32_t aAmount)
if (NS_SUCCEEDED(mFilterReadCode) && outCountRead) { if (NS_SUCCEEDED(mFilterReadCode) && outCountRead) {
LOG(("TLSFilterTransaction::FilterInput rv=%x read=%d input from net " LOG(("TLSFilterTransaction::FilterInput rv=%x read=%d input from net "
"1 layer stripped, 1 still on\n", mFilterReadCode, outCountRead)); "1 layer stripped, 1 still on\n", mFilterReadCode, outCountRead));
if (mReadSegmentBlocked) { if (mReadSegmentReturnValue == NS_BASE_STREAM_WOULD_BLOCK) {
mNudgeCounter = 0; mNudgeCounter = 0;
} }
} }
@ -325,19 +350,18 @@ TLSFilterTransaction::ReadSegments(nsAHttpSegmentReader *aReader,
return NS_ERROR_UNEXPECTED; return NS_ERROR_UNEXPECTED;
} }
mReadSegmentBlocked = false; mReadSegmentReturnValue = NS_OK;
mSegmentReader = aReader; mSegmentReader = aReader;
nsresult rv = mTransaction->ReadSegments(this, aCount, outCountRead); nsresult rv = mTransaction->ReadSegments(this, aCount, outCountRead);
LOG(("TLSFilterTransaction %p called trans->ReadSegments rv=%x %d\n", LOG(("TLSFilterTransaction %p called trans->ReadSegments rv=%x %d\n",
this, rv, *outCountRead)); this, rv, *outCountRead));
if (NS_SUCCEEDED(rv) && mReadSegmentBlocked) { if (NS_SUCCEEDED(rv) && (mReadSegmentReturnValue == NS_BASE_STREAM_WOULD_BLOCK)) {
rv = NS_BASE_STREAM_WOULD_BLOCK;
LOG(("TLSFilterTransaction %p read segment blocked found rv=%x\n", LOG(("TLSFilterTransaction %p read segment blocked found rv=%x\n",
this, rv)); this, static_cast<uint32_t>(rv)));
Connection()->ForceSend(); Connection()->ForceSend();
} }
return rv; return NS_SUCCEEDED(rv) ? mReadSegmentReturnValue : rv;
} }
nsresult nsresult
@ -442,7 +466,10 @@ TLSFilterTransaction::Notify(nsITimer *timer)
if (timer != mTimer) { if (timer != mTimer) {
return NS_ERROR_UNEXPECTED; return NS_ERROR_UNEXPECTED;
} }
StartTimerCallback(); nsresult rv = StartTimerCallback();
if (NS_FAILED(rv)) {
Close(rv);
}
return NS_OK; return NS_OK;
} }
@ -456,7 +483,7 @@ TLSFilterTransaction::StartTimerCallback()
// This class can be called re-entrantly, so cleanup m* before ->on() // This class can be called re-entrantly, so cleanup m* before ->on()
RefPtr<NudgeTunnelCallback> cb(mNudgeCallback); RefPtr<NudgeTunnelCallback> cb(mNudgeCallback);
mNudgeCallback = nullptr; mNudgeCallback = nullptr;
cb->OnTunnelNudged(this); return cb->OnTunnelNudged(this);
} }
return NS_OK; return NS_OK;
} }
@ -675,10 +702,12 @@ TLSFilterTransaction::TakeSubTransactions(
} }
nsresult nsresult
TLSFilterTransaction::SetProxiedTransaction(nsAHttpTransaction *aTrans) TLSFilterTransaction::SetProxiedTransaction(nsAHttpTransaction *aTrans,
nsAHttpTransaction *aSpdyConnectTransaction)
{ {
LOG(("TLSFilterTransaction::SetProxiedTransaction [this=%p] aTrans=%p\n", LOG(("TLSFilterTransaction::SetProxiedTransaction [this=%p] aTrans=%p, "
this, aTrans)); "aSpdyConnectTransaction=%p\n",
this, aTrans, aSpdyConnectTransaction));
mTransaction = aTrans; mTransaction = aTrans;
nsCOMPtr<nsIInterfaceRequestor> callbacks; nsCOMPtr<nsIInterfaceRequestor> callbacks;
@ -688,6 +717,8 @@ TLSFilterTransaction::SetProxiedTransaction(nsAHttpTransaction *aTrans)
secCtrl->SetNotificationCallbacks(callbacks); secCtrl->SetNotificationCallbacks(callbacks);
} }
mWeakTrans = do_GetWeakReference(aSpdyConnectTransaction);
return NS_OK; return NS_OK;
} }
@ -1075,7 +1106,7 @@ SpdyConnectTransaction::MapStreamToHttpConnection(nsISocketTransport *aTransport
if (mForcePlainText) { if (mForcePlainText) {
mTunneledConn->ForcePlainText(); mTunneledConn->ForcePlainText();
} else { } else {
mTunneledConn->SetupSecondaryTLS(); mTunneledConn->SetupSecondaryTLS(this);
mTunneledConn->SetInSpdyTunnel(true); mTunneledConn->SetInSpdyTunnel(true);
} }

View file

@ -93,10 +93,11 @@ class TLSFilterTransaction;
class NudgeTunnelCallback : public nsISupports class NudgeTunnelCallback : public nsISupports
{ {
public: public:
virtual void OnTunnelNudged(TLSFilterTransaction *) = 0; virtual nsresult OnTunnelNudged(TLSFilterTransaction *) = 0;
}; };
#define NS_DECL_NUDGETUNNELCALLBACK void OnTunnelNudged(TLSFilterTransaction *) override; #define NS_DECL_NUDGETUNNELCALLBACK \
nsresult OnTunnelNudged(TLSFilterTransaction *) override;
class TLSFilterTransaction final class TLSFilterTransaction final
: public nsAHttpTransaction : public nsAHttpTransaction
@ -121,7 +122,8 @@ public:
nsresult CommitToSegmentSize(uint32_t size, bool forceCommitment) override; nsresult CommitToSegmentSize(uint32_t size, bool forceCommitment) override;
nsresult GetTransactionSecurityInfo(nsISupports **) override; nsresult GetTransactionSecurityInfo(nsISupports **) override;
nsresult NudgeTunnel(NudgeTunnelCallback *callback); nsresult NudgeTunnel(NudgeTunnelCallback *callback);
nsresult SetProxiedTransaction(nsAHttpTransaction *aTrans); MOZ_MUST_USE nsresult SetProxiedTransaction(nsAHttpTransaction *aTrans,
nsAHttpTransaction *aSpdyConnectTransaction = nullptr);
void newIODriver(nsIAsyncInputStream *aSocketIn, void newIODriver(nsIAsyncInputStream *aSocketIn,
nsIAsyncOutputStream *aSocketOut, nsIAsyncOutputStream *aSocketOut,
nsIAsyncInputStream **outSocketIn, nsIAsyncInputStream **outSocketIn,
@ -153,6 +155,7 @@ private:
private: private:
RefPtr<nsAHttpTransaction> mTransaction; RefPtr<nsAHttpTransaction> mTransaction;
nsWeakPtr mWeakTrans; // SpdyConnectTransaction *
nsCOMPtr<nsISupports> mSecInfo; nsCOMPtr<nsISupports> mSecInfo;
nsCOMPtr<nsITimer> mTimer; nsCOMPtr<nsITimer> mTimer;
RefPtr<NudgeTunnelCallback> mNudgeCallback; RefPtr<NudgeTunnelCallback> mNudgeCallback;
@ -168,7 +171,7 @@ private:
nsresult mFilterReadCode; nsresult mFilterReadCode;
bool mForce; bool mForce;
bool mReadSegmentBlocked; nsresult mReadSegmentReturnValue;
uint32_t mNudgeCounter; uint32_t mNudgeCounter;
}; };

View file

@ -535,16 +535,16 @@ npnComplete:
return true; return true;
} }
void nsresult
nsHttpConnection::OnTunnelNudged(TLSFilterTransaction *trans) nsHttpConnection::OnTunnelNudged(TLSFilterTransaction *trans)
{ {
MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread); MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
LOG(("nsHttpConnection::OnTunnelNudged %p\n", this)); LOG(("nsHttpConnection::OnTunnelNudged %p\n", this));
if (trans != mTLSFilter) { if (trans != mTLSFilter) {
return; return NS_OK;
} }
LOG(("nsHttpConnection::OnTunnelNudged %p Calling OnSocketWritable\n", this)); LOG(("nsHttpConnection::OnTunnelNudged %p Calling OnSocketWritable\n", this));
OnSocketWritable(); return OnSocketWritable();
} }
// called on the socket thread // called on the socket thread
@ -639,7 +639,9 @@ nsHttpConnection::Activate(nsAHttpTransaction *trans, uint32_t caps, int32_t pri
} }
if (mTLSFilter) { if (mTLSFilter) {
mTLSFilter->SetProxiedTransaction(trans); RefPtr<NullHttpTransaction> baseTrans(do_QueryReferent(mWeakTrans));
rv = mTLSFilter->SetProxiedTransaction(trans, baseTrans);
NS_ENSURE_SUCCESS(rv, rv);
mTransaction = mTLSFilter; mTransaction = mTLSFilter;
} }
@ -1979,7 +1981,7 @@ nsHttpConnection::OnSocketReadable()
// negotiation are known (which is determined from the write path). // negotiation are known (which is determined from the write path).
// If the server speaks SPDY it is likely the readable data here is // If the server speaks SPDY it is likely the readable data here is
// a spdy settings frame and without NPN it would be misinterpreted // a spdy settings frame and without NPN it would be misinterpreted
// as HTTP/* // as HTTP
LOG(("nsHttpConnection::OnSocketReadable %p return due to inactive " LOG(("nsHttpConnection::OnSocketReadable %p return due to inactive "
"tunnel setup but incomplete NPN state\n", this)); "tunnel setup but incomplete NPN state\n", this));
@ -2019,12 +2021,14 @@ nsHttpConnection::OnSocketReadable()
} }
void void
nsHttpConnection::SetupSecondaryTLS() nsHttpConnection::SetupSecondaryTLS(nsAHttpTransaction *aSpdyConnectTransaction)
{ {
MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread); MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
MOZ_ASSERT(!mTLSFilter); MOZ_ASSERT(!mTLSFilter);
LOG(("nsHttpConnection %p SetupSecondaryTLS %s %d\n", LOG(("nsHttpConnection %p SetupSecondaryTLS %s %d "
this, mConnInfo->Origin(), mConnInfo->OriginPort())); "aSpdyConnectTransaction=%p\n",
this, mConnInfo->Origin(), mConnInfo->OriginPort(),
aSpdyConnectTransaction));
nsHttpConnectionInfo *ci = nullptr; nsHttpConnectionInfo *ci = nullptr;
if (mTransaction) { if (mTransaction) {
@ -2041,6 +2045,7 @@ nsHttpConnection::SetupSecondaryTLS()
if (mTransaction) { if (mTransaction) {
mTransaction = mTLSFilter; mTransaction = mTLSFilter;
} }
mWeakTrans = do_GetWeakReference(aSpdyConnectTransaction);
} }
void void

View file

@ -202,7 +202,7 @@ public:
static nsresult MakeConnectString(nsAHttpTransaction *trans, static nsresult MakeConnectString(nsAHttpTransaction *trans,
nsHttpRequestHead *request, nsHttpRequestHead *request,
nsACString &result); nsACString &result);
void SetupSecondaryTLS(); void SetupSecondaryTLS(nsAHttpTransaction *aSpdyConnectTransaction = nullptr);
void SetInSpdyTunnel(bool arg); void SetInSpdyTunnel(bool arg);
// Check active connections for traffic (or not). SPDY connections send a // Check active connections for traffic (or not). SPDY connections send a
@ -281,6 +281,7 @@ private:
// transaction is open, otherwise it is null. // transaction is open, otherwise it is null.
RefPtr<nsAHttpTransaction> mTransaction; RefPtr<nsAHttpTransaction> mTransaction;
RefPtr<TLSFilterTransaction> mTLSFilter; RefPtr<TLSFilterTransaction> mTLSFilter;
nsWeakPtr mWeakTrans; // SpdyConnectTransaction *
RefPtr<nsHttpHandler> mHttpHandler; // keep gHttpHandler alive RefPtr<nsHttpHandler> mHttpHandler; // keep gHttpHandler alive

View file

@ -29,8 +29,6 @@
#define LOG(args) MOZ_LOG(mLog, mozilla::LogLevel::Debug, args) #define LOG(args) MOZ_LOG(mLog, mozilla::LogLevel::Debug, args)
// helper methods: forward declarations... // helper methods: forward declarations...
static nsresult GetExtensionFrom4xRegistryInfo(const nsACString& aMimeType,
nsString& aFileExtension);
static nsresult GetExtensionFromWindowsMimeDatabase(const nsACString& aMimeType, static nsresult GetExtensionFromWindowsMimeDatabase(const nsACString& aMimeType,
nsString& aFileExtension); nsString& aFileExtension);
@ -77,79 +75,45 @@ static nsresult GetExtensionFromWindowsMimeDatabase(const nsACString& aMimeType,
return NS_OK; return NS_OK;
} }
// We have a serious problem!! I have this content type and the windows registry only gives me
// helper apps based on extension. Right now, we really don't have a good place to go for
// trying to figure out the extension for a particular mime type....One short term hack is to look
// this information in 4.x (it's stored in the windows regsitry).
static nsresult GetExtensionFrom4xRegistryInfo(const nsACString& aMimeType,
nsString& aFileExtension)
{
nsCOMPtr<nsIWindowsRegKey> regKey =
do_CreateInstance("@mozilla.org/windows-registry-key;1");
if (!regKey)
return NS_ERROR_NOT_AVAILABLE;
nsresult rv = regKey->
Open(nsIWindowsRegKey::ROOT_KEY_CURRENT_USER,
NS_LITERAL_STRING("Software\\Netscape\\Netscape Navigator\\Suffixes"),
nsIWindowsRegKey::ACCESS_QUERY_VALUE);
if (NS_FAILED(rv))
return NS_ERROR_NOT_AVAILABLE;
rv = regKey->ReadStringValue(NS_ConvertASCIItoUTF16(aMimeType),
aFileExtension);
if (NS_FAILED(rv))
return NS_OK;
aFileExtension.Insert(char16_t('.'), 0);
// this may be a comma separated list of extensions...just take the
// first one for now...
int32_t pos = aFileExtension.FindChar(char16_t(','));
if (pos > 0) {
// we have a comma separated list of types...
// truncate everything after the first comma (including the comma)
aFileExtension.Truncate(pos);
}
return NS_OK;
}
nsresult nsOSHelperAppService::OSProtocolHandlerExists(const char * aProtocolScheme, bool * aHandlerExists) nsresult nsOSHelperAppService::OSProtocolHandlerExists(const char * aProtocolScheme, bool * aHandlerExists)
{ {
// look up the protocol scheme in the windows registry....if we find a match then we have a handler for it... // look up the protocol scheme in the windows registry....if we find a match then we have a handler for it...
*aHandlerExists = false; *aHandlerExists = false;
if (aProtocolScheme && *aProtocolScheme) if (aProtocolScheme && *aProtocolScheme)
{ {
// Vista: use new application association interface NS_ENSURE_TRUE(mAppAssoc, NS_ERROR_NOT_AVAILABLE);
if (mAppAssoc) { wchar_t * pResult = nullptr;
wchar_t * pResult = nullptr; NS_ConvertASCIItoUTF16 scheme(aProtocolScheme);
NS_ConvertASCIItoUTF16 scheme(aProtocolScheme); // We are responsible for freeing returned strings.
// We are responsible for freeing returned strings. HRESULT hr = mAppAssoc->QueryCurrentDefault(scheme.get(),
HRESULT hr = mAppAssoc->QueryCurrentDefault(scheme.get(), AT_URLPROTOCOL, AL_EFFECTIVE,
AT_URLPROTOCOL, AL_EFFECTIVE, &pResult);
&pResult); if (SUCCEEDED(hr)) {
if (SUCCEEDED(hr)) { CoTaskMemFree(pResult);
CoTaskMemFree(pResult); // Check the registry to see if it's a valid handler.
*aHandlerExists = true; nsCOMPtr<nsIWindowsRegKey> regKey = do_CreateInstance("@mozilla.org/windows-registry-key;1");
if (!regKey) {
return NS_ERROR_NOT_AVAILABLE;
} }
return NS_OK;
}
HKEY hKey; nsresult rv = regKey->Open(nsIWindowsRegKey::ROOT_KEY_CLASSES_ROOT,
LONG err = ::RegOpenKeyExW(HKEY_CLASSES_ROOT, nsDependentString(scheme.get()),
NS_ConvertASCIItoUTF16(aProtocolScheme).get(), nsIWindowsRegKey::ACCESS_QUERY_VALUE);
0, if (NS_FAILED(rv)) {
KEY_QUERY_VALUE, // Open will fail if the registry key path doesn't exist.
&hKey); return NS_OK;
if (err == ERROR_SUCCESS) }
{
err = ::RegQueryValueExW(hKey, L"URL Protocol", bool hasValue;
nullptr, nullptr, nullptr, nullptr); rv = regKey->HasValue(NS_LITERAL_STRING("URL Protocol"), &hasValue);
*aHandlerExists = (err == ERROR_SUCCESS); if (NS_FAILED(rv)) {
// close the key return NS_ERROR_FAILURE;
::RegCloseKey(hKey); }
if (!hasValue) {
return NS_OK;
}
*aHandlerExists = true;
} }
} }
@ -180,40 +144,21 @@ NS_IMETHODIMP nsOSHelperAppService::GetApplicationDescription(const nsACString&
} }
} }
if (mAppAssoc) { NS_ENSURE_TRUE(mAppAssoc, NS_ERROR_NOT_AVAILABLE);
// Vista: use new application association interface wchar_t * pResult = nullptr;
wchar_t * pResult = nullptr; // We are responsible for freeing returned strings.
// We are responsible for freeing returned strings. HRESULT hr = mAppAssoc->QueryCurrentDefault(buf.get(),
HRESULT hr = mAppAssoc->QueryCurrentDefault(buf.get(), AT_URLPROTOCOL, AL_EFFECTIVE,
AT_URLPROTOCOL, AL_EFFECTIVE, &pResult);
&pResult); if (SUCCEEDED(hr)) {
if (SUCCEEDED(hr)) { nsCOMPtr<nsIFile> app;
nsCOMPtr<nsIFile> app; nsAutoString appInfo(pResult);
nsAutoString appInfo(pResult); CoTaskMemFree(pResult);
CoTaskMemFree(pResult); if (NS_SUCCEEDED(GetDefaultAppInfo(appInfo, _retval, getter_AddRefs(app))))
if (NS_SUCCEEDED(GetDefaultAppInfo(appInfo, _retval, getter_AddRefs(app)))) return NS_OK;
return NS_OK;
}
return NS_ERROR_NOT_AVAILABLE;
} }
nsCOMPtr<nsIFile> app; return NS_ERROR_NOT_AVAILABLE;
GetDefaultAppInfo(buf, _retval, getter_AddRefs(app));
if (!_retval.Equals(buf))
return NS_OK;
// Fall back to full path
buf.AppendLiteral("\\shell\\open\\command");
nsresult rv = regKey->Open(nsIWindowsRegKey::ROOT_KEY_CLASSES_ROOT,
buf,
nsIWindowsRegKey::ACCESS_QUERY_VALUE);
if (NS_FAILED(rv))
return NS_ERROR_NOT_AVAILABLE;
rv = regKey->ReadStringValue(EmptyString(), _retval);
return NS_SUCCEEDED(rv) ? NS_OK : NS_ERROR_NOT_AVAILABLE;
} }
// GetMIMEInfoFromRegistry: This function obtains the values of some of the nsIMIMEInfo // GetMIMEInfoFromRegistry: This function obtains the values of some of the nsIMIMEInfo
@ -421,36 +366,18 @@ already_AddRefed<nsMIMEInfoWin> nsOSHelperAppService::GetByExtension(const nsAFl
bool found; bool found;
// Retrieve the default application for this extension // Retrieve the default application for this extension
if (mAppAssoc) { NS_ENSURE_TRUE(mAppAssoc, nullptr);
// Vista: use the new application association COM interfaces nsString assocType(fileExtToUse);
// for resolving helpers. wchar_t * pResult = nullptr;
nsString assocType(fileExtToUse); HRESULT hr = mAppAssoc->QueryCurrentDefault(assocType.get(),
wchar_t * pResult = nullptr; AT_FILEEXTENSION, AL_EFFECTIVE,
HRESULT hr = mAppAssoc->QueryCurrentDefault(assocType.get(), &pResult);
AT_FILEEXTENSION, AL_EFFECTIVE, if (SUCCEEDED(hr)) {
&pResult); found = true;
if (SUCCEEDED(hr)) { appInfo.Assign(pResult);
found = true; CoTaskMemFree(pResult);
appInfo.Assign(pResult); } else {
CoTaskMemFree(pResult); found = false;
}
else {
found = false;
}
}
else
{
nsCOMPtr<nsIWindowsRegKey> regKey =
do_CreateInstance("@mozilla.org/windows-registry-key;1");
if (!regKey)
return nullptr;
nsresult rv = regKey->Open(nsIWindowsRegKey::ROOT_KEY_CLASSES_ROOT,
fileExtToUse,
nsIWindowsRegKey::ACCESS_QUERY_VALUE);
if (NS_SUCCEEDED(rv)) {
found = NS_SUCCEEDED(regKey->ReadStringValue(EmptyString(),
appInfo));
}
} }
// Bug 358297 - ignore the default handler, force the user to choose app // Bug 358297 - ignore the default handler, force the user to choose app
@ -496,14 +423,9 @@ already_AddRefed<nsIMIMEInfo> nsOSHelperAppService::GetMIMEInfoFromOS(const nsAC
* We'll do extension-based lookup for this type later in this function. * We'll do extension-based lookup for this type later in this function.
*/ */
if (!aMIMEType.LowerCaseEqualsLiteral(APPLICATION_OCTET_STREAM)) { if (!aMIMEType.LowerCaseEqualsLiteral(APPLICATION_OCTET_STREAM)) {
// (1) try to use the windows mime database to see if there is a mapping to a file extension // try to use the windows mime database to see if there is a mapping to a file extension
// (2) try to see if we have some left over 4.x registry info we can peek at...
GetExtensionFromWindowsMimeDatabase(aMIMEType, fileExtension); GetExtensionFromWindowsMimeDatabase(aMIMEType, fileExtension);
LOG(("Windows mime database: extension '%s'\n", fileExtension.get())); LOG(("Windows mime database: extension '%s'\n", fileExtension.get()));
if (fileExtension.IsEmpty()) {
GetExtensionFrom4xRegistryInfo(aMIMEType, fileExtension);
LOG(("4.x Registry: extension '%s'\n", fileExtension.get()));
}
} }
// If we found an extension for the type, do the lookup // If we found an extension for the type, do the lookup
RefPtr<nsMIMEInfoWin> mi; RefPtr<nsMIMEInfoWin> mi;