[evolution-patches] connector tasks on suse 9.1 fix (58528)



This fixes the task-parsing problem Tim found on SUSE 9.1, which is
caused by newer versions of libxml2 enforcing a piece of the XML grammar
that it was previously more relaxed about. So we have to edit the XML by
hand before passing it off to libxml... Ugh.


Index: ChangeLog
===================================================================
RCS file: /cvs/gnome/evolution-exchange/ChangeLog,v
retrieving revision 1.1.1.1.2.4
diff -u -r1.1.1.1.2.4 ChangeLog
--- ChangeLog	12 May 2004 11:10:51 -0000	1.1.1.1.2.4
+++ ChangeLog	17 May 2004 18:35:37 -0000
@@ -1,3 +1,17 @@
+2004-05-17  Dan Winship  <danw novell com>
+
+	* configure.in: 1.4.7.2
+
+	* lib/e2k-result.c (sanitize_bad_multistatus): New routine, used
+	by e2k_results_array_add_from_multistatus to fix broken Exchange
+	XML so recent versions of libxml2 will parse it correctly.
+	(#58528)
+	(prop_parse): Invert the transformation here so the rest of
+	connector still sees the invalid-but-canonical names.
+
+	* lib/e2k-propnames.h.in: add E2K_NS_MAPI_ID_LEN, the length of
+	E2K_NS_MAPI_ID.
+
 2004-05-12  Francisco Javier F. Serrador  <serrador cvs gnome org>
 
 	* po/es.po: Added partial Spanish translation
Index: configure.in
===================================================================
RCS file: /cvs/gnome/evolution-exchange/configure.in,v
retrieving revision 1.1.1.1.2.2
diff -u -r1.1.1.1.2.2 configure.in
--- configure.in	12 May 2004 11:10:51 -0000	1.1.1.1.2.2
+++ configure.in	17 May 2004 18:35:37 -0000
@@ -1,7 +1,7 @@
 # Process this file with autoconf to produce a configure script.
 AC_PREREQ(2.52)
 
-AC_INIT(ximian-connector, 1.4.7.1, http://bugzilla.ximian.com/enter_bug.cgi?product=Evolution)
+AC_INIT(ximian-connector, 1.4.7.2, http://bugzilla.ximian.com/enter_bug.cgi?product=Evolution)
 AC_CONFIG_SRCDIR(storage)
 AM_INIT_AUTOMAKE(AC_PACKAGE_NAME, AC_PACKAGE_VERSION)
 
Index: lib/e2k-propnames.h.in
===================================================================
RCS file: /cvs/gnome/evolution-exchange/lib/e2k-propnames.h.in,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 e2k-propnames.h.in
--- lib/e2k-propnames.h.in	11 May 2004 15:09:03 -0000	1.1.1.1
+++ lib/e2k-propnames.h.in	17 May 2004 18:35:37 -0000
@@ -177,6 +177,7 @@
 
 
 #define E2K_NS_MAPI_ID			"http://schemas.microsoft.com/mapi/id/";
+#define E2K_NS_MAPI_ID_LEN		(sizeof (E2K_NS_MAPI_ID) - 1)
 
 #define E2K_NS_OUTLOOK_APPOINTMENT	E2K_NS_MAPI_ID "{00062002-0000-0000-C000-000000000046}/"
 
Index: lib/e2k-result.c
===================================================================
RCS file: /cvs/gnome/evolution-exchange/lib/e2k-result.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 e2k-result.c
--- lib/e2k-result.c	11 May 2004 15:09:03 -0000	1.1.1.1
+++ lib/e2k-result.c	17 May 2004 18:35:37 -0000
@@ -113,7 +113,15 @@
 	if (!result->props)
 		result->props = e2k_properties_new ();
 
-	name = g_strdup_printf ("%s%s", node->ns->href, node->name);
+	if (!strncmp (node->ns->href, E2K_NS_MAPI_ID, E2K_NS_MAPI_ID_LEN)) {
+		/* Reinsert the illegal initial '0' that was stripped out
+		 * by sanitize_bad_multistatus. (This also covers us in
+		 * the cases where the server returns the property without
+		 * the '0'.)
+		 */
+		name = g_strdup_printf ("%s0%s", node->ns->href, node->name);
+	} else
+		name = g_strdup_printf ("%s%s", node->ns->href, node->name);
 
 	type = xmlGetNsProp (node, "dt", E2K_NS_TYPE);
 	if (type && !strcmp (type, "mv.bin.base64"))
@@ -181,6 +189,74 @@
 	return g_array_new (FALSE, FALSE, sizeof (E2kResult));
 }
 
+/* Properties in the /mapi/id/{...} namespaces are usually (though not
+ * always) returned with names that start with '0', which is illegal
+ * and makes libxml choke. So we preprocess them to fix that.
+ */
+static char *
+sanitize_bad_multistatus (const char *buf, int len)
+{
+	GString *body;
+	const char *p;
+	int start, end;
+	char ns, badprop[7], *ret;
+
+	/* If there are no "mapi/id/{...}" namespace declarations, then
+	 * we don't need any cleanup.
+	 */
+	if (!memchr (buf, '{', len))
+		return NULL;
+
+	body = g_string_new_len (buf, len);
+
+	/* Find the start and end of namespace declarations */
+	p = strstr (body->str, " xmlns:");
+	g_return_val_if_fail (p != NULL, NULL);
+	start = p + 1 - body->str;
+
+	p = strchr (p, '>');
+	g_return_val_if_fail (p != NULL, NULL);
+	end = p - body->str;
+
+	while (1) {
+		if (strncmp (body->str + start, "xmlns:", 6) != 0)
+			break;
+		if (strncmp (body->str + start + 7, "=\"", 2) != 0)
+			break;
+		if (strncmp (body->str + start + 9, E2K_NS_MAPI_ID, E2K_NS_MAPI_ID_LEN) != 0)
+			goto next;
+
+		ns = body->str[start + 6];
+
+		/* Find properties in this namespace and strip the
+		 * initial '0' from their names to make them valid
+		 * XML NCNames.
+		 */
+		snprintf (badprop, 6, "<%c:0x", ns);
+		while ((p = strstr (body->str, badprop)))
+			g_string_erase (body, p + 3 - body->str, 1);
+		snprintf (badprop, 7, "</%c:0x", ns);
+		while ((p = strstr (body->str, badprop)))
+			g_string_erase (body, p + 4 - body->str, 1);
+
+	next:
+		p = strchr (body->str + start, '"');
+		if (!p)
+			break;
+		p = strchr (p + 1, '"');
+		if (!p)
+			break;
+		if (p[1] != ' ')
+			break;
+
+		start = p + 2 - body->str;
+	}
+
+	ret = body->str;
+	g_string_free (body, FALSE);
+	return ret;
+}
+
 void
 e2k_results_array_add_from_multistatus (GArray *results_array,
 					SoupMessage *msg)
@@ -188,10 +264,16 @@
 	xmlDoc *doc;
 	xmlNode *node, *rnode;
 	E2kResult result;
+	char *body;
 
 	g_return_if_fail (msg->errorcode == SOUP_ERROR_DAV_MULTISTATUS);
 
-	doc = e2k_parse_xml (msg->response.body, msg->response.length);
+	body = sanitize_bad_multistatus (msg->response.body, msg->response.length);
+	if (body) {
+		doc = e2k_parse_xml (body, -1);
+		g_free (body);
+	} else
+		doc = e2k_parse_xml (msg->response.body, msg->response.length);
 	if (!doc)
 		return;
 	node = doc->xmlRootNode;


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]