]> granicus.if.org Git - graphviz/commitdiff
common: fix: avoid a use of 'itos'
authorMatthew Fernandez <matthew.fernandez@gmail.com>
Mon, 25 Apr 2022 15:12:01 +0000 (08:12 -0700)
committerMatthew Fernandez <matthew.fernandez@gmail.com>
Thu, 28 Apr 2022 03:19:16 +0000 (20:19 -0700)
Usage of `itos` in this way relies on lifetime extension of a struct member in
an rvalue. While these semantics exist in C11 and C++, they do not in C99. As a
result, this causes undefined behavior.

This commit effectively reverts 400a29f0dbc39682f98eff999bcd32448e328450.

Gitlab: #2229

lib/common/htmltable.c

index c9cf88e081478d7634c3cda12fda9d7833090abd..a8655b5c13e65ce62c2d2e666be5a2c5ebbc24a7 100644 (file)
@@ -39,6 +39,7 @@
 #include <cgraph/strcasecmp.h>
 #include <stddef.h>
 #include <stdbool.h>
+#include <stdio.h>
 
 #define DEFAULT_BORDER    1
 #define DEFAULT_CELLPADDING  2
@@ -1379,10 +1380,12 @@ static void makeGraphs(htmltbl_t * tbl, graph_t * rowg, graph_t * colg)
     node_t *lastn;
     node_t *h;
     int i;
+    char value_buffer[CHARS_FOR_NUL_TERM_INT];
 
     lastn = NULL;
     for (i = 0; i <= tbl->cc; i++) {
-       t = agnode(colg, itos(i).str, 1);
+       snprintf(value_buffer, sizeof(value_buffer), "%d", i);
+       t = agnode(colg, value_buffer, 1);
        agbindrec(t, "Agnodeinfo_t", sizeof(Agnodeinfo_t), true);
        alloc_elist(tbl->rc, ND_in(t));
        alloc_elist(tbl->rc, ND_out(t));
@@ -1395,7 +1398,8 @@ static void makeGraphs(htmltbl_t * tbl, graph_t * rowg, graph_t * colg)
     }
     lastn = NULL;
     for (i = 0; i <= tbl->rc; i++) {
-       t = agnode(rowg, itos(i).str, 1);
+       snprintf(value_buffer, sizeof(value_buffer), "%d", i);
+       t = agnode(rowg, value_buffer, 1);
        agbindrec(t, "Agnodeinfo_t", sizeof(Agnodeinfo_t), true);
        alloc_elist(tbl->cc, ND_in(t));
        alloc_elist(tbl->cc, ND_out(t));
@@ -1409,12 +1413,16 @@ static void makeGraphs(htmltbl_t * tbl, graph_t * rowg, graph_t * colg)
 
     for (cells = tbl->u.n.cells; *cells; cells++) {
        cp = *cells;
-       t = agfindnode(colg, itos(cp->col).str);
-       h = agfindnode(colg, itos(cp->col + cp->cspan).str);
+       snprintf(value_buffer, sizeof(value_buffer), "%d", cp->col);
+       t = agfindnode(colg, value_buffer);
+       snprintf(value_buffer, sizeof(value_buffer), "%d", cp->col + cp->cspan);
+       h = agfindnode(colg, value_buffer);
        checkEdge (colg, t, h, cp->data.box.UR.x);
 
-       t = agfindnode(rowg, itos(cp->row).str);
-       h = agfindnode(rowg, itos(cp->row + cp->rspan).str);
+       snprintf(value_buffer, sizeof(value_buffer), "%d", cp->row);
+       t = agfindnode(rowg, value_buffer);
+       snprintf(value_buffer, sizeof(value_buffer), "%d", cp->row + cp->rspan);
+       h = agfindnode(rowg, value_buffer);
        checkEdge (rowg, t, h, cp->data.box.UR.y);
     }