update_engine: Remove g_markup_escape_text usage.

g_markup_escape_text() is used to encode attributes before assembling
them in a XML request. To remove this dependency on glib we re-implement
it here.

BUG=chromium:499886
TEST=Unittest still pass. Updated with more cases.

Change-Id: Ib0b8e603c779741b7463a823dd8e94b3abf68525
Reviewed-on: https://chromium-review.googlesource.com/280585
Tested-by: Alex Deymo <deymo@chromium.org>
Reviewed-by: Jorge Lucangeli Obes <jorgelo@chromium.org>
Commit-Queue: Alex Deymo <deymo@chromium.org>
diff --git a/omaha_request_action.cc b/omaha_request_action.cc
index 251e607..c5cda55 100644
--- a/omaha_request_action.cc
+++ b/omaha_request_action.cc
@@ -435,11 +435,31 @@
     utils::HexDumpString(input);
     return false;
   }
-  gchar* escaped = g_markup_escape_text(input.c_str(), input.size());
-  if (escaped == nullptr)
-    return false;
-  *output = string(escaped);
-  g_free(escaped);
+  output->clear();
+  // We need at least input.size() space in the output, but the code below will
+  // handle it if we need more.
+  output->reserve(input.size());
+  for (char c : input) {
+    switch (c) {
+      case '\"':
+        output->append("&quot;");
+        break;
+      case '\'':
+        output->append("&apos;");
+        break;
+      case '&':
+        output->append("&amp;");
+        break;
+      case '<':
+        output->append("&lt;");
+        break;
+      case '>':
+        output->append("&gt;");
+        break;
+      default:
+        output->push_back(c);
+    }
+  }
   return true;
 }
 
diff --git a/omaha_request_action_unittest.cc b/omaha_request_action_unittest.cc
index 7ea513b..04c230d 100644
--- a/omaha_request_action_unittest.cc
+++ b/omaha_request_action_unittest.cc
@@ -983,11 +983,11 @@
   EXPECT_EQ("ab", output);
   EXPECT_TRUE(XmlEncode("a<b", &output));
   EXPECT_EQ("a&lt;b", output);
-  EXPECT_TRUE(XmlEncode("<&>", &output));
-  EXPECT_EQ("&lt;&amp;&gt;", output);
+  EXPECT_TRUE(XmlEncode("<&>\"\'\\", &output));
+  EXPECT_EQ("&lt;&amp;&gt;&quot;&apos;\\", output);
   EXPECT_TRUE(XmlEncode("&lt;&amp;&gt;", &output));
   EXPECT_EQ("&amp;lt;&amp;amp;&amp;gt;", output);
-  // g_markup_escape_text() would crash with unterminated UTF-8 strings.
+  // Check that unterminated UTF-8 strings are handled properly.
   EXPECT_FALSE(XmlEncode("\xc2", &output));
   // Fail with invalid ASCII-7 chars.
   EXPECT_FALSE(XmlEncode("This is an 'n' with a tilde: \xc3\xb1", &output));