aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAdam Hooper <adamh@src.gnome.org>2004-10-19 04:02:40 +0800
committerAdam Hooper <adamh@src.gnome.org>2004-10-19 04:02:40 +0800
commit046fa12c2feffd1f4bf1a90e2362911eab211e50 (patch)
tree84b52bdf05fd30792c27aa14ee0a52fe5248be68
parenta419d70f176b0b0cbe40e6458cc17e57bbaec67d (diff)
downloadgsoc2013-epiphany-046fa12c2feffd1f4bf1a90e2362911eab211e50.tar
gsoc2013-epiphany-046fa12c2feffd1f4bf1a90e2362911eab211e50.tar.gz
gsoc2013-epiphany-046fa12c2feffd1f4bf1a90e2362911eab211e50.tar.bz2
gsoc2013-epiphany-046fa12c2feffd1f4bf1a90e2362911eab211e50.tar.lz
gsoc2013-epiphany-046fa12c2feffd1f4bf1a90e2362911eab211e50.tar.xz
gsoc2013-epiphany-046fa12c2feffd1f4bf1a90e2362911eab211e50.tar.zst
gsoc2013-epiphany-046fa12c2feffd1f4bf1a90e2362911eab211e50.zip
Validate extension XML files against an XSD Schema.
-rw-r--r--ChangeLog10
-rw-r--r--data/epiphany-extension.xsd162
-rw-r--r--src/ephy-extensions-manager.c103
3 files changed, 137 insertions, 138 deletions
diff --git a/ChangeLog b/ChangeLog
index fe4f9d12d..35a7d427b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2004-10-18 Adam Hooper <adamh@cvs.gnome.org>
+
+ * data/epiphany-extension.xsd:
+ * src/ephy-extensions-manager.c:
+ (ephy_extensions_manager_load_file), (load_extension),
+ (xml_error_cb), (init_schema_ctxt), (ephy_extensions_manager_init),
+ (ephy_extensions_manager_finalize):
+
+ Validate extension XML files against an XSD Schema.
+
2004-10-18 Christian Persch <chpe@cvs.gnome.org>
* configure.ac:
diff --git a/data/epiphany-extension.xsd b/data/epiphany-extension.xsd
index aca452b2b..4898b1ce7 100644
--- a/data/epiphany-extension.xsd
+++ b/data/epiphany-extension.xsd
@@ -7,21 +7,7 @@
</xsd:documentation>
</xsd:annotation>
- <xsd:element name="extension-list" type="ExtensionListType"/>
-
- <xsd:complexType name="ExtensionListType">
- <xsd:annotation>
- <xsd:documentation xml:lang="en">
- List of extensions. Each extension has its set
- of metadata.
- </xsd:documentation>
- </xsd:annotation>
- <xsd:sequence>
- <xsd:element name="extension"
- type="ExtensionType"
- minOccurs="1"/>
- </xsd:sequence>
- </xsd:complexType>
+ <xsd:element name="extension" type="ExtensionType"/>
<xsd:complexType name="ExtensionType">
<xsd:annotation>
@@ -30,152 +16,62 @@
</xsd:documentation>
</xsd:annotation>
<xsd:sequence>
- <xsd:element name="filename"
- type="ExtensionFilenameType"
- minOccurs="1" maxOccurs="1"/>
- <xsd:element name="name"
- type="xsd:string"
- minOccurs="1" maxOccurs="1"/>
- <xsd:element name="description"
- type="xsd:string"
- minOccurs="1" maxOccurs="1"/>
+ <xsd:element name="name" type="xsd:string"/>
+ <xsd:element name="description" type="xsd:string"/>
+ <xsd:element name="author" type="AuthorType"
+ maxOccurs="unbounded"/>
+ <xsd:element name="url" type="xsd:anyURI"
+ minOccurs="0"/>
<xsd:element name="version"
- type="ExtensionVersionType"
- minOccurs="1" maxOccurs="1"/>
-<!--
- <xsd:element name="min-epiphany-version"
- type="EpiphanyVersionType"
- maxOccurs="1"/>
- <xsd:element name="max-epiphany-version"
- type="EpiphanyVersionType"
- maxOccurs="1"/>
- <xsd:element name="min-mozilla-version"
- type="MozillaVersionType"
- maxOccurs="1"/>
- <xsd:element name="max-mozilla-version"
- type="MozillaVersionType"
- maxOccurs="1"/>
--->
- <xsd:element name="author" type="AuthorType"/>
- <xsd:element name="url" type="xsd:anyURI"/>
+ type="ExtensionVersionType"/>
+ <xsd:element name="gettext-domain" type="xsd:string"/>
+ <xsd:element name="locale-directory" type="xsd:string"/>
+ <xsd:element name="loader" type="LoaderType"/>
</xsd:sequence>
</xsd:complexType>
- <xsd:simpleType name="ExtensionFilenameType">
- <xsd:annotation>
- <xsd:documentation xml:lang="en">
- The &quot;core&quot; of the extension's
- filename. For example, use &quot;gestures&quot;
- for an extension with a shared object name of
- &quot;libgesturesextension.so&quot;.
- </xsd:documentation>
- </xsd:annotation>
- <xsd:restriction base="xsd:string">
- <xsd:pattern value="[a-zA-Z0-9_-]+"/>
- </xsd:restriction>
- </xsd:simpleType>
-
<xsd:simpleType name="ExtensionVersionType">
<xsd:annotation>
<xsd:documentation xml:lang="en">
The version of the extension's API. For most
extensions, this number will remain at
&quot;1&quot; indefinitely. The only reason to
- increase it would be if any GObject classess
+ increase it would be if any GObject classes
within the extension change parents.
</xsd:documentation>
</xsd:annotation>
<xsd:restriction base="xsd:positiveInteger"/>
</xsd:simpleType>
-<!--
- <xsd:complexType name="EpiphanyVersionType">
+ <xsd:simpleType name="AuthorType">
<xsd:annotation>
<xsd:documentation xml:lang="en">
- An Epiphany version (major.minor.micro).
- Extensions may function properly across a range
- of Epiphany versions, as long as the relevant
- parts of the Epiphany API have not changed.
- </xsd:documentation>
- </xsd:annotation>
- <xsd:sequence>
- <xsd:element name="major"
- type="xsd:positiveInteger"
- minOccurs="1" maxOccurs="1"/>
- <xsd:element name="minor"
- type="xsd:positiveInteger"
- minOccurs="1" maxOccurs="1"/>
- <xsd:element name="micro"
- type="xsd:positiveInteger"
- minOccurs="1" maxOccurs="1"/>
- </xsd:sequence>
- </xsd:complexType>
-
- <xsd:complexType name="MozillaVersionType">
- <xsd:annotation>
- <xsd:documentation xml:lang="en">
- A Mozilla version (major, minor, type, micro).
- Extensions my function properly across a range
- of Mozilla versions, as long as the relevant
- parts of the Mozilla API have not changed.
- </xsd:documentation>
- </xsd:annotation>
- <xsd:sequence>
- <xsd:element name="major"
- type="xsd:positiveInteger"
- minOccurs="1" maxOccurs="1"/>
- <xsd:element name="minor"
- type="xsd:positiveInteger"
- minOccurs="1" maxOccurs="1"/>
- <xsd:element name="type"
- type="MozillaVersionTypeType"
- minOccurs="1" maxOccurs="1"/>
- <xsd:element name="micro"
- type="xsd:positiveInteger"
- minOccurs="1" maxOccurs="1"/>
- </xsd:sequence>
- </xsd:complexType>
-
- <xsd:simpleType name="MozillaVersionTypeType">
- <xsd:annotation>
- <xsd:documentation xml:lang="en">
- The &quot;type&quot; of a Mozilla version. 1
- means Alpha, 2 means Beta, 3 means RC and 4
- means release.
+ An extension author -- a name and (optionally)
+ an email address.
</xsd:documentation>
</xsd:annotation>
- <xsd:restriction base="xsd:positiveInteger">
- <xsd:minInclusive value="1"/>
- <xsd:maxInclusive value="4"/>
- </xsd:restriction>
+ <xsd:restriction base="xsd:string"/>
</xsd:simpleType>
--->
- <xsd:complexType name="AuthorType">
+ <xsd:complexType name="LoaderType">
<xsd:annotation>
<xsd:documentation xml:lang="en">
- An extension author -- a name and (optionally)
- an email address.
+ The type of loader to use for the extension.
+ For example, &quot;shlib&quot;.
</xsd:documentation>
</xsd:annotation>
<xsd:sequence>
- <xsd:element name="name"
- type="xsd:normalizedString"
- minOccurs="1" maxOccurs="1"/>
- <xsd:element name="email"
- type="EmailType"
- maxOccurs="1"/>
+ <xsd:element name="attribute" maxOccurs="unbounded">
+ <xsd:complexType>
+ <xsd:simpleContent>
+ <xsd:extension base="xsd:string">
+ <xsd:attribute name="name" type="xsd:ID"/>
+ </xsd:extension>
+ </xsd:simpleContent>
+ </xsd:complexType>
+ </xsd:element>
</xsd:sequence>
+ <xsd:attribute name="type" type="xsd:ID" use="required"/>
</xsd:complexType>
- <xsd:simpleType name="EmailType">
- <xsd:annotation>
- <xsd:documentation xml:lang="en">
- An email address
- </xsd:documentation>
- </xsd:annotation>
- <xsd:restriction base="xsd:string">
- <xsd:pattern value="[\.a-zA-Z0-9_-]+@([a-zA-Z0-9_-])+(([a-zA-Z0-9_-])*\.([a-zA-Z0-9_-])+)+"/>
- </xsd:restriction>
- </xsd:simpleType>
</xsd:schema>
diff --git a/src/ephy-extensions-manager.c b/src/ephy-extensions-manager.c
index 0fc15bcbd..5ec951168 100644
--- a/src/ephy-extensions-manager.c
+++ b/src/ephy-extensions-manager.c
@@ -35,13 +35,16 @@
#include "ephy-file-helpers.h"
#include "ephy-debug.h"
+#include <libxml/tree.h>
#include <libxml/xmlreader.h>
+#include <libxml/xmlschemas.h>
#include <gmodule.h>
#include <dirent.h>
#include <string.h>
-#define CONF_LOADED_EXTENSIONS "/apps/epiphany/general/active_extensions"
+#define CONF_LOADED_EXTENSIONS "/apps/epiphany/general/active_extensions"
+#define SCHEMA_FILE "/epiphany-extension.xsd"
#define EPHY_EXTENSIONS_MANAGER_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), EPHY_TYPE_EXTENSIONS_MANAGER, EphyExtensionsManagerPrivate))
@@ -54,6 +57,9 @@ struct _EphyExtensionsManagerPrivate
GList *extensions;
GList *windows;
guint active_extensions_notifier_id;
+
+ xmlSchemaPtr schema;
+ xmlSchemaValidCtxtPtr schema_ctxt;
};
typedef struct
@@ -307,6 +313,7 @@ ephy_extensions_manager_load_file (EphyExtensionsManager *manager,
const char *dir,
const char *filename)
{
+ xmlDocPtr doc;
xmlTextReaderPtr reader;
ParserState state = STATE_START;
GQuark attr_quark = 0;
@@ -339,17 +346,35 @@ ephy_extensions_manager_load_file (EphyExtensionsManager *manager,
g_free (path);
return;
}
-
- reader = xmlNewTextReaderFilename (path);
+
+ /* FIXME: Ideally we'd put the schema validator in the reader. libxml2
+ * doesn't seem to support that at this point in time, so we've got to
+ * put the schema validation on the Doc Tree and then pass that to the
+ * reader. (maybe switch to RelaxNG?)
+ */
+ doc = xmlParseFile (path);
g_free (path);
- if (reader == NULL)
+ if (doc == NULL)
{
g_warning ("Couldn't read '%s'\n", filename);
g_free (identifier);
return;
}
+ if (manager->priv->schema_ctxt)
+ {
+ if (xmlSchemaValidateDoc (manager->priv->schema_ctxt, doc))
+ {
+ g_warning ("Validation errors in '%s'\n", filename);
+ xmlFreeDoc (doc);
+ return;
+ }
+ }
+
+ reader = xmlReaderWalker (doc);
+ g_return_if_fail (reader != NULL);
+
info = g_new0 (ExtensionInfo, 1);
einfo = (EphyExtensionInfo *) info;
einfo->identifier = identifier;
@@ -580,6 +605,7 @@ ephy_extensions_manager_load_file (EphyExtensionsManager *manager,
}
xmlFreeTextReader (reader);
+ xmlFreeDoc (doc);
/* sanity check */
if (ret < 0 || state != STATE_STOP ||
@@ -647,7 +673,6 @@ static void
load_extension (EphyExtensionsManager *manager,
ExtensionInfo *info)
{
-
EphyLoader *loader;
g_return_if_fail (info->extension == NULL);
@@ -797,6 +822,63 @@ active_extensions_notifier (GConfClient *client,
}
static void
+xml_error_cb (EphyExtensionsManager *manager,
+ const char *msg,
+ ...)
+
+{
+ va_list args;
+
+ va_start (args, msg);
+ g_logv (G_LOG_DOMAIN, G_LOG_LEVEL_WARNING, msg, args);
+ va_end(args);
+}
+
+static void
+init_schema_ctxt (EphyExtensionsManager *manager)
+{
+ xmlSchemaParserCtxtPtr parse_ctxt;
+ const char *filename;
+
+ manager->priv->schema = NULL;
+ manager->priv->schema_ctxt = NULL;
+
+ filename = ephy_file (SCHEMA_FILE);
+ g_return_if_fail (filename != NULL);
+
+ parse_ctxt = xmlSchemaNewParserCtxt (filename);
+ if (parse_ctxt == NULL)
+ {
+ g_warning ("Error opening extensions description schema file "
+ "\"" SCHEMA_FILE "\"");
+ return;
+ }
+
+ manager->priv->schema = xmlSchemaParse (parse_ctxt);
+ xmlSchemaFreeParserCtxt (parse_ctxt);
+ if (manager->priv->schema == NULL)
+ {
+ g_warning ("Error parsing extensions description schema file "
+ "\"" SCHEMA_FILE "\"");
+ return;
+ }
+
+ manager->priv->schema_ctxt = xmlSchemaNewValidCtxt
+ (manager->priv->schema);
+ if (manager->priv->schema == NULL)
+ {
+ g_warning ("Error creating extensions description schema "
+ "validation context for \"" SCHEMA_FILE "\"");
+ return;
+ }
+
+ xmlSchemaSetValidErrors (manager->priv->schema_ctxt,
+ (xmlSchemaValidityErrorFunc) xml_error_cb,
+ (xmlSchemaValidityWarningFunc) xml_error_cb,
+ manager);
+}
+
+static void
ephy_extensions_manager_init (EphyExtensionsManager *manager)
{
char *path;
@@ -805,6 +887,8 @@ ephy_extensions_manager_init (EphyExtensionsManager *manager)
LOG ("EphyExtensionsManager initialising")
+ init_schema_ctxt (manager);
+
/* load the extensions descriptions */
path = g_build_filename (ephy_dot_dir (), "extensions", NULL);
ephy_extensions_manager_load_dir (manager, path);
@@ -841,6 +925,15 @@ ephy_extensions_manager_finalize (GObject *object)
g_list_free (priv->windows);
+ if (priv->schema)
+ {
+ xmlSchemaFree (priv->schema);
+ }
+ if (priv->schema_ctxt)
+ {
+ xmlSchemaFreeValidCtxt (priv->schema_ctxt);
+ }
+
parent_class->finalize (object);
}