Bug 1305339 - part 2: use URI flags to determine if data is from the web, r=mstange,bz

This actually accomplishes what was discussed in the bug and marks any file with the
relevant URI flags as WebDownload, and everything else as OtherDownload.

Note that I'm using DoGetProtocolFlags in order to deal with
nsIProtocolHandlerWithDynamicFlags correctly; while just getting protocol flags
from the IO service directly would be less work, it's technically less correct.

MozReview-Commit-ID: HgD1fV98IEc

--HG--
extra : rebase_source : f114532b48dbca5c83871e61c8d04c719e3b38d1
This commit is contained in:
Gijs Kruitbosch 2016-10-03 13:52:19 +01:00
parent 5fae01fcd2
commit a6e0fa62ec
4 changed files with 68 additions and 12 deletions

View File

@ -4,7 +4,10 @@
#include "DownloadPlatform.h"
#include "nsAutoPtr.h"
#include "nsNetUtil.h"
#include "nsString.h"
#include "nsINestedURI.h"
#include "nsIProtocolHandler.h"
#include "nsIURI.h"
#include "nsIFile.h"
#include "nsIObserverService.h"
@ -165,6 +168,8 @@ nsresult DownloadPlatform::DownloadDone(nsIURI* aSource, nsIURI* aReferrer, nsIF
path.Length());
}
if (pathCFStr) {
bool isFromWeb = IsURLPossiblyFromWeb(aSource);
CFURLRef sourceCFURL = CreateCFURLFromNSIURI(aSource);
CFURLRef referrerCFURL = CreateCFURLFromNSIURI(aReferrer);
@ -173,7 +178,8 @@ nsresult DownloadPlatform::DownloadDone(nsIURI* aSource, nsIURI* aReferrer, nsIF
referrerCFURL);
CocoaFileUtils::AddQuarantineMetadataToFile(pathCFStr,
sourceCFURL,
referrerCFURL);
referrerCFURL,
isFromWeb);
::CFRelease(pathCFStr);
if (sourceCFURL) {
@ -227,3 +233,55 @@ nsresult DownloadPlatform::MapUrlToZone(const nsAString& aURL,
return NS_ERROR_NOT_IMPLEMENTED;
#endif
}
// Check if a URI is likely to be web-based, by checking its URI flags.
// If in doubt (e.g. if anything fails during the check) claims things
// are from the web.
bool DownloadPlatform::IsURLPossiblyFromWeb(nsIURI* aURI)
{
nsCOMPtr<nsIIOService> ios = do_GetIOService();
nsCOMPtr<nsIURI> uri = aURI;
if (!ios) {
return true;
}
while (uri) {
// We're not using nsIIOService::ProtocolHasFlags because it doesn't
// take per-URI flags into account. We're also not using
// NS_URIChainHasFlags because we're checking for *any* of 3 flags
// to be present on *all* of the nested URIs, which it can't do.
nsAutoCString scheme;
nsresult rv = uri->GetScheme(scheme);
if (NS_FAILED(rv)) {
return true;
}
nsCOMPtr<nsIProtocolHandler> ph;
rv = ios->GetProtocolHandler(scheme.get(), getter_AddRefs(ph));
if (NS_FAILED(rv)) {
return true;
}
uint32_t flags;
rv = ph->DoGetProtocolFlags(uri, &flags);
if (NS_FAILED(rv)) {
return true;
}
// If not dangerous to load, not a UI resource and not a local file,
// assume this is from the web:
if (!(flags & nsIProtocolHandler::URI_DANGEROUS_TO_LOAD) &&
!(flags & nsIProtocolHandler::URI_IS_UI_RESOURCE) &&
!(flags & nsIProtocolHandler::URI_IS_LOCAL_FILE)) {
return true;
}
// Otherwise, check if the URI is nested, and if so go through
// the loop again:
nsCOMPtr<nsINestedURI> nestedURI = do_QueryInterface(uri);
uri = nullptr;
if (nestedURI) {
rv = nestedURI->GetInnerURI(getter_AddRefs(uri));
if (NS_FAILED(rv)) {
return true;
}
}
}
return false;
}

View File

@ -8,6 +8,7 @@
#include "mozIDownloadPlatform.h"
#include "nsCOMPtr.h"
class nsIURI;
class DownloadPlatform : public mozIDownloadPlatform
{
@ -25,6 +26,9 @@ public:
static DownloadPlatform *gDownloadPlatformService;
static DownloadPlatform* GetDownloadPlatform();
private:
static bool IsURLPossiblyFromWeb(nsIURI* aURI);
};
#endif

View File

@ -26,7 +26,8 @@ void AddOriginMetadataToFile(const CFStringRef filePath,
const CFURLRef referrerURL);
void AddQuarantineMetadataToFile(const CFStringRef filePath,
const CFURLRef sourceURL,
const CFURLRef referrerURL);
const CFURLRef referrerURL,
const bool isFromWeb);
} // namespace CocoaFileUtils

View File

@ -193,7 +193,8 @@ void AddOriginMetadataToFile(const CFStringRef filePath,
void AddQuarantineMetadataToFile(const CFStringRef filePath,
const CFURLRef sourceURL,
const CFURLRef referrerURL) {
const CFURLRef referrerURL,
const bool isFromWeb) {
CFURLRef fileURL = ::CFURLCreateWithFileSystemPath(kCFAllocatorDefault,
filePath,
kCFURLPOSIXPathStyle,
@ -234,15 +235,7 @@ void AddQuarantineMetadataToFile(const CFStringRef filePath,
// Add metadata that the OS couldn't infer.
if (!::CFDictionaryGetValue(mutQuarantineProps, kLSQuarantineTypeKey)) {
CFStringRef type = kLSQuarantineTypeOtherDownload;
CFStringRef scheme = ::CFURLCopyScheme(sourceURL);
if (::CFStringCompare(scheme, CFSTR("http"), kCFCompareCaseInsensitive) == kCFCompareEqualTo ||
::CFStringCompare(scheme, CFSTR("http"), kCFCompareCaseInsensitive) == kCFCompareEqualTo) {
type = kLSQuarantineTypeWebDownload;
}
::CFRelease(scheme);
CFStringRef type = isFromWeb ? kLSQuarantineTypeWebDownload : kLSQuarantineTypeOtherDownload;
::CFDictionarySetValue(mutQuarantineProps, kLSQuarantineTypeKey, type);
}