summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Hughes <richard@hughsie.com>2018-03-08 14:38:22 +0000
committerRichard Hughes <richard@hughsie.com>2018-03-08 14:38:24 +0000
commitba117f48563d8c65a4e9f7c593b6cb89f17f025a (patch)
tree6471688c14b0ce8c0dad3011e7961fd8359cce2a
parentcdad22c5fdc6579ea6aeccf67372e81372e857b1 (diff)
downloadappstream-glib-ba117f48563d8c65a4e9f7c593b6cb89f17f025a.tar.gz
Correctly validate files using OR in the metadata_license
Althought the correct way to do this would be to construct a GTree structure, splitting on AND and brackets, and having children of OR, I don't have a spare weekend to implement this and then write all the tests. This simplistic parser will correctly validate more files and that's good enough for now. Fixes https://github.com/hughsie/appstream-glib/issues/226
-rw-r--r--libappstream-glib/as-app-validate.c48
1 files changed, 38 insertions, 10 deletions
diff --git a/libappstream-glib/as-app-validate.c b/libappstream-glib/as-app-validate.c
index efb76a2..2829585 100644
--- a/libappstream-glib/as-app-validate.c
+++ b/libappstream-glib/as-app-validate.c
@@ -1032,28 +1032,56 @@ as_app_validate_is_content_license_id (const gchar *license_id)
return TRUE;
if (g_strcmp0 (license_id, "@FSFAP") == 0)
return TRUE;
- if (g_strcmp0 (license_id, "&") == 0)
- return TRUE;
- if (g_strcmp0 (license_id, "|") == 0)
- return TRUE;
- if (g_strcmp0 (license_id, "+") == 0)
- return TRUE;
return FALSE;
}
static gboolean
as_app_validate_is_content_license (const gchar *license)
{
- guint i;
+ gboolean requires_all_tokens = TRUE;
+ guint content_license_bad_cnt = 0;
+ guint content_license_good_cnt = 0;
g_auto(GStrv) tokens = NULL;
tokens = as_utils_spdx_license_tokenize (license);
if (tokens == NULL)
return FALSE;
- for (i = 0; tokens[i] != NULL; i++) {
- if (!as_app_validate_is_content_license_id (tokens[i]))
+
+ /* this is too complicated to process */
+ for (guint i = 0; tokens[i] != NULL; i++) {
+ if (g_strcmp0 (tokens[i], "(") == 0 ||
+ g_strcmp0 (tokens[i], ")") == 0)
return FALSE;
}
- return TRUE;
+
+ /* this is a simple expression parser and can be easily tricked */
+ for (guint i = 0; tokens[i] != NULL; i++) {
+ if (g_strcmp0 (tokens[i], "+") == 0)
+ continue;
+ if (g_strcmp0 (tokens[i], "|") == 0) {
+ requires_all_tokens = FALSE;
+ continue;
+ }
+ if (g_strcmp0 (tokens[i], "&") == 0) {
+ requires_all_tokens = TRUE;
+ continue;
+ }
+ if (as_app_validate_is_content_license_id (tokens[i])) {
+ content_license_good_cnt++;
+ } else {
+ content_license_bad_cnt++;
+ }
+ }
+
+ /* any valid token makes this valid */
+ if (!requires_all_tokens && content_license_good_cnt > 0)
+ return TRUE;
+
+ /* all tokens are required to be valid */
+ if (requires_all_tokens && content_license_bad_cnt == 0)
+ return TRUE;
+
+ /* either the license was bad, or it was too complex to process */
+ return FALSE;
}
static void