1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
|
--- audiofile-0.3.6.orig/libaudiofile/modules/MSADPCM.cpp 2013-03-06 06:30:03.000000000 +0100
+++ audiofile-0.3.6/libaudiofile/modules/MSADPCM.cpp 2017-04-26 02:15:29.573388050 +0200
@@ -101,24 +101,60 @@ static const int16_t adaptationTable[] =
768, 614, 512, 409, 307, 230, 230, 230
};
+int firstBitSet(int x)
+{
+ int position=0;
+ while (x!=0)
+ {
+ x>>=1;
+ ++position;
+ }
+ return position;
+}
+
+#ifndef __has_builtin
+#define __has_builtin(x) 0
+#endif
+
+int multiplyCheckOverflow(int a, int b, int *result)
+{
+#if (defined __GNUC__ && __GNUC__ >= 5) || ( __clang__ && __has_builtin(__builtin_mul_overflow))
+ return __builtin_mul_overflow(a, b, result);
+#else
+ if (firstBitSet(a)+firstBitSet(b)>31) // int is signed, so we can't use 32 bits
+ return true;
+ *result = a * b;
+ return false;
+#endif
+}
+
+
// Compute a linear PCM value from the given differential coded value.
static int16_t decodeSample(ms_adpcm_state &state,
- uint8_t code, const int16_t *coefficient)
+ uint8_t code, const int16_t *coefficient, bool *ok=NULL)
{
int linearSample = (state.sample1 * coefficient[0] +
state.sample2 * coefficient[1]) >> 8;
+ int delta;
linearSample += ((code & 0x08) ? (code - 0x10) : code) * state.delta;
linearSample = clamp(linearSample, MIN_INT16, MAX_INT16);
- int delta = (state.delta * adaptationTable[code]) >> 8;
+ if (multiplyCheckOverflow(state.delta, adaptationTable[code], &delta))
+ {
+ if (ok) *ok=false;
+ _af_error(AF_BAD_COMPRESSION, "Error decoding sample");
+ return 0;
+ }
+ delta >>= 8;
if (delta < 16)
delta = 16;
state.delta = delta;
state.sample2 = state.sample1;
state.sample1 = linearSample;
+ if (ok) *ok=true;
return static_cast<int16_t>(linearSample);
}
@@ -212,13 +248,16 @@ int MSADPCM::decodeBlock(const uint8_t *
{
uint8_t code;
int16_t newSample;
+ bool ok;
code = *encoded >> 4;
- newSample = decodeSample(*state[0], code, coefficient[0]);
+ newSample = decodeSample(*state[0], code, coefficient[0], &ok);
+ if (!ok) return 0;
*decoded++ = newSample;
code = *encoded & 0x0f;
- newSample = decodeSample(*state[1], code, coefficient[1]);
+ newSample = decodeSample(*state[1], code, coefficient[1], &ok);
+ if (!ok) return 0;
*decoded++ = newSample;
encoded++;
|