diff options
author | Michael Haggerty <mhagger@alum.mit.edu> | 2017-09-19 22:27:05 -0700 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2017-09-20 14:41:08 +0900 |
commit | ac7da78ede468315ba22d9ee1265b61a744371ee (patch) | |
tree | f1ed610d69399db07f0af1ce4337a8bb89a6cc74 /t/t5400-send-pack.sh | |
parent | RelNotes: further fixes for 2.14.2 from the master front (diff) | |
download | tgif-ac7da78ede468315ba22d9ee1265b61a744371ee.tar.xz |
for_each_string_list_item: avoid undefined behavior for empty list
If you pass a newly initialized or newly cleared `string_list` to
`for_each_string_list_item()`, then the latter does
for (
item = (list)->items; /* NULL */
item < (list)->items + (list)->nr; /* NULL + 0 */
++item)
Even though this probably works almost everywhere, it is undefined
behavior, and it could plausibly cause highly-optimizing compilers to
misbehave. C99 section 6.5.6 paragraph 8 explains:
If both the pointer operand and the result point to elements
of the same array object, or one past the last element of the
array object, the evaluation shall not produce an overflow;
otherwise, the behavior is undefined.
and (6.3.2.3.3) a null pointer does not point to anything.
Guard the loop with a NULL check to make the intent crystal clear to
even the most pedantic compiler. A suitably clever compiler could let
the NULL check only run in the first iteration, but regardless, this
overhead is likely to be dwarfed by the work to be done on each item.
This problem was noticed by Coverity.
[jn: using a NULL check instead of a placeholder empty list;
fleshed out the commit message based on mailing list discussion]
Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 't/t5400-send-pack.sh')
0 files changed, 0 insertions, 0 deletions