static void
gd_tagged_entry_action (GdTaggedEntry *self,
                        const gchar   *prefix,
                        const gchar   *action_name,
                        const gchar   *param)
{
    GVariant *variant = NULL;

    g_print ("action!!!\n");

    if (*param != 0)
    {
        g_autoptr(GError) error = NULL;

        variant = g_variant_parse (NULL, param, NULL, NULL, &error);

        if (variant == NULL)
        {
            g_warning ("can't parse keybinding parameters \"%s\": %s",
                       param, error->message);
            return;
        }
    }

    activate_action (GTK_WIDGET (self), prefix, action_name, variant);
}
static void
get_macaroon (GsPlugin *plugin, gchar **macaroon, gchar ***discharges)
{
	GsAuth *auth;
	const gchar *serialized_macaroon;
	g_autoptr(GVariant) macaroon_variant = NULL;
	g_autoptr (GError) error_local = NULL;

	*macaroon = NULL;
	*discharges = NULL;

	auth = gs_plugin_get_auth_by_id (plugin, "snapd");
	if (auth == NULL)
		return;
	serialized_macaroon = gs_auth_get_metadata_item (auth, "macaroon");
	if (serialized_macaroon == NULL)
		return;
	macaroon_variant = g_variant_parse (G_VARIANT_TYPE ("(sas)"),
					    serialized_macaroon,
					    NULL,
					    NULL,
					    NULL);
	if (macaroon_variant == NULL)
		return;
	g_variant_get (macaroon_variant, "(s^as)", macaroon, discharges);
}
Beispiel #3
0
/**
 * @brief
 * @param ui The GstSwitchUI instance.
 * @memberof GstSwitchUI
 */
static void
gst_switch_ui_prepare_videos (GstSwitchUI * ui)
{
  GVariant *preview_ports;
  gsize n, num_previews = 0;
  gint port;

  port = gst_switch_client_get_compose_port (GST_SWITCH_CLIENT (ui));
  gst_switch_ui_set_compose_port (ui, port);

  port = gst_switch_client_get_audio_port (GST_SWITCH_CLIENT (ui));
  gst_switch_ui_set_audio_port (ui, port);

  port = gst_switch_client_get_encode_port (GST_SWITCH_CLIENT (ui));
  INFO ("Encoded output port: %d", port);

  preview_ports = gst_switch_client_get_preview_ports (GST_SWITCH_CLIENT (ui));
  if (preview_ports) {
    GVariant *ports = NULL;
    GError *error = NULL;
    gchar *s = NULL;
    gint serve, type;

    g_variant_get (preview_ports, "(&s)", &s);
    ports = g_variant_parse (G_VARIANT_TYPE ("a(iii)"), s, NULL, NULL, &error);

    num_previews = g_variant_n_children (ports);
    for (n = 0; n < num_previews; ++n) {
      g_variant_get_child (ports, n, "(iii)", &port, &serve, &type);
      gst_switch_ui_add_preview_port (ui, port, serve, type);
      //INFO ("preview: %d, %d, %d", port, serve, type);
    }
  }
}
static GVariant *
get_properties (Server * server)
{
	RdpServer * rserver = RDP_SERVER(server);

	GVariantBuilder propbuilder;
	g_variant_builder_init(&propbuilder, G_VARIANT_TYPE_ARRAY);

	GVariantBuilder namebuilder;
	g_variant_builder_init(&namebuilder, G_VARIANT_TYPE_TUPLE);
	g_variant_builder_add_value(&namebuilder, g_variant_new_string("username"));
	g_variant_builder_add_value(&namebuilder, g_variant_new_boolean(TRUE));
	if (rserver->username == NULL) {
		g_variant_builder_add_value(&namebuilder, g_variant_new_variant(g_variant_new_string("")));
	} else {
		g_variant_builder_add_value(&namebuilder, g_variant_new_variant(g_variant_new_string(rserver->username)));
	}
	g_variant_builder_add_value(&namebuilder, g_variant_parse(G_VARIANT_TYPE_VARDICT, "{}", NULL, NULL, NULL));
	g_variant_builder_add_value(&propbuilder, g_variant_builder_end(&namebuilder));

	GVariantBuilder passbuilder;
	g_variant_builder_init(&passbuilder, G_VARIANT_TYPE_TUPLE);
	g_variant_builder_add_value(&passbuilder, g_variant_new_string("password"));
	g_variant_builder_add_value(&passbuilder, g_variant_new_boolean(TRUE));
	if (rserver->password == NULL) {
		g_variant_builder_add_value(&passbuilder, g_variant_new_variant(g_variant_new_string("")));
	} else {
		g_variant_builder_add_value(&passbuilder, g_variant_new_variant(g_variant_new_string(rserver->password)));
	}
	g_variant_builder_add_value(&passbuilder, g_variant_parse(G_VARIANT_TYPE_VARDICT, "{}", NULL, NULL, NULL));
	g_variant_builder_add_value(&propbuilder, g_variant_builder_end(&passbuilder));

	GVariantBuilder domainbuilder;
	g_variant_builder_init(&domainbuilder, G_VARIANT_TYPE_TUPLE);
	g_variant_builder_add_value(&domainbuilder, g_variant_new_string("domain"));
	g_variant_builder_add_value(&domainbuilder, g_variant_new_boolean(rserver->domain_required));
	if (rserver->domain == NULL) {
		g_variant_builder_add_value(&domainbuilder, g_variant_new_variant(g_variant_new_string("")));
	} else {
		g_variant_builder_add_value(&domainbuilder, g_variant_new_variant(g_variant_new_string(rserver->domain)));
	}
	g_variant_builder_add_value(&domainbuilder, g_variant_parse(G_VARIANT_TYPE_VARDICT, "{}", NULL, NULL, NULL));
	g_variant_builder_add_value(&propbuilder, g_variant_builder_end(&domainbuilder));

	return g_variant_builder_end(&propbuilder);
}
boost::shared_ptr<AuthProvider> createSignonAuthProvider(const InitStateString &username,
                                                         const InitStateString &password)
{
    // Expected content of parameter GVariant.
    boost::shared_ptr<GVariantType> hashtype(g_variant_type_new("a{sv}"), g_variant_type_free);

    // 'username' is the part after signon: which we can parse directly.
    GErrorCXX gerror;
    GVariantCXX parametersVar(g_variant_parse(hashtype.get(), username.c_str(), NULL, NULL, gerror),
                              TRANSFER_REF);
    if (!parametersVar) {
        gerror.throwError(SE_HERE, "parsing 'signon:' username");
    }
    GHashTableCXX parameters(Variant2HashTable(parametersVar));

    // Extract the values that we expect in the parameters hash.
    guint32 signonID;
    const char *method;
    const char *mechanism;

    GVariant *value;
    value = (GVariant *)g_hash_table_lookup(parameters, "identity");
    if (!value ||
        !g_variant_type_equal(G_VARIANT_TYPE_UINT32, g_variant_get_type(value))) {
        SE_THROW("need 'identity: <numeric ID>' in 'signon:' parameters");
    }
    signonID = g_variant_get_uint32(value);

    value = (GVariant *)g_hash_table_lookup(parameters, "method");
    if (!value ||
        !g_variant_type_equal(G_VARIANT_TYPE_STRING, g_variant_get_type(value))) {
        SE_THROW("need 'method: <string>' in 'signon:' parameters");
    }
    method = g_variant_get_string(value, NULL);

    value = (GVariant *)g_hash_table_lookup(parameters, "mechanism");
    if (!value ||
        !g_variant_type_equal(G_VARIANT_TYPE_STRING, g_variant_get_type(value))) {
        SE_THROW("need 'mechanism: <string>' in 'signon:' parameters");
    }
    mechanism = g_variant_get_string(value, NULL);

    value = (GVariant *)g_hash_table_lookup(parameters, "session");
    if (!value ||
        !g_variant_type_equal(hashtype.get(), g_variant_get_type(value))) {
        SE_THROW("need 'session: <hash>' in 'signon:' parameters");
    }
    GHashTableCXX sessionData(Variant2HashTable(value));

    SE_LOG_DEBUG(NULL, "using identity %u, method %s, mechanism %s",
                 signonID, method, mechanism);
    SignonIdentityCXX identity(signon_identity_new_from_db(signonID), TRANSFER_REF);
    SE_LOG_DEBUG(NULL, "using signond identity %d", signonID);
    SignonAuthSessionCXX authSession(signon_identity_create_session(identity, method, gerror), TRANSFER_REF);

    boost::shared_ptr<AuthProvider> provider(new SignonAuthProvider(authSession, sessionData, mechanism));
    return provider;
}
Beispiel #6
0
static int
app_action (gchar **args)
{
  GVariantBuilder params;
  const gchar *name;

  if (!app_check_name (args, "action"))
    return 1;

  if (args[1] == NULL)
    {
      g_printerr (_("action name must be given after application id\n"));
      return 1;
    }

  name = args[1];

  if (!g_action_name_is_valid (name))
    {
      g_printerr (_("invalid action name: '%s'\n"
                    "action names must consist of only alphanumerics, '-' and '.'\n"), name);
      return 1;
    }

  g_variant_builder_init (&params, G_VARIANT_TYPE ("av"));

  if (args[2])
    {
      GError *error = NULL;
      GVariant *parameter;

      parameter = g_variant_parse (NULL, args[2], NULL, NULL, &error);

      if (!parameter)
        {
          gchar *context;

          context = g_variant_parse_error_print_context (error, args[2]);
          g_printerr (_("error parsing action parameter: %s\n"), context);
          g_variant_builder_clear (&params);
          g_error_free (error);
          g_free (context);
          return 1;
        }

      g_variant_builder_add (&params, "v", parameter);
      g_variant_unref (parameter);

      if (args[3])
        {
          g_printerr (_("actions accept a maximum of one parameter\n"));
          g_variant_builder_clear (&params);
          return 1;
        }
    }

  return app_call (args[0], "ActivateAction", g_variant_new ("(sav@a{sv})", name, &params, app_get_platform_data ()));
}
Beispiel #7
0
/* Hack. We iterate over the accel map instead of the actions,
 * in order to pull the parameters out of accel map entries
 */
