зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1427229 - Perform validation when sending an EnumSet over IPC. r=botond,froydnj
MozReview-Commit-ID: Cmugi1ldc1Z --HG-- extra : amend_source : 88b792772ce7948172a68fda03d6d61de66347de
This commit is contained in:
Родитель
6ab3b67d62
Коммит
e80f2e7469
|
@ -15,6 +15,7 @@
|
|||
#include "mozilla/DebugOnly.h"
|
||||
#include "mozilla/dom/ipc/StructuredCloneData.h"
|
||||
#include "mozilla/EnumSet.h"
|
||||
#include "mozilla/EnumTypeTraits.h"
|
||||
#include "mozilla/Maybe.h"
|
||||
#include "mozilla/net/WebSocketFrame.h"
|
||||
#include "mozilla/TimeStamp.h"
|
||||
|
@ -24,7 +25,9 @@
|
|||
#include "mozilla/TypeTraits.h"
|
||||
#include "mozilla/IntegerTypeTraits.h"
|
||||
|
||||
#include <limits>
|
||||
#include <stdint.h>
|
||||
#include <type_traits>
|
||||
|
||||
#include "nsExceptionHandler.h"
|
||||
#include "nsID.h"
|
||||
|
@ -934,21 +937,43 @@ template<typename T>
|
|||
struct ParamTraits<mozilla::EnumSet<T>>
|
||||
{
|
||||
typedef mozilla::EnumSet<T> paramType;
|
||||
typedef typename mozilla::EnumSet<T>::serializedType serializedType;
|
||||
|
||||
static void Write(Message* msg, const paramType& param)
|
||||
{
|
||||
MOZ_RELEASE_ASSERT(IsLegalValue(param.serialize()));
|
||||
WriteParam(msg, param.serialize());
|
||||
}
|
||||
|
||||
static bool Read(const Message* msg, PickleIterator* iter, paramType* result)
|
||||
{
|
||||
decltype(result->serialize()) tmp;
|
||||
serializedType tmp;
|
||||
|
||||
if (ReadParam(msg, iter, &tmp)) {
|
||||
result->deserialize(tmp);
|
||||
return true;
|
||||
if (IsLegalValue(tmp)) {
|
||||
result->deserialize(tmp);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static constexpr serializedType AllEnumBits()
|
||||
{
|
||||
return ~serializedType(0) >>
|
||||
(std::numeric_limits<serializedType>::digits - (mozilla::MaxEnumValue<T>::value + 1));
|
||||
}
|
||||
|
||||
static constexpr bool IsLegalValue(const serializedType value)
|
||||
{
|
||||
static_assert(mozilla::MaxEnumValue<T>::value < std::numeric_limits<serializedType>::digits,
|
||||
"Enum max value is not in the range!");
|
||||
static_assert(std::is_unsigned<decltype(mozilla::MaxEnumValue<T>::value)>::value,
|
||||
"Type of MaxEnumValue<T>::value specialization should be unsigned!");
|
||||
|
||||
return (value & AllEnumBits()) == value;
|
||||
}
|
||||
};
|
||||
|
||||
template<class... Ts>
|
||||
|
|
|
@ -27,6 +27,8 @@ template<typename T>
|
|||
class EnumSet
|
||||
{
|
||||
public:
|
||||
typedef uint32_t serializedType;
|
||||
|
||||
EnumSet()
|
||||
: mBitField(0)
|
||||
{
|
||||
|
@ -209,12 +211,12 @@ public:
|
|||
return mBitField == 0;
|
||||
}
|
||||
|
||||
uint32_t serialize() const
|
||||
serializedType serialize() const
|
||||
{
|
||||
return mBitField;
|
||||
}
|
||||
|
||||
void deserialize(uint32_t aValue)
|
||||
void deserialize(serializedType aValue)
|
||||
{
|
||||
incVersion();
|
||||
mBitField = aValue;
|
||||
|
@ -320,7 +322,7 @@ private:
|
|||
}
|
||||
|
||||
static const size_t kMaxBits = 32;
|
||||
uint32_t mBitField;
|
||||
serializedType mBitField;
|
||||
|
||||
#ifdef DEBUG
|
||||
uint64_t mVersion = 0;
|
||||
|
|
|
@ -65,6 +65,29 @@ struct EnumTypeFitsWithin
|
|||
static_assert(std::is_integral<Storage>::value, "must provide an integral type");
|
||||
};
|
||||
|
||||
/*
|
||||
* Provides information about highest enum member value.
|
||||
* Each specialization of struct MaxEnumValue should define
|
||||
* "static constexpr unsigned int value".
|
||||
*
|
||||
* example:
|
||||
*
|
||||
* enum ExampleEnum
|
||||
* {
|
||||
* CAT = 0,
|
||||
* DOG,
|
||||
* HAMSTER
|
||||
* };
|
||||
*
|
||||
* template <>
|
||||
* struct MaxEnumValue<ExampleEnum>
|
||||
* {
|
||||
* static constexpr unsigned int value = static_cast<unsigned int>(HAMSTER);
|
||||
* };
|
||||
*/
|
||||
template <typename T>
|
||||
struct MaxEnumValue; // no need to define the primary template
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
#endif /* mozilla_EnumTypeTraits_h */
|
||||
|
|
Загрузка…
Ссылка в новой задаче