Skip to content

Commit 5e68372

Browse files
committed
[acquire/*.h,tests/{CMakeLists.txt,config_for_tests.h.in}] Fix tests on Windows (MSVC)
1 parent dc8669e commit 5e68372

12 files changed

+170
-172
lines changed

acquire/acquire_librhash.h

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -78,13 +78,12 @@ int _librhash_verify_async_start(struct acquire_handle *handle,
7878
break;
7979
case LIBACQUIRE_SHA512:
8080
rhash_algo_id = RHASH_SHA512;
81-
expected_len = 129;
81+
expected_len = 128;
8282
break;
8383
default:
8484
return -1;
8585
}
86-
if (strlen(expected_hash) != expected_len &&
87-
!(algorithm == LIBACQUIRE_SHA512 && strlen(expected_hash) == 128)) {
86+
if (strlen(expected_hash) != expected_len) {
8887
acquire_handle_set_error(handle, ACQUIRE_ERROR_UNSUPPORTED_CHECKSUM_FORMAT,
8988
"Invalid hash length for selected algorithm");
9089
return -1;
@@ -99,6 +98,7 @@ int _librhash_verify_async_start(struct acquire_handle *handle,
9998
"rhash backend allocation failed");
10099
return -1;
101100
} /* LCOV_EXCL_STOP */
101+
#if defined(_MSC_VER) || defined(__STDC_LIB_EXT1__) && __STDC_WANT_LIB_EXT1__
102102
{
103103
const errno_t err = fopen_s(&be->file, filepath, "rb");
104104
if (err != 0 || be->file == NULL) {
@@ -109,6 +109,16 @@ int _librhash_verify_async_start(struct acquire_handle *handle,
109109
return -1;
110110
}
111111
}
112+
#else
113+
be->file = fopen(filepath, "rb");
114+
if (!be->file) {
115+
fprintf(stderr, "couldn't open file for reading %s\n", filepath);
116+
acquire_handle_set_error(handle, ACQUIRE_ERROR_FILE_OPEN_FAILED,
117+
"Cannot open file: %s", strerror(errno));
118+
free(be);
119+
return -1;
120+
}
121+
#endif
112122
be->handle = rhash_init(rhash_algo_id);
113123
if (!be->handle) { /* LCOV_EXCL_START */
114124
cleanup_rhash_backend(handle);

acquire/acquire_string_extras.h

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -192,23 +192,25 @@ inline double wtf_vsnprintf(char *buffer, size_t count, const char *format,
192192
#endif /* !defined(HAVE_SNPRINTF) && defined(SNPRINTF_IMPL) && SNPRINTF_IMPL \
193193
*/
194194

195-
#if defined(_MSC_VER) && !defined(__INTEL_COMPILER) && !defined(STRNCASECMP_IMPL)
195+
#if defined(_MSC_VER) && !defined(__INTEL_COMPILER) && \
196+
!defined(STRNCASECMP_IMPL)
196197
/* TODO: remove this hack */
197198
#define STRNCASECMP_IMPL 1
198-
#endif /* defined(_MSC_VER) && !defined(__INTEL_COMPILER) && !defined(STRNCASECMP_IMPL) */
199+
#endif /* defined(_MSC_VER) && !defined(__INTEL_COMPILER) && \
200+
!defined(STRNCASECMP_IMPL) */
199201

200202
#if !defined(HAVE_STRNCASECMP) && defined(STRNCASECMP_IMPL) && STRNCASECMP_IMPL
201203
#define HAVE_STRNCASECMP 1
202204

203205
#if defined(_MSC_VER) && !defined(__INTEL_COMPILER)
204206
/* this didn't work `#define strncasecmp _strnicmp` */
205207
LIBACQUIRE_EXPORT int strncasecmp(const char *_l, const char *_r, size_t n) {
206-
return _strnicmp(_l, _r, n);
208+
return _strnicmp(_l, _r, n);
207209
}
208210

209211
/* this didn't work `#define strcasecmp _stricmp` */
210212
LIBACQUIRE_EXPORT int strcasecmp(const char *l, const char *r) {
211-
return _stricmp(l, r);
213+
return _stricmp(l, r);
212214
}
213215

214216
#else

acquire/acquire_url_utils.h

Lines changed: 41 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ extern "C" {
2525
#endif /* defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || \
2626
defined(__NT__) */
2727
#include <acquire_common_defs.h>
28+
#include <stdlib.h>
2829
#include <string.h>
2930
#ifndef NAME_MAX
3031
#define NAME_MAX 4096
@@ -34,14 +35,13 @@ extern "C" {
3435
* @brief Extract the path component (filename) from a URL string.
3536
*
3637
* Given a URL string, returns a newly allocated string containing
37-
* everything after the last '/' character in the URL, stopping before any
38-
* query ('?') or fragment ('#') delimiter.
39-
*
40-
* If the URL is NULL or empty, returns NULL.
38+
* everything after the last '/' character in the URL's path, stopping before
39+
* any query ('?') or fragment ('#') delimiter.
4140
*
4241
* @param url Input URL string.
43-
* @return Pointer to a newly allocated string, or `NULL` on failure.
44-
* The caller is responsible for freeing this memory.
42+
* @return Pointer to a newly allocated string, or `NULL` on failure or if the
43+
* input is NULL/empty. The caller is responsible for freeing this
44+
* memory.
4545
*/
4646
extern LIBACQUIRE_EXPORT char *get_path_from_url(const char *url);
4747

@@ -62,44 +62,52 @@ extern LIBACQUIRE_EXPORT bool is_url(const char *maybe_url);
6262
#include <acquire_string_extras.h>
6363

6464
char *get_path_from_url(const char *url) {
65-
char buf[NAME_MAX + 1];
66-
const char *last_slash, *end;
65+
const char *path_start, *filename_start, *query_or_frag;
6766
size_t len;
67+
char *result;
6868

69-
if (!url || url[0] == '\0')
69+
if (!url || !*url) {
7070
return NULL;
71+
}
7172

72-
last_slash = strrchr(url, '/');
73-
if (last_slash) {
74-
if ((last_slash - url) < 9)
73+
path_start = strstr(url, "://");
74+
if (path_start) {
75+
/* It's a URL. Find the path part, which starts after the authority. */
76+
path_start = strchr(path_start + 3, '/');
77+
if (!path_start) {
78+
/* URL has host, but no path. E.g. http://example.com */
7579
return strdup("");
76-
last_slash++;
77-
} else
78-
last_slash = url;
79-
80-
end = last_slash;
81-
while (*end != '\0' && *end != '?' && *end != '#') {
82-
end++;
80+
}
81+
} else {
82+
/* Not a full URL with scheme. Treat as local path. */
83+
path_start = url;
8384
}
8485

85-
len = end - last_slash;
86-
if (len >= sizeof(buf)) {
87-
len = sizeof(buf) - 1;
86+
/* Now path_start points to the beginning of the path, e.g.,
87+
* "/path/to/file.txt" */
88+
filename_start = strrchr(path_start, '/');
89+
if (filename_start) {
90+
/* We found a slash, the filename is after it */
91+
filename_start++;
92+
} else {
93+
/* No slashes in path, the whole path is the filename */
94+
filename_start = path_start;
8895
}
8996

90-
#if defined(_MSC_VER) && !defined(__INTEL_COMPILER) || \
91-
defined(__STDC_LIB_EXT1__) && __STDC_WANT_LIB_EXT1__
92-
{
93-
const errno_t e = strncpy_s(buf, sizeof buf, url, NAME_MAX + 1);
94-
if (e)
95-
buf[0] = '\0';
97+
/* Find end of filename (start of query or fragment) */
98+
query_or_frag = filename_start;
99+
while (*query_or_frag && *query_or_frag != '?' && *query_or_frag != '#') {
100+
query_or_frag++;
96101
}
97-
#else
98-
strncpy(buf, last_slash, len);
99-
#endif
100-
buf[len] = '\0';
101102

102-
return strdup(buf);
103+
len = query_or_frag - filename_start;
104+
result = (char *)malloc(len + 1);
105+
if (!result)
106+
return NULL; /* LCOV_EXCL_LINE */
107+
108+
memcpy(result, filename_start, len);
109+
result[len] = '\0';
110+
return result;
103111
}
104112

105113
bool is_url(const char *maybe_url) {

acquire/acquire_wincrypt.h

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,9 @@ extern "C" {
99

1010
#include "acquire_common_defs.h"
1111
#include "acquire_string_extras.h"
12-
// #include <ntdef.h>
1312
#include "acquire_windows.h"
1413

1514
#include <Guiddef.h>
16-
// #include <dvp.h>
1715

1816
#include <basetsd.h>
1917

@@ -44,8 +42,18 @@ struct wincrypt_backend {
4442
HCRYPTHASH hHash;
4543
FILE *file;
4644
char expected_hash[130];
45+
ALG_ID alg_id;
4746
};
4847

48+
static void reverse_bytes(BYTE *p, size_t len) {
49+
size_t i;
50+
for (i = 0; i < len / 2; ++i) {
51+
BYTE t = p[i];
52+
p[i] = p[len - 1 - i];
53+
p[len - 1 - i] = t;
54+
}
55+
}
56+
4957
static void cleanup_wincrypt_backend(struct acquire_handle *handle) {
5058
if (handle && handle->backend_handle) {
5159
struct wincrypt_backend *be =
@@ -107,6 +115,7 @@ int _wincrypt_verify_async_start(struct acquire_handle *handle,
107115
"wincrypt init failed");
108116
return -1;
109117
}
118+
be->alg_id = alg_id;
110119
#if defined(_MSC_VER) && !defined(__INTEL_COMPILER) || \
111120
defined(__STDC_LIB_EXT1__) && __STDC_WANT_LIB_EXT1__
112121
{
@@ -160,9 +169,9 @@ enum acquire_status _wincrypt_verify_async_poll(struct acquire_handle *handle) {
160169
size_t BUF_SIZE = sizeof(computed_hex);
161170
DWORD j;
162171

163-
for (j = 0; j < hash_len; j++)
164-
sprintf_s(computed_hex + (j * 2), BUF_SIZE - (j * 2), "%02x", hash[j]);
165-
computed_hex[hash_len * 2] = '\0';
172+
if (be->alg_id == CALG_SHA_512) {
173+
/*reverse_bytes(hash, hash_len);*/
174+
}
166175

167176
for (j = 0; j < hash_len; j++)
168177
sprintf_s(computed_hex + (j * 2), BUF_SIZE - (j * 2), "%02x", hash[j]);

acquire/acquire_wininet.h

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,6 @@
77
#include <stdio.h>
88
#include <string.h>
99

10-
// #include <winuser.h>
11-
// #include <windef.h>
12-
1310
#include "acquire_windows.h"
1411

1512
#include <wininet.h>
@@ -29,28 +26,43 @@ const char *get_download_dir(void) { return ".downloads"; }
2926
int acquire_download_sync(struct acquire_handle *handle, const char *url,
3027
const char *dest_path) {
3128
HINTERNET h_internet, h_url;
32-
DWORD bytes_read, content_len_size = sizeof(handle->total_size);
29+
DWORD bytes_read, content_len_size = sizeof(handle->total_size),
30+
dwStatusCode = 0, dwSize = sizeof(dwStatusCode);
3331
char buffer[4096];
34-
if (handle == NULL)
32+
33+
if (!handle || !url || !dest_path) {
34+
if (handle)
35+
acquire_handle_set_error(handle, ACQUIRE_ERROR_INVALID_ARGUMENT,
36+
"Invalid arguments for sync download");
3537
return -1;
38+
}
3639

3740
h_internet = InternetOpen("acquire_wininet", INTERNET_OPEN_TYPE_PRECONFIG,
3841
NULL, NULL, 0);
3942
if (h_internet == NULL) {
40-
strcpy_s(handle->error.message, sizeof(handle->error.message),
41-
"InternetOpen failed");
43+
acquire_handle_set_error(handle, ACQUIRE_ERROR_NETWORK_INIT_FAILED,
44+
"InternetOpen failed");
4245
return -1;
4346
}
4447

4548
h_url = InternetOpenUrl(h_internet, url, NULL, 0,
4649
INTERNET_FLAG_RELOAD | INTERNET_FLAG_SECURE, 0);
4750
if (h_url == NULL) {
48-
strcpy_s(handle->error.message, sizeof(handle->error.message),
49-
"InternetOpenUrl failed");
51+
acquire_handle_set_error(handle, ACQUIRE_ERROR_HOST_NOT_FOUND,
52+
"InternetOpenUrl failed");
5053
InternetCloseHandle(h_internet);
5154
return -1;
5255
}
5356

57+
if (HttpQueryInfo(h_url, HTTP_QUERY_STATUS_CODE | HTTP_QUERY_FLAG_NUMBER,
58+
&dwStatusCode, &dwSize, NULL)) {
59+
if (dwStatusCode >= 400) {
60+
acquire_handle_set_error(handle, ACQUIRE_ERROR_HTTP_FAILURE,
61+
"HTTP error: %lu", dwStatusCode);
62+
goto fail;
63+
}
64+
}
65+
5466
{
5567
const errno_t err = fopen_s(&handle->output_file, dest_path, "wb");
5668
if (err != 0 || handle->output_file == NULL) {
@@ -69,8 +81,8 @@ int acquire_download_sync(struct acquire_handle *handle, const char *url,
6981
while (InternetReadFile(h_url, buffer, sizeof(buffer), &bytes_read) &&
7082
bytes_read > 0) {
7183
if (handle->cancel_flag) { /* Check for cancellation */
72-
strcpy_s(handle->error.message, sizeof(handle->error.message),
73-
"Download cancelled");
84+
acquire_handle_set_error(handle, ACQUIRE_ERROR_CANCELLED,
85+
"Download cancelled");
7486
goto fail;
7587
}
7688
fwrite(buffer, 1, bytes_read, handle->output_file);
@@ -90,7 +102,6 @@ int acquire_download_sync(struct acquire_handle *handle, const char *url,
90102
handle->output_file = NULL;
91103
InternetCloseHandle(h_url);
92104
InternetCloseHandle(h_internet);
93-
handle->status = ACQUIRE_ERROR;
94105
return -1;
95106
}
96107

acquire/tests/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ if (NOT IS_DIRECTORY "${DOWNLOAD_DIR}/greatest")
2929
file(RENAME "${DOWNLOAD_DIR}/greatest-cmake-and-msvc" "${DOWNLOAD_DIR}/greatest")
3030
endif (NOT IS_DIRECTORY "${DOWNLOAD_DIR}/greatest")
3131
set(GREATEST_FILE "${DOWNLOAD_DIR}/greatest/greatest.h")
32+
file(SHA512 "${GREATEST_ARCHIVE}" GREATEST_ARCHIVE_SHA512)
3233

3334
###############################################
3435
# Create a dummy corrupted zip file for tests #

acquire/tests/config_for_tests.h.in

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313

1414
#define GREATEST_ZIP_SHA256 "@GREATEST_ARCHIVE_SHA256@"
1515

16+
#define GREATEST_ZIP_SHA512 "@GREATEST_ARCHIVE_SHA512@"
17+
1618
#define GREATEST_CRC32C "@GREATEST_CRC32C@"
1719

1820
#define GREATEST_SHA256 "@GREATEST_SHA256@"

acquire/tests/test_checksum.h

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,6 @@
1616

1717
#define EMPTY_FILE_SHA256 \
1818
"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
19-
#define GREATEST_SHA512 \
20-
"3dd506fcf7b60d46e3a3865b9159f19ad35b359398bcb736c9f8de239059187ae625fb0041" \
21-
"7f16a8bb8520c7bbeb388e974a3294aa3eb4c4f93185831ed2b6a2e"
2219
static const char *EMPTY_FILE_PATH = DOWNLOAD_DIR PATH_SEP "empty.txt";
2320

2421
TEST test_verify_sync_success_sha256(void) {
@@ -37,8 +34,8 @@ TEST test_verify_sync_success_sha512(void) {
3734
struct acquire_handle *h = acquire_handle_init();
3835
int result;
3936
ASSERT(h != NULL);
40-
result =
41-
acquire_verify_sync(h, GREATEST_FILE, LIBACQUIRE_SHA512, GREATEST_SHA512);
37+
result = acquire_verify_sync(h, GREATEST_ARCHIVE, LIBACQUIRE_SHA512,
38+
GREATEST_ZIP_SHA512);
4239
ASSERT_EQ_FMT(0, result, "%d");
4340
ASSERT_EQ_FMT(ACQUIRE_COMPLETE, h->status, "%d");
4441
acquire_handle_free(h);

0 commit comments

Comments
 (0)