static void
add_accel_closure (gpointer         data,
                   const gchar     *accel_path,
                   guint            accel_key,
                   GdkModifierType  accel_mods,
                   gboolean         changed)
{
    GtkApplicationWindow *window = data;
    GActionGroup *actions;
    const gchar *path;
    const gchar *p;
    gchar *action_name;
    GVariant *parameter;
    AccelClosure *closure;

    if (accel_key == 0)
        return;

    if (!g_str_has_prefix (accel_path, "<GAction>/"))
        return;

    path = accel_path + strlen ("<GAction>/");
    p = strchr (path, '/');
    if (p)
    {
        action_name = g_strndup (path, p - path);
        parameter = g_variant_parse (NULL, p + 1, NULL, NULL, NULL);
        if (!parameter)
            g_warning ("Failed to parse parameter from '%s'\n", accel_path);
    }
    else
    {
        action_name = g_strdup (path);
        parameter = NULL;
    }

    actions = G_ACTION_GROUP (_gtk_widget_get_action_muxer (GTK_WIDGET (window)));
    if (g_action_group_has_action (actions, action_name))
    {
        closure = (AccelClosure*) g_closure_new_object (sizeof (AccelClosure), g_object_ref (actions));
        g_closure_set_marshal (&closure->closure, accel_activate);

        closure->action_name = g_strdup (action_name);
        closure->parameter = parameter ? g_variant_ref_sink (parameter) : NULL;

        window->priv->accel_closures = g_slist_prepend (window->priv->accel_closures, g_closure_ref (&closure->closure));
        g_closure_sink (&closure->closure);

        gtk_accel_group_connect_by_path (window->priv->accels, accel_path, &closure->closure);
    }
    else if (parameter)
    {
        g_variant_unref (parameter);
    }

    g_free (action_name);
}
Beispiel #8
0
static void
load_auth (GsPlugin *plugin)
{
	GsPluginData *priv = gs_plugin_get_data (plugin);
	GsAuth *auth;
	GoaObject *goa_object;
	GoaPasswordBased *password_based;
	g_autofree gchar *macaroon = NULL;
	g_autofree gchar *discharges_str = NULL;
	g_autoptr(GVariant) discharges_var = NULL;
	g_auto(GStrv) discharges = NULL;
	g_autoptr(SnapdAuthData) auth_data = NULL;
	g_autoptr(GError) error = NULL;

	auth = gs_plugin_get_auth_by_id (plugin, "snapd");
	if (auth == NULL)
		return;

	g_clear_object (&priv->auth_data);
	goa_object = gs_auth_peek_goa_object (auth);
	if (goa_object == NULL)
		return;

	password_based = goa_object_peek_password_based (goa_object);
	g_return_if_fail (password_based != NULL);

	goa_password_based_call_get_password_sync (password_based,
						   "macaroon",
						   &macaroon,
						   NULL, &error);
	if (error != NULL) {
		g_warning ("Failed to get macaroon: %s", error->message);
		return;
	}

	goa_password_based_call_get_password_sync (password_based,
						   "discharges",
						   &discharges_str,
						   NULL, &error);
	if (error != NULL) {
		g_warning ("Failed to get discharges %s", error->message);
		return;
	}

	if (discharges_str)
		discharges_var = g_variant_parse (G_VARIANT_TYPE ("as"),
						  discharges_str,
						  NULL, NULL, NULL);
	if (discharges_var)
		discharges = g_variant_dup_strv (discharges_var, NULL);

	priv->auth_data = snapd_auth_data_new (macaroon, discharges);
}
Beispiel #9
0
/**
 * CacheEntryUnserialize:
 * @value: Serialized cache entry.
 * @error: (out)(allow-none): Error return location or #NULL.
 *
 * Returns: #CacheEntry instance with a reference count of one and attributes
 * filled in from parsing @value.
 */
