Prevent reading outside iSAC bitstream, if the stream is corrupted.
BUG=chrome_373312(#24) R=henrik.lundin@webrtc.org, tina.legrand@webrtc.org Review URL: https://webrtc-codereview.appspot.com/20089004 git-svn-id: http://webrtc.googlecode.com/svn/trunk@7379 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
@ -350,6 +350,7 @@ extern "C" {
|
||||
*
|
||||
* Input:
|
||||
* - encoded : Encoded bitstream
|
||||
* - encoded_len_bytes : Length of the bitstream in bytes.
|
||||
*
|
||||
* Output:
|
||||
* - frameLength : Length of frame in packet (in samples)
|
||||
@ -357,6 +358,7 @@ extern "C" {
|
||||
*/
|
||||
|
||||
int16_t WebRtcIsacfix_ReadFrameLen(const int16_t* encoded,
|
||||
int encoded_len_bytes,
|
||||
int16_t* frameLength);
|
||||
|
||||
/****************************************************************************
|
||||
@ -599,6 +601,7 @@ extern "C" {
|
||||
*
|
||||
* Input:
|
||||
* - encoded : Encoded bitstream
|
||||
* - encoded_len_bytes : Length of the bitstream in bytes.
|
||||
*
|
||||
* Output:
|
||||
* - rateIndex : Bandwidth estimate in bitstream
|
||||
@ -606,6 +609,7 @@ extern "C" {
|
||||
*/
|
||||
|
||||
int16_t WebRtcIsacfix_ReadBwIndex(const int16_t* encoded,
|
||||
int encoded_len_bytes,
|
||||
int16_t* rateIndex);
|
||||
|
||||
|
||||
|
@ -35,6 +35,19 @@ Time2Spec WebRtcIsacfix_Time2Spec;
|
||||
MatrixProduct1 WebRtcIsacfix_MatrixProduct1;
|
||||
MatrixProduct2 WebRtcIsacfix_MatrixProduct2;
|
||||
|
||||
/* This method assumes that |stream_size_bytes| is in valid range,
|
||||
* i.e. >= 0 && <= STREAM_MAXW16_60MS
|
||||
*/
|
||||
static void InitializeDecoderBitstream(int stream_size_bytes,
|
||||
Bitstr_dec* bitstream) {
|
||||
bitstream->W_upper = 0xFFFFFFFF;
|
||||
bitstream->streamval = 0;
|
||||
bitstream->stream_index = 0;
|
||||
bitstream->full = 1;
|
||||
bitstream->stream_size = (stream_size_bytes + 1) >> 1;
|
||||
memset(bitstream->stream, 0, sizeof(bitstream->stream));
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* WebRtcIsacfix_AssignSize(...)
|
||||
*
|
||||
@ -388,6 +401,7 @@ int16_t WebRtcIsacfix_Encode(ISACFIX_MainStruct *ISAC_main_inst,
|
||||
byte. */
|
||||
stream_len_even = stream_len % 2 == 0 ? stream_len : stream_len + 1;
|
||||
|
||||
/* convert from bytes to int16_t */
|
||||
#ifndef WEBRTC_ARCH_BIG_ENDIAN
|
||||
/* The encoded data vector is supposesd to be big-endian, but our internal
|
||||
representation is little-endian. So byteswap. */
|
||||
@ -632,6 +646,7 @@ int16_t WebRtcIsacfix_UpdateBwEstimate1(ISACFIX_MainStruct *ISAC_main_inst,
|
||||
int k;
|
||||
#endif
|
||||
int16_t err;
|
||||
const int kRequiredEncodedLenBytes = 10;
|
||||
|
||||
/* typecast pointer to real structure */
|
||||
ISAC_inst = (ISACFIX_SubStruct *)ISAC_main_inst;
|
||||
@ -653,17 +668,14 @@ int16_t WebRtcIsacfix_UpdateBwEstimate1(ISACFIX_MainStruct *ISAC_main_inst,
|
||||
return (-1);
|
||||
}
|
||||
|
||||
streamdata.W_upper = 0xFFFFFFFF;
|
||||
streamdata.streamval = 0;
|
||||
streamdata.stream_index = 0;
|
||||
streamdata.full = 1;
|
||||
InitializeDecoderBitstream(packet_size, &streamdata);
|
||||
|
||||
#ifndef WEBRTC_ARCH_BIG_ENDIAN
|
||||
for (k=0; k<5; k++) {
|
||||
for (k = 0; k < kRequiredEncodedLenBytes / 2; k++) {
|
||||
streamdata.stream[k] = (uint16_t) (((uint16_t)encoded[k] >> 8)|((encoded[k] & 0xFF)<<8));
|
||||
}
|
||||
#else
|
||||
memcpy(streamdata.stream, encoded, 5);
|
||||
memcpy(streamdata.stream, encoded, kRequiredEncodedLenBytes);
|
||||
#endif
|
||||
|
||||
err = WebRtcIsacfix_EstimateBandwidth(&ISAC_inst->bwestimator_obj,
|
||||
@ -716,6 +728,7 @@ int16_t WebRtcIsacfix_UpdateBwEstimate(ISACFIX_MainStruct *ISAC_main_inst,
|
||||
int k;
|
||||
#endif
|
||||
int16_t err;
|
||||
const int kRequiredEncodedLenBytes = 10;
|
||||
|
||||
/* typecast pointer to real structure */
|
||||
ISAC_inst = (ISACFIX_SubStruct *)ISAC_main_inst;
|
||||
@ -725,6 +738,9 @@ int16_t WebRtcIsacfix_UpdateBwEstimate(ISACFIX_MainStruct *ISAC_main_inst,
|
||||
/* return error code if the packet length is null or less */
|
||||
ISAC_inst->errorcode = ISAC_EMPTY_PACKET;
|
||||
return -1;
|
||||
} else if (packet_size < kRequiredEncodedLenBytes) {
|
||||
ISAC_inst->errorcode = ISAC_PACKET_TOO_SHORT;
|
||||
return -1;
|
||||
} else if (packet_size > (STREAM_MAXW16<<1)) {
|
||||
/* return error code if length of stream is too long */
|
||||
ISAC_inst->errorcode = ISAC_LENGTH_MISMATCH;
|
||||
@ -737,17 +753,14 @@ int16_t WebRtcIsacfix_UpdateBwEstimate(ISACFIX_MainStruct *ISAC_main_inst,
|
||||
return (-1);
|
||||
}
|
||||
|
||||
streamdata.W_upper = 0xFFFFFFFF;
|
||||
streamdata.streamval = 0;
|
||||
streamdata.stream_index = 0;
|
||||
streamdata.full = 1;
|
||||
InitializeDecoderBitstream(packet_size, &streamdata);
|
||||
|
||||
#ifndef WEBRTC_ARCH_BIG_ENDIAN
|
||||
for (k=0; k<5; k++) {
|
||||
for (k = 0; k < kRequiredEncodedLenBytes / 2; k++) {
|
||||
streamdata.stream[k] = (uint16_t) ((encoded[k] >> 8)|((encoded[k] & 0xFF)<<8));
|
||||
}
|
||||
#else
|
||||
memcpy(streamdata.stream, encoded, 5);
|
||||
memcpy(streamdata.stream, encoded, kRequiredEncodedLenBytes);
|
||||
#endif
|
||||
|
||||
err = WebRtcIsacfix_EstimateBandwidth(&ISAC_inst->bwestimator_obj,
|
||||
@ -823,7 +836,7 @@ int16_t WebRtcIsacfix_Decode(ISACFIX_MainStruct *ISAC_main_inst,
|
||||
return -1;
|
||||
}
|
||||
|
||||
ISAC_inst->ISACdec_obj.bitstr_obj.stream_size = (len + 1) >> 1;
|
||||
InitializeDecoderBitstream(len, &ISAC_inst->ISACdec_obj.bitstr_obj);
|
||||
|
||||
/* convert bitstream from int16_t to bytes */
|
||||
#ifndef WEBRTC_ARCH_BIG_ENDIAN
|
||||
@ -832,6 +845,8 @@ int16_t WebRtcIsacfix_Decode(ISACFIX_MainStruct *ISAC_main_inst,
|
||||
}
|
||||
if (len & 0x0001)
|
||||
(ISAC_inst->ISACdec_obj.bitstr_obj).stream[k] = (uint16_t) ((encoded[k] & 0xFF)<<8);
|
||||
#else
|
||||
memcpy(ISAC_inst->ISACdec_obj.bitstr_obj.stream, encoded, len);
|
||||
#endif
|
||||
|
||||
/* added for NetEq purposes (VAD/DTX related) */
|
||||
@ -917,14 +932,17 @@ int16_t WebRtcIsacfix_DecodeNb(ISACFIX_MainStruct *ISAC_main_inst,
|
||||
return (-1);
|
||||
}
|
||||
|
||||
if (len == 0)
|
||||
{ /* return error code if the packet length is null */
|
||||
|
||||
if (len <= 0) {
|
||||
/* return error code if the packet length is null or less */
|
||||
ISAC_inst->errorcode = ISAC_EMPTY_PACKET;
|
||||
return -1;
|
||||
} else if (len > (STREAM_MAXW16<<1)) {
|
||||
/* return error code if length of stream is too long */
|
||||
ISAC_inst->errorcode = ISAC_LENGTH_MISMATCH;
|
||||
return -1;
|
||||
}
|
||||
|
||||
ISAC_inst->ISACdec_obj.bitstr_obj.stream_size = (len + 1) >> 1;
|
||||
InitializeDecoderBitstream(len, &ISAC_inst->ISACdec_obj.bitstr_obj);
|
||||
|
||||
/* convert bitstream from int16_t to bytes */
|
||||
#ifndef WEBRTC_ARCH_BIG_ENDIAN
|
||||
@ -933,6 +951,8 @@ int16_t WebRtcIsacfix_DecodeNb(ISACFIX_MainStruct *ISAC_main_inst,
|
||||
}
|
||||
if (len & 0x0001)
|
||||
(ISAC_inst->ISACdec_obj.bitstr_obj).stream[k] = (uint16_t) ((encoded[k] & 0xFF)<<8);
|
||||
#else
|
||||
memcpy(ISAC_inst->ISACdec_obj.bitstr_obj.stream, encoded, len);
|
||||
#endif
|
||||
|
||||
/* added for NetEq purposes (VAD/DTX related) */
|
||||
@ -1296,6 +1316,7 @@ int16_t WebRtcIsacfix_UpdateUplinkBw(ISACFIX_MainStruct* ISAC_main_inst,
|
||||
*/
|
||||
|
||||
int16_t WebRtcIsacfix_ReadFrameLen(const int16_t* encoded,
|
||||
int encoded_len_bytes,
|
||||
int16_t* frameLength)
|
||||
{
|
||||
Bitstr_dec streamdata;
|
||||
@ -1303,18 +1324,20 @@ int16_t WebRtcIsacfix_ReadFrameLen(const int16_t* encoded,
|
||||
int k;
|
||||
#endif
|
||||
int16_t err;
|
||||
const int kRequiredEncodedLenBytes = 10;
|
||||
|
||||
streamdata.W_upper = 0xFFFFFFFF;
|
||||
streamdata.streamval = 0;
|
||||
streamdata.stream_index = 0;
|
||||
streamdata.full = 1;
|
||||
if (encoded_len_bytes < kRequiredEncodedLenBytes) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
InitializeDecoderBitstream(encoded_len_bytes, &streamdata);
|
||||
|
||||
#ifndef WEBRTC_ARCH_BIG_ENDIAN
|
||||
for (k=0; k<5; k++) {
|
||||
for (k = 0; k < kRequiredEncodedLenBytes / 2; k++) {
|
||||
streamdata.stream[k] = (uint16_t) (((uint16_t)encoded[k] >> 8)|((encoded[k] & 0xFF)<<8));
|
||||
}
|
||||
#else
|
||||
memcpy(streamdata.stream, encoded, 5);
|
||||
memcpy(streamdata.stream, encoded, kRequiredEncodedLenBytes);
|
||||
#endif
|
||||
|
||||
/* decode frame length */
|
||||
@ -1341,6 +1364,7 @@ int16_t WebRtcIsacfix_ReadFrameLen(const int16_t* encoded,
|
||||
*/
|
||||
|
||||
int16_t WebRtcIsacfix_ReadBwIndex(const int16_t* encoded,
|
||||
int encoded_len_bytes,
|
||||
int16_t* rateIndex)
|
||||
{
|
||||
Bitstr_dec streamdata;
|
||||
@ -1348,18 +1372,20 @@ int16_t WebRtcIsacfix_ReadBwIndex(const int16_t* encoded,
|
||||
int k;
|
||||
#endif
|
||||
int16_t err;
|
||||
const int kRequiredEncodedLenBytes = 10;
|
||||
|
||||
streamdata.W_upper = 0xFFFFFFFF;
|
||||
streamdata.streamval = 0;
|
||||
streamdata.stream_index = 0;
|
||||
streamdata.full = 1;
|
||||
if (encoded_len_bytes < kRequiredEncodedLenBytes) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
InitializeDecoderBitstream(encoded_len_bytes, &streamdata);
|
||||
|
||||
#ifndef WEBRTC_ARCH_BIG_ENDIAN
|
||||
for (k=0; k<5; k++) {
|
||||
for (k = 0; k < kRequiredEncodedLenBytes / 2; k++) {
|
||||
streamdata.stream[k] = (uint16_t) (((uint16_t)encoded[k] >> 8)|((encoded[k] & 0xFF)<<8));
|
||||
}
|
||||
#else
|
||||
memcpy(streamdata.stream, encoded, 5);
|
||||
memcpy(streamdata.stream, encoded, kRequiredEncodedLenBytes);
|
||||
#endif
|
||||
|
||||
/* decode frame length, needed to get to the rateIndex in the bitstream */
|
||||
|
@ -96,7 +96,16 @@
|
||||
#define STREAM_MAXW16 300 /* The old maximum size still needed for the decoding */
|
||||
#define STREAM_MAXW16_30MS 100 /* 100 Word16 = 200 bytes = 53.4 kbit/s @ 30 ms.framelength */
|
||||
#define STREAM_MAXW16_60MS 200 /* 200 Word16 = 400 bytes = 53.4 kbit/s @ 60 ms.framelength */
|
||||
|
||||
/* This is used only at the decoder bit-stream struct.
|
||||
* - The encoder and decoder bitstream containers are of different size because
|
||||
* old iSAC limited the encoded bitstream to 600 bytes. But newer versions
|
||||
* restrict to shorter bitstream.
|
||||
* - We add 10 bytes of guards to the internal bitstream container. The reason
|
||||
* is that entropy decoder might read few bytes (3 according to our
|
||||
* observations) more than the actual size of the bitstream. To avoid reading
|
||||
* outside memory, in rare occasion of full-size bitstream we add 10 bytes
|
||||
* of guard. */
|
||||
#define INTERNAL_STREAM_SIZE_W16 (STREAM_MAXW16 + 5)
|
||||
|
||||
/* storage size for bit counts */
|
||||
//#define BIT_COUNTER_SIZE 30
|
||||
@ -190,6 +199,7 @@
|
||||
/* 6600 Decoder */
|
||||
#define ISAC_DECODER_NOT_INITIATED 6610
|
||||
#define ISAC_EMPTY_PACKET 6620
|
||||
#define ISAC_PACKET_TOO_SHORT 6625
|
||||
#define ISAC_DISALLOWED_FRAME_MODE_DECODER 6630
|
||||
#define ISAC_RANGE_ERROR_DECODE_FRAME_LENGTH 6640
|
||||
#define ISAC_RANGE_ERROR_DECODE_BANDWIDTH 6650
|
||||
|
@ -26,7 +26,7 @@
|
||||
/* Bitstream struct for decoder */
|
||||
typedef struct Bitstreamstruct_dec {
|
||||
|
||||
uint16_t stream[STREAM_MAXW16_60MS]; /* Array bytestream to decode */
|
||||
uint16_t stream[INTERNAL_STREAM_SIZE_W16]; /* Array bytestream to decode */
|
||||
uint32_t W_upper; /* Upper boundary of interval W */
|
||||
uint32_t streamval;
|
||||
uint16_t stream_index; /* Index to the current position in bytestream */
|
||||
|
@ -571,7 +571,8 @@ int main(int argc, char* argv[])
|
||||
functions from the internal API. */
|
||||
if (stream_len>0) {
|
||||
if (testCE == 1) {
|
||||
err = WebRtcIsacfix_ReadBwIndex((int16_t*)streamdata, &bwe);
|
||||
err = WebRtcIsacfix_ReadBwIndex(
|
||||
(int16_t*)streamdata, stream_len, &bwe);
|
||||
stream_len = WebRtcIsacfix_GetNewBitStream(
|
||||
ISAC_main_inst,
|
||||
bwe,
|
||||
@ -740,7 +741,8 @@ int main(int argc, char* argv[])
|
||||
if (nbTest !=2 ) {
|
||||
short FL;
|
||||
/* Call getFramelen, only used here for function test */
|
||||
err = WebRtcIsacfix_ReadFrameLen((int16_t*)streamdata, &FL);
|
||||
err = WebRtcIsacfix_ReadFrameLen(
|
||||
(int16_t*)streamdata, stream_len, &FL);
|
||||
declen = WebRtcIsacfix_Decode( ISAC_main_inst, streamdata, stream_len,
|
||||
decoded, speechType );
|
||||
/* Error check */
|
||||
|
Reference in New Issue
Block a user