summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMax Kellermann <max@duempel.org>2016-03-07 14:30:43 +0100
committerMax Kellermann <max@duempel.org>2016-03-07 14:30:43 +0100
commit6ff01cc72c762d9f9b7423eadb7b3bd69c8800a6 (patch)
tree5a2f1ce975b99e1163b138252d99c1c3a797d9ca
parent031410c72b4622f265386c21fd1496e38779c2ba (diff)
parente140a28073f75375a33b28bcbcd0ecc669c5a518 (diff)
Merge branch 'v0.19.x'
-rw-r--r--NEWS8
-rw-r--r--src/archive/plugins/Iso9660ArchivePlugin.cxx43
-rw-r--r--src/decoder/plugins/DsdiffDecoderPlugin.cxx2
-rw-r--r--src/decoder/plugins/OpusReader.hxx2
-rw-r--r--src/mixer/plugins/PulseMixerPlugin.cxx2
-rw-r--r--src/protocol/ArgParser.cxx5
-rw-r--r--src/util/HugeAllocator.cxx2
7 files changed, 41 insertions, 23 deletions
diff --git a/NEWS b/NEWS
index 0be6fe953..98318b776 100644
--- a/NEWS
+++ b/NEWS
@@ -52,6 +52,14 @@ ver 0.20 (not yet released)
* update
- apply .mpdignore matches to subdirectories
+ver 0.19.14 (not yet released)
+* decoder
+ - dsdiff: fix off-by-one buffer overflow
+ - opus: limit tag size to 64 kB
+* archive
+ - iso9660: fix buffer overflow
+* fix build failures on non-glibc builds due to constexpr Mutex
+
ver 0.19.13 (2016/02/23)
* tags
- aiff, riff: fix ID3 chunk padding
diff --git a/src/archive/plugins/Iso9660ArchivePlugin.cxx b/src/archive/plugins/Iso9660ArchivePlugin.cxx
index 6c17b6ad8..d077e3aef 100644
--- a/src/archive/plugins/Iso9660ArchivePlugin.cxx
+++ b/src/archive/plugins/Iso9660ArchivePlugin.cxx
@@ -65,7 +65,11 @@ public:
return iso9660_iso_seek_read(iso, ptr, start, i_size);
}
- void Visit(const char *path, ArchiveVisitor &visitor);
+ /**
+ * @param capacity the path buffer size
+ */
+ void Visit(char *path, size_t length, size_t capacity,
+ ArchiveVisitor &visitor);
virtual void Close() override {
Unref();
@@ -83,32 +87,36 @@ static constexpr Domain iso9660_domain("iso9660");
/* archive open && listing routine */
inline void
-Iso9660ArchiveFile::Visit(const char *psz_path, ArchiveVisitor &visitor)
+Iso9660ArchiveFile::Visit(char *path, size_t length, size_t capacity,
+ ArchiveVisitor &visitor)
{
- CdioList_t *entlist;
- CdioListNode_t *entnode;
- iso9660_stat_t *statbuf;
- char pathname[4096];
-
- entlist = iso9660_ifs_readdir (iso, psz_path);
+ auto *entlist = iso9660_ifs_readdir(iso, path);
if (!entlist) {
return;
}
/* Iterate over the list of nodes that iso9660_ifs_readdir gives */
+ CdioListNode_t *entnode;
_CDIO_LIST_FOREACH (entnode, entlist) {
- statbuf = (iso9660_stat_t *) _cdio_list_node_data (entnode);
+ auto *statbuf = (iso9660_stat_t *)
+ _cdio_list_node_data(entnode);
+ const char *filename = statbuf->filename;
+ if (strcmp(filename, ".") == 0 || strcmp(filename, "..") == 0)
+ continue;
+
+ size_t filename_length = strlen(filename);
+ if (length + filename_length + 1 >= capacity)
+ /* file name is too long */
+ continue;
- strcpy(pathname, psz_path);
- strcat(pathname, statbuf->filename);
+ memcpy(path + length, filename, filename_length + 1);
+ size_t new_length = length + filename_length;
if (iso9660_stat_s::_STAT_DIR == statbuf->type ) {
- if (strcmp(statbuf->filename, ".") && strcmp(statbuf->filename, "..")) {
- strcat(pathname, "/");
- Visit(pathname, visitor);
- }
+ memcpy(path + new_length, "/", 2);
+ Visit(path, new_length + 1, capacity, visitor);
} else {
//remove leading /
- visitor.VisitArchiveEntry(pathname + 1);
+ visitor.VisitArchiveEntry(path + 1);
}
}
_cdio_list_free (entlist, true);
@@ -132,7 +140,8 @@ iso9660_archive_open(Path pathname, Error &error)
void
Iso9660ArchiveFile::Visit(ArchiveVisitor &visitor)
{
- Visit("/", visitor);
+ char path[4096] = "/";
+ Visit(path, 1, sizeof(path), visitor);
}
/* single archive handling */
diff --git a/src/decoder/plugins/DsdiffDecoderPlugin.cxx b/src/decoder/plugins/DsdiffDecoderPlugin.cxx
index abb263486..6653f2053 100644
--- a/src/decoder/plugins/DsdiffDecoderPlugin.cxx
+++ b/src/decoder/plugins/DsdiffDecoderPlugin.cxx
@@ -205,7 +205,7 @@ dsdiff_handle_native_tag(InputStream &is,
if (length == 0 || length > 60)
return;
- char string[length];
+ char string[length + 1];
char *label;
label = string;
diff --git a/src/decoder/plugins/OpusReader.hxx b/src/decoder/plugins/OpusReader.hxx
index b8a6083a6..4d11607cb 100644
--- a/src/decoder/plugins/OpusReader.hxx
+++ b/src/decoder/plugins/OpusReader.hxx
@@ -85,7 +85,7 @@ public:
char *ReadString() {
uint32_t length;
- if (!ReadWord(length))
+ if (!ReadWord(length) || length >= 65536)
return nullptr;
const char *src = (const char *)Read(length);
diff --git a/src/mixer/plugins/PulseMixerPlugin.cxx b/src/mixer/plugins/PulseMixerPlugin.cxx
index 6d003b47d..20846cfe0 100644
--- a/src/mixer/plugins/PulseMixerPlugin.cxx
+++ b/src/mixer/plugins/PulseMixerPlugin.cxx
@@ -213,7 +213,7 @@ PulseMixer::SetVolume(unsigned new_volume, Error &error)
struct pa_cvolume cvolume;
pa_cvolume_set(&cvolume, volume.channels,
- (pa_volume_t)new_volume * PA_VOLUME_NORM / 100 + 0.5);
+ (new_volume * PA_VOLUME_NORM + 50) / 100);
bool success = pulse_output_set_volume(output, &cvolume, error);
if (success)
volume = cvolume;
diff --git a/src/protocol/ArgParser.cxx b/src/protocol/ArgParser.cxx
index 454e2ee39..8557464fd 100644
--- a/src/protocol/ArgParser.cxx
+++ b/src/protocol/ArgParser.cxx
@@ -78,7 +78,7 @@ ParseCommandArgRange(const char *s)
throw FormatProtocolError(ACK_ERROR_ARG,
"Number is negative: %s", s);
- if (unsigned(value) > std::numeric_limits<unsigned>::max())
+ if (value > std::numeric_limits<int>::max())
throw FormatProtocolError(ACK_ERROR_ARG,
"Number too large: %s", s);
@@ -99,7 +99,8 @@ ParseCommandArgRange(const char *s)
throw FormatProtocolError(ACK_ERROR_ARG,
"Number is negative: %s", s);
- if (unsigned(value) > std::numeric_limits<unsigned>::max())
+
+ if (value > std::numeric_limits<int>::max())
throw FormatProtocolError(ACK_ERROR_ARG,
"Number too large: %s", s);
diff --git a/src/util/HugeAllocator.cxx b/src/util/HugeAllocator.cxx
index 1da049f2f..f26ffc814 100644
--- a/src/util/HugeAllocator.cxx
+++ b/src/util/HugeAllocator.cxx
@@ -46,7 +46,7 @@ static size_t
AlignToPageSize(size_t size)
{
static const long page_size = sysconf(_SC_PAGESIZE);
- if (page_size > 0)
+ if (page_size == 0)
return size;
size_t ps(page_size);