Backed out changeset 18b3c95f1a38 (bug 906420)

--HG--
extra : rebase_source : 2cb14884f71aa8a41e56c935abe93755b0b0d8db
This commit is contained in:
Carsten "Tomcat" Book 2016-06-09 15:30:35 +02:00
parent fc905af611
commit ed14bc0dce
6 changed files with 69 additions and 123 deletions

View File

@ -323,10 +323,6 @@ DataTransfer::GetTypes(ErrorResult& aRv) const
DataTransferItem* item = items->ElementAt(i); DataTransferItem* item = items->ElementAt(i);
MOZ_ASSERT(item); MOZ_ASSERT(item);
if (item->ChromeOnly() && !nsContentUtils::LegacyIsCallerChromeOrNativeCode()) {
continue;
}
nsAutoString type; nsAutoString type;
item->GetType(type); item->GetType(type);
if (NS_WARN_IF(!types->Add(type))) { if (NS_WARN_IF(!types->Add(type))) {
@ -542,26 +538,13 @@ DataTransfer::MozTypesAt(uint32_t aIndex, ErrorResult& aRv) const
// note that you can retrieve the types regardless of their principal // note that you can retrieve the types regardless of their principal
const nsTArray<RefPtr<DataTransferItem>>& items = *mItems->MozItemsAt(aIndex); const nsTArray<RefPtr<DataTransferItem>>& items = *mItems->MozItemsAt(aIndex);
bool addFile = false;
for (uint32_t i = 0; i < items.Length(); i++) { for (uint32_t i = 0; i < items.Length(); i++) {
if (items[i]->ChromeOnly() && !nsContentUtils::LegacyIsCallerChromeOrNativeCode()) {
continue;
}
nsAutoString type; nsAutoString type;
items[i]->GetType(type); items[i]->GetType(type);
if (NS_WARN_IF(!types->Add(type))) { if (NS_WARN_IF(!types->Add(type))) {
aRv.Throw(NS_ERROR_FAILURE); aRv.Throw(NS_ERROR_FAILURE);
return nullptr; return nullptr;
} }
if (items[i]->Kind() == DataTransferItem::KIND_FILE) {
addFile = true;
}
}
if (addFile) {
types->Add(NS_LITERAL_STRING("Files"));
} }
} }
@ -611,6 +594,16 @@ DataTransfer::GetDataAtInternal(const nsAString& aFormat, uint32_t aIndex,
nsAutoString format; nsAutoString format;
GetRealFormat(aFormat, format); GetRealFormat(aFormat, format);
const nsTArray<RefPtr<DataTransferItem>>& items = *mItems->MozItemsAt(aIndex);
if (!aFormat.EqualsLiteral(kFileMime) &&
!nsContentUtils::IsSystemPrincipal(aSubjectPrincipal)) {
for (uint32_t i = 0; i < items.Length(); ++i) {
if (items[i]->IsFile()) {
return NS_OK;
}
}
}
// Check if the caller is allowed to access the drag data. Callers with // Check if the caller is allowed to access the drag data. Callers with
// chrome privileges can always read the data. During the // chrome privileges can always read the data. During the
// drop event, allow retrieving the data except in the case where the // drop event, allow retrieving the data except in the case where the
@ -629,11 +622,6 @@ DataTransfer::GetDataAtInternal(const nsAString& aFormat, uint32_t aIndex,
return NS_OK; return NS_OK;
} }
// If we have chrome only content, and we aren't chrome, don't allow access
if (!nsContentUtils::IsSystemPrincipal(aSubjectPrincipal) && item->ChromeOnly()) {
return NS_OK;
}
if (item->Principal() && checkFormatItemPrincipal && if (item->Principal() && checkFormatItemPrincipal &&
!aSubjectPrincipal->Subsumes(item->Principal())) { !aSubjectPrincipal->Subsumes(item->Principal())) {
return NS_ERROR_DOM_SECURITY_ERR; return NS_ERROR_DOM_SECURITY_ERR;
@ -1256,10 +1244,7 @@ DataTransfer::SetDataWithPrincipal(const nsAString& aFormat,
ErrorResult rv; ErrorResult rv;
RefPtr<DataTransferItem> item = RefPtr<DataTransferItem> item =
mItems->SetDataWithPrincipal(format, aData, aIndex, aPrincipal, mItems->SetDataWithPrincipal(format, aData, aIndex, aPrincipal, false, rv);
/* aInsertOnly = */ false,
/* aHidden= */ false,
rv);
return rv.StealNSResult(); return rv.StealNSResult();
} }
@ -1297,39 +1282,24 @@ DataTransfer::GetRealFormat(const nsAString& aInFormat,
aOutFormat.Assign(lowercaseFormat); aOutFormat.Assign(lowercaseFormat);
} }
nsresult void
DataTransfer::CacheExternalData(const char* aFormat, uint32_t aIndex, DataTransfer::CacheExternalData(const char* aFormat, uint32_t aIndex,
nsIPrincipal* aPrincipal, bool aHidden) nsIPrincipal* aPrincipal)
{ {
ErrorResult rv;
RefPtr<DataTransferItem> item;
if (strcmp(aFormat, kUnicodeMime) == 0) { if (strcmp(aFormat, kUnicodeMime) == 0) {
item = mItems->SetDataWithPrincipal(NS_LITERAL_STRING("text/plain"), nullptr, SetDataWithPrincipal(NS_LITERAL_STRING("text/plain"), nullptr, aIndex,
aIndex, aPrincipal, false, aHidden, rv); aPrincipal);
if (NS_WARN_IF(rv.Failed())) { return;
return rv.StealNSResult();
}
return NS_OK;
} }
if (strcmp(aFormat, kURLDataMime) == 0) { if (strcmp(aFormat, kURLDataMime) == 0) {
item = mItems->SetDataWithPrincipal(NS_LITERAL_STRING("text/uri-list"), nullptr, SetDataWithPrincipal(NS_LITERAL_STRING("text/uri-list"), nullptr, aIndex,
aIndex, aPrincipal, false, aHidden, rv); aPrincipal);
if (NS_WARN_IF(rv.Failed())) { return;
return rv.StealNSResult();
}
return NS_OK;
} }
nsAutoString format; SetDataWithPrincipal(NS_ConvertUTF8toUTF16(aFormat), nullptr, aIndex,
GetRealFormat(NS_ConvertUTF8toUTF16(aFormat), format); aPrincipal);
item = mItems->SetDataWithPrincipal(format, nullptr, aIndex,
aPrincipal, false, aHidden, rv);
if (NS_WARN_IF(rv.Failed())) {
return rv.StealNSResult();
}
return NS_OK;
} }
// there isn't a way to get a list of the formats that might be available on // there isn't a way to get a list of the formats that might be available on
@ -1367,9 +1337,6 @@ DataTransfer::CacheExternalDragFormats()
uint32_t count; uint32_t count;
dragSession->GetNumDropItems(&count); dragSession->GetNumDropItems(&count);
for (uint32_t c = 0; c < count; c++) { for (uint32_t c = 0; c < count; c++) {
bool hasFileData = false;
dragSession->IsDataFlavorSupported(kFileMime, &hasFileData);
// First, check for the special format that holds custom types. // First, check for the special format that holds custom types.
bool supported; bool supported;
dragSession->IsDataFlavorSupported(kCustomTypesMime, &supported); dragSession->IsDataFlavorSupported(kCustomTypesMime, &supported);
@ -1387,7 +1354,7 @@ DataTransfer::CacheExternalDragFormats()
// if the format is supported, add an item to the array with null as // if the format is supported, add an item to the array with null as
// the data. When retrieved, GetRealData will read the data. // the data. When retrieved, GetRealData will read the data.
if (supported) { if (supported) {
CacheExternalData(kFormats[f], c, sysPrincipal, /* hidden = */ f && hasFileData); CacheExternalData(kFormats[f], c, sysPrincipal);
} }
} }
} }
@ -1413,11 +1380,6 @@ DataTransfer::CacheExternalClipboardFormats()
nsCOMPtr<nsIPrincipal> sysPrincipal; nsCOMPtr<nsIPrincipal> sysPrincipal;
ssm->GetSystemPrincipal(getter_AddRefs(sysPrincipal)); ssm->GetSystemPrincipal(getter_AddRefs(sysPrincipal));
// Check if the clipboard has any files
bool hasFileData = false;
const char *fileMime[] = { kFileMime };
clipboard->HasDataMatchingFlavors(fileMime, 1, mClipboardType, &hasFileData);
// there isn't a way to get a list of the formats that might be available on // there isn't a way to get a list of the formats that might be available on
// all platforms, so just check for the types that can actually be imported. // all platforms, so just check for the types that can actually be imported.
// Note that the loop below assumes that kCustomTypesMime will be first. // Note that the loop below assumes that kCustomTypesMime will be first.
@ -1436,8 +1398,7 @@ DataTransfer::CacheExternalClipboardFormats()
if (f == 0) { if (f == 0) {
FillInExternalCustomTypes(0, sysPrincipal); FillInExternalCustomTypes(0, sysPrincipal);
} else { } else {
// If we aren't the file data, and we have file data, we want to be hidden CacheExternalData(formats[f], 0, sysPrincipal);
CacheExternalData(formats[f], 0, sysPrincipal, /* hidden = */ f != 1 && hasFileData);
} }
} }
} }

