[seed] Allow the creation of a restricted/constrained SeedEngine and add APIs to expose choosen GObject nam



commit 31de08a8b76b7f277defe23b5ab5a371500e4c4a
Author: Alexandre Mazari <amazari igalia com>
Date:   Wed Mar 23 18:34:54 2011 +0100

    Allow the creation of a restricted/constrained SeedEngine and add APIs to expose choosen GObject namspaces and instance into this engine
    
    The Javascript context of a restricted SeedEngine is empty by default.
    The importer module, builtins and GType overriding facilities aren't
    exposed to JS Code.
    The developer must expose *explicitely* the objects and namespaces
    that should be accessible from the Javascript context.
    
    Add hight-level API to expose GObject instance and namespace in the JS context
    
    https://bugzilla.gnome.org/show_bug.cgi?id=645696

 libseed/seed-engine.c   |  165 +++++++++++++++++++++++++++++++++++++++++++----
 libseed/seed-importer.c |   13 +++-
 libseed/seed-importer.h |    2 +
 libseed/seed.h          |    9 +++
 4 files changed, 171 insertions(+), 18 deletions(-)
---
diff --git a/libseed/seed-engine.c b/libseed/seed-engine.c
index 58fabf5..68bfefb 100644
--- a/libseed/seed-engine.c
+++ b/libseed/seed-engine.c
@@ -1567,16 +1567,22 @@ seed_engine_destroy (SeedEngine *eng)
 }
 
 /**
- * seed_init_with_context_and_group:
+ * seed_init_constrained_with_context_and_group:
  * @argc: A reference to the number of arguments remaining to parse.
  * @argv: A reference to an array of string arguments remaining to parse.
  * @context A reference to an existing JavascriptCore context
  * @group: A #SeedContextGroup within which to create the initial context.
  *
- * Initializes a new #SeedEngine using an existing JavascriptCore context. 
- * This involves initializing GLib, adding @instance to @group, adding the 
- * default globals to the provided context, and initializing various internal
- * parts of Seed.
+ * Initializes an empty new #SeedEngine. The Javascript context of this engine is
+ * *not* filled with any builtins functions and the import system.
+ *
+ * The javascript code executed with this engine can't import arbitrary
+ * GObject introspected librairies.
+ *
+ * Use this when control over what is exposed in the Javascript context is required,
+ * for security concerns for example.
+ * GObject instances can be selectively exposed by calling @seed_engine_expose_gobject.
+ * Namespaces can be selectively exposed by calling
  *
  * This function should only be called once within a single Seed application.
  *
@@ -1584,10 +1590,11 @@ seed_engine_destroy (SeedEngine *eng)
  *
  */
 SeedEngine *
