Bug Summary

File:src/gnu/usr.sbin/mkhybrid/mkhybrid/../src/name.c
Warning:line 391, column 21
Access to field 'priority' results in a dereference of a null pointer (loaded from variable 'sresult')

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple amd64-unknown-openbsd7.0 -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name name.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 1 -pic-is-pie -mframe-pointer=all -relaxed-aliasing -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -target-feature +retpoline-indirect-calls -target-feature +retpoline-indirect-branches -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/usr/src/gnu/usr.sbin/mkhybrid/mkhybrid/obj -resource-dir /usr/local/lib/clang/13.0.0 -D SYSTEM_ID_DEFAULT="OpenBSD" -D APPLE_HYB -D VANILLA_AUTOCONF -I /usr/src/gnu/usr.sbin/mkhybrid/mkhybrid/../src -I /usr/src/gnu/usr.sbin/mkhybrid/mkhybrid/../src/include -I /usr/src/gnu/usr.sbin/mkhybrid/mkhybrid/../src/libhfs_iso -I /usr/src/gnu/usr.sbin/mkhybrid/mkhybrid/../src/libfile -internal-isystem /usr/local/lib/clang/13.0.0/include -internal-externc-isystem /usr/include -O2 -fdebug-compilation-dir=/usr/src/gnu/usr.sbin/mkhybrid/mkhybrid/obj -ferror-limit 19 -fwrapv -D_RET_PROTECTOR -ret-protector -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-valloc -fno-builtin-free -fno-builtin-strdup -fno-builtin-strndup -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /home/ben/Projects/vmm/scan-build/2022-01-12-194120-40624-1 -x c /usr/src/gnu/usr.sbin/mkhybrid/mkhybrid/../src/name.c
1/*
2 * File name.c - map full Unix file names to unique 8.3 names that
3 * would be valid on DOS.
4 *
5
6 Written by Eric Youngdale (1993).
7
8 Copyright 1993 Yggdrasil Computing, Incorporated
9
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2, or (at your option)
13 any later version.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
23
24#include "config.h"
25#include "mkisofs.h"
26
27#include <ctype.h>
28
29extern int allow_leading_dots;
30
31/*
32 * Function: iso9660_file_length
33 *
34 * Purpose: Map file name to 8.3 format, return length
35 * of result.
36 *
37 * Arguments: name file name we need to map.
38 * sresult directory entry structure to contain mapped name.
39 * dirflag flag indicating whether this is a directory or not.
40 *
41 * Notes: This procedure probably needs to be rationalized somehow.
42 * New options to affect the behavior of this function
43 * would also be nice to have.
44 */
45int FDECL3(iso9660_file_length,iso9660_file_length(const char* name, struct directory_entry *
sresult, int dirflag)
46 const char*, name,iso9660_file_length(const char* name, struct directory_entry *
sresult, int dirflag)
47 struct directory_entry *, sresult,iso9660_file_length(const char* name, struct directory_entry *
sresult, int dirflag)
48 int, dirflag)iso9660_file_length(const char* name, struct directory_entry *
sresult, int dirflag)
49{
50 char * c;
51 int chars_after_dot = 0;
52 int chars_before_dot = 0;
53 int current_length = 0;
54 int extra = 0;
55 int ignore = 0;
56 char * last_dot;
57 const char * pnt;
58 int priority = 32767;
59 char * result;
60 int seen_dot = 0;
61 int seen_semic = 0;
62 int tildes = 0;
63
64 result = sresult->isorec.name;
65
66 /*
67 * For the '.' entry, generate the correct record, and return
68 * 1 for the length.
69 */
70 if(strcmp(name,".") == 0)
1
Assuming the condition is false
2
Taking false branch
71 {
72 if(result)
73 {
74 *result = 0;
75 }
76 return 1;
77 }
78
79 /*
80 * For the '..' entry, generate the correct record, and return
81 * 1 for the length.
82 */
83 if(strcmp(name,"..") == 0)
3
Assuming the condition is false
4
Taking false branch
84 {
85 if(result)
86 {
87 *result++ = 1;
88 *result++ = 0;
89 }
90 return 1;
91 }
92
93 /*
94 * Now scan the directory one character at a time, and figure out
95 * what to do.
96 */
97 pnt = name;
98
99 /*
100 * Find the '.' that we intend to use for the extension. Usually this
101 * is the last dot, but if we have . followed by nothing or a ~, we
102 * would consider this to be unsatisfactory, and we keep searching.
103 */
104 last_dot = strrchr (pnt,'.');
105 if( (last_dot != NULL((void *)0))
5
Assuming 'last_dot' is equal to NULL
106 && ( (last_dot[1] == '~')
107 || (last_dot[1] == '\0')) )
108 {
109 c = last_dot;
110 *c = '\0';
111 last_dot = strrchr (pnt,'.');
112 *c = '.';
113 }
114
115 while(*pnt)
6
Loop condition is false. Execution continues on line 344
116 {
117#ifdef VMS
118 if( strcmp(pnt,".DIR;1") == 0 )
119 {
120 break;
121 }
122#endif
123
124 /*
125 * This character indicates a Unix style of backup file
126 * generated by some editors. Lower the priority of
127 * the file.
128 */
129 if(*pnt == '#')
130 {
131 priority = 1;
132 pnt++;
133 continue;
134 }
135
136 /*
137 * This character indicates a Unix style of backup file
138 * generated by some editors. Lower the priority of
139 * the file.
140 */
141 if(*pnt == '~')
142 {
143 priority = 1;
144 tildes++;
145 pnt++;
146 continue;
147 }
148
149 /*
150 * This might come up if we had some joker already try and put
151 * iso9660 version numbers into the file names. This would be
152 * a silly thing to do on a Unix box, but we check for it
153 * anyways. If we see this, then we don't have to add our
154 * own version number at the end.
155 * UNLESS the ';' is part of the filename and no version
156 * number is following. [VK]
157 */
158 if(*pnt == ';')
159 {
160 /* [VK] */
161 if (pnt[1] != '\0' && (pnt[1] < '0' || pnt[1] > '9'))
162 {
163 pnt++;
164 ignore++;
165 continue;
166 }
167 }
168
169 /*
170 * If we have a name with multiple '.' characters, we ignore everything
171 * after we have gotten the extension.
172 */
173 if(ignore)
174 {
175 pnt++;
176 continue;
177 }
178
179 /*
180 * Spin past any iso9660 version number we might have.
181 */
182 if(seen_semic)
183 {
184 if(*pnt >= '0' && *pnt <= '9')
185 {
186 *result++ = *pnt;
187 }
188 extra++;
189 pnt++;
190 continue;
191 }
192
193 /*
194 * If we have full names, the names we generate will not
195 * work on a DOS machine, since they are not guaranteed
196 * to be 8.3. Nonetheless, in many cases this is a useful
197 * option. We still only allow one '.' character in the
198 * name, however.
199 */
200 if(full_iso9660_filenames)
201 {
202 /* Here we allow a more relaxed syntax. */
203 if(*pnt == '.')
204 {
205 if (seen_dot)
206 {
207 ignore++;
208 continue;
209 }
210 seen_dot++;
211 }
212 if(current_length < 30)
213 {
214 if(!isascii((unsigned char)*pnt))
215 {
216 *result++ = '_';
217 }
218 else
219 {
220 *result++ = (islower((unsigned char)*pnt) ? toupper((unsigned char)*pnt) : *pnt);
221 }
222 }
223 }
224 else
225 {
226 /*
227 * Dos style filenames. We really restrict the
228 * names here.
229 */
230 /* It would be nice to have .tar.gz transform to .tgz,
231 * .ps.gz to .psz, ...
232 */
233 if(*pnt == '.')
234 {
235 if (!chars_before_dot && !allow_leading_dots)
236 {
237 /* DOS can't read files with dot first */
238 chars_before_dot++;
239 if (result)
240 {
241 *result++ = '_'; /* Substitute underscore */
242 }
243 }
244 else if( pnt != last_dot )
245 {
246 /*
247 * If this isn't the dot that we use for the extension,
248 * then change the character into a '_' instead.
249 */
250 if(chars_before_dot < 8)
251 {
252 chars_before_dot++;
253 if(result)
254 {
255 *result++ = '_';
256 }
257 }
258 }
259 else
260 {
261 if (seen_dot)
262 {
263 ignore++; continue;
264 }
265 if(result)
266 {
267 *result++ = '.';
268 }
269 seen_dot++;
270 }
271 }
272 else
273 {
274 if( (seen_dot && (chars_after_dot < 3) && ++chars_after_dot)
275 || (!seen_dot && (chars_before_dot < 8) && ++chars_before_dot) )
276 {
277 if(result)
278 {
279 switch (*pnt)
280 {
281 default:
282 if(!isascii((unsigned char)*pnt))
283 {
284 *result++ = '_';
285 }
286 else
287 {
288 *result++ = islower((unsigned char)*pnt) ? toupper((unsigned char)*pnt) : *pnt;
289 }
290 break;
291
292 /*
293 * Descriptions of DOS's 'Parse Filename'
294 * (function 29H) describes V1 and V2.0+
295 * separator and terminator characters.
296 * These characters in a DOS name make
297 * the file visible but un-manipulable
298 * (all useful operations error off.
299 */
300 /* separators */
301 case '+':
302 case '=':
303 case '%': /* not legal DOS filename */
304 case ':':
305 case ';': /* already handled */
306 case '.': /* already handled */
307 case ',': /* already handled */
308 case '\t':
309 case ' ':
310 /* V1 only separators */
311 case '/':
312 case '"':
313 case '[':
314 case ']':
315 /* terminators */
316 case '>':
317 case '<':
318 case '|':
319 /* Hmm - what to do here? Skip?
320 * Win95 looks like it substitutes '_'
321 */
322 *result++ = '_';
323 break;
324 } /* switch (*pnt) */
325 } /* if (result) */
326 } /* if (chars_{after,before}_dot) ... */
327 } /* else *pnt == '.' */
328 } /* else DOS file names */
329 current_length++;
330 pnt++;
331 } /* while (*pnt) */
332
333 /*
334 * OK, that wraps up the scan of the name. Now tidy up a few other
335 * things.
336 */
337
338 /*
339 * Look for emacs style of numbered backups, like foo.c.~3~. If
340 * we see this, convert the version number into the priority
341 * number. In case of name conflicts, this is what would end
342 * up being used as the 'extension'.
343 */
344 if(tildes
6.1
'tildes' is not equal to 2
== 2)
7
Taking false branch
345 {
346 int prio1 = 0;
347 pnt = name;
348 while (*pnt && *pnt != '~')
349 {
350 pnt++;
351 }
352 if (*pnt)
353 {
354 pnt++;
355 }
356 while(*pnt && *pnt != '~')
357 {
358 prio1 = 10*prio1 + *pnt - '0';
359 pnt++;
360 }
361 priority = prio1;
362 }
363
364 /*
365 * If this is not a directory, force a '.' in case we haven't
366 * seen one, and add a version number if we haven't seen one
367 * of those either.
368 */
369 if (!dirflag)
8
Assuming 'dirflag' is not equal to 0
9
Taking false branch
370 {
371 if (!seen_dot && !omit_period)
372 {
373 if (result) *result++ = '.';
374 extra++;
375 }
376 if(!omit_version_number && !seen_semic)
377 {
378 if(result)
379 {
380 *result++ = ';';
381 *result++ = '1';
382 };
383 extra += 2;
384 }
385 }
386
387 if(result)
10
Assuming 'result' is null
11
Taking false branch
388 {
389 *result++ = 0;
390 }
391 sresult->priority = priority;
12
Access to field 'priority' results in a dereference of a null pointer (loaded from variable 'sresult')
392
393 return (chars_before_dot + chars_after_dot + seen_dot + extra);
394}