diff --git a/releasenotes.md b/releasenotes.md index c010d1a52..57192a29e 100644 --- a/releasenotes.md +++ b/releasenotes.md @@ -15,6 +15,7 @@ - Concatenating a const empty slice with another array caused a null pointer access. - Fix `linux-crt` and `linux-crtbegin` not getting recognized as a project paramater - Fix dues to crash when converting a const vector to another vector #1864. +- Filter `$exec` output from `\r`, which otherwise would cause a compiler assert #1867. ### Stdlib changes - Added '%h' and '%H' for printing out binary data in hexadecimal using the formatter. diff --git a/src/compiler/compiler.c b/src/compiler/compiler.c index e85c9f593..6d9798922 100644 --- a/src/compiler/compiler.c +++ b/src/compiler/compiler.c @@ -1525,7 +1525,7 @@ File *compile_and_invoke(const char *file, const char *args, const char *stdin_d scratch_buffer_append_native_safe_path(file_name.ptr, file_name.len); } scratch_buffer_printf(" -o %s", output); - const char *out; + char *out; if (PLATFORM_WINDOWS) scratch_buffer_append_char('"'); if (!execute_cmd_failable(scratch_buffer_to_string(), &out, NULL)) { diff --git a/src/compiler/compiler_internal.h b/src/compiler/compiler_internal.h index 6b0511d09..aa113420a 100644 --- a/src/compiler/compiler_internal.h +++ b/src/compiler/compiler_internal.h @@ -2365,7 +2365,7 @@ bool sema_type_error_on_binop(SemaContext *context, Expr *expr); File *source_file_by_id(FileId file); File *source_file_load(const char *filename, bool *already_loaded, const char **error); File *source_file_generate(const char *filename); -File *source_file_text_load(const char *filename, const char *content); +File *source_file_text_load(const char *filename, char *content); File *compile_and_invoke(const char *file, const char *args, const char *stdin_data); void compiler_parse(void); diff --git a/src/compiler/sema_passes.c b/src/compiler/sema_passes.c index 9cc71c6aa..ddca42c67 100644 --- a/src/compiler/sema_passes.c +++ b/src/compiler/sema_passes.c @@ -296,7 +296,7 @@ static Decl **sema_run_exec(CompilationUnit *unit, Decl *decl) } else { - const char *output = execute_cmd(scratch_buffer_to_string(), false, stdin_string); + char *output = execute_cmd(scratch_buffer_to_string(), false, stdin_string); file = source_file_text_load(scratch_buffer_to_string(), output); } if (old_path) diff --git a/src/compiler/source_file.c b/src/compiler/source_file.c index b06237322..389d9ea0d 100644 --- a/src/compiler/source_file.c +++ b/src/compiler/source_file.c @@ -22,13 +22,13 @@ File *source_file_by_id(FileId file) return compiler.context.loaded_sources[file]; } -File *source_file_text_load(const char *filename, const char *content) +File *source_file_text_load(const char *filename, char *content) { File *file = CALLOCS(File); file->file_id = vec_size(compiler.context.loaded_sources); file->full_path = str_copy(filename, strlen(filename)); + file->content_len = file_clean_buffer(content, filename, strlen(content)); file->contents = content; - file->content_len = strlen(content); file->name = (char *)file->full_path; file->dir_path = str_copy("", 0); vec_add(compiler.context.loaded_sources, file); diff --git a/src/utils/file_utils.c b/src/utils/file_utils.c index 4d75705d0..ba3d81bc9 100644 --- a/src/utils/file_utils.c +++ b/src/utils/file_utils.c @@ -215,34 +215,8 @@ bool file_touch(const char *path) return fclose(file) == 0; } -char *file_read_all(const char *path, size_t *return_size) +size_t file_clean_buffer(char *buffer, const char *path, size_t file_size) { - FILE *file = file_open_read(path); - - if (file == NULL) - { - error_exit("Could not open file \"%s\".\n", path); - } - - fseek(file, 0L, SEEK_END); - size_t file_size = (size_t)ftell(file); - *return_size = file_size; - rewind(file); - - char *buffer = (char *)MALLOC(file_size + 1); - if (buffer == NULL) - { - error_exit("Not enough memory to read \"%s\".\n", path); - } - - size_t bytes_read = fread(buffer, sizeof(char), file_size, file); - if (bytes_read < file_size) - { - error_exit("Failed to read file \"%s\".\n", path); - } - ASSERT(bytes_read == file_size); - buffer[bytes_read] = '\0'; - size_t offset = 0; // Simple UTF16 detection if (buffer[0] == (char)0xFF || buffer[1] == (char)0xFE) @@ -269,8 +243,41 @@ char *file_read_all(const char *path, size_t *return_size) buffer[i] = c; } } - buffer[bytes_read - offset] = '\0'; + file_size -= offset; + buffer[file_size] = '\0'; + return file_size; +} + +char *file_read_all(const char *path, size_t *return_size) +{ + FILE *file = file_open_read(path); + + if (file == NULL) + { + error_exit("Could not open file \"%s\".\n", path); + } + + fseek(file, 0L, SEEK_END); + size_t file_size = (size_t)ftell(file); + *return_size = file_size; + rewind(file); + + char *buffer = (char *)MALLOC(file_size + 1); + if (buffer == NULL) + { + error_exit("Not enough memory to read \"%s\".\n", path); + } + + size_t bytes_read = fread(buffer, sizeof(char), file_size, file); + if (bytes_read < file_size) + { + error_exit("Failed to read file \"%s\".\n", path); + } + ASSERT(bytes_read == file_size); + + buffer[bytes_read] = '\0'; fclose(file); + file_clean_buffer(buffer, path, file_size); return buffer; } @@ -696,9 +703,9 @@ const char **target_expand_source_names(const char *base_dir, const char** dirs, #define BUFSIZE 1024 -const char *execute_cmd(const char *cmd, bool ignore_failure, const char *stdin_string) +char *execute_cmd(const char *cmd, bool ignore_failure, const char *stdin_string) { - const char *result = NULL; + char *result = NULL; bool success = execute_cmd_failable(cmd, &result, stdin_string); if (!success) { @@ -708,7 +715,7 @@ const char *execute_cmd(const char *cmd, bool ignore_failure, const char *stdin_ return result; } -bool execute_cmd_failable(const char *cmd, const char **result, const char *stdin_string) +bool execute_cmd_failable(const char *cmd, char **result, const char *stdin_string) { char buffer[BUFSIZE]; char *output = ""; diff --git a/src/utils/lib.h b/src/utils/lib.h index 44499d001..66ee7c74e 100644 --- a/src/utils/lib.h +++ b/src/utils/lib.h @@ -82,6 +82,7 @@ FILE *file_open_read(const char *path); bool file_touch(const char *path); char *file_read_binary(const char *path, size_t *size); char *file_read_all(const char *path, size_t *return_size); +size_t file_clean_buffer(char *buffer, const char *path, size_t file_size); void file_get_dir_and_filename_from_full(const char *full_path, char **filename, char **dir_path); void file_find_top_dir(); bool file_has_suffix_in_list(const char *file_name, int name_len, const char **suffix_list, int suffix_count); @@ -91,9 +92,9 @@ const char *file_append_path_temp(const char *path, const char *name); const char **target_expand_source_names(const char *base_dir, const char** dirs, const char **suffix_list, const char ***object_list_ref, int suffix_count, bool error_on_mismatch); -const char *execute_cmd(const char *cmd, bool ignore_failure, const char *stdin_string); +char * execute_cmd(const char *cmd, bool ignore_failure, const char *stdin_string); -bool execute_cmd_failable(const char *cmd, const char **result, const char *stdin_string); +bool execute_cmd_failable(const char *cmd, char **result, const char *stdin_string); void *cmalloc(size_t size); void *ccalloc(size_t size, size_t elements); void memory_init(size_t max_mem);