mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
390126 unescape the URL before compressing whitespace r+sr=bz
This commit is contained in:
parent
a11ff4a96f
commit
b5a1f780d7
@ -114,20 +114,13 @@ nsDataChannel::OpenContentStream(PRBool async, nsIInputStream **result)
|
||||
contentType.StripWhitespace();
|
||||
contentCharset.StripWhitespace();
|
||||
|
||||
char *dataBuffer = nsnull;
|
||||
PRBool cleanup = PR_FALSE;
|
||||
if (!lBase64 && ((strncmp(contentType.get(),"text/",5) == 0) ||
|
||||
contentType.Find("xml") != kNotFound)) {
|
||||
// it's text, don't compress spaces
|
||||
dataBuffer = comma+1;
|
||||
} else {
|
||||
nsCAutoString dataBuffer(comma + 1);
|
||||
NS_UnescapeURL(dataBuffer);
|
||||
|
||||
if (lBase64 || ((strncmp(contentType.get(),"text/",5) != 0) &&
|
||||
contentType.Find("xml") == kNotFound)) {
|
||||
// it's ascii encoded binary, don't let any spaces in
|
||||
nsCAutoString dataBuf(comma+1);
|
||||
dataBuf.StripWhitespace();
|
||||
dataBuffer = ToNewCString(dataBuf);
|
||||
if (!dataBuffer)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
cleanup = PR_TRUE;
|
||||
dataBuffer.StripWhitespace();
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIInputStream> bufInStream;
|
||||
@ -139,12 +132,12 @@ nsDataChannel::OpenContentStream(PRBool async, nsIInputStream **result)
|
||||
NET_DEFAULT_SEGMENT_SIZE, PR_UINT32_MAX,
|
||||
async, PR_TRUE);
|
||||
if (NS_FAILED(rv))
|
||||
goto cleanup;
|
||||
return rv;
|
||||
|
||||
PRUint32 dataLen, contentLen;
|
||||
dataLen = nsUnescapeCount(dataBuffer);
|
||||
PRUint32 contentLen;
|
||||
if (lBase64) {
|
||||
*base64 = ';';
|
||||
const PRUint32 dataLen = dataBuffer.Length();
|
||||
PRInt32 resultLen = 0;
|
||||
if (dataLen >= 1 && dataBuffer[dataLen-1] == '=') {
|
||||
if (dataLen >= 2 && dataBuffer[dataLen-2] == '=')
|
||||
@ -159,20 +152,19 @@ nsDataChannel::OpenContentStream(PRBool async, nsIInputStream **result)
|
||||
// XXX PL_Base64Decode will return a null pointer for decoding
|
||||
// errors. Since those are more likely than out-of-memory,
|
||||
// should we return NS_ERROR_MALFORMED_URI instead?
|
||||
char * decodedData = PL_Base64Decode(dataBuffer, dataLen, nsnull);
|
||||
char * decodedData = PL_Base64Decode(dataBuffer.get(), dataLen, nsnull);
|
||||
if (!decodedData) {
|
||||
rv = NS_ERROR_OUT_OF_MEMORY;
|
||||
goto cleanup;
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
rv = bufOutStream->Write(decodedData, resultLen, &contentLen);
|
||||
|
||||
PR_Free(decodedData);
|
||||
} else {
|
||||
rv = bufOutStream->Write(dataBuffer, dataLen, &contentLen);
|
||||
rv = bufOutStream->Write(dataBuffer.get(), dataBuffer.Length(), &contentLen);
|
||||
}
|
||||
if (NS_FAILED(rv))
|
||||
goto cleanup;
|
||||
return rv;
|
||||
|
||||
*comma = ',';
|
||||
|
||||
@ -182,8 +174,5 @@ nsDataChannel::OpenContentStream(PRBool async, nsIInputStream **result)
|
||||
|
||||
NS_ADDREF(*result = bufInStream);
|
||||
|
||||
cleanup:
|
||||
if (cleanup)
|
||||
nsMemory::Free(dataBuffer);
|
||||
return rv;
|
||||
return NS_OK;
|
||||
}
|
||||
|
125
netwerk/test/unit/test_data_protocol.js
Normal file
125
netwerk/test/unit/test_data_protocol.js
Normal file
@ -0,0 +1,125 @@
|
||||
/* run some tests on the data: protocol handler */
|
||||
|
||||
const Cc = Components.classes;
|
||||
const Ci = Components.interfaces;
|
||||
const Cr = Components.results;
|
||||
|
||||
var urls = [
|
||||
["data:,foo", "foo"],
|
||||
["data:text/plain,foo%00 bar", "foo\x00 bar"],
|
||||
["data:text/plain;base64,Zm9 vI%20GJ%0Dhc%0Ag==", "foo bar"]
|
||||
];
|
||||
|
||||
function run_next_test() {
|
||||
test_array[test_index++]();
|
||||
}
|
||||
|
||||
/* read count bytes from stream and return as a String object */
|
||||
function read_stream(stream, count) {
|
||||
/* assume stream has non-ASCII data */
|
||||
var wrapper =
|
||||
Cc["@mozilla.org/binaryinputstream;1"].
|
||||
createInstance(Ci.nsIBinaryInputStream);
|
||||
wrapper.setInputStream(stream);
|
||||
/* JS methods can be called with a maximum of 65535 arguments, and input
|
||||
streams don't have to return all the data they make .available() when
|
||||
asked to .read() that number of bytes. */
|
||||
var data = [];
|
||||
while (count > 0) {
|
||||
var bytes = wrapper.readByteArray(Math.min(65535, count));
|
||||
data.push(String.fromCharCode.apply(null, bytes));
|
||||
count -= bytes.length;
|
||||
if (bytes.length == 0)
|
||||
do_throw("Nothing read from input stream!");
|
||||
}
|
||||
return data.join('');
|
||||
}
|
||||
|
||||
/* stream listener */
|
||||
function Listener(closure, ctx) {
|
||||
this._closure = closure;
|
||||
this._closurectx = ctx;
|
||||
}
|
||||
Listener.prototype = {
|
||||
_closure: null,
|
||||
_closurectx: null,
|
||||
_buffer: "",
|
||||
_got_onstartrequest: false,
|
||||
_got_onstoprequest: false,
|
||||
_contentLen: -1,
|
||||
|
||||
QueryInterface: function(iid) {
|
||||
if (iid.Equals(Ci.nsIStreamListener) ||
|
||||
iid.Equals(Ci.nsIRequestObserver) ||
|
||||
iid.Equals(Ci.nsISupports))
|
||||
return this;
|
||||
throw Cr.NS_ERROR_NO_INTERFACE;
|
||||
},
|
||||
|
||||
onStartRequest: function(request, context) {
|
||||
if (this._got_onstartrequest)
|
||||
do_throw("Got second onStartRequest event!");
|
||||
this._got_onstartrequest = true;
|
||||
|
||||
request.QueryInterface(Ci.nsIChannel);
|
||||
this._contentLen = request.contentLength;
|
||||
if (this._contentLen == -1)
|
||||
do_throw("Content length is unknown in onStartRequest!");
|
||||
},
|
||||
|
||||
onDataAvailable: function(request, context, stream, offset, count) {
|
||||
if (!this._got_onstartrequest)
|
||||
do_throw("onDataAvailable without onStartRequest event!");
|
||||
if (this._got_onstoprequest)
|
||||
do_throw("onDataAvailable after onStopRequest event!");
|
||||
if (!request.isPending())
|
||||
do_throw("request reports itself as not pending from onStartRequest!");
|
||||
|
||||
this._buffer = this._buffer.concat(read_stream(stream, count));
|
||||
},
|
||||
|
||||
onStopRequest: function(request, context, status) {
|
||||
if (!this._got_onstartrequest)
|
||||
do_throw("onStopRequest without onStartRequest event!");
|
||||
if (this._got_onstoprequest)
|
||||
do_throw("Got second onStopRequest event!");
|
||||
this._got_onstoprequest = true;
|
||||
if (!Components.isSuccessCode(status))
|
||||
do_throw("Failed to load URL: " + status.toString(16));
|
||||
if (status != request.status)
|
||||
do_throw("request.status does not match status arg to onStopRequest!");
|
||||
if (request.isPending())
|
||||
do_throw("request reports itself as pending from onStopRequest!");
|
||||
if (this._contentLen != -1 && this._buffer.length != this._contentLen)
|
||||
do_throw("did not read nsIChannel.contentLength number of bytes!");
|
||||
|
||||
this._closure(this._buffer, this._closurectx);
|
||||
}
|
||||
};
|
||||
|
||||
function run_test() {
|
||||
dump("*** run_test\n");
|
||||
|
||||
function on_read_complete(data, idx) {
|
||||
dump("*** run_test.on_read_complete\n");
|
||||
|
||||
if (chan.contentType != "text/plain")
|
||||
do_throw("Type mismatch! Is <" + chan.contentType + ">, should be text/plain")
|
||||
|
||||
/* read completed successfully. now compare the data. */
|
||||
if (data != urls[idx][1])
|
||||
do_throw("Stream contents do not match with direct read!");
|
||||
do_test_finished();
|
||||
}
|
||||
|
||||
var ios = Cc["@mozilla.org/network/io-service;1"].
|
||||
getService(Ci.nsIIOService);
|
||||
for (var i = 0; i < urls.length; ++i) {
|
||||
dump("*** opening channel " + i + "\n");
|
||||
do_test_pending();
|
||||
var chan = ios.newChannel(urls[i][0], "", null);
|
||||
chan.contentType = "foo/bar"; // should be ignored
|
||||
chan.asyncOpen(new Listener(on_read_complete, i), null);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user