-seed_init_with_context_and_group (gint * argc,
-			      gchar *** argv, JSGlobalContextRef context, JSContextGroupRef group)
+seed_init_constrained_with_context_and_group (gint * argc,
+                                                     gchar *** argv,
+                                                     JSGlobalContextRef context,
+                                                     JSContextGroupRef group)
 {
-
   g_type_init ();
   g_log_set_handler ("GLib-GObject", G_LOG_LEVEL_WARNING, seed_log_handler, 0);
 
@@ -1645,16 +1652,40 @@ seed_init_with_context_and_group (gint * argc,
 
   g_irepository_require (g_irepository_get_default (), "GObject", NULL, 0, 0);
   g_irepository_require (g_irepository_get_default (), "GIRepository",
-			 NULL, 0, 0);
-
-  seed_initialize_importer (eng->context, eng->global);
+                         NULL, 0, 0);
 
-  seed_init_builtins (eng, argc, argv);
-  seed_closures_init ();
   seed_structs_init ();
+  seed_closures_init ();
 
-  seed_gtype_init (eng);
+  return eng;
+}
+
+/**
+ * seed_init_with_context_and_group:
+ * @argc: A reference to the number of arguments remaining to parse.
+ * @argv: A reference to an array of string arguments remaining to parse.
+ * @context A reference to an existing JavascriptCore context
+ * @group: A #SeedContextGroup within which to create the initial context.
+ *
+ * Initializes a new #SeedEngine using an existing JavascriptCore context.
+ * This involves initializing GLib, adding @instance to @group, adding the
+ * default globals to the provided context, and initializing various internal
+ * parts of Seed.
+ *
+ * This function should only be called once within a single Seed application.
+ *
+ * Return value: The newly created and initialized #SeedEngine.
+ *
+ */
+SeedEngine *
+seed_init_with_context_and_group (gint * argc,
+			      gchar *** argv, JSGlobalContextRef context, JSContextGroupRef group)
+{
 
+  eng = seed_init_constrained_with_context_and_group (argc, argv, context, group);
+  seed_init_builtins (eng, argc, argv);
+  seed_initialize_importer (eng->context, eng->global);
+  seed_gtype_init (eng);
 
   defaults_script =
     JSStringCreateWithUTF8CString ("Seed.include(\"" SEED_PREFIX_PATH
@@ -1739,4 +1770,110 @@ seed_init_with_context (gint * argc, gchar *** argv, JSGlobalContextRef context)
   return seed_init_with_context_and_group (argc, argv, context, context_group);
 }
 
+/**
+ * seed_init_constrained:
+ * @argc: A reference to the number of arguments remaining to parse.
+ * @argv: A reference to an array of string arguments remaining to parse.
+ *
+ * Initializes an empty new #SeedEngine. The Javascript context of this engine is
+ * *not* filled with any builtins functions and the import system.
+ *
+ * The javascript code executed with this engine can't import arbitrary
+ * GObject introspected librairies.
+ *
+ * Use this when control over what is exposed in the Javascript context is required,
+ * for security concerns for example.
+ * GObject instances can be selectively exposed by calling @seed_engine_expose_gobject.
+ * Namespaces can be selectively exposed by calling
+ *
+ * This function should only be called once within a single Seed application.
+ *
+ * Return value: The newly created and initialized #SeedEngine.
+ *
+ */
+SeedEngine *
+seed_init_constrained (gint * argc, gchar *** argv)
+{
+  context_group = JSContextGroupCreate ();
+  pthread_key_create(&seed_next_gobject_wrapper_key, NULL);
+
+  return seed_init_constrained_with_context_and_group(argc, argv,
+                                                             JSGlobalContextCreateInGroup (context_group, NULL),
+                                                             context_group);
+}
+
+/*
+ * seed_engine_expose_gobject:
+ * @engine:
+ * @name: The name of the global javascript variable pointing to @object
+ * @object: The #GObject instance that will be exposed in the the javascript context
+ * @gir_namespace: The Introspection namespace containing the type of the provided
+ * object.
+ *
+ * Expose a GObject instance to the global Javascript context and makes it accessible
+ * under the provided @js_name
+ *
+ * return: the SeedValue representing @object, NULL in case of error
+ */
+JSValueRef
+seed_engine_expose_gobject (SeedEngine *engine,
+                            gchar *js_name,
+                            GObject *object,
+                            gchar *gir_namespace,
+                            JSValueRef * exception)
+{
+  GError *error = NULL;
+
+  g_assert (engine != NULL && gir_namespace != NULL && js_name != NULL);
+
+  GITypelib *type_lib = g_irepository_require (g_irepository_get_default(),
+                                               gir_namespace, NULL, 0, &error);
+  if (type_lib == NULL)
+  {
+    seed_make_exception_from_gerror (engine->context, exception, error);
+    g_error_free (error);
+    return NULL;
+  }
+
+  JSValueRef obj_js_value = seed_value_from_object (engine->context,
+                                                    G_OBJECT(object),
+                                                    exception);
+  g_return_val_if_fail (obj_js_value != NULL, NULL);
+
+  g_return_val_if_fail (engine->global != NULL, NULL);
+
+  gboolean ok = seed_object_set_property (engine->context,
+                                          engine->global, js_name, obj_js_value);
+  g_return_val_if_fail (ok == TRUE, NULL);
 
+  return obj_js_value;
+}
+
+/*
+ * seed_engine_expose_namespace:
+ * @engine:
+ * @namespace: Name of the GIR Namespace that should be exposed in the JS context.
+ *
+ * Expose a GIR namespace in the global Javascript context and makes it accessible
+ * under a variable named after the namespace (ex: the namespace 'Notify' is held
+ * by the 'Notify' javascript variable.
+ *
+ * return: the SeedValue representing @namespace in the javascript context,
+ *  NULL in case of error
+ */
+JSValueRef
+seed_engine_expose_namespace (SeedEngine *engine,
+                              gchar *namespace_name,
+                              JSValueRef *exception)
+{
+  g_assert (engine != NULL && namespace_name != NULL);
+
+  JSValueRef namespace = seed_gi_importer_do_namespace (engine->context,
+                                                        namespace_name, exception);
+  g_return_val_if_fail (namespace != NULL, NULL);
+  gboolean ok = seed_object_set_property (engine->context,
+                                           engine->global, namespace_name, namespace);
+  g_return_val_if_fail (ok == TRUE, FALSE);
+
+  return namespace;
+}
diff --git a/libseed/seed-importer.c b/libseed/seed-importer.c
index 7c85a59..149180a 100644
--- a/libseed/seed-importer.c
+++ b/libseed/seed-importer.c
@@ -371,7 +371,7 @@ seed_gi_importer_get_version (JSContextRef ctx,
   return version;
 }
 
-static JSObjectRef
+JSObjectRef
 seed_gi_importer_do_namespace (JSContextRef ctx,
 			       gchar * namespace, JSValueRef * exception)
 {
@@ -379,10 +379,13 @@ seed_gi_importer_do_namespace (JSContextRef ctx,
   JSObjectRef namespace_ref;
   GError *e = NULL;
   guint n, i;
-  gchar *version;
+  gchar *version = NULL;
   gchar *jsextension;
   JSStringRef extension_script;
 
+  if (gi_imports == NULL)
+    gi_imports = g_hash_table_new (g_str_hash, g_str_equal);
+
   if ((namespace_ref = g_hash_table_lookup (gi_imports, namespace)))
     {
       SEED_NOTE (IMPORTER, "Using existing namespace ref (%p) for %s",
@@ -390,7 +393,8 @@ seed_gi_importer_do_namespace (JSContextRef ctx,
       return namespace_ref;
     }
 
-  version = seed_gi_importer_get_version (ctx, namespace, exception);
+  if (gi_importer_versions != NULL)
+    version = seed_gi_importer_get_version (ctx, namespace, exception);
   if (!g_irepository_require (NULL, namespace, version, 0, &e))
     {
       seed_make_exception_from_gerror (ctx, exception, e);
@@ -398,7 +402,8 @@ seed_gi_importer_do_namespace (JSContextRef ctx,
       g_free (version);
       return NULL;
     }
-  g_free (version);
+  if (version != NULL)
+    g_free (version);
 
   n = g_irepository_get_n_infos (NULL, namespace);
 
diff --git a/libseed/seed-importer.h b/libseed/seed-importer.h
index 50ea0c0..03b81c9 100644
--- a/libseed/seed-importer.h
+++ b/libseed/seed-importer.h
@@ -25,5 +25,7 @@
 extern JSObjectRef importer;
 
 void seed_initialize_importer (JSContextRef ctx, JSObjectRef global);
+JSObjectRef seed_gi_importer_do_namespace (JSContextRef ctx,
+                                           gchar * namespace, JSValueRef * exception);
 
 #endif
diff --git a/libseed/seed.h b/libseed/seed.h
index b71589c..6541eee 100644
--- a/libseed/seed.h
+++ b/libseed/seed.h
@@ -80,6 +80,11 @@ SeedEngine *seed_init_with_context_group (gint *argc, gchar ***argv,
 					  SeedContextGroup group);
 SeedEngine *seed_init_with_context_and_group (gint * argc,gchar *** argv,
 					  SeedGlobalContext context, SeedContextGroup group);
+SeedEngine *seed_init_constrained (gint * argc, gchar *** argv);
+SeedEngine *seed_init_constrained_with_context_and_group (gint * argc,
+                                                                 gchar *** argv,
+                                                                 SeedGlobalContext context,
+                                                                 SeedContextGroup group);
 void seed_engine_destroy (SeedEngine *eng);
 
 SeedValue seed_simple_evaluate (SeedContext ctx,
@@ -103,6 +108,10 @@ gchar *seed_exception_to_string (SeedContext ctx, SeedException exception);
 
 SeedValue seed_evaluate (SeedContext ctx, SeedScript * s, SeedObject this);
 
+SeedValue
+seed_engine_expose_gobject (SeedEngine *engine, gchar *js_name, GObject *object, gchar *gir_namespace, SeedException exception);
+SeedValue
+seed_engine_expose_namespace (SeedEngine *engine, gchar *namespace_name, SeedException exception);
 GOptionGroup * seed_get_option_group (void);
 
 /*



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