Skip to content

Commit

Permalink
ALAC : Improve input validation and error reporting.
Browse files Browse the repository at this point in the history
  • Loading branch information
erikd committed Feb 9, 2015
1 parent f4d42d7 commit b562efc
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 10 deletions.
8 changes: 8 additions & 0 deletions src/ALAC/ALACAudioTypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,14 @@ enum
kALAC_ParamError = -50,
kALAC_MemFullError = -108,
fALAC_FrameLengthError = -666,

/* Add for libsndfile */
kALAC_BadBitWidth = -0x100000,
kALAC_IncompatibleVersion = -0x100001,
kALAC_BadSpecificConfigSize = -0x100002,
kALAC_ZeroChannelCount = -0x100003,
kALAC_NumSamplesTooBig = -0x100004,
kALAC_UnsupportedElement = -0x100005,
} ;

enum
Expand Down
14 changes: 7 additions & 7 deletions src/ALAC/alac_decoder.c
Original file line number Diff line number Diff line change
Expand Up @@ -108,14 +108,14 @@ alac_decoder_init (ALAC_DECODER *p, void * inMagicCookie, uint32_t inMagicCookie
p->mConfig = theConfig ;
p->mNumChannels = theConfig.numChannels ;

RequireAction (p->mConfig.compatibleVersion <= kALACVersion, return kALAC_ParamError ;) ;

RequireAction (p->mConfig.compatibleVersion <= kALACVersion, return kALAC_IncompatibleVersion ;) ;
RequireAction ((p->mConfig.bitDepth >= 8 && p->mConfig.bitDepth <= 32), return kALAC_BadBitWidth ;) ;
RequireAction ((p->mMixBufferU != NULL) && (p->mMixBufferV != NULL) && (p->mPredictor != NULL),
status = kALAC_MemFullError ; goto Exit ;) ;
}
else
{
status = kALAC_ParamError ;
status = kALAC_BadSpecificConfigSize ;
}

