summaryrefslogtreecommitdiff
path: root/parser
diff options
context:
space:
mode:
authorByteHamster <ByteHamster@users.noreply.github.com>2021-11-21 21:03:12 +0100
committerGitHub <noreply@github.com>2021-11-21 21:03:12 +0100
commit473ba14f88a7df6edfa51d3ecc9e1f913ee6d6f0 (patch)
tree10f6f6216335558a24a679b06858cf399526ab06 /parser
parente353b276f68f24ff16b1238e1beb1793ef9b7f69 (diff)
parente2600f54e4ec8abe55b5e95fb338b5eb11b5db9a (diff)
downloadantennapod-473ba14f88a7df6edfa51d3ecc9e1f913ee6d6f0.zip
Merge pull request #5565 from ByteHamster/simplify-opus
Simplify opus parsing
Diffstat (limited to 'parser')
-rw-r--r--parser/media/src/main/java/de/danoeh/antennapod/parser/media/vorbis/OggInputStream.java81
-rw-r--r--parser/media/src/main/java/de/danoeh/antennapod/parser/media/vorbis/VorbisCommentChapterReader.java5
-rw-r--r--parser/media/src/main/java/de/danoeh/antennapod/parser/media/vorbis/VorbisCommentReader.java64
3 files changed, 37 insertions, 113 deletions
diff --git a/parser/media/src/main/java/de/danoeh/antennapod/parser/media/vorbis/OggInputStream.java b/parser/media/src/main/java/de/danoeh/antennapod/parser/media/vorbis/OggInputStream.java
deleted file mode 100644
index ed495bcf3..000000000
--- a/parser/media/src/main/java/de/danoeh/antennapod/parser/media/vorbis/OggInputStream.java
+++ /dev/null
@@ -1,81 +0,0 @@
-package de.danoeh.antennapod.parser.media.vorbis;
-
-import org.apache.commons.io.IOUtils;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.Arrays;
-
-class OggInputStream extends InputStream {
- private final InputStream input;
-
- /** True if OggInputStream is currently inside an Ogg page. */
- private boolean isInPage;
- private long bytesLeft;
-
- public OggInputStream(InputStream input) {
- super();
- isInPage = false;
- this.input = input;
- }
-
- @Override
- public int read() throws IOException {
- if (!isInPage) {
- readOggPage();
- }
-
- if (isInPage && bytesLeft > 0) {
- int result = input.read();
- bytesLeft -= 1;
- if (bytesLeft == 0) {
- isInPage = false;
- }
- return result;
- }
- return -1;
- }
-
- private void readOggPage() throws IOException {
- // find OggS
- int[] buffer = new int[4];
- int c;
- boolean isInOggS = false;
- while ((c = input.read()) != -1) {
- switch (c) {
- case 'O':
- isInOggS = true;
- buffer[0] = c;
- break;
- case 'g':
- if (buffer[1] != c) {
- buffer[1] = c;
- } else {
- buffer[2] = c;
- }
- break;
- case 'S':
- buffer[3] = c;
- break;
- default:
- if (isInOggS) {
- Arrays.fill(buffer, 0);
- isInOggS = false;
- }
- }
- if (buffer[0] == 'O' && buffer[1] == 'g' && buffer[2] == 'g'
- && buffer[3] == 'S') {
- break;
- }
- }
- // read segments
- IOUtils.skipFully(input, 22);
- bytesLeft = 0;
- int numSegments = input.read();
- for (int i = 0; i < numSegments; i++) {
- bytesLeft += input.read();
- }
- isInPage = true;
- }
-
-}
diff --git a/parser/media/src/main/java/de/danoeh/antennapod/parser/media/vorbis/VorbisCommentChapterReader.java b/parser/media/src/main/java/de/danoeh/antennapod/parser/media/vorbis/VorbisCommentChapterReader.java
index f833f683b..82455d180 100644
--- a/parser/media/src/main/java/de/danoeh/antennapod/parser/media/vorbis/VorbisCommentChapterReader.java
+++ b/parser/media/src/main/java/de/danoeh/antennapod/parser/media/vorbis/VorbisCommentChapterReader.java
@@ -66,11 +66,6 @@ public class VorbisCommentChapterReader extends VorbisCommentReader {
}
@Override
- public void onNoVorbisCommentFound() {
- System.out.println("No vorbis comment found");
- }
-
- @Override
public void onEndOfComment() {
System.out.println("End of comment");
for (Chapter c : chapters) {
diff --git a/parser/media/src/main/java/de/danoeh/antennapod/parser/media/vorbis/VorbisCommentReader.java b/parser/media/src/main/java/de/danoeh/antennapod/parser/media/vorbis/VorbisCommentReader.java
index 319d3759c..b4f87bd70 100644
--- a/parser/media/src/main/java/de/danoeh/antennapod/parser/media/vorbis/VorbisCommentReader.java
+++ b/parser/media/src/main/java/de/danoeh/antennapod/parser/media/vorbis/VorbisCommentReader.java
@@ -35,43 +35,54 @@ public abstract class VorbisCommentReader {
*/
protected abstract void onContentVectorValue(String key, String value) throws VorbisCommentReaderException;
- protected abstract void onNoVorbisCommentFound();
-
protected abstract void onEndOfComment();
protected abstract void onError(VorbisCommentReaderException exception);
public void readInputStream(InputStream input) throws VorbisCommentReaderException {
try {
- // look for identification header
- if (findIdentificationHeader(input)) {
- onVorbisCommentFound();
- input = new OggInputStream(input);
- if (findCommentHeader(input)) {
- VorbisCommentHeader commentHeader = readCommentHeader(input);
- onVorbisCommentHeaderFound(commentHeader);
- for (int i = 0; i < commentHeader.getUserCommentLength(); i++) {
- readUserComment(input);
- }
- onEndOfComment();
- } else {
- onError(new VorbisCommentReaderException("No comment header found"));
- }
- } else {
- onNoVorbisCommentFound();
+ findIdentificationHeader(input);
+ onVorbisCommentFound();
+ findOggPage(input);
+ findCommentHeader(input);
+ VorbisCommentHeader commentHeader = readCommentHeader(input);
+ onVorbisCommentHeaderFound(commentHeader);
+ for (int i = 0; i < commentHeader.getUserCommentLength(); i++) {
+ readUserComment(input);
}
+ onEndOfComment();
} catch (IOException e) {
onError(new VorbisCommentReaderException(e));
}
}
+ private void findOggPage(InputStream input) throws IOException {
+ // find OggS
+ byte[] buffer = new byte[4];
+ final byte[] oggPageHeader = {'O', 'g', 'g', 'S'};
+ for (int bytesRead = 0; bytesRead < SECOND_PAGE_MAX_LENGTH; bytesRead++) {
+ buffer[bytesRead % buffer.length] = (byte) input.read();
+ if (bufferMatches(buffer, oggPageHeader, bytesRead)) {
+ break;
+ }
+ }
+ // read segments
+ IOUtils.skipFully(input, 22);
+ int numSegments = input.read();
+ IOUtils.skipFully(input, numSegments);
+ }
+
private void readUserComment(InputStream input) throws VorbisCommentReaderException {
try {
long vectorLength = EndianUtils.readSwappedUnsignedInteger(input);
+ if (vectorLength > 20 * 1024 * 1024) {
+ // Avoid reading entire file if it is encoded incorrectly
+ throw new VorbisCommentReaderException("User comment unrealistically long: " + vectorLength);
+ }
String key = readContentVectorKey(input, vectorLength).toLowerCase(Locale.US);
boolean readValue = onContentVectorKey(key);
if (readValue) {
- String value = readUtf8String(input, (int) (vectorLength - key.length() - 1));
+ String value = readUtf8String(input, vectorLength - key.length() - 1);
onContentVectorValue(key, value);
} else {
IOUtils.skipFully(input, vectorLength - key.length() - 1);
@@ -93,33 +104,32 @@ public abstract class VorbisCommentReader {
* identification header is found, it will be skipped completely and the
* method will return true, otherwise false.
*/
- private boolean findIdentificationHeader(InputStream input) throws IOException {
+ private void findIdentificationHeader(InputStream input) throws IOException {
byte[] buffer = new byte[FIRST_OPUS_PAGE_LENGTH];
IOUtils.readFully(input, buffer);
final byte[] oggIdentificationHeader = new byte[]{ PACKET_TYPE_IDENTIFICATION, 'v', 'o', 'r', 'b', 'i', 's' };
for (int i = 6; i < buffer.length; i++) {
if (bufferMatches(buffer, oggIdentificationHeader, i)) {
IOUtils.skip(input, FIRST_OGG_PAGE_LENGTH - FIRST_OPUS_PAGE_LENGTH);
- return true;
} else if (bufferMatches(buffer, "OpusHead".getBytes(), i)) {
- return true;
+ return;
}
}
- return false;
+ throw new IOException("No identification header found");
}
- private boolean findCommentHeader(InputStream input) throws IOException {
+ private void findCommentHeader(InputStream input) throws IOException {
byte[] buffer = new byte[64]; // Enough space for some bytes. Used circularly.
final byte[] oggCommentHeader = new byte[]{ PACKET_TYPE_COMMENT, 'v', 'o', 'r', 'b', 'i', 's' };
for (int bytesRead = 0; bytesRead < SECOND_PAGE_MAX_LENGTH; bytesRead++) {
buffer[bytesRead % buffer.length] = (byte) input.read();
if (bufferMatches(buffer, oggCommentHeader, bytesRead)) {
- return true;
+ return;
} else if (bufferMatches(buffer, "OpusTags".getBytes(), bytesRead)) {
- return true;
+ return;
}
}
- return false;
+ throw new IOException("No comment header found");
}
/**