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

This commit is contained in:
2026-04-02 23:49:52 +08:00
9 changed files with 240 additions and 35 deletions
+4 -1
View File
@@ -2443,8 +2443,11 @@ FilterNodeConvolveMatrixSoftware::DoRender(const IntRect& aRect,
CoordType aKernelUnitLengthX,
CoordType aKernelUnitLengthY)
{
// Ensure multiply fits in an int32_t so convolve math won't overflow.
auto kernelArea = CheckedInt32(mKernelSize.width) * mKernelSize.height;
if (mKernelSize.width <= 0 || mKernelSize.height <= 0 ||
mKernelMatrix.size() != uint32_t(mKernelSize.width * mKernelSize.height) ||
!kernelArea.isValid() ||
mKernelMatrix.size() != size_t(kernelArea.value()) ||
!IntRect(IntPoint(0, 0), mKernelSize).Contains(mTarget) ||
mDivisor == 0) {
return Factory::CreateDataSourceSurface(aRect.Size(), SurfaceFormat::B8G8R8A8, true);
+29 -23
View File
@@ -1155,8 +1155,8 @@ AddOpenTypeFeature(const uint32_t& aTag, uint32_t& aValue, void *aUserArg)
* gfxFontShaper override to initialize the text run using HarfBuzz
*/
static hb_font_funcs_t * sHBFontFuncs = nullptr;
static hb_unicode_funcs_t * sHBUnicodeFuncs = nullptr;
static hb_font_funcs_t* sHBFontFuncs = nullptr;
static hb_unicode_funcs_t* sHBUnicodeFuncs = nullptr;
static const hb_script_t sMathScript =
hb_ot_tag_to_script(HB_TAG('m','a','t','h'));
@@ -1171,55 +1171,61 @@ gfxHarfBuzzShaper::Initialize()
mUseFontGlyphWidths = mFont->ProvidesGlyphWidths();
if (!sHBFontFuncs) {
// static function callback pointers, initialized by the first
// harfbuzz shaper used
sHBFontFuncs = hb_font_funcs_create();
hb_font_funcs_set_nominal_glyph_func(sHBFontFuncs,
// Function callback pointers; these are local statics to ensure thread-safe
// initialization on first use.
static hb_font_funcs_t* sHBFontFuncs = [] {
auto* funcs = hb_font_funcs_create();
hb_font_funcs_set_nominal_glyph_func(funcs,
HBGetNominalGlyph,
nullptr, nullptr);
hb_font_funcs_set_variation_glyph_func(sHBFontFuncs,
hb_font_funcs_set_variation_glyph_func(funcs,
HBGetVariationGlyph,
nullptr, nullptr);
hb_font_funcs_set_glyph_h_advance_func(sHBFontFuncs,
hb_font_funcs_set_glyph_h_advance_func(funcs,
HBGetGlyphHAdvance,
nullptr, nullptr);
hb_font_funcs_set_glyph_v_advance_func(sHBFontFuncs,
hb_font_funcs_set_glyph_v_advance_func(funcs,
HBGetGlyphVAdvance,
nullptr, nullptr);
hb_font_funcs_set_glyph_v_origin_func(sHBFontFuncs,
hb_font_funcs_set_glyph_v_origin_func(funcs,
HBGetGlyphVOrigin,
nullptr, nullptr);
hb_font_funcs_set_glyph_extents_func(sHBFontFuncs,
hb_font_funcs_set_glyph_extents_func(funcs,
HBGetGlyphExtents,
nullptr, nullptr);
hb_font_funcs_set_glyph_contour_point_func(sHBFontFuncs,
hb_font_funcs_set_glyph_contour_point_func(funcs,
HBGetContourPoint,
nullptr, nullptr);
hb_font_funcs_set_glyph_h_kerning_func(sHBFontFuncs,
hb_font_funcs_set_glyph_h_kerning_func(funcs,
HBGetHKerning,
nullptr, nullptr);
return funcs;
}();
sHBUnicodeFuncs =
hb_unicode_funcs_create(hb_unicode_funcs_get_empty());
hb_unicode_funcs_set_mirroring_func(sHBUnicodeFuncs,
static hb_unicode_funcs_t* sHBUnicodeFuncs = [] {
auto* funcs = hb_unicode_funcs_create(hb_unicode_funcs_get_empty());
hb_unicode_funcs_set_mirroring_func(funcs,
HBGetMirroring,
nullptr, nullptr);
hb_unicode_funcs_set_script_func(sHBUnicodeFuncs, HBGetScript,
hb_unicode_funcs_set_script_func(funcs,
HBGetScript,
nullptr, nullptr);
hb_unicode_funcs_set_general_category_func(sHBUnicodeFuncs,
hb_unicode_funcs_set_general_category_func(funcs,
HBGetGeneralCategory,
nullptr, nullptr);
hb_unicode_funcs_set_combining_class_func(sHBUnicodeFuncs,
hb_unicode_funcs_set_combining_class_func(funcs,
HBGetCombiningClass,
nullptr, nullptr);
hb_unicode_funcs_set_compose_func(sHBUnicodeFuncs,
hb_unicode_funcs_set_compose_func(funcs,
HBUnicodeCompose,
nullptr, nullptr);
hb_unicode_funcs_set_decompose_func(sHBUnicodeFuncs,
hb_unicode_funcs_set_decompose_func(funcs,
HBUnicodeDecompose,
nullptr, nullptr);
return funcs;
}();
if (!sNormalizer) {
UErrorCode error = U_ZERO_ERROR;
sNormalizer = unorm2_getNFCInstance(&error);
MOZ_ASSERT(U_SUCCESS(error), "failed to get ICU normalizer");
+67
View File
@@ -899,6 +899,73 @@ function TypedArrayToReversed() {
return A;
}
// ES2023 23.2.3.33 %TypedArray%.prototype.toSorted ( comparator )
function TypedArrayToSorted(comparator) {
// Step 1.
if (comparator !== undefined && !IsCallable(comparator))
ThrowTypeError(JSMSG_NOT_FUNCTION, DecompileArg(0, comparator));
// Step 2.
var O = this;
// Step 3.
// This function is not generic.
// We want to make sure that we have an attached buffer, per spec prose.
var isTypedArray = IsTypedArrayEnsuringArrayBuffer(O);
// If we got here, `this` is either a typed array or a wrapper for one.
// Step 4.
var len;
if (isTypedArray)
len = TypedArrayLength(O);
else
len = callFunction(CallTypedArrayMethodIfWrapped, O, "TypedArrayLengthMethod");
// Step 5.
var A = TypedArrayCreateSameType(O, len);
// Step 8.
var sortedList = new List();
for (var k = 0; k < len; k++) {
sortedList[k] = O[k];
}
if (len > 1) {
// Steps 6-7.
var sortCompare;
if (comparator === undefined) {
var isBigIntContentType;
if (isTypedArray) {
isBigIntContentType = callFunction(TypedArrayContentTypeIsBigIntMethod, O);
} else {
isBigIntContentType = callFunction(CallTypedArrayMethodIfWrapped, O,
"TypedArrayContentTypeIsBigIntMethod");
}
sortCompare = isBigIntContentType ? TypedArrayCompareBigInt : TypedArrayCompare;
} else {
var wrappedComparator = comparator;
sortCompare = function(x, y) {
// CompareTypedArrayElements step 2.a.
var v = ToNumber(callContentFunction(wrappedComparator, undefined, x, y));
// CompareTypedArrayElements step 2.b.
return Number_isNaN(v) ? 0 : v;
};
}
MergeSort(sortedList, len, sortCompare);
}
// Steps 9-10.
for (var j = 0; j < len; j++) {
A[j] = sortedList[j];
}
// Step 11.
return A;
}
// ES2023 23.2.3.36 %TypedArray%.prototype.with ( index, value )
function TypedArrayWith(index, value) {
// Step 1.
+119
View File
@@ -0,0 +1,119 @@
for (var constructor of anyTypedArrayConstructors) {
assertEq(constructor.prototype.toSorted.length, 1);
var original = new constructor([3, 1, 2]);
var sorted = original.toSorted();
assertDeepEq(sorted, new constructor([1, 2, 3]));
assertDeepEq(original, new constructor([3, 1, 2]));
assertEq(sorted === original, false);
assertEq(sorted.constructor, constructor);
var descending = original.toSorted((a, b) => b - a);
assertDeepEq(descending, new constructor([3, 2, 1]));
assertDeepEq(original, new constructor([3, 1, 2]));
var stableInput = new constructor([2, 1, 4, 3]);
var stableSorted = stableInput.toSorted((a, b) => (a % 2) - (b % 2));
assertDeepEq(stableSorted, new constructor([2, 4, 1, 3]));
var nanComparatorInput = new constructor([4, 1, 3, 2]);
var nanComparatorSorted = nanComparatorInput.toSorted(() => NaN);
assertDeepEq(nanComparatorSorted, nanComparatorInput);
var ctorIgnored = new constructor([5, 1, 4]);
Object.defineProperty(ctorIgnored, "constructor", {
get() {
throw new Error("constructor accessor called");
}
});
assertDeepEq(ctorIgnored.toSorted(), new constructor([1, 4, 5]));
if (isFloatConstructor(constructor)) {
var floatInput = new constructor([0, -0, 1, -1, NaN]);
var floatSorted = floatInput.toSorted();
assertEq(floatSorted[0], -1);
assertEq(1 / floatSorted[1], -Infinity);
assertEq(1 / floatSorted[2], Infinity);
assertEq(floatSorted[3], 1);
assertEq(Number.isNaN(floatSorted[4]), true);
}
var invalidReceivers = [undefined, null, 1, false, "", Symbol(), [], {}, /./,
new Proxy(new constructor(), {})];
invalidReceivers.forEach(invalidReceiver => {
assertThrowsInstanceOf(() => {
constructor.prototype.toSorted.call(invalidReceiver);
}, TypeError,
"Assert that toSorted fails if this value is not a TypedArray");
});
}
for (var constructor of typedArrayConstructors) {
if (typeof newGlobal === "function") {
var toSorted = newGlobal()[constructor.name].prototype.toSorted;
var original = new constructor([3, 2, 1]);
var sorted = toSorted.call(original);
assertDeepEq(sorted, new constructor([1, 2, 3]));
assertDeepEq(original, new constructor([3, 2, 1]));
}
}
assertThrowsInstanceOf(() => {
Int32Array.prototype.toSorted.call(new Int32Array([1, 2, 3]), 0);
}, TypeError);
if (typeof detachArrayBuffer === "function") {
assertThrowsInstanceOf(() => {
let buffer = new ArrayBuffer(16);
let array = new Int32Array(buffer);
detachArrayBuffer(buffer);
array.toSorted();
}, TypeError);
}
if (typeof detachArrayBuffer === "function") {
let ta = new Int32Array([3, 1, 2]);
let detached = false;
let sorted = ta.toSorted(function(a, b) {
if (!detached) {
detached = true;
detachArrayBuffer(ta.buffer);
}
return a - b;
});
assertDeepEq(sorted, new Int32Array([1, 2, 3]));
}
if (typeof newGlobal === "function" && typeof detachArrayBuffer === "function") {
let ta = new Int32Array([3, 1, 2]);
let otherGlobal = newGlobal();
let detached = false;
let sorted = otherGlobal.Int32Array.prototype.toSorted.call(ta, function(a, b) {
if (!detached) {
detached = true;
detachArrayBuffer(ta.buffer);
}
return a - b;
});
assertDeepEq(sorted, new Int32Array([1, 2, 3]));
}
if (typeof BigInt64Array === "function" && typeof BigUint64Array === "function") {
let bigIntArray = new BigInt64Array([3n, 1n, 2n]);
let bigIntSorted = bigIntArray.toSorted();
assertEq(BigInt64Array.prototype.toSorted.length, 1);
assertDeepEq(bigIntSorted, new BigInt64Array([1n, 2n, 3n]));
assertDeepEq(bigIntArray, new BigInt64Array([3n, 1n, 2n]));
assertThrowsInstanceOf(() => {
bigIntArray.toSorted((a, b) => a - b);
}, TypeError);
let bigUintArray = new BigUint64Array([3n, 1n, 2n]);
assertDeepEq(bigUintArray.toSorted(), new BigUint64Array([1n, 2n, 3n]));
}
if (typeof reportCompare === "function")
reportCompare(true, true);
+1
View File
@@ -1629,6 +1629,7 @@ TypedArrayObject::protoFunctions[] = {
JS_SELF_HOSTED_FN("reduceRight", "TypedArrayReduceRight", 1, 0),
JS_SELF_HOSTED_FN("reverse", "TypedArrayReverse", 0, 0),
JS_SELF_HOSTED_FN("toReversed", "TypedArrayToReversed", 0, 0),
JS_SELF_HOSTED_FN("toSorted", "TypedArrayToSorted", 1, 0),
JS_SELF_HOSTED_FN("with", "TypedArrayWith", 2, 0),
JS_SELF_HOSTED_FN("slice", "TypedArraySlice", 2, 0),
JS_SELF_HOSTED_FN("some", "TypedArraySome", 1, 0),
+8 -5
View File
@@ -19,11 +19,14 @@ if sys.platform == 'darwin':
print("find_sdk_uxp.py: error: Specified path does not exist or is not a directory")
sys.exit(1)
KNOWN_SDK_VERSIONS = ["10.7", "10.8", "10.9", "10.10", "10.11"
"10.12", "10.13", "10.14", "10.15", "10.16",
"11.0", "11.1", "11.2", "11.3", "12.0", "12.1", "12.3",
"13.0", "13.1", "13.2", "14.0", "14.2", "14.4", "14.5",
"15.0", "15.1", "15.2", "15.4"]
KNOWN_SDK_VERSIONS = ["10.4", "10.5", "10.6", "10.7", "10.8", "10.9", "10.10",
"10.11", "10.12", "10.13", "10.14", "10.15", "10.16",
"11.0", "11.1", "11.2", "11.3",
"12.0", "12.1", "12.3",
"13.0", "13.1", "13.2",
"14.0", "14.2", "14.4", "14.5",
"15.0", "15.1", "15.2", "15.4",
"26.0", "26.1", "26.4"]
REGEX = "^MacOSX(\d+\.\d+)\.sdk$"
SDK_VERSION = re.findall(REGEX, os.path.basename(SDK_PATH))
+7 -4
View File
@@ -625,10 +625,13 @@ nsHttpResponseHead::ParseHeaderLine_locked(const nsACString &line, bool original
LOG(("invalid content-length! %s\n", val.get()));
}
} else if (hdr == nsHttp::Content_Type) {
LOG(("ParseContentType [type=%s]\n", val.get()));
bool dummy;
net_ParseContentType(val,
mContentType, mContentCharset, &dummy);
if (mStatus == 304) {
LOG(("Non-compliant Content-type value ignored"));
} else {
LOG(("ParseContentType [type=%s]\n", val.get()));
bool dummy;
net_ParseContentType(val, mContentType, mContentCharset, &dummy);
}
} else if (hdr == nsHttp::Cache_Control) {
// Re-parse merged header in its entirety. See Issue #2852
ParseCacheControl(mHeaders.PeekHeader(hdr));
+1 -1
View File
@@ -286,7 +286,7 @@ PK11_ImportDERPrivateKeyInfoAndReturnKey(PK11SlotInfo *slot, SECItem *derPKI,
PORT_FreeArena(temparena, PR_TRUE);
return rv;
}
if (pki->privateKey.data == NULL) {
if (pki->privateKey.data == NULL || pki->privateKey.len == 0) {
/* If SEC_ASN1DecodeItems succeeds but SECKEYPrivateKeyInfo.privateKey
* is a zero-length octet string, free the arena and return a failure
* to avoid trying to zero the corresponding SECItem in
+4 -1
View File
@@ -22,7 +22,7 @@ static size_t CompressedBufferLength()
static size_t kCompressedBufferLength =
detail::SnappyFrameUtils::MaxCompressedBufferLength(snappy::kBlockSize);
MOZ_ASSERT(kCompressedBufferLength > 0);
MOZ_ASSERT(kCompressedBufferLength > detail::SnappyFrameUtils::kHeaderLength);
return kCompressedBufferLength;
}
@@ -269,6 +269,9 @@ SnappyUncompressInputStream::ParseNextChunk(uint32_t* aBytesReadOut)
// Read at least that much from the base stream.
uint32_t readLength = mNextChunkDataLength;
MOZ_ASSERT(readLength <= CompressedBufferLength());
if (readLength > CompressedBufferLength() - kHeaderLength) {
return NS_ERROR_CORRUPTED_CONTENT;
}
// However, if there is enough data in the base stream, also read the next
// chunk header. This helps optimize the stream by avoiding many small reads.