summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Hughes <richard@hughsie.com>2014-04-08 12:30:08 +0100
committerRichard Hughes <richard@hughsie.com>2014-04-08 12:31:20 +0100
commit365dade7b7d14fdb1d0ef358a1d6a6ff27a492e2 (patch)
tree78b98e4c1715c173676616317f963153ac93667f
parentd491d8809183d5930e6ae87ce32859f60a5712bf (diff)
downloadappstream-glib-365dade7b7d14fdb1d0ef358a1d6a6ff27a492e2.tar.gz
Load AppStream files assuming literal text strings
AppStream is a 'destination' format, so we don't want to try to parse the text data and reassemble strings and strip leading whitespace. However, as AsNode is used by AppData too (a source format) we just need to add a new flag to make this configurable.
-rw-r--r--libappstream-glib/as-node.c60
-rw-r--r--libappstream-glib/as-node.h2
-rw-r--r--libappstream-glib/as-self-test.c9
-rw-r--r--libappstream-glib/as-store.c4
4 files changed, 46 insertions, 29 deletions
diff --git a/libappstream-glib/as-node.c b/libappstream-glib/as-node.c
index 2a531f1..c8d6a6e 100644
--- a/libappstream-glib/as-node.c
+++ b/libappstream-glib/as-node.c
@@ -370,6 +370,11 @@ as_node_to_xml_string (GString *xml,
}
}
+typedef struct {
+ GNode *current;
+ AsNodeFromXmlFlags flags;
+} AsNodeToXmlHelper;
+
/**
* as_node_to_xml:
* @node: a #GNode.
@@ -398,13 +403,13 @@ as_node_to_xml (const GNode *node, AsNodeToXmlFlags flags)
**/
static void
as_node_start_element_cb (GMarkupParseContext *context,
- const gchar *element_name,
- const gchar **attribute_names,
- const gchar **attribute_values,
- gpointer user_data,
- GError **error)
+ const gchar *element_name,
+ const gchar **attribute_names,
+ const gchar **attribute_values,
+ gpointer user_data,
+ GError **error)
{
- GNode **current = (GNode **) user_data;
+ AsNodeToXmlHelper *helper = (AsNodeToXmlHelper *) user_data;
AsNodeData *data;
guint i;
@@ -418,7 +423,7 @@ as_node_start_element_cb (GMarkupParseContext *context,
}
/* add the node to the DOM */
- *current = g_node_append_data (*current, data);
+ helper->current = g_node_append_data (helper->current, data);
}
/**
@@ -426,12 +431,12 @@ as_node_start_element_cb (GMarkupParseContext *context,
**/
static void
as_node_end_element_cb (GMarkupParseContext *context,
- const gchar *element_name,
- gpointer user_data,
- GError **error)
+ const gchar *element_name,
+ gpointer user_data,
+ GError **error)
{
- GNode **current = (GNode **) user_data;
- (*current) = (*current)->parent;
+ AsNodeToXmlHelper *helper = (AsNodeToXmlHelper *) user_data;
+ helper->current = helper->current->parent;
}
/**
@@ -444,7 +449,7 @@ as_node_text_cb (GMarkupParseContext *context,
gpointer user_data,
GError **error)
{
- GNode **current = (GNode **) user_data;
+ AsNodeToXmlHelper *helper = (AsNodeToXmlHelper *) user_data;
AsNodeData *data;
guint i;
gchar **split;
@@ -462,10 +467,11 @@ as_node_text_cb (GMarkupParseContext *context,
return;
/* save cdata */
- data = (*current)->data;
+ data = helper->current->data;
/* create as it's now required */
- if (g_strstr_len (text, text_len, "\n") == NULL) {
+ if ((helper->flags & AS_NODE_FROM_XML_FLAG_LITERAL_TEXT) > 0 ||
+ g_strstr_len (text, text_len, "\n") == NULL) {
data->cdata = g_strndup (text, text_len);
/* split up into lines and add each with spaces stripped */
@@ -475,8 +481,10 @@ as_node_text_cb (GMarkupParseContext *context,
split = g_strsplit (text, "\n", -1);
for (i = 0; split[i] != NULL; i++) {
g_strstrip (split[i]);
- if (split[i][0] == '\0')
+ if (split[i][0] == '\0') {
+ g_string_append (tmp, "\n\n");
continue;
+ }
g_string_append_printf (tmp, "%s ", split[i]);
}
@@ -507,10 +515,10 @@ as_node_from_xml (const gchar *data,
AsNodeFromXmlFlags flags,
GError **error)
{
+ AsNodeToXmlHelper helper;
GError *error_local = NULL;
GMarkupParseContext *ctx;
GNode *root;
- GNode *current;
gboolean ret;
const GMarkupParser parser = {
as_node_start_element_cb,
@@ -521,10 +529,12 @@ as_node_from_xml (const gchar *data,
g_return_val_if_fail (data != NULL, FALSE);
- current = root = g_node_new (NULL);
+ root = g_node_new (NULL);
+ helper.flags = flags;
+ helper.current = root;
ctx = g_markup_parse_context_new (&parser,
G_MARKUP_PREFIX_ERROR_POSITION,
- &current,
+ &helper,
NULL);
ret = g_markup_parse_context_parse (ctx,
data,
@@ -542,7 +552,7 @@ as_node_from_xml (const gchar *data,
}
/* more opening than closing */
- if (root != current) {
+ if (root != helper.current) {
g_set_error_literal (error,
AS_NODE_ERROR,
AS_NODE_ERROR_FAILED,
@@ -575,13 +585,13 @@ as_node_from_file (GFile *file,
GCancellable *cancellable,
GError **error)
{
+ AsNodeToXmlHelper helper;
GConverter *conv = NULL;
GError *error_local = NULL;
GFileInfo *info = NULL;
GInputStream *file_stream = NULL;
GInputStream *stream_data = NULL;
GMarkupParseContext *ctx = NULL;
- GNode *current;
GNode *root = NULL;
const gchar *content_type = NULL;
gboolean ret = TRUE;
@@ -625,10 +635,12 @@ as_node_from_file (GFile *file,
}
/* parse */
- current = root = g_node_new (NULL);
+ root = g_node_new (NULL);
+ helper.flags = flags;
+ helper.current = root;
ctx = g_markup_parse_context_new (&parser,
G_MARKUP_PREFIX_ERROR_POSITION,
- &current,
+ &helper,
NULL);
data = g_malloc (chunk_size);
@@ -659,7 +671,7 @@ as_node_from_file (GFile *file,
}
/* more opening than closing */
- if (root != current) {
+ if (root != helper.current) {
g_set_error_literal (error,
AS_NODE_ERROR,
AS_NODE_ERROR_FAILED,
diff --git a/libappstream-glib/as-node.h b/libappstream-glib/as-node.h
index b72fa7a..1800bcf 100644
--- a/libappstream-glib/as-node.h
+++ b/libappstream-glib/as-node.h
@@ -55,11 +55,13 @@ typedef enum {
/**
* AsNodeFromXmlFlags:
* @AS_NODE_FROM_XML_FLAG_NONE: No extra flags to use
+ * @AS_NODE_FROM_XML_FLAG_LITERAL_TEXT: Treat the text as an exact string
*
* The flags for converting from XML.
**/
typedef enum {
AS_NODE_FROM_XML_FLAG_NONE = 0, /* Since: 0.1.0 */
+ AS_NODE_FROM_XML_FLAG_LITERAL_TEXT = 1, /* Since: 0.1.3 */
/*< private >*/
AS_NODE_FROM_XML_FLAG_LAST
} AsNodeFromXmlFlags;
diff --git a/libappstream-glib/as-self-test.c b/libappstream-glib/as-self-test.c
index d260d54..a0ca242 100644
--- a/libappstream-glib/as-self-test.c
+++ b/libappstream-glib/as-self-test.c
@@ -402,13 +402,15 @@ ch_test_app_no_markup_func (void)
const gchar *src =
"<application>"
"<id type=\"desktop\">org.gnome.Software.desktop</id>"
- "<description>Software</description>"
+ "<description>Software is awesome:\n\n * Bada\n * Boom!</description>"
"</application>";
app = as_app_new ();
/* to object */
- root = as_node_from_xml (src, -1, 0, &error);
+ root = as_node_from_xml (src, -1,
+ AS_NODE_FROM_XML_FLAG_LITERAL_TEXT,
+ &error);
g_assert_no_error (error);
g_assert (root != NULL);
n = as_node_find (root, "application");
@@ -419,7 +421,8 @@ ch_test_app_no_markup_func (void)
/* verify */
g_assert_cmpstr (as_app_get_id_full (app), ==, "org.gnome.Software.desktop");
- g_assert_cmpstr (as_app_get_description (app, "C"), ==, "Software");
+ g_assert_cmpstr (as_app_get_description (app, "C"), ==,
+ "Software is awesome:\n\n * Bada\n * Boom!");
as_node_unref (root);
/* back to node */
diff --git a/libappstream-glib/as-store.c b/libappstream-glib/as-store.c
index cb27757..ac4faf5 100644
--- a/libappstream-glib/as-store.c
+++ b/libappstream-glib/as-store.c
@@ -407,7 +407,7 @@ as_store_from_file (AsStore *store,
g_return_val_if_fail (AS_IS_STORE (store), FALSE);
root = as_node_from_file (file,
- AS_NODE_FROM_XML_FLAG_NONE,
+ AS_NODE_FROM_XML_FLAG_LITERAL_TEXT,
cancellable,
&error_local);
if (root == NULL) {
@@ -461,7 +461,7 @@ as_store_from_xml (AsStore *store,
g_return_val_if_fail (AS_IS_STORE (store), FALSE);
root = as_node_from_xml (data, data_len,
- AS_NODE_FROM_XML_FLAG_NONE,
+ AS_NODE_FROM_XML_FLAG_LITERAL_TEXT,
&error_local);
if (root == NULL) {
ret = FALSE;