Bug Summary

File:content/handlers/image/rsvg246.c
Warning:line 133, column 2
Value stored to 'renderres' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name rsvg246.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -pic-is-pie -mframe-pointer=none -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/var/lib/jenkins/workspace/scan-build-netsurf -resource-dir /usr/lib/llvm-14/lib/clang/14.0.6 -I . -I include -I build/Linux-gtk2 -I frontends -I content/handlers -D WITH_JPEG -U WITH_PDF_EXPORT -D LIBICONV_PLUG -I /var/lib/jenkins/artifacts-x86_64-linux-gnu/include -I /var/lib/jenkins/artifacts-x86_64-linux-gnu/include -I /var/lib/jenkins/artifacts-x86_64-linux-gnu/include -I /usr/include/x86_64-linux-gnu -D WITH_CURL -D WITH_OPENSSL -I /var/lib/jenkins/artifacts-x86_64-linux-gnu/include -D UTF8PROC_EXPORTS -D WITH_UTF8PROC -D WITH_WEBP -I /usr/include/libpng16 -D WITH_PNG -I /var/lib/jenkins/artifacts-x86_64-linux-gnu/include/ -D WITH_BMP -I /var/lib/jenkins/artifacts-x86_64-linux-gnu/include -D WITH_GIF -I /var/lib/jenkins/artifacts-x86_64-linux-gnu/include -D WITH_NS_SVG -I /var/lib/jenkins/artifacts-x86_64-linux-gnu/include -D WITH_NSSPRITE -I /var/lib/jenkins/artifacts-x86_64-linux-gnu/include -D WITH_NSPSL -I /var/lib/jenkins/artifacts-x86_64-linux-gnu/include -D WITH_NSLOG -D NETSURF_UA_FORMAT_STRING="Mozilla/5.0 (%s) NetSurf/%d.%d" -D NETSURF_HOMEPAGE="about:welcome" -D NETSURF_LOG_LEVEL=VERBOSE -D NETSURF_BUILTIN_LOG_FILTER="(level:WARNING || cat:jserrors)" -D NETSURF_BUILTIN_VERBOSE_FILTER="(level:VERBOSE || cat:jserrors)" -D STMTEXPR=1 -I /usr/include/librsvg-2.0 -I /usr/include/glib-2.0 -I /usr/lib/x86_64-linux-gnu/glib-2.0/include -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/libpng16 -I /usr/include/x86_64-linux-gnu -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/freetype2 -D WITH_RSVG -I /usr/include/gtk-2.0 -I /usr/lib/x86_64-linux-gnu/gtk-2.0/include -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib/x86_64-linux-gnu/glib-2.0/include -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/x86_64-linux-gnu -I /usr/include/atk-1.0 -I /usr/include/glib-2.0 -I /usr/lib/x86_64-linux-gnu/glib-2.0/include -I /usr/include/glib-2.0 -I /usr/lib/x86_64-linux-gnu/glib-2.0/include -D gtk -D nsgtk -D G_DISABLE_SINGLE_INCLUDES -D G_DISABLE_DEPRECATED -D GTK_DISABLE_SINGLE_INCLUDES -D GTK_MULTIHEAD_SAFE -D PANGO_DISABLE_DEPRECATED -D GTK_DISABLE_DEPRECATED -D _XOPEN_SOURCE=700 -D _POSIX_C_SOURCE=200809L -D _BSD_SOURCE -D _DEFAULT_SOURCE -D _NETBSD_SOURCE -D GTK_RESPATH="/var/lib/jenkins/artifacts-x86_64-linux-gnu/share/netsurf/:./frontends/gtk/res/" -D WITH_GRESOURCE -D DUK_OPT_HAVE_CUSTOM_H -internal-isystem /usr/lib/llvm-14/lib/clang/14.0.6/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-linux-gnu/12/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wwrite-strings -Wno-unused-parameter -Wno-unused-but-set-variable -std=c99 -fconst-strings -fdebug-compilation-dir=/var/lib/jenkins/workspace/scan-build-netsurf -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-display-progress -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /var/lib/jenkins/workspace/scan-build-netsurf/clangScanBuildReports/2024-12-17-121624-2792874-1 -x c content/handlers/image/rsvg246.c
1/*
2 * Copyright 2022 Vincent Sanders <vince@netsurf-browser.org>
3 *
4 * This file is part of NetSurf, http://www.netsurf-browser.org/
5 *
6 * NetSurf is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
9 *
10 * NetSurf is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19/**
20 * \file
21 * implementation of content handler for image/svg using librsvg 2.46 API.
22 *
23 * SVG files are rendered to a NetSurf bitmap by creating a Cairo rendering
24 * surface (content_rsvg_data.cs) over the bitmap's data, creating a Cairo
25 * drawing context using that surface, and then passing that drawing context
26 * to librsvg which then uses Cairo calls to plot the graphic to the bitmap.
27 * We store this in content->bitmap, and then use the usual bitmap plotter
28 * function to render it for redraw requests.
29 */
30
31#include <stdlib.h>
32#include <stdbool.h>
33#include <assert.h>
34#include <string.h>
35#include <sys/types.h>
36
37#include <librsvg/rsvg.h>
38
39#include <nsutils/endian.h>
40
41#include "utils/log.h"
42#include "utils/utils.h"
43#include "utils/messages.h"
44#include "netsurf/plotters.h"
45#include "netsurf/bitmap.h"
46#include "netsurf/content.h"
47#include "content/llcache.h"
48#include "content/content_protected.h"
49#include "content/content_factory.h"
50#include "desktop/gui_internal.h"
51#include "desktop/bitmap.h"
52
53#include "image/image_cache.h"
54
55#include "image/rsvg.h"
56
57
58typedef struct rsvg_content {
59 struct content base;
60
61 RsvgHandle *rsvgh; /**< Context handle for RSVG renderer */
62} rsvg_content;
63
64
65static nserror
66rsvg_create(const content_handler *handler,
67 lwc_string *imime_type,
68 const struct http_parameter *params,
69 llcache_handle *llcache,
70 const char *fallback_charset,
71 bool_Bool quirks,
72 struct content **c)
73{
74 rsvg_content *svg;
75 nserror error;
76
77 svg = calloc(1, sizeof(rsvg_content));
78 if (svg == NULL((void*)0))
79 return NSERROR_NOMEM;
80
81 error = content__init(&svg->base, handler, imime_type, params,
82 llcache, fallback_charset, quirks);
83 if (error != NSERROR_OK) {
84 free(svg);
85 return error;
86 }
87
88 *c = (struct content *)svg;
89
90 return NSERROR_OK;
91}
92
93
94/**
95 * create a bitmap from jpeg content for the image cache.
96 */
97static struct bitmap *
98rsvg_cache_convert(struct content *c)
99{
100 rsvg_content *svgc = (rsvg_content *)c;
101 struct bitmap *bitmap;
102 cairo_surface_t *cs;
103 cairo_t *cr;
104 RsvgRectangle viewport;
105 gboolean renderres;
106
107 if ((bitmap = guit->bitmap->create(c->width, c->height, BITMAP_NONE)) == NULL((void*)0)) {
108 NSLOG(netsurf, INFO, "Failed to create bitmap for rsvg render.")do { if (NSLOG_LEVEL_INFO >= NSLOG_LEVEL_VERBOSE) { static
nslog_entry_context_t _nslog_ctx = { &__nslog_category_netsurf
, NSLOG_LEVEL_INFO, "content/handlers/image/rsvg246.c", sizeof
("content/handlers/image/rsvg246.c") - 1, __PRETTY_FUNCTION__
, sizeof(__PRETTY_FUNCTION__) - 1, 108, }; nslog__log(&_nslog_ctx
, "Failed to create bitmap for rsvg render."); } } while(0)
;
109 return NULL((void*)0);
110 }
111
112 if ((cs = cairo_image_surface_create_for_data(
113 (unsigned char *)guit->bitmap->get_buffer(bitmap),
114 CAIRO_FORMAT_ARGB32,
115 c->width, c->height,
116 guit->bitmap->get_rowstride(bitmap))) == NULL((void*)0)) {
117 NSLOG(netsurf, INFO, "Failed to create Cairo image surface for rsvg render.")do { if (NSLOG_LEVEL_INFO >= NSLOG_LEVEL_VERBOSE) { static
nslog_entry_context_t _nslog_ctx = { &__nslog_category_netsurf
, NSLOG_LEVEL_INFO, "content/handlers/image/rsvg246.c", sizeof
("content/handlers/image/rsvg246.c") - 1, __PRETTY_FUNCTION__
, sizeof(__PRETTY_FUNCTION__) - 1, 117, }; nslog__log(&_nslog_ctx
, "Failed to create Cairo image surface for rsvg render."); }
} while(0)
;
118 guit->bitmap->destroy(bitmap);
119 return NULL((void*)0);
120 }
121 if ((cr = cairo_create(cs)) == NULL((void*)0)) {
122 NSLOG(netsurf, INFO,do { if (NSLOG_LEVEL_INFO >= NSLOG_LEVEL_VERBOSE) { static
nslog_entry_context_t _nslog_ctx = { &__nslog_category_netsurf
, NSLOG_LEVEL_INFO, "content/handlers/image/rsvg246.c", sizeof
("content/handlers/image/rsvg246.c") - 1, __PRETTY_FUNCTION__
, sizeof(__PRETTY_FUNCTION__) - 1, 123, }; nslog__log(&_nslog_ctx
, "Failed to create Cairo drawing context for rsvg render.");
} } while(0)
123 "Failed to create Cairo drawing context for rsvg render.")do { if (NSLOG_LEVEL_INFO >= NSLOG_LEVEL_VERBOSE) { static
nslog_entry_context_t _nslog_ctx = { &__nslog_category_netsurf
, NSLOG_LEVEL_INFO, "content/handlers/image/rsvg246.c", sizeof
("content/handlers/image/rsvg246.c") - 1, __PRETTY_FUNCTION__
, sizeof(__PRETTY_FUNCTION__) - 1, 123, }; nslog__log(&_nslog_ctx
, "Failed to create Cairo drawing context for rsvg render.");
} } while(0)
;
124 cairo_surface_destroy(cs);
125 guit->bitmap->destroy(bitmap);
126 return NULL((void*)0);
127 }
128
129 viewport.x = 0;
130 viewport.y = 0;
131 viewport.width = c->width;
132 viewport.height = c->height;
133 renderres = rsvg_handle_render_document(svgc->rsvgh, cr, &viewport, NULL((void*)0));
Value stored to 'renderres' is never read
134 NSLOG(netsurf, DEBUG, "rsvg render:%d, width:%d, height %d", renderres, c->width, c->height)do { if (NSLOG_LEVEL_DEBUG >= NSLOG_LEVEL_VERBOSE) { static
nslog_entry_context_t _nslog_ctx = { &__nslog_category_netsurf
, NSLOG_LEVEL_DEBUG, "content/handlers/image/rsvg246.c", sizeof
("content/handlers/image/rsvg246.c") - 1, __PRETTY_FUNCTION__
, sizeof(__PRETTY_FUNCTION__) - 1, 134, }; nslog__log(&_nslog_ctx
, "rsvg render:%d, width:%d, height %d", renderres, c->width
, c->height); } } while(0)
;
135
136 bitmap_format_to_client(bitmap, &(bitmap_fmt_t) {
137 .layout = BITMAP_LAYOUT_ARGB8888,
138 });
139 guit->bitmap->modified(bitmap);
140
141 cairo_destroy(cr);
142 cairo_surface_destroy(cs);
143
144 return bitmap;
145}
146
147static void rsvg__get_demensions(const rsvg_content *svgc,
148 int *width, int *height)
149{
150#if LIBRSVG_MAJOR_VERSION(2) >= 2 && LIBRSVG_MINOR_VERSION(54) >= 52
151 gdouble rwidth;
152 gdouble rheight;
153 gboolean gotsize;
154
155 gotsize = rsvg_handle_get_intrinsic_size_in_pixels(svgc->rsvgh,
156 &rwidth,
157 &rheight);
158 if (gotsize == TRUE(!(0))) {
159 *width = rwidth;
160 *height = rheight;
161 } else {
162 RsvgRectangle ink_rect;
163 RsvgRectangle logical_rect;
164 rsvg_handle_get_geometry_for_element(svgc->rsvgh,
165 NULL((void*)0),
166 &ink_rect,
167 &logical_rect,
168 NULL((void*)0));
169 *width = ink_rect.width;
170 *height = ink_rect.height;
171 }
172#else
173 RsvgDimensionData rsvgsize;
174
175 rsvg_handle_get_dimensions(svgc->rsvgh, &rsvgsize);
176 *width = rsvgsize.width;
177 *height = rsvgsize.height;
178#endif
179 NSLOG(netsurf, DEBUG, "rsvg width:%d height:%d.", *width, *height)do { if (NSLOG_LEVEL_DEBUG >= NSLOG_LEVEL_VERBOSE) { static
nslog_entry_context_t _nslog_ctx = { &__nslog_category_netsurf
, NSLOG_LEVEL_DEBUG, "content/handlers/image/rsvg246.c", sizeof
("content/handlers/image/rsvg246.c") - 1, __PRETTY_FUNCTION__
, sizeof(__PRETTY_FUNCTION__) - 1, 179, }; nslog__log(&_nslog_ctx
, "rsvg width:%d height:%d.", *width, *height); } } while(0)
;
180}
181
182static bool_Bool rsvg_convert(struct content *c)
183{
184 rsvg_content *svgc = (rsvg_content *)c;
185 const uint8_t *data; /* content data */
186 size_t size; /* content data size */
187 GInputStream * istream;
188 GError *gerror = NULL((void*)0);
189
190 /* check image header is valid and get width/height */
191
192 data = content__get_source_data(c, &size);
193
194 istream = g_memory_input_stream_new_from_data(data, size, NULL((void*)0));
195 svgc->rsvgh = rsvg_handle_new_from_stream_sync(istream,
196 NULL((void*)0),
197 RSVG_HANDLE_FLAGS_NONE,
198 NULL((void*)0),
199 &gerror);
200 g_object_unref(istream);
201 if (svgc->rsvgh == NULL((void*)0)) {
202 NSLOG(netsurf, INFO, "Failed to create rsvg handle for content.")do { if (NSLOG_LEVEL_INFO >= NSLOG_LEVEL_VERBOSE) { static
nslog_entry_context_t _nslog_ctx = { &__nslog_category_netsurf
, NSLOG_LEVEL_INFO, "content/handlers/image/rsvg246.c", sizeof
("content/handlers/image/rsvg246.c") - 1, __PRETTY_FUNCTION__
, sizeof(__PRETTY_FUNCTION__) - 1, 202, }; nslog__log(&_nslog_ctx
, "Failed to create rsvg handle for content."); } } while(0)
;
203 return false0;
204 }
205
206 rsvg__get_demensions(svgc, &c->width, &c->height);
207
208 c->size = c->width * c->height * 4;
209
210 image_cache_add(c, NULL((void*)0), rsvg_cache_convert);
211
212 content_set_ready(c);
213 content_set_done(c);
214 content_set_status(c, ""); /* Done: update status bar */
215
216 return true1;
217}
218
219
220static nserror rsvg_clone(const struct content *old, struct content **newc)
221{
222 rsvg_content *svg;
223 nserror error;
224
225 svg = calloc(1, sizeof(rsvg_content));
226 if (svg == NULL((void*)0))
227 return NSERROR_NOMEM;
228
229 error = content__clone(old, &svg->base);
230 if (error != NSERROR_OK) {
231 content_destroy(&svg->base);
232 return error;
233 }
234
235 /* re-convert if the content is ready */
236 if ((old->status == CONTENT_STATUS_READY) ||
237 (old->status == CONTENT_STATUS_DONE)) {
238 if (rsvg_convert(&svg->base) == false0) {
239 content_destroy(&svg->base);
240 return NSERROR_CLONE_FAILED;
241 }
242 }
243
244 *newc = (struct content *)svg;
245
246 return NSERROR_OK;
247}
248
249
250static void rsvg_destroy(struct content *c)
251{
252 rsvg_content *d = (rsvg_content *) c;
253
254 if (d->rsvgh != NULL((void*)0)) {
255 g_object_unref(d->rsvgh);
256 d->rsvgh = NULL((void*)0);
257 }
258
259 return image_cache_destroy(c);
260}
261
262static const content_handler rsvg_content_handler = {
263 .create = rsvg_create,
264 .data_complete = rsvg_convert,
265 .destroy = rsvg_destroy,
266 .redraw = image_cache_redraw,
267 .clone = rsvg_clone,
268 .get_internal = image_cache_get_internal,
269 .type = image_cache_content_type,
270 .is_opaque = image_cache_is_opaque,
271 .no_share = false0,
272};
273
274static const char *rsvg_types[] = {
275 "image/svg",
276 "image/svg+xml"
277};
278
279CONTENT_FACTORY_REGISTER_TYPES(nsrsvg, rsvg_types, rsvg_content_handler)nserror nsrsvg_init(void) { uint32_t i; nserror error = NSERROR_OK
; for (i = 0; i < (sizeof(rsvg_types)/sizeof(*(rsvg_types)
)); i++) { error = content_factory_register_handler( rsvg_types
[i], &rsvg_content_handler); if (error != NSERROR_OK) break
; } return error; }
;
280