[FFmpeg-devel,1/7] avutil: add FF_BAIL_ON_OVERFLOW

Submitted by Andreas Cadhalpun on Dec. 16, 2016, 2:32 a.m.

Details

Message ID 9663f686-48d6-0d43-ce9b-848b467366be@googlemail.com
State New
Headers show

Commit Message

Andreas Cadhalpun Dec. 16, 2016, 2:32 a.m.
Suggested-by: Rodger Combs <rodger.combs@gmail.com>
Signed-off-by: Andreas Cadhalpun <Andreas.Cadhalpun@googlemail.com>
---
 libavutil/common.h | 2 ++
 1 file changed, 2 insertions(+)

Comments

Muhammad Faiz Dec. 16, 2016, 6:36 a.m.
On 12/16/16, Andreas Cadhalpun <andreas.cadhalpun@googlemail.com> wrote:
> Suggested-by: Rodger Combs <rodger.combs@gmail.com>
> Signed-off-by: Andreas Cadhalpun <Andreas.Cadhalpun@googlemail.com>
> ---
>  libavutil/common.h | 2 ++
>  1 file changed, 2 insertions(+)
>
> diff --git a/libavutil/common.h b/libavutil/common.h
> index 8142b31..00b7504 100644
> --- a/libavutil/common.h
> +++ b/libavutil/common.h
> @@ -99,6 +99,8 @@
>  #define FFSWAP(type,a,b) do{type SWAP_tmp= b; b= a; a= SWAP_tmp;}while(0)
>  #define FF_ARRAY_ELEMS(a) (sizeof(a) / sizeof((a)[0]))
>
> +#define FF_BAIL_ON_OVERFLOW(ctx, x) if (x) {av_log(ctx, AV_LOG_ERROR,
> "Overflow check failed: " #x"\n"); return AVERROR_INVALIDDATA;}

Where is the overflow check calculation?
What about functions that need clean up with goto before return?
wm4 Dec. 16, 2016, 4:22 p.m.
On Fri, 16 Dec 2016 03:32:07 +0100
Andreas Cadhalpun <andreas.cadhalpun@googlemail.com> wrote:

> Suggested-by: Rodger Combs <rodger.combs@gmail.com>
> Signed-off-by: Andreas Cadhalpun <Andreas.Cadhalpun@googlemail.com>
> ---
>  libavutil/common.h | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/libavutil/common.h b/libavutil/common.h
> index 8142b31..00b7504 100644
> --- a/libavutil/common.h
> +++ b/libavutil/common.h
> @@ -99,6 +99,8 @@
>  #define FFSWAP(type,a,b) do{type SWAP_tmp= b; b= a; a= SWAP_tmp;}while(0)
>  #define FF_ARRAY_ELEMS(a) (sizeof(a) / sizeof((a)[0]))
>  
> +#define FF_BAIL_ON_OVERFLOW(ctx, x) if (x) {av_log(ctx, AV_LOG_ERROR, "Overflow check failed: " #x"\n"); return AVERROR_INVALIDDATA;}
> +
>  /* misc math functions */
>  
>  #ifdef HAVE_AV_CONFIG_H

Are you sure we need the message? It's quite ugly. Also maybe call it
"FF_RETURN_ON_OVERFLOW".

(This macros reminds me a lot of glib assertions. In a bad way.)
wm4 Dec. 16, 2016, 4:25 p.m.
On Fri, 16 Dec 2016 13:36:09 +0700
Muhammad Faiz <mfcc64@gmail.com> wrote:

> On 12/16/16, Andreas Cadhalpun <andreas.cadhalpun@googlemail.com> wrote:
> > Suggested-by: Rodger Combs <rodger.combs@gmail.com>
> > Signed-off-by: Andreas Cadhalpun <Andreas.Cadhalpun@googlemail.com>
> > ---
> >  libavutil/common.h | 2 ++
> >  1 file changed, 2 insertions(+)
> >
> > diff --git a/libavutil/common.h b/libavutil/common.h
> > index 8142b31..00b7504 100644
> > --- a/libavutil/common.h
> > +++ b/libavutil/common.h
> > @@ -99,6 +99,8 @@
> >  #define FFSWAP(type,a,b) do{type SWAP_tmp= b; b= a; a= SWAP_tmp;}while(0)
> >  #define FF_ARRAY_ELEMS(a) (sizeof(a) / sizeof((a)[0]))
> >
> > +#define FF_BAIL_ON_OVERFLOW(ctx, x) if (x) {av_log(ctx, AV_LOG_ERROR,
> > "Overflow check failed: " #x"\n"); return AVERROR_INVALIDDATA;}  
> 
> Where is the overflow check calculation?
> What about functions that need clean up with goto before return?

