release v0.19.14
-----BEGIN PGP SIGNATURE----- Version: GnuPG v2 iQIcBAABCAAGBQJW7DpiAAoJECNuiljG20USwwkP/1z3HeJjzzrwySH9MVeFpVtR fr9XL2pO6zTcaVAIk/fNWtrcT6G5IuK079GKVa2jADN8KRMfCvGDEgHfGevjRNmc USXkUm2pij67S3Ic74WhDISt32gYzBOCo/nFIFncLyjXXPW4WRq/3rb8tMwffZen d/wqZmzHGEom8z0BTLASY/QM2KTBXOHgAhTb4M8lowxlesK8O/6Mx14UxgcIKIDf 1lqRhaF6NRS56uwjt8GwkaH9Td8wJG/inVLQo08z26ycJNaPrkxSNrWsSzQdBr8Q DanbH4nefj8L33PVCV9nNPSjGe5s3R3D9WVEvt+cJ71UqBUQJkYgXaYRLQVEs1Mk 80a9MlFECF1UiS9FwmnUXRAY0Zzb19NLjm+v3CeMANqoFQ/OQaIe3/iaM0hT0yto akHWhgEE4SuwcHPpUXQlKlbYHW6DaHBULwpzcKxFUeQkzx5m4FshBSL73TEEyv8+ bRc4tGIqA2Pep/Ptg3R9mJZ5wr/crtJby9FxNUkXiGZeiHEya+mRdGVyogMnce/K BTg1bhiaE7Ofdxd4NuUIOZ6OkjpFnnQajJwnR1dJrZG+avOrGjcBPH5QGHWEYfs7 hVQhea2ehbcqQPq5celaZkL30SCxZmuN/0Lbmc8y7tpshLkdSUxmBoPSjvUD/UUz JyZf+npL5nmtF0Pqz7W8 =McwP -----END PGP SIGNATURE----- Merge tag 'v0.19.14' release v0.19.14
This commit is contained in:
commit
e8519fecb4
3
NEWS
3
NEWS
@ -52,12 +52,13 @@ ver 0.20 (not yet released)
|
|||||||
* update
|
* update
|
||||||
- apply .mpdignore matches to subdirectories
|
- apply .mpdignore matches to subdirectories
|
||||||
|
|
||||||
ver 0.19.14 (not yet released)
|
ver 0.19.14 (2016/03/18)
|
||||||
* decoder
|
* decoder
|
||||||
- dsdiff: fix off-by-one buffer overflow
|
- dsdiff: fix off-by-one buffer overflow
|
||||||
- opus: limit tag size to 64 kB
|
- opus: limit tag size to 64 kB
|
||||||
* archive
|
* archive
|
||||||
- iso9660: fix buffer overflow
|
- iso9660: fix buffer overflow
|
||||||
|
* fix quadratic runtime bug in the tag pool
|
||||||
* fix build failures on non-glibc builds due to constexpr Mutex
|
* fix build failures on non-glibc builds due to constexpr Mutex
|
||||||
|
|
||||||
ver 0.19.13 (2016/02/23)
|
ver 0.19.13 (2016/02/23)
|
||||||
|
@ -24,19 +24,23 @@
|
|||||||
#include "util/VarSize.hxx"
|
#include "util/VarSize.hxx"
|
||||||
#include "util/StringView.hxx"
|
#include "util/StringView.hxx"
|
||||||
|
|
||||||
|
#include <limits>
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
Mutex tag_pool_lock;
|
Mutex tag_pool_lock;
|
||||||
|
|
||||||
static constexpr size_t NUM_SLOTS = 4096;
|
static constexpr size_t NUM_SLOTS = 4093;
|
||||||
|
|
||||||
struct TagPoolSlot {
|
struct TagPoolSlot {
|
||||||
TagPoolSlot *next;
|
TagPoolSlot *next;
|
||||||
unsigned char ref;
|
unsigned char ref;
|
||||||
TagItem item;
|
TagItem item;
|
||||||
|
|
||||||
|
static constexpr unsigned MAX_REF = std::numeric_limits<decltype(ref)>::max();
|
||||||
|
|
||||||
TagPoolSlot(TagPoolSlot *_next, TagType type,
|
TagPoolSlot(TagPoolSlot *_next, TagType type,
|
||||||
StringView value)
|
StringView value)
|
||||||
:next(_next), ref(1) {
|
:next(_next), ref(1) {
|
||||||
@ -114,7 +118,7 @@ tag_pool_get_item(TagType type, StringView value)
|
|||||||
for (auto slot = *slot_p; slot != nullptr; slot = slot->next) {
|
for (auto slot = *slot_p; slot != nullptr; slot = slot->next) {
|
||||||
if (slot->item.type == type &&
|
if (slot->item.type == type &&
|
||||||
value.Equals(slot->item.value) &&
|
value.Equals(slot->item.value) &&
|
||||||
slot->ref < 0xff) {
|
slot->ref < TagPoolSlot::MAX_REF) {
|
||||||
assert(slot->ref > 0);
|
assert(slot->ref > 0);
|
||||||
++slot->ref;
|
++slot->ref;
|
||||||
return &slot->item;
|
return &slot->item;
|
||||||
@ -133,17 +137,14 @@ tag_pool_dup_item(TagItem *item)
|
|||||||
|
|
||||||
assert(slot->ref > 0);
|
assert(slot->ref > 0);
|
||||||
|
|
||||||
if (slot->ref < 0xff) {
|
if (slot->ref < TagPoolSlot::MAX_REF) {
|
||||||
++slot->ref;
|
++slot->ref;
|
||||||
return item;
|
return item;
|
||||||
} else {
|
} else {
|
||||||
/* the reference counter overflows above 0xff;
|
/* the reference counter overflows above MAX_REF;
|
||||||
duplicate the item, and start with 1 */
|
obtain a reference to a different TagPoolSlot which
|
||||||
auto slot_p = tag_value_slot_p(item->type, item->value);
|
isn't yet "full" */
|
||||||
slot = TagPoolSlot::Create(*slot_p, item->type,
|
return tag_pool_get_item(item->type, item->value);
|
||||||
item->value);
|
|
||||||
*slot_p = slot;
|
|
||||||
return &slot->item;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user