1
0
mirror of https://github.com/pbatard/rufus.git synced 2026-10-24 02:28:58 +03:00

[ui] fix a crash when opening the log for MinGW x86_32 executable

* DwmGetWindowAttribute() from dwmapi.dll is delay-loaded so it requires the MinGW DECLSPEC_IMPORT workaround.
* Closes #2728.
* Also fix a bunch of Coverity warnings in wimlib and ezxml.
This commit is contained in:
Pete Batard
2025-05-06 18:43:35 +01:00
parent ea01cd41c0
commit 965759f58a
16 changed files with 91 additions and 57 deletions

View File

@@ -22,6 +22,14 @@
#include <crtdbg.h>
#endif
// Temporary workaround for MinGW32 delay-loading
// See https://github.com/pbatard/rufus/pull/2513 as well as
// https://sourceware.org/bugzilla/show_bug.cgi?id=14339
#if defined(__MINGW32__)
#undef DECLSPEC_IMPORT
#define DECLSPEC_IMPORT __attribute__((visibility("hidden")))
#endif
#include <windows.h>
#include <windowsx.h>
#include <stdlib.h>

View File

@@ -33,7 +33,7 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
IDD_DIALOG DIALOGEX 12, 12, 232, 326
STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU
EXSTYLE WS_EX_ACCEPTFILES
CAPTION "Rufus 4.8.2241"
CAPTION "Rufus 4.8.2242"
FONT 9, "Segoe UI Symbol", 400, 0, 0x0
BEGIN
LTEXT "Drive Properties",IDS_DRIVE_PROPERTIES_TXT,8,6,53,12,NOT WS_GROUP
@@ -407,8 +407,8 @@ END
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 4,8,2241,0
PRODUCTVERSION 4,8,2241,0
FILEVERSION 4,8,2242,0
PRODUCTVERSION 4,8,2242,0
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
@@ -426,13 +426,13 @@ BEGIN
VALUE "Comments", "https://rufus.ie"
VALUE "CompanyName", "Akeo Consulting"
VALUE "FileDescription", "Rufus"
VALUE "FileVersion", "4.8.2241"
VALUE "FileVersion", "4.8.2242"
VALUE "InternalName", "Rufus"
VALUE "LegalCopyright", "© 2011-2025 Pete Batard (GPL v3)"
VALUE "LegalTrademarks", "https://www.gnu.org/licenses/gpl-3.0.html"
VALUE "OriginalFilename", "rufus-4.8.exe"
VALUE "ProductName", "Rufus"
VALUE "ProductVersion", "4.8.2241"
VALUE "ProductVersion", "4.8.2242"
END
END
BLOCK "VarFileInfo"

View File

@@ -490,7 +490,10 @@ calculate_dentry_full_path(struct wim_dentry *dentry)
d = d->d_parent; /* assumes d == d->d_parent for root */
} while (!dentry_is_root(d));
utf16lechar* ubuf = alloca(ulen * sizeof(utf16lechar));
// +1 to keep Coverity happy
utf16lechar *ubuf = alloca((ulen + 1) * sizeof(utf16lechar));
if (!ubuf)
return WIMLIB_ERR_NOMEM;
utf16lechar *p = &ubuf[ulen];
d = dentry;
@@ -518,7 +521,8 @@ calculate_dentry_full_path(struct wim_dentry *dentry)
tchar *
dentry_full_path(struct wim_dentry *dentry)
{
calculate_dentry_full_path(dentry);
if (calculate_dentry_full_path(dentry))
return NULL;
return dentry->d_full_path;
}

View File

@@ -390,6 +390,7 @@ create_temporary_file(struct filedes *fd_ret, tchar **name_ret)
#ifdef _WIN32
retry:
// coverity[secure_temp]
name = _wtempnam(NULL, L"wimlib");
if (!name) {
ERROR_WITH_ERRNO("Failed to create temporary filename");

View File

@@ -76,6 +76,8 @@ calculate_chunk_sha1(struct filedes *in_fd, size_t this_chunk_size,
"integrity checksums");
return ret;
}
// I have no idea what Coverity is hallucinating with here...
// coverity[overrun-call]
sha1_update(&ctx, buf, bytes_to_read);
bytes_remaining -= bytes_to_read;
offset += bytes_to_read;

View File

@@ -587,6 +587,7 @@ bool
lcpit_matchfinder_init(struct lcpit_matchfinder *mf, size_t max_bufsize,
u32 min_match_len, u32 nice_match_len)
{
// coverity[dead_error_condition]
if (lcpit_matchfinder_get_needed_memory(max_bufsize) > SIZE_MAX)
return false;
if (max_bufsize > MAX_HUGE_BUFSIZE - PREFETCH_SAFETY)

View File

@@ -1971,8 +1971,10 @@ begin:
if (next_item_idx < 0)
break;
if (next_item_idx == 0)
// coverity[assigned_value]
item_to_take = cur_node->item;
else
// coverity[assigned_value]
item_to_take = cur_node->extra_items[next_item_idx - 1];
--next_item_idx;
}

View File

