Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 65b6a603 authored by Chris Wren's avatar Chris Wren
Browse files

search for a valid journal

there are too many bytes, so we need to find the valid subset,
without stepping past the end!

Bug: 12489602
Change-Id: Ic9d7c804c199740ff50d0864f99632ae68619369
parent c4fa7a9c
Loading
Loading
Loading
Loading
+33 −19
Original line number Diff line number Diff line
@@ -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);