Opened 2 months ago
Last modified 8 weeks ago
#11188 new defect
ffmpeg_opt.c correct_input_start_times(void) calculates wrong ts_offset
Reported by: | Jens Viebig | Owned by: | |
---|---|---|---|
Priority: | normal | Component: | tools |
Version: | git-master | Keywords: | |
Cc: | Blocked By: | ||
Blocking: | Reproduced by developer: | no | |
Analyzed by developer: | no |
Description
Summary of the bug:
The abs_start_seek calculation in correct_input_start_times(void) is not done correctly since the sum on the left is evaluated before the shorthand if, giving unexecpected results
abs_start_seek = is->start_time + (ifile->start_time != AV_NOPTS_VALUE) ? ifile->start_time : 0;
This expression almost always evaluates to "ifile->start_time" but is expected to be evaluated to: is->start_time + ifile->start_time
As an example:
is->start_time = 10
ifile->start_time = 20
abs_start_seek = 10 + (20 != AV_NOPTS_VALUE) ? 20 : 0;
evaluates to
abs_start_seek = 10 + (true) ? 20 : 0;
then
abs_start_seek = 11 ? 20 : 0;
then
abs_start_seek = 20
We already submitted a patch for this issue, but it seems it was misunderstood by the maintainers and is still not merged to the current codebase
https://lists.ffmpeg.org/pipermail/ffmpeg-devel/2023-May/309555.html
With the patch the evaluation is corrected to:
abs_start_seek = is->start_time + ((ifile->start_time != AV_NOPTS_VALUE) ? ifile->start_time : 0);
With the example, this evaluates to:
is->start_time = 10
ifile->start_time = 20
abs_start_seek = 10 + ((20 != AV_NOPTS_VALUE) ? 20 : 0);
evaluates to
abs_start_seek = 10 + ((true) ? 20 : 0);
then
abs_start_seek = 10 + 20;
then
abs_start_seek = 30;
Change History (7)
comment:1 by , 2 months ago
Component: | undetermined → tools |
---|---|
Version: | unspecified → git-master |
comment:2 by , 2 months ago
comment:3 by , 2 months ago
We actually added parentheses to make it work.
Why should we remove the other existing parentheses ?
Feels unsafe and a new potential issue for wrong evaluation of the expression
comment:4 by , 2 months ago
This is much more clear to read:
abs_start_seek = is->start_time + ((ifile->start_time != AV_NOPTS_VALUE) ? ifile->start_time : 0);
if we remove the parenthesis like this:
abs_start_seek = is->start_time + (ifile->start_time != AV_NOPTS_VALUE ? ifile->start_time : 0);
is it guaranteed to evaluate "ifile->start_time != AV_NOPTS_VALUE" before the shorthand if ?
Or is there a risk that it will be evaluated as "AV_NOPTS_VALUE ? ifile->start_time : 0" ?
We think with both parenthesis in place is the most safe and readable option
comment:5 by , 2 months ago
Why should we remove the other existing parentheses?
Code style... Some other projects literally use clang format to remove all unneeded parentheses. This is high level code base, we do not care that people do not know C rules.
comment:6 by , 2 months ago
Yes, != has higher priority than ternary operation. Also (not that it matters here) everyone that is coding C needs to know that middle of the conditional operator (between ? and :) is parsed as if parenthesized: its precedence relative to ?: is ignored.
https://patchwork.ffmpeg.org/project/ffmpeg/patch/0eabd803-a3d7-3577-52f6-dfa5822c16b3@gmx.de/
Although the parentheses around (ifile->start_tile !=
AV_NOPTS_VALUE) can be removed as well.
Also change the name of the patch fftools: correct expression of ternary operation