+Wed Nov 8 16:58:56 CET 2006 Daniel Veillard <veillard@redhat.com>
+
+ * include/libvirt/virterror.h src/virterror.c src/xend_internal.c
+ src/xml.c: give proper indication of the failures raised by the
+ XML parser on not well formed XML, should fix rhbz#208545
+
Wed Nov 8 14:01:11 CET 2006 Daniel Veillard <veillard@redhat.com>
* src/libvirt.c src/proxy_internal.c src/xs_internal.c: fix the
VIR_ERR_READ_FAILED, /* failed to read a conf file */
VIR_ERR_PARSE_FAILED, /* failed to parse a conf file */
VIR_ERR_CONF_SYNTAX, /* failed to parse the syntax of a conf file */
- VIR_ERR_WRITE_FAILED /* failed to write a conf file */
+ VIR_ERR_WRITE_FAILED, /* failed to write a conf file */
+ VIR_ERR_XML_DETAIL /* detail of an XML error */
} virErrorNumber;
/**
case VIR_FROM_XEN:
dom = "Xen ";
break;
+ case VIR_FROM_XML:
+ dom = "XML ";
+ break;
case VIR_FROM_XEND:
dom = "Xen Daemon ";
break;
domain = err->dom->name;
}
len = strlen(err->message);
- if ((len == 0) || (err->message[len - 1] != '\n'))
+ if ((err->domain == VIR_FROM_XML) && (err->code == VIR_ERR_XML_DETAIL) &&
+ (err->int1 != 0))
+ fprintf(stderr, "libvir: %s%s %s: line %d: %s",
+ dom, lvl, domain, err->int1, err->message);
+ else if ((len == 0) || (err->message[len - 1] != '\n'))
fprintf(stderr, "libvir: %s%s %s: %s\n",
dom, lvl, domain, err->message);
else
else
errmsg = _("failed to write configuration file: %s");
break;
+ case VIR_ERR_XML_DETAIL:
+ if (info == NULL)
+ errmsg = _("parser error");
+ else
+ errmsg = "%s";
+ break;
}
return (errmsg);
}
}
if ((xendConfigVersion = xend_get_config_version(conn)) < 0) {
- virXendError(conn, VIR_ERR_INTERNAL_ERROR, "cannot determine xend config version");
+ virXendError(conn, VIR_ERR_INTERNAL_ERROR,
+ "cannot determine xend config version");
return (NULL);
}
sexpr = virDomainParseXMLDesc(xmlDesc, &name, xendConfigVersion);
if ((sexpr == NULL) || (name == NULL)) {
- virXendError(conn, VIR_ERR_XML_ERROR, "Failed to parse the XML domain description");
+ virXendError(conn, VIR_ERR_XML_ERROR, "domain");
if (sexpr != NULL)
free(sexpr);
if (name != NULL)
return (0);
}
+/**
+ * virCatchXMLParseError:
+ * @ctx: the context
+ * @msg: the error message
+ * @...: extra arguments
+ *
+ * SAX callback on parsing errors, act as a gate for libvirt own
+ * error reporting.
+ */
+static void
+virCatchXMLParseError(void *ctx, const char *msg, ...) {
+ xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
+
+ if ((ctxt != NULL) &&
+ (ctxt->lastError.level == XML_ERR_FATAL) &&
+ (ctxt->lastError.message != NULL)) {
+ virXMLError(VIR_ERR_XML_DETAIL, ctxt->lastError.message,
+ ctxt->lastError.line);
+ }
+}
+
/**
* virDomainParseXMLDiskDesc:
* @node: node containing disk description
char *ret = NULL, *nam = NULL;
virBuffer buf;
xmlChar *prop;
+ xmlParserCtxtPtr pctxt;
xmlXPathObjectPtr obj = NULL;
xmlXPathObjectPtr tmpobj = NULL;
xmlXPathContextPtr ctxt = NULL;
buf.size = 1000;
buf.use = 0;
- xml = xmlReadDoc((const xmlChar *) xmldesc, "domain.xml", NULL,
- XML_PARSE_NOENT | XML_PARSE_NONET |
- XML_PARSE_NOERROR | XML_PARSE_NOWARNING);
+ pctxt = xmlNewParserCtxt();
+ if ((pctxt == NULL) || (pctxt->sax == NULL)) {
+ goto error;
+ }
+
+ pctxt->sax->error = virCatchXMLParseError;
+
+ xml = xmlCtxtReadDoc(pctxt, (const xmlChar *) xmldesc, "domain.xml", NULL,
+ XML_PARSE_NOENT | XML_PARSE_NONET |
+ XML_PARSE_NOWARNING);
if (xml == NULL) {
goto error;
}