Bug 794067 Sync Feed Preview with Firefox as at 2012/09 r=IanN. Branch safe patch. a=Callek SEAMONKEY_2_13b6_BUILD1 SEAMONKEY_2_13b6_RELEASE
authorPhilip Chee <philip.chee@gmail.com>
Tue, 25 Sep 2012 21:51:13 +0800
changeset 13044 f4d39ec8e3cd32044942dc166db7ac3a38622909
parent 13043 82714f12926b1e5a79fcaab350c9253b43896415
child 13045 6e3a0a87b80e72cf35f16be55ed4dea1b9eff93f
child 13047 3bdab442abc07eaf7788760174c371194061ee58
push idunknown
push userunknown
push dateunknown
reviewersIanN, Callek
bugs794067
Bug 794067 Sync Feed Preview with Firefox as at 2012/09 r=IanN. Branch safe patch. a=Callek
suite/browser/test/Makefile.in
suite/browser/test/mochitest/test_maxSniffing.html
suite/browser/test/mochitest/valid-feed.xml
suite/browser/test/mochitest/valid-unsniffable-feed.xml
suite/feeds/src/FeedConverter.js
suite/feeds/src/WebContentConverter.js
suite/feeds/src/nsFeedSniffer.cpp
--- a/suite/browser/test/Makefile.in
+++ b/suite/browser/test/Makefile.in
@@ -14,16 +14,19 @@ include $(topsrcdir)/config/rules.mk
 _TEST_FILES =	test_feed_discovery.html \
 		feed_discovery.html \
 		test_bug395533.html \
 		bug395533-data.txt \
 		test_bug364677.html \
 		bug364677-data.xml \
 		bug364677-data.xml^headers^ \
 		test_registerHandler.html \
+		valid-feed.xml \
+		valid-unsniffable-feed.xml \
+		test_maxSniffing.html \
 		$(NULL)
 
 # test_contextmenu.html is disabled on Linux due to bug 513558
 ifneq (gtk2,$(MOZ_WIDGET_TOOLKIT))
 _TEST_FILES += \
 		test_contextmenu.html \
 		subtst_contextmenu.html \
 		ctxmenu-image.png \
