rmagick 7.0.2 → 7.0.4

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: '08ddd337d97e120559c7795dd051433b1453f7c420777083bf0ba29c094659b2'
4
- data.tar.gz: 06e68a270014d1a93bc4873723e82f2a83144086d33c3329ff583ea357694af4
3
+ metadata.gz: a6b67e7280c692114f508e96e6ddcf8d554825ba3705e917af4484158aba940f
4
+ data.tar.gz: 2ec01a3108eda0eebe35603ae94f675b0966343d5ccb8b2461706b67ea4f3e2c
5
5
  SHA512:
6
- metadata.gz: 8b21f2dacdd58215e7fdfe7cce5c057280c8450d77fdab2b5e6bf48b2d5ba4995309b54054db4e06537ea6bc496b9e4126a2fe2462704caeaeec3be520ce94f5
7
- data.tar.gz: 46e1f9816246476793cdf5f71c33abb794212a0d1935dcf81ec6a83aeb1a3668a6248cf1d7d8ad8993a758c3e129835f2cd8a4f5f5d2c0a695328a271869db29
6
+ metadata.gz: 1494b9956d04b5f569a39df7e436cae2cc361b093d8fc4339e7b6f56f893e0782f0e506d24faf807d8cc88c7fff697894b39f29cf651666ff1398d8bf421ed4a
7
+ data.tar.gz: 06e999110504c4ab2fc1c0ddbd9e43b7415c70173780e127d25132ad0d1e5f172622a445f61922800994ef6aed543f141d984602430f0db8ce0b48fafb2974b0
data/CHANGELOG.md CHANGED
@@ -3,6 +3,23 @@
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.4
7
+
8
+ Bug Fixes
9
+
10
+ * Fix report size in rm_kernel_info_memsize (#1808)
11
+ * Fix NULL dereference in KernelInfo instance methods (#1807)
12
+ * Fix memory leak and NULL deref in Image#properties (#1806)
13
+ * Fix memory leak when string conversion raises (#1805)
14
+ * Fix error handling in Pixel#to_color when QueryColorname fails (#1800)
15
+ * Reject NAN in Pixel#from_hsla() (#1798)
16
+
17
+ ## RMagick 7.0.3
18
+
19
+ Bug Fixes
20
+
21
+ * Fix potential stack buffer overflows in format_exception and add_format_prefix (#1796)
22
+
6
23
  ## RMagick 7.0.2
7
24
 
8
25
  Bug Fixes
data/README.md CHANGED
@@ -3,6 +3,7 @@ RMagick
3
3
 
4
4
  [![GemVersion](https://img.shields.io/gem/v/rmagick.svg?style=flat)](https://rubygems.org/gems/rmagick)
5
5
  ![CI](https://github.com/rmagick/rmagick/workflows/CI/badge.svg)
6
+ [![Ask DeepWiki](https://deepwiki.com/badge.svg)](https://deepwiki.com/rmagick/rmagick)
6
7
 
7
8
  Table of Contents
8
9
  -----------------
@@ -5355,16 +5355,17 @@ VALUE
5355
5355
  Image_delete_profile(VALUE self, VALUE name)
5356
5356
  {
5357
5357
  Image *image = rm_check_frozen(self);
5358
+ char *profile_name = StringValueCStr(name);
5358
5359
 
5359
5360
  #if defined(IMAGEMAGICK_7)
5360
5361
  ExceptionInfo *exception = AcquireExceptionInfo();
5361
5362
 
5362
- GVL_STRUCT_TYPE(ProfileImage) args = { image, StringValueCStr(name), NULL, 0, exception };
5363
+ GVL_STRUCT_TYPE(ProfileImage) args = { image, profile_name, NULL, 0, exception };
5363
5364
  CALL_FUNC_WITHOUT_GVL(GVL_FUNC(ProfileImage), &args);
5364
5365
  CHECK_EXCEPTION();
5365
5366
  DestroyExceptionInfo(exception);
5366
5367
  #else
5367
- GVL_STRUCT_TYPE(ProfileImage) args = { image, StringValueCStr(name), NULL, 0, MagickTrue };
5368
+ GVL_STRUCT_TYPE(ProfileImage) args = { image, profile_name, NULL, 0, MagickTrue };
5368
5369
  CALL_FUNC_WITHOUT_GVL(GVL_FUNC(ProfileImage), &args);
5369
5370
  #endif
5370
5371
  return self;
@@ -12838,7 +12839,12 @@ Image_properties(VALUE self)
12838
12839
 
12839
12840
  if (rb_block_given_p())
12840
12841
  {
12841
- ary = rb_ary_new2(2);
12842
+ long i;
12843
+
12844
+ // Collect the properties first so that neither the ExceptionInfo nor
12845
+ // the property iterator is held across rb_yield. The block may break
12846
+ // or raise, which would otherwise leak the ExceptionInfo.
12847
+ ary = rb_ary_new();
12842
12848
 
12843
12849
  ResetImagePropertyIterator(image);
12844
12850
  property = GetNextImageProperty(image);
@@ -12849,9 +12855,7 @@ Image_properties(VALUE self)
12849
12855
  #else
12850
12856
  value = GetImageProperty(image, property);
12851
12857
  #endif
12852
- rb_ary_store(ary, 0, rb_str_new2(property));
12853
- rb_ary_store(ary, 1, rb_str_new2(value));
12854
- rb_yield(ary);
12858
+ rb_ary_push(ary, rb_assoc_new(rb_str_new2(property), value ? rb_str_new2(value) : Qnil));
12855
12859
  property = GetNextImageProperty(image);
12856
12860
  }
12857
12861
  #if defined(IMAGEMAGICK_7)
@@ -12861,6 +12865,11 @@ Image_properties(VALUE self)
12861
12865
  rm_check_image_exception(image, RetainOnError);
12862
12866
  #endif
12863
12867
 
12868
+ for (i = 0; i < RARRAY_LEN(ary); i++)
12869
+ {
12870
+ rb_yield(rb_ary_entry(ary, i));
12871
+ }
12872
+
12864
12873
  RB_GC_GUARD(ary);
12865
12874
 
12866
12875
  return self;
@@ -12879,7 +12888,7 @@ Image_properties(VALUE self)
12879
12888
  #else
12880
12889
  value = GetImageProperty(image, property);
12881
12890
  #endif
12882
- rb_hash_aset(attr_hash, rb_str_new2(property), rb_str_new2(value));
12891
+ rb_hash_aset(attr_hash, rb_str_new2(property), value ? rb_str_new2(value) : Qnil);
12883
12892
  property = GetNextImageProperty(image);
12884
12893
  }
12885
12894
  #if defined(IMAGEMAGICK_7)
@@ -15833,6 +15842,9 @@ void add_format_prefix(Info *info, VALUE file)
15833
15842
  {
15834
15843
  memset(magic, '\0', sizeof(magic));
15835
15844
  magic_l = p - filename;
15845
+ if (magic_l >= sizeof(magic)) {
15846
+ magic_l = sizeof(magic) - 1;
15847
+ }
15836
15848
  memcpy(magic, filename, magic_l);
15837
15849
 
15838
15850
  exception = AcquireExceptionInfo();
@@ -51,7 +51,21 @@ rm_kernel_info_destroy(void *kernel)
51
51
  static size_t
52
52
  rm_kernel_info_memsize(const void *ptr)
53
53
  {
54
- return sizeof(KernelInfo);
54
+ const KernelInfo *kernel = (const KernelInfo *)ptr;
55
+ size_t size = 0;
56
+
57
+ // A KernelInfo may be a linked list of kernels, each owning a values array.
58
+ while (kernel)
59
+ {
60
+ size += sizeof(KernelInfo);
61
+ if (kernel->values)
62
+ {
63
+ size += kernel->width * kernel->height * sizeof(*kernel->values);
64
+ }
65
+ kernel = kernel->next;
66
+ }
67
+
68
+ return size;
55
69
  }
56
70
 
57
71
  /**
@@ -105,6 +119,32 @@ KernelInfo_initialize(VALUE self, VALUE kernel_string)
105
119
  }
106
120
 
107
121
 
122
+ /**
123
+ * Return the KernelInfo struct associated with the object, raising an
124
+ * exception if the object has not been initialized (for example, when it was
125
+ * created with KernelInfo.allocate or a previous initialize failed). Without
126
+ * this guard a NULL pointer would be handed to ImageMagick, causing a crash.
127
+ *
128
+ * No Ruby usage (internal function)
129
+ *
130
+ * @param self the KernelInfo object
131
+ * @return the KernelInfo struct
132
+ * @throw RuntimeError if the kernel has not been initialized
133
+ */
134
+ static KernelInfo *
135
+ get_kernel_info(VALUE self)
136
+ {
137
+ KernelInfo *kernel;
138
+
139
+ TypedData_Get_Struct(self, KernelInfo, &rm_kernel_info_data_type, kernel);
140
+ if (!kernel)
141
+ {
142
+ rb_raise(rb_eRuntimeError, "KernelInfo has not been initialized");
143
+ }
144
+ return kernel;
145
+ }
146
+
147
+
108
148
  /**
109
149
  * Adds a given amount of the 'Unity' Convolution Kernel to the given pre-scaled and normalized Kernel.
110
150
  *
@@ -113,7 +153,7 @@ KernelInfo_initialize(VALUE self, VALUE kernel_string)
113
153
  VALUE
114
154
  KernelInfo_unity_add(VALUE self, VALUE scale)
115
155
  {
116
- GVL_STRUCT_TYPE(UnityAddKernelInfo) args = { (KernelInfo*)DATA_PTR(self), NUM2DBL(scale) };
156
+ GVL_STRUCT_TYPE(UnityAddKernelInfo) args = { get_kernel_info(self), NUM2DBL(scale) };
117
157
  CALL_FUNC_WITHOUT_GVL(GVL_FUNC(UnityAddKernelInfo), &args);
118
158
  return Qnil;
119
159
  }
@@ -134,7 +174,7 @@ KernelInfo_scale(VALUE self, VALUE scale, VALUE flags)
134
174
 
135
175
  VALUE_TO_ENUM(flags, geoflags, GeometryFlags);
136
176
 
137
- GVL_STRUCT_TYPE(ScaleKernelInfo) args = { (KernelInfo*)DATA_PTR(self), NUM2DBL(scale), geoflags };
177
+ GVL_STRUCT_TYPE(ScaleKernelInfo) args = { get_kernel_info(self), NUM2DBL(scale), geoflags };
138
178
  CALL_FUNC_WITHOUT_GVL(GVL_FUNC(ScaleKernelInfo), &args);
139
179
  return Qnil;
140
180
  }
@@ -148,7 +188,7 @@ KernelInfo_scale(VALUE self, VALUE scale, VALUE flags)
148
188
  VALUE
149
189
  KernelInfo_scale_geometry(VALUE self, VALUE geometry)
150
190
  {
151
- GVL_STRUCT_TYPE(ScaleGeometryKernelInfo) args = { (KernelInfo*)DATA_PTR(self), StringValueCStr(geometry) };
191
+ GVL_STRUCT_TYPE(ScaleGeometryKernelInfo) args = { get_kernel_info(self), StringValueCStr(geometry) };
152
192
  CALL_FUNC_WITHOUT_GVL(GVL_FUNC(ScaleGeometryKernelInfo), &args);
153
193
  return Qnil;
154
194
  }
@@ -161,7 +201,7 @@ KernelInfo_scale_geometry(VALUE self, VALUE geometry)
161
201
  VALUE
162
202
  KernelInfo_clone(VALUE self)
163
203
  {
164
- KernelInfo *kernel = CloneKernelInfo((KernelInfo*)DATA_PTR(self));
204
+ KernelInfo *kernel = CloneKernelInfo(get_kernel_info(self));
165
205
  if (!kernel)
166
206
  {
167
207
  rb_raise(rb_eNoMemError, "not enough memory to continue");
@@ -473,8 +473,8 @@ Color_Name_to_PixelColor(PixelColor *color, VALUE name_arg)
473
473
  char *name;
474
474
  ExceptionInfo *exception;
475
475
 
476
- exception = AcquireExceptionInfo();
477
476
  name = StringValueCStr(name_arg);
477
+ exception = AcquireExceptionInfo();
478
478
  okay = QueryColorCompliance(name, AllCompliance, color, exception);
479
479
  DestroyExceptionInfo(exception);
480
480
  if (!okay)
@@ -683,15 +683,16 @@ Pixel_from_color(VALUE klass ATTRIBUTE_UNUSED, VALUE name)
683
683
  PixelColor pp;
684
684
  ExceptionInfo *exception;
685
685
  MagickBooleanType okay;
686
+ char *color = StringValueCStr(name);
686
687
 
687
688
  exception = AcquireExceptionInfo();
688
- okay = QueryColorCompliance(StringValueCStr(name), AllCompliance, &pp, exception);
689
+ okay = QueryColorCompliance(color, AllCompliance, &pp, exception);
689
690
  CHECK_EXCEPTION();
690
691
  DestroyExceptionInfo(exception);
691
692
 
692
693
  if (!okay)
693
694
  {
694
- rb_raise(rb_eArgError, "invalid color name: %s", StringValueCStr(name));
695
+ rb_raise(rb_eArgError, "invalid color name: %s", color);
695
696
  }
696
697
 
697
698
  return Pixel_from_PixelColor(&pp);
@@ -739,19 +740,19 @@ Pixel_from_hsla(int argc, VALUE *argv, VALUE klass ATTRIBUTE_UNUSED)
739
740
  break;
740
741
  }
741
742
 
742
- if (alpha && (a < 0.0 || a > 1.0))
743
+ if (alpha && !(a >= 0.0 && a <= 1.0))
743
744
  {
744
745
  rb_raise(rb_eRangeError, "alpha %g out of range [0.0, 1.0]", a);
745
746
  }
746
- if (l < 0.0 || l > 255.0)
747
+ if (!(l >= 0.0 && l <= 255.0))
747
748
  {
748
749
  rb_raise(rb_eRangeError, "lightness %g out of range [0.0, 255.0]", l);
749
750
  }
750
- if (s < 0.0 || s > 255.0)
751
+ if (!(s >= 0.0 && s <= 255.0))
751
752
  {
752
753
  rb_raise(rb_eRangeError, "saturation %g out of range [0.0, 255.0]", s);
753
754
  }
754
- if (h < 0.0 || h >= 360.0)
755
+ if (!(h >= 0.0 && h < 360.0))
755
756
  {
756
757
  rb_raise(rb_eRangeError, "hue %g out of range [0.0, 360.0)", h);
757
758
  }
@@ -1269,8 +1270,7 @@ Pixel_to_color(int argc, VALUE *argv, VALUE self)
1269
1270
  rm_init_magickpixel(image, &mpp);
1270
1271
  rm_set_magick_pixel_packet(pixel, &mpp);
1271
1272
 
1272
- // Support for hex-format color names moved out of QueryMagickColorname
1273
- // in 6.4.1-9. The 'hex' argument was removed as well.
1273
+ MagickBooleanType okay = MagickTrue;
1274
1274
  if (hex)
1275
1275
  {
1276
1276
  if (compliance == XPMCompliance)
@@ -1286,14 +1286,18 @@ Pixel_to_color(int argc, VALUE *argv, VALUE self)
1286
1286
  }
1287
1287
  else
1288
1288
  {
1289
- QueryColorname(image, &mpp, compliance, name, exception);
1289
+ okay = QueryColorname(image, &mpp, compliance, name, exception);
1290
1290
  }
1291
1291
 
1292
1292
  DestroyImage(image);
1293
1293
  CHECK_EXCEPTION();
1294
1294
  DestroyExceptionInfo(exception);
1295
1295
 
1296
- // Always return a string, even if it's ""
1296
+ if (!okay)
1297
+ {
1298
+ rb_raise(Class_ImageMagickError, "QueryColorname failed (unsupported colorspace)");
1299
+ }
1300
+
1297
1301
  return rb_str_new2(name);
1298
1302
  }
1299
1303
 
@@ -1574,15 +1574,11 @@ rm_check_image_exception(Image *imglist, ErrorRetention retention)
1574
1574
  static void
1575
1575
  format_exception(const ExceptionType severity, const char *reason, const char *description, char *msg)
1576
1576
  {
1577
- int len;
1578
1577
  memset(msg, 0, ERROR_MSG_SIZE);
1579
-
1580
- len = snprintf(msg, ERROR_MSG_SIZE, "%s%s%s",
1578
+ snprintf(msg, ERROR_MSG_SIZE, "%s%s%s",
1581
1579
  GetLocaleExceptionMessage(severity, reason),
1582
1580
  description ? ": " : "",
1583
1581
  description ? GetLocaleExceptionMessage(severity, description) : "");
1584
-
1585
- msg[len] = '\0';
1586
1582
  }
1587
1583
 
1588
1584
 
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Magick
4
- VERSION = '7.0.2'
4
+ VERSION = '7.0.4'
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.2
4
+ version: 7.0.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tim Hunter