diff options
author | wolfbeast <mcwerewolf@wolfbeast.com> | 2019-03-22 13:28:32 +0100 |
---|---|---|
committer | wolfbeast <mcwerewolf@wolfbeast.com> | 2019-03-22 13:28:32 +0100 |
commit | 411919cca7a3795d08ec3cd24efa0167683a80fb (patch) | |
tree | 777f339c378004fed20f8a269be9d28e35d5e15b | |
parent | c53602c802cfaeaede20cb0bb2180194389eeb05 (diff) | |
download | uxp-411919cca7a3795d08ec3cd24efa0167683a80fb.tar.gz |
Guard against re-entrancy in nsStringStream.
-rw-r--r-- | xpcom/io/nsStringStream.cpp | 34 |
1 files changed, 34 insertions, 0 deletions
diff --git a/xpcom/io/nsStringStream.cpp b/xpcom/io/nsStringStream.cpp index b65242c143..60da385cc9 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<uint64_t> nsStringInputStream::ExpectedSerializedLength() { + ReentrantMonitorAutoEnter lock(mMon); + return Some(static_cast<uint64_t>(Length())); } @@ -384,6 +416,8 @@ nsStringInputStream::GetCloneable(bool* aCloneableOut) NS_IMETHODIMP nsStringInputStream::Clone(nsIInputStream** aCloneOut) { + ReentrantMonitorAutoEnter lock(mMon); + RefPtr<nsIInputStream> ref = new nsStringInputStream(*this); ref.forget(aCloneOut); return NS_OK; |