Compare commits

...
37 Commits
Author SHA1 Message Date
Moonchild 53bf5b5a21 Bump NSS (UXP) patch level. 2026-07-28 15:51:54 +02:00
John Schanck 07b2881965 Bug 2043887 - guard against integer overflow in CERT_Hexify. 2026-07-28 15:51:45 +02:00
Benjamin Beurdouche ca1b7c2595 Bug 2027353 - clamp input.len to testString size in pk11_mergeSecretKey. 2026-07-28 15:51:41 +02:00
Benjamin Beurdouche a0d8eeb768 Bug 2029433 - Bounds-check wrap index in PK11_GetWrapKey to match PK11_SetWrapKey. 2026-07-28 15:51:34 +02:00
Anna Weine 278ce9a272 Bug 2028954 - CERT_DecodeAVAValue — Integer Overflow in Output Buffer Sizing. 2026-07-28 15:51:29 +02:00
Moonchild 9367b64f2a Bug 2027364 - Set tail pointer to null in static slot lists when deallocating. 2026-07-28 15:51:24 +02:00
John Schanck 080247cf2f Bug 2032110 - fix two integer overflows on LLP64 systems. 2026-07-28 15:51:19 +02:00
John Schanck 95bf9478c7 Bug 2030102 - avoid leaving a dangling ss->sec.ci.sid on allocation failure. 2026-07-28 15:51:13 +02:00
Maurice Dauer 4ae3149d2e Bug 2027325 - Reject empty nickname in PK11_TraverseCertsForNicknameInSlot. 2026-07-28 15:51:08 +02:00
Moonchild 9bf01636f1 Bug 2030563 - Validate CKA_CERTIFICATE_TYPE ulValueLen in nss_cert_type_from_ck_attrib. 2026-07-28 15:51:03 +02:00
Benjamin Beurdouche e48fe8e307 Bug 2029807 - Guard padding read against empty output in SEC_PKCS7DecryptContents. 2026-07-28 15:50:56 +02:00
Benjamin Beurdouche 27c12ad698 Bug 2027346 - validate encoded EC params length and tag in SECKEY_ECParamsToKeySize/BasePointOrderLen. 2026-07-28 15:50:51 +02:00
Benjamin Beurdouche 612ddb64e5 Bug 2027371 - rewrite labelLen bound in tls13_HkdfExpandLabelGeneral to avoid unsigned overflow. 2026-07-28 15:50:46 +02:00
Benjamin Beurdouche c6c8421a2a Bug 2027373 - guard space subtraction in ssl_CallCustomExtensionSenders. 2026-07-28 15:50:41 +02:00
Benjamin Beurdouche f9859d226c Bug 2029901 - Guard against keySize overflow in IKE PRF/PRF+ output sizing. 2026-07-28 15:50:36 +02:00
Benjamin Beurdouche 7c0e60c4f1 Bug 2027362 - bound usageCount in PK11_UnwrapPrivKey to keyTemplate capacity. 2026-07-28 15:50:27 +02:00
Benjamin Beurdouche e06ef010c4 Bug 2027349 - reject empty nickname in PK11_TraverseCertsForNicknameInSlot. 2026-07-28 15:50:20 +02:00
Moonchild 3935cd9ed3 [network] Fix CacheEntry::mDoomCallback data race. 2026-07-28 15:49:52 +02:00
Moonchild f781824676 [layout] Fix nsFrameSetFrame primary frame handling of replicated children. 2026-07-28 15:49:40 +02:00
Moonchild 5a231d5bf9 [DOM media] Perform more thorough checks on video regions. 2026-07-28 15:49:19 +02:00
az 02302031dd Bug 2045742 2026-07-28 15:49:11 +02:00
Andrew McCreight b59b350424 Bug 2049523 - Make ToJSValue for float consistent with double. 2026-07-28 15:48:56 +02:00
Moonchild 99b8669d0a Fix comment (nit) 2026-07-28 15:48:49 +02:00
Randell Jesup 919fbff2ec Bug 2029734: Flush before calling sctp_process_init() 2026-07-28 15:48:10 +02:00
Moonchild 4977713834 [image] Make sure the image was fully and cleanly decoded before finalizing its animation state as complete. 2026-07-28 15:48:01 +02:00
Moonchild 1f8bd8cf45 [parser] Associate image elements with form only if the form and the intended parent are in the same tree. 2026-07-28 15:47:55 +02:00
Moonchild 8f6bacf33e [DOM media] Stop accepting audio samples with too low sample rates.
This sets the floor to 8kHz audio, which is generally considered to be
the lowest acceptable "phone quality"/"walkie-talkie" audio rate.
Audio outside the range will refuse to decode after this commit and give
a console error.
This avoids a whole class of potential bugs.
2026-07-28 15:47:27 +02:00
Moonchild a79a1b55a1 [layout] Add corner-case correctness check in DottedCornerFinder::FindBestOverlap. 2026-07-28 15:47:21 +02:00
Moonchild fa4d389b91 [network] Add usrsctp TSN gap check. 2026-07-28 15:47:08 +02:00
Moonchild 36b884ff7f [js] Clamp length of regexp captures array for dollar substitution. 2026-07-28 15:46:52 +02:00
Moonchild f3a7e60608 [js] Initialize BaselineFrame return value slot in OnLeaveBaselineFrame. 2026-07-28 15:46:45 +02:00
Moonchild a8405c5667 [DOM] Make parser update form owner properly 2026-07-28 15:46:39 +02:00
Moonchild 829354fb65 [gfx] Hold a strong ref during GetFontAt lookup. 2026-07-28 15:46:33 +02:00
Moonchild 4be7883908 [gfx] Add bounds checks and limit reverse scanning of ligature data. 2026-07-28 15:46:27 +02:00
Moonchild 2f77b246b3 No issue - Use strnlen instead of strnlen_s.
Apparently, GCC doesn't like the _s variants.
2026-07-28 15:46:08 +02:00
Moonchild ddf950f5ed [js] Guard against OOB string sizes in internal Printf 2026-07-28 15:45:28 +02:00
Basilisk-Dev ad98fe5130 Issue #3140 - implement URL.parse() 2026-07-14 23:08:55 +02:00
46 changed files with 380 additions and 93 deletions

