зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1768077 - Fix math issue in DataPipeBase::ProcessSegments, r=asuth
This could lead to hangs or buffer overflow crashes when doing a partial read which is spread across both ends of the ring buffer. Differential Revision: https://phabricator.services.mozilla.com/D145670
This commit is contained in:
Родитель
1f32baf6d5
Коммит
f6d92d7332
|
@ -328,7 +328,7 @@ nsresult DataPipeBase::ProcessSegmentsInternal(
|
|||
// buffer which will be used .
|
||||
char* start = static_cast<char*>(link->mShmem->memory()) + link->mOffset;
|
||||
char* iter = start;
|
||||
char* end = start + std::min({aCount, link->mAvailable,
|
||||
char* end = start + std::min({aCount - *aProcessedCount, link->mAvailable,
|
||||
link->mCapacity - link->mOffset});
|
||||
|
||||
// Record the consumed region from our segment when exiting this scope,
|
||||
|
@ -373,6 +373,8 @@ nsresult DataPipeBase::ProcessSegmentsInternal(
|
|||
}
|
||||
}
|
||||
}
|
||||
MOZ_DIAGNOSTIC_ASSERT(*aProcessedCount == aCount,
|
||||
"Must have processed exactly aCount");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include "mozilla/ipc/DataPipe.h"
|
||||
#include "nsIAsyncInputStream.h"
|
||||
#include "nsIAsyncOutputStream.h"
|
||||
#include "nsNetUtil.h"
|
||||
#include "nsStreamUtils.h"
|
||||
|
||||
namespace mozilla::ipc {
|
||||
|
@ -136,6 +137,56 @@ TEST(DataPipe, SegmentedReadWrite)
|
|||
ConsumeAndValidateStream(reader, inputData2);
|
||||
}
|
||||
|
||||
TEST(DataPipe, SegmentedPartialRead)
|
||||
{
|
||||
RefPtr<DataPipeReceiver> reader;
|
||||
RefPtr<DataPipeSender> writer;
|
||||
|
||||
nsresult rv =
|
||||
NewDataPipe(1024, getter_AddRefs(writer), getter_AddRefs(reader));
|
||||
ASSERT_TRUE(NS_SUCCEEDED(rv));
|
||||
|
||||
nsCString inputData1;
|
||||
CreateData(512, inputData1);
|
||||
|
||||
uint32_t numWritten = 0;
|
||||
rv = writer->Write(inputData1.BeginReading(), inputData1.Length(),
|
||||
&numWritten);
|
||||
ASSERT_TRUE(NS_SUCCEEDED(rv));
|
||||
EXPECT_EQ(numWritten, 512u);
|
||||
|
||||
uint64_t available = 0;
|
||||
rv = reader->Available(&available);
|
||||
EXPECT_EQ(available, 512u);
|
||||
ConsumeAndValidateStream(reader, inputData1);
|
||||
|
||||
nsCString inputData2;
|
||||
CreateData(1024, inputData2);
|
||||
|
||||
rv = writer->Write(inputData2.BeginReading(), inputData2.Length(),
|
||||
&numWritten);
|
||||
ASSERT_TRUE(NS_SUCCEEDED(rv));
|
||||
EXPECT_EQ(numWritten, 1024u);
|
||||
|
||||
rv = reader->Available(&available);
|
||||
EXPECT_EQ(available, 1024u);
|
||||
|
||||
nsAutoCString outputData;
|
||||
rv = NS_ReadInputStreamToString(reader, outputData, 768);
|
||||
ASSERT_TRUE(NS_SUCCEEDED(rv));
|
||||
ASSERT_EQ(768u, outputData.Length());
|
||||
ASSERT_TRUE(Substring(inputData2, 0, 768).Equals(outputData));
|
||||
|
||||
rv = reader->Available(&available);
|
||||
EXPECT_EQ(available, 256u);
|
||||
|
||||
nsAutoCString outputData2;
|
||||
rv = NS_ReadInputStreamToString(reader, outputData2, 256);
|
||||
ASSERT_TRUE(NS_SUCCEEDED(rv));
|
||||
ASSERT_EQ(256u, outputData2.Length());
|
||||
ASSERT_TRUE(Substring(inputData2, 768).Equals(outputData2));
|
||||
}
|
||||
|
||||
TEST(DataPipe, Write_AsyncWait)
|
||||
{
|
||||
RefPtr<DataPipeReceiver> reader;
|
||||
|
|
Загрузка…
Ссылка в новой задаче