Merge mozilla-inbound to mozilla-central. a=merge

This commit is contained in:
Andreea Pavel 2018-06-30 12:49:32 +03:00
Родитель 36f73c43d8 c4900d4847
Коммит 91a9c110e2
104 изменённых файлов: 1684 добавлений и 977 удалений

Просмотреть файл

@ -3,6 +3,7 @@
TOOLTOOL_DIR=${TOOLTOOL_DIR:-$topsrcdir}
ac_add_options --disable-sandbox
ac_add_options --disable-warnings-as-errors
ac_add_options --enable-coverage
export CFLAGS="-coverage"

Просмотреть файл

@ -6,6 +6,7 @@ MOZ_AUTOMATION_L10N_CHECK=0
ac_add_options --enable-optimize
ac_add_options --enable-debug
ac_add_options --disable-sandbox
ac_add_options --disable-warnings-as-errors
ac_add_options --enable-coverage
# Needed to enable breakpad in application.ini

Просмотреть файл

@ -1,5 +1,5 @@
This is the PDF.js project output, https://github.com/mozilla/pdf.js
Current extension version is: 2.0.625
Current extension version is: 2.0.641
Taken from upstream commit: e8b50883
Taken from upstream commit: 6fa2c779

Просмотреть файл

@ -123,8 +123,8 @@ return /******/ (function(modules) { // webpackBootstrap
"use strict";
var pdfjsVersion = '2.0.625';
var pdfjsBuild = 'e8b50883';
var pdfjsVersion = '2.0.641';
var pdfjsBuild = '6fa2c779';
var pdfjsSharedUtil = __w_pdfjs_require__(1);
var pdfjsDisplayAPI = __w_pdfjs_require__(6);
var pdfjsDisplayTextLayer = __w_pdfjs_require__(18);
@ -4223,7 +4223,7 @@ function _fetchDocument(worker, source, pdfDataRangeTransport, docId) {
}
return worker.messageHandler.sendWithPromise('GetDocRequest', {
docId,
apiVersion: '2.0.625',
apiVersion: '2.0.641',
source: {
data: source.data,
url: source.url,
@ -4530,6 +4530,7 @@ var PDFPageProxy = function PDFPageProxyClosure() {
argsArray: [],
lastChunk: false
};
this._stats.time('Page Request');
this.transport.messageHandler.send('RenderPageRequest', {
pageIndex: this.pageIndex,
intent: renderingIntent
@ -5562,8 +5563,8 @@ var InternalRenderTask = function InternalRenderTaskClosure() {
}();
var version, build;
{
exports.version = version = '2.0.625';
exports.build = build = 'e8b50883';
exports.version = version = '2.0.641';
exports.build = build = '6fa2c779';
}
exports.getDocument = getDocument;
exports.LoopbackPort = LoopbackPort;

Просмотреть файл

@ -123,8 +123,8 @@ return /******/ (function(modules) { // webpackBootstrap
"use strict";
var pdfjsVersion = '2.0.625';
var pdfjsBuild = 'e8b50883';
var pdfjsVersion = '2.0.641';
var pdfjsBuild = '6fa2c779';
var pdfjsCoreWorker = __w_pdfjs_require__(1);
exports.WorkerMessageHandler = pdfjsCoreWorker.WorkerMessageHandler;
@ -327,7 +327,7 @@ var WorkerMessageHandler = {
var cancelXHRs = null;
var WorkerTasks = [];
let apiVersion = docParams.apiVersion;
let workerVersion = '2.0.625';
let workerVersion = '2.0.641';
if (apiVersion !== workerVersion) {
throw new Error(`The API version "${apiVersion}" does not match ` + `the Worker version "${workerVersion}".`);
}
@ -11387,6 +11387,46 @@ var Jbig2Image = function Jbig2ImageClosure() {
}
return visitor.buffer;
}
function parseJbig2(data) {
let position = 0,
end = data.length;
if (data[position] !== 0x97 || data[position + 1] !== 0x4A || data[position + 2] !== 0x42 || data[position + 3] !== 0x32 || data[position + 4] !== 0x0D || data[position + 5] !== 0x0A || data[position + 6] !== 0x1A || data[position + 7] !== 0x0A) {
throw new Jbig2Error('parseJbig2 - invalid header.');
}
let header = Object.create(null);
position += 8;
const flags = data[position++];
header.randomAccess = !(flags & 1);
if (!(flags & 2)) {
header.numberOfPages = (0, _util.readUint32)(data, position);
position += 4;
}
let segments = readSegments(header, data, position, end);
let visitor = new SimpleSegmentVisitor();
processSegments(segments, visitor);
const { width, height } = visitor.currentPageInfo;
const bitPacked = visitor.buffer;
let imgData = new Uint8ClampedArray(width * height);
let q = 0,
k = 0;
for (let i = 0; i < height; i++) {
let mask = 0,
buffer;
for (let j = 0; j < width; j++) {
if (!mask) {
mask = 128;
buffer = bitPacked[k++];
}
imgData[q++] = buffer & mask ? 0 : 255;
mask >>= 1;
}
}
return {
imgData,
width,
height
};
}
function SimpleSegmentVisitor() {}
SimpleSegmentVisitor.prototype = {
onPageInformation: function SimpleSegmentVisitor_onPageInformation(info) {
@ -11986,8 +12026,14 @@ var Jbig2Image = function Jbig2ImageClosure() {
}
function Jbig2Image() {}
Jbig2Image.prototype = {
parseChunks: function Jbig2Image_parseChunks(chunks) {
parseChunks(chunks) {
return parseJbig2Chunks(chunks);
},
parse(data) {
const { imgData, width, height } = parseJbig2(data);
this.width = width;
this.height = height;
return imgData;
}
};
return Jbig2Image;
@ -12381,7 +12427,10 @@ let JpegStream = function JpegStreamClosure() {
if (this.eof) {
return;
}
let jpegImage = new _jpg.JpegImage();
let jpegOptions = {
decodeTransform: undefined,
colorTransform: undefined
};
let decodeArr = this.dict.getArray('Decode', 'D');
if (this.forceRGB && Array.isArray(decodeArr)) {
let bitsPerComponent = this.dict.get('BitsPerComponent') || 8;
@ -12397,15 +12446,16 @@ let JpegStream = function JpegStreamClosure() {
}
}
if (transformNeeded) {
jpegImage.decodeTransform = transform;
jpegOptions.decodeTransform = transform;
}
}
if ((0, _primitives.isDict)(this.params)) {
let colorTransform = this.params.get('ColorTransform');
if (Number.isInteger(colorTransform)) {
jpegImage.colorTransform = colorTransform;
jpegOptions.colorTransform = colorTransform;
}
}
const jpegImage = new _jpg.JpegImage(jpegOptions);
jpegImage.parse(this.bytes);
let data = jpegImage.getData(this.drawWidth, this.drawHeight, this.forceRGB);
this.buffer = data;
@ -12471,9 +12521,9 @@ var JpegImage = function JpegImageClosure() {
var dctSin6 = 3784;
var dctSqrt2 = 5793;
var dctSqrt1d2 = 2896;
function JpegImage() {
this.decodeTransform = null;
this.colorTransform = -1;
function JpegImage({ decodeTransform = null, colorTransform = -1 } = {}) {
this._decodeTransform = decodeTransform;
this._colorTransform = colorTransform;
}
function buildHuffmanTable(codeLengths, values) {
var k = 0,
@ -13276,7 +13326,7 @@ var JpegImage = function JpegImageClosure() {
}
}
}
var transform = this.decodeTransform;
const transform = this._decodeTransform;
if (transform) {
for (i = 0; i < dataLength;) {
for (j = 0, k = 0; j < numComponents; j++, i++, k += 2) {
@ -13291,12 +13341,12 @@ var JpegImage = function JpegImageClosure() {
return !!this.adobe.transformCode;
}
if (this.numComponents === 3) {
if (this.colorTransform === 0) {
if (this._colorTransform === 0) {
return false;
}
return true;
}
if (this.colorTransform === 1) {
if (this._colorTransform === 1) {
return true;
}
return false;
@ -21484,11 +21534,13 @@ var EvaluatorPreprocessor = function EvaluatorPreprocessorClosure() {
t['nul'] = null;
t['null'] = null;
});
const MAX_INVALID_PATH_OPS = 20;
function EvaluatorPreprocessor(stream, xref, stateManager) {
this.opMap = getOPMap();
this.parser = new _parser.Parser(new _parser.Lexer(stream, this.opMap), false, xref);
this.stateManager = stateManager;
this.nonProcessedArgs = [];
this._numInvalidPathOPS = 0;
}
EvaluatorPreprocessor.prototype = {
get savedStatesDepth() {
@ -21502,7 +21554,7 @@ var EvaluatorPreprocessor = function EvaluatorPreprocessorClosure() {
var cmd = obj.cmd;
var opSpec = this.opMap[cmd];
if (!opSpec) {
(0, _util.warn)('Unknown command "' + cmd + '"');
(0, _util.warn)(`Unknown command "${cmd}".`);
continue;
}
var fn = opSpec.id;
@ -21524,14 +21576,18 @@ var EvaluatorPreprocessor = function EvaluatorPreprocessorClosure() {
}
}
if (argsLength < numArgs) {
(0, _util.warn)('Skipping command ' + fn + ': expected ' + numArgs + ' args, but received ' + argsLength + ' args.');
const partialMsg = `command ${cmd}: expected ${numArgs} args, ` + `but received ${argsLength} args.`;
if (fn >= _util.OPS.moveTo && fn <= _util.OPS.endPath && ++this._numInvalidPathOPS > MAX_INVALID_PATH_OPS) {
throw new _util.FormatError(`Invalid ${partialMsg}`);
}
(0, _util.warn)(`Skipping ${partialMsg}`);
if (args !== null) {
args.length = 0;
}
continue;
}
} else if (argsLength > numArgs) {
(0, _util.info)('Command ' + fn + ': expected [0,' + numArgs + '] args, but received ' + argsLength + ' args.');
(0, _util.info)(`Command ${cmd}: expected [0, ${numArgs}] args, ` + `but received ${argsLength} args.`);
}
this.preprocessCommand(fn, args);
operation.fn = fn;

Просмотреть файл

@ -319,6 +319,7 @@ var _view_history = __webpack_require__(31);
const DEFAULT_SCALE_DELTA = 1.1;
const DISABLE_AUTO_FETCH_LOADING_BAR_TIMEOUT = 5000;
const FORCE_PAGES_LOADED_TIMEOUT = 10000;
const DefaultExternalServices = {
updateFindControlState(data) {},
initPassiveLoading(callbacks) {},
@ -959,8 +960,7 @@ let PDFViewerApplication = {
hash: null
};
let storePromise = store.getMultiple({
exists: false,
page: '1',
page: null,
zoom: _ui_utils.DEFAULT_SCALE_VALUE,
scrollLeft: '0',
scrollTop: '0',
@ -970,13 +970,14 @@ let PDFViewerApplication = {
spreadMode: null
}).catch(() => {});
Promise.all([storePromise, pageModePromise]).then(([values = {}, pageMode]) => {
let hash = _app_options.AppOptions.get('defaultZoomValue') ? 'zoom=' + _app_options.AppOptions.get('defaultZoomValue') : null;
const zoom = _app_options.AppOptions.get('defaultZoomValue');
let hash = zoom ? `zoom=${zoom}` : null;
let rotation = null;
let sidebarView = _app_options.AppOptions.get('sidebarViewOnLoad');
let scrollMode = _app_options.AppOptions.get('scrollModeOnLoad');
let spreadMode = _app_options.AppOptions.get('spreadModeOnLoad');
if (values.exists && _app_options.AppOptions.get('showPreviousViewOnLoad')) {
hash = 'page=' + values.page + '&zoom=' + (_app_options.AppOptions.get('defaultZoomValue') || values.zoom) + ',' + values.scrollLeft + ',' + values.scrollTop;
if (values.page && _app_options.AppOptions.get('showPreviousViewOnLoad')) {
hash = 'page=' + values.page + '&zoom=' + (zoom || values.zoom) + ',' + values.scrollLeft + ',' + values.scrollTop;
rotation = parseInt(values.rotation, 10);
sidebarView = sidebarView || values.sidebarView | 0;
if (values.scrollMode !== null) {
@ -1008,7 +1009,9 @@ let PDFViewerApplication = {
if (!this.isViewerEmbedded) {
pdfViewer.focus();
}
return pagesPromise;
return Promise.race([pagesPromise, new Promise(resolve => {
setTimeout(resolve, FORCE_PAGES_LOADED_TIMEOUT);
})]);
}).then(() => {
if (!initialParams.bookmark && !initialParams.hash) {
return;
@ -1482,7 +1485,6 @@ function webViewerUpdateViewarea(evt) {
store = PDFViewerApplication.store;
if (store && PDFViewerApplication.isInitialViewSet) {
store.setMultiple({
'exists': true,
'page': location.pageNumber,
'zoom': location.scale,
'scrollLeft': location.left,
@ -1941,7 +1943,7 @@ exports.PDFPrintServiceFactory = PDFPrintServiceFactory;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.moveToEndOfArray = exports.waitOnEventOrTimeout = exports.WaitOnType = exports.animationStarted = exports.normalizeWheelEventDelta = exports.binarySearchFirstItem = exports.watchScroll = exports.scrollIntoView = exports.getOutputScale = exports.approximateFraction = exports.getPageSizeInches = exports.roundToDivide = exports.getVisibleElements = exports.backtrackBeforeAllVisibleElements = exports.parseQueryString = exports.noContextMenuHandler = exports.getPDFFileNameFromURL = exports.ProgressBar = exports.EventBus = exports.NullL10n = exports.TextLayerMode = exports.RendererType = exports.PresentationModeState = exports.cloneObj = exports.isPortraitOrientation = exports.isValidRotation = exports.VERTICAL_PADDING = exports.SCROLLBAR_PADDING = exports.MAX_AUTO_SCALE = exports.UNKNOWN_SCALE = exports.MAX_SCALE = exports.MIN_SCALE = exports.DEFAULT_SCALE = exports.DEFAULT_SCALE_VALUE = exports.CSS_UNITS = undefined;
exports.moveToEndOfArray = exports.waitOnEventOrTimeout = exports.WaitOnType = exports.animationStarted = exports.normalizeWheelEventDelta = exports.binarySearchFirstItem = exports.watchScroll = exports.scrollIntoView = exports.getOutputScale = exports.approximateFraction = exports.getPageSizeInches = exports.roundToDivide = exports.getVisibleElements = exports.backtrackBeforeAllVisibleElements = exports.parseQueryString = exports.noContextMenuHandler = exports.getPDFFileNameFromURL = exports.ProgressBar = exports.EventBus = exports.NullL10n = exports.TextLayerMode = exports.RendererType = exports.PresentationModeState = exports.isPortraitOrientation = exports.isValidRotation = exports.VERTICAL_PADDING = exports.SCROLLBAR_PADDING = exports.MAX_AUTO_SCALE = exports.UNKNOWN_SCALE = exports.MAX_SCALE = exports.MIN_SCALE = exports.DEFAULT_SCALE = exports.DEFAULT_SCALE_VALUE = exports.CSS_UNITS = undefined;
var _pdfjsLib = __webpack_require__(3);
@ -2293,15 +2295,6 @@ function isValidRotation(angle) {
function isPortraitOrientation(size) {
return size.width <= size.height;
}
function cloneObj(obj) {
let result = Object.create(null);
for (let i in obj) {
if (Object.prototype.hasOwnProperty.call(obj, i)) {
result[i] = obj[i];
}
}
return result;
}
const WaitOnType = {
EVENT: 'event',
TIMEOUT: 'timeout'
@ -2452,7 +2445,6 @@ exports.SCROLLBAR_PADDING = SCROLLBAR_PADDING;
exports.VERTICAL_PADDING = VERTICAL_PADDING;
exports.isValidRotation = isValidRotation;
exports.isPortraitOrientation = isPortraitOrientation;
exports.cloneObj = cloneObj;
exports.PresentationModeState = PresentationModeState;
exports.RendererType = RendererType;
exports.TextLayerMode = TextLayerMode;
@ -3850,7 +3842,7 @@ class PDFDocumentProperties {
if (fileSize === this.fieldData['fileSize']) {
return;
}
let data = (0, _ui_utils.cloneObj)(this.fieldData);
let data = Object.assign(Object.create(null), this.fieldData);
data['fileSize'] = fileSize;
freezeFieldData(data);
this._updateUI();
@ -4723,7 +4715,7 @@ class PDFHistory {
}
let position = this._position;
if (temporary) {
position = (0, _ui_utils.cloneObj)(this._position);
position = Object.assign(Object.create(null), this._position);
position.temporary = true;
}
if (!this._destination) {
@ -8484,11 +8476,12 @@ class ViewHistory {
let database = JSON.parse(databaseStr || '{}');
if (!('files' in database)) {
database.files = [];
} else {
while (database.files.length >= this.cacheSize) {
database.files.shift();
}
}
if (database.files.length >= this.cacheSize) {
database.files.shift();
}
let index;
let index = -1;
for (let i = 0, length = database.files.length; i < length; i++) {
let branch = database.files[i];
if (branch.fingerprint === this.fingerprint) {
@ -8496,7 +8489,7 @@ class ViewHistory {
break;
}
}
if (typeof index !== 'number') {
if (index === -1) {
index = database.files.push({ fingerprint: this.fingerprint }) - 1;
}
this.file = database.files[index];
@ -8903,10 +8896,6 @@ exports.FirefoxCom = FirefoxCom;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.BasePreferences = undefined;
var _ui_utils = __webpack_require__(2);
let defaultPreferences = null;
function getDefaultPreferences() {
if (!defaultPreferences) {
@ -8948,7 +8937,7 @@ class BasePreferences {
enumerable: true,
configurable: false
});
this.prefs = (0, _ui_utils.cloneObj)(defaults);
this.prefs = Object.assign(Object.create(null), defaults);
return this._readFromStorage(defaults);
}).then(prefObj => {
if (prefObj) {
@ -8964,7 +8953,7 @@ class BasePreferences {
}
reset() {
return this._initializedPromise.then(() => {
this.prefs = (0, _ui_utils.cloneObj)(this.defaults);
this.prefs = Object.assign(Object.create(null), this.defaults);
return this._writeToStorage(this.defaults);
});
}

Просмотреть файл

@ -267,8 +267,8 @@ class RemoteAutomation(Automation):
app, moz_env=env, extra_args=args, url=url)
# Setting timeout at 1 hour since on a remote device this takes much longer.
# Temporarily increased to 90 minutes because no more chunks can be created.
self.timeout = 5400
# Temporarily increased to 110 minutes because no more chunks can be created.
self.timeout = 6600
# Used to buffer log messages until we meet a line break
self.logBuffer = ""

Просмотреть файл

@ -645,7 +645,7 @@ static_assert(sizeof(FragmentOrElement::nsDOMSlots) <= MaxDOMSlotSizeAllowed,
"DOM slots cannot be grown without consideration");
void
nsIContent::nsExtendedContentSlots::Unlink()
nsIContent::nsExtendedContentSlots::UnlinkExtendedSlots()
{
mBindingParent = nullptr;
mXBLInsertionPoint = nullptr;
@ -654,7 +654,7 @@ nsIContent::nsExtendedContentSlots::Unlink()
}
void
nsIContent::nsExtendedContentSlots::Traverse(nsCycleCollectionTraversalCallback& aCb)
nsIContent::nsExtendedContentSlots::TraverseExtendedSlots(nsCycleCollectionTraversalCallback& aCb)
{
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(aCb, "mExtendedSlots->mBindingParent");
aCb.NoteXPCOMChild(NS_ISUPPORTS_CAST(nsIContent*, mBindingParent));
@ -679,10 +679,13 @@ FragmentOrElement::nsDOMSlots::nsDOMSlots()
: nsIContent::nsContentSlots(),
mDataset(nullptr)
{
MOZ_COUNT_CTOR(nsDOMSlots);
}
FragmentOrElement::nsDOMSlots::~nsDOMSlots()
{
MOZ_COUNT_DTOR(nsDOMSlots);
if (mAttributeMap) {
mAttributeMap->DropReference();
}
@ -723,8 +726,8 @@ size_t
FragmentOrElement::nsDOMSlots::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const
{
size_t n = aMallocSizeOf(this);
if (mExtendedSlots) {
n += aMallocSizeOf(mExtendedSlots.get());
if (OwnsExtendedSlots()) {
n += aMallocSizeOf(GetExtendedContentSlots());
}
if (mAttributeMap) {
@ -758,9 +761,9 @@ FragmentOrElement::nsExtendedDOMSlots::~nsExtendedDOMSlots()
}
void
FragmentOrElement::nsExtendedDOMSlots::Unlink()
FragmentOrElement::nsExtendedDOMSlots::UnlinkExtendedSlots()
{
nsIContent::nsExtendedContentSlots::Unlink();
nsIContent::nsExtendedContentSlots::UnlinkExtendedSlots();
// Don't clear mXBLBinding, it'll be done in
// BindingManager::RemovedFromDocument from FragmentOrElement::Unlink.
@ -780,9 +783,9 @@ FragmentOrElement::nsExtendedDOMSlots::Unlink()
}
void
FragmentOrElement::nsExtendedDOMSlots::Traverse(nsCycleCollectionTraversalCallback& aCb)
FragmentOrElement::nsExtendedDOMSlots::TraverseExtendedSlots(nsCycleCollectionTraversalCallback& aCb)
{
nsIContent::nsExtendedContentSlots::Traverse(aCb);
nsIContent::nsExtendedContentSlots::TraverseExtendedSlots(aCb);
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(aCb, "mExtendedSlots->mSMILOverrideStyle");
aCb.NoteXPCOMChild(mSMILOverrideStyle.get());

Просмотреть файл

@ -171,14 +171,14 @@ public:
* accessed through the DOM.
*/
class nsExtendedDOMSlots final : public nsIContent::nsExtendedContentSlots
class nsExtendedDOMSlots : public nsIContent::nsExtendedContentSlots
{
public:
nsExtendedDOMSlots();
~nsExtendedDOMSlots() final;
~nsExtendedDOMSlots();
void Traverse(nsCycleCollectionTraversalCallback&) final;
void Unlink() final;
void TraverseExtendedSlots(nsCycleCollectionTraversalCallback&) final;
void UnlinkExtendedSlots() final;
/**
* SMIL Overridde style rules (for SMIL animation of CSS properties)
@ -223,11 +223,11 @@ public:
};
class nsDOMSlots final : public nsIContent::nsContentSlots
class nsDOMSlots : public nsIContent::nsContentSlots
{
public:
nsDOMSlots();
~nsDOMSlots() final;
~nsDOMSlots();
void Traverse(nsCycleCollectionTraversalCallback&) final;
void Unlink() final;
@ -263,6 +263,29 @@ public:
RefPtr<nsDOMTokenList> mClassList;
};
/**
* In case ExtendedDOMSlots is needed before normal DOMSlots, an instance of
* FatSlots class, which combines those two slot types, is created.
* This way we can avoid extra allocation for ExtendedDOMSlots.
* FatSlots is useful for example when creating Custom Elements.
*/
class FatSlots final : public nsDOMSlots, public nsExtendedDOMSlots
{
public:
FatSlots()
: nsDOMSlots()
, nsExtendedDOMSlots()
{
MOZ_COUNT_CTOR(FatSlots);
SetExtendedContentSlots(this, false);
}
~FatSlots() final
{
MOZ_COUNT_DTOR(FatSlots);
}
};
protected:
void GetMarkup(bool aIncludeSelf, nsAString& aMarkup);
void SetInnerHTMLInternal(const nsAString& aInnerHTML, ErrorResult& aError);
@ -290,7 +313,18 @@ protected:
nsExtendedDOMSlots* ExtendedDOMSlots()
{
return static_cast<nsExtendedDOMSlots*>(ExtendedContentSlots());
nsContentSlots* slots = GetExistingContentSlots();
if (!slots) {
FatSlots* fatSlots = new FatSlots();
mSlots = fatSlots;
return fatSlots;
}
if (!slots->GetExtendedContentSlots()) {
slots->SetExtendedContentSlots(CreateExtendedSlots(), true);
}
return static_cast<nsExtendedDOMSlots*>(slots->GetExtendedContentSlots());
}
const nsExtendedDOMSlots* GetExistingExtendedDOMSlots() const

Просмотреть файл

@ -791,8 +791,8 @@ protected:
nsExtendedContentSlots();
virtual ~nsExtendedContentSlots();
virtual void Traverse(nsCycleCollectionTraversalCallback&);
virtual void Unlink();
virtual void TraverseExtendedSlots(nsCycleCollectionTraversalCallback&);
virtual void UnlinkExtendedSlots();
/**
* The nearest enclosing content node with a binding that created us.
@ -821,11 +821,24 @@ protected:
class nsContentSlots : public nsINode::nsSlots
{
public:
nsContentSlots()
: nsINode::nsSlots()
, mExtendedSlots(0)
{
}
~nsContentSlots()
{
if (!(mExtendedSlots & sNonOwningExtendedSlotsFlag)) {
delete GetExtendedContentSlots();
}
}
void Traverse(nsCycleCollectionTraversalCallback& aCb) override
{
nsINode::nsSlots::Traverse(aCb);
if (mExtendedSlots) {
mExtendedSlots->Traverse(aCb);
GetExtendedContentSlots()->TraverseExtendedSlots(aCb);
}
}
@ -833,11 +846,33 @@ protected:
{
nsINode::nsSlots::Unlink();
if (mExtendedSlots) {
mExtendedSlots->Unlink();
GetExtendedContentSlots()->UnlinkExtendedSlots();
}
}
mozilla::UniquePtr<nsExtendedContentSlots> mExtendedSlots;
void SetExtendedContentSlots(nsExtendedContentSlots* aSlots, bool aOwning)
{
mExtendedSlots = reinterpret_cast<uintptr_t>(aSlots);
if (!aOwning) {
mExtendedSlots |= sNonOwningExtendedSlotsFlag;
}
}
bool OwnsExtendedSlots() const
{
return !(mExtendedSlots & sNonOwningExtendedSlotsFlag);
}
nsExtendedContentSlots* GetExtendedContentSlots() const
{
return reinterpret_cast<nsExtendedContentSlots*>(
mExtendedSlots & ~sNonOwningExtendedSlotsFlag);
}
private:
static const uintptr_t sNonOwningExtendedSlotsFlag = 1u;
uintptr_t mExtendedSlots;
};
// Override from nsINode
@ -869,22 +904,22 @@ protected:
const nsExtendedContentSlots* GetExistingExtendedContentSlots() const
{
const nsContentSlots* slots = GetExistingContentSlots();
return slots ? slots->mExtendedSlots.get() : nullptr;
return slots ? slots->GetExtendedContentSlots() : nullptr;
}
nsExtendedContentSlots* GetExistingExtendedContentSlots()
{
nsContentSlots* slots = GetExistingContentSlots();
return slots ? slots->mExtendedSlots.get() : nullptr;
return slots ? slots->GetExtendedContentSlots() : nullptr;
}
nsExtendedContentSlots* ExtendedContentSlots()
{
nsContentSlots* slots = ContentSlots();
if (!slots->mExtendedSlots) {
slots->mExtendedSlots.reset(CreateExtendedSlots());
if (!slots->GetExtendedContentSlots()) {
slots->SetExtendedContentSlots(CreateExtendedSlots(), true);
}
return slots->mExtendedSlots.get();
return slots->GetExtendedContentSlots();
}
/**

Просмотреть файл

@ -66,6 +66,10 @@ WebCryptoThreadPool::DispatchInternal(nsIRunnable* aRunnable)
{
MutexAutoLock lock(mMutex);
if (mShutdown) {
return NS_ERROR_FAILURE;
}
if (!mPool) {
NS_ENSURE_TRUE(EnsureNSSInitializedChromeOrContent(), NS_ERROR_FAILURE);
@ -85,10 +89,21 @@ void
WebCryptoThreadPool::Shutdown()
{
MOZ_ASSERT(NS_IsMainThread(), "Wrong thread!");
MutexAutoLock lock(mMutex);
if (mPool) {
mPool->Shutdown();
// Limit the scope of locking to avoid deadlocking if DispatchInternal ends
// up getting called during shutdown event processing.
nsCOMPtr<nsIThreadPool> pool;
{
MutexAutoLock lock(mMutex);
if (mShutdown) {
return;
}
pool = mPool;
mShutdown = true;
}
if (pool) {
pool->Shutdown();
}
nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();

Просмотреть файл

@ -29,6 +29,7 @@ private:
WebCryptoThreadPool()
: mMutex("WebCryptoThreadPool::mMutex")
, mPool(nullptr)
, mShutdown(false)
{ }
virtual ~WebCryptoThreadPool()
{ }
@ -48,6 +49,7 @@ private:
mozilla::Mutex mMutex;
nsCOMPtr<nsIThreadPool> mPool;
bool mShutdown;
};
} // namespace dom

Просмотреть файл

@ -429,6 +429,7 @@ UnregisterSensorObserver(SensorType aSensor, ISensorObserver *aObserver) {
AssertMainThread();
if (!gSensorObservers) {
HAL_ERR("Un-registering a sensor when none have been registered");
return;
}

Просмотреть файл

@ -18,7 +18,6 @@ namespace hal {
* If you add or change any here, do the same in GeckoHalDefines.java.
*/
enum SensorType {
SENSOR_UNKNOWN = -1,
SENSOR_ORIENTATION = 0,
SENSOR_ACCELERATION = 1,
SENSOR_PROXIMITY = 2,
@ -51,7 +50,7 @@ namespace IPC {
struct ParamTraits<mozilla::hal::SensorType>:
public ContiguousEnumSerializer<
mozilla::hal::SensorType,
mozilla::hal::SENSOR_UNKNOWN,
mozilla::hal::SENSOR_ORIENTATION,
mozilla::hal::NUM_SENSOR_TYPE> {
};
} // namespace IPC

Просмотреть файл

@ -16,6 +16,7 @@
#include "mozilla/dom/network/Types.h"
#include "mozilla/dom/ScreenOrientation.h"
#include "mozilla/fallback/FallbackScreenConfiguration.h"
#include "mozilla/EnumeratedRange.h"
#include "mozilla/Observer.h"
#include "mozilla/Unused.h"
#include "nsAutoPtr.h"
@ -232,9 +233,8 @@ public:
hal::UnregisterBatteryObserver(this);
hal::UnregisterNetworkObserver(this);
hal::UnregisterScreenConfigurationObserver(this);
for (int32_t sensor = SENSOR_UNKNOWN + 1;
sensor < NUM_SENSOR_TYPE; ++sensor) {
hal::UnregisterSensorObserver(SensorType(sensor), this);
for (auto sensor : MakeEnumeratedRange(NUM_SENSOR_TYPE)) {
hal::UnregisterSensorObserver(sensor, this);
}
hal::UnregisterWakeLockObserver(this);
}

Просмотреть файл

@ -2816,6 +2816,11 @@ imgLoader::GetMimeTypeFromContent(const char* aContents,
!memcmp(aContents, "\000\000\002\000", 4))) {
aContentType.AssignLiteral(IMAGE_ICO);
// WebPs always begin with RIFF, a 32-bit length, and WEBP.
} else if (aLength >= 12 && !memcmp(aContents, "RIFF", 4) &&
!memcmp(aContents + 8, "WEBP", 4)) {
aContentType.AssignLiteral(IMAGE_WEBP);
} else {
/* none of the above? I give up */
return NS_ERROR_NOT_AVAILABLE;

Просмотреть файл

@ -39,6 +39,7 @@
#include "imgIRequest.h"
#include "mozilla/IntegerPrintfMacros.h"
#include "mozilla/Telemetry.h"
using namespace mozilla;
using namespace mozilla::image;
@ -940,6 +941,7 @@ imgRequest::OnStopRequest(nsIRequest* aRequest,
struct mimetype_closure
{
nsACString* newType;
uint32_t segmentSize;
};
/* prototype for these defined below */
@ -986,11 +988,49 @@ PrepareForNewPart(nsIRequest* aRequest, nsIInputStream* aInStr, uint32_t aCount,
if (aInStr) {
mimetype_closure closure;
closure.newType = &result.mContentType;
closure.segmentSize = 0;
// Look at the first few bytes and see if we can tell what the data is from
// that since servers tend to lie. :(
uint32_t out;
aInStr->ReadSegments(sniff_mimetype_callback, &closure, aCount, &out);
// We don't support WebP but we are getting reports of Firefox being served
// WebP content in the wild. In particular this appears to be a problem on
// Fennec where content authors assume Android implies WebP support. The
// telemetry below is intended to get a sense of how prevalent this is.
//
// From the Google WebP FAQ example and the Modernizr library, websites may
// supply a tiny WebP image to probe for feature support using scripts. The
// probes are implemented as data URIs thus we should have all the content
// upfront. We don't want to consider a probe as having observed WebP since
// in theory the client should do the right thing when we fail to decode it.
// See https://developers.google.com/speed/webp/faq for details.
bool webp = result.mContentType.EqualsLiteral(IMAGE_WEBP);
bool webpProbe = false;
if (webp) {
// The probes from the example/library are all < 90 bytes. Round it up
// just in case.
const uint32_t kMaxProbeSize = 100;
if (closure.segmentSize < kMaxProbeSize &&
NS_FAILED(aURI->SchemeIs("data", &webpProbe))) {
webpProbe = false;
}
if (webpProbe) {
Telemetry::ScalarSet(Telemetry::ScalarID::IMAGES_WEBP_PROBE_OBSERVED,
true);
} else {
Telemetry::ScalarSet(Telemetry::ScalarID::IMAGES_WEBP_CONTENT_OBSERVED,
true);
}
}
if (!webpProbe) {
Telemetry::ScalarAdd(Telemetry::ScalarID::IMAGES_WEBP_CONTENT_FREQUENCY,
webp ? NS_LITERAL_STRING("webp") :
NS_LITERAL_STRING("other"), 1);
}
}
nsCOMPtr<nsIChannel> chan(do_QueryInterface(aRequest));
@ -1241,6 +1281,7 @@ sniff_mimetype_callback(nsIInputStream* in,
NS_ASSERTION(closure, "closure is null!");
closure->segmentSize = count;
if (count > 0) {
imgLoader::GetMimeTypeFromContent(fromRawSegment, count, *closure->newType);
}

Просмотреть файл

@ -0,0 +1,84 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "gtest/gtest.h"
#include "Common.h"
#include "imgLoader.h"
#include "nsMimeTypes.h"
#include "nsString.h"
using namespace mozilla;
using namespace mozilla::image;
static void
CheckMimeType(const char* aContents, size_t aLength, const char* aExpected)
{
nsAutoCString detected;
nsresult rv = imgLoader::GetMimeTypeFromContent(aContents, aLength, detected);
if (aExpected) {
ASSERT_TRUE(NS_SUCCEEDED(rv));
EXPECT_TRUE(detected.EqualsASCII(aExpected));
} else {
ASSERT_TRUE(NS_FAILED(rv));
EXPECT_TRUE(detected.IsEmpty());
}
}
class ImageLoader : public ::testing::Test
{
protected:
AutoInitializeImageLib mInit;
};
TEST_F(ImageLoader, DetectGIF)
{
const char buffer[] = "GIF87a";
CheckMimeType(buffer, sizeof(buffer), IMAGE_GIF);
}
TEST_F(ImageLoader, DetectPNG)
{
const char buffer[] = "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A";
CheckMimeType(buffer, sizeof(buffer), IMAGE_PNG);
}
TEST_F(ImageLoader, DetectJPEG)
{
const char buffer[] = "\xFF\xD8\xFF";
CheckMimeType(buffer, sizeof(buffer), IMAGE_JPEG);
}
TEST_F(ImageLoader, DetectART)
{
const char buffer[] = "\x4A\x47\xFF\xFF\x00";
CheckMimeType(buffer, sizeof(buffer), IMAGE_ART);
}
TEST_F(ImageLoader, DetectBMP)
{
const char buffer[] = "BM";
CheckMimeType(buffer, sizeof(buffer), IMAGE_BMP);
}
TEST_F(ImageLoader, DetectICO)
{
const char buffer[] = "\x00\x00\x01\x00";
CheckMimeType(buffer, sizeof(buffer), IMAGE_ICO);
}
TEST_F(ImageLoader, DetectWebP)
{
const char buffer[] = "RIFF\xFF\xFF\xFF\xFFWEBPVP8L";
CheckMimeType(buffer, sizeof(buffer), IMAGE_WEBP);
}
TEST_F(ImageLoader, DetectNone)
{
const char buffer[] = "abcdefghijklmnop";
CheckMimeType(buffer, sizeof(buffer), nullptr);
}

Просмотреть файл

@ -15,6 +15,7 @@ UNIFIED_SOURCES = [
'TestDecoders.cpp',
'TestDecodeToSurface.cpp',
'TestDeinterlacingFilter.cpp',
'TestLoader.cpp',
'TestMetadata.cpp',
'TestRemoveFrameRectFilter.cpp',
'TestSourceBuffer.cpp',

Просмотреть файл

@ -13,6 +13,7 @@
#include "js/AllocPolicy.h"
#include "js/UbiNodeBreadthFirst.h"
#include "js/UniquePtr.h"
#include "js/Vector.h"
namespace JS {
@ -28,7 +29,7 @@ struct JS_PUBLIC_API(BackEdge)
EdgeName name_;
public:
using Ptr = mozilla::UniquePtr<BackEdge, JS::DeletePolicy<BackEdge>>;
using Ptr = js::UniquePtr<BackEdge>;
BackEdge() : predecessor_(), name_(nullptr) { }
@ -147,7 +148,7 @@ struct JS_PUBLIC_API(ShortestPaths)
"saw it.");
if (ptr->value().length() < shortestPaths.maxNumPaths_) {
BackEdge::Ptr thisBackEdge(js_new<BackEdge>());
auto thisBackEdge = js::MakeUnique<BackEdge>();
if (!thisBackEdge || !thisBackEdge->init(origin, edge))
return false;
ptr->value().infallibleAppend(std::move(thisBackEdge));

Просмотреть файл

@ -306,11 +306,10 @@ MapIteratorObject::objectMoved(JSObject* obj, JSObject* old)
}
AutoEnterOOMUnsafeRegion oomUnsafe;
auto newRange = iter->zone()->pod_malloc<ValueMap::Range>();
auto newRange = iter->zone()->new_<ValueMap::Range>(*range);
if (!newRange)
oomUnsafe.crash("MapIteratorObject failed to allocate Range data while tenuring.");
new (newRange) ValueMap::Range(*range);
range->~Range();
iter->setReservedSlot(MapIteratorObject::RangeSlot, PrivateValue(newRange));
return sizeof(ValueMap::Range);
@ -1161,11 +1160,10 @@ SetIteratorObject::objectMoved(JSObject* obj, JSObject* old)
}
AutoEnterOOMUnsafeRegion oomUnsafe;
auto newRange = iter->zone()->pod_malloc<ValueSet::Range>();
auto newRange = iter->zone()->new_<ValueSet::Range>(*range);
if (!newRange)
oomUnsafe.crash("SetIteratorObject failed to allocate Range data while tenuring.");
new (newRange) ValueSet::Range(*range);
range->~Range();
iter->setReservedSlot(SetIteratorObject::RangeSlot, PrivateValue(newRange));
return sizeof(ValueSet::Range);

Просмотреть файл

@ -28,6 +28,8 @@
# define getpid _getpid
#endif
#include "js/Utility.h"
#include "util/Text.h"
#include "vm/Probes.h"
#include "vm/JSContext-inl.h"
@ -188,27 +190,21 @@ JS_DumpProfile(const char* outfile, const char* profileName)
#ifdef MOZ_PROFILING
struct RequiredStringArg {
JSContext* mCx;
char* mBytes;
RequiredStringArg(JSContext* cx, const CallArgs& args, size_t argi, const char* caller)
: mCx(cx), mBytes(nullptr)
{
if (args.length() <= argi) {
JS_ReportErrorASCII(cx, "%s: not enough arguments", caller);
} else if (!args[argi].isString()) {
JS_ReportErrorASCII(cx, "%s: invalid arguments (string expected)", caller);
} else {
mBytes = JS_EncodeString(cx, args[argi].toString());
}
static UniqueChars
RequiredStringArg(JSContext* cx, const CallArgs& args, size_t argi, const char* caller)
{
if (args.length() <= argi) {
JS_ReportErrorASCII(cx, "%s: not enough arguments", caller);
return nullptr;
}
operator void*() {
return (void*) mBytes;
if (!args[argi].isString()) {
JS_ReportErrorASCII(cx, "%s: invalid arguments (string expected)", caller);
return nullptr;
}
~RequiredStringArg() {
js_free(mBytes);
}
};
return UniqueChars(JS_EncodeString(cx, args[argi].toString()));
}
static bool
StartProfiling(JSContext* cx, unsigned argc, Value* vp)
@ -219,12 +215,12 @@ StartProfiling(JSContext* cx, unsigned argc, Value* vp)
return true;
}
RequiredStringArg profileName(cx, args, 0, "startProfiling");
UniqueChars profileName = RequiredStringArg(cx, args, 0, "startProfiling");
if (!profileName)
return false;
if (args.length() == 1) {
args.rval().setBoolean(JS_StartProfiling(profileName.mBytes, getpid()));
args.rval().setBoolean(JS_StartProfiling(profileName.get(), getpid()));
return true;
}
@ -233,7 +229,7 @@ StartProfiling(JSContext* cx, unsigned argc, Value* vp)
return false;
}
pid_t pid = static_cast<pid_t>(args[1].toInt32());
args.rval().setBoolean(JS_StartProfiling(profileName.mBytes, pid));
args.rval().setBoolean(JS_StartProfiling(profileName.get(), pid));
return true;
}
@ -246,10 +242,10 @@ StopProfiling(JSContext* cx, unsigned argc, Value* vp)
return true;
}
RequiredStringArg profileName(cx, args, 0, "stopProfiling");
UniqueChars profileName = RequiredStringArg(cx, args, 0, "stopProfiling");
if (!profileName)
return false;
args.rval().setBoolean(JS_StopProfiling(profileName.mBytes));
args.rval().setBoolean(JS_StopProfiling(profileName.get()));
return true;
}
@ -262,10 +258,10 @@ PauseProfilers(JSContext* cx, unsigned argc, Value* vp)
return true;
}
RequiredStringArg profileName(cx, args, 0, "pauseProfiling");
UniqueChars profileName = RequiredStringArg(cx, args, 0, "pauseProfiling");
if (!profileName)
return false;
args.rval().setBoolean(JS_PauseProfilers(profileName.mBytes));
args.rval().setBoolean(JS_PauseProfilers(profileName.get()));
return true;
}
@ -278,10 +274,10 @@ ResumeProfilers(JSContext* cx, unsigned argc, Value* vp)
return true;
}
RequiredStringArg profileName(cx, args, 0, "resumeProfiling");
UniqueChars profileName = RequiredStringArg(cx, args, 0, "resumeProfiling");
if (!profileName)
return false;
args.rval().setBoolean(JS_ResumeProfilers(profileName.mBytes));
args.rval().setBoolean(JS_ResumeProfilers(profileName.get()));
return true;
}
@ -294,18 +290,18 @@ DumpProfile(JSContext* cx, unsigned argc, Value* vp)
if (args.length() == 0) {
ret = JS_DumpProfile(nullptr, nullptr);
} else {
RequiredStringArg filename(cx, args, 0, "dumpProfile");
UniqueChars filename = RequiredStringArg(cx, args, 0, "dumpProfile");
if (!filename)
return false;
if (args.length() == 1) {
ret = JS_DumpProfile(filename.mBytes, nullptr);
ret = JS_DumpProfile(filename.get(), nullptr);
} else {
RequiredStringArg profileName(cx, args, 1, "dumpProfile");
UniqueChars profileName = RequiredStringArg(cx, args, 1, "dumpProfile");
if (!profileName)
return false;
ret = JS_DumpProfile(filename.mBytes, profileName.mBytes);
ret = JS_DumpProfile(filename.get(), profileName.get());
}
}
@ -367,11 +363,11 @@ DumpCallgrind(JSContext* cx, unsigned argc, Value* vp)
return true;
}
RequiredStringArg outFile(cx, args, 0, "dumpCallgrind");
UniqueChars outFile = RequiredStringArg(cx, args, 0, "dumpCallgrind");
if (!outFile)
return false;
args.rval().setBoolean(js_DumpCallgrind(outFile.mBytes));
args.rval().setBoolean(js_DumpCallgrind(outFile.get()));
return true;
}
#endif
@ -547,10 +543,9 @@ bool js_StartPerf()
flags = "--call-graph";
}
UniqueChars flags2((char*)js_malloc(strlen(flags) + 1));
UniqueChars flags2 = DuplicateString(flags);
if (!flags2)
return false;
strcpy(flags2.get(), flags);
// Split |flags2| on spaces.
char* toksave;

Просмотреть файл

@ -192,12 +192,7 @@ class MOZ_NON_PARAM InlineCharBuffer
MOZ_ASSERT(heapStorage, "heap storage was not allocated for non-inline string");
heapStorage.get()[length] = '\0'; // Null-terminate
JSString* res = NewStringDontDeflate<CanGC>(cx, heapStorage.get(), length);
if (!res)
return nullptr;
mozilla::Unused << heapStorage.release();
return res;
return NewStringDontDeflate<CanGC>(cx, std::move(heapStorage), length);
}
JSString* toString(JSContext* cx, size_t length)
@ -214,12 +209,7 @@ class MOZ_NON_PARAM InlineCharBuffer
MOZ_ASSERT(heapStorage, "heap storage was not allocated for non-inline string");
heapStorage.get()[length] = '\0'; // Null-terminate
JSString* res = NewString<CanGC>(cx, heapStorage.get(), length);
if (!res)
return nullptr;
mozilla::Unused << heapStorage.release();
return res;
return NewString<CanGC>(cx, std::move(heapStorage), length);
}
};
@ -3558,7 +3548,7 @@ js::str_fromCodePoint(JSContext* cx, unsigned argc, Value* vp)
// Step 3.
static_assert(ARGS_LENGTH_MAX < std::numeric_limits<decltype(args.length())>::max() / 2,
"|args.length() * 2 + 1| does not overflow");
char16_t* elements = cx->pod_malloc<char16_t>(args.length() * 2 + 1);
auto elements = cx->make_pod_array<char16_t>(args.length() * 2 + 1);
if (!elements)
return false;
@ -3567,22 +3557,18 @@ js::str_fromCodePoint(JSContext* cx, unsigned argc, Value* vp)
for (unsigned nextIndex = 0; nextIndex < args.length(); nextIndex++) {
// Steps 5.a-d.
uint32_t codePoint;
if (!ToCodePoint(cx, args[nextIndex], &codePoint)) {
js_free(elements);
if (!ToCodePoint(cx, args[nextIndex], &codePoint))
return false;
}
// Step 5.e.
unicode::UTF16Encode(codePoint, elements, &length);
unicode::UTF16Encode(codePoint, elements.get(), &length);
}
elements[length] = 0;
// Step 6.
JSString* str = NewString<CanGC>(cx, elements, length);
if (!str) {
js_free(elements);
JSString* str = NewString<CanGC>(cx, std::move(elements), length);
if (!str)
return false;
}
args.rval().setString(str);
return true;

Просмотреть файл

@ -1438,7 +1438,7 @@ NewExternalString(JSContext* cx, unsigned argc, Value* vp)
RootedString str(cx, args[0].toString());
size_t len = str->length();
UniqueTwoByteChars buf(cx->pod_malloc<char16_t>(len));
auto buf = cx->make_pod_array<char16_t>(len);
if (!buf)
return false;
@ -1467,7 +1467,7 @@ NewMaybeExternalString(JSContext* cx, unsigned argc, Value* vp)
RootedString str(cx, args[0].toString());
size_t len = str->length();
UniqueTwoByteChars buf(cx->pod_malloc<char16_t>(len));
auto buf = cx->make_pod_array<char16_t>(len);
if (!buf)
return false;
@ -2435,13 +2435,9 @@ ReadGeckoProfilingStack(JSContext* cx, unsigned argc, Value* vp)
if (!JS_DefineProperty(cx, inlineFrameInfo, "kind", frameKind, propAttrs))
return false;
size_t length = strlen(inlineFrame.label.get());
auto* label = reinterpret_cast<Latin1Char*>(inlineFrame.label.release());
frameLabel = NewString<CanGC>(cx, label, length);
if (!frameLabel) {
js_free(label);
frameLabel = NewLatin1StringZ(cx, std::move(inlineFrame.label));
if (!frameLabel)
return false;
}
if (!JS_DefineProperty(cx, inlineFrameInfo, "label", frameLabel, propAttrs))
return false;
@ -2927,7 +2923,7 @@ class CloneBufferObject : public NativeObject {
return false;
size_t size = data->Size();
UniqueChars buffer(static_cast<char*>(js_malloc(size)));
UniqueChars buffer(js_pod_malloc<char>(size));
if (!buffer) {
ReportOutOfMemory(cx);
return false;
@ -2957,7 +2953,7 @@ class CloneBufferObject : public NativeObject {
return false;
size_t size = data->Size();
UniqueChars buffer(static_cast<char*>(js_malloc(size)));
UniqueChars buffer(js_pod_malloc<char>(size));
if (!buffer) {
ReportOutOfMemory(cx);
return false;
@ -3645,10 +3641,10 @@ FindPath(JSContext* cx, unsigned argc, Value* vp)
heaptools::EdgeName edgeName = std::move(edges[i]);
RootedString edgeStr(cx, NewString<CanGC>(cx, edgeName.get(), js_strlen(edgeName.get())));
size_t edgeNameLength = js_strlen(edgeName.get());
RootedString edgeStr(cx, NewString<CanGC>(cx, std::move(edgeName), edgeNameLength));
if (!edgeStr)
return false;
mozilla::Unused << edgeName.release(); // edgeStr acquired ownership
if (!JS_DefineProperty(cx, obj, "edge", edgeStr, JSPROP_ENUMERATE))
return false;
@ -4347,18 +4343,16 @@ GetLcovInfo(JSContext* cx, unsigned argc, Value* vp)
}
size_t length = 0;
char* content = nullptr;
UniqueChars content;
{
AutoRealm ar(cx, global);
content = js::GetCodeCoverageSummary(cx, &length);
content.reset(js::GetCodeCoverageSummary(cx, &length));
}
if (!content)
return false;
JSString* str = JS_NewStringCopyN(cx, content, length);
js_free(content);
JSString* str = JS_NewStringCopyN(cx, content.get(), length);
if (!str)
return false;

Просмотреть файл

@ -10,6 +10,7 @@
#include "mozilla/MemoryReporting.h"
#include "mozilla/Sprintf.h"
#include "mozilla/TextUtils.h"
#include "mozilla/Unused.h"
#include "mozilla/Vector.h"
#include "mozilla/WrappingOperations.h"
@ -7699,7 +7700,7 @@ CData::Create(JSContext* cx,
// attach the buffer. since it might not be 2-byte aligned, we need to
// allocate an aligned space for it and store it there. :(
char** buffer = cx->new_<char*>();
UniquePtr<char*, JS::FreePolicy> buffer(cx->new_<char*>());
if (!buffer)
return nullptr;
@ -7713,7 +7714,6 @@ CData::Create(JSContext* cx,
if (!data) {
// Report a catchable allocation error.
JS_ReportAllocationOverflow(cx);
js_free(buffer);
return nullptr;
}
@ -7723,8 +7723,8 @@ CData::Create(JSContext* cx,
memcpy(data, source, size);
}
*buffer = data;
JS_SetReservedSlot(dataObj, SLOT_DATA, PrivateValue(buffer));
*buffer.get() = data;
JS_SetReservedSlot(dataObj, SLOT_DATA, PrivateValue(buffer.release()));
// If this is an array, wrap it in a proxy so we can intercept element
// gets/sets.
@ -8014,16 +8014,15 @@ ReadStringCommon(JSContext* cx, InflateUTF8Method inflateUTF8, unsigned argc,
size_t length = strnlen(bytes, maxLength);
// Determine the length.
char16_t* dst = inflateUTF8(cx, JS::UTF8Chars(bytes, length), &length).get();
UniqueTwoByteChars dst(inflateUTF8(cx, JS::UTF8Chars(bytes, length), &length).get());
if (!dst)
return false;
result = JS_NewUCString(cx, dst, length);
if (!result) {
js_free(dst);
result = JS_NewUCString(cx, dst.get(), length);
if (!result)
return false;
}
mozilla::Unused << dst.release();
break;
}
case TYPE_int16_t:

Просмотреть файл

@ -18,6 +18,7 @@
#include "jit/mips64/Simulator-mips64.h"
#include "jit/Recover.h"
#include "jit/RematerializedFrame.h"
#include "js/Utility.h"
#include "vm/ArgumentsObject.h"
#include "vm/Debugger.h"
#include "vm/TraceLogging.h"
@ -118,7 +119,7 @@ struct BaselineStackBuilder
MOZ_MUST_USE bool init() {
MOZ_ASSERT(!buffer_);
MOZ_ASSERT(bufferUsed_ == 0);
buffer_ = reinterpret_cast<uint8_t*>(js_calloc(bufferTotal_));
buffer_ = js_pod_calloc<uint8_t>(bufferTotal_);
if (!buffer_)
return false;
bufferAvail_ = bufferTotal_ - HeaderSize();
@ -148,7 +149,7 @@ struct BaselineStackBuilder
if (bufferTotal_ & mozilla::tl::MulOverflowMask<2>::value)
return false;
size_t newSize = bufferTotal_ * 2;
uint8_t* newBuffer = reinterpret_cast<uint8_t*>(js_calloc(newSize));
uint8_t* newBuffer = js_pod_calloc<uint8_t>(newSize);
if (!newBuffer)
return false;
memcpy((newBuffer + newSize) - bufferUsed_, header_->copyStackBottom, bufferUsed_);
@ -1236,20 +1237,19 @@ InitFromBailout(JSContext* cx, size_t frameNo,
if (filename == nullptr)
filename = "<unknown>";
unsigned len = strlen(filename) + 200;
char* buf = js_pod_malloc<char>(len);
UniqueChars buf(js_pod_malloc<char>(len));
if (buf == nullptr) {
ReportOutOfMemory(cx);
return false;
}
snprintf(buf, len, "%s %s %s on line %u of %s:%u",
snprintf(buf.get(), len, "%s %s %s on line %u of %s:%u",
BailoutKindString(bailoutKind),
resumeAfter ? "after" : "at",
CodeName[op],
PCToLineNumber(script, pc),
filename,
script->lineno());
cx->runtime()->geckoProfiler().markEvent(buf);
js_free(buf);
cx->runtime()->geckoProfiler().markEvent(buf.get());
}
return true;

Просмотреть файл

@ -5384,7 +5384,7 @@ CodeGenerator::maybeCreateScriptCounts()
if (!script)
return nullptr;
UniquePtr<IonScriptCounts> counts(js_new<IonScriptCounts>());
auto counts = MakeUnique<IonScriptCounts>();
if (!counts || !counts->init(graph.numBlocks()))
return nullptr;
@ -5405,7 +5405,7 @@ CodeGenerator::maybeCreateScriptCounts()
if (block->entryResumePoint()->caller()) {
// Get the filename and line number of the inner script.
JSScript* innerScript = block->info().script();
description = (char*) js_calloc(200);
description = js_pod_calloc<char>(200);
if (description) {
snprintf(description, 200, "%s:%u",
innerScript->filename(), innerScript->lineno());

Просмотреть файл

@ -1872,16 +1872,14 @@ GenerateCode(MIRGenerator* mir, LIRGraph* lir)
TraceLoggerThread* logger = TraceLoggerForCurrentThread();
AutoTraceLog log(logger, TraceLogger_GenerateCode);
CodeGenerator* codegen = js_new<CodeGenerator>(mir, lir);
auto codegen = MakeUnique<CodeGenerator>(mir, lir);
if (!codegen)
return nullptr;
if (!codegen->generate()) {
js_delete(codegen);
if (!codegen->generate())
return nullptr;
}
return codegen;
return codegen.release();
}
CodeGenerator*

Просмотреть файл

@ -1413,7 +1413,7 @@ GetPcScript(JSContext* cx, JSScript** scriptRes, jsbytecode** pcRes)
// Lazily initialize the cache. The allocation may safely fail and will not GC.
if (MOZ_UNLIKELY(cx->ionPcScriptCache == nullptr)) {
cx->ionPcScriptCache = (PcScriptCache*)js_malloc(sizeof(struct PcScriptCache));
cx->ionPcScriptCache = js_pod_malloc<PcScriptCache>();
if (cx->ionPcScriptCache)
cx->ionPcScriptCache->clear(cx->runtime()->gc.gcNumber());
}

Просмотреть файл

@ -73,10 +73,7 @@ RematerializedFrame::New(JSContext* cx, uint8_t* top, InlineFrameIterator& iter,
if (extraSlots > 0)
extraSlots -= 1;
size_t numBytes = sizeof(RematerializedFrame) + (extraSlots * sizeof(Value));
MOZ_ASSERT(numBytes >= sizeof(RematerializedFrame));
void* buf = cx->pod_calloc<uint8_t>(numBytes);
RematerializedFrame* buf = cx->pod_calloc_with_extra<RematerializedFrame, Value>(extraSlots);
if (!buf)
return nullptr;

Просмотреть файл

@ -38,6 +38,8 @@
#include "jit/arm/Assembler-arm.h"
#include "jit/arm/disasm/Constants-arm.h"
#include "jit/AtomicOperations.h"
#include "js/UniquePtr.h"
#include "js/Utility.h"
#include "threading/LockGuard.h"
#include "vm/Runtime.h"
#include "vm/SharedMem.h"
@ -414,14 +416,12 @@ int64_t Simulator::StopSimAt = -1L;
Simulator*
Simulator::Create(JSContext* cx)
{
Simulator* sim = js_new<Simulator>(cx);
auto sim = MakeUnique<Simulator>(cx);
if (!sim)
return nullptr;
if (!sim->init()) {
js_delete(sim);
if (!sim->init())
return nullptr;
}
char* stopAtStr = getenv("ARM_SIM_STOP_AT");
int64_t stopAt;
@ -430,7 +430,7 @@ Simulator::Create(JSContext* cx)
Simulator::StopSimAt = stopAt;
}
return sim;
return sim.release();
}
void
@ -620,7 +620,7 @@ ArmDebugger::redoBreakpoints()
static char*
ReadLine(const char* prompt)
{
char* result = nullptr;
UniqueChars result;
char line_buf[256];
int offset = 0;
bool keep_going = true;
@ -629,8 +629,6 @@ ReadLine(const char* prompt)
while (keep_going) {
if (fgets(line_buf, sizeof(line_buf), stdin) == nullptr) {
// fgets got an error. Just give up.
if (result)
js_delete(result);
return nullptr;
}
int len = strlen(line_buf);
@ -642,29 +640,28 @@ ReadLine(const char* prompt)
if (!result) {
// Allocate the initial result and make room for the terminating
// '\0'.
result = (char*)js_malloc(len + 1);
result.reset(js_pod_malloc<char>(len + 1));
if (!result)
return nullptr;
} else {
// Allocate a new result with enough room for the new addition.
int new_len = offset + len + 1;
char* new_result = (char*)js_malloc(new_len);
char* new_result = js_pod_malloc<char>(new_len);
if (!new_result)
return nullptr;
// Copy the existing input into the new array and set the new
// array as the result.
memcpy(new_result, result, offset * sizeof(char));
js_free(result);
result = new_result;
memcpy(new_result, result.get(), offset * sizeof(char));
result.reset(new_result);
}
// Copy the newly read line into the result.
memcpy(result + offset, line_buf, len * sizeof(char));
memcpy(result.get() + offset, line_buf, len * sizeof(char));
offset += len;
}
MOZ_ASSERT(result);
result[offset] = '\0';
return result;
return result.release();
}
@ -1199,7 +1196,7 @@ Simulator::init()
{
// Allocate 2MB for the stack. Note that we will only use 1MB, see below.
static const size_t stackSize = 2 * 1024*1024;
stack_ = reinterpret_cast<char*>(js_malloc(stackSize));
stack_ = js_pod_malloc<char>(stackSize);
if (!stack_)
return false;
@ -1257,7 +1254,7 @@ class Redirection
}
AutoEnterOOMUnsafeRegion oomUnsafe;
Redirection* redir = (Redirection*)js_malloc(sizeof(Redirection));
Redirection* redir = js_pod_malloc<Redirection>();
if (!redir)
oomUnsafe.crash("Simulator redirection");
new(redir) Redirection(nativeFunction, type);

Просмотреть файл

@ -136,7 +136,7 @@ class IdentifierToken : public ValueToken<char*> {
public:
explicit IdentifierToken(const char* name) {
size_t size = strlen(name) + 1;
value_ = (char*)js_malloc(size);
value_ = js_pod_malloc<char>(size);
strncpy(value_, name, size);
}
virtual ~IdentifierToken() { js_free(value_); }
@ -244,7 +244,7 @@ class UnknownToken : public Token {
public:
explicit UnknownToken(const char* arg) {
size_t size = strlen(arg) + 1;
unknown_ = (char*)js_malloc(size);
unknown_ = js_pod_malloc<char>(size);
strncpy(unknown_, arg, size);
}
virtual ~UnknownToken() { js_free(unknown_); }

Просмотреть файл

@ -29,6 +29,7 @@
#include "jit/arm64/vixl/Debugger-vixl.h"
#include "jit/arm64/vixl/Simulator-vixl.h"
#include "jit/IonTypes.h"
#include "js/UniquePtr.h"
#include "js/Utility.h"
#include "threading/LockGuard.h"
#include "vm/Runtime.h"
@ -124,7 +125,7 @@ void Simulator::init(Decoder* decoder, FILE* stream) {
ResetState();
// Allocate and set up the simulator stack.
stack_ = (byte*)js_malloc(stack_size_);
stack_ = js_pod_malloc<byte>(stack_size_);
if (!stack_) {
oom_ = true;
return;
@ -168,19 +169,17 @@ Simulator* Simulator::Create(JSContext* cx) {
// FIXME: This just leaks the Decoder object for now, which is probably OK.
// FIXME: We should free it at some point.
// FIXME: Note that it can't be stored in the SimulatorRuntime due to lifetime conflicts.
Simulator *sim;
js::UniquePtr<Simulator> sim;
if (getenv("USE_DEBUGGER") != nullptr)
sim = js_new<Debugger>(cx, decoder, stdout);
sim.reset(js_new<Debugger>(cx, decoder, stdout));
else
sim = js_new<Simulator>(cx, decoder, stdout);
sim.reset(js_new<Simulator>(cx, decoder, stdout));
// Check if Simulator:init ran out of memory.
if (sim && sim->oom()) {
js_delete(sim);
if (sim && sim->oom())
return nullptr;
}
return sim;
return sim.release();
}
@ -392,7 +391,7 @@ class Redirection
}
js::AutoEnterOOMUnsafeRegion oomUnsafe;
Redirection* redir = (Redirection*)js_malloc(sizeof(Redirection));
Redirection* redir = js_pod_malloc<Redirection>();
if (!redir)
oomUnsafe.crash("Simulator redirection");
new(redir) Redirection(nativeFunction, type);

Просмотреть файл

@ -37,6 +37,8 @@
#include "jit/AtomicOperations.h"
#include "jit/mips32/Assembler-mips32.h"
#include "js/UniquePtr.h"
#include "js/Utility.h"
#include "vm/Runtime.h"
#include "wasm/WasmInstance.h"
#include "wasm/WasmSignalHandlers.h"
@ -523,14 +525,12 @@ int Simulator::StopSimAt = -1;
Simulator*
Simulator::Create(JSContext* cx)
{
Simulator* sim = js_new<Simulator>();
auto sim = MakeUnique<Simulator>();
if (!sim)
return nullptr;
if (!sim->init()) {
js_delete(sim);
if (!sim->init())
return nullptr;
}
char* stopAtStr = getenv("MIPS_SIM_STOP_AT");
int64_t stopAt;
@ -539,7 +539,7 @@ Simulator::Create(JSContext* cx)
Simulator::StopSimAt = stopAt;
}
return sim;
return sim.release();
}
void
@ -749,7 +749,7 @@ MipsDebugger::printAllRegsIncludingFPU()
static char*
ReadLine(const char* prompt)
{
char* result = nullptr;
UniqueChars result;
char lineBuf[256];
int offset = 0;
bool keepGoing = true;
@ -758,8 +758,6 @@ ReadLine(const char* prompt)
while (keepGoing) {
if (fgets(lineBuf, sizeof(lineBuf), stdin) == nullptr) {
// fgets got an error. Just give up.
if (result)
js_delete(result);
return nullptr;
}
int len = strlen(lineBuf);
@ -770,29 +768,28 @@ ReadLine(const char* prompt)
}
if (!result) {
// Allocate the initial result and make room for the terminating '\0'
result = (char*)js_malloc(len + 1);
result.reset(js_pod_malloc<char>(len + 1));
if (!result)
return nullptr;
} else {
// Allocate a new result with enough room for the new addition.
int new_len = offset + len + 1;
char* new_result = (char*)js_malloc(new_len);
char* new_result = js_pod_malloc<char>(new_len);
if (!new_result)
return nullptr;
// Copy the existing input into the new array and set the new
// array as the result.
memcpy(new_result, result, offset * sizeof(char));
js_free(result);
result = new_result;
memcpy(new_result, result.get(), offset * sizeof(char));
result.reset(new_result);
}
// Copy the newly read line into the result.
memcpy(result + offset, lineBuf, len * sizeof(char));
memcpy(result.get() + offset, lineBuf, len * sizeof(char));
offset += len;
}
MOZ_ASSERT(result);
result[offset] = '\0';
return result;
return result.release();
}
static void
@ -1288,7 +1285,7 @@ Simulator::init()
{
// Allocate 2MB for the stack. Note that we will only use 1MB, see below.
static const size_t stackSize = 2 * 1024 * 1024;
stack_ = static_cast<char*>(js_malloc(stackSize));
stack_ = js_pod_malloc<char>(stackSize);
if (!stack_)
return false;
@ -1347,7 +1344,7 @@ class Redirection
}
AutoEnterOOMUnsafeRegion oomUnsafe;
Redirection* redir = (Redirection*)js_malloc(sizeof(Redirection));
Redirection* redir = js_pod_malloc<Redirection>();
if (!redir) {
oomUnsafe.crash("Simulator redirection");
}

Просмотреть файл

@ -40,6 +40,8 @@
#include "jit/AtomicOperations.h"
#include "jit/mips64/Assembler-mips64.h"
#include "js/UniquePtr.h"
#include "js/Utility.h"
#include "threading/LockGuard.h"
#include "vm/Runtime.h"
#include "wasm/WasmInstance.h"
@ -558,14 +560,12 @@ int64_t Simulator::StopSimAt = -1;
Simulator *
Simulator::Create(JSContext* cx)
{
Simulator* sim = js_new<Simulator>();
auto sim = MakeUnique<Simulator>();
if (!sim)
return nullptr;
if (!sim->init()) {
js_delete(sim);
if (!sim->init())
return nullptr;
}
int64_t stopAt;
char* stopAtStr = getenv("MIPS_SIM_STOP_AT");
@ -574,7 +574,7 @@ Simulator::Create(JSContext* cx)
Simulator::StopSimAt = stopAt;
}
return sim;
return sim.release();
}
void
@ -767,7 +767,7 @@ MipsDebugger::printAllRegsIncludingFPU()
static char*
ReadLine(const char* prompt)
{
char* result = nullptr;
UniqueChars result;
char lineBuf[256];
int offset = 0;
bool keepGoing = true;
@ -776,8 +776,6 @@ ReadLine(const char* prompt)
while (keepGoing) {
if (fgets(lineBuf, sizeof(lineBuf), stdin) == nullptr) {
// fgets got an error. Just give up.
if (result)
js_delete(result);
return nullptr;
}
int len = strlen(lineBuf);
@ -788,29 +786,28 @@ ReadLine(const char* prompt)
}
if (!result) {
// Allocate the initial result and make room for the terminating '\0'
result = (char*)js_malloc(len + 1);
result.reset(js_pod_malloc<char>(len + 1));
if (!result)
return nullptr;
} else {
// Allocate a new result with enough room for the new addition.
int new_len = offset + len + 1;
char* new_result = (char*)js_malloc(new_len);
char* new_result = js_pod_malloc<char>(new_len);
if (!new_result)
return nullptr;
// Copy the existing input into the new array and set the new
// array as the result.
memcpy(new_result, result, offset * sizeof(char));
js_free(result);
result = new_result;
memcpy(new_result, result.get(), offset * sizeof(char));
result.reset(new_result);
}
// Copy the newly read line into the result.
memcpy(result + offset, lineBuf, len * sizeof(char));
memcpy(result.get() + offset, lineBuf, len * sizeof(char));
offset += len;
}
MOZ_ASSERT(result);
result[offset] = '\0';
return result;
return result.release();
}
static void
@ -1296,7 +1293,7 @@ Simulator::init()
{
// Allocate 2MB for the stack. Note that we will only use 1MB, see below.
static const size_t stackSize = 2 * 1024 * 1024;
stack_ = static_cast<char*>(js_malloc(stackSize));
stack_ = js_pod_malloc<char>(stackSize);
if (!stack_)
return false;
@ -1355,7 +1352,7 @@ class Redirection
}
AutoEnterOOMUnsafeRegion oomUnsafe;
Redirection* redir = (Redirection*)js_malloc(sizeof(Redirection));
Redirection* redir = js_pod_malloc<Redirection>();
if (!redir) {
oomUnsafe.crash("Simulator redirection");
}

Просмотреть файл

@ -237,7 +237,7 @@ DisassemblerSpew::Node*
DisassemblerSpew::add(const Label* key, uint32_t value)
{
MOZ_ASSERT(!lookup(key));
Node* node = (Node*)js_malloc(sizeof(Node));
Node* node = js_pod_malloc<Node>();
if (node) {
node->key = key;
node->value = value;

Просмотреть файл

@ -4361,7 +4361,7 @@ JS_BufferIsCompilableUnit(JSContext* cx, HandleObject obj, const char* utf8, siz
cx->clearPendingException();
UniquePtr<char16_t> chars
UniqueTwoByteChars chars
{ JS::UTF8CharsToNewTwoByteCharsZ(cx, JS::UTF8Chars(utf8, length), &length).get() };
if (!chars)
return true;
@ -5812,7 +5812,7 @@ JS_NewLatin1String(JSContext* cx, JS::Latin1Char* chars, size_t length)
{
AssertHeapIsIdle();
CHECK_REQUEST(cx);
return NewString<CanGC>(cx, chars, length);
return NewString(cx, chars, length);
}
JS_PUBLIC_API(JSString*)
@ -5820,7 +5820,7 @@ JS_NewUCString(JSContext* cx, char16_t* chars, size_t length)
{
AssertHeapIsIdle();
CHECK_REQUEST(cx);
return NewString<CanGC>(cx, chars, length);
return NewString(cx, chars, length);
}
JS_PUBLIC_API(JSString*)
@ -5828,7 +5828,7 @@ JS_NewUCStringDontDeflate(JSContext* cx, char16_t* chars, size_t length)
{
AssertHeapIsIdle();
CHECK_REQUEST(cx);
return NewStringDontDeflate<CanGC>(cx, chars, length);
return NewStringDontDeflate(cx, chars, length);
}
JS_PUBLIC_API(JSString*)

Просмотреть файл

@ -374,7 +374,7 @@ namespace JS {
* Example use:
*
* size_t length = 512;
* char16_t* chars = static_cast<char16_t*>(js_malloc(sizeof(char16_t) * length));
* char16_t* chars = js_pod_malloc<char16_t>(length);
* JS::SourceBufferHolder srcBuf(chars, length, JS::SourceBufferHolder::GiveOwnership);
* JS::Compile(cx, options, srcBuf);
*/

Просмотреть файл

@ -86,7 +86,7 @@ ComputeAccurateDecimalInteger(JSContext* cx, const CharT* start, const CharT* en
double* dp)
{
size_t length = end - start;
UniqueChars cstr(cx->pod_malloc<char>(length + 1));
auto cstr = cx->make_pod_array<char>(length + 1);
if (!cstr)
return false;

Просмотреть файл

@ -773,20 +773,11 @@ ReportSysError(JSContext* cx, const char* prefix)
if (!errstr)
errstr = "unknown error";
size_t nbytes = strlen(prefix) + strlen(errstr) + 3;
char* final = (char*) js_malloc(nbytes);
if (!final) {
JS_ReportOutOfMemory(cx);
return;
}
snprintf(final, nbytes, "%s: %s", prefix, errstr);
/*
* Use Latin1 variant here because the encoding of the return value of
* strerror_s and strerror_r function can be non-UTF-8.
*/
JS_ReportErrorLatin1(cx, "%s", final);
js_free(final);
JS_ReportErrorLatin1(cx, "%s: %s", prefix, errstr);
}
static bool

Просмотреть файл

@ -884,7 +884,7 @@ InitModuleLoader(JSContext* cx)
// the module loader for the current compartment.
uint32_t srcLen = moduleloader::GetRawScriptsSize();
UniqueChars src(cx->pod_malloc<char>(srcLen));
auto src = cx->make_pod_array<char>(srcLen);
if (!src || !DecompressString(moduleloader::compressedSources, moduleloader::GetCompressedSize(),
reinterpret_cast<unsigned char*>(src.get()), srcLen))
{
@ -2128,7 +2128,7 @@ js::shell::FileAsString(JSContext* cx, JS::HandleString pathnameStr)
return nullptr;
}
UniqueChars buf(static_cast<char*>(js_malloc(len + 1)));
UniqueChars buf(js_pod_malloc<char>(len + 1));
if (!buf)
return nullptr;
@ -3562,25 +3562,22 @@ EnsureGeckoProfilingStackInstalled(JSContext* cx, ShellContext* sc)
struct WorkerInput
{
JSRuntime* parentRuntime;
char16_t* chars;
UniqueTwoByteChars chars;
size_t length;
WorkerInput(JSRuntime* parentRuntime, char16_t* chars, size_t length)
: parentRuntime(parentRuntime), chars(chars), length(length)
WorkerInput(JSRuntime* parentRuntime, UniqueTwoByteChars chars, size_t length)
: parentRuntime(parentRuntime), chars(std::move(chars)), length(length)
{}
~WorkerInput() {
js_free(chars);
}
~WorkerInput() = default;
};
static void SetWorkerContextOptions(JSContext* cx);
static bool ShellBuildId(JS::BuildIdCharVector* buildId);
static void
WorkerMain(void* arg)
WorkerMain(WorkerInput* input)
{
WorkerInput* input = (WorkerInput*) arg;
MOZ_ASSERT(input->parentRuntime);
JSContext* cx = JS_NewContext(8L * 1024L * 1024L, 2L * 1024L * 1024L, input->parentRuntime);
@ -3635,7 +3632,7 @@ WorkerMain(void* arg)
AutoReportException are(cx);
RootedScript script(cx);
if (!JS::Compile(cx, options, input->chars, input->length, &script))
if (!JS::Compile(cx, options, input->chars.get(), input->length, &script))
break;
RootedValue result(cx);
JS_ExecuteScript(cx, script, &result);
@ -3694,15 +3691,16 @@ EvalInWorker(JSContext* cx, unsigned argc, Value* vp)
JSLinearString* str = &args[0].toString()->asLinear();
char16_t* chars = (char16_t*) js_malloc(str->length() * sizeof(char16_t));
UniqueTwoByteChars chars(js_pod_malloc<char16_t>(str->length()));
if (!chars) {
ReportOutOfMemory(cx);
return false;
}
CopyChars(chars, *str);
CopyChars(chars.get(), *str);
WorkerInput* input = js_new<WorkerInput>(JS_GetParentRuntime(cx), chars, str->length());
WorkerInput* input = js_new<WorkerInput>(JS_GetParentRuntime(cx), std::move(chars),
str->length());
if (!input) {
ReportOutOfMemory(cx);
return false;
@ -5029,7 +5027,7 @@ EscapeForShell(JSContext* cx, AutoCStringVector& argv)
newLen++;
}
UniqueChars escaped(cx->pod_malloc<char>(newLen));
auto escaped = cx->make_pod_array<char>(newLen);
if (!escaped)
return false;

Просмотреть файл

@ -0,0 +1,60 @@
// ToNumber(value) is executed for OOB writes when using a direct assignment.
function plainSet() {
var callCount = 0;
var value = {
valueOf() {
callCount++;
return 1;
}
};
var N = 100;
var ta = new Int32Array(0);
for (var i = 0; i < N; ++i)
ta[0] = value
assertEq(callCount, N);
}
for (var i = 0; i < 2; ++i) plainSet();
// ToNumber(value) is executed for OOB writes when using Reflect.set(...).
function reflectSet() {
var callCount = 0;
var value = {
valueOf() {
callCount++;
return 1;
}
};
var N = 100;
var ta = new Int32Array(0);
for (var i = 0; i < N; ++i)
assertEq(Reflect.set(ta, 0, value), false);
assertEq(callCount, N);
}
for (var i = 0; i < 2; ++i) reflectSet();
// ToNumber(value) is not executed for OOB writes when using Reflect.defineProperty(...).
function defineProp() {
var callCount = 0;
var value = {
valueOf() {
callCount++;
return 1;
}
};
var desc = {value, writable: true, enumerable: true, configurable: false};
var N = 100;
var ta = new Int32Array(0);
for (var i = 0; i < N; ++i)
assertEq(Reflect.defineProperty(ta, 0, desc), false);
assertEq(callCount, 0);
}
for (var i = 0; i < 2; ++i) defineProp();
if (typeof reportCompare === "function")
reportCompare(true, true);

Просмотреть файл

@ -307,7 +307,7 @@ js_dtobasestr(DtoaState* state, int base, double dinput)
MOZ_ASSERT(base >= 2 && base <= 36);
dval(d) = dinput;
buffer = (char*) js_malloc(DTOBASESTR_BUFFER_SIZE);
buffer = js_pod_malloc<char>(DTOBASESTR_BUFFER_SIZE);
if (!buffer)
return nullptr;
p = buffer;

Просмотреть файл

@ -84,7 +84,7 @@ FinishStringFlat(JSContext* cx, StringBuffer& sb, Buffer& cb)
if (!buf)
return nullptr;
JSFlatString* str = NewStringDontDeflate<CanGC>(cx, buf.get(), len);
JSFlatString* str = NewStringDontDeflate<CanGC>(cx, std::move(buf), len);
if (!str)
return nullptr;
@ -94,7 +94,6 @@ FinishStringFlat(JSContext* cx, StringBuffer& sb, Buffer& cb)
*/
cx->updateMallocCounter(sizeof(CharT) * len);
mozilla::Unused << buf.release();
return str;
}

Просмотреть файл

@ -216,7 +216,7 @@ BigInt::toString(JSContext* cx, BigInt* x, uint8_t radix)
MOZ_ASSERT(2 <= radix && radix <= 36);
// We need two extra chars for '\0' and potentially '-'.
size_t strSize = mpz_sizeinbase(x->num_, 10) + 2;
UniqueChars str(static_cast<char*>(js_malloc(strSize)));
UniqueChars str(js_pod_malloc<char>(strSize));
if (!str) {
ReportOutOfMemory(cx);
return nullptr;

Просмотреть файл

@ -1,4 +1,4 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* vim: set ts=8 sts=4 et sw=4 tw=99:
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
@ -95,7 +95,7 @@ const char * const js::CodeName[] = {
/************************************************************************/
static bool
DecompileArgumentFromStack(JSContext* cx, int formalIndex, char** res);
DecompileArgumentFromStack(JSContext* cx, int formalIndex, UniqueChars* res);
size_t
js::GetVariableBytecodeLength(jsbytecode* pc)
@ -1652,7 +1652,7 @@ struct ExpressionDecompiler
bool quote(JSString* s, uint32_t quote);
bool write(const char* s);
bool write(JSString* str);
bool getOutput(char** out);
UniqueChars getOutput();
#if defined(DEBUG) || defined(JS_JITSPEW)
void setStackDump() {
isStackDump = true;
@ -1725,17 +1725,14 @@ ExpressionDecompiler::decompilePC(jsbytecode* pc, uint8_t defIndex)
#endif /* DEBUG */
)
{
char* result;
UniqueChars result;
if (!DecompileArgumentFromStack(cx, slot, &result))
return false;
// Note that decompiling the argument in the parent frame might
// not succeed.
if (result) {
bool ok = write(result);
js_free(result);
return ok;
}
if (result)
return write(result.get());
}
JSAtom* atom = getArg(slot);
@ -2160,16 +2157,16 @@ ExpressionDecompiler::getArg(unsigned slot)
MOZ_CRASH("No binding");
}
bool
ExpressionDecompiler::getOutput(char** res)
UniqueChars
ExpressionDecompiler::getOutput()
{
ptrdiff_t len = sprinter.stringEnd() - sprinter.stringAt(0);
*res = cx->pod_malloc<char>(len + 1);
if (!*res)
return false;
js_memcpy(*res, sprinter.stringAt(0), len);
(*res)[len] = 0;
return true;
auto res = cx->make_pod_array<char>(len + 1);
if (!res)
return nullptr;
js_memcpy(res.get(), sprinter.stringAt(0), len);
res[len] = 0;
return res;
}
} // anonymous namespace
@ -2187,13 +2184,11 @@ DecompileAtPCForStackDump(JSContext* cx, HandleScript script,
if (!ed.decompilePC(offsetAndDefIndex))
return false;
char* result;
if (!ed.getOutput(&result))
UniqueChars result = ed.getOutput();
if (!result)
return false;
bool ok = sp->put(result);
js_free(result);
return ok;
return sp->put(result.get());
}
#endif /* defined(DEBUG) || defined(JS_JITSPEW) */
@ -2260,7 +2255,8 @@ FindStartPC(JSContext* cx, const FrameIter& iter, int spindex, int skipStackHits
}
static bool
DecompileExpressionFromStack(JSContext* cx, int spindex, int skipStackHits, HandleValue v, char** res)
DecompileExpressionFromStack(JSContext* cx, int spindex, int skipStackHits, HandleValue v,
UniqueChars* res)
{
MOZ_ASSERT(spindex < 0 ||
spindex == JSDVG_IGNORE_STACK ||
@ -2303,7 +2299,8 @@ DecompileExpressionFromStack(JSContext* cx, int spindex, int skipStackHits, Hand
if (!ed.decompilePC(valuepc, defIndex))
return false;
return ed.getOutput(res);
*res = ed.getOutput();
return *res != nullptr;
}
UniqueChars
@ -2312,14 +2309,11 @@ js::DecompileValueGenerator(JSContext* cx, int spindex, HandleValue v,
{
RootedString fallback(cx, fallbackArg);
{
char* result;
UniqueChars result;
if (!DecompileExpressionFromStack(cx, spindex, skipStackHits, v, &result))
return nullptr;
if (result) {
if (strcmp(result, "(intermediate value)"))
return UniqueChars(result);
js_free(result);
}
if (result && strcmp(result.get(), "(intermediate value)"))
return result;
}
if (!fallback) {
if (v.isUndefined())
@ -2333,7 +2327,7 @@ js::DecompileValueGenerator(JSContext* cx, int spindex, HandleValue v,
}
static bool
DecompileArgumentFromStack(JSContext* cx, int formalIndex, char** res)
DecompileArgumentFromStack(JSContext* cx, int formalIndex, UniqueChars* res)
{
MOZ_ASSERT(formalIndex >= 0);
@ -2398,21 +2392,19 @@ DecompileArgumentFromStack(JSContext* cx, int formalIndex, char** res)
if (!ed.decompilePCForStackOperand(current, formalStackIndex))
return false;
return ed.getOutput(res);
*res = ed.getOutput();
return *res != nullptr;
}
UniqueChars
js::DecompileArgument(JSContext* cx, int formalIndex, HandleValue v)
{
{
char* result;
UniqueChars result;
if (!DecompileArgumentFromStack(cx, formalIndex, &result))
return nullptr;
if (result) {
if (strcmp(result, "(intermediate value)"))
return UniqueChars(result);
js_free(result);
}
if (result && strcmp(result.get(), "(intermediate value)"))
return result;
}
if (v.isUndefined())
return DuplicateString(cx, js_undefined_str); // Prevent users from seeing "(void 0)"
@ -2755,11 +2747,10 @@ GetPCCountJSON(JSContext* cx, const ScriptAndCounts& sac, StringBuffer& buf)
// defIndex passed here is not used.
if (!ed.decompilePC(pc, /* defIndex = */ 0))
return false;
char* text;
if (!ed.getOutput(&text))
UniqueChars text = ed.getOutput();
if (!text)
return false;
JSString* str = JS_NewStringCopyZ(cx, text);
js_free(text);
JSString* str = NewLatin1StringZ(cx, std::move(text));
if (!AppendJSONProperty(buf, "text"))
return false;
if (!str || !(str = StringToSource(cx, str)))

Просмотреть файл

@ -17,7 +17,7 @@ RuntimeCaches::createMathCache(JSContext* cx)
{
MOZ_ASSERT(!mathCache_);
UniquePtr<MathCache> newMathCache(js_new<MathCache>());
auto newMathCache = MakeUnique<MathCache>();
if (!newMathCache) {
ReportOutOfMemory(cx);
return nullptr;

Просмотреть файл

@ -131,22 +131,14 @@ CopyStringPure(JSContext* cx, JSString* str)
if (!copiedChars)
return nullptr;
auto* rawCopiedChars = copiedChars.release();
auto* result = NewString<CanGC>(cx, rawCopiedChars, len);
if (!result)
js_free(rawCopiedChars);
return result;
return NewString<CanGC>(cx, std::move(copiedChars), len);
}
UniqueTwoByteChars copiedChars = str->asRope().copyTwoByteCharsZ(cx);
if (!copiedChars)
return nullptr;
auto* rawCopiedChars = copiedChars.release();
auto* result = NewStringDontDeflate<CanGC>(cx, rawCopiedChars, len);
if (!result)
js_free(rawCopiedChars);
return result;
return NewStringDontDeflate<CanGC>(cx, std::move(copiedChars), len);
}
bool

Просмотреть файл

@ -455,11 +455,7 @@ ParseTask::finish(JSContext* cx)
return true;
}
ParseTask::~ParseTask()
{
for (size_t i = 0; i < errors.length(); i++)
js_delete(errors[i]);
}
ParseTask::~ParseTask() = default;
void
ParseTask::trace(JSTracer* trc)
@ -2059,11 +2055,12 @@ JSContext::addPendingCompileError(js::CompileError** error)
auto errorPtr = make_unique<js::CompileError>();
if (!errorPtr)
return false;
if (!helperThread()->parseTask()->errors.append(errorPtr.get())) {
ParseTask* parseTask = helperThread()->parseTask();
if (!parseTask->errors.append(std::move(errorPtr))) {
ReportOutOfMemory(this);
return false;
}
*error = errorPtr.release();
*error = parseTask->errors.back().get();
return true;
}

Просмотреть файл

@ -692,7 +692,7 @@ struct ParseTask : public mozilla::LinkedListElement<ParseTask>, public JS::OffT
// Any errors or warnings produced during compilation. These are reported
// when finishing the script.
Vector<CompileError*, 0, SystemAllocPolicy> errors;
Vector<UniquePtr<CompileError>, 0, SystemAllocPolicy> errors;
bool overRecursed;
bool outOfMemory;

Просмотреть файл

@ -745,6 +745,7 @@ js::XDRAtom(XDRState<mode>* xdr, MutableHandleAtom atomp)
*/
char16_t* chars;
char16_t stackChars[256];
UniqueTwoByteChars heapChars;
if (length <= ArrayLength(stackChars)) {
chars = stackChars;
} else {
@ -753,15 +754,15 @@ js::XDRAtom(XDRState<mode>* xdr, MutableHandleAtom atomp)
* most allocations here will be bigger than tempLifoAlloc's default
* chunk size.
*/
chars = cx->pod_malloc<char16_t>(length);
if (!chars)
heapChars.reset(cx->pod_malloc<char16_t>(length));
if (!heapChars)
return xdr->fail(JS::TranscodeResult_Throw);
chars = heapChars.get();
}
MOZ_TRY(xdr->codeChars(chars, length));
atom = AtomizeChars(cx, chars, length);
if (chars != stackChars)
js_free(chars);
#endif /* !MOZ_LITTLE_ENDIAN */
}

Просмотреть файл

@ -2137,7 +2137,7 @@ ScriptSource::performXDR(XDRState<mode>* xdr)
size_t byteLen = compressedLength ? compressedLength : (len * sizeof(char16_t));
if (mode == XDR_DECODE) {
UniqueChars bytes(xdr->cx()->template pod_malloc<char>(Max<size_t>(byteLen, 1)));
auto bytes = xdr->cx()->template make_pod_array<char>(Max<size_t>(byteLen, 1));
if (!bytes)
return xdr->fail(JS::TranscodeResult_Throw);
MOZ_TRY(xdr->codeBytes(bytes.get(), byteLen));

Просмотреть файл

@ -1938,13 +1938,31 @@ DefineNonexistentProperty(JSContext* cx, HandleNativeObject obj, HandleId id,
return result.fail(JSMSG_CANT_DEFINE_PAST_ARRAY_LENGTH);
}
} else if (obj->is<TypedArrayObject>()) {
// 9.4.5.3 step 3. Indexed properties of typed arrays are special.
// 9.4.5.5 step 2. Indexed properties of typed arrays are special.
uint64_t index;
if (IsTypedArrayIndex(id, &index)) {
// ES2019 draft rev e7dc63fb5d1c26beada9ffc12dc78aa6548f1fb5
// 9.4.5.9 IntegerIndexedElementSet
// This method is only called for non-existent properties, which
// means any absent indexed property must be out of range.
MOZ_ASSERT(index >= obj->as<TypedArrayObject>().length());
// Steps 1-2 are enforced by the caller.
// Step 3.
// We still need to call ToNumber, because of its possible side
// effects.
double d;
if (!ToNumber(cx, v, &d))
return false;
// Steps 4-5.
// ToNumber may have detached the array buffer.
if (obj->as<TypedArrayObject>().hasDetachedBuffer())
return result.failSoft(JSMSG_TYPED_ARRAY_DETACHED);
// Steps 6-9.
// We (wrongly) ignore out of range defines.
return result.failSoft(JSMSG_BAD_INDEX);
}
@ -2645,10 +2663,19 @@ SetDenseOrTypedArrayElement(JSContext* cx, HandleNativeObject obj, uint32_t inde
ObjectOpResult& result)
{
if (obj->is<TypedArrayObject>()) {
// ES2019 draft rev e7dc63fb5d1c26beada9ffc12dc78aa6548f1fb5
// 9.4.5.9 IntegerIndexedElementSet
// Steps 1-2 are enforced by the caller.
// Step 3.
double d;
if (!ToNumber(cx, v, &d))
return false;
// Steps 6-7 don't apply for existing typed array elements.
// Steps 8-16.
// Silently do nothing for out-of-bounds sets, for consistency with
// current behavior. (ES6 currently says to throw for this in
// strict mode code, so we may eventually need to change.)
@ -2658,6 +2685,7 @@ SetDenseOrTypedArrayElement(JSContext* cx, HandleNativeObject obj, uint32_t inde
return result.succeed();
}
// Steps 4-5.
// A previously existing typed array element can only be out-of-bounds
// if the above ToNumber call detached the typed array's buffer.
MOZ_ASSERT(obj->as<TypedArrayObject>().hasDetachedBuffer());

Просмотреть файл

@ -1252,14 +1252,13 @@ ObjectGroup::newPlainObject(JSContext* cx, IdValuePair* properties, size_t nprop
group->setPreliminaryObjects(preliminaryObjects);
preliminaryObjects->registerNewObject(obj);
UniquePtr<jsid[], JS::FreePolicy> ids(group->zone()->pod_calloc<jsid>(nproperties));
auto ids = group->zone()->make_zeroed_pod_array<jsid>(nproperties);
if (!ids) {
ReportOutOfMemory(cx);
return nullptr;
}
UniquePtr<TypeSet::Type[], JS::FreePolicy> types(
group->zone()->pod_calloc<TypeSet::Type>(nproperties));
auto types = group->zone()->make_zeroed_pod_array<TypeSet::Type>(nproperties);
if (!types) {
ReportOutOfMemory(cx);
return nullptr;

Просмотреть файл

@ -16,6 +16,7 @@
#include "jsutil.h"
#include "ds/LifoAlloc.h"
#include "util/Text.h"
#include "util/Windows.h"
#include "vm/JSContext.h"
@ -124,7 +125,7 @@ bool
Sprinter::init()
{
MOZ_ASSERT(!initialized);
base = (char*) js_malloc(DefaultSize);
base = js_pod_malloc<char>(DefaultSize);
if (!base) {
reportOutOfMemory();
return false;
@ -447,13 +448,11 @@ Fprinter::put(const char* s, size_t len)
}
#ifdef XP_WIN32
if ((file_ == stderr) && (IsDebuggerPresent())) {
UniqueChars buf(static_cast<char*>(js_malloc(len + 1)));
UniqueChars buf = DuplicateString(s, len);
if (!buf) {
reportOutOfMemory();
return false;
}
PodCopy(buf.get(), s, len);
buf[len] = '\0';
OutputDebugStringA(buf.get());
}
#endif

Просмотреть файл

@ -322,7 +322,7 @@ JSRuntime::destroyRuntime()
js_delete(defaultFreeOp_.ref());
js_free(defaultLocale);
defaultLocale = nullptr;
js_delete(jitRuntime_.ref());
#ifdef DEBUG
@ -532,27 +532,25 @@ JSRuntime::setDefaultLocale(const char* locale)
if (!locale)
return false;
char* newLocale = DuplicateString(mainContextFromOwnThread(), locale).release();
UniqueChars newLocale = DuplicateString(mainContextFromOwnThread(), locale);
if (!newLocale)
return false;
resetDefaultLocale();
defaultLocale = newLocale;
defaultLocale.ref() = std::move(newLocale);
return true;
}
void
JSRuntime::resetDefaultLocale()
{
js_free(defaultLocale);
defaultLocale = nullptr;
}
const char*
JSRuntime::getDefaultLocale()
{
if (defaultLocale)
return defaultLocale;
if (defaultLocale.ref())
return defaultLocale.ref().get();
const char* locale = setlocale(LC_ALL, nullptr);
@ -560,18 +558,18 @@ JSRuntime::getDefaultLocale()
if (!locale || !strcmp(locale, "C"))
locale = "und";
char* lang = DuplicateString(mainContextFromOwnThread(), locale).release();
UniqueChars lang = DuplicateString(mainContextFromOwnThread(), locale);
if (!lang)
return nullptr;
char* p;
if ((p = strchr(lang, '.')))
if ((p = strchr(lang.get(), '.')))
*p = '\0';
while ((p = strchr(lang, '_')))
while ((p = strchr(lang.get(), '_')))
*p = '-';
defaultLocale = lang;
return defaultLocale;
defaultLocale.ref() = std::move(lang);
return defaultLocale.ref().get();
}
void

Просмотреть файл

@ -36,6 +36,7 @@
# include "js/Proxy.h" // For AutoEnterPolicy
#endif
#include "js/UniquePtr.h"
#include "js/Utility.h"
#include "js/Vector.h"
#include "threading/Thread.h"
#include "vm/Caches.h"
@ -528,7 +529,7 @@ struct JSRuntime : public js::MallocProvider<JSRuntime>
js::MainThreadData<const JSLocaleCallbacks*> localeCallbacks;
/* Default locale for Internationalization API */
js::MainThreadData<char*> defaultLocale;
js::MainThreadData<js::UniqueChars> defaultLocale;
/* If true, new scripts must be created with PC counter information. */
js::MainThreadOrIonCompileData<bool> profilingScripts;

Просмотреть файл

@ -2955,7 +2955,7 @@ JSRuntime::initSelfHosting(JSContext* cx)
const unsigned char* compressed = compressedSources;
uint32_t compressedLen = GetCompressedSize();
UniqueChars src(selfHostingGlobal_->zone()->pod_malloc<char>(srcLen));
auto src = selfHostingGlobal_->zone()->make_pod_array<char>(srcLen);
if (!src || !DecompressString(compressed, compressedLen,
reinterpret_cast<unsigned char*>(src.get()), srcLen))
{

Просмотреть файл

@ -16,6 +16,7 @@
#include "gc/Policy.h"
#include "gc/PublicIterators.h"
#include "js/HashTable.h"
#include "js/UniquePtr.h"
#include "util/Text.h"
#include "vm/JSAtom.h"
#include "vm/JSContext.h"
@ -1628,15 +1629,13 @@ ShapeHasher::match(const Key k, const Lookup& l)
static KidsHash*
HashChildren(Shape* kid1, Shape* kid2)
{
KidsHash* hash = js_new<KidsHash>();
if (!hash || !hash->init(2)) {
js_delete(hash);
auto hash = MakeUnique<KidsHash>();
if (!hash || !hash->init(2))
return nullptr;
}
hash->putNewInfallible(StackShape(kid1), kid1);
hash->putNewInfallible(StackShape(kid2), kid2);
return hash;
return hash.release();
}
bool

Просмотреть файл

@ -16,6 +16,7 @@
#include "builtin/String.h"
#include "js/HashTable.h"
#include "js/UniquePtr.h"
#include "js/Utility.h"
#include "threading/ExclusiveData.h"
@ -239,7 +240,7 @@ class SharedImmutableStringsCache
public:
mutable size_t refcount;
using Ptr = mozilla::UniquePtr<StringBox, JS::DeletePolicy<StringBox>>;
using Ptr = js::UniquePtr<StringBox>;
StringBox(OwnedChars&& chars, size_t length)
: chars_(std::move(chars))
@ -250,7 +251,7 @@ class SharedImmutableStringsCache
}
static Ptr Create(OwnedChars&& chars, size_t length) {
return Ptr(js_new<StringBox>(std::move(chars), length));
return js::MakeUnique<StringBox>(std::move(chars), length);
}
StringBox(const StringBox&) = delete;

Просмотреть файл

@ -41,6 +41,8 @@ using mozilla::Unused;
using JS::AutoCheckCannotGC;
using UniqueLatin1Chars = UniquePtr<Latin1Char[], JS::FreePolicy>;
size_t
JSString::sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf)
{
@ -279,7 +281,7 @@ AllocChars(JSString* str, size_t length, CharT** chars, size_t* capacity)
return *chars != nullptr;
}
UniquePtr<Latin1Char[], JS::FreePolicy>
UniqueLatin1Chars
JSRope::copyLatin1CharsZ(JSContext* maybecx) const
{
return copyCharsInternal<Latin1Char>(maybecx, true);
@ -291,7 +293,7 @@ JSRope::copyTwoByteCharsZ(JSContext* maybecx) const
return copyCharsInternal<char16_t>(maybecx, true);
}
UniquePtr<Latin1Char[], JS::FreePolicy>
UniqueLatin1Chars
JSRope::copyLatin1Chars(JSContext* maybecx) const
{
return copyCharsInternal<Latin1Char>(maybecx, false);
@ -782,22 +784,21 @@ JSFlatString*
JSDependentString::undependInternal(JSContext* cx)
{
size_t n = length();
CharT* s = cx->pod_malloc<CharT>(n + 1);
auto s = cx->make_pod_array<CharT>(n + 1);
if (!s)
return nullptr;
if (!isTenured()) {
if (!cx->runtime()->gc.nursery().registerMallocedBuffer(s)) {
js_free(s);
if (!cx->runtime()->gc.nursery().registerMallocedBuffer(s.get())) {
ReportOutOfMemory(cx);
return nullptr;
}
}
AutoCheckCannotGC nogc;
PodCopy(s, nonInlineChars<CharT>(nogc), n);
PodCopy(s.get(), nonInlineChars<CharT>(nogc), n);
s[n] = '\0';
setNonInlineChars<CharT>(s);
setNonInlineChars<CharT>(s.release());
/*
* Transform *this into an undepended string so 'base' will remain rooted
@ -1358,13 +1359,12 @@ JSExternalString::ensureFlat(JSContext* cx)
MOZ_ASSERT(hasTwoByteChars());
size_t n = length();
char16_t* s = cx->pod_malloc<char16_t>(n + 1);
auto s = cx->make_pod_array<char16_t>(n + 1);
if (!s)
return nullptr;
if (!isTenured()) {
if (!cx->runtime()->gc.nursery().registerMallocedBuffer(s)) {
js_free(s);
if (!cx->runtime()->gc.nursery().registerMallocedBuffer(s.get())) {
ReportOutOfMemory(cx);
return nullptr;
}
@ -1373,7 +1373,7 @@ JSExternalString::ensureFlat(JSContext* cx)
// Copy the chars before finalizing the string.
{
AutoCheckCannotGC nogc;
PodCopy(s, nonInlineChars<char16_t>(nogc), n);
PodCopy(s.get(), nonInlineChars<char16_t>(nogc), n);
s[n] = '\0';
}
@ -1383,7 +1383,7 @@ JSExternalString::ensureFlat(JSContext* cx)
// Transform the string into a non-external, flat string. Note that the
// resulting string will still be in an AllocKind::EXTERNAL_STRING arena,
// but will no longer be an external string.
setNonInlineChars<char16_t>(s);
setNonInlineChars<char16_t>(s.release());
d.u1.flags = INIT_FLAT_FLAGS;
return &this->asFlat();
@ -1506,7 +1506,7 @@ NewStringDeflated(JSContext* cx, const char16_t* s, size_t n)
if (JSInlineString::lengthFits<Latin1Char>(n))
return NewInlineStringDeflated<allowGC>(cx, mozilla::Range<const char16_t>(s, n));
UniquePtr<Latin1Char[], JS::FreePolicy> news(cx->pod_malloc<Latin1Char>(n + 1));
auto news = cx->make_pod_array<Latin1Char>(n + 1);
if (!news)
return nullptr;
@ -1531,7 +1531,7 @@ NewStringDeflated(JSContext* cx, const Latin1Char* s, size_t n)
MOZ_CRASH("Shouldn't be called for Latin1 chars");
}
template <AllowGC allowGC, typename CharT>
template <typename CharT>
JSFlatString*
js::NewStringDontDeflate(JSContext* cx, CharT* chars, size_t length)
{
@ -1544,7 +1544,7 @@ js::NewStringDontDeflate(JSContext* cx, CharT* chars, size_t length)
if (JSInlineString::lengthFits<CharT>(length)) {
JSInlineString* str =
NewInlineString<allowGC>(cx, mozilla::Range<const CharT>(chars, length));
NewInlineString<CanGC>(cx, mozilla::Range<const CharT>(chars, length));
if (!str)
return nullptr;
@ -1552,27 +1552,21 @@ js::NewStringDontDeflate(JSContext* cx, CharT* chars, size_t length)
return str;
}
return JSFlatString::new_<allowGC>(cx, chars, length);
return JSFlatString::new_<CanGC>(cx, chars, length);
}
template JSFlatString*
js::NewStringDontDeflate<CanGC>(JSContext* cx, char16_t* chars, size_t length);
js::NewStringDontDeflate(JSContext* cx, char16_t* chars, size_t length);
template JSFlatString*
js::NewStringDontDeflate<NoGC>(JSContext* cx, char16_t* chars, size_t length);
js::NewStringDontDeflate(JSContext* cx, Latin1Char* chars, size_t length);
template JSFlatString*
js::NewStringDontDeflate<CanGC>(JSContext* cx, Latin1Char* chars, size_t length);
template JSFlatString*
js::NewStringDontDeflate<NoGC>(JSContext* cx, Latin1Char* chars, size_t length);
template <AllowGC allowGC, typename CharT>
template <typename CharT>
JSFlatString*
js::NewString(JSContext* cx, CharT* chars, size_t length)
{
if (IsSame<CharT, char16_t>::value && CanStoreCharsAsLatin1(chars, length)) {
JSFlatString* s = NewStringDeflated<allowGC>(cx, chars, length);
JSFlatString* s = NewStringDeflated<CanGC>(cx, chars, length);
if (!s)
return nullptr;
@ -1581,20 +1575,66 @@ js::NewString(JSContext* cx, CharT* chars, size_t length)
return s;
}
return NewStringDontDeflate<allowGC>(cx, chars, length);
return NewStringDontDeflate(cx, chars, length);
}
template JSFlatString*
js::NewString<CanGC>(JSContext* cx, char16_t* chars, size_t length);
js::NewString(JSContext* cx, char16_t* chars, size_t length);
template JSFlatString*
js::NewString<NoGC>(JSContext* cx, char16_t* chars, size_t length);
js::NewString(JSContext* cx, Latin1Char* chars, size_t length);
template <AllowGC allowGC, typename CharT>
JSFlatString*
js::NewStringDontDeflate(JSContext* cx, UniquePtr<CharT[], JS::FreePolicy> chars, size_t length)
{
if (JSFlatString* str = TryEmptyOrStaticString(cx, chars.get(), length))
return str;
if (JSInlineString::lengthFits<CharT>(length))
return NewInlineString<allowGC>(cx, mozilla::Range<const CharT>(chars.get(), length));
JSFlatString* str = JSFlatString::new_<allowGC>(cx, chars.get(), length);
if (!str)
return nullptr;
mozilla::Unused << chars.release();
return str;
}
template JSFlatString*
js::NewString<CanGC>(JSContext* cx, Latin1Char* chars, size_t length);
js::NewStringDontDeflate<CanGC>(JSContext* cx, UniqueTwoByteChars chars, size_t length);
template JSFlatString*
js::NewString<NoGC>(JSContext* cx, Latin1Char* chars, size_t length);
js::NewStringDontDeflate<NoGC>(JSContext* cx, UniqueTwoByteChars chars, size_t length);
template JSFlatString*
js::NewStringDontDeflate<CanGC>(JSContext* cx, UniqueLatin1Chars chars, size_t length);
template JSFlatString*
js::NewStringDontDeflate<NoGC>(JSContext* cx, UniqueLatin1Chars chars, size_t length);
template <AllowGC allowGC, typename CharT>
JSFlatString*
js::NewString(JSContext* cx, UniquePtr<CharT[], JS::FreePolicy> chars, size_t length)
{
if (IsSame<CharT, char16_t>::value && CanStoreCharsAsLatin1(chars.get(), length))
return NewStringDeflated<allowGC>(cx, chars.get(), length);
return NewStringDontDeflate<allowGC>(cx, std::move(chars), length);
}
template JSFlatString*
js::NewString<CanGC>(JSContext* cx, UniqueTwoByteChars chars, size_t length);
template JSFlatString*
js::NewString<NoGC>(JSContext* cx, UniqueTwoByteChars chars, size_t length);
template JSFlatString*
js::NewString<CanGC>(JSContext* cx, UniqueLatin1Chars chars, size_t length);
template JSFlatString*
js::NewString<NoGC>(JSContext* cx, UniqueLatin1Chars chars, size_t length);
namespace js {
@ -1608,7 +1648,7 @@ NewStringCopyNDontDeflate(JSContext* cx, const CharT* s, size_t n)
if (JSInlineString::lengthFits<CharT>(n))
return NewInlineString<allowGC>(cx, mozilla::Range<const CharT>(s, n));
UniquePtr<CharT[], JS::FreePolicy> news(cx->pod_malloc<CharT>(n + 1));
auto news = cx->make_pod_array<CharT>(n + 1);
if (!news) {
if (!allowGC)
cx->recoverFromOutOfMemory();
@ -1641,12 +1681,9 @@ NewStringCopyNDontDeflate<NoGC>(JSContext* cx, const Latin1Char* s, size_t n);
JSFlatString*
NewLatin1StringZ(JSContext* cx, UniqueChars chars)
{
JSFlatString* str = NewString<CanGC>(cx, (Latin1Char*)chars.get(), strlen(chars.get()));
if (!str)
return nullptr;
mozilla::Unused << chars.release();
return str;
size_t length = strlen(chars.get());
UniqueLatin1Chars latin1(reinterpret_cast<Latin1Char*>(chars.release()));
return NewString<CanGC>(cx, std::move(latin1), length);
}
template <AllowGC allowGC, typename CharT>
@ -1681,26 +1718,20 @@ NewStringCopyUTF8N(JSContext* cx, const JS::UTF8Chars utf8)
size_t length;
if (encoding == JS::SmallestEncoding::Latin1) {
Latin1Char* latin1 = UTF8CharsToNewLatin1CharsZ(cx, utf8, &length).get();
UniqueLatin1Chars latin1(UTF8CharsToNewLatin1CharsZ(cx, utf8, &length).get());
if (!latin1)
return nullptr;
JSFlatString* result = NewString<allowGC>(cx, latin1, length);
if (!result)
js_free((void*)latin1);
return result;
return NewString<allowGC>(cx, std::move(latin1), length);
}
MOZ_ASSERT(encoding == JS::SmallestEncoding::UTF16);
char16_t* utf16 = UTF8CharsToNewTwoByteCharsZ(cx, utf8, &length).get();
UniqueTwoByteChars utf16(UTF8CharsToNewTwoByteCharsZ(cx, utf8, &length).get());
if (!utf16)
return nullptr;
JSFlatString* result = NewString<allowGC>(cx, utf16, length);
if (!result)
js_free((void*)utf16);
return result;
return NewString<allowGC>(cx, std::move(utf16), length);
}
template JSFlatString*

Просмотреть файл

@ -1444,15 +1444,25 @@ StringToNewUTF8CharsZ(JSContext* maybecx, JSString& str)
}
/* GC-allocate a string descriptor for the given malloc-allocated chars. */
template <js::AllowGC allowGC, typename CharT>
template <typename CharT>
extern JSFlatString*
NewString(JSContext* cx, CharT* chars, size_t length);
/* Like NewString, but doesn't try to deflate to Latin1. */
template <js::AllowGC allowGC, typename CharT>
template <typename CharT>
extern JSFlatString*
NewStringDontDeflate(JSContext* cx, CharT* chars, size_t length);
/* GC-allocate a string descriptor for the given malloc-allocated chars. */
template <js::AllowGC allowGC, typename CharT>
extern JSFlatString*
NewString(JSContext* cx, UniquePtr<CharT[], JS::FreePolicy> chars, size_t length);
/* Like NewString, but doesn't try to deflate to Latin1. */
template <js::AllowGC allowGC, typename CharT>
extern JSFlatString*
NewStringDontDeflate(JSContext* cx, UniquePtr<CharT[], JS::FreePolicy> chars, size_t length);
extern JSLinearString*
NewDependentString(JSContext* cx, JSString* base, size_t start, size_t length);

Просмотреть файл

@ -32,6 +32,7 @@
#include "mozilla/EndianUtils.h"
#include "mozilla/FloatingPoint.h"
#include "mozilla/RangedPtr.h"
#include "mozilla/Unused.h"
#include <algorithm>
#include <utility>
@ -1187,7 +1188,7 @@ JSStructuredCloneWriter::writeBigInt(uint32_t tag, BigInt* bi)
return false;
uint32_t lengthAndSign = length | (static_cast<uint32_t>(signBit) << 31);
js::UniquePtr<uint8_t> buf(static_cast<uint8_t*>(js_malloc(length)));
js::UniquePtr<uint8_t> buf(js_pod_malloc<uint8_t>(length));
if (!buf)
return false;
@ -1905,31 +1906,16 @@ JSStructuredCloneReader::checkDouble(double d)
return true;
}
namespace {
template <typename CharT>
class Chars {
JSContext* cx;
CharT* p;
public:
explicit Chars(JSContext* cx) : cx(cx), p(nullptr) {}
~Chars() { js_free(p); }
bool allocate(size_t len) {
MOZ_ASSERT(!p);
// We're going to null-terminate!
p = cx->pod_malloc<CharT>(len + 1);
if (p) {
p[len] = CharT(0);
return true;
}
return false;
}
CharT* get() { return p; }
void forget() { p = nullptr; }
};
} // anonymous namespace
static UniquePtr<CharT[], JS::FreePolicy>
AllocateChars(JSContext* cx, size_t len)
{
// We're going to null-terminate!
auto p = cx->make_pod_array<CharT>(len + 1);
if (p)
p[len] = CharT(0);
return p;
}
template <typename CharT>
JSString*
@ -1940,13 +1926,10 @@ JSStructuredCloneReader::readStringImpl(uint32_t nchars)
"string length");
return nullptr;
}
Chars<CharT> chars(context());
if (!chars.allocate(nchars) || !in.readChars(chars.get(), nchars))
UniquePtr<CharT[], JS::FreePolicy> chars = AllocateChars<CharT>(context(), nchars);
if (!chars || !in.readChars(chars.get(), nchars))
return nullptr;
JSString* str = NewString<CanGC>(context(), chars.get(), nchars);
if (str)
chars.forget();
return str;
return NewString<CanGC>(context(), std::move(chars), nchars);
}
JSString*
@ -1967,7 +1950,7 @@ JSStructuredCloneReader::readBigInt(uint32_t data)
if (nbytes == 0)
return BigInt::create(context());
UniquePtr<uint8_t> buf(static_cast<uint8_t*>(js_malloc(nbytes)));
UniquePtr<uint8_t> buf(js_pod_malloc<uint8_t>(nbytes));
if (!buf)
return nullptr;
if (!in.readBytes(buf.get(), nbytes))

Просмотреть файл

@ -54,8 +54,6 @@ TraceLoggerGraphState* traceLoggerGraphState = nullptr;
static js::UniqueChars
MOZ_FORMAT_PRINTF(1, 2)
AllocTraceLogFilename(const char* pattern, ...) {
js::UniqueChars filename;
va_list ap;
static const char* outdir = getenv("TLDIR") ? getenv("TLDIR") : DEFAULT_TRACE_LOG_DIR;
@ -77,7 +75,7 @@ AllocTraceLogFilename(const char* pattern, ...) {
len++; // For the terminating NUL.
filename.reset((char*) js_malloc(len));
js::UniqueChars filename(js_pod_malloc<char>(len));
if (!filename)
return nullptr;
char* rest = filename.get() + sprintf(filename.get(), "%s/", outdir);

Просмотреть файл

@ -170,7 +170,7 @@ class ContinuousSpace {
bool init() {
capacity_ = 64;
size_ = 0;
data_ = (T*) js_malloc(capacity_ * sizeof(T));
data_ = js_pod_malloc<T>(capacity_);
if (!data_)
return false;
@ -230,7 +230,7 @@ class ContinuousSpace {
uint32_t nCapacity = capacity_ * 2;
nCapacity = (nCapacity < maxSize()) ? nCapacity : maxSize();
T* entries = (T*) js_realloc(data_, nCapacity * sizeof(T));
T* entries = js_pod_realloc<T>(data_, capacity_, nCapacity);
if (!entries)
return false;

Просмотреть файл

@ -351,7 +351,7 @@ IsTypedArrayIndex(jsid id, uint64_t* indexp)
if (JSID_IS_INT(id)) {
int32_t i = JSID_TO_INT(id);
MOZ_ASSERT(i >= 0);
*indexp = (double)i;
*indexp = static_cast<uint64_t>(i);
return true;
}

Просмотреть файл

@ -333,14 +333,14 @@ template JS::Zone* TracerConcrete<JSString>::zone() const;
template<typename Referent>
UniquePtr<EdgeRange>
TracerConcrete<Referent>::edges(JSContext* cx, bool wantNames) const {
UniquePtr<SimpleEdgeRange, JS::DeletePolicy<SimpleEdgeRange>> range(js_new<SimpleEdgeRange>());
auto range = js::MakeUnique<SimpleEdgeRange>();
if (!range)
return nullptr;
if (!range->init(cx->runtime(), ptr, JS::MapTypeToTraceKind<Referent>::kind, wantNames))
return nullptr;
return UniquePtr<EdgeRange>(range.release());
return range;
}
template UniquePtr<EdgeRange> TracerConcrete<JSScript>::edges(JSContext* cx, bool wantNames) const;
@ -556,7 +556,7 @@ const char16_t Concrete<RootList>::concreteTypeName[] = u"JS::ubi::RootList";
UniquePtr<EdgeRange>
Concrete<RootList>::edges(JSContext* cx, bool wantNames) const {
MOZ_ASSERT_IF(wantNames, get().wantNames);
return UniquePtr<EdgeRange>(js_new<PreComputedEdgeRange>(get().edges));
return js::MakeUnique<PreComputedEdgeRange>(get().edges);
}
} // namespace ubi

Просмотреть файл

@ -438,7 +438,7 @@ ByObjectClass::makeCount()
if (!otherCount)
return nullptr;
UniquePtr<Count> count(js_new<Count>(*this, otherCount));
auto count = js::MakeUnique<Count>(*this, otherCount);
if (!count || !count->init())
return nullptr;
@ -532,7 +532,7 @@ class ByUbinodeType : public CountType {
CountBasePtr
ByUbinodeType::makeCount()
{
UniquePtr<Count> count(js_new<Count>(*this));
auto count = js::MakeUnique<Count>(*this);
if (!count || !count->init())
return nullptr;
@ -679,7 +679,7 @@ ByAllocationStack::makeCount()
if (!noStackCount)
return nullptr;
UniquePtr<Count> count(js_new<Count>(*this, noStackCount));
auto count = js::MakeUnique<Count>(*this, noStackCount);
if (!count || !count->init())
return nullptr;
return CountBasePtr(count.release());
@ -855,7 +855,7 @@ ByFilename::makeCount()
if (!noFilenameCount)
return nullptr;
UniquePtr<Count> count(js_new<Count>(*this, std::move(thenCount), std::move(noFilenameCount)));
auto count = js::MakeUnique<Count>(*this, std::move(thenCount), std::move(noFilenameCount));
if (!count || !count->init())
return nullptr;

Просмотреть файл

@ -18,7 +18,7 @@ namespace ubi {
JS_PUBLIC_API(BackEdge::Ptr)
BackEdge::clone() const
{
BackEdge::Ptr clone(js_new<BackEdge>());
auto clone = js::MakeUnique<BackEdge>();
if (!clone)
return nullptr;

Просмотреть файл

@ -211,7 +211,7 @@ Module::startTier2(const CompileArgs& args)
// ~Tier2GeneratorTaskImpl() to call notifyCompilationListeners() if it
// hasn't been already.
UniqueTier2GeneratorTask task(js_new<Tier2GeneratorTaskImpl>(*this, args));
auto task = MakeUnique<Tier2GeneratorTaskImpl>(*this, args);
if (!task)
return;

Просмотреть файл

@ -320,6 +320,9 @@ NS_NewScrollbarFrame (nsIPresShell* aPresShell, ComputedStyle* aStyle);
nsIFrame*
NS_NewScrollbarButtonFrame (nsIPresShell* aPresShell, ComputedStyle* aStyle);
nsIFrame*
NS_NewImageFrameForContentProperty(nsIPresShell*, ComputedStyle*);
#ifdef NOISY_FINDFRAME
static int32_t FFWC_totalCount=0;
@ -5625,6 +5628,17 @@ ShouldSuppressFrameInNonOpenDetails(const HTMLDetailsElement* aDetails,
return true;
}
static bool
ShouldCreateImageFrameForContent(ComputedStyle& aStyle)
{
auto& content = *aStyle.StyleContent();
if (content.ContentCount() != 1) {
return false;
}
return content.ContentAt(0).GetType() == eStyleContentType_Image;
}
void
nsCSSFrameConstructor::AddFrameConstructionItemsInternal(nsFrameConstructorState& aState,
nsIContent* aContent,
@ -5789,6 +5803,14 @@ nsCSSFrameConstructor::AddFrameConstructionItemsInternal(nsFrameConstructorState
computedStyle);
}
// Check for 'content: <image-url>' on the element (which makes us ignore
// 'display' values other than 'none' or 'contents').
if (!data && ShouldCreateImageFrameForContent(*computedStyle)) {
static const FrameConstructionData sImgData =
SIMPLE_FCDATA(NS_NewImageFrameForContentProperty);
data = &sImgData;
}
// Now check for XUL display types
if (!data) {
data = FindXULDisplayData(display, element, computedStyle);
@ -8598,7 +8620,8 @@ nsCSSFrameConstructor::CreateContinuingFrame(nsPresContext* aPresContext,
newFrame = NS_NewFirstLetterFrame(shell, computedStyle);
newFrame->Init(content, aParentFrame, aFrame);
} else if (LayoutFrameType::Image == frameType) {
newFrame = NS_NewImageFrame(shell, computedStyle);
auto* imageFrame = static_cast<nsImageFrame*>(aFrame);
newFrame = imageFrame->CreateContinuingFrame(shell, computedStyle);
newFrame->Init(content, aParentFrame, aFrame);
} else if (LayoutFrameType::ImageControl == frameType) {
newFrame = NS_NewImageControlFrame(shell, computedStyle);

Просмотреть файл

@ -148,11 +148,7 @@ public:
{
}
virtual ~RefreshDriverTimer()
{
MOZ_ASSERT(mContentRefreshDrivers.Length() == 0, "Should have removed all content refresh drivers from here by now!");
MOZ_ASSERT(mRootRefreshDrivers.Length() == 0, "Should have removed all root refresh drivers from here by now!");
}
NS_INLINE_DECL_REFCOUNTING(RefreshDriverTimer)
virtual void AddRefreshDriver(nsRefreshDriver* aDriver)
{
@ -259,6 +255,12 @@ public:
}
protected:
virtual ~RefreshDriverTimer()
{
MOZ_ASSERT(mContentRefreshDrivers.Length() == 0, "Should have removed all content refresh drivers from here by now!");
MOZ_ASSERT(mRootRefreshDrivers.Length() == 0, "Should have removed all root refresh drivers from here by now!");
}
virtual void StartTimer() = 0;
virtual void StopTimer() = 0;
virtual void ScheduleNextTick(TimeStamp aNowTime) = 0;
@ -336,10 +338,11 @@ protected:
nsTArray<RefPtr<nsRefreshDriver>> mRootRefreshDrivers;
// useful callback for nsITimer-based derived classes, here
// bacause of c++ protected shenanigans
// because of c++ protected shenanigans
static void TimerTick(nsITimer* aTimer, void* aClosure)
{
RefreshDriverTimer *timer = static_cast<RefreshDriverTimer*>(aClosure);
RefPtr<RefreshDriverTimer> timer =
static_cast<RefreshDriverTimer*>(aClosure);
timer->Tick();
}
};
@ -471,9 +474,7 @@ public:
private:
// Since VsyncObservers are refCounted, but the RefreshDriverTimer are
// explicitly shutdown. We create an inner class that has the VsyncObserver
// and is shutdown when the RefreshDriverTimer is deleted. The alternative is
// to (a) make all RefreshDriverTimer RefCounted or (b) use different
// VsyncObserver types.
// and is shutdown when the RefreshDriverTimer is deleted.
class RefreshDriverVsyncObserver final : public VsyncObserver
{
public:
@ -537,6 +538,9 @@ private:
bool NotifyVsync(TimeStamp aVsyncTimestamp) override
{
// IMPORTANT: All paths through this method MUST hold a strong ref on
// |this| for the duration of the TickRefreshDriver callback.
if (!NS_IsMainThread()) {
MOZ_ASSERT(XRE_IsParentProcess());
// Compress vsync notifications such that only 1 may run at a time
@ -571,6 +575,7 @@ private:
return true;
}
RefPtr<RefreshDriverVsyncObserver> kungFuDeathGrip(this);
TickRefreshDriver(aVsyncTimestamp);
}
@ -670,7 +675,9 @@ private:
// the scheduled TickRefreshDriver() runs. Check mVsyncRefreshDriverTimer
// before use.
if (mVsyncRefreshDriverTimer) {
mVsyncRefreshDriverTimer->RunRefreshDrivers(aVsyncTimestamp);
RefPtr<VsyncRefreshDriverTimer> timer = mVsyncRefreshDriverTimer;
timer->RunRefreshDrivers(aVsyncTimestamp);
// Note: mVsyncRefreshDriverTimer might be null now.
}
if (!XRE_IsParentProcess()) {
@ -952,7 +959,8 @@ protected:
static void TimerTickOne(nsITimer* aTimer, void* aClosure)
{
InactiveRefreshDriverTimer *timer = static_cast<InactiveRefreshDriverTimer*>(aClosure);
RefPtr<InactiveRefreshDriverTimer> timer =
static_cast<InactiveRefreshDriverTimer*>(aClosure);
timer->TickOne();
}
@ -963,8 +971,8 @@ protected:
} // namespace mozilla
static RefreshDriverTimer* sRegularRateTimer;
static InactiveRefreshDriverTimer* sThrottledRateTimer;
static StaticRefPtr<RefreshDriverTimer> sRegularRateTimer;
static StaticRefPtr<InactiveRefreshDriverTimer> sThrottledRateTimer;
static void
CreateContentVsyncRefreshTimer(void*)
@ -1038,9 +1046,6 @@ GetFirstFrameDelay(imgIRequest* req)
nsRefreshDriver::Shutdown()
{
// clean up our timers
delete sRegularRateTimer;
delete sThrottledRateTimer;
sRegularRateTimer = nullptr;
sThrottledRateTimer = nullptr;
}
@ -2288,16 +2293,15 @@ nsRefreshDriver::PVsyncActorCreated(VsyncChild* aVsyncChild)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(!XRE_IsParentProcess());
auto* vsyncRefreshDriverTimer =
new VsyncRefreshDriverTimer(aVsyncChild);
RefPtr<RefreshDriverTimer> vsyncRefreshDriverTimer =
new VsyncRefreshDriverTimer(aVsyncChild);
// If we are using software timer, swap current timer to
// VsyncRefreshDriverTimer.
if (sRegularRateTimer) {
sRegularRateTimer->SwapRefreshDrivers(vsyncRefreshDriverTimer);
delete sRegularRateTimer;
}
sRegularRateTimer = vsyncRefreshDriverTimer;
sRegularRateTimer = vsyncRefreshDriverTimer.forget();
}
void

Просмотреть файл

@ -130,15 +130,31 @@ inline bool HaveFixedSize(const ReflowInput& aReflowInput)
nsIFrame*
NS_NewImageFrame(nsIPresShell* aPresShell, ComputedStyle* aStyle)
{
return new (aPresShell) nsImageFrame(aStyle);
return new (aPresShell) nsImageFrame(aStyle, nsImageFrame::Kind::ImageElement);
}
nsIFrame*
NS_NewImageFrameForContentProperty(nsIPresShell* aPresShell,
ComputedStyle* aStyle)
{
return new (aPresShell) nsImageFrame(
aStyle, nsImageFrame::Kind::NonGeneratedContentProperty);
}
nsImageFrame*
nsImageFrame::CreateContinuingFrame(nsIPresShell* aPresShell,
ComputedStyle* aStyle) const
{
return new (aPresShell) nsImageFrame(aStyle, mKind);
}
NS_IMPL_FRAMEARENA_HELPERS(nsImageFrame)
nsImageFrame::nsImageFrame(ComputedStyle* aStyle, ClassID aID)
nsImageFrame::nsImageFrame(ComputedStyle* aStyle, ClassID aID, Kind aKind)
: nsAtomicContainerFrame(aStyle, aID)
, mComputedSize(0, 0)
, mIntrinsicRatio(0, 0)
, mKind(aKind)
, mDisplayingIcon(false)
, mFirstFrameComplete(false)
, mReflowCallbackPosted(false)
@ -203,20 +219,25 @@ nsImageFrame::DestroyFrom(nsIFrame* aDestructRoot, PostDestroyData& aPostDestroy
// a DOM listener.
DisconnectMap();
// set the frame to null so we don't send messages to a dead object.
if (mListener) {
MOZ_ASSERT(mListener);
if (mKind == Kind::ImageElement) {
MOZ_ASSERT(!mContentURLRequest);
nsCOMPtr<nsIImageLoadingContent> imageLoader = do_QueryInterface(mContent);
if (imageLoader) {
// Notify our image loading content that we are going away so it can
// deregister with our refresh driver.
imageLoader->FrameDestroyed(this);
MOZ_ASSERT(imageLoader);
imageLoader->RemoveNativeObserver(mListener);
// Notify our image loading content that we are going away so it can
// deregister with our refresh driver.
imageLoader->FrameDestroyed(this);
imageLoader->RemoveNativeObserver(mListener);
} else {
if (mContentURLRequest) {
mContentURLRequest->Cancel(NS_BINDING_ABORTED);
}
mListener->SetFrame(nullptr);
}
// set the frame to null so we don't send messages to a dead object.
mListener->SetFrame(nullptr);
mListener = nullptr;
// If we were displaying an icon, take ourselves off the list
@ -254,11 +275,27 @@ nsImageFrame::DidSetComputedStyle(ComputedStyle* aOldComputedStyle)
}
}
void
nsImageFrame::Init(nsIContent* aContent,
nsContainerFrame* aParent,
nsIFrame* aPrevInFlow)
static bool
SizeIsAvailable(imgIRequest* aRequest)
{
if (!aRequest) {
return false;
}
uint32_t imageStatus = 0;
nsresult rv = aRequest->GetImageStatus(&imageStatus);
return NS_SUCCEEDED(rv) && (imageStatus & imgIRequest::STATUS_SIZE_AVAILABLE);
}
void
nsImageFrame::Init(nsIContent* aContent,
nsContainerFrame* aParent,
nsIFrame* aPrevInFlow)
{
MOZ_ASSERT_IF(aPrevInFlow,
aPrevInFlow->Type() == LayoutFrameType::Image &&
static_cast<nsImageFrame*>(aPrevInFlow)->mKind == mKind);
nsAtomicContainerFrame::Init(aContent, aParent, aPrevInFlow);
mListener = new nsImageListener(this);
@ -266,17 +303,27 @@ nsImageFrame::Init(nsIContent* aContent,
if (!gIconLoad)
LoadIcons(PresContext());
nsCOMPtr<nsIImageLoadingContent> imageLoader = do_QueryInterface(aContent);
if (!imageLoader) {
MOZ_CRASH("Why do we have an nsImageFrame here at all?");
if (mKind == Kind::ImageElement) {
nsCOMPtr<nsIImageLoadingContent> imageLoader = do_QueryInterface(aContent);
MOZ_ASSERT(imageLoader);
imageLoader->AddNativeObserver(mListener);
// We have a PresContext now, so we need to notify the image content node
// that it can register images.
imageLoader->FrameCreated(this);
} else {
if (auto* proxy = StyleContent()->ContentAt(0).GetImage()) {
proxy->Clone(mListener,
mContent->OwnerDoc(),
getter_AddRefs(mContentURLRequest));
// Make sure we get the intrinsic size and such ASAP if available.
if (SizeIsAvailable(mContentURLRequest)) {
nsCOMPtr<imgIContainer> image;
mContentURLRequest->GetImage(getter_AddRefs(image));
OnSizeAvailable(mContentURLRequest, image);
}
}
}
imageLoader->AddNativeObserver(mListener);
// We have a PresContext now, so we need to notify the image content node that
// it can register images.
imageLoader->FrameCreated(this);
// Give image loads associated with an image frame a small priority boost.
if (nsCOMPtr<imgIRequest> currentRequest = GetCurrentRequest()) {
uint32_t categoryToBoostPriority = imgIRequest::CATEGORY_FRAME_INIT;
@ -330,7 +377,9 @@ nsImageFrame::UpdateIntrinsicSize(imgIContainer* aImage)
// Set intrinsic size to match aImage's reported intrinsic width & height.
nsSize intrinsicSize;
if (NS_SUCCEEDED(aImage->GetIntrinsicSize(&intrinsicSize))) {
ScaleIntrinsicSizeForDensity(*mContent, intrinsicSize);
if (mKind == Kind::ImageElement) {
ScaleIntrinsicSizeForDensity(*mContent, intrinsicSize);
}
// If the image has no intrinsic width, intrinsicSize.width will be -1, and
// we can leave mIntrinsicSize.width at its default value of eStyleUnit_None.
// Otherwise we use intrinsicSize.width. Height works the same way.
@ -408,8 +457,13 @@ bool
nsImageFrame::IsPendingLoad(imgIRequest* aRequest) const
{
// Default to pending load in case of errors
if (mKind == Kind::NonGeneratedContentProperty) {
MOZ_ASSERT(aRequest == mContentURLRequest);
return false;
}
nsCOMPtr<nsIImageLoadingContent> imageLoader(do_QueryInterface(mContent));
NS_ASSERTION(imageLoader, "No image loading content?");
MOZ_ASSERT(imageLoader);
int32_t requestType = nsIImageLoadingContent::UNKNOWN_REQUEST;
imageLoader->GetRequestType(aRequest, &requestType);
@ -550,22 +604,12 @@ nsImageFrame::Notify(imgIRequest* aRequest,
return NS_OK;
}
static bool
SizeIsAvailable(imgIRequest* aRequest)
{
if (!aRequest)
return false;
uint32_t imageStatus = 0;
nsresult rv = aRequest->GetImageStatus(&imageStatus);
return NS_SUCCEEDED(rv) && (imageStatus & imgIRequest::STATUS_SIZE_AVAILABLE);
}
nsresult
nsImageFrame::OnSizeAvailable(imgIRequest* aRequest, imgIContainer* aImage)
{
if (!aImage) return NS_ERROR_INVALID_ARG;
if (!aImage) {
return NS_ERROR_INVALID_ARG;
}
/* Get requested animation policy from the pres context:
* normal = 0
@ -598,9 +642,13 @@ nsImageFrame::OnSizeAvailable(imgIRequest* aRequest, imgIContainer* aImage)
intrinsicSizeChanged = true;
}
if (!GotInitialReflow()) {
return NS_OK;
}
MarkNeedsDisplayItemRebuild();
if (intrinsicSizeChanged && GotInitialReflow()) {
if (intrinsicSizeChanged) {
// Now we need to reflow if we have an unconstrained size and have
// already gotten the initial reflow
if (!(mState & IMAGE_SIZECONSTRAINED)) {
@ -821,46 +869,56 @@ nsImageFrame::EnsureIntrinsicSizeAndRatio()
{
// If mIntrinsicSize.width and height are 0, then we need to update from the
// image container.
if (mIntrinsicSize.width.GetUnit() == eStyleUnit_Coord &&
mIntrinsicSize.width.GetCoordValue() == 0 &&
mIntrinsicSize.height.GetUnit() == eStyleUnit_Coord &&
mIntrinsicSize.height.GetCoordValue() == 0) {
if (mIntrinsicSize.width.GetUnit() != eStyleUnit_Coord ||
mIntrinsicSize.width.GetCoordValue() != 0 ||
mIntrinsicSize.height.GetUnit() != eStyleUnit_Coord ||
mIntrinsicSize.height.GetCoordValue() != 0) {
return;
}
if (mImage) {
UpdateIntrinsicSize(mImage);
UpdateIntrinsicRatio(mImage);
} else {
// image request is null or image size not known, probably an
// invalid image specified
if (!(GetStateBits() & NS_FRAME_GENERATED_CONTENT)) {
bool imageInvalid = false;
if (mImage) {
UpdateIntrinsicSize(mImage);
UpdateIntrinsicRatio(mImage);
return;
}
// check for broken images. valid null images (eg. img src="") are
// not considered broken because they have no image requests
if (nsCOMPtr<imgIRequest> currentRequest = GetCurrentRequest()) {
uint32_t imageStatus;
imageInvalid =
NS_SUCCEEDED(currentRequest->GetImageStatus(&imageStatus)) &&
(imageStatus & imgIRequest::STATUS_ERROR);
} else if (nsCOMPtr<nsIImageLoadingContent> loader = do_QueryInterface(mContent)) {
// check if images are user-disabled (or blocked for other
// reasons)
int16_t imageBlockingStatus;
loader->GetImageBlockingStatus(&imageBlockingStatus);
imageInvalid = imageBlockingStatus != nsIContentPolicy::ACCEPT;
}
// NOTE(emilio, https://github.com/w3c/csswg-drafts/issues/2832): WebKit
// and Blink behave differently here for content: url(..), for now adapt to
// Blink's behavior.
const bool mayDisplayBrokenIcon = IsForNonGeneratedImageElement();
if (!mayDisplayBrokenIcon) {
return;
}
// image request is null or image size not known, probably an
// invalid image specified
bool imageInvalid = false;
// invalid image specified. make the image big enough for the "broken" icon
if (imageInvalid) {
nscoord edgeLengthToUse =
nsPresContext::CSSPixelsToAppUnits(
ICON_SIZE + (2 * (ICON_PADDING + ALT_BORDER_WIDTH)));
mIntrinsicSize.width.SetCoordValue(edgeLengthToUse);
mIntrinsicSize.height.SetCoordValue(edgeLengthToUse);
mIntrinsicRatio.SizeTo(1, 1);
}
}
}
// check for broken images. valid null images (eg. img src="") are
// not considered broken because they have no image requests
if (nsCOMPtr<imgIRequest> currentRequest = GetCurrentRequest()) {
uint32_t imageStatus;
imageInvalid =
NS_SUCCEEDED(currentRequest->GetImageStatus(&imageStatus)) &&
(imageStatus & imgIRequest::STATUS_ERROR);
} else {
MOZ_ASSERT(mKind == Kind::ImageElement);
nsCOMPtr<nsIImageLoadingContent> loader = do_QueryInterface(mContent);
MOZ_ASSERT(loader);
// check if images are user-disabled (or blocked for other reasons)
int16_t imageBlockingStatus;
loader->GetImageBlockingStatus(&imageBlockingStatus);
imageInvalid = imageBlockingStatus != nsIContentPolicy::ACCEPT;
}
// invalid image specified. make the image big enough for the "broken" icon
if (imageInvalid) {
nscoord edgeLengthToUse =
nsPresContext::CSSPixelsToAppUnits(
ICON_SIZE + (2 * (ICON_PADDING + ALT_BORDER_WIDTH)));
mIntrinsicSize.width.SetCoordValue(edgeLengthToUse);
mIntrinsicSize.height.SetCoordValue(edgeLengthToUse);
mIntrinsicRatio.SizeTo(1, 1);
}
}
@ -1461,14 +1519,11 @@ nsImageFrame::DisplayAltFeedback(gfxContext& aRenderingContext,
// If there's still room, display the alt-text
if (!inner.IsEmpty()) {
nsIContent* content = GetContent();
if (content) {
nsAutoString altText;
nsCSSFrameConstructor::GetAlternateTextFor(content->AsElement(),
content->NodeInfo()->NameAtom(),
altText);
DisplayAltText(PresContext(), aRenderingContext, altText, inner);
}
nsAutoString altText;
nsCSSFrameConstructor::GetAlternateTextFor(mContent->AsElement(),
mContent->NodeInfo()->NameAtom(),
altText);
DisplayAltText(PresContext(), aRenderingContext, altText, inner);
}
aRenderingContext.Restore();
@ -1780,14 +1835,17 @@ nsImageFrame::PaintImage(gfxContext& aRenderingContext, nsPoint aPt,
already_AddRefed<imgIRequest>
nsImageFrame::GetCurrentRequest() const
{
nsCOMPtr<imgIRequest> request;
if (mKind == Kind::NonGeneratedContentProperty) {
return do_AddRef(mContentURLRequest);
}
MOZ_ASSERT(!mContentURLRequest);
nsCOMPtr<imgIRequest> request;
nsCOMPtr<nsIImageLoadingContent> imageLoader = do_QueryInterface(mContent);
MOZ_ASSERT(imageLoader);
imageLoader->GetRequest(nsIImageLoadingContent::CURRENT_REQUEST,
getter_AddRefs(request));
return request.forget();
}
@ -2118,15 +2176,11 @@ void
nsImageFrame::OnVisibilityChange(Visibility aNewVisibility,
const Maybe<OnNonvisible>& aNonvisibleAction)
{
nsCOMPtr<nsIImageLoadingContent> imageLoader = do_QueryInterface(mContent);
if (!imageLoader) {
MOZ_ASSERT_UNREACHABLE("Should have an nsIImageLoadingContent");
nsAtomicContainerFrame::OnVisibilityChange(aNewVisibility, aNonvisibleAction);
return;
if (mKind == Kind::ImageElement) {
nsCOMPtr<nsIImageLoadingContent> imageLoader = do_QueryInterface(mContent);
imageLoader->OnVisibilityChange(aNewVisibility, aNonvisibleAction);
}
imageLoader->OnVisibilityChange(aNewVisibility, aNonvisibleAction);
if (aNewVisibility == Visibility::APPROXIMATELY_VISIBLE) {
MaybeDecodeForPredictedSize();
}

Просмотреть файл

@ -180,13 +180,42 @@ public:
virtual bool ReflowFinished() override;
virtual void ReflowCallbackCanceled() override;
// The kind of image frame we are.
enum class Kind : uint8_t
{
// For an nsImageLoadingContent, including generated ::before and ::after
// content, which are an nsGenConImageContent.
ImageElement,
// For css 'content: url(..)' on other elements.
NonGeneratedContentProperty,
};
// Whether this frame is for a non-generated image element, that is, one that
// isn't a ::before / ::after.
bool IsForNonGeneratedImageElement() const
{
return mKind == Kind::ImageElement &&
!HasAnyStateBits(NS_FRAME_GENERATED_CONTENT);
}
// Creates a suitable continuing frame for this frame.
nsImageFrame* CreateContinuingFrame(nsIPresShell*, ComputedStyle*) const;
private:
friend nsIFrame* NS_NewImageFrame(nsIPresShell*, ComputedStyle*);
explicit nsImageFrame(ComputedStyle* aStyle)
: nsImageFrame(aStyle, kClassID) {}
friend nsIFrame* NS_NewImageFrameForContentProperty(nsIPresShell*, ComputedStyle*);
nsImageFrame(ComputedStyle* aStyle, Kind aKind)
: nsImageFrame(aStyle, kClassID, aKind)
{ }
nsImageFrame(ComputedStyle*, ClassID, Kind);
protected:
nsImageFrame(ComputedStyle* aStyle, ClassID aID);
nsImageFrame(ComputedStyle* aStyle, ClassID aID)
: nsImageFrame(aStyle, aID, Kind::ImageElement)
{ }
virtual ~nsImageFrame();
void EnsureIntrinsicSizeAndRatio();
@ -338,12 +367,16 @@ private:
RefPtr<nsImageListener> mListener;
// An image request created for content: url(..).
RefPtr<imgRequestProxy> mContentURLRequest;
nsCOMPtr<imgIContainer> mImage;
nsCOMPtr<imgIContainer> mPrevImage;
nsSize mComputedSize;
mozilla::IntrinsicSize mIntrinsicSize;
nsSize mIntrinsicRatio;
const Kind mKind;
bool mDisplayingIcon;
bool mFirstFrameComplete;
bool mReflowCallbackPosted;

Просмотреть файл

@ -114,6 +114,7 @@
#define IMAGE_MNG "video/x-mng"
#define IMAGE_JNG "image/x-jng"
#define IMAGE_SVG_XML "image/svg+xml"
#define IMAGE_WEBP "image/webp"
#define MESSAGE_EXTERNAL_BODY "message/external-body"
#define MESSAGE_NEWS "message/news"

Просмотреть файл

@ -1099,7 +1099,8 @@ nsHttpTransaction::Close(nsresult reason)
if ((reason == NS_ERROR_NET_RESET ||
reason == NS_OK ||
reason == psm::GetXPCOMFromNSSError(SSL_ERROR_DOWNGRADE_WITH_EARLY_DATA)) &&
(!(mCaps & NS_HTTP_STICKY_CONNECTION) || (mCaps & NS_HTTP_CONNECTION_RESTARTABLE))) {
(!(mCaps & NS_HTTP_STICKY_CONNECTION) || (mCaps & NS_HTTP_CONNECTION_RESTARTABLE) ||
(mEarlyDataDisposition == EARLY_425))) {
if (mForceRestart && NS_SUCCEEDED(Restart())) {
if (mResponseHead) {

Просмотреть файл

@ -1 +1 @@
93cbd336eaca
c84a61acb17d

Просмотреть файл

@ -10,4 +10,3 @@
*/
#error "Do not include this header file."

Просмотреть файл

@ -37,6 +37,50 @@ TEST_P(TlsConnectGeneric, ServerAuthRsaChain) {
EXPECT_EQ(2UL, chain_length);
}
TEST_P(TlsConnectTls12Plus, ServerAuthRsaPss) {
static const SSLSignatureScheme kSignatureSchemePss[] = {
ssl_sig_rsa_pss_pss_sha256};
Reset(TlsAgent::kServerRsaPss);
client_->SetSignatureSchemes(kSignatureSchemePss,
PR_ARRAY_SIZE(kSignatureSchemePss));
server_->SetSignatureSchemes(kSignatureSchemePss,
PR_ARRAY_SIZE(kSignatureSchemePss));
Connect();
CheckKeys(ssl_kea_ecdh, ssl_grp_ec_curve25519, ssl_auth_rsa_pss,
ssl_sig_rsa_pss_pss_sha256);
}
// PSS doesn't work with TLS 1.0 or 1.1 because we can't signal it.
TEST_P(TlsConnectPre12, ServerAuthRsaPssFails) {
static const SSLSignatureScheme kSignatureSchemePss[] = {
ssl_sig_rsa_pss_pss_sha256};
Reset(TlsAgent::kServerRsaPss);
client_->SetSignatureSchemes(kSignatureSchemePss,
PR_ARRAY_SIZE(kSignatureSchemePss));
server_->SetSignatureSchemes(kSignatureSchemePss,
PR_ARRAY_SIZE(kSignatureSchemePss));
ConnectExpectAlert(server_, kTlsAlertHandshakeFailure);
server_->CheckErrorCode(SSL_ERROR_NO_CYPHER_OVERLAP);
client_->CheckErrorCode(SSL_ERROR_NO_CYPHER_OVERLAP);
}
// Check that a PSS certificate with no parameters works.
TEST_P(TlsConnectTls12Plus, ServerAuthRsaPssNoParameters) {
static const SSLSignatureScheme kSignatureSchemePss[] = {
ssl_sig_rsa_pss_pss_sha256};
Reset("rsa_pss_noparam");
client_->SetSignatureSchemes(kSignatureSchemePss,
PR_ARRAY_SIZE(kSignatureSchemePss));
server_->SetSignatureSchemes(kSignatureSchemePss,
PR_ARRAY_SIZE(kSignatureSchemePss));
Connect();
CheckKeys(ssl_kea_ecdh, ssl_grp_ec_curve25519, ssl_auth_rsa_pss,
ssl_sig_rsa_pss_pss_sha256);
}
TEST_P(TlsConnectGeneric, ServerAuthRsaPssChain) {
Reset("rsa_pss_chain");
Connect();
@ -218,13 +262,13 @@ TEST_P(TlsConnectTls12, ClientAuthNoSigAlgsFallback) {
CheckSigScheme(capture_cert_verify, 0, server_, ssl_sig_rsa_pkcs1_sha1, 1024);
}
static const SSLSignatureScheme SignatureSchemeEcdsaSha384[] = {
static const SSLSignatureScheme kSignatureSchemeEcdsaSha384[] = {
ssl_sig_ecdsa_secp384r1_sha384};
static const SSLSignatureScheme SignatureSchemeEcdsaSha256[] = {
static const SSLSignatureScheme kSignatureSchemeEcdsaSha256[] = {
ssl_sig_ecdsa_secp256r1_sha256};
static const SSLSignatureScheme SignatureSchemeRsaSha384[] = {
static const SSLSignatureScheme kSignatureSchemeRsaSha384[] = {
ssl_sig_rsa_pkcs1_sha384};
static const SSLSignatureScheme SignatureSchemeRsaSha256[] = {
static const SSLSignatureScheme kSignatureSchemeRsaSha256[] = {
ssl_sig_rsa_pkcs1_sha256};
static SSLNamedGroup NamedGroupForEcdsa384(uint16_t version) {
@ -241,10 +285,10 @@ static SSLNamedGroup NamedGroupForEcdsa384(uint16_t version) {
// for TLS 1.1 and 1.0, where they should be ignored.
TEST_P(TlsConnectGeneric, SignatureAlgorithmServerAuth) {
Reset(TlsAgent::kServerEcdsa384);
client_->SetSignatureSchemes(SignatureSchemeEcdsaSha384,
PR_ARRAY_SIZE(SignatureSchemeEcdsaSha384));
server_->SetSignatureSchemes(SignatureSchemeEcdsaSha384,
PR_ARRAY_SIZE(SignatureSchemeEcdsaSha384));
client_->SetSignatureSchemes(kSignatureSchemeEcdsaSha384,
PR_ARRAY_SIZE(kSignatureSchemeEcdsaSha384));
server_->SetSignatureSchemes(kSignatureSchemeEcdsaSha384,
PR_ARRAY_SIZE(kSignatureSchemeEcdsaSha384));
Connect();
CheckKeys(ssl_kea_ecdh, NamedGroupForEcdsa384(version_), ssl_auth_ecdsa,
ssl_sig_ecdsa_secp384r1_sha384);
@ -273,8 +317,8 @@ TEST_P(TlsConnectGeneric, SignatureAlgorithmClientOnly) {
// Defaults on the client include the provided option.
TEST_P(TlsConnectGeneric, SignatureAlgorithmServerOnly) {
Reset(TlsAgent::kServerEcdsa384);
server_->SetSignatureSchemes(SignatureSchemeEcdsaSha384,
PR_ARRAY_SIZE(SignatureSchemeEcdsaSha384));
server_->SetSignatureSchemes(kSignatureSchemeEcdsaSha384,
PR_ARRAY_SIZE(kSignatureSchemeEcdsaSha384));
Connect();
CheckKeys(ssl_kea_ecdh, NamedGroupForEcdsa384(version_), ssl_auth_ecdsa,
ssl_sig_ecdsa_secp384r1_sha384);
@ -283,16 +327,16 @@ TEST_P(TlsConnectGeneric, SignatureAlgorithmServerOnly) {
// In TLS 1.2, curve and hash aren't bound together.
TEST_P(TlsConnectTls12, SignatureSchemeCurveMismatch) {
Reset(TlsAgent::kServerEcdsa256);
client_->SetSignatureSchemes(SignatureSchemeEcdsaSha384,
PR_ARRAY_SIZE(SignatureSchemeEcdsaSha384));
client_->SetSignatureSchemes(kSignatureSchemeEcdsaSha384,
PR_ARRAY_SIZE(kSignatureSchemeEcdsaSha384));
Connect();
}
// In TLS 1.3, curve and hash are coupled.
TEST_P(TlsConnectTls13, SignatureSchemeCurveMismatch) {
Reset(TlsAgent::kServerEcdsa256);
client_->SetSignatureSchemes(SignatureSchemeEcdsaSha384,
PR_ARRAY_SIZE(SignatureSchemeEcdsaSha384));
client_->SetSignatureSchemes(kSignatureSchemeEcdsaSha384,
PR_ARRAY_SIZE(kSignatureSchemeEcdsaSha384));
ConnectExpectAlert(server_, kTlsAlertHandshakeFailure);
server_->CheckErrorCode(SSL_ERROR_UNSUPPORTED_SIGNATURE_ALGORITHM);
client_->CheckErrorCode(SSL_ERROR_NO_CYPHER_OVERLAP);
@ -301,16 +345,16 @@ TEST_P(TlsConnectTls13, SignatureSchemeCurveMismatch) {
// Configuring a P-256 cert with only SHA-384 signatures is OK in TLS 1.2.
TEST_P(TlsConnectTls12, SignatureSchemeBadConfig) {
Reset(TlsAgent::kServerEcdsa256); // P-256 cert can't be used.
server_->SetSignatureSchemes(SignatureSchemeEcdsaSha384,
PR_ARRAY_SIZE(SignatureSchemeEcdsaSha384));
server_->SetSignatureSchemes(kSignatureSchemeEcdsaSha384,
PR_ARRAY_SIZE(kSignatureSchemeEcdsaSha384));
Connect();
}
// A P-256 certificate in TLS 1.3 needs a SHA-256 signature scheme.
TEST_P(TlsConnectTls13, SignatureSchemeBadConfig) {
Reset(TlsAgent::kServerEcdsa256); // P-256 cert can't be used.
server_->SetSignatureSchemes(SignatureSchemeEcdsaSha384,
PR_ARRAY_SIZE(SignatureSchemeEcdsaSha384));
server_->SetSignatureSchemes(kSignatureSchemeEcdsaSha384,
PR_ARRAY_SIZE(kSignatureSchemeEcdsaSha384));
ConnectExpectAlert(server_, kTlsAlertHandshakeFailure);
server_->CheckErrorCode(SSL_ERROR_UNSUPPORTED_SIGNATURE_ALGORITHM);
client_->CheckErrorCode(SSL_ERROR_NO_CYPHER_OVERLAP);
@ -319,10 +363,10 @@ TEST_P(TlsConnectTls13, SignatureSchemeBadConfig) {
// Where there is no overlap on signature schemes, we still connect successfully
// if we aren't going to use a signature.
TEST_P(TlsConnectGenericPre13, SignatureAlgorithmNoOverlapStaticRsa) {
client_->SetSignatureSchemes(SignatureSchemeRsaSha384,
PR_ARRAY_SIZE(SignatureSchemeRsaSha384));
server_->SetSignatureSchemes(SignatureSchemeRsaSha256,
PR_ARRAY_SIZE(SignatureSchemeRsaSha256));
client_->SetSignatureSchemes(kSignatureSchemeRsaSha384,
PR_ARRAY_SIZE(kSignatureSchemeRsaSha384));
server_->SetSignatureSchemes(kSignatureSchemeRsaSha256,
PR_ARRAY_SIZE(kSignatureSchemeRsaSha256));
EnableOnlyStaticRsaCiphers();
Connect();
CheckKeys(ssl_kea_rsa, ssl_auth_rsa_decrypt);
@ -330,10 +374,10 @@ TEST_P(TlsConnectGenericPre13, SignatureAlgorithmNoOverlapStaticRsa) {
TEST_P(TlsConnectTls12Plus, SignatureAlgorithmNoOverlapEcdsa) {
Reset(TlsAgent::kServerEcdsa256);
client_->SetSignatureSchemes(SignatureSchemeEcdsaSha384,
PR_ARRAY_SIZE(SignatureSchemeEcdsaSha384));
server_->SetSignatureSchemes(SignatureSchemeEcdsaSha256,
PR_ARRAY_SIZE(SignatureSchemeEcdsaSha256));
client_->SetSignatureSchemes(kSignatureSchemeEcdsaSha384,
PR_ARRAY_SIZE(kSignatureSchemeEcdsaSha384));
server_->SetSignatureSchemes(kSignatureSchemeEcdsaSha256,
PR_ARRAY_SIZE(kSignatureSchemeEcdsaSha256));
ConnectExpectAlert(server_, kTlsAlertHandshakeFailure);
client_->CheckErrorCode(SSL_ERROR_NO_CYPHER_OVERLAP);
server_->CheckErrorCode(SSL_ERROR_UNSUPPORTED_SIGNATURE_ALGORITHM);
@ -342,10 +386,10 @@ TEST_P(TlsConnectTls12Plus, SignatureAlgorithmNoOverlapEcdsa) {
// Pre 1.2, a mismatch on signature algorithms shouldn't affect anything.
TEST_P(TlsConnectPre12, SignatureAlgorithmNoOverlapEcdsa) {
Reset(TlsAgent::kServerEcdsa256);
client_->SetSignatureSchemes(SignatureSchemeEcdsaSha384,
PR_ARRAY_SIZE(SignatureSchemeEcdsaSha384));
server_->SetSignatureSchemes(SignatureSchemeEcdsaSha256,
PR_ARRAY_SIZE(SignatureSchemeEcdsaSha256));
client_->SetSignatureSchemes(kSignatureSchemeEcdsaSha384,
PR_ARRAY_SIZE(kSignatureSchemeEcdsaSha384));
server_->SetSignatureSchemes(kSignatureSchemeEcdsaSha256,
PR_ARRAY_SIZE(kSignatureSchemeEcdsaSha256));
Connect();
}
@ -411,8 +455,8 @@ TEST_P(TlsConnectTls13, InconsistentSignatureSchemeAlert) {
}
TEST_P(TlsConnectTls12Plus, RequestClientAuthWithSha384) {
server_->SetSignatureSchemes(SignatureSchemeRsaSha384,
PR_ARRAY_SIZE(SignatureSchemeRsaSha384));
server_->SetSignatureSchemes(kSignatureSchemeRsaSha384,
PR_ARRAY_SIZE(kSignatureSchemeRsaSha384));
server_->RequestClientAuth(false);
Connect();
}
@ -754,15 +798,15 @@ TEST_F(TlsAgentStreamTestServer, ConfigureCertRsaPkcs1SignAndKEX) {
PRFileDesc* ssl_fd = agent_->ssl_fd();
EXPECT_TRUE(SSLInt_HasCertWithAuthType(ssl_fd, ssl_auth_rsa_decrypt));
EXPECT_TRUE(SSLInt_HasCertWithAuthType(ssl_fd, ssl_auth_rsa_sign));
EXPECT_TRUE(SSLInt_HasCertWithAuthType(ssl_fd, ssl_auth_rsa_pss));
EXPECT_FALSE(SSLInt_HasCertWithAuthType(ssl_fd, ssl_auth_rsa_pss));
// Configuring for only rsa_sign, rsa_pss, or rsa_decrypt should work.
// Configuring for only rsa_sign or rsa_decrypt should work.
EXPECT_TRUE(agent_->ConfigServerCert(TlsAgent::kServerRsa, false,
&ServerCertDataRsaPkcs1Decrypt));
EXPECT_TRUE(agent_->ConfigServerCert(TlsAgent::kServerRsa, false,
&ServerCertDataRsaPkcs1Sign));
EXPECT_TRUE(agent_->ConfigServerCert(TlsAgent::kServerRsa, false,
&ServerCertDataRsaPss));
EXPECT_FALSE(agent_->ConfigServerCert(TlsAgent::kServerRsa, false,
&ServerCertDataRsaPss));
}
// Test RSA cert with usage=[signature].
@ -772,17 +816,17 @@ TEST_F(TlsAgentStreamTestServer, ConfigureCertRsaPkcs1Sign) {
PRFileDesc* ssl_fd = agent_->ssl_fd();
EXPECT_FALSE(SSLInt_HasCertWithAuthType(ssl_fd, ssl_auth_rsa_decrypt));
EXPECT_TRUE(SSLInt_HasCertWithAuthType(ssl_fd, ssl_auth_rsa_sign));
EXPECT_TRUE(SSLInt_HasCertWithAuthType(ssl_fd, ssl_auth_rsa_pss));
EXPECT_FALSE(SSLInt_HasCertWithAuthType(ssl_fd, ssl_auth_rsa_pss));
// Configuring for only rsa_decrypt should fail.
EXPECT_FALSE(agent_->ConfigServerCert(TlsAgent::kServerRsaSign, false,
&ServerCertDataRsaPkcs1Decrypt));
// Configuring for only rsa_sign or rsa_pss should work.
// Configuring for only rsa_sign should work.
EXPECT_TRUE(agent_->ConfigServerCert(TlsAgent::kServerRsaSign, false,
&ServerCertDataRsaPkcs1Sign));
EXPECT_TRUE(agent_->ConfigServerCert(TlsAgent::kServerRsaSign, false,
&ServerCertDataRsaPss));
EXPECT_FALSE(agent_->ConfigServerCert(TlsAgent::kServerRsaSign, false,
&ServerCertDataRsaPss));
}
// Test RSA cert with usage=[encipherment].

Просмотреть файл

@ -84,6 +84,18 @@ class TlsCipherSuiteTestBase : public TlsConnectTestBase {
Reset(TlsAgent::kRsa2048);
auth_type_ = ssl_auth_rsa_sign;
break;
case ssl_sig_rsa_pss_pss_sha256:
Reset(TlsAgent::kServerRsaPss);
auth_type_ = ssl_auth_rsa_pss;
break;
case ssl_sig_rsa_pss_pss_sha384:
Reset("rsa_pss384");
auth_type_ = ssl_auth_rsa_pss;
break;
case ssl_sig_rsa_pss_pss_sha512:
Reset("rsa_pss512");
auth_type_ = ssl_auth_rsa_pss;
break;
case ssl_sig_ecdsa_secp256r1_sha256:
Reset(TlsAgent::kServerEcdsa256);
auth_type_ = ssl_auth_ecdsa;
@ -310,14 +322,13 @@ static const auto kDummyNamedGroupParams = ::testing::Values(ssl_grp_none);
static const auto kDummySignatureSchemesParams =
::testing::Values(ssl_sig_none);
#ifndef NSS_DISABLE_TLS_1_3
static SSLSignatureScheme kSignatureSchemesParamsArr[] = {
ssl_sig_rsa_pkcs1_sha256, ssl_sig_rsa_pkcs1_sha384,
ssl_sig_rsa_pkcs1_sha512, ssl_sig_ecdsa_secp256r1_sha256,
ssl_sig_ecdsa_secp384r1_sha384, ssl_sig_rsa_pss_rsae_sha256,
ssl_sig_rsa_pss_rsae_sha384, ssl_sig_rsa_pss_rsae_sha512,
};
#endif
ssl_sig_rsa_pss_pss_sha256, ssl_sig_rsa_pss_pss_sha384,
ssl_sig_rsa_pss_pss_sha512};
INSTANTIATE_CIPHER_TEST_P(RC4, Stream, V10ToV12, kDummyNamedGroupParams,
kDummySignatureSchemesParams,
@ -372,6 +383,14 @@ INSTANTIATE_CIPHER_TEST_P(
TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, TLS_ECDH_RSA_WITH_AES_256_CBC_SHA,
TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA);
INSTANTIATE_CIPHER_TEST_P(
TLS12SigSchemes, All, V12, ::testing::ValuesIn(kFasterDHEGroups),
::testing::ValuesIn(kSignatureSchemesParamsArr),
TLS_DHE_RSA_WITH_AES_256_CBC_SHA256, TLS_RSA_WITH_AES_256_CBC_SHA256,
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, TLS_DHE_RSA_WITH_AES_128_CBC_SHA256,
TLS_RSA_WITH_AES_128_CBC_SHA256, TLS_DHE_DSS_WITH_AES_128_CBC_SHA256,
TLS_DHE_DSS_WITH_AES_256_CBC_SHA256);
#ifndef NSS_DISABLE_TLS_1_3
INSTANTIATE_CIPHER_TEST_P(TLS13, All, V13,
::testing::ValuesIn(kFasterDHEGroups),

Просмотреть файл

@ -583,6 +583,7 @@ void TlsAgent::CheckAuthType(SSLAuthType auth,
// switch statement because default label is different.
switch (auth) {
case ssl_auth_rsa_sign:
case ssl_auth_rsa_pss:
EXPECT_EQ(ssl_auth_rsa_decrypt, csinfo_.authAlgorithm)
<< "authAlgorithm for RSA is always decrypt";
break;

Просмотреть файл

@ -765,6 +765,9 @@ ssl_HasCert(const sslSocket *ss, SSLAuthType authType)
}
return PR_TRUE;
}
if (authType == ssl_auth_rsa_sign) {
return ssl_HasCert(ss, ssl_auth_rsa_pss);
}
return PR_FALSE;
}
@ -1120,6 +1123,8 @@ ssl3_SignHashes(sslSocket *ss, SSL3Hashes *hash, SECKEYPrivateKey *key,
if (ss->sec.isServer) {
ss->sec.signatureScheme = ss->ssl3.hs.signatureScheme;
ss->sec.authType =
ssl_SignatureSchemeToAuthType(ss->ssl3.hs.signatureScheme);
}
PRINT_BUF(60, (NULL, "signed hashes", (unsigned char *)buf->data, buf->len));
done:
@ -1255,6 +1260,7 @@ ssl3_VerifySignedHashes(sslSocket *ss, SSLSignatureScheme scheme, SSL3Hashes *ha
}
if (!ss->sec.isServer) {
ss->sec.signatureScheme = scheme;
ss->sec.authType = ssl_SignatureSchemeToAuthType(scheme);
}
loser:
@ -4002,8 +4008,8 @@ ssl_SignatureSchemeToHashType(SSLSignatureScheme scheme)
return ssl_hash_none;
}
KeyType
ssl_SignatureSchemeToKeyType(SSLSignatureScheme scheme)
static PRBool
ssl_SignatureSchemeMatchesSpkiOid(SSLSignatureScheme scheme, SECOidTag spkiOid)
{
switch (scheme) {
case ssl_sig_rsa_pkcs1_sha256:
@ -4013,133 +4019,243 @@ ssl_SignatureSchemeToKeyType(SSLSignatureScheme scheme)
case ssl_sig_rsa_pss_rsae_sha256:
case ssl_sig_rsa_pss_rsae_sha384:
case ssl_sig_rsa_pss_rsae_sha512:
case ssl_sig_rsa_pkcs1_sha1md5:
return (spkiOid == SEC_OID_X500_RSA_ENCRYPTION) ||
(spkiOid == SEC_OID_PKCS1_RSA_ENCRYPTION);
case ssl_sig_rsa_pss_pss_sha256:
case ssl_sig_rsa_pss_pss_sha384:
case ssl_sig_rsa_pss_pss_sha512:
case ssl_sig_rsa_pkcs1_sha1md5:
return rsaKey;
return spkiOid == SEC_OID_PKCS1_RSA_PSS_SIGNATURE;
case ssl_sig_ecdsa_secp256r1_sha256:
case ssl_sig_ecdsa_secp384r1_sha384:
case ssl_sig_ecdsa_secp521r1_sha512:
case ssl_sig_ecdsa_sha1:
return ecKey;
return spkiOid == SEC_OID_ANSIX962_EC_PUBLIC_KEY;
case ssl_sig_dsa_sha256:
case ssl_sig_dsa_sha384:
case ssl_sig_dsa_sha512:
case ssl_sig_dsa_sha1:
return dsaKey;
return spkiOid == SEC_OID_ANSIX9_DSA_SIGNATURE;
case ssl_sig_none:
case ssl_sig_ed25519:
case ssl_sig_ed448:
break;
}
PORT_Assert(0);
return nullKey;
return PR_FALSE;
}
static SSLNamedGroup
ssl_NamedGroupForSignatureScheme(SSLSignatureScheme scheme)
{
switch (scheme) {
case ssl_sig_ecdsa_secp256r1_sha256:
return ssl_grp_ec_secp256r1;
case ssl_sig_ecdsa_secp384r1_sha384:
return ssl_grp_ec_secp384r1;
case ssl_sig_ecdsa_secp521r1_sha512:
return ssl_grp_ec_secp521r1;
default:
break;
}
PORT_Assert(0);
return 0;
}
/* Validate that the signature scheme works for the given key.
* If |allowSha1| is set, we allow the use of SHA-1.
* If |matchGroup| is set, we also check that the group and hash match. */
/* Validate that the signature scheme works for the given key type. */
static PRBool
ssl_SignatureSchemeValidForKey(PRBool allowSha1, PRBool matchGroup,
KeyType keyType,
const sslNamedGroupDef *ecGroup,
SSLSignatureScheme scheme)
ssl_SignatureSchemeValid(SSLSignatureScheme scheme, SECOidTag spkiOid,
PRBool isTls13)
{
if (!ssl_IsSupportedSignatureScheme(scheme)) {
return PR_FALSE;
}
if (keyType != ssl_SignatureSchemeToKeyType(scheme)) {
if (!ssl_SignatureSchemeMatchesSpkiOid(scheme, spkiOid)) {
return PR_FALSE;
}
if (!allowSha1 && ssl_SignatureSchemeToHashType(scheme) == ssl_hash_sha1) {
return PR_FALSE;
if (isTls13) {
if (ssl_SignatureSchemeToHashType(scheme) == ssl_hash_sha1) {
return PR_FALSE;
}
/* With TLS 1.3, EC keys should have been selected based on calling
* ssl_SignatureSchemeFromSpki(), reject them otherwise. */
return spkiOid != SEC_OID_ANSIX962_EC_PUBLIC_KEY;
}
if (keyType != ecKey) {
return PR_TRUE;
}
if (!ecGroup) {
return PR_FALSE;
}
/* If |allowSha1| is present and the scheme is ssl_sig_ecdsa_sha1, it's OK.
* This scheme isn't bound to a specific group. */
if (allowSha1 && (scheme == ssl_sig_ecdsa_sha1)) {
return PR_TRUE;
}
if (!matchGroup) {
return PR_TRUE;
}
return ecGroup->name == ssl_NamedGroupForSignatureScheme(scheme);
return PR_TRUE;
}
/* ssl3_CheckSignatureSchemeConsistency checks that the signature
* algorithm identifier in |sigAndHash| is consistent with the public key in
* |cert|. It also checks the hash algorithm against the configured signature
* algorithms. If all the tests pass, SECSuccess is returned. Otherwise,
* PORT_SetError is called and SECFailure is returned. */
SECStatus
ssl_CheckSignatureSchemeConsistency(
sslSocket *ss, SSLSignatureScheme scheme, CERTCertificate *cert)
static SECStatus
ssl_SignatureSchemeFromPssSpki(CERTSubjectPublicKeyInfo *spki,
SSLSignatureScheme *scheme)
{
unsigned int i;
const sslNamedGroupDef *group = NULL;
SECKEYPublicKey *key;
KeyType keyType;
PRBool isTLS13 = ss->version == SSL_LIBRARY_VERSION_TLS_1_3;
SECKEYRSAPSSParams pssParam = { 0 };
PORTCheapArenaPool arena;
SECStatus rv;
key = CERT_ExtractPublicKey(cert);
if (key == NULL) {
ssl_MapLowLevelError(SSL_ERROR_EXTRACT_PUBLIC_KEY_FAILURE);
/* The key doesn't have parameters, boo. */
if (!spki->algorithm.parameters.len) {
*scheme = ssl_sig_none;
return SECSuccess;
}
PORT_InitCheapArena(&arena, DER_DEFAULT_CHUNKSIZE);
rv = SEC_QuickDERDecodeItem(&arena.arena, &pssParam,
SEC_ASN1_GET(SECKEY_RSAPSSParamsTemplate),
&spki->algorithm.parameters);
if (rv != SECSuccess) {
goto loser;
}
/* Not having hashAlg means SHA-1 and we don't accept that. */
if (!pssParam.hashAlg) {
goto loser;
}
switch (SECOID_GetAlgorithmTag(pssParam.hashAlg)) {
case SEC_OID_SHA256:
*scheme = ssl_sig_rsa_pss_pss_sha256;
break;
case SEC_OID_SHA384:
*scheme = ssl_sig_rsa_pss_pss_sha384;
break;
case SEC_OID_SHA512:
*scheme = ssl_sig_rsa_pss_pss_sha512;
break;
default:
goto loser;
}
PORT_DestroyCheapArena(&arena);
return SECSuccess;
loser:
PORT_DestroyCheapArena(&arena);
PORT_SetError(SSL_ERROR_BAD_CERTIFICATE);
return SECFailure;
}
static SECStatus
ssl_SignatureSchemeFromEcSpki(CERTSubjectPublicKeyInfo *spki,
SSLSignatureScheme *scheme)
{
const sslNamedGroupDef *group;
SECKEYPublicKey *key;
key = SECKEY_ExtractPublicKey(spki);
if (!key) {
PORT_SetError(SSL_ERROR_BAD_CERTIFICATE);
return SECFailure;
}
keyType = SECKEY_GetPublicKeyType(key);
if (keyType == ecKey) {
group = ssl_ECPubKey2NamedGroup(key);
}
group = ssl_ECPubKey2NamedGroup(key);
SECKEY_DestroyPublicKey(key);
if (!group) {
PORT_SetError(SSL_ERROR_BAD_CERTIFICATE);
return SECFailure;
}
switch (group->name) {
case ssl_grp_ec_secp256r1:
*scheme = ssl_sig_ecdsa_secp256r1_sha256;
return SECSuccess;
case ssl_grp_ec_secp384r1:
*scheme = ssl_sig_ecdsa_secp384r1_sha384;
return SECSuccess;
case ssl_grp_ec_secp521r1:
*scheme = ssl_sig_ecdsa_secp521r1_sha512;
return SECSuccess;
default:
break;
}
PORT_SetError(SSL_ERROR_BAD_CERTIFICATE);
return SECFailure;
}
/* Newer signature schemes are designed so that a single SPKI can be used with
* that scheme. This determines that scheme from the SPKI. If the SPKI doesn't
* have a single scheme, |*scheme| is set to ssl_sig_none. */
static SECStatus
ssl_SignatureSchemeFromSpki(CERTSubjectPublicKeyInfo *spki,
PRBool isTls13, SSLSignatureScheme *scheme)
{
SECOidTag spkiOid = SECOID_GetAlgorithmTag(&spki->algorithm);
if (spkiOid == SEC_OID_PKCS1_RSA_PSS_SIGNATURE) {
return ssl_SignatureSchemeFromPssSpki(spki, scheme);
}
/* Only do this lookup for TLS 1.3, where the scheme can be determined from
* the SPKI alone because the ECDSA key size determines the hash. Earlier
* TLS versions allow the same EC key to be used with different hashes. */
if (isTls13 && spkiOid == SEC_OID_ANSIX962_EC_PUBLIC_KEY) {
return ssl_SignatureSchemeFromEcSpki(spki, scheme);
}
*scheme = ssl_sig_none;
return SECSuccess;
}
static PRBool
ssl_SignatureSchemeEnabled(sslSocket *ss, SSLSignatureScheme scheme)
{
unsigned int i;
for (i = 0; i < ss->ssl3.signatureSchemeCount; ++i) {
if (scheme == ss->ssl3.signatureSchemes[i]) {
return PR_TRUE;
}
}
return PR_FALSE;
}
static PRBool
ssl_SignatureKeyMatchesSpkiOid(const ssl3KEADef *keaDef, SECOidTag spkiOid)
{
switch (spkiOid) {
case SEC_OID_X500_RSA_ENCRYPTION:
case SEC_OID_PKCS1_RSA_ENCRYPTION:
case SEC_OID_PKCS1_RSA_PSS_SIGNATURE:
return keaDef->signKeyType == rsaKey;
case SEC_OID_ANSIX9_DSA_SIGNATURE:
return keaDef->signKeyType == dsaKey;
case SEC_OID_ANSIX962_EC_PUBLIC_KEY:
return keaDef->signKeyType == ecKey;
default:
break;
}
return PR_FALSE;
}
/* ssl3_CheckSignatureSchemeConsistency checks that the signature algorithm
* identifier in |scheme| is consistent with the public key in |cert|. It also
* checks the hash algorithm against the configured signature algorithms. If
* all the tests pass, SECSuccess is returned. Otherwise, PORT_SetError is
* called and SECFailure is returned. */
SECStatus
ssl_CheckSignatureSchemeConsistency(sslSocket *ss, SSLSignatureScheme scheme,
CERTCertificate *cert)
{
SSLSignatureScheme spkiScheme;
PRBool isTLS13 = ss->version == SSL_LIBRARY_VERSION_TLS_1_3;
SECOidTag spkiOid;
SECStatus rv;
rv = ssl_SignatureSchemeFromSpki(&cert->subjectPublicKeyInfo, isTLS13,
&spkiScheme);
if (rv != SECSuccess) {
return SECFailure;
}
if (spkiScheme != ssl_sig_none) {
/* The SPKI in the certificate can only be used for a single scheme. */
if (spkiScheme != scheme ||
!ssl_SignatureSchemeEnabled(ss, scheme)) {
PORT_SetError(SSL_ERROR_INCORRECT_SIGNATURE_ALGORITHM);
return SECFailure;
}
return SECSuccess;
}
spkiOid = SECOID_GetAlgorithmTag(&cert->subjectPublicKeyInfo.algorithm);
/* If we're a client, check that the signature algorithm matches the signing
* key type of the cipher suite. */
if (!isTLS13 &&
!ss->sec.isServer &&
ss->ssl3.hs.kea_def->signKeyType != keyType) {
PORT_SetError(SSL_ERROR_INCORRECT_SIGNATURE_ALGORITHM);
return SECFailure;
if (!isTLS13 && !ss->sec.isServer) {
if (!ssl_SignatureKeyMatchesSpkiOid(ss->ssl3.hs.kea_def, spkiOid)) {
PORT_SetError(SSL_ERROR_INCORRECT_SIGNATURE_ALGORITHM);
return SECFailure;
}
}
/* Verify that the signature scheme matches the signing key. */
if (!ssl_SignatureSchemeValidForKey(!isTLS13 /* allowSha1 */,
isTLS13 /* matchGroup */,
keyType, group, scheme)) {
if (!ssl_SignatureSchemeValid(scheme, spkiOid, isTLS13)) {
PORT_SetError(SSL_ERROR_INCORRECT_SIGNATURE_ALGORITHM);
return SECFailure;
}
for (i = 0; i < ss->ssl3.signatureSchemeCount; ++i) {
if (scheme == ss->ssl3.signatureSchemes[i]) {
return SECSuccess;
}
if (!ssl_SignatureSchemeEnabled(ss, scheme)) {
PORT_SetError(SSL_ERROR_UNSUPPORTED_SIGNATURE_ALGORITHM);
return SECFailure;
}
PORT_SetError(SSL_ERROR_UNSUPPORTED_SIGNATURE_ALGORITHM);
return SECFailure;
return SECSuccess;
}
PRBool
@ -4153,6 +4269,9 @@ ssl_IsSupportedSignatureScheme(SSLSignatureScheme scheme)
case ssl_sig_rsa_pss_rsae_sha256:
case ssl_sig_rsa_pss_rsae_sha384:
case ssl_sig_rsa_pss_rsae_sha512:
case ssl_sig_rsa_pss_pss_sha256:
case ssl_sig_rsa_pss_pss_sha384:
case ssl_sig_rsa_pss_pss_sha512:
case ssl_sig_ecdsa_secp256r1_sha256:
case ssl_sig_ecdsa_secp384r1_sha384:
case ssl_sig_ecdsa_secp521r1_sha512:
@ -4164,9 +4283,6 @@ ssl_IsSupportedSignatureScheme(SSLSignatureScheme scheme)
return PR_TRUE;
case ssl_sig_rsa_pkcs1_sha1md5:
case ssl_sig_rsa_pss_pss_sha256:
case ssl_sig_rsa_pss_pss_sha384:
case ssl_sig_rsa_pss_pss_sha512:
case ssl_sig_none:
case ssl_sig_ed25519:
case ssl_sig_ed448:
@ -4182,6 +4298,9 @@ ssl_IsRsaPssSignatureScheme(SSLSignatureScheme scheme)
case ssl_sig_rsa_pss_rsae_sha256:
case ssl_sig_rsa_pss_rsae_sha384:
case ssl_sig_rsa_pss_rsae_sha512:
case ssl_sig_rsa_pss_pss_sha256:
case ssl_sig_rsa_pss_pss_sha384:
case ssl_sig_rsa_pss_pss_sha512:
return PR_TRUE;
default:
@ -4190,6 +4309,41 @@ ssl_IsRsaPssSignatureScheme(SSLSignatureScheme scheme)
return PR_FALSE;
}
SSLAuthType
ssl_SignatureSchemeToAuthType(SSLSignatureScheme scheme)
{
switch (scheme) {
case ssl_sig_rsa_pkcs1_sha1:
case ssl_sig_rsa_pkcs1_sha1md5:
case ssl_sig_rsa_pkcs1_sha256:
case ssl_sig_rsa_pkcs1_sha384:
case ssl_sig_rsa_pkcs1_sha512:
/* We report based on the key type for PSS signatures. */
case ssl_sig_rsa_pss_rsae_sha256:
case ssl_sig_rsa_pss_rsae_sha384:
case ssl_sig_rsa_pss_rsae_sha512:
return ssl_auth_rsa_sign;
case ssl_sig_rsa_pss_pss_sha256:
case ssl_sig_rsa_pss_pss_sha384:
case ssl_sig_rsa_pss_pss_sha512:
return ssl_auth_rsa_pss;
case ssl_sig_ecdsa_secp256r1_sha256:
case ssl_sig_ecdsa_secp384r1_sha384:
case ssl_sig_ecdsa_secp521r1_sha512:
case ssl_sig_ecdsa_sha1:
return ssl_auth_ecdsa;
case ssl_sig_dsa_sha1:
case ssl_sig_dsa_sha256:
case ssl_sig_dsa_sha384:
case ssl_sig_dsa_sha512:
return ssl_auth_dsa;
default:
PORT_Assert(0);
}
return ssl_auth_null;
}
/* ssl_ConsumeSignatureScheme reads a SSLSignatureScheme (formerly
* SignatureAndHashAlgorithm) structure from |b| and puts the resulting value
* into |out|. |b| and |length| are updated accordingly.
@ -5394,6 +5548,7 @@ ssl3_GetWrappingKey(sslSocket *ss,
switch (authType) {
case ssl_auth_rsa_decrypt:
case ssl_auth_rsa_sign: /* bad: see Bug 1248320 */
case ssl_auth_rsa_pss:
asymWrapMechanism = CKM_RSA_PKCS;
rv = PK11_PubWrapSymKey(asymWrapMechanism, svrPubKey,
unwrappedWrappingKey, &wrappedKey);
@ -5843,20 +5998,59 @@ ssl3_SendClientKeyExchange(sslSocket *ss)
return rv; /* err code already set. */
}
/* Used by ssl_PickSignatureScheme(). */
static PRBool
ssl_CanUseSignatureScheme(SSLSignatureScheme scheme,
const SSLSignatureScheme *peerSchemes,
unsigned int peerSchemeCount,
PRBool requireSha1,
PRBool slotDoesPss)
{
SSLHashType hashType;
SECOidTag hashOID;
PRUint32 policy;
unsigned int i;
/* Skip RSA-PSS schemes when the certificate's private key slot does
* not support this signature mechanism. */
if (ssl_IsRsaPssSignatureScheme(scheme) && !slotDoesPss) {
return PR_FALSE;
}
hashType = ssl_SignatureSchemeToHashType(scheme);
if (requireSha1 && (hashType != ssl_hash_sha1)) {
return PR_FALSE;
}
hashOID = ssl3_HashTypeToOID(hashType);
if ((NSS_GetAlgorithmPolicy(hashOID, &policy) == SECSuccess) &&
!(policy & NSS_USE_ALG_IN_SSL_KX)) {
return PR_FALSE;
}
for (i = 0; i < peerSchemeCount; i++) {
if (peerSchemes[i] == scheme) {
return PR_TRUE;
}
}
return PR_FALSE;
}
SECStatus
ssl_PickSignatureScheme(sslSocket *ss,
CERTCertificate *cert,
SECKEYPublicKey *pubKey,
SECKEYPrivateKey *privKey,
const SSLSignatureScheme *peerSchemes,
unsigned int peerSchemeCount,
PRBool requireSha1)
{
unsigned int i, j;
const sslNamedGroupDef *group = NULL;
KeyType keyType;
unsigned int i;
PK11SlotInfo *slot;
PRBool slotDoesPss;
PRBool isTLS13 = ss->version >= SSL_LIBRARY_VERSION_TLS_1_3;
SECStatus rv;
SSLSignatureScheme scheme;
SECOidTag spkiOid;
/* We can't require SHA-1 in TLS 1.3. */
PORT_Assert(!(requireSha1 && isTLS13));
@ -5874,47 +6068,35 @@ ssl_PickSignatureScheme(sslSocket *ss,
slotDoesPss = PK11_DoesMechanism(slot, auth_alg_defs[ssl_auth_rsa_pss]);
PK11_FreeSlot(slot);
keyType = SECKEY_GetPublicKeyType(pubKey);
if (keyType == ecKey) {
group = ssl_ECPubKey2NamedGroup(pubKey);
/* If the certificate SPKI indicates a single scheme, don't search. */
rv = ssl_SignatureSchemeFromSpki(&cert->subjectPublicKeyInfo,
isTLS13, &scheme);
if (rv != SECSuccess) {
return SECFailure;
}
if (scheme != ssl_sig_none) {
if (!ssl_SignatureSchemeEnabled(ss, scheme) ||
!ssl_CanUseSignatureScheme(scheme, peerSchemes, peerSchemeCount,
requireSha1, slotDoesPss)) {
PORT_SetError(SSL_ERROR_UNSUPPORTED_SIGNATURE_ALGORITHM);
return SECFailure;
}
ss->ssl3.hs.signatureScheme = scheme;
return SECSuccess;
}
/* Here we look for the first local preference that the client has
* indicated support for in their signature_algorithms extension. */
spkiOid = SECOID_GetAlgorithmTag(&cert->subjectPublicKeyInfo.algorithm);
/* Now we have to search based on the key type. Go through our preferred
* schemes in order and find the first that can be used. */
for (i = 0; i < ss->ssl3.signatureSchemeCount; ++i) {
SSLHashType hashType;
SECOidTag hashOID;
SSLSignatureScheme preferred = ss->ssl3.signatureSchemes[i];
PRUint32 policy;
scheme = ss->ssl3.signatureSchemes[i];
if (!ssl_SignatureSchemeValidForKey(!isTLS13 /* allowSha1 */,
isTLS13 /* matchGroup */,
keyType, group, preferred)) {
continue;
}
/* Skip RSA-PSS schemes when the certificate's private key slot does
* not support this signature mechanism. */
if (ssl_IsRsaPssSignatureScheme(preferred) && !slotDoesPss) {
continue;
}
hashType = ssl_SignatureSchemeToHashType(preferred);
if (requireSha1 && (hashType != ssl_hash_sha1)) {
continue;
}
hashOID = ssl3_HashTypeToOID(hashType);
if ((NSS_GetAlgorithmPolicy(hashOID, &policy) == SECSuccess) &&
!(policy & NSS_USE_ALG_IN_SSL_KX)) {
/* we ignore hashes we don't support */
continue;
}
for (j = 0; j < peerSchemeCount; j++) {
if (peerSchemes[j] == preferred) {
ss->ssl3.hs.signatureScheme = preferred;
return SECSuccess;
}
if (ssl_SignatureSchemeValid(scheme, spkiOid, isTLS13) &&
ssl_CanUseSignatureScheme(scheme, peerSchemes, peerSchemeCount,
requireSha1, slotDoesPss)) {
ss->ssl3.hs.signatureScheme = scheme;
return SECSuccess;
}
}
@ -5956,17 +6138,19 @@ ssl_PickFallbackSignatureScheme(sslSocket *ss, SECKEYPublicKey *pubKey)
static SECStatus
ssl3_PickServerSignatureScheme(sslSocket *ss)
{
sslKeyPair *keyPair = ss->sec.serverCert->serverKeyPair;
const sslServerCert *cert = ss->sec.serverCert;
PRBool isTLS12 = ss->version >= SSL_LIBRARY_VERSION_TLS_1_2;
if (!isTLS12 || !ssl3_ExtensionNegotiated(ss, ssl_signature_algorithms_xtn)) {
/* If the client didn't provide any signature_algorithms extension then
* we can assume that they support SHA-1: RFC5246, Section 7.4.1.4.1. */
return ssl_PickFallbackSignatureScheme(ss, keyPair->pubKey);
return ssl_PickFallbackSignatureScheme(ss, cert->serverKeyPair->pubKey);
}
/* Sets error code, if needed. */
return ssl_PickSignatureScheme(ss, keyPair->pubKey, keyPair->privKey,
return ssl_PickSignatureScheme(ss, cert->serverCert,
cert->serverKeyPair->pubKey,
cert->serverKeyPair->privKey,
ss->xtnData.sigSchemes,
ss->xtnData.numSigSchemes,
PR_FALSE /* requireSha1 */);
@ -5977,11 +6161,10 @@ ssl_PickClientSignatureScheme(sslSocket *ss, const SSLSignatureScheme *schemes,
unsigned int numSchemes)
{
SECKEYPrivateKey *privKey = ss->ssl3.clientPrivateKey;
SECKEYPublicKey *pubKey;
SECStatus rv;
PRBool isTLS13 = (PRBool)ss->version >= SSL_LIBRARY_VERSION_TLS_1_3;
pubKey = CERT_ExtractPublicKey(ss->ssl3.clientCertificate);
SECKEYPublicKey *pubKey = CERT_ExtractPublicKey(ss->ssl3.clientCertificate);
PORT_Assert(pubKey);
if (!isTLS13 && numSchemes == 0) {
@ -6004,7 +6187,8 @@ ssl_PickClientSignatureScheme(sslSocket *ss, const SSLSignatureScheme *schemes,
* older, DSA key size is at most 1024 bits and the hash function must
* be SHA-1.
*/
rv = ssl_PickSignatureScheme(ss, pubKey, privKey, schemes, numSchemes,
rv = ssl_PickSignatureScheme(ss, ss->ssl3.clientCertificate,
pubKey, privKey, schemes, numSchemes,
PR_TRUE /* requireSha1 */);
if (rv == SECSuccess) {
SECKEY_DestroyPublicKey(pubKey);
@ -6013,7 +6197,8 @@ ssl_PickClientSignatureScheme(sslSocket *ss, const SSLSignatureScheme *schemes,
/* If this fails, that's because the peer doesn't advertise SHA-1,
* so fall back to the full negotiation. */
}
rv = ssl_PickSignatureScheme(ss, pubKey, privKey, schemes, numSchemes,
rv = ssl_PickSignatureScheme(ss, ss->ssl3.clientCertificate,
pubKey, privKey, schemes, numSchemes,
PR_FALSE /* requireSha1 */);
SECKEY_DestroyPublicKey(pubKey);
return rv;
@ -7845,6 +8030,7 @@ ssl3_SelectServerCert(sslSocket *ss)
{
const ssl3KEADef *kea_def = ss->ssl3.hs.kea_def;
PRCList *cursor;
SECStatus rv;
/* If the client didn't include the supported groups extension, assume just
* P-256 support and disable all the other ECDHE groups. This also affects
@ -7870,24 +8056,40 @@ ssl3_SelectServerCert(sslSocket *ss)
cursor != &ss->serverCerts;
cursor = PR_NEXT_LINK(cursor)) {
sslServerCert *cert = (sslServerCert *)cursor;
if (!SSL_CERT_IS(cert, kea_def->authKeyType)) {
continue;
}
if (SSL_CERT_IS_EC(cert) &&
!ssl_NamedGroupEnabled(ss, cert->namedCurve)) {
continue;
if (kea_def->authKeyType == ssl_auth_rsa_sign) {
/* We consider PSS certificates here as well for TLS 1.2. */
if (!SSL_CERT_IS(cert, ssl_auth_rsa_sign) &&
(!SSL_CERT_IS(cert, ssl_auth_rsa_pss) ||
ss->version < SSL_LIBRARY_VERSION_TLS_1_2)) {
continue;
}
} else {
if (!SSL_CERT_IS(cert, kea_def->authKeyType)) {
continue;
}
if (SSL_CERT_IS_EC(cert) &&
!ssl_NamedGroupEnabled(ss, cert->namedCurve)) {
continue;
}
}
/* Found one. */
ss->sec.serverCert = cert;
ss->sec.authType = kea_def->authKeyType;
ss->sec.authKeyBits = cert->serverKeyBits;
/* Don't pick a signature scheme if we aren't going to use it. */
if (kea_def->signKeyType == nullKey) {
ss->sec.authType = kea_def->authKeyType;
return SECSuccess;
}
return ssl3_PickServerSignatureScheme(ss);
rv = ssl3_PickServerSignatureScheme(ss);
if (rv != SECSuccess) {
return SECFailure;
}
ss->sec.authType =
ssl_SignatureSchemeToAuthType(ss->ssl3.hs.signatureScheme);
return SECSuccess;
}
PORT_SetError(SSL_ERROR_NO_CYPHER_OVERLAP);

Просмотреть файл

@ -436,8 +436,6 @@ ssl_GetCertificateAuthTypes(CERTCertificate *cert, SSLAuthType targetAuthType)
case SEC_OID_PKCS1_RSA_ENCRYPTION:
if (cert->keyUsage & KU_DIGITAL_SIGNATURE) {
authTypes |= 1 << ssl_auth_rsa_sign;
/* This certificate is RSA, assume that it's also PSS. */
authTypes |= 1 << ssl_auth_rsa_pss;
}
if (cert->keyUsage & KU_KEY_ENCIPHERMENT) {

Просмотреть файл

@ -1640,6 +1640,7 @@ SECStatus ssl3_FillInCachedSID(sslSocket *ss, sslSessionID *sid,
const ssl3CipherSuiteDef *ssl_LookupCipherSuiteDef(ssl3CipherSuite suite);
SECStatus ssl3_SelectServerCert(sslSocket *ss);
SECStatus ssl_PickSignatureScheme(sslSocket *ss,
CERTCertificate *cert,
SECKEYPublicKey *pubKey,
SECKEYPrivateKey *privKey,
const SSLSignatureScheme *peerSchemes,
@ -1647,7 +1648,7 @@ SECStatus ssl_PickSignatureScheme(sslSocket *ss,
PRBool requireSha1);
SECOidTag ssl3_HashTypeToOID(SSLHashType hashType);
SSLHashType ssl_SignatureSchemeToHashType(SSLSignatureScheme scheme);
KeyType ssl_SignatureSchemeToKeyType(SSLSignatureScheme scheme);
SSLAuthType ssl_SignatureSchemeToAuthType(SSLSignatureScheme scheme);
SECStatus ssl3_SetupCipherSuite(sslSocket *ss, PRBool initHashes);
SECStatus ssl_InsertRecordHeader(const sslSocket *ss, ssl3CipherSpec *cwSpec,

Просмотреть файл

@ -117,6 +117,7 @@ const char kHkdfLabelFinishedSecret[] = "finished";
const char kHkdfLabelResumptionMasterSecret[] = "res master";
const char kHkdfLabelExporterMasterSecret[] = "exp master";
const char kHkdfLabelResumption[] = "resumption";
const char kHkdfLabelTrafficUpdate[] = "traffic upd";
const char kHkdfPurposeKey[] = "key";
const char kHkdfPurposeIv[] = "iv";
@ -603,8 +604,8 @@ tls13_UpdateTrafficKeys(sslSocket *ss, CipherSpecDirection direction)
secret = tls13_TrafficSecretRef(ss, direction);
rv = tls13_HkdfExpandLabel(*secret, tls13_GetHash(ss),
NULL, 0,
kHkdfLabelApplicationTrafficSecret,
strlen(kHkdfLabelApplicationTrafficSecret),
kHkdfLabelTrafficUpdate,
strlen(kHkdfLabelTrafficUpdate),
tls13_GetHmacMechanism(ss),
tls13_GetHashSize(ss),
&updatedSecret);
@ -1417,30 +1418,6 @@ tls13_NegotiateKeyExchange(sslSocket *ss,
return SECSuccess;
}
SSLAuthType
ssl_SignatureSchemeToAuthType(SSLSignatureScheme scheme)
{
switch (scheme) {
case ssl_sig_rsa_pkcs1_sha1:
case ssl_sig_rsa_pkcs1_sha256:
case ssl_sig_rsa_pkcs1_sha384:
case ssl_sig_rsa_pkcs1_sha512:
/* We report PSS signatures as being just RSA signatures. */
case ssl_sig_rsa_pss_rsae_sha256:
case ssl_sig_rsa_pss_rsae_sha384:
case ssl_sig_rsa_pss_rsae_sha512:
return ssl_auth_rsa_sign;
case ssl_sig_ecdsa_secp256r1_sha256:
case ssl_sig_ecdsa_secp384r1_sha384:
case ssl_sig_ecdsa_secp521r1_sha512:
case ssl_sig_ecdsa_sha1:
return ssl_auth_ecdsa;
default:
PORT_Assert(0);
}
return ssl_auth_null;
}
SECStatus
tls13_SelectServerCert(sslSocket *ss)
{
@ -1469,6 +1446,7 @@ tls13_SelectServerCert(sslSocket *ss)
}
rv = ssl_PickSignatureScheme(ss,
cert->serverCert,
cert->serverKeyPair->pubKey,
cert->serverKeyPair->privKey,
ss->xtnData.sigSchemes,

Просмотреть файл

@ -42,29 +42,38 @@ certscript() {
make_cert() {
name=$1
type=$2
unset type_args trust sign
# defaults
type_args=()
trust=',,'
sign=(-x)
sighash=(-Z SHA256)
case $type in
dsa) type_args='-g 1024' ;;
rsa) type_args='-g 1024' ;;
rsa2048) type_args='-g 2048';type=rsa ;;
rsa8192) type_args='-g 8192';type=rsa ;;
rsapss) type_args='-g 1024 --pss';type=rsa ;;
p256) type_args='-q nistp256';type=ec ;;
p384) type_args='-q secp384r1';type=ec ;;
p521) type_args='-q secp521r1';type=ec ;;
rsa_ca) type_args='-g 1024';trust='CT,CT,CT';type=rsa ;;
rsa_chain) type_args='-g 1024';sign='-c rsa_ca';type=rsa;;
rsapss_ca) type_args='-g 1024 --pss';trust='CT,CT,CT';type=rsa ;;
rsapss_chain) type_args='-g 1024';sign='-c rsa_pss_ca';type=rsa;;
rsa_ca_rsapss_chain) type_args='-g 1024 --pss-sign';sign='-c rsa_ca';type=rsa;;
ecdh_rsa) type_args='-q nistp256';sign='-c rsa_ca';type=ec ;;
dsa) type_args=(-g 1024) ;;
rsa) type_args=(-g 1024) ;;
rsa2048) type_args=(-g 2048);type=rsa ;;
rsa8192) type_args=(-g 8192);type=rsa ;;
rsapss) type_args=(-g 1024 --pss);type=rsa ;;
rsapss384) type_args=(-g 1024 --pss);type=rsa;sighash=(-Z SHA384) ;;
rsapss512) type_args=(-g 2048 --pss);type=rsa;sighash=(-Z SHA512) ;;
rsapss_noparam) type_args=(-g 2048 --pss);type=rsa;sighash=() ;;
p256) type_args=(-q nistp256);type=ec ;;
p384) type_args=(-q secp384r1);type=ec ;;
p521) type_args=(-q secp521r1);type=ec ;;
rsa_ca) type_args=(-g 1024);trust='CT,CT,CT';type=rsa ;;
rsa_chain) type_args=(-g 1024);sign=(-c rsa_ca);type=rsa;;
rsapss_ca) type_args=(-g 1024 --pss);trust='CT,CT,CT';type=rsa ;;
rsapss_chain) type_args=(-g 1024);sign=(-c rsa_pss_ca);type=rsa;;
rsa_ca_rsapss_chain) type_args=(-g 1024 --pss-sign);sign=(-c rsa_ca);type=rsa;;
ecdh_rsa) type_args=(-q nistp256);sign=(-c rsa_ca);type=ec ;;
esac
shift 2
counter=$(($counter + 1))
certscript $@ | ${BINDIR}/certutil -S \
-z ${R_NOISE_FILE} -d "${PROFILEDIR}" \
-n $name -s "CN=$name" -t ${trust:-,,} ${sign:--x} -m $counter \
-w -2 -v 120 -k $type $type_args -Z SHA256 -1 -2
-n $name -s "CN=$name" -t "$trust" "${sign[@]}" -m "$counter" \
-w -2 -v 120 -k "$type" "${type_args[@]}" "${sighash[@]}" -1 -2
html_msg $? 0 "create certificate: $@"
}
@ -87,6 +96,9 @@ ssl_gtest_certs() {
make_cert rsa8192 rsa8192 sign kex
make_cert rsa_sign rsa sign
make_cert rsa_pss rsapss sign
make_cert rsa_pss384 rsapss384 sign
make_cert rsa_pss512 rsapss512 sign
make_cert rsa_pss_noparam rsapss_noparam sign
make_cert rsa_decrypt rsa kex
make_cert ecdsa256 p256 sign
make_cert ecdsa384 p384 sign

Просмотреть файл

@ -651,7 +651,10 @@ impl<'le> GeckoElement<'le> {
#[inline]
fn extended_slots(&self) -> Option<&structs::FragmentOrElement_nsExtendedDOMSlots> {
self.dom_slots().and_then(|s| unsafe {
(s._base.mExtendedSlots.mPtr as *const structs::FragmentOrElement_nsExtendedDOMSlots)
// For the bit usage, see nsContentSlots::GetExtendedSlots.
let e_slots = s._base.mExtendedSlots &
!structs::nsIContent_nsContentSlots_sNonOwningExtendedSlotsFlag;
(e_slots as *const structs::FragmentOrElement_nsExtendedDOMSlots)
.as_ref()
})
}

Просмотреть файл

@ -10,6 +10,5 @@
"startup.homepage_override_url": "",
"startup.homepage_welcome_url": "",
"browser.startup.homepage": "about:blank",
"browser.newtabpage.enabled": false,
"security.sandbox.content.level": 0
"browser.newtabpage.enabled": false
}

Просмотреть файл

@ -8,6 +8,5 @@
"network.proxy.type": 1,
"plugin.disable": true,
"startup.homepage_override_url": "",
"startup.homepage_welcome_url": "",
"security.sandbox.content.level": 0
"startup.homepage_welcome_url": ""
}

Просмотреть файл

@ -153,6 +153,7 @@ class AWSY(TestingMixin, MercurialScript, TooltoolMixin, CodeCoverageMixin):
'resultsDir': self.results_dir}
# Check if this is a DMD build and if so enable it.
dmd_enabled = False
dmd_py_lib_dir = os.path.dirname(self.binary_path)
if mozinfo.os == 'mac':
# On mac binary is in MacOS and dmd.py is in Resources, ie:
@ -162,6 +163,7 @@ class AWSY(TestingMixin, MercurialScript, TooltoolMixin, CodeCoverageMixin):
dmd_path = os.path.join(dmd_py_lib_dir, "dmd.py")
if os.path.isfile(dmd_path):
dmd_enabled = True
runtime_testvars['dmd'] = True
# Allow the child process to import dmd.py
@ -208,6 +210,8 @@ class AWSY(TestingMixin, MercurialScript, TooltoolMixin, CodeCoverageMixin):
prefs_file = "prefs.json"
cmd.append("--preferences=%s" % os.path.join(self.awsy_path, "conf", prefs_file))
if dmd_enabled:
cmd.append("--pref=security.sandbox.content.level:0")
cmd.append(test_file)
if self.config['single_stylo_traversal']:

Просмотреть файл

@ -109435,6 +109435,42 @@
{}
]
],
"css/css-content/element-replacement-alt.html": [
[
"/css/css-content/element-replacement-alt.html",
[
[
"/css/css-content/element-replacement-alt-ref.html",
"=="
]
],
{}
]
],
"css/css-content/element-replacement-display-contents.html": [
[
"/css/css-content/element-replacement-display-contents.html",
[
[
"/css/css-content/resources/blank.html",
"=="
]
],
{}
]
],
"css/css-content/element-replacement-display-none.html": [
[
"/css/css-content/element-replacement-display-none.html",
[
[
"/css/css-content/resources/blank.html",
"=="
]
],
{}
]
],
"css/css-content/element-replacement.html": [
[
"/css/css-content/element-replacement.html",
@ -240880,11 +240916,21 @@
{}
]
],
"css/css-content/element-replacement-alt-ref.html": [
[
{}
]
],
"css/css-content/element-replacement-ref.html": [
[
{}
]
],
"css/css-content/resources/blank.html": [
[
{}
]
],
"css/css-content/resources/rect.svg": [
[
{}
@ -502683,6 +502729,22 @@
"6b6cf2c15295940fb8831d17209635dc4e31cd78",
"reftest"
],
"css/css-content/element-replacement-alt-ref.html": [
"6c67290991bc0ca57223e65a995054bae04bca0a",
"support"
],
"css/css-content/element-replacement-alt.html": [
"383ba1ffc142ae6d783cc9300b296b83b4b2521f",
"reftest"
],
"css/css-content/element-replacement-display-contents.html": [
"980d17c7c90c1de3f703423bcf41d0f14d25f4c1",
"reftest"
],
"css/css-content/element-replacement-display-none.html": [
"b30f852673badcc7f9cb8a39cc4a12452d886d6f",
"reftest"
],
"css/css-content/element-replacement-ref.html": [
"f1ad3fca133b1b671e45ae1307fbe9454c40e3ec",
"support"
@ -502691,6 +502753,10 @@
"f491ddf2b3062ea2f9b616c968c88b9cc95f22eb",
"reftest"
],
"css/css-content/resources/blank.html": [
"d96d45f3a57b58460787fcde5fd15ccb324b123c",
"support"
],
"css/css-content/resources/rect.svg": [
"e0c37ea653aee58f962133219edc4484a734c6e0",
"support"
@ -549660,7 +549726,7 @@
"support"
],
"css/mediaqueries/test_media_queries.html": [
"cff3585932589f611a7101329d3b5b6ca27820aa",
"a7d78b13e119f8cd1ffa8812a9af67e59280084d",
"testharness"
],
"css/mediaqueries/viewport-script-dynamic-ref.html": [
@ -561264,7 +561330,7 @@
"support"
],
"docs/assets/pullrequestbtn.png": [
"85e1015ecff6ee444168858cea8cd41804696905",
"41213000ac1fb6ab53c6a1199744ecde452eef55",
"support"
],
"docs/assets/reftest_graph_example.svg": [
@ -618412,7 +618478,7 @@
"testharness"
],
"web-animations/animation-model/animation-types/property-list.js": [
"9416f470f1ac1d320bb4d46461938e85946439e2",
"5a818163c3ddcb6e0901b4f0086d555e9d440e27",
"support"
],
"web-animations/animation-model/animation-types/property-types.js": [

Просмотреть файл

@ -1,2 +0,0 @@
[element-replacement.html]
expected: FAIL

Просмотреть файл

@ -0,0 +1,4 @@
<!DOCTYPE html>
<title>CSS Test Reference</title>
<link rel="author" href="mailto:emilio@crisal.io" title="Emilio Cobos Álvarez">
<div style="content: url(broken);"></div>

Просмотреть файл

@ -0,0 +1,6 @@
<!DOCTYPE html>
<title>The content CSS property with a broken image doesn't pull the alt attribute from that element</title>
<link rel="author" href="mailto:emilio@crisal.io" title="Emilio Cobos Álvarez">
<link rel="match" href="element-replacement-alt-ref.html">
<link rel="help" href="https://drafts.csswg.org/css-content-3/#content-property">
<div style="content: url(broken);" alt="Alt text">FAIL</div>

Просмотреть файл

@ -0,0 +1,12 @@
<!doctype html>
<title>The content CSS property doesn't override display: contents</title>
<link rel="author" href="mailto:emilio@crisal.io" title="Emilio Cobos Álvarez">
<link rel="match" href="resources/blank.html">
<link rel="help" href="https://drafts.csswg.org/css-content-3/#content-property">
<style>
div {
display: contents;
content: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAIAAAD8GO2jAAAAKElEQVR42u3NQQ0AAAgEoNP+nTWFDzcoQE1udQQCgUAgEAgEAsGTYAGjxAE/G/Q2tQAAAABJRU5ErkJggg==);
}
</style>
<div></div>

Просмотреть файл

@ -0,0 +1,12 @@
<!doctype html>
<title>The content CSS property doesn't override display: none</title>
<link rel="author" href="mailto:emilio@crisal.io" title="Emilio Cobos Álvarez">
<link rel="match" href="resources/blank.html">
<link rel="help" href="https://drafts.csswg.org/css-content-3/#content-property">
<style>
div {
display: none;
content: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAIAAAD8GO2jAAAAKElEQVR42u3NQQ0AAAgEoNP+nTWFDzcoQE1udQQCgUAgEAgEAsGTYAGjxAE/G/Q2tQAAAABJRU5ErkJggg==);
}
</style>
<div>FAIL</div>

Просмотреть файл

@ -0,0 +1,4 @@
<!doctype html>
<title>CSS Test Reference</title>
<link rel="author" href="mailto:emilio@crisal.io" title="Emilio Cobos Álvarez">
<!-- Intentionally blank -->

Просмотреть файл

@ -740,13 +740,8 @@ AsyncFetchAndSetIconForPage::OnStopRequest(nsIRequest* aRequest,
nsresult rv;
// If fetching the icon failed, add it to the failed cache.
// If fetching the icon failed, bail out.
if (NS_FAILED(aStatusCode) || mIcon.payloads.Length() == 0) {
nsCOMPtr<nsIURI> iconURI;
rv = NS_NewURI(getter_AddRefs(iconURI), mIcon.spec);
NS_ENSURE_SUCCESS(rv, rv);
rv = favicons->AddFailedFavicon(iconURI);
NS_ENSURE_SUCCESS(rv, rv);
return NS_OK;
}
@ -769,13 +764,8 @@ AsyncFetchAndSetIconForPage::OnStopRequest(nsIRequest* aRequest,
payload.mimeType);
}
// If the icon does not have a valid MIME type, add it to the failed cache.
// If the icon does not have a valid MIME type, bail out.
if (payload.mimeType.IsEmpty()) {
nsCOMPtr<nsIURI> iconURI;
rv = NS_NewURI(getter_AddRefs(iconURI), mIcon.spec);
NS_ENSURE_SUCCESS(rv, rv);
rv = favicons->AddFailedFavicon(iconURI);
NS_ENSURE_SUCCESS(rv, rv);
return NS_OK;
}

Просмотреть файл

@ -33,9 +33,6 @@
#include "NullPrincipal.h"
#include "imgICache.h"
#define MAX_FAILED_FAVICONS 256
#define FAVICON_CACHE_REDUCE_COUNT 64
#define UNASSOCIATED_FAVICONS_LENGTH 32
// When replaceFaviconData is called, we store the icons in an in-memory cache
@ -132,9 +129,7 @@ NS_IMPL_ISUPPORTS_CI(
)
nsFaviconService::nsFaviconService()
: mFailedFaviconSerial(0)
, mFailedFavicons(MAX_FAILED_FAVICONS / 2)
, mUnassociatedIcons(UNASSOCIATED_FAVICONS_LENGTH)
: mUnassociatedIcons(UNASSOCIATED_FAVICONS_LENGTH)
, mDefaultIconURIPreferredSize(UINT16_MAX)
{
NS_ASSERTION(!gFaviconService,
@ -327,19 +322,6 @@ nsFaviconService::SetAndFetchFaviconForPage(nsIURI* aPageURI,
NS_ENSURE_ARG(aFaviconURI);
NS_ENSURE_ARG_POINTER(_canceler);
// If a favicon is in the failed cache, only load it during a forced reload.
bool previouslyFailed;
nsresult rv = IsFailedFavicon(aFaviconURI, &previouslyFailed);
NS_ENSURE_SUCCESS(rv, rv);
if (previouslyFailed) {
if (aForceReload) {
RemoveFailedFavicon(aFaviconURI);
}
else {
return NS_OK;
}
}
nsCOMPtr<nsIPrincipal> loadingPrincipal = aLoadingPrincipal;
MOZ_ASSERT(loadingPrincipal, "please provide aLoadingPrincipal for this favicon");
if (!loadingPrincipal) {
@ -362,7 +344,7 @@ nsFaviconService::SetAndFetchFaviconForPage(nsIURI* aPageURI,
// Build page data.
PageData page;
rv = aPageURI->GetSpec(page.spec);
nsresult rv = aPageURI->GetSpec(page.spec);
NS_ENSURE_SUCCESS(rv, rv);
// URIs can arguably lack a host.
Unused << aPageURI->GetHost(page.host);
@ -709,62 +691,6 @@ nsFaviconService::GetFaviconLinkForIcon(nsIURI* aFaviconURI,
}
NS_IMETHODIMP
nsFaviconService::AddFailedFavicon(nsIURI* aFaviconURI)
{
NS_ENSURE_ARG(aFaviconURI);
nsAutoCString spec;
nsresult rv = aFaviconURI->GetSpec(spec);
NS_ENSURE_SUCCESS(rv, rv);
mFailedFavicons.Put(spec, mFailedFaviconSerial);
mFailedFaviconSerial ++;
if (mFailedFavicons.Count() > MAX_FAILED_FAVICONS) {
// need to expire some entries, delete the FAVICON_CACHE_REDUCE_COUNT number
// of items that are the oldest
uint32_t threshold = mFailedFaviconSerial -
MAX_FAILED_FAVICONS + FAVICON_CACHE_REDUCE_COUNT;
for (auto iter = mFailedFavicons.Iter(); !iter.Done(); iter.Next()) {
if (iter.Data() < threshold) {
iter.Remove();
}
}
}
return NS_OK;
}
NS_IMETHODIMP
nsFaviconService::RemoveFailedFavicon(nsIURI* aFaviconURI)
{
NS_ENSURE_ARG(aFaviconURI);
nsAutoCString spec;
nsresult rv = aFaviconURI->GetSpec(spec);
NS_ENSURE_SUCCESS(rv, rv);
// we silently do nothing and succeed if the icon is not in the cache
mFailedFavicons.Remove(spec);
return NS_OK;
}
NS_IMETHODIMP
nsFaviconService::IsFailedFavicon(nsIURI* aFaviconURI, bool* _retval)
{
NS_ENSURE_ARG(aFaviconURI);
nsAutoCString spec;
nsresult rv = aFaviconURI->GetSpec(spec);
NS_ENSURE_SUCCESS(rv, rv);
uint32_t serial;
*_retval = mFailedFavicons.Get(spec, &serial);
return NS_OK;
}
// nsFaviconService::GetFaviconLinkForIconString
//
// This computes a favicon URL with string input and using the cached

Просмотреть файл

@ -150,9 +150,6 @@ private:
*/
nsCOMPtr<nsIURI> mDefaultIcon;
uint32_t mFailedFaviconSerial;
nsDataHashtable<nsCStringHashKey, uint32_t> mFailedFavicons;
// This class needs access to the icons cache.
friend class mozilla::places::AsyncReplaceFaviconData;
nsTHashtable<UnassociatedIconHashKey> mUnassociatedIcons;

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше