rmagick 7.0.5 → 7.1.0

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: c56286daf220fd8db82fce268ce2116705e192b643641cc88b4d7e53b6a46d1a
4
+ data.tar.gz: 1a060762de65e6bf6a384a7f10c3036f85d6876ec89c1be54fede6ea4f20e604
5
5
  SHA512:
6
- metadata.gz: 8879e76297539f5ab7816fb3ba4894530141292fdd828277774d5631655176c717f0888f4624d22f6b7006e9d1b544f7065705220d06df77eadbb428216d6dce
7
- data.tar.gz: 67e8ff6082884e98cf7cf3dfc35eee092377fc2e4a1d60cc6679b9872dc4c52effc6a6ad6b95966a552eb6f15c2b0264ee2580d768dfce0b71a9aa1ee90b866a
6
+ metadata.gz: c7ebbec352d94fdeb8873353c8c13a8d3432b2f89c26c05a8520ee56353c1daedde3717429ad6ec1b9c66a9d9ca71eb51c498833ea0e7419fb572f38642d4fcd
7
+ data.tar.gz: c7a7941f288dd513f5ab88d009011c07575fc07e95c772fd3950db9d8828738c7ab49e6fa3484a4ead018ecbe0a002b260f4e0c670c70647aac11419465f09a5
data/CHANGELOG.md CHANGED
@@ -3,6 +3,45 @@
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.0
7
+
8
+ > [!IMPORTANT]
9
+ > `Draw#annotate` and `Draw#get_type_metrics` no longer interpret the text they are given.
10
+ > A `%[...]` or `%x` escape in it is now drawn as written instead of being replaced by an image property.
11
+ > 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.
12
+ >
13
+ > 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.
14
+
15
+ Breaking Changes
16
+
17
+ * Draw annotation text as given instead of interpreting it (#1843)
18
+ * Draw text starting with '@' instead of reading it from that file (#1837)
19
+ * Validate RVG path data against the SVG path grammar (#1839)
20
+ * Escape values and quote the clip-path and encoding names in the MVG program (#1841)
21
+ * Reject embedded NUL bytes in pathname arguments (#1827)
22
+
23
+ Improvements
24
+
25
+ * Add Image#artifact to read the artifacts Image#define writes (#1842)
26
+ * Fix grammar, typos, and content errors in the documentation (#1824)
27
+
28
+ Bug Fixes
29
+
30
+ * Fix RVG text being quoted twice and the added quotes being drawn (#1840)
31
+ * Fix MVG injection in Draw#text from unescaped backslashes (#1838)
32
+ * Fix memory leak in ImageList#composite_layers with an unusable source list (#1836)
33
+ * Fix heap over-read in Image#import_pixels with a long or empty map (#1835)
34
+ * Fix SEGV from integer overflow in Image#import_pixels geometry (#1834)
35
+ * Fix heap over-read in Image#recolor (#1833)
36
+ * Fix SEGV in Draw#marshal_load with a non-String pattern (#1832)
37
+ * Fix use-after-free of cloned images in images_from_imagelist() (#1831)
38
+ * Fix double free of the interpreted text in Draw#get_type_metrics (#1830)
39
+ * Fix double free of the annotation text in Draw#annotate (#1829)
40
+ * Fix SEGV in Info#stroke_width= and Info#attenuate= with a large Float (#1828)
41
+ * Fix Magick#set_log_event_mask() (#1826)
42
+ * Fix copy_options() using the option value as the artifact key (#1823)
43
+ * Fix unchecked SetImageArtifact() calls (#1822)
44
+
6
45
  ## RMagick 7.0.5
7
46
 
8
47
  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);
@@ -1163,6 +1164,7 @@ 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
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 };
@@ -836,7 +838,7 @@ Draw_undercolor_eq(VALUE self, VALUE undercolor)
836
838
  * Annotates an image with text.
837
839
  *
838
840
  * - Additional Draw attribute methods may be called in the optional block,
839
- * which is executed in the context of an Draw object.
841
+ * which is executed in the context of a Draw object.
840
842
  *
841
843
  * @param image_arg [Magick::Image, Magick::ImageList] Either an imagelist or an image. If an
842
844
  * imagelist, uses the current image.
@@ -882,29 +884,15 @@ VALUE Draw_annotate(
882
884
  rb_yield(self);
883
885
  }
884
886
 
885
- // Translate & store in Draw structure
887
+ // Store in Draw structure. The text is drawn as given: it is not run
888
+ // through InterpretImageProperties(), so a `%[...]` or `%x` escape in it is
889
+ // not expanded. Everything those escapes provide is available directly from
890
+ // Ruby -- Image#columns, Image#filename, Image#artifact and so on.
886
891
  embed_text = StringValueCStr(text);
892
+ draw->info->text = ConstantString(embed_text);
887
893
  #if defined(IMAGEMAGICK_7)
888
894
  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
895
  #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
896
 
909
897
  // Create geometry string, copy to Draw structure, overriding
910
898
  // any previously existing value.
@@ -1147,7 +1135,7 @@ Draw_dup(VALUE self)
1147
1135
  * imagelist, uses the current image.
1148
1136
  * @param text [String] The string to be rendered.
1149
1137
  *
1150
- * @return [Magick::TypeMetric] The information for a specific string if rendered on a image.
1138
+ * @return [Magick::TypeMetric] The information for a specific string if rendered on an image.
1151
1139
  */
1152
1140
  VALUE
1153
1141
  Draw_get_type_metrics(
@@ -1174,7 +1162,7 @@ Draw_get_type_metrics(
1174
1162
  * imagelist, uses the current image.
1175
1163
  * @param text [String] The string to be rendered.
1176
1164
  *
1177
- * @return [Magick::TypeMetric] The information for a specific string if rendered on a image.
1165
+ * @return [Magick::TypeMetric] The information for a specific string if rendered on an image.
1178
1166
  */
1179
1167
  VALUE
1180
1168
  Draw_get_multiline_type_metrics(
@@ -1340,7 +1328,7 @@ Draw_mark(void *drawptr)
1340
1328
 
1341
1329
 
1342
1330
  /**
1343
- * Free the memory associated with an Draw object.
1331
+ * Free the memory associated with a Draw object.
1344
1332
  *
1345
1333
  * No Ruby usage (internal function)
1346
1334
  *
@@ -1401,7 +1389,7 @@ new_DrawOptions(void)
1401
1389
  /**
1402
1390
  * Create a DrawOptions object.
1403
1391
  *
1404
- * - The DrawOptions class is the same as the Draw class except is has only
1392
+ * - The DrawOptions class is the same as the Draw class except it has only
1405
1393
  * the attribute writer functions
1406
1394
  *
1407
1395
  * @return [Magick::Image::DrawOptions] a new DrawOptions object
@@ -1659,29 +1647,11 @@ get_type_metrics(int argc, VALUE *argv, VALUE self, gvl_function_t fp)
1659
1647
  }
1660
1648
 
1661
1649
  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
- }
1650
+ // Measured as given: see the comment in Draw_annotate().
1651
+ draw->info->text = ConstantString(text);
1683
1652
 
1684
1653
  #if defined(IMAGEMAGICK_7)
1654
+ exception = AcquireExceptionInfo();
1685
1655
  GVL_STRUCT_TYPE(get_type_metrics) args = { image, draw->info, &metrics, exception };
1686
1656
  #else
1687
1657
  GVL_STRUCT_TYPE(get_type_metrics) args = { image, draw->info, &metrics };
@@ -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