alsa/0013-tlv-improve-robustness-of-raw-value-ranges.patch

85 lines
2.5 KiB
Diff
Raw Normal View History

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