rmagick 7.0.4 → 7.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a6b67e7280c692114f508e96e6ddcf8d554825ba3705e917af4484158aba940f
4
- data.tar.gz: 2ec01a3108eda0eebe35603ae94f675b0966343d5ccb8b2461706b67ea4f3e2c
3
+ metadata.gz: 6a209cf0d468a316b82b18e0dc8cdfe37d07e3a9a89a54750303c48fddbc4721
4
+ data.tar.gz: ec494eed858ad482b7fbc1a3784c471bed373ab2ad1cd3835c99b3c998548736
5
5
  SHA512:
6
- metadata.gz: 1494b9956d04b5f569a39df7e436cae2cc361b093d8fc4339e7b6f56f893e0782f0e506d24faf807d8cc88c7fff697894b39f29cf651666ff1398d8bf421ed4a
7
- data.tar.gz: 06e999110504c4ab2fc1c0ddbd9e43b7415c70173780e127d25132ad0d1e5f172622a445f61922800994ef6aed543f141d984602430f0db8ce0b48fafb2974b0
6
+ metadata.gz: 8879e76297539f5ab7816fb3ba4894530141292fdd828277774d5631655176c717f0888f4624d22f6b7006e9d1b544f7065705220d06df77eadbb428216d6dce
7
+ data.tar.gz: 67e8ff6082884e98cf7cf3dfc35eee092377fc2e4a1d60cc6679b9872dc4c52effc6a6ad6b95966a552eb6f15c2b0264ee2580d768dfce0b71a9aa1ee90b866a
data/CHANGELOG.md CHANGED
@@ -3,6 +3,15 @@
3
3
  All notable changes to this project are documented in this file.
