From: Michael Haggerty <mhagger@alum.mit.edu>
To: Junio C Hamano <gitster@pobox.com>
Cc: Alex Riesen <raa.lkml@gmail.com>,
git@vger.kernel.org, Michael Haggerty <mhagger@alum.mit.edu>
Subject: [PATCH] for_each_string_list_item(): behave correctly for empty list
Date: Fri, 15 Sep 2017 18:00:38 +0200 [thread overview]
Message-ID: <cb2d4d71c7c1db452b86c8076c153cabe7384e28.1505490776.git.mhagger@alum.mit.edu> (raw)
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; /* note, this is NULL */
item < (list)->items + (list)->nr; /* note: NULL + 0 */
++item)
Even though this probably works almost everywhere, it is undefined
behavior, and it could plausibly cause highly-optimizing compilers to
misbehave.
It would be a pain to have to change the signature of this macro, and
we'd prefer not to add overhead to each iteration of the loop. So
instead, whenever `list->items` is NULL, initialize `item` to point at
a dummy `string_list_item` created for the purpose.
This problem was noticed by Coverity.
Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
---
Just a little thing I noticed in a Coverity report. This macro has
been broken since it was first introduced, in 2010.
This patch applies against maint. It is also available from my Git
fork [1] as branch `iter-empty-string-list`.
Michael
[1] https://github.com/mhagger/git
string-list.c | 2 ++
string-list.h | 7 +++++--
2 files changed, 7 insertions(+), 2 deletions(-)
diff --git a/string-list.c b/string-list.c
index 806b4c8723..7eacf6037f 100644
--- a/string-list.c
+++ b/string-list.c
@@ -1,6 +1,8 @@
#include "cache.h"
#include "string-list.h"
+struct string_list_item dummy_string_list_item;
+
void string_list_init(struct string_list *list, int strdup_strings)
{
memset(list, 0, sizeof(*list));
diff --git a/string-list.h b/string-list.h
index 29bfb7ae45..79bb78d80a 100644
--- a/string-list.h
+++ b/string-list.h
@@ -32,8 +32,11 @@ void string_list_clear_func(struct string_list *list, string_list_clear_func_t c
typedef int (*string_list_each_func_t)(struct string_list_item *, void *);
int for_each_string_list(struct string_list *list,
string_list_each_func_t, void *cb_data);
-#define for_each_string_list_item(item,list) \
- for (item = (list)->items; item < (list)->items + (list)->nr; ++item)
+extern struct string_list_item dummy_string_list_item;
+#define for_each_string_list_item(item,list) \
+ for (item = (list)->items ? (list)->items : &dummy_string_list_item; \
+ item < (list)->items + (list)->nr; \
+ ++item)
/*
* Apply want to each item in list, retaining only the ones for which
--
2.14.1
next reply other threads:[~2017-09-15 16:00 UTC|newest]
Thread overview: 29+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-09-15 16:00 Michael Haggerty [this message]
2017-09-15 18:43 ` [PATCH] for_each_string_list_item(): behave correctly for empty list Jonathan Nieder
2017-09-16 4:06 ` Michael Haggerty
2017-09-16 11:51 ` SZEDER Gábor
2017-09-17 10:19 ` Michael Haggerty
2017-09-19 14:38 ` Kaartic Sivaraam
2017-09-20 1:38 ` Junio C Hamano
2017-09-20 1:43 ` Jonathan Nieder
2017-09-20 5:14 ` Junio C Hamano
2017-09-20 2:30 ` Jonathan Nieder
2017-09-20 3:54 ` Junio C Hamano
2017-09-20 5:27 ` [PATCH v2] for_each_string_list_item: avoid undefined behavior " Jonathan Nieder
2017-09-20 5:40 ` Junio C Hamano
2017-09-20 7:00 ` Michael Haggerty
2017-09-20 7:40 ` Kaartic Sivaraam
2017-09-20 12:22 ` [PATCH v2] doc: camelCase the config variables to improve readability Kaartic Sivaraam
2017-09-20 16:28 ` [PATCH v2] for_each_string_list_item: avoid undefined behavior for empty list Andreas Schwab
2017-09-20 17:31 ` Jonathan Nieder
2017-09-20 21:51 ` Andreas Schwab
2017-09-21 1:12 ` Junio C Hamano
2017-09-21 15:39 ` Andreas Schwab
2017-09-20 7:35 ` [PATCH] for_each_string_list_item(): behave correctly " Kaartic Sivaraam
2017-09-17 0:59 ` Junio C Hamano
2017-09-17 10:24 ` Michael Haggerty
2017-09-18 0:37 ` Junio C Hamano
2017-09-19 0:08 ` Stefan Beller
2017-09-19 6:51 ` Michael Haggerty
2017-09-19 13:38 ` SZEDER Gábor
2017-09-19 13:45 ` SZEDER Gábor
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: http://vger.kernel.org/majordomo-info.html
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=cb2d4d71c7c1db452b86c8076c153cabe7384e28.1505490776.git.mhagger@alum.mit.edu \
--to=mhagger@alum.mit.edu \
--cc=git@vger.kernel.org \
--cc=gitster@pobox.com \
--cc=raa.lkml@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://80x24.org/mirrors/git.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).