diff options
author | Richard Hughes <richard@hughsie.com> | 2014-04-30 15:04:45 +0100 |
---|---|---|
committer | Richard Hughes <richard@hughsie.com> | 2014-04-30 15:04:45 +0100 |
commit | d7e4f54befa906c2e9c3ec908a7f1799db84e938 (patch) | |
tree | 608dd67af07501bf93dfcec4efdfc5a0f60cdfb7 | |
parent | 27ead4b48da3f99fb1205627c7201064cb9b6c14 (diff) | |
download | appstream-glib-d7e4f54befa906c2e9c3ec908a7f1799db84e938.tar.gz |
Check the project_license against the list of SPDX IDs when validating
-rw-r--r-- | data/tests/broken.appdata.xml | 1 | ||||
-rw-r--r-- | libappstream-glib/Makefile.am | 5 | ||||
-rw-r--r-- | libappstream-glib/appstream-glib.gresource.xml | 1 | ||||
-rw-r--r-- | libappstream-glib/as-app-validate.c | 58 | ||||
-rw-r--r-- | libappstream-glib/as-license-ids.txt | 216 | ||||
-rw-r--r-- | libappstream-glib/as-self-test.c | 10 | ||||
-rw-r--r-- | libappstream-glib/as-utils.c | 33 | ||||
-rw-r--r-- | libappstream-glib/as-utils.h | 1 |
8 files changed, 314 insertions, 11 deletions
diff --git a/data/tests/broken.appdata.xml b/data/tests/broken.appdata.xml index 8d21e77..f39c61b 100644 --- a/data/tests/broken.appdata.xml +++ b/data/tests/broken.appdata.xml @@ -3,6 +3,7 @@ <id type="unknown">gnome-power-statistics</id> <metadata_license>GPLv3+</metadata_license> <metadata_license>BSD</metadata_license> + <project_license>CC1</project_license> <name>Power Statistics.</name> <summary>Observe power management.</summary> <description> diff --git a/libappstream-glib/Makefile.am b/libappstream-glib/Makefile.am index c9834ed..13ceb1a 100644 --- a/libappstream-glib/Makefile.am +++ b/libappstream-glib/Makefile.am @@ -26,7 +26,7 @@ as-tag-private.h: as-tag.gperf $(AM_V_GEN) gperf < $< > $@ endif -as-resources.c: appstream-glib.gresource.xml as-stock-icons.txt +as-resources.c: appstream-glib.gresource.xml as-stock-icons.txt as-license-ids.txt $(AM_V_GEN) \ glib-compile-resources \ --sourcedir=$(srcdir) \ @@ -35,7 +35,7 @@ as-resources.c: appstream-glib.gresource.xml as-stock-icons.txt --generate-source \ --c-name as \ $(srcdir)/appstream-glib.gresource.xml -as-resources.h: appstream-glib.gresource.xml as-stock-icons.txt +as-resources.h: appstream-glib.gresource.xml as-stock-icons.txt as-license-ids.txt $(AM_V_GEN) \ glib-compile-resources \ --sourcedir=$(srcdir) \ @@ -177,6 +177,7 @@ DISTCLEANFILES = \ EXTRA_DIST = \ appstream-glib.gresource.xml \ appstream-glib.pc.in \ + as-license-ids.txt \ as-stock-icons.txt \ as-tag.gperf \ as-version.h.in diff --git a/libappstream-glib/appstream-glib.gresource.xml b/libappstream-glib/appstream-glib.gresource.xml index 8c6302d..f3f33fb 100644 --- a/libappstream-glib/appstream-glib.gresource.xml +++ b/libappstream-glib/appstream-glib.gresource.xml @@ -2,5 +2,6 @@ <gresources> <gresource prefix="/org/freedesktop/appstream-glib"> <file>as-stock-icons.txt</file> + <file>as-license-ids.txt</file> </gresource> </gresources> diff --git a/libappstream-glib/as-app-validate.c b/libappstream-glib/as-app-validate.c index 86c2f96..e3e59cc 100644 --- a/libappstream-glib/as-app-validate.c +++ b/libappstream-glib/as-app-validate.c @@ -29,6 +29,7 @@ #include "as-app-private.h" #include "as-node-private.h" #include "as-problem.h" +#include "as-utils.h" typedef struct { AsAppValidateFlags flags; @@ -617,6 +618,33 @@ out: } /** + * as_app_validate_license: + **/ +static gboolean +as_app_validate_license (const gchar *license_text, GError **error) +{ + gboolean ret = TRUE; + gchar **licenses; + guint i; + + licenses = g_strsplit (license_text, " and ", -1); + for (i = 0; licenses[i] != NULL; i++) { + if (!as_utils_is_spdx_license_id (licenses[i])) { + ret = FALSE; + g_set_error (error, + AS_APP_ERROR, + AS_APP_ERROR_FAILED, + "SPDX ID '%s' unknown", + licenses[i]); + goto out; + } + } +out: + g_strfreev (licenses); + return ret; +} + +/** * as_app_validate: * @app: a #AsApp instance. * @flags: the #AsAppValidateFlags to use, e.g. %AS_APP_VALIDATE_FLAG_NONE @@ -641,7 +669,7 @@ as_app_validate (AsApp *app, AsAppValidateFlags flags, GError **error) const gchar *description; const gchar *id_full; const gchar *key; - const gchar *metadata_license; + const gchar *license; const gchar *name; const gchar *summary; const gchar *tmp; @@ -727,24 +755,38 @@ as_app_validate (AsApp *app, AsAppValidateFlags flags, GError **error) } /* metadata_license */ - metadata_license = as_app_get_metadata_license (app); - if (metadata_license != NULL) { - if (g_strcmp0 (metadata_license, "CC0") != 0 && - g_strcmp0 (metadata_license, "CC-BY") != 0 && - g_strcmp0 (metadata_license, "CC-BY-SA") != 0 && - g_strcmp0 (metadata_license, "GFDL") != 0) { + license = as_app_get_metadata_license (app); + if (license != NULL) { + if (g_strcmp0 (license, "CC0") != 0 && + g_strcmp0 (license, "CC-BY") != 0 && + g_strcmp0 (license, "CC-BY-SA") != 0 && + g_strcmp0 (license, "GFDL") != 0) { ai_app_validate_add (probs, AS_PROBLEM_KIND_TAG_INVALID, "<metadata_license> is not valid"); } } if (as_app_get_source_kind (app) == AS_APP_SOURCE_KIND_APPDATA && - metadata_license == NULL) { + license == NULL) { ai_app_validate_add (probs, AS_PROBLEM_KIND_TAG_MISSING, "<metadata_license> is not present"); } + /* project_license */ + license = as_app_get_project_license (app); + if (license != NULL) { + ret = as_app_validate_license (license, &error_local); + if (!ret) { + g_prefix_error (&error_local, + "<project_license> is not valid: "); + ai_app_validate_add (probs, + AS_PROBLEM_KIND_TAG_INVALID, + error_local->message); + g_clear_error (&error_local); + } + } + /* updatecontact */ update_contact = as_app_get_update_contact (app); if (g_strcmp0 (update_contact, diff --git a/libappstream-glib/as-license-ids.txt b/libappstream-glib/as-license-ids.txt new file mode 100644 index 0000000..330cb93 --- /dev/null +++ b/libappstream-glib/as-license-ids.txt @@ -0,0 +1,216 @@ +# this file contains the list of known licenses from http://spdx.org/licenses/ +AFL-1.1 +AFL-1.2 +AFL-2.0 +AFL-2.1 +AFL-3.0 +APL-1.0 +Aladdin +ANTLR-PD +Apache-1.0 +Apache-1.1 +Apache-2.0 +APSL-1.0 +APSL-1.1 +APSL-1.2 +APSL-2.0 +Artistic-1.0 +Artistic-1.0-cl8 +Artistic-1.0-Perl +Artistic-2.0 +AAL +BitTorrent-1.0 +BitTorrent-1.1 +BSL-1.0 +BSD-2-Clause +BSD-2-Clause-FreeBSD +BSD-2-Clause-NetBSD +BSD-3-Clause +BSD-3-Clause-Clear +BSD-4-Clause +BSD-4-Clause-UC +CECILL-1.0 +CECILL-1.1 +CECILL-2.0 +CECILL-B +CECILL-C +ClArtistic +CNRI-Python +CNRI-Python-GPL-Compatible +CPOL-1.02 +CDDL-1.0 +CDDL-1.1 +CPAL-1.0 +CPL-1.0 +CATOSL-1.1 +Condor-1.1 +CC-BY-1.0 +CC-BY-2.0 +CC-BY-2.5 +CC-BY-3.0 +CC-BY-ND-1.0 +CC-BY-ND-2.0 +CC-BY-ND-2.5 +CC-BY-ND-3.0 +CC-BY-NC-1.0 +CC-BY-NC-2.0 +CC-BY-NC-2.5 +CC-BY-NC-3.0 +CC-BY-NC-ND-1.0 +CC-BY-NC-ND-2.0 +CC-BY-NC-ND-2.5 +CC-BY-NC-ND-3.0 +CC-BY-NC-SA-1.0 +CC-BY-NC-SA-2.0 +CC-BY-NC-SA-2.5 +CC-BY-NC-SA-3.0 +CC-BY-SA-1.0 +CC-BY-SA-2.0 +CC-BY-SA-2.5 +CC-BY-SA-3.0 +CC0-1.0 +CUA-OPL-1.0 +D-FSL-1.0 +WTFPL +EPL-1.0 +eCos-2.0 +ECL-1.0 +ECL-2.0 +EFL-1.0 +EFL-2.0 +Entessa +ErlPL-1.1 +EUDatagrid +EUPL-1.0 +EUPL-1.1 +Fair +Frameworx-1.0 +FTL +AGPL-1.0 +AGPL-3.0 +GFDL-1.1 +GFDL-1.2 +GFDL-1.3 +GPL-1.0 +GPL-1.0+ +GPL-2.0 +GPL-2.0+ +GPL-2.0-with-autoconf-exception +GPL-2.0-with-bison-exception +GPL-2.0-with-classpath-exception +GPL-2.0-with-font-exception +GPL-2.0-with-GCC-exception +GPL-3.0 +GPL-3.0+ +GPL-3.0-with-autoconf-exception +GPL-3.0-with-GCC-exception +LGPL-2.1 +LGPL-2.1+ +LGPL-3.0 +LGPL-3.0+ +LGPL-2.0 +LGPL-2.0+ +gSOAP-1.3b +HPND +IBM-pibs +IPL-1.0 +Imlib2 +IJG +Intel +IPA +ISC +JSON +LPPL-1.3a +LPPL-1.0 +LPPL-1.1 +LPPL-1.2 +LPPL-1.3c +Libpng +LPL-1.02 +LPL-1.0 +MS-PL +MS-RL +MirOS +MIT +Motosoto +MPL-1.0 +MPL-1.1 +MPL-2.0 +MPL-2.0-no-copyleft-exception +Multics +NASA-1.3 +Naumen +NBPL-1.0 +NGPL +NOSL +NPL-1.0 +NPL-1.1 +Nokia +NPOSL-3.0 +NTP +OCLC-2.0 +ODbL-1.0 +PDDL-1.0 +OGTSL +OLDAP-2.2.2 +OLDAP-1.1 +OLDAP-1.2 +OLDAP-1.3 +OLDAP-1.4 +OLDAP-2.0 +OLDAP-2.0.1 +OLDAP-2.1 +OLDAP-2.2 +OLDAP-2.2.1 +OLDAP-2.3 +OLDAP-2.4 +OLDAP-2.5 +OLDAP-2.6 +OLDAP-2.7 +OPL-1.0 +OSL-1.0 +OSL-2.0 +OSL-2.1 +OSL-3.0 +OLDAP-2.8 +OpenSSL +PHP-3.0 +PHP-3.01 +PostgreSQL +Python-2.0 +QPL-1.0 +RPSL-1.0 +RPL-1.1 +RPL-1.5 +RHeCos-1.1 +RSCPL +Ruby +SAX-PD +SGI-B-1.0 +SGI-B-1.1 +SGI-B-2.0 +OFL-1.0 +OFL-1.1 +SimPL-2.0 +Sleepycat +SMLNJ +SugarCRM-1.1.3 +SISSL +SISSL-1.2 +SPL-1.0 +Watcom-1.0 +NCSA +VSL-1.0 +W3C +WXwindows +Xnet +X11 +XFree86-1.1 +YPL-1.0 +YPL-1.1 +Zimbra-1.3 +Zlib +ZPL-1.1 +ZPL-2.0 +ZPL-2.1 +Unlicense diff --git a/libappstream-glib/as-self-test.c b/libappstream-glib/as-self-test.c index a98215a..5fb7b44 100644 --- a/libappstream-glib/as-self-test.c +++ b/libappstream-glib/as-self-test.c @@ -360,6 +360,12 @@ ch_test_app_validate_check (GPtrArray *array, g_strcmp0 (as_problem_get_message (problem), message) == 0) return; } + for (i = 0; i < array->len; i++) { + problem = g_ptr_array_index (array, i); + g_print ("%i\t%s\n", + as_problem_get_kind (problem), + as_problem_get_message (problem)); + } g_assert_cmpstr (message, ==, "not-found"); } @@ -447,7 +453,7 @@ ch_test_app_validate_file_bad_func (void) problem = g_ptr_array_index (probs, i); g_debug ("%s", as_problem_get_message (problem)); } - g_assert_cmpint (probs->len, ==, 17); + g_assert_cmpint (probs->len, ==, 18); ch_test_app_validate_check (probs, AS_PROBLEM_KIND_ATTRIBUTE_INVALID, "<id> has invalid type attribute"); @@ -455,6 +461,8 @@ ch_test_app_validate_file_bad_func (void) "<id> does not have correct extension for kind"); ch_test_app_validate_check (probs, AS_PROBLEM_KIND_TAG_INVALID, "<metadata_license> is not valid"); + ch_test_app_validate_check (probs, AS_PROBLEM_KIND_TAG_INVALID, + "<project_license> is not valid: SPDX ID 'CC1' unknown"); ch_test_app_validate_check (probs, AS_PROBLEM_KIND_TAG_MISSING, "<updatecontact> is not present"); ch_test_app_validate_check (probs, AS_PROBLEM_KIND_TAG_INVALID, diff --git a/libappstream-glib/as-utils.c b/libappstream-glib/as-utils.c index 8a45581..fd2e422 100644 --- a/libappstream-glib/as-utils.c +++ b/libappstream-glib/as-utils.c @@ -229,6 +229,39 @@ out: } /** + * as_utils_is_spdx_license_id: + * @license_id: a single SPDX license ID, e.g. "CC-BY-3.0" + * + * Searches the known list of SPDX license IDs. + * + * Returns: %TRUE if the icon is a valid "SPDX license ID" + * + * Since: 0.1.5 + **/ +gboolean +as_utils_is_spdx_license_id (const gchar *license_id) +{ + GBytes *data; + gboolean ret = FALSE; + gchar *key = NULL; + + /* load the readonly data section and look for the icon name */ + data = g_resource_lookup_data (as_get_resource (), + "/org/freedesktop/appstream-glib/as-license-ids.txt", + G_RESOURCE_LOOKUP_FLAGS_NONE, + NULL); + if (data == NULL) + goto out; + key = g_strdup_printf ("\n%s\n", license_id); + ret = g_strstr_len (g_bytes_get_data (data, NULL), -1, key) != NULL; +out: + if (data != NULL) + g_bytes_unref (data); + g_free (key); + return ret; +} + +/** * as_util_get_possible_kudos: * * Returns a list of all known kudos, which are metadata values that diff --git a/libappstream-glib/as-utils.h b/libappstream-glib/as-utils.h index ddfd6a4..9932d76 100644 --- a/libappstream-glib/as-utils.h +++ b/libappstream-glib/as-utils.h @@ -34,6 +34,7 @@ gchar *as_markup_convert_simple (const gchar *markup, gssize markup_len, GError **error); gboolean as_utils_is_stock_icon_name (const gchar *name); +gboolean as_utils_is_spdx_license_id (const gchar *license_id); const gchar * const *as_util_get_possible_kudos (void); G_END_DECLS |