No files matched your search

+2 -2
View File
@@ -97,7 +97,7 @@ ToJSValue(JSContext* aCx,
return true;
}
// accept floating point types
// Accept floating point types
inline bool
ToJSValue(JSContext* aCx,
float aArgument,
@@ -106,7 +106,7 @@ ToJSValue(JSContext* aCx,
// Make sure we're called in a compartment
MOZ_ASSERT(JS::CurrentGlobalOrNull(aCx));
aValue.setNumber(aArgument);
aValue.set(JS_NumberValue(double(aArgument)));
return true;
}
+2 -10
View File
@@ -876,20 +876,12 @@ HTMLImageElement::WrapNode(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
return HTMLImageElementBinding::Wrap(aCx, this, aGivenProto);
}
#ifdef DEBUG
nsIDOMHTMLFormElement*
HTMLImageElement::GetForm() const
{
return mForm;
}
#endif
void
HTMLImageElement::SetForm(nsIDOMHTMLFormElement* aForm)
{
NS_PRECONDITION(aForm, "Don't pass null here");
NS_ASSERTION(!mForm,
"We don't support switching from one non-null form to another.");
MOZ_ASSERT(!mForm && !HasFlag(ADDED_TO_FORM),
"We don't support switching from one non-null form to another.");
mForm = static_cast<HTMLFormElement*>(aForm);
}
+2 -3
View File
@@ -216,9 +216,8 @@ public:
SetHTMLAttr(nsGkAtoms::lowsrc, aLowsrc, aError);
}
#ifdef DEBUG
nsIDOMHTMLFormElement* GetForm() const;
#endif
HTMLFormElement* GetForm() const { return mForm; };
void SetForm(nsIDOMHTMLFormElement* aForm);
void ClearForm(bool aRemoveFromForm);
+2 -2
View File
@@ -1824,8 +1824,8 @@ void
nsGenericHTMLFormElement::SetForm(nsIDOMHTMLFormElement* aForm)
{
NS_PRECONDITION(aForm, "Don't pass null here");
NS_ASSERTION(!mForm,
"We don't support switching from one non-null form to another.");
MOZ_ASSERT(!mForm && !HasFlag(ADDED_TO_FORM),
"We don't support switching from one non-null form to another.");
// keep a *weak* ref to the form here
mForm = static_cast<HTMLFormElement*>(aForm);
+2 -1
View File
@@ -367,12 +367,13 @@ public:
{
}
static const uint32_t MIN_RATE = 8000;
static const uint32_t MAX_RATE = 640000;
bool IsValid() const override
{
return mChannels > 0 && mChannels <= MAX_AUDIO_CHANNELS
&& mRate > 0 && mRate <= MAX_RATE;
&& mRate >= MIN_RATE && mRate <= MAX_RATE;
}
AudioInfo* GetAsAudioInfo() override
+6
View File
@@ -179,12 +179,18 @@ IsValidVideoRegion(const nsIntSize& aFrame, const nsIntRect& aPicture,
aFrame.height <= PlanarYCbCrImage::MAX_DIMENSION &&
aFrame.width * aFrame.height <= MAX_VIDEO_WIDTH * MAX_VIDEO_HEIGHT &&
aFrame.width * aFrame.height != 0 &&
aPicture.width > 0 &&
aPicture.width <= PlanarYCbCrImage::MAX_DIMENSION &&
aPicture.x >= 0 &&
aPicture.x < PlanarYCbCrImage::MAX_DIMENSION &&
aPicture.x + aPicture.width < PlanarYCbCrImage::MAX_DIMENSION &&
aPicture.XMost() <= aFrame.width &&
aPicture.height > 0 &&
aPicture.height <= PlanarYCbCrImage::MAX_DIMENSION &&
aPicture.y >= 0 &&
aPicture.y < PlanarYCbCrImage::MAX_DIMENSION &&
aPicture.y + aPicture.height < PlanarYCbCrImage::MAX_DIMENSION &&
aPicture.YMost() <= aFrame.height &&
aPicture.width * aPicture.height <= MAX_VIDEO_WIDTH * MAX_VIDEO_HEIGHT &&
aPicture.width * aPicture.height != 0 &&
aDisplay.width <= PlanarYCbCrImage::MAX_DIMENSION &&
+1 -1
View File
@@ -439,7 +439,7 @@ private:
Maybe<size_t> mInitOffset;
Maybe<size_t> mMediaOffset;
bool mValid = true;
char mLastInvalidBox[5];
char mLastInvalidBox[5]{};
};
public:
+14 -5
View File
@@ -20,6 +20,7 @@
#include "WebMBufferedParser.h"
#include "gfx2DGlue.h"
#include "mozilla/Atomics.h"
#include "mozilla/CheckedInt.h"
#include "mozilla/EndianUtils.h"
#include "mozilla/Maybe.h"
#include "mozilla/SharedThreadPool.h"
@@ -352,19 +353,27 @@ WebMDemuxer::ReadMetadata()
mInfo.mVideo.mExtraData = new MediaByteBuffer(length);
mInfo.mVideo.mExtraData->AppendElements(data, length);
break;
}
}
default:
NS_WARNING("Unknown WebM video codec");
return NS_ERROR_FAILURE;
}
// Picture region, taking into account cropping, before scaling
// to the display size.
unsigned int cropH = params.crop_right + params.crop_left;
unsigned int cropV = params.crop_bottom + params.crop_top;
CheckedInt<uint32_t> cropH = CheckedInt<uint32_t>(params.crop_left) + params.crop_right;
CheckedInt<uint32_t> cropV = CheckedInt<uint32_t>(params.crop_top) + params.crop_bottom;
if (!cropH.isValid() || !cropV.isValid() ||
cropH.value() >= params.width || cropV.value() >= params.height) {
WEBM_DEBUG("Invalid crop values left: {} right: {} top: {} bottom: {}",
params.crop_left, params.crop_right, params.crop_top,
params.crop_bottom);
// Ignore invalid crop parameters.
continue;
}
nsIntRect pictureRect(params.crop_left,
params.crop_top,
params.width - cropH,
params.height - cropV);
params.width - cropH.value(),
params.height - cropV.value());
// If the cropping data appears invalid then use the frame data
if (pictureRect.width <= 0 ||
+14 -5
View File
@@ -1789,17 +1789,26 @@ URL::IsValidURL(const GlobalObject& aGlobal, const nsAString& aURL,
return URLWorker::IsValidURL(aGlobal, aURL, aRv);
}
bool
URL::CanParse(const GlobalObject& aGlobal, const nsAString& aURL,
const Optional<nsAString>& aBase) {
already_AddRefed<URL>
URL::Parse(const GlobalObject& aGlobal, const nsAString& aURL,
const Optional<nsAString>& aBase)
{
ErrorResult rv;
RefPtr<URL> parsed = URL::Constructor(aGlobal, aURL, aBase, rv);
if (rv.Failed() || !parsed) {
rv.SuppressException();
return false;
return nullptr;
}
return true;
return parsed.forget();
}
bool
URL::CanParse(const GlobalObject& aGlobal, const nsAString& aURL,
const Optional<nsAString>& aBase)
{
RefPtr<URL> parsed = URL::Parse(aGlobal, aURL, aBase);
return !!parsed;
}
already_AddRefed<URLSearchParams>
+4
View File
@@ -88,6 +88,10 @@ public:
IsValidURL(const GlobalObject& aGlobal, const nsAString& aURL,
ErrorResult& aRv);
static already_AddRefed<URL>
Parse(const GlobalObject& aGlobal, const nsAString& aURL,
const Optional<nsAString>& aBase);
static bool
CanParse(const GlobalObject& aGlobal, const nsAString& aURL,
const Optional<nsAString>& aBase);
+28
View File
@@ -448,6 +448,34 @@
!URL.canParse("/static/client/runtime.js", "mailto:test@example.com"),
"URL.canParse rejects root-relative input against opaque mailto: base",
);
ok("parse" in URL, "URL.parse exists");
is(URL.parse.length, 1, "URL.parse has one required argument");
var parsed = URL.parse("/static/client/runtime.js", "x:/");
ok(parsed instanceof URL, "URL.parse returns a URL object on success");
is(parsed.href, "x:/static/client/runtime.js", "URL.parse resolves against a base");
is(URL.parse("/static/client/runtime.js"), null, "URL.parse returns null for invalid input");
is(
URL.parse("/static/client/runtime.js", "mailto:test@example.com"),
null,
"URL.parse returns null for an invalid base/input combination",
);
var conversionOrder = [];
parsed = URL.parse(
{ toString: function() { conversionOrder.push("url"); return "child"; } },
{ toString: function() { conversionOrder.push("base"); return "https://example.com/root/"; } },
);
is(conversionOrder.join(","), "url,base", "URL.parse converts its arguments in order");
is(parsed.href, "https://example.com/root/child", "URL.parse uses converted arguments");
var sentinel = {};
var thrown;
try {
URL.parse({ toString: function() { throw sentinel; } });
} catch (e) {
thrown = e;
}
is(thrown, sentinel, "URL.parse propagates argument conversion exceptions");
SimpleTest.doesThrow(() => {
new URL("/static/client/runtime.js", "mailto:test@example.com");
}, "constructor rejects root-relative input against opaque mailto: base");
+58
View File
@@ -301,6 +301,64 @@ onmessage = function () {
!URL.canParse("/static/client/runtime.js", "mailto:test@example.com"),
"URL.canParse rejects root-relative input against opaque mailto: base",
);
ok("parse" in URL, "URL.parse exists");
is(URL.parse.length, 1, "URL.parse has one required argument");
let parsed = URL.parse("/static/client/runtime.js", "x:/");
ok(parsed instanceof URL, "URL.parse returns a URL object on success");
is(
parsed.href,
"x:/static/client/runtime.js",
"URL.parse resolves against a base",
);
is(
URL.parse("/static/client/runtime.js"),
null,
"URL.parse returns null for invalid input",
);
is(
URL.parse("/static/client/runtime.js", "mailto:test@example.com"),
null,
"URL.parse returns null for an invalid base/input combination",
);
const conversionOrder = [];
parsed = URL.parse(
{
toString() {
conversionOrder.push("url");
return "child";
},
},
{
toString() {
conversionOrder.push("base");
return "https://example.com/root/";
},
},
);
is(
conversionOrder.join(","),
"url,base",
"URL.parse converts its arguments in order",
);
is(
parsed.href,
"https://example.com/root/child",
"URL.parse uses converted arguments",
);
const sentinel = {};
let thrown;
try {
URL.parse({
toString() {
throw sentinel;
},
});
} catch (e) {
thrown = e;
}
is(thrown, sentinel, "URL.parse propagates argument conversion exceptions");
let mailtoRelativeFailed = false;
try {
new URL("/static/client/runtime.js", "mailto:test@example.com");
+1
View File
@@ -23,6 +23,7 @@ interface URL {
[Throws]
stringifier;
static URL? parse(USVString url, optional USVString base);
static boolean canParse(USVString url, optional USVString base);
[Throws]
+14 -1
View File
@@ -336,7 +336,20 @@ gfxGraphiteShaper::SetGlyphsFromSegment(DrawTarget *aDrawTarget,
// not a one-to-one mapping with simple metrics: use DetailedGlyph
AutoTArray<gfxShapedText::DetailedGlyph,8> details;
float clusterLoc;
for (uint32_t j = c.baseGlyph; j < c.baseGlyph + c.nGlyphs; ++j) {
uint32_t glyph_start = c.baseGlyph;
uint32_t glyph_end = glyph_start + c.nGlyphs;
if (glyph_end < glyph_start) {
return NS_ERROR_ILLEGAL_VALUE;
}
if (glyph_end - glyph_start > 0xFFFF) {
return NS_ERROR_ILLEGAL_VALUE;
}
if (!details.SetCapacity(glyph_end - glyph_start, fallible)) {
return NS_ERROR_OUT_OF_MEMORY;
}
for (uint32_t j = glyph_start; j < glyph_end; ++j) {
gfxShapedText::DetailedGlyph* d = details.AppendElement();
d->mGlyphID = gids[j];
d->mYOffset = roundY ? NSToIntRound(-yLocs[j]) * dev2appUnits :
+15 -7
View File
@@ -231,11 +231,13 @@ gfxTextRun::ComputeLigatureData(Range aPartRange,
LigatureData result;
const CompressedGlyph *charGlyphs = mCharacterGlyphs;
uint32_t i;
for (i = aPartRange.start; !charGlyphs[i].IsLigatureGroupStart(); --i) {
NS_ASSERTION(i > 0, "Ligature at the start of the run??");
uint32_t i = aPartRange.start;
while (i && !charGlyphs[i].IsLigatureGroupStart()) {
--i;
}
NS_ASSERTION(charGlyphs[i].IsLigatureGroupStart(), "Ligature at run start?");
result.mRange.start = i;
for (i = aPartRange.start + 1;
i < GetLength() && !charGlyphs[i].IsLigatureGroupStart(); ++i) {
}
@@ -1704,21 +1706,27 @@ gfxFontGroup::GetFontAt(int32_t i, uint32_t aCh)
RefPtr<gfxFont> font = ff.Font();
if (!font) {
gfxFontEntry* fe = mFonts[i].FontEntry();
gfxCharacterMap* unicodeRangeMap = nullptr;
RefPtr<gfxFontEntry> fe = ff.FontEntry();
if (!fe) {
return nullptr;
}
RefPtr<gfxCharacterMap> unicodeRangeMap;
if (fe->mIsUserFontContainer) {
gfxUserFontEntry* ufe = static_cast<gfxUserFontEntry*>(fe);
// This raw pointer is OK because fe holds a strong ref to the object.
gfxUserFontEntry* ufe = static_cast<gfxUserFontEntry*>(fe.get());
if (ufe->LoadState() == gfxUserFontEntry::STATUS_NOT_LOADED &&
ufe->CharacterInUnicodeRange(aCh) &&
!FontLoadingForFamily(ff.Family(), aCh)) {
ufe->Load();
ff.CheckState(mSkipDrawing);
}
unicodeRangeMap = ufe->GetUnicodeRangeMap();
// Update fe to refer to the actual platform font entry, rather than the
// webfont wrapper. After this, we no longer have a strong ref to ufe.
fe = ufe->GetPlatformFontEntry();
if (!fe) {
return nullptr;
}
unicodeRangeMap = ufe->GetUnicodeRangeMap();
}
font = fe->FindOrMakeFont(&mStyle, mFonts[i].NeedsBold(),
unicodeRangeMap);
+7 -4
View File
@@ -1637,10 +1637,13 @@ RasterImage::NotifyDecodeComplete(const DecoderFinalStatus& aStatus,
if (!(aDecoderFlags & DecoderFlags::FIRST_FRAME_ONLY) &&
mHasBeenDecoded && mAnimationState) {
// We've finished a full decode of all animation frames and our AnimationState
// has been notified about them all, so let it know not to expect anymore.
mAnimationState->NotifyDecodeComplete();
mAnimationState->UpdateState(mAnimationFinished, this, mSize);
// If we've successfully finished a full decode of all animation frames
// then let our animation state know it's complete and to not to expect
// any more frames.
if (aStatus.mFinished && !aStatus.mHadError) {
mAnimationState->NotifyDecodeComplete();
mAnimationState->UpdateState(mAnimationFinished, this, mSize);
}
}
// Only act on errors if we have no usable frames from the decoder.
+6 -1
View File
@@ -8,8 +8,11 @@
#include "mozilla/CheckedInt.h"
#include "mozilla/TypeTraits.h"
#include <algorithm>
#include "jscntxt.h"
#include "builtin/SelfHostingDefines.h"
#include "irregexp/RegExpParser.h"
#include "jit/InlinableNatives.h"
#include "vm/RegExpStatics.h"
@@ -1754,7 +1757,9 @@ js::RegExpGetSubstitution(JSContext* cx, HandleArrayObject matchResult, HandleLi
// Step 6.
MOZ_ASSERT(position <= string->length());
uint32_t nCaptures = matchResultLength - 1;
// String substitutions can only reference $1 through $99.
uint32_t nCaptures = std::min<uint32_t>(matchResultLength - 1,
REGEXP_MAX_SUBSTITUTION_CAPTURES);
Rooted<CapturesVector> captures(cx, CapturesVector(cx));
if (!captures.reserve(nCaptures))
return false;
+9 -1
View File
@@ -463,6 +463,12 @@ function RegExpGetComplexReplacement(result, matched, S, position,
// Step 14.k.i (reordered).
_DefineDataProperty(captures, capturesLength++, matched);
// String substitutions can only reference $1 through $99. Keep getting and
// stringifying all captures because those operations are observable.
var storedCaptures = functionalReplace ?
nCaptures :
std_Math_min(nCaptures, REGEXP_MAX_SUBSTITUTION_CAPTURES);
// Step 14.g, 14.i, 14.i.iv.
for (var n = 1; n <= nCaptures; n++) {
// Step 14.i.i.
@@ -473,7 +479,9 @@ function RegExpGetComplexReplacement(result, matched, S, position,
capN = ToString(capN);
// Step 14.i.iii.
_DefineDataProperty(captures, capturesLength++, capN);
if (n <= storedCaptures) {
_DefineDataProperty(captures, capturesLength++, capN);
}
}
// Step 14.j.
+2
View File
@@ -79,6 +79,8 @@
#define REGEXP_FLAGS_SLOT 2
#define REGEXP_MAX_SUBSTITUTION_CAPTURES 99
#define REGEXP_IGNORECASE_FLAG 0x01
#define REGEXP_GLOBAL_FLAG 0x02
#define REGEXP_MULTILINE_FLAG 0x04
+3
View File
@@ -494,6 +494,9 @@ OnLeaveBaselineFrame(JSContext* cx, const JitFrameIterator& frame, jsbytecode* p
{
BaselineFrame* baselineFrame = frame.baselineFrame();
if (jit::DebugEpilogue(cx, baselineFrame, pc, frameOk)) {
if (!baselineFrame->hasReturnValue()) {
baselineFrame->setReturnValue(UndefinedValue());
}
rfe->kind = ResumeFromException::RESUME_FORCED_RETURN;
rfe->framePointer = frame.fp() - BaselineFrame::FramePointerOffset;
rfe->stackPointer = reinterpret_cast<uint8_t*>(baselineFrame);
+5 -4
View File
@@ -312,12 +312,13 @@ cvt_s(SprintfState* ss, const char* s, int width, int prec, int flags)
s = generic_null_str(s);
// Limit string length by precision value
int slen = int(generic_strlen(s));
if (0 < prec && prec < slen)
slen = prec;
size_t slen = strnlen(s, size_t(prec));
if (slen > INT_MAX) {
return false;
}
// and away we go
return fill2(ss, s, slen, width, flags);
return fill2(ss, s, int(slen), width, flags);
}
/*
+7
View File
@@ -411,6 +411,13 @@ DottedCornerFinder::FindBestOverlap(Float aMinR, Float aMinBorderRadius,
mCount = mMaxCount;
break;
}
// GetCountAndLastOverlap() failed without writing |count| and
// |actualOverlap|: the walk needed more than mMaxCount circles, i.e.
// this overlap produces too many circles. Narrow the search toward
// smaller overlaps.
upper = overlap;
overlap = (upper + lower) / 2.0f;
continue;
}
if (j == 0) {
+5 -1
View File
@@ -318,7 +318,11 @@ nsHTMLFramesetFrame::Init(nsIContent* aContent,
mChildFrameborder[mChildCount] = GetFrameBorder(child);
mChildBorderColors[mChildCount].Set(GetBorderColor(child));
}
child->SetPrimaryFrame(frame);
if (MOZ_LIKELY(!child->GetPrimaryFrame())) {
// Child might have a pre-existing primary frame if we're doing fixed-pos
// replication... So, only set it if there is no primary frame yet.
child->SetPrimaryFrame(frame);
}
mFrames.AppendFrame(nullptr, frame);
+13 -3
View File
@@ -481,7 +481,12 @@ NS_IMETHODIMP CacheEntry::OnFileReady(nsresult aResult, bool aIsNew)
NS_IMETHODIMP CacheEntry::OnFileDoomed(nsresult aResult)
{
if (mDoomCallback) {
bool doomCallback = false;
{
mozilla::MutexAutoLock lock(mLock);
doomCallback = bool(mDoomCallback);
}
if (doomCallback) {
RefPtr<DoomCallbackRunnable> event =
new DoomCallbackRunnable(this, aResult);
NS_DispatchToMainThread(event);
@@ -1738,8 +1743,13 @@ void CacheEntry::DoomFile()
}
}
// Always posts to the main thread.
OnFileDoomed(rv);
// mLock is already held in the caller; dispatch directly
// instead of calling OnFileDoomed() which would deadlock when
// re-acquiring the lock.
if (mDoomCallback) {
RefPtr<DoomCallbackRunnable> event = new DoomCallbackRunnable(this, rv);
NS_DispatchToMainThread(event);
}
}
void CacheEntry::RemoveForcedValidity()
+8
View File
@@ -318,6 +318,14 @@ sctp_mark_non_revokable(struct sctp_association *asoc, uint32_t tsn)
return;
}
SCTP_CALC_TSN_TO_GAP(gap, tsn, asoc->mapping_array_base_tsn);
if (gap >= (uint32_t)(asoc->mapping_array_size << 3)) {
/*
* The TSN falls outside the mapping window, e.g. a control
* queued before a large FORWARD-TSN moved the window past it.
* It has no bit in either map, so there is nothing to mark.
*/
return;
}
in_r = SCTP_IS_TSN_PRESENT(asoc->mapping_array, gap);
in_nr = SCTP_IS_TSN_PRESENT(asoc->nr_mapping_array, gap);
KASSERT(in_r || in_nr, ("%s: Things are really messed up now", __func__));
+27 -17
View File
@@ -258,6 +258,8 @@ sctp_process_init(struct sctp_init_chunk *cp, struct sctp_tcb *stcb)
struct sctp_init *init;
struct sctp_association *asoc;
struct sctp_nets *lnet;
struct sctp_stream_reset_list *strrst, *nstrrst;
struct sctp_queued_to_read *sq, *nsq;
unsigned int i;
SCTP_TCB_LOCK_ASSERT(stcb);
@@ -358,6 +360,27 @@ sctp_process_init(struct sctp_init_chunk *cp, struct sctp_tcb *stcb)
asoc->advanced_peer_ack_point = asoc->last_acked_seq;
/* open the requested streams */
/*
* Flush inbound stream state carrying stream ids validated against the
* old streamincnt before strmin is reallocated below; otherwise a later
* drain of pending_reply_queue could index the new (smaller) strmin out
* of bounds.
*/
TAILQ_FOREACH_SAFE(strrst, &asoc->resetHead, next_resp, nstrrst) {
TAILQ_REMOVE(&asoc->resetHead, strrst, next_resp);
SCTP_FREE(strrst, SCTP_M_STRESET);
}
TAILQ_FOREACH_SAFE(sq, &asoc->pending_reply_queue, next, nsq) {
TAILQ_REMOVE(&asoc->pending_reply_queue, sq, next);
if (sq->data) {
sctp_m_freem(sq->data);
sq->data = NULL;
}
sctp_free_remote_addr(sq->whoFrom);
sq->whoFrom = NULL;
sq->stcb = NULL;
sctp_free_a_readq(stcb, sq);
}
if (asoc->strmin != NULL) {
/* Free the old ones */
for (i = 0; i < asoc->streamincnt; i++) {
@@ -1475,8 +1498,6 @@ sctp_process_cookie_existing(struct mbuf *m, int iphlen, int offset,
struct sctp_asconf_addr *aparam, *naparam;
struct sctp_asconf_ack *aack, *naack;
struct sctp_tmit_chunk *chk, *nchk;
struct sctp_stream_reset_list *strrst, *nstrrst;
struct sctp_queued_to_read *sq, *nsq;
struct sctp_nets *net;
struct mbuf *op_err;
int init_offset, initack_offset, i;
@@ -1989,21 +2010,10 @@ sctp_process_cookie_existing(struct mbuf *m, int iphlen, int offset,
stcb->asoc.strmout[i].sid = i;
stcb->asoc.strmout[i].last_msg_incomplete = 0;
}
TAILQ_FOREACH_SAFE(strrst, &asoc->resetHead, next_resp, nstrrst) {
TAILQ_REMOVE(&asoc->resetHead, strrst, next_resp);
SCTP_FREE(strrst, SCTP_M_STRESET);
}
TAILQ_FOREACH_SAFE(sq, &asoc->pending_reply_queue, next, nsq) {
TAILQ_REMOVE(&asoc->pending_reply_queue, sq, next);
if (sq->data) {
sctp_m_freem(sq->data);
sq->data = NULL;
}
sctp_free_remote_addr(sq->whoFrom);
sq->whoFrom = NULL;
sq->stcb = NULL;
sctp_free_a_readq(stcb, sq);
}
/*
* resetHead and pending_reply_queue are flushed by
* sctp_process_init() below, where strmin is reallocated.
*/
TAILQ_FOREACH_SAFE(chk, &asoc->control_send_queue, sctp_next, nchk) {
TAILQ_REMOVE(&asoc->control_send_queue, chk, sctp_next);
if (chk->data) {
+6 -1
View File
@@ -690,6 +690,9 @@ nsHtml5TreeOperation::CreateMathMLElement(nsIAtom* aName,
void
nsHtml5TreeOperation::SetFormElement(nsIContent* aNode, nsIContent* aParent)
{
if (aNode->SubtreeRoot() != aParent->SubtreeRoot()) {
return;
}
nsCOMPtr<nsIFormControl> formControl(do_QueryInterface(aNode));
nsCOMPtr<nsIDOMHTMLImageElement> domImageElement = do_QueryInterface(aNode);
// NS_ASSERTION(formControl, "Form-associated element did not implement nsIFormControl.");
@@ -704,7 +707,9 @@ nsHtml5TreeOperation::SetFormElement(nsIContent* aNode, nsIContent* aParent)
RefPtr<dom::HTMLImageElement> imageElement =
static_cast<dom::HTMLImageElement*>(domImageElement.get());
MOZ_ASSERT(imageElement);
imageElement->SetForm(formElement);
if (!imageElement->GetForm()) {
imageElement->SetForm(formElement);
}
}
}
+10
View File
@@ -8,6 +8,7 @@
#include "secasn1.h"
#include "secitem.h"
#include <stdarg.h>
#include <limits.h>
#include "secerr.h"
#include "certi.h"
@@ -652,9 +653,18 @@ CERT_DecodeAVAValue(const SECItem *derAVAValue)
}
if (convert != conv_none) {
if (avaValue.len > UINT_MAX / 3) {
PORT_DestroyCheapArena(&tmpArena);
PORT_SetError(SEC_ERROR_INVALID_AVA);
return NULL;
}
unsigned int utf8ValLen = avaValue.len * 3;
unsigned char *utf8Val =
(unsigned char *)PORT_ArenaZAlloc(&tmpArena.arena, utf8ValLen);
if (!utf8Val) {
PORT_DestroyCheapArena(&tmpArena);
return NULL;
}
switch (convert) {
case conv_ucs4:
+8
View File
@@ -6,6 +6,8 @@
* certhtml.c --- convert a cert to html
*/
#include <limits.h>
#include "seccomon.h"
#include "secitem.h"
#include "sechash.h"
@@ -14,6 +16,7 @@
#include "secder.h"
#include "prprf.h"
#include "secport.h"
#include "secerr.h"
#include "secasn1.h"
#include "pk11func.h"
@@ -32,6 +35,11 @@ CERT_Hexify(SECItem *i, int do_colon)
return PORT_Strdup("00");
}
if (i->len > UINT_MAX / 3) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return NULL;
}
rv = o = (char *)PORT_Alloc(i->len * 3);
if (!rv)
return rv;
+7
View File
@@ -696,6 +696,13 @@ SECKEY_ECParamsToKeySize(const SECItem *encodedParams)
/* The encodedParams data contains 0x06 (SEC_ASN1_OBJECT_ID),
* followed by the length of the curve oid and the curve oid.
*/
if (!encodedParams || !encodedParams->data ||
encodedParams->len < 2 ||
encodedParams->data[0] != SEC_ASN1_OBJECT_ID ||
(unsigned)encodedParams->data[1] > encodedParams->len - 2) {
PORT_SetError(SEC_ERROR_BAD_DER);
return 0;
}
oid.len = encodedParams->data[1];
oid.data = encodedParams->data + 2;
if ((tag = SECOID_FindOIDTag(&oid)) == SEC_OID_UNKNOWN)
+5
View File
@@ -248,6 +248,11 @@ nss_cert_type_from_ck_attrib(CK_ATTRIBUTE_PTR attrib)
/* default to PKIX */
return NSSCertificateType_PKIX;
}
/* The token controls ulValueLen; reject any size that cannot hold a
* full CK_CERTIFICATE_TYPE to avoid an out-of-bounds heap read. */
if (attrib->ulValueLen != sizeof(CK_CERTIFICATE_TYPE)) {
return NSSCertificateType_Unknown;
}
ckCertType = *((CK_ULONG *)attrib->pValue);
switch (ckCertType) {
case CKC_X_509:
+2 -2
View File
@@ -22,10 +22,10 @@
* The format of the version string should be
* "<major version>.<minor version>[.<patch level>[.<build number>]][ <ECC>][ <Beta>]"
*/
#define NSS_VERSION "3.90.12.0 (UXP)" _NSS_CUSTOMIZED
#define NSS_VERSION "3.90.13.0 (UXP)" _NSS_CUSTOMIZED
#define NSS_VMAJOR 3
#define NSS_VMINOR 90
#define NSS_VPATCH 12
#define NSS_VPATCH 13
#define NSS_VBUILD 0
#define NSS_BETA PR_FALSE
+9
View File
@@ -2269,11 +2269,20 @@ PK11_TraverseCertsForNicknameInSlot(SECItem *nickname, PK11SlotInfo *slot,
NSSCertificate **certs;
nssList *nameList = NULL;
nssTokenSearchType tokenOnly = nssTokenSearchType_TokenOnly;
if (!nickname || !nickname->data || nickname->len == 0) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure;
}
token = PK11Slot_GetNSSToken(slot);
if (!token || !nssToken_IsPresent(token)) {
(void)nssToken_Destroy(token);
return SECSuccess;
}
if (!nickname || !nickname->data || nickname->len == 0) {
(void)nssToken_Destroy(token);
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure;
}
if (nickname->data[nickname->len - 1] != '\0') {
nick = nssUTF8_Create(NULL, nssStringType_UTF8String,
nickname->data, nickname->len);
+1 -1
View File
@@ -521,7 +521,7 @@ pk11_mergeSecretKey(PK11SlotInfo *targetSlot, PK11SlotInfo *sourceSlot,
goto done;
}
input.len = blockSize;
if (input.len == 0) {
if (input.len == 0 || input.len > sizeof(testString)) {
input.len = sizeof(testString);
}
while (targetKeyID != CK_INVALID_HANDLE) {
+6
View File
@@ -1214,6 +1214,12 @@ PK11_UnwrapPrivKey(PK11SlotInfo *slot, PK11SymKey *wrappingKey,
return NULL;
}
if (usageCount < 0 ||
usageCount > (int)(PR_ARRAY_SIZE(keyTemplate) - 8)) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return NULL;
}
ck_id = PK11_MakeIDFromPubKey(idValue);
if (!ck_id) {
return NULL;
+4 -1
View File
@@ -371,7 +371,10 @@ PK11_GetWrapKey(PK11SlotInfo *slot, int wrap, CK_MECHANISM_TYPE type,
CK_OBJECT_HANDLE keyHandle;
PK11_EnterSlotMonitor(slot);
if (slot->series != series ||
/* refKeys is a fixed-size array; bounds-check wrap to match
* PK11_SetWrapKey. */
if (wrap < 0 || (size_t)wrap >= PR_ARRAY_SIZE(slot->refKeys) ||
slot->series != series ||
slot->refKeys[wrap] == CK_INVALID_HANDLE) {
PK11_ExitSlotMonitor(slot);
return NULL;
+2
View File
@@ -162,6 +162,7 @@ pk11_FreeSlotListStatic(PK11SlotList *list)
}
list->lock = NULL;
list->head = NULL;
list->tail = NULL;
}
/*
@@ -820,6 +821,7 @@ pk11_InitSlotListStatic(PK11SlotList *list)
{
list->lock = PZ_NewLock(nssILockList);
list->head = NULL;
list->tail = NULL;
}
/* initialize the system slotlists */
+28 -7
View File
@@ -1105,7 +1105,7 @@ p12u_DigestClose(void *arg, PRBool removeFile)
static int
p12u_DigestRead(void *arg, unsigned char *buf, unsigned long len)
{
int toread = len;
int toread;
SEC_PKCS12DecoderContext *p12cxt = arg;
if (!buf || len == 0 || !p12cxt->buffer) {
@@ -1113,10 +1113,16 @@ p12u_DigestRead(void *arg, unsigned char *buf, unsigned long len)
return -1;
}
if ((p12cxt->filesize - p12cxt->currentpos) < (long)len) {
/* trying to read past the end of the buffer */
toread = p12cxt->filesize - p12cxt->currentpos;
/* Clamp `len` to the bytes left in the buffer. toread is positive here,
* so the comparison stays unsigned and `len` cannot wrap. */
toread = p12cxt->filesize - p12cxt->currentpos;
if (toread <= 0) {
return 0;
}
if (len < (unsigned long)toread) {
toread = (int)len;
}
memcpy(buf, (char *)p12cxt->buffer + p12cxt->currentpos, toread);
p12cxt->currentpos += toread;
return toread;
@@ -1131,10 +1137,18 @@ p12u_DigestWrite(void *arg, unsigned char *buf, unsigned long len)
return -1;
}
if (p12cxt->currentpos + (long)len > p12cxt->filesize) {
p12cxt->filesize = p12cxt->currentpos + len;
/* The buffer position counters are signed PRInt32. Reject any write
* whose length would not fit so that `len` cannot overflow or wrap them
* on LLP64 platforms where unsigned long is 32-bit (Win64). */
if (len > (unsigned long)(PR_INT32_MAX - p12cxt->currentpos)) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return -1;
}
if (p12cxt->currentpos + (PRInt32)len > p12cxt->filesize) {
p12cxt->filesize = p12cxt->currentpos + (PRInt32)len;
} else {
p12cxt->filesize += len;
p12cxt->filesize += (PRInt32)len;
}
if (p12cxt->filesize > p12cxt->allocated) {
void *newbuffer;
@@ -1693,6 +1707,13 @@ sec_pkcs12_sanitize_nickname(PK11SlotInfo *slot, SECItem *nick)
slotName[slotNameLen] = '\0';
if (PORT_Strcmp(PK11_GetTokenName(slot), slotName) == 0) {
delimitlen = PORT_Strlen(delimit + 1);
if (delimitlen == 0) {
/* Nickname was exactly "TokenName:" with nothing after the
* prefix. Stripping it would yield an empty SECItem, which
* is not a useful nickname; leave the original in place. */
PORT_Free(slotName);
return;
}
PORT_Memmove(nickname, delimit + 1, delimitlen + 1);
nick->len = delimitlen;
}
+11 -6
View File
@@ -606,15 +606,20 @@ SEC_PKCS7DecryptContents(PLArenaPool *poolp,
rv = PK11_CipherOp((PK11Context *)cx, dest->data, (int *)(&dest->len),
(int)(src->len + 64), src->data, (int)src->len);
PK11_DestroyContext((PK11Context *)cx, PR_TRUE);
/* PK11_CipherOp may leave dest->len at 0; bail out before the padding
* check so dest->len - 1 does not underflow. */
if (rv != SECSuccess) {
goto loser;
}
bs = PK11_GetBlockSize(cryptoMechType, c_param);
if (bs) {
/* check for proper badding in block algorithms. this assumes
* RC2 cbc or a DES cbc variant. and the padding is thus defined
*/
if (((int)dest->data[dest->len - 1] <= bs) &&
((int)dest->data[dest->len - 1] > 0)) {
dest->len -= (int)dest->data[dest->len - 1];
/* Check for proper PKCS#7 padding: the last byte gives the number of
* pad bytes, which must be in [1, bs]. */
unsigned int pad = dest->data[dest->len - 1];
if ((dest->len >= (unsigned int)bs) &&
pad >= 1 && pad <= (unsigned int)bs) {
dest->len -= pad;
} else {
rv = SECFailure;
/* set an error ? */
+6
View File
@@ -773,6 +773,12 @@ sftk_ike1_appendix_b_prf(CK_SESSION_HANDLE hSession, const SFTKAttribute *inKey,
}
outKeySize = PR_ROUNDUP(keySize, macSize);
/* Reject if PR_ROUNDUP overflowed 32-bit unsigned arithmetic, which
* would yield an undersized allocation for the loop below. */
if (outKeySize < keySize) {
crv = CKR_KEY_SIZE_RANGE;
goto fail;
}
outKeyData = PORT_Alloc(outKeySize);
if (outKeyData == NULL) {
crv = CKR_HOST_MEMORY;
+2 -2
View File
@@ -17,10 +17,10 @@
* The format of the version string should be
* "<major version>.<minor version>[.<patch level>[.<build number>]][ <ECC>][ <Beta>]"
*/
#define SOFTOKEN_VERSION "3.90.12.0 (UXP)" SOFTOKEN_ECC_STRING
#define SOFTOKEN_VERSION "3.90.13.0 (UXP)" SOFTOKEN_ECC_STRING
#define SOFTOKEN_VMAJOR 3
#define SOFTOKEN_VMINOR 90
#define SOFTOKEN_VPATCH 12
#define SOFTOKEN_VPATCH 13
#define SOFTOKEN_VBUILD 0
#define SOFTOKEN_BETA PR_FALSE
+6 -1
View File
@@ -722,7 +722,12 @@ ssl_CallCustomExtensionSenders(sslSocket *ss, sslBuffer *buf,
if (hook->writer) {
/* The writer writes directly into |buf|. Provide space that allows
* for the existing extensions, any tail, plus type and length. */
unsigned int space = buf->space - (buf->len + tail.len + 4);
unsigned int used = buf->len + tail.len + 4;
if (used > buf->space) {
PORT_SetError(SEC_ERROR_APPLICATION_CALLBACK_ERROR);
goto loser;
}
unsigned int space = buf->space - used;
append = (*hook->writer)(ss->fd, message,
buf->buf + buf->len + 4, &len, space,
hook->writerArg);
+6
View File
@@ -164,6 +164,12 @@ ssl_BeginClientHandshake(sslSocket *ss)
ss->sec.localCert = CERT_DupCertificate(sid->localCert);
} else {
ssl_UncacheSessionID(ss);
if (ss->sec.ci.sid == sid) {
/* sid aliases ss->sec.ci.sid (external cache); clear it so
* the socket cannot hold a dangling pointer if the
* ssl3_NewSessionID allocation below fails. */
ss->sec.ci.sid = NULL;
}
ssl_FreeSID(sid);
sid = NULL;
}
+1 -1
View File
@@ -165,7 +165,7 @@ tls13_HkdfExpandLabelGeneral(CK_MECHANISM_TYPE deriveMech, PK11SymKey *prk,
PORT_Assert(keyp);
if ((handshakeHashLen > 255) ||
(handshakeHash == NULL && handshakeHashLen > 0) ||
(labelLen + kLabelPrefixLen > 255)) {
(labelLen > 255 - kLabelPrefixLen)) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure;
}
+2 -2
View File
@@ -19,10 +19,10 @@
* The format of the version string should be
* "<major version>.<minor version>[.<patch level>[.<build number>]][ <Beta>]"
*/
#define NSSUTIL_VERSION "3.90.12.0 (UXP)"
#define NSSUTIL_VERSION "3.90.13.0 (UXP)"
#define NSSUTIL_VMAJOR 3
#define NSSUTIL_VMINOR 90
#define NSSUTIL_VPATCH 12
#define NSSUTIL_VPATCH 13
#define NSSUTIL_VBUILD 0
#define NSSUTIL_BETA PR_FALSE
+1 -1
View File
@@ -542,7 +542,7 @@ DecodeGroup(void* dest,
rv = SECFailure;
}
if (SECSuccess == rv) {
void* entriesData = (unsigned char*)entries + (unsigned long)(sizeof(void*) * (totalEntries + 1));
void* entriesData = (unsigned char*)entries + sizeof(void*) * (totalEntries + 1);
/* and fix the pointers in the array */
PRUint32 entriesIndex = 0;
for (entriesIndex = 0; entriesIndex < totalEntries; entriesIndex++) {