Bug 637683: Ensure that the underlying buffer does not go away before any streams handed out by nsDOMMemoryFile. r=sicking a=blocker

This commit is contained in:
Kyle Huey 2011-03-01 18:35:53 -05:00
Родитель ad7ec27893
Коммит ad22b0f8cc
2 изменённых файлов: 60 добавлений и 4 удалений

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

@ -153,6 +153,7 @@ public:
const nsAString& aContentType, nsIDOMBlob **aBlob);
protected:
friend class DataOwnerAdapter; // Needs to see DataOwner
class DataOwner {
public:
NS_INLINE_DECL_REFCOUNTING(DataOwner)

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

@ -69,6 +69,64 @@
using namespace mozilla;
// XXXkhuey the input stream that we pass out of a DOMFile
// can outlive the actual DOMFile object. Thus, we must
// ensure that the buffer underlying the stream we get
// from NS_NewByteInputStream is held alive as long as the
// stream is. We do that by passing back this class instead.
class DataOwnerAdapter : public nsIInputStream,
public nsISeekableStream {
typedef nsDOMMemoryFile::DataOwner DataOwner;
public:
static nsresult Create(DataOwner* aDataOwner,
PRUint32 aStart,
PRUint32 aLength,
nsIInputStream** _retval);
NS_DECL_ISUPPORTS
NS_FORWARD_NSIINPUTSTREAM(mStream->)
NS_FORWARD_NSISEEKABLESTREAM(mSeekableStream->)
private:
DataOwnerAdapter(DataOwner* aDataOwner,
nsIInputStream* aStream)
: mDataOwner(aDataOwner), mStream(aStream),
mSeekableStream(do_QueryInterface(aStream))
{
NS_ASSERTION(mSeekableStream, "Somebody gave us the wrong stream!");
}
nsRefPtr<DataOwner> mDataOwner;
nsCOMPtr<nsIInputStream> mStream;
nsCOMPtr<nsISeekableStream> mSeekableStream;
};
NS_IMPL_THREADSAFE_ISUPPORTS2(DataOwnerAdapter, nsIInputStream, nsISeekableStream)
nsresult DataOwnerAdapter::Create(DataOwner* aDataOwner,
PRUint32 aStart,
PRUint32 aLength,
nsIInputStream** _retval)
{
nsresult rv;
NS_ASSERTION(aDataOwner, "Uh ...");
nsCOMPtr<nsIInputStream> stream;
rv = NS_NewByteInputStream(getter_AddRefs(stream),
static_cast<const char*>(aDataOwner->mData) +
aStart,
(PRInt32)aLength,
NS_ASSIGNMENT_DEPEND);
NS_ENSURE_SUCCESS(rv, rv);
NS_ADDREF(*_retval = new DataOwnerAdapter(aDataOwner, stream));
return NS_OK;
}
// nsDOMFile implementation
DOMCI_DATA(File, nsDOMFile)
@ -585,10 +643,7 @@ nsDOMMemoryFile::GetInternalStream(nsIInputStream **aStream)
if (mLength > PR_INT32_MAX)
return NS_ERROR_FAILURE;
return NS_NewByteInputStream(aStream,
static_cast<const char*>(mDataOwner->mData) +
mStart,
(PRInt32)mLength);
return DataOwnerAdapter::Create(mDataOwner, mStart, mLength, aStream);
}
NS_IMETHODIMP