Bug Summary

File:sb-file.c
Warning:line 85, column 14
Dereference of null pointer (loaded from variable 'err')

Annotated Source Code

1/*
2 * squareball: A general-purpose library for C99.
3 * Copyright (C) 2014-2018 Rafael G. Martins <rafael@rafaelmartins.eng.br>
4 *
5 * This program can be distributed under the terms of the BSD License.
6 * See the file LICENSE.
7 */
8
9#ifdef HAVE_CONFIG_H1
10#include <config.h>
11#endif /* HAVE_CONFIG_H */
12
13#ifdef HAVE_SYS_STAT_H1
14#include <sys/stat.h>
15#endif /* HAVE_SYS_STAT_H */
16
17#ifdef HAVE_SYS_TYPES_H1
18#include <sys/types.h>
19#endif /* HAVE_SYS_TYPES_H */
20
21#include <errno(*__errno_location ()).h>
22#include <stdbool.h>
23#include <stdio.h>
24#include <stdlib.h>
25#include <string.h>
26#include <squareball/sb-error.h>
27#include <squareball/sb-strfuncs.h>
28#include <squareball/sb-string.h>
29#include <squareball/sb-utf8.h>
30
31
32static char*
33file_get_contents(const char *path, bool_Bool utf8, size_t *len, sb_error_t **err)
34{
35 if (path == NULL((void*)0) || len == NULL((void*)0))
3
Assuming 'path' is not equal to NULL
4
Assuming 'len' is not equal to NULL
5
Taking false branch
36 return NULL((void*)0);
37
38 if (err != NULL((void*)0) && *err != NULL((void*)0))
6
Assuming 'err' is equal to NULL
39 return NULL((void*)0);
40
41 *len = 0;
42
43 FILE *fp = fopen(path, "r");
44 int tmp_errno = errno(*__errno_location ());
45
46 if (fp == NULL((void*)0)) {
7
Assuming 'fp' is not equal to NULL
8
Taking false branch
47 if (err != NULL((void*)0))
48 *err = sb_error_new_printf(SB_ERROR_FILE_OPEN,
49 "Failed to open file (%s): %s", path, strerror(tmp_errno));
50 return NULL((void*)0);
51 }
52
53 sb_string_t *str = sb_string_new();
54
55 char buffer[1024];
56 char *tmp;
57
58 while (!feof(fp) && !ferror(fp)) {
9
Assuming the condition is false
59 size_t read_len = fread(buffer, sizeof(char), 1024, fp);
60 tmp_errno = errno(*__errno_location ());
61 if (ferror(fp)) {
62 if (err != NULL((void*)0))
63 *err = sb_error_new_printf(SB_ERROR_FILE_READ,
64 "Failed to read from file (%s): %s", path,
65 strerror(tmp_errno));
66 fclose(fp);
67 *len = 0;
68 sb_string_free(str, true1);
69 return NULL((void*)0);
70 }
71 tmp = buffer;
72 if (utf8 && str->len == 0 && read_len > 0) {
73 // skipping BOM before validation, for performance. should be safe
74 size_t skip = sb_utf8_bom_length((uint8_t*) buffer, read_len);
75 read_len -= skip;
76 tmp += skip;
77 }
78 *len += read_len;
79 sb_string_append_len(str, buffer, read_len);
80 }
81
82 fclose(fp);
83
84 if (utf8 && !sb_utf8_validate_str(str)) {
10
Assuming the condition is true
11
Taking true branch
85 *err = sb_error_new_printf(SB_ERROR_FILE_READ,
12
Dereference of null pointer (loaded from variable 'err')
86 "File content is not valid UTF-8: %s", path);
87 sb_string_free(str, true1);
88 return NULL((void*)0);
89 }
90
91 return sb_string_free(str, false0);
92}
93
94
95char*
96sb_file_get_contents(const char *path, size_t *len, sb_error_t **err)
97{
98 return file_get_contents(path, false0, len, err);
99}
100
101
102char*
103sb_file_get_contents_utf8(const char *path, size_t *len, sb_error_t **err)
104{
105 return file_get_contents(path, true1, len, err);
1
Passing value via 4th parameter 'err'
2
Calling 'file_get_contents'
106}
107
108
109void
110sb_file_put_contents(const char *path, const char* contents, ssize_t len,
111 sb_error_t **err)
112{
113 if (path == NULL((void*)0) || contents == NULL((void*)0) || len == 0)
114 return;
115
116 if (err != NULL((void*)0) && *err != NULL((void*)0))
117 return;
118
119 FILE *fp = fopen(path, "w");
120 int tmp_errno = errno(*__errno_location ());
121
122 if (fp == NULL((void*)0)) {
123 if (err != NULL((void*)0))
124 *err = sb_error_new_printf(SB_ERROR_FILE_OPEN,
125 "Failed to open file (%s): %s", path, strerror(tmp_errno));
126 return;
127 }
128
129 // TODO: optimize. write in chunks, maybe?
130 if (len < 0)
131 len = strlen(contents);
132 size_t written_len = fwrite(contents, sizeof(char), len, fp);
133 tmp_errno = errno(*__errno_location ());
134
135 if (ferror(fp)) {
136 if (err != NULL((void*)0))
137 *err = sb_error_new_printf(SB_ERROR_FILE_WRITE,
138 "Failed to write to file (%s): %s", path, strerror(tmp_errno));
139 fclose(fp);
140 return;
141 }
142
143 fclose(fp);
144
145 if (written_len != len && err != NULL((void*)0))
146 *err = sb_error_new_printf(SB_ERROR_FILE_WRITE,
147 "Failed to write to file (%s): only %zu bytes written, from %zu",
148 written_len, len);
149}
150
151
152void
153sb_mkdir_recursive(const char *path, sb_error_t **err)
154{
155 if (path == NULL((void*)0))
156 return;
157
158 if (err != NULL((void*)0) && *err != NULL((void*)0))
159 return;
160
161 char *fname = sb_strdup(path);
162 char *tmp = fname;
163
164 while (1) {
165
166 if (*tmp != '/' && *tmp != '\\' && *tmp != '\0') {
167 tmp++;
168 continue;
169 }
170
171#if defined(HAVE_SYS_STAT_H1) && defined(HAVE_SYS_TYPES_H1)
172 char bkp = *tmp;
173 *tmp = '\0';
174 if ((strlen(fname) > 0) &&
175#if defined(WIN32) || defined(_WIN32)
176 (-1 == mkdir(fname)) &&
177#else
178 (-1 == mkdir(fname, 0777)) &&
179#endif
180 (errno(*__errno_location ()) != EEXIST17))
181 {
182 if (err != NULL((void*)0))
183 *err = sb_error_new_printf(SB_ERROR_DIR_CREATE,
184 "Failed to create directory (%s): %s", path,
185 strerror(errno(*__errno_location ())));
186 break;
187 }
188 *tmp = bkp;
189#else
190 if (err != NULL((void*)0))
191 *err = sb_error_new_printf(SB_ERROR_DIR_CREATE,
192 "Failed to create directory (%s): Unsupported platform", path);
193 break;
194#endif
195
196 if (*tmp == '\0')
197 break;
198
199 tmp++;
200 }
201 free(fname);
202}