Send documents with null input encoding (e.g. those created with createDocument) as UTF-8 from XMLHttpRequest. Bug 431701, r+sr=sicking, a=dveditz

git-svn-id: svn://10.0.0.236/trunk@254556 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
bzbarsky%mit.edu 2008-10-07 16:34:22 +00:00
parent 2c4a75a793
commit 8cecd68fb5
7 changed files with 146 additions and 7 deletions

View File

@ -223,9 +223,7 @@ public:
virtual void SetBaseTarget(const nsAString &aBaseTarget) = 0;
/**
* Return a standard name for the document's character set. This
* will trigger a startDocumentLoad if necessary to answer the
* question.
* Return a standard name for the document's character set.
*/
const nsCString& GetDocumentCharacterSet() const
{

View File

@ -1477,6 +1477,8 @@ nsDocument::StartDocumentLoad(const char* aCommand, nsIChannel* aChannel,
mMayStartLayout = PR_FALSE;
mHaveInputEncoding = PR_TRUE;
if (aReset) {
Reset(aChannel, aLoadGroup);
}
@ -4375,7 +4377,12 @@ nsDocument::LookupNamespaceURI(const nsAString& aNamespacePrefix,
NS_IMETHODIMP
nsDocument::GetInputEncoding(nsAString& aInputEncoding)
{
return GetCharacterSet(aInputEncoding);
if (mHaveInputEncoding) {
return GetCharacterSet(aInputEncoding);
}
SetDOMStringToNull(aInputEncoding);
return NS_OK;
}
NS_IMETHODIMP

View File

@ -797,6 +797,10 @@ protected:
PRPackedBool mDelayFrameLoaderInitialization:1;
// If true, we have an input encoding. If this is false, then the
// document was created entirely in memory
PRPackedBool mHaveInputEncoding:1;
PRUint8 mXMLDeclarationBits;
PRUint8 mDefaultElementType;

View File

@ -84,6 +84,7 @@
#include "nsLayoutStatics.h"
#include "nsDOMError.h"
#include "nsIHTMLDocument.h"
#include "nsIDOM3Document.h"
#include "nsWhitespaceTokenizer.h"
#include "nsIMultiPartChannel.h"
#include "nsIScriptObjectPrincipal.h"
@ -1770,9 +1771,15 @@ nsXMLHttpRequest::Send(nsIVariant *aBody)
nsCOMPtr<nsIDOMSerializer> serializer(do_CreateInstance(NS_XMLSERIALIZER_CONTRACTID, &rv));
if (NS_FAILED(rv)) return rv;
nsCOMPtr<nsIDocument> baseDoc(do_QueryInterface(doc));
if (baseDoc) {
charset = baseDoc->GetDocumentCharacterSet();
nsCOMPtr<nsIDOM3Document> dom3doc(do_QueryInterface(doc));
if (dom3doc) {
nsAutoString inputEncoding;
dom3doc->GetInputEncoding(inputEncoding);
if (DOMStringIsNull(inputEncoding)) {
charset.AssignLiteral("UTF-8");
} else {
CopyUTF16toUTF8(inputEncoding, charset);
}
}
// Serialize to a stream so that the encoding used will

View File

@ -167,6 +167,7 @@ _TEST_FILES = test_bug5141.html \
file_bug426646-1.html \
file_bug426646-2.html \
test_bug429157.html \
test_bug431701.html \
test_XHR.html \
file_XHR_pass1.xml \
file_XHR_pass2.txt \

View File

@ -0,0 +1,120 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=431701
-->
<head>
<title>Test for Bug 431701</title>
<script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
<script type="text/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=431701">Mozilla Bug 431701</a>
<p id="display"></p>
<div id="content" style="display: none">
<iframe id="one"></iframe>
<iframe id="two"></iframe>
<iframe id="three"></iframe>
<iframe id="four"></iframe>
<iframe id="five"></iframe>
<iframe id="six"></iframe>
<iframe id="seven"></iframe>
</div>
<pre id="test">
<script class="testbody" type="text/javascript">
/** Test for Bug 431701 **/
SimpleTest.waitForExplicitFinish();
var docSources = [
"data:text/html,<html></html>",
"data:text/html;charset=UTF-8,<html></html>",
"data:text/html;charset=ISO-8859-1,<html></html>",
"data:text/xml,<html></html>",
"data:text/xml,<?xml version='1.0'?><html></html>",
"data:text/xml,<?xml version='1.0' encoding='UTF-8'?><html></html>",
"data:text/xml,<?xml version='1.0' encoding='ISO-8859-1'?><html></html>",
];
for (var i = 0; i < docSources.length; ++i) {
document.getElementsByTagName("iframe")[i].src = docSources[i];
}
function frameDoc(id) {
return function() { return $(id).contentDocument; };
}
function createDoc() {
return document.implementation.createDocument('', 'html', null);
}
function xhrDoc(idx) {
return function() {
// Defy same-origin restrictions!
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
var xhr = new XMLHttpRequest();
xhr.open("GET", docSources[idx], false);
xhr.send(null);
return xhr.responseXML;
};
}
// Each row has the document getter function, then the characterSet,
// inputEncoding, xmlEncoding expected for that document.
var tests = [
[ frameDoc("one"), "ISO-8859-1", "ISO-8859-1", null ],
[ frameDoc("two"), "UTF-8", "UTF-8", null ],
[ frameDoc("three"), "ISO-8859-1", "ISO-8859-1", null ],
[ frameDoc("four"), "UTF-8", "UTF-8", null ],
[ frameDoc("five"), "UTF-8", "UTF-8", null ],
[ frameDoc("six"), "UTF-8", "UTF-8", "UTF-8"],
[ frameDoc("seven"), "ISO-8859-1", "ISO-8859-1", "ISO-8859-1" ],
[ createDoc, "ISO-8859-1", null, null ],
[ xhrDoc(4), "UTF-8", "UTF-8", null ],
[ xhrDoc(5), "UTF-8", "UTF-8", "UTF-8" ],
[ xhrDoc(6), "ISO-8859-1", "ISO-8859-1", "ISO-8859-1" ],
];
function doTest(idx) {
var [docGetter, expectedCharacterSet,
expectedInputEncoding, expectedXMLEncoding] = tests[idx];
var doc = docGetter();
// Have to be careful here to catch null vs ""
is(doc.characterSet, expectedCharacterSet, "Test " + idx + " characterSet");
is(doc.inputEncoding, expectedInputEncoding,
"Test " + idx + " inputEncoding");
is(doc.xmlEncoding, expectedXMLEncoding, "Test " + idx + " xmlEncoding");
}
addLoadEvent(function() {
// sanity check
isnot("", null, "Shouldn't be equal!");
for (var i = 0; i < tests.length; ++i) {
doTest(i);
}
// Now check what xhr does
var xhr = new XMLHttpRequest();
xhr.open("POST", document.location.href);
xhr.send(createDoc());
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
is(xhr.channel.QueryInterface(Components.interfaces.nsIHttpChannel)
.getRequestHeader("Content-Type"),
"application/xml; charset=UTF-8", "Testing correct type on the wire");
xhr.abort();
SimpleTest.finish();
});
</script>
</pre>
</body>
</html>

View File

@ -429,6 +429,8 @@ nsXULDocument::StartDocumentLoad(const char* aCommand, nsIChannel* aChannel,
mChannel = aChannel;
mHaveInputEncoding = PR_TRUE;
// Get the URI. Note that this should match nsDocShell::OnLoadingSite
nsresult rv =
NS_GetFinalChannelURI(aChannel, getter_AddRefs(mDocumentURI));