Read entire file into malloc'd buffer. Returns NULL on error. */
| 1279 | |
| 1280 | /* Read entire file into malloc'd buffer. Returns NULL on error. */ |
| 1281 | static char *read_file_str(const char *path, size_t *out_len) { |
| 1282 | FILE *f = fopen(path, "r"); |
| 1283 | if (!f) { |
| 1284 | if (out_len) { |
| 1285 | *out_len = 0; |
| 1286 | } |
| 1287 | return NULL; |
| 1288 | } |
| 1289 | (void)fseek(f, 0, SEEK_END); |
| 1290 | long size = ftell(f); |
| 1291 | (void)fseek(f, 0, SEEK_SET); |
| 1292 | if (size < 0 || size > (long)CLI_MB_10 * CLI_MB_FACTOR) { /* cap at 10 MB */ |
| 1293 | (void)fclose(f); |
| 1294 | return NULL; |
| 1295 | } |
| 1296 | |
| 1297 | char *buf = malloc((size_t)size + CLI_SKIP_ONE); |
| 1298 | if (!buf) { |
| 1299 | (void)fclose(f); |
| 1300 | return NULL; |
| 1301 | } |
| 1302 | size_t nread = fread(buf, CLI_ELEM_SIZE, (size_t)size, f); |
| 1303 | (void)fclose(f); |
| 1304 | if (nread > (size_t)size) { |
| 1305 | nread = (size_t)size; |
| 1306 | } |
| 1307 | buf[nread] = '\0'; |
| 1308 | if (out_len) { |
| 1309 | *out_len = nread; |
| 1310 | } |
| 1311 | return buf; |
| 1312 | } |
| 1313 | |
| 1314 | /* Write string to file, creating parent dirs if needed. */ |
| 1315 | static int write_file_str(const char *path, const char *content) { |
no outgoing calls
no test coverage detected