Bug 525222 - XML errors possible on file:// listings; r=bzbarsky a=jst
authorEhsan Akhgari <ehsan@mozilla.com>
Tue, 12 Oct 2010 18:30:42 -0400
changeset 55871 09adce374ccd1e46cc83e92250693d99174f0b10
parent 55870 ce62f87104e1863e89c4a7174ff4cdc78f1f41eb
child 55872 26f3aecd3d79d753f54aa5aa87171172e713e96c
push idunknown
push userunknown
push dateunknown
reviewersbzbarsky, jst
bugs525222
milestone2.0b8pre
Bug 525222 - XML errors possible on file:// listings; r=bzbarsky a=jst
netwerk/streamconv/converters/nsIndexedToHTML.cpp
toolkit/content/tests/chrome/test_bug437844.xul
xpfe/components/directory/nsDirectoryViewer.cpp
--- a/netwerk/streamconv/converters/nsIndexedToHTML.cpp
+++ b/netwerk/streamconv/converters/nsIndexedToHTML.cpp
@@ -49,16 +49,17 @@
 #include "prtime.h"
 #include "nsDateTimeFormatCID.h"
 #include "nsURLHelper.h"
 #include "nsCRT.h"
 #include "nsIPlatformCharset.h"
 #include "nsIPrefService.h"
 #include "nsIPrefBranch.h"
 #include "nsIPrefLocalizedString.h"
+#include "nsIChromeRegistry.h"
 
 NS_IMPL_ISUPPORTS4(nsIndexedToHTML,
                    nsIDirIndexListener,
                    nsIStreamConverter,
                    nsIRequestObserver,
                    nsIStreamListener)
 
 static void AppendNonAsciiToNCR(const nsAString& in, nsAFlatString& out)
@@ -152,17 +153,17 @@ NS_IMETHODIMP
 nsIndexedToHTML::OnStartRequest(nsIRequest* request, nsISupports *aContext) {
     nsresult rv;
 
     nsCOMPtr<nsIChannel> channel = do_QueryInterface(request);
     nsCOMPtr<nsIURI> uri;
     rv = channel->GetURI(getter_AddRefs(uri));
     if (NS_FAILED(rv)) return rv;
 
-    channel->SetContentType(NS_LITERAL_CSTRING("application/xhtml+xml"));
+    channel->SetContentType(NS_LITERAL_CSTRING("text/html"));
 
     mParser = do_CreateInstance("@mozilla.org/dirIndexParser;1",&rv);
     if (NS_FAILED(rv)) return rv;
 
     rv = mParser->SetListener(this);
     if (NS_FAILED(rv)) return rv;
     
     rv = mParser->OnStartRequest(request, aContext);
@@ -268,35 +269,32 @@ nsIndexedToHTML::OnStartRequest(nsIReque
         }
         if (!path.EqualsLiteral("/")) {
             rv = uri->Resolve(NS_LITERAL_CSTRING(".."), parentStr);
             if (NS_FAILED(rv)) return rv;
         }
     }
 
     nsString buffer;
-    buffer.AppendLiteral("<?xml version=\"1.0\" encoding=\"");
+    buffer.AppendLiteral("<!DOCTYPE html>\n"
+                         "<html>\n<head>\n"
+                         "<meta http-equiv=\"content-type\" content=\"text/html; charset=");
     
     // Get the encoding from the parser
     // XXX - this won't work for any encoding set via a 301: line in the
     // format - this output stuff would need to move to OnDataAvailable
     // for that.
 
     nsXPIDLCString encoding;
     rv = mParser->GetEncoding(getter_Copies(encoding));
     if (NS_FAILED(rv)) return rv;
 
     AppendASCIItoUTF16(encoding, buffer);
