diff options
| author | Paul Eggert | 2025-01-26 22:15:49 -0800 |
|---|---|---|
| committer | Paul Eggert | 2025-01-26 23:05:51 -0800 |
| commit | c50e8c24247eb69d85b004a72197e710c8e1e32a (patch) | |
| tree | c7832a7d59efd1c3c9e20e8019b532375db7c917 /src | |
| parent | 028fae966142b6e2330b9250fb4cdf2cbd8e1446 (diff) | |
| download | emacs-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.c | 72 |
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 | ||