From 84e900d96fd7343302490e29a0702eac271c8282 Mon Sep 17 00:00:00 2001
From: Adam Magness <adam.magness@gmail.com>
Date: Sat, 3 Nov 2018 13:08:01 -0400
Subject: [PATCH 01/11] Move to XML

move functions from text to xml
---
 include/text.php | 98 +++---------------------------------------------
 src/Util/XML.php | 39 +++++++++++++++++++
 2 files changed, 44 insertions(+), 93 deletions(-)

diff --git a/include/text.php b/include/text.php
index 7f66268ad4..fadd375921 100644
--- a/include/text.php
+++ b/include/text.php
@@ -26,6 +26,7 @@ use Friendica\Util\Proxy as ProxyUtils;
 use Friendica\Core\Logger;
 use Friendica\Core\Renderer;
 use Friendica\Model\FileTag;
+use Friendica\Util\XML;
 
 require_once "include/conversation.php";
 
@@ -162,80 +163,6 @@ function autoname($len) {
 	return $word;
 }
 
-
-/**
- * escape text ($str) for XML transport
- * @param string $str
- * @return string Escaped text.
- */
-function xmlify($str) {
-	/// @TODO deprecated code found?
-/*	$buffer = '';
-
-	$len = mb_strlen($str);
-	for ($x = 0; $x < $len; $x ++) {
-		$char = mb_substr($str,$x,1);
-
-		switch($char) {
-
-			case "\r" :
-				break;
-			case "&" :
-				$buffer .= '&amp;';
-				break;
-			case "'" :
-				$buffer .= '&apos;';
-				break;
-			case "\"" :
-				$buffer .= '&quot;';
-				break;
-			case '<' :
-				$buffer .= '&lt;';
-				break;
-			case '>' :
-				$buffer .= '&gt;';
-				break;
-			case "\n" :
-				$buffer .= "\n";
-				break;
-			default :
-				$buffer .= $char;
-				break;
-		}
-	}*/
-	/*
-	$buffer = mb_ereg_replace("&", "&amp;", $str);
-	$buffer = mb_ereg_replace("'", "&apos;", $buffer);
-	$buffer = mb_ereg_replace('"', "&quot;", $buffer);
-	$buffer = mb_ereg_replace("<", "&lt;", $buffer);
-	$buffer = mb_ereg_replace(">", "&gt;", $buffer);
-	*/
-	$buffer = htmlspecialchars($str, ENT_QUOTES, "UTF-8");
-	$buffer = trim($buffer);
-
-	return $buffer;
-}
-
-
-/**
- * undo an xmlify
- * @param string $s xml escaped text
- * @return string unescaped text
- */
-function unxmlify($s) {
-	/// @TODO deprecated code found?
-//	$ret = str_replace('&amp;','&', $s);
-//	$ret = str_replace(array('&lt;','&gt;','&quot;','&apos;'),array('<','>','"',"'"),$ret);
-	/*$ret = mb_ereg_replace('&amp;', '&', $s);
-	$ret = mb_ereg_replace('&apos;', "'", $ret);
-	$ret = mb_ereg_replace('&quot;', '"', $ret);
-	$ret = mb_ereg_replace('&lt;', "<", $ret);
-	$ret = mb_ereg_replace('&gt;', ">", $ret);
-	*/
-	$ret = htmlspecialchars_decode($s, ENT_QUOTES);
-	return $ret;
-}
-
 /**
  * Loader for infinite scrolling
  * @return string html for loader
@@ -1047,9 +974,9 @@ function get_cats_and_terms($item)
 	if ($cnt) {
 		foreach ($matches as $mtch) {
 			$categories[] = [
-				'name' => xmlify(FileTag::decode($mtch[1])),
+				'name' => XML::xmlify(FileTag::decode($mtch[1])),
 				'url' =>  "#",
-				'removeurl' => ((local_user() == $item['uid'])?'filerm/' . $item['id'] . '?f=&cat=' . xmlify(FileTag::decode($mtch[1])):""),
+				'removeurl' => ((local_user() == $item['uid'])?'filerm/' . $item['id'] . '?f=&cat=' . XML::xmlify(FileTag::decode($mtch[1])):""),
 				'first' => $first,
 				'last' => false
 			];
@@ -1068,9 +995,9 @@ function get_cats_and_terms($item)
 		if ($cnt) {
 			foreach ($matches as $mtch) {
 				$folders[] = [
-					'name' => xmlify(FileTag::decode($mtch[1])),
+					'name' => XML::xmlify(FileTag::decode($mtch[1])),
 					'url' =>  "#",
-					'removeurl' => ((local_user() == $item['uid']) ? 'filerm/' . $item['id'] . '?f=&term=' . xmlify(FileTag::decode($mtch[1])) : ""),
+					'removeurl' => ((local_user() == $item['uid']) ? 'filerm/' . $item['id'] . '?f=&term=' . XML::xmlify(FileTag::decode($mtch[1])) : ""),
 					'first' => $first,
 					'last' => false
 				];
@@ -1234,21 +1161,6 @@ function html2bb_video($s) {
 	return $s;
 }
 
-/**
- * apply xmlify() to all values of array $val, recursively
- * @param array $val
- * @return array
- */
-function array_xmlify($val){
-	if (is_bool($val)) {
-		return $val?"true":"false";
-	} elseif (is_array($val)) {
-		return array_map('array_xmlify', $val);
-	}
-	return xmlify((string) $val);
-}
-
-
 /**
  * transform link href and img src from relative to absolute
  *
diff --git a/src/Util/XML.php b/src/Util/XML.php
index 865c60406b..9a3108ca98 100644
--- a/src/Util/XML.php
+++ b/src/Util/XML.php
@@ -462,4 +462,43 @@ class XML
 
 		return $first_item->attributes;
 	}
+
+	/**
+	 * escape text ($str) for XML transport
+	 * @param string $str
+	 * @return string Escaped text.
+	 */
+	public static function xmlify($str)
+	{
+		$buffer = htmlspecialchars($str, ENT_QUOTES, "UTF-8");
+		$buffer = trim($buffer);
+
+		return $buffer;
+	}
+
+	/**
+	 * undo an xmlify
+	 * @param string $s xml escaped text
+	 * @return string unescaped text
+	 */
+	public static function unxmlify($s)
+	{
+		$ret = htmlspecialchars_decode($s, ENT_QUOTES);
+		return $ret;
+	}
+
+	/**
+	 * apply xmlify() to all values of array $val, recursively
+	 * @param array $val
+	 * @return array
+	 */
+	public static function arrayXmlify($val)
+	{
+		if (is_bool($val)) {
+			return $val?"true":"false";
+		} elseif (is_array($val)) {
+			return array_map('XML::arrayXmlify', $val);
+		}
+		return self::xmlify((string) $val);
+	}
 }

From 61bc9facc8e32cf06834c9406a71ecfc4f7cac71 Mon Sep 17 00:00:00 2001
From: Adam Magness <adam.magness@gmail.com>
Date: Sat, 3 Nov 2018 13:08:30 -0400
Subject: [PATCH 02/11] Implement functions

implement functions relocated to xml class
---
 include/conversation.php  |   2 +-
 mod/dfrn_confirm.php      |   2 +-
 mod/filer.php             |   3 +-
 mod/filerm.php            |   5 +-
 mod/photos.php            |   7 +-
 mod/poco.php              |   3 +-
 mod/poke.php              |   5 +-
 mod/profile.php           |   3 +-
 mod/subthread.php         |   3 +-
 mod/tagger.php            |   7 +-
 src/Content/Widget.php    |   5 +-
 src/Model/Event.php       |   9 +--
 src/Protocol/DFRN.php     |   2 +-
 src/Protocol/Diaspora.php | 142 +++++++++++++++++++-------------------
 14 files changed, 104 insertions(+), 94 deletions(-)

diff --git a/include/conversation.php b/include/conversation.php
index c1d428f244..7a0bf6c400 100644
--- a/include/conversation.php
+++ b/include/conversation.php
@@ -195,7 +195,7 @@ function localize_item(&$item)
 		$xmlhead="<"."?xml version='1.0' encoding='UTF-8' ?".">";
 
 		$obj = XML::parseString($xmlhead.$item['object']);
-		$links = XML::parseString($xmlhead."<links>".unxmlify($obj->link)."</links>");
+		$links = XML::parseString($xmlhead."<links>".XML::unxmlify($obj->link)."</links>");
 
 		$Bname = $obj->title;
 		$Blink = "";
diff --git a/mod/dfrn_confirm.php b/mod/dfrn_confirm.php
index 0403085f85..6771a21575 100644
--- a/mod/dfrn_confirm.php
+++ b/mod/dfrn_confirm.php
@@ -256,7 +256,7 @@ function dfrn_confirm_post(App $a, $handsfree = null)
 
 			$xml = XML::parseString($res);
 			$status = (int) $xml->status;
-			$message = unxmlify($xml->message);   // human readable text of what may have gone wrong.
+			$message = XML::unxmlify($xml->message);   // human readable text of what may have gone wrong.
 			switch ($status) {
 				case 0:
 					info(L10n::t("Confirmation completed successfully.") . EOL);
diff --git a/mod/filer.php b/mod/filer.php
index 11a5dd0576..d61f67e1ef 100644
--- a/mod/filer.php
+++ b/mod/filer.php
@@ -8,6 +8,7 @@ use Friendica\Core\Logger;
 use Friendica\Core\PConfig;
 use Friendica\Core\Renderer;
 use Friendica\Model\FileTag;
+use Friendica\Util\XML;
 
 require_once 'include/items.php';
 
@@ -17,7 +18,7 @@ function filer_content(App $a)
 		killme();
 	}
 
-	$term = unxmlify(trim(defaults($_GET, 'term', '')));
+	$term = XML::unxmlify(trim(defaults($_GET, 'term', '')));
 	$item_id = (($a->argc > 1) ? intval($a->argv[1]) : 0);
 
 	Logger::log('filer: tag ' . $term . ' item ' . $item_id);
diff --git a/mod/filerm.php b/mod/filerm.php
index d899d8f3f2..60ac439bf8 100644
--- a/mod/filerm.php
+++ b/mod/filerm.php
@@ -4,6 +4,7 @@ use Friendica\App;
 use Friendica\Core\Logger;
 use Friendica\Core\System;
 use Friendica\Model\FileTag;
+use Friendica\Util\XML;
 
 function filerm_content(App $a)
 {
@@ -12,8 +13,8 @@ function filerm_content(App $a)
 		killme();
 	}
 
-	$term = unxmlify(trim($_GET['term']));
-	$cat = unxmlify(trim($_GET['cat']));
+	$term = XML::unxmlify(trim($_GET['term']));
+	$cat = XML::unxmlify(trim($_GET['cat']));
 
 	$category = (($cat) ? true : false);
 
diff --git a/mod/photos.php b/mod/photos.php
index 82a6ccca29..0deb164b39 100644
--- a/mod/photos.php
+++ b/mod/photos.php
@@ -30,6 +30,7 @@ use Friendica\Util\DateTimeFormat;
 use Friendica\Util\Map;
 use Friendica\Util\Security;
 use Friendica\Util\Temporal;
+use Friendica\Util\XML;
 
 require_once 'include/items.php';
 
@@ -682,15 +683,15 @@ function photos_post(App $a)
 					$arr['body'] .= "\n\n" . '[url=' . System::baseUrl() . '/photos/' . $owner_record['nickname'] . '/image/' . $p[0]['resource-id'] . ']' . '[img]' . System::baseUrl() . "/photo/" . $p[0]['resource-id'] . '-' . $best . '.' . $ext . '[/img][/url]' . "\n" ;
 
 					$arr['object'] = '<object><type>' . ACTIVITY_OBJ_PERSON . '</type><title>' . $tagged[0] . '</title><id>' . $tagged[1] . '/' . $tagged[0] . '</id>';
-					$arr['object'] .= '<link>' . xmlify('<link rel="alternate" type="text/html" href="' . $tagged[1] . '" />' . "\n");
+					$arr['object'] .= '<link>' . XML::xmlify('<link rel="alternate" type="text/html" href="' . $tagged[1] . '" />' . "\n");
 					if ($tagged[3]) {
-						$arr['object'] .= xmlify('<link rel="photo" type="'.$p[0]['type'].'" href="' . $tagged[3]['photo'] . '" />' . "\n");
+						$arr['object'] .= XML::xmlify('<link rel="photo" type="'.$p[0]['type'].'" href="' . $tagged[3]['photo'] . '" />' . "\n");
 					}
 					$arr['object'] .= '</link></object>' . "\n";
 
 					$arr['target'] = '<target><type>' . ACTIVITY_OBJ_IMAGE . '</type><title>' . $p[0]['desc'] . '</title><id>'
 						. System::baseUrl() . '/photos/' . $owner_record['nickname'] . '/image/' . $p[0]['resource-id'] . '</id>';
-					$arr['target'] .= '<link>' . xmlify('<link rel="alternate" type="text/html" href="' . System::baseUrl() . '/photos/' . $owner_record['nickname'] . '/image/' . $p[0]['resource-id'] . '" />' . "\n" . '<link rel="preview" type="'.$p[0]['type'].'" href="' . System::baseUrl() . "/photo/" . $p[0]['resource-id'] . '-' . $best . '.' . $ext . '" />') . '</link></target>';
+					$arr['target'] .= '<link>' . XML::xmlify('<link rel="alternate" type="text/html" href="' . System::baseUrl() . '/photos/' . $owner_record['nickname'] . '/image/' . $p[0]['resource-id'] . '" />' . "\n" . '<link rel="preview" type="'.$p[0]['type'].'" href="' . System::baseUrl() . "/photo/" . $p[0]['resource-id'] . '-' . $best . '.' . $ext . '" />') . '</link></target>';
 
 					$item_id = Item::insert($arr);
 				}
diff --git a/mod/poco.php b/mod/poco.php
index 41fabff4ea..119250f2fd 100644
--- a/mod/poco.php
+++ b/mod/poco.php
@@ -15,6 +15,7 @@ use Friendica\Core\System;
 use Friendica\Database\DBA;
 use Friendica\Protocol\PortableContact;
 use Friendica\Util\DateTimeFormat;
+use Friendica\Util\XML;
 
 function poco_init(App $a) {
 	$system_mode = false;
@@ -375,7 +376,7 @@ function poco_init(App $a) {
 
 	if ($format === 'xml') {
 		header('Content-type: text/xml');
-		echo Renderer::replaceMacros(Renderer::getMarkupTemplate('poco_xml.tpl'), array_xmlify(['$response' => $ret]));
+		echo Renderer::replaceMacros(Renderer::getMarkupTemplate('poco_xml.tpl'), XML::arrayXmlify(['$response' => $ret]));
 		killme();
 	}
 	if ($format === 'json') {
diff --git a/mod/poke.php b/mod/poke.php
index be26254384..e459be345f 100644
--- a/mod/poke.php
+++ b/mod/poke.php
@@ -22,6 +22,7 @@ use Friendica\Core\System;
 use Friendica\Core\Worker;
 use Friendica\Database\DBA;
 use Friendica\Model\Item;
+use Friendica\Util\XML;
 
 require_once 'include/items.php';
 
@@ -124,9 +125,9 @@ function poke_init(App $a)
 	$arr['body']          = '[url=' . $poster['url'] . ']' . $poster['name'] . '[/url]' . ' ' . L10n::t($verbs[$verb][0]) . ' ' . '[url=' . $target['url'] . ']' . $target['name'] . '[/url]';
 
 	$arr['object'] = '<object><type>' . ACTIVITY_OBJ_PERSON . '</type><title>' . $target['name'] . '</title><id>' . $target['url'] . '</id>';
-	$arr['object'] .= '<link>' . xmlify('<link rel="alternate" type="text/html" href="' . $target['url'] . '" />' . "\n");
+	$arr['object'] .= '<link>' . XML::xmlify('<link rel="alternate" type="text/html" href="' . $target['url'] . '" />' . "\n");
 
-	$arr['object'] .= xmlify('<link rel="photo" type="image/jpeg" href="' . $target['photo'] . '" />' . "\n");
+	$arr['object'] .= XML::xmlify('<link rel="photo" type="image/jpeg" href="' . $target['photo'] . '" />' . "\n");
 	$arr['object'] .= '</link></object>' . "\n";
 
 	$item_id = Item::insert($arr);
diff --git a/mod/profile.php b/mod/profile.php
index f2df82849e..b92b8453e6 100644
--- a/mod/profile.php
+++ b/mod/profile.php
@@ -24,6 +24,7 @@ use Friendica\Protocol\ActivityPub;
 use Friendica\Protocol\DFRN;
 use Friendica\Util\DateTimeFormat;
 use Friendica\Util\Security;
+use Friendica\Util\XML;
 
 function profile_init(App $a)
 {
@@ -209,7 +210,7 @@ function profile_content(App $a, $update = 0)
 		$commvisitor = $commpage && $remote_contact;
 
 		$a->page['aside'] .= posted_date_widget(System::baseUrl(true) . '/profile/' . $a->profile['nickname'], $a->profile['profile_uid'], true);
-		$a->page['aside'] .= Widget::categories(System::baseUrl(true) . '/profile/' . $a->profile['nickname'], (!empty($category) ? xmlify($category) : ''));
+		$a->page['aside'] .= Widget::categories(System::baseUrl(true) . '/profile/' . $a->profile['nickname'], (!empty($category) ? XML::xmlify($category) : ''));
 		$a->page['aside'] .= Widget::tagCloud();
 
 		if (Security::canWriteToUserWall($a->profile['profile_uid'])) {
diff --git a/mod/subthread.php b/mod/subthread.php
index 36cf835c28..7a8ada08b5 100644
--- a/mod/subthread.php
+++ b/mod/subthread.php
@@ -10,6 +10,7 @@ use Friendica\Core\System;
 use Friendica\Database\DBA;
 use Friendica\Model\Item;
 use Friendica\Util\Security;
+use Friendica\Util\XML;
 
 require_once 'include/items.php';
 
@@ -87,7 +88,7 @@ function subthread_content(App $a) {
 
 	$post_type = (($item['resource-id']) ? L10n::t('photo') : L10n::t('status'));
 	$objtype = (($item['resource-id']) ? ACTIVITY_OBJ_IMAGE : ACTIVITY_OBJ_NOTE );
-	$link = xmlify('<link rel="alternate" type="text/html" href="' . System::baseUrl() . '/display/' . $owner['nickname'] . '/' . $item['id'] . '" />' . "\n") ;
+	$link = XML::xmlify('<link rel="alternate" type="text/html" href="' . System::baseUrl() . '/display/' . $owner['nickname'] . '/' . $item['id'] . '" />' . "\n") ;
 	$body = $item['body'];
 
 	$obj = <<< EOT
diff --git a/mod/tagger.php b/mod/tagger.php
index edfcd7bd13..8b7e7d0040 100644
--- a/mod/tagger.php
+++ b/mod/tagger.php
@@ -10,6 +10,7 @@ use Friendica\Core\System;
 use Friendica\Core\Worker;
 use Friendica\Database\DBA;
 use Friendica\Model\Item;
+use Friendica\Util\XML;
 
 require_once 'include/items.php';
 
@@ -66,7 +67,7 @@ function tagger_content(App $a) {
 	}
 
 	$uri = Item::newURI($owner_uid);
-	$xterm = xmlify($term);
+	$xterm = XML::xmlify($term);
 	$post_type = (($item['resource-id']) ? L10n::t('photo') : L10n::t('status'));
 	$targettype = (($item['resource-id']) ? ACTIVITY_OBJ_IMAGE : ACTIVITY_OBJ_NOTE );
 
@@ -76,9 +77,9 @@ function tagger_content(App $a) {
 		$href = System::baseUrl() . '/display/' . $item['guid'];
 	}
 
-	$link = xmlify('<link rel="alternate" type="text/html" href="'. $href . '" />' . "\n") ;
+	$link = XML::xmlify('<link rel="alternate" type="text/html" href="'. $href . '" />' . "\n") ;
 
-	$body = xmlify($item['body']);
+	$body = XML::xmlify($item['body']);
 
 	$target = <<< EOT
 	<target>
diff --git a/src/Content/Widget.php b/src/Content/Widget.php
index 2f78d0fd3d..3e076729e1 100644
--- a/src/Content/Widget.php
+++ b/src/Content/Widget.php
@@ -18,6 +18,7 @@ use Friendica\Model\Contact;
 use Friendica\Model\FileTag;
 use Friendica\Model\GContact;
 use Friendica\Model\Profile;
+use Friendica\Util\XML;
 
 require_once 'boot.php';
 require_once 'include/dba.php';
@@ -189,7 +190,7 @@ class Widget
 		if ($cnt) {
 			foreach ($matches as $mtch)
 			{
-				$unescaped = xmlify(FileTag::decode($mtch[1]));
+				$unescaped = XML::xmlify(FileTag::decode($mtch[1]));
 				$terms[] = array('name' => $unescaped, 'selected' => (($selected == $unescaped) ? 'selected' : ''));
 			}
 		}
@@ -229,7 +230,7 @@ class Widget
 
 		if ($cnt) {
 			foreach ($matches as $mtch) {
-				$unescaped = xmlify(FileTag::decode($mtch[1]));
+				$unescaped = XML::xmlify(FileTag::decode($mtch[1]));
 				$terms[] = array('name' => $unescaped, 'selected' => (($selected == $unescaped) ? 'selected' : ''));
 			}
 		}
diff --git a/src/Model/Event.php b/src/Model/Event.php
index ee61149de5..1f0b44693f 100644
--- a/src/Model/Event.php
+++ b/src/Model/Event.php
@@ -17,6 +17,7 @@ use Friendica\Database\DBA;
 use Friendica\Model\Contact;
 use Friendica\Util\DateTimeFormat;
 use Friendica\Util\Map;
+use Friendica\Util\XML;
 
 require_once 'boot.php';
 require_once 'include/dba.php';
@@ -302,8 +303,8 @@ class Event extends BaseObject
 
 			$item = Item::selectFirst(['id'], ['event-id' => $event['id'], 'uid' => $event['uid']]);
 			if (DBA::isResult($item)) {
-				$object = '<object><type>' . xmlify(ACTIVITY_OBJ_EVENT) . '</type><title></title><id>' . xmlify($event['uri']) . '</id>';
-				$object .= '<content>' . xmlify(self::getBBCode($event)) . '</content>';
+				$object = '<object><type>' . XML::xmlify(ACTIVITY_OBJ_EVENT) . '</type><title></title><id>' . XML::xmlify($event['uri']) . '</id>';
+				$object .= '<content>' . XML::xmlify(self::getBBCode($event)) . '</content>';
 				$object .= '</object>' . "\n";
 
 				$fields = ['body' => self::getBBCode($event), 'object' => $object, 'edited' => $event['edited']];
@@ -353,8 +354,8 @@ class Event extends BaseObject
 			$item_arr['body']          = self::getBBCode($event);
 			$item_arr['event-id']      = $event['id'];
 
-			$item_arr['object']  = '<object><type>' . xmlify(ACTIVITY_OBJ_EVENT) . '</type><title></title><id>' . xmlify($event['uri']) . '</id>';
-			$item_arr['object'] .= '<content>' . xmlify(self::getBBCode($event)) . '</content>';
+			$item_arr['object']  = '<object><type>' . XML::xmlify(ACTIVITY_OBJ_EVENT) . '</type><title></title><id>' . XML::xmlify($event['uri']) . '</id>';
+			$item_arr['object'] .= '<content>' . XML::xmlify(self::getBBCode($event)) . '</content>';
 			$item_arr['object'] .= '</object>' . "\n";
 
 			$item_id = Item::insert($item_arr);
diff --git a/src/Protocol/DFRN.php b/src/Protocol/DFRN.php
index 07a56cf240..1b83beb0ed 100644
--- a/src/Protocol/DFRN.php
+++ b/src/Protocol/DFRN.php
@@ -2547,7 +2547,7 @@ class DFRN
 		$item["guid"] = XML::getFirstNodeValue($xpath, "dfrn:diaspora_guid/text()", $entry);
 
 		// We store the data from "dfrn:diaspora_signature" in a different table, this is done in "Item::insert"
-		$dsprsig = unxmlify(XML::getFirstNodeValue($xpath, "dfrn:diaspora_signature/text()", $entry));
+		$dsprsig = XML::unxmlify(XML::getFirstNodeValue($xpath, "dfrn:diaspora_signature/text()", $entry));
 		if ($dsprsig != "") {
 			$item["dsprsig"] = $dsprsig;
 		}
diff --git a/src/Protocol/Diaspora.php b/src/Protocol/Diaspora.php
index 66a19d839c..dccc3358bd 100644
--- a/src/Protocol/Diaspora.php
+++ b/src/Protocol/Diaspora.php
@@ -463,7 +463,7 @@ class Diaspora
 		}
 
 		return ['message' => (string)base64url_decode($base->data),
-				'author' => unxmlify($author_addr),
+				'author' => XML::unxmlify($author_addr),
 				'key' => (string)$key];
 	}
 
@@ -603,7 +603,7 @@ class Diaspora
 		Logger::log('Message verified.');
 
 		return ['message' => (string)$inner_decrypted,
-				'author' => unxmlify($author_link),
+				'author' => XML::unxmlify($author_link),
 				'key' => (string)$key];
 	}
 
@@ -1505,9 +1505,9 @@ class Diaspora
 	 */
 	private static function receiveAccountMigration(array $importer, $data)
 	{
-		$old_handle = notags(unxmlify($data->author));
-		$new_handle = notags(unxmlify($data->profile->author));
-		$signature = notags(unxmlify($data->signature));
+		$old_handle = notags(XML::unxmlify($data->author));
+		$new_handle = notags(XML::unxmlify($data->profile->author));
+		$signature = notags(XML::unxmlify($data->signature));
 
 		$contact = self::contactByHandle($importer["uid"], $old_handle);
 		if (!$contact) {
@@ -1565,7 +1565,7 @@ class Diaspora
 	 */
 	private static function receiveAccountDeletion($data)
 	{
-		$author = notags(unxmlify($data->author));
+		$author = notags(XML::unxmlify($data->author));
 
 		$contacts = DBA::select('contact', ['id'], ['addr' => $author]);
 		while ($contact = DBA::fetch($contacts)) {
@@ -1656,19 +1656,19 @@ class Diaspora
 	 */
 	private static function receiveComment(array $importer, $sender, $data, $xml)
 	{
-		$author = notags(unxmlify($data->author));
-		$guid = notags(unxmlify($data->guid));
-		$parent_guid = notags(unxmlify($data->parent_guid));
-		$text = unxmlify($data->text);
+		$author = notags(XML::unxmlify($data->author));
+		$guid = notags(XML::unxmlify($data->guid));
+		$parent_guid = notags(XML::unxmlify($data->parent_guid));
+		$text = XML::unxmlify($data->text);
 
 		if (isset($data->created_at)) {
-			$created_at = DateTimeFormat::utc(notags(unxmlify($data->created_at)));
+			$created_at = DateTimeFormat::utc(notags(XML::unxmlify($data->created_at)));
 		} else {
 			$created_at = DateTimeFormat::utcNow();
 		}
 
 		if (isset($data->thread_parent_guid)) {
-			$thread_parent_guid = notags(unxmlify($data->thread_parent_guid));
+			$thread_parent_guid = notags(XML::unxmlify($data->thread_parent_guid));
 			$thr_uri = self::getUriFromGuid("", $thread_parent_guid, true);
 		} else {
 			$thr_uri = "";
@@ -1773,24 +1773,24 @@ class Diaspora
 	 */
 	private static function receiveConversationMessage(array $importer, array $contact, $data, $msg, $mesg, $conversation)
 	{
-		$author = notags(unxmlify($data->author));
-		$guid = notags(unxmlify($data->guid));
-		$subject = notags(unxmlify($data->subject));
+		$author = notags(XML::unxmlify($data->author));
+		$guid = notags(XML::unxmlify($data->guid));
+		$subject = notags(XML::unxmlify($data->subject));
 
 		// "diaspora_handle" is the element name from the old version
 		// "author" is the element name from the new version
 		if ($mesg->author) {
-			$msg_author = notags(unxmlify($mesg->author));
+			$msg_author = notags(XML::unxmlify($mesg->author));
 		} elseif ($mesg->diaspora_handle) {
-			$msg_author = notags(unxmlify($mesg->diaspora_handle));
+			$msg_author = notags(XML::unxmlify($mesg->diaspora_handle));
 		} else {
 			return false;
 		}
 
-		$msg_guid = notags(unxmlify($mesg->guid));
-		$msg_conversation_guid = notags(unxmlify($mesg->conversation_guid));
-		$msg_text = unxmlify($mesg->text);
-		$msg_created_at = DateTimeFormat::utc(notags(unxmlify($mesg->created_at)));
+		$msg_guid = notags(XML::unxmlify($mesg->guid));
+		$msg_conversation_guid = notags(XML::unxmlify($mesg->conversation_guid));
+		$msg_text = XML::unxmlify($mesg->text);
+		$msg_created_at = DateTimeFormat::utc(notags(XML::unxmlify($mesg->created_at)));
 
 		if ($msg_conversation_guid != $guid) {
 			Logger::log("message conversation guid does not belong to the current conversation.");
@@ -1861,11 +1861,11 @@ class Diaspora
 	 */
 	private static function receiveConversation(array $importer, $msg, $data)
 	{
-		$author = notags(unxmlify($data->author));
-		$guid = notags(unxmlify($data->guid));
-		$subject = notags(unxmlify($data->subject));
-		$created_at = DateTimeFormat::utc(notags(unxmlify($data->created_at)));
-		$participants = notags(unxmlify($data->participants));
+		$author = notags(XML::unxmlify($data->author));
+		$guid = notags(XML::unxmlify($data->guid));
+		$subject = notags(XML::unxmlify($data->subject));
+		$created_at = DateTimeFormat::utc(notags(XML::unxmlify($data->created_at)));
+		$participants = notags(XML::unxmlify($data->participants));
 
 		$messages = $data->message;
 
@@ -1919,11 +1919,11 @@ class Diaspora
 	 */
 	private static function receiveLike(array $importer, $sender, $data)
 	{
-		$author = notags(unxmlify($data->author));
-		$guid = notags(unxmlify($data->guid));
-		$parent_guid = notags(unxmlify($data->parent_guid));
-		$parent_type = notags(unxmlify($data->parent_type));
-		$positive = notags(unxmlify($data->positive));
+		$author = notags(XML::unxmlify($data->author));
+		$guid = notags(XML::unxmlify($data->guid));
+		$parent_guid = notags(XML::unxmlify($data->parent_guid));
+		$parent_type = notags(XML::unxmlify($data->parent_type));
+		$positive = notags(XML::unxmlify($data->positive));
 
 		// likes on comments aren't supported by Diaspora - only on posts
 		// But maybe this will be supported in the future, so we will accept it.
@@ -2028,11 +2028,11 @@ class Diaspora
 	 */
 	private static function receiveMessage(array $importer, $data)
 	{
-		$author = notags(unxmlify($data->author));
-		$guid = notags(unxmlify($data->guid));
-		$conversation_guid = notags(unxmlify($data->conversation_guid));
-		$text = unxmlify($data->text);
-		$created_at = DateTimeFormat::utc(notags(unxmlify($data->created_at)));
+		$author = notags(XML::unxmlify($data->author));
+		$guid = notags(XML::unxmlify($data->guid));
+		$conversation_guid = notags(XML::unxmlify($data->conversation_guid));
+		$text = XML::unxmlify($data->text);
+		$created_at = DateTimeFormat::utc(notags(XML::unxmlify($data->created_at)));
 
 		$contact = self::allowedContactByHandle($importer, $author, true);
 		if (!$contact) {
@@ -2103,8 +2103,8 @@ class Diaspora
 	 */
 	private static function receiveParticipation(array $importer, $data)
 	{
-		$author = strtolower(notags(unxmlify($data->author)));
-		$parent_guid = notags(unxmlify($data->parent_guid));
+		$author = strtolower(notags(XML::unxmlify($data->author)));
+		$parent_guid = notags(XML::unxmlify($data->parent_guid));
 
 		$contact_id = Contact::getIdForURL($author);
 		if (!$contact_id) {
@@ -2196,22 +2196,22 @@ class Diaspora
 	 */
 	private static function receiveProfile(array $importer, $data)
 	{
-		$author = strtolower(notags(unxmlify($data->author)));
+		$author = strtolower(notags(XML::unxmlify($data->author)));
 
 		$contact = self::contactByHandle($importer["uid"], $author);
 		if (!$contact) {
 			return false;
 		}
 
-		$name = unxmlify($data->first_name).((strlen($data->last_name)) ? " ".unxmlify($data->last_name) : "");
-		$image_url = unxmlify($data->image_url);
-		$birthday = unxmlify($data->birthday);
-		$gender = unxmlify($data->gender);
-		$about = Markdown::toBBCode(unxmlify($data->bio));
-		$location = Markdown::toBBCode(unxmlify($data->location));
-		$searchable = (unxmlify($data->searchable) == "true");
-		$nsfw = (unxmlify($data->nsfw) == "true");
-		$tags = unxmlify($data->tag_string);
+		$name = XML::unxmlify($data->first_name).((strlen($data->last_name)) ? " ".XML::unxmlify($data->last_name) : "");
+		$image_url = XML::unxmlify($data->image_url);
+		$birthday = XML::unxmlify($data->birthday);
+		$gender = XML::unxmlify($data->gender);
+		$about = Markdown::toBBCode(XML::unxmlify($data->bio));
+		$location = Markdown::toBBCode(XML::unxmlify($data->location));
+		$searchable = (XML::unxmlify($data->searchable) == "true");
+		$nsfw = (XML::unxmlify($data->nsfw) == "true");
+		$tags = XML::unxmlify($data->tag_string);
 
 		$tags = explode("#", $tags);
 
@@ -2310,8 +2310,8 @@ class Diaspora
 	 */
 	private static function receiveContactRequest(array $importer, $data)
 	{
-		$author = unxmlify($data->author);
-		$recipient = unxmlify($data->recipient);
+		$author = XML::unxmlify($data->author);
+		$recipient = XML::unxmlify($data->recipient);
 
 		if (!$author || !$recipient) {
 			return false;
@@ -2320,13 +2320,13 @@ class Diaspora
 		// the current protocol version doesn't know these fields
 		// That means that we will assume their existance
 		if (isset($data->following)) {
-			$following = (unxmlify($data->following) == "true");
+			$following = (XML::unxmlify($data->following) == "true");
 		} else {
 			$following = true;
 		}
 
 		if (isset($data->sharing)) {
-			$sharing = (unxmlify($data->sharing) == "true");
+			$sharing = (XML::unxmlify($data->sharing) == "true");
 		} else {
 			$sharing = true;
 		}
@@ -2573,13 +2573,13 @@ class Diaspora
 	 */
 	private static function receiveReshare(array $importer, $data, $xml)
 	{
-		$author = notags(unxmlify($data->author));
-		$guid = notags(unxmlify($data->guid));
-		$created_at = DateTimeFormat::utc(notags(unxmlify($data->created_at)));
-		$root_author = notags(unxmlify($data->root_author));
-		$root_guid = notags(unxmlify($data->root_guid));
+		$author = notags(XML::unxmlify($data->author));
+		$guid = notags(XML::unxmlify($data->guid));
+		$created_at = DateTimeFormat::utc(notags(XML::unxmlify($data->created_at)));
+		$root_author = notags(XML::unxmlify($data->root_author));
+		$root_guid = notags(XML::unxmlify($data->root_guid));
 		/// @todo handle unprocessed property "provider_display_name"
-		$public = notags(unxmlify($data->public));
+		$public = notags(XML::unxmlify($data->public));
 
 		$contact = self::allowedContactByHandle($importer, $author, false);
 		if (!$contact) {
@@ -2665,9 +2665,9 @@ class Diaspora
 	 */
 	private static function itemRetraction(array $importer, array $contact, $data)
 	{
-		$author = notags(unxmlify($data->author));
-		$target_guid = notags(unxmlify($data->target_guid));
-		$target_type = notags(unxmlify($data->target_type));
+		$author = notags(XML::unxmlify($data->author));
+		$target_guid = notags(XML::unxmlify($data->target_guid));
+		$target_type = notags(XML::unxmlify($data->target_type));
 
 		$person = self::personByHandle($author);
 		if (!is_array($person)) {
@@ -2729,7 +2729,7 @@ class Diaspora
 	 */
 	private static function receiveRetraction(array $importer, $sender, $data)
 	{
-		$target_type = notags(unxmlify($data->target_type));
+		$target_type = notags(XML::unxmlify($data->target_type));
 
 		$contact = self::contactByHandle($importer["uid"], $sender);
 		if (!$contact && (in_array($target_type, ["Contact", "Person"]))) {
@@ -2774,12 +2774,12 @@ class Diaspora
 	 */
 	private static function receiveStatusMessage(array $importer, SimpleXMLElement $data, $xml)
 	{
-		$author = notags(unxmlify($data->author));
-		$guid = notags(unxmlify($data->guid));
-		$created_at = DateTimeFormat::utc(notags(unxmlify($data->created_at)));
-		$public = notags(unxmlify($data->public));
-		$text = unxmlify($data->text);
-		$provider_display_name = notags(unxmlify($data->provider_display_name));
+		$author = notags(XML::unxmlify($data->author));
+		$guid = notags(XML::unxmlify($data->guid));
+		$created_at = DateTimeFormat::utc(notags(XML::unxmlify($data->created_at)));
+		$public = notags(XML::unxmlify($data->public));
+		$text = XML::unxmlify($data->text);
+		$provider_display_name = notags(XML::unxmlify($data->provider_display_name));
 
 		$contact = self::allowedContactByHandle($importer, $author, false);
 		if (!$contact) {
@@ -2794,7 +2794,7 @@ class Diaspora
 		$address = [];
 		if ($data->location) {
 			foreach ($data->location->children() as $fieldname => $data) {
-				$address[$fieldname] = notags(unxmlify($data));
+				$address[$fieldname] = notags(XML::unxmlify($data));
 			}
 		}
 
@@ -2805,8 +2805,8 @@ class Diaspora
 		// Attach embedded pictures to the body
 		if ($data->photo) {
 			foreach ($data->photo as $photo) {
-				$body = "[img]".unxmlify($photo->remote_photo_path).
-					unxmlify($photo->remote_photo_name)."[/img]\n".$body;
+				$body = "[img]".XML::unxmlify($photo->remote_photo_path).
+					XML::unxmlify($photo->remote_photo_name)."[/img]\n".$body;
 			}
 
 			$datarray["object-type"] = ACTIVITY_OBJ_IMAGE;

From ae4aab872ff98151639729997306ed9a7a3aa1cf Mon Sep 17 00:00:00 2001
From: Adam Magness <adam.magness@gmail.com>
Date: Sat, 3 Nov 2018 13:25:00 -0400
Subject: [PATCH 03/11] forgotten self

forgotten self references
---
 src/Util/XML.php | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/src/Util/XML.php b/src/Util/XML.php
index 9a3108ca98..6ba6d14f14 100644
--- a/src/Util/XML.php
+++ b/src/Util/XML.php
@@ -36,7 +36,7 @@ class XML
 					$root = new SimpleXMLElement("<".$key."/>");
 					self::fromArray($value, $root, $remove_header, $namespaces, false);
 				} else {
-					$root = new SimpleXMLElement("<".$key.">".xmlify($value)."</".$key.">");
+					$root = new SimpleXMLElement("<".$key.">".self::xmlify($value)."</".$key.">");
 				}
 
 				$dom = dom_import_simplexml($root)->ownerDocument;
@@ -104,7 +104,7 @@ class XML
 			}
 
 			if (!is_array($value)) {
-				$element = $xml->addChild($key, xmlify($value), $namespace);
+				$element = $xml->addChild($key, self::xmlify($value), $namespace);
 			} elseif (is_array($value)) {
 				$element = $xml->addChild($key, null, $namespace);
 				self::fromArray($value, $element, $remove_header, $namespaces, false);
@@ -123,7 +123,7 @@ class XML
 	public static function copy(&$source, &$target, $elementname)
 	{
 		if (count($source->children()) == 0) {
-			$target->addChild($elementname, xmlify($source));
+			$target->addChild($elementname, self::xmlify($source));
 		} else {
 			$child = $target->addChild($elementname);
 			foreach ($source->children() as $childfield => $childentry) {
@@ -144,11 +144,11 @@ class XML
 	 */
 	public static function createElement($doc, $element, $value = "", $attributes = [])
 	{
-		$element = $doc->createElement($element, xmlify($value));
+		$element = $doc->createElement($element, self::xmlify($value));
 
 		foreach ($attributes as $key => $value) {
 			$attribute = $doc->createAttribute($key);
-			$attribute->value = xmlify($value);
+			$attribute->value = self::xmlify($value);
 			$element->appendChild($attribute);
 		}
 		return $element;

From 6cc339031abfebabfc4326ecc1ae0fb1e69fa1f6 Mon Sep 17 00:00:00 2001
From: Adam Magness <adam.magness@gmail.com>
Date: Sun, 4 Nov 2018 08:21:37 -0500
Subject: [PATCH 04/11] Rename functions

rename functions
---
 src/Util/XML.php | 24 ++++++++++++------------
 1 file changed, 12 insertions(+), 12 deletions(-)

diff --git a/src/Util/XML.php b/src/Util/XML.php
index 6ba6d14f14..c115e4d0de 100644
--- a/src/Util/XML.php
+++ b/src/Util/XML.php
@@ -36,7 +36,7 @@ class XML
 					$root = new SimpleXMLElement("<".$key."/>");
 					self::fromArray($value, $root, $remove_header, $namespaces, false);
 				} else {
-					$root = new SimpleXMLElement("<".$key.">".self::xmlify($value)."</".$key.">");
+					$root = new SimpleXMLElement("<".$key.">".self::escape($value)."</".$key.">");
 				}
 
 				$dom = dom_import_simplexml($root)->ownerDocument;
@@ -104,7 +104,7 @@ class XML
 			}
 
 			if (!is_array($value)) {
-				$element = $xml->addChild($key, self::xmlify($value), $namespace);
+				$element = $xml->addChild($key, self::escape($value), $namespace);
 			} elseif (is_array($value)) {
 				$element = $xml->addChild($key, null, $namespace);
 				self::fromArray($value, $element, $remove_header, $namespaces, false);
@@ -123,7 +123,7 @@ class XML
 	public static function copy(&$source, &$target, $elementname)
 	{
 		if (count($source->children()) == 0) {
-			$target->addChild($elementname, self::xmlify($source));
+			$target->addChild($elementname, self::escape($source));
 		} else {
 			$child = $target->addChild($elementname);
 			foreach ($source->children() as $childfield => $childentry) {
@@ -144,11 +144,11 @@ class XML
 	 */
 	public static function createElement($doc, $element, $value = "", $attributes = [])
 	{
-		$element = $doc->createElement($element, self::xmlify($value));
+		$element = $doc->createElement($element, self::escape($value));
 
 		foreach ($attributes as $key => $value) {
 			$attribute = $doc->createAttribute($key);
-			$attribute->value = self::xmlify($value);
+			$attribute->value = self::escape($value);
 			$element->appendChild($attribute);
 		}
 		return $element;
@@ -468,7 +468,7 @@ class XML
 	 * @param string $str
 	 * @return string Escaped text.
 	 */
-	public static function xmlify($str)
+	public static function escape($str)
 	{
 		$buffer = htmlspecialchars($str, ENT_QUOTES, "UTF-8");
 		$buffer = trim($buffer);
@@ -477,28 +477,28 @@ class XML
 	}
 
 	/**
-	 * undo an xmlify
+	 * undo an escape
 	 * @param string $s xml escaped text
 	 * @return string unescaped text
 	 */
-	public static function unxmlify($s)
+	public static function unescape($s)
 	{
 		$ret = htmlspecialchars_decode($s, ENT_QUOTES);
 		return $ret;
 	}
 
 	/**
-	 * apply xmlify() to all values of array $val, recursively
+	 * apply escape() to all values of array $val, recursively
 	 * @param array $val
 	 * @return array
 	 */
-	public static function arrayXmlify($val)
+	public static function arrayEscape($val)
 	{
 		if (is_bool($val)) {
 			return $val?"true":"false";
 		} elseif (is_array($val)) {
-			return array_map('XML::arrayXmlify', $val);
+			return array_map('XML::arrayEscape', $val);
 		}
-		return self::xmlify((string) $val);
+		return self::escape((string) $val);
 	}
 }

From b07d47b0f78c93543b742b04446a923a474e25fc Mon Sep 17 00:00:00 2001
From: Adam Magness <adam.magness@gmail.com>
Date: Sun, 4 Nov 2018 08:23:19 -0500
Subject: [PATCH 05/11] Update function calls

update function calls to new names
---
 include/conversation.php  |   2 +-
 include/text.php          |   8 +--
 mod/dfrn_confirm.php      |   2 +-
 mod/filer.php             |   2 +-
 mod/filerm.php            |   4 +-
 mod/photos.php            |   6 +-
 mod/poco.php              |   2 +-
 mod/poke.php              |   4 +-
 mod/profile.php           |   2 +-
 mod/subthread.php         |   2 +-
 mod/tagger.php            |   6 +-
 src/Content/Widget.php    |   4 +-
 src/Model/Event.php       |   8 +--
 src/Protocol/DFRN.php     |   2 +-
 src/Protocol/Diaspora.php | 142 +++++++++++++++++++-------------------
 15 files changed, 98 insertions(+), 98 deletions(-)

diff --git a/include/conversation.php b/include/conversation.php
index 7a0bf6c400..c10a7bec73 100644
--- a/include/conversation.php
+++ b/include/conversation.php
@@ -195,7 +195,7 @@ function localize_item(&$item)
 		$xmlhead="<"."?xml version='1.0' encoding='UTF-8' ?".">";
 
 		$obj = XML::parseString($xmlhead.$item['object']);
-		$links = XML::parseString($xmlhead."<links>".XML::unxmlify($obj->link)."</links>");
+		$links = XML::parseString($xmlhead."<links>".XML::unescape($obj->link)."</links>");
 
 		$Bname = $obj->title;
 		$Blink = "";
diff --git a/include/text.php b/include/text.php
index fadd375921..5da54b5fc9 100644
--- a/include/text.php
+++ b/include/text.php
@@ -974,9 +974,9 @@ function get_cats_and_terms($item)
 	if ($cnt) {
 		foreach ($matches as $mtch) {
 			$categories[] = [
-				'name' => XML::xmlify(FileTag::decode($mtch[1])),
+				'name' => XML::escape(FileTag::decode($mtch[1])),
 				'url' =>  "#",
-				'removeurl' => ((local_user() == $item['uid'])?'filerm/' . $item['id'] . '?f=&cat=' . XML::xmlify(FileTag::decode($mtch[1])):""),
+				'removeurl' => ((local_user() == $item['uid'])?'filerm/' . $item['id'] . '?f=&cat=' . XML::escape(FileTag::decode($mtch[1])):""),
 				'first' => $first,
 				'last' => false
 			];
@@ -995,9 +995,9 @@ function get_cats_and_terms($item)
 		if ($cnt) {
 			foreach ($matches as $mtch) {
 				$folders[] = [
-					'name' => XML::xmlify(FileTag::decode($mtch[1])),
+					'name' => XML::escape(FileTag::decode($mtch[1])),
 					'url' =>  "#",
-					'removeurl' => ((local_user() == $item['uid']) ? 'filerm/' . $item['id'] . '?f=&term=' . XML::xmlify(FileTag::decode($mtch[1])) : ""),
+					'removeurl' => ((local_user() == $item['uid']) ? 'filerm/' . $item['id'] . '?f=&term=' . XML::escape(FileTag::decode($mtch[1])) : ""),
 					'first' => $first,
 					'last' => false
 				];
diff --git a/mod/dfrn_confirm.php b/mod/dfrn_confirm.php
index 6771a21575..0f001b11a2 100644
--- a/mod/dfrn_confirm.php
+++ b/mod/dfrn_confirm.php
@@ -256,7 +256,7 @@ function dfrn_confirm_post(App $a, $handsfree = null)
 
 			$xml = XML::parseString($res);
 			$status = (int) $xml->status;
-			$message = XML::unxmlify($xml->message);   // human readable text of what may have gone wrong.
+			$message = XML::unescape($xml->message);   // human readable text of what may have gone wrong.
 			switch ($status) {
 				case 0:
 					info(L10n::t("Confirmation completed successfully.") . EOL);
diff --git a/mod/filer.php b/mod/filer.php
index d61f67e1ef..3508079400 100644
--- a/mod/filer.php
+++ b/mod/filer.php
@@ -18,7 +18,7 @@ function filer_content(App $a)
 		killme();
 	}
 
-	$term = XML::unxmlify(trim(defaults($_GET, 'term', '')));
+	$term = XML::unescape(trim(defaults($_GET, 'term', '')));
 	$item_id = (($a->argc > 1) ? intval($a->argv[1]) : 0);
 
 	Logger::log('filer: tag ' . $term . ' item ' . $item_id);
diff --git a/mod/filerm.php b/mod/filerm.php
index 60ac439bf8..335b27b320 100644
--- a/mod/filerm.php
+++ b/mod/filerm.php
@@ -13,8 +13,8 @@ function filerm_content(App $a)
 		killme();
 	}
 
-	$term = XML::unxmlify(trim($_GET['term']));
-	$cat = XML::unxmlify(trim($_GET['cat']));
+	$term = XML::unescape(trim($_GET['term']));
+	$cat = XML::unescape(trim($_GET['cat']));
 
 	$category = (($cat) ? true : false);
 
diff --git a/mod/photos.php b/mod/photos.php
index 0deb164b39..69b1972d4c 100644
--- a/mod/photos.php
+++ b/mod/photos.php
@@ -683,15 +683,15 @@ function photos_post(App $a)
 					$arr['body'] .= "\n\n" . '[url=' . System::baseUrl() . '/photos/' . $owner_record['nickname'] . '/image/' . $p[0]['resource-id'] . ']' . '[img]' . System::baseUrl() . "/photo/" . $p[0]['resource-id'] . '-' . $best . '.' . $ext . '[/img][/url]' . "\n" ;
 
 					$arr['object'] = '<object><type>' . ACTIVITY_OBJ_PERSON . '</type><title>' . $tagged[0] . '</title><id>' . $tagged[1] . '/' . $tagged[0] . '</id>';
-					$arr['object'] .= '<link>' . XML::xmlify('<link rel="alternate" type="text/html" href="' . $tagged[1] . '" />' . "\n");
+					$arr['object'] .= '<link>' . XML::escape('<link rel="alternate" type="text/html" href="' . $tagged[1] . '" />' . "\n");
 					if ($tagged[3]) {
-						$arr['object'] .= XML::xmlify('<link rel="photo" type="'.$p[0]['type'].'" href="' . $tagged[3]['photo'] . '" />' . "\n");
+						$arr['object'] .= XML::escape('<link rel="photo" type="'.$p[0]['type'].'" href="' . $tagged[3]['photo'] . '" />' . "\n");
 					}
 					$arr['object'] .= '</link></object>' . "\n";
 
 					$arr['target'] = '<target><type>' . ACTIVITY_OBJ_IMAGE . '</type><title>' . $p[0]['desc'] . '</title><id>'
 						. System::baseUrl() . '/photos/' . $owner_record['nickname'] . '/image/' . $p[0]['resource-id'] . '</id>';
-					$arr['target'] .= '<link>' . XML::xmlify('<link rel="alternate" type="text/html" href="' . System::baseUrl() . '/photos/' . $owner_record['nickname'] . '/image/' . $p[0]['resource-id'] . '" />' . "\n" . '<link rel="preview" type="'.$p[0]['type'].'" href="' . System::baseUrl() . "/photo/" . $p[0]['resource-id'] . '-' . $best . '.' . $ext . '" />') . '</link></target>';
+					$arr['target'] .= '<link>' . XML::escape('<link rel="alternate" type="text/html" href="' . System::baseUrl() . '/photos/' . $owner_record['nickname'] . '/image/' . $p[0]['resource-id'] . '" />' . "\n" . '<link rel="preview" type="'.$p[0]['type'].'" href="' . System::baseUrl() . "/photo/" . $p[0]['resource-id'] . '-' . $best . '.' . $ext . '" />') . '</link></target>';
 
 					$item_id = Item::insert($arr);
 				}
diff --git a/mod/poco.php b/mod/poco.php
index 119250f2fd..08677ef8d4 100644
--- a/mod/poco.php
+++ b/mod/poco.php
@@ -376,7 +376,7 @@ function poco_init(App $a) {
 
 	if ($format === 'xml') {
 		header('Content-type: text/xml');
-		echo Renderer::replaceMacros(Renderer::getMarkupTemplate('poco_xml.tpl'), XML::arrayXmlify(['$response' => $ret]));
+		echo Renderer::replaceMacros(Renderer::getMarkupTemplate('poco_xml.tpl'), XML::arrayEscape(['$response' => $ret]));
 		killme();
 	}
 	if ($format === 'json') {
diff --git a/mod/poke.php b/mod/poke.php
index e459be345f..60ed5c402e 100644
--- a/mod/poke.php
+++ b/mod/poke.php
@@ -125,9 +125,9 @@ function poke_init(App $a)
 	$arr['body']          = '[url=' . $poster['url'] . ']' . $poster['name'] . '[/url]' . ' ' . L10n::t($verbs[$verb][0]) . ' ' . '[url=' . $target['url'] . ']' . $target['name'] . '[/url]';
 
 	$arr['object'] = '<object><type>' . ACTIVITY_OBJ_PERSON . '</type><title>' . $target['name'] . '</title><id>' . $target['url'] . '</id>';
-	$arr['object'] .= '<link>' . XML::xmlify('<link rel="alternate" type="text/html" href="' . $target['url'] . '" />' . "\n");
+	$arr['object'] .= '<link>' . XML::escape('<link rel="alternate" type="text/html" href="' . $target['url'] . '" />' . "\n");
 
-	$arr['object'] .= XML::xmlify('<link rel="photo" type="image/jpeg" href="' . $target['photo'] . '" />' . "\n");
+	$arr['object'] .= XML::escape('<link rel="photo" type="image/jpeg" href="' . $target['photo'] . '" />' . "\n");
 	$arr['object'] .= '</link></object>' . "\n";
 
 	$item_id = Item::insert($arr);
diff --git a/mod/profile.php b/mod/profile.php
index b92b8453e6..cfbe07dadb 100644
--- a/mod/profile.php
+++ b/mod/profile.php
@@ -210,7 +210,7 @@ function profile_content(App $a, $update = 0)
 		$commvisitor = $commpage && $remote_contact;
 
 		$a->page['aside'] .= posted_date_widget(System::baseUrl(true) . '/profile/' . $a->profile['nickname'], $a->profile['profile_uid'], true);
-		$a->page['aside'] .= Widget::categories(System::baseUrl(true) . '/profile/' . $a->profile['nickname'], (!empty($category) ? XML::xmlify($category) : ''));
+		$a->page['aside'] .= Widget::categories(System::baseUrl(true) . '/profile/' . $a->profile['nickname'], (!empty($category) ? XML::escape($category) : ''));
 		$a->page['aside'] .= Widget::tagCloud();
 
 		if (Security::canWriteToUserWall($a->profile['profile_uid'])) {
diff --git a/mod/subthread.php b/mod/subthread.php
index 7a8ada08b5..425306b6f7 100644
--- a/mod/subthread.php
+++ b/mod/subthread.php
@@ -88,7 +88,7 @@ function subthread_content(App $a) {
 
 	$post_type = (($item['resource-id']) ? L10n::t('photo') : L10n::t('status'));
 	$objtype = (($item['resource-id']) ? ACTIVITY_OBJ_IMAGE : ACTIVITY_OBJ_NOTE );
-	$link = XML::xmlify('<link rel="alternate" type="text/html" href="' . System::baseUrl() . '/display/' . $owner['nickname'] . '/' . $item['id'] . '" />' . "\n") ;
+	$link = XML::escape('<link rel="alternate" type="text/html" href="' . System::baseUrl() . '/display/' . $owner['nickname'] . '/' . $item['id'] . '" />' . "\n") ;
 	$body = $item['body'];
 
 	$obj = <<< EOT
diff --git a/mod/tagger.php b/mod/tagger.php
index 8b7e7d0040..dd859e61cd 100644
--- a/mod/tagger.php
+++ b/mod/tagger.php
@@ -67,7 +67,7 @@ function tagger_content(App $a) {
 	}
 
 	$uri = Item::newURI($owner_uid);
-	$xterm = XML::xmlify($term);
+	$xterm = XML::escape($term);
 	$post_type = (($item['resource-id']) ? L10n::t('photo') : L10n::t('status'));
 	$targettype = (($item['resource-id']) ? ACTIVITY_OBJ_IMAGE : ACTIVITY_OBJ_NOTE );
 
@@ -77,9 +77,9 @@ function tagger_content(App $a) {
 		$href = System::baseUrl() . '/display/' . $item['guid'];
 	}
 
-	$link = XML::xmlify('<link rel="alternate" type="text/html" href="'. $href . '" />' . "\n") ;
+	$link = XML::escape('<link rel="alternate" type="text/html" href="'. $href . '" />' . "\n") ;
 
-	$body = XML::xmlify($item['body']);
+	$body = XML::escape($item['body']);
 
 	$target = <<< EOT
 	<target>
diff --git a/src/Content/Widget.php b/src/Content/Widget.php
index 3e076729e1..397a1863d3 100644
--- a/src/Content/Widget.php
+++ b/src/Content/Widget.php
@@ -190,7 +190,7 @@ class Widget
 		if ($cnt) {
 			foreach ($matches as $mtch)
 			{
-				$unescaped = XML::xmlify(FileTag::decode($mtch[1]));
+				$unescaped = XML::escape(FileTag::decode($mtch[1]));
 				$terms[] = array('name' => $unescaped, 'selected' => (($selected == $unescaped) ? 'selected' : ''));
 			}
 		}
@@ -230,7 +230,7 @@ class Widget
 
 		if ($cnt) {
 			foreach ($matches as $mtch) {
-				$unescaped = XML::xmlify(FileTag::decode($mtch[1]));
+				$unescaped = XML::escape(FileTag::decode($mtch[1]));
 				$terms[] = array('name' => $unescaped, 'selected' => (($selected == $unescaped) ? 'selected' : ''));
 			}
 		}
diff --git a/src/Model/Event.php b/src/Model/Event.php
index 1f0b44693f..f4df6ac9f6 100644
--- a/src/Model/Event.php
+++ b/src/Model/Event.php
@@ -303,8 +303,8 @@ class Event extends BaseObject
 
 			$item = Item::selectFirst(['id'], ['event-id' => $event['id'], 'uid' => $event['uid']]);
 			if (DBA::isResult($item)) {
-				$object = '<object><type>' . XML::xmlify(ACTIVITY_OBJ_EVENT) . '</type><title></title><id>' . XML::xmlify($event['uri']) . '</id>';
-				$object .= '<content>' . XML::xmlify(self::getBBCode($event)) . '</content>';
+				$object = '<object><type>' . XML::escape(ACTIVITY_OBJ_EVENT) . '</type><title></title><id>' . XML::escape($event['uri']) . '</id>';
+				$object .= '<content>' . XML::escape(self::getBBCode($event)) . '</content>';
 				$object .= '</object>' . "\n";
 
 				$fields = ['body' => self::getBBCode($event), 'object' => $object, 'edited' => $event['edited']];
@@ -354,8 +354,8 @@ class Event extends BaseObject
 			$item_arr['body']          = self::getBBCode($event);
 			$item_arr['event-id']      = $event['id'];
 
-			$item_arr['object']  = '<object><type>' . XML::xmlify(ACTIVITY_OBJ_EVENT) . '</type><title></title><id>' . XML::xmlify($event['uri']) . '</id>';
-			$item_arr['object'] .= '<content>' . XML::xmlify(self::getBBCode($event)) . '</content>';
+			$item_arr['object']  = '<object><type>' . XML::escape(ACTIVITY_OBJ_EVENT) . '</type><title></title><id>' . XML::escape($event['uri']) . '</id>';
+			$item_arr['object'] .= '<content>' . XML::escape(self::getBBCode($event)) . '</content>';
 			$item_arr['object'] .= '</object>' . "\n";
 
 			$item_id = Item::insert($item_arr);
diff --git a/src/Protocol/DFRN.php b/src/Protocol/DFRN.php
index 1b83beb0ed..33df28d92b 100644
--- a/src/Protocol/DFRN.php
+++ b/src/Protocol/DFRN.php
@@ -2547,7 +2547,7 @@ class DFRN
 		$item["guid"] = XML::getFirstNodeValue($xpath, "dfrn:diaspora_guid/text()", $entry);
 
 		// We store the data from "dfrn:diaspora_signature" in a different table, this is done in "Item::insert"
-		$dsprsig = XML::unxmlify(XML::getFirstNodeValue($xpath, "dfrn:diaspora_signature/text()", $entry));
+		$dsprsig = XML::unescape(XML::getFirstNodeValue($xpath, "dfrn:diaspora_signature/text()", $entry));
 		if ($dsprsig != "") {
 			$item["dsprsig"] = $dsprsig;
 		}
diff --git a/src/Protocol/Diaspora.php b/src/Protocol/Diaspora.php
index dccc3358bd..0b5c9c9496 100644
--- a/src/Protocol/Diaspora.php
+++ b/src/Protocol/Diaspora.php
@@ -463,7 +463,7 @@ class Diaspora
 		}
 
 		return ['message' => (string)base64url_decode($base->data),
-				'author' => XML::unxmlify($author_addr),
+				'author' => XML::unescape($author_addr),
 				'key' => (string)$key];
 	}
 
@@ -603,7 +603,7 @@ class Diaspora
 		Logger::log('Message verified.');
 
 		return ['message' => (string)$inner_decrypted,
-				'author' => XML::unxmlify($author_link),
+				'author' => XML::unescape($author_link),
 				'key' => (string)$key];
 	}
 
@@ -1505,9 +1505,9 @@ class Diaspora
 	 */
 	private static function receiveAccountMigration(array $importer, $data)
 	{
-		$old_handle = notags(XML::unxmlify($data->author));
-		$new_handle = notags(XML::unxmlify($data->profile->author));
-		$signature = notags(XML::unxmlify($data->signature));
+		$old_handle = notags(XML::unescape($data->author));
+		$new_handle = notags(XML::unescape($data->profile->author));
+		$signature = notags(XML::unescape($data->signature));
 
 		$contact = self::contactByHandle($importer["uid"], $old_handle);
 		if (!$contact) {
@@ -1565,7 +1565,7 @@ class Diaspora
 	 */
 	private static function receiveAccountDeletion($data)
 	{
-		$author = notags(XML::unxmlify($data->author));
+		$author = notags(XML::unescape($data->author));
 
 		$contacts = DBA::select('contact', ['id'], ['addr' => $author]);
 		while ($contact = DBA::fetch($contacts)) {
@@ -1656,19 +1656,19 @@ class Diaspora
 	 */
 	private static function receiveComment(array $importer, $sender, $data, $xml)
 	{
-		$author = notags(XML::unxmlify($data->author));
-		$guid = notags(XML::unxmlify($data->guid));
-		$parent_guid = notags(XML::unxmlify($data->parent_guid));
-		$text = XML::unxmlify($data->text);
+		$author = notags(XML::unescape($data->author));
+		$guid = notags(XML::unescape($data->guid));
+		$parent_guid = notags(XML::unescape($data->parent_guid));
+		$text = XML::unescape($data->text);
 
 		if (isset($data->created_at)) {
-			$created_at = DateTimeFormat::utc(notags(XML::unxmlify($data->created_at)));
+			$created_at = DateTimeFormat::utc(notags(XML::unescape($data->created_at)));
 		} else {
 			$created_at = DateTimeFormat::utcNow();
 		}
 
 		if (isset($data->thread_parent_guid)) {
-			$thread_parent_guid = notags(XML::unxmlify($data->thread_parent_guid));
+			$thread_parent_guid = notags(XML::unescape($data->thread_parent_guid));
 			$thr_uri = self::getUriFromGuid("", $thread_parent_guid, true);
 		} else {
 			$thr_uri = "";
@@ -1773,24 +1773,24 @@ class Diaspora
 	 */
 	private static function receiveConversationMessage(array $importer, array $contact, $data, $msg, $mesg, $conversation)
 	{
-		$author = notags(XML::unxmlify($data->author));
-		$guid = notags(XML::unxmlify($data->guid));
-		$subject = notags(XML::unxmlify($data->subject));
+		$author = notags(XML::unescape($data->author));
+		$guid = notags(XML::unescape($data->guid));
+		$subject = notags(XML::unescape($data->subject));
 
 		// "diaspora_handle" is the element name from the old version
 		// "author" is the element name from the new version
 		if ($mesg->author) {
-			$msg_author = notags(XML::unxmlify($mesg->author));
+			$msg_author = notags(XML::unescape($mesg->author));
 		} elseif ($mesg->diaspora_handle) {
-			$msg_author = notags(XML::unxmlify($mesg->diaspora_handle));
+			$msg_author = notags(XML::unescape($mesg->diaspora_handle));
 		} else {
 			return false;
 		}
 
-		$msg_guid = notags(XML::unxmlify($mesg->guid));
-		$msg_conversation_guid = notags(XML::unxmlify($mesg->conversation_guid));
-		$msg_text = XML::unxmlify($mesg->text);
-		$msg_created_at = DateTimeFormat::utc(notags(XML::unxmlify($mesg->created_at)));
+		$msg_guid = notags(XML::unescape($mesg->guid));
+		$msg_conversation_guid = notags(XML::unescape($mesg->conversation_guid));
+		$msg_text = XML::unescape($mesg->text);
+		$msg_created_at = DateTimeFormat::utc(notags(XML::unescape($mesg->created_at)));
 
 		if ($msg_conversation_guid != $guid) {
 			Logger::log("message conversation guid does not belong to the current conversation.");
@@ -1861,11 +1861,11 @@ class Diaspora
 	 */
 	private static function receiveConversation(array $importer, $msg, $data)
 	{
-		$author = notags(XML::unxmlify($data->author));
-		$guid = notags(XML::unxmlify($data->guid));
-		$subject = notags(XML::unxmlify($data->subject));
-		$created_at = DateTimeFormat::utc(notags(XML::unxmlify($data->created_at)));
-		$participants = notags(XML::unxmlify($data->participants));
+		$author = notags(XML::unescape($data->author));
+		$guid = notags(XML::unescape($data->guid));
+		$subject = notags(XML::unescape($data->subject));
+		$created_at = DateTimeFormat::utc(notags(XML::unescape($data->created_at)));
+		$participants = notags(XML::unescape($data->participants));
 
 		$messages = $data->message;
 
@@ -1919,11 +1919,11 @@ class Diaspora
 	 */
 	private static function receiveLike(array $importer, $sender, $data)
 	{
-		$author = notags(XML::unxmlify($data->author));
-		$guid = notags(XML::unxmlify($data->guid));
-		$parent_guid = notags(XML::unxmlify($data->parent_guid));
-		$parent_type = notags(XML::unxmlify($data->parent_type));
-		$positive = notags(XML::unxmlify($data->positive));
+		$author = notags(XML::unescape($data->author));
+		$guid = notags(XML::unescape($data->guid));
+		$parent_guid = notags(XML::unescape($data->parent_guid));
+		$parent_type = notags(XML::unescape($data->parent_type));
+		$positive = notags(XML::unescape($data->positive));
 
 		// likes on comments aren't supported by Diaspora - only on posts
 		// But maybe this will be supported in the future, so we will accept it.
@@ -2028,11 +2028,11 @@ class Diaspora
 	 */
 	private static function receiveMessage(array $importer, $data)
 	{
-		$author = notags(XML::unxmlify($data->author));
-		$guid = notags(XML::unxmlify($data->guid));
-		$conversation_guid = notags(XML::unxmlify($data->conversation_guid));
-		$text = XML::unxmlify($data->text);
-		$created_at = DateTimeFormat::utc(notags(XML::unxmlify($data->created_at)));
+		$author = notags(XML::unescape($data->author));
+		$guid = notags(XML::unescape($data->guid));
+		$conversation_guid = notags(XML::unescape($data->conversation_guid));
+		$text = XML::unescape($data->text);
+		$created_at = DateTimeFormat::utc(notags(XML::unescape($data->created_at)));
 
 		$contact = self::allowedContactByHandle($importer, $author, true);
 		if (!$contact) {
@@ -2103,8 +2103,8 @@ class Diaspora
 	 */
 	private static function receiveParticipation(array $importer, $data)
 	{
-		$author = strtolower(notags(XML::unxmlify($data->author)));
-		$parent_guid = notags(XML::unxmlify($data->parent_guid));
+		$author = strtolower(notags(XML::unescape($data->author)));
+		$parent_guid = notags(XML::unescape($data->parent_guid));
 
 		$contact_id = Contact::getIdForURL($author);
 		if (!$contact_id) {
@@ -2196,22 +2196,22 @@ class Diaspora
 	 */
 	private static function receiveProfile(array $importer, $data)
 	{
-		$author = strtolower(notags(XML::unxmlify($data->author)));
+		$author = strtolower(notags(XML::unescape($data->author)));
 
 		$contact = self::contactByHandle($importer["uid"], $author);
 		if (!$contact) {
 			return false;
 		}
 
-		$name = XML::unxmlify($data->first_name).((strlen($data->last_name)) ? " ".XML::unxmlify($data->last_name) : "");
-		$image_url = XML::unxmlify($data->image_url);
-		$birthday = XML::unxmlify($data->birthday);
-		$gender = XML::unxmlify($data->gender);
-		$about = Markdown::toBBCode(XML::unxmlify($data->bio));
-		$location = Markdown::toBBCode(XML::unxmlify($data->location));
-		$searchable = (XML::unxmlify($data->searchable) == "true");
-		$nsfw = (XML::unxmlify($data->nsfw) == "true");
-		$tags = XML::unxmlify($data->tag_string);
+		$name = XML::unescape($data->first_name).((strlen($data->last_name)) ? " ".XML::unescape($data->last_name) : "");
+		$image_url = XML::unescape($data->image_url);
+		$birthday = XML::unescape($data->birthday);
+		$gender = XML::unescape($data->gender);
+		$about = Markdown::toBBCode(XML::unescape($data->bio));
+		$location = Markdown::toBBCode(XML::unescape($data->location));
+		$searchable = (XML::unescape($data->searchable) == "true");
+		$nsfw = (XML::unescape($data->nsfw) == "true");
+		$tags = XML::unescape($data->tag_string);
 
 		$tags = explode("#", $tags);
 
@@ -2310,8 +2310,8 @@ class Diaspora
 	 */
 	private static function receiveContactRequest(array $importer, $data)
 	{
-		$author = XML::unxmlify($data->author);
-		$recipient = XML::unxmlify($data->recipient);
+		$author = XML::unescape($data->author);
+		$recipient = XML::unescape($data->recipient);
 
 		if (!$author || !$recipient) {
 			return false;
@@ -2320,13 +2320,13 @@ class Diaspora
 		// the current protocol version doesn't know these fields
 		// That means that we will assume their existance
 		if (isset($data->following)) {
-			$following = (XML::unxmlify($data->following) == "true");
+			$following = (XML::unescape($data->following) == "true");
 		} else {
 			$following = true;
 		}
 
 		if (isset($data->sharing)) {
-			$sharing = (XML::unxmlify($data->sharing) == "true");
+			$sharing = (XML::unescape($data->sharing) == "true");
 		} else {
 			$sharing = true;
 		}
@@ -2573,13 +2573,13 @@ class Diaspora
 	 */
 	private static function receiveReshare(array $importer, $data, $xml)
 	{
-		$author = notags(XML::unxmlify($data->author));
-		$guid = notags(XML::unxmlify($data->guid));
-		$created_at = DateTimeFormat::utc(notags(XML::unxmlify($data->created_at)));
-		$root_author = notags(XML::unxmlify($data->root_author));
-		$root_guid = notags(XML::unxmlify($data->root_guid));
+		$author = notags(XML::unescape($data->author));
+		$guid = notags(XML::unescape($data->guid));
+		$created_at = DateTimeFormat::utc(notags(XML::unescape($data->created_at)));
+		$root_author = notags(XML::unescape($data->root_author));
+		$root_guid = notags(XML::unescape($data->root_guid));
 		/// @todo handle unprocessed property "provider_display_name"
-		$public = notags(XML::unxmlify($data->public));
+		$public = notags(XML::unescape($data->public));
 
 		$contact = self::allowedContactByHandle($importer, $author, false);
 		if (!$contact) {
@@ -2665,9 +2665,9 @@ class Diaspora
 	 */
 	private static function itemRetraction(array $importer, array $contact, $data)
 	{
-		$author = notags(XML::unxmlify($data->author));
-		$target_guid = notags(XML::unxmlify($data->target_guid));
-		$target_type = notags(XML::unxmlify($data->target_type));
+		$author = notags(XML::unescape($data->author));
+		$target_guid = notags(XML::unescape($data->target_guid));
+		$target_type = notags(XML::unescape($data->target_type));
 
 		$person = self::personByHandle($author);
 		if (!is_array($person)) {
@@ -2729,7 +2729,7 @@ class Diaspora
 	 */
 	private static function receiveRetraction(array $importer, $sender, $data)
 	{
-		$target_type = notags(XML::unxmlify($data->target_type));
+		$target_type = notags(XML::unescape($data->target_type));
 
 		$contact = self::contactByHandle($importer["uid"], $sender);
 		if (!$contact && (in_array($target_type, ["Contact", "Person"]))) {
@@ -2774,12 +2774,12 @@ class Diaspora
 	 */
 	private static function receiveStatusMessage(array $importer, SimpleXMLElement $data, $xml)
 	{
-		$author = notags(XML::unxmlify($data->author));
-		$guid = notags(XML::unxmlify($data->guid));
-		$created_at = DateTimeFormat::utc(notags(XML::unxmlify($data->created_at)));
-		$public = notags(XML::unxmlify($data->public));
-		$text = XML::unxmlify($data->text);
-		$provider_display_name = notags(XML::unxmlify($data->provider_display_name));
+		$author = notags(XML::unescape($data->author));
+		$guid = notags(XML::unescape($data->guid));
+		$created_at = DateTimeFormat::utc(notags(XML::unescape($data->created_at)));
+		$public = notags(XML::unescape($data->public));
+		$text = XML::unescape($data->text);
+		$provider_display_name = notags(XML::unescape($data->provider_display_name));
 
 		$contact = self::allowedContactByHandle($importer, $author, false);
 		if (!$contact) {
@@ -2794,7 +2794,7 @@ class Diaspora
 		$address = [];
 		if ($data->location) {
 			foreach ($data->location->children() as $fieldname => $data) {
-				$address[$fieldname] = notags(XML::unxmlify($data));
+				$address[$fieldname] = notags(XML::unescape($data));
 			}
 		}
 
@@ -2805,8 +2805,8 @@ class Diaspora
 		// Attach embedded pictures to the body
 		if ($data->photo) {
 			foreach ($data->photo as $photo) {
-				$body = "[img]".XML::unxmlify($photo->remote_photo_path).
-					XML::unxmlify($photo->remote_photo_name)."[/img]\n".$body;
+				$body = "[img]".XML::unescape($photo->remote_photo_path).
+					XML::unescape($photo->remote_photo_name)."[/img]\n".$body;
 			}
 
 			$datarray["object-type"] = ACTIVITY_OBJ_IMAGE;

From 97fcf23371cb24c7c9dbb144ed7f250813176f45 Mon Sep 17 00:00:00 2001
From: Adam Magness <adam.magness@gmail.com>
Date: Mon, 5 Nov 2018 07:31:45 -0500
Subject: [PATCH 06/11] Move methods to new Util/Strings class

move string methods from xml to strings class.
---
 src/Util/Strings.php | 51 ++++++++++++++++++++++++++++++++++++++++++++
 src/Util/XML.php     | 50 ++++++-------------------------------------
 2 files changed, 57 insertions(+), 44 deletions(-)
 create mode 100644 src/Util/Strings.php

diff --git a/src/Util/Strings.php b/src/Util/Strings.php
new file mode 100644
index 0000000000..5efc214afc
--- /dev/null
+++ b/src/Util/Strings.php
@@ -0,0 +1,51 @@
+<?php
+/**
+ * @file src/Util/Strings.php
+ */
+
+namespace Friendica\Util;
+
+/**
+ * @brief This class contains methods to modify/transform strings.
+ */
+class Strings
+{
+    /**
+	 * escape text ($str) for XML transport
+	 * @param string $str
+	 * @return string Escaped text.
+	 */
+	public static function escape($str)
+	{
+		$buffer = htmlspecialchars($str, ENT_QUOTES, "UTF-8");
+		$buffer = trim($buffer);
+
+		return $buffer;
+	}
+
+	/**
+	 * undo an escape
+	 * @param string $s xml escaped text
+	 * @return string unescaped text
+	 */
+	public static function unescape($s)
+	{
+		$ret = htmlspecialchars_decode($s, ENT_QUOTES);
+		return $ret;
+	}
+
+	/**
+	 * apply escape() to all values of array $val, recursively
+	 * @param array $val
+	 * @return array
+	 */
+	public static function arrayEscape($val)
+	{
+		if (is_bool($val)) {
+			return $val?"true":"false";
+		} elseif (is_array($val)) {
+			return array_map('XML::arrayEscape', $val);
+		}
+		return self::escape((string) $val);
+	}
+}
diff --git a/src/Util/XML.php b/src/Util/XML.php
index c115e4d0de..ed0d4bbb04 100644
--- a/src/Util/XML.php
+++ b/src/Util/XML.php
@@ -5,6 +5,7 @@
 namespace Friendica\Util;
 
 use Friendica\Core\Logger;
+use Friendica\Util\Strings;
 use DOMXPath;
 use SimpleXMLElement;
 
@@ -36,7 +37,7 @@ class XML
 					$root = new SimpleXMLElement("<".$key."/>");
 					self::fromArray($value, $root, $remove_header, $namespaces, false);
 				} else {
-					$root = new SimpleXMLElement("<".$key.">".self::escape($value)."</".$key.">");
+					$root = new SimpleXMLElement("<".$key.">".Strings::escape($value)."</".$key.">");
 				}
 
 				$dom = dom_import_simplexml($root)->ownerDocument;
@@ -104,7 +105,7 @@ class XML
 			}
 
 			if (!is_array($value)) {
-				$element = $xml->addChild($key, self::escape($value), $namespace);
+				$element = $xml->addChild($key, Strings::escape($value), $namespace);
 			} elseif (is_array($value)) {
 				$element = $xml->addChild($key, null, $namespace);
 				self::fromArray($value, $element, $remove_header, $namespaces, false);
@@ -123,7 +124,7 @@ class XML
 	public static function copy(&$source, &$target, $elementname)
 	{
 		if (count($source->children()) == 0) {
-			$target->addChild($elementname, self::escape($source));
+			$target->addChild($elementname, Strings::escape($source));
 		} else {
 			$child = $target->addChild($elementname);
 			foreach ($source->children() as $childfield => $childentry) {
@@ -144,11 +145,11 @@ class XML
 	 */
 	public static function createElement($doc, $element, $value = "", $attributes = [])
 	{
-		$element = $doc->createElement($element, self::escape($value));
+		$element = $doc->createElement($element, Strings::escape($value));
 
 		foreach ($attributes as $key => $value) {
 			$attribute = $doc->createAttribute($key);
-			$attribute->value = self::escape($value);
+			$attribute->value = Strings::escape($value);
 			$element->appendChild($attribute);
 		}
 		return $element;
@@ -462,43 +463,4 @@ class XML
 
 		return $first_item->attributes;
 	}
-
-	/**
-	 * escape text ($str) for XML transport
-	 * @param string $str
-	 * @return string Escaped text.
-	 */
-	public static function escape($str)
-	{
-		$buffer = htmlspecialchars($str, ENT_QUOTES, "UTF-8");
-		$buffer = trim($buffer);
-
-		return $buffer;
-	}
-
-	/**
-	 * undo an escape
-	 * @param string $s xml escaped text
-	 * @return string unescaped text
-	 */
-	public static function unescape($s)
-	{
-		$ret = htmlspecialchars_decode($s, ENT_QUOTES);
-		return $ret;
-	}
-
-	/**
-	 * apply escape() to all values of array $val, recursively
-	 * @param array $val
-	 * @return array
-	 */
-	public static function arrayEscape($val)
-	{
-		if (is_bool($val)) {
-			return $val?"true":"false";
-		} elseif (is_array($val)) {
-			return array_map('XML::arrayEscape', $val);
-		}
-		return self::escape((string) $val);
-	}
 }

From 748fb8b94693ea468ef6b539d6268ea3f7ab9bea Mon Sep 17 00:00:00 2001
From: Adam Magness <adam.magness@gmail.com>
Date: Mon, 5 Nov 2018 07:40:18 -0500
Subject: [PATCH 07/11] Update function calls

update function calls to new class
---
 include/conversation.php  |   3 +-
 include/text.php          |  10 +--
 mod/dfrn_confirm.php      |   3 +-
 mod/filer.php             |   4 +-
 mod/filerm.php            |   6 +-
 mod/photos.php            |   8 +--
 mod/poco.php              |   4 +-
 mod/poke.php              |   6 +-
 mod/profile.php           |   4 +-
 mod/subthread.php         |   4 +-
 mod/tagger.php            |   8 +--
 src/Content/Widget.php    |   6 +-
 src/Model/Event.php       |  10 +--
 src/Protocol/DFRN.php     |   3 +-
 src/Protocol/Diaspora.php | 143 +++++++++++++++++++-------------------
 src/Util/Strings.php      |   2 +-
 16 files changed, 114 insertions(+), 110 deletions(-)

diff --git a/include/conversation.php b/include/conversation.php
index c10a7bec73..b69ce939e8 100644
--- a/include/conversation.php
+++ b/include/conversation.php
@@ -25,6 +25,7 @@ use Friendica\Object\Post;
 use Friendica\Object\Thread;
 use Friendica\Util\DateTimeFormat;
 use Friendica\Util\Proxy as ProxyUtils;
+use Friendica\Util\Strings;
 use Friendica\Util\Temporal;
 use Friendica\Util\XML;
 
@@ -195,7 +196,7 @@ function localize_item(&$item)
 		$xmlhead="<"."?xml version='1.0' encoding='UTF-8' ?".">";
 
 		$obj = XML::parseString($xmlhead.$item['object']);
-		$links = XML::parseString($xmlhead."<links>".XML::unescape($obj->link)."</links>");
+		$links = XML::parseString($xmlhead."<links>".Strings::unescape($obj->link)."</links>");
 
 		$Bname = $obj->title;
 		$Blink = "";
diff --git a/include/text.php b/include/text.php
index 5da54b5fc9..15b482f106 100644
--- a/include/text.php
+++ b/include/text.php
@@ -26,7 +26,7 @@ use Friendica\Util\Proxy as ProxyUtils;
 use Friendica\Core\Logger;
 use Friendica\Core\Renderer;
 use Friendica\Model\FileTag;
-use Friendica\Util\XML;
+use Friendica\Util\Strings;
 
 require_once "include/conversation.php";
 
@@ -974,9 +974,9 @@ function get_cats_and_terms($item)
 	if ($cnt) {
 		foreach ($matches as $mtch) {
 			$categories[] = [
-				'name' => XML::escape(FileTag::decode($mtch[1])),
+				'name' => Strings::escape(FileTag::decode($mtch[1])),
 				'url' =>  "#",
-				'removeurl' => ((local_user() == $item['uid'])?'filerm/' . $item['id'] . '?f=&cat=' . XML::escape(FileTag::decode($mtch[1])):""),
+				'removeurl' => ((local_user() == $item['uid'])?'filerm/' . $item['id'] . '?f=&cat=' . Strings::escape(FileTag::decode($mtch[1])):""),
 				'first' => $first,
 				'last' => false
 			];
@@ -995,9 +995,9 @@ function get_cats_and_terms($item)
 		if ($cnt) {
 			foreach ($matches as $mtch) {
 				$folders[] = [
-					'name' => XML::escape(FileTag::decode($mtch[1])),
+					'name' => Strings::escape(FileTag::decode($mtch[1])),
 					'url' =>  "#",
-					'removeurl' => ((local_user() == $item['uid']) ? 'filerm/' . $item['id'] . '?f=&term=' . XML::escape(FileTag::decode($mtch[1])) : ""),
+					'removeurl' => ((local_user() == $item['uid']) ? 'filerm/' . $item['id'] . '?f=&term=' . Strings::escape(FileTag::decode($mtch[1])) : ""),
 					'first' => $first,
 					'last' => false
 				];
diff --git a/mod/dfrn_confirm.php b/mod/dfrn_confirm.php
index 0f001b11a2..449a39cbbe 100644
--- a/mod/dfrn_confirm.php
+++ b/mod/dfrn_confirm.php
@@ -33,6 +33,7 @@ use Friendica\Protocol\ActivityPub;
 use Friendica\Util\Crypto;
 use Friendica\Util\DateTimeFormat;
 use Friendica\Util\Network;
+use Friendica\Util\Strings;
 use Friendica\Util\XML;
 
 require_once 'include/enotify.php';
@@ -256,7 +257,7 @@ function dfrn_confirm_post(App $a, $handsfree = null)
 
 			$xml = XML::parseString($res);
 			$status = (int) $xml->status;
-			$message = XML::unescape($xml->message);   // human readable text of what may have gone wrong.
+			$message = Strings::unescape($xml->message);   // human readable text of what may have gone wrong.
 			switch ($status) {
 				case 0:
 					info(L10n::t("Confirmation completed successfully.") . EOL);
diff --git a/mod/filer.php b/mod/filer.php
index 3508079400..1ccc4213af 100644
--- a/mod/filer.php
+++ b/mod/filer.php
@@ -8,7 +8,7 @@ use Friendica\Core\Logger;
 use Friendica\Core\PConfig;
 use Friendica\Core\Renderer;
 use Friendica\Model\FileTag;
-use Friendica\Util\XML;
+use Friendica\Util\Strings;
 
 require_once 'include/items.php';
 
@@ -18,7 +18,7 @@ function filer_content(App $a)
 		killme();
 	}
 
-	$term = XML::unescape(trim(defaults($_GET, 'term', '')));
+	$term = Strings::unescape(trim(defaults($_GET, 'term', '')));
 	$item_id = (($a->argc > 1) ? intval($a->argv[1]) : 0);
 
 	Logger::log('filer: tag ' . $term . ' item ' . $item_id);
diff --git a/mod/filerm.php b/mod/filerm.php
index 335b27b320..8ad1cddbf1 100644
--- a/mod/filerm.php
+++ b/mod/filerm.php
@@ -4,7 +4,7 @@ use Friendica\App;
 use Friendica\Core\Logger;
 use Friendica\Core\System;
 use Friendica\Model\FileTag;
-use Friendica\Util\XML;
+use Friendica\Util\Strings;
 
 function filerm_content(App $a)
 {
@@ -13,8 +13,8 @@ function filerm_content(App $a)
 		killme();
 	}
 
-	$term = XML::unescape(trim($_GET['term']));
-	$cat = XML::unescape(trim($_GET['cat']));
+	$term = Strings::unescape(trim($_GET['term']));
+	$cat = Strings::unescape(trim($_GET['cat']));
 
 	$category = (($cat) ? true : false);
 
diff --git a/mod/photos.php b/mod/photos.php
index 69b1972d4c..0e5e3349ad 100644
--- a/mod/photos.php
+++ b/mod/photos.php
@@ -29,8 +29,8 @@ use Friendica\Protocol\DFRN;
 use Friendica\Util\DateTimeFormat;
 use Friendica\Util\Map;
 use Friendica\Util\Security;
+use Friendica\Util\Strings;
 use Friendica\Util\Temporal;
-use Friendica\Util\XML;
 
 require_once 'include/items.php';
 
@@ -683,15 +683,15 @@ function photos_post(App $a)
 					$arr['body'] .= "\n\n" . '[url=' . System::baseUrl() . '/photos/' . $owner_record['nickname'] . '/image/' . $p[0]['resource-id'] . ']' . '[img]' . System::baseUrl() . "/photo/" . $p[0]['resource-id'] . '-' . $best . '.' . $ext . '[/img][/url]' . "\n" ;
 
 					$arr['object'] = '<object><type>' . ACTIVITY_OBJ_PERSON . '</type><title>' . $tagged[0] . '</title><id>' . $tagged[1] . '/' . $tagged[0] . '</id>';
-					$arr['object'] .= '<link>' . XML::escape('<link rel="alternate" type="text/html" href="' . $tagged[1] . '" />' . "\n");
+					$arr['object'] .= '<link>' . Strings::escape('<link rel="alternate" type="text/html" href="' . $tagged[1] . '" />' . "\n");
 					if ($tagged[3]) {
-						$arr['object'] .= XML::escape('<link rel="photo" type="'.$p[0]['type'].'" href="' . $tagged[3]['photo'] . '" />' . "\n");
+						$arr['object'] .= Strings::escape('<link rel="photo" type="'.$p[0]['type'].'" href="' . $tagged[3]['photo'] . '" />' . "\n");
 					}
 					$arr['object'] .= '</link></object>' . "\n";
 
 					$arr['target'] = '<target><type>' . ACTIVITY_OBJ_IMAGE . '</type><title>' . $p[0]['desc'] . '</title><id>'
 						. System::baseUrl() . '/photos/' . $owner_record['nickname'] . '/image/' . $p[0]['resource-id'] . '</id>';
-					$arr['target'] .= '<link>' . XML::escape('<link rel="alternate" type="text/html" href="' . System::baseUrl() . '/photos/' . $owner_record['nickname'] . '/image/' . $p[0]['resource-id'] . '" />' . "\n" . '<link rel="preview" type="'.$p[0]['type'].'" href="' . System::baseUrl() . "/photo/" . $p[0]['resource-id'] . '-' . $best . '.' . $ext . '" />') . '</link></target>';
+					$arr['target'] .= '<link>' . Strings::escape('<link rel="alternate" type="text/html" href="' . System::baseUrl() . '/photos/' . $owner_record['nickname'] . '/image/' . $p[0]['resource-id'] . '" />' . "\n" . '<link rel="preview" type="'.$p[0]['type'].'" href="' . System::baseUrl() . "/photo/" . $p[0]['resource-id'] . '-' . $best . '.' . $ext . '" />') . '</link></target>';
 
 					$item_id = Item::insert($arr);
 				}
diff --git a/mod/poco.php b/mod/poco.php
index 08677ef8d4..37d7cb7a91 100644
--- a/mod/poco.php
+++ b/mod/poco.php
@@ -15,7 +15,7 @@ use Friendica\Core\System;
 use Friendica\Database\DBA;
 use Friendica\Protocol\PortableContact;
 use Friendica\Util\DateTimeFormat;
-use Friendica\Util\XML;
+use Friendica\Util\Strings;
 
 function poco_init(App $a) {
 	$system_mode = false;
@@ -376,7 +376,7 @@ function poco_init(App $a) {
 
 	if ($format === 'xml') {
 		header('Content-type: text/xml');
-		echo Renderer::replaceMacros(Renderer::getMarkupTemplate('poco_xml.tpl'), XML::arrayEscape(['$response' => $ret]));
+		echo Renderer::replaceMacros(Renderer::getMarkupTemplate('poco_xml.tpl'), Strings::arrayEscape(['$response' => $ret]));
 		killme();
 	}
 	if ($format === 'json') {
diff --git a/mod/poke.php b/mod/poke.php
index 60ed5c402e..bf04d4480f 100644
--- a/mod/poke.php
+++ b/mod/poke.php
@@ -22,7 +22,7 @@ use Friendica\Core\System;
 use Friendica\Core\Worker;
 use Friendica\Database\DBA;
 use Friendica\Model\Item;
-use Friendica\Util\XML;
+use Friendica\Util\Strings;
 
 require_once 'include/items.php';
 
@@ -125,9 +125,9 @@ function poke_init(App $a)
 	$arr['body']          = '[url=' . $poster['url'] . ']' . $poster['name'] . '[/url]' . ' ' . L10n::t($verbs[$verb][0]) . ' ' . '[url=' . $target['url'] . ']' . $target['name'] . '[/url]';
 
 	$arr['object'] = '<object><type>' . ACTIVITY_OBJ_PERSON . '</type><title>' . $target['name'] . '</title><id>' . $target['url'] . '</id>';
-	$arr['object'] .= '<link>' . XML::escape('<link rel="alternate" type="text/html" href="' . $target['url'] . '" />' . "\n");
+	$arr['object'] .= '<link>' . Strings::escape('<link rel="alternate" type="text/html" href="' . $target['url'] . '" />' . "\n");
 
-	$arr['object'] .= XML::escape('<link rel="photo" type="image/jpeg" href="' . $target['photo'] . '" />' . "\n");
+	$arr['object'] .= Strings::escape('<link rel="photo" type="image/jpeg" href="' . $target['photo'] . '" />' . "\n");
 	$arr['object'] .= '</link></object>' . "\n";
 
 	$item_id = Item::insert($arr);
diff --git a/mod/profile.php b/mod/profile.php
index cfbe07dadb..c94353b5c0 100644
--- a/mod/profile.php
+++ b/mod/profile.php
@@ -24,7 +24,7 @@ use Friendica\Protocol\ActivityPub;
 use Friendica\Protocol\DFRN;
 use Friendica\Util\DateTimeFormat;
 use Friendica\Util\Security;
-use Friendica\Util\XML;
+use Friendica\Util\Strings;
 
 function profile_init(App $a)
 {
@@ -210,7 +210,7 @@ function profile_content(App $a, $update = 0)
 		$commvisitor = $commpage && $remote_contact;
 
 		$a->page['aside'] .= posted_date_widget(System::baseUrl(true) . '/profile/' . $a->profile['nickname'], $a->profile['profile_uid'], true);
-		$a->page['aside'] .= Widget::categories(System::baseUrl(true) . '/profile/' . $a->profile['nickname'], (!empty($category) ? XML::escape($category) : ''));
+		$a->page['aside'] .= Widget::categories(System::baseUrl(true) . '/profile/' . $a->profile['nickname'], (!empty($category) ? Strings::escape($category) : ''));
 		$a->page['aside'] .= Widget::tagCloud();
 
 		if (Security::canWriteToUserWall($a->profile['profile_uid'])) {
diff --git a/mod/subthread.php b/mod/subthread.php
index 425306b6f7..e3cfe39e6e 100644
--- a/mod/subthread.php
+++ b/mod/subthread.php
@@ -10,7 +10,7 @@ use Friendica\Core\System;
 use Friendica\Database\DBA;
 use Friendica\Model\Item;
 use Friendica\Util\Security;
-use Friendica\Util\XML;
+use Friendica\Util\Strings;
 
 require_once 'include/items.php';
 
@@ -88,7 +88,7 @@ function subthread_content(App $a) {
 
 	$post_type = (($item['resource-id']) ? L10n::t('photo') : L10n::t('status'));
 	$objtype = (($item['resource-id']) ? ACTIVITY_OBJ_IMAGE : ACTIVITY_OBJ_NOTE );
-	$link = XML::escape('<link rel="alternate" type="text/html" href="' . System::baseUrl() . '/display/' . $owner['nickname'] . '/' . $item['id'] . '" />' . "\n") ;
+	$link = Strings::escape('<link rel="alternate" type="text/html" href="' . System::baseUrl() . '/display/' . $owner['nickname'] . '/' . $item['id'] . '" />' . "\n") ;
 	$body = $item['body'];
 
 	$obj = <<< EOT
diff --git a/mod/tagger.php b/mod/tagger.php
index dd859e61cd..f978b5d3b1 100644
--- a/mod/tagger.php
+++ b/mod/tagger.php
@@ -10,7 +10,7 @@ use Friendica\Core\System;
 use Friendica\Core\Worker;
 use Friendica\Database\DBA;
 use Friendica\Model\Item;
-use Friendica\Util\XML;
+use Friendica\Util\Strings;
 
 require_once 'include/items.php';
 
@@ -67,7 +67,7 @@ function tagger_content(App $a) {
 	}
 
 	$uri = Item::newURI($owner_uid);
-	$xterm = XML::escape($term);
+	$xterm = Strings::escape($term);
 	$post_type = (($item['resource-id']) ? L10n::t('photo') : L10n::t('status'));
 	$targettype = (($item['resource-id']) ? ACTIVITY_OBJ_IMAGE : ACTIVITY_OBJ_NOTE );
 
@@ -77,9 +77,9 @@ function tagger_content(App $a) {
 		$href = System::baseUrl() . '/display/' . $item['guid'];
 	}
 
-	$link = XML::escape('<link rel="alternate" type="text/html" href="'. $href . '" />' . "\n") ;
+	$link = Strings::escape('<link rel="alternate" type="text/html" href="'. $href . '" />' . "\n") ;
 
-	$body = XML::escape($item['body']);
+	$body = Strings::escape($item['body']);
 
 	$target = <<< EOT
 	<target>
diff --git a/src/Content/Widget.php b/src/Content/Widget.php
index 397a1863d3..2bbf3f8258 100644
--- a/src/Content/Widget.php
+++ b/src/Content/Widget.php
@@ -18,7 +18,7 @@ use Friendica\Model\Contact;
 use Friendica\Model\FileTag;
 use Friendica\Model\GContact;
 use Friendica\Model\Profile;
-use Friendica\Util\XML;
+use Friendica\Util\Strings;
 
 require_once 'boot.php';
 require_once 'include/dba.php';
@@ -190,7 +190,7 @@ class Widget
 		if ($cnt) {
 			foreach ($matches as $mtch)
 			{
-				$unescaped = XML::escape(FileTag::decode($mtch[1]));
+				$unescaped = Strings::escape(FileTag::decode($mtch[1]));
 				$terms[] = array('name' => $unescaped, 'selected' => (($selected == $unescaped) ? 'selected' : ''));
 			}
 		}
@@ -230,7 +230,7 @@ class Widget
 
 		if ($cnt) {
 			foreach ($matches as $mtch) {
-				$unescaped = XML::escape(FileTag::decode($mtch[1]));
+				$unescaped = Strings::escape(FileTag::decode($mtch[1]));
 				$terms[] = array('name' => $unescaped, 'selected' => (($selected == $unescaped) ? 'selected' : ''));
 			}
 		}
diff --git a/src/Model/Event.php b/src/Model/Event.php
index f4df6ac9f6..b5dec7c785 100644
--- a/src/Model/Event.php
+++ b/src/Model/Event.php
@@ -17,7 +17,7 @@ use Friendica\Database\DBA;
 use Friendica\Model\Contact;
 use Friendica\Util\DateTimeFormat;
 use Friendica\Util\Map;
-use Friendica\Util\XML;
+use Friendica\Util\Strings;
 
 require_once 'boot.php';
 require_once 'include/dba.php';
@@ -303,8 +303,8 @@ class Event extends BaseObject
 
 			$item = Item::selectFirst(['id'], ['event-id' => $event['id'], 'uid' => $event['uid']]);
 			if (DBA::isResult($item)) {
-				$object = '<object><type>' . XML::escape(ACTIVITY_OBJ_EVENT) . '</type><title></title><id>' . XML::escape($event['uri']) . '</id>';
-				$object .= '<content>' . XML::escape(self::getBBCode($event)) . '</content>';
+				$object = '<object><type>' . Strings::escape(ACTIVITY_OBJ_EVENT) . '</type><title></title><id>' . Strings::escape($event['uri']) . '</id>';
+				$object .= '<content>' . Strings::escape(self::getBBCode($event)) . '</content>';
 				$object .= '</object>' . "\n";
 
 				$fields = ['body' => self::getBBCode($event), 'object' => $object, 'edited' => $event['edited']];
@@ -354,8 +354,8 @@ class Event extends BaseObject
 			$item_arr['body']          = self::getBBCode($event);
 			$item_arr['event-id']      = $event['id'];
 
-			$item_arr['object']  = '<object><type>' . XML::escape(ACTIVITY_OBJ_EVENT) . '</type><title></title><id>' . XML::escape($event['uri']) . '</id>';
-			$item_arr['object'] .= '<content>' . XML::escape(self::getBBCode($event)) . '</content>';
+			$item_arr['object']  = '<object><type>' . Strings::escape(ACTIVITY_OBJ_EVENT) . '</type><title></title><id>' . Strings::escape($event['uri']) . '</id>';
+			$item_arr['object'] .= '<content>' . Strings::escape(self::getBBCode($event)) . '</content>';
 			$item_arr['object'] .= '</object>' . "\n";
 
 			$item_id = Item::insert($item_arr);
diff --git a/src/Protocol/DFRN.php b/src/Protocol/DFRN.php
index 33df28d92b..7cb23299ba 100644
--- a/src/Protocol/DFRN.php
+++ b/src/Protocol/DFRN.php
@@ -33,6 +33,7 @@ use Friendica\Object\Image;
 use Friendica\Util\Crypto;
 use Friendica\Util\DateTimeFormat;
 use Friendica\Util\Network;
+use Friendica\Util\Strings;
 use Friendica\Util\XML;
 use HTMLPurifier;
 use HTMLPurifier_Config;
@@ -2547,7 +2548,7 @@ class DFRN
 		$item["guid"] = XML::getFirstNodeValue($xpath, "dfrn:diaspora_guid/text()", $entry);
 
 		// We store the data from "dfrn:diaspora_signature" in a different table, this is done in "Item::insert"
-		$dsprsig = XML::unescape(XML::getFirstNodeValue($xpath, "dfrn:diaspora_signature/text()", $entry));
+		$dsprsig = Strings::unescape(XML::getFirstNodeValue($xpath, "dfrn:diaspora_signature/text()", $entry));
 		if ($dsprsig != "") {
 			$item["dsprsig"] = $dsprsig;
 		}
diff --git a/src/Protocol/Diaspora.php b/src/Protocol/Diaspora.php
index 0b5c9c9496..30db886b46 100644
--- a/src/Protocol/Diaspora.php
+++ b/src/Protocol/Diaspora.php
@@ -34,6 +34,7 @@ use Friendica\Util\Crypto;
 use Friendica\Util\DateTimeFormat;
 use Friendica\Util\Map;
 use Friendica\Util\Network;
+use Friendica\Util\Strings;
 use Friendica\Util\XML;
 use SimpleXMLElement;
 
@@ -463,7 +464,7 @@ class Diaspora
 		}
 
 		return ['message' => (string)base64url_decode($base->data),
-				'author' => XML::unescape($author_addr),
+				'author' => Strings::unescape($author_addr),
 				'key' => (string)$key];
 	}
 
@@ -603,7 +604,7 @@ class Diaspora
 		Logger::log('Message verified.');
 
 		return ['message' => (string)$inner_decrypted,
-				'author' => XML::unescape($author_link),
+				'author' => Strings::unescape($author_link),
 				'key' => (string)$key];
 	}
 
@@ -1505,9 +1506,9 @@ class Diaspora
 	 */
 	private static function receiveAccountMigration(array $importer, $data)
 	{
-		$old_handle = notags(XML::unescape($data->author));
-		$new_handle = notags(XML::unescape($data->profile->author));
-		$signature = notags(XML::unescape($data->signature));
+		$old_handle = notags(Strings::unescape($data->author));
+		$new_handle = notags(Strings::unescape($data->profile->author));
+		$signature = notags(Strings::unescape($data->signature));
 
 		$contact = self::contactByHandle($importer["uid"], $old_handle);
 		if (!$contact) {
@@ -1565,7 +1566,7 @@ class Diaspora
 	 */
 	private static function receiveAccountDeletion($data)
 	{
-		$author = notags(XML::unescape($data->author));
+		$author = notags(Strings::unescape($data->author));
 
 		$contacts = DBA::select('contact', ['id'], ['addr' => $author]);
 		while ($contact = DBA::fetch($contacts)) {
@@ -1656,19 +1657,19 @@ class Diaspora
 	 */
 	private static function receiveComment(array $importer, $sender, $data, $xml)
 	{
-		$author = notags(XML::unescape($data->author));
-		$guid = notags(XML::unescape($data->guid));
-		$parent_guid = notags(XML::unescape($data->parent_guid));
-		$text = XML::unescape($data->text);
+		$author = notags(Strings::unescape($data->author));
+		$guid = notags(Strings::unescape($data->guid));
+		$parent_guid = notags(Strings::unescape($data->parent_guid));
+		$text = Strings::unescape($data->text);
 
 		if (isset($data->created_at)) {
-			$created_at = DateTimeFormat::utc(notags(XML::unescape($data->created_at)));
+			$created_at = DateTimeFormat::utc(notags(Strings::unescape($data->created_at)));
 		} else {
 			$created_at = DateTimeFormat::utcNow();
 		}
 
 		if (isset($data->thread_parent_guid)) {
-			$thread_parent_guid = notags(XML::unescape($data->thread_parent_guid));
+			$thread_parent_guid = notags(Strings::unescape($data->thread_parent_guid));
 			$thr_uri = self::getUriFromGuid("", $thread_parent_guid, true);
 		} else {
 			$thr_uri = "";
@@ -1773,24 +1774,24 @@ class Diaspora
 	 */
 	private static function receiveConversationMessage(array $importer, array $contact, $data, $msg, $mesg, $conversation)
 	{
-		$author = notags(XML::unescape($data->author));
-		$guid = notags(XML::unescape($data->guid));
-		$subject = notags(XML::unescape($data->subject));
+		$author = notags(Strings::unescape($data->author));
+		$guid = notags(Strings::unescape($data->guid));
+		$subject = notags(Strings::unescape($data->subject));
 
 		// "diaspora_handle" is the element name from the old version
 		// "author" is the element name from the new version
 		if ($mesg->author) {
-			$msg_author = notags(XML::unescape($mesg->author));
+			$msg_author = notags(Strings::unescape($mesg->author));
 		} elseif ($mesg->diaspora_handle) {
-			$msg_author = notags(XML::unescape($mesg->diaspora_handle));
+			$msg_author = notags(Strings::unescape($mesg->diaspora_handle));
 		} else {
 			return false;
 		}
 
-		$msg_guid = notags(XML::unescape($mesg->guid));
-		$msg_conversation_guid = notags(XML::unescape($mesg->conversation_guid));
-		$msg_text = XML::unescape($mesg->text);
-		$msg_created_at = DateTimeFormat::utc(notags(XML::unescape($mesg->created_at)));
+		$msg_guid = notags(Strings::unescape($mesg->guid));
+		$msg_conversation_guid = notags(Strings::unescape($mesg->conversation_guid));
+		$msg_text = Strings::unescape($mesg->text);
+		$msg_created_at = DateTimeFormat::utc(notags(Strings::unescape($mesg->created_at)));
 
 		if ($msg_conversation_guid != $guid) {
 			Logger::log("message conversation guid does not belong to the current conversation.");
@@ -1861,11 +1862,11 @@ class Diaspora
 	 */
 	private static function receiveConversation(array $importer, $msg, $data)
 	{
-		$author = notags(XML::unescape($data->author));
-		$guid = notags(XML::unescape($data->guid));
-		$subject = notags(XML::unescape($data->subject));
-		$created_at = DateTimeFormat::utc(notags(XML::unescape($data->created_at)));
-		$participants = notags(XML::unescape($data->participants));
+		$author = notags(Strings::unescape($data->author));
+		$guid = notags(Strings::unescape($data->guid));
+		$subject = notags(Strings::unescape($data->subject));
+		$created_at = DateTimeFormat::utc(notags(Strings::unescape($data->created_at)));
+		$participants = notags(Strings::unescape($data->participants));
 
 		$messages = $data->message;
 
@@ -1919,11 +1920,11 @@ class Diaspora
 	 */
 	private static function receiveLike(array $importer, $sender, $data)
 	{
-		$author = notags(XML::unescape($data->author));
-		$guid = notags(XML::unescape($data->guid));
-		$parent_guid = notags(XML::unescape($data->parent_guid));
-		$parent_type = notags(XML::unescape($data->parent_type));
-		$positive = notags(XML::unescape($data->positive));
+		$author = notags(Strings::unescape($data->author));
+		$guid = notags(Strings::unescape($data->guid));
+		$parent_guid = notags(Strings::unescape($data->parent_guid));
+		$parent_type = notags(Strings::unescape($data->parent_type));
+		$positive = notags(Strings::unescape($data->positive));
 
 		// likes on comments aren't supported by Diaspora - only on posts
 		// But maybe this will be supported in the future, so we will accept it.
@@ -2028,11 +2029,11 @@ class Diaspora
 	 */
 	private static function receiveMessage(array $importer, $data)
 	{
-		$author = notags(XML::unescape($data->author));
-		$guid = notags(XML::unescape($data->guid));
-		$conversation_guid = notags(XML::unescape($data->conversation_guid));
-		$text = XML::unescape($data->text);
-		$created_at = DateTimeFormat::utc(notags(XML::unescape($data->created_at)));
+		$author = notags(Strings::unescape($data->author));
+		$guid = notags(Strings::unescape($data->guid));
+		$conversation_guid = notags(Strings::unescape($data->conversation_guid));
+		$text = Strings::unescape($data->text);
+		$created_at = DateTimeFormat::utc(notags(Strings::unescape($data->created_at)));
 
 		$contact = self::allowedContactByHandle($importer, $author, true);
 		if (!$contact) {
@@ -2103,8 +2104,8 @@ class Diaspora
 	 */
 	private static function receiveParticipation(array $importer, $data)
 	{
-		$author = strtolower(notags(XML::unescape($data->author)));
-		$parent_guid = notags(XML::unescape($data->parent_guid));
+		$author = strtolower(notags(Strings::unescape($data->author)));
+		$parent_guid = notags(Strings::unescape($data->parent_guid));
 
 		$contact_id = Contact::getIdForURL($author);
 		if (!$contact_id) {
@@ -2196,22 +2197,22 @@ class Diaspora
 	 */
 	private static function receiveProfile(array $importer, $data)
 	{
-		$author = strtolower(notags(XML::unescape($data->author)));
+		$author = strtolower(notags(Strings::unescape($data->author)));
 
 		$contact = self::contactByHandle($importer["uid"], $author);
 		if (!$contact) {
 			return false;
 		}
 
-		$name = XML::unescape($data->first_name).((strlen($data->last_name)) ? " ".XML::unescape($data->last_name) : "");
-		$image_url = XML::unescape($data->image_url);
-		$birthday = XML::unescape($data->birthday);
-		$gender = XML::unescape($data->gender);
-		$about = Markdown::toBBCode(XML::unescape($data->bio));
-		$location = Markdown::toBBCode(XML::unescape($data->location));
-		$searchable = (XML::unescape($data->searchable) == "true");
-		$nsfw = (XML::unescape($data->nsfw) == "true");
-		$tags = XML::unescape($data->tag_string);
+		$name = Strings::unescape($data->first_name).((strlen($data->last_name)) ? " ".Strings::unescape($data->last_name) : "");
+		$image_url = Strings::unescape($data->image_url);
+		$birthday = Strings::unescape($data->birthday);
+		$gender = Strings::unescape($data->gender);
+		$about = Markdown::toBBCode(Strings::unescape($data->bio));
+		$location = Markdown::toBBCode(Strings::unescape($data->location));
+		$searchable = (Strings::unescape($data->searchable) == "true");
+		$nsfw = (Strings::unescape($data->nsfw) == "true");
+		$tags = Strings::unescape($data->tag_string);
 
 		$tags = explode("#", $tags);
 
@@ -2310,8 +2311,8 @@ class Diaspora
 	 */
 	private static function receiveContactRequest(array $importer, $data)
 	{
-		$author = XML::unescape($data->author);
-		$recipient = XML::unescape($data->recipient);
+		$author = Strings::unescape($data->author);
+		$recipient = Strings::unescape($data->recipient);
 
 		if (!$author || !$recipient) {
 			return false;
@@ -2320,13 +2321,13 @@ class Diaspora
 		// the current protocol version doesn't know these fields
 		// That means that we will assume their existance
 		if (isset($data->following)) {
-			$following = (XML::unescape($data->following) == "true");
+			$following = (Strings::unescape($data->following) == "true");
 		} else {
 			$following = true;
 		}
 
 		if (isset($data->sharing)) {
-			$sharing = (XML::unescape($data->sharing) == "true");
+			$sharing = (Strings::unescape($data->sharing) == "true");
 		} else {
 			$sharing = true;
 		}
@@ -2573,13 +2574,13 @@ class Diaspora
 	 */
 	private static function receiveReshare(array $importer, $data, $xml)
 	{
-		$author = notags(XML::unescape($data->author));
-		$guid = notags(XML::unescape($data->guid));
-		$created_at = DateTimeFormat::utc(notags(XML::unescape($data->created_at)));
-		$root_author = notags(XML::unescape($data->root_author));
-		$root_guid = notags(XML::unescape($data->root_guid));
+		$author = notags(Strings::unescape($data->author));
+		$guid = notags(Strings::unescape($data->guid));
+		$created_at = DateTimeFormat::utc(notags(Strings::unescape($data->created_at)));
+		$root_author = notags(Strings::unescape($data->root_author));
+		$root_guid = notags(Strings::unescape($data->root_guid));
 		/// @todo handle unprocessed property "provider_display_name"
-		$public = notags(XML::unescape($data->public));
+		$public = notags(Strings::unescape($data->public));
 
 		$contact = self::allowedContactByHandle($importer, $author, false);
 		if (!$contact) {
@@ -2665,9 +2666,9 @@ class Diaspora
 	 */
 	private static function itemRetraction(array $importer, array $contact, $data)
 	{
-		$author = notags(XML::unescape($data->author));
-		$target_guid = notags(XML::unescape($data->target_guid));
-		$target_type = notags(XML::unescape($data->target_type));
+		$author = notags(Strings::unescape($data->author));
+		$target_guid = notags(Strings::unescape($data->target_guid));
+		$target_type = notags(Strings::unescape($data->target_type));
 
 		$person = self::personByHandle($author);
 		if (!is_array($person)) {
@@ -2729,7 +2730,7 @@ class Diaspora
 	 */
 	private static function receiveRetraction(array $importer, $sender, $data)
 	{
-		$target_type = notags(XML::unescape($data->target_type));
+		$target_type = notags(Strings::unescape($data->target_type));
 
 		$contact = self::contactByHandle($importer["uid"], $sender);
 		if (!$contact && (in_array($target_type, ["Contact", "Person"]))) {
@@ -2774,12 +2775,12 @@ class Diaspora
 	 */
 	private static function receiveStatusMessage(array $importer, SimpleXMLElement $data, $xml)
 	{
-		$author = notags(XML::unescape($data->author));
-		$guid = notags(XML::unescape($data->guid));
-		$created_at = DateTimeFormat::utc(notags(XML::unescape($data->created_at)));
-		$public = notags(XML::unescape($data->public));
-		$text = XML::unescape($data->text);
-		$provider_display_name = notags(XML::unescape($data->provider_display_name));
+		$author = notags(Strings::unescape($data->author));
+		$guid = notags(Strings::unescape($data->guid));
+		$created_at = DateTimeFormat::utc(notags(Strings::unescape($data->created_at)));
+		$public = notags(Strings::unescape($data->public));
+		$text = Strings::unescape($data->text);
+		$provider_display_name = notags(Strings::unescape($data->provider_display_name));
 
 		$contact = self::allowedContactByHandle($importer, $author, false);
 		if (!$contact) {
@@ -2794,7 +2795,7 @@ class Diaspora
 		$address = [];
 		if ($data->location) {
 			foreach ($data->location->children() as $fieldname => $data) {
-				$address[$fieldname] = notags(XML::unescape($data));
+				$address[$fieldname] = notags(Strings::unescape($data));
 			}
 		}
 
@@ -2805,8 +2806,8 @@ class Diaspora
 		// Attach embedded pictures to the body
 		if ($data->photo) {
 			foreach ($data->photo as $photo) {
-				$body = "[img]".XML::unescape($photo->remote_photo_path).
-					XML::unescape($photo->remote_photo_name)."[/img]\n".$body;
+				$body = "[img]".Strings::unescape($photo->remote_photo_path).
+					Strings::unescape($photo->remote_photo_name)."[/img]\n".$body;
 			}
 
 			$datarray["object-type"] = ACTIVITY_OBJ_IMAGE;
diff --git a/src/Util/Strings.php b/src/Util/Strings.php
index 5efc214afc..19843d9f61 100644
--- a/src/Util/Strings.php
+++ b/src/Util/Strings.php
@@ -44,7 +44,7 @@ class Strings
 		if (is_bool($val)) {
 			return $val?"true":"false";
 		} elseif (is_array($val)) {
-			return array_map('XML::arrayEscape', $val);
+			return array_map('Strings::arrayEscape', $val);
 		}
 		return self::escape((string) $val);
 	}

From 119b4afddfc820e954b86e76249633223adb2bd4 Mon Sep 17 00:00:00 2001
From: Adam Magness <adam.magness@gmail.com>
Date: Mon, 5 Nov 2018 07:53:12 -0500
Subject: [PATCH 08/11] Create/Update tests

create new test class and update old one.
---
 tests/include/TextTest.php     | 39 ---------------------------
 tests/src/Util/StringsTest.php | 49 ++++++++++++++++++++++++++++++++++
 2 files changed, 49 insertions(+), 39 deletions(-)
 create mode 100644 tests/src/Util/StringsTest.php

diff --git a/tests/include/TextTest.php b/tests/include/TextTest.php
index ac1b7d7757..1422ee2ae2 100644
--- a/tests/include/TextTest.php
+++ b/tests/include/TextTest.php
@@ -249,45 +249,6 @@ class TextTest extends TestCase
 		);
 	}
 
-	/**
-	 *xmlify and unxmlify
-	 */
-	public function testXmlify()
-	{
-		$text="<tag>I want to break\n this!11!<?hard?></tag>";
-		$xml=xmlify($text);
-		$retext=unxmlify($text);
-
-		$this->assertEquals($text, $retext);
-	}
-
-	/**
-	 * xmlify and put in a document
-	 */
-	public function testXmlifyDocument()
-	{
-		$tag="<tag>I want to break</tag>";
-		$xml=xmlify($tag);
-		$text='<text>'.$xml.'</text>';
-
-		$xml_parser=xml_parser_create();
-		//should be possible to parse it
-		$values=array();
-		$index=array();
-		$this->assertEquals(1, xml_parse_into_struct($xml_parser, $text, $values, $index));
-
-		$this->assertEquals(
-			array('TEXT'=>array(0)),
-			$index
-		);
-		$this->assertEquals(
-			array(array('tag'=>'TEXT', 'type'=>'complete', 'level'=>1, 'value'=>$tag)),
-			$values
-		);
-
-		xml_parser_free($xml_parser);
-	}
-
 	/**
 	 * test hex2bin and reverse
 	 */
diff --git a/tests/src/Util/StringsTest.php b/tests/src/Util/StringsTest.php
new file mode 100644
index 0000000000..eb5e707a70
--- /dev/null
+++ b/tests/src/Util/StringsTest.php
@@ -0,0 +1,49 @@
+<?php
+/**
+ * @file tests/src/Util/StringsTest.php
+ */
+namespace Friendica\Test\Util;
+
+use Friendica\Util\Strings;
+use PHPUnit\Framework\TestCase;
+
+/**
+ * @brief Strings utility test class
+ */
+class StringsTest extends TestCase
+{
+    /**
+	* escape and unescape
+	*/
+	public function testEscapeUnescape()
+	{
+		$text="<tag>I want to break\n this!11!<?hard?></tag>";
+		$xml=XML::escape($text);
+		$retext=XML::unescape($text);
+		$this->assertEquals($text, $retext);
+    }
+    
+	/**
+	 * escape and put in a document
+	 */
+	public function testEscapeDocument()
+	{
+		$tag="<tag>I want to break</tag>";
+		$xml=XML::escape($tag);
+		$text='<text>'.$xml.'</text>';
+		$xml_parser=xml_parser_create();
+		//should be possible to parse it
+		$values=array();
+		$index=array();
+		$this->assertEquals(1, xml_parse_into_struct($xml_parser, $text, $values, $index));
+		$this->assertEquals(
+			array('TEXT'=>array(0)),
+			$index
+		);
+		$this->assertEquals(
+			array(array('tag'=>'TEXT', 'type'=>'complete', 'level'=>1, 'value'=>$tag)),
+			$values
+		);
+		xml_parser_free($xml_parser);
+	}
+}

From 9e51be7554ead01c4ff2726d81418da6a9551137 Mon Sep 17 00:00:00 2001
From: Adam Magness <adam.magness@gmail.com>
Date: Mon, 5 Nov 2018 07:40:18 -0500
Subject: [PATCH 09/11] Revert "Update function calls"

This reverts commit 748fb8b94693ea468ef6b539d6268ea3f7ab9bea.
---
 include/conversation.php  |   3 +-
 include/text.php          |  10 +--
 mod/dfrn_confirm.php      |   3 +-
 mod/filer.php             |   4 +-
 mod/filerm.php            |   6 +-
 mod/photos.php            |   8 +--
 mod/poco.php              |   4 +-
 mod/poke.php              |   6 +-
 mod/profile.php           |   4 +-
 mod/subthread.php         |   4 +-
 mod/tagger.php            |   8 +--
 src/Content/Widget.php    |   6 +-
 src/Model/Event.php       |  10 +--
 src/Protocol/DFRN.php     |   3 +-
 src/Protocol/Diaspora.php | 143 +++++++++++++++++++-------------------
 src/Util/Strings.php      |   2 +-
 16 files changed, 110 insertions(+), 114 deletions(-)

diff --git a/include/conversation.php b/include/conversation.php
index b69ce939e8..c10a7bec73 100644
--- a/include/conversation.php
+++ b/include/conversation.php
@@ -25,7 +25,6 @@ use Friendica\Object\Post;
 use Friendica\Object\Thread;
 use Friendica\Util\DateTimeFormat;
 use Friendica\Util\Proxy as ProxyUtils;
-use Friendica\Util\Strings;
 use Friendica\Util\Temporal;
 use Friendica\Util\XML;
 
@@ -196,7 +195,7 @@ function localize_item(&$item)
 		$xmlhead="<"."?xml version='1.0' encoding='UTF-8' ?".">";
 
 		$obj = XML::parseString($xmlhead.$item['object']);
-		$links = XML::parseString($xmlhead."<links>".Strings::unescape($obj->link)."</links>");
+		$links = XML::parseString($xmlhead."<links>".XML::unescape($obj->link)."</links>");
 
 		$Bname = $obj->title;
 		$Blink = "";
diff --git a/include/text.php b/include/text.php
index 15b482f106..5da54b5fc9 100644
--- a/include/text.php
+++ b/include/text.php
@@ -26,7 +26,7 @@ use Friendica\Util\Proxy as ProxyUtils;
 use Friendica\Core\Logger;
 use Friendica\Core\Renderer;
 use Friendica\Model\FileTag;
-use Friendica\Util\Strings;
+use Friendica\Util\XML;
 
 require_once "include/conversation.php";
 
@@ -974,9 +974,9 @@ function get_cats_and_terms($item)
 	if ($cnt) {
 		foreach ($matches as $mtch) {
 			$categories[] = [
-				'name' => Strings::escape(FileTag::decode($mtch[1])),
+				'name' => XML::escape(FileTag::decode($mtch[1])),
 				'url' =>  "#",
-				'removeurl' => ((local_user() == $item['uid'])?'filerm/' . $item['id'] . '?f=&cat=' . Strings::escape(FileTag::decode($mtch[1])):""),
+				'removeurl' => ((local_user() == $item['uid'])?'filerm/' . $item['id'] . '?f=&cat=' . XML::escape(FileTag::decode($mtch[1])):""),
 				'first' => $first,
 				'last' => false
 			];
@@ -995,9 +995,9 @@ function get_cats_and_terms($item)
 		if ($cnt) {
 			foreach ($matches as $mtch) {
 				$folders[] = [
-					'name' => Strings::escape(FileTag::decode($mtch[1])),
+					'name' => XML::escape(FileTag::decode($mtch[1])),
 					'url' =>  "#",
-					'removeurl' => ((local_user() == $item['uid']) ? 'filerm/' . $item['id'] . '?f=&term=' . Strings::escape(FileTag::decode($mtch[1])) : ""),
+					'removeurl' => ((local_user() == $item['uid']) ? 'filerm/' . $item['id'] . '?f=&term=' . XML::escape(FileTag::decode($mtch[1])) : ""),
 					'first' => $first,
 					'last' => false
 				];
diff --git a/mod/dfrn_confirm.php b/mod/dfrn_confirm.php
index 449a39cbbe..0f001b11a2 100644
--- a/mod/dfrn_confirm.php
+++ b/mod/dfrn_confirm.php
@@ -33,7 +33,6 @@ use Friendica\Protocol\ActivityPub;
 use Friendica\Util\Crypto;
 use Friendica\Util\DateTimeFormat;
 use Friendica\Util\Network;
-use Friendica\Util\Strings;
 use Friendica\Util\XML;
 
 require_once 'include/enotify.php';
@@ -257,7 +256,7 @@ function dfrn_confirm_post(App $a, $handsfree = null)
 
 			$xml = XML::parseString($res);
 			$status = (int) $xml->status;
-			$message = Strings::unescape($xml->message);   // human readable text of what may have gone wrong.
+			$message = XML::unescape($xml->message);   // human readable text of what may have gone wrong.
 			switch ($status) {
 				case 0:
 					info(L10n::t("Confirmation completed successfully.") . EOL);
diff --git a/mod/filer.php b/mod/filer.php
index 1ccc4213af..3508079400 100644
--- a/mod/filer.php
+++ b/mod/filer.php
@@ -8,7 +8,7 @@ use Friendica\Core\Logger;
 use Friendica\Core\PConfig;
 use Friendica\Core\Renderer;
 use Friendica\Model\FileTag;
-use Friendica\Util\Strings;
+use Friendica\Util\XML;
 
 require_once 'include/items.php';
 
@@ -18,7 +18,7 @@ function filer_content(App $a)
 		killme();
 	}
 
-	$term = Strings::unescape(trim(defaults($_GET, 'term', '')));
+	$term = XML::unescape(trim(defaults($_GET, 'term', '')));
 	$item_id = (($a->argc > 1) ? intval($a->argv[1]) : 0);
 
 	Logger::log('filer: tag ' . $term . ' item ' . $item_id);
diff --git a/mod/filerm.php b/mod/filerm.php
index 8ad1cddbf1..335b27b320 100644
--- a/mod/filerm.php
+++ b/mod/filerm.php
@@ -4,7 +4,7 @@ use Friendica\App;
 use Friendica\Core\Logger;
 use Friendica\Core\System;
 use Friendica\Model\FileTag;
-use Friendica\Util\Strings;
+use Friendica\Util\XML;
 
 function filerm_content(App $a)
 {
@@ -13,8 +13,8 @@ function filerm_content(App $a)
 		killme();
 	}
 
-	$term = Strings::unescape(trim($_GET['term']));
-	$cat = Strings::unescape(trim($_GET['cat']));
+	$term = XML::unescape(trim($_GET['term']));
+	$cat = XML::unescape(trim($_GET['cat']));
 
 	$category = (($cat) ? true : false);
 
diff --git a/mod/photos.php b/mod/photos.php
index 0e5e3349ad..69b1972d4c 100644
--- a/mod/photos.php
+++ b/mod/photos.php
@@ -29,8 +29,8 @@ use Friendica\Protocol\DFRN;
 use Friendica\Util\DateTimeFormat;
 use Friendica\Util\Map;
 use Friendica\Util\Security;
-use Friendica\Util\Strings;
 use Friendica\Util\Temporal;
+use Friendica\Util\XML;
 
 require_once 'include/items.php';
 
@@ -683,15 +683,15 @@ function photos_post(App $a)
 					$arr['body'] .= "\n\n" . '[url=' . System::baseUrl() . '/photos/' . $owner_record['nickname'] . '/image/' . $p[0]['resource-id'] . ']' . '[img]' . System::baseUrl() . "/photo/" . $p[0]['resource-id'] . '-' . $best . '.' . $ext . '[/img][/url]' . "\n" ;
 
 					$arr['object'] = '<object><type>' . ACTIVITY_OBJ_PERSON . '</type><title>' . $tagged[0] . '</title><id>' . $tagged[1] . '/' . $tagged[0] . '</id>';
-					$arr['object'] .= '<link>' . Strings::escape('<link rel="alternate" type="text/html" href="' . $tagged[1] . '" />' . "\n");
+					$arr['object'] .= '<link>' . XML::escape('<link rel="alternate" type="text/html" href="' . $tagged[1] . '" />' . "\n");
 					if ($tagged[3]) {
-						$arr['object'] .= Strings::escape('<link rel="photo" type="'.$p[0]['type'].'" href="' . $tagged[3]['photo'] . '" />' . "\n");
+						$arr['object'] .= XML::escape('<link rel="photo" type="'.$p[0]['type'].'" href="' . $tagged[3]['photo'] . '" />' . "\n");
 					}
 					$arr['object'] .= '</link></object>' . "\n";
 
 					$arr['target'] = '<target><type>' . ACTIVITY_OBJ_IMAGE . '</type><title>' . $p[0]['desc'] . '</title><id>'
 						. System::baseUrl() . '/photos/' . $owner_record['nickname'] . '/image/' . $p[0]['resource-id'] . '</id>';
-					$arr['target'] .= '<link>' . Strings::escape('<link rel="alternate" type="text/html" href="' . System::baseUrl() . '/photos/' . $owner_record['nickname'] . '/image/' . $p[0]['resource-id'] . '" />' . "\n" . '<link rel="preview" type="'.$p[0]['type'].'" href="' . System::baseUrl() . "/photo/" . $p[0]['resource-id'] . '-' . $best . '.' . $ext . '" />') . '</link></target>';
+					$arr['target'] .= '<link>' . XML::escape('<link rel="alternate" type="text/html" href="' . System::baseUrl() . '/photos/' . $owner_record['nickname'] . '/image/' . $p[0]['resource-id'] . '" />' . "\n" . '<link rel="preview" type="'.$p[0]['type'].'" href="' . System::baseUrl() . "/photo/" . $p[0]['resource-id'] . '-' . $best . '.' . $ext . '" />') . '</link></target>';
 
 					$item_id = Item::insert($arr);
 				}
diff --git a/mod/poco.php b/mod/poco.php
index 37d7cb7a91..08677ef8d4 100644
--- a/mod/poco.php
+++ b/mod/poco.php
@@ -15,7 +15,7 @@ use Friendica\Core\System;
 use Friendica\Database\DBA;
 use Friendica\Protocol\PortableContact;
 use Friendica\Util\DateTimeFormat;
-use Friendica\Util\Strings;
+use Friendica\Util\XML;
 
 function poco_init(App $a) {
 	$system_mode = false;
@@ -376,7 +376,7 @@ function poco_init(App $a) {
 
 	if ($format === 'xml') {
 		header('Content-type: text/xml');
-		echo Renderer::replaceMacros(Renderer::getMarkupTemplate('poco_xml.tpl'), Strings::arrayEscape(['$response' => $ret]));
+		echo Renderer::replaceMacros(Renderer::getMarkupTemplate('poco_xml.tpl'), XML::arrayEscape(['$response' => $ret]));
 		killme();
 	}
 	if ($format === 'json') {
diff --git a/mod/poke.php b/mod/poke.php
index bf04d4480f..60ed5c402e 100644
--- a/mod/poke.php
+++ b/mod/poke.php
@@ -22,7 +22,7 @@ use Friendica\Core\System;
 use Friendica\Core\Worker;
 use Friendica\Database\DBA;
 use Friendica\Model\Item;
-use Friendica\Util\Strings;
+use Friendica\Util\XML;
 
 require_once 'include/items.php';
 
@@ -125,9 +125,9 @@ function poke_init(App $a)
 	$arr['body']          = '[url=' . $poster['url'] . ']' . $poster['name'] . '[/url]' . ' ' . L10n::t($verbs[$verb][0]) . ' ' . '[url=' . $target['url'] . ']' . $target['name'] . '[/url]';
 
 	$arr['object'] = '<object><type>' . ACTIVITY_OBJ_PERSON . '</type><title>' . $target['name'] . '</title><id>' . $target['url'] . '</id>';
-	$arr['object'] .= '<link>' . Strings::escape('<link rel="alternate" type="text/html" href="' . $target['url'] . '" />' . "\n");
+	$arr['object'] .= '<link>' . XML::escape('<link rel="alternate" type="text/html" href="' . $target['url'] . '" />' . "\n");
 
-	$arr['object'] .= Strings::escape('<link rel="photo" type="image/jpeg" href="' . $target['photo'] . '" />' . "\n");
+	$arr['object'] .= XML::escape('<link rel="photo" type="image/jpeg" href="' . $target['photo'] . '" />' . "\n");
 	$arr['object'] .= '</link></object>' . "\n";
 
 	$item_id = Item::insert($arr);
diff --git a/mod/profile.php b/mod/profile.php
index c94353b5c0..cfbe07dadb 100644
--- a/mod/profile.php
+++ b/mod/profile.php
@@ -24,7 +24,7 @@ use Friendica\Protocol\ActivityPub;
 use Friendica\Protocol\DFRN;
 use Friendica\Util\DateTimeFormat;
 use Friendica\Util\Security;
-use Friendica\Util\Strings;
+use Friendica\Util\XML;
 
 function profile_init(App $a)
 {
@@ -210,7 +210,7 @@ function profile_content(App $a, $update = 0)
 		$commvisitor = $commpage && $remote_contact;
 
 		$a->page['aside'] .= posted_date_widget(System::baseUrl(true) . '/profile/' . $a->profile['nickname'], $a->profile['profile_uid'], true);
-		$a->page['aside'] .= Widget::categories(System::baseUrl(true) . '/profile/' . $a->profile['nickname'], (!empty($category) ? Strings::escape($category) : ''));
+		$a->page['aside'] .= Widget::categories(System::baseUrl(true) . '/profile/' . $a->profile['nickname'], (!empty($category) ? XML::escape($category) : ''));
 		$a->page['aside'] .= Widget::tagCloud();
 
 		if (Security::canWriteToUserWall($a->profile['profile_uid'])) {
diff --git a/mod/subthread.php b/mod/subthread.php
index e3cfe39e6e..425306b6f7 100644
--- a/mod/subthread.php
+++ b/mod/subthread.php
@@ -10,7 +10,7 @@ use Friendica\Core\System;
 use Friendica\Database\DBA;
 use Friendica\Model\Item;
 use Friendica\Util\Security;
-use Friendica\Util\Strings;
+use Friendica\Util\XML;
 
 require_once 'include/items.php';
 
@@ -88,7 +88,7 @@ function subthread_content(App $a) {
 
 	$post_type = (($item['resource-id']) ? L10n::t('photo') : L10n::t('status'));
 	$objtype = (($item['resource-id']) ? ACTIVITY_OBJ_IMAGE : ACTIVITY_OBJ_NOTE );
-	$link = Strings::escape('<link rel="alternate" type="text/html" href="' . System::baseUrl() . '/display/' . $owner['nickname'] . '/' . $item['id'] . '" />' . "\n") ;
+	$link = XML::escape('<link rel="alternate" type="text/html" href="' . System::baseUrl() . '/display/' . $owner['nickname'] . '/' . $item['id'] . '" />' . "\n") ;
 	$body = $item['body'];
 
 	$obj = <<< EOT
diff --git a/mod/tagger.php b/mod/tagger.php
index f978b5d3b1..dd859e61cd 100644
--- a/mod/tagger.php
+++ b/mod/tagger.php
@@ -10,7 +10,7 @@ use Friendica\Core\System;
 use Friendica\Core\Worker;
 use Friendica\Database\DBA;
 use Friendica\Model\Item;
-use Friendica\Util\Strings;
+use Friendica\Util\XML;
 
 require_once 'include/items.php';
 
@@ -67,7 +67,7 @@ function tagger_content(App $a) {
 	}
 
 	$uri = Item::newURI($owner_uid);
-	$xterm = Strings::escape($term);
+	$xterm = XML::escape($term);
 	$post_type = (($item['resource-id']) ? L10n::t('photo') : L10n::t('status'));
 	$targettype = (($item['resource-id']) ? ACTIVITY_OBJ_IMAGE : ACTIVITY_OBJ_NOTE );
 
@@ -77,9 +77,9 @@ function tagger_content(App $a) {
 		$href = System::baseUrl() . '/display/' . $item['guid'];
 	}
 
-	$link = Strings::escape('<link rel="alternate" type="text/html" href="'. $href . '" />' . "\n") ;
+	$link = XML::escape('<link rel="alternate" type="text/html" href="'. $href . '" />' . "\n") ;
 
-	$body = Strings::escape($item['body']);
+	$body = XML::escape($item['body']);
 
 	$target = <<< EOT
 	<target>
diff --git a/src/Content/Widget.php b/src/Content/Widget.php
index 2bbf3f8258..397a1863d3 100644
--- a/src/Content/Widget.php
+++ b/src/Content/Widget.php
@@ -18,7 +18,7 @@ use Friendica\Model\Contact;
 use Friendica\Model\FileTag;
 use Friendica\Model\GContact;
 use Friendica\Model\Profile;
-use Friendica\Util\Strings;
+use Friendica\Util\XML;
 
 require_once 'boot.php';
 require_once 'include/dba.php';
@@ -190,7 +190,7 @@ class Widget
 		if ($cnt) {
 			foreach ($matches as $mtch)
 			{
-				$unescaped = Strings::escape(FileTag::decode($mtch[1]));
+				$unescaped = XML::escape(FileTag::decode($mtch[1]));
 				$terms[] = array('name' => $unescaped, 'selected' => (($selected == $unescaped) ? 'selected' : ''));
 			}
 		}
@@ -230,7 +230,7 @@ class Widget
 
 		if ($cnt) {
 			foreach ($matches as $mtch) {
-				$unescaped = Strings::escape(FileTag::decode($mtch[1]));
+				$unescaped = XML::escape(FileTag::decode($mtch[1]));
 				$terms[] = array('name' => $unescaped, 'selected' => (($selected == $unescaped) ? 'selected' : ''));
 			}
 		}
diff --git a/src/Model/Event.php b/src/Model/Event.php
index b5dec7c785..f4df6ac9f6 100644
--- a/src/Model/Event.php
+++ b/src/Model/Event.php
@@ -17,7 +17,7 @@ use Friendica\Database\DBA;
 use Friendica\Model\Contact;
 use Friendica\Util\DateTimeFormat;
 use Friendica\Util\Map;
-use Friendica\Util\Strings;
+use Friendica\Util\XML;
 
 require_once 'boot.php';
 require_once 'include/dba.php';
@@ -303,8 +303,8 @@ class Event extends BaseObject
 
 			$item = Item::selectFirst(['id'], ['event-id' => $event['id'], 'uid' => $event['uid']]);
 			if (DBA::isResult($item)) {
-				$object = '<object><type>' . Strings::escape(ACTIVITY_OBJ_EVENT) . '</type><title></title><id>' . Strings::escape($event['uri']) . '</id>';
-				$object .= '<content>' . Strings::escape(self::getBBCode($event)) . '</content>';
+				$object = '<object><type>' . XML::escape(ACTIVITY_OBJ_EVENT) . '</type><title></title><id>' . XML::escape($event['uri']) . '</id>';
+				$object .= '<content>' . XML::escape(self::getBBCode($event)) . '</content>';
 				$object .= '</object>' . "\n";
 
 				$fields = ['body' => self::getBBCode($event), 'object' => $object, 'edited' => $event['edited']];
@@ -354,8 +354,8 @@ class Event extends BaseObject
 			$item_arr['body']          = self::getBBCode($event);
 			$item_arr['event-id']      = $event['id'];
 
-			$item_arr['object']  = '<object><type>' . Strings::escape(ACTIVITY_OBJ_EVENT) . '</type><title></title><id>' . Strings::escape($event['uri']) . '</id>';
-			$item_arr['object'] .= '<content>' . Strings::escape(self::getBBCode($event)) . '</content>';
+			$item_arr['object']  = '<object><type>' . XML::escape(ACTIVITY_OBJ_EVENT) . '</type><title></title><id>' . XML::escape($event['uri']) . '</id>';
+			$item_arr['object'] .= '<content>' . XML::escape(self::getBBCode($event)) . '</content>';
 			$item_arr['object'] .= '</object>' . "\n";
 
 			$item_id = Item::insert($item_arr);
diff --git a/src/Protocol/DFRN.php b/src/Protocol/DFRN.php
index 7cb23299ba..33df28d92b 100644
--- a/src/Protocol/DFRN.php
+++ b/src/Protocol/DFRN.php
@@ -33,7 +33,6 @@ use Friendica\Object\Image;
 use Friendica\Util\Crypto;
 use Friendica\Util\DateTimeFormat;
 use Friendica\Util\Network;
-use Friendica\Util\Strings;
 use Friendica\Util\XML;
 use HTMLPurifier;
 use HTMLPurifier_Config;
@@ -2548,7 +2547,7 @@ class DFRN
 		$item["guid"] = XML::getFirstNodeValue($xpath, "dfrn:diaspora_guid/text()", $entry);
 
 		// We store the data from "dfrn:diaspora_signature" in a different table, this is done in "Item::insert"
-		$dsprsig = Strings::unescape(XML::getFirstNodeValue($xpath, "dfrn:diaspora_signature/text()", $entry));
+		$dsprsig = XML::unescape(XML::getFirstNodeValue($xpath, "dfrn:diaspora_signature/text()", $entry));
 		if ($dsprsig != "") {
 			$item["dsprsig"] = $dsprsig;
 		}
diff --git a/src/Protocol/Diaspora.php b/src/Protocol/Diaspora.php
index 30db886b46..0b5c9c9496 100644
--- a/src/Protocol/Diaspora.php
+++ b/src/Protocol/Diaspora.php
@@ -34,7 +34,6 @@ use Friendica\Util\Crypto;
 use Friendica\Util\DateTimeFormat;
 use Friendica\Util\Map;
 use Friendica\Util\Network;
-use Friendica\Util\Strings;
 use Friendica\Util\XML;
 use SimpleXMLElement;
 
@@ -464,7 +463,7 @@ class Diaspora
 		}
 
 		return ['message' => (string)base64url_decode($base->data),
-				'author' => Strings::unescape($author_addr),
+				'author' => XML::unescape($author_addr),
 				'key' => (string)$key];
 	}
 
@@ -604,7 +603,7 @@ class Diaspora
 		Logger::log('Message verified.');
 
 		return ['message' => (string)$inner_decrypted,
-				'author' => Strings::unescape($author_link),
+				'author' => XML::unescape($author_link),
 				'key' => (string)$key];
 	}
 
@@ -1506,9 +1505,9 @@ class Diaspora
 	 */
 	private static function receiveAccountMigration(array $importer, $data)
 	{
-		$old_handle = notags(Strings::unescape($data->author));
-		$new_handle = notags(Strings::unescape($data->profile->author));
-		$signature = notags(Strings::unescape($data->signature));
+		$old_handle = notags(XML::unescape($data->author));
+		$new_handle = notags(XML::unescape($data->profile->author));
+		$signature = notags(XML::unescape($data->signature));
 
 		$contact = self::contactByHandle($importer["uid"], $old_handle);
 		if (!$contact) {
@@ -1566,7 +1565,7 @@ class Diaspora
 	 */
 	private static function receiveAccountDeletion($data)
 	{
-		$author = notags(Strings::unescape($data->author));
+		$author = notags(XML::unescape($data->author));
 
 		$contacts = DBA::select('contact', ['id'], ['addr' => $author]);
 		while ($contact = DBA::fetch($contacts)) {
@@ -1657,19 +1656,19 @@ class Diaspora
 	 */
 	private static function receiveComment(array $importer, $sender, $data, $xml)
 	{
-		$author = notags(Strings::unescape($data->author));
-		$guid = notags(Strings::unescape($data->guid));
-		$parent_guid = notags(Strings::unescape($data->parent_guid));
-		$text = Strings::unescape($data->text);
+		$author = notags(XML::unescape($data->author));
+		$guid = notags(XML::unescape($data->guid));
+		$parent_guid = notags(XML::unescape($data->parent_guid));
+		$text = XML::unescape($data->text);
 
 		if (isset($data->created_at)) {
-			$created_at = DateTimeFormat::utc(notags(Strings::unescape($data->created_at)));
+			$created_at = DateTimeFormat::utc(notags(XML::unescape($data->created_at)));
 		} else {
 			$created_at = DateTimeFormat::utcNow();
 		}
 
 		if (isset($data->thread_parent_guid)) {
-			$thread_parent_guid = notags(Strings::unescape($data->thread_parent_guid));
+			$thread_parent_guid = notags(XML::unescape($data->thread_parent_guid));
 			$thr_uri = self::getUriFromGuid("", $thread_parent_guid, true);
 		} else {
 			$thr_uri = "";
@@ -1774,24 +1773,24 @@ class Diaspora
 	 */
 	private static function receiveConversationMessage(array $importer, array $contact, $data, $msg, $mesg, $conversation)
 	{
-		$author = notags(Strings::unescape($data->author));
-		$guid = notags(Strings::unescape($data->guid));
-		$subject = notags(Strings::unescape($data->subject));
+		$author = notags(XML::unescape($data->author));
+		$guid = notags(XML::unescape($data->guid));
+		$subject = notags(XML::unescape($data->subject));
 
 		// "diaspora_handle" is the element name from the old version
 		// "author" is the element name from the new version
 		if ($mesg->author) {
-			$msg_author = notags(Strings::unescape($mesg->author));
+			$msg_author = notags(XML::unescape($mesg->author));
 		} elseif ($mesg->diaspora_handle) {
-			$msg_author = notags(Strings::unescape($mesg->diaspora_handle));
+			$msg_author = notags(XML::unescape($mesg->diaspora_handle));
 		} else {
 			return false;
 		}
 
-		$msg_guid = notags(Strings::unescape($mesg->guid));
-		$msg_conversation_guid = notags(Strings::unescape($mesg->conversation_guid));
-		$msg_text = Strings::unescape($mesg->text);
-		$msg_created_at = DateTimeFormat::utc(notags(Strings::unescape($mesg->created_at)));
+		$msg_guid = notags(XML::unescape($mesg->guid));
+		$msg_conversation_guid = notags(XML::unescape($mesg->conversation_guid));
+		$msg_text = XML::unescape($mesg->text);
+		$msg_created_at = DateTimeFormat::utc(notags(XML::unescape($mesg->created_at)));
 
 		if ($msg_conversation_guid != $guid) {
 			Logger::log("message conversation guid does not belong to the current conversation.");
@@ -1862,11 +1861,11 @@ class Diaspora
 	 */
 	private static function receiveConversation(array $importer, $msg, $data)
 	{
-		$author = notags(Strings::unescape($data->author));
-		$guid = notags(Strings::unescape($data->guid));
-		$subject = notags(Strings::unescape($data->subject));
-		$created_at = DateTimeFormat::utc(notags(Strings::unescape($data->created_at)));
-		$participants = notags(Strings::unescape($data->participants));
+		$author = notags(XML::unescape($data->author));
+		$guid = notags(XML::unescape($data->guid));
+		$subject = notags(XML::unescape($data->subject));
+		$created_at = DateTimeFormat::utc(notags(XML::unescape($data->created_at)));
+		$participants = notags(XML::unescape($data->participants));
 
 		$messages = $data->message;
 
@@ -1920,11 +1919,11 @@ class Diaspora
 	 */
 	private static function receiveLike(array $importer, $sender, $data)
 	{
-		$author = notags(Strings::unescape($data->author));
-		$guid = notags(Strings::unescape($data->guid));
-		$parent_guid = notags(Strings::unescape($data->parent_guid));
-		$parent_type = notags(Strings::unescape($data->parent_type));
-		$positive = notags(Strings::unescape($data->positive));
+		$author = notags(XML::unescape($data->author));
+		$guid = notags(XML::unescape($data->guid));
+		$parent_guid = notags(XML::unescape($data->parent_guid));
+		$parent_type = notags(XML::unescape($data->parent_type));
+		$positive = notags(XML::unescape($data->positive));
 
 		// likes on comments aren't supported by Diaspora - only on posts
 		// But maybe this will be supported in the future, so we will accept it.
@@ -2029,11 +2028,11 @@ class Diaspora
 	 */
 	private static function receiveMessage(array $importer, $data)
 	{
-		$author = notags(Strings::unescape($data->author));
-		$guid = notags(Strings::unescape($data->guid));
-		$conversation_guid = notags(Strings::unescape($data->conversation_guid));
-		$text = Strings::unescape($data->text);
-		$created_at = DateTimeFormat::utc(notags(Strings::unescape($data->created_at)));
+		$author = notags(XML::unescape($data->author));
+		$guid = notags(XML::unescape($data->guid));
+		$conversation_guid = notags(XML::unescape($data->conversation_guid));
+		$text = XML::unescape($data->text);
+		$created_at = DateTimeFormat::utc(notags(XML::unescape($data->created_at)));
 
 		$contact = self::allowedContactByHandle($importer, $author, true);
 		if (!$contact) {
@@ -2104,8 +2103,8 @@ class Diaspora
 	 */
 	private static function receiveParticipation(array $importer, $data)
 	{
-		$author = strtolower(notags(Strings::unescape($data->author)));
-		$parent_guid = notags(Strings::unescape($data->parent_guid));
+		$author = strtolower(notags(XML::unescape($data->author)));
+		$parent_guid = notags(XML::unescape($data->parent_guid));
 
 		$contact_id = Contact::getIdForURL($author);
 		if (!$contact_id) {
@@ -2197,22 +2196,22 @@ class Diaspora
 	 */
 	private static function receiveProfile(array $importer, $data)
 	{
-		$author = strtolower(notags(Strings::unescape($data->author)));
+		$author = strtolower(notags(XML::unescape($data->author)));
 
 		$contact = self::contactByHandle($importer["uid"], $author);
 		if (!$contact) {
 			return false;
 		}
 
-		$name = Strings::unescape($data->first_name).((strlen($data->last_name)) ? " ".Strings::unescape($data->last_name) : "");
-		$image_url = Strings::unescape($data->image_url);
-		$birthday = Strings::unescape($data->birthday);
-		$gender = Strings::unescape($data->gender);
-		$about = Markdown::toBBCode(Strings::unescape($data->bio));
-		$location = Markdown::toBBCode(Strings::unescape($data->location));
-		$searchable = (Strings::unescape($data->searchable) == "true");
-		$nsfw = (Strings::unescape($data->nsfw) == "true");
-		$tags = Strings::unescape($data->tag_string);
+		$name = XML::unescape($data->first_name).((strlen($data->last_name)) ? " ".XML::unescape($data->last_name) : "");
+		$image_url = XML::unescape($data->image_url);
+		$birthday = XML::unescape($data->birthday);
+		$gender = XML::unescape($data->gender);
+		$about = Markdown::toBBCode(XML::unescape($data->bio));
+		$location = Markdown::toBBCode(XML::unescape($data->location));
+		$searchable = (XML::unescape($data->searchable) == "true");
+		$nsfw = (XML::unescape($data->nsfw) == "true");
+		$tags = XML::unescape($data->tag_string);
 
 		$tags = explode("#", $tags);
 
@@ -2311,8 +2310,8 @@ class Diaspora
 	 */
 	private static function receiveContactRequest(array $importer, $data)
 	{
-		$author = Strings::unescape($data->author);
-		$recipient = Strings::unescape($data->recipient);
+		$author = XML::unescape($data->author);
+		$recipient = XML::unescape($data->recipient);
 
 		if (!$author || !$recipient) {
 			return false;
@@ -2321,13 +2320,13 @@ class Diaspora
 		// the current protocol version doesn't know these fields
 		// That means that we will assume their existance
 		if (isset($data->following)) {
-			$following = (Strings::unescape($data->following) == "true");
+			$following = (XML::unescape($data->following) == "true");
 		} else {
 			$following = true;
 		}
 
 		if (isset($data->sharing)) {
-			$sharing = (Strings::unescape($data->sharing) == "true");
+			$sharing = (XML::unescape($data->sharing) == "true");
 		} else {
 			$sharing = true;
 		}
@@ -2574,13 +2573,13 @@ class Diaspora
 	 */
 	private static function receiveReshare(array $importer, $data, $xml)
 	{
-		$author = notags(Strings::unescape($data->author));
-		$guid = notags(Strings::unescape($data->guid));
-		$created_at = DateTimeFormat::utc(notags(Strings::unescape($data->created_at)));
-		$root_author = notags(Strings::unescape($data->root_author));
-		$root_guid = notags(Strings::unescape($data->root_guid));
+		$author = notags(XML::unescape($data->author));
+		$guid = notags(XML::unescape($data->guid));
+		$created_at = DateTimeFormat::utc(notags(XML::unescape($data->created_at)));
+		$root_author = notags(XML::unescape($data->root_author));
+		$root_guid = notags(XML::unescape($data->root_guid));
 		/// @todo handle unprocessed property "provider_display_name"
-		$public = notags(Strings::unescape($data->public));
+		$public = notags(XML::unescape($data->public));
 
 		$contact = self::allowedContactByHandle($importer, $author, false);
 		if (!$contact) {
@@ -2666,9 +2665,9 @@ class Diaspora
 	 */
 	private static function itemRetraction(array $importer, array $contact, $data)
 	{
-		$author = notags(Strings::unescape($data->author));
-		$target_guid = notags(Strings::unescape($data->target_guid));
-		$target_type = notags(Strings::unescape($data->target_type));
+		$author = notags(XML::unescape($data->author));
+		$target_guid = notags(XML::unescape($data->target_guid));
+		$target_type = notags(XML::unescape($data->target_type));
 
 		$person = self::personByHandle($author);
 		if (!is_array($person)) {
@@ -2730,7 +2729,7 @@ class Diaspora
 	 */
 	private static function receiveRetraction(array $importer, $sender, $data)
 	{
-		$target_type = notags(Strings::unescape($data->target_type));
+		$target_type = notags(XML::unescape($data->target_type));
 
 		$contact = self::contactByHandle($importer["uid"], $sender);
 		if (!$contact && (in_array($target_type, ["Contact", "Person"]))) {
@@ -2775,12 +2774,12 @@ class Diaspora
 	 */
 	private static function receiveStatusMessage(array $importer, SimpleXMLElement $data, $xml)
 	{
-		$author = notags(Strings::unescape($data->author));
-		$guid = notags(Strings::unescape($data->guid));
-		$created_at = DateTimeFormat::utc(notags(Strings::unescape($data->created_at)));
-		$public = notags(Strings::unescape($data->public));
-		$text = Strings::unescape($data->text);
-		$provider_display_name = notags(Strings::unescape($data->provider_display_name));
+		$author = notags(XML::unescape($data->author));
+		$guid = notags(XML::unescape($data->guid));
+		$created_at = DateTimeFormat::utc(notags(XML::unescape($data->created_at)));
+		$public = notags(XML::unescape($data->public));
+		$text = XML::unescape($data->text);
+		$provider_display_name = notags(XML::unescape($data->provider_display_name));
 
 		$contact = self::allowedContactByHandle($importer, $author, false);
 		if (!$contact) {
@@ -2795,7 +2794,7 @@ class Diaspora
 		$address = [];
 		if ($data->location) {
 			foreach ($data->location->children() as $fieldname => $data) {
-				$address[$fieldname] = notags(Strings::unescape($data));
+				$address[$fieldname] = notags(XML::unescape($data));
 			}
 		}
 
@@ -2806,8 +2805,8 @@ class Diaspora
 		// Attach embedded pictures to the body
 		if ($data->photo) {
 			foreach ($data->photo as $photo) {
-				$body = "[img]".Strings::unescape($photo->remote_photo_path).
-					Strings::unescape($photo->remote_photo_name)."[/img]\n".$body;
+				$body = "[img]".XML::unescape($photo->remote_photo_path).
+					XML::unescape($photo->remote_photo_name)."[/img]\n".$body;
 			}
 
 			$datarray["object-type"] = ACTIVITY_OBJ_IMAGE;
diff --git a/src/Util/Strings.php b/src/Util/Strings.php
index 19843d9f61..5efc214afc 100644
--- a/src/Util/Strings.php
+++ b/src/Util/Strings.php
@@ -44,7 +44,7 @@ class Strings
 		if (is_bool($val)) {
 			return $val?"true":"false";
 		} elseif (is_array($val)) {
-			return array_map('Strings::arrayEscape', $val);
+			return array_map('XML::arrayEscape', $val);
 		}
 		return self::escape((string) $val);
 	}

From 186cd1d41578fcfc78f11d561880b332ce596617 Mon Sep 17 00:00:00 2001
From: Adam Magness <adam.magness@gmail.com>
Date: Mon, 5 Nov 2018 07:31:45 -0500
Subject: [PATCH 10/11] Revert "Move methods to new Util/Strings class"

This reverts commit 97fcf23371cb24c7c9dbb144ed7f250813176f45.
---
 src/Util/Strings.php | 51 --------------------------------------------
 src/Util/XML.php     | 50 +++++++++++++++++++++++++++++++++++++------
 2 files changed, 44 insertions(+), 57 deletions(-)
 delete mode 100644 src/Util/Strings.php

diff --git a/src/Util/Strings.php b/src/Util/Strings.php
deleted file mode 100644
index 5efc214afc..0000000000
--- a/src/Util/Strings.php
+++ /dev/null
@@ -1,51 +0,0 @@
-<?php
-/**
- * @file src/Util/Strings.php
- */
-
-namespace Friendica\Util;
-
-/**
- * @brief This class contains methods to modify/transform strings.
- */
-class Strings
-{
-    /**
-	 * escape text ($str) for XML transport
-	 * @param string $str
-	 * @return string Escaped text.
-	 */
-	public static function escape($str)
-	{
-		$buffer = htmlspecialchars($str, ENT_QUOTES, "UTF-8");
-		$buffer = trim($buffer);
-
-		return $buffer;
-	}
-
-	/**
-	 * undo an escape
-	 * @param string $s xml escaped text
-	 * @return string unescaped text
-	 */
-	public static function unescape($s)
-	{
-		$ret = htmlspecialchars_decode($s, ENT_QUOTES);
-		return $ret;
-	}
-
-	/**
-	 * apply escape() to all values of array $val, recursively
-	 * @param array $val
-	 * @return array
-	 */
-	public static function arrayEscape($val)
-	{
-		if (is_bool($val)) {
-			return $val?"true":"false";
-		} elseif (is_array($val)) {
-			return array_map('XML::arrayEscape', $val);
-		}
-		return self::escape((string) $val);
-	}
-}
diff --git a/src/Util/XML.php b/src/Util/XML.php
index ed0d4bbb04..c115e4d0de 100644
--- a/src/Util/XML.php
+++ b/src/Util/XML.php
@@ -5,7 +5,6 @@
 namespace Friendica\Util;
 
 use Friendica\Core\Logger;
-use Friendica\Util\Strings;
 use DOMXPath;
 use SimpleXMLElement;
 
@@ -37,7 +36,7 @@ class XML
 					$root = new SimpleXMLElement("<".$key."/>");
 					self::fromArray($value, $root, $remove_header, $namespaces, false);
 				} else {
-					$root = new SimpleXMLElement("<".$key.">".Strings::escape($value)."</".$key.">");
+					$root = new SimpleXMLElement("<".$key.">".self::escape($value)."</".$key.">");
 				}
 
 				$dom = dom_import_simplexml($root)->ownerDocument;
@@ -105,7 +104,7 @@ class XML
 			}
 
 			if (!is_array($value)) {
-				$element = $xml->addChild($key, Strings::escape($value), $namespace);
+				$element = $xml->addChild($key, self::escape($value), $namespace);
 			} elseif (is_array($value)) {
 				$element = $xml->addChild($key, null, $namespace);
 				self::fromArray($value, $element, $remove_header, $namespaces, false);
@@ -124,7 +123,7 @@ class XML
 	public static function copy(&$source, &$target, $elementname)
 	{
 		if (count($source->children()) == 0) {
-			$target->addChild($elementname, Strings::escape($source));
+			$target->addChild($elementname, self::escape($source));
 		} else {
 			$child = $target->addChild($elementname);
 			foreach ($source->children() as $childfield => $childentry) {
@@ -145,11 +144,11 @@ class XML
 	 */
 	public static function createElement($doc, $element, $value = "", $attributes = [])
 	{
-		$element = $doc->createElement($element, Strings::escape($value));
+		$element = $doc->createElement($element, self::escape($value));
 
 		foreach ($attributes as $key => $value) {
 			$attribute = $doc->createAttribute($key);
-			$attribute->value = Strings::escape($value);
+			$attribute->value = self::escape($value);
 			$element->appendChild($attribute);
 		}
 		return $element;
@@ -463,4 +462,43 @@ class XML
 
 		return $first_item->attributes;
 	}
+
+	/**
+	 * escape text ($str) for XML transport
+	 * @param string $str
+	 * @return string Escaped text.
+	 */
+	public static function escape($str)
+	{
+		$buffer = htmlspecialchars($str, ENT_QUOTES, "UTF-8");
+		$buffer = trim($buffer);
+
+		return $buffer;
+	}
+
+	/**
+	 * undo an escape
+	 * @param string $s xml escaped text
+	 * @return string unescaped text
+	 */
+	public static function unescape($s)
+	{
+		$ret = htmlspecialchars_decode($s, ENT_QUOTES);
+		return $ret;
+	}
+
+	/**
+	 * apply escape() to all values of array $val, recursively
+	 * @param array $val
+	 * @return array
+	 */
+	public static function arrayEscape($val)
+	{
+		if (is_bool($val)) {
+			return $val?"true":"false";
+		} elseif (is_array($val)) {
+			return array_map('XML::arrayEscape', $val);
+		}
+		return self::escape((string) $val);
+	}
 }

From cace4a8991575418e13a4212b20c220a5c8f227a Mon Sep 17 00:00:00 2001
From: Adam Magness <adam.magness@gmail.com>
Date: Mon, 5 Nov 2018 13:08:33 -0500
Subject: [PATCH 11/11] Update and rename test class

update and rename test class.
---
 tests/src/Util/{StringsTest.php => XmlTest.php} | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)
 rename tests/src/Util/{StringsTest.php => XmlTest.php} (86%)

diff --git a/tests/src/Util/StringsTest.php b/tests/src/Util/XmlTest.php
similarity index 86%
rename from tests/src/Util/StringsTest.php
rename to tests/src/Util/XmlTest.php
index eb5e707a70..ba78e4ff1a 100644
--- a/tests/src/Util/StringsTest.php
+++ b/tests/src/Util/XmlTest.php
@@ -1,16 +1,16 @@
 <?php
 /**
- * @file tests/src/Util/StringsTest.php
+ * @file tests/src/Util/XmlTest.php
  */
 namespace Friendica\Test\Util;
 
-use Friendica\Util\Strings;
+use Friendica\Util\XML;
 use PHPUnit\Framework\TestCase;
 
 /**
- * @brief Strings utility test class
+ * @brief XML utility test class
  */
-class StringsTest extends TestCase
+class XmlTest extends TestCase
 {
     /**
 	* escape and unescape