decoder/OpusReader: return StringView

Since we now don't duplicate all items, we can easily remove the 64kB
limit from OpusReader::ReadString() and instead silently ignore and
skip all strings which are longer than 4 kB.

This fixes a tag duplication bug with Opus file containing a very long
`METADATA_BLOCK_PICTURE` tag, which occurred because the Opus plugin
returned false after parsing all tags, and then the MPD core fell back
to FFmpeg which scanned the tags again.
This commit is contained in:
Max Kellermann
2019-06-05 22:19:35 +02:00
parent f9ca2f52c1
commit 3fae2150f5
3 changed files with 25 additions and 14 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2003-2018 The Music Player Daemon Project
* Copyright 2003-2019 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
@@ -20,6 +20,8 @@
#ifndef MPD_OPUS_READER_HXX
#define MPD_OPUS_READER_HXX
#include "util/StringView.hxx"
#include <algorithm>
#include <stdint.h>
@@ -81,18 +83,16 @@ public:
return ReadWord(length) && Skip(length);
}
char *ReadString() {
StringView ReadString() {
uint32_t length;
if (!ReadWord(length) || length >= 65536)
if (!ReadWord(length))
return nullptr;
const char *src = (const char *)Read(length);
if (src == nullptr)
return nullptr;
char *dest = new char[length + 1];
*std::copy_n(src, length, dest) = 0;
return dest;
return {src, length};
}
};