libgit2-sys
Advanced tools
| { | ||
| "git": { | ||
| "sha1": "c8e5d5d616fae4c965d38300083b87aadbec6d82" | ||
| "sha1": "591952f8cf344b2676db16b4f67c68875713f2e8" | ||
| }, | ||
| "path_in_vcs": "libgit2-sys" | ||
| } |
+1
-1
@@ -10,3 +10,3 @@ use std::env; | ||
| let mut cfg = pkg_config::Config::new(); | ||
| match cfg.range_version("1.9.0".."1.10.0").probe("libgit2") { | ||
| match cfg.range_version("1.9.2".."1.10.0").probe("libgit2") { | ||
| Ok(lib) => { | ||
@@ -13,0 +13,0 @@ for include in &lib.include_paths { |
+1
-1
@@ -67,3 +67,3 @@ # This file is automatically @generated by Cargo. | ||
| name = "libgit2-sys" | ||
| version = "0.18.2+1.9.1" | ||
| version = "0.18.3+1.9.2" | ||
| dependencies = [ | ||
@@ -70,0 +70,0 @@ "cc", |
+2
-2
@@ -13,5 +13,5 @@ # THIS FILE IS AUTOMATICALLY GENERATED BY CARGO | ||
| [package] | ||
| edition = "2018" | ||
| edition = "2021" | ||
| name = "libgit2-sys" | ||
| version = "0.18.2+1.9.1" | ||
| version = "0.18.3+1.9.2" | ||
| authors = [ | ||
@@ -18,0 +18,0 @@ "Josh Triplett <josh@joshtriplett.org>", |
+11
-0
| # Changelog | ||
| ## 0.18.3+1.9.2 - 2025-12-06 | ||
| [0.18.2...0.18.3](https://github.com/rust-lang/git2-rs/compare/libgit2-sys-0.18.2+1.9.1...libgit2-sys-0.18.3+1.9.2) | ||
| ### Changed | ||
| - Updated to libgit2 [1.9.2](https://github.com/libgit2/libgit2/releases/tag/v1.9.2) | ||
| [#1195](https://github.com/rust-lang/git2-rs/pull/1195) | ||
| Note that this release fixes two security issues. However, the Rust bindings do not provide direct support for the affected APIs. In particular: | ||
| - The `libgit2-sys` crate does not support building the vendored C library with the `GIT_SSH_EXEC` setting. This will only be an issue if you are binding to a system-provided library built with this setting. | ||
| - The `git2` crate does not support custom SSH credentials. However, the `libgit2-sys` crate does export the `git_cred_ssh_custom_new` C-binding. Any projects using the C bindings directly are affected. | ||
| ## 0.18.2+1.9.1 - 2025-06-21 | ||
@@ -4,0 +15,0 @@ [0.18.1...0.18.2](https://github.com/rust-lang/git2-rs/compare/libgit2-sys-0.18.1+1.9.0...libgit2-sys-0.18.2+1.9.1) |
@@ -16,2 +16,5 @@ # Platform specific compilation flags | ||
| # Remove warnings about operands that use different enum types. | ||
| set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /wd5287") | ||
| if(NOT (MSVC_VERSION LESS 1900)) | ||
@@ -18,0 +21,0 @@ # /guard:cf - Enable Control Flow Guard |
@@ -9,3 +9,3 @@ # libgit2: the cross-platform, linkable library implementation of git. | ||
| project(libgit2 VERSION "1.9.1" LANGUAGES C) | ||
| project(libgit2 VERSION "1.9.2" LANGUAGES C) | ||
@@ -12,0 +12,0 @@ # Add find modules to the path |
@@ -24,3 +24,3 @@ /* | ||
| */ | ||
| #define LIBGIT2_VERSION "1.9.1" | ||
| #define LIBGIT2_VERSION "1.9.2" | ||
@@ -34,3 +34,3 @@ /** The major version number for this version of libgit2. */ | ||
| /** The revision ("teeny") version number for this version of libgit2. */ | ||
| #define LIBGIT2_VERSION_REVISION 1 | ||
| #define LIBGIT2_VERSION_REVISION 2 | ||
@@ -37,0 +37,0 @@ /** The Windows DLL patch number for this version of libgit2. */ |
| { | ||
| "name": "libgit2", | ||
| "version": "1.9.1", | ||
| "version": "1.9.2", | ||
| "repo": "https://github.com/libgit2/libgit2", | ||
@@ -5,0 +5,0 @@ "description": " A cross-platform, linkable library implementation of Git that you can use in your application.", |
@@ -164,3 +164,3 @@ /* | ||
| /* Zero the memory which previously held the publickey */ | ||
| size_t key_len = strlen(c->publickey); | ||
| size_t key_len = c->publickey_len; | ||
| git__memzero(c->publickey, key_len); | ||
@@ -167,0 +167,0 @@ git__free(c->publickey); |
@@ -123,3 +123,4 @@ /* | ||
| static int get_ssh_cmdline( | ||
| git_str *out, | ||
| git_vector *args, | ||
| bool *use_shell, | ||
| ssh_exec_subtransport *transport, | ||
@@ -132,3 +133,4 @@ git_net_url *url, | ||
| git_config *cfg; | ||
| git_str ssh_cmd = GIT_STR_INIT; | ||
| git_str ssh_cmd = GIT_STR_INIT, url_and_host = GIT_STR_INIT, | ||
| remote_cmd = GIT_STR_INIT; | ||
| const char *default_ssh_cmd = "ssh"; | ||
@@ -156,21 +158,53 @@ int error; | ||
| if ((error = git__getenv(&ssh_cmd, "GIT_SSH")) == 0) | ||
| ; | ||
| if ((error = git__getenv(&ssh_cmd, "GIT_SSH_COMMAND")) == 0) | ||
| *use_shell = true; | ||
| else if (error != GIT_ENOTFOUND) | ||
| goto done; | ||
| else if ((error = git__getenv(&ssh_cmd, "GIT_SSH")) == 0) | ||
| *use_shell = false; | ||
| else if (error != GIT_ENOTFOUND) | ||
| goto done; | ||
| else if ((error = git_config__get_string_buf(&ssh_cmd, cfg, "core.sshcommand")) < 0 && error != GIT_ENOTFOUND) | ||
| goto done; | ||
| error = git_str_printf(out, "%s %s %s \"%s%s%s\" \"%s\" \"%s\"", | ||
| ssh_cmd.size > 0 ? ssh_cmd.ptr : default_ssh_cmd, | ||
| url->port_specified ? "-p" : "", | ||
| url->port_specified ? url->port : "", | ||
| url->username ? url->username : "", | ||
| url->username ? "@" : "", | ||
| url->host, | ||
| command, | ||
| url->path); | ||
| git_error_clear(); | ||
| if (!ssh_cmd.size && | ||
| git_str_puts(&ssh_cmd, default_ssh_cmd) < 0) | ||
| goto done; | ||
| if ((error = git_vector_insert(args, git_str_detach(&ssh_cmd))) < 0) | ||
| goto done; | ||
| if (url->port_specified) { | ||
| char *p = git__strdup("-p"); | ||
| char *port = git__strdup(url->port); | ||
| if (!p || !port || | ||
| (error = git_vector_insert(args, p)) < 0 || | ||
| (error = git_vector_insert(args, port)) < 0) | ||
| goto done; | ||
| } | ||
| if (url->username) { | ||
| if ((error = git_str_puts(&url_and_host, url->username)) < 0 || | ||
| (error = git_str_putc(&url_and_host, '@')) < 0) | ||
| goto done; | ||
| } | ||
| if ((error = git_str_puts(&url_and_host, url->host)) < 0 || | ||
| (error = git_vector_insert(args, git_str_detach(&url_and_host))) < 0) | ||
| goto done; | ||
| if ((error = git_str_puts(&remote_cmd, command)) < 0 || | ||
| (error = git_str_puts(&remote_cmd, " '")) < 0 || | ||
| (error = git_str_puts_escaped(&remote_cmd, url->path, "'!", "'\\", "'")) < 0 || | ||
| (error = git_str_puts(&remote_cmd, "'")) < 0 || | ||
| (error = git_vector_insert(args, git_str_detach(&remote_cmd))) < 0) | ||
| goto done; | ||
| done: | ||
| git_str_dispose(&ssh_cmd); | ||
| git_str_dispose(&url_and_host); | ||
| git_str_dispose(&remote_cmd); | ||
| git_config_free(cfg); | ||
@@ -189,3 +223,4 @@ return error; | ||
| git_net_url url = GIT_NET_URL_INIT; | ||
| git_str ssh_cmdline = GIT_STR_INIT; | ||
| git_vector args = GIT_VECTOR_INIT; | ||
| bool use_shell = false; | ||
| const char *command; | ||
@@ -221,7 +256,11 @@ int error; | ||
| if ((error = get_ssh_cmdline(&ssh_cmdline, transport, &url, command)) < 0) | ||
| if ((error = get_ssh_cmdline(&args, &use_shell, | ||
| transport, &url, command)) < 0) | ||
| goto done; | ||
| if ((error = git_process_new_from_cmdline(&transport->process, | ||
| ssh_cmdline.ptr, env, ARRAY_SIZE(env), &process_opts)) < 0 || | ||
| process_opts.use_shell = use_shell; | ||
| if ((error = git_process_new(&transport->process, | ||
| (const char **)args.contents, args.length, | ||
| env, ARRAY_SIZE(env), &process_opts)) < 0 || | ||
| (error = git_process_start(transport->process)) < 0) { | ||
@@ -234,3 +273,3 @@ git_process_free(transport->process); | ||
| done: | ||
| git_str_dispose(&ssh_cmdline); | ||
| git_vector_dispose_deep(&args); | ||
| git_net_url_dispose(&url); | ||
@@ -237,0 +276,0 @@ return error; |
@@ -614,2 +614,33 @@ /* | ||
| #ifdef GIT_WIN32 | ||
| bool git_fs_path_isexecutable(const char *path) | ||
| { | ||
| struct stat st; | ||
| GIT_ASSERT_ARG_WITH_RETVAL(path, false); | ||
| if (git__suffixcmp_icase(path, ".exe") != 0 && | ||
| git__suffixcmp_icase(path, ".cmd") != 0) | ||
| return false; | ||
| return (p_stat(path, &st) == 0); | ||
| } | ||
| #else | ||
| bool git_fs_path_isexecutable(const char *path) | ||
| { | ||
| struct stat st; | ||
| GIT_ASSERT_ARG_WITH_RETVAL(path, false); | ||
| if (p_stat(path, &st) < 0) | ||
| return false; | ||
| return S_ISREG(st.st_mode) != 0 && | ||
| ((st.st_mode & S_IXUSR) != 0); | ||
| } | ||
| #endif | ||
| bool git_fs_path_islink(const char *path) | ||
@@ -2024,5 +2055,6 @@ { | ||
| int git_fs_path_find_executable(git_str *fullpath, const char *executable) | ||
| #ifdef GIT_WIN32 | ||
| static int find_executable(git_str *fullpath, const char *executable) | ||
| { | ||
| #ifdef GIT_WIN32 | ||
| git_win32_path fullpath_w, executable_w; | ||
@@ -2040,5 +2072,11 @@ int error; | ||
| return error; | ||
| } | ||
| #else | ||
| static int find_executable(git_str *fullpath, const char *executable) | ||
| { | ||
| git_str path = GIT_STR_INIT; | ||
| const char *current_dir, *term; | ||
| size_t current_dirlen; | ||
| bool found = false; | ||
@@ -2055,9 +2093,17 @@ | ||
| current_dirlen = term - current_dir; | ||
| git_str_clear(fullpath); | ||
| if (git_str_put(fullpath, current_dir, (term - current_dir)) < 0 || | ||
| git_str_putc(fullpath, '/') < 0 || | ||
| /* An empty path segment is treated as '.' */ | ||
| if (current_dirlen == 0 && git_str_putc(fullpath, '.')) | ||
| return -1; | ||
| else if (current_dirlen != 0 && | ||
| git_str_put(fullpath, current_dir, current_dirlen) < 0) | ||
| return -1; | ||
| if (git_str_putc(fullpath, '/') < 0 || | ||
| git_str_puts(fullpath, executable) < 0) | ||
| return -1; | ||
| if (git_fs_path_isfile(fullpath->ptr)) { | ||
| if (git_fs_path_isexecutable(fullpath->ptr)) { | ||
| found = true; | ||
@@ -2069,3 +2115,3 @@ break; | ||
| while (*current_dir == GIT_PATH_LIST_SEPARATOR) | ||
| if (*current_dir == GIT_PATH_LIST_SEPARATOR) | ||
| current_dir++; | ||
@@ -2081,3 +2127,17 @@ } | ||
| return GIT_ENOTFOUND; | ||
| } | ||
| #endif | ||
| int git_fs_path_find_executable(git_str *fullpath, const char *executable) | ||
| { | ||
| /* For qualified paths we do not look in PATH */ | ||
| if (strchr(executable, '/') != NULL) { | ||
| if (!git_fs_path_isexecutable(executable)) | ||
| return GIT_ENOTFOUND; | ||
| return git_str_puts(fullpath, executable); | ||
| } | ||
| return find_executable(fullpath, executable); | ||
| } |
@@ -208,2 +208,8 @@ /* | ||
| /** | ||
| * Check if the given path points to an executable. | ||
| * @return true or false | ||
| */ | ||
| extern bool git_fs_path_isexecutable(const char *path); | ||
| /** | ||
| * Check if the given path points to a symbolic link. | ||
@@ -210,0 +216,0 @@ * @return true or false |
@@ -14,3 +14,4 @@ /* | ||
| typedef struct { | ||
| unsigned int capture_in : 1, | ||
| unsigned int use_shell : 1, | ||
| capture_in : 1, | ||
| capture_out : 1, | ||
@@ -17,0 +18,0 @@ capture_err : 1, |
@@ -1068,6 +1068,9 @@ /* | ||
| const char *esc_chars, | ||
| const char *esc_with) | ||
| const char *esc_prefix, | ||
| const char *esc_suffix) | ||
| { | ||
| const char *scan; | ||
| size_t total = 0, esc_len = strlen(esc_with), count, alloclen; | ||
| size_t total = 0, count, alloclen; | ||
| size_t esc_prefix_len = esc_prefix ? strlen(esc_prefix) : 0; | ||
| size_t esc_suffix_len = esc_suffix ? strlen(esc_suffix) : 0; | ||
@@ -1084,3 +1087,3 @@ if (!string) | ||
| count = strspn(scan, esc_chars); | ||
| total += count * (esc_len + 1); | ||
| total += count * (esc_prefix_len + esc_suffix_len + 1); | ||
| scan += count; | ||
@@ -1101,5 +1104,8 @@ } | ||
| for (count = strspn(scan, esc_chars); count > 0; --count) { | ||
| /* copy escape sequence */ | ||
| memmove(buf->ptr + buf->size, esc_with, esc_len); | ||
| buf->size += esc_len; | ||
| /* copy escape prefix sequence */ | ||
| if (esc_prefix) { | ||
| memmove(buf->ptr + buf->size, esc_prefix, esc_prefix_len); | ||
| buf->size += esc_prefix_len; | ||
| } | ||
| /* copy character to be escaped */ | ||
@@ -1109,2 +1115,8 @@ buf->ptr[buf->size] = *scan; | ||
| scan++; | ||
| /* copy escape suffix sequence */ | ||
| if (esc_suffix) { | ||
| memmove(buf->ptr + buf->size, esc_suffix, esc_suffix_len); | ||
| buf->size += esc_suffix_len; | ||
| } | ||
| } | ||
@@ -1111,0 +1123,0 @@ } |
@@ -271,3 +271,4 @@ /* | ||
| * @param esc_chars Characters to be escaped | ||
| * @param esc_with String to insert in from of each found character | ||
| * @param esc_prefix String to insert as prefix of each found character | ||
| * @param esc_suffix String to insert as suffix of each found character | ||
| * @return 0 on success, <0 on failure (probably allocation problem) | ||
@@ -279,3 +280,4 @@ */ | ||
| const char *esc_chars, | ||
| const char *esc_with); | ||
| const char *esc_prefix, | ||
| const char *esc_suffix); | ||
@@ -287,3 +289,3 @@ /** | ||
| { | ||
| return git_str_puts_escaped(str, string, "^.[]$()|*+?{}\\", "\\"); | ||
| return git_str_puts_escaped(str, string, "^.[]$()|*+?{}\\", "\\", NULL); | ||
| } | ||
@@ -290,0 +292,0 @@ |
@@ -15,2 +15,3 @@ /* | ||
| #include "vector.h" | ||
| #include "futils.h" | ||
| #include "process.h" | ||
@@ -32,3 +33,4 @@ #include "strlist.h" | ||
| unsigned int capture_in : 1, | ||
| unsigned int use_shell : 1, | ||
| capture_in : 1, | ||
| capture_out : 1, | ||
@@ -55,2 +57,49 @@ capture_err : 1; | ||
| GIT_INLINE(int) insert_dup(git_vector *v, const char *s) | ||
| { | ||
| char *dup = git__strdup(s); | ||
| GIT_ERROR_CHECK_ALLOC(dup); | ||
| return git_vector_insert(v, dup); | ||
| } | ||
| static int setup_args( | ||
| char ***out, | ||
| const char **args, | ||
| size_t args_len, | ||
| bool use_shell) | ||
| { | ||
| git_vector prefixed = GIT_VECTOR_INIT; | ||
| git_str first = GIT_STR_INIT; | ||
| size_t cnt; | ||
| GIT_ASSERT(args && args_len); | ||
| if (use_shell) { | ||
| if (git_str_puts(&first, args[0]) < 0 || | ||
| git_str_puts(&first, " \"$@\"") < 0 || | ||
| insert_dup(&prefixed, "/bin/sh") < 0 || | ||
| insert_dup(&prefixed, "-c") < 0 || | ||
| git_vector_insert(&prefixed, git_str_detach(&first)) < 0) | ||
| goto on_error; | ||
| } | ||
| for (cnt = 0; args && cnt < args_len; cnt++) { | ||
| if (insert_dup(&prefixed, args[cnt]) < 0) | ||
| goto on_error; | ||
| } | ||
| git_vector_insert(&prefixed, NULL); | ||
| *out = (char **)prefixed.contents; | ||
| return 0; | ||
| on_error: | ||
| git_str_dispose(&first); | ||
| git_vector_dispose_deep(&prefixed); | ||
| return -1; | ||
| } | ||
| static int merge_env( | ||
@@ -63,3 +112,3 @@ char ***out, | ||
| git_vector merged = GIT_VECTOR_INIT; | ||
| char **kv, *dup; | ||
| char **kv; | ||
| size_t max, cnt; | ||
@@ -78,6 +127,3 @@ int error = 0; | ||
| dup = git__strdup(env[cnt]); | ||
| GIT_ERROR_CHECK_ALLOC(dup); | ||
| if ((error = git_vector_insert(&merged, dup)) < 0) | ||
| if (insert_dup(&merged, env[cnt]) < 0) | ||
| goto on_error; | ||
@@ -91,6 +137,3 @@ } | ||
| dup = git__strdup(*kv); | ||
| GIT_ERROR_CHECK_ALLOC(dup); | ||
| if ((error = git_vector_insert(&merged, dup)) < 0) | ||
| if (insert_dup(&merged, *kv) < 0) | ||
| goto on_error; | ||
@@ -134,3 +177,3 @@ } | ||
| if (git_strlist_copy_with_null(&process->args, args, args_len) < 0 || | ||
| if (setup_args(&process->args, args, args_len, opts ? opts->use_shell : false) < 0 || | ||
| merge_env(&process->env, env, env_len, opts ? opts->exclude_env : false) < 0) { | ||
@@ -142,2 +185,3 @@ git_process_free(process); | ||
| if (opts) { | ||
| process->use_shell = opts->use_shell; | ||
| process->capture_in = opts->capture_in; | ||
@@ -169,6 +213,8 @@ process->capture_out = opts->capture_out; | ||
| { | ||
| const char *args[] = { "/bin/sh", "-c", cmdline }; | ||
| git_process_options merged_opts = {0}; | ||
| return git_process_new(out, | ||
| args, ARRAY_SIZE(args), env, env_len, opts); | ||
| memcpy(&merged_opts, opts, sizeof(git_process_options)); | ||
| merged_opts.use_shell = 1; | ||
| return git_process_new(out, &cmdline, 1, env, env_len, &merged_opts); | ||
| } | ||
@@ -283,2 +329,29 @@ | ||
| static int resolve_path(git_process *process) | ||
| { | ||
| git_str full_path = GIT_STR_INIT; | ||
| int error = 0; | ||
| /* The shell will resolve the path for us */ | ||
| if (process->use_shell) | ||
| goto done; | ||
| error = git_fs_path_find_executable(&full_path, process->args[0]); | ||
| if (error == GIT_ENOTFOUND) { | ||
| git_error_set(GIT_ERROR_SSH, "cannot run %s: No such file or directory", process->args[0]); | ||
| error = -1; | ||
| } | ||
| if (error) | ||
| goto done; | ||
| git__free(process->args[0]); | ||
| process->args[0] = git_str_detach(&full_path); | ||
| done: | ||
| git_str_dispose(&full_path); | ||
| return error; | ||
| } | ||
| int git_process_start(git_process *process) | ||
@@ -291,2 +364,6 @@ { | ||
| /* Locate the path (unless we're letting the shell do it for us) */ | ||
| if ((error = resolve_path(process)) < 0) | ||
| goto on_error; | ||
| /* Set up the pipes to read from/write to the process */ | ||
@@ -293,0 +370,0 @@ if ((process->capture_in && pipe(in) < 0) || |
@@ -272,11 +272,24 @@ /* | ||
| int git__suffixcmp(const char *str, const char *suffix) | ||
| static int suffixcmp(const char *str, const char *suffix, bool icase) | ||
| { | ||
| size_t a = strlen(str); | ||
| size_t b = strlen(suffix); | ||
| if (a < b) | ||
| return -1; | ||
| return strcmp(str + (a - b), suffix); | ||
| return icase ? strcasecmp(str + (a - b), suffix) : | ||
| strcmp(str + (a - b), suffix); | ||
| } | ||
| int git__suffixcmp(const char *str, const char *suffix) | ||
| { | ||
| return suffixcmp(str, suffix, false); | ||
| } | ||
| int git__suffixcmp_icase(const char *str, const char *suffix) | ||
| { | ||
| return suffixcmp(str, suffix, true); | ||
| } | ||
| char *git__strtok(char **end, const char *sep) | ||
@@ -283,0 +296,0 @@ { |
@@ -60,2 +60,3 @@ /* | ||
| extern int git__suffixcmp(const char *str, const char *suffix); | ||
| extern int git__suffixcmp_icase(const char *str, const char *suffix); | ||
@@ -62,0 +63,0 @@ GIT_INLINE(int) git__signum(int val) |
@@ -156,2 +156,3 @@ /* | ||
| git_win32_path dest, | ||
| size_t *dest_len, | ||
| const wchar_t *one, | ||
@@ -180,2 +181,5 @@ size_t one_len, | ||
| if (dest_len) | ||
| *dest_len = one_len + backslash + two_len; | ||
| return 0; | ||
@@ -258,2 +262,57 @@ } | ||
| struct executable_suffix { | ||
| const wchar_t *suffix; | ||
| size_t len; | ||
| }; | ||
| static struct executable_suffix suffixes[] = { { NULL, 0 }, { L".exe", 4 }, { L".cmd", 4 } }; | ||
| static bool has_executable_suffix(wchar_t *exe, size_t exe_len) | ||
| { | ||
| size_t i; | ||
| for (i = 0; i < ARRAY_SIZE(suffixes); i++) { | ||
| struct executable_suffix *suffix = &suffixes[i]; | ||
| if (!suffix->len) | ||
| continue; | ||
| if (exe_len < suffix->len) | ||
| continue; | ||
| if (memcmp(&exe[exe_len - suffix->len], suffix->suffix, suffix->len) == 0) | ||
| return true; | ||
| } | ||
| return false; | ||
| } | ||
| static int is_executable(git_win32_path path, size_t path_len, bool suffixed) | ||
| { | ||
| size_t i; | ||
| /* | ||
| * if the given name has an executable suffix, then try looking for it | ||
| * directly. in all cases, append executable extensions | ||
| * (".exe", ".cmd"...) | ||
| */ | ||
| for (i = suffixed ? 0 : 1; i < ARRAY_SIZE(suffixes); i++) { | ||
| struct executable_suffix *suffix = &suffixes[i]; | ||
| if (suffix->len) { | ||
| if (path_len + suffix->len > MAX_PATH) | ||
| continue; | ||
| wcscat(path, suffix->suffix); | ||
| } | ||
| if (_waccess(path, 0) == 0) | ||
| return true; | ||
| path[path_len] = L'\0'; | ||
| } | ||
| return false; | ||
| } | ||
| int git_win32_path_find_executable(git_win32_path fullpath, wchar_t *exe) | ||
@@ -263,13 +322,29 @@ { | ||
| const wchar_t *dir; | ||
| size_t dir_len, exe_len = wcslen(exe); | ||
| bool found = false; | ||
| size_t dir_len, exe_len, fullpath_len; | ||
| bool suffixed = false, found = false; | ||
| if ((exe_len = wcslen(exe)) > MAX_PATH) | ||
| goto done; | ||
| /* see if the given executable has an executable suffix; if so we will | ||
| * look for the explicit name directly, as well as with added suffixes. | ||
| */ | ||
| suffixed = has_executable_suffix(exe, exe_len); | ||
| /* For fully-qualified paths we do not look in PATH */ | ||
| if (wcschr(exe, L'\\') != NULL || wcschr(exe, L'/') != NULL) { | ||
| if ((found = is_executable(exe, exe_len, suffixed))) | ||
| wcscpy(fullpath, exe); | ||
| goto done; | ||
| } | ||
| if (win32_path_iter_init(&path_iter) < 0) | ||
| return -1; | ||
| while (win32_path_iter_next(&dir, &dir_len, &path_iter) != GIT_ITEROVER) { | ||
| if (git_win32_path_join(fullpath, dir, dir_len, exe, exe_len) < 0) | ||
| while (win32_path_iter_next(&dir, &dir_len, &path_iter) != GIT_ITEROVER && !found) { | ||
| if (git_win32_path_join(fullpath, &fullpath_len, dir, dir_len, exe, exe_len) < 0) | ||
| continue; | ||
| if (_waccess(fullpath, 0) == 0) { | ||
| if (is_executable(fullpath, fullpath_len, suffixed)) { | ||
| found = true; | ||
@@ -282,2 +357,3 @@ break; | ||
| done: | ||
| if (found) | ||
@@ -284,0 +360,0 @@ return 0; |
@@ -14,2 +14,3 @@ /* | ||
| #include "strlist.h" | ||
| #include "fs_path.h" | ||
@@ -23,3 +24,4 @@ #ifndef DWORD_MAX | ||
| struct git_process { | ||
| wchar_t *appname; | ||
| char *app_name; | ||
| wchar_t *app_path; | ||
| wchar_t *cmdline; | ||
@@ -183,4 +185,3 @@ wchar_t *env; | ||
| if (appname && | ||
| git_utf8_to_16_alloc(&process->appname, appname) < 0) { | ||
| if (appname && (process->app_name = git__strdup(appname)) == NULL) { | ||
| error = -1; | ||
@@ -239,3 +240,3 @@ goto done; | ||
| { | ||
| git_str cmdline = GIT_STR_INIT; | ||
| git_str cmd_path = GIT_STR_INIT, cmdline = GIT_STR_INIT; | ||
| int error; | ||
@@ -251,2 +252,3 @@ | ||
| done: | ||
| git_str_dispose(&cmd_path); | ||
| git_str_dispose(&cmdline); | ||
@@ -267,2 +269,15 @@ return error; | ||
| if (process->app_name) { | ||
| git_str cmd_path = GIT_STR_INIT; | ||
| int error; | ||
| if ((error = git_fs_path_find_executable(&cmd_path, process->app_name)) == 0) | ||
| error = git_utf8_to_16_alloc(&process->app_path, cmd_path.ptr); | ||
| git_str_dispose(&cmd_path); | ||
| if (error < 0) | ||
| goto on_error; | ||
| } | ||
| memset(&security_attrs, 0, sizeof(SECURITY_ATTRIBUTES)); | ||
@@ -312,3 +327,3 @@ security_attrs.bInheritHandle = TRUE; | ||
| if (!CreateProcessW(process->appname, process->cmdline, | ||
| if (!CreateProcessW(process->app_path, process->cmdline, | ||
| NULL, NULL, TRUE, flags, process->env, | ||
@@ -511,4 +526,5 @@ process->cwd, | ||
| git__free(process->cmdline); | ||
| git__free(process->appname); | ||
| git__free(process->app_path); | ||
| git__free(process->app_name); | ||
| git__free(process); | ||
| } |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display