From e1ca935c008874c3ffac9125b36e503f43719067 Mon Sep 17 00:00:00 2001 From: Tobias Stoeckmann Date: Sat, 31 May 2025 11:33:07 +0200 Subject: [PATCH] Always check archive_wstring_ensure return value Memory allocation might fail, so check if it was successful. Signed-off-by: Tobias Stoeckmann --- libarchive/archive_read_disk_windows.c | 34 ++++++++++++++------ libarchive/archive_read_support_format_cab.c | 7 +++- libarchive/archive_write_disk_windows.c | 28 ++++++++++++---- 3 files changed, 52 insertions(+), 17 deletions(-) diff --git a/libarchive/archive_read_disk_windows.c b/libarchive/archive_read_disk_windows.c index a774305d0..689a45958 100644 --- a/libarchive/archive_read_disk_windows.c +++ b/libarchive/archive_read_disk_windows.c @@ -1652,7 +1652,7 @@ tree_push(struct tree *t, const wchar_t *path, const wchar_t *full_path, /* * Append a name to the current dir path. */ -static void +static int tree_append(struct tree *t, const wchar_t *name, size_t name_length) { size_t size_needed; @@ -1665,7 +1665,8 @@ tree_append(struct tree *t, const wchar_t *name, size_t name_length) /* Resize pathname buffer as needed. */ size_needed = name_length + t->dirname_length + 2; - archive_wstring_ensure(&t->path, size_needed); + if (archive_wstring_ensure(&t->path, size_needed) == NULL) + return (TREE_ERROR_FATAL); /* Add a separating '/' if it's needed. */ if (t->dirname_length > 0 && t->path.s[archive_strlen(&t->path)-1] != L'/') @@ -1677,13 +1678,15 @@ tree_append(struct tree *t, const wchar_t *name, size_t name_length) t->full_path.s[t->full_path_dir_length] = L'\0'; t->full_path.length = t->full_path_dir_length; size_needed = name_length + t->full_path_dir_length + 2; - archive_wstring_ensure(&t->full_path, size_needed); + if (archive_wstring_ensure(&t->full_path, size_needed) == NULL) + return (TREE_ERROR_FATAL); /* Add a separating '\' if it's needed. */ if (t->full_path.s[archive_strlen(&t->full_path)-1] != L'\\') archive_wstrappend_wchar(&t->full_path, L'\\'); archive_wstrncat(&t->full_path, name, name_length); t->restore_time.full_path = t->full_path.s; } + return (0); } /* @@ -1697,7 +1700,10 @@ tree_open(const wchar_t *path, int symlink_mode, int restore_time) t = calloc(1, sizeof(*t)); archive_string_init(&(t->full_path)); archive_string_init(&t->path); - archive_wstring_ensure(&t->path, 15); + if (archive_wstring_ensure(&t->path, 15) == NULL) { + free(t); + return (NULL); + } t->initial_symlink_mode = symlink_mode; return (tree_reopen(t, path, restore_time)); } @@ -1756,7 +1762,8 @@ tree_reopen(struct tree *t, const wchar_t *path, int restore_time) p = wcsrchr(base, L'/'); if (p != NULL) { *p = L'\0'; - tree_append(t, base, p - base); + if (tree_append(t, base, p - base)) + goto failed; t->dirname_length = archive_strlen(&t->path); base = p + 1; } @@ -1892,8 +1899,10 @@ tree_next(struct tree *t) } /* Top stack item needs a regular visit. */ t->current = t->stack; - tree_append(t, t->stack->name.s, + r = tree_append(t, t->stack->name.s, archive_strlen(&(t->stack->name))); + if (r != 0) + return (r); //t->dirname_length = t->path_length; //tree_pop(t); t->stack->flags &= ~needsFirstVisit; @@ -1901,8 +1910,10 @@ tree_next(struct tree *t) } else if (t->stack->flags & needsDescent) { /* Top stack item is dir to descend into. */ t->current = t->stack; - tree_append(t, t->stack->name.s, + r = tree_append(t, t->stack->name.s, archive_strlen(&(t->stack->name))); + if (r != 0) + return (r); t->stack->flags &= ~needsDescent; r = tree_descent(t); if (r != 0) { @@ -1945,9 +1956,10 @@ tree_dir_next_windows(struct tree *t, const wchar_t *pattern) struct archive_wstring pt; archive_string_init(&pt); - archive_wstring_ensure(&pt, + if (archive_wstring_ensure(&pt, archive_strlen(&(t->full_path)) - + 2 + wcslen(pattern)); + + 2 + wcslen(pattern)) == NULL) + return (TREE_ERROR_FATAL); archive_wstring_copy(&pt, &(t->full_path)); archive_wstrappend_wchar(&pt, L'\\'); archive_wstrcat(&pt, pattern); @@ -1979,7 +1991,9 @@ tree_dir_next_windows(struct tree *t, const wchar_t *pattern) continue; if (name[0] == L'.' && name[1] == L'.' && name[2] == L'\0') continue; - tree_append(t, name, namelen); + r = tree_append(t, name, namelen); + if (r != 0) + return (r); return (t->visit_type = TREE_REGULAR); } } diff --git a/libarchive/archive_read_support_format_cab.c b/libarchive/archive_read_support_format_cab.c index e012248a5..a96f7d313 100644 --- a/libarchive/archive_read_support_format_cab.c +++ b/libarchive/archive_read_support_format_cab.c @@ -363,7 +363,12 @@ archive_read_support_format_cab(struct archive *_a) return (ARCHIVE_FATAL); } archive_string_init(&cab->ws); - archive_wstring_ensure(&cab->ws, 256); + if (archive_wstring_ensure(&cab->ws, 256) == NULL) { + archive_set_error(&a->archive, ENOMEM, + "Can't allocate memory"); + free(cab); + return (ARCHIVE_FATAL); + } r = __archive_read_register_format(a, cab, diff --git a/libarchive/archive_write_disk_windows.c b/libarchive/archive_write_disk_windows.c index 98c7a223a..c7339c4ec 100644 --- a/libarchive/archive_write_disk_windows.c +++ b/libarchive/archive_write_disk_windows.c @@ -408,7 +408,11 @@ permissive_name_w(struct archive_write_disk *a) wn = _wcsdup(wnp); if (wn == NULL) return (-1); - archive_wstring_ensure(&(a->_name_data), 4 + wcslen(wn) + 1); + if (archive_wstring_ensure(&(a->_name_data), + 4 + wcslen(wn) + 1) == NULL) { + free(wn); + return (-1); + } a->name = a->_name_data.s; /* Prepend "\\?\" */ archive_wstrncpy(&(a->_name_data), L"\\\\?\\", 4); @@ -438,8 +442,11 @@ permissive_name_w(struct archive_write_disk *a) wn = _wcsdup(wnp); if (wn == NULL) return (-1); - archive_wstring_ensure(&(a->_name_data), - 8 + wcslen(wn) + 1); + if (archive_wstring_ensure(&(a->_name_data), + 8 + wcslen(wn) + 1) == NULL) { + free(wn); + return (-1); + } a->name = a->_name_data.s; /* Prepend "\\?\UNC\" */ archive_wstrncpy(&(a->_name_data), @@ -475,8 +482,12 @@ permissive_name_w(struct archive_write_disk *a) free(wsp); return (-1); } - archive_wstring_ensure(&(a->_name_data), - 4 + 2 + wcslen(wn) + 1); + if (archive_wstring_ensure(&(a->_name_data), + 4 + 2 + wcslen(wn) + 1) == NULL) { + free(wsp); + free(wn); + return (-1); + } a->name = a->_name_data.s; /* Prepend "\\?\" and drive name. */ archive_wstrncpy(&(a->_name_data), L"\\\\?\\", 4); @@ -492,7 +503,12 @@ permissive_name_w(struct archive_write_disk *a) free(wsp); return (-1); } - archive_wstring_ensure(&(a->_name_data), 4 + l + 1 + wcslen(wn) + 1); + if (archive_wstring_ensure(&(a->_name_data), + 4 + l + 1 + wcslen(wn) + 1) == NULL) { + free(wsp); + free(wn); + return (-1); + } a->name = a->_name_data.s; /* Prepend "\\?\" and drive name if not already added. */ if (l > 3 && wsp[0] == L'\\' && wsp[1] == L'\\' && -- 2.47.2