@@ -1452,6 +1452,7 @@ lzx_walk_item_list(struct lzx_compressor *c, u32 block_size, bool is_16_bit,
/* Tally/record a match. */
matchlen = item & OPTIMUM_LEN_MASK;
adjusted_offset = item >> OPTIMUM_OFFSET_SHIFT;
// coverity[overrun-call]
mainsym = lzx_tally_main_and_lensyms(c, matchlen,
adjusted_offset,
is_16_bit);

View File

@@ -610,7 +610,9 @@ sha1_final(struct sha1_ctx *ctx, u8 hash[SHA1_HASH_SIZE])
ctx->buffer[buffered++] = 0x80;
if (buffered > SHA1_BLOCK_SIZE - 8) {
memset(&ctx->buffer[buffered], 0, SHA1_BLOCK_SIZE - buffered);
// Keep Coverity happy
if (buffered != SHA1_BLOCK_SIZE)
memset(&ctx->buffer[buffered], 0, SHA1_BLOCK_SIZE - buffered);
sha1_blocks(ctx->h, ctx->buffer, 1);
buffered = 0;
}

View File

@@ -1044,8 +1044,8 @@ wimlib_get_version_string(void)
return T(PACKAGE_VERSION);
}
static volatile uint16_t lib_initialization_mutex = 0;
static bool lib_initialized = false;
static struct mutex lib_initialization_mutex = MUTEX_INITIALIZER;
/* API function documented in wimlib.h */
WIMLIBAPI int
@@ -1053,11 +1053,13 @@ wimlib_global_init(int init_flags)
{
int ret = 0;
if (lib_initialized)
goto out;
mutex_init(&lib_initialization_mutex);
mutex_lock(&lib_initialization_mutex);
// Non problematic init/cleanup mutex (Windows only) to keep static
// analysers happy. Only one thread at a time can run the code between
// initial InterlockedIncrement and ending InterlockedDecrement.
while (InterlockedIncrement16(&lib_initialization_mutex) >= 2) {
InterlockedDecrement16(&lib_initialization_mutex);
Sleep(100);
}
if (lib_initialized)
goto out_unlock;
@@ -1095,8 +1097,7 @@ wimlib_global_init(int init_flags)
lib_initialized = true;
ret = 0;
out_unlock:
mutex_unlock(&lib_initialization_mutex);
out:
InterlockedDecrement16(&lib_initialization_mutex);
return ret;
}
@@ -1104,10 +1105,10 @@ out:
WIMLIBAPI void
wimlib_global_cleanup(void)
{
if (!lib_initialized)
return;
mutex_lock(&lib_initialization_mutex);
while (InterlockedIncrement16(&lib_initialization_mutex) >= 2) {
InterlockedDecrement16(&lib_initialization_mutex);
Sleep(100);
}
if (!lib_initialized)
goto out_unlock;
@@ -1120,6 +1121,5 @@ wimlib_global_cleanup(void)
lib_initialized = false;
out_unlock:
mutex_unlock(&lib_initialization_mutex);
mutex_destroy(&lib_initialization_mutex);
InterlockedDecrement16(&lib_initialization_mutex);
}

View File

