mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-05 07:18:39 +09:00
Merge remote-tracking branch 'origin/master' into custom
This commit is contained in:
commit
b186b7ea74
24 changed files with 230 additions and 248 deletions
|
|
@ -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@");
|
||||
// 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");
|
||||
// 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.
|
||||
pref("@GUAO_PREF@.deviantart.com","Mozilla/5.0 (@OS_SLICE@ rv:@GRE_VERSION@) @GRE_DATE_SLICE@ @PM_SLICE@");
|
||||
|
|
|
|||
|
|
@ -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%);
|
||||
}
|
||||
|
||||
/* 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,
|
||||
.tabs-newtab-button {
|
||||
position: static;
|
||||
|
|
|
|||
|
|
@ -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%);
|
||||
}
|
||||
|
||||
/* 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) {
|
||||
#main-window[sizemode=normal] #TabsToolbar {
|
||||
padding-left: 2px;
|
||||
|
|
|
|||
|
|
@ -31,6 +31,8 @@
|
|||
%endif
|
||||
|
||||
:root {
|
||||
--toolbox-after-color: ThreeDShadow;
|
||||
|
||||
--toolbar-custom-color: hsl(210,75%,92%);
|
||||
--toolbar-highlight-top: rgba(255,255,255,.5);
|
||||
--toolbar-highlight-bottom: transparent;
|
||||
|
|
@ -91,7 +93,7 @@
|
|||
display: -moz-box;
|
||||
-moz-box-ordinal-group: 101; /* tabs toolbar is 100 */
|
||||
height: 1px;
|
||||
background-color: ThreeDShadow;
|
||||
background-color: var(--toolbox-after-color);
|
||||
}
|
||||
#navigator-toolbox[tabsontop=false]::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%);
|
||||
}
|
||||
|
||||
/* 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,
|
||||
.tabs-newtab-button {
|
||||
-moz-appearance: none;
|
||||
|
|
@ -3044,8 +3057,8 @@ toolbar[brighttext] #addonbar-closebutton {
|
|||
|
||||
@media (-moz-os-version: windows-vista),
|
||||
(-moz-os-version: windows-win7) {
|
||||
#navigator-toolbox:not(:-moz-lwtheme)::after {
|
||||
background-color: #aabccf;
|
||||
:root:not(:-moz-lwtheme) {
|
||||
--toolbox-after-color: #aabccf;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -3054,9 +3067,9 @@ toolbar[brighttext] #addonbar-closebutton {
|
|||
:root {
|
||||
--toolbar-custom-color: hsl(210,0%,92%);
|
||||
}
|
||||
|
||||
#navigator-toolbox:not(:-moz-lwtheme)::after {
|
||||
background-color: #bcbcbc;
|
||||
|
||||
:root:not(:-moz-lwtheme) {
|
||||
--toolbox-after-color: #bcbcbc;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -6329,6 +6329,13 @@ CanvasRenderingContext2D::ShouldForceInactiveLayer(LayerManager* aManager)
|
|||
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_UNROOT_NATIVE(CanvasPath, Release)
|
||||
|
||||
|
|
|
|||
|
|
@ -1156,9 +1156,7 @@ protected:
|
|||
|
||||
// For the origin-clean algorithm (mWriteOnly == !origin-clean)
|
||||
// See https://html.spec.whatwg.org/multipage/imagebitmap-and-animations.html
|
||||
void SetWriteOnly() {
|
||||
mWriteOnly = true;
|
||||
}
|
||||
void SetWriteOnly();
|
||||
|
||||
bool IsWriteOnly() const {
|
||||
return mWriteOnly;
|
||||
|
|
|
|||
|
|
@ -421,11 +421,10 @@ HTMLTableElement::CreateTHead()
|
|||
void
|
||||
HTMLTableElement::DeleteTHead()
|
||||
{
|
||||
HTMLTableSectionElement* tHead = GetTHead();
|
||||
RefPtr<HTMLTableSectionElement> tHead = GetTHead();
|
||||
if (tHead) {
|
||||
mozilla::ErrorResult rv;
|
||||
mozilla::IgnoredErrorResult rv;
|
||||
nsINode::RemoveChild(*tHead, rv);
|
||||
MOZ_ASSERT(!rv.Failed());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -452,11 +451,10 @@ HTMLTableElement::CreateTFoot()
|
|||
void
|
||||
HTMLTableElement::DeleteTFoot()
|
||||
{
|
||||
HTMLTableSectionElement* tFoot = GetTFoot();
|
||||
RefPtr<HTMLTableSectionElement> tFoot = GetTFoot();
|
||||
if (tFoot) {
|
||||
mozilla::ErrorResult rv;
|
||||
mozilla::IgnoredErrorResult rv;
|
||||
nsINode::RemoveChild(*tFoot, rv);
|
||||
MOZ_ASSERT(!rv.Failed());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -483,11 +481,10 @@ HTMLTableElement::CreateCaption()
|
|||
void
|
||||
HTMLTableElement::DeleteCaption()
|
||||
{
|
||||
HTMLTableCaptionElement* caption = GetCaption();
|
||||
RefPtr<HTMLTableCaptionElement> caption = GetCaption();
|
||||
if (caption) {
|
||||
mozilla::ErrorResult rv;
|
||||
mozilla::IgnoredErrorResult rv;
|
||||
nsINode::RemoveChild(*caption, rv);
|
||||
MOZ_ASSERT(!rv.Failed());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -122,7 +122,7 @@ HTMLTableSectionElement::DeleteRow(int32_t aValue, ErrorResult& aError)
|
|||
refIndex = (uint32_t)aValue;
|
||||
}
|
||||
|
||||
nsINode* row = rows->Item(refIndex);
|
||||
nsCOMPtr<nsINode> row = rows->Item(refIndex);
|
||||
if (!row) {
|
||||
aError.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -233,7 +233,7 @@ void
|
|||
nsSMILAnimationController::NotifyRefreshDriverCreated(
|
||||
nsRefreshDriver* aRefreshDriver)
|
||||
{
|
||||
if (!mPauseState) {
|
||||
if (!mPauseState && mChildContainerTable.Count()) {
|
||||
MaybeStartSampling(aRefreshDriver);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -567,8 +567,11 @@ class MOZ_NON_PARAM alignas(8) Value
|
|||
}
|
||||
|
||||
bool isMagic(JSWhyMagic why) const {
|
||||
MOZ_ASSERT_IF(isMagic(), data.s.payload.why == why);
|
||||
return isMagic();
|
||||
if (!isMagic()) {
|
||||
return false;
|
||||
}
|
||||
MOZ_RELEASE_ASSERT(data.s.payload.why == why);
|
||||
return true;
|
||||
}
|
||||
|
||||
JS::TraceKind traceKind() const {
|
||||
|
|
|
|||
|
|
@ -210,6 +210,7 @@ js::Nursery::disable()
|
|||
return;
|
||||
updateNumChunks(0);
|
||||
currentEnd_ = 0;
|
||||
position_ = 0;
|
||||
runtime()->gc.storeBuffer.disable();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -245,6 +245,7 @@ class Nursery
|
|||
|
||||
// Free space remaining, not counting chunk trailers.
|
||||
MOZ_ALWAYS_INLINE size_t freeSpace() const {
|
||||
MOZ_ASSERT(isEnabled());
|
||||
MOZ_ASSERT(currentEnd_ - position_ <= NurseryChunkUsableSize);
|
||||
return (currentEnd_ - position_) +
|
||||
(numChunks() - currentChunk_ - 1) * NurseryChunkUsableSize;
|
||||
|
|
|
|||
|
|
@ -222,7 +222,7 @@ DefaultJitOptions::DefaultJitOptions()
|
|||
}
|
||||
|
||||
// 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.
|
||||
SET_DEFAULT(asmJSAtomicsEnable, false);
|
||||
|
|
|
|||
|
|
@ -6410,6 +6410,9 @@ JS_SetGlobalJitCompilerOption(JSContext* cx, JSJitCompilerOption opt, uint32_t v
|
|||
}
|
||||
jit::JitOptions.jumpThreshold = value;
|
||||
break;
|
||||
case JSJITCOMPILER_UNBOXED_OBJECTS:
|
||||
jit::JitOptions.disableUnboxedObjects = !value;
|
||||
break;
|
||||
case JSJITCOMPILER_ASMJS_ATOMICS_ENABLE:
|
||||
jit::JitOptions.asmJSAtomicsEnable = !!value;
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -5783,19 +5783,20 @@ JS_SetParallelParsingEnabled(JSContext* cx, bool enabled);
|
|||
extern JS_PUBLIC_API(void)
|
||||
JS_SetOffthreadIonCompilationEnabled(JSContext* cx, bool enabled);
|
||||
|
||||
#define JIT_COMPILER_OPTIONS(Register) \
|
||||
Register(BASELINE_WARMUP_TRIGGER, "baseline.warmup.trigger") \
|
||||
Register(ION_WARMUP_TRIGGER, "ion.warmup.trigger") \
|
||||
Register(ION_GVN_ENABLE, "ion.gvn.enable") \
|
||||
Register(ION_FORCE_IC, "ion.forceinlineCaches") \
|
||||
Register(ION_ENABLE, "ion.enable") \
|
||||
#define JIT_COMPILER_OPTIONS(Register) \
|
||||
Register(BASELINE_WARMUP_TRIGGER, "baseline.warmup.trigger") \
|
||||
Register(ION_WARMUP_TRIGGER, "ion.warmup.trigger") \
|
||||
Register(ION_GVN_ENABLE, "ion.gvn.enable") \
|
||||
Register(ION_FORCE_IC, "ion.forceinlineCaches") \
|
||||
Register(ION_ENABLE, "ion.enable") \
|
||||
Register(ION_INTERRUPT_WITHOUT_SIGNAL, "ion.interrupt-without-signals") \
|
||||
Register(ION_CHECK_RANGE_ANALYSIS, "ion.check-range-analysis") \
|
||||
Register(BASELINE_ENABLE, "baseline.enable") \
|
||||
Register(OFFTHREAD_COMPILATION_ENABLE, "offthread-compilation.enable") \
|
||||
Register(JUMP_THRESHOLD, "jump-threshold") \
|
||||
Register(ASMJS_ATOMICS_ENABLE, "asmjs.atomics.enable") \
|
||||
Register(WASM_TEST_MODE, "wasm.test-mode") \
|
||||
Register(ION_CHECK_RANGE_ANALYSIS, "ion.check-range-analysis") \
|
||||
Register(BASELINE_ENABLE, "baseline.enable") \
|
||||
Register(OFFTHREAD_COMPILATION_ENABLE, "offthread-compilation.enable") \
|
||||
Register(JUMP_THRESHOLD, "jump-threshold") \
|
||||
Register(UNBOXED_OBJECTS, "unboxed_objects") \
|
||||
Register(ASMJS_ATOMICS_ENABLE, "asmjs.atomics.enable") \
|
||||
Register(WASM_TEST_MODE, "wasm.test-mode") \
|
||||
Register(WASM_FOLD_OFFSETS, "wasm.fold-offsets")
|
||||
|
||||
typedef enum JSJitCompilerOption {
|
||||
|
|
|
|||
|
|
@ -288,6 +288,12 @@ CallerGetterImpl(JSContext* cx, const CallArgs& args)
|
|||
return true;
|
||||
}
|
||||
|
||||
if (JS_IsDeadWrapper(callerObj)) {
|
||||
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
|
||||
JSMSG_DEAD_OBJECT);
|
||||
return false;
|
||||
}
|
||||
|
||||
JSFunction* callerFun = &callerObj->as<JSFunction>();
|
||||
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()));
|
||||
|
||||
// Beware! This function can be invoked on *any* function! It can't
|
||||
// assume it'll never be invoked on natives, strict mode functions, bound
|
||||
// functions, or anything else that ordinarily has immutable .caller
|
||||
// defined with [[ThrowTypeError]].
|
||||
RootedFunction fun(cx, &args.thisv().toObject().as<JSFunction>());
|
||||
if (!CallerRestrictions(cx, fun))
|
||||
return false;
|
||||
// We just have to return |undefined|, but first we call CallerGetterImpl
|
||||
// because we need the same strict-mode and security checks.
|
||||
|
||||
if (!CallerGetterImpl(cx, args)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Return |undefined| unless an error must be thrown.
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1427,6 +1427,8 @@ ReloadPrefsCallback(const char* pref, void* data)
|
|||
|
||||
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");
|
||||
|
||||
#ifdef DEBUG
|
||||
|
|
@ -1455,6 +1457,8 @@ ReloadPrefsCallback(const char* pref, void* data)
|
|||
useBaselineEager ? 0 : -1);
|
||||
JS_SetGlobalJitCompilerOption(cx, JSJITCOMPILER_ION_WARMUP_TRIGGER,
|
||||
useIonEager ? 0 : -1);
|
||||
JS_SetGlobalJitCompilerOption(cx, JSJITCOMPILER_UNBOXED_OBJECTS,
|
||||
unboxedObjects);
|
||||
}
|
||||
|
||||
XPCJSContext::~XPCJSContext()
|
||||
|
|
|
|||
|
|
@ -212,7 +212,7 @@ public:
|
|||
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));
|
||||
return *create(mPtr + aIndex);
|
||||
|
|
|
|||
|
|
@ -1264,6 +1264,7 @@ pref("javascript.options.strict", false);
|
|||
#ifdef DEBUG
|
||||
pref("javascript.options.strict.debug", false);
|
||||
#endif
|
||||
pref("javascript.options.unboxed_objects", false);
|
||||
pref("javascript.options.baselinejit", true);
|
||||
pref("javascript.options.ion", true);
|
||||
pref("javascript.options.asmjs", true);
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@
|
|||
#include "nsNetCID.h"
|
||||
#include "nsServiceManagerUtils.h"
|
||||
#include "nsComponentManagerUtils.h"
|
||||
#include "nsSocketTransport2.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace net {
|
||||
|
|
@ -42,6 +43,7 @@ TLSFilterTransaction::TLSFilterTransaction(nsAHttpTransaction *aWrapped,
|
|||
, mSegmentReader(aReader)
|
||||
, mSegmentWriter(aWriter)
|
||||
, mForce(false)
|
||||
, mReadSegmentReturnValue(NS_OK)
|
||||
, mNudgeCounter(0)
|
||||
{
|
||||
MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
|
||||
|
|
@ -130,6 +132,19 @@ TLSFilterTransaction::Close(nsresult aReason)
|
|||
}
|
||||
mTransaction->Close(aReason);
|
||||
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
|
||||
|
|
@ -140,7 +155,7 @@ TLSFilterTransaction::OnReadSegment(const char *aData,
|
|||
LOG(("TLSFilterTransaction %p OnReadSegment %d (buffered %d)\n",
|
||||
this, aCount, mEncryptedTextUsed));
|
||||
|
||||
mReadSegmentBlocked = false;
|
||||
mReadSegmentReturnValue = NS_OK;
|
||||
MOZ_ASSERT(mSegmentReader);
|
||||
if (!mSecInfo) {
|
||||
return NS_ERROR_FAILURE;
|
||||
|
|
@ -188,10 +203,12 @@ TLSFilterTransaction::OnReadSegment(const char *aData,
|
|||
return NS_OK;
|
||||
}
|
||||
// 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
|
||||
mReadSegmentBlocked = (PR_GetError() == PR_WOULD_BLOCK_ERROR);
|
||||
return mReadSegmentBlocked ? NS_BASE_STREAM_WOULD_BLOCK : NS_ERROR_FAILURE;
|
||||
PRErrorCode code = PR_GetError();
|
||||
mReadSegmentReturnValue = ErrorAccordingToNSPR(code);
|
||||
|
||||
return mReadSegmentReturnValue;
|
||||
}
|
||||
aCount -= written;
|
||||
aData += written;
|
||||
|
|
@ -273,10 +290,18 @@ TLSFilterTransaction::OnWriteSegment(char *aData,
|
|||
mFilterReadCode = NS_OK;
|
||||
int32_t bytesRead = PR_Read(mFD, aData, aCount);
|
||||
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_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;
|
||||
|
||||
|
|
@ -303,7 +328,7 @@ TLSFilterTransaction::FilterInput(char *aBuf, int32_t aAmount)
|
|||
if (NS_SUCCEEDED(mFilterReadCode) && outCountRead) {
|
||||
LOG(("TLSFilterTransaction::FilterInput rv=%x read=%d input from net "
|
||||
"1 layer stripped, 1 still on\n", mFilterReadCode, outCountRead));
|
||||
if (mReadSegmentBlocked) {
|
||||
if (mReadSegmentReturnValue == NS_BASE_STREAM_WOULD_BLOCK) {
|
||||
mNudgeCounter = 0;
|
||||
}
|
||||
}
|
||||
|
|
@ -325,19 +350,18 @@ TLSFilterTransaction::ReadSegments(nsAHttpSegmentReader *aReader,
|
|||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
mReadSegmentBlocked = false;
|
||||
mReadSegmentReturnValue = NS_OK;
|
||||
mSegmentReader = aReader;
|
||||
nsresult rv = mTransaction->ReadSegments(this, aCount, outCountRead);
|
||||
LOG(("TLSFilterTransaction %p called trans->ReadSegments rv=%x %d\n",
|
||||
this, rv, *outCountRead));
|
||||
if (NS_SUCCEEDED(rv) && mReadSegmentBlocked) {
|
||||
rv = NS_BASE_STREAM_WOULD_BLOCK;
|
||||
if (NS_SUCCEEDED(rv) && (mReadSegmentReturnValue == NS_BASE_STREAM_WOULD_BLOCK)) {
|
||||
LOG(("TLSFilterTransaction %p read segment blocked found rv=%x\n",
|
||||
this, rv));
|
||||
this, static_cast<uint32_t>(rv)));
|
||||
Connection()->ForceSend();
|
||||
}
|
||||
|
||||
return rv;
|
||||
return NS_SUCCEEDED(rv) ? mReadSegmentReturnValue : rv;
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
|
@ -442,7 +466,10 @@ TLSFilterTransaction::Notify(nsITimer *timer)
|
|||
if (timer != mTimer) {
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
StartTimerCallback();
|
||||
nsresult rv = StartTimerCallback();
|
||||
if (NS_FAILED(rv)) {
|
||||
Close(rv);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
@ -456,7 +483,7 @@ TLSFilterTransaction::StartTimerCallback()
|
|||
// This class can be called re-entrantly, so cleanup m* before ->on()
|
||||
RefPtr<NudgeTunnelCallback> cb(mNudgeCallback);
|
||||
mNudgeCallback = nullptr;
|
||||
cb->OnTunnelNudged(this);
|
||||
return cb->OnTunnelNudged(this);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
@ -675,10 +702,12 @@ TLSFilterTransaction::TakeSubTransactions(
|
|||
}
|
||||
|
||||
nsresult
|
||||
TLSFilterTransaction::SetProxiedTransaction(nsAHttpTransaction *aTrans)
|
||||
TLSFilterTransaction::SetProxiedTransaction(nsAHttpTransaction *aTrans,
|
||||
nsAHttpTransaction *aSpdyConnectTransaction)
|
||||
{
|
||||
LOG(("TLSFilterTransaction::SetProxiedTransaction [this=%p] aTrans=%p\n",
|
||||
this, aTrans));
|
||||
LOG(("TLSFilterTransaction::SetProxiedTransaction [this=%p] aTrans=%p, "
|
||||
"aSpdyConnectTransaction=%p\n",
|
||||
this, aTrans, aSpdyConnectTransaction));
|
||||
|
||||
mTransaction = aTrans;
|
||||
nsCOMPtr<nsIInterfaceRequestor> callbacks;
|
||||
|
|
@ -688,6 +717,8 @@ TLSFilterTransaction::SetProxiedTransaction(nsAHttpTransaction *aTrans)
|
|||
secCtrl->SetNotificationCallbacks(callbacks);
|
||||
}
|
||||
|
||||
mWeakTrans = do_GetWeakReference(aSpdyConnectTransaction);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
@ -1075,7 +1106,7 @@ SpdyConnectTransaction::MapStreamToHttpConnection(nsISocketTransport *aTransport
|
|||
if (mForcePlainText) {
|
||||
mTunneledConn->ForcePlainText();
|
||||
} else {
|
||||
mTunneledConn->SetupSecondaryTLS();
|
||||
mTunneledConn->SetupSecondaryTLS(this);
|
||||
mTunneledConn->SetInSpdyTunnel(true);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -93,10 +93,11 @@ class TLSFilterTransaction;
|
|||
class NudgeTunnelCallback : public nsISupports
|
||||
{
|
||||
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
|
||||
: public nsAHttpTransaction
|
||||
|
|
@ -121,7 +122,8 @@ public:
|
|||
nsresult CommitToSegmentSize(uint32_t size, bool forceCommitment) override;
|
||||
nsresult GetTransactionSecurityInfo(nsISupports **) override;
|
||||
nsresult NudgeTunnel(NudgeTunnelCallback *callback);
|
||||
nsresult SetProxiedTransaction(nsAHttpTransaction *aTrans);
|
||||
MOZ_MUST_USE nsresult SetProxiedTransaction(nsAHttpTransaction *aTrans,
|
||||
nsAHttpTransaction *aSpdyConnectTransaction = nullptr);
|
||||
void newIODriver(nsIAsyncInputStream *aSocketIn,
|
||||
nsIAsyncOutputStream *aSocketOut,
|
||||
nsIAsyncInputStream **outSocketIn,
|
||||
|
|
@ -153,6 +155,7 @@ private:
|
|||
|
||||
private:
|
||||
RefPtr<nsAHttpTransaction> mTransaction;
|
||||
nsWeakPtr mWeakTrans; // SpdyConnectTransaction *
|
||||
nsCOMPtr<nsISupports> mSecInfo;
|
||||
nsCOMPtr<nsITimer> mTimer;
|
||||
RefPtr<NudgeTunnelCallback> mNudgeCallback;
|
||||
|
|
@ -168,7 +171,7 @@ private:
|
|||
|
||||
nsresult mFilterReadCode;
|
||||
bool mForce;
|
||||
bool mReadSegmentBlocked;
|
||||
nsresult mReadSegmentReturnValue;
|
||||
uint32_t mNudgeCounter;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -535,16 +535,16 @@ npnComplete:
|
|||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
nsresult
|
||||
nsHttpConnection::OnTunnelNudged(TLSFilterTransaction *trans)
|
||||
{
|
||||
MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
|
||||
LOG(("nsHttpConnection::OnTunnelNudged %p\n", this));
|
||||
if (trans != mTLSFilter) {
|
||||
return;
|
||||
return NS_OK;
|
||||
}
|
||||
LOG(("nsHttpConnection::OnTunnelNudged %p Calling OnSocketWritable\n", this));
|
||||
OnSocketWritable();
|
||||
return OnSocketWritable();
|
||||
}
|
||||
|
||||
// called on the socket thread
|
||||
|
|
@ -639,7 +639,9 @@ nsHttpConnection::Activate(nsAHttpTransaction *trans, uint32_t caps, int32_t pri
|
|||
}
|
||||
|
||||
if (mTLSFilter) {
|
||||
mTLSFilter->SetProxiedTransaction(trans);
|
||||
RefPtr<NullHttpTransaction> baseTrans(do_QueryReferent(mWeakTrans));
|
||||
rv = mTLSFilter->SetProxiedTransaction(trans, baseTrans);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
mTransaction = mTLSFilter;
|
||||
}
|
||||
|
||||
|
|
@ -1979,7 +1981,7 @@ nsHttpConnection::OnSocketReadable()
|
|||
// negotiation are known (which is determined from the write path).
|
||||
// If the server speaks SPDY it is likely the readable data here is
|
||||
// a spdy settings frame and without NPN it would be misinterpreted
|
||||
// as HTTP/*
|
||||
// as HTTP
|
||||
|
||||
LOG(("nsHttpConnection::OnSocketReadable %p return due to inactive "
|
||||
"tunnel setup but incomplete NPN state\n", this));
|
||||
|
|
@ -2019,12 +2021,14 @@ nsHttpConnection::OnSocketReadable()
|
|||
}
|
||||
|
||||
void
|
||||
nsHttpConnection::SetupSecondaryTLS()
|
||||
nsHttpConnection::SetupSecondaryTLS(nsAHttpTransaction *aSpdyConnectTransaction)
|
||||
{
|
||||
MOZ_ASSERT(PR_GetCurrentThread() == gSocketThread);
|
||||
MOZ_ASSERT(!mTLSFilter);
|
||||
LOG(("nsHttpConnection %p SetupSecondaryTLS %s %d\n",
|
||||
this, mConnInfo->Origin(), mConnInfo->OriginPort()));
|
||||
LOG(("nsHttpConnection %p SetupSecondaryTLS %s %d "
|
||||
"aSpdyConnectTransaction=%p\n",
|
||||
this, mConnInfo->Origin(), mConnInfo->OriginPort(),
|
||||
aSpdyConnectTransaction));
|
||||
|
||||
nsHttpConnectionInfo *ci = nullptr;
|
||||
if (mTransaction) {
|
||||
|
|
@ -2041,6 +2045,7 @@ nsHttpConnection::SetupSecondaryTLS()
|
|||
if (mTransaction) {
|
||||
mTransaction = mTLSFilter;
|
||||
}
|
||||
mWeakTrans = do_GetWeakReference(aSpdyConnectTransaction);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
|||
|
|
@ -202,7 +202,7 @@ public:
|
|||
static nsresult MakeConnectString(nsAHttpTransaction *trans,
|
||||
nsHttpRequestHead *request,
|
||||
nsACString &result);
|
||||
void SetupSecondaryTLS();
|
||||
void SetupSecondaryTLS(nsAHttpTransaction *aSpdyConnectTransaction = nullptr);
|
||||
void SetInSpdyTunnel(bool arg);
|
||||
|
||||
// Check active connections for traffic (or not). SPDY connections send a
|
||||
|
|
@ -281,6 +281,7 @@ private:
|
|||
// transaction is open, otherwise it is null.
|
||||
RefPtr<nsAHttpTransaction> mTransaction;
|
||||
RefPtr<TLSFilterTransaction> mTLSFilter;
|
||||
nsWeakPtr mWeakTrans; // SpdyConnectTransaction *
|
||||
|
||||
RefPtr<nsHttpHandler> mHttpHandler; // keep gHttpHandler alive
|
||||
|
||||
|
|
|
|||
|
|
@ -29,8 +29,6 @@
|
|||
#define LOG(args) MOZ_LOG(mLog, mozilla::LogLevel::Debug, args)
|
||||
|
||||
// helper methods: forward declarations...
|
||||
static nsresult GetExtensionFrom4xRegistryInfo(const nsACString& aMimeType,
|
||||
nsString& aFileExtension);
|
||||
static nsresult GetExtensionFromWindowsMimeDatabase(const nsACString& aMimeType,
|
||||
nsString& aFileExtension);
|
||||
|
||||
|
|
@ -77,79 +75,45 @@ static nsresult GetExtensionFromWindowsMimeDatabase(const nsACString& aMimeType,
|
|||
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)
|
||||
{
|
||||
// look up the protocol scheme in the windows registry....if we find a match then we have a handler for it...
|
||||
*aHandlerExists = false;
|
||||
if (aProtocolScheme && *aProtocolScheme)
|
||||
{
|
||||
// Vista: use new application association interface
|
||||
if (mAppAssoc) {
|
||||
wchar_t * pResult = nullptr;
|
||||
NS_ConvertASCIItoUTF16 scheme(aProtocolScheme);
|
||||
// We are responsible for freeing returned strings.
|
||||
HRESULT hr = mAppAssoc->QueryCurrentDefault(scheme.get(),
|
||||
AT_URLPROTOCOL, AL_EFFECTIVE,
|
||||
&pResult);
|
||||
if (SUCCEEDED(hr)) {
|
||||
CoTaskMemFree(pResult);
|
||||
*aHandlerExists = true;
|
||||
NS_ENSURE_TRUE(mAppAssoc, NS_ERROR_NOT_AVAILABLE);
|
||||
wchar_t * pResult = nullptr;
|
||||
NS_ConvertASCIItoUTF16 scheme(aProtocolScheme);
|
||||
// We are responsible for freeing returned strings.
|
||||
HRESULT hr = mAppAssoc->QueryCurrentDefault(scheme.get(),
|
||||
AT_URLPROTOCOL, AL_EFFECTIVE,
|
||||
&pResult);
|
||||
if (SUCCEEDED(hr)) {
|
||||
CoTaskMemFree(pResult);
|
||||
// Check the registry to see if it's a valid handler.
|
||||
nsCOMPtr<nsIWindowsRegKey> regKey = do_CreateInstance("@mozilla.org/windows-registry-key;1");
|
||||
if (!regKey) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
HKEY hKey;
|
||||
LONG err = ::RegOpenKeyExW(HKEY_CLASSES_ROOT,
|
||||
NS_ConvertASCIItoUTF16(aProtocolScheme).get(),
|
||||
0,
|
||||
KEY_QUERY_VALUE,
|
||||
&hKey);
|
||||
if (err == ERROR_SUCCESS)
|
||||
{
|
||||
err = ::RegQueryValueExW(hKey, L"URL Protocol",
|
||||
nullptr, nullptr, nullptr, nullptr);
|
||||
*aHandlerExists = (err == ERROR_SUCCESS);
|
||||
// close the key
|
||||
::RegCloseKey(hKey);
|
||||
nsresult rv = regKey->Open(nsIWindowsRegKey::ROOT_KEY_CLASSES_ROOT,
|
||||
nsDependentString(scheme.get()),
|
||||
nsIWindowsRegKey::ACCESS_QUERY_VALUE);
|
||||
if (NS_FAILED(rv)) {
|
||||
// Open will fail if the registry key path doesn't exist.
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
bool hasValue;
|
||||
rv = regKey->HasValue(NS_LITERAL_STRING("URL Protocol"), &hasValue);
|
||||
if (NS_FAILED(rv)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
if (!hasValue) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
*aHandlerExists = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -180,40 +144,21 @@ NS_IMETHODIMP nsOSHelperAppService::GetApplicationDescription(const nsACString&
|
|||
}
|
||||
}
|
||||
|
||||
if (mAppAssoc) {
|
||||
// Vista: use new application association interface
|
||||
wchar_t * pResult = nullptr;
|
||||
// We are responsible for freeing returned strings.
|
||||
HRESULT hr = mAppAssoc->QueryCurrentDefault(buf.get(),
|
||||
AT_URLPROTOCOL, AL_EFFECTIVE,
|
||||
&pResult);
|
||||
if (SUCCEEDED(hr)) {
|
||||
nsCOMPtr<nsIFile> app;
|
||||
nsAutoString appInfo(pResult);
|
||||
CoTaskMemFree(pResult);
|
||||
if (NS_SUCCEEDED(GetDefaultAppInfo(appInfo, _retval, getter_AddRefs(app))))
|
||||
return NS_OK;
|
||||
}
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
NS_ENSURE_TRUE(mAppAssoc, NS_ERROR_NOT_AVAILABLE);
|
||||
wchar_t * pResult = nullptr;
|
||||
// We are responsible for freeing returned strings.
|
||||
HRESULT hr = mAppAssoc->QueryCurrentDefault(buf.get(),
|
||||
AT_URLPROTOCOL, AL_EFFECTIVE,
|
||||
&pResult);
|
||||
if (SUCCEEDED(hr)) {
|
||||
nsCOMPtr<nsIFile> app;
|
||||
nsAutoString appInfo(pResult);
|
||||
CoTaskMemFree(pResult);
|
||||
if (NS_SUCCEEDED(GetDefaultAppInfo(appInfo, _retval, getter_AddRefs(app))))
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIFile> app;
|
||||
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;
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
// GetMIMEInfoFromRegistry: This function obtains the values of some of the nsIMIMEInfo
|
||||
|
|
@ -421,36 +366,18 @@ already_AddRefed<nsMIMEInfoWin> nsOSHelperAppService::GetByExtension(const nsAFl
|
|||
bool found;
|
||||
|
||||
// Retrieve the default application for this extension
|
||||
if (mAppAssoc) {
|
||||
// Vista: use the new application association COM interfaces
|
||||
// for resolving helpers.
|
||||
nsString assocType(fileExtToUse);
|
||||
wchar_t * pResult = nullptr;
|
||||
HRESULT hr = mAppAssoc->QueryCurrentDefault(assocType.get(),
|
||||
AT_FILEEXTENSION, AL_EFFECTIVE,
|
||||
&pResult);
|
||||
if (SUCCEEDED(hr)) {
|
||||
found = true;
|
||||
appInfo.Assign(pResult);
|
||||
CoTaskMemFree(pResult);
|
||||
}
|
||||
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));
|
||||
}
|
||||
NS_ENSURE_TRUE(mAppAssoc, nullptr);
|
||||
nsString assocType(fileExtToUse);
|
||||
wchar_t * pResult = nullptr;
|
||||
HRESULT hr = mAppAssoc->QueryCurrentDefault(assocType.get(),
|
||||
AT_FILEEXTENSION, AL_EFFECTIVE,
|
||||
&pResult);
|
||||
if (SUCCEEDED(hr)) {
|
||||
found = true;
|
||||
appInfo.Assign(pResult);
|
||||
CoTaskMemFree(pResult);
|
||||
} else {
|
||||
found = false;
|
||||
}
|
||||
|
||||
// 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.
|
||||
*/
|
||||
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
|
||||
// (2) try to see if we have some left over 4.x registry info we can peek at...
|
||||
// try to use the windows mime database to see if there is a mapping to a file extension
|
||||
GetExtensionFromWindowsMimeDatabase(aMIMEType, fileExtension);
|
||||
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
|
||||
RefPtr<nsMIMEInfoWin> mi;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue