Bug 1361020 - Bug 968342 follow-up: Enhance GetPrincipalSpec() for mailbox: URLs and use it in ShouldLoad(). r=rkent
authorJorg K <jorgk@jorgk.com>
Mon, 08 May 2017 07:23:46 +0200
changeset 21527 92e89bd8daf85910e04d9c44098ba9279735a8a7
parent 21526 dbede130480d58636bc82e6afc88f9b2362161cb
child 21528 35cd2a0110f30b655ef10b5d2fa45494bd310f15
push id13107
push usermozilla@jorgk.com
push dateMon, 08 May 2017 05:26:49 +0000
treeherdercomm-central@35cd2a0110f3 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersrkent
bugs1361020, 968342
Bug 1361020 - Bug 968342 follow-up: Enhance GetPrincipalSpec() for mailbox: URLs and use it in ShouldLoad(). r=rkent
mailnews/base/src/nsMsgContentPolicy.cpp
mailnews/local/src/nsMailboxUrl.cpp
--- a/mailnews/base/src/nsMsgContentPolicy.cpp
+++ b/mailnews/base/src/nsMsgContentPolicy.cpp
@@ -234,29 +234,42 @@ nsMsgContentPolicy::ShouldLoad(uint32_t 
   // If the requesting location is safe, accept the content location request.
   if (IsSafeRequestingLocation(aRequestingLocation))
     return rv;
 
   // Now default to reject so early returns via NS_ENSURE_SUCCESS
   // cause content to be rejected.
   *aDecision = nsIContentPolicy::REJECT_REQUEST;
 
-  // If aContentLocation uses a protocol we handle (imap, pop, mailbox, news),
-  // we require that the load comes from the same scheme/account/server/port.
-  // This is basically a simplyfied "same origin" test.
-  // Pre-paths for example are:
-  // mailbox: mailbox://
-  // imap:    imap://user@domain@server:port
-  // news:    news://server:port
+  // If aContentLocation uses a protocol we handle, we require that the load
+  // comes from the "normalised" principal which exists for imap, mailbox, news
+  // and other protocols where the URL inherits from nsIMsgMessageUrl.
+  // This is basically a "same origin" test. For other protocols we check the
+  // pre-paths.
+  nsCOMPtr<nsIMsgMessageUrl> contentURL(do_QueryInterface(aContentLocation));
+  if (contentURL) {
+    nsCOMPtr<nsIMsgMessageUrl> requestURL(do_QueryInterface(aRequestingLocation));
+    // If the request URL is not also a message URL, then we don't accept.
+    if (requestURL) {
+      nsCString contentPrincipalSpec, requestPrincipalSpec;
+      contentURL->GetPrincipalSpec(contentPrincipalSpec);
+      requestURL->GetPrincipalSpec(requestPrincipalSpec);
+      if (contentPrincipalSpec.Equals(requestPrincipalSpec))
+        *aDecision = nsIContentPolicy::ACCEPT;
+    }
+    return NS_OK;
+  }
+
+  // Compare pre-paths.
   nsCOMPtr<nsIMsgMailNewsUrl> mailnewsUrl(do_QueryInterface(aContentLocation));
   if (mailnewsUrl) {
     nsCString contentPrePath, requestingPrePath;
     aContentLocation->GetPrePath(contentPrePath);
     aRequestingLocation->GetPrePath(requestingPrePath);
-    if (contentPrePath.Equals(requestingPrePath))  {
+    if (contentPrePath.Equals(requestingPrePath)) {
       *aDecision = nsIContentPolicy::ACCEPT;
       return NS_OK;
     }
   }
 
   // If exposed protocol not covered by the test above or protocol that has been
   // specifically exposed by an add-on, or is a chrome url, then allow the load.
   if (IsExposedProtocol(aContentLocation))
--- a/mailnews/local/src/nsMailboxUrl.cpp
+++ b/mailnews/local/src/nsMailboxUrl.cpp
@@ -128,33 +128,46 @@ NS_IMETHODIMP nsMailboxUrl::GetPrincipal
 {
   nsCOMPtr<nsIMsgMailNewsUrl> mailnewsURL;
   QueryInterface(NS_GET_IID(nsIMsgMailNewsUrl), getter_AddRefs(mailnewsURL));
 
   nsAutoCString spec;
   mailnewsURL->GetSpec(spec);
 
   // mailbox: URLs contain a lot of query parts. We want need a normalised form:
-  // mailbox://folder?number=nn.
+  // mailbox:///path/to/folder?number=nn.
+  // We also need to translate the second form mailbox://user@domain@server/folder?number=nn.
 
   char* messageKey = extractAttributeValue(spec.get(), "number=");
 
   // Strip any query part beginning with ? & or /;
   int32_t ind = spec.Find("/;");
   if (ind != kNotFound)
     spec.SetLength(ind);
 
   ind = spec.FindChar('?');
   if (ind != kNotFound)
     spec.SetLength(ind);
 
   ind = spec.FindChar('&');
   if (ind != kNotFound)
     spec.SetLength(ind);
 
+  // Check for format lacking absolute path.
+  if (spec.Find("///") == kNotFound) {
+    nsCString folderPath;
+    nsresult rv = nsLocalURI2Path(kMailboxRootURI, spec.get(), folderPath);
+    if (NS_SUCCEEDED (rv)) {
+      nsAutoCString buf;
+      MsgEscapeURL(folderPath,
+                   nsINetUtil::ESCAPE_URL_DIRECTORY | nsINetUtil::ESCAPE_URL_FORCED, buf);
+      spec = NS_LITERAL_CSTRING("mailbox://") + buf;
+    }
+  }
+
   spec += NS_LITERAL_CSTRING("?number=");
   spec.Append(messageKey);
   PR_Free(messageKey);
 
   aPrincipalSpec.Assign(spec);
   return NS_OK;
 }