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:
Daniel Zielas 2018-01-21 21:23:21 +01:00
Родитель 6ab3b67d62
Коммит e80f2e7469
3 изменённых файлов: 56 добавлений и 6 удалений

Просмотреть файл

@ -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 */