git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
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


             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).