Bug 1950424 part 2 - make nsFilePicker call the new Content Analysis "batch" entry point r=dlp-reviewers,win-reviewers,rkraesig,handyman

Differential Revision: https://phabricator.services.mozilla.com/D241090
This commit is contained in:
Greg Stoll
2025-03-13 21:34:51 +00:00
parent 4bbcbbad28
commit 67e81e9465
3 changed files with 45 additions and 43 deletions

View File

@@ -3487,7 +3487,11 @@ ContentAnalysis::CheckFilesInBatchMode(
uri = aURI; uri = aURI;
} }
for (auto* file : aFiles) { for (auto* file : aFiles) {
#ifdef XP_WIN
nsString pathString(file->NativePath()); nsString pathString(file->NativePath());
#else
nsString pathString = NS_ConvertUTF8toUTF16(file->NativePath());
#endif
RefPtr<nsIContentAnalysisRequest> request = RefPtr<nsIContentAnalysisRequest> request =
new mozilla::contentanalysis::ContentAnalysisRequest( new mozilla::contentanalysis::ContentAnalysisRequest(

View File

@@ -699,61 +699,48 @@ nsFilePicker::CheckContentAnalysisService() {
if (!contentAnalysisIsActive || if (!contentAnalysisIsActive ||
!mozilla::StaticPrefs:: !mozilla::StaticPrefs::
browser_contentanalysis_interception_point_file_upload_enabled()) { browser_contentanalysis_interception_point_file_upload_enabled()) {
return nsFilePicker::ContentAnalysisResponse::CreateAndResolve(true, nsCOMArray<nsIFile> files;
__func__); if (mMode == modeGetFolder || !mUnicodeFile.IsEmpty()) {
RefPtr<nsIFile> folderOrFile;
nsresult rv = GetFile(getter_AddRefs(folderOrFile));
if (NS_WARN_IF(NS_FAILED(rv) || !folderOrFile)) {
return nsFilePicker::ContentAnalysisResponse::CreateAndReject(rv,
__func__);
}
files.AppendElement(folderOrFile);
} else {
// multiple selections
files.AppendElements(mFiles);
}
return nsFilePicker::ContentAnalysisResponse::CreateAndResolve(
std::move(files), __func__);
} }
// Entries may be files or folders. Folder contents will be recursively // Entries may be files or folders. Folder contents will be recursively
// checked. // checked.
nsTArray<mozilla::PathString> filePaths; nsCOMArray<nsIFile> files;
if (mMode == modeGetFolder || !mUnicodeFile.IsEmpty()) { if (mMode == modeGetFolder || !mUnicodeFile.IsEmpty()) {
RefPtr<nsIFile> folderOrFile; nsCOMPtr<nsIFile> folderOrFile;
nsresult rv = GetFile(getter_AddRefs(folderOrFile)); nsresult rv = GetFile(getter_AddRefs(folderOrFile));
if (NS_WARN_IF(NS_FAILED(rv) || !folderOrFile)) { if (NS_WARN_IF(NS_FAILED(rv) || !folderOrFile)) {
return nsFilePicker::ContentAnalysisResponse::CreateAndReject(rv, return nsFilePicker::ContentAnalysisResponse::CreateAndReject(rv,
__func__); __func__);
} }
filePaths.AppendElement(folderOrFile->NativePath()); files.AppendElement(folderOrFile);
} else { } else {
// multiple selections // multiple selections
std::transform(mFiles.begin(), mFiles.end(), MakeBackInserter(filePaths), files.AppendElements(mFiles);
[](auto* entry) { return entry->NativePath(); });
} }
MOZ_ASSERT(!filePaths.IsEmpty()); MOZ_ASSERT(!files.IsEmpty());
auto promise =
mozilla::MakeRefPtr<nsFilePicker::ContentAnalysisResponse::Private>(
__func__);
auto contentAnalysisCallback =
mozilla::MakeRefPtr<mozilla::contentanalysis::ContentAnalysisCallback>(
[promise](nsIContentAnalysisResult* aResult) {
promise->Resolve(aResult->GetShouldAllowContent(), __func__);
});
auto* windowGlobal = mBrowsingContext->Canonical()->GetCurrentWindowGlobal(); auto* windowGlobal = mBrowsingContext->Canonical()->GetCurrentWindowGlobal();
NS_ENSURE_TRUE( NS_ENSURE_TRUE(
windowGlobal, windowGlobal,
nsFilePicker::ContentAnalysisResponse::CreateAndReject(rv, __func__)); nsFilePicker::ContentAnalysisResponse::CreateAndReject(rv, __func__));
// This will check all of the files even if BLOCK responses are received for
nsTArray<RefPtr<nsIContentAnalysisRequest>> requests(filePaths.Length()); // some of them, and the promise will resolve with the files that are ALLOWed.
for (auto& path : filePaths) { return mozilla::contentanalysis::ContentAnalysis::CheckFilesInBatchMode(
#ifdef XP_WIN std::move(files), windowGlobal,
nsString pathString(std::move(path)); nsIContentAnalysisRequest::Reason::eFilePickerDialog);
#else
nsString pathString = NS_ConvertUTF8toUTF16(path);
#endif
requests.AppendElement(new mozilla::contentanalysis::ContentAnalysisRequest(
nsIContentAnalysisRequest::AnalysisType::eFileAttached,
nsIContentAnalysisRequest::Reason::eFilePickerDialog, pathString,
true /* aStringIsFilePath */, EmptyCString(), nullptr,
nsIContentAnalysisRequest::OperationType::eCustomDisplayString,
windowGlobal));
}
contentAnalysis->AnalyzeContentRequestsCallback(
requests, true /* aAutoAcknowledge */, contentAnalysisCallback);
return promise;
}; };
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
@@ -818,13 +805,23 @@ nsresult nsFilePicker::Open(nsIFilePickerShownCallback* aCallback) {
self->mMode != modeSave && retValue != ResultCode::returnCancel) { self->mMode != modeSave && retValue != ResultCode::returnCancel) {
self->CheckContentAnalysisService()->Then( self->CheckContentAnalysisService()->Then(
mozilla::GetMainThreadSerialEventTarget(), __func__, mozilla::GetMainThreadSerialEventTarget(), __func__,
[retValue, callback, self = RefPtr{self}](bool aAllowContent) { [retValue, callback,
if (aAllowContent) { self = RefPtr{self}](nsCOMArray<nsIFile> aAllowedFiles) {
callback->Done(retValue); if (aAllowedFiles.IsEmpty()) {
} else {
self->ClearFiles(); self->ClearFiles();
callback->Done(ResultCode::returnCancel); callback->Done(ResultCode::returnCancel);
} }
if (self->mMode == modeGetFolder ||
!self->mUnicodeFile.IsEmpty()) {
// Callers will use mUnicodeFile, so just call the callback
callback->Done(retValue);
return;
}
// Only the files in aAllowedFiles should be returned, so
// swap these into mFiles.
self->ClearFiles();
aAllowedFiles.SwapElements(self->mFiles);
callback->Done(retValue);
}, },
[callback, self = RefPtr{self}](nsresult aError) { [callback, self = RefPtr{self}](nsresult aError) {
self->ClearFiles(); self->ClearFiles();

View File

@@ -99,7 +99,8 @@ class nsFilePicker final : public nsBaseWinFilePicker {
const nsString& aInitialDir); const nsString& aInitialDir);
void ClearFiles(); void ClearFiles();
using ContentAnalysisResponse = mozilla::MozPromise<bool, nsresult, true>; using ContentAnalysisResponse =
mozilla::MozPromise<nsCOMArray<nsIFile>, nsresult, true>;
RefPtr<ContentAnalysisResponse> CheckContentAnalysisService(); RefPtr<ContentAnalysisResponse> CheckContentAnalysisService();
protected: protected: