rmagick 7.0.5 → 7.1.1

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: 6a209cf0d468a316b82b18e0dc8cdfe37d07e3a9a89a54750303c48fddbc4721
4
- data.tar.gz: ec494eed858ad482b7fbc1a3784c471bed373ab2ad1cd3835c99b3c998548736
3
+ metadata.gz: 5ee430e845ae8794dc88e1af56d944fe511321c91eaabdda600810127f522c5e
4
+ data.tar.gz: b8705aec273d52d277bf4f73caeb00c78befdf803426eb14fedc3ddf0028399a
5
5
  SHA512:
6
- metadata.gz: 8879e76297539f5ab7816fb3ba4894530141292fdd828277774d5631655176c717f0888f4624d22f6b7006e9d1b544f7065705220d06df77eadbb428216d6dce
7
- data.tar.gz: 67e8ff6082884e98cf7cf3dfc35eee092377fc2e4a1d60cc6679b9872dc4c52effc6a6ad6b95966a552eb6f15c2b0264ee2580d768dfce0b71a9aa1ee90b866a
6
+ metadata.gz: 48bc5436488b2b05f990e645ab294674b6d176dc584010686098b03b51cae5d67564b47d3ad5532a9001026027c1fb316f6b9b07fd7284c1825b82c5d084c365
7
+ data.tar.gz: 1a389dc68b01846feb575c5dcc3b42988baf99bfef0c03e7231db3d013973e1a74440dac99980295baa72efe5e1d01733a236854b43b6770aa461d7a6ed7e2e0
data/CHANGELOG.md CHANGED
@@ -3,6 +3,51 @@
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.1.1
7
+
8
+ Bug Fixes
9
+
10
+ * Fix Strings being recycled while the C pointers into them are in use (#1847)
11
+
12
+ ## RMagick 7.1.0
13
+
14
+ > [!IMPORTANT]
15
+ > `Draw#annotate` and `Draw#get_type_metrics` no longer interpret the text they are given.
16
+ > A `%[...]` or `%x` escape in it is now drawn as written instead of being replaced by an image property.
17
+ > Everything those escapes provided is available directly from Ruby -- `Image#columns`, `Image#rows`, `Image#format`, `Image#filesize`, `Image#filename`, `Image#[]`, `Image#artifact`, `Image#channel_mean`, `Image#pixel_color` and `Image#fx` -- so build the string in Ruby and pass the result.
18
+ >
19
+ > The interpolation was undocumented, and it handed any caller that passed user-supplied text an expression evaluator, a pixel and metadata reader, and an unbounded CPU sink. It also corrupted ordinary captions: `"%d items"` was drawn as the directory the image had been read from.
20
+
21
+ Breaking Changes
22
+
23
+ * Draw annotation text as given instead of interpreting it (#1843)
24
+ * Draw text starting with '@' instead of reading it from that file (#1837)
25
+ * Validate RVG path data against the SVG path grammar (#1839)
26
+ * Escape values and quote the clip-path and encoding names in the MVG program (#1841)
27
+ * Reject embedded NUL bytes in pathname arguments (#1827)
28
+
29
+ Improvements
30
+
31
+ * Add Image#artifact to read the artifacts Image#define writes (#1842)
32
+ * Fix grammar, typos, and content errors in the documentation (#1824)
33
+
34
+ Bug Fixes
35
+
36
+ * Fix RVG text being quoted twice and the added quotes being drawn (#1840)
37
+ * Fix MVG injection in Draw#text from unescaped backslashes (#1838)
38
+ * Fix memory leak in ImageList#composite_layers with an unusable source list (#1836)
39
+ * Fix heap over-read in Image#import_pixels with a long or empty map (#1835)
40
+ * Fix SEGV from integer overflow in Image#import_pixels geometry (#1834)
41
+ * Fix heap over-read in Image#recolor (#1833)
42
+ * Fix SEGV in Draw#marshal_load with a non-String pattern (#1832)
43
+ * Fix use-after-free of cloned images in images_from_imagelist() (#1831)
44
+ * Fix double free of the interpreted text in Draw#get_type_metrics (#1830)
45
+ * Fix double free of the annotation text in Draw#annotate (#1829)
46
+ * Fix SEGV in Info#stroke_width= and Info#attenuate= with a large Float (#1828)
47
+ * Fix Magick#set_log_event_mask() (#1826)
48
+ * Fix copy_options() using the option value as the artifact key (#1823)
49
+ * Fix unchecked SetImageArtifact() calls (#1822)
50
+
6
51
  ## RMagick 7.0.5
7
52
 
8
53
  Bug Fixes
data/Rakefile CHANGED
@@ -188,6 +188,12 @@ end
188
188
  if RUBY_PLATFORM.include?('linux')
189
189
  require 'ruby_memcheck'
190
190
  require 'ruby_memcheck/rspec/rake_task'
191
+
192
+ RubyMemcheck.config(
193
+ binary_name: 'RMagick2',
194
+ valgrind_suppressions_dir: 'spec/valgrind'
195
+ )
196
+
191
197
  namespace :spec do
192
198
  RubyMemcheck::RSpec::RakeTask.new(valgrind: :compile)
193
199
  end
@@ -123,7 +123,7 @@ module RMagick
123
123
  $LDFLAGS += " #{ldflags} #{rpath}"
124
124
 
125
125
  unless try_link("int main() { }")
126
- # if linker does not recognizes '-Wl,-rpath,somewhere' option, it revert to original option
126
+ # if linker does not recognize '-Wl,-rpath,somewhere' option, it reverts to original option
127
127
  $LDFLAGS = "#{original_ldflags} #{ldflags}"
128
128
  end
129
129
  end
@@ -344,7 +344,7 @@ module RMagick
344
344
  end
345
345
 
346
346
  def print_summary
347
- summary = <<~"END_SUMMARY"
347
+ summary = <<~END_SUMMARY
348
348
  #{'=' * 70}
349
349
  #{Time.now.strftime('%a %d %b %y %T')}
350
350
  This installation of RMagick #{RMAGICK_VERS} is configured for
@@ -312,7 +312,7 @@ Magick_limit_resource(int argc, VALUE *argv, VALUE klass)
312
312
 
313
313
  /**
314
314
  * Set the amount of free memory allocated for the pixel cache. Once this
315
- * threshold is exceeded, all subsequent pixels cache operations are to/from
315
+ * threshold is exceeded, all subsequent pixel cache operations are to/from
316
316
  * disk.
317
317
  *
318
318
  * @param threshold [Numeric] the number of megabytes to set.
@@ -346,23 +346,45 @@ Magick_set_cache_threshold(VALUE klass, VALUE threshold)
346
346
  * - "user"
347
347
  * - "x11"
348
348
  *
349
- * Multiple events can be specified as the aruments. Event names may be capitalized.
349
+ * Multiple events can be specified as the arguments. Event names may be capitalized.
350
350
  *
351
- * @param args [String] the mask of log event.
351
+ * @param args [Array<String>] one or more log event types (comma-separated lists and/or multiple arguments).
352
+ * @raise [ArgumentError] if an event name is invalid
352
353
  */
353
354
  VALUE
354
355
  Magick_set_log_event_mask(int argc, VALUE *argv, VALUE klass)
355
356
  {
357
+ VALUE events;
356
358
  int x;
357
359
 
358
360
  if (argc == 0)
359
361
  {
360
362
  rb_raise(rb_eArgError, "wrong number of arguments (at least 1 required)");
361
363
  }
364
+
365
+ // SetLogEventMask() does not provide a way to check if it failed
366
+ // since it returns the old mask.
362
367
  for (x = 0; x < argc; x++)
363
368
  {
364
- SetLogEventMask(StringValueCStr(argv[x]));
369
+ const char *event = StringValueCStr(argv[x]);
370
+ if (ParseCommandOption(MagickLogEventOptions, MagickTrue, event) == -1)
371
+ {
372
+ rb_raise(rb_eArgError, "invalid log event type: %s", event);
373
+ }
374
+ }
375
+
376
+ // SetLogEventMask() replaces the mask on each call rather than adding to it,
377
+ // so multiple events must be passed as a single comma-separated list.
378
+ events = rb_str_dup(argv[0]);
379
+ for (x = 1; x < argc; x++)
380
+ {
381
+ rb_str_cat_cstr(events, ",");
382
+ rb_str_append(events, argv[x]);
365
383
  }
384
+ SetLogEventMask(StringValueCStr(events));
385
+
386
+ RB_GC_GUARD(events);
387
+
366
388
  return klass;
367
389
  }
368
390
 
@@ -108,10 +108,10 @@ extern "C" {
108
108
  #define NUM2QUANTUM(n) (Quantum)NUM2UINT((n)) /**< Quantum <- Ruby Numeric conversion */
109
109
  #elif (MAGICKCORE_QUANTUM_DEPTH == 32)
110
110
  #define QUANTUM2NUM(q) UINT2NUM((q)) /**< Quantum -> Ruby Numeric conversion */
111
- #define NUM2QUANTUM(n) (Quantum)NUM2UINT((n)) /**< Quntum <- Ruby Numeric conversion */
111
+ #define NUM2QUANTUM(n) (Quantum)NUM2UINT((n)) /**< Quantum <- Ruby Numeric conversion */
112
112
  #elif (MAGICKCORE_QUANTUM_DEPTH == 64)
113
113
  #define QUANTUM2NUM(q) ULL2NUM((q)) /**< Quantum -> Ruby Numeric conversion */
114
- #define NUM2QUANTUM(n) (Quantum)NUM2ULL((n)) /**< Quntum <- Ruby Numeric conversion */
114
+ #define NUM2QUANTUM(n) (Quantum)NUM2ULL((n)) /**< Quantum <- Ruby Numeric conversion */
115
115
  #else
116
116
  #error Specified MAGICKCORE_QUANTUM_DEPTH is not supported.
117
117
  #endif
@@ -247,7 +247,7 @@ typedef enum {
247
247
  //! Draw#text_anchor AnchorType argument
248
248
  typedef enum {
249
249
  StartAnchor = 1, /**< start */
250
- MiddleAnchor = 2, /**< midle */
250
+ MiddleAnchor = 2, /**< middle */
251
251
  EndAnchor = 3 /**< end */
252
252
  } AnchorType;
253
253
 
@@ -813,6 +813,7 @@ extern VALUE Image_affine_transform(VALUE, VALUE);
813
813
  extern VALUE Image_alpha(int, VALUE *, VALUE);
814
814
  extern VALUE Image_alpha_q(VALUE);
815
815
  extern VALUE Image_aref(VALUE, VALUE);
816
+ extern VALUE Image_artifact(VALUE, VALUE);
816
817
  extern VALUE Image_aset(VALUE, VALUE, VALUE);
817
818
  extern VALUE Image_auto_gamma_channel(int, VALUE *, VALUE);
818
819
  extern VALUE Image_auto_level_channel(int, VALUE *, VALUE);
@@ -1162,7 +1163,8 @@ extern void rm_check_ary_len(VALUE, long);
1162
1163
  extern VALUE rm_check_ary_type(VALUE ary);
1163
1164
  extern Image *rm_check_destroyed(VALUE);
1164
1165
  extern Image *rm_check_frozen(VALUE);
1165
- extern char *rm_str2cstr(VALUE, size_t *);
1166
+ extern char *rm_str2cstr(VALUE *, size_t *);
1167
+ extern char *rm_path2cstr(VALUE *, size_t *);
1166
1168
  extern int rm_check_num2dbl(VALUE);
1167
1169
  extern double rm_fuzz_to_dbl(VALUE);
1168
1170
  extern Quantum rm_app2quantum(VALUE);
@@ -500,6 +500,8 @@ Image *str_to_image(VALUE str)
500
500
  Info *info;
501
501
  ExceptionInfo *exception;
502
502
 
503
+ StringValue(str);
504
+
503
505
  info = CloneImageInfo(NULL);
504
506
  exception = AcquireExceptionInfo();
505
507
  GVL_STRUCT_TYPE(BlobToImage) args = { info, RSTRING_PTR(str), (size_t)RSTRING_LEN(str), exception };
@@ -509,6 +511,8 @@ Image *str_to_image(VALUE str)
509
511
  DestroyExceptionInfo(exception);
510
512
  }
511
513
 
514
+ RB_GC_GUARD(str);
515
+
512
516
  return image;
513
517
  }
514
518
 
@@ -836,7 +840,7 @@ Draw_undercolor_eq(VALUE self, VALUE undercolor)
836
840
  * Annotates an image with text.
837
841
  *
838
842
  * - Additional Draw attribute methods may be called in the optional block,
839
- * which is executed in the context of an Draw object.
843
+ * which is executed in the context of a Draw object.
840
844
  *
841
845
  * @param image_arg [Magick::Image, Magick::ImageList] Either an imagelist or an image. If an
842
846
  * imagelist, uses the current image.
@@ -882,29 +886,15 @@ VALUE Draw_annotate(
882
886
  rb_yield(self);
883
887
  }
884
888
 
885
- // Translate & store in Draw structure
889
+ // Store in Draw structure. The text is drawn as given: it is not run
890
+ // through InterpretImageProperties(), so a `%[...]` or `%x` escape in it is
891
+ // not expanded. Everything those escapes provide is available directly from
892
+ // Ruby -- Image#columns, Image#filename, Image#artifact and so on.
886
893
  embed_text = StringValueCStr(text);
894
+ draw->info->text = ConstantString(embed_text);
887
895
  #if defined(IMAGEMAGICK_7)
888
896
  exception = AcquireExceptionInfo();
889
- draw->info->text = InterpretImageProperties(NULL, image, embed_text, exception);
890
- if (rm_should_raise_exception(exception, RetainExceptionRetention))
891
- {
892
- if (draw->info->text)
893
- {
894
- magick_free(draw->info->text);
895
- }
896
- rm_raise_exception(exception);
897
- }
898
- #else
899
- draw->info->text = InterpretImageProperties(NULL, image, embed_text);
900
897
  #endif
901
- if (!draw->info->text)
902
- {
903
- #if defined(IMAGEMAGICK_7)
904
- DestroyExceptionInfo(exception);
905
- #endif
906
- rb_raise(rb_eArgError, "no text");
907
- }
908
898
 
909
899
  // Create geometry string, copy to Draw structure, overriding
910
900
  // any previously existing value.
@@ -1147,7 +1137,7 @@ Draw_dup(VALUE self)
1147
1137
  * imagelist, uses the current image.
1148
1138
  * @param text [String] The string to be rendered.
1149
1139
  *
1150
- * @return [Magick::TypeMetric] The information for a specific string if rendered on a image.
1140
+ * @return [Magick::TypeMetric] The information for a specific string if rendered on an image.
1151
1141
  */
1152
1142
  VALUE
1153
1143
  Draw_get_type_metrics(
@@ -1174,7 +1164,7 @@ Draw_get_type_metrics(
1174
1164
  * imagelist, uses the current image.
1175
1165
  * @param text [String] The string to be rendered.
1176
1166
  *
1177
- * @return [Magick::TypeMetric] The information for a specific string if rendered on a image.
1167
+ * @return [Magick::TypeMetric] The information for a specific string if rendered on an image.
1178
1168
  */
1179
1169
  VALUE
1180
1170
  Draw_get_multiline_type_metrics(
@@ -1340,7 +1330,7 @@ Draw_mark(void *drawptr)
1340
1330
 
1341
1331
 
1342
1332
  /**
1343
- * Free the memory associated with an Draw object.
1333
+ * Free the memory associated with a Draw object.
1344
1334
  *
1345
1335
  * No Ruby usage (internal function)
1346
1336
  *
@@ -1401,7 +1391,7 @@ new_DrawOptions(void)
1401
1391
  /**
1402
1392
  * Create a DrawOptions object.
1403
1393
  *
1404
- * - The DrawOptions class is the same as the Draw class except is has only
1394
+ * - The DrawOptions class is the same as the Draw class except it has only
1405
1395
  * the attribute writer functions
1406
1396
  *
1407
1397
  * @return [Magick::Image::DrawOptions] a new DrawOptions object
@@ -1629,6 +1619,7 @@ get_type_metrics(int argc, VALUE *argv, VALUE self, gvl_function_t fp)
1629
1619
  Image *image;
1630
1620
  Draw *draw;
1631
1621
  VALUE t;
1622
+ VALUE text_arg = Qnil;
1632
1623
  TypeMetric metrics;
1633
1624
  char *text = NULL;
1634
1625
  size_t text_l;
@@ -1640,13 +1631,15 @@ get_type_metrics(int argc, VALUE *argv, VALUE self, gvl_function_t fp)
1640
1631
  switch (argc)
1641
1632
  {
1642
1633
  case 1: // use default image
1643
- text = rm_str2cstr(argv[0], &text_l);
1634
+ text_arg = argv[0];
1635
+ text = rm_str2cstr(&text_arg, &text_l);
1644
1636
  TypedData_Get_Struct(get_dummy_tm_img(CLASS_OF(self)), Image, &rm_image_data_type, image);
1645
1637
  break;
1646
1638
  case 2:
1647
1639
  t = rm_cur_image(argv[0]);
1648
1640
  image = rm_check_destroyed(t);
1649
- text = rm_str2cstr(argv[1], &text_l);
1641
+ text_arg = argv[1];
1642
+ text = rm_str2cstr(&text_arg, &text_l);
1650
1643
  break; // okay
1651
1644
  default:
1652
1645
  rb_raise(rb_eArgError, "wrong number of arguments (%d for 1 or 2)", argc);
@@ -1659,29 +1652,11 @@ get_type_metrics(int argc, VALUE *argv, VALUE self, gvl_function_t fp)
1659
1652
  }
1660
1653
 
1661
1654
  draw = get_draw(self);
1662
- #if defined(IMAGEMAGICK_7)
1663
- exception = AcquireExceptionInfo();
1664
- draw->info->text = InterpretImageProperties(NULL, image, text, exception);
1665
- if (rm_should_raise_exception(exception, RetainExceptionRetention))
1666
- {
1667
- if (draw->info->text)
1668
- {
1669
- magick_free(draw->info->text);
1670
- }
1671
- rm_raise_exception(exception);
1672
- }
1673
- #else
1674
- draw->info->text = InterpretImageProperties(NULL, image, text);
1675
- #endif
1676
- if (!draw->info->text)
1677
- {
1678
- #if defined(IMAGEMAGICK_7)
1679
- DestroyExceptionInfo(exception);
1680
- #endif
1681
- rb_raise(rb_eArgError, "no text to measure");
1682
- }
1655
+ // Measured as given: see the comment in Draw_annotate().
1656
+ draw->info->text = ConstantString(text);
1683
1657
 
1684
1658
  #if defined(IMAGEMAGICK_7)
1659
+ exception = AcquireExceptionInfo();
1685
1660
  GVL_STRUCT_TYPE(get_type_metrics) args = { image, draw->info, &metrics, exception };
1686
1661
  #else
1687
1662
  GVL_STRUCT_TYPE(get_type_metrics) args = { image, draw->info, &metrics };
@@ -1710,6 +1685,7 @@ get_type_metrics(int argc, VALUE *argv, VALUE self, gvl_function_t fp)
1710
1685
  #endif
1711
1686
 
1712
1687
  RB_GC_GUARD(t);
1688
+ RB_GC_GUARD(text_arg);
1713
1689
 
1714
1690
  return Import_TypeMetric(&metrics);
1715
1691
  }
@@ -219,7 +219,7 @@ Enum_spaceship(VALUE self, VALUE other)
219
219
  /**
220
220
  * Bitwise OR for enums
221
221
  *
222
- * @param another [Magick::Enum] the another enum
222
+ * @param another [Magick::Enum] the other enum
223
223
  * @return [Magick::Enum] new Enum instance
224
224
  */
225
225
  VALUE
@@ -361,7 +361,7 @@ Enum_type_values(VALUE klass)
361
361
  *
362
362
  * @param klass the class type
363
363
  * @param value the value for enum
364
- * @return a enumerator
364
+ * @return an enumerator
365
365
  */
366
366
 
367
367
  VALUE
@@ -541,7 +541,7 @@ CompressionType_find(CompressionType ct)
541
541
 
542
542
 
543
543
  /**
544
- * Returns a DisposeType enum object for the specified value..new.
544
+ * Returns a DisposeType enum object for the specified value.
545
545
  *
546
546
  * No Ruby usage (internal function)
547
547
  *
@@ -661,7 +661,7 @@ PixelInterpolateMethod_find(PixelInterpolateMethod interpolate)
661
661
 
662
662
 
663
663
  /**
664
- * Construct an RenderingIntent enum object for the specified value.
664
+ * Construct a RenderingIntent enum object for the specified value.
665
665
  *
666
666
  * No Ruby usage (internal function)
667
667
  *
@@ -785,7 +785,7 @@ StyleType_find(StyleType style)
785
785
  *
786
786
  * No Ruby usage (internal function)
787
787
  *
788
- * @param style theVirtualPixelMethod
788
+ * @param style the VirtualPixelMethod
789
789
  * @return a new VirtualPixelMethod enumerator
790
790
  */
791
791
  VALUE