From 48743a1e619a2043099a7b60eec0dd1c80fc73f7 Mon Sep 17 00:00:00 2001 From: Matthew Fernandez Date: Sat, 20 Aug 2022 18:58:20 -0700 Subject: [PATCH] API BREAK: libxdot: use size_t instead of int for op sizes/counts MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit This allows exceeding operation counts of 2³¹ - 1, which is not particularly likely. But its more important effect is to make arithmetic operations less error prone and make it impossible by-construction to arrive at a negative operation size or count. Doing this as a single sweeping change seemed less error prone and clearer, despite how large the resulting diff is. For lines that would have been changed anyway, this commit also fixes white space and tightens variable scoping where possible. --- CHANGELOG.md | 5 +++++ cmd/smyrna/topviewfuncs.c | 10 ++++------ lib/common/emit.c | 8 ++++---- lib/xdot/xdot.c | 22 ++++++++-------------- lib/xdot/xdot.h | 11 ++++++----- plugin/core/gvrender_core_json.c | 3 +-- 6 files changed, 28 insertions(+), 31 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 911511fec..f73ea66e6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased (6.0.0)] +### Changed + +- **Breaking**: libxdot fields for the size and number of operations are now + `size_t` values instead of `int` values + ### Removed - The `$GV_FILE_PATH` sandboxing mechanism has been removed #2257 diff --git a/cmd/smyrna/topviewfuncs.c b/cmd/smyrna/topviewfuncs.c index 15cd6e490..e08cf25fc 100644 --- a/cmd/smyrna/topviewfuncs.c +++ b/cmd/smyrna/topviewfuncs.c @@ -24,11 +24,10 @@ #include #include #include +#include static xdot *parseXdotwithattrs(void *e) { - - int cnt=0; xdot* xDot=NULL; xDot=parseXDotFOn (agget(e,"_draw_" ), OpFns,sizeof(sdot_op), xDot); if (agobjkind(e) == AGRAPH) @@ -40,7 +39,7 @@ static xdot *parseXdotwithattrs(void *e) xDot=parseXDotFOn (agget(e,"_tldraw_" ), OpFns,sizeof(sdot_op), xDot); if(xDot) { - for (cnt=0;cnt < xDot->cnt ; cnt++) + for (size_t cnt = 0; cnt < xDot->cnt; cnt++) { ((sdot_op*)(xDot->ops))[cnt].obj=e; } @@ -73,7 +72,6 @@ static void set_boundaries(Agraph_t * g) static void draw_xdot(xdot* x,float base_z) { - int i; sdot_op *op; if (!x) return; @@ -81,7 +79,7 @@ static void draw_xdot(xdot* x,float base_z) view->Topview->global_z=base_z; op=(sdot_op*)x->ops; - for (i=0; i < x->cnt; i++,op++) + for (size_t i = 0; i < x->cnt; i++, op++) { if(op->op.drawfunc) op->op.drawfunc(&op->op,0); @@ -556,7 +554,7 @@ static xdot* makeXDotSpline (char* pos) { xdot_point s, e; int v, have_s, have_e, cnt; - int sz = sizeof(sdot_op); + static const size_t sz = sizeof(sdot_op); xdot* xd; xdot_op* op; xdot_point* pts; diff --git a/lib/common/emit.c b/lib/common/emit.c index 8b1bec672..c2ea7e0bd 100644 --- a/lib/common/emit.c +++ b/lib/common/emit.c @@ -15,6 +15,7 @@ #include "config.h" #include #include +#include #include #include #include @@ -1474,12 +1475,12 @@ static void emit_xdot (GVJ_t * job, xdot* xd) int ptsize = INITPTS; pointf* pts = N_GNEW(INITPTS, pointf); exdot_op* op; - int i, angle; + int angle; char** styles = NULL; int filled = FILL; op = (exdot_op*)(xd->ops); - for (i = 0; i < xd->cnt; i++) { + for (size_t i = 0; i < xd->cnt; i++) { switch (op->op.kind) { case xd_filled_ellipse : case xd_unfilled_ellipse : @@ -2932,7 +2933,6 @@ boxf xdotBB (Agraph_t* g) { GVC_t *gvc = GD_gvc(g); exdot_op* op; - int i; double fontsize = 0.0; char* fontname = NULL; pointf pts[2]; @@ -2951,7 +2951,7 @@ boxf xdotBB (Agraph_t* g) } op = (exdot_op*)xd->ops; - for (i = 0; i < xd->cnt; i++) { + for (size_t i = 0; i < xd->cnt; i++) { tf = null_tf; switch (op->op.kind) { case xd_filled_ellipse : diff --git a/lib/xdot/xdot.c b/lib/xdot/xdot.c index 6defcb217..d32a28fdf 100644 --- a/lib/xdot/xdot.c +++ b/lib/xdot/xdot.c @@ -329,26 +329,24 @@ static char *parseOp(xdot_op * op, char *s, drawfunc_t ops[], int* error) * Parse and append additional xops onto a given xdot object. * Return x. */ -xdot *parseXDotFOn (char *s, drawfunc_t fns[], int sz, xdot* x) -{ +xdot *parseXDotFOn(char *s, drawfunc_t fns[], size_t sz, xdot *x) { xdot_op op; char *ops; - int oldsz, bufsz; + size_t oldsz, bufsz; int error; - int initcnt; if (!s) return x; if (!x) { x = gv_alloc(sizeof(*x)); - if (sz < 0 || (size_t)sz <= sizeof(xdot_op)) + if (sz <= sizeof(xdot_op)) sz = sizeof(xdot_op); /* cnt, freefunc, ops, flags zeroed by gv_alloc */ x->sz = sz; } - initcnt = x->cnt; + size_t initcnt = x->cnt; sz = x->sz; if (initcnt == 0) { @@ -385,8 +383,7 @@ xdot *parseXDotFOn (char *s, drawfunc_t fns[], int sz, xdot* x) } -xdot *parseXDotF(char *s, drawfunc_t fns[], int sz) -{ +xdot *parseXDotF(char *s, drawfunc_t fns[], size_t sz) { return parseXDotFOn (s, fns, sz, NULL); } @@ -728,10 +725,9 @@ static void jsonXDot_Op(xdot_op * op, pf print, void *info, int more) static void _printXDot(xdot * x, pf print, void *info, print_op ofn) { - int i; xdot_op *op; char *base = (char *) (x->ops); - for (i = 0; i < x->cnt; i++) { + for (size_t i = 0; i < x->cnt; i++) { op = (xdot_op *) (base + i * x->sz); ofn(op, print, info, i < x->cnt - 1); } @@ -799,14 +795,13 @@ static void freeXOpData(xdot_op * x) void freeXDot (xdot * x) { - int i; xdot_op *op; char *base; freefunc_t ff = x->freefunc; if (!x) return; base = (char *) (x->ops); - for (i = 0; i < x->cnt; i++) { + for (size_t i = 0; i < x->cnt; i++) { op = (xdot_op *) (base + i * x->sz); if (ff) ff (op); freeXOpData(op); @@ -817,7 +812,6 @@ void freeXDot (xdot * x) int statXDot (xdot* x, xdot_stats* sp) { - int i; xdot_op *op; char *base; @@ -825,7 +819,7 @@ int statXDot (xdot* x, xdot_stats* sp) memset(sp, 0, sizeof(xdot_stats)); sp->cnt = x->cnt; base = (char *) (x->ops); - for (i = 0; i < x->cnt; i++) { + for (size_t i = 0; i < x->cnt; i++) { op = (xdot_op *) (base + i * x->sz); switch (op->kind) { case xd_filled_ellipse: diff --git a/lib/xdot/xdot.h b/lib/xdot/xdot.h index b150bfc32..d681774ce 100644 --- a/lib/xdot/xdot.h +++ b/lib/xdot/xdot.h @@ -10,6 +10,7 @@ #pragma once +#include #include #ifdef __cplusplus @@ -143,15 +144,15 @@ struct _xdot_op { #define XDOT_PARSE_ERROR 1 typedef struct { - int cnt; /* no. of xdot ops */ - int sz; /* sizeof structure containing xdot_op as first field */ + size_t cnt; /* no. of xdot ops */ + size_t sz; /* sizeof structure containing xdot_op as first field */ xdot_op* ops; freefunc_t freefunc; int flags; } xdot; typedef struct { - int cnt; /* no. of xdot ops */ + size_t cnt; /* no. of xdot ops */ int n_ellipse; int n_polygon; int n_polygon_pts; @@ -169,8 +170,8 @@ typedef struct { } xdot_stats; /* ops are indexed by xop_kind */ -XDOT_API xdot* parseXDotF (char*, drawfunc_t opfns[], int sz); -XDOT_API xdot* parseXDotFOn (char*, drawfunc_t opfns[], int sz, xdot*); +XDOT_API xdot *parseXDotF(char*, drawfunc_t opfns[], size_t sz); +XDOT_API xdot *parseXDotFOn(char*, drawfunc_t opfns[], size_t sz, xdot*); XDOT_API xdot* parseXDot (char*); XDOT_API char* sprintXDot (xdot*); XDOT_API void fprintXDot (FILE*, xdot*); diff --git a/plugin/core/gvrender_core_json.c b/plugin/core/gvrender_core_json.c index 88715a93a..df2c78917 100644 --- a/plugin/core/gvrender_core_json.c +++ b/plugin/core/gvrender_core_json.c @@ -308,7 +308,6 @@ static void write_xdot (xdot_op * op, GVJ_t * job, state_t* sp) static void write_xdots (char * val, GVJ_t * job, state_t* sp) { xdot* cmds; - int i; if (!val || *val == '\0') return; @@ -321,7 +320,7 @@ static void write_xdots (char * val, GVJ_t * job, state_t* sp) gvputs(job, "\n"); indent(job, sp->Level++); gvputs(job, "[\n"); - for (i = 0; i < cmds->cnt; i++) { + for (size_t i = 0; i < cmds->cnt; i++) { if (i > 0) gvputs(job, ",\n"); write_xdot (cmds->ops+i, job, sp); -- 2.40.0