- extra concept index entries
[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) {
5caa40a6 69 int bytes;
77157728
TC
70 i_clear_error();
71
72 if (width <= 0) {
73 i_push_errorf(0, "file size limit - image width of %d is not positive",
74 width);
75 return 0;
76 }
77 if (max_width && width > max_width) {
78 i_push_errorf(0, "file size limit - image width of %d exceeds limit of %d",
79 width, max_width);
80 return 0;
81 }
82
83 if (height <= 0) {
84 i_push_errorf(0, "file size limit - image height %d is not positive",
85 height);
86 return 0;
87 }
88
89 if (max_height && height > max_height) {
90 i_push_errorf(0, "file size limit - image height of %d "
91 "exceeds limit of %d", height, max_height);
92 return 0;
93 }
94
95 if (channels < 1 || channels > MAXCHANNELS) {
96 i_push_errorf(0, "file size limit - channels %d out of range",
97 channels);
98 return 0;
99 }
100
101 if (sample_size < 1 || sample_size > sizeof(long double)) {
102 i_push_errorf(0, "file size limit - sample_size %d out of range",
103 sample_size);
104 return 0;
105 }
106
107 /* This overflow check is a bit more paranoid than usual.
108 We don't protect it under max_bytes since we always want to check
109 for overflow.
110 */
5caa40a6 111 bytes = width * height * channels * sample_size;
77157728
TC
112 if (bytes / width != height * channels * sample_size
113 || bytes / height != width * channels * sample_size) {
114 i_push_error(0, "file size limit - integer overflow calculating storage");
115 return 0;
116 }
117 if (max_bytes) {
118 if (bytes > max_bytes) {
119 i_push_errorf(0, "file size limit - storage size of %d "
120 "exceeds limit of %d", bytes, max_bytes);
121 return 0;
122 }
123 }
124
125 return 1;
126}