Skip to content

Commit

Permalink
Merge pull request #450 from ktakahashimtb/ktakahashimtb/treat-dedupe…
Browse files Browse the repository at this point in the history
…d-file-as-regular

Fix zip_open failure with data-deduplicated file (Windows)
  • Loading branch information
0-wiz-0 authored Aug 21, 2024
2 parents 81af911 + 22751db commit eaefd9d
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 4 deletions.
1 change: 1 addition & 0 deletions lib/zip_source_file_win32.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ struct zip_win32_file_operations {
BOOL(__stdcall *move_file)(const void *from, const void *to, DWORD flags);
BOOL(__stdcall *set_file_attributes)(const void *name, DWORD attributes);
char *(*string_duplicate)(const char *string);
HANDLE(__stdcall *find_first_file)(const void *name, void *data);
};

typedef struct zip_win32_file_operations zip_win32_file_operations_t;
Expand Down
10 changes: 9 additions & 1 deletion lib/zip_source_file_win32_ansi.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ static BOOL __stdcall ansi_get_file_attributes_ex(const void *name, GET_FILEEX_I
static void ansi_make_tempname(char *buf, size_t len, const char *name, zip_uint32_t i);
static BOOL __stdcall ansi_move_file(const void *from, const void *to, DWORD flags);
static BOOL __stdcall ansi_set_file_attributes(const void *name, DWORD attributes);
static HANDLE __stdcall ansi_find_first_file(const void *name, void* data);

/* clang-format off */
zip_win32_file_operations_t ops_ansi = {
Expand All @@ -52,7 +53,8 @@ zip_win32_file_operations_t ops_ansi = {
ansi_make_tempname,
ansi_move_file,
ansi_set_file_attributes,
strdup
strdup,
ansi_find_first_file,
};
/* clang-format on */

Expand Down Expand Up @@ -122,3 +124,9 @@ ansi_set_file_attributes(const void *name, DWORD attributes)
{
return SetFileAttributesA((const char *)name, attributes);
}

static HANDLE __stdcall
ansi_find_first_file(const void *name, void *data)
{
return FindFirstFileA((const char *)name, data);
}
12 changes: 10 additions & 2 deletions lib/zip_source_file_win32_named.c
Original file line number Diff line number Diff line change
Expand Up @@ -221,8 +221,16 @@ _zip_win32_named_op_stat(zip_source_file_context_t *ctx, zip_source_file_stat_t
st->regular_file = false;

if (file_attributes.dwFileAttributes != INVALID_FILE_ATTRIBUTES) {
if ((file_attributes.dwFileAttributes & (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_DEVICE | FILE_ATTRIBUTE_REPARSE_POINT)) == 0) {
st->regular_file = true;
if ((file_attributes.dwFileAttributes & (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_DEVICE)) == 0) {
if (file_attributes.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
WIN32_FIND_DATA find_data;
if (file_ops->find_first_file(ctx->fname, &find_data) != INVALID_HANDLE_VALUE) {
st->regular_file = (find_data.dwReserved0 == IO_REPARSE_TAG_DEDUP);
}
}
else {
st->regular_file = true;
}
}
}

Expand Down
11 changes: 10 additions & 1 deletion lib/zip_source_file_win32_utf16.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ static void utf16_make_tempname(char *buf, size_t len, const char *name, zip_uin
static BOOL __stdcall utf16_move_file(const void *from, const void *to, DWORD flags);
static BOOL __stdcall utf16_set_file_attributes(const void *name, DWORD attributes);
static char *utf16_strdup(const char *string);
static HANDLE __stdcall utf16_find_first_file(const void *name, void* data);


/* clang-format off */
Expand All @@ -54,7 +55,8 @@ zip_win32_file_operations_t ops_utf16 = {
utf16_make_tempname,
utf16_move_file,
utf16_set_file_attributes,
utf16_strdup
utf16_strdup,
utf16_find_first_file
};
/* clang-format on */

Expand Down Expand Up @@ -141,3 +143,10 @@ static char *
utf16_strdup(const char *string) {
return (char *)_wcsdup((const wchar_t *)string);
}


static HANDLE __stdcall
utf16_find_first_file(const void *name, void* data)
{
return FindFirstFileW((const wchar_t *)name, data);
}

0 comments on commit eaefd9d

Please sign in to comment.