Bug Summary

File:lib/string.c
Warning:line 185, column 6
Array access (from variable 'start') results in a null pointer dereference

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name string.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 static -fno-delete-null-pointer-checks -mframe-pointer=none -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -ffreestanding -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -ffunction-sections -fdata-sections -fcoverage-compilation-dir=/home/coreboot/node-root/workspace/coreboot_scanbuild -nostdsysteminc -nobuiltininc -resource-dir /opt/xgcc/lib/clang/17 -include src/include/kconfig.h -include src/include/rules.h -include src/commonlib/bsd/include/commonlib/bsd/compiler.h -I src -I src/include -I src/commonlib/include -I src/commonlib/bsd/include -I /cb-build/coreboot_scanbuild.0/EMULATION_QEMU_RISCV_RV64_ -I 3rdparty/vboot/firmware/include -I 3rdparty -D __BUILD_DIR__="/cb-build/coreboot_scanbuild.0/EMULATION_QEMU_RISCV_RV64_" -D __COREBOOT__ -D __TIMELESS__ -I /home/coreboot/node-root/workspace/coreboot_scanbuild/3rdparty/opensbi/include -I src/mainboard/emulation/qemu-riscv/include -I src/arch/riscv/include -D __ARCH_riscv__ -I src/arch/riscv/ -D __riscv -D __riscv_xlen=64 -D __riscv_flen=64 -D __RAMSTAGE__ -source-date-epoch 1715206807 -Os -Wwrite-strings -Wno-trigraphs -Wno-address-of-packed-member -std=gnu11 -fconst-strings -fdebug-compilation-dir=/home/coreboot/node-root/workspace/coreboot_scanbuild -ferror-limit 19 -fno-builtin -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-max-loop 10 -analyzer-output=plist-html -faddrsig -o /cb-build/coreboot_scanbuild.0/EMULATION_QEMU_RISCV_RV64_-scanbuildtmp/2024-05-09-075035-3021732-1/report-pb9Yr7.plist -x c src/lib/string.c
1/* SPDX-License-Identifier: GPL-2.0-only */
2
3#include <assert.h>
4#include <ctype.h>
5#include <string.h>
6#include <stddef.h>
7#include <stdlib.h>
8
9char *strdup(const char *s)
10{
11 if (!ENV_RAMSTAGE1)
12 dead_code()_dead_code_assertion_failed(); /* This can't be used without malloc(). */
13
14 size_t sz = strlen(s) + 1;
15 char *d = malloc(sz);
16 if (d)
17 memcpy(d, s, sz);
18 return d;
19}
20
21char *strconcat(const char *s1, const char *s2)
22{
23 if (!ENV_RAMSTAGE1)
24 dead_code()_dead_code_assertion_failed(); /* This can't be used without malloc(). */
25
26 size_t sz_1 = strlen(s1);
27 size_t sz_2 = strlen(s2);
28 char *d = malloc(sz_1 + sz_2 + 1);
29 if (d) {
30 memcpy(d, s1, sz_1);
31 memcpy(d + sz_1, s2, sz_2 + 1);
32 }
33 return d;
34}
35
36size_t strnlen(const char *src, size_t max)
37{
38 size_t i = 0;
39 while ((*src++) && (i < max))
40 i++;
41 return i;
42}
43
44size_t strlen(const char *src)
45{
46 size_t i = 0;
47 while (*src++)
48 i++;
49 return i;
50}
51
52char *strchr(const char *s, int c)
53{
54 do {
55 if (*s == c)
56 return (char *)s;
57 } while (*s++);
58
59 return NULL((void *)0);
60}
61
62char *strrchr(const char *s, int c)
63{
64 char *p = NULL((void *)0);
65
66 do {
67 if (*s == c)
68 p = (char *)s;
69 } while (*s++);
70
71 return p;
72}
73
74char *strncpy(char *to, const char *from, int count)
75{
76 char *ret = to;
77 char data;
78
79 while (count > 0) {
80 count--;
81 data = *from++;
82 *to++ = data;
83 if (data == '\0')
84 break;
85 }
86
87 while (count > 0) {
88 count--;
89 *to++ = '\0';
90 }
91 return ret;
92}
93
94char *strcpy(char *dst, const char *src)
95{
96 char *ptr = dst;
97
98 while (*src)
99 *dst++ = *src++;
100 *dst = '\0';
101
102 return ptr;
103}
104
105int strcmp(const char *s1, const char *s2)
106{
107 int r;
108
109 while ((r = (*s1 - *s2)) == 0 && *s1) {
110 s1++;
111 s2++;
112 }
113 return r;
114}
115
116int strncmp(const char *s1, const char *s2, int maxlen)
117{
118 int i;
119
120 for (i = 0; i < maxlen; i++) {
121 if ((s1[i] != s2[i]) || (s1[i] == '\0'))
122 return s1[i] - s2[i];
123 }
124
125 return 0;
126}
127
128unsigned int skip_atoi(char **s)
129{
130 unsigned int i = 0;
131
132 while (isdigit(**s))
133 i = i*10 + *((*s)++) - '0';
134 return i;
135}
136
137int strspn(const char *str, const char *spn)
138{
139 int ret = 0;
140
141 while (*str != 0) {
142 const char *p;
143 for (p = spn; *str != *p; p++)
144 if (*p == '\0')
145 return ret;
146 ret++;
147 str++;
148 }
149 return ret;
150}
151
152int strcspn(const char *str, const char *spn)
153{
154 int ret = 0;
155
156 while (*str != 0) {
157 const char *p;
158 for (p = spn; *p != '\0'; p++)
159 if (*p == *str)
160 return ret;
161 ret++;
162 str++;
163 }
164 return ret;
165}
166
167char *strstr(const char *haystack, const char *needle)
168{
169 size_t needle_len = strlen(needle);
170 for (; *haystack; haystack++) {
171 if (!strncmp(haystack, needle, needle_len))
172 return (char *)haystack;
173 }
174 return NULL((void *)0);
175}
176
177char *strtok_r(char *str, const char *delim, char **ptr)
178{
179 char *start;
180 char *end;
181
182 if (str == NULL((void *)0))
2
Assuming 'str' is equal to NULL
3
Taking true branch
183 str = *ptr;
4
Null pointer value stored to 'str'
184 start = str + strspn(str, delim);
5
Null pointer value stored to 'start'
185 if (start[0] == '\0')
6
Array access (from variable 'start') results in a null pointer dereference
186 return NULL((void *)0);
187
188 end = start + strcspn(start, delim);
189 *ptr = end;
190 if (end[0] != '\0')
191 *(*ptr)++ = '\0';
192 return start;
193}
194
195char *strtok(char *str, const char *delim)
196{
197 static char *strtok_ptr;
198
199 return strtok_r(str, delim, &strtok_ptr);
1
Calling 'strtok_r'
200}
201
202long atol(const char *str)
203{
204 long ret = 0;
205 long sign = 1;
206
207 str += strspn(str, " \t\n\r\f\v");
208
209 if (*str == '+') {
210 sign = 1;
211 str++;
212 } else if (*str == '-') {
213 sign = -1;
214 str++;
215 }
216
217 while (isdigit(*str)) {
218 ret *= 10;
219 ret += *str++ - '0';
220 }
221 return ret * sign;
222}