Fix not thread safe static buffer usage

DefaultExtractorInput.SCRATCH_SPACE buffer is used to skip data by
reading it into this buffer and discarding.

Simultaneous use of skip methods corrupts this buffer. Normally the
read data is discarded so it doesn't matter but the underlying
DataSource may use the buffer too. If it's a CacheDataSource it uses
this buffer to read data from upstream then write to cache.

Issue: #3762

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=184502170
This commit is contained in:
eguven 2018-02-05 02:36:34 -08:00 committed by Oliver Woodman
parent 2d76d63c3e
commit b210c20e84

View File

@ -30,8 +30,9 @@ public final class DefaultExtractorInput implements ExtractorInput {
private static final int PEEK_MIN_FREE_SPACE_AFTER_RESIZE = 64 * 1024;
private static final int PEEK_MAX_FREE_SPACE = 512 * 1024;
private static final byte[] SCRATCH_SPACE = new byte[4096];
private static final int SCRATCH_SPACE_SIZE = 4096;
private final byte[] scratchSpace;
private final DataSource dataSource;
private final long streamLength;
@ -50,6 +51,7 @@ public final class DefaultExtractorInput implements ExtractorInput {
this.position = position;
this.streamLength = length;
peekBuffer = new byte[PEEK_MIN_FREE_SPACE_AFTER_RESIZE];
scratchSpace = new byte[SCRATCH_SPACE_SIZE];
}
@Override
@ -84,7 +86,7 @@ public final class DefaultExtractorInput implements ExtractorInput {
int bytesSkipped = skipFromPeekBuffer(length);
if (bytesSkipped == 0) {
bytesSkipped =
readFromDataSource(SCRATCH_SPACE, 0, Math.min(length, SCRATCH_SPACE.length), 0, true);
readFromDataSource(scratchSpace, 0, Math.min(length, scratchSpace.length), 0, true);
}
commitBytesRead(bytesSkipped);
return bytesSkipped;
@ -95,8 +97,9 @@ public final class DefaultExtractorInput implements ExtractorInput {
throws IOException, InterruptedException {
int bytesSkipped = skipFromPeekBuffer(length);
while (bytesSkipped < length && bytesSkipped != C.RESULT_END_OF_INPUT) {
bytesSkipped = readFromDataSource(SCRATCH_SPACE, -bytesSkipped,
Math.min(length, bytesSkipped + SCRATCH_SPACE.length), bytesSkipped, allowEndOfInput);
int minLength = Math.min(length, bytesSkipped + scratchSpace.length);
bytesSkipped =
readFromDataSource(scratchSpace, -bytesSkipped, minLength, bytesSkipped, allowEndOfInput);
}
commitBytesRead(bytesSkipped);
return bytesSkipped != C.RESULT_END_OF_INPUT;