Bug 705072 - Limit HTML support in XHR to responseType == "document" to avoid changing the behavior for legacy users. r=smaug.

This commit is contained in:
Henri Sivonen 2011-11-24 17:28:12 +02:00
Родитель 1f97f4a559
Коммит a9fb0d6f91
5 изменённых файлов: 24 добавлений и 58 удалений

Просмотреть файл

@ -884,7 +884,7 @@ NS_IMETHODIMP nsXMLHttpRequest::GetResponseText(nsAString& aResponseText)
// We only decode text lazily if we're also parsing to a doc.
// Also, if we've decoded all current data already, then no need to decode
// more.
if (IsWaitingForHTMLCharset() || !mResponseXML ||
if (!mResponseXML ||
mResponseBodyDecodedPos == mResponseBody.Length()) {
aResponseText = mResponseText;
return NS_OK;
@ -1473,16 +1473,6 @@ nsXMLHttpRequest::IsSystemXHR()
return !!nsContentUtils::IsSystemPrincipal(mPrincipal);
}
bool
nsXMLHttpRequest::IsWaitingForHTMLCharset()
{
if (!mIsHtml || !mResponseXML) {
return false;
}
nsCOMPtr<nsIDocument> doc = do_QueryInterface(mResponseXML);
return doc->GetDocumentCharacterSetSource() < kCharsetFromDocTypeDefault;
}
nsresult
nsXMLHttpRequest::CheckChannelForCrossSiteRequest(nsIChannel* aChannel)
{
@ -1928,7 +1918,13 @@ nsXMLHttpRequest::OnStartRequest(nsIRequest *request, nsISupports *ctxt)
nsCAutoString type;
channel->GetContentType(type);
if (type.EqualsLiteral("text/html")) {
if ((mResponseType == XML_HTTP_RESPONSE_TYPE_DOCUMENT) &&
type.EqualsLiteral("text/html")) {
// HTML parsing is only supported for responseType == "document" to
// avoid running the parser and, worse, populating responseXML for
// legacy users of XHR who use responseType == "" for retrieving the
// responseText of text/html resources. This legacy case is so common
// that it's not useful to emit a warning about it.
if (!(mState & XML_HTTP_REQUEST_ASYNC)) {
// We don't make cool new features available in the bad synchronous
// mode. The synchronous mode is for legacy only.
@ -3138,13 +3134,11 @@ nsXMLHttpRequest::MaybeDispatchProgressEvents(bool aFinalProgress)
mLoadTotal = mLoadTransferred;
mLoadLengthComputable = true;
}
if (aFinalProgress || !IsWaitingForHTMLCharset()) {
mInLoadProgressEvent = true;
DispatchProgressEvent(this, NS_LITERAL_STRING(PROGRESS_STR),
true, mLoadLengthComputable, mLoadTransferred,
mLoadTotal, mLoadTransferred, mLoadTotal);
mInLoadProgressEvent = false;
}
mInLoadProgressEvent = true;
DispatchProgressEvent(this, NS_LITERAL_STRING(PROGRESS_STR),
true, mLoadLengthComputable, mLoadTransferred,
mLoadTotal, mLoadTransferred, mLoadTotal);
mInLoadProgressEvent = false;
if (mResponseType == XML_HTTP_RESPONSE_TYPE_CHUNKED_TEXT ||
mResponseType == XML_HTTP_RESPONSE_TYPE_CHUNKED_ARRAYBUFFER) {
mResponseBody.Truncate();

Просмотреть файл

@ -236,8 +236,6 @@ protected:
bool IsSystemXHR();
bool IsWaitingForHTMLCharset();
void ChangeStateToDone();
/**

Просмотреть файл

@ -510,7 +510,6 @@ _TEST_FILES2 = \
file_html_in_xhr2.html \
file_html_in_xhr3.html \
file_html_in_xhr.sjs \
file_html_in_xhr_slow.sjs \
test_bug664916.html \
test_bug666604.html \
test_bug675121.html \

Просмотреть файл

@ -1,24 +0,0 @@
var timer;
function handleRequest(request, response)
{
var converter = Components.classes["@mozilla.org/intl/scriptableunicodeconverter"]
.createInstance(Components.interfaces.nsIScriptableUnicodeConverter);
converter.charset = "windows-1251";
var stream = converter.convertToInputStream("\u042E");
var out = response.bodyOutputStream;
response.setHeader("Cache-Control", "no-cache", false);
response.setHeader("Content-Type", "text/html", false);
out.writeFrom(stream, 1);
var firstPart = "<meta charset='windows";
out.write(firstPart, firstPart.length);
out.flush();
response.processAsync();
timer = Components.classes["@mozilla.org/timer;1"]
.createInstance(Components.interfaces.nsITimer);
timer.initWithCallback(function() {
response.write("-1251'>");
response.finish();
}, 500, Components.interfaces.nsITimer.TYPE_ONE_SHOT);
}

Просмотреть файл

@ -29,7 +29,12 @@ function runTest() {
ok(this.responseXML, "Should have gotten responseXML");
is(this.responseXML.characterSet, "windows-1251", "Wrong character encoding");
is(this.responseXML.documentElement.firstChild.data, " \u042E ", "Decoded using the wrong encoding.");
is(this.responseText.indexOf("\u042E"), 27, "Bad responseText");
try {
this.responseText;
ok(false, "responseText access should have thrown.");
} catch (e) {
is(e.code, 11, "Should have thrown INVALID_STATE_ERR.");
}
is(this.responseXML.getElementsByTagName("div").length, 1, "There should be one div.");
ok(!this.responseXML.documentElement.hasAttribute("data-fail"), "Should not have a data-fail attribute.");
var scripts = this.responseXML.getElementsByTagName("script");
@ -44,27 +49,21 @@ function runTest() {
}
}
xhr.open("GET", "file_html_in_xhr.html", true);
xhr.responseType = "document";
xhr.send();
}
function continueAfterReport() {
ok(!document.documentElement.hasAttribute("data-fail"), "Should not have a data-fail attribute on mochitest doc.");
xhr = new XMLHttpRequest();
xhr.onprogress = function() {
ok(this.responseText, "Got falsy responseText");
if (this.responseText) {
ok(this.responseText.length, "Got zero-length responseText");
if (this.responseText.length) {
is(this.responseText.charCodeAt(0), 0x042E, "Wrong character encoding for slow text");
}
}
}
xhr.onreadystatechange = function() {
if (this.readyState == 4) {
is(this.responseText.indexOf("\u042E"), -1, "Honored meta in default mode.");
is(this.responseText.indexOf("\uFFFD"), 29, "Honored meta in default mode 2.");
is(this.responseXML, null, "responseXML should be null for HTML in the default mode");
testNonParsingText();
}
}
xhr.open("GET", "file_html_in_xhr_slow.sjs");
xhr.open("GET", "file_html_in_xhr2.html");
xhr.send();
}