Bug Summary

File:capplets/common/ctkrc-utils.c
Warning:line 163, column 32
Dereference of null pointer (loaded from variable 'engines')

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 ctkrc-utils.c -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 -fhalf-no-semantic-interposition -mframe-pointer=all -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=/rootdir/capplets/common -resource-dir /usr/lib/llvm-16/lib/clang/16 -D HAVE_CONFIG_H -I . -I ../.. -D CAFECC_DATA_DIR="/usr/share/cafe-control-center" -D CAFELOCALEDIR="/usr/share/locale" -D CTK_ENGINE_DIR="/usr/lib/x86_64-linux-gnu/ctk-3.0/3.0.0/theming-engines" -D G_LOG_DOMAIN="capplet-common" -D INSTALL_PREFIX="/usr" -I ../.. -I ../../libwindow-settings -D PIXMAP_DIR="/usr/share/cafe-control-center/pixmaps" -I /usr/include/ctk-3.0 -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/sysprof-6 -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/webp -I /usr/include/gio-unix-2.0 -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/at-spi-2.0 -I /usr/include/dbus-1.0 -I /usr/lib/x86_64-linux-gnu/dbus-1.0/include -I /usr/include/libxml2 -I /usr/include/cafe-desktop-2.0 -I /usr/include/startup-notification-1.0 -I /usr/include/dconf -I /usr/include/dbus-1.0 -I /usr/lib/x86_64-linux-gnu/dbus-1.0/include -I /usr/include/glib-2.0 -I /usr/lib/x86_64-linux-gnu/glib-2.0/include -I /usr/include/sysprof-6 -I /usr/include/cafe-desktop-2.0 -I /usr/include/ctk-3.0 -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/sysprof-6 -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/webp -I /usr/include/gio-unix-2.0 -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/at-spi-2.0 -I /usr/include/dbus-1.0 -I /usr/lib/x86_64-linux-gnu/dbus-1.0/include -I /usr/include/startup-notification-1.0 -I /usr/include/dconf -I /usr/include/croma-1 -I /usr/include/ctk-3.0 -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/sysprof-6 -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/webp -I /usr/include/gio-unix-2.0 -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/at-spi-2.0 -I /usr/include/dbus-1.0 -I /usr/lib/x86_64-linux-gnu/dbus-1.0/include -I /usr/include/cafe-settings-daemon -I /usr/include/glib-2.0 -I /usr/lib/x86_64-linux-gnu/glib-2.0/include -I /usr/include/sysprof-6 -I /usr/include/dbus-1.0 -I /usr/lib/x86_64-linux-gnu/dbus-1.0/include -I /usr/include/glib-2.0 -I /usr/lib/x86_64-linux-gnu/glib-2.0/include -I /usr/include/sysprof-6 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/dconf -I /usr/include/glib-2.0 -I /usr/lib/x86_64-linux-gnu/glib-2.0/include -I /usr/include/sysprof-6 -I /usr/include/libmount -I /usr/include/blkid -D PIC -internal-isystem /usr/lib/llvm-16/lib/clang/16/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/13/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -fdebug-compilation-dir=/rootdir/capplets/common -ferror-limit 19 -fgnuc-version=4.2.1 -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2024-08-06-105345-113087-1 -x c ctkrc-utils.c
1/*
2 * Copyright (C) 2007 The GNOME Foundation
3 * Written by Thomas Wood <thos@gnome.org>
4 * Jens Granseuer <jensgr@gmx.net>
5 * All Rights Reserved
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License along
18 * with this program; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 */
21
22#ifdef HAVE_CONFIG_H1
23#include <config.h>
24#endif
25
26#include <string.h>
27#include <unistd.h>
28#include <glib.h>
29#include <glib/gstdio.h>
30#include <fcntl.h>
31#include <ctk/ctk.h>
32
33#define INCLUDE_SYMBOL((gpointer) 1) ((gpointer) 1)
34#define ENGINE_SYMBOL((gpointer) 2) ((gpointer) 2)
35#define COLOR_SCHEME_SYMBOL((gpointer) 3) ((gpointer) 3)
36
37gchar* ctkrc_find_named(const gchar* name)
38{
39 /* find the ctkrc of the named theme
40 * taken from ctkrc.c (ctk_rc_parse_named)
41 */
42 gchar* path = NULL((void*)0);
43 const gchar* home_dir;
44 const gchar* subpath = "ctk-2.0" G_DIR_SEPARATOR_S"/" "ctkrc";
45
46 /* First look in the users home directory
47 */
48 home_dir = g_get_home_dir();
49
50 if (home_dir)
51 {
52 path = g_build_filename(home_dir, ".themes", name, subpath, NULL((void*)0));
53
54 if (!g_file_test (path, G_FILE_TEST_EXISTS))
55 {
56 g_free (path);
57 path = NULL((void*)0);
58 }
59 }
60
61 if (!path)
62 {
63 const gchar * const * dirs = g_get_system_data_dirs();
64
65 if (dirs != NULL((void*)0))
66 for (; !path && *dirs != NULL((void*)0); ++dirs)
67 {
68 path = g_build_filename(*dirs, "themes", name, subpath, NULL((void*)0));
69
70 if (!g_file_test(path, G_FILE_TEST_EXISTS))
71 {
72 g_free (path);
73 path = NULL((void*)0);
74 }
75 }
76 }
77
78 return path;
79
80}
81
82void ctkrc_get_details(gchar* filename, GSList** engines, GSList** symbolic_colors)
83{
84 gint file = -1;
85 GSList* files = NULL((void*)0);
86 GSList* read_files = NULL((void*)0);
87 GTokenType token;
88 GScanner *scanner = g_scanner_new (NULL((void*)0));
89
90 g_scanner_scope_add_symbol (scanner, 0, "include", INCLUDE_SYMBOL((gpointer) 1));
91
92 if (engines != NULL((void*)0))
1
Assuming 'engines' is equal to NULL
2
Taking false branch
93 {
94 g_scanner_scope_add_symbol (scanner, 0, "engine", ENGINE_SYMBOL((gpointer) 2));
95 }
96
97 files = g_slist_prepend (files, g_strdup (filename)g_strdup_inline (filename));
98
99 while (files != NULL((void*)0))
3
Assuming 'files' is not equal to NULL
4
Loop condition is true. Entering loop body
100 {
101 filename = files->data;
102 files = g_slist_delete_link (files, files);
103
104 if (filename == NULL((void*)0))
5
Assuming 'filename' is not equal to NULL
6
Taking false branch
105 continue;
106
107 if (g_slist_find_custom (read_files, filename, (GCompareFunc) strcmp))
7
Assuming the condition is false
8
Taking false branch
108 {
109 g_warning ("Recursion in the ctkrc detected!");
110 g_free (filename);
111 continue; /* skip this file since we've done it before... */
112 }
113
114 read_files = g_slist_prepend (read_files, filename);
115
116 file = g_openopen (filename, O_RDONLY00);
117 if (file == -1)
9
Assuming the condition is false
10
Taking false branch
118 {
119 g_warning ("Could not open file \"%s\"", filename);
120 }
121 else
122 {
123 g_scanner_input_file (scanner, file);
124 while ((token = g_scanner_get_next_token (scanner)) != G_TOKEN_EOF)
11
Assuming the condition is true
12
Loop condition is true. Entering loop body
125 {
126 GTokenType string_token;
127 if (token == '@')
13
Assuming the condition is false
14
Taking false branch
128 {
129 if (symbolic_colors == NULL((void*)0))
130 continue;
131 token = g_scanner_get_next_token (scanner);
132 if (token != G_TOKEN_IDENTIFIER)
133 continue;
134 if (!g_slist_find_custom (*symbolic_colors, scanner->value.v_identifier, (GCompareFunc) strcmp))
135 *symbolic_colors = g_slist_append (*symbolic_colors, g_strdup (scanner->value.v_identifier)g_strdup_inline (scanner->value.v_identifier));
136 continue;
137 }
138
139 if (token != G_TOKEN_SYMBOL)
15
Assuming 'token' is equal to G_TOKEN_SYMBOL
16
Taking false branch
140 continue;
141
142 if (scanner->value.v_symbol == INCLUDE_SYMBOL((gpointer) 1))
17
Assuming field 'v_symbol' is not equal to INCLUDE_SYMBOL
18
Taking false branch
143 {
144 string_token = g_scanner_get_next_token (scanner);
145 if (string_token != G_TOKEN_STRING)
146 continue;
147 if (g_path_is_absolute (scanner->value.v_string))
148 {
149 files = g_slist_prepend (files, g_strdup (scanner->value.v_string)g_strdup_inline (scanner->value.v_string));
150 }
151 else
152 {
153 gchar *basedir = g_path_get_dirname (filename);
154 files = g_slist_prepend (files, g_build_path (G_DIR_SEPARATOR_S"/", basedir, scanner->value.v_string, NULL((void*)0)));
155 g_free (basedir);
156 }
157 }
158 else if (scanner->value.v_symbol == ENGINE_SYMBOL((gpointer) 2))
19
Assuming field 'v_symbol' is equal to ENGINE_SYMBOL
20
Taking true branch
159 {
160 string_token = g_scanner_get_next_token (scanner);
161 if (string_token != G_TOKEN_STRING || scanner->value.v_string[0] == '\0')
21
Assuming 'string_token' is equal to G_TOKEN_STRING
22
Assuming the condition is false
23
Taking false branch
162 continue;
163 if (!g_slist_find_custom (*engines, scanner->value.v_string, (GCompareFunc) strcmp))
24
Dereference of null pointer (loaded from variable 'engines')
164 *engines = g_slist_append (*engines, g_strdup (scanner->value.v_string)g_strdup_inline (scanner->value.v_string));
165 }
166
167 }
168 close (file);
169 }
170 }
171
172 g_slist_foreach (read_files, (GFunc) g_free, NULL((void*)0));
173 g_slist_free (read_files);
174
175 g_scanner_destroy (scanner);
176}
177
178
179gchar *
180ctkrc_get_color_scheme (const gchar *ctkrc_file)
181{
182 gint file = -1;
183 gchar *result = NULL((void*)0);
184 GSList *files = NULL((void*)0);
185 GSList *read_files = NULL((void*)0);
186 GTokenType token;
187 GScanner *scanner = ctk_rc_scanner_new ();
188
189 g_scanner_scope_add_symbol (scanner, 0, "include", INCLUDE_SYMBOL((gpointer) 1));
190 g_scanner_scope_add_symbol (scanner, 0, "ctk_color_scheme", COLOR_SCHEME_SYMBOL((gpointer) 3));
191 g_scanner_scope_add_symbol (scanner, 0, "ctk-color-scheme", COLOR_SCHEME_SYMBOL((gpointer) 3));
192
193 files = g_slist_prepend (files, g_strdup (ctkrc_file)g_strdup_inline (ctkrc_file));
194 while (files != NULL((void*)0))
195 {
196 gchar *filename = files->data;
197 files = g_slist_delete_link (files, files);
198
199 if (filename == NULL((void*)0))
200 continue;
201
202 if (g_slist_find_custom (read_files, filename, (GCompareFunc) strcmp))
203 {
204 g_warning ("Recursion in the ctkrc detected!");
205 g_free (filename);
206 continue; /* skip this file since we've done it before... */
207 }
208
209 read_files = g_slist_prepend (read_files, filename);
210
211 file = g_openopen (filename, O_RDONLY00);
212 if (file == -1)
213 {
214 g_warning ("Could not open file \"%s\"", filename);
215 }
216 else
217 {
218 g_scanner_input_file (scanner, file);
219 while ((token = g_scanner_get_next_token (scanner)) != G_TOKEN_EOF)
220 {
221 if (GINT_TO_POINTER (token)((gpointer) (glong) (token)) == COLOR_SCHEME_SYMBOL((gpointer) 3))
222 {
223 if (g_scanner_get_next_token (scanner) == '=')
224 {
225 token = g_scanner_get_next_token (scanner);
226 if (token == G_TOKEN_STRING)
227 {
228 g_free (result);
229 result = g_strdup (scanner->value.v_string)g_strdup_inline (scanner->value.v_string);
230 }
231 }
232 }
233 }
234 close (file);
235 }
236 }
237
238 g_slist_foreach (read_files, (GFunc) g_free, NULL((void*)0));
239 g_slist_free (read_files);
240
241 g_scanner_destroy (scanner);
242 return result;
243}
244
245gchar* ctkrc_get_color_scheme_for_theme(const gchar* theme_name)
246{
247 /* try to find the color scheme from the ctkrc */
248 gchar* ctkrc_file;
249 gchar* scheme = NULL((void*)0);
250
251 ctkrc_file = ctkrc_find_named(theme_name);
252
253 if (ctkrc_file)
254 {
255 scheme = ctkrc_get_color_scheme(ctkrc_file);
256 g_free(ctkrc_file);
257 }
258
259 return scheme;
260}