Issue #1990 - Part 4 - Add a number of Mozilla patches from between Part 1 and 2. 1334081 - prevent null pointer dereference in StreamReaderFunc. 1330631 - Convert the EventSourceImpl::Message to be UniquePtr. 1337619 - Reset mGoingToDispatchAllMessages flag before early return.

This commit is contained in:
Brian Smith 2022-08-22 13:23:34 -05:00 • committed by roytam1
commit 9f945d160d

View file

@ -129,7 +129,7 @@ public:
uint32_t* aWriteCount); uint32_t* aWriteCount);
void ParseSegment(const char* aBuffer, uint32_t aLength); void ParseSegment(const char* aBuffer, uint32_t aLength);
nsresult SetFieldAndClear(); nsresult SetFieldAndClear();
nsresult ClearFields(); void ClearFields();
nsresult ResetEvent(); nsresult ResetEvent();
nsresult DispatchCurrentMessageEvent(); nsresult DispatchCurrentMessageEvent();
nsresult ParseCharacter(char16_t aChr); nsresult ParseCharacter(char16_t aChr);
@ -282,7 +282,7 @@ public:
// Message related data members. May be set / initialized when initializing // Message related data members. May be set / initialized when initializing
// EventSourceImpl on target thread but should only be used on target thread. // EventSourceImpl on target thread but should only be used on target thread.
nsString mLastEventID; nsString mLastEventID;
Message mCurrentMessage; UniquePtr<Message> mCurrentMessage;
nsDeque mMessagesToDispatch; nsDeque mMessagesToDispatch;
ParserStatus mStatus; ParserStatus mStatus;
nsCOMPtr<nsIUnicodeDecoder> mUnicodeDecoder; nsCOMPtr<nsIUnicodeDecoder> mUnicodeDecoder;
@ -710,12 +710,11 @@ EventSourceImpl::StreamReaderFunc(nsIInputStream* aInputStream,
uint32_t* aWriteCount) uint32_t* aWriteCount)
{ {
EventSourceImpl* thisObject = static_cast<EventSourceImpl*>(aClosure); EventSourceImpl* thisObject = static_cast<EventSourceImpl*>(aClosure);
thisObject->AssertIsOnTargetThread();
if (!thisObject || !aWriteCount) { if (!thisObject || !aWriteCount) {
NS_WARNING("EventSource cannot read from stream: no aClosure or aWriteCount"); NS_WARNING("EventSource cannot read from stream: no aClosure or aWriteCount");
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
} }
MOZ_ASSERT(!thisObject->IsShutDown()); thisObject->AssertIsOnTargetThread();
thisObject->ParseSegment((const char*)aFromRawSegment, aCount); thisObject->ParseSegment((const char*)aFromRawSegment, aCount);
*aWriteCount = aCount; *aWriteCount = aCount;
return NS_OK; return NS_OK;
@ -1439,13 +1438,11 @@ nsresult
EventSourceImpl::DispatchCurrentMessageEvent() EventSourceImpl::DispatchCurrentMessageEvent()
{ {
AssertIsOnTargetThread(); AssertIsOnTargetThread();
MOZ_ASSERT(!IsShutDown()); UniquePtr<Message> message(Move(mCurrentMessage));
nsAutoPtr<Message> message(new Message());
*message = mCurrentMessage;
ClearFields(); ClearFields();
if (message->mData.IsEmpty()) { if (!message || message->mData.IsEmpty()) {
return NS_OK; return NS_OK;
} }
@ -1463,7 +1460,7 @@ EventSourceImpl::DispatchCurrentMessageEvent()
} }
size_t sizeBefore = mMessagesToDispatch.GetSize(); size_t sizeBefore = mMessagesToDispatch.GetSize();
mMessagesToDispatch.Push(message.forget()); mMessagesToDispatch.Push(message.release());
NS_ENSURE_TRUE(mMessagesToDispatch.GetSize() == sizeBefore + 1, NS_ENSURE_TRUE(mMessagesToDispatch.GetSize() == sizeBefore + 1,
NS_ERROR_OUT_OF_MEMORY); NS_ERROR_OUT_OF_MEMORY);
@ -1485,12 +1482,12 @@ void
EventSourceImpl::DispatchAllMessageEvents() EventSourceImpl::DispatchAllMessageEvents()
{ {
AssertIsOnTargetThread(); AssertIsOnTargetThread();
mGoingToDispatchAllMessages = false;
if (IsClosed() || IsFrozen()) { if (IsClosed() || IsFrozen()) {
return; return;
} }
mGoingToDispatchAllMessages = false;
nsresult rv = mEventSource->CheckInnerWindowCorrectness(); nsresult rv = mEventSource->CheckInnerWindowCorrectness();
if (NS_FAILED(rv)) { if (NS_FAILED(rv)) {
return; return;
@ -1510,9 +1507,7 @@ EventSourceImpl::DispatchAllMessageEvents()
JSContext* cx = jsapi.cx(); JSContext* cx = jsapi.cx();
while (mMessagesToDispatch.GetSize() > 0) { while (mMessagesToDispatch.GetSize() > 0) {
nsAutoPtr<Message> UniquePtr<Message> message(static_cast<Message*>(mMessagesToDispatch.PopFront()));
message(static_cast<Message*>(mMessagesToDispatch.PopFront()));
// Now we can turn our string into a jsval // Now we can turn our string into a jsval
JS::Rooted<JS::Value> jsData(cx); JS::Rooted<JS::Value> jsData(cx);
{ {
@ -1550,19 +1545,13 @@ EventSourceImpl::DispatchAllMessageEvents()
} }
} }
nsresult void
EventSourceImpl::ClearFields() EventSourceImpl::ClearFields()
{ {
AssertIsOnTargetThread(); AssertIsOnTargetThread();
// mLastEventID and mReconnectionTime must be cached mCurrentMessage = nullptr;
mCurrentMessage.mEventName.Truncate();
mCurrentMessage.mLastEventID.Truncate();
mCurrentMessage.mData.Truncate();
mLastFieldName.Truncate(); mLastFieldName.Truncate();
mLastFieldValue.Truncate(); mLastFieldValue.Truncate();
return NS_OK;
} }
nsresult nsresult
@ -1574,7 +1563,9 @@ EventSourceImpl::SetFieldAndClear()
mLastFieldValue.Truncate(); mLastFieldValue.Truncate();
return NS_OK; return NS_OK;
} }
if (!mCurrentMessage) {
mCurrentMessage = MakeUnique<Message>();
}
char16_t first_char; char16_t first_char;
first_char = mLastFieldName.CharAt(0); first_char = mLastFieldName.CharAt(0);
@ -1585,20 +1576,20 @@ EventSourceImpl::SetFieldAndClear()
// If the field name is "data" append the field value to the data // If the field name is "data" append the field value to the data
// buffer, then append a single U+000A LINE FEED (LF) character // buffer, then append a single U+000A LINE FEED (LF) character
// to the data buffer. // to the data buffer.
mCurrentMessage.mData.Append(mLastFieldValue); mCurrentMessage->mData.Append(mLastFieldValue);
mCurrentMessage.mData.Append(LF_CHAR); mCurrentMessage->mData.Append(LF_CHAR);
} }
break; break;
case char16_t('e'): case char16_t('e'):
if (mLastFieldName.EqualsLiteral("event")) { if (mLastFieldName.EqualsLiteral("event")) {
mCurrentMessage.mEventName.Assign(mLastFieldValue); mCurrentMessage->mEventName.Assign(mLastFieldValue);
} }
break; break;
case char16_t('i'): case char16_t('i'):
if (mLastFieldName.EqualsLiteral("id")) { if (mLastFieldName.EqualsLiteral("id")) {
mCurrentMessage.mLastEventID.Assign(mLastFieldValue); mCurrentMessage->mLastEventID.Assign(mLastFieldValue);
} }
break; break;