CacheEntry *CacheEntryUnserialize(const gchar *value, GError **error) {
  GError *parse_error = NULL;
  GVariant *dict = NULL;
  CacheEntry *self = NULL;
  gint version = 0;
  const gchar *tmp_str = NULL;

  dict = g_variant_parse(
      G_VARIANT_TYPE_VARDICT, value, NULL, NULL, &parse_error);
  if (!dict) {
    g_assert(parse_error);
    g_set_error(error, CACHE_ENTRY_ERROR, CACHE_ENTRY_PARSE_ERROR,
                "Failed to parse cache entry: %s", parse_error->message);
    g_error_free(parse_error);
    return NULL;
  }


  g_variant_lookup(dict, "version", "i", &version);
  if (version != 1) {
    g_set_error(error, CACHE_ENTRY_ERROR, CACHE_ENTRY_PARSE_ERROR,
                "Entry version %d not supported", version);
    goto done;
  }

  // TODO(vonhollen): Check for all of the keys so we know each g_variant_lookup
  // will work, then add error handling to each CacheUtil*FromString() call.

  self = CacheEntryNew();
  g_variant_lookup(dict, "tries", "i", &self->tries);

  if (g_variant_lookup(dict, "algorithm", "&s", &tmp_str))
    CacheUtilHashalgFromString(tmp_str, &self->algorithm);

  if (g_variant_lookup(dict, "salt", "&s", &tmp_str))
    CacheUtilBytesFromString(tmp_str, &self->salt);
  if (g_variant_lookup(dict, "hash", "&s", &tmp_str))
    CacheUtilBytesFromString(tmp_str, &self->hash);

  if (g_variant_lookup(dict, "last_verified", "&s", &tmp_str))
    CacheUtilDatetimeFromString(tmp_str, &self->last_verified);
  if (g_variant_lookup(dict, "last_used", "&s", &tmp_str))
    CacheUtilDatetimeFromString(tmp_str, &self->last_used);
  if (g_variant_lookup(dict, "last_tried", "&s", &tmp_str))
    CacheUtilDatetimeFromString(tmp_str, &self->last_tried);

done:
  g_variant_unref(dict);
  return self;
}
Beispiel #10
0
/* DATA */
static void
_eventd_protocol_evp_parse_data(EventdProtocol *self, const gchar * const *argv, GError **error)
{
    GError *_inner_error_ = NULL;
    GVariant *value;

    value = g_variant_parse(NULL, argv[1], NULL, NULL, &_inner_error_);
    if ( value == NULL )
    {
        g_set_error(error, EVENTD_PROTOCOL_PARSE_ERROR, EVENTD_PROTOCOL_PARSE_ERROR_MALFORMED, "DATA content malformed: %s", _inner_error_->message);
        g_error_free(_inner_error_);
        return;
    }

    if ( self->data.hash == NULL )
        self->data.hash = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, (GDestroyNotify) g_variant_unref);
    g_hash_table_insert(self->data.hash, g_strdup(argv[0]), g_variant_ref_sink(value));
}
Beispiel #11
0
static gboolean
deserialize_secret (const char  *secret,
		    char       **token,
		    char       **token_secret)
{
	GVariant *variant;

	variant = g_variant_parse (NULL, secret, NULL, NULL, NULL);
	if (variant == NULL)
		return FALSE;

	if (token != NULL)
		g_variant_get_child (variant, 0, "ms", token, NULL);
	if (token_secret != NULL)
		g_variant_get_child (variant, 1, "ms", token_secret, NULL);

	g_variant_unref (variant);

	return TRUE;
}
Beispiel #12
0
static void
web_extension_form_auth_data_message_received_cb (WebKitUserContentManager *manager,
                                                  WebKitJavascriptResult *message,
                                                  EphyEmbedShell *shell)
{
  guint request_id;
  guint64 page_id;
  const char *hostname;
  const char *username;
  GVariant *variant;
  gchar *message_str;

  message_str = ephy_embed_utils_get_js_result_as_string (message);
  variant = g_variant_parse (G_VARIANT_TYPE ("(utss)"), message_str, NULL, NULL, NULL);
  g_free (message_str);

  g_variant_get (variant, "(ut&s&s)", &request_id, &page_id, &hostname, &username);
  g_signal_emit (shell, signals[FORM_AUTH_DATA_SAVE_REQUESTED], 0,
                 request_id, page_id, hostname, username);
  g_variant_unref (variant);
}
Beispiel #13
0
gboolean
ide_widget_action_with_string (GtkWidget   *widget,
                               const gchar *group,
                               const gchar *name,
                               const gchar *param)
{
  GVariant *variant = NULL;
  gboolean ret;

  IDE_ENTRY;

  g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
  g_return_val_if_fail (group != NULL, FALSE);
  g_return_val_if_fail (name != NULL, FALSE);

  if (param == NULL)
    param = "";

  if (*param != 0)
    {
      g_autoptr(GError) error = NULL;

      variant = g_variant_parse (NULL, param, NULL, NULL, &error);

      if (variant == NULL)
        {
          g_warning ("can't parse keybinding parameters \"%s\": %s",
                     param, error->message);
          IDE_RETURN (FALSE);
        }
    }

  ret = ide_widget_action (widget, group, name, variant);

  IDE_RETURN (ret);
}
Beispiel #14
0
static GVariant *
get_from_keyfile (GKeyfileSettingsBackend *kfsb,
                  const GVariantType      *type,
                  const gchar             *key)
{
  GVariant *return_value = NULL;
  gchar *group, *name;

  if (convert_path (kfsb, key, &group, &name))
    {
      gchar *str;
      gchar *sysstr;

      g_assert (*name);

      sysstr = g_key_file_get_value (kfsb->system_keyfile, group, name, NULL);
      str = g_key_file_get_value (kfsb->keyfile, group, name, NULL);
      if (sysstr &&
          (g_hash_table_contains (kfsb->system_locks, key) ||
           str == NULL))
        {
          g_free (str);
          str = g_steal_pointer (&sysstr);
        }

      if (str)
        {
          return_value = g_variant_parse (type, str, NULL, NULL, NULL);

          /* As a special case, support values of type %G_VARIANT_TYPE_STRING
           * not being quoted, since users keep forgetting to do it and then
           * getting confused. */
          if (return_value == NULL &&
              g_variant_type_equal (type, G_VARIANT_TYPE_STRING) &&
              str[0] != '\"')
            {
              GString *s = g_string_sized_new (strlen (str) + 2);
              char *p = str;

              g_string_append_c (s, '\"');
              while (*p)
                {
                  if (*p == '\"')
                    g_string_append_c (s, '\\');
                  g_string_append_c (s, *p);
                  p++;
                }
              g_string_append_c (s, '\"');
              return_value = g_variant_parse (type, s->str, NULL, NULL, NULL);
              g_string_free (s, TRUE);
            }
          g_free (str);
        }

      g_free (sysstr);

      g_free (group);
      g_free (name);
    }

  return return_value;
}
Beispiel #15
0
static void
start_element (GMarkupParseContext  *context,
               const gchar          *element_name,
               const gchar         **attribute_names,
               const gchar         **attribute_values,
               gpointer              user_data,
               GError              **error)
{
  ParseState *state = user_data;
  const GSList *element_stack;
  const gchar *container;

  element_stack = g_markup_parse_context_get_element_stack (context);
  container = element_stack->next ? element_stack->next->data : NULL;

#define COLLECT(first, ...) \
  g_markup_collect_attributes (element_name,                                 \
                               attribute_names, attribute_values, error,     \
                               first, __VA_ARGS__, G_MARKUP_COLLECT_INVALID)
#define OPTIONAL   G_MARKUP_COLLECT_OPTIONAL
#define STRDUP     G_MARKUP_COLLECT_STRDUP
#define STRING     G_MARKUP_COLLECT_STRING
#define NO_ATTRS()  COLLECT (G_MARKUP_COLLECT_INVALID, NULL)

  if (container == NULL)
    {
      if (strcmp (element_name, "schemalist") == 0)
        {
          COLLECT (OPTIONAL | STRDUP,
                   "gettext-domain",
                   &state->schemalist_domain);
          return;
        }
    }
  else if (strcmp (container, "schemalist") == 0)
    {
      if (strcmp (element_name, "schema") == 0)
        {
          const gchar *id, *path;

          if (COLLECT (STRING, "id", &id,
                       OPTIONAL | STRING, "path", &path,
                       OPTIONAL | STRDUP, "gettext-domain",
                                          &state->schema_domain))
            {
              if (!g_hash_table_lookup (state->schemas, id))
                {
                  state->schema = gvdb_hash_table_new (state->schemas, id);
                  state->schema_root = gvdb_hash_table_insert (state->schema, "");

                  if (path != NULL)
                    gvdb_hash_table_insert_string (state->schema,
                                                   ".path", path);
                }
              else
                g_set_error (error, G_MARKUP_ERROR,
                             G_MARKUP_ERROR_INVALID_CONTENT,
                             "<schema id='%s'> already specified", id);
            }
          return;
        }
    }
  else if (strcmp (container, "schema") == 0)
    {
      if (strcmp (element_name, "key") == 0)
        {
          const gchar *name, *type;

          if (COLLECT (STRING, "name", &name, STRING, "type", &type))
            {
              if (!is_valid_keyname (name, error))
                return;

              if (!g_hash_table_lookup (state->schema, name))
                {
                  state->key = gvdb_hash_table_insert (state->schema, name);
                  gvdb_item_set_parent (state->key, state->schema_root);
                }
              else
                {
                  g_set_error (error, G_MARKUP_ERROR,
                               G_MARKUP_ERROR_INVALID_CONTENT,
                               "<key name='%s'> already specified", name);
                  return;
                }

              if (g_variant_type_string_is_valid (type))
                state->type = g_variant_type_new (type);
              else
                {
                  g_set_error (error, G_MARKUP_ERROR,
                               G_MARKUP_ERROR_INVALID_CONTENT,
                               "invalid GVariant type string '%s'", type);
                  return;
                }

              g_variant_builder_init (&state->key_options,
                                      G_VARIANT_TYPE ("a{sv}"));
            }

          return;
        }
      else if (strcmp (element_name, "child") == 0)
        {
          const gchar *name, *schema;

          if (COLLECT (STRING, "name", &name, STRING, "schema", &schema))
            {
              gchar *childname;

              if (!is_valid_keyname (name, error))
                return;

              childname = g_strconcat (name, "/", NULL);

              if (!g_hash_table_lookup (state->schema, childname))
                gvdb_hash_table_insert_string (state->schema, childname, schema);
              else
                g_set_error (error, G_MARKUP_ERROR,
                             G_MARKUP_ERROR_INVALID_CONTENT,
                             "<child name='%s'> already specified", name);

              g_free (childname);
              return;
            }
        }
    }
  else if (strcmp (container, "key") == 0)
    {
      if (strcmp (element_name, "default") == 0)
        {
          const gchar *l10n;

          if (COLLECT (STRING | OPTIONAL, "l10n", &l10n,
                       STRDUP | OPTIONAL, "context", &state->context))
            {
              if (l10n != NULL)
                {
                  if (!g_hash_table_lookup (state->schema, ".gettext-domain"))
                    {
                      const gchar *domain = state->schema_domain ?
                                            state->schema_domain :
                                            state->schemalist_domain;

                      if (domain == NULL)
                        {
                          g_set_error_literal (error, G_MARKUP_ERROR,
                                               G_MARKUP_ERROR_INVALID_CONTENT,
                                               "l10n requested, but no "
                                               "gettext domain given");
                          return;
                        }

                      gvdb_hash_table_insert_string (state->schema,
                                                     ".gettext-domain",
                                                     domain);

                      if (strcmp (l10n, "messages") == 0)
                        state->l10n = 'm';
                      else if (strcmp (l10n, "time") == 0)
                        state->l10n = 't';
                      else
                        {
                          g_set_error (error, G_MARKUP_ERROR,
                                       G_MARKUP_ERROR_INVALID_CONTENT,
                                       "unsupported l10n category: %s", l10n);
                          return;
                        }
                    }
                }
              else
                {
                  state->l10n = '\0';

                  if (state->context != NULL)
                    {
                      g_set_error_literal (error, G_MARKUP_ERROR,
                                           G_MARKUP_ERROR_INVALID_CONTENT,
                                           "translation context given for "
                                           " value without l10n enabled");
                      return;
                    }
                }

              state->string = g_string_new (NULL);
            }

          return;
        }
      else if (strcmp (element_name, "summary") == 0 ||
               strcmp (element_name, "description") == 0)
        {
          state->string = g_string_new (NULL);
          NO_ATTRS ();
          return;
        }
      else if (strcmp (element_name, "range") == 0)
        {
          const gchar *min_str, *max_str;

          if (!type_allows_range (state->type))
            {
              gchar *type = g_variant_type_dup_string (state->type);
              g_set_error (error, G_MARKUP_ERROR,
                          G_MARKUP_ERROR_INVALID_CONTENT,
                          "Element <%s> not allowed for keys of type \"%s\"\n",
                          element_name, type);
              g_free (type);
              return;
            }

          if (!COLLECT (STRING, "min", &min_str,
                        STRING, "max", &max_str))
            return;

          state->min = g_variant_parse (state->type, min_str, NULL, NULL, error);
          if (state->min == NULL)
            return;

          state->max = g_variant_parse (state->type, max_str, NULL, NULL, error);
          if (state->max == NULL)
            return;

          if (g_variant_compare (state->min, state->max) > 0)
            {
              g_set_error (error, G_MARKUP_ERROR,
                           G_MARKUP_ERROR_INVALID_CONTENT,
                           "Element <%s> specified minimum is greater than maxmimum",
                           element_name);
              return;
            }

          g_variant_builder_add (&state->key_options, "{sv}", "range",
                                 g_variant_new ("(@?@?)", state->min, state->max));
          return;
        }
      else if (strcmp (element_name, "choices") == 0)
        {
          if (!type_allows_choices (state->type))
            {
              gchar *type = g_variant_type_dup_string (state->type);
              g_set_error (error, G_MARKUP_ERROR,
                           G_MARKUP_ERROR_INVALID_CONTENT,
                           "Element <%s> not allowed for keys of type \"%s\"\n",
                           element_name, type);
              g_free (type);
              return;
            }

          state->choices = g_string_new ("\xff");

          NO_ATTRS ();
          return;
        }
    }
  else if (strcmp (container, "choices") == 0)
    {
      if (strcmp (element_name, "choice") == 0)
        {
          const gchar *value;

          if (COLLECT (STRING, "value", &value))
            g_string_append_printf (state->choices, "%s\xff", value);

          return;
        }
    }

  if (container)
    g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_UNKNOWN_ELEMENT,
                 "Element <%s> not allowed inside <%s>\n",
                 element_name, container);
  else
    g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_UNKNOWN_ELEMENT,
                 "Element <%s> not allowed at toplevel\n", element_name);
}
Beispiel #16
0
static void
end_element (GMarkupParseContext  *context,
             const gchar          *element_name,
             gpointer              user_data,
             GError              **error)
{
  ParseState *state = user_data;

  if (strcmp (element_name, "default") == 0)
    {
      state->value = g_variant_parse (state->type, state->string->str,
                                      NULL, NULL, error);
      if (state->value == NULL)
        return;

      if (state->l10n)
        {
          if (state->context)
            {
              gint len;

              /* Contextified messages are supported by prepending the
               * context, followed by '\004' to the start of the message
               * string.  We do that here to save GSettings the work
               * later on.
               *
               * Note: we are about to g_free() the context anyway...
               */
              len = strlen (state->context);
              state->context[len] = '\004';
              g_string_prepend_len (state->string, state->context, len + 1);
            }

          g_variant_builder_add (&state->key_options, "{sv}", "l10n",
                                 g_variant_new ("(ys)",
                                                state->l10n,
                                                state->string->str));
        }

      g_string_free (state->string, TRUE);
      state->string = NULL;
      g_free (state->context);
      state->context = NULL;
    }

  else if (strcmp (element_name, "key") == 0)
    {
      if (state->value == NULL)
        {
          g_set_error_literal (error,
                               G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT,
                               "element <default> is required in <key>\n");
          return;
        }

      if (state->min != NULL)
        {
          if (g_variant_compare (state->value, state->min) < 0 ||
              g_variant_compare (state->value, state->max) > 0)
            {
              g_set_error (error, G_MARKUP_ERROR,
                           G_MARKUP_ERROR_INVALID_CONTENT,
                           "<default> is not contained in the specified range");
              return;
            }

          state->min = state->max = NULL;
        }
      else if (state->choices != NULL)
        {
          if (!is_valid_choices (state->value, state->choices->str))
            {
              g_set_error_literal (error, G_MARKUP_ERROR,
                                   G_MARKUP_ERROR_INVALID_CONTENT,
                                   "<default> contains string not in <choices>");
              return;
            }

          state->choices = NULL;
        }

      gvdb_item_set_value (state->key, state->value);
      gvdb_item_set_options (state->key,
                             g_variant_builder_end (&state->key_options));

      state->value = NULL;
    }

  else if (strcmp (element_name, "summary") == 0 ||
           strcmp (element_name, "description") == 0)
    {
      g_string_free (state->string, TRUE);
      state->string = NULL;
    }

  else if (strcmp (element_name, "choices") == 0)
    {
      gchar *choices;

      choices = g_string_free (state->choices, FALSE);
      g_variant_builder_add (&state->key_options, "{sv}", "choices",
                             g_variant_new_byte_array (choices, -1));
      g_free (choices);
    }
}
Beispiel #17
0
void
_rb_add_display_page_actions (GActionMap *map, GObject *shell, const GActionEntry *actions, gint n_entries)
{
	int i;
	for (i = 0; i < n_entries; i++) {
		GSimpleAction *action;
		const GVariantType *parameter_type;
		DisplayPageActionData *page_action_data;

		if (g_action_map_lookup_action (map, actions[i].name) != NULL) {
			/* action was already added */
			continue;
		}

		if (actions[i].parameter_type) {
			parameter_type = G_VARIANT_TYPE (actions[i].parameter_type);
		} else {
			parameter_type = NULL;
		}

		if (actions[i].state) {
			GVariant *state;
			GError *error = NULL;
			state = g_variant_parse (NULL, actions[i].state, NULL, NULL, &error);
			if (state == NULL) {
				g_critical ("could not parse state value '%s' for action "
					    "%s: %s",
					    actions[i].state, actions[i].name, error->message);
				g_error_free (error);
				continue;
			}
			action = g_simple_action_new_stateful (actions[i].name,
							       parameter_type,
							       state);
		} else {
			action = g_simple_action_new (actions[i].name, parameter_type);
		}

		if (actions[i].activate) {
			GClosure *closure;
			page_action_data = g_slice_new0 (DisplayPageActionData);
			page_action_data->u.gaction = (DisplayPageActionActivateCallback) actions[i].activate;
			page_action_data->shell = shell;
			g_object_add_weak_pointer (shell, &page_action_data->shell);

			closure = g_cclosure_new (G_CALLBACK (display_page_action_activate_cb),
						  page_action_data,
						  (GClosureNotify) display_page_action_data_destroy);
			g_signal_connect_closure (action, "activate", closure, FALSE);
		}

		if (actions[i].change_state) {
			GClosure *closure;
			page_action_data = g_slice_new0 (DisplayPageActionData);
			page_action_data->u.gactionstate = (DisplayPageActionChangeStateCallback) actions[i].change_state;
			page_action_data->shell = shell;
			g_object_add_weak_pointer (shell, &page_action_data->shell);

			closure = g_cclosure_new (G_CALLBACK (display_page_action_change_state_cb),
						  page_action_data,
						  (GClosureNotify) display_page_action_data_destroy);
			g_signal_connect_closure (action, "change-state", closure, FALSE);
		}

		g_action_map_add_action (map, G_ACTION (action));
		g_object_unref (action);
	}
}
Beispiel #18
0
/**
 * g_action_parse_detailed_name:
 * @detailed_name: a detailed action name
 * @action_name: (out): the action name
 * @target_value: (out): the target value, or %NULL for no target
 * @error: a pointer to a %NULL #GError, or %NULL
 *
 * Parses a detailed action name into its separate name and target
 * components.
 *
 * Detailed action names can have three formats.
 *
 * The first format is used to represent an action name with no target
 * value and consists of just an action name containing no whitespace
 * nor the characters ':', '(' or ')'.  For example: "app.action".
 *
 * The second format is used to represent an action with a target value
 * that is a non-empty string consisting only of alphanumerics, plus '-'
 * and '.'.  In that case, the action name and target value are
 * separated by a double colon ("::").  For example:
 * "app.action::target".
 *
 * The third format is used to represent an action with any type of
 * target value, including strings.  The target value follows the action
 * name, surrounded in parens.  For example: "app.action(42)".  The
 * target value is parsed using g_variant_parse().  If a tuple-typed
 * value is desired, it must be specified in the same way, resulting in
 * two sets of parens, for example: "app.action((1,2,3))".  A string
 * target can be specified this way as well: "app.action('target')".
 * For strings, this third format must be used if * target value is
 * empty or contains characters other than alphanumerics, '-' and '.'.
 *
 * Returns: %TRUE if successful, else %FALSE with @error set
 *
 * Since: 2.38
 **/