// skip to Channel Layout Info
Expand Down Expand Up @@ -166,7 +166,7 @@ alac_decode (ALAC_DECODER *p, struct BitBuffer * bits, int32_t * sampleBuffer, u
uint32_t numChannels = p->mNumChannels ;

RequireAction ((bits != NULL) && (sampleBuffer != NULL) && (outNumSamples != NULL), return kALAC_ParamError ;) ;
RequireAction (p->mNumChannels > 0, return kALAC_ParamError ;) ;
RequireAction (p->mNumChannels > 0, return kALAC_ZeroChannelCount ;) ;

p->mActiveElements = 0 ;
channelIndex = 0 ;
Expand Down Expand Up @@ -217,7 +217,7 @@ alac_decode (ALAC_DECODER *p, struct BitBuffer * bits, int32_t * sampleBuffer, u
numSamples = BitBufferRead (bits, 16) << 16 ;
numSamples |= BitBufferRead (bits, 16) ;

RequireAction (numSamples < kALACDefaultFramesPerPacket, return kALAC_ParamError ;) ;
RequireAction (numSamples < kALACDefaultFramesPerPacket, return kALAC_NumSamplesTooBig ;) ;
}

if (escapeFlag == 0)
Expand Down Expand Up @@ -370,7 +370,7 @@ alac_decode (ALAC_DECODER *p, struct BitBuffer * bits, int32_t * sampleBuffer, u
numSamples = BitBufferRead (bits, 16) << 16 ;
numSamples |= BitBufferRead (bits, 16) ;

RequireAction (numSamples < kALACDefaultFramesPerPacket, return kALAC_ParamError ;) ;
RequireAction (numSamples < kALACDefaultFramesPerPacket, return kALAC_NumSamplesTooBig ;) ;
}

if (escapeFlag == 0)
Expand Down Expand Up @@ -527,7 +527,7 @@ alac_decode (ALAC_DECODER *p, struct BitBuffer * bits, int32_t * sampleBuffer, u
{
// unsupported element, bail
//AssertNoErr (tag) ;
status = kALAC_ParamError ;
status = kALAC_UnsupportedElement ;
break ;
}

Expand Down
41 changes: 38 additions & 3 deletions src/alac.c
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,8 @@ static PAKT_INFO * alac_pakt_append (PAKT_INFO * info, uint32_t value) ;
static uint8_t * alac_pakt_encode (const SF_PRIVATE *psf, uint32_t * pakt_size) ;
static sf_count_t alac_pakt_block_offset (const PAKT_INFO *info, uint32_t block) ;

static const char * alac_error_string (int error) ;

/*============================================================================================
** ALAC Reader initialisation function.
*/
Expand Down Expand Up @@ -233,6 +235,7 @@ static int
alac_reader_init (SF_PRIVATE *psf, const ALAC_DECODER_INFO * info)
{ ALAC_PRIVATE *plac ;
uint32_t kuki_size ;
int error ;
union { uint8_t kuki [512] ; uint32_t alignment ; } u ;

if (info == NULL)
Expand Down Expand Up @@ -264,7 +267,11 @@ alac_reader_init (SF_PRIVATE *psf, const ALAC_DECODER_INFO * info)
/* Read in the ALAC cookie data and pass it to the init function. */
kuki_size = alac_kuki_read (psf, info->kuki_offset, u.kuki, sizeof (u.kuki)) ;

alac_decoder_init (&plac->decoder, u.kuki, kuki_size) ;
if ((error = alac_decoder_init (&plac->decoder, u.kuki, kuki_size)) != ALAC_noErr)
{ psf_log_printf (psf, "*** alac_decoder_init() returned %s. ***\n", alac_error_string (error)) ;
return SFE_INTERNAL ;
} ;


if (plac->decoder.mNumChannels != (unsigned) psf->sf.channels)
{ psf_log_printf (psf, "*** Initialized decoder has %u channels, but it should be %d. ***\n", plac->decoder.mNumChannels, psf->sf.channels) ;
Expand Down Expand Up @@ -395,7 +402,7 @@ alac_reader_calc_frames (SF_PRIVATE *psf, ALAC_PRIVATE *plac)
static int
alac_decode_block (SF_PRIVATE *psf, ALAC_PRIVATE *plac)
{ ALAC_DECODER *pdec = &plac->decoder ;
uint8_t byte_buffer [ALAC_BYTE_BUFFER_SIZE] ;
uint8_t byte_buffer [psf->sf.channels * ALAC_BYTE_BUFFER_SIZE] ;
uint32_t packet_size ;
BitBuffer bit_buffer ;

Expand All @@ -408,7 +415,7 @@ alac_decode_block (SF_PRIVATE *psf, ALAC_PRIVATE *plac)

psf_fseek (psf, plac->input_data_pos, SEEK_SET) ;

if (packet_size > SIGNED_SIZEOF (byte_buffer))
if (packet_size > sizeof (byte_buffer))
{ psf_log_printf (psf, "%s : bad packet_size (%u)\n", __func__, packet_size) ;
return 0 ;
} ;
Expand Down Expand Up @@ -958,3 +965,31 @@ alac_kuki_read (SF_PRIVATE * psf, uint32_t kuki_offset, uint8_t * kuki, size_t k

return kuki_size ;
} /* alac_kuki_read */

#define CASE_NAME(x) case x : return #x ; break ;

static const char *
alac_error_string (int error)
{ static char errstr [128] ;
switch (error)
{ CASE_NAME (kALAC_UnimplementedError) ;
CASE_NAME (kALAC_FileNotFoundError) ;
CASE_NAME (kALAC_ParamError) ;
CASE_NAME (kALAC_MemFullError) ;
CASE_NAME (fALAC_FrameLengthError) ;

/* Added for libsndfile */
CASE_NAME (kALAC_BadBitWidth) ;
CASE_NAME (kALAC_IncompatibleVersion) ;
CASE_NAME (kALAC_BadSpecificConfigSize) ;
CASE_NAME (kALAC_ZeroChannelCount) ;
CASE_NAME (kALAC_NumSamplesTooBig) ;
CASE_NAME (kALAC_UnsupportedElement) ;
default :
break ;
} ;

snprintf (errstr, sizeof (errstr), "Unknown error %d", error) ;
return errstr ;
} /* alac_error_string */

0 comments on commit b562efc

Please sign in to comment.