1
0
Fork 0
mirror of https://github.com/syncthing/syncthing-android.git synced 2024-11-26 06:11:19 +00:00

Preserve xml encoding on read, parse and save (fixes #88) (#89)

* Preserve xml encoding on read, parse and save (fixes #88)
This commit is contained in:
Catfriend1 2018-10-11 22:42:34 +02:00 committed by GitHub
parent f9145b9fd5
commit 85daca6eb7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -12,16 +12,15 @@ import com.nutomic.syncthingandroid.R;
import com.nutomic.syncthingandroid.service.Constants; import com.nutomic.syncthingandroid.service.Constants;
import com.nutomic.syncthingandroid.service.SyncthingRunnable; import com.nutomic.syncthingandroid.service.SyncthingRunnable;
import org.mindrot.jbcrypt.BCrypt; import java.io.ByteArrayOutputStream;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
import java.io.File;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.io.IOException; import java.io.IOException;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException; import java.net.MalformedURLException;
import java.net.URL; import java.net.URL;
import java.util.Locale; import java.util.Locale;
@ -33,12 +32,21 @@ import javax.inject.Inject;
import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer; import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException; import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory; import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource; import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult; import javax.xml.transform.stream.StreamResult;
import org.mindrot.jbcrypt.BCrypt;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
import org.xml.sax.InputSource;
/** /**
* Provides direct access to the config.xml file in the file system. * Provides direct access to the config.xml file in the file system.
* This class should only be used if the syncthing API is not available (usually during startup). * This class should only be used if the syncthing API is not available (usually during startup).
@ -95,14 +103,19 @@ public class ConfigXml {
throw new OpenConfigException(); throw new OpenConfigException();
} }
try { try {
FileInputStream inputStream = new FileInputStream(mConfigFile);
InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "UTF-8");
InputSource inputSource = new InputSource(inputStreamReader);
inputSource.setEncoding("UTF-8");
DocumentBuilder db = DocumentBuilderFactory.newInstance().newDocumentBuilder(); DocumentBuilder db = DocumentBuilderFactory.newInstance().newDocumentBuilder();
Log.d(TAG, "Trying to read '" + mConfigFile + "'"); Log.d(TAG, "Parsing config file '" + mConfigFile + "'");
mConfig = db.parse(mConfigFile); mConfig = db.parse(inputSource);
inputStream.close();
Log.i(TAG, "Successfully parsed config file");
} catch (SAXException | ParserConfigurationException | IOException e) { } catch (SAXException | ParserConfigurationException | IOException e) {
Log.w(TAG, "Cannot read '" + mConfigFile + "'", e); Log.w(TAG, "Failed to parse config file '" + mConfigFile + "'", e);
throw new OpenConfigException(); throw new OpenConfigException();
} }
Log.i(TAG, "Loaded Syncthing config file");
} }
public URL getWebGuiUrl() { public URL getWebGuiUrl() {
@ -339,14 +352,34 @@ public class ConfigXml {
Log.i(TAG, "Writing updated config file"); Log.i(TAG, "Writing updated config file");
File mConfigTempFile = Constants.getConfigTempFile(mContext); File mConfigTempFile = Constants.getConfigTempFile(mContext);
try { try {
// Write XML header.
FileOutputStream fileOutputStream = new FileOutputStream(mConfigTempFile);
fileOutputStream.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>".getBytes("UTF-8"));
// Prepare Object-to-XML transform.
TransformerFactory transformerFactory = TransformerFactory.newInstance(); TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer(); Transformer transformer = transformerFactory.newTransformer();
DOMSource domSource = new DOMSource(mConfig); transformer.setOutputProperty(OutputKeys.METHOD, "xml");
StreamResult streamResult = new StreamResult(mConfigTempFile); transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-16");
transformer.transform(domSource, streamResult); transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
transformer.setOutputProperty(OutputKeys.INDENT, "no");
// Output XML body.
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
StreamResult streamResult = new StreamResult(new OutputStreamWriter(byteArrayOutputStream, "UTF-8"));
transformer.transform(new DOMSource(mConfig), streamResult);
byte[] outputBytes = byteArrayOutputStream.toByteArray();
fileOutputStream.write(outputBytes);
fileOutputStream.close();
} catch (TransformerException e) { } catch (TransformerException e) {
Log.w(TAG, "Failed to save temporary config file", e); Log.w(TAG, "Failed to transform object to xml and save temporary config file", e);
return; return;
} catch (FileNotFoundException e) {
Log.w(TAG, "Failed to save temporary config file, FileNotFoundException", e);
} catch (UnsupportedEncodingException e) {
Log.w(TAG, "Failed to save temporary config file, UnsupportedEncodingException", e);
} catch (IOException e) {
Log.w(TAG, "Failed to save temporary config file, IOException", e);
} }
try { try {
mConfigTempFile.renameTo(mConfigFile); mConfigTempFile.renameTo(mConfigFile);