Skip to content

Commit

Permalink
Merge
Browse files Browse the repository at this point in the history
Reviewed-by: jvos
  • Loading branch information
kevinrushforth committed Jan 21, 2025
2 parents d07d408 + ecec264 commit f2f5639
Show file tree
Hide file tree
Showing 3 changed files with 86 additions and 10 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2010, 2022, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2010, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -108,6 +108,10 @@ protected void addMetadataItem(String tag, Object value) {
metadata.put(tag, value);
}

protected void disposeMetadata() {
metadata.clear();
}

protected void done() {
synchronized (listeners) {
if (!metadata.isEmpty()) {
Expand All @@ -130,6 +134,10 @@ protected int getStreamPosition() {
return streamPosition;
}

protected long getStreamLength() {
return locator.getContentLength();
}

protected void startRawMetadata(int sizeHint) {
rawMetaBlob = ByteBuffer.allocate(sizeHint);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2010, 2022, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2010, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -38,6 +38,11 @@ final class ID3MetadataParser extends MetadataParserImpl {
private static final int ID3_VERSION_MIN = 2;
private static final int ID3_VERSION_MAX = 4;

// Max tag size cannot be more than 256 MB
private static final int MAX_TAG_SIZE = 256 * 1024 * 1024;
// Max frame size cannot be more than 16 MB
private static final int MAX_FRAME_SIZE = 16 * 1024 * 1024;

private static final String CHARSET_UTF_8 = "UTF-8";
private static final String CHARSET_ISO_8859_1 = "ISO-8859-1";
private static final String CHARSET_UTF_16 = "UTF-16";
Expand All @@ -46,6 +51,7 @@ final class ID3MetadataParser extends MetadataParserImpl {
private int COMMCount = 0;
private int TXXXCount = 0;
private int version = 3; // Default to 3
private int tagSize = 0;
private boolean unsynchronized = false;

public ID3MetadataParser(Locator locator) {
Expand Down Expand Up @@ -82,12 +88,15 @@ protected void parse() {
unsynchronized = true;
}

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

if (!validateTagSize()) {
return; // Abort parser if tag size is invalid.
}

startRawMetadata(tagSize + 10);
stuffRawMetadata(buf, 0, 10); // put the header back in the raw metadata blob
readRawMetadata(tagSize);
Expand All @@ -108,6 +117,14 @@ protected void parse() {
skipBytes(2);
}

if (!validateFrameSize(frameSize)) {
// Dispose any parsed or partially parsed metadata
disposeMetadata();
setParseRawMetadata(false);
disposeRawMetadata();
return; // Abort parser if frame size is invalid.
}

if (0 == idBytes[0]) {
// terminate on zero padding, NULL characters not allowed in frame ID
if (Logger.canLog(Logger.DEBUG)) {
Expand Down Expand Up @@ -239,6 +256,30 @@ protected void parse() {
}
}

// Tag size should be <= MAX_TAG_SIZE and stream length.
private boolean validateTagSize() {
long streamLength = getStreamLength(); // Can be -1 if unknown
if ((streamLength > 0 && tagSize > streamLength) ||
tagSize > MAX_TAG_SIZE) {
Logger.logMsg(Logger.ERROR, "Unexpected ID3 tag size("
+ tagSize +"). ID3 metadata will be ignored.");
return false;
}

return true;
}

// Frame size should be <= MAX_FRAME_SIZE and tag size.
private boolean validateFrameSize(int frameSize) {
if (frameSize > tagSize || frameSize > MAX_FRAME_SIZE) {
Logger.logMsg(Logger.ERROR, "Unexpected ID3 frame size("
+ frameSize +"). ID3 metadata will be ignored.");
return false;
}

return true;
}

private int getFrameSize() throws IOException {
if (version == 4) {
byte[] buf = getBytes(4);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ using namespace std;
#define AAC_PTS_INPUT_DEBUG 0
#define EOS_DEBUG 0

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

Expand Down Expand Up @@ -635,17 +636,25 @@ void dshowwrapper_deliver_post_process_mp2t(GstBuffer *pBuffer, GstDShowWrapper
data = info.data;
size = info.size;

if (data == NULL || size < 3)
// PES header 6 bytes + optional extension + payload
// We should have at least 7 bytes (header + 1 byte for payload)
if (data == NULL || size < 7)
{
gst_buffer_unmap(pBuffer, &info);
return;
}

if (data[0] == 0x00 && data[1] == 0x00 && data[2] == 0x01) // PES header start
{
if ((data[6] & 0x80) == 0x80) // Optional PES header
// Check for optional PES header and make sure we have enough bytes
// to continue parsing optional PES header which is 3 bytes.
if ((data[6] & 0x80) == 0x80 && size >= 9) // Optional PES header
{
__int64 PTS = 0;
GstClockTime gst_pts = GST_CLOCK_TIME_NONE;

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

guint8 optional_remaining_header_size = data[8];
size -= (PES_HEADER_SIZE + PES_OPTIONAL_HEADER_SIZE + optional_remaining_header_size);
offset = (PES_HEADER_SIZE + PES_OPTIONAL_HEADER_SIZE + optional_remaining_header_size);
if ((PES_HEADER_SIZE + PES_OPTIONAL_HEADER_SIZE + optional_remaining_header_size) < size)
{
size -= (PES_HEADER_SIZE + PES_OPTIONAL_HEADER_SIZE + optional_remaining_header_size);
offset = (PES_HEADER_SIZE + PES_OPTIONAL_HEADER_SIZE + optional_remaining_header_size);
}
else
{
// Something wrong.
gst_buffer_unmap(pBuffer, &info);
return;
}
}
else
{
// Skip 6 bytes of PES header
size -= PES_HEADER_SIZE;
offset = PES_HEADER_SIZE;
}
Expand Down Expand Up @@ -1551,7 +1570,14 @@ static gboolean dshowwrapper_load_decoder_aac(GstStructure *s, GstDShowWrapper *
codec_data = gst_value_get_buffer(v);
if (codec_data != NULL)
if (gst_buffer_map(codec_data, &info, GST_MAP_READ))
codec_data_size = info.size;
codec_data_size = (gint)info.size;
}

// Make sure header has reasonable size
if (codec_data_size < 0 || codec_data_size > MAX_HEADER_SIZE)
{
gst_buffer_unmap(codec_data, &info);
return FALSE;
}

inputFormat.type = MEDIATYPE_Audio;
Expand Down Expand Up @@ -2071,13 +2097,14 @@ static gboolean dshowwrapper_load_decoder_h264(GstStructure *s, GstDShowWrapper
if (gst_buffer_map(codec_data, &codec_data_info, GST_MAP_READ))
{
if (codec_data_info.size <= MAX_HEADER_SIZE)
header_size = dshowwrapper_get_avc_config(codec_data_info.data, codec_data_info.size, header, MAX_HEADER_SIZE, &decoder->lengthSizeMinusOne);
header_size = (gint)dshowwrapper_get_avc_config(codec_data_info.data, codec_data_info.size, header, MAX_HEADER_SIZE, &decoder->lengthSizeMinusOne);
gst_buffer_unmap(codec_data, &codec_data_info);
}
}
else
return FALSE;

// dshowwrapper_get_avc_config() will make sure that (header_size <= MAX_HEADER_SIZE)
if (header_size <= 0)
return FALSE;

Expand Down

3 comments on commit f2f5639

@openjdk-notifier
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@kevinrushforth
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/skara tag 25+1

@openjdk
Copy link

@openjdk openjdk bot commented on f2f5639 Jan 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@kevinrushforth The tag 25+1 was successfully created.

Please sign in to comment.