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;
}
for (auto* file : aFiles) {
#ifdef XP_WIN
nsString pathString(file->NativePath());
#else
nsString pathString = NS_ConvertUTF8toUTF16(file->NativePath());
#endif
RefPtr<nsIContentAnalysisRequest> request =
new mozilla::contentanalysis::ContentAnalysisRequest(

View File

@@ -699,13 +699,7 @@ nsFilePicker::CheckContentAnalysisService() {
if (!contentAnalysisIsActive ||
!mozilla::StaticPrefs::
browser_contentanalysis_interception_point_file_upload_enabled()) {
return nsFilePicker::ContentAnalysisResponse::CreateAndResolve(true,
__func__);
}
// Entries may be files or folders. Folder contents will be recursively
// checked.
nsTArray<mozilla::PathString> filePaths;
nsCOMArray<nsIFile> files;
if (mMode == modeGetFolder || !mUnicodeFile.IsEmpty()) {
RefPtr<nsIFile> folderOrFile;
nsresult rv = GetFile(getter_AddRefs(folderOrFile));
@@ -713,47 +707,40 @@ nsFilePicker::CheckContentAnalysisService() {
return nsFilePicker::ContentAnalysisResponse::CreateAndReject(rv,
__func__);
}
filePaths.AppendElement(folderOrFile->NativePath());
files.AppendElement(folderOrFile);
} else {
// multiple selections
std::transform(mFiles.begin(), mFiles.end(), MakeBackInserter(filePaths),
[](auto* entry) { return entry->NativePath(); });
files.AppendElements(mFiles);
}
return nsFilePicker::ContentAnalysisResponse::CreateAndResolve(
std::move(files), __func__);
}
MOZ_ASSERT(!filePaths.IsEmpty());
auto promise =
mozilla::MakeRefPtr<nsFilePicker::ContentAnalysisResponse::Private>(
// Entries may be files or folders. Folder contents will be recursively
// checked.
nsCOMArray<nsIFile> files;
if (mMode == modeGetFolder || !mUnicodeFile.IsEmpty()) {
nsCOMPtr<nsIFile> folderOrFile;
nsresult rv = GetFile(getter_AddRefs(folderOrFile));
if (NS_WARN_IF(NS_FAILED(rv) || !folderOrFile)) {
return nsFilePicker::ContentAnalysisResponse::CreateAndReject(rv,
__func__);
auto contentAnalysisCallback =
mozilla::MakeRefPtr<mozilla::contentanalysis::ContentAnalysisCallback>(
[promise](nsIContentAnalysisResult* aResult) {
promise->Resolve(aResult->GetShouldAllowContent(), __func__);
});
}
files.AppendElement(folderOrFile);
} else {
// multiple selections
files.AppendElements(mFiles);
}
MOZ_ASSERT(!files.IsEmpty());
auto* windowGlobal = mBrowsingContext->Canonical()->GetCurrentWindowGlobal();
NS_ENSURE_TRUE(
windowGlobal,
nsFilePicker::ContentAnalysisResponse::CreateAndReject(rv, __func__));
nsTArray<RefPtr<nsIContentAnalysisRequest>> requests(filePaths.Length());
for (auto& path : filePaths) {
#ifdef XP_WIN
nsString pathString(std::move(path));
#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;
// This will check all of the files even if BLOCK responses are received for
// some of them, and the promise will resolve with the files that are ALLOWed.
return mozilla::contentanalysis::ContentAnalysis::CheckFilesInBatchMode(
std::move(files), windowGlobal,
nsIContentAnalysisRequest::Reason::eFilePickerDialog);
};
///////////////////////////////////////////////////////////////////////////////
@@ -818,13 +805,23 @@ nsresult nsFilePicker::Open(nsIFilePickerShownCallback* aCallback) {
self->mMode != modeSave && retValue != ResultCode::returnCancel) {
self->CheckContentAnalysisService()->Then(
mozilla::GetMainThreadSerialEventTarget(), __func__,
[retValue, callback, self = RefPtr{self}](bool aAllowContent) {
if (aAllowContent) {
callback->Done(retValue);
} else {
[retValue, callback,
self = RefPtr{self}](nsCOMArray<nsIFile> aAllowedFiles) {
if (aAllowedFiles.IsEmpty()) {
self->ClearFiles();
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) {
self->ClearFiles();

View File

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