summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Hughes <richard@hughsie.com>2014-04-30 15:04:45 +0100
committerRichard Hughes <richard@hughsie.com>2014-04-30 15:04:45 +0100
commitd7e4f54befa906c2e9c3ec908a7f1799db84e938 (patch)
tree608dd67af07501bf93dfcec4efdfc5a0f60cdfb7
parent27ead4b48da3f99fb1205627c7201064cb9b6c14 (diff)
downloadappstream-glib-d7e4f54befa906c2e9c3ec908a7f1799db84e938.tar.gz
Check the project_license against the list of SPDX IDs when validating
-rw-r--r--data/tests/broken.appdata.xml1
-rw-r--r--libappstream-glib/Makefile.am5
-rw-r--r--libappstream-glib/appstream-glib.gresource.xml1
-rw-r--r--libappstream-glib/as-app-validate.c58
-rw-r--r--libappstream-glib/as-license-ids.txt216
-rw-r--r--libappstream-glib/as-self-test.c10
-rw-r--r--libappstream-glib/as-utils.c33
-rw-r--r--libappstream-glib/as-utils.h1
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