new file mode 100644
--- /dev/null
+++ b/suite/browser/test/mochitest/test_maxSniffing.html
@@ -0,0 +1,37 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=739040
+-->
+<head>
+  <title>Test that we only sniff 512 bytes</title>
+  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=739040">Mozilla Bug 739040</a>
+<p id="display">
+  <iframe id="validTestFrame" src="http://mochi.test:8888/tests/suite/browser/test/valid-feed.xml"></iframe>
+  <iframe id="unsniffableTestFrame" src="http://mochi.test:8888/tests/suite/browser/test/valid-unsniffable-feed.xml"></iframe>
+</p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+
+/** Test for Bug 739040 **/
+SimpleTest.waitForExplicitFinish();
+
+addLoadEvent(function() {
+  is($("validTestFrame").contentDocument.documentElement.id, "feedHandler",
+     "valid feed should be sniffed");
+  isnot($("unsniffableTestFrame").contentDocument.documentElement.id, "feedHandler",
+        "unsniffable feed should not be sniffed");
+});
+addLoadEvent(SimpleTest.finish);
+
+</script>
+</pre>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/suite/browser/test/mochitest/valid-feed.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+  <title>Example Feed</title>
+  <link href="http://example.org/"/>
+  <updated>2010-08-22T18:30:02Z</updated>
+
+  <author>
+    <name>John Doe</name>
+  </author>
+  <id>urn:uuid:e2df8375-99be-4848-b05e-b9d407555267</id>
+
+  <entry>
+
+    <title>Item</title>
+    <link href="http://example.org/first"/>
+    <id>urn:uuid:9e0f4bed-33d3-4a9d-97ab-ecaa31b3f14a</id>
+    <updated>2010-08-22T18:30:02Z</updated>
+
+    <summary>Some text.</summary>
+  </entry>
+
+</feed>
new file mode 100644
--- /dev/null
+++ b/suite/browser/test/mochitest/valid-unsniffable-feed.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 512 bytes!
+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+  -->
+<feed xmlns="http://www.w3.org/2005/Atom">
+
+  <title>Example Feed</title>
+  <link href="http://example.org/"/>
+  <updated>2010-08-22T18:30:02Z</updated>
+
+  <author>
+    <name>John Doe</name>
+  </author>
+  <id>urn:uuid:e2df8375-99be-4848-b05e-b9d407555267</id>
+
+  <entry>
+
+    <title>Item</title>
+    <link href="http://example.org/first"/>
+    <id>urn:uuid:9e0f4bed-33d3-4a9d-97ab-ecaa31b3f14a</id>
+    <updated>2010-08-22T18:30:02Z</updated>
+
+    <summary>Some text.</summary>
+  </entry>
+
+</feed>
--- a/suite/feeds/src/FeedConverter.js
+++ b/suite/feeds/src/FeedConverter.js
@@ -286,16 +286,23 @@ FeedConverter.prototype = {
    */
   onStartRequest: function onStartRequest(request, context) {
     var channel = request.QueryInterface(Components.interfaces.nsIChannel);
 
     // Check for a header that tells us there was no sniffing
     // The value doesn't matter.
     try {
       var httpChannel = channel.QueryInterface(Components.interfaces.nsIHttpChannel);
+      // Make sure to check requestSucceeded before the potentially-throwing
+      // getResponseHeader.
+      if (!httpChannel.requestSucceeded) {
+        // Just give up, but don't forget to cancel the channel first!
+        request.cancel(Components.results.NS_BINDING_ABORTED);
+        return;
+      }
       var noSniff = httpChannel.getResponseHeader("X-Moz-Is-Feed");
     }
     catch (ex) {
       this._sniffed = true;
     }
 
     this._request = request;
 
--- a/suite/feeds/src/WebContentConverter.js
+++ b/suite/feeds/src/WebContentConverter.js
@@ -1,15 +1,14 @@
 /* -*- Mode: Javascript; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
-Components.utils.import("resource://gre/modules/debug.js");
 
 const WCCR_CONTRACTID = "@mozilla.org/embeddor.implemented/web-content-handler-registrar;1";
 const WCCR_CLASSID = Components.ID("{792a7e82-06a0-437c-af63-b2d12e808acc}");
 
 const WCC_CLASSID = Components.ID("{db7ebf28-cc40-415f-8a51-1b111851df1e}");
 const WCC_CLASSNAME = "Web Service Handler";
 
 const TYPE_MAYBE_FEED = "application/vnd.mozilla.maybe.feed";
--- a/suite/feeds/src/nsFeedSniffer.cpp
+++ b/suite/feeds/src/nsFeedSniffer.cpp
@@ -29,17 +29,17 @@
 
 #define TYPE_ATOM "application/atom+xml"
 #define TYPE_RSS "application/rss+xml"
 #define TYPE_MAYBE_FEED "application/vnd.mozilla.maybe.feed"
 
 #define NS_RDF "http://www.w3.org/1999/02/22-rdf-syntax-ns#"
 #define NS_RSS "http://purl.org/rss/1.0/"
 
-#define MAX_BYTES 512
+#define MAX_BYTES 512u
 
 NS_IMPL_ISUPPORTS3(nsFeedSniffer,
                    nsIContentSniffer,
                    nsIStreamListener,
                    nsIRequestObserver)
 
 nsresult
 nsFeedSniffer::ConvertEncodedData(nsIRequest* request,
@@ -270,29 +270,32 @@ nsFeedSniffer::GetMIMETypeFromContent(ns
   }
 
   // Now we need to potentially decompress data served with
   // Content-Encoding: gzip
   nsresult rv = ConvertEncodedData(request, data, length);
   if (NS_FAILED(rv))
     return rv;
 
-  const char* testData =
-    mDecodedData.IsEmpty() ? (const char*)data : mDecodedData.get();
+  // We cap the number of bytes to scan at MAX_BYTES to prevent picking up
+  // false positives by accidentally reading document content, e.g. a "how to
+  // make a feed" page.
+  const char* testData;
+  if (mDecodedData.IsEmpty()) {
+    testData = (const char*)data;
+    length = NS_MIN(length, MAX_BYTES);
+  } else {
+    testData = mDecodedData.get();
+    length = NS_MIN(mDecodedData.Length(), MAX_BYTES);
+  }
 
   // The strategy here is based on that described in:
   // http://blogs.msdn.com/rssteam/articles/PublishersGuide.aspx
   // for interoperarbility purposes.
 
-  // We cap the number of bytes to scan at MAX_BYTES to prevent picking up
-  // false positives by accidentally reading document content, e.g. a "how to
-  // make a feed" page.
-  if (length > MAX_BYTES)
-    length = MAX_BYTES;
-
   // Thus begins the actual sniffing.
   nsDependentCSubstring dataString((const char*)testData, length);
 
   bool isFeed = false;
 
   // RSS 0.91/0.92/2.0
   isFeed = ContainsTopLevelSubstring(dataString, "<rss");