зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1231213 - Correctly choose nsBufferedStream's underlying nsIInputStream after initialization. r=asuth
Differential Revision: https://phabricator.services.mozilla.com/D26159 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
931915402d
Коммит
166ecc9374
|
@ -9,6 +9,7 @@
|
|||
#include "nsStreamUtils.h"
|
||||
#include "nsNetCID.h"
|
||||
#include "nsIClassInfoImpl.h"
|
||||
#include "mozilla/DebugOnly.h"
|
||||
#include "mozilla/ipc/InputStreamUtils.h"
|
||||
#include <algorithm>
|
||||
|
||||
|
@ -38,6 +39,7 @@ static struct {
|
|||
#endif
|
||||
|
||||
using namespace mozilla::ipc;
|
||||
using mozilla::DebugOnly;
|
||||
using mozilla::Maybe;
|
||||
using mozilla::MutexAutoLock;
|
||||
using mozilla::Nothing;
|
||||
|
@ -276,7 +278,16 @@ NS_IMPL_CLASSINFO(nsBufferedInputStream, nullptr, nsIClassInfo::THREADSAFE,
|
|||
NS_BUFFEREDINPUTSTREAM_CID)
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN(nsBufferedInputStream)
|
||||
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsIInputStream, nsIBufferedInputStream)
|
||||
// Unfortunately there isn't a macro that combines ambiguous and conditional,
|
||||
// and as far as I can tell, no other class would need such a macro.
|
||||
if (mIsAsyncInputStream && aIID.Equals(NS_GET_IID(nsIInputStream))) {
|
||||
foundInterface =
|
||||
static_cast<nsIInputStream*>(static_cast<nsIAsyncInputStream*>(this));
|
||||
} else if (!mIsAsyncInputStream && aIID.Equals(NS_GET_IID(nsIInputStream))) {
|
||||
foundInterface = static_cast<nsIInputStream*>(
|
||||
static_cast<nsIBufferedInputStream*>(this));
|
||||
} else
|
||||
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIBufferedInputStream)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIBufferedInputStream)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIStreamBufferAccess)
|
||||
NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIIPCSerializableInputStream,
|
||||
|
@ -348,6 +359,19 @@ nsBufferedInputStream::Init(nsIInputStream* stream, uint32_t bufferSize) {
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
already_AddRefed<nsIInputStream> nsBufferedInputStream::GetInputStream() {
|
||||
// A non-null mStream implies Init() has been called.
|
||||
MOZ_ASSERT(mStream);
|
||||
|
||||
nsIInputStream* out = nullptr;
|
||||
DebugOnly<nsresult> rv = QueryInterface(NS_GET_IID(nsIInputStream),
|
||||
reinterpret_cast<void**>(&out));
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||
MOZ_ASSERT(out);
|
||||
|
||||
return already_AddRefed<nsIInputStream>(out);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsBufferedInputStream::Close() {
|
||||
nsresult rv1 = NS_OK, rv2;
|
||||
|
@ -764,7 +788,9 @@ nsBufferedInputStream::Clone(nsIInputStream** aResult) {
|
|||
rv = bis->Init(clonedStream, mBufferSize);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
bis.forget(aResult);
|
||||
*aResult =
|
||||
static_cast<nsBufferedInputStream*>(bis.get())->GetInputStream().take();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -92,6 +92,22 @@ class nsBufferedInputStream final : public nsBufferedStream,
|
|||
|
||||
nsIInputStream* Source() { return (nsIInputStream*)mStream.get(); }
|
||||
|
||||
/**
|
||||
* If there's a reference/pointer to an nsBufferedInputStream BEFORE calling
|
||||
* Init() AND the intent is to ultimately convert/assign that
|
||||
* reference/pointer to an nsIInputStream, DO NOT use that initial
|
||||
* reference/pointer. Instead, use the value of QueryInterface-ing to an
|
||||
* nsIInputStream (and, again, the QueryInterface must be performed after
|
||||
* Init()). This is because nsBufferedInputStream has multiple underlying
|
||||
* nsIInputStreams (one from nsIBufferedInputStream and one from
|
||||
* nsIAsyncInputStream), and the correct base nsIInputStream to use will be
|
||||
* unknown until the final value of mIsAsyncInputStream is set in Init().
|
||||
*
|
||||
* This method, however, does just that but also hides the QI details and
|
||||
* will assert if called before Init().
|
||||
*/
|
||||
already_AddRefed<nsIInputStream> GetInputStream();
|
||||
|
||||
protected:
|
||||
virtual ~nsBufferedInputStream() = default;
|
||||
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#include "nsIAuthPrompt2.h"
|
||||
#include "nsIAuthPromptAdapterFactory.h"
|
||||
#include "nsIBufferedStreams.h"
|
||||
#include "nsBufferedStreams.h"
|
||||
#include "nsIChannelEventSink.h"
|
||||
#include "nsIContentSniffer.h"
|
||||
#include "mozilla/dom/Document.h"
|
||||
|
@ -1269,7 +1270,9 @@ MOZ_MUST_USE nsresult NS_NewBufferedInputStream(
|
|||
if (NS_SUCCEEDED(rv)) {
|
||||
rv = in->Init(inputStream, aBufferSize);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
in.forget(aResult);
|
||||
*aResult = static_cast<nsBufferedInputStream*>(in.get())
|
||||
->GetInputStream()
|
||||
.take();
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
|
|
Загрузка…
Ссылка в новой задаче