@@ -809,6 +809,7 @@ update_wimoverlay_manually(const wchar_t *drive, const wchar_t *wim_path,
if (ret)
goto out;
// coverity[tainted_data]
ret = prepare_wimoverlay_dat(old_contents, wim_path, wim_guid, image,
&new_contents, &new_contents_size,
&new_data_source_id);

View File

@@ -234,14 +234,15 @@ uint32_t __inline __builtin_ctz(uint32_t value)
unsigned long trailing_zero = 0;
if (_BitScanForward(&trailing_zero, value))
return trailing_zero;
return 32;
// Undefined behaviour => return 0 to appease static analyzers
return 0;
}
uint32_t __inline __builtin_clz(uint32_t value)
{
unsigned long leading_zero = 0;
if (_BitScanReverse(&leading_zero, value))
return 31 - leading_zero;
return 32;
return 0;
}
#if defined(_M_X64) || defined(_M_ARM64)
uint32_t __inline __builtin_clzll(uint64_t value)
@@ -249,20 +250,20 @@ uint32_t __inline __builtin_clzll(uint64_t value)
unsigned long leading_zero = 0;
if (_BitScanReverse64(&leading_zero, value))
return 63 - leading_zero;
return 64;
return 0;
}
uint32_t __inline __builtin_ctzll(uint64_t value)
{
unsigned long trailing_zero = 0;
if (_BitScanForward64(&trailing_zero, value))
return trailing_zero;
return 64;
return 0;
}
#else
uint32_t __inline __builtin_clzll(uint64_t value)
{
if (value == 0)
return 64;
return 0;
uint32_t msh = (uint32_t)(value >> 32);
uint32_t lsh = (uint32_t)(value & 0xFFFFFFFF);
if (msh != 0)
@@ -272,7 +273,7 @@ uint32_t __inline __builtin_clzll(uint64_t value)
uint32_t __inline __builtin_ctzll(uint64_t value)
{
if (value == 0)
return 64;
return 0;
uint32_t msh = (uint32_t)(value >> 32);
uint32_t lsh = (uint32_t)(value & 0xFFFFFFFF);
if (msh != 0)

View File

@@ -2800,10 +2800,8 @@ generate_wim_structures_recursive(struct wim_dentry **root_ret,
root->d_short_name_nbytes = nbytes;
}
if (inode->i_nlink > 1) { /* Already seen this inode? */
ret = 0;
if (inode->i_nlink > 1) /* Already seen this inode? */
goto out_progress;
}
/* The file attributes and timestamps were cached from the MFT. */
inode->i_attributes = ni->attributes;

View File

@@ -215,7 +215,7 @@ struct IVssBackupComponentsVTable {
*----------------------------------------------------------------------------*/
static bool vss_initialized;
static struct mutex vss_initialization_mutex = MUTEX_INITIALIZER;
static volatile uint16_t vss_initialization_mutex = 0;
/* vssapi.dll */
static HANDLE hVssapi;
@@ -282,35 +282,47 @@ err:
static bool
vss_global_init(void)
{
if (vss_initialized)
return true;
bool ret = true;
mutex_lock(&vss_initialization_mutex);
if (!vss_initialized)
vss_initialized = vss_global_init_impl();
mutex_unlock(&vss_initialization_mutex);
while (InterlockedIncrement16(&vss_initialization_mutex) >= 2) {
InterlockedDecrement16(&vss_initialization_mutex);
Sleep(100);
}
if (vss_initialized)
return true;
ERROR("The Volume Shadow Copy Service (VSS) API could not be "
"initialized.");
return false;
goto out_unlock;
vss_initialized = vss_global_init_impl();
if (!vss_initialized) {
ERROR("The Volume Shadow Copy Service (VSS) API could not be "
"initialized.");
ret = false;
}
out_unlock:
InterlockedDecrement16(&vss_initialization_mutex);
return ret;
}
void
vss_global_cleanup(void)
{
if (!vss_initialized)
return;
mutex_lock(&vss_initialization_mutex);
if (vss_initialized) {
(*func_CoUninitialize)();
FreeLibrary(hOle32);
FreeLibrary(hVssapi);
vss_initialized = false;
while (InterlockedIncrement16(&vss_initialization_mutex) >= 2) {
InterlockedDecrement16(&vss_initialization_mutex);
Sleep(100);
}
mutex_unlock(&vss_initialization_mutex);
if (!vss_initialized)
goto out_unlock;
(*func_CoUninitialize)();
FreeLibrary(hOle32);
FreeLibrary(hVssapi);
vss_initialized = false;
out_unlock:
InterlockedDecrement16(&vss_initialization_mutex);
}
/*----------------------------------------------------------------------------*

View File

@@ -644,7 +644,8 @@ xml_parse_document(const tchar *p, struct xml_node **doc_ret)
int ret;
struct xml_node *doc;
skip_string(&p, BYTE_ORDER_MARK);
// Keep static analysers happy since we don't care about returned value.
(void)skip_string(&p, BYTE_ORDER_MARK);
if (!skip_misc(&p))
return WIMLIB_ERR_XML;
ret = parse_element(&p, NULL, 0, &doc);

View File

@@ -237,7 +237,7 @@ char *ezxml_decode(char *s, char **ent, char t)
if (ent[b++]) { // found a match
if ((c = (long)strlen(ent[b])) - 1 > (e = strchr(s, ';')) - s) {
l = (d = (long)(s - r)) + c + (long)strlen(e); // new length
l = (d = (long)(s - r)) + c + (long)(e ? strlen(e) : 0); // new length
r = (r == m) ? strcpy(malloc(l), r) : _realloc(r, l);
e = strchr((s = r + d), ';'); // fix up pointers
}
@@ -683,8 +683,7 @@ ezxml_t ezxml_parse_fd(int fd)
size_t l;
void *m;
if (fd < 0) return NULL;
fstat(fd, &st);
if (fd < 0 || fstat(fd, &st)) return NULL;
#ifndef EZXML_NOMMAP
l = (st.st_size + sysconf(_SC_PAGESIZE) - 1) & ~(sysconf(_SC_PAGESIZE) -1);
@@ -698,6 +697,7 @@ ezxml_t ezxml_parse_fd(int fd)
else { // mmap failed, read file into memory
#endif // EZXML_NOMMAP
l = (long)_read(fd, m = malloc((size_t)st.st_size), (unsigned int)st.st_size);
if (l < 0) { free(m); return NULL; };
root = (ezxml_root_t)ezxml_parse_str(m, l);
if (!root) { free(m); return NULL; };
root->len = -1; // so we know to free s in ezxml_free()
@@ -719,7 +719,7 @@ ezxml_t ezxml_parse_file(const char *file)
// Encodes ampersand sequences appending the results to *dst, reallocating *dst
// if length excedes max. a is non-zero for attribute encoding. Returns *dst
char *ezxml_ampencode(const char *s, size_t len, char **dst, size_t *dlen,
char *ezxml_ampencode(const char *s, ssize_t len, char **dst, size_t *dlen,
size_t *max, short a)
{
const char *e;