aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPaul Eggert2025-01-26 22:15:49 -0800
committerPaul Eggert2025-01-26 23:05:51 -0800
commitc50e8c24247eb69d85b004a72197e710c8e1e32a (patch)
treec7832a7d59efd1c3c9e20e8019b532375db7c917 /src
parent028fae966142b6e2330b9250fb4cdf2cbd8e1446 (diff)
downloademacs-c50e8c24247eb69d85b004a72197e710c8e1e32a.tar.gz
emacs-c50e8c24247eb69d85b004a72197e710c8e1e32a.zip
Prefer make_formatted_string in svg_load_image
* src/image.c (svg_load_image): Prefer make_formatted_string to snprintf, as this simplifies the code and does not truncate the resulting string arbitrarily.
Diffstat (limited to 'src')
-rw-r--r--src/image.c72
1 files changed, 18 insertions, 54 deletions
diff --git a/src/image.c b/src/image.c
index 901063c9bde..0d7e77164b6 100644
--- a/src/image.c
+++ b/src/image.c
@@ -12048,17 +12048,11 @@ svg_load_image (struct frame *f, struct image *img, char *contents,
12048 int height; 12048 int height;
12049 const guint8 *pixels; 12049 const guint8 *pixels;
12050 int rowstride; 12050 int rowstride;
12051 char *wrapped_contents = NULL; 12051 Lisp_Object wrapped_contents;
12052 ptrdiff_t wrapped_size;
12053
12054 bool empty_errmsg = true; 12052 bool empty_errmsg = true;
12055 const char *errmsg = ""; 12053 const char *errmsg = "";
12056 ptrdiff_t errlen = 0; 12054 ptrdiff_t errlen = 0;
12057 12055
12058#if LIBRSVG_CHECK_VERSION (2, 48, 0)
12059 char *css = NULL;
12060#endif
12061
12062#if ! GLIB_CHECK_VERSION (2, 36, 0) 12056#if ! GLIB_CHECK_VERSION (2, 36, 0)
12063 /* g_type_init is a glib function that must be called prior to 12057 /* g_type_init is a glib function that must be called prior to
12064 using gnome type library functions (obsolete since 2.36.0). */ 12058 using gnome type library functions (obsolete since 2.36.0). */
@@ -12096,23 +12090,11 @@ svg_load_image (struct frame *f, struct image *img, char *contents,
12096 SVG supports, however it's only available in librsvg 2.48 and 12090 SVG supports, however it's only available in librsvg 2.48 and
12097 above so some things we could set here are handled in the 12091 above so some things we could set here are handled in the
12098 wrapper below. */ 12092 wrapper below. */
12099 /* FIXME: The below calculations leave enough space for a font 12093 lcss = make_formatted_string ("svg{font-family:\"%s\";font-size:%dpx}",
12100 size up to 9999, if it overflows we just throw an error but 12094 img->face_font_family,
12101 should probably increase the buffer size. */ 12095 img->face_font_size);
12102 const char *css_spec = "svg{font-family:\"%s\";font-size:%dpx}"; 12096 rsvg_handle_set_stylesheet (rsvg_handle, (guint8 *) SDATA (lcss),
12103 int css_len = strlen (css_spec) + strlen (img->face_font_family) + 1; 12097 SBYTES (lcss), NULL);
12104 css = xmalloc (css_len);
12105 if (css_len <= snprintf (css, css_len, css_spec,
12106 img->face_font_family, img->face_font_size))
12107 goto rsvg_error;
12108
12109 rsvg_handle_set_stylesheet (rsvg_handle, (guint8 *)css, strlen (css), NULL);
12110 }
12111 else
12112 {
12113 css = xmalloc (SBYTES (lcss) + 1);
12114 strncpy (css, SSDATA (lcss), SBYTES (lcss));
12115 *(css + SBYTES (lcss) + 1) = 0;
12116 } 12098 }
12117#endif 12099#endif
12118 12100
@@ -12280,7 +12262,7 @@ svg_load_image (struct frame *f, struct image *img, char *contents,
12280 background color, before including the original image. This 12262 background color, before including the original image. This
12281 acts to set the background color, instead of leaving it 12263 acts to set the background color, instead of leaving it
12282 transparent. */ 12264 transparent. */
12283 const char *wrapper = 12265 static char const wrapper[] =
12284 "<svg xmlns:xlink=\"http://www.w3.org/1999/xlink\" " 12266 "<svg xmlns:xlink=\"http://www.w3.org/1999/xlink\" "
12285 "xmlns:xi=\"http://www.w3.org/2001/XInclude\" " 12267 "xmlns:xi=\"http://www.w3.org/2001/XInclude\" "
12286 "style=\"color: #%06X; fill: currentColor;\" " 12268 "style=\"color: #%06X; fill: currentColor;\" "
@@ -12290,10 +12272,6 @@ svg_load_image (struct frame *f, struct image *img, char *contents,
12290 "<xi:include href=\"data:image/svg+xml;base64,%s\"></xi:include>" 12272 "<xi:include href=\"data:image/svg+xml;base64,%s\"></xi:include>"
12291 "</svg>"; 12273 "</svg>";
12292 12274
12293 /* FIXME: I've added 64 in the hope it will cover the size of the
12294 width and height strings and things. */
12295 int buffer_size = SBYTES (encoded_contents) + strlen (wrapper) + 64;
12296
12297 value = image_spec_value (img->spec, QCforeground, NULL); 12275 value = image_spec_value (img->spec, QCforeground, NULL);
12298 if (!NILP (value)) 12276 if (!NILP (value))
12299 foreground = image_alloc_image_color (f, img, value, img->face_foreground); 12277 foreground = image_alloc_image_color (f, img, value, img->face_foreground);
@@ -12317,22 +12295,18 @@ svg_load_image (struct frame *f, struct image *img, char *contents,
12317 | (background & 0x00FF00); 12295 | (background & 0x00FF00);
12318#endif 12296#endif
12319 12297
12320 wrapped_contents = xmalloc (buffer_size); 12298 unsigned int color = foreground & 0xFFFFFF, fill = background & 0xFFFFFF;
12321 12299 wrapped_contents
12322 if (buffer_size <= snprintf (wrapped_contents, buffer_size, wrapper, 12300 = make_formatted_string (wrapper, color, width, height,
12323 foreground & 0xFFFFFF, width, height, 12301 viewbox_width, viewbox_height,
12324 viewbox_width, viewbox_height, 12302 fill, SSDATA (encoded_contents));
12325 background & 0xFFFFFF,
12326 SSDATA (encoded_contents)))
12327 goto rsvg_error;
12328
12329 wrapped_size = strlen (wrapped_contents);
12330 } 12303 }
12331 12304
12332 /* Now we parse the wrapped version. */ 12305 /* Now we parse the wrapped version. */
12333 12306
12334#if LIBRSVG_CHECK_VERSION (2, 32, 0) 12307#if LIBRSVG_CHECK_VERSION (2, 32, 0)
12335 input_stream = g_memory_input_stream_new_from_data (wrapped_contents, wrapped_size, NULL); 12308 input_stream = g_memory_input_stream_new_from_data
12309 (SDATA (wrapped_contents), SBYTES (wrapped_contents), NULL);
12336 base_file = filename ? g_file_new_for_path (filename) : NULL; 12310 base_file = filename ? g_file_new_for_path (filename) : NULL;
12337 rsvg_handle = rsvg_handle_new_from_stream_sync (input_stream, base_file, 12311 rsvg_handle = rsvg_handle_new_from_stream_sync (input_stream, base_file,
12338 RSVG_HANDLE_FLAGS_NONE, 12312 RSVG_HANDLE_FLAGS_NONE,
@@ -12351,7 +12325,8 @@ svg_load_image (struct frame *f, struct image *img, char *contents,
12351#if LIBRSVG_CHECK_VERSION (2, 48, 0) 12325#if LIBRSVG_CHECK_VERSION (2, 48, 0)
12352 /* Set the CSS for the wrapped SVG. See the comment above the 12326 /* Set the CSS for the wrapped SVG. See the comment above the
12353 previous use of 'css'. */ 12327 previous use of 'css'. */
12354 rsvg_handle_set_stylesheet (rsvg_handle, (guint8 *)css, strlen (css), NULL); 12328 rsvg_handle_set_stylesheet (rsvg_handle, (guint8 *) SDATA (lcss),
12329 SBYTES (lcss), NULL);
12355#endif 12330#endif
12356#else 12331#else
12357 /* Make a handle to a new rsvg object. */ 12332 /* Make a handle to a new rsvg object. */
@@ -12369,7 +12344,8 @@ svg_load_image (struct frame *f, struct image *img, char *contents,
12369 rsvg_handle_set_base_uri (rsvg_handle, filename); 12344 rsvg_handle_set_base_uri (rsvg_handle, filename);
12370 12345
12371 /* Parse the contents argument and fill in the rsvg_handle. */ 12346 /* Parse the contents argument and fill in the rsvg_handle. */
12372 rsvg_handle_write (rsvg_handle, (unsigned char *) wrapped_contents, wrapped_size, &err); 12347 rsvg_handle_write (rsvg_handle, SDATA (wrapped_contents),
12348 SBYTES (wrapped_contents), &err);
12373 if (err) goto rsvg_error; 12349 if (err) goto rsvg_error;
12374 12350
12375 /* The parsing is complete, rsvg_handle is ready to used, close it 12351 /* The parsing is complete, rsvg_handle is ready to used, close it
@@ -12389,12 +12365,6 @@ svg_load_image (struct frame *f, struct image *img, char *contents,
12389 if (!pixbuf) goto rsvg_error; 12365 if (!pixbuf) goto rsvg_error;
12390#endif 12366#endif
12391 g_object_unref (rsvg_handle); 12367 g_object_unref (rsvg_handle);
12392 xfree (wrapped_contents);
12393
12394#if LIBRSVG_CHECK_VERSION (2, 48, 0)
12395 if (!STRINGP (lcss))
12396 xfree (css);
12397#endif
12398 12368
12399 /* Extract some meta data from the svg handle. */ 12369 /* Extract some meta data from the svg handle. */
12400 width = gdk_pixbuf_get_width (pixbuf); 12370 width = gdk_pixbuf_get_width (pixbuf);
@@ -12485,12 +12455,6 @@ svg_load_image (struct frame *f, struct image *img, char *contents,
12485 done_error: 12455 done_error:
12486 if (rsvg_handle) 12456 if (rsvg_handle)
12487 g_object_unref (rsvg_handle); 12457 g_object_unref (rsvg_handle);
12488 if (wrapped_contents)
12489 xfree (wrapped_contents);
12490#if LIBRSVG_CHECK_VERSION (2, 48, 0)
12491 if (css && !STRINGP (lcss))
12492 xfree (css);
12493#endif
12494 return false; 12458 return false;
12495} 12459}
12496 12460