Skip to content

Commit ada1ad1

Browse files
committed
Further mp4 and flv work
1 parent 8461301 commit ada1ad1

4 files changed

Lines changed: 36 additions & 3 deletions

File tree

tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-audiovideo-module/src/main/java/org/apache/tika/parser/mp4/MP4Parser.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,9 @@ public long getMaxBoxSize() {
112112
}
113113

114114
public void setMaxBoxSize(long maxBoxSize) {
115+
if (maxBoxSize <= 0) {
116+
throw new IllegalArgumentException("maxBoxSize must be positive: " + maxBoxSize);
117+
}
115118
this.maxBoxSize = maxBoxSize;
116119
}
117120

tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-audiovideo-module/src/main/java/org/apache/tika/parser/mp4/boxes/TikaUserDataBox.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,9 @@ private void processIList(SequentialReader reader, long totalLen)
163163
if ("covr".equals(fieldName)) {
164164
//covr holds one image per data atom and may repeat the data atom
165165
//for further images; the realign below consumes any leftover
166-
handleCoverArt(reader, valueType, toRead);
166+
if (reader.getPosition() + toRead <= recordEnd) {
167+
handleCoverArt(reader, valueType, toRead);
168+
}
167169
while (reader.getPosition() + 16 <= recordEnd) {
168170
long extraLen = reader.getUInt32();
169171
String extraType =
@@ -200,7 +202,7 @@ private void processIList(SequentialReader reader, long totalLen)
200202
metadata.set(Audio.DISC_COUNT, b);
201203
}
202204
}
203-
} else {
205+
} else if (reader.getPosition() + toRead <= recordEnd) {
204206
String val = reader.getString(toRead, StandardCharsets.UTF_8);
205207
try {
206208
addMetadata(fieldName, val);

tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-audiovideo-module/src/main/java/org/apache/tika/parser/video/FLVParser.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,12 +164,18 @@ private String readAMFString(DataInputStream input) throws IOException {
164164

165165
private Object readAMFObject(DataInputStream input, int depth) throws IOException {
166166
HashMap<String, Object> array = new HashMap<>();
167-
while (true) {
167+
//an object has no declared count (it runs to the type-9 end marker), so bound the
168+
//entry count too, or a crafted flat object of cheap entries would exhaust memory
169+
for (int i = 0; ; i++) {
168170
String key = readAMFString(input);
169171
int dataType = input.read();
170172
if (dataType == 9) { // object end marker
171173
break;
172174
}
175+
if (i >= MAX_AMF_ELEMENTS) {
176+
throw new IOException("AMF object exceeds the maximum of " + MAX_AMF_ELEMENTS
177+
+ " entries");
178+
}
173179
array.put(key, readAMFData(input, dataType, depth + 1));
174180
}
175181
return array;

tika-parsers/tika-parsers-standard/tika-parsers-standard-modules/tika-parser-audiovideo-module/src/test/java/org/apache/tika/parser/mp4/MP4ParserTest.java

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -497,6 +497,28 @@ public void testNestedContainerRecursionIsBounded() throws Exception {
497497
boxes.length));
498498
}
499499

500+
@Test
501+
public void testLargeSizeBoxHeaderAccounting() throws Exception {
502+
//a 64-bit largesize box (size field == 1) has a 16-byte header, not 8; accounting
503+
//for only 8 over-reads it by 8 bytes and misparses everything after it. Put a
504+
//largesize udta before a normal ftyp and confirm the ftyp's major brand still
505+
//comes through, which it only does if the largesize header is 16 bytes. TIKA-4812
506+
ByteArrayOutputStream bos = new ByteArrayOutputStream();
507+
//box 1: largesize udta, 24 bytes total (16-byte header + 8-byte payload)
508+
bos.write(new byte[]{0, 0, 0, 1}); //size == 1 -> a 64-bit size follows
509+
bos.write("udta".getBytes(StandardCharsets.ISO_8859_1));
510+
bos.write(new byte[]{0, 0, 0, 0, 0, 0, 0, 24}); //64-bit box size = 24
511+
bos.write(new byte[]{0, 0, 0, 8}); //payload: a dummy 8-byte 'free' sub-box
512+
bos.write("free".getBytes(StandardCharsets.ISO_8859_1));
513+
//box 2: normal ftyp, 16 bytes
514+
bos.write(new byte[]{0, 0, 0, 16});
515+
bos.write("ftyp".getBytes(StandardCharsets.ISO_8859_1));
516+
bos.write("isom".getBytes(StandardCharsets.ISO_8859_1)); //major brand
517+
bos.write(new byte[]{0, 0, 0, 0}); //minor version
518+
519+
assertEquals("isom", majorBrand(bos.toByteArray(), 1000L));
520+
}
521+
500522
private static String majorBrand(byte[] boxes, long maxBoxSize) throws Exception {
501523
com.drew.metadata.Metadata mp4Metadata = new com.drew.metadata.Metadata();
502524
Metadata tikaMetadata = new Metadata();

0 commit comments

Comments
 (0)