[FFmpeg-devel] [PATCH 2/2] all: use FFDIFFSIGN to resolve possible undefined behavior in comparators
Ganesh Ajjanagadde
gajjanagadde at gmail.com
Sun Nov 1 18:19:48 CET 2015
FFDIFFSIGN was created explicitly for this purpose, since the common
return a - b idiom is unsafe regarding overflow on signed integers. It
optimizes to branchless code on common compilers.
FFDIFFSIGN also has the subjective benefit of being easier to read due
to lack of ternary operators.
Tested with FATE.
--------------------------------------------------------------------------------
Things not covered by this are unsigned integers, for which overflows
are well defined, and also places where overflow is clearly impossible,
e.g an instance where the a - b was being done on 24 bit values.
I can convert some of these to FFDIFFSIGN if people find it a
readability improvement.
Signed-off-by: Ganesh Ajjanagadde <gajjanagadde at gmail.com>
---
cmdutils.c | 2 +-
cmdutils_opencl.c | 2 +-
ffmpeg.c | 3 +--
libavcodec/aacsbr_template.c | 2 +-
libavcodec/motion_est.c | 2 +-
libavfilter/f_sendcmd.c | 8 +++-----
libavfilter/vf_deshake.c | 3 +--
libavfilter/vf_palettegen.c | 2 +-
libavfilter/vf_removegrain.c | 5 +----
libavformat/subtitles.c | 9 +++------
libswresample/swresample-test.c | 2 +-
11 files changed, 15 insertions(+), 25 deletions(-)
diff --git a/cmdutils.c b/cmdutils.c
index e3e9891..41daa95 100644
--- a/cmdutils.c
+++ b/cmdutils.c
@@ -1421,7 +1421,7 @@ static int compare_codec_desc(const void *a, const void *b)
const AVCodecDescriptor * const *da = a;
const AVCodecDescriptor * const *db = b;
- return (*da)->type != (*db)->type ? (*da)->type - (*db)->type :
+ return (*da)->type != (*db)->type ? FFDIFFSIGN((*da)->type, (*db)->type) :
strcmp((*da)->name, (*db)->name);
}
diff --git a/cmdutils_opencl.c b/cmdutils_opencl.c
index d9095b6..5621ebc 100644
--- a/cmdutils_opencl.c
+++ b/cmdutils_opencl.c
@@ -206,7 +206,7 @@ end:
static int compare_ocl_device_desc(const void *a, const void *b)
{
- return ((const OpenCLDeviceBenchmark*)a)->runtime - ((const OpenCLDeviceBenchmark*)b)->runtime;
+ return FFDIFFSIGN((const OpenCLDeviceBenchmark*)a->runtime , (const OpenCLDeviceBenchmark*)b->runtime);
}
int opt_opencl_bench(void *optctx, const char *opt, const char *arg)
diff --git a/ffmpeg.c b/ffmpeg.c
index f8b071a..d3b8c4d 100644
--- a/ffmpeg.c
+++ b/ffmpeg.c
@@ -2578,8 +2578,7 @@ static InputStream *get_input_stream(OutputStream *ost)
static int compare_int64(const void *a, const void *b)
{
- int64_t va = *(int64_t *)a, vb = *(int64_t *)b;
- return va < vb ? -1 : va > vb ? +1 : 0;
+ return FFDIFFSIGN(*(const int64_t *)a, *(const int64_t *)b);
}
static int init_output_stream(OutputStream *ost, char *error, int error_len)
diff --git a/libavcodec/aacsbr_template.c b/libavcodec/aacsbr_template.c
index d31b71e..1e6f149 100644
--- a/libavcodec/aacsbr_template.c
+++ b/libavcodec/aacsbr_template.c
@@ -104,7 +104,7 @@ av_cold void AAC_RENAME(ff_aac_sbr_ctx_close)(SpectralBandReplication *sbr)
static int qsort_comparison_function_int16(const void *a, const void *b)
{
- return *(const int16_t *)a - *(const int16_t *)b;
+ return FFDIFFSIGN(*(const int16_t *)a , *(const int16_t *)b);
}
static inline int in_table_int16(const int16_t *table, int last_el, int16_t needle)
diff --git a/libavcodec/motion_est.c b/libavcodec/motion_est.c
index 9f71568..8560819 100644
--- a/libavcodec/motion_est.c
+++ b/libavcodec/motion_est.c
@@ -73,7 +73,7 @@ static int minima_cmp(const void *a, const void *b){
const Minima *da = (const Minima *) a;
const Minima *db = (const Minima *) b;
- return da->height - db->height;
+ return FFDIFFSIGN(da->height , db->height);
}
#define FLAG_QPEL 1 //must be 1
diff --git a/libavfilter/f_sendcmd.c b/libavfilter/f_sendcmd.c
index 37aedc5..f06773a 100644
--- a/libavfilter/f_sendcmd.c
+++ b/libavfilter/f_sendcmd.c
@@ -364,11 +364,9 @@ static int cmp_intervals(const void *a, const void *b)
{
const Interval *i1 = a;
const Interval *i2 = b;
- int64_t ts_diff = i1->start_ts - i2->start_ts;
- int ret;
-
- ret = ts_diff > 0 ? 1 : ts_diff < 0 ? -1 : 0;
- return ret == 0 ? i1->index - i2->index : ret;
+ if (i1->start_ts == i2->start_ts)
+ return FFDIFFSIGN(i1->index, i2->index);
+ return FFDIFFSIGN(i1->start_ts, i2->start_ts);
}
static av_cold int init(AVFilterContext *ctx)
diff --git a/libavfilter/vf_deshake.c b/libavfilter/vf_deshake.c
index e32436d..79fcc20 100644
--- a/libavfilter/vf_deshake.c
+++ b/libavfilter/vf_deshake.c
@@ -94,8 +94,7 @@ AVFILTER_DEFINE_CLASS(deshake);
static int cmp(const void *a, const void *b)
{
- const double va = *(const double *)a, vb = *(const double *)b;
- return va < vb ? -1 : ( va > vb ? 1 : 0 );
+ return FFDIFFSIGN(*(const double *)a, *(const double *)b);
}
/**
diff --git a/libavfilter/vf_palettegen.c b/libavfilter/vf_palettegen.c
index df57c10..fccc5ca 100644
--- a/libavfilter/vf_palettegen.c
+++ b/libavfilter/vf_palettegen.c
@@ -130,7 +130,7 @@ static int cmp_color(const void *a, const void *b)
{
const struct range_box *box1 = a;
const struct range_box *box2 = b;
- return box1->color - box2->color;
+ return FFDIFFSIGN(box1->color , box2->color);
}
static av_always_inline int diff(const uint32_t a, const uint32_t b)
diff --git a/libavfilter/vf_removegrain.c b/libavfilter/vf_removegrain.c
index 3a28b15..e29ac8f 100644
--- a/libavfilter/vf_removegrain.c
+++ b/libavfilter/vf_removegrain.c
@@ -83,10 +83,7 @@ static int mode01(int c, int a1, int a2, int a3, int a4, int a5, int a6, int a7,
static int cmp_int(const void *p1, const void *p2)
{
- int left = *(const int *)p1;
- int right = *(const int *)p2;
-
- return ((left > right) - (left < right));
+ return FFDIFFSIGN(*(const int *)p1, *(const int *)p2);
}
static int mode02(int c, int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8)
diff --git a/libavformat/subtitles.c b/libavformat/subtitles.c
index 471d600..7c6cd5f 100644
--- a/libavformat/subtitles.c
+++ b/libavformat/subtitles.c
@@ -146,12 +146,9 @@ static int cmp_pkt_sub_ts_pos(const void *a, const void *b)
{
const AVPacket *s1 = a;
const AVPacket *s2 = b;
- if (s1->pts == s2->pts) {
- if (s1->pos == s2->pos)
- return 0;
- return s1->pos > s2->pos ? 1 : -1;
- }
- return s1->pts > s2->pts ? 1 : -1;
+ if (s1->pts == s2->pts)
+ return FFDIFFSIGN(s1->pos, s2->pos);
+ return FFDIFFSIGN(s1->pts , s2->pts);
}
static int cmp_pkt_sub_pos_ts(const void *a, const void *b)
diff --git a/libswresample/swresample-test.c b/libswresample/swresample-test.c
index 0aa47c8..ff735a0 100644
--- a/libswresample/swresample-test.c
+++ b/libswresample/swresample-test.c
@@ -139,7 +139,7 @@ static void setup_array(uint8_t *out[SWR_CH_MAX], uint8_t *in, enum AVSampleForm
}
static int cmp(const void *a, const void *b){
- return *(const int *)a - *(const int *)b;
+ return FFDIFFSIGN(*(const int *)a , *(const int *)b);
}
static void audiogen(void *data, enum AVSampleFormat sample_fmt,
--
2.6.2
More information about the ffmpeg-devel
mailing list