/* =head1 NAME limits.c - manages data/functions for limiting the sizes of images read from files. =head1 SYNOPSIS // user code if (!i_set_image_file_limits(max_width, max_height, max_bytes)) { // error } i_get_image_file_limits(&max_width, &max_height, &max_bytes); // file reader implementations if (!i_int_check_image_file_limits(width, height, channels, sizeof(i_sample_t))) { // error handling } =head1 DESCRIPTION Manage limits for image files read by Imager. Setting a value of zero means that limit will be ignored. */ #include "imageri.h" static int max_width, max_height; static int max_bytes; /* =item i_set_image_file_limits(width, height, bytes) =category Files =synopsis i_set_image_file_limits(500, 500, 1000000); Set limits on the sizes of images read by Imager. Setting a limit to 0 means that limit is ignored. Negative limits result in failure. Returns non-zero on success. =cut */ int i_set_image_file_limits(int width, int height, int bytes) { i_clear_error(); if (width < 0) { i_push_error(0, "width must be non-negative"); return 0; } if (height < 0) { i_push_error(0, "height must be non-negative"); return 0; } if (bytes < 0) { i_push_error(0, "bytes must be non-negative"); return 0; } max_width = width; max_height = height; max_bytes = bytes; return 1; } /* =item i_get_image_file_limits(&width, &height, &bytes) =category Files =synopsis i_get_image_file_limits(&width, &height, &bytes) Retrieves the file limits set by i_set_image_file_limits(). =cut */ int i_get_image_file_limits(int *width, int *height, int *bytes) { i_clear_error(); *width = max_width; *height = max_height; *bytes = max_bytes; return 1; } /* =item i_int_check_image_file_limits(width, height, channels, sample_size) =category Files =synopsis i_i_int_check_image_file_limits(width, height, channels, sizeof(i_sample_t)) Checks the size of a file in memory against the configured image file limits. This also range checks the values to those permitted by Imager and checks for overflows in calculating the size. Returns non-zero if the file is within limits. This function is intended to be called by image file read functions. =cut */ int i_int_check_image_file_limits(int width, int height, int channels, int sample_size) { int bytes; i_clear_error(); if (width <= 0) { i_push_errorf(0, "file size limit - image width of %d is not positive", width); return 0; } if (max_width && width > max_width) { i_push_errorf(0, "file size limit - image width of %d exceeds limit of %d", width, max_width); return 0; } if (height <= 0) { i_push_errorf(0, "file size limit - image height %d is not positive", height); return 0; } if (max_height && height > max_height) { i_push_errorf(0, "file size limit - image height of %d " "exceeds limit of %d", height, max_height); return 0; } if (channels < 1 || channels > MAXCHANNELS) { i_push_errorf(0, "file size limit - channels %d out of range", channels); return 0; } if (sample_size < 1 || sample_size > sizeof(long double)) { i_push_errorf(0, "file size limit - sample_size %d out of range", sample_size); return 0; } /* This overflow check is a bit more paranoid than usual. We don't protect it under max_bytes since we always want to check for overflow. */ bytes = width * height * channels * sample_size; if (bytes / width != height * channels * sample_size || bytes / height != width * channels * sample_size) { i_push_error(0, "file size limit - integer overflow calculating storage"); return 0; } if (max_bytes) { if (bytes > max_bytes) { i_push_errorf(0, "file size limit - storage size of %d " "exceeds limit of %d", bytes, max_bytes); return 0; } } return 1; }