diff -urN PackageKit-0.5.6/backends/zypp/pk-backend-zypp.cpp PackageKit-0.5.6-new/backends/zypp/pk-backend-zypp.cpp
--- PackageKit-0.5.6/backends/zypp/pk-backend-zypp.cpp	2009-12-04 06:05:37.000000000 +0800
+++ PackageKit-0.5.6-new/backends/zypp/pk-backend-zypp.cpp	2009-12-20 19:15:17.000000000 +0800
@@ -126,11 +126,12 @@
 static gboolean
 backend_get_requires_thread (PkBackend *backend)
 {
-	PkPackageId *pi = NULL;
+	gchar *pi = NULL;
 	gchar **package_ids;
+	gchar **sections;
 
 	package_ids = pk_backend_get_strv (backend, "package_ids");
-	if (package_ids == NULL) {
+	if (!pk_package_ids_check(package_ids)) {
 		pk_backend_error_code (backend, PK_ERROR_ENUM_PACKAGE_ID_INVALID, "invalid package id");
 		pk_backend_finished (backend);
 		return FALSE;
@@ -143,7 +144,8 @@
 
 	for (uint i = 0; i < g_strv_length(package_ids); i++) {
 
-		pi = pk_package_id_new_from_string (package_ids[i]);
+		pi = package_ids[i];
+		sections = pk_package_id_split(pi);
 
 		zypp::sat::Solvable solvable = zypp_get_package_by_id (package_ids[i]);
 		zypp::PoolItem package;
@@ -153,8 +155,8 @@
 
 			gboolean found = FALSE;
 
-			for (zypp::ResPool::byIdent_iterator it = pool.byIdentBegin (zypp::ResKind::package, pi->name);
-					it != pool.byIdentEnd (zypp::ResKind::package, pi->name); it++) {
+			for (zypp::ResPool::byIdent_iterator it = pool.byIdentBegin (zypp::ResKind::package, sections[0]);
+					it != pool.byIdentEnd (zypp::ResKind::package, sections[0]); it++) {
 				if (it->status ().isInstalled ()) {
 					package = (*it);
 					found = TRUE;
@@ -163,7 +165,7 @@
 
 			if (found == FALSE) {
 				pk_backend_error_code (backend, PK_ERROR_ENUM_PACKAGE_NOT_INSTALLED, "Package is not installed");
-				pk_package_id_free (pi);
+				g_strfreev(sections);
 				pk_backend_finished (backend);
 				return FALSE;
 			}
@@ -173,7 +175,7 @@
 		} else {
 			if (solvable == zypp::sat::Solvable::noSolvable) {
 				pk_backend_error_code (backend, PK_ERROR_ENUM_PACKAGE_NOT_FOUND, "Package couldn't be found");
-				pk_package_id_free (pi);
+				g_strfreev(sections);
 				pk_backend_finished (backend);
 				return FALSE;
 			}
@@ -196,7 +198,7 @@
 				egg_warning("Solver problem (This should never happen): '%s'", (*it)->description ().c_str ());
 			}
 			pk_backend_error_code (backend, PK_ERROR_ENUM_DEP_RESOLUTION_FAILED, "Resolution failed");
-			pk_package_id_free (pi);
+			g_strfreev(sections);
 			pk_backend_finished (backend);
 			return FALSE;
 		}
@@ -236,13 +238,12 @@
 			it->statusReset ();
 		}
 
+		g_strfreev(sections);
 		// undo the status-change of the package and disable forceResolve
 		package.statusReset ();
 		solver.setForceResolve (false);
 	}
 
-	pk_package_id_free (pi);
-
 	pk_backend_finished (backend);
 	return TRUE;
 }
@@ -303,18 +304,22 @@
 backend_get_depends_thread (PkBackend *backend)
 {
 	gchar **package_ids;
+	gchar **sections;
 
 	pk_backend_set_status (backend, PK_STATUS_ENUM_QUERY);
 	pk_backend_set_percentage (backend, 0);
 
 	package_ids = pk_backend_get_strv (backend, "package_ids");
-	PkPackageId *pi = pk_package_id_new_from_string (package_ids[0]);
-	if (pi == NULL) {
+	gchar *pi = package_ids[0];
+	
+	if (!pk_package_id_check (pi)) {
 		pk_backend_error_code (backend, PK_ERROR_ENUM_PACKAGE_ID_INVALID, "invalid package id");
 		pk_backend_finished (backend);
 		return FALSE;
 	}
 
+	sections = pk_package_id_split(pi);
+
 	zypp::ZYpp::Ptr zypp;
 	zypp = get_zypp ();
 
@@ -327,14 +332,14 @@
 		zypp::PoolItem pool_item;
 		gboolean pool_item_found = FALSE;
 		// Iterate over the resolvables and mark the one we want to check its dependencies
-		for (zypp::ResPool::byIdent_iterator it = pool.byIdentBegin (zypp::ResKind::package, pi->name);
-				it != pool.byIdentEnd (zypp::ResKind::package, pi->name); it++) {
+		for (zypp::ResPool::byIdent_iterator it = pool.byIdentBegin (zypp::ResKind::package, sections[0]);
+				it != pool.byIdentEnd (zypp::ResKind::package, sections[0]); it++) {
 			zypp::PoolItem selectable = *it;
-			if (strcmp (selectable->name().c_str(), pi->name) == 0) {
+			if (strcmp (selectable->name().c_str(), sections[0]) == 0) {
 				// This package matches the name we're looking
 				char *edition_str = g_strdup (selectable->edition ().asString ().c_str());
 
-				if (strcmp (edition_str, pi->version) == 0) {
+				if (strcmp (edition_str, sections[1]) == 0) {
 					g_free (edition_str);
 					// this is the one, mark it to be installed
 					pool_item = selectable;
@@ -435,18 +440,19 @@
 		// TODO: make sure this dumps out the right sring.
 		pk_backend_error_code (backend, PK_ERROR_ENUM_REPO_NOT_FOUND, ex.asUserString().c_str() );
 
-		pk_package_id_free (pi);
+		g_strfreev (sections);
 		pk_backend_finished (backend);
 		return FALSE;
 	} catch (const zypp::Exception &ex) {
 		//pk_backend_error_code (backend, PK_ERROR_ENUM_INTERNAL_ERROR, "Error enumerating repositories");
 		pk_backend_error_code (backend, PK_ERROR_ENUM_INTERNAL_ERROR, ex.asUserString().c_str() );
 
-		pk_package_id_free (pi);
+		g_strfreev (sections);
 		pk_backend_finished (backend);
 		return FALSE;
 	}
 
+	g_strfreev (sections);
 	pk_backend_finished (backend);
 	return TRUE;
 }
@@ -465,10 +471,11 @@
 backend_get_details_thread (PkBackend *backend)
 {
 	gchar **package_ids;
-	PkPackageId *pi;
+	gchar **sections;
+	gchar *pi;
 
 	package_ids = pk_backend_get_strv (backend, "package_ids");
-	if (package_ids == NULL) {
+	if (!pk_package_ids_check(package_ids)) {
 		pk_backend_error_code (backend, PK_ERROR_ENUM_PACKAGE_ID_INVALID, "invalid package id");
 		pk_backend_finished (backend);
 		return FALSE;
@@ -477,19 +484,15 @@
 
 	for (uint i = 0; i < g_strv_length(package_ids); i++) {
 
-		pi = pk_package_id_new_from_string (package_ids[i]);
-		if (pi == NULL) {
-			pk_backend_error_code (backend, PK_ERROR_ENUM_PACKAGE_ID_INVALID, "invalid package id");
-			pk_backend_finished (backend);
-			return FALSE;
-		}
+		pi = package_ids[i];
+		sections = pk_package_id_split(pi);
 
 		std::vector<zypp::sat::Solvable> *v;
 		std::vector<zypp::sat::Solvable> *v2;
 		std::vector<zypp::sat::Solvable> *v3;
-		v = zypp_get_packages_by_name ((const gchar *)pi->name, zypp::ResKind::package, TRUE);
-		v2 = zypp_get_packages_by_name ((const gchar *)pi->name, zypp::ResKind::patch, TRUE);
-		v3 = zypp_get_packages_by_name ((const gchar *)pi->name, zypp::ResKind::srcpackage, TRUE);
+		v = zypp_get_packages_by_name ((const gchar *)sections[0], zypp::ResKind::package, TRUE);
+		v2 = zypp_get_packages_by_name ((const gchar *)sections[0], zypp::ResKind::patch, TRUE);
+		v3 = zypp_get_packages_by_name ((const gchar *)sections[0], zypp::ResKind::srcpackage, TRUE);
 
 		v->insert (v->end (), v2->begin (), v2->end ());
 		v->insert (v->end (), v3->begin (), v3->end ());
@@ -500,7 +503,7 @@
 			gchar *version = g_strdup (it->edition ().asString ().c_str ());
 			gchar *arch = g_strdup (it->arch ().c_str ());
 
-			if (strcmp (pi->version, version) == 0 && strcmp (pi->arch, arch) == 0) {
+			if (strcmp (sections[1], version) == 0 && strcmp (sections[2], arch) == 0) {
 				package = *it;
 				break;
 			}
@@ -513,7 +516,7 @@
 
 		if (package == NULL) {
 			pk_backend_error_code (backend, PK_ERROR_ENUM_PACKAGE_NOT_FOUND, "couldn't find package");
-			pk_package_id_free (pi);
+			g_strfreev (sections);
 			pk_backend_finished (backend);
 			return FALSE;
 		}
@@ -554,7 +557,7 @@
 			return FALSE;
 		}
 
-		pk_package_id_free (pi);
+		g_strfreev (sections);
 	}
 
 	pk_backend_finished (backend);
@@ -1027,6 +1030,7 @@
 backend_install_packages_thread (PkBackend *backend)
 {
 	gchar **package_ids;
+	gchar **sections;
 
 	pk_backend_set_status (backend, PK_STATUS_ENUM_QUERY);
 	pk_backend_set_percentage (backend, 0);
@@ -1035,6 +1039,7 @@
 	zypp = get_zypp ();
 
 	package_ids = pk_backend_get_strv (backend, "package_ids");
+
 	/* FIXME: support only_trusted */
 
 	try
@@ -1047,18 +1052,18 @@
 
 		for (guint i = 0; i < g_strv_length (package_ids); i++) {
 
-			PkPackageId *pi = pk_package_id_new_from_string (package_ids[i]);
-			if (pi == NULL) {
+			gchar *pi = package_ids[i];
+			if (!pk_package_id_check(pi)) {
 				pk_backend_error_code (backend, PK_ERROR_ENUM_PACKAGE_ID_INVALID, "invalid package id");
 				pk_backend_finished (backend);
 				return FALSE;
 			}
-
+			sections = pk_package_id_split (pi);
 			// Iterate over the selectables and mark the one with the right name
 			zypp::ui::Selectable::Ptr selectable;
 			for (zypp::ResPoolProxy::const_iterator it = zypp->poolProxy().byKindBegin <zypp::Package>();
 					it != zypp->poolProxy().byKindEnd <zypp::Package>(); it++) {
-				if (strcmp ((*it)->name ().c_str (), pi->name) == 0) {
+				if (strcmp ((*it)->name ().c_str (), sections[0]) == 0) {
 					selectable = *it;
 					break;
 				}
@@ -1067,8 +1072,8 @@
 			// Choose the PoolItem with the right architecture and version
 			for (zypp::ui::Selectable::available_iterator it = selectable->availableBegin ();
 					it != selectable->availableEnd (); it++) {
-				if (strcmp ((*it)->edition ().asString ().c_str (), pi->version) == 0
-						&& strcmp ((*it)->arch ().c_str (), pi->arch) == 0 ) {
+				if (strcmp ((*it)->edition ().asString ().c_str (), sections[1]) == 0
+						&& strcmp ((*it)->arch ().c_str (), sections[2]) == 0 ) {
 					hit = true;
 					// set status to ToBeInstalled
 					it->status ().setToBeInstalled (zypp::ResStatus::USER);
@@ -1079,13 +1084,13 @@
 
 			if (!hit) {
 				pk_backend_error_code (backend, PK_ERROR_ENUM_PACKAGE_NOT_FOUND, "Couldn't find the package.");
-				pk_package_id_free (pi);
+				g_strfreev (sections);
 				pk_backend_finished (backend);
 				return FALSE;
 			}
 
 			pk_backend_set_percentage (backend, 40);
-			pk_package_id_free (pi);
+			g_strfreev (sections);
 		}
 
 		if (!zypp_perform_execution (backend, INSTALL, FALSE)) {
@@ -1146,7 +1151,8 @@
 backend_remove_packages_thread (PkBackend *backend)
 {
 	gchar **package_ids;
-	PkPackageId *pi;
+	gchar **sections;
+	gchar *pi;
 	std::vector<zypp::PoolItem> *items = new std::vector<zypp::PoolItem> ();
 
 	pk_backend_set_status (backend, PK_STATUS_ENUM_REMOVE);
@@ -1164,24 +1170,25 @@
 
 	package_ids = pk_backend_get_strv (backend, "package_ids");
 	for (guint i = 0; i < g_strv_length (package_ids); i++) {
-		pi = pk_package_id_new_from_string (package_ids[i]);
-		if (pi == NULL) {
+		pi = package_ids[i];
+		if (!pk_package_id_check(pi)) {
 			pk_backend_error_code (backend, PK_ERROR_ENUM_PACKAGE_ID_INVALID, "invalid package id");
 			pk_backend_finished (backend);
 			return FALSE;
 		}
+		sections = pk_package_id_split (pi);
 
 		// Iterate over the resolvables and mark the ones we want to remove
 		zypp::ResPool pool = zypp::ResPool::instance ();
-		for (zypp::ResPool::byIdent_iterator it = pool.byIdentBegin (zypp::ResKind::package, pi->name);
-				it != pool.byIdentEnd (zypp::ResKind::package, pi->name); it++) {
+		for (zypp::ResPool::byIdent_iterator it = pool.byIdentBegin (zypp::ResKind::package, sections[0]);
+				it != pool.byIdentEnd (zypp::ResKind::package, sections[0]); it++) {
 			if ((*it)->isSystem ()) {
 				it->status ().setToBeUninstalled (zypp::ResStatus::USER);
 				items->push_back (*it);
 				break;
 			}
 		}
-		pk_package_id_free (pi);
+		g_strfreev (sections);
 	}
 
 	pk_backend_set_percentage (backend, 40);
@@ -1491,26 +1498,26 @@
 static gboolean
 backend_get_files_thread (PkBackend *backend)
 {
-	PkPackageId *pi;
+	gchar *pi;
 	gchar **package_ids;
+	gchar **sections;
 
 	package_ids = pk_backend_get_strv (backend, "package_ids");
 
 	for(uint i = 0; i < g_strv_length(package_ids); i++) {
-		pi = pk_package_id_new_from_string (package_ids[i]);
-		if (pi == NULL) {
+		pi = package_ids[i];
+		if (!pk_package_id_check(pi)) {
 			pk_backend_error_code (backend, PK_ERROR_ENUM_PACKAGE_ID_INVALID, "invalid package id");
-			pk_package_id_free (pi);
-
 			pk_backend_finished (backend);
 			return FALSE;
 		}
+		sections = pk_package_id_split (pi);
 		pk_backend_set_status (backend, PK_STATUS_ENUM_QUERY);
 
 		std::vector<zypp::sat::Solvable> *v;
 		std::vector<zypp::sat::Solvable> *v2;
-		v = zypp_get_packages_by_name ((const gchar *)pi->name, zypp::ResKind::package, TRUE);
-		v2 = zypp_get_packages_by_name ((const gchar *)pi->name, zypp::ResKind::srcpackage, TRUE);
+		v = zypp_get_packages_by_name ((const gchar *)sections[0], zypp::ResKind::package, TRUE);
+		v2 = zypp_get_packages_by_name ((const gchar *)sections[0], zypp::ResKind::srcpackage, TRUE);
 
 		v->insert (v->end (), v2->begin (), v2->end ());
 
@@ -1518,7 +1525,7 @@
 		for (std::vector<zypp::sat::Solvable>::iterator it = v->begin ();
 				it != v->end (); it++) {
 			char *version = g_strdup (it->edition ().asString ().c_str ());
-			if (strcmp (pi->version, version) == 0) {
+			if (strcmp (sections[1], version) == 0) {
 				g_free (version);
 				package = *it;
 				break;
@@ -1531,8 +1538,7 @@
 
 		if (package == NULL) {
 			pk_backend_error_code (backend, PK_ERROR_ENUM_PACKAGE_NOT_FOUND, "couldn't find package");
-			pk_package_id_free (pi);
-
+			g_strfreev (sections);
 			pk_backend_finished (backend);
 			return FALSE;
 		}
@@ -1558,7 +1564,7 @@
 		}
 
 		pk_backend_files (backend, package_ids[i], temp.c_str ());	// file_list
-		pk_package_id_free (pi);
+		g_strfreev (sections);
 	}
 
 	pk_backend_finished (backend);
diff -urN PackageKit-0.5.6/backends/zypp/zypp-utils.cpp PackageKit-0.5.6-new/backends/zypp/zypp-utils.cpp
--- PackageKit-0.5.6/backends/zypp/zypp-utils.cpp	2009-12-04 06:05:37.000000000 +0800
+++ PackageKit-0.5.6-new/backends/zypp/zypp-utils.cpp	2009-12-20 18:52:55.000000000 +0800
@@ -53,7 +53,6 @@
 #include <zypp/base/Logger.h>
 
 #include <pk-backend.h>
-#include <packagekit-glib/packagekit.h>
 
 #include "zypp-utils.h"
 
@@ -393,15 +392,16 @@
 zypp::sat::Solvable
 zypp_get_package_by_id (const gchar *package_id)
 {
-	PkPackageId *pi;
-	pi = pk_package_id_new_from_string (package_id);
-	if (pi == NULL) {
+	gchar **sections;
+
+	if (!pk_package_id_check(package_id)) {
 		// TODO: Do we need to do something more for this error?
 		return zypp::sat::Solvable::noSolvable;
 	}
+	sections = pk_package_id_split (package_id);
 
-	std::vector<zypp::sat::Solvable> *v = zypp_get_packages_by_name (pi->name, zypp::ResKind::package, TRUE);
-	std::vector<zypp::sat::Solvable> *v2 = zypp_get_packages_by_name (pi->name, zypp::ResKind::patch, TRUE);
+	std::vector<zypp::sat::Solvable> *v = zypp_get_packages_by_name (sections[0], zypp::ResKind::package, TRUE);
+	std::vector<zypp::sat::Solvable> *v2 = zypp_get_packages_by_name (sections[0], zypp::ResKind::patch, TRUE);
 
 	v->insert (v->end (), v2->begin (), v2->end ());
 	
@@ -414,13 +414,14 @@
 			it != v->end (); it++) {
 		gchar *version = g_strdup (it->edition ().c_str ());
 		gchar *arch = g_strdup (it->arch ().c_str ());
-		if (strcmp (pi->version, version) == 0 && strcmp (pi->arch, arch) == 0) {
+		if (strcmp (sections[1], version) == 0 && strcmp (sections[2], arch) == 0) {
 			package = *it;
 			break;
 		}
 		g_free (version);
 		g_free (arch);
 	}
+	g_strfreev(sections);
 
 	delete (v);
 	delete (v2);
diff -urN PackageKit-0.5.6/lib/packagekit-glib2/pk-common.c PackageKit-0.5.6-new/lib/packagekit-glib2/pk-common.c
--- PackageKit-0.5.6/lib/packagekit-glib2/pk-common.c	2009-12-04 06:05:37.000000000 +0800
+++ PackageKit-0.5.6-new/lib/packagekit-glib2/pk-common.c	2009-12-20 19:25:24.000000000 +0800
@@ -129,6 +129,41 @@
 }
 
 /**
+ * pk_strsafe:
+ * @text: The input text to make safe
+ *
+ * Replaces chars in the text that may be dangerous, or that may print
+ * incorrectly. These chars include new lines, tabs and line feed, and are
+ * replaced by spaces.
+ *
+ * Return value: the new string with no insane chars
+ **/
+
+gchar *
+pk_strsafe (const gchar *text)
+{
+        gchar *text_safe;
+        gboolean ret;
+        const gchar *delimiters;
+
+        if (text == NULL)
+                return NULL;
+
+        /* is valid UTF8? */
+        ret = g_utf8_validate (text, -1, NULL);
+        if (!ret) {
+                egg_warning ("text '%s' was not valid UTF8!", text);
+                return NULL;
+        }
+
+        /* rip out any insane characters */
+        delimiters = "\\\f\r\t";
+        text_safe = g_strdup (text);
+        g_strdelimit (text_safe, delimiters, ' ');
+        return text_safe;
+}
+
+/**
  * pk_ptr_array_to_strv:
  * @array: the GPtrArray of strings
  *
diff -urN PackageKit-0.5.6/lib/packagekit-glib2/pk-common.h PackageKit-0.5.6-new/lib/packagekit-glib2/pk-common.h
--- PackageKit-0.5.6/lib/packagekit-glib2/pk-common.h	2009-12-04 06:05:37.000000000 +0800
+++ PackageKit-0.5.6-new/lib/packagekit-glib2/pk-common.h	2009-12-20 19:23:17.000000000 +0800
@@ -82,6 +82,8 @@
 } PkTristate;
 
 void		 pk_common_test				(gpointer	 user_data);
+gchar           *pk_strsafe                             (const gchar    *text)
+                                                         G_GNUC_WARN_UNUSED_RESULT;
 gchar		**pk_ptr_array_to_strv			(GPtrArray	*array)
 							 G_GNUC_WARN_UNUSED_RESULT;
 gchar		*pk_iso8601_present			(void)
