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.
#include <gvc/gvplugin.h>
#include <gvc/gvcjob.h>
#include <gvc/gvcint.h>
+#include <limits.h>
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)