Fix parsing chapters with multiple null bytes
Previously, we relied on the string to fill the complete frame. Some podcasts terminate the string early and leave some garbage in the frame data. Skip that garbage, so that the reader is at a valid frame header position when starting the next iteration.
This commit is contained in:
parent
aaeea78b37
commit
4f2dcc189c
@ -53,7 +53,7 @@ public class ChapterReader extends ID3Reader {
|
||||
| ((int) startTimeSource[2] << 8) | startTimeSource[3];
|
||||
currentChapter = new ID3Chapter(elementId.toString(), startTime);
|
||||
skipBytes(input, 12);
|
||||
return ID3Reader.ACTION_DONT_SKIP;
|
||||
return ID3Reader.ACTION_DONT_SKIP; // Let reader discover the sub-frames
|
||||
case FRAME_ID_TITLE:
|
||||
if (currentChapter != null && currentChapter.getTitle() == null) {
|
||||
StringBuilder title = new StringBuilder();
|
||||
@ -62,7 +62,7 @@ public class ChapterReader extends ID3Reader {
|
||||
.setTitle(title.toString());
|
||||
Log.d(TAG, "Found title: " + currentChapter.getTitle());
|
||||
|
||||
return ID3Reader.ACTION_DONT_SKIP;
|
||||
return ID3Reader.ACTION_SKIP;
|
||||
}
|
||||
break;
|
||||
case FRAME_ID_LINK:
|
||||
@ -79,7 +79,7 @@ public class ChapterReader extends ID3Reader {
|
||||
Log.w(TAG, "Bad URL found in ID3 data");
|
||||
}
|
||||
|
||||
return ID3Reader.ACTION_DONT_SKIP;
|
||||
return ID3Reader.ACTION_SKIP;
|
||||
}
|
||||
break;
|
||||
case FRAME_ID_PICTURE:
|
||||
@ -109,7 +109,7 @@ public class ChapterReader extends ID3Reader {
|
||||
}
|
||||
skipBytes(input, length);
|
||||
}
|
||||
return ID3Reader.ACTION_DONT_SKIP;
|
||||
return ID3Reader.ACTION_SKIP;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -20,7 +20,14 @@ public class ID3Reader {
|
||||
private static final int ID3_LENGTH = 3;
|
||||
private static final int FRAME_ID_LENGTH = 4;
|
||||
|
||||
private static final int ACTION_SKIP = 1;
|
||||
/**
|
||||
* Should skip remaining bytes of the current frame.
|
||||
*/
|
||||
static final int ACTION_SKIP = 1;
|
||||
|
||||
/**
|
||||
* Should not skip remaining bytes of the current frame. Can be used to parse sub-frames.
|
||||
*/
|
||||
static final int ACTION_DONT_SKIP = 2;
|
||||
|
||||
private int readerPosition;
|
||||
@ -49,12 +56,17 @@ public class ID3Reader {
|
||||
if (checkForNullString(frameHeader.getId())) {
|
||||
break;
|
||||
}
|
||||
int readerPositionBeforeFrame = input.getCount();
|
||||
rc = onStartFrameHeader(frameHeader, input);
|
||||
if (rc == ACTION_SKIP) {
|
||||
if (frameHeader.getSize() + readerPosition > tagHeader.getSize()) {
|
||||
break;
|
||||
}
|
||||
skipBytes(input, frameHeader.getSize());
|
||||
int bytesAlreadyHandled = input.getCount() - readerPositionBeforeFrame;
|
||||
int bytesLeftToSkip = frameHeader.getSize() - bytesAlreadyHandled;
|
||||
if (bytesLeftToSkip > 0) {
|
||||
skipBytes(input, bytesLeftToSkip);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,17 +1,20 @@
|
||||
package de.danoeh.antennapod.core.util.id3reader.model;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
public class FrameHeader extends Header {
|
||||
|
||||
private final char flags;
|
||||
private final char flags;
|
||||
|
||||
public FrameHeader(String id, int size, char flags) {
|
||||
super(id, size);
|
||||
this.flags = flags;
|
||||
}
|
||||
public FrameHeader(String id, int size, char flags) {
|
||||
super(id, size);
|
||||
this.flags = flags;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("FrameHeader [flags=%s, id=%s, size=%s]", Integer.toBinaryString(flags), id, Integer.toBinaryString(size));
|
||||
@Override
|
||||
@NonNull
|
||||
public String toString() {
|
||||
return String.format("FrameHeader [flags=%s, id=%s, size=%s]", Integer.toBinaryString(flags), id, size);
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user