• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

Tatsh / winprefs / 17632092298

11 Sep 2025 02:22AM UTC coverage: 99.583% (-0.1%) from 99.71%
17632092298

push

github

Tatsh
git: quote SSH key when configuring git

13 of 17 new or added lines in 3 files covered. (76.47%)

3101 of 3114 relevant lines covered (99.58%)

211.8 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

96.72
/native/git.c
1
#include "git.h"
2
#include "constants.h"
3
#include "git_branch.h"
4

5
// This function does NOT escape double quotes. Inner double quotes must be escaped by the caller.
6
static inline bool run_process_no_window(int n_args, wchar_t *arg0, ...) {
39✔
7
    PROCESS_INFORMATION pi = {0};
39✔
8
    STARTUPINFO si = {.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES,
39✔
9
                      .wShowWindow = SW_HIDE};
10
    wchar_t cmd[32767];
11
    wmemset(cmd, L'\0', 32767);
39✔
12
    va_list args;
13
    va_start(args, arg0);
39✔
14
    wchar_t *cur;
15
    size_t i = 0;
39✔
16
    size_t req_size = (size_t)_snwprintf(nullptr, 0, L"\"%ls\" ", arg0);
39✔
17
    _snwprintf(cmd, req_size + 1, L"\"%ls\" ", arg0);
39✔
18
    i += req_size;
39✔
19
    int index = 0;
39✔
20
    for (index = 0; index < (n_args - 1); index++) {
179✔
21
        cur = va_arg(args, wchar_t *);
140✔
22
        if (!cur) { // LCOV_EXCL_START
23
            break;
24
        } // LCOV_EXCL_STOP
25
        req_size = (size_t)_snwprintf(nullptr, 0, L"\"%ls\" ", cur);
140✔
26
        _snwprintf(cmd + i, req_size + 1, L"\"%ls\" ", cur);
140✔
27
        i += req_size;
140✔
28
    }
29
    va_end(args);
39✔
30
    if (i >= 32767) { // LCOV_EXCL_START
31
        return false;
32
    } // LCOV_EXCL_STOP
33
    cmd[i - 1] = L'\0';
39✔
34
    debug_print(L"Executing: '%ls'\n", cmd);
39✔
35
    bool ret = CreateProcess(
39✔
36
        nullptr, cmd, nullptr, nullptr, false, CREATE_NO_WINDOW, nullptr, nullptr, &si, &pi);
37
    if (ret) {
39✔
38
        WaitForSingleObject(pi.hProcess, INFINITE);
33✔
39
        DWORD exit_code;
40
        bool result = GetExitCodeProcess(pi.hProcess, &exit_code);
33✔
41
        CloseHandle(pi.hProcess);
33✔
42
        CloseHandle(pi.hThread);
33✔
43
        if (!result) {
33✔
44
            debug_print(L"Failed to get exit code.\n");
1✔
45
            return false;
1✔
46
        }
47
        debug_print(L"Exit code: %lu\n", exit_code);
32✔
48
        return exit_code == 0;
32✔
49
    }
50
    return ret;
6✔
51
}
52

53
static inline bool has_git() {
16✔
54
    return run_process_no_window(2, L"git.exe", L"--version");
16✔
55
}
56

57
static inline bool dir_exists(wchar_t *path) {
15✔
58
    DWORD attrib = GetFileAttributes(path);
15✔
59
    return attrib != INVALID_FILE_ATTRIBUTES && (attrib & FILE_ATTRIBUTE_DIRECTORY);
15✔
60
}
61

