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

Commit b048c33d authored by Christopher Tate's avatar Christopher Tate
Browse files

Don't assume that we're at start of file at ctor time

BackupDataReader / BackupDataWriter were implicitly assuming that when
instantiated, the underlying fd was positioned at start-of-file.  If one
tried to e.g. open an existing data stream to append further data to it,
things might randomly fail (at read time, possibly when consuming the
stream later) due to incorrect alignment of the data entities: the
appending writer would assume that no padding was needed to achieve
correct alignment, and this might easily be false.

Now the underlying native reader/writer helpers recognize the true
position within the file when constructed, and as a result it's now
safe to e.g. construct a BackupDataOutput for an existing file and
then append to it.

Change-Id: If0484921e687852f923a4b4efabff573a6c16981
parent 1a405db2
Loading
Loading
Loading
Loading
+25 −2
Original line number Diff line number Diff line
@@ -35,6 +35,11 @@ import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

import libcore.io.ErrnoException;
import libcore.io.Libcore;
import libcore.io.StructStat;
import static libcore.io.OsConstants.*;

/**
 * Backup transport for stashing stuff into a known location on disk, and
 * later restoring from there.  For testing only.
@@ -96,7 +101,16 @@ public class LocalTransport extends IBackupTransport.Stub {
    }

    public int performBackup(PackageInfo packageInfo, ParcelFileDescriptor data) {
        if (DEBUG) Log.v(TAG, "performBackup() pkg=" + packageInfo.packageName);
        if (DEBUG) {
            try {
            StructStat ss = Libcore.os.fstat(data.getFileDescriptor());
            Log.v(TAG, "performBackup() pkg=" + packageInfo.packageName
                    + " size=" + ss.st_size);
            } catch (ErrnoException e) {
                Log.w(TAG, "Unable to stat input file in performBackup() on "
                        + packageInfo.packageName);
            }
        }

        File packageDir = new File(mDataDir, packageInfo.packageName);
        packageDir.mkdirs();
@@ -130,7 +144,16 @@ public class LocalTransport extends IBackupTransport.Stub {
                        buf = new byte[bufSize];
                    }
                    changeSet.readEntityData(buf, 0, dataSize);
                    if (DEBUG) Log.v(TAG, "  data size " + dataSize);
                    if (DEBUG) {
                        try {
                            long cur = Libcore.os.lseek(data.getFileDescriptor(), 0, SEEK_CUR);
                            Log.v(TAG, "  read entity data; new pos=" + cur);
                        }
                        catch (ErrnoException e) {
                            Log.w(TAG, "Unable to stat input file in performBackup() on "
                                    + packageInfo.packageName);
                        }
                    }

                    try {
                        entity.write(buf, 0, dataSize);
+4 −2
Original line number Diff line number Diff line
@@ -59,9 +59,10 @@ padding_extra(size_t n)
BackupDataWriter::BackupDataWriter(int fd)
    :m_fd(fd),
     m_status(NO_ERROR),
     m_pos(0),
     m_entityCount(0)
{
    m_pos = (ssize_t) lseek(fd, 0, SEEK_CUR);
    if (DEBUG) ALOGI("BackupDataWriter(%d) @ %ld", fd, (long)m_pos);
}

BackupDataWriter::~BackupDataWriter()
@@ -184,10 +185,11 @@ BackupDataReader::BackupDataReader(int fd)
    :m_fd(fd),
     m_done(false),
     m_status(NO_ERROR),
     m_pos(0),
     m_entityCount(0)
{
    memset(&m_header, 0, sizeof(m_header));
    m_pos = (ssize_t) lseek(fd, 0, SEEK_CUR);
    if (DEBUG) ALOGI("BackupDataReader(%d) @ %ld", fd, (long)m_pos);
}

BackupDataReader::~BackupDataReader()