diff --git a/ebml/EbmlBinary.h b/ebml/EbmlBinary.h index 3bf5dd6c..e57b0958 100644 --- a/ebml/EbmlBinary.h +++ b/ebml/EbmlBinary.h @@ -30,7 +30,7 @@ class EBML_DLL_API EbmlBinary : public EbmlElement { EbmlBinary& operator=(const EbmlBinary & ElementToClone); ~EbmlBinary() override; - bool SizeIsValid(std::uint64_t size) const override {return size < 0x7FFFFFFF;} // we don't mind about what's inside + static inline bool SizeIsValid(std::uint64_t size) {return size < 0x7FFFFFFF;} // we don't mind about what's inside filepos_t RenderData(IOCallback & output, bool bForceRender, const ShouldWrite & writeFilter = WriteSkipDefault) override; filepos_t ReadData(IOCallback & input, ScopeMode ReadFully = SCOPE_ALL_DATA) override; diff --git a/ebml/EbmlCrc32.h b/ebml/EbmlCrc32.h index a8ed9326..4b456e82 100644 --- a/ebml/EbmlCrc32.h +++ b/ebml/EbmlCrc32.h @@ -13,7 +13,7 @@ namespace libebml { -DECLARE_EBML_BINARY_LENGTH(EbmlCrc32, 4) +DECLARE_EBML_BINARY(EbmlCrc32) public: filepos_t RenderData(IOCallback & output, bool bForceRender, const ShouldWrite & writeFilter = WriteSkipDefault) override; filepos_t ReadData(IOCallback & input, ScopeMode ReadFully = SCOPE_ALL_DATA) override; @@ -55,6 +55,11 @@ DECLARE_EBML_BINARY_LENGTH(EbmlCrc32, 4) std::uint32_t m_crc; std::uint32_t m_crc_final{0}; + static inline bool ValidateSize(std::uint64_t Size) + { + return Size == 4; + } + EBML_CONCRETE_CLASS(EbmlCrc32) }; diff --git a/ebml/EbmlDate.h b/ebml/EbmlDate.h index 6c3b5775..ab1c1867 100644 --- a/ebml/EbmlDate.h +++ b/ebml/EbmlDate.h @@ -41,7 +41,7 @@ class EBML_DLL_API EbmlDate : public EbmlElementDefaultSameStorage std::int64_t GetEpochDate() const {return EbmlToEpoch(EbmlElementDefaultSameStorage::GetValue());} std::int64_t GetValue() const {return GetEpochDate();} - bool SizeIsValid(std::uint64_t size) const override {return size == 8 || size == 0;} + static inline bool SizeIsValid(std::uint64_t size) {return size == 8 || size == 0;} /*! \note no Default date handled diff --git a/ebml/EbmlElement.h b/ebml/EbmlElement.h index a5c20120..c30593fe 100644 --- a/ebml/EbmlElement.h +++ b/ebml/EbmlElement.h @@ -77,71 +77,71 @@ class EbmlElement; static constexpr const libebml::EbmlId Id_##x {id}; static_assert(libebml::EbmlId::IsValid(Id_##x .GetValue()), "invalid id for " name ); \ static constexpr const libebml::EbmlSemanticContext Context_##x = libebml::EbmlSemanticContext( &parent::SemanticContext, global, &EBML_INFO(x)); -#define DEFINE_xxx_CLASS_BASE(x,BaseClass,id,parent,name,versions,global) \ +#define DEFINE_xxx_CLASS_BASE(x,BaseClass,id,parent,name,valid,versions,global) \ DEFINE_xxx_CLASS_CONS(x,id,parent,name,global) \ - constexpr const libebml::EbmlCallbacks x::ClassInfos(x::Create, Id_##x, false, false, name, Context_##x, versions); \ + constexpr const libebml::EbmlCallbacks x::ClassInfos(x::Create, Id_##x, false, false, name, Context_##x, versions, valid); \ x::x() : BaseClass(x::ClassInfos) {} -#define DEFINE_xxx_CLASS_BASE_DEFAULT(x,BaseClass,id,parent,name,global,StorageType,defval,versions) \ +#define DEFINE_xxx_CLASS_BASE_DEFAULT(x,BaseClass,id,parent,name,global,StorageType,defval,valid,versions) \ DEFINE_xxx_CLASS_CONS(x,id,parent,name,global) \ - constexpr const libebml::EbmlCallbacksWithDefault x::ClassInfos(x::Create, Id_##x, defval, name, Context_##x, versions); \ + constexpr const libebml::EbmlCallbacksWithDefault x::ClassInfos(x::Create, Id_##x, defval, name, Context_##x, versions, valid); \ x::x() : BaseClass(x::ClassInfos) {} -#define DEFINE_xxx_CLASS_BASE_NODEFAULT(x,BaseClass,id,parent,name,global,StorageType,versions) \ +#define DEFINE_xxx_CLASS_BASE_NODEFAULT(x,BaseClass,id,parent,name,global,StorageType,valid,versions) \ DEFINE_xxx_CLASS_CONS(x,id,parent,name,global) \ - constexpr const libebml::EbmlCallbacksDefault x::ClassInfos(x::Create, Id_##x, name, Context_##x, versions); \ + constexpr const libebml::EbmlCallbacksDefault x::ClassInfos(x::Create, Id_##x, name, Context_##x, versions, valid); \ x::x() : BaseClass(x::ClassInfos) {} #define DEFINE_xxx_UINTEGER(x,id,parent,name,versions,global) \ - DEFINE_xxx_CLASS_BASE_NODEFAULT(x,EbmlUInteger,id,parent,name,global,std::uint64_t,versions) + DEFINE_xxx_CLASS_BASE_NODEFAULT(x,EbmlUInteger,id,parent,name,global,std::uint64_t, libebml::EbmlUInteger::SizeIsValid, versions) #define DEFINE_xxx_SINTEGER(x,id,parent,name,versions,global) \ - DEFINE_xxx_CLASS_BASE_NODEFAULT(x,EbmlSInteger,id,parent,name,global,std::int64_t,versions) + DEFINE_xxx_CLASS_BASE_NODEFAULT(x,EbmlSInteger,id,parent,name,global,std::int64_t, libebml::EbmlSInteger::SizeIsValid, versions) #define DEFINE_xxx_STRING(x,id,parent,name,versions,global) \ - DEFINE_xxx_CLASS_BASE_NODEFAULT(x,EbmlString,id,parent,name,global,const char *,versions) + DEFINE_xxx_CLASS_BASE_NODEFAULT(x,EbmlString,id,parent,name,global,const char *, libebml::EbmlString::SizeIsValid, versions) #define DEFINE_xxx_UNISTRING(x,id,parent,name,versions,global) \ - DEFINE_xxx_CLASS_BASE_NODEFAULT(x,EbmlUnicodeString,id,parent,name,global, const wchar_t *,versions) + DEFINE_xxx_CLASS_BASE_NODEFAULT(x,EbmlUnicodeString,id,parent,name,global, const wchar_t *, libebml::EbmlUnicodeString::SizeIsValid, versions) #define DEFINE_xxx_FLOAT(x,id,parent,name,versions,global) \ - DEFINE_xxx_CLASS_BASE_NODEFAULT(x,EbmlFloat,id,parent,name,global,double,versions) + DEFINE_xxx_CLASS_BASE_NODEFAULT(x,EbmlFloat,id,parent,name,global,double, libebml::EbmlFloat::SizeIsValid, versions) #define DEFINE_xxx_DATE(x,id,parent,name,versions,global) \ - DEFINE_xxx_CLASS_BASE_NODEFAULT(x,EbmlDate,id,parent,name,global,std::int64_t,versions) + DEFINE_xxx_CLASS_BASE_NODEFAULT(x,EbmlDate,id,parent,name,global,std::int64_t, libebml::EbmlDate::SizeIsValid, versions) -#define DEFINE_xxx_BINARY(x,id,parent,name,versions,global) \ - DEFINE_xxx_CLASS_BASE(x,EbmlBinary,id,parent,name,versions,global) +#define DEFINE_xxx_BINARY(x,id,parent,name,valid,versions,global) \ + DEFINE_xxx_CLASS_BASE(x,EbmlBinary,id,parent,name,valid,versions,global) #define DEFINE_xxx_UINTEGER_DEF(x,id,parent,name,versions,global,defval) \ - DEFINE_xxx_CLASS_BASE_DEFAULT(x,EbmlUInteger,id,parent,name,global,std::uint64_t,defval, versions) + DEFINE_xxx_CLASS_BASE_DEFAULT(x,EbmlUInteger,id,parent,name,global,std::uint64_t,defval, libebml::EbmlUInteger::SizeIsValid, versions) #define DEFINE_xxx_SINTEGER_DEF(x,id,parent,name,versions,global,defval) \ - DEFINE_xxx_CLASS_BASE_DEFAULT(x,EbmlSInteger,id,parent,name,global,std::int64_t,defval, versions) + DEFINE_xxx_CLASS_BASE_DEFAULT(x,EbmlSInteger,id,parent,name,global,std::int64_t,defval, libebml::EbmlSInteger::SizeIsValid, versions) #define DEFINE_xxx_STRING_DEF(x,id,parent,name,versions,global,defval) \ - DEFINE_xxx_CLASS_BASE_DEFAULT(x,EbmlString,id,parent,name,global,const char *,defval, versions) + DEFINE_xxx_CLASS_BASE_DEFAULT(x,EbmlString,id,parent,name,global,const char *,defval, libebml::EbmlString::SizeIsValid, versions) #define DEFINE_xxx_UNISTRING_DEF(x,id,parent,name,versions,global,defval) \ - DEFINE_xxx_CLASS_BASE_DEFAULT(x,EbmlUnicodeString,id,parent,name,global,const wchar_t*,defval, versions) + DEFINE_xxx_CLASS_BASE_DEFAULT(x,EbmlUnicodeString,id,parent,name,global,const wchar_t*,defval, libebml::EbmlUnicodeString::SizeIsValid, versions) #define DEFINE_xxx_FLOAT_DEF(x,id,parent,name,versions,global,defval) \ - DEFINE_xxx_CLASS_BASE_DEFAULT(x,EbmlFloat,id,parent,name,global,double,defval, versions) + DEFINE_xxx_CLASS_BASE_DEFAULT(x,EbmlFloat,id,parent,name,global,double,defval, libebml::EbmlFloat::SizeIsValid, versions) #define DEFINE_xxx_DATE_DEF(x,id,parent,name,versions,global,defval) \ - DEFINE_xxx_CLASS_BASE_DEFAULT(x,EbmlDate,id,parent,name,versions,global,defval, versions) + DEFINE_xxx_CLASS_BASE_DEFAULT(x,EbmlDate,id,parent,name,versions,global,defval, libebml::EbmlDate::SizeIsValid, versions) // define a class with no parent class (can be used globally) -#define DEFINE_xxx_CLASS_ORPHAN(x,id,name,versions,global) \ +#define DEFINE_xxx_CLASS_ORPHAN(x,id,name,valid,versions,global) \ static constexpr const libebml::EbmlId Id_##x {id}; static_assert(libebml::EbmlId::IsValid(Id_##x .GetValue()), "invalid id for " name ); \ static constexpr const libebml::EbmlSemanticContext Context_##x = libebml::EbmlSemanticContext(nullptr, global, nullptr); \ - constexpr const libebml::EbmlCallbacks x::ClassInfos(x::Create, Id_##x, false, false, name, Context_##x, versions); \ + constexpr const libebml::EbmlCallbacks x::ClassInfos(x::Create, Id_##x, false, false, name, Context_##x, versions, valid); \ #define DEFINE_EBML_CONTEXT(x) DEFINE_xxx_CONTEXT(x,GetEbmlGlobal_Context) #define DEFINE_EBML_MASTER(x,id,parent,infinite,name,versions) DEFINE_xxx_MASTER(x,id,parent,infinite,name,versions,GetEbmlGlobal_Context) #define DEFINE_EBML_MASTER_ORPHAN(x,id,infinite,name,versions) DEFINE_xxx_MASTER_ORPHAN(x,id,infinite,name,versions,GetEbmlGlobal_Context) -#define DEFINE_EBML_CLASS_ORPHAN(x,id,name,versions) DEFINE_xxx_CLASS_ORPHAN(x,id,name,versions,GetEbmlGlobal_Context) +#define DEFINE_EBML_CLASS_ORPHAN(x,id,name,valid,versions) DEFINE_xxx_CLASS_ORPHAN(x,id,name,valid,versions,GetEbmlGlobal_Context) #define DEFINE_EBML_UINTEGER_DEF(x,id,parent,name,val,versions) DEFINE_xxx_UINTEGER_DEF(x,id,parent,name,versions,GetEbmlGlobal_Context,val) #define DEFINE_EBML_STRING_DEF(x,id,parent,name,val,versions) DEFINE_xxx_STRING_DEF(x,id,parent,name,versions,GetEbmlGlobal_Context,val) @@ -199,10 +199,6 @@ class DllApi x : public BaseClass { \ #define DECLARE_xxx_BINARY(x,DllApi) \ DECLARE_xxx_BASE(x, DllApi, libebml::EbmlBinary) -#define DECLARE_xxx_BINARY_LENGTH(x,len,DllApi) \ - DECLARE_xxx_BASE(x, DllApi, libebml::EbmlBinary) \ - bool SizeIsValid(std::uint64_t size) const override {return size == len;} - #define DECLARE_xxx_UINTEGER(x,DllApi) \ DECLARE_xxx_BASE_NODEFAULT(x, DllApi, libebml::EbmlUInteger, std::uint64_t) @@ -243,7 +239,6 @@ class DllApi x : public BaseClass { \ #define DECLARE_EBML_UINTEGER_DEF(x) DECLARE_xxx_UINTEGER_DEF(x,EBML_DLL_API) #define DECLARE_EBML_STRING_DEF(x) DECLARE_xxx_STRING_DEF( x,EBML_DLL_API) #define DECLARE_EBML_BINARY(x) DECLARE_xxx_BINARY( x,EBML_DLL_API) -#define DECLARE_EBML_BINARY_LENGTH(x,len) DECLARE_xxx_BINARY_LENGTH(x,len,EBML_DLL_API) #define EBML_CONCRETE_CLASS(Type) \ public: \ @@ -339,9 +334,10 @@ class EBML_DLL_API EbmlDocVersion { class EBML_DLL_API EbmlCallbacks { public: using CreateOperator = EbmlElement & (*)(void); + using SizeValidator = bool (*)(std::uint64_t); constexpr EbmlCallbacks(const CreateOperator & Creator, const EbmlId & aGlobalId, bool aCanInfinite, bool aHasDefault, const char * aDebugName, const EbmlSemanticContext & aContext, - const EbmlDocVersion & aVersion) + const EbmlDocVersion & aVersion, const SizeValidator & aSizeCheck) :Create(Creator) ,GlobalId(aGlobalId) ,CanInfinite(aCanInfinite) @@ -349,6 +345,7 @@ class EBML_DLL_API EbmlCallbacks { ,Version(aVersion) ,DebugName(aDebugName) ,Context(aContext) + ,SizeCheck(aSizeCheck) { } @@ -361,6 +358,11 @@ class EBML_DLL_API EbmlCallbacks { inline constexpr bool HasDefault() const { return hasDefault; } // get information about supported version for this element inline constexpr const EbmlDocVersion & GetVersions() const { return Version; } + inline constexpr bool IsSizeValid(std::uint64_t size, bool AsInfinite) const { + if (AsInfinite) + return CanHaveInfiniteSize(); + return SizeCheck(size); + } private: const CreateOperator Create; @@ -370,14 +372,15 @@ class EBML_DLL_API EbmlCallbacks { const EbmlDocVersion &Version; const char * DebugName; const EbmlSemanticContext & Context; + const SizeValidator SizeCheck; }; template class EBML_DLL_API EbmlCallbacksDefault : public EbmlCallbacks { public: constexpr EbmlCallbacksDefault(EbmlElement & (*Creator)(), const EbmlId & aGlobalId, const char * aDebugName, const EbmlSemanticContext & aContext, - const EbmlDocVersion & aVersion, bool aHasDefault = false) - :EbmlCallbacks(Creator, aGlobalId, false, aHasDefault, aDebugName, aContext, aVersion) + const EbmlDocVersion & aVersion, const SizeValidator & aValid, bool aHasDefault = false) + :EbmlCallbacks(Creator, aGlobalId, false, aHasDefault, aDebugName, aContext, aVersion, aValid) { } }; @@ -386,8 +389,8 @@ template class EBML_DLL_API EbmlCallbacksWithDefault : public EbmlCallbacksDefault { public: constexpr EbmlCallbacksWithDefault(EbmlElement & (*Creator)(), const EbmlId & aGlobalId, const T &def, const char * aDebugName, const EbmlSemanticContext & aContext, - const EbmlDocVersion & aVersion) - :EbmlCallbacksDefault(Creator, aGlobalId, aDebugName, aContext, aVersion, true) + const EbmlDocVersion & aVersion, const EbmlCallbacks::SizeValidator & aValid) + :EbmlCallbacksDefault(Creator, aGlobalId, aDebugName, aContext, aVersion, aValid, true) ,defaultValue(def) { } @@ -537,20 +540,6 @@ static inline const EbmlSemantic & tEBML_CTX_IDX(const EbmlSemanticContextMaster return c.GetSemantic(i); } -class EBML_DLL_API EbmlCallbacksMaster : public EbmlCallbacks { - public: - constexpr EbmlCallbacksMaster(EbmlElement & (*Creator)(), const EbmlId & aGlobalId, bool aCanInfinite, - const char * aDebugName, const EbmlSemanticContextMaster & aContext, - const EbmlDocVersion & aVersion) - :EbmlCallbacks(Creator, aGlobalId, aCanInfinite, false, aDebugName, aContext, aVersion) - { - } - - inline constexpr const EbmlSemanticContextMaster & GetContextMaster() const { - return static_cast(GetContext()); - } -}; - /*! \class EbmlElement \brief Hold basic informations about an EBML element (ID + length) @@ -619,8 +608,7 @@ class EBML_DLL_API EbmlElement { return false; } - virtual bool SizeIsValid(std::uint64_t) const = 0; - bool ValidateSize() const { return SizeIsValid(GetSize()); } + bool ValidateSize() const { return ElementSpec().IsSizeValid(GetSize(), !IsFiniteSize()); } std::uint64_t GetElementPosition() const { return ElementPosition; @@ -688,7 +676,7 @@ class EBML_DLL_API EbmlElement { \return a DummyRawElement if the element is unknown or nullptr if the element dummy is not allowed */ static EbmlElement *CreateElementUsingContext(const EbmlId & aID, const EbmlSemanticContext & Context, int & LowLevel, bool IsGlobalContext, - bool AsInfiniteSize, + std::uint64_t WithSize, bool AsInfiniteSize, bool bAllowDummy = false, unsigned int MaxLowerLevel = 1); filepos_t RenderHead(IOCallback & output, bool bForceRender, const ShouldWrite& writeFilter = WriteSkipDefault, bool bKeepPosition = false); diff --git a/ebml/EbmlFloat.h b/ebml/EbmlFloat.h index 4a9f71ab..7189aa29 100644 --- a/ebml/EbmlFloat.h +++ b/ebml/EbmlFloat.h @@ -25,7 +25,7 @@ class EBML_DLL_API EbmlFloat : public EbmlElementDefaultSameStorage { EbmlFloat(const EbmlCallbacksDefault &, Precision prec = FLOAT_32); - bool SizeIsValid(std::uint64_t size) const override + static inline bool SizeIsValid(std::uint64_t size) { return (size == 4 || size == 8); } diff --git a/ebml/EbmlMaster.h b/ebml/EbmlMaster.h index 18084341..d8e53182 100644 --- a/ebml/EbmlMaster.h +++ b/ebml/EbmlMaster.h @@ -22,6 +22,8 @@ namespace libebml { constexpr const bool bChecksumUsedByDefault = false; +class EbmlCallbacksMaster; + /*! \class EbmlMaster \brief Handle all operations on an EBML element that contains other EBML elements @@ -31,7 +33,7 @@ class EBML_DLL_API EbmlMaster : public EbmlElement { explicit EbmlMaster(const EbmlCallbacksMaster &, bool bSizeIsKnown = true); EbmlMaster(const EbmlMaster & ElementToClone); EbmlMaster& operator=(const EbmlMaster&) = delete; - bool SizeIsValid(std::uint64_t /*size*/) const override {return true;} + static inline bool SizeIsValid(std::uint64_t /*size*/) {return true;} /*! \warning be carefull to clear the memory allocated in the ElementList elsewhere */ @@ -151,6 +153,20 @@ class EBML_DLL_API EbmlMaster : public EbmlElement { bool ProcessMandatory(); }; +class EBML_DLL_API EbmlCallbacksMaster : public EbmlCallbacks { + public: + constexpr EbmlCallbacksMaster(EbmlElement & (*Creator)(), const EbmlId & aGlobalId, bool aCanInfinite, + const char * aDebugName, const EbmlSemanticContextMaster & aContext, + const EbmlDocVersion & aVersion) + :EbmlCallbacks(Creator, aGlobalId, aCanInfinite, false, aDebugName, aContext, aVersion, libebml::EbmlMaster::SizeIsValid) + { + } + + inline constexpr const EbmlSemanticContextMaster & GetContextMaster() const { + return static_cast(GetContext()); + } +}; + static inline constexpr const EbmlSemanticContextMaster & tEBML_CONTEXT(const EbmlMaster * e) { return e->ContextMaster(); diff --git a/ebml/EbmlSInteger.h b/ebml/EbmlSInteger.h index cde784d8..3c2d1e33 100644 --- a/ebml/EbmlSInteger.h +++ b/ebml/EbmlSInteger.h @@ -31,7 +31,7 @@ class EBML_DLL_API EbmlSInteger : public EbmlElementDefaultSameStorage &); - bool SizeIsValid(std::uint64_t size) const override {return size < 0x7FFFFFFF;} // any size is possible + static inline bool SizeIsValid(std::uint64_t size) {return size < 0x7FFFFFFF;} // any size is possible filepos_t RenderData(IOCallback & output, bool bForceRender, const ShouldWrite & writeFilter = WriteSkipDefault) override; filepos_t ReadData(IOCallback & input, ScopeMode ReadFully = SCOPE_ALL_DATA) override; filepos_t UpdateSize(const ShouldWrite & writeFilter = WriteSkipDefault, bool bForceRender = false) override; diff --git a/ebml/EbmlUInteger.h b/ebml/EbmlUInteger.h index 8c829fa9..bb22e12c 100644 --- a/ebml/EbmlUInteger.h +++ b/ebml/EbmlUInteger.h @@ -29,7 +29,7 @@ class EBML_DLL_API EbmlUInteger : public EbmlElementDefaultSameStorage &); - bool SizeIsValid(std::uint64_t /*size*/) const override {return true;} // any size is possible + static inline bool SizeIsValid(std::uint64_t /*size*/) {return true;} // any size is possible filepos_t RenderData(IOCallback & output, bool bForceRender, const ShouldWrite & writeFilter = WriteSkipDefault) override; filepos_t ReadData(IOCallback & input, ScopeMode ReadFully = SCOPE_ALL_DATA) override; filepos_t UpdateSize(const ShouldWrite & writeFilter = WriteSkipDefault, bool bForceRender = false) override; diff --git a/src/EbmlCrc32.cpp b/src/EbmlCrc32.cpp index 257a44ed..435abc1e 100644 --- a/src/EbmlCrc32.cpp +++ b/src/EbmlCrc32.cpp @@ -27,7 +27,7 @@ namespace libebml { static constexpr EbmlDocVersion AllEbmlVersions{"ebml"}; -DEFINE_EBML_CLASS_ORPHAN(EbmlCrc32, 0xBF, "EBMLCrc32", AllEbmlVersions) +DEFINE_EBML_CLASS_ORPHAN(EbmlCrc32, 0xBF, "EBMLCrc32", EbmlCrc32::ValidateSize, AllEbmlVersions) static constexpr std::array s_tab { #ifdef WORDS_BIGENDIAN diff --git a/src/EbmlDummy.cpp b/src/EbmlDummy.cpp index 95b6516f..c18f99ae 100644 --- a/src/EbmlDummy.cpp +++ b/src/EbmlDummy.cpp @@ -12,7 +12,7 @@ namespace libebml { static constexpr EbmlDocVersion AllEbmlVersions{"ebml"}; -DEFINE_EBML_CLASS_ORPHAN(EbmlDummy, 0xFF, "DummyElement", AllEbmlVersions ) +DEFINE_EBML_CLASS_ORPHAN(EbmlDummy, 0xFF, "DummyElement", EbmlBinary::SizeIsValid, AllEbmlVersions ) EbmlDummy::EbmlDummy(const EbmlId & aId) : EbmlBinary(EbmlDummy::ClassInfos), DummyId(aId) {} diff --git a/src/EbmlElement.cpp b/src/EbmlElement.cpp index 3f8615c1..c977cb8f 100644 --- a/src/EbmlElement.cpp +++ b/src/EbmlElement.cpp @@ -191,8 +191,7 @@ EbmlElement * EbmlElement::FindNextID(IOCallback & DataStream, const EbmlCallbac } if (SizeFound != SizeUnknown && MaxDataSize < SizeFound) return nullptr; - // check if the size is not all 1s - if (SizeFound == SizeUnknown && !ClassInfos.CanHaveInfiniteSize()) + if (!ClassInfos.IsSizeValid(SizeFound, SizeFound == SizeUnknown)) return nullptr; return &EBML_INFO_CREATE(ClassInfos); }(); @@ -200,11 +199,6 @@ EbmlElement * EbmlElement::FindNextID(IOCallback & DataStream, const EbmlCallbac if (!Result) return nullptr; - if (!Result->SizeIsValid(SizeFound)) { - delete Result; - return nullptr; - } - Result->SetSizeLength(PossibleSizeLength); Result->Size = SizeFound; @@ -309,10 +303,11 @@ EbmlElement * EbmlElement::FindNextElement(IOCallback & DataStream, const EbmlSe if (bFound) { // find the element in the context and use the correct creator const auto PossibleID = EbmlId(EbmlId::FromBuffer(PossibleIdNSize.data(), PossibleID_Length)); - EbmlElement * Result = CreateElementUsingContext(PossibleID, Context, UpperLevel, false, SizeFound == SizeUnknown, AllowDummyElt, MaxLowerLevel); + EbmlElement * Result = CreateElementUsingContext(PossibleID, Context, UpperLevel, false, SizeFound, SizeFound == SizeUnknown, AllowDummyElt, MaxLowerLevel); ///< \todo continue is misplaced if (Result != nullptr) { if (AllowDummyElt || !Result->IsDummy()) { + assert(Result->ElementSpec().IsSizeValid(SizeFound, SizeFound == SizeUnknown)); Result->SetSizeLength(_SizeLength); Result->Size = SizeFound; @@ -321,7 +316,7 @@ EbmlElement * EbmlElement::FindNextElement(IOCallback & DataStream, const EbmlSe // 0 : child // 1 : same level // + : further parent - if (Result->SizeIsValid(SizeFound) && (SizeFound == SizeUnknown || UpperLevel > 0 || MaxDataSize == 0 || + if ((SizeFound == SizeUnknown || UpperLevel > 0 || MaxDataSize == 0 || MaxDataSize >= (IdStart + PossibleID_Length + _SizeLength + SizeFound))) { Result->ElementPosition = ParseStart + IdStart; Result->SizePosition = Result->ElementPosition + PossibleID_Length; @@ -409,7 +404,7 @@ EbmlElement * EbmlElement::SkipData(EbmlStream & DataStream, const EbmlSemanticC EbmlElement *EbmlElement::CreateElementUsingContext(const EbmlId & aID, const EbmlSemanticContext & Context, int & LowLevel, bool IsGlobalContext, - bool AsInfiniteSize, + std::uint64_t WithSize, bool AsInfiniteSize, bool bAllowDummy, unsigned int MaxLowerLevel) { EbmlElement *Result = nullptr; @@ -420,7 +415,7 @@ EbmlElement *EbmlElement::CreateElementUsingContext(const EbmlId & aID, const Eb const auto & MasterContext = static_cast(Context); for (unsigned int ContextIndex = 0; ContextIndex < EBML_CTX_SIZE(MasterContext); ContextIndex++) { if (aID == EBML_CTX_IDX_ID(MasterContext,ContextIndex)) { - if (AsInfiniteSize && !EBML_CTX_IDX_INFO(MasterContext,ContextIndex).CanHaveInfiniteSize()) + if (!EBML_CTX_IDX_INFO(MasterContext,ContextIndex).IsSizeValid(WithSize, AsInfiniteSize)) return nullptr; Result = &EBML_SEM_CREATE(EBML_CTX_IDX(MasterContext,ContextIndex)); Result->SetSizeInfinite(AsInfiniteSize); @@ -436,7 +431,7 @@ EbmlElement *EbmlElement::CreateElementUsingContext(const EbmlId & aID, const Eb LowLevel--; MaxLowerLevel--; // recursive is good, but be carefull... - Result = CreateElementUsingContext(aID, tstContext, LowLevel, true, AsInfiniteSize, bAllowDummy, MaxLowerLevel); + Result = CreateElementUsingContext(aID, tstContext, LowLevel, true, WithSize, AsInfiniteSize, bAllowDummy, MaxLowerLevel); if (Result != nullptr) { return Result; } @@ -449,7 +444,7 @@ EbmlElement *EbmlElement::CreateElementUsingContext(const EbmlId & aID, const Eb // parent elements if (EBML_CTX_MASTER(Context) != nullptr && aID == EBML_INFO_ID(*EBML_CTX_MASTER(Context))) { const auto& Callbacks = *EBML_CTX_MASTER(Context); - if (AsInfiniteSize && !Callbacks.CanHaveInfiniteSize()) + if (!Callbacks.IsSizeValid(WithSize, AsInfiniteSize)) return nullptr; LowLevel++; // already one level up (same as context) Result = &EBML_INFO_CREATE(Callbacks); @@ -461,7 +456,7 @@ EbmlElement *EbmlElement::CreateElementUsingContext(const EbmlId & aID, const Eb if (EBML_CTX_PARENT(Context) != nullptr) { LowLevel++; MaxLowerLevel++; - return CreateElementUsingContext(aID, *EBML_CTX_PARENT(Context), LowLevel, IsGlobalContext, AsInfiniteSize, bAllowDummy, MaxLowerLevel); + return CreateElementUsingContext(aID, *EBML_CTX_PARENT(Context), LowLevel, IsGlobalContext, WithSize, AsInfiniteSize, bAllowDummy, MaxLowerLevel); } if (!IsGlobalContext && bAllowDummy && !AsInfiniteSize) { diff --git a/src/EbmlVoid.cpp b/src/EbmlVoid.cpp index 12dd8176..d0b6ea66 100644 --- a/src/EbmlVoid.cpp +++ b/src/EbmlVoid.cpp @@ -12,7 +12,7 @@ namespace libebml { static constexpr EbmlDocVersion AllEbmlVersions{"ebml"}; -DEFINE_EBML_CLASS_ORPHAN(EbmlVoid, 0xEC, "EBMLVoid", AllEbmlVersions) +DEFINE_EBML_CLASS_ORPHAN(EbmlVoid, 0xEC, "EBMLVoid", EbmlBinary::SizeIsValid, AllEbmlVersions) EbmlVoid::EbmlVoid() :EbmlBinary(EbmlVoid::ClassInfos)