diff options
author | Richard Hughes <richard@hughsie.com> | 2018-03-08 14:38:22 +0000 |
---|---|---|
committer | Richard Hughes <richard@hughsie.com> | 2018-03-08 14:38:24 +0000 |
commit | ba117f48563d8c65a4e9f7c593b6cb89f17f025a (patch) | |
tree | 6471688c14b0ce8c0dad3011e7961fd8359cce2a | |
parent | cdad22c5fdc6579ea6aeccf67372e81372e857b1 (diff) | |
download | appstream-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.c | 48 |
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 |