View File

@ -259,8 +259,8 @@ protected:
// caches text and uri-list data formats that exist in the drag service or // caches text and uri-list data formats that exist in the drag service or
// clipboard for retrieval later. // clipboard for retrieval later.
nsresult CacheExternalData(const char* aFormat, uint32_t aIndex, void CacheExternalData(const char* aFormat, uint32_t aIndex,
nsIPrincipal* aPrincipal, bool aHidden); nsIPrincipal* aPrincipal);
// caches the formats that exist in the drag service that were added by an // caches the formats that exist in the drag service that were added by an
// external drag // external drag

View File

@ -31,6 +31,22 @@ FileMimeNameData kFileMimeNameMap[] = {
{ kPNGImageMime, "GenericImageNamePNG" }, { kPNGImageMime, "GenericImageNamePNG" },
}; };
already_AddRefed<mozilla::dom::File>
FileFromISupports(nsISupports* aSupports)
{
MOZ_ASSERT(aSupports);
nsCOMPtr<nsIDOMBlob> domBlob = do_QueryInterface(aSupports);
if (domBlob) {
// Get out the blob - this is OK, because nsIDOMBlob is a builtinclass
// and the only implementer is Blob.
mozilla::dom::Blob* blob = static_cast<mozilla::dom::Blob*>(domBlob.get());
return blob->ToFile();
}
return nullptr;
}
} // anonymous namespace } // anonymous namespace
namespace mozilla { namespace mozilla {
@ -182,6 +198,22 @@ DataTransferItem::FillInExternalData()
// whatever type happens to actually be stored into a dom::File. // whatever type happens to actually be stored into a dom::File.
RefPtr<File> file = FileFromISupports(data); RefPtr<File> file = FileFromISupports(data);
if (!file) {
if (nsCOMPtr<nsIFile> ifile = do_QueryInterface(data)) {
file = File::CreateFromFile(GetParentObject(), ifile);
} else if (nsCOMPtr<nsIInputStream> stream = do_QueryInterface(data)) {
// This consumes the stream object
ErrorResult rv;
file = CreateFileFromInputStream(GetParentObject(), stream, rv);
if (NS_WARN_IF(rv.Failed())) {
rv.SuppressException();
}
} else if (nsCOMPtr<BlobImpl> blobImpl = do_QueryInterface(data)) {
MOZ_ASSERT(blobImpl->IsFile());
file = File::Create(GetParentObject(), blobImpl);
}
}
MOZ_ASSERT(file, "Invalid format for Kind() == KIND_FILE"); MOZ_ASSERT(file, "Invalid format for Kind() == KIND_FILE");
data = do_QueryObject(file); data = do_QueryObject(file);
@ -248,37 +280,6 @@ DataTransferItem::GetAsFile(ErrorResult& aRv)
return file.forget(); return file.forget();
} }
already_AddRefed<File>
DataTransferItem::FileFromISupports(nsISupports* aSupports)
{
MOZ_ASSERT(aSupports);
RefPtr<File> file;
nsCOMPtr<nsIDOMBlob> domBlob = do_QueryInterface(aSupports);
if (domBlob) {
// Get out the blob - this is OK, because nsIDOMBlob is a builtinclass
// and the only implementer is Blob.
Blob* blob = static_cast<Blob*>(domBlob.get());
file = blob->ToFile();
} else if (nsCOMPtr<nsIFile> ifile = do_QueryInterface(aSupports)) {
printf("Creating a File from a nsIFile!\n");
file = File::CreateFromFile(GetParentObject(), ifile);
} else if (nsCOMPtr<nsIInputStream> stream = do_QueryInterface(aSupports)) {
// This consumes the stream object
ErrorResult rv;
file = CreateFileFromInputStream(GetParentObject(), stream, rv);
if (NS_WARN_IF(rv.Failed())) {
rv.SuppressException();
}
} else if (nsCOMPtr<BlobImpl> blobImpl = do_QueryInterface(aSupports)) {
MOZ_ASSERT(blobImpl->IsFile());
file = File::Create(GetParentObject(), blobImpl);
}
return file.forget();
}
already_AddRefed<File> already_AddRefed<File>
DataTransferItem::CreateFileFromInputStream(nsISupports* aParent, DataTransferItem::CreateFileFromInputStream(nsISupports* aParent,
nsIInputStream* aStream, nsIInputStream* aStream,
@ -320,7 +321,7 @@ DataTransferItem::CreateFileFromInputStream(nsISupports* aParent,
} }
void void
DataTransferItem::GetAsString(FunctionStringCallback* aCallback, DataTransferItem::GetAsString(const RefPtr<FunctionStringCallback>& aCallback,
ErrorResult& aRv) ErrorResult& aRv)
{ {
if (!aCallback || mKind != KIND_STRING) { if (!aCallback || mKind != KIND_STRING) {
@ -339,7 +340,7 @@ DataTransferItem::GetAsString(FunctionStringCallback* aCallback,
class GASRunnable final : public Runnable class GASRunnable final : public Runnable
{ {
public: public:
GASRunnable(FunctionStringCallback* aCallback, GASRunnable(const RefPtr<FunctionStringCallback>& aCallback,
const nsAString& aStringData) const nsAString& aStringData)
: mCallback(aCallback), mStringData(aStringData) : mCallback(aCallback), mStringData(aStringData)
{} {}

View File

@ -35,13 +35,14 @@ public:
}; };
DataTransferItem(DataTransferItemList* aParent, const nsAString& aType) DataTransferItem(DataTransferItemList* aParent, const nsAString& aType)
: mIndex(0), mChromeOnly(false), mKind(KIND_OTHER), mType(aType), mParent(aParent) : mIndex(0), mKind(KIND_OTHER), mType(aType), mParent(aParent)
{} {}
already_AddRefed<DataTransferItem> Clone(DataTransferItemList* aParent) const; already_AddRefed<DataTransferItem> Clone(DataTransferItemList* aParent) const;
virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override; virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
void GetAsString(FunctionStringCallback* aCallback, ErrorResult& aRv); void GetAsString(const RefPtr<FunctionStringCallback>& aCallback,
ErrorResult& aRv);
void GetKind(nsAString& aKind) const void GetKind(nsAString& aKind) const
{ {
switch (mKind) { switch (mKind) {
@ -107,18 +108,8 @@ public:
} }
void FillInExternalData(); void FillInExternalData();
bool ChromeOnly() const
{
return mChromeOnly;
}
void SetChromeOnly(bool aChromeOnly)
{
mChromeOnly = aChromeOnly;
}
private: private:
~DataTransferItem() {} ~DataTransferItem() {}
already_AddRefed<File> FileFromISupports(nsISupports* aParent);
already_AddRefed<File> CreateFileFromInputStream(nsISupports* aParent, already_AddRefed<File> CreateFileFromInputStream(nsISupports* aParent,
nsIInputStream* aStream, nsIInputStream* aStream,
ErrorResult& aRv); ErrorResult& aRv);
@ -126,7 +117,6 @@ private:
// The index in the 2d mIndexedItems array // The index in the 2d mIndexedItems array
uint32_t mIndex; uint32_t mIndex;
bool mChromeOnly;
eKind mKind; eKind mKind;
nsString mType; nsString mType;
nsCOMPtr<nsIVariant> mData; nsCOMPtr<nsIVariant> mData;

View File

@ -212,9 +212,7 @@ DataTransferItemList::Add(const nsAString& aData,
RefPtr<DataTransferItem> item = RefPtr<DataTransferItem> item =
SetDataWithPrincipal(format, data, 0, SetDataWithPrincipal(format, data, 0,
nsContentUtils::SubjectPrincipal(), nsContentUtils::SubjectPrincipal(),
/* aInsertOnly = */ true, true, aRv);
/* aHidden = */ false,
aRv);
if (NS_WARN_IF(aRv.Failed())) { if (NS_WARN_IF(aRv.Failed())) {
return nullptr; return nullptr;
} }
@ -245,7 +243,7 @@ DataTransferItemList::Add(File& aData, ErrorResult& aRv)
RefPtr<DataTransferItem> item = RefPtr<DataTransferItem> item =
SetDataWithPrincipal(type, data, index, SetDataWithPrincipal(type, data, index,
nsContentUtils::SubjectPrincipal(), nsContentUtils::SubjectPrincipal(),
true, false, aRv); true, aRv);
if (NS_WARN_IF(aRv.Failed())) { if (NS_WARN_IF(aRv.Failed())) {
return nullptr; return nullptr;
} }
@ -334,7 +332,6 @@ DataTransferItemList::SetDataWithPrincipal(const nsAString& aType,
uint32_t aIndex, uint32_t aIndex,
nsIPrincipal* aPrincipal, nsIPrincipal* aPrincipal,
bool aInsertOnly, bool aInsertOnly,
bool aHidden,
ErrorResult& aRv) ErrorResult& aRv)
{ {
if (aIndex < mIndexedItems.Length()) { if (aIndex < mIndexedItems.Length()) {
@ -394,7 +391,7 @@ DataTransferItemList::SetDataWithPrincipal(const nsAString& aType,
} }
// Add the new item // Add the new item
RefPtr<DataTransferItem> item = AppendNewItem(aIndex, aType, aData, aPrincipal, aHidden); RefPtr<DataTransferItem> item = AppendNewItem(aIndex, aType, aData, aPrincipal);
if (item->Kind() == DataTransferItem::KIND_FILE) { if (item->Kind() == DataTransferItem::KIND_FILE) {
RegenerateFiles(); RegenerateFiles();
@ -407,8 +404,7 @@ DataTransferItem*
DataTransferItemList::AppendNewItem(uint32_t aIndex, DataTransferItemList::AppendNewItem(uint32_t aIndex,
const nsAString& aType, const nsAString& aType,
nsIVariant* aData, nsIVariant* aData,
nsIPrincipal* aPrincipal, nsIPrincipal* aPrincipal)
bool aHidden)
{ {
if (mIndexedItems.Length() <= aIndex) { if (mIndexedItems.Length() <= aIndex) {
MOZ_ASSERT(mIndexedItems.Length() == aIndex); MOZ_ASSERT(mIndexedItems.Length() == aIndex);
@ -418,7 +414,6 @@ DataTransferItemList::AppendNewItem(uint32_t aIndex,
item->SetIndex(aIndex); item->SetIndex(aIndex);
item->SetPrincipal(aPrincipal); item->SetPrincipal(aPrincipal);
item->SetData(aData); item->SetData(aData);
item->SetChromeOnly(aHidden);
mIndexedItems[aIndex].AppendElement(item); mIndexedItems[aIndex].AppendElement(item);
@ -427,7 +422,7 @@ DataTransferItemList::AppendNewItem(uint32_t aIndex,
// which is not a file to a non-zero index, invariants could be broken. // which is not a file to a non-zero index, invariants could be broken.
// (namely the invariant that there are not 2 non-file entries in the items // (namely the invariant that there are not 2 non-file entries in the items
// array with the same type) // array with the same type)
if (!aHidden && (item->Kind() == DataTransferItem::KIND_FILE || aIndex == 0)) { if (item->Kind() == DataTransferItem::KIND_FILE || aIndex == 0) {
mItems.AppendElement(item); mItems.AppendElement(item);
} }

View File

@ -75,7 +75,7 @@ public:
already_AddRefed<DataTransferItem> already_AddRefed<DataTransferItem>
SetDataWithPrincipal(const nsAString& aType, nsIVariant* aData, SetDataWithPrincipal(const nsAString& aType, nsIVariant* aData,
uint32_t aIndex, nsIPrincipal* aPrincipal, uint32_t aIndex, nsIPrincipal* aPrincipal,
bool aInsertOnly, bool aHidden, ErrorResult& aRv); bool aInsertOnly, ErrorResult& aRv);
FileList* Files(); FileList* Files();
@ -97,8 +97,7 @@ private:
void ClearDataHelper(DataTransferItem* aItem, uint32_t aIndexHint, void ClearDataHelper(DataTransferItem* aItem, uint32_t aIndexHint,
uint32_t aMozOffsetHint, ErrorResult& aRv); uint32_t aMozOffsetHint, ErrorResult& aRv);
DataTransferItem* AppendNewItem(uint32_t aIndex, const nsAString& aType, DataTransferItem* AppendNewItem(uint32_t aIndex, const nsAString& aType,
nsIVariant* aData, nsIPrincipal* aPrincipal, nsIVariant* aData, nsIPrincipal* aPrincipal);
bool aHidden);
void RegenerateFiles(); void RegenerateFiles();
~DataTransferItemList() {} ~DataTransferItemList() {}