]> nmode's Git Repositories - signal-cli/commitdiff
Prevent corrupting account file, when serialization fails
authorAsamK <asamk@gmx.de>
Fri, 11 Sep 2020 07:14:41 +0000 (09:14 +0200)
committerAsamK <asamk@gmx.de>
Fri, 11 Sep 2020 07:14:41 +0000 (09:14 +0200)
src/main/java/org/asamk/signal/storage/SignalAccount.java

index f3acb47ccc98304e71ca1971382486da8d39d200..6043d803407b82457359ed59e5044797605184e4 100644 (file)
@@ -34,6 +34,8 @@ import org.whispersystems.libsignal.util.Pair;
 import org.whispersystems.signalservice.api.push.SignalServiceAddress;
 import org.whispersystems.util.Base64;
 
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
 import java.io.Closeable;
 import java.io.File;
 import java.io.IOException;
@@ -305,11 +307,16 @@ public class SignalAccount implements Closeable {
                 .putPOJO("profileStore", profileStore)
         ;
         try {
-            synchronized (fileChannel) {
-                fileChannel.position(0);
-                jsonProcessor.writeValue(Channels.newOutputStream(fileChannel), rootNode);
-                fileChannel.truncate(fileChannel.position());
-                fileChannel.force(false);
+            try (ByteArrayOutputStream output = new ByteArrayOutputStream()) {
+                // Write to memory first to prevent corrupting the file in case of serialization errors
+                jsonProcessor.writeValue(output, rootNode);
+                ByteArrayInputStream input = new ByteArrayInputStream(output.toByteArray());
+                synchronized (fileChannel) {
+                    fileChannel.position(0);
+                    input.transferTo(Channels.newOutputStream(fileChannel));
+                    fileChannel.truncate(fileChannel.position());
+                    fileChannel.force(false);
+                }
             }
         } catch (Exception e) {
             System.err.println(String.format("Error saving file: %s", e.getMessage()));