62
bool git_commit(const wchar_t *output_dir, const wchar_t *deploy_key) {
16✔
63
    bool ret = true;
16✔
64
    wchar_t *cwd, *date_buf, *escaped_full_deploy_key_path, *git_dir, *git_dir_arg, *message_buf,
65
        *ssh_command, *time_buf, *work_tree_arg;
66
    cwd = date_buf = escaped_full_deploy_key_path = git_dir = git_dir_arg = message_buf =
16✔
67
        ssh_command = time_buf = work_tree_arg = nullptr;
16✔
68
    if (!has_git()) {
16✔
69
        debug_print(L"Wanted to commit but git.exe is not in PATH or failed to run.\n");
1✔
70
        goto cleanup;
1✔
71
    }
72
    debug_print(L"Committing changes.\n");
15✔
73
    size_t work_tree_arg_len = wcslen(output_dir) + wcslen(L"--work-tree=") + 1;
15✔
74
    work_tree_arg = calloc(work_tree_arg_len, WL);
15✔
75
    if (!work_tree_arg) { // LCOV_EXCL_START
76
        goto fail;
77
    } // LCOV_EXCL_STOP
78
    wmemset(work_tree_arg, L'\0', work_tree_arg_len);
15✔
79
    _snwprintf(work_tree_arg, work_tree_arg_len, L"--work-tree=%ls", output_dir);
15✔
80
    size_t git_dir_len = wcslen(output_dir) + wcslen(L"\\.git") + 1;
15✔
81
    git_dir = calloc(git_dir_len, WL);
15✔
82
    if (!git_dir) { // LCOV_EXCL_START
83
        goto fail;
84
    } // LCOV_EXCL_STOP
85
    _snwprintf(git_dir, git_dir_len, L"%ls\\.git", output_dir);
15✔
86
    git_dir[git_dir_len - 1] = L'\0';
15✔
87
    if (!dir_exists(git_dir)) {
15✔
88
        cwd = calloc(MAX_PATH, WL);
5✔
89
        if (!cwd) { // LCOV_EXCL_START
90
            goto fail;
91
        } // LCOV_EXCL_STOP
92
        wmemset(cwd, L'\0', MAX_PATH);
5✔
93
        if (!_wgetcwd(cwd, MAX_PATH) || _wchdir(output_dir) != 0 ||
5✔
94
            !run_process_no_window(3, L"git.exe", L"init", L"--quiet") || _wchdir(cwd) != 0) {
3✔
95
            goto fail;
5✔
96
        }
97
    }
98
    size_t git_dir_arg_len = git_dir_len + wcslen(L"--git-dir=") + 1;
10✔
99
    git_dir_arg = calloc(git_dir_arg_len, WL);
10✔
100
    if (!git_dir_arg) { // LCOV_EXCL_START
101
        goto fail;
102
    } // LCOV_EXCL_STOP
103
    wmemset(git_dir_arg, L'\0', git_dir_arg_len);
10✔
104
    _snwprintf(git_dir_arg, git_dir_arg_len, L"--git-dir=%ls", git_dir);
10✔
105
    git_dir_arg[git_dir_arg_len - 1] = L'\0';
10✔
106
    if (!run_process_no_window(5, L"git.exe", git_dir_arg, work_tree_arg, L"add", L".")) {
10✔
107
        goto fail;
1✔
108
    }
109
    size_t time_needed_size =
9✔
110
        (size_t)GetTimeFormat(LOCALE_USER_DEFAULT, 0, nullptr, nullptr, nullptr, 0);
9✔
111
    if (!time_needed_size) {
9✔
112
        goto fail;
1✔
113
    }
114
    time_buf = calloc(time_needed_size, WL);
8✔
115
    if (!time_buf) { // LCOV_EXCL_START
116
        goto fail;
117
    } // LCOV_EXCL_STOP
118
    if (!GetTimeFormat(LOCALE_USER_DEFAULT, 0, nullptr, nullptr, time_buf, (int)time_needed_size)) {
8✔
119
        goto fail;
1✔
120
    }
121
    size_t date_needed_size =
7✔
122
        (size_t)GetDateFormat(LOCALE_USER_DEFAULT, 0, nullptr, nullptr, nullptr, 0);
7✔
123
    if (!date_needed_size) {
7✔
124
        goto fail;
1✔
125
    }
126
    date_buf = calloc(date_needed_size, WL);
6✔
127
    if (!date_buf) { // LCOV_EXCL_START
128
        goto fail;
129
    } // LCOV_EXCL_STOP
130
    if (!GetDateFormat(LOCALE_USER_DEFAULT, 0, nullptr, nullptr, date_buf, (int)date_needed_size)) {
6✔
131
        goto fail;
1✔
132
    }
133
    size_t needed_size =
5✔
134
        wcslen(AUTOMATIC_COMMIT_MESSAGE_PREFIX) + 3 + time_needed_size + date_needed_size;
5✔
135
    message_buf = calloc(needed_size, WL);
5✔
136
    if (!message_buf) { // LCOV_EXCL_START
137
        goto fail;
138
    } // LCOV_EXCL_STOP
139
    wmemset(message_buf, L'\0', needed_size);
5✔
140
    _snwprintf(message_buf,
5✔
141
               needed_size,
142
               L"%ls%ls %ls",
143
               AUTOMATIC_COMMIT_MESSAGE_PREFIX,
144
               date_buf,
145
               time_buf);
146
    if (!run_process_no_window(10,
5✔
147
                               L"git.exe",
148
                               git_dir_arg,
149
                               work_tree_arg,
150
                               L"commit",
151
                               L"--no-gpg-sign",
152
                               L"--quiet",
153
                               L"--no-verify",
154
                               L"--author=winprefs <winprefs@tat.sh>",
155
                               L"-m",
156
                               message_buf)) {
157
        goto fail;
1✔
158
    }
159
    if (deploy_key) {
4✔
160
        wchar_t full_deploy_key_path[MAX_PATH];
161
        if (!_wfullpath(full_deploy_key_path, deploy_key, MAX_PATH)) {
4✔
162
            goto fail;
3✔
163
        }
164
        escaped_full_deploy_key_path = calloc(MAX_PATH + 2, WL);
3✔
165
        wmemset(escaped_full_deploy_key_path, L'\0', MAX_PATH + 2);
3✔
166
        escaped_full_deploy_key_path[0] = L'\'';
3✔
167
        int i, j = 1;
3✔
168
        for (i = 0; i < (int)wcslen(full_deploy_key_path) && j < MAX_PATH; i++, j++) {
3✔
NEW
169
            if (full_deploy_key_path[i] == L'\'') {
×
NEW
170
                if (j < (MAX_PATH - 1)) {
×
NEW
171
                    escaped_full_deploy_key_path[j++] = L'\\';
×
172
                } else { // LCOV_EXCL_START
173
                    break;
174
                } // LCOV_EXCL_STOP
175
            }
NEW
176
            escaped_full_deploy_key_path[j] = full_deploy_key_path[i];
×
177
        }
178
        escaped_full_deploy_key_path[j] = L'\'';
3✔
179
        debug_print(L"Deploy key: %ls\n", escaped_full_deploy_key_path);
3✔
180
        size_t ssh_command_len = 68 + wcslen(escaped_full_deploy_key_path) + 3;
3✔
181
        ssh_command = calloc(ssh_command_len, WL);
3✔
182
        if (!ssh_command) { // LCOV_EXCL_START
183
            goto fail;
184
        } // LCOV_EXCL_STOP
185
        wmemset(ssh_command, L'\0', ssh_command_len);
3✔
186
        _snwprintf(ssh_command,
3✔
187
                   ssh_command_len,
188
                   L"ssh -i %ls -F nul -o UserKnownHostsFile=nul -o StrictHostKeyChecking=no",
189
                   full_deploy_key_path);
190
        if (!run_process_no_window(6,
3✔
191
                                   L"git.exe",
192
                                   git_dir_arg,
193
                                   work_tree_arg,
194
                                   L"config",
195
                                   L"core.sshCommand",
196
                                   ssh_command)) {
197
            goto fail;
1✔
198
        }
199
        wchar_t *branch_arg =
200
            get_git_branch(git_dir_arg, git_dir_arg_len, work_tree_arg, work_tree_arg_len);
2✔
201
        if (!run_process_no_window(10,
2✔
202
                                   L"git.exe",
203
                                   git_dir_arg,
204
                                   work_tree_arg,
205
                                   L"push",
206
                                   L"-u",
207
                                   L"--porcelain",
208
                                   L"--no-signed",
209
                                   L"origin",
210
                                   L"origin",
211
                                   branch_arg)) {
212
            goto fail;
1✔
213
        }
214
    }
215
    goto cleanup;
1✔
216
fail:
14✔
217
    ret = false;
14✔
218
cleanup:
16✔
219
    free(cwd);
16✔
220
    free(date_buf);
16✔
221
    free(escaped_full_deploy_key_path);
16✔
222
    free(git_dir);
16✔
223
    free(git_dir_arg);
16✔
224
    free(message_buf);
16✔
225
    free(ssh_command);
16✔
226
    free(time_buf);
16✔
227
    free(work_tree_arg);
16✔
228
    return ret;
16✔
229
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc