Skip to content

fix some int32 limits on windows #3935

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jun 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion ChangeLog
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
- pngload: disable ADLER32/CRC checking in non-fail mode [kleisauke]
- improve target_clones support check [kleisauke]
- fix pipe read limit
- fix a rare crash on windows in highly threaded applications [Julianiolo]
- fix a rare crash on Windows in highly threaded applications [Julianiolo]
- vipssave: fix infinite loop on Windows with large images [pdbourke]

12/3/24 8.15.2

Expand Down
2 changes: 1 addition & 1 deletion libvips/deprecated/package.c
Original file line number Diff line number Diff line change
Expand Up @@ -323,7 +323,7 @@ static int
getext_vec(im_object *argv)
{
void **out = (void **) &argv[1];
int size;
size_t size;

/* void/char confusion is fine.
*/
Expand Down
27 changes: 9 additions & 18 deletions libvips/foreign/rawsave.c
Original file line number Diff line number Diff line change
Expand Up @@ -93,16 +93,12 @@ vips_foreign_save_raw_write(VipsRegion *region, VipsRect *area, void *a)
{
VipsForeignSave *save = (VipsForeignSave *) a;
VipsForeignSaveRaw *raw = (VipsForeignSaveRaw *) a;
int i;

for (i = 0; i < area->height; i++) {
VipsPel *p =
VIPS_REGION_ADDR(region, area->left, area->top + i);

if (vips__write(raw->fd, p,
VIPS_IMAGE_SIZEOF_PEL(save->in) * area->width))
for (int i = 0; i < area->height; i++)
if (vips__write(raw->fd,
VIPS_REGION_ADDR(region, area->left, area->top + i),
VIPS_IMAGE_SIZEOF_PEL(save->in) * area->width))
return -1;
}

return 0;
}
Expand Down Expand Up @@ -207,16 +203,12 @@ vips_foreign_save_raw_fd_write(VipsRegion *region, VipsRect *area, void *a)
{
VipsForeignSave *save = (VipsForeignSave *) a;
VipsForeignSaveRawFd *fd = (VipsForeignSaveRawFd *) a;
int i;

for (i = 0; i < area->height; i++) {
VipsPel *p =
VIPS_REGION_ADDR(region, area->left, area->top + i);

if (vips__write(fd->fd, p,
VIPS_IMAGE_SIZEOF_PEL(save->in) * area->width))
for (int i = 0; i < area->height; i++)
if (vips__write(fd->fd,
VIPS_REGION_ADDR(region, area->left, area->top + i),
VIPS_IMAGE_SIZEOF_PEL(save->in) * area->width))
return -1;
}

return 0;
}
Expand All @@ -231,8 +223,7 @@ vips_foreign_save_raw_fd_build(VipsObject *object)
return -1;

if (vips_image_pio_input(save->in) ||
vips_sink_disc(save->in,
vips_foreign_save_raw_fd_write, fd))
vips_sink_disc(save->in, vips_foreign_save_raw_fd_write, fd))
return -1;

return 0;
Expand Down
4 changes: 2 additions & 2 deletions libvips/include/vips/internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -222,11 +222,11 @@ int vips__has_extension_block(VipsImage *im);
/* TODO(kleisauke): VIPS_API is required by vipsheader.
*/
VIPS_API
void *vips__read_extension_block(VipsImage *im, int *size);
void *vips__read_extension_block(VipsImage *im, size_t *size);
/* TODO(kleisauke): VIPS_API is required by vipsedit.
*/
VIPS_API
int vips__write_extension_block(VipsImage *im, void *buf, int size);
int vips__write_extension_block(VipsImage *im, void *buf, size_t size);
int vips__writehist(VipsImage *image);
/* TODO(kleisauke): VIPS_API is required by vipsedit.
*/
Expand Down
3 changes: 1 addition & 2 deletions libvips/include/vips/util.h
Original file line number Diff line number Diff line change
Expand Up @@ -335,8 +335,7 @@ int vips__file_write(void *data, size_t size, size_t nmemb, FILE *stream);
/* TODO(kleisauke): VIPS_API is required by the magick module.
*/
VIPS_API
gint64 vips__get_bytes(const char *filename,
unsigned char buf[], gint64 len);
gint64 vips__get_bytes(const char *filename, unsigned char buf[], gint64 len);
int vips__fgetc(FILE *fp);