4
4
  This project adheres to [Semantic Versioning](http://semver.org/).
5
5
 
6
+ ## RMagick 7.0.5
7
+
8
+ Bug Fixes
9
+
10
+ * Fix heap overflow from integer overflow in dispatch/export_pixels geometry (#1816)
11
+ * Fix SEGV in Image/Pixel/Draw #marshal_load on a non-collection argument (#1815)
12
+ * Fix SEGV when a Draw method is called on an uninitialized object (#1814)
13
+ * Fix SEGV in Draw#primitive on non-String argument (#1813)
14
+
6
15
  ## RMagick 7.0.4
7
16
 
8
17
  Bug Fixes
@@ -47,6 +47,33 @@ DEFINE_GVL_STUB3(GetTypeMetrics, Image *, const DrawInfo *, TypeMetric *);
47
47
  #endif
48
48
 
49
49
 
50
+ /**
51
+ * Fetch the Draw struct and ensure it has been initialized (draw->info != NULL).
52
+ *
53
+ * Draw_alloc() leaves draw->info NULL until #initialize runs, so a Draw obtained
54
+ * via .allocate (or a subclass whose #initialize skips super) would otherwise
55
+ * dereference a NULL DrawInfo and crash the process. Raise instead.
56
+ *
57
+ * No Ruby usage (internal function)
58
+ *
59
+ * @param self the Draw object
60
+ * @return the initialized Draw struct
61
+ * @throw RuntimeError if the Draw object has not been initialized
62
+ */
63
+ static Draw *
64
+ get_draw(VALUE self)
65
+ {
66
+ Draw *draw;
67
+
68
+ TypedData_Get_Struct(self, Draw, &rm_draw_data_type, draw);
69
+ if (!draw->info)
70
+ {
71
+ rb_raise(rb_eRuntimeError, "%s has not been initialized", rb_obj_classname(self));
72
+ }
73
+ return draw;
74
+ }
75
+
76
+
50
77
  /**
51
78
  * Set the affine matrix from an {Magick::AffineMatrix}.
52
79
  *
@@ -59,7 +86,7 @@ Draw_affine_eq(VALUE self, VALUE matrix)
59
86
  Draw *draw;
60
87
 
61
88
  rb_check_frozen(self);
62
- TypedData_Get_Struct(self, Draw, &rm_draw_data_type, draw);
89
+ draw = get_draw(self);
63
90
  Export_AffineMatrix(&draw->info->affine, matrix);
64
91
  return matrix;
65
92
  }
@@ -77,7 +104,7 @@ Draw_align_eq(VALUE self, VALUE align)
77
104
  Draw *draw;
78
105
 
79
106
  rb_check_frozen(self);
80
- TypedData_Get_Struct(self, Draw, &rm_draw_data_type, draw);
107
+ draw = get_draw(self);
81
108
  VALUE_TO_ENUM(align, draw->info->align, AlignType);
82
109
  return align;
83
110
  }
@@ -95,7 +122,7 @@ Draw_decorate_eq(VALUE self, VALUE decorate)
95
122
  Draw *draw;
96
123
 
97
124
  rb_check_frozen(self);
98
- TypedData_Get_Struct(self, Draw, &rm_draw_data_type, draw);
125
+ draw = get_draw(self);
99
126
  VALUE_TO_ENUM(decorate, draw->info->decorate, DecorationType);
100
127
  return decorate;
101
128
  }
@@ -113,7 +140,7 @@ Draw_density_eq(VALUE self, VALUE density)
113
140
  Draw *draw;
114
141
 
115
142
  rb_check_frozen(self);
116
- TypedData_Get_Struct(self, Draw, &rm_draw_data_type, draw);
143
+ draw = get_draw(self);
117
144
  magick_clone_string(&draw->info->density, StringValueCStr(density));
118
145
 
119
146
  return density;
@@ -132,7 +159,7 @@ Draw_encoding_eq(VALUE self, VALUE encoding)
132
159
  Draw *draw;
133
160
 
134
161
  rb_check_frozen(self);
135
- TypedData_Get_Struct(self, Draw, &rm_draw_data_type, draw);
162
+ draw = get_draw(self);
136
163
  magick_clone_string(&draw->info->encoding, StringValueCStr(encoding));
137
164
 
138
165
  return encoding;
@@ -151,7 +178,7 @@ Draw_fill_eq(VALUE self, VALUE fill)
151
178
  Draw *draw;
152
179
 
153
180
  rb_check_frozen(self);
154
- TypedData_Get_Struct(self, Draw, &rm_draw_data_type, draw);
181
+ draw = get_draw(self);
155
182
  Color_to_PixelColor(&draw->info->fill, fill);
156
183
  return fill;
157
184
  }
@@ -172,7 +199,7 @@ Draw_fill_pattern_eq(VALUE self, VALUE pattern)
172
199
  Draw *draw;
173
200
 
174
201
  rb_check_frozen(self);
175
- TypedData_Get_Struct(self, Draw, &rm_draw_data_type, draw);
202
+ draw = get_draw(self);
176
203
 
177
204
  if (draw->info->fill_pattern != NULL)
178
205
  {
@@ -207,7 +234,7 @@ Draw_font_eq(VALUE self, VALUE font)
207
234
  Draw *draw;
208
235
 
209
236
  rb_check_frozen(self);
210
- TypedData_Get_Struct(self, Draw, &rm_draw_data_type, draw);
237
+ draw = get_draw(self);
211
238
  magick_clone_string(&draw->info->font, StringValueCStr(font));
212
239
 
213
240
  return font;
@@ -226,7 +253,7 @@ Draw_font_family_eq(VALUE self, VALUE family)
226
253
  Draw *draw;
227
254
 
228
255
  rb_check_frozen(self);
229
- TypedData_Get_Struct(self, Draw, &rm_draw_data_type, draw);
256
+ draw = get_draw(self);
230
257
  magick_clone_string(&draw->info->family, StringValueCStr(family));
231
258
 
232
259
  return family;
@@ -245,7 +272,7 @@ Draw_font_stretch_eq(VALUE self, VALUE stretch)
245
272
  Draw *draw;
246
273
 
247
274
  rb_check_frozen(self);
248
- TypedData_Get_Struct(self, Draw, &rm_draw_data_type, draw);
275
+ draw = get_draw(self);
249
276
  VALUE_TO_ENUM(stretch, draw->info->stretch, StretchType);
250
277
  return stretch;
251
278
  }
@@ -263,7 +290,7 @@ Draw_font_style_eq(VALUE self, VALUE style)
263
290
  Draw *draw;
264
291
 
265
292
  rb_check_frozen(self);
266
- TypedData_Get_Struct(self, Draw, &rm_draw_data_type, draw);
293
+ draw = get_draw(self);
267
294
  VALUE_TO_ENUM(style, draw->info->style, StyleType);
268
295
  return style;
269
296
  }
@@ -283,7 +310,7 @@ Draw_font_weight_eq(VALUE self, VALUE weight)
283
310
  size_t w;
284
311
 
285
312
  rb_check_frozen(self);
286
- TypedData_Get_Struct(self, Draw, &rm_draw_data_type, draw);
313
+ draw = get_draw(self);
287
314
 
288
315
  if (FIXNUM_P(weight))
289
316
  {
@@ -349,7 +376,7 @@ Draw_gravity_eq(VALUE self, VALUE grav)
349
376
  Draw *draw;
350
377
 
351
378
  rb_check_frozen(self);
352
- TypedData_Get_Struct(self, Draw, &rm_draw_data_type, draw);
379
+ draw = get_draw(self);
353
380
  VALUE_TO_ENUM(grav, draw->info->gravity, GravityType);
354
381
 
355
382
  return grav;
@@ -368,7 +395,7 @@ Draw_kerning_eq(VALUE self, VALUE kerning)
368
395
  Draw *draw;
369
396
 
370
397
  rb_check_frozen(self);
371
- TypedData_Get_Struct(self, Draw, &rm_draw_data_type, draw);
398
+ draw = get_draw(self);
372
399
  draw->info->kerning = NUM2DBL(kerning);
373
400
  return kerning;
374
401
  }
@@ -386,7 +413,7 @@ Draw_interline_spacing_eq(VALUE self, VALUE spacing)
386
413
  Draw *draw;
387
414
 
388
415
  rb_check_frozen(self);
389
- TypedData_Get_Struct(self, Draw, &rm_draw_data_type, draw);
416
+ draw = get_draw(self);
390
417
  draw->info->interline_spacing = NUM2DBL(spacing);
391
418
  return spacing;
392
419
  }
@@ -404,7 +431,7 @@ Draw_interword_spacing_eq(VALUE self, VALUE spacing)
404
431
  Draw *draw;
405
432
 
406
433
  rb_check_frozen(self);
407
- TypedData_Get_Struct(self, Draw, &rm_draw_data_type, draw);
434
+ draw = get_draw(self);
408
435
  draw->info->interword_spacing = NUM2DBL(spacing);
409
436
  return spacing;
410
437
  }
@@ -505,7 +532,7 @@ Draw_marshal_dump(VALUE self)
505
532
  Draw *draw;
506
533
  VALUE ddraw;
507
534
 
508
- TypedData_Get_Struct(self, Draw, &rm_draw_data_type, draw);
535
+ draw = get_draw(self);
509
536
 
510
537
  // Raise an exception if the Draw has a non-NULL gradient or element_reference field
511
538
  if (draw->info->element_reference.type != UndefinedReference
@@ -566,6 +593,8 @@ Draw_marshal_load(VALUE self, VALUE ddraw)
566
593
 
567
594
  TypedData_Get_Struct(self, Draw, &rm_draw_data_type, draw);
568
595
 
596
+ Check_Type(ddraw, T_HASH);
597
+
569
598
  if (draw->info == NULL)
570
599
  {
571
600
  ImageInfo *image_info;
@@ -636,7 +665,7 @@ Draw_pointsize_eq(VALUE self, VALUE pointsize)
636
665
  Draw *draw;
637
666
 
638
667
  rb_check_frozen(self);
639
- TypedData_Get_Struct(self, Draw, &rm_draw_data_type, draw);
668
+ draw = get_draw(self);
640
669
  draw->info->pointsize = NUM2DBL(pointsize);
641
670
  return pointsize;
642
671
  }
@@ -656,7 +685,7 @@ Draw_rotation_eq(VALUE self, VALUE deg)
656
685
  AffineMatrix affine, current;
657
686
 
658
687
  rb_check_frozen(self);
659
- TypedData_Get_Struct(self, Draw, &rm_draw_data_type, draw);
688
+ draw = get_draw(self);
660
689
 
661
690
  degrees = NUM2DBL(deg);
662
691
  if (fabs(degrees) > DBL_EPSILON)
@@ -692,7 +721,7 @@ Draw_stroke_eq(VALUE self, VALUE stroke)
692
721
  Draw *draw;
693
722
 
694
723
  rb_check_frozen(self);
695
- TypedData_Get_Struct(self, Draw, &rm_draw_data_type, draw);
724
+ draw = get_draw(self);
696
725
  Color_to_PixelColor(&draw->info->stroke, stroke);
697
726
  return stroke;
698
727
  }
@@ -712,7 +741,7 @@ Draw_stroke_pattern_eq(VALUE self, VALUE pattern)
712
741
  Draw *draw;
713
742
 
714
743
  rb_check_frozen(self);
715
- TypedData_Get_Struct(self, Draw, &rm_draw_data_type, draw);
744
+ draw = get_draw(self);
716
745
 
717
746
  if (draw->info->stroke_pattern != NULL)
718
747
  {
@@ -748,7 +777,7 @@ Draw_stroke_width_eq(VALUE self, VALUE stroke_width)
748
777
  Draw *draw;
749
778
 
750
779
  rb_check_frozen(self);
751
- TypedData_Get_Struct(self, Draw, &rm_draw_data_type, draw);
780
+ draw = get_draw(self);
752
781
  draw->info->stroke_width = NUM2DBL(stroke_width);
753
782
  return stroke_width;
754
783
  }
@@ -766,7 +795,7 @@ Draw_text_antialias_eq(VALUE self, VALUE text_antialias)
766
795
  Draw *draw;
767
796
 
768
797
  rb_check_frozen(self);
769
- TypedData_Get_Struct(self, Draw, &rm_draw_data_type, draw);
798
+ draw = get_draw(self);
770
799
  draw->info->text_antialias = (MagickBooleanType) RTEST(text_antialias);
771
800
  return text_antialias;
772
801
  }
@@ -797,7 +826,7 @@ Draw_undercolor_eq(VALUE self, VALUE undercolor)
797
826
  Draw *draw;
798
827
 
799
828
  rb_check_frozen(self);
800
- TypedData_Get_Struct(self, Draw, &rm_draw_data_type, draw);
829
+ draw = get_draw(self);
801
830
  Color_to_PixelColor(&draw->info->undercolor, undercolor);
802
831
  return undercolor;
803
832
  }
@@ -840,7 +869,7 @@ VALUE Draw_annotate(
840
869
 
841
870
  // Save the affine matrix in case it is modified by
842
871
  // Draw#rotation=
843
- TypedData_Get_Struct(self, Draw, &rm_draw_data_type, draw);
872
+ draw = get_draw(self);
844
873
  keep = draw->info->affine;
845
874
 
846
875
  image_arg = rm_cur_image(image_arg);
@@ -1050,7 +1079,7 @@ Draw_draw(VALUE self, VALUE image_arg)
1050
1079
  image_arg = rm_cur_image(image_arg);
1051
1080
  image = rm_check_frozen(image_arg);
1052
1081
 
1053
- TypedData_Get_Struct(self, Draw, &rm_draw_data_type, draw);
1082
+ draw = get_draw(self);
1054
1083
  if (draw->primitives == 0)
1055
1084
  {
1056
1085
  rb_raise(rb_eArgError, "nothing to draw");
@@ -1257,6 +1286,7 @@ Draw_primitive(VALUE self, VALUE primitive)
1257
1286
  Draw *draw;
1258
1287
 
1259
1288
  rb_check_frozen(self);
1289
+ StringValue(primitive);
1260
1290
  TypedData_Get_Struct(self, Draw, &rm_draw_data_type, draw);
1261
1291
 
1262
1292
  if (draw->primitives == (VALUE)0)
@@ -1463,7 +1493,7 @@ PolaroidOptions_initialize(VALUE self)
1463
1493
  ExceptionInfo *exception;
1464
1494
 
1465
1495
  // Default shadow color
1466
- TypedData_Get_Struct(self, Draw, &rm_draw_data_type, draw);
1496
+ draw = get_draw(self);
1467
1497
 
1468
1498
  exception = AcquireExceptionInfo();
1469
1499
  QueryColorCompliance("gray75", AllCompliance, &draw->shadow_color, exception);
@@ -1525,7 +1555,7 @@ PolaroidOptions_border_color_eq(VALUE self, VALUE border)
1525
1555
  Draw *draw;
1526
1556
 
1527
1557
  rb_check_frozen(self);
1528
- TypedData_Get_Struct(self, Draw, &rm_draw_data_type, draw);
1558
+ draw = get_draw(self);
1529
1559
  Color_to_PixelColor(&draw->info->border_color, border);
1530
1560
  return border;
1531
1561
  }
@@ -1628,7 +1658,7 @@ get_type_metrics(int argc, VALUE *argv, VALUE self, gvl_function_t fp)
1628
1658
  rb_raise(rb_eArgError, "no text to measure");
1629
1659
  }
1630
1660
 
1631
- TypedData_Get_Struct(self, Draw, &rm_draw_data_type, draw);
1661
+ draw = get_draw(self);
1632
1662
  #if defined(IMAGEMAGICK_7)
1633
1663
  exception = AcquireExceptionInfo();
1634
1664
  draw->info->text = InterpretImageProperties(NULL, image, text, exception);
@@ -5630,6 +5630,41 @@ Image_displace(int argc, VALUE *argv, VALUE self)
5630
5630
  }
5631
5631
 
5632
5632
 
5633
+ /**
5634
+ * Compute columns * rows * map_length for a pixel buffer, raising RangeError on
5635
+ * overflow.
5636
+ *
5637
+ * The product is used to size the buffer that ImageMagick fills based on the
5638
+ * (caller-supplied) columns and rows. If the multiplication wrapped around, the
5639
+ * buffer would be allocated too small and ImageMagick would write out of bounds.
5640
+ *
5641
+ * No Ruby usage (internal function)
5642
+ *
5643
+ * @param columns the number of columns
5644
+ * @param rows the number of rows
5645
+ * @param map_length the number of channels per pixel (length of the map string)
5646
+ * @return columns * rows * map_length
5647
+ * @throw RangeError if the multiplication overflows
5648
+ */
5649
+ static size_t
5650
+ pixel_buffer_count(size_t columns, size_t rows, size_t map_length)
5651
+ {
5652
+ size_t pixels;
5653
+
5654
+ if (columns != 0 && rows > SIZE_MAX / columns)
5655
+ {
5656
+ rb_raise(rb_eRangeError, "pixel buffer dimensions too large (%" RMIuSIZE "x%" RMIuSIZE ")", columns, rows);
5657
+ }
5658
+ pixels = columns * rows;
5659
+ if (map_length != 0 && pixels > SIZE_MAX / map_length)
5660
+ {
5661
+ rb_raise(rb_eRangeError, "pixel buffer dimensions too large (%" RMIuSIZE "x%" RMIuSIZE " map=%" RMIuSIZE ")",
5662
+ columns, rows, map_length);
5663
+ }
5664
+ return pixels * map_length;
5665
+ }
5666
+
5667
+
5633
5668
  /**
5634
5669
  * Extract pixel data from the image and returns it as an array of pixels. The "x", "y", "width" and
5635
5670
  * "height" parameters specify the rectangle to be extracted. The "map" parameter reflects the
@@ -5685,7 +5720,7 @@ Image_dispatch(int argc, VALUE *argv, VALUE self)
5685
5720
  }
5686
5721
 
5687
5722
  // Compute the size of the pixel array and allocate the memory.
5688
- npixels = columns * rows * mapL;
5723
+ npixels = pixel_buffer_count(columns, rows, mapL);
5689
5724
  pixels.v = stg_type == QuantumPixel ? (void *) ALLOC_N(Quantum, npixels)
5690
5725
  : (void *) ALLOC_N(double, npixels);
5691
5726
 
@@ -6636,7 +6671,7 @@ Image_export_pixels(int argc, VALUE *argv, VALUE self)
6636
6671
  }
6637
6672
 
6638
6673
 
6639
- npixels = (long)(cols * rows * strlen(map));
6674
+ npixels = (long)pixel_buffer_count(cols, rows, strlen(map));
6640
6675
  pixels = ALLOC_N(Quantum, npixels);
6641
6676
  if (!pixels) // app recovered from exception
6642
6677
  {
@@ -6804,7 +6839,7 @@ Image_export_pixels_to_str(int argc, VALUE *argv, VALUE self)
6804
6839
  }
6805
6840
 
6806
6841
 
6807
- npixels = cols * rows * strlen(map);
6842
+ npixels = pixel_buffer_count(cols, rows, strlen(map));
6808
6843
  switch (type)
6809
6844
  {
6810
6845
  case CharPixel:
@@ -6833,6 +6868,10 @@ Image_export_pixels_to_str(int argc, VALUE *argv, VALUE self)
6833
6868
 
6834
6869
  // Allocate a string long enough to hold the exported pixel data.
6835
6870
  // Get a pointer to the buffer.
6871
+ if (npixels != 0 && sz > (size_t)LONG_MAX / npixels)
6872
+ {
6873
+ rb_raise(rb_eRangeError, "pixel buffer dimensions too large");
6874
+ }
6836
6875
  string = rb_str_new2("");
6837
6876
  rb_str_resize(string, (long)(sz * npixels));
6838
6877
 
@@ -9056,6 +9095,8 @@ Image_marshal_load(VALUE self, VALUE ary)
9056
9095
 
9057
9096
  TypedData_Get_Struct(self, Image, &rm_image_data_type, image);
9058
9097
 
9098
+ Check_Type(ary, T_ARRAY);
9099
+
9059
9100
  filename = rb_ary_shift(ary);
9060
9101
  blob = rb_ary_shift(ary);
9061
9102
 
@@ -1046,6 +1046,9 @@ Pixel_marshal_load(VALUE self, VALUE dpixel)
1046
1046
  Pixel *pixel;
1047
1047
 
1048
1048
  TypedData_Get_Struct(self, Pixel, &rm_pixel_data_type, pixel);
1049
+
1050
+ Check_Type(dpixel, T_HASH);
1051
+
1049
1052
  pixel->red = NUM2QUANTUM(rb_hash_aref(dpixel, CSTR2SYM("red")));
1050
1053
  pixel->green = NUM2QUANTUM(rb_hash_aref(dpixel, CSTR2SYM("green")));
1051
1054
  pixel->blue = NUM2QUANTUM(rb_hash_aref(dpixel, CSTR2SYM("blue")));
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Magick
4
- VERSION = '7.0.4'
4
+ VERSION = '7.0.5'
5
5
  MIN_RUBY_VERSION = '3.2.0'
6
6
  MIN_IM6_VERSION = '6.9.0'
7
7
  MIN_IM7_VERSION = '7.1.0'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rmagick
3
3
  version: !ruby/object:Gem::Version
4
- version: 7.0.4
4
+ version: 7.0.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tim Hunter
@@ -143,7 +143,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
143
143
  version: '0'
144
144
  requirements:
145
145
  - ImageMagick 6.9.0+ (for ImageMagick 6) or 7.1.0+ (for ImageMagick 7)
146
- rubygems_version: 4.0.10
146
+ rubygems_version: 4.0.15
147
147
  specification_version: 4
148
148
  summary: Ruby binding to ImageMagick
149
149
  test_files: []