summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorwolfbeast <mcwerewolf@wolfbeast.com>2019-03-22 13:28:32 +0100
committerwolfbeast <mcwerewolf@wolfbeast.com>2019-03-22 13:28:32 +0100
commit411919cca7a3795d08ec3cd24efa0167683a80fb (patch)
tree777f339c378004fed20f8a269be9d28e35d5e15b
parentc53602c802cfaeaede20cb0bb2180194389eeb05 (diff)
downloaduxp-411919cca7a3795d08ec3cd24efa0167683a80fb.tar.gz
Guard against re-entrancy in nsStringStream.
-rw-r--r--xpcom/io/nsStringStream.cpp34
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;