GValue *vips__gvalue_ref_string_new(const char *text);
Expand Down
13 changes: 10 additions & 3 deletions libvips/iofuncs/generate.c
Original file line number Diff line number Diff line change
Expand Up @@ -628,15 +628,22 @@ vips_allocate_input_array(VipsImage *out, ...)
static int
write_vips(VipsRegion *region, VipsRect *area, void *a)
{
size_t nwritten, count;
size_t count;
void *buf;

count = (size_t) region->bpl * area->height;
buf = VIPS_REGION_ADDR(region, 0, area->top);

do {
nwritten = write(region->im->fd, buf, count);
if (nwritten == (size_t) -1)
// write() uses int not size_t on windows, so we need to chunk
// ... max 1gb, why not
int chunk_size = VIPS_MIN(1024 * 1024 * 1024, count);
ssize_t nwritten = write(region->im->fd, buf, chunk_size);

/* n == 0 isn't strictly an error, but we treat it as
* one to make sure we don't get stuck in this loop.
*/
if (nwritten <= 0)
return errno;

buf = (void *) ((char *) buf + nwritten);
Expand Down
11 changes: 4 additions & 7 deletions libvips/iofuncs/image.c
Original file line number Diff line number Diff line change
Expand Up @@ -3194,7 +3194,7 @@ vips_image_write_prepare(VipsImage *image)
int
vips_image_write_line(VipsImage *image, int ypos, VipsPel *linebuffer)
{
int linesize = VIPS_IMAGE_SIZEOF_LINE(image);
guint64 linesize = VIPS_IMAGE_SIZEOF_LINE(image);

/* Is this the start of eval?
*/
Expand All @@ -3215,8 +3215,7 @@ vips_image_write_line(VipsImage *image, int ypos, VipsPel *linebuffer)
switch (image->dtype) {
case VIPS_IMAGE_SETBUF:
case VIPS_IMAGE_SETBUF_FOREIGN:
memcpy(VIPS_IMAGE_ADDR(image, 0, ypos),
linebuffer, linesize);
memcpy(VIPS_IMAGE_ADDR(image, 0, ypos), linebuffer, linesize);
break;

case VIPS_IMAGE_OPENOUT:
Expand All @@ -3227,10 +3226,8 @@ vips_image_write_line(VipsImage *image, int ypos, VipsPel *linebuffer)
break;

default:
vips_error("VipsImage",
_("unable to output to a %s image"),
vips_enum_string(VIPS_TYPE_IMAGE_TYPE,
image->dtype));
vips_error("VipsImage", _("unable to output to a %s image"),
vips_enum_string(VIPS_TYPE_IMAGE_TYPE, image->dtype));
return -1;
}

Expand Down
7 changes: 4 additions & 3 deletions libvips/iofuncs/target.c
Original file line number Diff line number Diff line change
Expand Up @@ -459,9 +459,10 @@ vips_target_write_unbuffered(VipsTarget *target,
return 0;

while (length > 0) {
gint64 bytes_written;

bytes_written = class->write(target, data, length);
// write() uses int not size_t on windows, so we need to chunk
// ... max 1gb, why not
int chunk_size = VIPS_MIN(1024 * 1024 * 1024, length);
gint64 bytes_written = class->write(target, data, chunk_size);

/* n == 0 isn't strictly an error, but we treat it as
* one to make sure we don't get stuck in this loop.
Expand Down
25 changes: 13 additions & 12 deletions libvips/iofuncs/util.c
Original file line number Diff line number Diff line change
Expand Up @@ -538,11 +538,16 @@ int
vips__write(int fd, const void *buf, size_t count)
{
do {
size_t nwritten = write(fd, buf, count);
// write() uses int not size_t on windows, so we need to chunk
// ... max 1gb, why not
int chunk_size = VIPS_MIN(1024 * 1024 * 1024, count);
ssize_t nwritten = write(fd, buf, chunk_size);

if (nwritten == (size_t) -1) {
vips_error_system(errno, "vips__write",
"%s", _("write failed"));
/* n == 0 isn't strictly an error, but we treat it as
* one to make sure we don't get stuck in this loop.
*/
if (nwritten <= 0) {
vips_error_system(errno, "vips__write", "%s", _("write failed"));
return -1;
}

Expand Down Expand Up @@ -727,8 +732,7 @@ vips__file_read(FILE *fp, const char *filename, size_t *length_out)
if (len > 1024 * 1024 * 1024) {
/* Over a gb? Seems crazy!
*/
vips_error("vips__file_read",
_("\"%s\" too long"), filename);
vips_error("vips__file_read", _("\"%s\" too long"), filename);
return NULL;
}

Expand All @@ -750,17 +754,15 @@ vips__file_read(FILE *fp, const char *filename, size_t *length_out)
if (size > 1024 * 1024 * 1024 ||
!(str2 = realloc(str, size))) {
free(str);
vips_error("vips__file_read",
"%s", _("out of memory"));
vips_error("vips__file_read", "%s", _("out of memory"));
return NULL;
}
str = str2;

/* -1 to allow space for an extra NULL we add later.
*/
read = fread(str + len, sizeof(char),
(size - len - 1) / sizeof(char),
fp);
(size - len - 1) / sizeof(char), fp);
len += read;
} while (!feof(fp));

Expand All @@ -778,8 +780,7 @@ vips__file_read(FILE *fp, const char *filename, size_t *length_out)
if (read != (size_t) len) {
g_free(str);
vips_error("vips__file_read",
_("error reading from file \"%s\""),
filename);
_("error reading from file \"%s\""), filename);
return NULL;
}
}
Expand Down
9 changes: 4 additions & 5 deletions libvips/iofuncs/vips.c
Original file line number Diff line number Diff line change
Expand Up @@ -506,7 +506,7 @@ vips__has_extension_block(VipsImage *im)
/* Read everything after the pixels into memory.
*/
void *
vips__read_extension_block(VipsImage *im, int *size)
vips__read_extension_block(VipsImage *im, size_t *size)
{
gint64 psize;
void *buf;
Expand All @@ -515,8 +515,7 @@ vips__read_extension_block(VipsImage *im, int *size)
g_assert(im->file_length > 0);
if (im->file_length - psize > 100 * 1024 * 1024) {
vips_error("VipsImage",
"%s", _("more than 100 megabytes of XML? "
"sufferin' succotash!"));
"%s", _("more than 100 megabytes of XML? sufferin' succotash!"));
return NULL;
}
if (im->file_length - psize == 0)
Expand Down Expand Up @@ -774,7 +773,7 @@ readhist(VipsImage *im)
}

int
vips__write_extension_block(VipsImage *im, void *buf, int size)
vips__write_extension_block(VipsImage *im, void *buf, size_t size)
{
gint64 length;
gint64 psize;
Expand All @@ -794,7 +793,7 @@ vips__write_extension_block(VipsImage *im, void *buf, int size)
return -1;

#ifdef DEBUG
printf("vips__write_extension_block: written %d bytes of XML to %s\n",
printf("vips__write_extension_block: written %zd bytes of XML to %s\n",
size, im->filename);
#endif /*DEBUG*/

Expand Down
5 changes: 2 additions & 3 deletions tools/vipsheader.c
Original file line number Diff line number Diff line change
Expand Up @@ -135,10 +135,9 @@ print_header(VipsImage *image, gboolean many)
else if (strcmp(main_option_field, "getext") == 0) {
if (vips__has_extension_block(image)) {
void *buf;
int size;
size_t size;

if (!(buf =
vips__read_extension_block(image, &size)))
if (!(buf = vips__read_extension_block(image, &size)))
return -1;
printf("%s", (char *) buf);
g_free(buf);
Expand Down
Loading