Read entire file into malloc'd buffer. Returns NULL on error. */
| 3137 | |
| 3138 | /* Read entire file into malloc'd buffer. Returns NULL on error. */ |
| 3139 | static char *read_file_str(const char *path, size_t *out_len) { |
| 3140 | FILE *f = fopen(path, "r"); |
| 3141 | if (!f) { |
| 3142 | if (out_len) { |
| 3143 | *out_len = 0; |
| 3144 | } |
| 3145 | return NULL; |
| 3146 | } |
| 3147 | (void)fseek(f, 0, SEEK_END); |
| 3148 | long size = ftell(f); |
| 3149 | (void)fseek(f, 0, SEEK_SET); |
| 3150 | if (size < 0 || size > (long)CLI_MB_10 * CLI_MB_FACTOR) { /* cap at 10 MB */ |
| 3151 | (void)fclose(f); |
| 3152 | return NULL; |
| 3153 | } |
| 3154 | |
| 3155 | char *buf = malloc((size_t)size + CLI_SKIP_ONE); |
| 3156 | if (!buf) { |
| 3157 | (void)fclose(f); |
| 3158 | return NULL; |
| 3159 | } |
| 3160 | size_t nread = fread(buf, CLI_ELEM_SIZE, (size_t)size, f); |
| 3161 | (void)fclose(f); |
| 3162 | if (nread > (size_t)size) { |
| 3163 | nread = (size_t)size; |
| 3164 | } |
| 3165 | buf[nread] = '\0'; |
| 3166 | if (out_len) { |
| 3167 | *out_len = nread; |
| 3168 | } |
| 3169 | return buf; |
| 3170 | } |
| 3171 | |
| 3172 | static int ensure_parent_dir(const char *path) { |
| 3173 | if (!path || !path[0]) { |
no outgoing calls
no test coverage detected