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 Andrew Lewis
parent e437248f4f
commit de293af3a4

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;