[libpeas] Prevent returning an extension that is not valid



commit 4d9871f94148af1655eb9428e2e37935850c6cf2
Author: Garrett Regier <garrettregier gmail com>
Date:   Sat Nov 19 16:45:36 2011 -0800

    Prevent returning an extension that is not valid
    
    With multiple interfaces an interface could have a prerequisite
    in which case if the extension does not implement that prerequisite
    we would return an extension that is not valid and not NULL.

 libpeas/peas-extension-subclasses.c                |   13 +++++
 loaders/gjs/peas-extension-gjs.c                   |    5 ++
 loaders/python/peas-extension-python.c             |    5 ++
 loaders/seed/peas-extension-seed.c                 |    5 ++
 tests/libpeas/introspection/Makefile.am            |   16 +++---
 .../introspection-has-missing-prerequisite.c       |   37 ++++++++++++++
 .../introspection-has-missing-prerequisite.h       |   52 ++++++++++++++++++++
 tests/libpeas/plugins/extension-js/extension-js.js |    7 ++-
 tests/libpeas/testing/testing-extension.c          |   18 +++++++
 9 files changed, 149 insertions(+), 9 deletions(-)
---
diff --git a/libpeas/peas-extension-subclasses.c b/libpeas/peas-extension-subclasses.c
index 54870a5..ed44a7a 100644
--- a/libpeas/peas-extension-subclasses.c
+++ b/libpeas/peas-extension-subclasses.c
@@ -369,6 +369,19 @@ peas_extension_register_subclass (GType  parent_type,
         g_type_add_interface_static (the_type, extension_types[i], &iface_info);
     }
 
+  /* Must be done outside of type registration
+   * in the event that the same type is requested again.
+   */
+  for (i = 0; extension_types[i] != 0; ++i)
+    {
+      if (!g_type_is_a (the_type, extension_types[i]))
+        {
+          g_warning ("Type '%s' is invalid", type_name->str);
+          the_type = G_TYPE_INVALID;
+          break;
+        }
+    }
+
   g_string_free (type_name, TRUE);
 
   return the_type;
