Bug Summary

File:var/lib/jenkins/workspace/firefox-scan-build/config/pathsub.c
Warning:line 95, column 9
Access to field 'd_ino' results in a dereference of a null pointer (loaded from variable 'ep')

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 pathsub.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 -analyzer-config-compatibility-mode=true -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 -fdebug-compilation-dir=/var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/config -fcoverage-compilation-dir=/var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/config -resource-dir /usr/lib/llvm-18/lib/clang/18 -D XP_UNIX -D DEBUG=1 -D UNICODE -D _UNICODE -I /var/lib/jenkins/workspace/firefox-scan-build/config -I /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/config -I /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/dist/include -I /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/dist/include/nspr -internal-isystem /usr/lib/llvm-18/lib/clang/18/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 -O3 -std=gnu99 -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-checker optin.performance.Padding -analyzer-output=html -analyzer-config stable-report-filename=true -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /tmp/scan-build-2024-05-16-034744-15991-1 -x c /var/lib/jenkins/workspace/firefox-scan-build/config/pathsub.c
1/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2/* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5/*
6** Pathname subroutines.
7**
8** Brendan Eich, 8/29/95
9*/
10#include <assert.h>
11#include <sys/types.h>
12#include <dirent.h>
13#include <errno(*__errno_location ()).h>
14#include <stdarg.h>
15#include <stdio.h>
16#include <stdlib.h>
17#include <string.h>
18#include <unistd.h>
19#include <sys/stat.h>
20#include "pathsub.h"
21
22#ifdef USE_REENTRANT_LIBC
23# include <libc_r.h>
24#endif
25
26#ifdef SUNOS4
27# include "sunos4.h"
28#endif
29
30char* program;
31
32void fail(const char* format, ...) {
33 int error;
34 va_list ap;
35
36#ifdef USE_REENTRANT_LIBC
37 R_STRERROR_INIT_R();
38#endif
39
40 error = errno(*__errno_location ());
41 fprintf(stderrstderr, "%s: ", program);
42 va_start(ap, format)__builtin_va_start(ap, format);
43 vfprintf(stderrstderr, format, ap);
44 va_end(ap)__builtin_va_end(ap);
45 if (error) {
46#ifdef USE_REENTRANT_LIBC
47 R_STRERROR_R(errno(*__errno_location ()));
48 fprintf(stderrstderr, ": %s", r_strerror_r);
49#else
50 fprintf(stderrstderr, ": %s", strerror(errno(*__errno_location ())));
51#endif
52 }
53
54 putc('\n', stderrstderr);
55 exit(1);
56}
57
58char* getcomponent(char* path, char* name) {
59 if (*path == '\0') return 0;
60 if (*path == '/') {
61 *name++ = '/';
62 } else {
63 do {
64 *name++ = *path++;
65 } while (*path != '/' && *path != '\0');
66 }
67 *name = '\0';
68 while (*path == '/') path++;
69 return path;
70}
71
72#ifdef LAME_READDIR
73# include <sys/param.h>
74/*
75** The static buffer in Unixware's readdir is too small.
76*/
77struct dirent* readdir(DIR* d) {
78 static struct dirent* buf = NULL((void*)0);
79
80 if (buf == NULL((void*)0))
81 buf = (struct dirent*)malloc(sizeof(struct dirent) + MAXPATHLEN);
82 return (readdir_r(d, buf));
83}
84#endif
85
86char* ino2name(ino_t ino) {
87 DIR* dp;
88 struct dirent* ep;
89 char* name;
90
91 dp = opendir("..");
92 if (!dp) fail("cannot read parent directory");
9
Assuming 'dp' is non-null
10
Taking false branch
93 for (;;) {
11
Loop condition is true. Entering loop body
94 if (!(ep = readdir(dp))) fail("cannot find current directory");
12
Value assigned to 'ep'
13
Assuming 'ep' is null
14
Assuming pointer value is null
15
Taking true branch
95 if (ep->d_ino == ino) break;
16
Access to field 'd_ino' results in a dereference of a null pointer (loaded from variable 'ep')
96 }
97 name = xstrdup(ep->d_name);
98 closedir(dp);
99 return name;
100}
101
102void* xmalloc(size_t size) {
103 void* p = malloc(size);
104 if (!p) fail("cannot allocate %u bytes", size);
105 return p;
106}
107
108char* xstrdup(char* s) { return strcpy(xmalloc(strlen(s) + 1), s); }
109
110char* xbasename(char* path) {
111 char* cp;
112
113 while ((cp = strrchr(path, '/')) && cp[1] == '\0') *cp = '\0';
114 if (!cp) return path;
115 return cp + 1;
116}
117
118void xchdir(const char* dir) {
119 if (chdir(dir) < 0) fail("cannot change directory to %s", dir);
120}
121
122int relatepaths(char* from, char* to, char* outpath) {
123 char *cp, *cp2;
124 int len;
125 char buf[NAME_MAX256];
126
127 assert(*from == '/' && *to == '/')((void) sizeof ((*from == '/' && *to == '/') ? 1 : 0)
, __extension__ ({ if (*from == '/' && *to == '/') ; else
__assert_fail ("*from == '/' && *to == '/'", "/var/lib/jenkins/workspace/firefox-scan-build/config/pathsub.c"
, 127, __extension__ __PRETTY_FUNCTION__); }))
;
128 for (cp = to, cp2 = from; *cp == *cp2; cp++, cp2++)
129 if (*cp == '\0') break;
130 while (cp[-1] != '/') cp--, cp2--;
131 if (cp - 1 == to) {
132 /* closest common ancestor is /, so use full pathname */
133 len = strlen(strcpy(outpath, to));
134 if (outpath[len] != '/') {
135 outpath[len++] = '/';
136 outpath[len] = '\0';
137 }
138 } else {
139 len = 0;
140 while ((cp2 = getcomponent(cp2, buf)) != 0) {
141 strcpy(outpath + len, "../");
142 len += 3;
143 }
144 while ((cp = getcomponent(cp, buf)) != 0) {
145 sprintf(outpath + len, "%s/", buf);
146 len += strlen(outpath + len);
147 }
148 }
149 return len;
150}
151
152void reversepath(char* inpath, char* name, int len, char* outpath) {
153 char *cp, *cp2;
154 char buf[NAME_MAX256];
155 struct stat sb;
156
157 cp = strcpy(outpath + PATH_MAX4096 - (len + 1), name);
158 cp2 = inpath;
159 while ((cp2 = getcomponent(cp2, buf)) != 0) {
1
Loop condition is true. Entering loop body
160 if (strcmp(buf, ".") == 0) continue;
2
Assuming the condition is false
3
Taking false branch
161 if (strcmp(buf, "..") == 0) {
4
Assuming the condition is true
5
Taking true branch
162 if (stat(".", &sb) < 0) fail("cannot stat current directory");
6
Assuming the condition is false
7
Taking false branch
163 name = ino2name(sb.st_ino);
8
Calling 'ino2name'
164 len = strlen(name);
165 cp -= len + 1;
166 strcpy(cp, name);
167 cp[len] = '/';
168 free(name);
169 xchdir("..");
170 } else {
171 cp -= 3;
172 strncpy(cp, "../", 3);
173 xchdir(buf);
174 }
175 }
176 strcpy(outpath, cp);
177}