зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1382251: Part 5 - Add IpdlTuple for type-safely marshaling tuples r=jld
IpdlTuple is an array of Variants that is accessed by type and that reports an error if there is a type error. This is used for safe and easy communication of IPDL objects, validated at run time since IPC data is untrusted. --HG-- extra : rebase_source : ee113d501d5372cfd01f0be9a58e2db50ab539b3
This commit is contained in:
Родитель
c6a908099a
Коммит
d0d0e5ba2f
|
@ -0,0 +1,184 @@
|
|||
#ifndef dom_plugins_ipc_ipdltuple_h
|
||||
#define dom_plugins_ipc_ipdltuple_h
|
||||
|
||||
#include "mozilla/plugins/FunctionBrokerIPCUtils.h"
|
||||
#include "mozilla/Variant.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace plugins {
|
||||
|
||||
/**
|
||||
* IpdlTuple is used by automatic function brokering to pass parameter
|
||||
* lists for brokered functions. It supports a limited set of types
|
||||
* (see IpdlTuple::IpdlTupleElement).
|
||||
*/
|
||||
class IpdlTuple
|
||||
{
|
||||
public:
|
||||
uint32_t NumElements() const { return mTupleElements.Length(); }
|
||||
|
||||
template<typename EltType>
|
||||
EltType* Element(uint32_t index)
|
||||
{
|
||||
if ((index >= mTupleElements.Length()) ||
|
||||
!mTupleElements[index].GetVariant().is<EltType>()) {
|
||||
return nullptr;
|
||||
}
|
||||
return &mTupleElements[index].GetVariant().as<EltType>();
|
||||
}
|
||||
|
||||
template<typename EltType>
|
||||
const EltType* Element(uint32_t index) const
|
||||
{
|
||||
return const_cast<IpdlTuple*>(this)->Element<EltType>(index);
|
||||
}
|
||||
|
||||
template <typename EltType>
|
||||
void AddElement(const EltType& aElt)
|
||||
{
|
||||
IpdlTupleElement* newEntry = mTupleElements.AppendElement();
|
||||
newEntry->Set(aElt);
|
||||
}
|
||||
|
||||
private:
|
||||
struct InvalidType {};
|
||||
|
||||
// Like Variant but with a default constructor.
|
||||
template <typename ... Types>
|
||||
struct MaybeVariant
|
||||
{
|
||||
public:
|
||||
MaybeVariant() : mValue(InvalidType()) {}
|
||||
MaybeVariant(MaybeVariant&& o) : mValue(Move(o.mValue)) {}
|
||||
|
||||
template <typename Param> void Set(const Param& aParam)
|
||||
{
|
||||
mValue = mozilla::AsVariant(aParam);
|
||||
}
|
||||
|
||||
typedef mozilla::Variant<InvalidType, Types...> MaybeVariantType;
|
||||
MaybeVariantType& GetVariant() { return mValue; }
|
||||
const MaybeVariantType& GetVariant() const { return mValue; }
|
||||
|
||||
private:
|
||||
MaybeVariantType mValue;
|
||||
};
|
||||
|
||||
#if defined(XP_WIN)
|
||||
typedef MaybeVariant<int8_t,uint8_t,int16_t,uint16_t,int32_t,uint32_t,
|
||||
int64_t,uint64_t,nsCString,bool,OpenFileNameIPC,
|
||||
OpenFileNameRetIPC,NativeWindowHandle,
|
||||
IPCSchannelCred,IPCInternetBuffers,StringArray,
|
||||
IPCPrintDlg> IpdlTupleElement;
|
||||
#else
|
||||
typedef MaybeVariant<int8_t,uint8_t,int16_t,uint16_t,int32_t,uint32_t,
|
||||
int64_t,uint64_t,nsCString,bool> IpdlTupleElement;
|
||||
#endif // defined(XP_WIN)
|
||||
|
||||
friend struct IPC::ParamTraits<IpdlTuple>;
|
||||
friend struct IPC::ParamTraits<IpdlTuple::IpdlTupleElement>;
|
||||
friend struct IPC::ParamTraits<IpdlTuple::InvalidType>;
|
||||
|
||||
nsTArray<IpdlTupleElement> mTupleElements;
|
||||
};
|
||||
|
||||
template <> template<>
|
||||
inline void IpdlTuple::IpdlTupleElement::Set<nsDependentCSubstring>(const nsDependentCSubstring& aParam)
|
||||
{
|
||||
mValue = MaybeVariantType(mozilla::VariantType<nsCString>(), aParam);
|
||||
}
|
||||
|
||||
} // namespace plugins
|
||||
} // namespace mozilla
|
||||
|
||||
namespace IPC {
|
||||
|
||||
using namespace mozilla::plugins;
|
||||
|
||||
template <>
|
||||
struct ParamTraits<IpdlTuple>
|
||||
{
|
||||
typedef IpdlTuple paramType;
|
||||
|
||||
static void Write(Message* aMsg, const paramType& aParam)
|
||||
{
|
||||
WriteParam(aMsg, aParam.mTupleElements);
|
||||
}
|
||||
|
||||
static bool Read(const Message* aMsg, PickleIterator* aIter,
|
||||
paramType* aParam)
|
||||
{
|
||||
return ReadParam(aMsg, aIter, &aParam->mTupleElements);
|
||||
}
|
||||
|
||||
static void Log(const paramType& aParam, std::wstring* aLog)
|
||||
{
|
||||
LogParam(aParam.mTupleElements, aLog);
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct ParamTraits<IpdlTuple::IpdlTupleElement>
|
||||
{
|
||||
typedef IpdlTuple::IpdlTupleElement paramType;
|
||||
|
||||
static void Write(Message* aMsg, const paramType& aParam)
|
||||
{
|
||||
MOZ_RELEASE_ASSERT(!aParam.GetVariant().is<IpdlTuple::InvalidType>());
|
||||
WriteParam(aMsg, aParam.GetVariant());
|
||||
}
|
||||
|
||||
static bool Read(const Message* aMsg, PickleIterator* aIter,
|
||||
paramType* aParam)
|
||||
{
|
||||
bool ret = ReadParam(aMsg, aIter, &aParam->GetVariant());
|
||||
MOZ_RELEASE_ASSERT(!aParam->GetVariant().is<IpdlTuple::InvalidType>());
|
||||
return ret;
|
||||
}
|
||||
|
||||
struct LogMatcher
|
||||
{
|
||||
explicit LogMatcher(std::wstring* aLog) : mLog(aLog) {}
|
||||
|
||||
template <typename EntryType>
|
||||
void match(const EntryType& aParam)
|
||||
{
|
||||
LogParam(aParam, mLog);
|
||||
}
|
||||
|
||||
private:
|
||||
std::wstring* mLog;
|
||||
};
|
||||
|
||||
static void Log(const paramType& aParam, std::wstring* aLog)
|
||||
{
|
||||
aParam.GetVariant().match(LogMatcher(aLog));
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct ParamTraits<IpdlTuple::InvalidType>
|
||||
{
|
||||
typedef IpdlTuple::InvalidType paramType;
|
||||
|
||||
static void Write(Message* aMsg, const paramType& aParam)
|
||||
{
|
||||
MOZ_ASSERT_UNREACHABLE("Attempt to serialize an invalid tuple element");
|
||||
}
|
||||
|
||||
static bool Read(const Message* aMsg, PickleIterator* aIter,
|
||||
paramType* aParam)
|
||||
{
|
||||
MOZ_ASSERT_UNREACHABLE("Attempt to deserialize an invalid tuple element");
|
||||
return false;
|
||||
}
|
||||
|
||||
static void Log(const paramType& aParam, std::wstring* aLog)
|
||||
{
|
||||
aLog->append(L"<Invalid Tuple Entry>");
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace IPC
|
||||
|
||||
#endif /* dom_plugins_ipc_ipdltuple_h */
|
Загрузка…
Ссылка в новой задаче