gboolean
g_action_parse_detailed_name (const gchar  *detailed_name,
                              gchar       **action_name,
                              GVariant    **target_value,
                              GError      **error)
{
  const gchar *target;
  gsize target_len;
  gsize base_len;

  /* For historical (compatibility) reasons, this function accepts some
   * cases of invalid action names as long as they don't interfere with
   * the separation of the action from the target value.
   *
   * We decide which format we have based on which we see first between
   * '::' '(' and '\0'.
   */

  if (*detailed_name == '\0' || *detailed_name == ' ')
    goto bad_fmt;

  base_len = strcspn (detailed_name, ": ()");
  target = detailed_name + base_len;
  target_len = strlen (target);

  switch (target[0])
    {
    case ' ':
    case ')':
      goto bad_fmt;

    case ':':
      if (target[1] != ':')
        goto bad_fmt;

      *target_value = g_variant_ref_sink (g_variant_new_string (target + 2));
      break;

    case '(':
      {
        if (target[target_len - 1] != ')')
          goto bad_fmt;

        *target_value = g_variant_parse (NULL, target + 1, target + target_len - 1, NULL, error);
        if (*target_value == NULL)
          goto bad_fmt;
      }
      break;

    case '\0':
      *target_value = NULL;
      break;
    }

  *action_name = g_strndup (detailed_name, base_len);

  return TRUE;

bad_fmt:
  if (error)
    {
      if (*error == NULL)
        g_set_error (error, G_VARIANT_PARSE_ERROR, G_VARIANT_PARSE_ERROR_FAILED,
                     "Detailed action name '%s' has invalid format", detailed_name);
      else
        g_prefix_error (error, "Detailed action name '%s' has invalid format: ", detailed_name);
    }

  return FALSE;
}
Beispiel #19
0
static gboolean
check_gsettings_condition (NemoAction *action, const gchar *condition)
{

    gchar **split = g_strsplit (condition, " ", 6);
    gint len = g_strv_length (split);

    if (len != 6 && 
        len != 3) {
        g_strfreev (split);
        return FALSE;
    }

    if (g_strcmp0 (split[0], "gsettings") != 0) {
        g_strfreev (split);
        return FALSE;
    }

    if (len == 6 &&
        (!g_variant_type_string_is_valid (split[GSETTINGS_TYPE_INDEX]) || 
         !operator_is_valid (split[GSETTINGS_OP_INDEX]))) {
        g_printerr ("Nemo Action: Either gsettings variant type (%s) or operator (%s) is invalid.\n",
                    split[GSETTINGS_TYPE_INDEX], split[GSETTINGS_OP_INDEX]);
        g_strfreev (split);
        return FALSE;
    }

    GSettingsSchemaSource *schema_source;
    gboolean ret = FALSE;
    const GVariantType *target_type;

    if (len == 3) {
        target_type = G_VARIANT_TYPE_BOOLEAN;
    } else {
        target_type = G_VARIANT_TYPE (split[GSETTINGS_TYPE_INDEX]);
    }

    schema_source = g_settings_schema_source_get_default();

    if (g_settings_schema_source_lookup (schema_source, split[GSETTINGS_SCHEMA_INDEX], TRUE)) {
        GSettings *s = g_settings_new (split[GSETTINGS_SCHEMA_INDEX]);
        gchar **keys = g_settings_list_keys (s);
        gint i;
        for (i = 0; i < g_strv_length (keys); i++) {
            if (len == 3) {
                if (g_strcmp0 (keys[i], split[GSETTINGS_KEY_INDEX]) == 0) {
                    GVariant *setting_var = g_settings_get_value (s, split[GSETTINGS_KEY_INDEX]);
                    const GVariantType *setting_type = g_variant_get_type (setting_var);
                    if (g_variant_type_equal (setting_type, target_type))
                        ret = g_variant_get_boolean (setting_var);
                    g_variant_unref (setting_var);
                }
            } else {
                if (g_strcmp0 (keys[i], split[GSETTINGS_KEY_INDEX]) == 0) {
                    GVariant *setting_var = g_settings_get_value (s, split[GSETTINGS_KEY_INDEX]);
                    const GVariantType *setting_type = g_variant_get_type (setting_var);
                    if (g_variant_type_equal (setting_type, target_type)) {
                        GVariant *target_var = g_variant_parse (target_type,
                                                                split[GSETTINGS_VAL_INDEX],
                                                                NULL, NULL, NULL);
                        if (target_var != NULL) {
                            gint vector = g_variant_compare (setting_var, target_var);
                            ret = try_vector (split[GSETTINGS_OP_INDEX], vector);
                            g_variant_unref (target_var);
                        } else {
                            g_printerr ("Nemo Action: gsettings value could not be parsed into a valid GVariant\n");
                        }
                    }
                    g_variant_unref (setting_var);
                }
            }
        }
        g_strfreev (keys);
        g_object_unref (s);
        g_strfreev (split);
        return ret;
    } else {
        g_strfreev (split);
        return FALSE;
    }
}
static gboolean
panel_layout_maybe_append_object_instance_config (GKeyFile    *keyfile,
                                                  const char  *group,
                                                  const char  *key,
                                                  const char  *path_prefix,
                                                  const char  *unique_id,
                                                  gboolean     dry_run,
                                                  gboolean    *key_handled,
                                                  GError     **error)
{
        char       *value_str;
        const char *keyname;
        GVariant   *variant;

        *key_handled = FALSE;

        if (!g_str_has_prefix(key, PANEL_LAYOUT_INSTANCE_CONFIG_SUBPATH))
                return TRUE;

        *key_handled = TRUE;

        value_str = g_key_file_get_string (
                                keyfile,
                                group, key,
                                error);
        if (!value_str)
                return FALSE;

        variant = g_variant_parse (NULL, value_str,
                                   NULL, NULL, error);

        if (!variant) {
                g_free (value_str);
                return FALSE;
        }

        keyname = key + strlen (PANEL_LAYOUT_INSTANCE_CONFIG_SUBPATH);

        if (dry_run) {
                /* the key can actually be in a subdirectory
                 * like instance-config/foo/key, so we split
                 * the tokens to validate all of them */
                char **tokens;
                char **token;

                tokens = g_strsplit (keyname, "/", -1);

                for (token = tokens; *token; token++) {
                        if (!panel_gsettings_is_valid_keyname (*token,
                                                               error)) {
                                g_strfreev (tokens);
                                g_variant_unref (variant);
                                g_free (value_str);
                                return FALSE;
                        }
                }

                g_strfreev (tokens);
        } else {
                char *key;

                key = g_strdup_printf ("%s%s/%s%s",
                                       path_prefix, unique_id,
                                       PANEL_LAYOUT_OBJECT_CONFIG_SUFFIX,
                                       keyname);
                panel_dconf_write_sync (key, variant, NULL);
                g_free (key);
        }

        g_variant_unref (variant);
        g_free (value_str);

        return TRUE;
}
GVariant *
goa_utils_lookup_credentials_sync (GoaProvider   *provider,
                                   GoaObject     *object,
                                   GCancellable  *cancellable,
                                   GError       **error)
{
  gchar *password_key;
  GVariant *ret;
  gchar *password;
  const gchar *id;
  GError *sec_error = NULL;

  g_return_val_if_fail (GOA_IS_PROVIDER (provider), NULL);
  g_return_val_if_fail (GOA_IS_OBJECT (object) && goa_object_peek_account (object) != NULL, FALSE);
  g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), NULL);
  g_return_val_if_fail (error == NULL || *error == NULL, NULL);

  ret = NULL;
  password_key = NULL;
  password = NULL;

  id = goa_account_get_id (goa_object_peek_account (object));

  password_key = g_strdup_printf ("%s:gen%d:%s",
                                  goa_provider_get_provider_type (GOA_PROVIDER (provider)),
                                  goa_provider_get_credentials_generation (GOA_PROVIDER (provider)),
                                  id);

  password = secret_password_lookup_sync (&secret_password_schema,
                                          cancellable,
                                          &sec_error,
                                          "goa-identity", password_key,
                                          NULL);
  if (sec_error != NULL)
    {
      g_warning ("secret_password_lookup_sync() failed: %s", sec_error->message);
      g_set_error_literal (error,
                           GOA_ERROR,
                           GOA_ERROR_FAILED, /* TODO: more specific */
                           _("Failed to retrieve credentials from the keyring"));
      g_error_free (sec_error);
      goto out;
    }
  else if (password == NULL)
    {
      g_warning ("secret_password_lookup_sync() returned NULL");
      g_set_error_literal (error,
                           GOA_ERROR,
                           GOA_ERROR_FAILED, /* TODO: more specific */
                           _("No credentials found in the keyring"));
      goto out;
    }

  g_debug ("Retrieved keyring credentials for id: %s", id);

  ret = g_variant_parse (NULL, /* GVariantType */
                         password,
                         NULL, /* limit */
                         NULL, /* endptr */
                         error);
  if (ret == NULL)
    {
      g_prefix_error (error, _("Error parsing result obtained from the keyring: "));
      goto out;
    }

  if (g_variant_is_floating (ret))
    g_variant_ref_sink (ret);

 out:
  g_free (password);
  g_free (password_key);
  return ret;
}
Beispiel #22
0
static void
_eventd_events_parse_group(EventdEvents *self, const gchar *group, GKeyFile *config_file)
{
    gchar *name = NULL;

    const gchar *id, *s;
    id = group + strlen("Event ");
    if ( ( s = g_utf8_strchr(id, -1, ' ') ) != NULL )
    {
        const gchar *e = s;
        s = g_utf8_next_char(s);
        gunichar c = g_utf8_get_char(s);
        if ( c == '*' )
        {
            c = g_utf8_get_char(g_utf8_next_char(s));
            if ( ( c != ' ' ) && ( c != '\0' ) )
            {
                g_warning("Wrong event specification '%s': * should be alone", id);
                return;
            }
            name = g_strndup(id, e - id);
        }
        else if ( ( s = g_utf8_strchr(g_utf8_next_char(s), -1, ' ') ) != NULL )
            name = g_strndup(id, s - id);
        else
            name = g_strdup(id);
    }
    else
        name = g_strdup(id);
    g_strstrip(name);

    gboolean disable = FALSE;

    if ( ( evhelpers_config_key_file_get_boolean(config_file, group, "Disable", &disable) < 0 ) || disable )
        goto fail;

    gchar **actions = NULL;

    if ( evhelpers_config_key_file_get_string_list(config_file, group, "Actions", &actions, NULL) < 0 )
        goto fail;

    eventd_debug("Parsing event: %s", id);

    EventdEventsEvent *event;
    event = g_new0(EventdEventsEvent, 1);

    if ( actions != NULL )
    {
        gchar **action;
        for ( action = actions ; *action != NULL ; ++action )
            event->actions = g_list_prepend(event->actions, *action);
        g_free(actions);
    }


    gchar **if_data;
    gchar **if_data_matches;
    gchar **if_data_regexes;
    gchar **flags;
    gsize length;

    if ( evhelpers_config_key_file_get_string_list(config_file, group, "IfData", &if_data, NULL) == 0 )
        event->if_data = if_data;

    if ( evhelpers_config_key_file_get_string_list(config_file, group, "IfDataMatches", &if_data_matches, &length) == 0 )
    {
        gchar **if_data_match;
        EventdEventsEventDataMatch *match;
        gchar *tmp, *data, *key = NULL, *operator, *value_;
        gint accepted[2];
        GVariant *value;
        GError *error = NULL;

        event->if_data_matches = g_new0(EventdEventsEventDataMatch, length + 1);
        match = event->if_data_matches;

        for ( if_data_match = if_data_matches ; *if_data_match != NULL ; ++if_data_match )
        {
            data = *if_data_match;
            tmp = g_utf8_strchr(data, -1, ',');
            if ( tmp == NULL )
            {
                g_warning("Data matches must be of the form 'data-name,operator,value'");
                g_free(data);
                continue;
            }
            operator = g_utf8_next_char(tmp);
            *tmp = '\0';

            tmp = g_utf8_strchr(data, -1, '[');
            if ( tmp != NULL )
            {
                key = g_utf8_next_char(tmp);
                *tmp = '\0';
                tmp = g_utf8_strchr(key, -1, ']');
                if ( ( tmp == NULL ) || ( g_utf8_get_char(g_utf8_next_char(tmp)) != '\0' ) )
                {
                    g_warning("Data matches must be of the form 'data-name[key],operator,value'");
                    g_free(data);
                    continue;
                }
                *tmp = '\0';
            }

            tmp = g_utf8_strchr(operator, -1, ',');
            if ( tmp == NULL )
            {
                g_warning("Data matches must be of the form 'data-name,operator,value'");
                g_free(data);
                continue;
            }
            value_ = g_utf8_next_char(tmp);
            *tmp = '\0';

            gsize l = g_utf8_strlen(operator, -1);
            if ( ( l > 2 ) || ( l < 1 ) )
            {
                g_warning("Unsupported operator: %s", operator);
                g_free(data);
                continue;
            }
            accepted[0] = -2;
            switch ( g_utf8_get_char(g_utf8_next_char(operator)) )
            {
            case '=':
                accepted[1] = 0;
                switch ( g_utf8_get_char(operator) )
                {
                case '<':
                    accepted[0] = -1;
                break;
                case '>':
                    accepted[0] = 1;
                break;
                case '=':
                    accepted[0] = 0;
                break;
                case '!':
                    accepted[0] = -1;
                    accepted[1] = 1;
                break;
                }
            break;
            case '\0':
                switch ( g_utf8_get_char(operator) )
                {
                case '<':
                    accepted[0] = accepted[1] = -1;
                break;
                case '>':
                    accepted[0] = accepted[1] = 1;
                break;
                }
            }
            if ( accepted[0] == -2 )
            {
                g_warning("Unsupported operator: %s", operator);
                g_free(data);
                continue;
            }

            value = g_variant_parse(NULL, value_, NULL, NULL, &error);
            if ( value == NULL )
            {
                g_warning("Could not parse variant '%s': %s", value_, error->message);
                g_clear_error(&error);
                g_free(data);
                continue;
            }

            match->data = data;
            match->key = key;
            match->accepted[0] = accepted[0];
            match->accepted[1] = accepted[1];
            match->value = value;
            ++match;
        }
        match->data = NULL;
        g_free(if_data_matches);
    }

    if ( evhelpers_config_key_file_get_string_list(config_file, group, "IfDataRegex", &if_data_regexes, &length) == 0 )
    {
        gchar **if_data_regex;
        EventdEventsEventDataRegex *match;
        gchar *data, *regex_;
        GError *error = NULL;
        GRegex *regex;

        event->if_data_regexes = g_new0(EventdEventsEventDataRegex, length + 1);
        match = event->if_data_regexes;

        for ( if_data_regex = if_data_regexes ; *if_data_regex != NULL ; ++if_data_regex )
        {
            data = *if_data_regex;
            regex_ = g_utf8_strchr(data, -1, ',');
            if ( regex_ == NULL )
            {
                g_warning("Data matches must be of the form 'data-name,regex'");
                g_free(data);
                continue;
            }
            *regex_ = '\0';
            ++regex_;

            regex = g_regex_new(regex_, G_REGEX_OPTIMIZE, 0, &error);
            if ( regex == NULL )
            {
                g_warning("Could not compile regex '%s': %s", regex_, error->message);
                g_clear_error(&error);
                g_free(data);
                continue;
            }

            match->data = data;
            match->regex = regex;
            ++match;
        }
        match->data = NULL;
        g_free(if_data_regexes);
    }

    if ( evhelpers_config_key_file_get_string_list(config_file, group, "OnlyIfFlags", &flags, &length) == 0 )
        event->flags_whitelist = _eventd_events_parse_event_flags(flags, length);

    if ( evhelpers_config_key_file_get_string_list(config_file, group, "NotIfFlags", &flags, &length) == 0 )
        event->flags_blacklist = _eventd_events_parse_event_flags(flags, length);

    gint64 default_importance, importance;

    if ( ( event->if_data != NULL ) || ( event->if_data_matches != NULL ) || ( event->if_data_regexes != NULL ) || ( event->flags_whitelist != NULL ) || ( event->flags_blacklist != NULL ) )
        default_importance = 0;
    else
        default_importance = G_MAXINT64;
    if ( evhelpers_config_key_file_get_int_with_default(config_file, group, "Importance", default_importance, &importance) >= 0 )
        event->importance = importance;

    GList *list = NULL;
    gchar *old_key = NULL;
    g_hash_table_lookup_extended(self->events, name, (gpointer *)&old_key, (gpointer *)&list);
    g_hash_table_steal(self->events, name);
    g_free(old_key);
    list = g_list_insert_sorted(list, event, _eventd_events_compare_event);
    g_hash_table_insert(self->events, name, list);
    name = NULL;

fail:
    g_free(name);
}
static void testWebContextSecurityFileXHR(WebViewTest* test, gconstpointer)
{
    GUniquePtr<char> fileURL(g_strdup_printf("file://%s/simple.html", Test::getResourcesDir(Test::WebKit2Resources).data()));
    test->loadURI(fileURL.get());
    test->waitUntilLoadFinished();

    GUniquePtr<char> jsonURL(g_strdup_printf("file://%s/simple.json", Test::getResourcesDir().data()));
    GUniquePtr<char> xhr(g_strdup_printf("var xhr = new XMLHttpRequest; xhr.open(\"GET\", \"%s\"); xhr.send();", jsonURL.get()));

    WebKitJavascriptResult* consoleMessage = nullptr;
    webkit_user_content_manager_register_script_message_handler(test->m_userContentManager.get(), "console");
    g_signal_connect(test->m_userContentManager.get(), "script-message-received::console", G_CALLBACK(consoleMessageReceivedCallback), &consoleMessage);

    // By default file access is not allowed, this will show a console message with a cross-origin error.
    GUniqueOutPtr<GError> error;
    WebKitJavascriptResult* javascriptResult = test->runJavaScriptAndWaitUntilFinished(xhr.get(), &error.outPtr());
    g_assert(javascriptResult);
    g_assert(!error);
    g_assert(consoleMessage);
    GUniquePtr<char> messageString(WebViewTest::javascriptResultToCString(consoleMessage));
    GRefPtr<GVariant> variant = g_variant_parse(G_VARIANT_TYPE("(uusus)"), messageString.get(), nullptr, nullptr, nullptr);
    g_assert(variant.get());
    unsigned level;
    const char* messageText;
    g_variant_get(variant.get(), "(uu&su&s)", nullptr, &level, &messageText, nullptr, nullptr);
    g_assert_cmpuint(level, ==, 3); // Console error message.
    GUniquePtr<char> expectedErrorMessage(g_strdup_printf("XMLHttpRequest cannot load %s. Cross origin requests are only supported for HTTP.", jsonURL.get()));
    g_assert_cmpstr(messageText, ==, expectedErrorMessage.get());
    webkit_javascript_result_unref(consoleMessage);
    consoleMessage = nullptr;
    level = 0;
    messageText = nullptr;
    variant = nullptr;

    // Allow file access from file URLs.
    webkit_settings_set_allow_file_access_from_file_urls(webkit_web_view_get_settings(test->m_webView), TRUE);
    test->loadURI(fileURL.get());
    test->waitUntilLoadFinished();
    javascriptResult = test->runJavaScriptAndWaitUntilFinished(xhr.get(), &error.outPtr());
    g_assert(javascriptResult);
    g_assert(!error);

    // It isn't still possible to load file from an HTTP URL.
    test->loadURI(kServer->getURIForPath("/").data());
    test->waitUntilLoadFinished();
    javascriptResult = test->runJavaScriptAndWaitUntilFinished(xhr.get(), &error.outPtr());
    g_assert(javascriptResult);
    g_assert(!error);
    g_assert(consoleMessage);
    variant = g_variant_parse(G_VARIANT_TYPE("(uusus)"), messageString.get(), nullptr, nullptr, nullptr);
    g_assert(variant.get());
    g_variant_get(variant.get(), "(uu&su&s)", nullptr, &level, &messageText, nullptr, nullptr);
    g_assert_cmpuint(level, ==, 3); // Console error message.
    g_assert_cmpstr(messageText, ==, expectedErrorMessage.get());
    webkit_javascript_result_unref(consoleMessage);

    g_signal_handlers_disconnect_matched(test->m_userContentManager.get(), G_SIGNAL_MATCH_DATA, 0, 0, nullptr, nullptr, &consoleMessage);
    webkit_user_content_manager_unregister_script_message_handler(test->m_userContentManager.get(), "console");

    webkit_settings_set_allow_file_access_from_file_urls(webkit_web_view_get_settings(test->m_webView), FALSE);
}