- backport upstream fixes: * Add support for Echo3G devices * Blacklist iec958 for some USB devices * Remove redundant CHECK_ENUM() from snd_mixer_selem_is_enum*() * Document fixes / updates * Add ability to specify TLV data to external control plugins * Fix invalid long long format specifier * Fix missing break in PCM non-interleaved mmap handling * improve robustness of TLV raw value ranges OBS-URL: https://build.opensuse.org/request/show/122709 OBS-URL: https://build.opensuse.org/package/show/multimedia:libs/alsa?expand=0&rev=101
85 lines
2.5 KiB
Diff
85 lines
2.5 KiB
Diff
From 70b958f460a253f2cbdfd9773d54d489d3dcc4ba Mon Sep 17 00:00:00 2001
|
|
From: =?UTF-8?q?Beno=C3=AEt=20Th=C3=A9baudeau?=
|
|
<benoit.thebaudeau@advansee.com>
|
|
Date: Wed, 23 May 2012 01:53:01 +0200
|
|
Subject: [PATCH 13/14] tlv: improve robustness of raw value ranges
|
|
MIME-Version: 1.0
|
|
Content-Type: text/plain; charset=UTF-8
|
|
Content-Transfer-Encoding: 8bit
|
|
|
|
snd_tlv_convert_from_dB() relies on rangemin/max blindly.
|
|
Since this function is exported, it is better for robustness and
|
|
consistency to parse the range properly, which this patch does.
|
|
|
|
Signed-off-by: Benoît Thébaudeau <benoit.thebaudeau@advansee.com>
|
|
Signed-off-by: Takashi Iwai <tiwai@suse.de>
|
|
---
|
|
src/control/tlv.c | 36 ++++++++++++++++--------------------
|
|
1 file changed, 16 insertions(+), 20 deletions(-)
|
|
|
|
diff --git a/src/control/tlv.c b/src/control/tlv.c
|
|
index f7c9976..6b0b9f4 100644
|
|
--- a/src/control/tlv.c
|
|
+++ b/src/control/tlv.c
|
|
@@ -291,41 +291,37 @@ int snd_tlv_convert_from_dB(unsigned int *tlv, long rangemin, long rangemax,
|
|
{
|
|
switch (tlv[0]) {
|
|
case SND_CTL_TLVT_DB_RANGE: {
|
|
- long dbmin, dbmax, prev_rangemax;
|
|
+ long dbmin, dbmax, prev_submax;
|
|
unsigned int pos, len;
|
|
len = int_index(tlv[1]);
|
|
- if (len > MAX_TLV_RANGE_SIZE)
|
|
- return -EINVAL;
|
|
- if (snd_tlv_get_dB_range(tlv, rangemin, rangemax,
|
|
- &dbmin, &dbmax))
|
|
+ if (len < 6 || len > MAX_TLV_RANGE_SIZE)
|
|
return -EINVAL;
|
|
- if (db_gain <= dbmin) {
|
|
- *value = rangemin;
|
|
- return 0;
|
|
- } else if (db_gain >= dbmax) {
|
|
- *value = rangemax;
|
|
- return 0;
|
|
- }
|
|
pos = 2;
|
|
- prev_rangemax = 0;
|
|
+ prev_submax = 0;
|
|
while (pos + 4 <= len) {
|
|
- rangemin = (int)tlv[pos];
|
|
- rangemax = (int)tlv[pos + 1];
|
|
+ long submin, submax;
|
|
+ submin = (int)tlv[pos];
|
|
+ submax = (int)tlv[pos + 1];
|
|
+ if (rangemax < submax)
|
|
+ submax = rangemax;
|
|
if (!snd_tlv_get_dB_range(tlv + pos + 2,
|
|
- rangemin, rangemax,
|
|
+ submin, submax,
|
|
&dbmin, &dbmax) &&
|
|
db_gain >= dbmin && db_gain <= dbmax)
|
|
return snd_tlv_convert_from_dB(tlv + pos + 2,
|
|
- rangemin, rangemax,
|
|
+ submin, submax,
|
|
db_gain, value, xdir);
|
|
else if (db_gain < dbmin) {
|
|
- *value = xdir ? rangemin : prev_rangemax;
|
|
+ *value = xdir || pos == 2 ? submin : prev_submax;
|
|
return 0;
|
|
}
|
|
- prev_rangemax = rangemax;
|
|
+ prev_submax = submax;
|
|
+ if (rangemax == submax)
|
|
+ break;
|
|
pos += int_index(tlv[pos + 3]) + 4;
|
|
}
|
|
- return -EINVAL;
|
|
+ *value = prev_submax;
|
|
+ return 0;
|
|
}
|
|
case SND_CTL_TLVT_DB_SCALE: {
|
|
int min, step, max;
|
|
--
|
|
1.7.9.2
|
|
|