From bc6daa0aea7247d845a36ce067907b4e433354c6 Mon Sep 17 00:00:00 2001 From: Cameron Kaiser Date: Sat, 17 Sep 2022 20:08:09 -0700 Subject: [PATCH] #651: M1767365+backbugs M1757604 M1497246 M1771774 M1776658 M1761981 M1773717; mark clobber; fix zlib warning; now officially on 102ESR --- CLOBBER | 2 +- README.md | 2 +- dom/bindings/ToJSValue.h | 2 +- dom/canvas/CanvasRenderingContext2D.cpp | 30 ++++--- dom/indexedDB/KeyPath.cpp | 2 +- dom/jsurl/nsJSProtocolHandler.cpp | 2 +- gfx/2d/BaseRect.h | 57 +++++++++++++ js/xpconnect/src/XPCConvert.cpp | 2 +- js/xpconnect/src/XPCVariant.cpp | 2 +- modules/libjar/moz.build | 4 + modules/libjar/nsJARChannel.cpp | 103 +++++++++++++++--------- modules/libjar/nsJARChannel.h | 3 + modules/libpref/init/all.js | 3 + modules/zlib/src/mozzconf.h | 3 + xpcom/glue/nsTArray.h | 2 + 15 files changed, 164 insertions(+), 55 deletions(-) diff --git a/CLOBBER b/CLOBBER index 823634b1b..713425d99 100644 --- a/CLOBBER +++ b/CLOBBER @@ -22,4 +22,4 @@ # changes to stick? As of bug 928195, this shouldn't be necessary! Please # don't change CLOBBER for WebIDL changes any more. -Rolling release +Rebuild for 102ESR base diff --git a/README.md b/README.md index 011070bfb..c53840cab 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ A fork of Firefox to maintain support for the Power Mac, supporting Mac OS X 10. This project is specifically for Mac OS X 10.4+. If you're looking for a browser for Mac OS 8.6-10.3, look at our sister project, [Classilla](http://www.classilla.org/). -**TenFourFox is a "hobby" project: you build it yourself, with no guarantees on updates, update frequency, security or stability.** Our Github project site houses our source code, [documentation wiki](https://github.com/classilla/tenfourfox/wiki) with complete build instructions, and [the current worklist](https://github.com/classilla/tenfourfox/issues). For archived downloads, language packs and contributed tools, visit our [SourceForge download repository](https://sourceforge.net/projects/tenfourfox/files/). **There is no support for any version of TenFourFox.** The current update source is Firefox 91ESR. +**TenFourFox is a "hobby" project: you build it yourself, with no guarantees on updates, update frequency, security or stability.** Our Github project site houses our source code, [documentation wiki](https://github.com/classilla/tenfourfox/wiki) with complete build instructions, and [the current worklist](https://github.com/classilla/tenfourfox/issues). For archived downloads, language packs and contributed tools, visit our [SourceForge download repository](https://sourceforge.net/projects/tenfourfox/files/). **There is no support for any version of TenFourFox.** The current update source is Firefox 102ESR. **If you file a Github issue without a patch, or without declaring your intention to file a pull request addressing that issue, it may be summarily closed or deleted at the maintainer's sole discretion.** The issue list is an active worklist, and if no work will occur on an issue, even if the issue is real and verifiable, it will be closed. There are lots of acknowledged deficiencies in TenFourFox and not everyone is going to prioritize a deficiency the way you might. If you are not willing or able to fix your most important issues yourself, you may not want to use this browser. diff --git a/dom/bindings/ToJSValue.h b/dom/bindings/ToJSValue.h index d2e91366b..f47fba312 100644 --- a/dom/bindings/ToJSValue.h +++ b/dom/bindings/ToJSValue.h @@ -117,7 +117,7 @@ ToJSValue(JSContext* aCx, // Make sure we're called in a compartment MOZ_ASSERT(JS::CurrentGlobalOrNull(aCx)); - aValue.setNumber(aArgument); + aValue.set(JS_NumberValue(aArgument)); return true; } diff --git a/dom/canvas/CanvasRenderingContext2D.cpp b/dom/canvas/CanvasRenderingContext2D.cpp index 0ccf80670..9b76c0afa 100644 --- a/dom/canvas/CanvasRenderingContext2D.cpp +++ b/dom/canvas/CanvasRenderingContext2D.cpp @@ -5229,6 +5229,16 @@ CanvasRenderingContext2D::GetImageData(JSContext* aCx, double aSx, return imageData.forget(); } +static IntRect ClipImageDataTransfer(IntRect& aSrc, const IntPoint& aDestOffset, + const IntSize& aDestBounds) { + IntRect dest = aSrc; + dest.SafeMoveBy(aDestOffset); + dest = IntRect(IntPoint(0, 0), aDestBounds).SafeIntersect(dest); + + aSrc = aSrc.SafeIntersect(dest - aDestOffset); + return aSrc + aDestOffset; +} + nsresult CanvasRenderingContext2D::GetImageDataArray(JSContext* aCx, int32_t aX, @@ -5266,8 +5276,9 @@ CanvasRenderingContext2D::GetImageDataArray(JSContext* aCx, } IntRect srcRect(0, 0, mWidth, mHeight); - IntRect destRect(aX, aY, aWidth, aHeight); - IntRect srcReadRect = srcRect.Intersect(destRect); + IntRect dstWriteRect(0, 0, aWidth, aHeight); + IntRect srcReadRect = ClipImageDataTransfer(dstWriteRect, IntPoint(aX, aY), + IntSize(mWidth, mHeight)); RefPtr readback; DataSourceSurface::MappedSurface rawData; if (!srcReadRect.IsEmpty()) { @@ -5280,9 +5291,6 @@ CanvasRenderingContext2D::GetImageDataArray(JSContext* aCx, } } - IntRect dstWriteRect = srcReadRect; - dstWriteRect.MoveBy(-aX, -aY); - uint8_t* src; uint32_t srcStride; @@ -5467,10 +5475,10 @@ CanvasRenderingContext2D::PutImageData_explicit(int32_t x, int32_t y, uint32_t w dirtyRect = imageDataRect; } - dirtyRect.MoveBy(IntPoint(x, y)); - dirtyRect = IntRect(0, 0, mWidth, mHeight).Intersect(dirtyRect); - - if (dirtyRect.Width() <= 0 || dirtyRect.Height() <= 0) { + IntRect srcRect = dirtyRect; + dirtyRect = ClipImageDataTransfer(srcRect, IntPoint(x, y), + IntSize(mWidth, mHeight)); + if (dirtyRect.IsEmpty()) { return NS_OK; } @@ -5492,8 +5500,8 @@ CanvasRenderingContext2D::PutImageData_explicit(int32_t x, int32_t y, uint32_t w return NS_ERROR_FAILURE; } - uint32_t copyX = dirtyRect.x - x; - uint32_t copyY = dirtyRect.y - y; + uint32_t copyX = dirtyRect.x; + uint32_t copyY = dirtyRect.y; //uint8_t *src = aArray->Data(); uint8_t *dst = imgsurf->Data(); uint8_t* srcLine = aArray->Data() + copyY * (w * 4) + copyX * 4; diff --git a/dom/indexedDB/KeyPath.cpp b/dom/indexedDB/KeyPath.cpp index dc8d10668..99ea9b160 100644 --- a/dom/indexedDB/KeyPath.cpp +++ b/dom/indexedDB/KeyPath.cpp @@ -107,7 +107,7 @@ GetJSValFromKeyPathString(JSContext* aCx, // step 4 substep 1: check for .length on a String value. if (currentVal.isString() && !tokenizer.hasMoreTokens() && token.EqualsLiteral("length") && aOptions == DoNotCreateProperties) { - aKeyJSVal->setNumber(double(JS_GetStringLength(currentVal.toString()))); + aKeyJSVal->setNumber(uint32_t(JS_GetStringLength(currentVal.toString()))); break; } diff --git a/dom/jsurl/nsJSProtocolHandler.cpp b/dom/jsurl/nsJSProtocolHandler.cpp index b1b295e2b..86ef33cd6 100644 --- a/dom/jsurl/nsJSProtocolHandler.cpp +++ b/dom/jsurl/nsJSProtocolHandler.cpp @@ -201,7 +201,7 @@ nsresult nsJSThunk::EvaluateScript(nsIChannel *aChannel, // Sandboxed document check: javascript: URI's are disabled // in a sandboxed document unless 'allow-scripts' was specified. nsIDocument* doc = aOriginalInnerWindow->GetExtantDoc(); - if (doc && doc->HasScriptsBlockedBySandbox()) { + if (doc && !doc->IsScriptEnabled()) { return NS_ERROR_DOM_RETVAL_UNDEFINED; } diff --git a/gfx/2d/BaseRect.h b/gfx/2d/BaseRect.h index b802df5e3..481213e3d 100644 --- a/gfx/2d/BaseRect.h +++ b/gfx/2d/BaseRect.h @@ -118,12 +118,36 @@ struct BaseRect { } return result; } + // Gives the same results as Intersect() but handles integer overflow + // better. This comes at a tiny cost in performance. + // e.g. {INT_MIN, 0, 0, 20} Intersect { 5000, 0, 500, 20 } gives: + // {5000, 0, 0, 0} + MOZ_WARN_UNUSED_RESULT Sub SafeIntersect(const Sub& aRect) const { + Sub result; + result.x = std::max(x, aRect.x); + result.y = std::max(y, aRect.y); + T right = std::min(x + width, aRect.x + aRect.width); + T bottom = std::min(y + height, aRect.y + aRect.height); + // See bug 1457110, this function expects to -only- size to 0,0 if the + // width/height is explicitly negative. + if (right < result.x || bottom < result.y) { + result.width = 0; + result.height = 0; + } else { + result.width = right - result.x; + result.height = bottom - result.y; + } + return result; + } // Sets *this to be the rectangle containing the intersection of the points // (including edges) of *this and aRect. If there are no points in that // intersection, sets *this to be an empty rectangle with x/y set to the std::max // of the x/y of *this and aRect. // // 'this' can be the same object as either aRect1 or aRect2 + // Note: bug 1457110 changed this due to a regression from bug 1387399, + // but we never used that code, and it was subsequently backed out. We have + // SafeIntersect only so we can implement bug 1767365. bool IntersectRect(const Sub& aRect1, const Sub& aRect2) { *static_cast(this) = aRect1.Intersect(aRect2); @@ -209,6 +233,39 @@ struct BaseRect { void SizeTo(T aWidth, T aHeight) { width = aWidth; height = aHeight; } void SizeTo(const SizeT& aSize) { width = aSize.width; height = aSize.height; } + // Variant of MoveBy that ensures that even after translation by a point that + // the rectangle coordinates will still fit within numeric limits. The origin + // and size will be clipped within numeric limits to ensure this. + void SafeMoveByX(T aDx) { + T x2 = XMost(); + if (aDx >= T(0)) { + T limit = std::numeric_limits::max(); + x = limit - aDx < x ? limit : x + aDx; + width = (limit - aDx < x2 ? limit : x2 + aDx) - x; + } else { + T limit = std::numeric_limits::min(); + x = limit - aDx > x ? limit : x + aDx; + width = (limit - aDx > x2 ? limit : x2 + aDx) - x; + } + } + void SafeMoveByY(T aDy) { + T y2 = YMost(); + if (aDy >= T(0)) { + T limit = std::numeric_limits::max(); + y = limit - aDy < y ? limit : y + aDy; + height = (limit - aDy < y2 ? limit : y2 + aDy) - y; + } else { + T limit = std::numeric_limits::min(); + y = limit - aDy > y ? limit : y + aDy; + height = (limit - aDy > y2 ? limit : y2 + aDy) - y; + } + } + void SafeMoveBy(T aDx, T aDy) { + SafeMoveByX(aDx); + SafeMoveByY(aDy); + } + void SafeMoveBy(const Point& aPoint) { SafeMoveBy(aPoint.x, aPoint.y); } + void Inflate(T aD) { Inflate(aD, aD); } void Inflate(T aDx, T aDy) { diff --git a/js/xpconnect/src/XPCConvert.cpp b/js/xpconnect/src/XPCConvert.cpp index a4c07ab57..753a10a5d 100644 --- a/js/xpconnect/src/XPCConvert.cpp +++ b/js/xpconnect/src/XPCConvert.cpp @@ -134,7 +134,7 @@ XPCConvert::NativeData2JS(MutableHandleValue d, const void* s, d.setNumber(*static_cast(s)); return true; case nsXPTType::T_DOUBLE: - d.setNumber(*static_cast(s)); + d.set(JS_NumberValue(*static_cast(s))); return true; case nsXPTType::T_BOOL : d.setBoolean(*static_cast(s)); diff --git a/js/xpconnect/src/XPCVariant.cpp b/js/xpconnect/src/XPCVariant.cpp index d37d0eb01..0fea6bc10 100644 --- a/js/xpconnect/src/XPCVariant.cpp +++ b/js/xpconnect/src/XPCVariant.cpp @@ -425,7 +425,7 @@ XPCVariant::VariantDataToJS(nsIVariant* variant, double d; if (NS_FAILED(variant->GetAsDouble(&d))) return false; - pJSVal.setNumber(d); + pJSVal.set(JS_NumberValue(d)); return true; } case nsIDataType::VTYPE_BOOL: diff --git a/modules/libjar/moz.build b/modules/libjar/moz.build index c4f86a484..097c9b3c8 100644 --- a/modules/libjar/moz.build +++ b/modules/libjar/moz.build @@ -48,5 +48,9 @@ include('/ipc/chromium/chromium-config.mozbuild') FINAL_LIBRARY = 'xul' +LOCAL_INCLUDES += [ + '/netwerk/base', +] + if CONFIG['GNU_CXX']: CXXFLAGS += ['-Wshadow'] diff --git a/modules/libjar/nsJARChannel.cpp b/modules/libjar/nsJARChannel.cpp index c9ec701da..c4cd74fa0 100644 --- a/modules/libjar/nsJARChannel.cpp +++ b/modules/libjar/nsJARChannel.cpp @@ -28,6 +28,7 @@ #include "nsINetworkInterceptController.h" #include "InterceptedJARChannel.h" #include "nsInputStreamPump.h" +#include "nsStandardURL.h" using namespace mozilla; using namespace mozilla::net; @@ -83,6 +84,24 @@ public: fullJarURI->GetAsciiSpec(mJarDirSpec); NS_ASSERTION(NS_SUCCEEDED(rv), "this shouldn't fail"); } + /* implement bug 1771774 without NS_MutateURI: use asciispec above */ + if (ENTRY_IS_DIRECTORY(mJarEntry) && fullJarURI) { + RefPtr cleanuri = new nsStandardURL(); + + if (NS_SUCCEEDED(cleanuri->Init( + nsIStandardURL::URLTYPE_NO_AUTHORITY, -1, + mJarDirSpec, nullptr, nullptr))) { + cleanuri->SetQuery(NS_LITERAL_CSTRING("")); + cleanuri->SetRef(NS_LITERAL_CSTRING("")); +#ifdef DEBUG + nsresult rv = +#endif + cleanuri->GetAsciiSpec(mJarDirSpec); + NS_ASSERTION(NS_SUCCEEDED(rv), "this shouldn't fail either"); + } else { + MOZ_CRASH("failed to clean jar URI"); + } + } } int64_t GetContentLength() @@ -696,47 +715,49 @@ nsJARChannel::GetSecurityInfo(nsISupports **aSecurityInfo) } NS_IMETHODIMP -nsJARChannel::GetContentType(nsACString &result) +nsJARChannel::SetContentTypeGuess() { + // + // generate content type and set it + // + const char *ext = nullptr, *fileName = mJarEntry.get(); + int32_t len = mJarEntry.Length(); + + // check if we're displaying a directory + // mJarEntry will be empty if we're trying to display + // the topmost directory in a zip, e.g. jar:foo.zip!/ + if (ENTRY_IS_DIRECTORY(mJarEntry)) { + mContentType.AssignLiteral(APPLICATION_HTTP_INDEX_FORMAT); + } else { + // not a directory, take a guess by its extension + for (int32_t i = len-1; i >= 0; i--) { + if (fileName[i] == '.') { + ext = &fileName[i + 1]; + break; + } + } + if (ext) { + nsIMIMEService *mimeServ = gJarHandler->MimeService(); + if (mimeServ) + mimeServ->GetTypeFromExtension(nsDependentCString(ext), mContentType); + } + if (mContentType.IsEmpty()) + mContentType.AssignLiteral(UNKNOWN_CONTENT_TYPE); + } + + return NS_OK; +} + +NS_IMETHODIMP +nsJARChannel::GetContentType(nsACString &aResult) { // If the Jar file has not been open yet, // We return application/x-unknown-content-type - if (!mOpened) { - result.Assign(UNKNOWN_CONTENT_TYPE); + if (!mOpened || mContentType.IsEmpty()) { + aResult.Assign(UNKNOWN_CONTENT_TYPE); return NS_OK; } - if (mContentType.IsEmpty()) { - - // - // generate content type and set it - // - const char *ext = nullptr, *fileName = mJarEntry.get(); - int32_t len = mJarEntry.Length(); - - // check if we're displaying a directory - // mJarEntry will be empty if we're trying to display - // the topmost directory in a zip, e.g. jar:foo.zip!/ - if (ENTRY_IS_DIRECTORY(mJarEntry)) { - mContentType.AssignLiteral(APPLICATION_HTTP_INDEX_FORMAT); - } - else { - // not a directory, take a guess by its extension - for (int32_t i = len-1; i >= 0; i--) { - if (fileName[i] == '.') { - ext = &fileName[i + 1]; - break; - } - } - if (ext) { - nsIMIMEService *mimeServ = gJarHandler->MimeService(); - if (mimeServ) - mimeServ->GetTypeFromExtension(nsDependentCString(ext), mContentType); - } - if (mContentType.IsEmpty()) - mContentType.AssignLiteral(UNKNOWN_CONTENT_TYPE); - } - } - result = mContentType; + aResult = mContentType; return NS_OK; } @@ -847,7 +868,7 @@ nsJARChannel::Open(nsIInputStream **stream) return rv; input.forget(stream); - mOpened = true; + SetOpened(); // local files are always considered safe mIsUnsafe = false; return NS_OK; @@ -934,6 +955,14 @@ nsJARChannel::OverrideWithSynthesizedResponse(nsIInputStream* aSynthesizedInput, NS_ENSURE_SUCCESS_VOID(rv); } +void +nsJARChannel::SetOpened() { + MOZ_ASSERT(!mOpened, "Opening channel twice?"); + mOpened = true; + // Compute the content type now. + NS_ASSERTION(NS_SUCCEEDED(SetContentTypeGuess()), "content type guess failure"); +} + NS_IMETHODIMP nsJARChannel::AsyncOpen(nsIStreamListener *listener, nsISupports *ctx) { @@ -1068,7 +1097,7 @@ nsJARChannel::FinishAsyncOpen() if (mLoadGroup) mLoadGroup->AddRequest(this, nullptr); - mOpened = true; + SetOpened(); } //----------------------------------------------------------------------------- diff --git a/modules/libjar/nsJARChannel.h b/modules/libjar/nsJARChannel.h index 8c5d6f6ab..ce2e312d4 100644 --- a/modules/libjar/nsJARChannel.h +++ b/modules/libjar/nsJARChannel.h @@ -82,6 +82,9 @@ private: bool BypassServiceWorker() const; + nsresult SetContentTypeGuess(); + void SetOpened(); + // Returns true if this channel should intercept the network request and // prepare for a possible synthesized response instead. bool ShouldIntercept(); diff --git a/modules/libpref/init/all.js b/modules/libpref/init/all.js index 65db2524a..a32f996d8 100644 --- a/modules/libpref/init/all.js +++ b/modules/libpref/init/all.js @@ -1224,7 +1224,10 @@ pref("network.protocol-handler.external.iehistory", false); pref("network.protocol-handler.external.ierss", false); pref("network.protocol-handler.external.mk", false); pref("network.protocol-handler.external.ms-help", false); +pref("network.protocol-handler.external.ms-msdt", false); pref("network.protocol-handler.external.res", false); +pref("network.protocol-handler.external.search", false); +pref("network.protocol-handler.external.search-ms", false); pref("network.protocol-handler.external.shell", false); pref("network.protocol-handler.external.vnd.ms.radio", false); #ifdef XP_MACOSX diff --git a/modules/zlib/src/mozzconf.h b/modules/zlib/src/mozzconf.h index f1da5ae28..f26687280 100644 --- a/modules/zlib/src/mozzconf.h +++ b/modules/zlib/src/mozzconf.h @@ -44,7 +44,10 @@ #define gzputs MOZ_Z_gzputs #define gzgets MOZ_Z_gzgets #define gzputc MOZ_Z_gzputc +/* +This is now a macro #define gzgetc MOZ_Z_gzgetc +*/ #define gzungetc MOZ_Z_gzungetc #define gzflush MOZ_Z_gzflush #define gzseek MOZ_Z_gzseek diff --git a/xpcom/glue/nsTArray.h b/xpcom/glue/nsTArray.h index ad80cab8d..e0704581a 100644 --- a/xpcom/glue/nsTArray.h +++ b/xpcom/glue/nsTArray.h @@ -1278,6 +1278,8 @@ protected: elem_type* ReplaceElementsAt(index_type aStart, size_type aCount, const Item* aArray, size_type aArrayLen) { + MOZ_RELEASE_ASSERT(!(aStart > Length())); + MOZ_RELEASE_ASSERT(!(aCount > (Length() - aStart))); // Adjust memory allocation up-front to catch errors. if (!ActualAlloc::Successful(this->template EnsureCapacity( Length() + aArrayLen - aCount, sizeof(elem_type)))) {