- convert t/t107bmp.t to Test::More
[imager.git] / limits.c
CommitLineData
77157728
TC
1/*
2=head1 NAME
3
4limits.c - manages data/functions for limiting the sizes of images read from files.
5
6=head1 SYNOPSIS
7
8 // user code
9 if (!i_set_image_file_limits(max_width, max_height, max_bytes)) {
10 // error
11 }
12 i_get_image_file_limits(&max_width, &max_height, &max_bytes);
13
14 // file reader implementations
15 if (!i_int_check_image_file_limits(width, height, channels, sizeof(i_sample_t))) {
16 // error handling
17 }
18
19=head1 DESCRIPTION
20
21Manage limits for image files read by Imager.
22
23Setting a value of zero means that limit will be ignored.
24
25 */
26
27#include "imagei.h"
28
29static int max_width, max_height;
30static int max_bytes;
31
32int
33i_set_image_file_limits(int width, int height, int bytes) {
34 i_clear_error();
35
36 if (width < 0) {
37 i_push_error(0, "width must be non-negative");
38 return 0;
39 }
40 if (height < 0) {
41 i_push_error(0, "height must be non-negative");
42 return 0;
43 }
44 if (bytes < 0) {
45 i_push_error(0, "bytes must be non-negative");
46 return 0;
47 }
48
49 max_width = width;
50 max_height = height;
51 max_bytes = bytes;
52
53 return 1;
54}
55
56int
57i_get_image_file_limits(int *width, int *height, int *bytes) {
58 i_clear_error();
59
60 *width = max_width;
61 *height = max_height;
62 *bytes = max_bytes;
63
64 return 1;
65}
66
67int
68i_int_check_image_file_limits(int width, int height, int channels, int sample_size) {
69 i_clear_error();
70
71 if (width <= 0) {
72 i_push_errorf(0, "file size limit - image width of %d is not positive",
73 width);
74 return 0;
75 }
76 if (max_width && width > max_width) {
77 i_push_errorf(0, "file size limit - image width of %d exceeds limit of %d",
78 width, max_width);
79 return 0;
80 }
81
82 if (height <= 0) {
83 i_push_errorf(0, "file size limit - image height %d is not positive",
84 height);
85 return 0;
86 }
87
88 if (max_height && height > max_height) {
89 i_push_errorf(0, "file size limit - image height of %d "
90 "exceeds limit of %d", height, max_height);
91 return 0;
92 }
93
94 if (channels < 1 || channels > MAXCHANNELS) {
95 i_push_errorf(0, "file size limit - channels %d out of range",
96 channels);
97 return 0;
98 }
99
100 if (sample_size < 1 || sample_size > sizeof(long double)) {
101 i_push_errorf(0, "file size limit - sample_size %d out of range",
102 sample_size);
103 return 0;
104 }
105
106 /* This overflow check is a bit more paranoid than usual.
107 We don't protect it under max_bytes since we always want to check
108 for overflow.
109 */
110 int bytes = width * height * channels * sample_size;
111 if (bytes / width != height * channels * sample_size
112 || bytes / height != width * channels * sample_size) {
113 i_push_error(0, "file size limit - integer overflow calculating storage");
114 return 0;
115 }
116 if (max_bytes) {
117 if (bytes > max_bytes) {
118 i_push_errorf(0, "file size limit - storage size of %d "
119 "exceeds limit of %d", bytes, max_bytes);
120 return 0;
121 }
122 }
123
124 return 1;
125}