Handle case when Vorbis Comment exceeds max. size in FLAC stream

This commit is contained in:
Martchus 2018-04-29 19:45:20 +02:00
parent 30553c947c
commit 9b83cc37f6
1 changed files with 13 additions and 5 deletions

View File

@ -171,7 +171,8 @@ void FlacStream::internalParseHeader(Diagnostics &diag)
* - "METADATA_BLOCK_PICTURE" are updated. * - "METADATA_BLOCK_PICTURE" are updated.
* - Padding is skipped * - Padding is skipped
* *
* \returns Returns the start offset of the last "METADATA_BLOCK_HEADER" withing \a outputStream. * \returns Returns the start offset of the last "METADATA_BLOCK_HEADER" within \a outputStream.
* \todo Return as std::streamoff in v8 to avoid conversion.
*/ */
uint32 FlacStream::makeHeader(ostream &outputStream, Diagnostics &diag) uint32 FlacStream::makeHeader(ostream &outputStream, Diagnostics &diag)
{ {
@ -183,7 +184,7 @@ uint32 FlacStream::makeHeader(ostream &outputStream, Diagnostics &diag)
BE::getBytes(static_cast<uint32>(0x664C6143u), copy.buffer()); BE::getBytes(static_cast<uint32>(0x664C6143u), copy.buffer());
outputStream.write(copy.buffer(), 4); outputStream.write(copy.buffer(), 4);
uint32 lastStartOffset = 0; std::streamoff lastStartOffset = 0;
// write meta data blocks which don't need to be adjusted // write meta data blocks which don't need to be adjusted
for (FlacMetaDataBlockHeader header; !header.isLast();) { for (FlacMetaDataBlockHeader header; !header.isLast();) {
@ -220,14 +221,19 @@ uint32 FlacStream::makeHeader(ostream &outputStream, Diagnostics &diag)
m_vorbisComment->make(outputStream, VorbisCommentFlags::NoSignature | VorbisCommentFlags::NoFramingByte | VorbisCommentFlags::NoCovers, diag); m_vorbisComment->make(outputStream, VorbisCommentFlags::NoSignature | VorbisCommentFlags::NoFramingByte | VorbisCommentFlags::NoCovers, diag);
// write "METADATA_BLOCK_HEADER" // write "METADATA_BLOCK_HEADER"
const uint32 endOffset = outputStream.tellp(); const auto endOffset = outputStream.tellp();
FlacMetaDataBlockHeader header; FlacMetaDataBlockHeader header;
header.setType(FlacMetaDataBlockType::VorbisComment); header.setType(FlacMetaDataBlockType::VorbisComment);
header.setDataSize(endOffset - lastStartOffset - 4); auto dataSize(static_cast<uint64>(endOffset) - static_cast<uint64>(lastStartOffset) - 4);
if (dataSize > 0xFFFFFF) {
dataSize = 0xFFFFFF;
diag.emplace_back(DiagLevel::Critical, "Vorbis Comment is too big and will be truncated.", "write Vorbis Comment to FLAC stream");
}
header.setDataSize(static_cast<uint32>(dataSize));
header.setLast(!m_vorbisComment->hasField(coverId)); header.setLast(!m_vorbisComment->hasField(coverId));
outputStream.seekp(lastStartOffset); outputStream.seekp(lastStartOffset);
header.makeHeader(outputStream); header.makeHeader(outputStream);
outputStream.seekp(endOffset); outputStream.seekp(static_cast<streamoff>(dataSize), ios_base::cur);
// write cover fields separately as "METADATA_BLOCK_PICTURE" // write cover fields separately as "METADATA_BLOCK_PICTURE"
if (header.isLast()) { if (header.isLast()) {
@ -254,6 +260,8 @@ uint32 FlacStream::makeHeader(ostream &outputStream, Diagnostics &diag)
*/ */
void FlacStream::makePadding(ostream &stream, uint32 size, bool isLast, Diagnostics &diag) void FlacStream::makePadding(ostream &stream, uint32 size, bool isLast, Diagnostics &diag)
{ {
VAR_UNUSED(diag)
// make header // make header
FlacMetaDataBlockHeader header; FlacMetaDataBlockHeader header;
header.setType(FlacMetaDataBlockType::Padding); header.setType(FlacMetaDataBlockType::Padding);