ma1 pushed to branch mullvad-browser-140.2.0esr-15.0-1 at The Tor Project / Applications / Mullvad Browser

Commits:

1 changed file:

Changes:

  • uriloader/base/nsURILoader.cpp
    ... ... @@ -320,7 +320,11 @@ NS_IMETHODIMP nsDocumentOpenInfo::OnStopRequest(nsIRequest* request,
    320 320
       return NS_OK;
    
    321 321
     }
    
    322 322
     
    
    323
    -static bool IsContentPDF(nsIChannel* aChannel, const nsACString& aContentType) {
    
    323
    +static bool IsContentPDF(
    
    324
    +    nsIChannel* aChannel, const nsACString& aContentType,
    
    325
    +    nsAutoCString* aOutExt =
    
    326
    +        nullptr  // best-guess file extension, useful for non-PDFs
    
    327
    +) {
    
    324 328
       bool isPDF = aContentType.LowerCaseEqualsASCII(APPLICATION_PDF);
    
    325 329
       if (!isPDF && (aContentType.LowerCaseEqualsASCII(APPLICATION_OCTET_STREAM) ||
    
    326 330
                      aContentType.IsEmpty())) {
    
    ... ... @@ -328,14 +332,25 @@ static bool IsContentPDF(nsIChannel* aChannel, const nsACString& aContentType) {
    328 332
         aChannel->GetContentDispositionFilename(flname);
    
    329 333
         isPDF = StringEndsWith(flname, u".pdf"_ns);
    
    330 334
         if (!isPDF) {
    
    335
    +      nsAutoCString ext;
    
    331 336
           nsCOMPtr<nsIURI> uri;
    
    332 337
           aChannel->GetURI(getter_AddRefs(uri));
    
    333 338
           nsCOMPtr<nsIURL> url(do_QueryInterface(uri));
    
    334 339
           if (url) {
    
    335
    -        nsAutoCString ext;
    
    336 340
             url->GetFileExtension(ext);
    
    337 341
             isPDF = ext.EqualsLiteral("pdf");
    
    338 342
           }
    
    343
    +      if (aOutExt) {
    
    344
    +        // Fill the extension out param if required
    
    345
    +        if (!(isPDF || flname.IsEmpty())) {
    
    346
    +          // For non PDFs, fallback to filename from content disposition
    
    347
    +          int32_t extStart = flname.RFindChar(u'.');
    
    348
    +          if (extStart != kNotFound) {
    
    349
    +            CopyUTF16toUTF8(Substring(flname, extStart + 1), ext);
    
    350
    +          }
    
    351
    +        }
    
    352
    +        *aOutExt = ext;
    
    353
    +      }
    
    339 354
         }
    
    340 355
       }
    
    341 356
     
    
    ... ... @@ -343,7 +358,7 @@ static bool IsContentPDF(nsIChannel* aChannel, const nsACString& aContentType) {
    343 358
     }
    
    344 359
     
    
    345 360
     static mozilla::Result<bool, nsresult> ShouldHandleExternally(
    
    346
    -    const nsACString& aMimeType) {
    
    361
    +    const nsACString& aMimeType, const nsACString& aExtension) {
    
    347 362
       // For a PDF, check if the preference is set that forces attachments to be
    
    348 363
       // opened inline. If so, treat it as a non-attachment by clearing
    
    349 364
       // 'forceExternalHandling' again. This allows it open a PDF directly
    
    ... ... @@ -356,7 +371,7 @@ static mozilla::Result<bool, nsresult> ShouldHandleExternally(
    356 371
         return mozilla::Err(NS_ERROR_FAILURE);
    
    357 372
       }
    
    358 373
     
    
    359
    -  mimeSvc->GetFromTypeAndExtension(aMimeType, EmptyCString(),
    
    374
    +  mimeSvc->GetFromTypeAndExtension(aMimeType, aExtension,
    
    360 375
                                        getter_AddRefs(mimeInfo));
    
    361 376
     
    
    362 377
       if (mimeInfo) {
    
    ... ... @@ -430,31 +445,43 @@ nsresult nsDocumentOpenInfo::DispatchContent(nsIRequest* request) {
    430 445
         forceExternalHandling = false;
    
    431 446
       }
    
    432 447
     
    
    448
    +  nsAutoCString ext;
    
    449
    +  bool isPDF =
    
    450
    +      forceExternalHandling && IsContentPDF(aChannel, mContentType, &ext);
    
    451
    +
    
    433 452
       bool maybeForceInternalHandling =
    
    434
    -      forceExternalHandling &&
    
    435
    -      (mozilla::StaticPrefs::browser_download_open_pdf_attachments_inline() ||
    
    436
    -       mozilla::StaticPrefs::browser_download_ignore_content_disposition());
    
    453
    +      (isPDF &&
    
    454
    +        mozilla::StaticPrefs::browser_download_open_pdf_attachments_inline()) ||
    
    455
    +       (
    
    456
    +        forceExternalHandling &&
    
    457
    +        mozilla::StaticPrefs::browser_download_ignore_content_disposition() &&
    
    458
    +        // we want to exclude html and svg files, which could execute
    
    459
    +        // scripts (tor-browser#43211)
    
    460
    +        kNotFound == mContentType.LowerCaseFindASCII("html") &&
    
    461
    +        kNotFound == ext.LowerCaseFindASCII("htm") &&
    
    462
    +        kNotFound == mContentType.LowerCaseFindASCII("/svg+") &&
    
    463
    +        !ext.EqualsIgnoreCase("svg"));
    
    437 464
     
    
    438 465
       // Check if this is a PDF which should be opened internally. We also handle
    
    439 466
       // octet-streams that look like they might be PDFs based on their extension.
    
    467
    +  // Additionally, we try to avoid downloading also non-PDF attachments
    
    468
    +  // when the general Content-Disposition override preference is set to true.
    
    440 469
       if (maybeForceInternalHandling) {
    
    441
    -    // For a PDF, check if the preference is set that forces attachments to be
    
    442
    -    // opened inline. If so, treat it as a non-attachment by clearing
    
    470
    +    // Preferences are set to open attachments inline by clearing
    
    443 471
         // 'forceExternalHandling' again. This allows it open a PDF directly
    
    444 472
         // instead of downloading it first. It may still end up being handled by
    
    445 473
         // a helper app depending anyway on the later checks.
    
    446
    -    nsCString mimeType = IsContentPDF(aChannel, mContentType)
    
    447
    -                             ? nsLiteralCString(APPLICATION_PDF)
    
    448
    -                             : mContentType;
    
    449
    -    auto result = ShouldHandleExternally(mimeType);
    
    474
    +    // This may apply to other file types if an internal handler exists.
    
    475
    +    auto result = ShouldHandleExternally(
    
    476
    +        isPDF ? nsLiteralCString(APPLICATION_PDF) : mContentType, ext);
    
    450 477
         if (result.isErr()) {
    
    451 478
           return result.unwrapErr();
    
    452 479
         }
    
    453 480
         forceExternalHandling = result.unwrap();
    
    454 481
     
    
    455
    -    // If we're not opening the PDF externally we block it if it's sandboxed.
    
    482
    +    // If we're not opening the file externally and it's sandboxed we block it.
    
    456 483
         if (IsSandboxed(aChannel) && !forceExternalHandling) {
    
    457
    -      LOG(("Blocked sandboxed PDF"));
    
    484
    +      LOG(("Blocked sandboxed file"));
    
    458 485
           nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(aChannel);
    
    459 486
           if (httpChannel) {
    
    460 487
             nsContentSecurityUtils::LogMessageToConsole(