Skip to content

Commit f2f5639

Browse files
Merge
Reviewed-by: jvos
2 parents d07d408 + ecec264 commit f2f5639

File tree

3 files changed

+86
-10
lines changed

3 files changed

+86
-10
lines changed

modules/javafx.media/src/main/java/com/sun/media/jfxmediaimpl/MetadataParserImpl.java

+9-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2010, 2022, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2010, 2024, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -108,6 +108,10 @@ protected void addMetadataItem(String tag, Object value) {
108108
metadata.put(tag, value);
109109
}
110110

111+
protected void disposeMetadata() {
112+
metadata.clear();
113+
}
114+
111115
protected void done() {
112116
synchronized (listeners) {
113117
if (!metadata.isEmpty()) {
@@ -130,6 +134,10 @@ protected int getStreamPosition() {
130134
return streamPosition;
131135
}
132136

137+
protected long getStreamLength() {
138+
return locator.getContentLength();
139+
}
140+
133141
protected void startRawMetadata(int sizeHint) {
134142
rawMetaBlob = ByteBuffer.allocate(sizeHint);
135143
}

modules/javafx.media/src/main/java/com/sun/media/jfxmediaimpl/platform/java/ID3MetadataParser.java

+43-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2010, 2022, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2010, 2024, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -38,6 +38,11 @@ final class ID3MetadataParser extends MetadataParserImpl {
3838
private static final int ID3_VERSION_MIN = 2;
3939
private static final int ID3_VERSION_MAX = 4;
4040

41+
// Max tag size cannot be more than 256 MB
42+
private static final int MAX_TAG_SIZE = 256 * 1024 * 1024;
43+
// Max frame size cannot be more than 16 MB
44+
private static final int MAX_FRAME_SIZE = 16 * 1024 * 1024;
45+
4146
private static final String CHARSET_UTF_8 = "UTF-8";
4247
private static final String CHARSET_ISO_8859_1 = "ISO-8859-1";
4348
private static final String CHARSET_UTF_16 = "UTF-16";
@@ -46,6 +51,7 @@ final class ID3MetadataParser extends MetadataParserImpl {
4651
private int COMMCount = 0;
4752
private int TXXXCount = 0;
4853
private int version = 3; // Default to 3
54+
private int tagSize = 0;
4955
private boolean unsynchronized = false;
5056

5157
public ID3MetadataParser(Locator locator) {
@@ -82,12 +88,15 @@ protected void parse() {
8288
unsynchronized = true;
8389
}
8490

85-
int tagSize = 0;
8691
for (int i = 6, shift = 21; i < 10; i++) {
8792
tagSize += (buf[i] & 0x7f) << shift;
8893
shift -= 7;
8994
}
9095

96+
if (!validateTagSize()) {
97+
return; // Abort parser if tag size is invalid.
98+
}
99+
91100
startRawMetadata(tagSize + 10);
92101
stuffRawMetadata(buf, 0, 10); // put the header back in the raw metadata blob
93102
readRawMetadata(tagSize);
@@ -108,6 +117,14 @@ protected void parse() {
108117
skipBytes(2);
109118
}
110119

120+
if (!validateFrameSize(frameSize)) {
121+
// Dispose any parsed or partially parsed metadata
122+
disposeMetadata();
123+
setParseRawMetadata(false);
124+
disposeRawMetadata();
125+
return; // Abort parser if frame size is invalid.
126+
}
127+
111128
if (0 == idBytes[0]) {
112129
// terminate on zero padding, NULL characters not allowed in frame ID
113130
if (Logger.canLog(Logger.DEBUG)) {
@@ -239,6 +256,30 @@ protected void parse() {
239256
}
240257
}
241258

259+
// Tag size should be <= MAX_TAG_SIZE and stream length.
260+
private boolean validateTagSize() {
261+
long streamLength = getStreamLength(); // Can be -1 if unknown
262+
if ((streamLength > 0 && tagSize > streamLength) ||
263+
tagSize > MAX_TAG_SIZE) {
264+
Logger.logMsg(Logger.ERROR, "Unexpected ID3 tag size("
265+
+ tagSize +"). ID3 metadata will be ignored.");
266+
return false;
267+
}
268+
269+
return true;
270+
}
271+
272+
// Frame size should be <= MAX_FRAME_SIZE and tag size.
273+
private boolean validateFrameSize(int frameSize) {
274+
if (frameSize > tagSize || frameSize > MAX_FRAME_SIZE) {
275+
Logger.logMsg(Logger.ERROR, "Unexpected ID3 frame size("
276+
+ frameSize +"). ID3 metadata will be ignored.");
277+
return false;
278+
}
279+
280+
return true;
281+
}
282+
242283
private int getFrameSize() throws IOException {
243284
if (version == 4) {
244285
byte[] buf = getBytes(4);

modules/javafx.media/src/main/native/gstreamer/plugins/dshowwrapper/dshowwrapper.cpp

+34-7
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ using namespace std;
5959
#define AAC_PTS_INPUT_DEBUG 0
6060
#define EOS_DEBUG 0
6161

62+
// MAX_HEADER_SIZE is valid max size for H.264 and AAC, however AAC header is actually smaller.
6263
#define MAX_HEADER_SIZE 256
6364
#define INPUT_BUFFERS_BEFORE_ERROR 500
6465

@@ -635,17 +636,25 @@ void dshowwrapper_deliver_post_process_mp2t(GstBuffer *pBuffer, GstDShowWrapper
635636
data = info.data;
636637
size = info.size;
637638

638-
if (data == NULL || size < 3)
639+
// PES header 6 bytes + optional extension + payload
640+
// We should have at least 7 bytes (header + 1 byte for payload)
641+
if (data == NULL || size < 7)
642+
{
643+
gst_buffer_unmap(pBuffer, &info);
639644
return;
645+
}
640646

641647
if (data[0] == 0x00 && data[1] == 0x00 && data[2] == 0x01) // PES header start
642648
{
643-
if ((data[6] & 0x80) == 0x80) // Optional PES header
649+
// Check for optional PES header and make sure we have enough bytes
650+
// to continue parsing optional PES header which is 3 bytes.
651+
if ((data[6] & 0x80) == 0x80 && size >= 9) // Optional PES header
644652
{
645653
__int64 PTS = 0;
646654
GstClockTime gst_pts = GST_CLOCK_TIME_NONE;
647655

648-
if ((data[7] & 0x80) == 0x80) // Get PTS
656+
// Make sure we have enough bytes to read PTS
657+
if ((data[7] & 0x80) == 0x80 && size >= 14) // Get PTS
649658
{
650659
PTS |= ((__int64)(data[9] & 0x0E) << 29);
651660
PTS |= (data[10] << 22);
@@ -694,11 +703,21 @@ void dshowwrapper_deliver_post_process_mp2t(GstBuffer *pBuffer, GstDShowWrapper
694703
}
695704

696705
guint8 optional_remaining_header_size = data[8];
697-
size -= (PES_HEADER_SIZE + PES_OPTIONAL_HEADER_SIZE + optional_remaining_header_size);
698-
offset = (PES_HEADER_SIZE + PES_OPTIONAL_HEADER_SIZE + optional_remaining_header_size);
706+
if ((PES_HEADER_SIZE + PES_OPTIONAL_HEADER_SIZE + optional_remaining_header_size) < size)
707+
{
708+
size -= (PES_HEADER_SIZE + PES_OPTIONAL_HEADER_SIZE + optional_remaining_header_size);
709+
offset = (PES_HEADER_SIZE + PES_OPTIONAL_HEADER_SIZE + optional_remaining_header_size);
710+
}
711+
else
712+
{
713+
// Something wrong.
714+
gst_buffer_unmap(pBuffer, &info);
715+
return;
716+
}
699717
}
700718
else
701719
{
720+
// Skip 6 bytes of PES header
702721
size -= PES_HEADER_SIZE;
703722
offset = PES_HEADER_SIZE;
704723
}
@@ -1551,7 +1570,14 @@ static gboolean dshowwrapper_load_decoder_aac(GstStructure *s, GstDShowWrapper *
15511570
codec_data = gst_value_get_buffer(v);
15521571
if (codec_data != NULL)
15531572
if (gst_buffer_map(codec_data, &info, GST_MAP_READ))
1554-
codec_data_size = info.size;
1573+
codec_data_size = (gint)info.size;
1574+
}
1575+
1576+
// Make sure header has reasonable size
1577+
if (codec_data_size < 0 || codec_data_size > MAX_HEADER_SIZE)
1578+
{
1579+
gst_buffer_unmap(codec_data, &info);
1580+
return FALSE;
15551581
}
15561582

15571583
inputFormat.type = MEDIATYPE_Audio;
@@ -2071,13 +2097,14 @@ static gboolean dshowwrapper_load_decoder_h264(GstStructure *s, GstDShowWrapper
20712097
if (gst_buffer_map(codec_data, &codec_data_info, GST_MAP_READ))
20722098
{
20732099
if (codec_data_info.size <= MAX_HEADER_SIZE)
2074-
header_size = dshowwrapper_get_avc_config(codec_data_info.data, codec_data_info.size, header, MAX_HEADER_SIZE, &decoder->lengthSizeMinusOne);
2100+
header_size = (gint)dshowwrapper_get_avc_config(codec_data_info.data, codec_data_info.size, header, MAX_HEADER_SIZE, &decoder->lengthSizeMinusOne);
20752101
gst_buffer_unmap(codec_data, &codec_data_info);
20762102
}
20772103
}
20782104
else
20792105
return FALSE;
20802106

2107+
// dshowwrapper_get_avc_config() will make sure that (header_size <= MAX_HEADER_SIZE)
20812108
if (header_size <= 0)
20822109
return FALSE;
20832110

0 commit comments

Comments
 (0)