Bug Summary

File:java-utils.c
Warning:line 262, column 7
Although the value stored to 'i' is used in the enclosing expression, the value is never actually read from 'i'

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 java-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 -pic-is-pie -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 -fdebug-compilation-dir=/rootdir/src -fcoverage-compilation-dir=/rootdir/src -resource-dir /usr/lib/llvm-19/lib/clang/19 -D HAVE_CONFIG_H -I . -I .. -I .. -I .. -D GRAPA_RESOURCE_UI_PATH="/org/cafe/Grapa/ui" -D FR_PREFIX="/usr" -D FR_SYSCONFDIR="/usr/etc" -D FR_DATADIR="/usr/share" -D PRIVDATADIR="/usr/share/grapa/" -D FR_LIBDIR="/usr/lib" -D PKG_DATA_DIR="/usr/share/grapa" -D PIXMAPSDIR="/usr/share/pixmaps" -D GLADEDIR="" -D LOCALEDIR="/usr/share/locale" -D SHDIR="/usr/libexec/grapa/" -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/gio-unix-2.0 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/ctk-3.0 -I /usr/include/pango-1.0 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -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/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/json-glib-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/libmount -I /usr/include/blkid -internal-isystem /usr/lib/llvm-19/lib/clang/19/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -ferror-limit 19 -fgnuc-version=4.2.1 -fskip-odr-check-in-gmf -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.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/2025-02-05-124345-49853-1 -x c java-utils.c
1/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2
3/*
4 * Grapa
5 *
6 * Copyright (C) 2006 The Free Software Foundation, Inc.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 */
22
23#include <config.h>
24#include <fcntl.h>
25#include <unistd.h>
26#include <errno(*__errno_location ()).h>
27#include <string.h>
28#include <ctype.h>
29#include <glib.h>
30#include "java-utils.h"
31
32
33/*
34 * The following code conforms to the JVM specification.(Java 2 Platform)
35 * For further changes to the classfile structure, please update the
36 * following macros.
37 */
38
39
40/* Tags that identify structures */
41
42#define CONST_CLASS7 7
43#define CONST_FIELDREF9 9
44#define CONST_METHODREF10 10
45#define CONST_INTERFACEMETHODREF11 11
46#define CONST_STRING8 8
47#define CONST_INTEGER3 3
48#define CONST_FLOAT4 4
49#define CONST_LONG5 5
50#define CONST_DOUBLE6 6
51#define CONST_NAMEANDTYPE12 12
52#define CONST_UTF81 1
53
54/* Sizes of structures */
55
56#define CONST_FIELDREF_INFO4 4
57#define CONST_METHODREF_INFO4 4
58#define CONST_INTERFACEMETHODREF_INFO4 4
59#define CONST_STRING_INFO2 2
60#define CONST_INTEGER_INFO4 4
61#define CONST_FLOAT_INFO4 4
62#define CONST_LONG_INFO8 8
63#define CONST_DOUBLE_INFO8 8
64#define CONST_NAMEANDTYPE_INFO4 4
65
66
67/* represents the utf8 strings in class file */
68struct utf_string
69{
70 guint16 index;
71 guint16 length;
72 char *str;
73};
74
75/* structure that holds class information in a class file */
76struct class_info
77{
78 guint16 index;
79 guint16 name_index; /* index into the utf_strings */
80};
81
82typedef struct {
83 int fd;
84
85 guint32 magic_no; /* 0xCAFEBABE (JVM Specification) :) */
86
87 guint16 major; /* versions */
88 guint16 minor;
89
90 guint16 const_pool_count;
91 GSList *const_pool_class; /* (const_pool_count - 1) elements of tye 'CONST_class_info' */
92 GSList *const_pool_utf; /* (const_pool_count - 1) elements of type 'utf_strings' */
93
94 guint16 access_flags;
95 guint16 this_class; /* the index of the class the file is named after. */
96
97#if 0 /* not needed */
98 guint16 super_class;
99 guint16 interfaces_count;
100 guint16 *interfaces;
101 guint16 fields_count;
102 field_info *fields;
103 guint16 methods_count;
104 method_info *methods;
105 guint16 attributes_count;
106 attribute_info *attributes;
107#endif
108} JavaClassFile;
109
110
111static JavaClassFile*
112java_class_file_new (void)
113{
114 JavaClassFile *cfile;
115
116 cfile = g_new0 (JavaClassFile, 1)((JavaClassFile *) g_malloc0_n ((1), sizeof (JavaClassFile)));
117 cfile->fd = -1;
118
119 return cfile;
120}
121
122
123static void
124java_class_file_free (JavaClassFile *cfile)
125{
126 GSList *scan;
127
128 if (cfile->const_pool_class != NULL((void*)0))
129 g_slist_free_full (cfile->const_pool_class, g_free);
130
131 for (scan = cfile->const_pool_utf; scan ; scan = scan->next) {
132 struct utf_string *string = scan->data;
133 g_free (string->str);
134 }
135
136 if (cfile->const_pool_utf != NULL((void*)0))
137 g_slist_free_full (cfile->const_pool_utf, g_free);
138
139 if (cfile->fd != -1)
140 close (cfile->fd);
141
142 g_free (cfile);
143}
144
145
146/* The following function loads the utf8 strings and class structures from the
147 * class file. */
148static void
149load_constant_pool_utfs (JavaClassFile *cfile)
150{
151 guint8 tag;
152 guint16 i = 0; /* should be comparable with const_pool_count */
153
154 while ((i < cfile->const_pool_count - 1) && (read (cfile->fd, &tag, 1) != -1)) {
155 struct utf_string *txt = NULL((void*)0);
156 struct class_info *class = NULL((void*)0);
157
158 switch (tag) {
159 case CONST_CLASS7:
160 class = g_new0 (struct class_info, 1)((struct class_info *) g_malloc0_n ((1), sizeof (struct class_info
)))
;
161 class->index = i + 1;
162 if (read (cfile->fd, &class->name_index, 2) != 2) {
163 g_free (class);
164 return; /* error reading */
165 }
166 class->name_index = GUINT16_FROM_BE (class->name_index)(((((guint16) ( (guint16) ((guint16) (class->name_index) >>
8) | (guint16) ((guint16) (class->name_index) << 8)
)))))
;
167 cfile->const_pool_class = g_slist_append (cfile->const_pool_class, class);
168 break;
169
170 case CONST_FIELDREF9:
171 lseek (cfile->fd, CONST_FIELDREF_INFO4, SEEK_CUR1);
172 break;
173
174 case CONST_METHODREF10:
175 lseek (cfile->fd, CONST_METHODREF_INFO4, SEEK_CUR1);
176 break;
177
178 case CONST_INTERFACEMETHODREF11:
179 lseek (cfile->fd, CONST_INTERFACEMETHODREF_INFO4, SEEK_CUR1);
180 break;
181
182 case CONST_STRING8:
183 lseek (cfile->fd, CONST_STRING_INFO2, SEEK_CUR1);
184 break;
185
186 case CONST_INTEGER3:
187 lseek (cfile->fd, CONST_INTEGER_INFO4, SEEK_CUR1);
188 break;
189
190 case CONST_FLOAT4:
191 lseek (cfile->fd, CONST_FLOAT_INFO4, SEEK_CUR1);
192 break;
193
194 case CONST_LONG5:
195 lseek (cfile->fd, CONST_LONG_INFO8, SEEK_CUR1);
196 break;
197
198 case CONST_DOUBLE6:
199 lseek (cfile->fd, CONST_DOUBLE_INFO8, SEEK_CUR1);
200 break;
201
202 case CONST_NAMEANDTYPE12:
203 lseek (cfile->fd, CONST_NAMEANDTYPE_INFO4, SEEK_CUR1);
204 break;
205
206 case CONST_UTF81:
207 txt = g_new0 (struct utf_string, 1)((struct utf_string *) g_malloc0_n ((1), sizeof (struct utf_string
)))
;
208 txt->index = i + 1;
209 if (read (cfile->fd, &(txt->length), 2) == -1) {
210 g_free (txt);
211 return; /* error while reading */
212 }
213 txt->length = GUINT16_FROM_BE (txt->length)(((((guint16) ( (guint16) ((guint16) (txt->length) >>
8) | (guint16) ((guint16) (txt->length) << 8))))))
;
214 txt->str = g_new0 (char, txt->length)((char *) g_malloc0_n ((txt->length), sizeof (char)));
215 if (read (cfile->fd, txt->str, txt->length) == -1) {
216 g_free (txt);
217 return; /* error while reading */
218 }
219 cfile->const_pool_utf = g_slist_append (cfile->const_pool_utf, txt);
220 break;
221
222 default:
223 return; /* error - unknown tag in class file */
224 break;
225 }
226 i++;
227 }
228
229#ifdef CAFE_ENABLE_DEBUG
230 g_print( "Number of Entries: %d\n", i );
231#endif
232}
233
234
235static char*
236close_and_exit (JavaClassFile *cfile)
237{
238 java_class_file_free (cfile);
239 return NULL((void*)0);
240}
241
242
243/* This function extracts the package name from a class file */
244char*
245get_package_name_from_class_file (char *fname)
246{
247 char *package = NULL((void*)0);
248 JavaClassFile *cfile;
249 guint16 length = 0, end = 0, utf_index = 0;
250 guint32 magic;
251 guint16 major, minor, count;
252 guint i = 0;
253
254 if (! g_file_test (fname, G_FILE_TEST_EXISTS))
255 return NULL((void*)0);
256
257 cfile = java_class_file_new ();
258 cfile->fd = open (fname, O_RDONLY00);
259 if (cfile->fd == -1)
260 return close_and_exit (cfile);
261
262 if ((i = read (cfile->fd, &magic, 4)) != 4)
Although the value stored to 'i' is used in the enclosing expression, the value is never actually read from 'i'
263 return close_and_exit (cfile);
264 cfile->magic_no = GUINT32_FROM_BE (magic)(((((guint32) ( (((guint32) (magic) & (guint32) 0x000000ffU
) << 24) | (((guint32) (magic) & (guint32) 0x0000ff00U
) << 8) | (((guint32) (magic) & (guint32) 0x00ff0000U
) >> 8) | (((guint32) (magic) & (guint32) 0xff000000U
) >> 24))))))
;
265
266 if (read (cfile->fd, &major, 2 ) != 2)
267 return close_and_exit (cfile);
268 cfile->major = GUINT16_FROM_BE (major)(((((guint16) ( (guint16) ((guint16) (major) >> 8) | (guint16
) ((guint16) (major) << 8))))))
;
269
270 if (read (cfile->fd, &minor, 2) != 2)
271 return close_and_exit (cfile);
272 cfile->minor = GUINT16_FROM_BE (minor)(((((guint16) ( (guint16) ((guint16) (minor) >> 8) | (guint16
) ((guint16) (minor) << 8))))))
;
273
274 if (read (cfile->fd, &count, 2) != 2)
275 return close_and_exit (cfile);
276 cfile->const_pool_count = GUINT16_FROM_BE(count)(((((guint16) ( (guint16) ((guint16) (count) >> 8) | (guint16
) ((guint16) (count) << 8))))))
;
277 load_constant_pool_utfs (cfile);
278
279 if (read (cfile->fd, &cfile->access_flags, 2) != 2)
280 return close_and_exit (cfile);
281 cfile->access_flags = GUINT16_FROM_BE (cfile->access_flags)(((((guint16) ( (guint16) ((guint16) (cfile->access_flags)
>> 8) | (guint16) ((guint16) (cfile->access_flags) <<
8))))))
;
282
283 if (read (cfile->fd, &cfile->this_class, 2) != 2)
284 return close_and_exit (cfile);
285 cfile->this_class = GUINT16_FROM_BE(cfile->this_class)(((((guint16) ( (guint16) ((guint16) (cfile->this_class) >>
8) | (guint16) ((guint16) (cfile->this_class) << 8)
)))))
;
286
287 /* now search for the class structure with index = cfile->this_class */
288
289 for (i = 0; (i < g_slist_length (cfile->const_pool_class)) && (utf_index == 0); i++ ) {
290 struct class_info *class = g_slist_nth_data (cfile->const_pool_class, i);
291 if (class->index == cfile->this_class)
292 utf_index = class->name_index; /* terminates loop */
293 }
294
295 /* now search for the utf8 string with index = utf_index */
296
297 for (i = 0; i < g_slist_length (cfile->const_pool_utf); i++) {
298 struct utf_string *data = g_slist_nth_data (cfile->const_pool_utf, i);
299 if (data->index == utf_index) {
300 package = g_strndup (data->str, data->length);
301 length = data->length;
302 break;
303 }
304 }
305
306 if (package != NULL((void*)0)) {
307 int j;
308 for (j = length; (j >= 0) && (end == 0); j--)
309 if (package[j] == '/')
310 end = j;
311 char *package_padded = g_strndup (package, end);
312 g_free(package);
313 package = package_padded;
314 }
315
316 java_class_file_free (cfile);
317
318 return package;
319}
320
321
322/* This function consumes a comment from the java file
323 * multiline = TRUE implies that comment is multiline */
324static void
325consume_comment (int fdesc,
326 gboolean multiline)
327{
328 gboolean escaped = FALSE(0);
329 gboolean star = FALSE(0);
330 char ch;
331
332 while (read (fdesc, &ch, 1) == 1) {
333 switch (ch) {
334 case '/':
335 if (escaped)
336 break;
337 else if (star)
338 return;
339 break;
340
341 case '\n':
342 if (! multiline)
343 return;
344 break;
345
346 case '*':
347 escaped = FALSE(0);
348 star = TRUE(!(0));
349 break;
350
351 case '\\':
352 escaped = ! escaped;
353 break;
354
355 default:
356 escaped = FALSE(0);
357 star = FALSE(0);
358 break;
359 }
360 }
361}
362
363
364/* This function extracts package name from a java file */
365char*
366get_package_name_from_java_file (char *fname)
367{
368 char *package = NULL((void*)0);
369 JavaClassFile *cfile;
370 gboolean prev_char_is_bslash = FALSE(0);
371 gboolean valid_char_found = FALSE(0);
372 char ch;
373
374 if (! g_file_test (fname, G_FILE_TEST_EXISTS))
375 return NULL((void*)0);
376
377 cfile = java_class_file_new ();
378 cfile->fd = open (fname, O_RDONLY00);
379 if (cfile->fd == -1)
380 return close_and_exit (cfile);
381
382 while (! valid_char_found && (read (cfile->fd, &ch, 1) == 1)) {
383 switch (ch) {
384 case '/':
385 if (prev_char_is_bslash == TRUE(!(0))) {
386 consume_comment (cfile->fd, FALSE(0));
387 prev_char_is_bslash = FALSE(0);
388 }
389 else
390 prev_char_is_bslash = TRUE(!(0));
391 break;
392
393 case '*':
394 if (prev_char_is_bslash == TRUE(!(0)))
395 consume_comment (cfile->fd, TRUE(!(0)));
396 prev_char_is_bslash = FALSE(0);
397 break;
398
399 case ' ':
400 case '\t':
401 case '\r':
402 case '\n':
403 prev_char_is_bslash = FALSE(0);
404 break;
405
406 default:
407 prev_char_is_bslash = FALSE(0);
408 valid_char_found = TRUE(!(0));
409 break;
410 }
411 }
412
413 if (ch == 'p') {
414 char first_valid_word[8] = "";
415
416 first_valid_word[0] = 'p';
417 if (read (cfile->fd, &first_valid_word[1], 6) != 6)
418 return close_and_exit (cfile);
419
420 first_valid_word[7] = 0;
421 if (g_ascii_strcasecmp (first_valid_word, "package") == 0) {
422 char buffer[500];
423 int index = 0;
424
425 while (read (cfile->fd, &ch, 1) == 1) {
426 if ((ch != ' ') && (ch != '\t'))
427 break;
428 }
429 do {
430 if (ch == ';')
431 break;
432 if (ch == '.') {
433 buffer[index++] = '/';
434 } else if (isalnum (ch)((*__ctype_b_loc ())[(int) ((ch))] & (unsigned short int)
_ISalnum)
!= 0) {
435 buffer[index++] = ch;
436 } else if ((ch == '_') || (ch == '$')) {
437 buffer[index++] = ch;
438 } else {
439 index = 0;
440 break;
441 }
442 } while (read (cfile->fd, &ch, 1) == 1);
443 buffer[index] = 0;
444 package = g_strdup (buffer)g_strdup_inline (buffer);
445 }
446 }
447
448 java_class_file_free (cfile);
449
450 return package;
451}