From 411919cca7a3795d08ec3cd24efa0167683a80fb Mon Sep 17 00:00:00 2001 From: wolfbeast Date: Fri, 22 Mar 2019 13:28:32 +0100 Subject: Guard against re-entrancy in nsStringStream. --- xpcom/io/nsStringStream.cpp | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) (limited to 'xpcom') diff --git a/xpcom/io/nsStringStream.cpp b/xpcom/io/nsStringStream.cpp index b65242c14..60da385cc 100644 --- a/xpcom/io/nsStringStream.cpp +++ b/xpcom/io/nsStringStream.cpp @@ -22,6 +22,7 @@ #include "nsIClassInfoImpl.h" #include "mozilla/Attributes.h" #include "mozilla/ipc/InputStreamUtils.h" +#include "mozilla/ReentrantMonitor.h" #include "nsIIPCSerializableInputStream.h" using namespace mozilla::ipc; @@ -50,6 +51,7 @@ public: NS_DECL_NSICLONEABLEINPUTSTREAM nsStringInputStream() + : mMon("nsStringInputStream") { Clear(); } @@ -89,6 +91,8 @@ private: nsDependentCSubstring mData; uint32_t mOffset; + + mozilla::ReentrantMonitor mMon; }; // This class needs to support threadsafe refcounting since people often @@ -126,6 +130,8 @@ nsStringInputStream::GetType(uint16_t* aType) NS_IMETHODIMP nsStringInputStream::GetData(nsACString& data) { + ReentrantMonitorAutoEnter lock(mMon); + // The stream doesn't have any data when it is closed. We could fake it // and return an empty string here, but it seems better to keep this return // value consistent with the behavior of the other 'getter' methods. @@ -140,6 +146,8 @@ nsStringInputStream::GetData(nsACString& data) NS_IMETHODIMP nsStringInputStream::SetData(const nsACString& aData) { + ReentrantMonitorAutoEnter lock(mMon); + mData.Assign(aData); mOffset = 0; return NS_OK; @@ -159,6 +167,8 @@ nsStringInputStream::ToString(char** aResult) NS_IMETHODIMP nsStringInputStream::SetData(const char* aData, int32_t aDataLen) { + ReentrantMonitorAutoEnter lock(mMon); + if (NS_WARN_IF(!aData)) { return NS_ERROR_INVALID_ARG; } @@ -170,6 +180,8 @@ nsStringInputStream::SetData(const char* aData, int32_t aDataLen) NS_IMETHODIMP nsStringInputStream::AdoptData(char* aData, int32_t aDataLen) { + ReentrantMonitorAutoEnter lock(mMon); + if (NS_WARN_IF(!aData)) { return NS_ERROR_INVALID_ARG; } @@ -181,6 +193,8 @@ nsStringInputStream::AdoptData(char* aData, int32_t aDataLen) NS_IMETHODIMP nsStringInputStream::ShareData(const char* aData, int32_t aDataLen) { + ReentrantMonitorAutoEnter lock(mMon); + if (NS_WARN_IF(!aData)) { return NS_ERROR_INVALID_ARG; } @@ -197,6 +211,8 @@ nsStringInputStream::ShareData(const char* aData, int32_t aDataLen) NS_IMETHODIMP_(size_t) nsStringInputStream::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) { + ReentrantMonitorAutoEnter lock(mMon); + size_t n = aMallocSizeOf(this); n += mData.SizeOfExcludingThisIfUnshared(aMallocSizeOf); return n; @@ -209,6 +225,8 @@ nsStringInputStream::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) NS_IMETHODIMP nsStringInputStream::Close() { + ReentrantMonitorAutoEnter lock(mMon); + Clear(); return NS_OK; } @@ -216,6 +234,8 @@ nsStringInputStream::Close() NS_IMETHODIMP nsStringInputStream::Available(uint64_t* aLength) { + ReentrantMonitorAutoEnter lock(mMon); + NS_ASSERTION(aLength, "null ptr"); if (Closed()) { @@ -237,6 +257,8 @@ NS_IMETHODIMP nsStringInputStream::ReadSegments(nsWriteSegmentFun aWriter, void* aClosure, uint32_t aCount, uint32_t* aResult) { + ReentrantMonitorAutoEnter lock(mMon); + NS_ASSERTION(aResult, "null ptr"); NS_ASSERTION(Length() >= mOffset, "bad stream state"); @@ -280,6 +302,8 @@ nsStringInputStream::IsNonBlocking(bool* aNonBlocking) NS_IMETHODIMP nsStringInputStream::Seek(int32_t aWhence, int64_t aOffset) { + ReentrantMonitorAutoEnter lock(mMon); + if (Closed()) { return NS_BASE_STREAM_CLOSED; } @@ -312,6 +336,8 @@ nsStringInputStream::Seek(int32_t aWhence, int64_t aOffset) NS_IMETHODIMP nsStringInputStream::Tell(int64_t* aOutWhere) { + ReentrantMonitorAutoEnter lock(mMon); + if (Closed()) { return NS_BASE_STREAM_CLOSED; } @@ -323,6 +349,8 @@ nsStringInputStream::Tell(int64_t* aOutWhere) NS_IMETHODIMP nsStringInputStream::SetEOF() { + ReentrantMonitorAutoEnter lock(mMon); + if (Closed()) { return NS_BASE_STREAM_CLOSED; } @@ -339,6 +367,8 @@ void nsStringInputStream::Serialize(InputStreamParams& aParams, FileDescriptorArray& /* aFDs */) { + ReentrantMonitorAutoEnter lock(mMon); + StringInputStreamParams params; params.data() = PromiseFlatCString(mData); aParams = params; @@ -367,6 +397,8 @@ nsStringInputStream::Deserialize(const InputStreamParams& aParams, Maybe nsStringInputStream::ExpectedSerializedLength() { + ReentrantMonitorAutoEnter lock(mMon); + return Some(static_cast(Length())); } @@ -384,6 +416,8 @@ nsStringInputStream::GetCloneable(bool* aCloneableOut) NS_IMETHODIMP nsStringInputStream::Clone(nsIInputStream** aCloneOut) { + ReentrantMonitorAutoEnter lock(mMon); + RefPtr ref = new nsStringInputStream(*this); ref.forget(aCloneOut); return NS_OK; -- cgit v1.2.3