[tz] [PROPOSED] Fix recently-introduced zic infloop
Paul Eggert
eggert at cs.ucla.edu
Fri Oct 28 05:25:36 UTC 2022
* zic.c (make_links): Diagnose link cycles instead of looping.
---
zic.c | 20 +++++++++++++++++---
1 file changed, 17 insertions(+), 3 deletions(-)
diff --git a/zic.c b/zic.c
index 4222869..501718f 100644
--- a/zic.c
+++ b/zic.c
@@ -688,7 +688,7 @@ bsearch_linkcmp(void const *key, void const *b)
static void
make_links(void)
{
- ptrdiff_t i, j, nalinks;
+ ptrdiff_t i, j, nalinks, pass_size;
if (1 < nlinks)
qsort(links, nlinks, sizeof *links, qsort_linkcmp);
@@ -700,7 +700,7 @@ make_links(void)
i++;
links[j++] = links[i];
}
- nlinks = j;
+ nlinks = pass_size = j;
/* Walk through the link array making links. However,
if a link's target has not been made yet, append a copy to the
@@ -739,8 +739,22 @@ make_links(void)
eat(links[i].l_filenum, links[i].l_linenum);
/* If this pass examined all its links, start the next pass. */
- if (i == j)
+ if (i == j) {
+ if (nalinks - i == pass_size) {
+ error(_("\"Link %s %s\" is part of a link cycle"),
+ links[i].l_target, links[i].l_linkname);
+ break;
+ }
j = nalinks;
+ pass_size = nalinks - i;
+ }
+
+ /* Diagnose self links, which the cycle detection algorithm would not
+ otherwise catch. */
+ if (strcmp(links[i].l_target, links[i].l_linkname) == 0) {
+ error(_("link %s targets itself"), links[i].l_target);
+ continue;
+ }
/* Make this link unless its target has not been made yet. */
l = bsearch(links[i].l_target, &links[i + 1], j - (i + 1),
--
2.37.3
More information about the tz
mailing list