[libvirt] [PATCH 8/9] virobject: Check if @parent is the first member in class

Michal Privoznik mprivozn at redhat.com
Fri Apr 13 14:47:15 UTC 2018


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 at 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




More information about the libvir-list mailing list