Our virObject code relies heavily on the fact that the first
member of the class struct is type of virObject (or some
derivation of if). Let's check for that.
Signed-off-by: Michal Privoznik <mprivozn(a)redhat.com>
---
src/util/virobject.c | 31 +++++++++++++++++++++----------
src/util/virobject.h | 5 ++++-
2 files changed, 25 insertions(+), 11 deletions(-)
diff --git a/src/util/virobject.c b/src/util/virobject.c
index c5a98d21cc..e184f5349e 100644
--- a/src/util/virobject.c
+++ b/src/util/virobject.c
@@ -77,6 +77,7 @@ virObjectOnceInit(void)
{
if (!(virObjectClass = virClassNew(NULL,
"virObject",
+ 0,
sizeof(virObject),
NULL)))
return -1;
@@ -159,21 +160,31 @@ virClassForObjectRWLockable(void)
virClassPtr
virClassNew(virClassPtr parent,
const char *name,
+ size_t off,
size_t objectSize,
virObjectDisposeCallback dispose)
{
virClassPtr klass;
- if (parent == NULL &&
- STRNEQ(name, "virObject")) {
- virReportInvalidNonNullArg(parent);
- return NULL;
- } else if (parent &&
- objectSize <= parent->objectSize) {
- virReportInvalidArg(objectSize,
- _("object size %zu of %s is smaller than parent class
%zu"),
- objectSize, name, parent->objectSize);
- return NULL;
+ if (parent == NULL) {
+ if (STRNEQ(name, "virObject")) {
+ virReportInvalidNonNullArg(parent);
+ return NULL;
+ }
+ } else {
+ if (objectSize <= parent->objectSize) {
+ virReportInvalidArg(objectSize,
+ _("object size %zu of %s is smaller than parent
class %zu"),
+ objectSize, name, parent->objectSize);
+ return NULL;
+ }
+
+ if (off) {
+ virReportInvalidArg(off,
+ _("struct %s doesn't have 'parent' as
its first member"),
+ name);
+ return NULL;
+ }
}
if (VIR_ALLOC(klass) < 0)
diff --git a/src/util/virobject.h b/src/util/virobject.h
index 92dd512399..25db3a0c22 100644
--- a/src/util/virobject.h
+++ b/src/util/virobject.h
@@ -76,11 +76,14 @@ virClassPtr virClassForObjectRWLockable(void);
# endif
# define VIR_CLASS_NEW(prnt, name) \
- virClassNew(prnt, #name, sizeof(name), name##Dispose)
+ virClassNew(prnt, #name, \
+ offsetof(name, parent), \
+ sizeof(name), name##Dispose)
virClassPtr
virClassNew(virClassPtr parent,
const char *name,
+ size_t off,
size_t objectSize,
virObjectDisposeCallback dispose)
VIR_PARENT_REQUIRED ATTRIBUTE_NONNULL(2);
--
2.16.1