OSDN Git Service

search for a valid journal
authorChris Wren <cwren@android.com>
Fri, 10 Jan 2014 19:11:25 +0000 (14:11 -0500)
committerChris Wren <cwren@android.com>
Tue, 14 Jan 2014 22:46:27 +0000 (17:46 -0500)
there are too many bytes, so we need to find the valid subset,
without stepping past the end!

Bug: 12489602
Change-Id: Ic9d7c804c199740ff50d0864f99632ae68619369

src/com/android/launcher3/LauncherBackupHelper.java

index 556d4af..7268b08 100644 (file)
@@ -858,7 +858,7 @@ public class LauncherBackupHelper implements BackupHelper {
      * in that case, do a full backup.
      *
      * @param oldState the read-0only file descriptor pointing to the old journal
-     * @return a Journal protocol bugffer
+     * @return a Journal protocol buffer
      */
     private Journal readJournal(ParcelFileDescriptor oldState) {
         Journal journal = new Journal();
@@ -867,39 +867,51 @@ public class LauncherBackupHelper implements BackupHelper {
         }
         FileInputStream inStream = new FileInputStream(oldState.getFileDescriptor());
         try {
-            int remaining = inStream.available();
-            if (DEBUG) Log.d(TAG, "available " + remaining);
-            if (remaining < MAX_JOURNAL_SIZE) {
-                byte[] buffer = new byte[remaining];
+            int availableBytes = inStream.available();
+            if (DEBUG) Log.d(TAG, "available " + availableBytes);
+            if (availableBytes < MAX_JOURNAL_SIZE) {
+                byte[] buffer = new byte[availableBytes];
                 int bytesRead = 0;
-                while (remaining > 0) {
+                boolean valid = false;
+                while (availableBytes > 0) {
                     try {
-                        int result = inStream.read(buffer, bytesRead, remaining);
+                        // OMG what are you doing? This is crazy inefficient!
+                        // If we read a byte that is not ours, we will cause trouble: b/12491813
+                        // However, we don't know how many bytes to expect (oops).
+                        // So we have to step through *slowly*, watching for the end.
+                        int result = inStream.read(buffer, bytesRead, 1);
                         if (result > 0) {
-                            if (DEBUG) Log.d(TAG, "read some bytes: " + result);
-                            remaining -= result;
+                            availableBytes -= result;
                             bytesRead += result;
+                            if (DEBUG && (bytesRead % 100 == 0)) {
+                                Log.d(TAG, "read some bytes: " + bytesRead);
+                            }
                         } else {
-                            // stop reading ands see what there is to parse
-                            Log.w(TAG, "read error: " + result);
-                            remaining = 0;
+                            Log.w(TAG, "unexpected end of file while reading journal.");
+                            // stop reading and see what there is to parse
+                            availableBytes = 0;
                         }
                     } catch (IOException e) {
-                        Log.w(TAG, "failed to read the journal", e);
+                        Log.e(TAG, "failed to read the journal", e);
                         buffer = null;
-                        remaining = 0;
+                        availableBytes = 0;
                     }
-                }
-                if (DEBUG) Log.d(TAG, "journal bytes read: " + bytesRead);
 
-                if (buffer != null) {
+                    // check the buffer to see if we have a valid journal
                     try {
                         MessageNano.mergeFrom(journal, readCheckedBytes(buffer, 0, bytesRead));
+                        // if we are here, then we have read a valid, checksum-verified journal
+                        valid = true;
+                        availableBytes = 0;
                     } catch (InvalidProtocolBufferNanoException e) {
-                        Log.d(TAG, "failed to read the journal", e);
+                        // if we don't have the whole journal yet, mergeFrom will throw. keep going.
                         journal.clear();
                     }
                 }
+                if (DEBUG) Log.d(TAG, "journal bytes read: " + bytesRead);
+                if (!valid) {
+                    Log.w(TAG, "failed to read the journal: could not find a valid journal");
+                }
             }
         } catch (IOException e) {
             Log.d(TAG, "failed to close the journal", e);
@@ -968,7 +980,9 @@ public class LauncherBackupHelper implements BackupHelper {
         FileOutputStream outStream = null;
         try {
             outStream = new FileOutputStream(newState.getFileDescriptor());
-            outStream.write(writeCheckedBytes(journal));
+            final byte[] journalBytes = writeCheckedBytes(journal);
+            if (DEBUG) Log.d(TAG, "writing " + journalBytes.length + " bytes of journal");
+            outStream.write(journalBytes);
             outStream.close();
         } catch (IOException e) {
             Log.d(TAG, "failed to write backup journal", e);