Bug 1566595. Stop using [array] in nsIBinaryOutputStream. r=froydnj

Differential Revision: https://phabricator.services.mozilla.com/D38387

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Boris Zbarsky 2019-07-22 20:27:39 +00:00
parent 0129dacbea
commit 0f70d08ec8
33 changed files with 99 additions and 87 deletions

View File

@ -6,6 +6,6 @@ function handleRequest(request, response)
.createInstance(Components.interfaces.nsIBinaryOutputStream);
bos.setOutputStream(response.bodyOutputStream);
bos.writeByteArray(body, body.length);
bos.writeByteArray(body);
}

View File

@ -7,6 +7,7 @@
#include "mozilla/ArrayUtils.h"
#include "mozilla/BasicEvents.h"
#include "mozilla/CheckedInt.h"
#include "mozilla/Span.h"
#include "DataTransfer.h"
@ -1104,8 +1105,12 @@ already_AddRefed<nsITransferable> DataTransfer::GetTransferable(
totalCustomLength = 0;
continue;
}
rv = stream->WriteBytes((const char*)type.get(),
formatLength.value());
MOZ_ASSERT(formatLength.isValid() &&
formatLength.value() ==
type.Length() * sizeof(nsString::char_type),
"Why is formatLength off?");
rv = stream->WriteBytes(
AsBytes(MakeSpan(type.BeginReading(), type.Length())));
if (NS_WARN_IF(NS_FAILED(rv))) {
totalCustomLength = 0;
continue;
@ -1115,7 +1120,13 @@ already_AddRefed<nsITransferable> DataTransfer::GetTransferable(
totalCustomLength = 0;
continue;
}
rv = stream->WriteBytes((const char*)data.get(), lengthInBytes);
// XXXbz it's not obvious to me that lengthInBytes is the actual
// length of "data" if the variant contained an nsISupportsString
// as VTYPE_INTERFACE, say. We used lengthInBytes above for
// sizing, so just keep doing that.
rv = stream->WriteBytes(MakeSpan(
reinterpret_cast<const uint8_t*>(data.BeginReading()),
lengthInBytes));
if (NS_WARN_IF(NS_FAILED(rv))) {
totalCustomLength = 0;
continue;

View File

@ -15,6 +15,6 @@ function handleRequest(request, response) {
var bos = new BinaryOutputStream(response.bodyOutputStream);
response.processAsync();
bos.writeByteArray(bodyBytes, bodyBytes.length);
bos.writeByteArray(bodyBytes);
response.finish();
}

View File

@ -13,5 +13,5 @@ function handleRequest(request, response) {
.createInstance(Components.interfaces.nsIBinaryOutputStream);
bos.setOutputStream(response.bodyOutputStream);
bos.writeByteArray(bytes, bytes.length);
bos.writeByteArray(bytes);
}

View File

@ -21,10 +21,10 @@ function handleRequest(request, response) {
response.processAsync();
var part = bodyBytes.splice(0, 256);
bos.writeByteArray(part, part.length);
bos.writeByteArray(part);
response.timer1 = new Timer(function(timer) {
bos.writeByteArray(bodyBytes, bodyBytes.length);
bos.writeByteArray(bodyBytes);
}, 1000, Components.interfaces.nsITimer.TYPE_ONE_SHOT);
response.timer2 = new Timer(function(timer) {

View File

@ -62,7 +62,7 @@ function handleRequest(request, response)
response.setHeader("Content-Type", "image/png", false);
var stream = new BinaryOutputStream(response.bodyOutputStream);
stream.writeByteArray(IMAGE_DATA, IMAGE_DATA.length);
stream.writeByteArray(IMAGE_DATA);
}
else
{

View File

@ -25,7 +25,7 @@ function dumpToFile(aData) {
);
bos.setOutputStream(outputStream);
bos.writeByteArray(aData, aData.length);
bos.writeByteArray(aData);
outputStream.close();
}

View File

@ -89,7 +89,7 @@ function test_cross_conversion()
while ((av = fin.available()) > 0)
{
var data = fin.readByteArray(av);
bos.writeByteArray(data, data.length);
bos.writeByteArray(data);
}
fin.close();
bos.close();

View File

@ -973,7 +973,8 @@ static nsresult WriteScriptOrFunction(nsIObjectOutputStream* stream,
}
rv = stream->Write32(size);
if (NS_SUCCEEDED(rv)) {
rv = stream->WriteBytes(reinterpret_cast<char*>(buffer.begin()), size);
// Ideally we could just pass "buffer" here. See bug 1566574.
rv = stream->WriteBytes(MakeSpan(buffer.begin(), size));
}
return rv;

View File

@ -62,7 +62,7 @@ function handleRequest(request, response)
response.setHeader("Content-Type", "image/png", false);
var stream = new BinaryOutputStream(response.bodyOutputStream);
stream.writeByteArray(IMAGE_DATA, IMAGE_DATA.length);
stream.writeByteArray(IMAGE_DATA);
}
else
{

View File

@ -43,7 +43,7 @@ function handleRequest(request, response) {
function imageWrite() {
var stream = new BinaryOutputStream(response.bodyOutputStream);
stream.writeByteArray(IMAGE_DATA, IMAGE_DATA.length);
stream.writeByteArray(IMAGE_DATA);
}
// If there is no delay, we write the image and leave.

View File

@ -205,7 +205,7 @@ function handleRequest(request, response) {
function fontWrite(data) {
var stream = new BinaryOutputStream(response.bodyOutputStream);
stream.writeByteArray(data, data.length);
stream.writeByteArray(data);
}
const nsITimer = Components.interfaces.nsITimer;

View File

@ -19,7 +19,7 @@ function handleRequest(request, response)
response.setHeader("Cache-Control", "no-cache", false);
var stream = new BinaryOutputStream(response.bodyOutputStream);
stream.writeByteArray(FONT_DATA, FONT_DATA.length);
stream.writeByteArray(FONT_DATA);
}
/**

View File

@ -37,7 +37,7 @@ function handleRequest(request, response) {
function fontWrite(data) {
var stream = new BinaryOutputStream(response.bodyOutputStream);
stream.writeByteArray(data, data.length);
stream.writeByteArray(data);
}
var f;

View File

@ -39,11 +39,11 @@ function handleRequest(request, response)
if (query["q"] == "init") {
log = "init"; // initialize the log, and return a PNG image
response.setHeader("Content-Type", "image/png", false);
stream.writeByteArray(RED_SQUARE, RED_SQUARE.length);
stream.writeByteArray(RED_SQUARE);
} else if (query["q"] == "image") {
log = log + ";" + query["q"];
response.setHeader("Content-Type", "image/png", false);
stream.writeByteArray(RED_SQUARE, RED_SQUARE.length);
stream.writeByteArray(RED_SQUARE);
} else if (query["q"] == "font") {
log = log + ";" + query["q"];
// we don't provide a real font; that's ok, OTS will just reject it

View File

@ -1532,9 +1532,10 @@ RequestReader.prototype = {
" excess=" +
(data.length - count)
);
data.length = count;
var bos = new BinaryOutputStream(this._metadata._bodyOutputStream);
bos.writeByteArray(data, count);
bos.writeByteArray(data);
this._contentLength -= count;
}
@ -2861,7 +2862,7 @@ ServerHandler.prototype = {
", expected " +
chunkSize
);
output.writeByteArray(data, data.length);
output.writeByteArray(data);
if (count === 0) {
fis.close();
response.finish();

View File

@ -867,19 +867,9 @@ function CustomPipe(name) {
//
// see nsIBinaryOutputStream.writeByteArray
//
writeByteArray: function writeByteArray(bytes, length) {
dumpn(
"*** [" +
this.name +
"].writeByteArray" +
"([" +
bytes +
"], " +
length +
")"
);
writeByteArray: function writeByteArray(bytes) {
dumpn(`*** [${this.name}].writeByteArray([${bytes}])`);
Assert.equal(bytes.length, length, "sanity");
if (!Components.isSuccessCode(self._status)) {
throw self._status;
}
@ -890,12 +880,12 @@ function CustomPipe(name) {
"writeByteArray can't support specified-length writes"
);
if (this._writable < length) {
if (this._writable < bytes.length) {
throw Cr.NS_BASE_STREAM_WOULD_BLOCK;
}
self._data.push.apply(self._data, bytes);
this._writable -= length;
this._writable -= bytes.length;
if (
input._readable === Infinity &&
@ -1164,7 +1154,7 @@ CopyTest.prototype = {
try {
self._copyableDataStream.makeWritable(bytes.length);
self._copyableDataStream.writeByteArray(bytes, bytes.length);
self._copyableDataStream.writeByteArray(bytes);
} finally {
self._stageNextTask();
}

View File

@ -240,7 +240,7 @@ function handleAsyncOrdering(request, response) {
}
try {
out.writeByteArray(data, data.length);
out.writeByteArray(data);
step();
} catch (e) {
try {

View File

@ -91,6 +91,6 @@ function handler(metadata, response) {
bos.setOutputStream(response.bodyOutputStream);
response.processAsync();
bos.writeByteArray(responseBody, responseBody.length);
bos.writeByteArray(responseBody);
response.finish();
}

View File

@ -203,6 +203,6 @@ function handler(metadata, response) {
bos.setOutputStream(response.bodyOutputStream);
response.processAsync();
bos.writeByteArray(tests[index].body, tests[index].body.length);
bos.writeByteArray(tests[index].body);
response.finish();
}

View File

@ -118,7 +118,7 @@ function cachedHandler(metadata, response) {
bos.setOutputStream(response.bodyOutputStream);
response.processAsync();
bos.writeByteArray(body, body.length);
bos.writeByteArray(body);
response.finish();
}

View File

@ -261,7 +261,7 @@ function handler_4(metadata, response) {
);
bos.setOutputStream(response.bodyOutputStream);
response.processAsync();
bos.writeByteArray(body, body.length);
bos.writeByteArray(body);
response.finish();
break;
case 1:

View File

@ -129,7 +129,7 @@ function serverHandler_GZip(metadata, response) {
Ci.nsIBinaryOutputStream
);
bos.setOutputStream(response.bodyOutputStream);
bos.writeByteArray(httpbodyGZip, httpbodyGZip.length);
bos.writeByteArray(httpbodyGZip);
if (dbg) {
print("============== serverHandler GZip: out");
}

View File

@ -13,6 +13,7 @@
#include "mozilla/Base64.h"
#include "mozilla/Casting.h"
#include "mozilla/NotNull.h"
#include "mozilla/Span.h"
#include "mozilla/Unused.h"
#include "nsArray.h"
#include "nsCOMPtr.h"
@ -1194,7 +1195,7 @@ nsNSSCertificate::Write(nsIObjectOutputStream* aStream) {
if (NS_FAILED(rv)) {
return rv;
}
return aStream->WriteByteArray(mCert->derCert.data, mCert->derCert.len);
return aStream->WriteBytes(AsBytes(MakeSpan(mCert->derCert.data, mCert->derCert.len)));
}
NS_IMETHODIMP

View File

@ -1809,10 +1809,7 @@ add_task(async function test_with_content_encoding() {
);
let bos = new BinaryOutputStream(aResponse.bodyOutputStream);
bos.writeByteArray(
TEST_DATA_SHORT_GZIP_ENCODED,
TEST_DATA_SHORT_GZIP_ENCODED.length
);
bos.writeByteArray(TEST_DATA_SHORT_GZIP_ENCODED);
});
let download = await promiseStartDownload(sourceUrl);
@ -1849,10 +1846,7 @@ add_task(async function test_with_content_encoding_ignore_extension() {
);
let bos = new BinaryOutputStream(aResponse.bodyOutputStream);
bos.writeByteArray(
TEST_DATA_SHORT_GZIP_ENCODED,
TEST_DATA_SHORT_GZIP_ENCODED.length
);
bos.writeByteArray(TEST_DATA_SHORT_GZIP_ENCODED);
});
let download = await promiseStartDownload(sourceUrl);

View File

@ -870,17 +870,11 @@ add_task(function test_common_initialize() {
);
let bos = new BinaryOutputStream(aResponse.bodyOutputStream);
bos.writeByteArray(
TEST_DATA_SHORT_GZIP_ENCODED_FIRST,
TEST_DATA_SHORT_GZIP_ENCODED_FIRST.length
);
bos.writeByteArray(TEST_DATA_SHORT_GZIP_ENCODED_FIRST);
},
function secondPart(aRequest, aResponse) {
let bos = new BinaryOutputStream(aResponse.bodyOutputStream);
bos.writeByteArray(
TEST_DATA_SHORT_GZIP_ENCODED_SECOND,
TEST_DATA_SHORT_GZIP_ENCODED_SECOND.length
);
bos.writeByteArray(TEST_DATA_SHORT_GZIP_ENCODED_SECOND);
}
);

View File

@ -111,7 +111,7 @@ function handler(metadata, response) {
response.setHeader("Content-Type", "", false);
var body = getFileContents(do_get_file(tests[testRan].path));
var bos = new BinaryOutputStream(response.bodyOutputStream);
bos.writeByteArray(body, body.length);
bos.writeByteArray(body);
}
function run_test() {

View File

@ -49,13 +49,13 @@ function streamDefaultFavicon(uri, loadInfo, outputStream, originalChannel) {
}
}
function serveIcon(pipe, data, len) {
function serveIcon(pipe, data) {
// Pass the icon data to the output stream.
let stream = Cc["@mozilla.org/binaryoutputstream;1"].createInstance(
Ci.nsIBinaryOutputStream
);
stream.setOutputStream(pipe.outputStream);
stream.writeByteArray(data, len);
stream.writeByteArray(data);
stream.close();
pipe.outputStream.close();
}
@ -109,7 +109,10 @@ PageIconProtocolHandler.prototype = {
try {
channel.contentType = mimeType;
channel.contentLength = len;
serveIcon(pipe, data, len);
if (len != data.length) {
throw new Error("Unexpected data length");
}
serveIcon(pipe, data);
} catch (ex) {
streamDefaultFavicon(uri, loadInfo, pipe.outputStream, channel);
}

View File

@ -48,7 +48,7 @@ function write_string_to_file(file, contents) {
bos.setOutputStream(ostream);
let utf8 = new TextEncoder("utf-8").encode(contents);
bos.writeByteArray(utf8, utf8.length);
bos.writeByteArray(utf8);
ostream.QueryInterface(Ci.nsISafeOutputStream).finish();
ostream.close();
}

View File

@ -26,6 +26,7 @@
#include "mozilla/EndianUtils.h"
#include "mozilla/PodOperations.h"
#include "mozilla/RefPtr.h"
#include "mozilla/Span.h"
#include "mozilla/UniquePtr.h"
#include "nsCRT.h"
@ -41,8 +42,11 @@
#include "js/RootingAPI.h" // JS::{Handle,Rooted}
#include "js/Value.h" // JS::Value
using mozilla::AsBytes;
using mozilla::MakeSpan;
using mozilla::MakeUnique;
using mozilla::PodCopy;
using mozilla::Span;
using mozilla::UniquePtr;
already_AddRefed<nsIObjectOutputStream> NS_NewObjectOutputStream(
@ -206,11 +210,8 @@ nsBinaryOutputStream::WriteStringZ(const char* aString) {
NS_IMETHODIMP
nsBinaryOutputStream::WriteWStringZ(const char16_t* aString) {
uint32_t length, byteCount;
nsresult rv;
length = NS_strlen(aString);
rv = Write32(length);
uint32_t length = NS_strlen(aString);
nsresult rv = Write32(length);
if (NS_FAILED(rv)) {
return rv;
}
@ -218,10 +219,9 @@ nsBinaryOutputStream::WriteWStringZ(const char16_t* aString) {
if (length == 0) {
return NS_OK;
}
byteCount = length * sizeof(char16_t);
#ifdef IS_BIG_ENDIAN
rv = WriteBytes(reinterpret_cast<const char*>(aString), byteCount);
rv = WriteBytes(AsBytes(MakeSpan(aString, length)));
#else
// XXX use WriteSegments here to avoid copy!
char16_t* copy;
@ -229,14 +229,14 @@ nsBinaryOutputStream::WriteWStringZ(const char16_t* aString) {
if (length <= 64) {
copy = temp;
} else {
copy = reinterpret_cast<char16_t*>(malloc(byteCount));
copy = static_cast<char16_t*>(malloc(length * sizeof(char16_t)));
if (!copy) {
return NS_ERROR_OUT_OF_MEMORY;
}
}
NS_ASSERTION((uintptr_t(aString) & 0x1) == 0, "aString not properly aligned");
mozilla::NativeEndian::copyAndSwapToBigEndian(copy, aString, length);
rv = WriteBytes(reinterpret_cast<const char*>(copy), byteCount);
rv = WriteBytes(AsBytes(MakeSpan(copy, length)));
if (copy != temp) {
free(copy);
}
@ -250,24 +250,29 @@ nsBinaryOutputStream::WriteUtf8Z(const char16_t* aString) {
return WriteStringZ(NS_ConvertUTF16toUTF8(aString).get());
}
NS_IMETHODIMP
nsBinaryOutputStream::WriteBytes(const char* aString, uint32_t aLength) {
nsresult nsBinaryOutputStream::WriteBytes(Span<const uint8_t> aBytes) {
nsresult rv;
uint32_t bytesWritten;
rv = Write(aString, aLength, &bytesWritten);
rv = Write(reinterpret_cast<const char*>(aBytes.Elements()), aBytes.Length(),
&bytesWritten);
if (NS_FAILED(rv)) {
return rv;
}
if (bytesWritten != aLength) {
if (bytesWritten != aBytes.Length()) {
return NS_ERROR_FAILURE;
}
return rv;
}
NS_IMETHODIMP
nsBinaryOutputStream::WriteByteArray(uint8_t* aBytes, uint32_t aLength) {
return WriteBytes(reinterpret_cast<char*>(aBytes), aLength);
nsBinaryOutputStream::WriteBytesFromJS(const char* aString, uint32_t aLength) {
return WriteBytes(AsBytes(MakeSpan(aString, aLength)));
}
NS_IMETHODIMP
nsBinaryOutputStream::WriteByteArray(const nsTArray<uint8_t>& aByteArray) {
return WriteBytes(aByteArray);
}
NS_IMETHODIMP
@ -340,7 +345,7 @@ nsBinaryOutputStream::WriteID(const nsIID& aIID) {
return rv;
}
rv = WriteBytes(reinterpret_cast<const char*>(&aIID.m3[0]), sizeof(aIID.m3));
rv = WriteBytes(aIID.m3);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}

View File

@ -5,6 +5,13 @@
#include "nsIOutputStream.idl"
%{C++
namespace mozilla {
template<class ElementType, size_t Extent> class Span;
}
%}
native Bytes(mozilla::Span<const uint8_t>);
/**
* This interface allows writing of primitive data types (integers,
* floating-point values, booleans, etc.) to a stream in a binary, untagged,
@ -55,15 +62,20 @@ interface nsIBinaryOutputStream : nsIOutputStream {
/**
* Write an opaque byte array to the stream.
*/
[binaryname(WriteBytesFromJS)]
void writeBytes([size_is(aLength)] in string aString,
[optional] in uint32_t aLength);
/**
* Non-scriptable and saner-signature version of the same.
*/
[noscript, nostdcall, binaryname(WriteBytes)]
void writeBytesNative(in Bytes aBytes);
/**
* Write an opaque byte array to the stream.
*/
void writeByteArray([array, size_is(aLength)] in uint8_t aBytes,
[optional] in uint32_t aLength);
void writeByteArray(in Array<uint8_t> aBytes);
};
%{C++

View File

@ -117,7 +117,7 @@ function test4() {
);
bos.setOutputStream(outStream);
bos.writeByteArray(bytes, bytes.length);
bos.writeByteArray(bytes);
bos.close();
var inp = ss.newInputStream(0);

View File

@ -67,13 +67,13 @@ function test_binary_streams() {
Assert.equal(msg, HelloStr);
msg = null;
countObj.value = -1;
os.writeByteArray(HelloArray, HelloArray.length);
os.writeByteArray(HelloArray);
Assert.equal(is.available(), HelloStr.length);
msg = is.readByteArray(HelloStr.length);
Assert.equal(typeof msg, typeof HelloArray);
Assert.equal(msg.toSource(), HelloArray.toSource());
Assert.equal(is.available(), 0);
os.writeByteArray(HelloArray, HelloArray.length);
os.writeByteArray(HelloArray);
Assert.equal(
is.readArrayBuffer(buffer.byteLength, buffer),
HelloArray.length
@ -96,7 +96,7 @@ function test_binary_streams() {
os.writeStringZ("Mozilla");
os.writeWStringZ("Gecko");
os.writeBytes(HelloStr, HelloStr.length);
os.writeByteArray(HelloArray, HelloArray.length);
os.writeByteArray(HelloArray);
// Available should not be zero after a long write like this.
Assert.notEqual(is.available(), 0);