Bug 464339 - Links to images and non-textish media should not have view-source: links, r+sr=roc
authorCurtis Bartley <cbartley@mozilla.com>
Thu, 15 Jan 2009 20:02:20 -0800
changeset 23775 745c0c2aa1fe3565012fc62e9daa164912f1d262
parent 23774 5f6a14938c33034ba61d599b6de076e8f78d8a2e
child 23776 ff19e9cd2dfdc34acb70df9c1eebb98616498d5e
push idunknown
push userunknown
push dateunknown
bugs464339
milestone1.9.2a1pre
Bug 464339 - Links to images and non-textish media should not have view-source: links, r+sr=roc
layout/build/nsContentDLF.cpp
layout/build/nsContentDLF.h
layout/reftests/view-source/reftests.list
layout/reftests/view-source/view-source-image-ref.html
layout/reftests/view-source/view-source-image.html
--- a/layout/build/nsContentDLF.cpp
+++ b/layout/build/nsContentDLF.cpp
@@ -159,28 +159,32 @@ nsContentDLF::CreateInstance(const char*
                              nsIChannel* aChannel,
                              nsILoadGroup* aLoadGroup,
                              const char* aContentType, 
                              nsISupports* aContainer,
                              nsISupports* aExtraInfo,
                              nsIStreamListener** aDocListener,
                              nsIContentViewer** aDocViewer)
 {
+  // Declare "type" here.  This is because although the variable itself only
+  // needs limited scope, we need to use the raw string memory -- as returned
+  // by "type.get()" farther down in the function.
+  nsCAutoString type;
+
   // Are we viewing source?
 #ifdef MOZ_VIEW_SOURCE
   nsCOMPtr<nsIViewSourceChannel> viewSourceChannel = do_QueryInterface(aChannel);
   if (viewSourceChannel)
   {
     aCommand = "view-source";
 
     // The parser freaks out when it sees the content-type that a
     // view-source channel normally returns.  Get the actual content
     // type of the data.  If it's known, use it; otherwise use
     // text/plain.
-    nsCAutoString type;
     viewSourceChannel->GetOriginalContentType(type);
     PRBool knownType = PR_FALSE;
     PRInt32 typeIndex;
     for (typeIndex = 0; gHTMLTypes[typeIndex] && !knownType; ++typeIndex) {
       if (type.Equals(gHTMLTypes[typeIndex]) &&
           !type.EqualsLiteral("application/x-view-source")) {
         knownType = PR_TRUE;
       }
@@ -205,16 +209,20 @@ nsContentDLF::CreateInstance(const char*
     for (typeIndex = 0; gXULTypes[typeIndex] && !knownType; ++typeIndex) {
       if (type.Equals(gXULTypes[typeIndex])) {
         knownType = PR_TRUE;
       }
     }
 
     if (knownType) {
       viewSourceChannel->SetContentType(type);
+    } else if (IsImageContentType(type.get())) {
+      // If it's an image, we want to display it the same way we normally would.
+      // Also note the lifetime of "type" allows us to safely use "get()" here.
+      aContentType = type.get();
     } else {
       viewSourceChannel->SetContentType(NS_LITERAL_CSTRING("text/plain"));
     }
   } else if (0 == PL_strcmp("application/x-view-source", aContentType)) {
     aChannel->SetContentType(NS_LITERAL_CSTRING("text/plain"));
     aContentType = "text/plain";
   }
 #endif
@@ -274,20 +282,17 @@ nsContentDLF::CreateInstance(const char*
     return CreateDocument(aCommand, 
                           aChannel, aLoadGroup,
                           aContainer, kVideoDocumentCID,
                           aDocListener, aDocViewer);
   }  
 #endif
 
   // Try image types
-  nsCOMPtr<imgILoader> loader(do_GetService("@mozilla.org/image/loader;1"));
-  PRBool isReg = PR_FALSE;
-  loader->SupportImageWithMimeType(aContentType, &isReg);
-  if (isReg) {
+  if (IsImageContentType(aContentType)) {
     return CreateDocument(aCommand, 
                           aChannel, aLoadGroup,
                           aContainer, kImageDocumentCID,
                           aDocListener, aDocViewer);
   }
 
   nsCOMPtr<nsIPluginHost> ph (do_GetService(kPluginManagerCID));
   if(ph && NS_SUCCEEDED(ph->IsPluginEnabledForType(aContentType))) {
@@ -601,8 +606,16 @@ nsContentDLF::UnregisterDocumentFactorie
 #endif
     rv = UnregisterTypes(catmgr, gXULTypes);
     if (NS_FAILED(rv))
       break;
   } while (PR_FALSE);
 
   return rv;
 }
+
+PRBool nsContentDLF::IsImageContentType(const char* aContentType) {
+  nsCOMPtr<imgILoader> loader(do_GetService("@mozilla.org/image/loader;1"));
+  PRBool isDecoderAvailable = PR_FALSE;
+  loader->SupportImageWithMimeType(aContentType, &isDecoderAvailable);
+  return isDecoderAvailable;
+}
+
--- a/layout/build/nsContentDLF.h
+++ b/layout/build/nsContentDLF.h
@@ -96,15 +96,16 @@ public:
   static NS_IMETHODIMP
   UnregisterDocumentFactories(nsIComponentManager* aCompMgr,
                               nsIFile* aPath,
                               const char* aRegistryLocation,
                               const nsModuleComponentInfo* aInfo);
 
 private:
   static nsresult EnsureUAStyleSheet();
+  static PRBool IsImageContentType(const char* aContentType);
 };
 
 nsresult
 NS_NewContentDocumentLoaderFactory(nsIDocumentLoaderFactory** aResult);
 
 #endif
 
new file mode 100644
--- /dev/null
+++ b/layout/reftests/view-source/reftests.list
@@ -0,0 +1,2 @@
+== view-source-image.html view-source-image-ref.html
+
new file mode 100644
--- /dev/null
+++ b/layout/reftests/view-source/view-source-image-ref.html
@@ -0,0 +1,2 @@
+<iframe src="mozilla-16.png">
+
new file mode 100644
--- /dev/null
+++ b/layout/reftests/view-source/view-source-image.html
@@ -0,0 +1,8 @@
+<script>
+  var url = document.location.href;
+  var imageUrl = url.replace(/[/][^/]*$/, "/mozilla-16.png");
+  var viewSourceImageUrl = "view-source:" + imageUrl;
+  var html = "<iframe src='#url#'>".replace(/#url#/, viewSourceImageUrl);
+  document.write(html);
+</script>
+