From: Matthew Fernandez Date: Sun, 11 Jul 2021 01:40:56 +0000 (-0700) Subject: gv_channel_writer: gracefully handle sizes that exceed INT_MAX X-Git-Tag: 2.49.0~62^2~10 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=06f29b7bba9e97429de9f6bfd5dfc8f6be3a54bb;p=graphviz gv_channel_writer: gracefully handle sizes that exceed INT_MAX The compiler (correctly) says: gv_tcl_init.c: In function ‘gv_channel_writer’: gv_tcl_init.c:25:58: warning: conversion from ‘size_t’ {aka ‘long unsigned int’} to ‘int’ may change value [-Wconversion] return Tcl_Write((Tcl_Channel)(job->output_file), s, len); ^~~ gv_tcl_init.c:25:12: warning: conversion to ‘size_t’ {aka ‘long unsigned int’} from ‘int’ may change the sign of the result [-Wsign-conversion] return Tcl_Write((Tcl_Channel)(job->output_file), s, len); ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ This stems from a mismatch between gv_channel_write (or back tracking this, the write_fn member of GVC) dealing in size_t and the TCL API dealing in int. Prior to this change, a write of more than INT_MAX through this function would result in passing a negative value to TCL. I do not know how it responds to such things. Following this change, a write of more than INT_MAX results in a truncated write of at most INT_MAX, something callers should already be anticipating. Squashes two compiler warnings. --- diff --git a/tclpkg/gv/gv_tcl_init.c b/tclpkg/gv/gv_tcl_init.c index 84ff5843e..9e72a82ae 100644 --- a/tclpkg/gv/gv_tcl_init.c +++ b/tclpkg/gv/gv_tcl_init.c @@ -13,6 +13,7 @@ #include #include #include +#include static size_t gv_string_writer(GVJ_t *job, const char *s, size_t len) { @@ -22,7 +23,9 @@ static size_t gv_string_writer(GVJ_t *job, const char *s, size_t len) static size_t gv_channel_writer(GVJ_t *job, const char *s, size_t len) { - return Tcl_Write((Tcl_Channel)(job->output_file), s, len); + // clamp to INT_MAX + int l = len > (size_t)INT_MAX ? INT_MAX : (int)len; + return (size_t)Tcl_Write((Tcl_Channel)(job->output_file), s, l); } void gv_string_writer_init(GVC_t *gvc)