The whole thing is in "x". Having overflow-safe primitives for each
operation would probably be nicer.
Andreas Cadhalpun Dec. 19, 2016, 10:32 p.m.
On 16.12.2016 07:36, Muhammad Faiz wrote:
> On 12/16/16, Andreas Cadhalpun <andreas.cadhalpun@googlemail.com> wrote:
>> Suggested-by: Rodger Combs <rodger.combs@gmail.com>
>> Signed-off-by: Andreas Cadhalpun <Andreas.Cadhalpun@googlemail.com>
>> ---
>>  libavutil/common.h | 2 ++
>>  1 file changed, 2 insertions(+)
>>
>> diff --git a/libavutil/common.h b/libavutil/common.h
>> index 8142b31..00b7504 100644
>> --- a/libavutil/common.h
>> +++ b/libavutil/common.h
>> @@ -99,6 +99,8 @@
>>  #define FFSWAP(type,a,b) do{type SWAP_tmp= b; b= a; a= SWAP_tmp;}while(0)
>>  #define FF_ARRAY_ELEMS(a) (sizeof(a) / sizeof((a)[0]))
>>
>> +#define FF_BAIL_ON_OVERFLOW(ctx, x) if (x) {av_log(ctx, AV_LOG_ERROR,
>> "Overflow check failed: " #x"\n"); return AVERROR_INVALIDDATA;}
> 
> Where is the overflow check calculation?

The parameter 'x' is the overflow check used in 'if (x)'.

> What about functions that need clean up with goto before return?

This is only needed rarely, e.g. in none of the patches I sent.
It happens occasionally for the more common checks needed to
validate codec parameters that I'm working on, but these can be
handled on a case by case basis.
The general macros are only for the common, trivial cases.

Best regards,
Andreas
Andreas Cadhalpun Dec. 19, 2016, 10:36 p.m.
On 16.12.2016 17:22, wm4 wrote:
> On Fri, 16 Dec 2016 03:32:07 +0100
> Andreas Cadhalpun <andreas.cadhalpun@googlemail.com> wrote:
> 
>> Suggested-by: Rodger Combs <rodger.combs@gmail.com>
>> Signed-off-by: Andreas Cadhalpun <Andreas.Cadhalpun@googlemail.com>
>> ---
>>  libavutil/common.h | 2 ++
>>  1 file changed, 2 insertions(+)
>>
>> diff --git a/libavutil/common.h b/libavutil/common.h
>> index 8142b31..00b7504 100644
>> --- a/libavutil/common.h
>> +++ b/libavutil/common.h
>> @@ -99,6 +99,8 @@
>>  #define FFSWAP(type,a,b) do{type SWAP_tmp= b; b= a; a= SWAP_tmp;}while(0)
>>  #define FF_ARRAY_ELEMS(a) (sizeof(a) / sizeof((a)[0]))
>>  
>> +#define FF_BAIL_ON_OVERFLOW(ctx, x) if (x) {av_log(ctx, AV_LOG_ERROR, "Overflow check failed: " #x"\n"); return AVERROR_INVALIDDATA;}
>> +
>>  /* misc math functions */
>>  
>>  #ifdef HAVE_AV_CONFIG_H
> 
> Are you sure we need the message?

Yes, since such an overflow could just be a sign of a limitation in our
framework (think of bit_rate being int32_t) and does not necessarily mean
that the sample is invalid.

> It's quite ugly.

Do you have any suggestions for improving it?

> Also maybe call it "FF_RETURN_ON_OVERFLOW".

That sounds a bit better, so changed locally.

Best regards,
Andreas
Muhammad Faiz Dec. 20, 2016, 9:23 a.m.
On 12/20/16, Andreas Cadhalpun <andreas.cadhalpun@googlemail.com> wrote:
> On 16.12.2016 07:36, Muhammad Faiz wrote:
>> On 12/16/16, Andreas Cadhalpun <andreas.cadhalpun@googlemail.com> wrote:
>>> Suggested-by: Rodger Combs <rodger.combs@gmail.com>
>>> Signed-off-by: Andreas Cadhalpun <Andreas.Cadhalpun@googlemail.com>
>>> ---
>>>  libavutil/common.h | 2 ++
>>>  1 file changed, 2 insertions(+)
>>>
>>> diff --git a/libavutil/common.h b/libavutil/common.h
>>> index 8142b31..00b7504 100644
>>> --- a/libavutil/common.h
>>> +++ b/libavutil/common.h
>>> @@ -99,6 +99,8 @@
>>>  #define FFSWAP(type,a,b) do{type SWAP_tmp= b; b= a; a=
>>> SWAP_tmp;}while(0)
>>>  #define FF_ARRAY_ELEMS(a) (sizeof(a) / sizeof((a)[0]))
>>>
>>> +#define FF_BAIL_ON_OVERFLOW(ctx, x) if (x) {av_log(ctx, AV_LOG_ERROR,
>>> "Overflow check failed: " #x"\n"); return AVERROR_INVALIDDATA;}
>>
>> Where is the overflow check calculation?
>
> The parameter 'x' is the overflow check used in 'if (x)'.

Is it impossible to do something like
int ff_mul_check_overflow(int *result, int a, int b)
with AVERROR return code on overlow?
I suggest this is AVERROR(ERANGE)

>
>> What about functions that need clean up with goto before return?
>
> This is only needed rarely, e.g. in none of the patches I sent.
> It happens occasionally for the more common checks needed to
> validate codec parameters that I'm working on, but these can be
> handled on a case by case basis.
> The general macros are only for the common, trivial cases.

I think if macro for very specific case exists, the generic ones
should also exist,
especially generic error handling. Probably, I'm going to post that.

Thank's.

>
> Best regards,
> Andreas
>
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>
wm4 Dec. 20, 2016, 2:22 p.m.
On Mon, 19 Dec 2016 23:36:11 +0100
Andreas Cadhalpun <andreas.cadhalpun@googlemail.com> wrote:

> On 16.12.2016 17:22, wm4 wrote:
> > On Fri, 16 Dec 2016 03:32:07 +0100
> > Andreas Cadhalpun <andreas.cadhalpun@googlemail.com> wrote:
> >   
> >> Suggested-by: Rodger Combs <rodger.combs@gmail.com>
> >> Signed-off-by: Andreas Cadhalpun <Andreas.Cadhalpun@googlemail.com>
> >> ---
> >>  libavutil/common.h | 2 ++
> >>  1 file changed, 2 insertions(+)
> >>
> >> diff --git a/libavutil/common.h b/libavutil/common.h
> >> index 8142b31..00b7504 100644
> >> --- a/libavutil/common.h
> >> +++ b/libavutil/common.h
> >> @@ -99,6 +99,8 @@
> >>  #define FFSWAP(type,a,b) do{type SWAP_tmp= b; b= a; a= SWAP_tmp;}while(0)
> >>  #define FF_ARRAY_ELEMS(a) (sizeof(a) / sizeof((a)[0]))
> >>  
> >> +#define FF_BAIL_ON_OVERFLOW(ctx, x) if (x) {av_log(ctx, AV_LOG_ERROR, "Overflow check failed: " #x"\n"); return AVERROR_INVALIDDATA;}
> >> +
> >>  /* misc math functions */
> >>  
> >>  #ifdef HAVE_AV_CONFIG_H  
> > 
> > Are you sure we need the message?  
> 
> Yes, since such an overflow could just be a sign of a limitation in our
> framework (think of bit_rate being int32_t) and does not necessarily mean
> that the sample is invalid.
> 
> > It's quite ugly.  
> 
> Do you have any suggestions for improving it?

I'm pretty much against such macros for rather specific use-cases, and
putting them into a public headers. I'm thinking it'd be better to
actually provide overflow-checking primitives, and I also don't think
every overflow has to be logged. Almost all of these cases happen only
when fuzzing anyway.

> 
> > Also maybe call it "FF_RETURN_ON_OVERFLOW".  
> 
> That sounds a bit better, so changed locally.
Paul B Mahol Dec. 20, 2016, 2:33 p.m.
On 12/20/16, wm4 <nfxjfg@googlemail.com> wrote:
> On Mon, 19 Dec 2016 23:36:11 +0100
> Andreas Cadhalpun <andreas.cadhalpun@googlemail.com> wrote:
>
>> On 16.12.2016 17:22, wm4 wrote:
>> > On Fri, 16 Dec 2016 03:32:07 +0100
>> > Andreas Cadhalpun <andreas.cadhalpun@googlemail.com> wrote:
>> >
>> >> Suggested-by: Rodger Combs <rodger.combs@gmail.com>
>> >> Signed-off-by: Andreas Cadhalpun <Andreas.Cadhalpun@googlemail.com>
>> >> ---
>> >>  libavutil/common.h | 2 ++
>> >>  1 file changed, 2 insertions(+)
>> >>
>> >> diff --git a/libavutil/common.h b/libavutil/common.h
>> >> index 8142b31..00b7504 100644
>> >> --- a/libavutil/common.h
>> >> +++ b/libavutil/common.h
>> >> @@ -99,6 +99,8 @@
>> >>  #define FFSWAP(type,a,b) do{type SWAP_tmp= b; b= a; a=
>> >> SWAP_tmp;}while(0)
>> >>  #define FF_ARRAY_ELEMS(a) (sizeof(a) / sizeof((a)[0]))
>> >>
>> >> +#define FF_BAIL_ON_OVERFLOW(ctx, x) if (x) {av_log(ctx, AV_LOG_ERROR,
>> >> "Overflow check failed: " #x"\n"); return AVERROR_INVALIDDATA;}
>> >> +
>> >>  /* misc math functions */
>> >>
>> >>  #ifdef HAVE_AV_CONFIG_H
>> >
>> > Are you sure we need the message?
>>
>> Yes, since such an overflow could just be a sign of a limitation in our
>> framework (think of bit_rate being int32_t) and does not necessarily mean
>> that the sample is invalid.
>>
>> > It's quite ugly.
>>
>> Do you have any suggestions for improving it?
>
> I'm pretty much against such macros for rather specific use-cases, and
> putting them into a public headers. I'm thinking it'd be better to
> actually provide overflow-checking primitives, and I also don't think
> every overflow has to be logged. Almost all of these cases happen only
> when fuzzing anyway.

Yes, if one wants logs let them compile with sanitizer options.
Andreas Cadhalpun Dec. 21, 2016, 12:38 a.m.
On 20.12.2016 10:23, Muhammad Faiz wrote:
> On 12/20/16, Andreas Cadhalpun <andreas.cadhalpun@googlemail.com> wrote:
>> On 16.12.2016 07:36, Muhammad Faiz wrote:
>>> On 12/16/16, Andreas Cadhalpun <andreas.cadhalpun@googlemail.com> wrote:
>>>> Suggested-by: Rodger Combs <rodger.combs@gmail.com>
>>>> Signed-off-by: Andreas Cadhalpun <Andreas.Cadhalpun@googlemail.com>
>>>> ---
>>>>  libavutil/common.h | 2 ++
>>>>  1 file changed, 2 insertions(+)
>>>>
>>>> diff --git a/libavutil/common.h b/libavutil/common.h
>>>> index 8142b31..00b7504 100644
>>>> --- a/libavutil/common.h
>>>> +++ b/libavutil/common.h
>>>> @@ -99,6 +99,8 @@
>>>>  #define FFSWAP(type,a,b) do{type SWAP_tmp= b; b= a; a=
>>>> SWAP_tmp;}while(0)
>>>>  #define FF_ARRAY_ELEMS(a) (sizeof(a) / sizeof((a)[0]))
>>>>
>>>> +#define FF_BAIL_ON_OVERFLOW(ctx, x) if (x) {av_log(ctx, AV_LOG_ERROR,
>>>> "Overflow check failed: " #x"\n"); return AVERROR_INVALIDDATA;}
>>>
>>> Where is the overflow check calculation?
>>
>> The parameter 'x' is the overflow check used in 'if (x)'.
> 
> Is it impossible to do something like
> int ff_mul_check_overflow(int *result, int a, int b)
> with AVERROR return code on overlow?

Not really, as the point of the macro is to do the error handling,
which would be needed for a function. Also the function is not
generic enough, as the type can be int64_t. And then using such
a function would make the code rather less readable.

> I suggest this is AVERROR(ERANGE)

This seems like a better fit for the error type, so I've locally
change the error in the macro to this.

Best regards,
Andreas
Andreas Cadhalpun Dec. 21, 2016, 12:43 a.m.
On 20.12.2016 15:22, wm4 wrote:
> On Mon, 19 Dec 2016 23:36:11 +0100
> Andreas Cadhalpun <andreas.cadhalpun@googlemail.com> wrote:
> 
>> On 16.12.2016 17:22, wm4 wrote:
>>> On Fri, 16 Dec 2016 03:32:07 +0100
>>> Andreas Cadhalpun <andreas.cadhalpun@googlemail.com> wrote:
>>>   
>>>> Suggested-by: Rodger Combs <rodger.combs@gmail.com>
>>>> Signed-off-by: Andreas Cadhalpun <Andreas.Cadhalpun@googlemail.com>
>>>> ---
>>>>  libavutil/common.h | 2 ++
>>>>  1 file changed, 2 insertions(+)
>>>>
>>>> diff --git a/libavutil/common.h b/libavutil/common.h
>>>> index 8142b31..00b7504 100644
>>>> --- a/libavutil/common.h
>>>> +++ b/libavutil/common.h
>>>> @@ -99,6 +99,8 @@
>>>>  #define FFSWAP(type,a,b) do{type SWAP_tmp= b; b= a; a= SWAP_tmp;}while(0)
>>>>  #define FF_ARRAY_ELEMS(a) (sizeof(a) / sizeof((a)[0]))
>>>>  
>>>> +#define FF_BAIL_ON_OVERFLOW(ctx, x) if (x) {av_log(ctx, AV_LOG_ERROR, "Overflow check failed: " #x"\n"); return AVERROR_INVALIDDATA;}
>>>> +
>>>>  /* misc math functions */
>>>>  
>>>>  #ifdef HAVE_AV_CONFIG_H  
>>>
>>> Are you sure we need the message?  
>>
>> Yes, since such an overflow could just be a sign of a limitation in our
>> framework (think of bit_rate being int32_t) and does not necessarily mean
>> that the sample is invalid.
>>
>>> It's quite ugly.  
>>
>> Do you have any suggestions for improving it?
> 
> I'm pretty much against such macros for rather specific use-cases, and
> putting them into a public headers.

It is added to an "internal and external API header".
Feel free to send patches separating it into an internal and a public header.

> I'm thinking it'd be better to actually provide overflow-checking primitives,

Why?

> and I also don't think every overflow has to be logged.

I disagree for the reason I mentioned above.

Best regards,
Andreas
wm4 Dec. 21, 2016, 12:46 p.m.
On Wed, 21 Dec 2016 01:43:46 +0100
Andreas Cadhalpun <andreas.cadhalpun@googlemail.com> wrote:

> On 20.12.2016 15:22, wm4 wrote:
> > On Mon, 19 Dec 2016 23:36:11 +0100
> > Andreas Cadhalpun <andreas.cadhalpun@googlemail.com> wrote:
> >   
> >> On 16.12.2016 17:22, wm4 wrote:  
> >>> On Fri, 16 Dec 2016 03:32:07 +0100
> >>> Andreas Cadhalpun <andreas.cadhalpun@googlemail.com> wrote:
> >>>     
> >>>> Suggested-by: Rodger Combs <rodger.combs@gmail.com>
> >>>> Signed-off-by: Andreas Cadhalpun <Andreas.Cadhalpun@googlemail.com>
> >>>> ---
> >>>>  libavutil/common.h | 2 ++
> >>>>  1 file changed, 2 insertions(+)
> >>>>
> >>>> diff --git a/libavutil/common.h b/libavutil/common.h
> >>>> index 8142b31..00b7504 100644
> >>>> --- a/libavutil/common.h
> >>>> +++ b/libavutil/common.h
> >>>> @@ -99,6 +99,8 @@
> >>>>  #define FFSWAP(type,a,b) do{type SWAP_tmp= b; b= a; a= SWAP_tmp;}while(0)
> >>>>  #define FF_ARRAY_ELEMS(a) (sizeof(a) / sizeof((a)[0]))
> >>>>  
> >>>> +#define FF_BAIL_ON_OVERFLOW(ctx, x) if (x) {av_log(ctx, AV_LOG_ERROR, "Overflow check failed: " #x"\n"); return AVERROR_INVALIDDATA;}
> >>>> +
> >>>>  /* misc math functions */
> >>>>  
> >>>>  #ifdef HAVE_AV_CONFIG_H    
> >>>
> >>> Are you sure we need the message?    
> >>
> >> Yes, since such an overflow could just be a sign of a limitation in our
> >> framework (think of bit_rate being int32_t) and does not necessarily mean
> >> that the sample is invalid.
> >>  
> >>> It's quite ugly.    
> >>
> >> Do you have any suggestions for improving it?  
> > 
> > I'm pretty much against such macros for rather specific use-cases, and
> > putting them into a public headers.  
> 
> It is added to an "internal and external API header".
> Feel free to send patches separating it into an internal and a public header.

Macros starting with FF are public API, so don't put that macro in a
public header. Or we're stuck with it forever.

> > I'm thinking it'd be better to actually provide overflow-checking primitives,  
> 
> Why?

Because that would have actual value, since overflowing checks are
annoying and there's also a chance to get them wrong. The code gets
less ugly too. If you're going to add such overflow checks to every
single operation in libavcodec that could overflow, you better come up
with something that won't add tons of crap to the code.

> > and I also don't think every overflow has to be logged.  
> 
> I disagree for the reason I mentioned above.

Which was? Not going to read the whole thread again.
Muhammad Faiz Dec. 22, 2016, 9:21 a.m.
On 12/21/16, Andreas Cadhalpun <andreas.cadhalpun@googlemail.com> wrote:
> On 20.12.2016 10:23, Muhammad Faiz wrote:
>> On 12/20/16, Andreas Cadhalpun <andreas.cadhalpun@googlemail.com> wrote:
>>> On 16.12.2016 07:36, Muhammad Faiz wrote:
>>>> On 12/16/16, Andreas Cadhalpun <andreas.cadhalpun@googlemail.com> wrote:
>>>>> Suggested-by: Rodger Combs <rodger.combs@gmail.com>
>>>>> Signed-off-by: Andreas Cadhalpun <Andreas.Cadhalpun@googlemail.com>
>>>>> ---
>>>>>  libavutil/common.h | 2 ++
>>>>>  1 file changed, 2 insertions(+)
>>>>>
>>>>> diff --git a/libavutil/common.h b/libavutil/common.h
>>>>> index 8142b31..00b7504 100644
>>>>> --- a/libavutil/common.h
>>>>> +++ b/libavutil/common.h
>>>>> @@ -99,6 +99,8 @@
>>>>>  #define FFSWAP(type,a,b) do{type SWAP_tmp= b; b= a; a=
>>>>> SWAP_tmp;}while(0)
>>>>>  #define FF_ARRAY_ELEMS(a) (sizeof(a) / sizeof((a)[0]))
>>>>>
>>>>> +#define FF_BAIL_ON_OVERFLOW(ctx, x) if (x) {av_log(ctx, AV_LOG_ERROR,
>>>>> "Overflow check failed: " #x"\n"); return AVERROR_INVALIDDATA;}
>>>>
>>>> Where is the overflow check calculation?
>>>
>>> The parameter 'x' is the overflow check used in 'if (x)'.
>>
>> Is it impossible to do something like
>> int ff_mul_check_overflow(int *result, int a, int b)
>> with AVERROR return code on overlow?
>
> Not really, as the point of the macro is to do the error handling,
> which would be needed for a function. Also the function is not
> generic enough, as the type can be int64_t. And then using such
> a function would make the code rather less readable.

Probably provide both ff_mul_ and ff_mul64_ like av_clip/av_clip64
Andreas Cadhalpun Dec. 22, 2016, 11:52 p.m.
On 21.12.2016 13:46, wm4 wrote:
> On Wed, 21 Dec 2016 01:43:46 +0100
> Andreas Cadhalpun <andreas.cadhalpun@googlemail.com> wrote:
>> On 20.12.2016 15:22, wm4 wrote:
>>> On Mon, 19 Dec 2016 23:36:11 +0100
>>> Andreas Cadhalpun <andreas.cadhalpun@googlemail.com> wrote:
>>>> On 16.12.2016 17:22, wm4 wrote:  
>>>>> Are you sure we need the message?    
>>>>
>>>> Yes, since such an overflow could just be a sign of a limitation in our
>>>> framework (think of bit_rate being int32_t) and does not necessarily mean
>>>> that the sample is invalid.
>>>>  
>>>>> It's quite ugly.    
>>>>
>>>> Do you have any suggestions for improving it?  
>>>
>>> I'm pretty much against such macros for rather specific use-cases, and
>>> putting them into a public headers.  
>>
>> It is added to an "internal and external API header".
>> Feel free to send patches separating it into an internal and a public header.
> 
> Macros starting with FF are public API,

No, public macros start with AV.

> so don't put that macro in a public header. Or we're stuck with it forever.
> 
>>> I'm thinking it'd be better to actually provide overflow-checking primitives,  
>>
>> Why?
> 
> Because that would have actual value,

That's a meaningless argument.

> since overflowing checks are annoying

Using overflow-checking primitives is even more annoying.

> and there's also a chance to get them wrong.

That's always the case with anything.

> The code gets less ugly too.

Rather the contrary. Compare
        FF_RETURN_ON_OVERFLOW(s, ea->bytes > INT_MAX / 8 / 2)
        st->codecpar->bits_per_coded_sample = ea->bytes * 8;
        st->codecpar->bit_rate              = (int64_t)st->codecpar->channels *
                                              st->codecpar->sample_rate *
                                              st->codecpar->bits_per_coded_sample / 4;
        st->codecpar->block_align           = st->codecpar->channels *
                                              st->codecpar->bits_per_coded_sample;
with:
        ret = ff_mul_check_overflow(&st->codecpar->bits_per_coded_sample, ea->bytes, 8)
        if (ret < 0)
            return ret;
        st->codecpar->bit_rate              = (int64_t)st->codecpar->channels *
                                              st->codecpar->sample_rate *
                                              st->codecpar->bits_per_coded_sample / 4;
        ret = ff_mul_check_overflow(&st->codecpar->block_align, st->codecpar->channels, st->codecpar->bits_per_coded_sample)
        if (ret < 0)
            return ret;

> If you're going to add such overflow checks to every
> single operation in libavcodec that could overflow, you better come up
> with something that won't add tons of crap to the code.

Code that overflows is "crap", not the checks preventing that.

>>> and I also don't think every overflow has to be logged.  
>>
>> I disagree for the reason I mentioned above.
> 
> Which was? Not going to read the whole thread again.

Reading either of the mails you replied to would have been sufficient.
You've got a third chance with this mail.

Best regards,
Andreas

Patch hide | download patch | download mbox

diff --git a/libavutil/common.h b/libavutil/common.h
index 8142b31..00b7504 100644
--- a/libavutil/common.h
+++ b/libavutil/common.h
@@ -99,6 +99,8 @@ 
 #define FFSWAP(type,a,b) do{type SWAP_tmp= b; b= a; a= SWAP_tmp;}while(0)
 #define FF_ARRAY_ELEMS(a) (sizeof(a) / sizeof((a)[0]))
 
+#define FF_BAIL_ON_OVERFLOW(ctx, x) if (x) {av_log(ctx, AV_LOG_ERROR, "Overflow check failed: " #x"\n"); return AVERROR_INVALIDDATA;}
+
 /* misc math functions */
 
 #ifdef HAVE_AV_CONFIG_H