]> git.imager.perl.org - imager.git/blob - ICO/t/t60writefail.t
Change note for strerror() fix
[imager.git] / ICO / t / t60writefail.t
1 #!perl -w
2 use strict;
3 use Test::More tests => 69;
4 use Imager ':handy';
5
6 # this file tries to cover as much of the write error handling cases in 
7 # msicon.c/imicon.c as possible.
8 #
9 # coverage checked with gcc/gcov
10
11 # image too big for format tests, for each entry point
12 {
13   my $im = Imager->new(xsize => 257, ysize => 256);
14   my $data;
15   ok(!$im->write(data => \$data, type=>'ico'),
16      "image too large");
17   is($im->errstr, "image too large for ico file", "check message");
18 }
19
20 {
21   my $im = Imager->new(xsize => 257, ysize => 256);
22   my $data;
23   ok(!Imager->write_multi({ data => \$data, type=>'ico' }, $im, $im),
24      "image too large");
25   is(Imager->errstr, "image too large for ico file", "check message");
26   Imager->_set_error('');
27 }
28
29 {
30   my $im = Imager->new(xsize => 257, ysize => 256);
31   my $data;
32   ok(!$im->write(data => \$data, type=>'cur'),
33      "image too large");
34   is($im->errstr, "image too large for ico file", "check message");
35 }
36
37 {
38   my $im = Imager->new(xsize => 257, ysize => 256);
39   my $data;
40   ok(!Imager->write_multi({ data => \$data, type=>'cur' }, $im),
41      "image too large");
42   is(Imager->errstr, "image too large for ico file", "check message");
43   Imager->_set_error('');
44 }
45
46 # low level write failure tests for each entry point (fail on close)
47 {
48   my $im = Imager->new(xsize => 10, ysize => 10);
49   ok(!$im->write(callback => \&write_failure, type=>'ico'),
50      "low level write failure (ico)");
51   is($im->errstr, "error closing output: synthetic error", "check message");
52 }
53
54 {
55   my $im = Imager->new(xsize => 10, ysize => 10);
56   ok(!$im->write(callback => \&write_failure, type=>'cur'),
57      "low level write failure (cur)");
58   is($im->errstr, "error closing output: synthetic error", "check message");
59 }
60
61 {
62   my $im = Imager->new(xsize => 10, ysize => 10);
63   ok(!Imager->write_multi({ callback => \&write_failure, type=>'ico' }, $im, $im),
64      "low level write_multi failure (ico)");
65   is(Imager->errstr, "error closing output: synthetic error", "check message");
66   Imager->_set_error('');
67 }
68
69 {
70   my $im = Imager->new(xsize => 10, ysize => 10);
71   ok(!Imager->write_multi({ callback => \&write_failure, type=>'cur' }, $im, $im),
72      "low level write_multi failure (cur)");
73   is(Imager->errstr, "error closing output: synthetic error", "check message");
74   Imager->_set_error('');
75 }
76
77 # low level write failure tests for each entry point (fail on write)
78 {
79   my $im = Imager->new(xsize => 10, ysize => 10);
80   my $io = Imager::io_new_cb(\&write_failure, undef, undef, undef, 1);
81   $io->set_buffered(0);
82   ok(!$im->write(io => $io, type=>'ico'),
83      "low level write failure (ico)");
84   is($im->errstr, "Write failure: synthetic error", "check message");
85 }
86
87 {
88   my $im = Imager->new(xsize => 10, ysize => 10);
89   my $io = Imager::io_new_cb(\&write_failure, undef, undef, undef, 1);
90   $io->set_buffered(0);
91   ok(!$im->write(io => $io, type=>'cur'),
92      "low level write failure (cur)");
93   is($im->errstr, "Write failure: synthetic error", "check message");
94 }
95
96 {
97   my $im = Imager->new(xsize => 10, ysize => 10);
98   my $io = Imager::io_new_cb(\&write_failure, undef, undef, undef, 1);
99   $io->set_buffered(0);
100   ok(!Imager->write_multi({ io => $io, type=>'ico' }, $im, $im),
101      "low level write_multi failure (ico)");
102   is(Imager->errstr, "Write failure: synthetic error", "check message");
103   Imager->_set_error('');
104 }
105
106 {
107   my $im = Imager->new(xsize => 10, ysize => 10);
108   my $io = Imager::io_new_cb(\&write_failure, undef, undef, undef, 1);
109   $io->set_buffered(0);
110   ok(!Imager->write_multi({ io => $io, type=>'cur' }, $im, $im),
111      "low level write_multi failure (cur)");
112   is(Imager->errstr, "Write failure: synthetic error", "check message");
113   Imager->_set_error('');
114 }
115
116 {
117   my $im = Imager->new(xsize => 10, ysize => 10);
118   ok(!$im->write(type => 'ico', io => limited_write_io(6)),
119      "second write (resource) should fail (ico)");
120   is($im->errstr, "Write failure: limit reached", "check message");
121   $im->_set_error('');
122
123   ok(!$im->write(type => 'cur', io => limited_write_io(6)),
124      "second (resource) write should fail (cur)");
125   is($im->errstr, "Write failure: limit reached", "check message");
126   $im->_set_error('');
127
128   ok(!$im->write(type => 'ico', io => limited_write_io(22)),
129      "third write (bmi) should fail (32-bit)");
130   is($im->errstr, "Write failure: limit reached", "check message");
131   $im->_set_error('');
132
133   ok(!$im->write(type => 'ico', io => limited_write_io(62)),
134      "fourth write (data) should fail (32-bit)");
135   is($im->errstr, "Write failure: limit reached", "check message");
136   $im->_set_error('');
137
138   ok(!$im->write(type => 'ico', io => limited_write_io(462)),
139      "mask write should fail (32-bit)");
140   is($im->errstr, "Write failure: limit reached", "check message");
141 }
142
143 { # 1 bit write fails
144   my $im = Imager->new(xsize => 10, ysize => 10, type => 'paletted');
145   my $red = NC(255, 0, 0);
146   my $blue = NC(0, 0, 255);
147   $im->addcolors(colors => [ $red, $blue ]);
148   $im->box(filled => 1, color => $red, ymax => 5);
149   $im->box(filled => 1, color => $blue, ymin => 6);
150   ok(!$im->write(type => 'ico', io => limited_write_io(22)),
151      "third write (bmi) should fail (1-bit)");
152   is($im->errstr, "Write failure: limit reached", "check message");
153   
154   ok(!$im->write(type => 'ico', io => limited_write_io(66)),
155      "fourth write (palette) should fail (1-bit)");
156   is($im->errstr, "Write failure: limit reached", "check message");
157   ok(!$im->write(type => 'ico', io => limited_write_io(74)),
158      "fifth write (image) should fail (1-bit)");
159   is($im->errstr, "Write failure: limit reached", "check message");
160   my $data;
161   ok($im->write(data => \$data, type => 'ico'), "write 1 bit successfully");
162   my $read = Imager->new;
163   ok($read->read(data => $data), "read it back");
164   is($read->type, 'paletted', "check type");
165   is($read->tags(name => 'ico_bits'), 1, "check bits");
166   is(Imager::i_img_diff($read, $im), 0, "check image correct");
167 }
168
169 { # 4 bit write fails
170   my $im = Imager->new(xsize => 10, ysize => 10, type => 'paletted');
171   my $red = NC(255, 0, 0);
172   my $blue = NC(0, 0, 255);
173   $im->addcolors(colors => [ ($red, $blue) x 8 ]);
174   $im->box(filled => 1, color => $red, ymax => 5);
175   $im->box(filled => 1, color => $blue, ymin => 6);
176   ok(!$im->write(type => 'ico', io => limited_write_io(22)),
177      "third write (bmi) should fail (4-bit)");
178   is($im->errstr, "Write failure: limit reached", "check message");
179   
180   ok(!$im->write(type => 'ico', io => limited_write_io(66)),
181      "fourth write (palette) should fail (4-bit)");
182   is($im->errstr, "Write failure: limit reached", "check message");
183   ok(!$im->write(type => 'ico', io => limited_write_io(130)),
184      "fifth write (image) should fail (4-bit)");
185   is($im->errstr, "Write failure: limit reached", "check message");
186   my $data;
187   ok($im->write(data => \$data, type => 'ico'), "write 4 bit successfully");
188   my $read = Imager->new;
189   ok($read->read(data => $data), "read it back");
190   is($read->type, 'paletted', "check type");
191   is($read->tags(name => 'ico_bits'), 4, "check bits");
192   is(Imager::i_img_diff($read, $im), 0, "check image correct");
193 }
194
195 { # 8 bit write fails
196   my $im = Imager->new(xsize => 10, ysize => 10, type => 'paletted');
197   my $red = NC(255, 0, 0);
198   my $blue = NC(0, 0, 255);
199   $im->addcolors(colors => [ ($red, $blue) x 9 ]);
200   $im->box(filled => 1, color => $red, ymax => 5);
201   $im->box(filled => 1, color => $blue, ymin => 6);
202   ok(!$im->write(type => 'ico', io => limited_write_io(22)),
203      "third write (bmi) should fail (8-bit)");
204   is($im->errstr, "Write failure: limit reached", "check message");
205   
206   ok(!$im->write(type => 'ico', io => limited_write_io(62)),
207      "fourth write (palette) should fail (8-bit)");
208   is($im->errstr, "Write failure: limit reached", "check message");
209   ok(!$im->write(type => 'ico', io => limited_write_io(62 + 1024)),
210      "fifth write (image) should fail (8-bit)");
211   is($im->errstr, "Write failure: limit reached", "check message");
212   ok(!$im->write(type => 'ico', io => limited_write_io(62 + 1024 + 10)),
213      "sixth write (zeroes) should fail (8-bit)");
214   is($im->errstr, "Write failure: limit reached", "check message");
215   my $data;
216   ok($im->write(data => \$data, type => 'ico'), "write 8 bit successfully");
217   my $read = Imager->new;
218   ok($read->read(data => $data), "read it back");
219   is($read->type, 'paletted', "check type");
220   is($read->tags(name => 'ico_bits'), 8, "check bits");
221   is(Imager::i_img_diff($read, $im), 0, "check image correct");
222 }
223
224 # write callback that fails
225 sub write_failure {
226   print "# synthesized write failure\n";
227   Imager::i_push_error(0, "synthetic error");
228   return;
229 }
230
231 sub limited_write_io {
232   my ($limit) = @_;
233
234   my $io = Imager::io_new_cb(limited_write($limit), undef, undef, undef, 1);
235   $io->set_buffered(0);
236
237   return $io;
238 }
239
240 sub limited_write {
241   my ($limit) = @_;
242
243   return
244      sub {
245        my ($data) = @_;
246        $limit -= length $data;
247        if ($limit >= 0) {
248          print "# write of ", length $data, " bytes successful ($limit left)\n";
249          return 1;
250        }
251        else {
252          print "# write of ", length $data, " bytes failed\n";
253          Imager::i_push_error(0, "limit reached");
254          return;
255        }
256      };
257 }