-    buffer.AppendLiteral("\"?>\n"
-                         "<!DOCTYPE html ["
-                         " <!ENTITY % globalDTD SYSTEM \"chrome://global/locale/global.dtd\">\n"
-                         " %globalDTD;\n"
-                         "]>\n"
-                         "<html xmlns=\"http://www.w3.org/1999/xhtml\">\n<head>\n"
-                         "<style type=\"text/css\"><![CDATA[\n"
+    buffer.AppendLiteral("\">\n"
+                         "<style type=\"text/css\">\n"
                          ":root {\n"
                          "  font-family: sans-serif;\n"
                          "}\n"
                          "img {\n"
                          "  border: 0;\n"
                          "}\n"
                          "th {\n"
                          "  text-align: start;\n"
@@ -372,20 +370,20 @@ nsIndexedToHTML::OnStartRequest(nsIReque
                          ".file > img {\n"
                          "  -moz-margin-end: 4px;\n"
                          "  -moz-margin-start: -20px;\n"
                          "  vertical-align: middle;\n"
                          "}\n"
                          ".dir::before {\n"
                          "  content: url(resource://gre/res/html/folder.png);\n"
                          "}\n"
-                         "]]></style>\n"
+                         "</style>\n"
                          "<link rel=\"stylesheet\" media=\"screen, projection\" type=\"text/css\""
-                         " href=\"chrome://global/skin/dirListing/dirListing.css\" />\n"
-                         "<script type=\"application/javascript\"><![CDATA[\n"
+                         " href=\"chrome://global/skin/dirListing/dirListing.css\">\n"
+                         "<script type=\"application/javascript\">\n"
                          "var gTable, gOrderBy, gTBody, gRows, gUI_showHidden;\n"
                          "document.addEventListener(\"DOMContentLoaded\", function() {\n"
                          "  gTable = document.getElementsByTagName(\"table\")[0];\n"
                          "  gTBody = gTable.tBodies[0];\n"
                          "  if (gTBody.rows.length < 2)\n"
                          "    return;\n"
                          "  gUI_showHidden = document.getElementById(\"UI_showHidden\");\n"
                          "  var headCells = gTable.tHead.rows[0].cells,\n"
@@ -453,17 +451,17 @@ nsIndexedToHTML::OnStartRequest(nsIReque
                          "      gTBody.appendChild(gRows[i]);\n"
                          "  gTable.appendChild(gTBody);\n"
                          "}\n"
                          "function updateHidden() {\n"
                          "  gTable.className = gUI_showHidden.getElementsByTagName(\"input\")[0].checked ?\n"
                          "                     \"\" :\n"
                          "                     \"remove-hidden\";\n"
                          "}\n"
-                         "]]></script>\n");
+                         "</script>\n");
 
     buffer.AppendLiteral("<link rel=\"icon\" type=\"image/png\" href=\"");
     nsCOMPtr<nsIURI> innerUri = NS_GetInnermostURI(uri);
     if (!innerUri)
         return NS_ERROR_UNEXPECTED;
     nsCOMPtr<nsIFileURL> fileURL(do_QueryInterface(innerUri));
     //XXX bug 388553: can't use skinnable icons here due to security restrictions
     if (fileURL) {
@@ -504,17 +502,17 @@ nsIndexedToHTML::OnStartRequest(nsIReque
                              "ZM04bddgG%2F9%2B8WGj87qDdsrK9m%2BoA%2BpbhQTDh2l1"
                              "%2Bi2weNbSHMZyjvNXmVbqh9Fj5Oz27uEoP%2BSTxANruJs9"
                              "L%2FT6P0ewqPx5nmiAG5f6AoCtN1PbJzuRyJAyDBzzSQYvEr"
                              "f06yYxhGXlEa8H2KVGoasjwLx3Ewk858opQWXm%2B%2Fib9E"
                              "QrBzclLLLy89xYvlpchvtixcX6uo1y%2FzsiwHrkIsgKbp%2"
                              "BYWFOWicuqppoNTnStHzPFCPQhBEBOyGAX4JMADFetubi4BS"
                              "YAAAAABJRU5ErkJggg%3D%3D");
     }
-    buffer.AppendLiteral("\" />\n<title>");
+    buffer.AppendLiteral("\">\n<title>");
 
     // Everything needs to end in a /,
     // otherwise we end up linking to file:///foo/dirfile
 
     if (!mTextToSubURI) {
         mTextToSubURI = do_GetService(NS_ITEXTTOSUBURI_CONTRACTID, &rv);
         if (NS_FAILED(rv)) return rv;
     }
@@ -580,17 +578,30 @@ nsIndexedToHTML::OnStartRequest(nsIReque
         buffer.Append(htmlEscapedUri);
         buffer.AppendLiteral("\" />\n");
     }
     else
     {
         NS_ERROR("broken protocol handler didn't escape double-quote.");
     }
 
-    buffer.AppendLiteral("</head>\n<body dir=\"&locale.dir;\">\n<h1>");
+    nsAutoString direction(NS_LITERAL_STRING("ltr"));
+    nsCOMPtr<nsIXULChromeRegistry> reg =
+      mozilla::services::GetXULChromeRegistryService();
+    if (reg) {
+      PRBool isRTL = PR_FALSE;
+      reg->IsLocaleRTL(NS_LITERAL_CSTRING("global"), &isRTL);
+      if (isRTL) {
+        direction.AssignLiteral("rtl");
+      }
+    }
+
+    buffer.AppendLiteral("</head>\n<body dir=\"");
+    buffer.Append(direction);
+    buffer.AppendLiteral("\">\n<h1>");
     
     const PRUnichar* formatHeading[] = {
         htmlEscSpec.get()
     };
 
     rv = mBundle->FormatStringFromName(NS_LITERAL_STRING("DirTitle").get(),
                                        formatHeading,
                                        sizeof(formatHeading)/sizeof(PRUnichar*),
@@ -618,17 +629,17 @@ nsIndexedToHTML::OnStartRequest(nsIReque
     }
 
     if (isSchemeFile) {
         nsXPIDLString showHiddenText;
         rv = mBundle->GetStringFromName(NS_LITERAL_STRING("ShowHidden").get(),
                                         getter_Copies(showHiddenText));
         if (NS_FAILED(rv)) return rv;
 
-        buffer.AppendLiteral("<p id=\"UI_showHidden\" style=\"display:none\"><label><input type=\"checkbox\" checked=\"checked\" onchange=\"updateHidden()\" />");
+        buffer.AppendLiteral("<p id=\"UI_showHidden\" style=\"display:none\"><label><input type=\"checkbox\" checked onchange=\"updateHidden()\">");
         AppendNonAsciiToNCR(showHiddenText, buffer);
         buffer.AppendLiteral("</label></p>\n");
     }
 
     buffer.AppendLiteral("<table>\n");
 
     nsXPIDLString columnText;
 
@@ -929,17 +940,17 @@ nsIndexedToHTML::OnIndexAvailable(nsIReq
         }
         pushBuffer.AppendLiteral("?size=16\" alt=\"");
 
         nsXPIDLString altText;
         rv = mBundle->GetStringFromName(NS_LITERAL_STRING("DirFileLabel").get(),
                                         getter_Copies(altText));
         if (NS_FAILED(rv)) return rv;
         AppendNonAsciiToNCR(altText, pushBuffer);
-        pushBuffer.AppendLiteral("\" />");
+        pushBuffer.AppendLiteral("\">");
     }
 
     pushBuffer.Append(escapedShort);
     pushBuffer.AppendLiteral("</a></td>\n <td");
 
     if (type == nsIDirIndex::TYPE_DIRECTORY || type == nsIDirIndex::TYPE_SYMLINK) {
         pushBuffer.AppendLiteral(">");
     } else {
--- a/toolkit/content/tests/chrome/test_bug437844.xul
+++ b/toolkit/content/tests/chrome/test_bug437844.xul
@@ -39,16 +39,20 @@ https://bugzilla.mozilla.org/show_bug.cg
   </body>
 
   <script class="testbody" type="application/javascript">
     <![CDATA[
 
       /** Test for Bug 437844 and Bug 348233 **/
       SimpleTest.waitForExplicitFinish();
 
+      let prefs = Components.classes["@mozilla.org/preferences-service;1"]
+                            .getService(Components.interfaces.nsIPrefBranch);
+      prefs.setCharPref("intl.uidirection.en-US", "rtl");
+
       let rootDir = getRootDirectory(window.location.href);
       let manifest = rootDir + "rtlchrome/rtl.manifest";
 
       //copy rtlchrome to profile/rtlchrome and generate .manifest
       let filePath = chromeURIToFile(manifest);
       let tempProfileDir = copyDirToTempProfile(filePath.path, 'rtlchrome');
       if (tempProfileDir.path.lastIndexOf('\\') >= 0) {
         manifest = "content rtlchrome /" + tempProfileDir.path.replace(/\\/g, '/') + "\n";
@@ -75,16 +79,17 @@ https://bugzilla.mozilla.org/show_bug.cg
           frame = document.createElement("iframe");
           frame.setAttribute("src", "file://" + tmpd.path); // a file:// URI, bug 348233
           frame.addEventListener("load", function () {
               frame.removeEventListener("load", arguments.callee, false);
 
               is(frame.contentDocument.body.dir, "rtl", "file:// listings should be RTL in RTL locales");
 
               cleanupFunc();
+              prefs.clearUserPref("intl.uidirection.en-US");
               SimpleTest.finish();
             }, false);
           document.documentElement.appendChild(frame);
         }, false);
       document.documentElement.appendChild(frame);
 
     ]]>
   </script>
--- a/xpfe/components/directory/nsDirectoryViewer.cpp
+++ b/xpfe/components/directory/nsDirectoryViewer.cpp
@@ -1420,39 +1420,39 @@ nsDirectoryViewerFactory::CreateInstance
     *aDocListenerResult = listener.get();
     NS_ADDREF(*aDocListenerResult);
     
     return NS_OK;
   }
 #endif
 
   // setup the original channel's content type
-  (void)aChannel->SetContentType(NS_LITERAL_CSTRING("application/xhtml+xml"));
+  (void)aChannel->SetContentType(NS_LITERAL_CSTRING("text/html"));
 
   // Otherwise, lets use the html listing
   nsCOMPtr<nsICategoryManager> catMan(do_GetService(NS_CATEGORYMANAGER_CONTRACTID, &rv));
   if (NS_FAILED(rv))
     return rv;
   nsXPIDLCString contractID;
-  rv = catMan->GetCategoryEntry("Gecko-Content-Viewers", "application/xhtml+xml",
+  rv = catMan->GetCategoryEntry("Gecko-Content-Viewers", "text/html",
                                 getter_Copies(contractID));
   if (NS_FAILED(rv))
     return rv;
 
   nsCOMPtr<nsIDocumentLoaderFactory> factory(do_GetService(contractID, &rv));
   if (NS_FAILED(rv)) return rv;
   
   nsCOMPtr<nsIStreamListener> listener;
 
   if (viewSource) {
-    rv = factory->CreateInstance("view-source", aChannel, aLoadGroup, "application/xhtml+xml; x-view-type=view-source",
+    rv = factory->CreateInstance("view-source", aChannel, aLoadGroup, "text/html; x-view-type=view-source",
                                  aContainer, aExtraInfo, getter_AddRefs(listener),
                                  aDocViewerResult);
   } else {
-    rv = factory->CreateInstance("view", aChannel, aLoadGroup, "application/xhtml+xml",
+    rv = factory->CreateInstance("view", aChannel, aLoadGroup, "text/html",
                                  aContainer, aExtraInfo, getter_AddRefs(listener),
                                  aDocViewerResult);
   }
 
   if (NS_FAILED(rv)) return rv;
 
   nsCOMPtr<nsIStreamConverterService> scs = do_GetService("@mozilla.org/streamConverters;1", &rv);
   if (NS_FAILED(rv)) return rv;