X-Git-Url: http://git.imager.perl.org/imager.git/blobdiff_plain/77157728e2173c7fc0bc905fc4b3db5df6669e96..8b810590436c296f9eb0992cf444b14fdaa8a933:/limits.c diff --git a/limits.c b/limits.c index 01e89022..36ae45b5 100644 --- a/limits.c +++ b/limits.c @@ -21,16 +21,52 @@ limits.c - manages data/functions for limiting the sizes of images read from fil Manage limits for image files read by Imager. Setting a value of zero means that limit will be ignored. - + +=over + +=cut */ -#include "imagei.h" +#define IMAGER_NO_CONTEXT +#include "imageri.h" + +/* +=item im_set_image_file_limits(ctx, width, height, bytes) +XX +=category Files +=synopsis im_set_image_file_limits(aIMCTX, 500, 500, 1000000); +=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. + +Parameters: + +=over -static int max_width, max_height; -static int max_bytes; +=item * + +i_img_dim width, height - maximum width and height. + +=item * + +size_t bytes - maximum size in memory in bytes. A value of zero sets +this limit to one gigabyte. + +=back + +Returns non-zero on success. + +Also callable as C. + +=cut +*/ int -i_set_image_file_limits(int width, int height, int bytes) { +im_set_image_file_limits(pIMCTX, i_img_dim width, i_img_dim height, size_t bytes) { i_clear_error(); if (width < 0) { @@ -46,60 +82,109 @@ i_set_image_file_limits(int width, int height, int bytes) { return 0; } - max_width = width; - max_height = height; - max_bytes = bytes; + aIMCTX->max_width = width; + aIMCTX->max_height = height; + aIMCTX->max_bytes = bytes ? bytes : DEF_BYTES_LIMIT; return 1; } +/* +=item im_get_image_file_limits(ctx, &width, &height, &bytes) +XX +=category Files +=synopsis im_get_image_file_limits(aIMCTX, &width, &height, &bytes) +=synopsis i_get_image_file_limits(&width, &height, &bytes) + +Retrieves the file limits set by i_set_image_file_limits(). + +=over + +=item * + +i_img_dim *width, *height - the maximum width and height of the image. + +=item * + +size_t *bytes - size in memory of the image in bytes. + +=back + +Also callable as C. + +=cut +*/ + int -i_get_image_file_limits(int *width, int *height, int *bytes) { - i_clear_error(); +im_get_image_file_limits(pIMCTX, i_img_dim *width, i_img_dim *height, size_t *bytes) { + im_clear_error(aIMCTX); - *width = max_width; - *height = max_height; - *bytes = max_bytes; + *width = aIMCTX->max_width; + *height = aIMCTX->max_height; + *bytes = aIMCTX->max_bytes; return 1; } +/* +=item im_int_check_image_file_limits(width, height, channels, sample_size) +XX +=category Files +=synopsis im_int_check_image_file_limits(aIMCTX, width, height, channels, sizeof(i_sample_t)) +=synopsis 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. + +Also callable as C. + +=cut +*/ + int -i_int_check_image_file_limits(int width, int height, int channels, int sample_size) { - i_clear_error(); +im_int_check_image_file_limits(pIMCTX, i_img_dim width, i_img_dim height, int channels, size_t sample_size) { + size_t bytes; + im_clear_error(aIMCTX); if (width <= 0) { - i_push_errorf(0, "file size limit - image width of %d is not positive", - width); + im_push_errorf(aIMCTX, 0, "file size limit - image width of %" i_DF " is not positive", + i_DFc(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); + if (aIMCTX->max_width && width > aIMCTX->max_width) { + im_push_errorf(aIMCTX, 0, "file size limit - image width of %" i_DF " exceeds limit of %" i_DF, + i_DFc(width), i_DFc(aIMCTX->max_width)); return 0; } if (height <= 0) { - i_push_errorf(0, "file size limit - image height %d is not positive", - height); + im_push_errorf(aIMCTX, 0, "file size limit - image height of %" i_DF " is not positive", + i_DFc(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); + if (aIMCTX->max_height && height > aIMCTX->max_height) { + im_push_errorf(aIMCTX, 0, "file size limit - image height of %" i_DF + " exceeds limit of %" i_DF, i_DFc(height), i_DFc(aIMCTX->max_height)); return 0; } if (channels < 1 || channels > MAXCHANNELS) { - i_push_errorf(0, "file size limit - channels %d out of range", + im_push_errorf(aIMCTX, 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); + im_push_errorf(aIMCTX, 0, "file size limit - sample_size %ld out of range", + (long)sample_size); return 0; } @@ -107,16 +192,17 @@ i_int_check_image_file_limits(int width, int height, int channels, int sample_si We don't protect it under max_bytes since we always want to check for overflow. */ - int bytes = width * height * channels * sample_size; + 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"); + im_push_error(aIMCTX, 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); + if (aIMCTX->max_bytes) { + if (bytes > aIMCTX->max_bytes) { + im_push_errorf(aIMCTX, 0, "file size limit - storage size of %lu " + "exceeds limit of %lu", (unsigned long)bytes, + (unsigned long)aIMCTX->max_bytes); return 0; } }