diff --git a/loaders/gjs/peas-extension-gjs.c b/loaders/gjs/peas-extension-gjs.c
index 694fdd7..0e5d652 100644
--- a/loaders/gjs/peas-extension-gjs.c
+++ b/loaders/gjs/peas-extension-gjs.c
@@ -402,6 +402,11 @@ peas_extension_gjs_new (GType      exten_type,
 
   real_type = peas_extension_register_subclass (PEAS_TYPE_EXTENSION_GJS,
                                                 interfaces);
+
+  /* Already Warned */
+  if (real_type == G_TYPE_INVALID)
+    return NULL;
+
   gexten = PEAS_EXTENSION_GJS (g_object_new (real_type, NULL));
 
   gexten->js_context = js_context;
diff --git a/loaders/python/peas-extension-python.c b/loaders/python/peas-extension-python.c
index b722561..bcac503 100644
--- a/loaders/python/peas-extension-python.c
+++ b/loaders/python/peas-extension-python.c
@@ -144,6 +144,11 @@ peas_extension_python_new (GType     exten_type,
   
   real_type = peas_extension_register_subclass (PEAS_TYPE_EXTENSION_PYTHON,
                                                 interfaces);
+
+  /* Already Warned */
+  if (real_type == G_TYPE_INVALID)
+    return NULL;
+
   pyexten = PEAS_EXTENSION_PYTHON (g_object_new (real_type, NULL));
 
   pyexten->instance = instance;
diff --git a/loaders/seed/peas-extension-seed.c b/loaders/seed/peas-extension-seed.c
index bf0e428..d1a8bfb 100644
--- a/loaders/seed/peas-extension-seed.c
+++ b/loaders/seed/peas-extension-seed.c
@@ -309,6 +309,11 @@ peas_extension_seed_new (GType        exten_type,
 
   real_type = peas_extension_register_subclass (PEAS_TYPE_EXTENSION_SEED,
                                                 interfaces);
+
+  /* Already Warned */
+  if (real_type == G_TYPE_INVALID)
+    return NULL;
+
   sexten = PEAS_EXTENSION_SEED (g_object_new (real_type, NULL));
 
   sexten->js_context = js_context;
diff --git a/tests/libpeas/introspection/Makefile.am b/tests/libpeas/introspection/Makefile.am
index ff9393c..1907573 100644
--- a/tests/libpeas/introspection/Makefile.am
+++ b/tests/libpeas/introspection/Makefile.am
@@ -15,13 +15,15 @@ libintrospection_1_0_la_LDFLAGS = \
 libintrospection_1_0_la_LIBADD = $(PEAS_LIBS)
 
 libintrospection_1_0_la_SOURCES = \
-	introspection-callable.c		\
-	introspection-callable.h		\
-	introspection-has-prerequisite.c	\
-	introspection-has-prerequisite.h	\
-	introspection-properties.c		\
-	introspection-properties.h		\
-	introspection-unimplemented.c		\
+	introspection-callable.c			\
+	introspection-callable.h			\
+	introspection-has-missing-prerequisite.c	\
+	introspection-has-missing-prerequisite.h	\
+	introspection-has-prerequisite.c		\
+	introspection-has-prerequisite.h		\
+	introspection-properties.c			\
+	introspection-properties.h			\
+	introspection-unimplemented.c			\
 	introspection-unimplemented.h
 
 INCLUDES += $(INTROSPECTION_INCLUDES)
diff --git a/tests/libpeas/introspection/introspection-has-missing-prerequisite.c b/tests/libpeas/introspection/introspection-has-missing-prerequisite.c
new file mode 100644
index 0000000..1a0f7e9
--- /dev/null
+++ b/tests/libpeas/introspection/introspection-has-missing-prerequisite.c
@@ -0,0 +1,37 @@
+/*
+ * introspection-has-prerequisite.h
+ * This file is part of libpeas
+ *
+ * Copyright (C) 2011 Garrett Regier
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU Library General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Library General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "introspection-has-missing-prerequisite.h"
+
+#include "introspection-callable.h"
+
+G_DEFINE_INTERFACE(IntrospectionHasMissingPrerequisite,
+                   introspection_has_missing_prerequisite,
+                   INTROSPECTION_TYPE_CALLABLE)
+
+void
+introspection_has_missing_prerequisite_default_init (IntrospectionHasMissingPrerequisiteInterface *iface)
+{
+}
diff --git a/tests/libpeas/introspection/introspection-has-missing-prerequisite.h b/tests/libpeas/introspection/introspection-has-missing-prerequisite.h
new file mode 100644
index 0000000..c65a058
--- /dev/null
+++ b/tests/libpeas/introspection/introspection-has-missing-prerequisite.h
@@ -0,0 +1,52 @@
+/*
+ * introspection-has-prerequisite.h
+ * This file is part of libpeas
+ *
+ * Copyright (C) 2011 - Garrett Regier
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU Library General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU Library General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Library General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __INTROSPECTION_HAS_MISSING_PREREQUISITE_H__
+#define __INTROSPECTION_HAS_MISSING_PREREQUISITE_H__
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+/*
+ * Type checking and casting macros
+ */
+#define INTROSPECTION_TYPE_HAS_MISSING_PREREQUISITE             (introspection_has_missing_prerequisite_get_type ())
+#define INTROSPECTION_HAS_MISSING_PREREQUISITE(obj)             (G_TYPE_CHECK_INSTANCE_CAST ((obj), INTROSPECTION_TYPE_HAS_MISSING_PREREQUISITE, IntrospectionHasMissingPrerequisite))
+#define INTROSPECTION_HAS_MISSING_PREREQUISITE_IFACE(obj)       (G_TYPE_CHECK_CLASS_CAST ((obj), INTROSPECTION_TYPE_HAS_MISSING_PREREQUISITE, IntrospectionHasMissingPrerequisiteInterface))
+#define INTROSPECTION_IS_HAS_MISSING_PREREQUISITE(obj)          (G_TYPE_CHECK_INSTANCE_TYPE ((obj), INTROSPECTION_TYPE_HAS_MISSING_PREREQUISITE))
+#define INTROSPECTION_HAS_MISSING_PREREQUISITE_GET_IFACE(obj)   (G_TYPE_INSTANCE_GET_INTERFACE ((obj), INTROSPECTION_TYPE_HAS_MISSING_PREREQUISITE, IntrospectionHasMissingPrerequisiteInterface))
+
+typedef struct _IntrospectionHasMissingPrerequisite           IntrospectionHasMissingPrerequisite; /* dummy typedef */
+typedef struct _IntrospectionHasMissingPrerequisiteInterface  IntrospectionHasMissingPrerequisiteInterface;
+
+struct _IntrospectionHasMissingPrerequisiteInterface {
+  GTypeInterface g_iface;
+};
+
+/*
+ * Public methods
+ */
+GType        introspection_has_missing_prerequisite_get_type         (void) G_GNUC_CONST;
+
+G_END_DECLS
+
+#endif /* __INTROSPECTION_HAS_MISSING_PREREQUISITE_H__ */
diff --git a/tests/libpeas/plugins/extension-js/extension-js.js b/tests/libpeas/plugins/extension-js/extension-js.js
index e632f67..6953d6b 100644
--- a/tests/libpeas/plugins/extension-js/extension-js.js
+++ b/tests/libpeas/plugins/extension-js/extension-js.js
@@ -24,9 +24,12 @@ function properties_extension() {
   this.readwrite = "readwrite";
 }
 
+function missing_prerequisite_extension() {}
+
 var extensions = {
   "PeasActivatable": callable_extension,
   "IntrospectionCallable": callable_extension,
   "IntrospectionProperties": properties_extension,
-  "IntrospectionHasPrerequisite": callable_extension
-}
+  "IntrospectionHasPrerequisite": callable_extension,
+  "IntrospectionHasMissingPrerequisite": missing_prerequisite_extension
+};
diff --git a/tests/libpeas/testing/testing-extension.c b/tests/libpeas/testing/testing-extension.c
index 65296e4..111ca6c 100644
--- a/tests/libpeas/testing/testing-extension.c
+++ b/tests/libpeas/testing/testing-extension.c
@@ -34,6 +34,7 @@
 #include "testing-extension.h"
 
 #include "introspection-callable.h"
+#include "introspection-has-missing-prerequisite.h"
 #include "introspection-has-prerequisite.h"
 #include "introspection-properties.h"
 #include "introspection-unimplemented.h"
@@ -186,6 +187,23 @@ testing_extension_create_invalid_ (PeasEngine *engine)
                                             "invalid-property", "does-not-exist",
                                             NULL);
   g_assert (!PEAS_IS_EXTENSION (extension));
+
+  /* This cannot be tested in PyGI and Seed's log handler messes this up */
+  if (g_strcmp0 (extension_plugin, "extension-c") == 0 ||
+      g_strcmp0 (extension_plugin, "extension-python") == 0 ||
+      g_strcmp0 (extension_plugin, "extension-seed") == 0)
+    return;
+
+  testing_util_push_log_hook ("*cannot add *IntrospectionHasMissingPrerequisite* "
+                              "which does not conform to *IntrospectionCallable*");
+  testing_util_push_log_hook ("*Type *HasMissingPrerequisite* is invalid");
+  testing_util_push_log_hook ("*does not provide a *HasMissingPrerequisite* extension");
+
+  /* Missing Prerequisite */
+  extension = peas_engine_create_extension (engine, info,
+                                            INTROSPECTION_TYPE_HAS_MISSING_PREREQUISITE,
+                                            NULL);
+  g_assert (!PEAS_IS_EXTENSION (extension));
 }
 
 void



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]