Merge m-c to inbound.

This commit is contained in:
Ryan VanderMeulen 2012-10-18 21:44:09 -04:00
commit 2afc7e809e
15 changed files with 209 additions and 42 deletions

View File

@ -208,3 +208,14 @@
fun:_ZN2js3ion5Range6updateEPKS1_
...
}
{
Bug 803386
Memcheck:Free
fun:_ZdlPv
fun:_ZN16SkMallocPixelRefD0Ev
fun:_ZNK8SkRefCnt16internal_disposeEv
fun:_ZN8SkBitmap10freePixelsEv
fun:_ZN8SkBitmapD1Ev
fun:_ZN7mozilla3gfx5ScaleEPhiiiS1_iiiNS0_13SurfaceFormatE
...
}

View File

@ -54,14 +54,14 @@ public:
void
SetLazyData(const nsAString& aName, const nsAString& aContentType,
uint64_t aLength)
uint64_t aLength, uint64_t aLastModifiedDate)
{
NS_ASSERTION(aLength, "must have length");
mName = aName;
mContentType = aContentType;
mLength = aLength;
mLastModificationDate = aLastModifiedDate;
mIsFile = !aName.IsVoid();
}
@ -70,11 +70,25 @@ public:
return mLength == UINT64_MAX;
}
bool IsDateUnknown() const
{
return mIsFile && mLastModificationDate == UINT64_MAX;
}
protected:
nsDOMFileBase(const nsAString& aName, const nsAString& aContentType,
uint64_t aLength, uint64_t aLastModifiedDate)
: mIsFile(true), mImmutable(false), mContentType(aContentType),
mName(aName), mStart(0), mLength(aLength), mLastModificationDate(aLastModifiedDate)
{
// Ensure non-null mContentType by default
mContentType.SetIsVoid(false);
}
nsDOMFileBase(const nsAString& aName, const nsAString& aContentType,
uint64_t aLength)
: mIsFile(true), mImmutable(false), mContentType(aContentType),
mName(aName), mStart(0), mLength(aLength)
mName(aName), mStart(0), mLength(aLength), mLastModificationDate(UINT64_MAX)
{
// Ensure non-null mContentType by default
mContentType.SetIsVoid(false);
@ -82,7 +96,7 @@ protected:
nsDOMFileBase(const nsAString& aContentType, uint64_t aLength)
: mIsFile(false), mImmutable(false), mContentType(aContentType),
mStart(0), mLength(aLength)
mStart(0), mLength(aLength), mLastModificationDate(UINT64_MAX)
{
// Ensure non-null mContentType by default
mContentType.SetIsVoid(false);
@ -91,7 +105,7 @@ protected:
nsDOMFileBase(const nsAString& aContentType, uint64_t aStart,
uint64_t aLength)
: mIsFile(false), mImmutable(false), mContentType(aContentType),
mStart(aStart), mLength(aLength)
mStart(aStart), mLength(aLength), mLastModificationDate(UINT64_MAX)
{
NS_ASSERTION(aLength != UINT64_MAX,
"Must know length when creating slice");
@ -127,12 +141,15 @@ protected:
bool mIsFile;
bool mImmutable;
nsString mContentType;
nsString mName;
uint64_t mStart;
uint64_t mLength;
uint64_t mLastModificationDate;
// Protected by IndexedDatabaseManager::FileMutex()
nsTArray<nsRefPtr<FileInfo> > mFileInfos;
};
@ -140,6 +157,11 @@ protected:
class nsDOMFile : public nsDOMFileBase
{
public:
nsDOMFile(const nsAString& aName, const nsAString& aContentType,
uint64_t aLength, uint64_t aLastModifiedDate)
: nsDOMFileBase(aName, aContentType, aLength, aLastModifiedDate)
{ }
nsDOMFile(const nsAString& aName, const nsAString& aContentType,
uint64_t aLength)
: nsDOMFileBase(aName, aContentType, aLength)
@ -183,7 +205,7 @@ class nsDOMFileFile : public nsDOMFile,
public:
// Create as a file
nsDOMFileFile(nsIFile *aFile)
: nsDOMFile(EmptyString(), EmptyString(), UINT64_MAX),
: nsDOMFile(EmptyString(), EmptyString(), UINT64_MAX, UINT64_MAX),
mFile(aFile), mWholeFile(true), mStoredFile(false)
{
NS_ASSERTION(mFile, "must have file");
@ -195,7 +217,15 @@ public:
// Create as a file
nsDOMFileFile(const nsAString& aName, const nsAString& aContentType,
uint64_t aLength, nsIFile *aFile)
: nsDOMFile(aName, aContentType, aLength),
: nsDOMFile(aName, aContentType, aLength, UINT64_MAX),
mFile(aFile), mWholeFile(true), mStoredFile(false)
{
NS_ASSERTION(mFile, "must have file");
}
nsDOMFileFile(const nsAString& aName, const nsAString& aContentType,
uint64_t aLength, nsIFile *aFile, uint64_t aLastModificationDate)
: nsDOMFile(aName, aContentType, aLength, aLastModificationDate),
mFile(aFile), mWholeFile(true), mStoredFile(false)
{
NS_ASSERTION(mFile, "must have file");
@ -213,7 +243,7 @@ public:
// Create as a file with custom name
nsDOMFileFile(nsIFile *aFile, const nsAString& aName)
: nsDOMFile(aName, EmptyString(), UINT64_MAX),
: nsDOMFile(aName, EmptyString(), UINT64_MAX, UINT64_MAX),
mFile(aFile), mWholeFile(true), mStoredFile(false)
{
NS_ASSERTION(mFile, "must have file");
@ -225,7 +255,7 @@ public:
nsDOMFileFile(const nsAString& aName, const nsAString& aContentType,
uint64_t aLength, nsIFile* aFile,
FileInfo* aFileInfo)
: nsDOMFile(aName, aContentType, aLength),
: nsDOMFile(aName, aContentType, aLength, UINT64_MAX),
mFile(aFile), mWholeFile(true), mStoredFile(true)
{
NS_ASSERTION(mFile, "must have file");
@ -244,7 +274,7 @@ public:
// Create as a file to be later initialized
nsDOMFileFile()
: nsDOMFile(EmptyString(), EmptyString(), UINT64_MAX),
: nsDOMFile(EmptyString(), EmptyString(), UINT64_MAX, UINT64_MAX),
mWholeFile(true), mStoredFile(false)
{
// Lazily get the content type and size
@ -264,7 +294,8 @@ public:
// Overrides
NS_IMETHOD GetSize(uint64_t* aSize);
NS_IMETHOD GetType(nsAString& aType);
NS_IMETHOD GetLastModifiedDate(JSContext* cx, JS::Value *aLastModifiedDate);
NS_IMETHOD GetLastModifiedDate(JSContext* cx, JS::Value* aLastModifiedDate);
NS_IMETHOD GetMozLastModifiedDate(uint64_t* aLastModifiedDate);
NS_IMETHOD GetMozFullPathInternal(nsAString& aFullPath);
NS_IMETHOD GetInternalStream(nsIInputStream**);
@ -328,7 +359,7 @@ public:
uint64_t aLength,
const nsAString& aName,
const nsAString& aContentType)
: nsDOMFile(aName, aContentType, aLength),
: nsDOMFile(aName, aContentType, aLength, UINT64_MAX),
mDataOwner(new DataOwner(aMemoryBuffer))
{
NS_ASSERTION(mDataOwner && mDataOwner->mData, "must have data");

View File

@ -28,7 +28,7 @@ interface nsIURI;
interface nsIPrincipal;
interface nsIDOMBlob;
[scriptable, builtinclass, uuid(16e3f8d1-7f31-48cc-93f5-9c931a977cf6)]
[scriptable, builtinclass, uuid(52d22585-7737-460e-9731-c658df03304a)]
interface nsIDOMBlob : nsISupports
{
readonly attribute unsigned long long size;
@ -73,4 +73,6 @@ interface nsIDOMFile : nsIDOMBlob
// This performs no security checks!
[noscript] readonly attribute DOMString mozFullPathInternal;
[noscript] readonly attribute uint64_t mozLastModifiedDate;
};

View File

@ -888,11 +888,15 @@ nsIContent::PreHandleEvent(nsEventChainPreVisitor& aVisitor)
// Event may need to be retargeted if this is the root of a native
// anonymous content subtree or event is dispatched somewhere inside XBL.
if (isAnonForEvents) {
#ifdef DEBUG
// If a DOM event is explicitly dispatched using node.dispatchEvent(), then
// all the events are allowed even in the native anonymous content..
NS_ASSERTION(aVisitor.mEvent->eventStructType != NS_MUTATION_EVENT ||
nsCOMPtr<nsIContent> t = do_QueryInterface(aVisitor.mEvent->originalTarget);
NS_ASSERTION(!t || !t->ChromeOnlyAccess() ||
aVisitor.mEvent->eventStructType != NS_MUTATION_EVENT ||
aVisitor.mDOMEvent,
"Mutation event dispatched in native anonymous content!?!");
#endif
aVisitor.mEventTargetAtParent = parent;
} else if (parent && aVisitor.mOriginalTargetIsInAnon) {
nsCOMPtr<nsIContent> content(do_QueryInterface(aVisitor.mEvent->target));

View File

@ -174,6 +174,14 @@ nsDOMFileBase::GetType(nsAString &aType)
return NS_OK;
}
NS_IMETHODIMP
nsDOMFileBase::GetMozLastModifiedDate(uint64_t* aLastModifiedDate)
{
NS_ASSERTION(mIsFile, "Should only be called on files");
*aLastModifiedDate = mLastModificationDate;
return NS_OK;
}
// Makes sure that aStart and aEnd is less then or equal to aSize and greater
// than 0
static void
@ -498,10 +506,20 @@ nsDOMFileFile::GetMozFullPathInternal(nsAString &aFilename)
}
NS_IMETHODIMP
nsDOMFileFile::GetLastModifiedDate(JSContext* cx, JS::Value *aLastModifiedDate)
nsDOMFileFile::GetLastModifiedDate(JSContext* cx, JS::Value* aLastModifiedDate)
{
NS_ASSERTION(mIsFile, "Should only be called on files");
PRTime msecs;
mFile->GetLastModifiedTime(&msecs);
if (IsDateUnknown()) {
nsresult rv = mFile->GetLastModifiedTime(&msecs);
NS_ENSURE_SUCCESS(rv, rv);
mLastModificationDate = msecs;
} else {
msecs = mLastModificationDate;
}
JSObject* date = JS_NewDateObjectMsec(cx, msecs);
if (date) {
aLastModifiedDate->setObject(*date);
@ -562,6 +580,14 @@ nsDOMFileFile::GetType(nsAString &aType)
return NS_OK;
}
NS_IMETHODIMP
nsDOMFileFile::GetMozLastModifiedDate(uint64_t* aLastModifiedDate)
{
NS_ASSERTION(mIsFile, "Should only be called on files");
*aLastModifiedDate = mLastModificationDate;
return NS_OK;
}
const uint32_t sFileStreamFlags =
nsIFileInputStream::CLOSE_ON_EOF |
nsIFileInputStream::REOPEN_ON_REWIND |

View File

@ -10,14 +10,21 @@
namespace mozilla {
namespace dom {
// CHANGING THE ORDER/PLACEMENT OF EXISTING ENUM VALUES MAY BREAK INDEXEDDB.
// PROCEED WITH EXTREME CAUTION.
enum StructuredCloneTags {
SCTAG_BASE = JS_SCTAG_USER_MIN,
// These tags are used only for main thread structured clone.
SCTAG_DOM_BLOB,
SCTAG_DOM_FILE,
// This tag is obsolete and exists only for backwards compatibility with
// existing IndexedDB databases.
SCTAG_DOM_FILE_WITHOUT_LASTMODIFIEDDATE,
SCTAG_DOM_FILELIST,
SCTAG_DOM_FILEHANDLE,
SCTAG_DOM_FILE,
// These tags are used for both main thread and workers.
SCTAG_DOM_IMAGEDATA,

View File

@ -175,9 +175,11 @@ DeviceStorageRequestParent::PostSuccessEvent::CancelableRun() {
DeviceStorageRequestParent::PostBlobSuccessEvent::PostBlobSuccessEvent(DeviceStorageRequestParent* aParent,
DeviceStorageFile* aFile,
uint32_t aLength,
nsACString& aMimeType)
nsACString& aMimeType,
uint64_t aLastModifiedDate)
: CancelableRunnable(aParent)
, mLength(aLength)
, mLastModificationDate(aLastModifiedDate)
, mFile(aFile)
, mMimeType(aMimeType)
{
@ -192,7 +194,7 @@ DeviceStorageRequestParent::PostBlobSuccessEvent::CancelableRun() {
nsString mime;
CopyASCIItoUTF16(mMimeType, mime);
nsCOMPtr<nsIDOMBlob> blob = new nsDOMFileFile(mFile->mPath, mime, mLength, mFile->mFile);
nsCOMPtr<nsIDOMBlob> blob = new nsDOMFileFile(mFile->mPath, mime, mLength, mFile->mFile, mLastModificationDate);
ContentParent* cp = static_cast<ContentParent*>(mParent->Manager());
BlobParent* actor = cp->GetOrCreateActorForBlob(blob);
@ -374,7 +376,15 @@ DeviceStorageRequestParent::ReadFileEvent::CancelableRun()
return NS_OK;
}
r = new PostBlobSuccessEvent(mParent, mFile, fileSize, mMimeType);
PRTime modDate;
rv = mFile->mFile->GetLastModifiedTime(&modDate);
if (NS_FAILED(rv)) {
r = new PostErrorEvent(mParent, POST_ERROR_EVENT_UNKNOWN);
NS_DispatchToMainThread(r);
return NS_OK;
}
r = new PostBlobSuccessEvent(mParent, mFile, fileSize, mMimeType, modDate);
NS_DispatchToMainThread(r);
return NS_OK;
}

View File

@ -86,11 +86,12 @@ private:
class PostBlobSuccessEvent : public CancelableRunnable
{
public:
PostBlobSuccessEvent(DeviceStorageRequestParent* aParent, DeviceStorageFile* aFile, uint32_t aLength, nsACString& aMimeType);
PostBlobSuccessEvent(DeviceStorageRequestParent* aParent, DeviceStorageFile* aFile, uint32_t aLength, nsACString& aMimeType, uint64_t aLastModifiedDate);
virtual ~PostBlobSuccessEvent();
virtual nsresult CancelableRun();
private:
uint32_t mLength;
uint64_t mLastModificationDate;
nsRefPtr<DeviceStorageFile> mFile;
nsCString mMimeType;
};

View File

@ -61,6 +61,9 @@ function getSuccess(e) {
ok(navigator.getDeviceStorage, "Should have getDeviceStorage");
ok(e.target.result.name == gFileName, "File name should match");
ok(e.target.result.size > 0, "File size be greater than zero");
ok(e.target.result.type, "File should have a mime type");
ok(e.target.result.lastModifiedDate, "File should have a last modified date");
var name = e.target.result.name;

View File

@ -604,12 +604,14 @@ ActorFromRemoteBlob(nsIDOMBlob* aBlob)
inline
bool
ResolveMysteryBlob(nsIDOMBlob* aBlob, const nsString& aName,
const nsString& aContentType, uint64_t aSize)
ResolveMysteryFile(nsIDOMBlob* aBlob, const nsString& aName,
const nsString& aContentType, uint64_t aSize,
uint64_t aLastModifiedDate)
{
BlobChild* actor = ActorFromRemoteBlob(aBlob);
if (actor) {
return actor->SetMysteryBlobInfo(aName, aContentType, aSize);
return actor->SetMysteryBlobInfo(aName, aContentType,
aSize, aLastModifiedDate);
}
return true;
}
@ -1095,7 +1097,18 @@ IDBObjectStore::StructuredCloneReadCallback(JSContext* aCx,
uint32_t aData,
void* aClosure)
{
if (aTag == SCTAG_DOM_FILEHANDLE || aTag == SCTAG_DOM_BLOB ||
// We need to statically assert that our tag values are what we expect
// so that if people accidentally change them they notice.
MOZ_STATIC_ASSERT(SCTAG_DOM_BLOB == 0xFFFF8001 &&
SCTAG_DOM_FILE_WITHOUT_LASTMODIFIEDDATE == 0xFFFF8002 &&
SCTAG_DOM_FILEHANDLE == 0xFFFF8004 &&
SCTAG_DOM_FILE == 0xFFFF8005,
"You changed our structured clone tag values and just ate "
"everyone's IndexedDB data. I hope you are happy.");
if (aTag == SCTAG_DOM_FILE_WITHOUT_LASTMODIFIEDDATE ||
aTag == SCTAG_DOM_FILEHANDLE ||
aTag == SCTAG_DOM_BLOB ||
aTag == SCTAG_DOM_FILE) {
StructuredCloneReadInfo* cloneReadInfo =
reinterpret_cast<StructuredCloneReadInfo*>(aClosure);
@ -1141,6 +1154,7 @@ IDBObjectStore::StructuredCloneReadCallback(JSContext* aCx,
return JSVAL_TO_OBJECT(wrappedFileHandle);
}
// If it's not a FileHandle, it's a Blob or a File.
uint64_t size;
if (!JS_ReadBytes(aReader, &size, sizeof(uint64_t))) {
NS_WARNING("Failed to read size!");
@ -1196,7 +1210,15 @@ IDBObjectStore::StructuredCloneReadCallback(JSContext* aCx,
return JSVAL_TO_OBJECT(wrappedBlob);
}
NS_ASSERTION(aTag == SCTAG_DOM_FILE, "Huh?!");
NS_ASSERTION(aTag == SCTAG_DOM_FILE ||
aTag == SCTAG_DOM_FILE_WITHOUT_LASTMODIFIEDDATE, "Huh?!");
uint64_t lastModifiedDate = UINT64_MAX;
if (aTag != SCTAG_DOM_FILE_WITHOUT_LASTMODIFIEDDATE &&
!JS_ReadBytes(aReader, &lastModifiedDate, sizeof(lastModifiedDate))) {
NS_WARNING("Failed to read lastModifiedDate");
return nullptr;
}
nsCString name;
if (!StructuredCloneReadString(aReader, name)) {
@ -1206,7 +1228,7 @@ IDBObjectStore::StructuredCloneReadCallback(JSContext* aCx,
nsCOMPtr<nsIDOMFile> domFile;
if (file.mFile) {
if (!ResolveMysteryBlob(file.mFile, convName, convType, size)) {
if (!ResolveMysteryFile(file.mFile, convName, convType, size, lastModifiedDate)) {
return nullptr;
}
domFile = do_QueryInterface(file.mFile);
@ -1320,6 +1342,14 @@ IDBObjectStore::StructuredCloneWriteCallback(JSContext* aCx,
}
if (file) {
uint64_t lastModifiedDate = 0;
if (NS_FAILED(file->GetMozLastModifiedDate(&lastModifiedDate))) {
NS_WARNING("Failed to get last modified date!");
return false;
}
lastModifiedDate = SwapBytes(lastModifiedDate);
nsString name;
if (NS_FAILED(file->GetName(name))) {
NS_WARNING("Failed to get name!");
@ -1328,7 +1358,8 @@ IDBObjectStore::StructuredCloneWriteCallback(JSContext* aCx,
NS_ConvertUTF16toUTF8 convName(name);
uint32_t convNameLength = SwapBytes(convName.Length());
if (!JS_WriteBytes(aWriter, &convNameLength, sizeof(convNameLength)) ||
if (!JS_WriteBytes(aWriter, &lastModifiedDate, sizeof(lastModifiedDate)) ||
!JS_WriteBytes(aWriter, &convNameLength, sizeof(convNameLength)) ||
!JS_WriteBytes(aWriter, convName.get(), convName.Length())) {
return false;
}

View File

@ -584,6 +584,13 @@ private:
public:
NS_DECL_ISUPPORTS_INHERITED
RemoteBlob(const nsAString& aName, const nsAString& aContentType,
uint64_t aLength, uint64_t aModDate)
: nsDOMFile(aName, aContentType, aLength, aModDate), mActor(nullptr)
{
mImmutable = true;
}
RemoteBlob(const nsAString& aName, const nsAString& aContentType,
uint64_t aLength)
: nsDOMFile(aName, aContentType, aLength), mActor(nullptr)
@ -598,7 +605,8 @@ public:
}
RemoteBlob()
: nsDOMFile(EmptyString(), EmptyString(), UINT64_MAX), mActor(nullptr)
: nsDOMFile(EmptyString(), EmptyString(), UINT64_MAX, UINT64_MAX)
, mActor(nullptr)
{
mImmutable = true;
}
@ -651,6 +659,21 @@ public:
{
return static_cast<typename ActorType::ProtocolType*>(mActor);
}
NS_IMETHOD
GetLastModifiedDate(JSContext* cx, JS::Value* aLastModifiedDate)
{
if (IsDateUnknown()) {
aLastModifiedDate->setNull();
} else {
JSObject* date = JS_NewDateObjectMsec(cx, mLastModificationDate);
if (!date) {
return NS_ERROR_OUT_OF_MEMORY;
}
aLastModifiedDate->setObject(*date);
}
return NS_OK;
}
};
template <ActorFlavorEnum ActorFlavor>
@ -686,7 +709,7 @@ Blob<ActorFlavor>::Blob(const BlobConstructorParams& aParams)
aParams.get_FileBlobConstructorParams();
remoteBlob =
new RemoteBlobType(params.name(), params.contentType(),
params.length());
params.length(), params.modDate());
mBlobIsFile = true;
break;
}
@ -770,16 +793,20 @@ template <ActorFlavorEnum ActorFlavor>
bool
Blob<ActorFlavor>::SetMysteryBlobInfo(const nsString& aName,
const nsString& aContentType,
uint64_t aLength)
uint64_t aLength,
uint64_t aLastModifiedDate)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(mBlob);
MOZ_ASSERT(mRemoteBlob);
MOZ_ASSERT(aLength);
MOZ_ASSERT(aLastModifiedDate != UINT64_MAX);
ToConcreteBlob(mBlob)->SetLazyData(aName, aContentType, aLength);
ToConcreteBlob(mBlob)->SetLazyData(aName, aContentType,
aLength, aLastModifiedDate);
FileBlobConstructorParams params(aName, aContentType, aLength);
FileBlobConstructorParams params(aName, aContentType,
aLength, aLastModifiedDate);
return ProtocolType::SendResolveMystery(params);
}
@ -796,7 +823,8 @@ Blob<ActorFlavor>::SetMysteryBlobInfo(const nsString& aContentType,
nsString voidString;
voidString.SetIsVoid(true);
ToConcreteBlob(mBlob)->SetLazyData(voidString, aContentType, aLength);
ToConcreteBlob(mBlob)->SetLazyData(voidString, aContentType,
aLength, UINT64_MAX);
NormalBlobConstructorParams params(aContentType, aLength);
return ProtocolType::SendResolveMystery(params);
@ -890,14 +918,16 @@ Blob<ActorFlavor>::RecvResolveMystery(const ResolveMysteryParams& aParams)
aParams.get_NormalBlobConstructorParams();
nsString voidString;
voidString.SetIsVoid(true);
blob->SetLazyData(voidString, params.contentType(), params.length());
blob->SetLazyData(voidString, params.contentType(),
params.length(), UINT64_MAX);
break;
}
case ResolveMysteryParams::TFileBlobConstructorParams: {
const FileBlobConstructorParams& params =
aParams.get_FileBlobConstructorParams();
blob->SetLazyData(params.name(), params.contentType(), params.length());
blob->SetLazyData(params.name(), params.contentType(),
params.length(), params.modDate());
break;
}

View File

@ -173,7 +173,7 @@ public:
// Use this for files.
bool
SetMysteryBlobInfo(const nsString& aName, const nsString& aContentType,
uint64_t aLength);
uint64_t aLength, uint64_t aLastModifiedDate);
// Use this for non-file blobs.
bool

View File

@ -540,9 +540,11 @@ ContentChild::GetOrCreateActorForBlob(nsIDOMBlob* aBlob)
BlobConstructorParams params;
if (blob->IsSizeUnknown()) {
// We don't want to call GetSize yet since that may stat a file on the main
// thread here. Instead we'll learn the size lazily from the other process.
if (blob->IsSizeUnknown() || blob->IsDateUnknown()) {
// We don't want to call GetSize or GetLastModifiedDate
// yet since that may stat a file on the main thread
// here. Instead we'll learn the size lazily from the
// other process.
params = MysteryBlobConstructorParams();
}
else {
@ -561,6 +563,9 @@ ContentChild::GetOrCreateActorForBlob(nsIDOMBlob* aBlob)
rv = file->GetName(fileParams.name());
NS_ENSURE_SUCCESS(rv, nullptr);
rv = file->GetMozLastModifiedDate(&fileParams.modDate());
NS_ENSURE_SUCCESS(rv, nullptr);
fileParams.contentType() = contentType;
fileParams.length() = length;

View File

@ -1238,9 +1238,11 @@ ContentParent::GetOrCreateActorForBlob(nsIDOMBlob* aBlob)
BlobConstructorParams params;
if (blob->IsSizeUnknown()) {
// We don't want to call GetSize yet since that may stat a file on the main
// thread here. Instead we'll learn the size lazily from the other process.
if (blob->IsSizeUnknown() || /*blob->IsDateUnknown()*/ 0) {
// We don't want to call GetSize or GetLastModifiedDate
// yet since that may stat a file on the main thread
// here. Instead we'll learn the size lazily from the
// other process.
params = MysteryBlobConstructorParams();
}
else {
@ -1256,6 +1258,9 @@ ContentParent::GetOrCreateActorForBlob(nsIDOMBlob* aBlob)
if (file) {
FileBlobConstructorParams fileParams;
rv = file->GetMozLastModifiedDate(&fileParams.modDate());
NS_ENSURE_SUCCESS(rv, nullptr);
rv = file->GetName(fileParams.name());
NS_ENSURE_SUCCESS(rv, nullptr);

View File

@ -28,6 +28,7 @@ struct FileBlobConstructorParams
nsString name;
nsString contentType;
uint64_t length;
uint64_t modDate;
};
} // namespace dom