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

Commit 9d659aef authored by Andrew Lewis's avatar Andrew Lewis Committed by android-build-merger
Browse files

Merge "Redact ISOBMFF boxes with 'free'" into qt-dev am: f68a201e

am: 65ded6c6

Change-Id: Ie7ec846fc38c9f1877067e13d0f912cc3f4eea33
parents df130ae5 65ded6c6
Loading
Loading
Loading
Loading
+21 −5
Original line number Diff line number Diff line
@@ -35,7 +35,7 @@ import java.util.Arrays;

/**
 * Variant of {@link FileDescriptor} that allows its creator to specify regions
 * that should be redacted (appearing as zeros to the reader).
 * that should be redacted.
 *
 * @hide
 */
@@ -44,13 +44,16 @@ public class RedactingFileDescriptor {
    private static final boolean DEBUG = true;

    private volatile long[] mRedactRanges;
    private volatile long[] mFreeOffsets;

    private FileDescriptor mInner = null;
    private ParcelFileDescriptor mOuter = null;

    private RedactingFileDescriptor(Context context, File file, int mode, long[] redactRanges)
    private RedactingFileDescriptor(
            Context context, File file, int mode, long[] redactRanges, long[] freeOffsets)
            throws IOException {
        mRedactRanges = checkRangesArgument(redactRanges);
        mFreeOffsets = freeOffsets;

        try {
            try {
@@ -88,13 +91,17 @@ public class RedactingFileDescriptor {
     *
     * @param file The underlying file to open.
     * @param mode The {@link ParcelFileDescriptor} mode to open with.
     * @param redactRanges List of file offsets that should be redacted, stored
     * @param redactRanges List of file ranges that should be redacted, stored
     *            as {@code [start1, end1, start2, end2, ...]}. Start values are
     *            inclusive and end values are exclusive.
     * @param freePositions List of file offsets at which the four byte value 'free' should be
     *            written instead of zeros within parts of the file covered by {@code redactRanges}.
     *            Non-redacted bytes will not be modified even if covered by a 'free'. This is
     *            useful for overwriting boxes in ISOBMFF files with padding data.
     */
    public static ParcelFileDescriptor open(Context context, File file, int mode,
            long[] redactRanges) throws IOException {
        return new RedactingFileDescriptor(context, file, mode, redactRanges).mOuter;
            long[] redactRanges, long[] freePositions) throws IOException {
        return new RedactingFileDescriptor(context, file, mode, redactRanges, freePositions).mOuter;
    }

    /**
@@ -169,6 +176,15 @@ public class RedactingFileDescriptor {
                for (long j = start; j < end; j++) {
                    data[(int) (j - offset)] = 0;
                }
                // Overwrite data at 'free' offsets within the redaction ranges.
                for (long freeOffset : mFreeOffsets) {
                    final long freeEnd = freeOffset + 4;
                    final long redactFreeStart = Math.max(freeOffset, start);
                    final long redactFreeEnd = Math.min(freeEnd, end);
                    for (long j = redactFreeStart; j < redactFreeEnd; j++) {
                        data[(int) (j - offset)] = (byte) "free".charAt((int) (j - freeOffset));
                    }
                }
            }
            return n;
        }
+76 −4
Original line number Diff line number Diff line
@@ -64,7 +64,7 @@ public class RedactingFileDescriptorTest {
    @Test
    public void testSingleByte() throws Exception {
        final FileDescriptor fd = RedactingFileDescriptor.open(mContext, mFile, MODE_READ_ONLY,
                new long[] { 10, 11 }).getFileDescriptor();
                new long[] { 10, 11 }, new long[] {}).getFileDescriptor();

        final byte[] buf = new byte[1_000];
        assertEquals(buf.length, Os.read(fd, buf, 0, buf.length));
@@ -80,7 +80,7 @@ public class RedactingFileDescriptorTest {
    @Test
    public void testRanges() throws Exception {
        final FileDescriptor fd = RedactingFileDescriptor.open(mContext, mFile, MODE_READ_ONLY,
                new long[] { 100, 200, 300, 400 }).getFileDescriptor();
                new long[] { 100, 200, 300, 400 }, new long[] {}).getFileDescriptor();

        final byte[] buf = new byte[10];
        assertEquals(buf.length, Os.pread(fd, buf, 0, 10, 90));
@@ -102,7 +102,7 @@ public class RedactingFileDescriptorTest {
    @Test
    public void testEntireFile() throws Exception {
        final FileDescriptor fd = RedactingFileDescriptor.open(mContext, mFile, MODE_READ_ONLY,
                new long[] { 0, 5_000_000 }).getFileDescriptor();
                new long[] { 0, 5_000_000 }, new long[] {}).getFileDescriptor();

        try (FileInputStream in = new FileInputStream(fd)) {
            int val;
@@ -115,7 +115,7 @@ public class RedactingFileDescriptorTest {
    @Test
    public void testReadWrite() throws Exception {
        final FileDescriptor fd = RedactingFileDescriptor.open(mContext, mFile, MODE_READ_WRITE,
                new long[] { 100, 200, 300, 400 }).getFileDescriptor();
                new long[] { 100, 200, 300, 400 }, new long[] {}).getFileDescriptor();

        // Redacted at first
        final byte[] buf = new byte[10];
@@ -168,4 +168,76 @@ public class RedactingFileDescriptorTest {
        assertArrayEquals(new long[] { 100, 200 },
                removeRange(new long[] { 100, 200 }, 150, 150));
    }

    @Test
    public void testFreeAtStart() throws Exception {
        final FileDescriptor fd = RedactingFileDescriptor.open(mContext, mFile, MODE_READ_WRITE,
                new long[] { 1, 10 }, new long[] {1}).getFileDescriptor();

        final byte[] buf = new byte[10];
        assertEquals(buf.length, Os.pread(fd, buf, 0, 10, 0));
        assertArrayEquals(
                new byte[] { 64, (byte) 'f', (byte) 'r', (byte) 'e', (byte) 'e', 0, 0, 0, 0, 0 },
                buf);
    }

    @Test
    public void testFreeAtOffset() throws Exception {
        final FileDescriptor fd = RedactingFileDescriptor.open(mContext, mFile, MODE_READ_WRITE,
                new long[] { 1, 10 }, new long[] {3}).getFileDescriptor();

        final byte[] buf = new byte[10];
        assertEquals(buf.length, Os.pread(fd, buf, 0, 10, 0));
        assertArrayEquals(
                new byte[] { 64, 0, 0, (byte) 'f', (byte) 'r', (byte) 'e', (byte) 'e', 0, 0, 0 },
                buf);
    }

    @Test
    public void testFreeAcrossRedactionStart() throws Exception {
        final FileDescriptor fd = RedactingFileDescriptor.open(mContext, mFile, MODE_READ_WRITE,
                new long[] { 1, 10 }, new long[] {0}).getFileDescriptor();

        final byte[] buf = new byte[10];
        assertEquals(buf.length, Os.pread(fd, buf, 0, 10, 0));
        assertArrayEquals(
                new byte[] { 64, (byte) 'r', (byte) 'e', (byte) 'e', 0, 0, 0, 0, 0, 0 },
                buf);
    }

    @Test
    public void testFreeAcrossRedactionEnd() throws Exception {
        final FileDescriptor fd = RedactingFileDescriptor.open(mContext, mFile, MODE_READ_WRITE,
                new long[] { 1, 3 }, new long[] {2}).getFileDescriptor();

        final byte[] buf = new byte[10];
        assertEquals(buf.length, Os.pread(fd, buf, 0, 10, 0));
        assertArrayEquals(
                new byte[] { 64, 0, (byte) 'f', 64, 64, 64, 64, 64, 64, 64 },
                buf);
    }

    @Test
    public void testFreeOutsideRedaction() throws Exception {
        final FileDescriptor fd = RedactingFileDescriptor.open(mContext, mFile, MODE_READ_WRITE,
                new long[] { 1, 8 }, new long[] { 8 }).getFileDescriptor();

        final byte[] buf = new byte[10];
        assertEquals(buf.length, Os.pread(fd, buf, 0, 10, 0));
        assertArrayEquals(
                new byte[] { 64, 0, 0, 0, 0, 0, 0, 0, 64, 64 },
                buf);
    }

    @Test
    public void testFreeMultipleRedactions() throws Exception {
        final FileDescriptor fd = RedactingFileDescriptor.open(mContext, mFile, MODE_READ_WRITE,
                new long[] { 1, 2, 3, 4 }, new long[] { 0 }).getFileDescriptor();

        final byte[] buf = new byte[10];
        assertEquals(buf.length, Os.pread(fd, buf, 0, 10, 0));
        assertArrayEquals(
                new byte[] { 64, (byte) 'r', 64, (byte) 'e', 64, 64, 64, 64, 64, 64 },
                buf);
    }
}