diff options
author | Matthias P. Braendli <matthias.braendli@mpb.li> | 2024-01-05 17:50:19 +0100 |
---|---|---|
committer | Matthias P. Braendli <matthias.braendli@mpb.li> | 2024-01-05 17:50:19 +0100 |
commit | 571316f329948dc464cc2be37b210f0b3e7816f7 (patch) | |
tree | 8396262af9d84f5a0490af9805cde11cf5fc9eed /libMpegTPDec/src | |
parent | e778887e4e5589528b06b04404ce4c71aaae267a (diff) | |
parent | 716f4394641d53f0d79c9ddac3fa93b03a49f278 (diff) | |
download | fdk-aac-dabplus2.tar.gz fdk-aac-dabplus2.tar.bz2 fdk-aac-dabplus2.zip |
Merge fdk-aac 'v2.0.3' into dabplus2dabplus2
Diffstat (limited to 'libMpegTPDec/src')
-rw-r--r-- | libMpegTPDec/src/tpdec_asc.cpp | 243 | ||||
-rw-r--r-- | libMpegTPDec/src/tpdec_latm.cpp | 41 | ||||
-rw-r--r-- | libMpegTPDec/src/tpdec_latm.h | 4 | ||||
-rw-r--r-- | libMpegTPDec/src/tpdec_lib.cpp | 8 |
4 files changed, 249 insertions, 47 deletions
diff --git a/libMpegTPDec/src/tpdec_asc.cpp b/libMpegTPDec/src/tpdec_asc.cpp index bb4094b..8f77017 100644 --- a/libMpegTPDec/src/tpdec_asc.cpp +++ b/libMpegTPDec/src/tpdec_asc.cpp @@ -1,7 +1,7 @@ /* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten +© Copyright 1995 - 2020 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. All rights reserved. 1. INTRODUCTION @@ -266,11 +266,118 @@ static int CProgramConfig_ReadHeightExt(CProgramConfig *pPce, return (err); } +/** + * \brief Sanity checks for program config element. + * Check order of elements according to ISO/IEC 13818-7:2003(E), + * chapter 8.5.1 + * + * \param pPce pointer to program config element. + * + * \return 0 if successful, otherwise 1. + */ +static int CProgramConfig_Check(CProgramConfig *pPce) { + INT i; + INT err = 0; + INT numBackChannels[3] = {0}; + INT numSideChannels[3] = {0}; + INT numFrontChannels[3] = {0}; + UCHAR *pCpeFront = pPce->FrontElementIsCpe; + UCHAR *pCpeSide = pPce->SideElementIsCpe; + UCHAR *pCpeBack = pPce->BackElementIsCpe; + UCHAR *pHeight; + + pHeight = pPce->BackElementHeightInfo; + for (i = 0; i < pPce->NumBackChannelElements; i++) { + numBackChannels[*pHeight] += pPce->BackElementIsCpe[i] ? 2 : 1; + pHeight++; + } + pHeight = pPce->SideElementHeightInfo; + for (i = 0; i < pPce->NumSideChannelElements; i++) { + numSideChannels[*pHeight] += pPce->SideElementIsCpe[i] ? 2 : 1; + pHeight++; + } + pHeight = pPce->FrontElementHeightInfo; + for (i = 0; i < pPce->NumFrontChannelElements; i++) { + numFrontChannels[*pHeight] += pPce->FrontElementIsCpe[i] ? 2 : 1; + pHeight++; + } + + /* 0 = normal height channels, 1 = top height channels, 2 = bottom height + * channels */ + for (i = 0; i < 3; i++) { + /* if number of channels is odd => first element must be a SCE (front center + * channel) */ + if (numFrontChannels[i] & 1) { + if (*pCpeFront++ == ID_CPE) { + err = 1; + goto bail; + } + numFrontChannels[i]--; + } + while (numFrontChannels[i] > 0) { + /* must be CPE or paired SCE */ + if (*pCpeFront++ == ID_SCE) { + if (*pCpeFront++ == ID_CPE) { + err = 1; + goto bail; + } + } + numFrontChannels[i] -= 2; + }; + + /* in case that a top center surround channel (Ts) is transmitted the number + * of channels can be odd */ + if (i != 1) { + /* number of channels must be even */ + if (numSideChannels[i] & 1) { + err = 1; + goto bail; + } + while (numSideChannels[i] > 0) { + /* must be CPE or paired SCE */ + if (*pCpeSide++ == ID_SCE) { + if (*pCpeSide++ == ID_CPE) { + err = 1; + goto bail; + } + } + numSideChannels[i] -= 2; + }; + } + + while (numBackChannels[i] > 1) { + /* must be CPE or paired SCE */ + if (*pCpeBack++ == ID_SCE) { + if (*pCpeBack++ == ID_CPE) { + err = 1; + goto bail; + } + } + numBackChannels[i] -= 2; + }; + /* if number of channels is odd => last element must be a SCE (back center + * channel) */ + if (numBackChannels[i]) { + if (*pCpeBack++ == ID_CPE) { + err = 1; + goto bail; + } + } + } + +bail: + + return err; +} + void CProgramConfig_Read(CProgramConfig *pPce, HANDLE_FDK_BITSTREAM bs, UINT alignmentAnchor) { - int i, err = 0; + int i; int commentBytes; + UCHAR tag, isCpe; + UCHAR checkElementTagSelect[3][PC_FSB_CHANNELS_MAX] = {{0}}; + pPce->isValid = 1; pPce->NumEffectiveChannels = 0; pPce->NumChannels = 0; pPce->ElementInstanceTag = (UCHAR)FDKreadBits(bs, 4); @@ -297,28 +404,60 @@ void CProgramConfig_Read(CProgramConfig *pPce, HANDLE_FDK_BITSTREAM bs, } for (i = 0; i < pPce->NumFrontChannelElements; i++) { - pPce->FrontElementIsCpe[i] = (UCHAR)FDKreadBits(bs, 1); - pPce->FrontElementTagSelect[i] = (UCHAR)FDKreadBits(bs, 4); + pPce->FrontElementIsCpe[i] = isCpe = (UCHAR)FDKreadBits(bs, 1); + pPce->FrontElementTagSelect[i] = tag = (UCHAR)FDKreadBits(bs, 4); pPce->NumChannels += pPce->FrontElementIsCpe[i] ? 2 : 1; + + /* Check element instance tag according to ISO/IEC 13818-7:2003(E), + * chapter 8.2.1.1 */ + if (checkElementTagSelect[isCpe][tag] == 0) { + checkElementTagSelect[isCpe][tag] = 1; + } else { + pPce->isValid = 0; + } } for (i = 0; i < pPce->NumSideChannelElements; i++) { - pPce->SideElementIsCpe[i] = (UCHAR)FDKreadBits(bs, 1); - pPce->SideElementTagSelect[i] = (UCHAR)FDKreadBits(bs, 4); + pPce->SideElementIsCpe[i] = isCpe = (UCHAR)FDKreadBits(bs, 1); + pPce->SideElementTagSelect[i] = tag = (UCHAR)FDKreadBits(bs, 4); pPce->NumChannels += pPce->SideElementIsCpe[i] ? 2 : 1; + + /* Check element instance tag according to ISO/IEC 13818-7:2003(E), + * chapter 8.2.1.1 */ + if (checkElementTagSelect[isCpe][tag] == 0) { + checkElementTagSelect[isCpe][tag] = 1; + } else { + pPce->isValid = 0; + } } for (i = 0; i < pPce->NumBackChannelElements; i++) { - pPce->BackElementIsCpe[i] = (UCHAR)FDKreadBits(bs, 1); - pPce->BackElementTagSelect[i] = (UCHAR)FDKreadBits(bs, 4); + pPce->BackElementIsCpe[i] = isCpe = (UCHAR)FDKreadBits(bs, 1); + pPce->BackElementTagSelect[i] = tag = (UCHAR)FDKreadBits(bs, 4); pPce->NumChannels += pPce->BackElementIsCpe[i] ? 2 : 1; + + /* Check element instance tag according to ISO/IEC 13818-7:2003(E), + * chapter 8.2.1.1 */ + if (checkElementTagSelect[isCpe][tag] == 0) { + checkElementTagSelect[isCpe][tag] = 1; + } else { + pPce->isValid = 0; + } } pPce->NumEffectiveChannels = pPce->NumChannels; for (i = 0; i < pPce->NumLfeChannelElements; i++) { - pPce->LfeElementTagSelect[i] = (UCHAR)FDKreadBits(bs, 4); + pPce->LfeElementTagSelect[i] = tag = (UCHAR)FDKreadBits(bs, 4); pPce->NumChannels += 1; + + /* Check element instance tag according to ISO/IEC 13818-7:2003(E), + * chapter 8.2.1.1 */ + if (checkElementTagSelect[2][tag] == 0) { + checkElementTagSelect[2][tag] = 1; + } else { + pPce->isValid = 0; + } } for (i = 0; i < pPce->NumAssocDataElements; i++) { @@ -336,7 +475,15 @@ void CProgramConfig_Read(CProgramConfig *pPce, HANDLE_FDK_BITSTREAM bs, commentBytes = pPce->CommentFieldBytes; /* Search for height info extension and read it if available */ - err = CProgramConfig_ReadHeightExt(pPce, bs, &commentBytes, alignmentAnchor); + if (CProgramConfig_ReadHeightExt(pPce, bs, &commentBytes, alignmentAnchor)) { + pPce->isValid = 0; + } + + /* Check order of elements according to ISO / IEC 13818 - 7:2003(E), + * chapter 8.5.1 */ + if (CProgramConfig_Check(pPce)) { + pPce->isValid = 0; + } for (i = 0; i < commentBytes; i++) { UCHAR text; @@ -347,8 +494,6 @@ void CProgramConfig_Read(CProgramConfig *pPce, HANDLE_FDK_BITSTREAM bs, pPce->Comment[i] = text; } } - - pPce->isValid = (err) ? 0 : 1; } /* @@ -1415,7 +1560,7 @@ static TRANSPORTDEC_ERROR EldSpecificConfig_Parse(CSAudioSpecificConfig *asc, cb->cbSscData, hBs, asc->m_aot, asc->m_samplingFrequency << esc->m_sbrSamplingRate, asc->m_samplesPerFrame << esc->m_sbrSamplingRate, - 1, /* stereoConfigIndex */ + asc->m_channelConfiguration, 1, /* stereoConfigIndex */ -1, /* nTimeSlots: read from bitstream */ eldExtLen, asc->configMode, &asc->SacConfigChanged); if (ErrorStatus != TRANSPORTDEC_OK) { @@ -1549,7 +1694,7 @@ static TRANSPORTDEC_ERROR extElementConfig(CSUsacExtElementConfig *extElement, const AUDIO_OBJECT_TYPE aot) { TRANSPORTDEC_ERROR ErrorStatus = TRANSPORTDEC_OK; - int usacExtElementType = escapedValue(hBs, 4, 8, 16); + UINT usacExtElementType = escapedValue(hBs, 4, 8, 16); /* recurve extension elements which are invalid for USAC */ if (aot == AOT_USAC) { @@ -1566,7 +1711,6 @@ static TRANSPORTDEC_ERROR extElementConfig(CSUsacExtElementConfig *extElement, } } - extElement->usacExtElementType = (USAC_EXT_ELEMENT_TYPE)usacExtElementType; int usacExtElementConfigLength = escapedValue(hBs, 4, 8, 16); extElement->usacExtElementConfigLength = (USHORT)usacExtElementConfigLength; INT bsAnchor; @@ -1600,8 +1744,10 @@ static TRANSPORTDEC_ERROR extElementConfig(CSUsacExtElementConfig *extElement, } } break; default: + usacExtElementType = ID_EXT_ELE_UNKNOWN; break; } + extElement->usacExtElementType = (USAC_EXT_ELEMENT_TYPE)usacExtElementType; /* Adjust bit stream position. This is required because of byte alignment and * unhandled extensions. */ @@ -1630,8 +1776,12 @@ static TRANSPORTDEC_ERROR configExtension(CSUsacConfig *usc, TRANSPORTDEC_ERROR ErrorStatus = TRANSPORTDEC_OK; int numConfigExtensions; - int usacConfigExtType; + UINT usacConfigExtType; int usacConfigExtLength; + int loudnessInfoSetIndex = + -1; /* index of loudnessInfoSet config extension. -1 if not contained. */ + int tmp_subStreamIndex = 0; + AUDIO_OBJECT_TYPE tmp_aot = AOT_USAC; numConfigExtensions = (int)escapedValue(hBs, 2, 4, 8) + 1; for (int confExtIdx = 0; confExtIdx < numConfigExtensions; confExtIdx++) { @@ -1661,10 +1811,12 @@ static TRANSPORTDEC_ERROR configExtension(CSUsacConfig *usc, ErrorStatus = (TRANSPORTDEC_ERROR)cb->cbUniDrc( cb->cbUniDrcData, hBs, usacConfigExtLength, 1, /* loudnessInfoSet */ - 0, loudnessInfoSetConfigExtensionPosition, AOT_USAC); + tmp_subStreamIndex, loudnessInfoSetConfigExtensionPosition, + tmp_aot); if (ErrorStatus != TRANSPORTDEC_OK) { return ErrorStatus; } + loudnessInfoSetIndex = confExtIdx; } } break; default: @@ -1680,6 +1832,17 @@ static TRANSPORTDEC_ERROR configExtension(CSUsacConfig *usc, FDKpushFor(hBs, usacConfigExtLength); } + if (loudnessInfoSetIndex == -1 && cb->cbUniDrc != NULL) { + /* no loudnessInfoSet contained. Clear the loudnessInfoSet struct by feeding + * an empty config extension */ + ErrorStatus = (TRANSPORTDEC_ERROR)cb->cbUniDrc( + cb->cbUniDrcData, NULL, 0, 1 /* loudnessInfoSet */, tmp_subStreamIndex, + 0, tmp_aot); + if (ErrorStatus != TRANSPORTDEC_OK) { + return ErrorStatus; + } + } + return ErrorStatus; } @@ -1696,6 +1859,8 @@ static TRANSPORTDEC_ERROR UsacRsv60DecoderConfig_Parse( int channelElementIdx = 0; /* index for elements which contain audio channels (sce, cpe, lfe) */ SC_CHANNEL_CONFIG sc_chan_config = {0, 0, 0, 0}; + int uniDrcElement = + -1; /* index of uniDrc extension element. -1 if not contained. */ numberOfElements = (int)escapedValue(hBs, 4, 8, 16) + 1; usc->m_usacNumElements = numberOfElements; @@ -1826,6 +1991,8 @@ static TRANSPORTDEC_ERROR UsacRsv60DecoderConfig_Parse( /* Mps212Config() ISO/IEC FDIS 23003-3 */ if (cb->cbSsc(cb->cbSscData, hBs, asc->m_aot, asc->m_extensionSamplingFrequency, samplesPerFrame, + 1, /* only downmix channels (residual channels are + not counted) */ usc->element[i].m_stereoConfigIndex, usc->m_coreSbrFrameLengthIndex, 0, /* don't know the length */ @@ -1869,6 +2036,10 @@ static TRANSPORTDEC_ERROR UsacRsv60DecoderConfig_Parse( case ID_USAC_EXT: ErrorStatus = extElementConfig(&usc->element[i].extElement, hBs, cb, 0, asc->m_samplesPerFrame, 0, asc->m_aot); + if (usc->element[i].extElement.usacExtElementType == + ID_EXT_ELE_UNI_DRC) { + uniDrcElement = i; + } if (ErrorStatus) { return ErrorStatus; @@ -1897,6 +2068,18 @@ static TRANSPORTDEC_ERROR UsacRsv60DecoderConfig_Parse( } } + if (uniDrcElement == -1 && cb->cbUniDrc != NULL) { + /* no uniDrcConfig contained. Clear the uniDrcConfig struct by feeding an + * empty extension element */ + int subStreamIndex = 0; + ErrorStatus = (TRANSPORTDEC_ERROR)cb->cbUniDrc( + cb->cbUniDrcData, NULL, 0, 0 /* uniDrcConfig */, subStreamIndex, 0, + asc->m_aot); + if (ErrorStatus != TRANSPORTDEC_OK) { + return ErrorStatus; + } + } + return ErrorStatus; } @@ -1983,6 +2166,14 @@ static TRANSPORTDEC_ERROR UsacConfig_Parse(CSAudioSpecificConfig *asc, if (err != TRANSPORTDEC_OK) { return err; } + } else if (cb->cbUniDrc != NULL) { + /* no loudnessInfoSet contained. Clear the loudnessInfoSet struct by feeding + * an empty config extension */ + err = (TRANSPORTDEC_ERROR)cb->cbUniDrc( + cb->cbUniDrcData, NULL, 0, 1 /* loudnessInfoSet */, 0, 0, asc->m_aot); + if (err != TRANSPORTDEC_OK) { + return err; + } } /* sanity check whether number of channels signaled in UsacDecoderConfig() @@ -1995,9 +2186,11 @@ static TRANSPORTDEC_ERROR UsacConfig_Parse(CSAudioSpecificConfig *asc, /* Copy UsacConfig() to asc->m_sc.m_usacConfig.UsacConfig[] buffer. */ INT configSize_bits = (INT)FDKgetValidBits(hBs) - nbits; - StoreConfigAsBitstream(hBs, configSize_bits, - asc->m_sc.m_usacConfig.UsacConfig, - TP_USAC_MAX_CONFIG_LEN); + if (StoreConfigAsBitstream(hBs, configSize_bits, + asc->m_sc.m_usacConfig.UsacConfig, + TP_USAC_MAX_CONFIG_LEN)) { + return TRANSPORTDEC_PARSE_ERROR; + } asc->m_sc.m_usacConfig.UsacConfigBits = fAbs(configSize_bits); return err; @@ -2218,7 +2411,7 @@ TRANSPORTDEC_ERROR AudioSpecificConfig_Parse( case AOT_MPEGS: if (cb->cbSsc != NULL) { if (cb->cbSsc(cb->cbSscData, bs, self->m_aot, self->m_samplingFrequency, - self->m_samplesPerFrame, 1, + self->m_samplesPerFrame, self->m_channelConfiguration, 1, -1, /* nTimeSlots: read from bitstream */ 0, /* don't know the length */ self->configMode, &self->SacConfigChanged)) { @@ -2299,8 +2492,10 @@ TRANSPORTDEC_ERROR AudioSpecificConfig_Parse( /* Copy config() to asc->config[] buffer. */ if ((ErrorStatus == TRANSPORTDEC_OK) && (self->m_aot == AOT_USAC)) { INT configSize_bits = (INT)FDKgetValidBits(bs) - (INT)ascStartAnchor; - StoreConfigAsBitstream(bs, configSize_bits, self->config, - TP_USAC_MAX_CONFIG_LEN); + if (StoreConfigAsBitstream(bs, configSize_bits, self->config, + TP_USAC_MAX_CONFIG_LEN)) { + return TRANSPORTDEC_PARSE_ERROR; + } self->configBits = fAbs(configSize_bits); } @@ -2414,6 +2609,8 @@ static TRANSPORTDEC_ERROR Drm_xHEAACDecoderConfig( cb->cbSscData, hBs, AOT_DRM_USAC, /* syntax differs from MPEG Mps212Config() */ asc->m_extensionSamplingFrequency, samplesPerFrame, + 1, /* only downmix channels (residual channels are not + counted) */ usc->element[elemIdx].m_stereoConfigIndex, usc->m_coreSbrFrameLengthIndex, 0, /* don't know the length */ asc->configMode, &asc->SacConfigChanged); diff --git a/libMpegTPDec/src/tpdec_latm.cpp b/libMpegTPDec/src/tpdec_latm.cpp index 3b71db8..c32be54 100644 --- a/libMpegTPDec/src/tpdec_latm.cpp +++ b/libMpegTPDec/src/tpdec_latm.cpp @@ -1,7 +1,7 @@ /* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten +© Copyright 1995 - 2021 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. All rights reserved. 1. INTRODUCTION @@ -591,6 +591,18 @@ bail: return (ErrorStatus); } +static int CLatmDemux_ReadAuChunkLengthInfo(HANDLE_FDK_BITSTREAM bs) { + int len = 0, tmp = 255; + int validBytes = (int)FDKgetValidBits(bs) >> 3; + + while (tmp == 255 && validBytes-- > 0) { + tmp = (int)FDKreadBits(bs, 8); + len += tmp; + } + + return ((tmp == 255) ? -1 : (len << 3)); +} + TRANSPORTDEC_ERROR CLatmDemux_ReadPayloadLengthInfo(HANDLE_FDK_BITSTREAM bs, CLatmDemux *pLatmDemux) { TRANSPORTDEC_ERROR ErrorStatus = TRANSPORTDEC_OK; @@ -602,11 +614,17 @@ TRANSPORTDEC_ERROR CLatmDemux_ReadPayloadLengthInfo(HANDLE_FDK_BITSTREAM bs, FDK_ASSERT(pLatmDemux->m_numLayer[prog] <= LATM_MAX_LAYER); for (UINT lay = 0; lay < pLatmDemux->m_numLayer[prog]; lay++) { LATM_LAYER_INFO *p_linfo = &pLatmDemux->m_linfo[prog][lay]; + int auChunkLengthInfo = 0; switch (p_linfo->m_frameLengthType) { case 0: - p_linfo->m_frameLengthInBits = CLatmDemux_ReadAuChunkLengthInfo(bs); - totalPayloadBits += p_linfo->m_frameLengthInBits; + auChunkLengthInfo = CLatmDemux_ReadAuChunkLengthInfo(bs); + if (auChunkLengthInfo >= 0) { + p_linfo->m_frameLengthInBits = (UINT)auChunkLengthInfo; + totalPayloadBits += p_linfo->m_frameLengthInBits; + } else { + return TRANSPORTDEC_PARSE_ERROR; + } break; case 3: case 5: @@ -627,23 +645,6 @@ TRANSPORTDEC_ERROR CLatmDemux_ReadPayloadLengthInfo(HANDLE_FDK_BITSTREAM bs, return (ErrorStatus); } -int CLatmDemux_ReadAuChunkLengthInfo(HANDLE_FDK_BITSTREAM bs) { - UCHAR endFlag; - int len = 0; - - do { - UCHAR tmp = (UCHAR)FDKreadBits(bs, 8); - endFlag = (tmp < 255); - - len += tmp; - - } while (endFlag == 0); - - len <<= 3; /* convert from bytes to bits */ - - return len; -} - UINT CLatmDemux_GetFrameLengthInBits(CLatmDemux *pLatmDemux, const UINT prog, const UINT layer) { UINT nFrameLenBits = 0; diff --git a/libMpegTPDec/src/tpdec_latm.h b/libMpegTPDec/src/tpdec_latm.h index 6af553d..8b8c971 100644 --- a/libMpegTPDec/src/tpdec_latm.h +++ b/libMpegTPDec/src/tpdec_latm.h @@ -1,7 +1,7 @@ /* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2018 Fraunhofer-Gesellschaft zur Förderung der angewandten +© Copyright 1995 - 2021 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. All rights reserved. 1. INTRODUCTION @@ -151,8 +151,6 @@ typedef struct { AudioPreRoll */ } CLatmDemux; -int CLatmDemux_ReadAuChunkLengthInfo(HANDLE_FDK_BITSTREAM bs); - TRANSPORTDEC_ERROR CLatmDemux_Read(HANDLE_FDK_BITSTREAM bs, CLatmDemux *pLatmDemux, TRANSPORT_TYPE tt, CSTpCallBacks *pTpDecCallbacks, diff --git a/libMpegTPDec/src/tpdec_lib.cpp b/libMpegTPDec/src/tpdec_lib.cpp index 091d011..8cd9cb0 100644 --- a/libMpegTPDec/src/tpdec_lib.cpp +++ b/libMpegTPDec/src/tpdec_lib.cpp @@ -1,7 +1,7 @@ /* ----------------------------------------------------------------------------- Software License for The Fraunhofer FDK AAC Codec Library for Android -© Copyright 1995 - 2019 Fraunhofer-Gesellschaft zur Förderung der angewandten +© Copyright 1995 - 2022 Fraunhofer-Gesellschaft zur Förderung der angewandten Forschung e.V. All rights reserved. 1. INTRODUCTION @@ -351,6 +351,12 @@ TRANSPORTDEC_ERROR transportDec_OutOfBandConfig(HANDLE_TRANSPORTDEC hTp, } } } + + /* if an error is detected terminate config parsing to avoid that an invalid + * config is accepted in the second pass */ + if (err != TRANSPORTDEC_OK) { + break; + } } if (err == TRANSPORTDEC_OK && fConfigFound) { |