diff --git a/src/gb/gb.h b/src/gb/gb.h index 84bbc2e0e..793011028 100644 --- a/src/gb/gb.h +++ b/src/gb/gb.h @@ -5613,7 +5613,7 @@ gb_inline b32 gb_path_is_absolute(char const *path) { b32 result = false; GB_ASSERT(path != NULL); #if defined(GB_SYSTEM_WINDOWS) - result == (gb_strlen(path) > 2) && + result = (gb_strlen(path) > 2) && gb_char_is_alpha(path[0]) && (path[1] == ':' && path[2] == GB_PATH_SEPARATOR); #else diff --git a/src/main.cpp b/src/main.cpp index ba2718194..c4b4441d8 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -2743,10 +2743,11 @@ gb_internal int print_show_help(String const arg0, String command, String option if (check) { if (print_flag("-collection:=")) { - print_usage_line(2, "Defines a library collection used for imports."); + print_usage_line(2, "Defines a library collection used for imports and foreign imports."); print_usage_line(2, "Example: -collection:shared=dir/to/shared"); print_usage_line(2, "Usage in Code:"); print_usage_line(3, "import \"shared:foo\""); + print_usage_line(3, "foreign import lib \"shared:libfoo.a\""); } if (print_flag("-custom-attribute:")) { diff --git a/src/parser.cpp b/src/parser.cpp index 0e7ec1d60..64112e085 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -6054,6 +6054,19 @@ gb_internal bool is_import_path_valid(String const &path) { return false; } +gb_internal bool is_import_path_absolute(String const &path) { + if (path.len > 0 && path[0] == '/') { + return true; + } + if (path.len > 2 && + gb_char_is_alpha(path[0]) && + path[1] == ':' && + (path[2] == '/' || path[2] == '\\')) { + return true; + } + return false; +} + gb_internal bool is_build_flag_path_valid(String const &path) { if (path.len > 0) { u8 *start = path.text; @@ -6116,12 +6129,13 @@ gb_internal bool determine_path_from_string(BlockingMutex *file_mutex, Ast *node do_warning = &syntax_warning; if (use_check_errors) { do_error = &error; - do_error = &warning; + do_warning = &warning; } // NOTE(bill): if file_mutex == nullptr, this means that the code is used within the semantics stage String collection_name = {}; + bool is_import_decl_path = node->kind == Ast_ImportDecl || node->kind == Ast_ForeignImportDecl; isize colon_pos = -1; for (isize j = 0; j < original_string.len; j++) { @@ -6134,11 +6148,13 @@ gb_internal bool determine_path_from_string(BlockingMutex *file_mutex, Ast *node bool has_windows_drive = false; #if defined(GB_SYSTEM_WINDOWS) if (file_mutex == nullptr) { - if (colon_pos == 1 && original_string.len > 2) { - if (original_string[2] == '/' || original_string[2] == '\\') { - colon_pos = -1; - has_windows_drive = true; - } + if (!is_import_decl_path && + colon_pos == 1 && + original_string.len > 2 && + gb_char_is_alpha(original_string[0]) && + (original_string[2] == '/' || original_string[2] == '\\')) { + colon_pos = -1; + has_windows_drive = true; } for (isize i = 0; i < original_string.len; i++) { @@ -6162,6 +6178,10 @@ gb_internal bool determine_path_from_string(BlockingMutex *file_mutex, Ast *node file_str = original_string; } + if (is_import_decl_path && is_import_path_absolute(file_str)) { + do_error(node, "Invalid import path: '%.*s'", LIT(file_str)); + return false; + } if (has_windows_drive) { String sub_file_path = substring(file_str, 3, file_str.len); @@ -6234,8 +6254,7 @@ gb_internal bool determine_path_from_string(BlockingMutex *file_mutex, Ast *node if (has_windows_drive) { *path = file_str; } else { - bool ok = false; - String fullpath = string_trim_whitespace(get_fullpath_relative(permanent_allocator(), base_dir, file_str, &ok)); + String fullpath = string_trim_whitespace(get_fullpath_relative(permanent_allocator(), base_dir, file_str, nullptr)); *path = fullpath; } return true; @@ -6287,6 +6306,12 @@ gb_internal void parse_setup_file_decls(Parser *p, AstFile *f, String const &bas ast_node(id, ImportDecl, node); String original_string = string_trim_whitespace(string_value_from_token(f, id->relpath)); + if (is_import_path_absolute(original_string)) { + syntax_error(node, "Invalid import path: '%.*s'", LIT(original_string)); + decls[i] = ast_bad_decl(f, id->relpath, id->relpath); + continue; + } + String import_path = {}; bool ok = determine_path_from_string(&p->file_decl_mutex, node, base_dir, original_string, &import_path); if (!ok) { @@ -6313,6 +6338,12 @@ gb_internal void parse_setup_file_decls(Parser *p, AstFile *f, String const &bas GB_ASSERT(fp->kind == Ast_BasicLit); Token fp_token = fp->BasicLit.token; String file_str = string_trim_whitespace(string_value_from_token(f, fp_token)); + if (is_import_path_absolute(file_str)) { + syntax_error(node, "Invalid import path: '%.*s'", LIT(file_str)); + decls[i] = ast_bad_decl(f, fp_token, fp_token); + goto end; + } + String fullpath = file_str; if (!is_arch_wasm() || string_ends_with(fullpath, str_lit(".o"))) { String foreign_path = {}; @@ -7100,4 +7131,3 @@ gb_internal ParseFileError parse_packages(Parser *p, String init_filename) { return ParseFile_None; } -