static GVariant * parse_json_with_sig (JsonObject *object, GError **error) { GVariantType *inner_type; GVariant *inner; JsonNode *val; const gchar *sig; val = json_object_get_member (object, "val"); if (val == NULL) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA, "JSON did not contain a 'val' field"); return NULL; } if (!cockpit_json_get_string (object, "sig", NULL, &sig) || !sig) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA, "JSON did not contain valid 'sig' fields"); return NULL; } if (!g_variant_type_string_is_valid (sig)) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_DATA, "JSON 'sig' field '%s' is invalid", sig); return NULL; } inner_type = g_variant_type_new (sig); inner = parse_json (val, inner_type, error); g_variant_type_free (inner_type); if (!inner) return NULL; return g_variant_new_variant (inner); }
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); }
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; } }