parse_xml.cpp: Deserilization does not touch lastError()

The global mLastError fields for each converters can
potentially cause a segfault when a program with multiple
threads tries to deserialize a bad file at the same time.

- deserialization APIs that touches the mLastError field are
  marked as non-const APIs
- const variants are provided (error is provided as an output
  parameter)
- Functionalities are equivalent (tests ensure this).

Test: libvintf_test
Test: vintf_object_test
Fixes: 71874788

Change-Id: I416de909b32809a4ac377d9da998c48d7d409457
diff --git a/test/LibVintfTest.cpp b/test/LibVintfTest.cpp
index ef19a4c..6eedf01 100644
--- a/test/LibVintfTest.cpp
+++ b/test/LibVintfTest.cpp
@@ -32,12 +32,12 @@
 namespace android {
 namespace vintf {
 
-extern const XmlConverter<Version> &gVersionConverter;
-extern const XmlConverter<ManifestHal> &gManifestHalConverter;
-extern const XmlConverter<MatrixHal> &gMatrixHalConverter;
-extern const XmlConverter<KernelConfigTypedValue> &gKernelConfigTypedValueConverter;
-extern const XmlConverter<HalManifest> &gHalManifestConverter;
-extern const XmlConverter<CompatibilityMatrix> &gCompatibilityMatrixConverter;
+extern XmlConverter<Version>& gVersionConverter;
+extern XmlConverter<ManifestHal>& gManifestHalConverter;
+extern XmlConverter<MatrixHal>& gMatrixHalConverter;
+extern XmlConverter<KernelConfigTypedValue>& gKernelConfigTypedValueConverter;
+extern XmlConverter<HalManifest>& gHalManifestConverter;
+extern XmlConverter<CompatibilityMatrix>& gCompatibilityMatrixConverter;
 
 static bool In(const std::string& sub, const std::string& str) {
     return str.find(sub) != std::string::npos;
@@ -2749,6 +2749,33 @@
     }
 }
 
+TEST_F(LibVintfTest, ManifestLastError) {
+    HalManifest e;
+    // Set mLastError to something else before testing.
+    EXPECT_FALSE(gHalManifestConverter(&e, "<manifest/>"));
+    EXPECT_NE("Not a valid XML", gHalManifestConverter.lastError());
+
+    std::string error;
+    std::string prevError = gHalManifestConverter.lastError();
+    EXPECT_FALSE(gHalManifestConverter(&e, "", &error));
+    EXPECT_EQ("Not a valid XML", error);
+    EXPECT_EQ(prevError, gHalManifestConverter.lastError()) << "lastError() should not be modified";
+}
+
+TEST_F(LibVintfTest, MatrixLastError) {
+    CompatibilityMatrix e;
+    // Set mLastError to something else before testing.
+    EXPECT_FALSE(gCompatibilityMatrixConverter(&e, "<compatibility-matrix/>"));
+    EXPECT_NE("Not a valid XML", gCompatibilityMatrixConverter.lastError());
+
+    std::string error;
+    std::string prevError = gCompatibilityMatrixConverter.lastError();
+    EXPECT_FALSE(gCompatibilityMatrixConverter(&e, "", &error));
+    EXPECT_EQ("Not a valid XML", error);
+    EXPECT_EQ(prevError, gCompatibilityMatrixConverter.lastError())
+        << "lastError() should not be modified";
+}
+
 } // namespace vintf
 } // namespace android