diff options
author | bruvzg <7645683+bruvzg@users.noreply.github.com> | 2022-05-11 15:15:58 +0300 |
---|---|---|
committer | bruvzg <7645683+bruvzg@users.noreply.github.com> | 2022-05-11 16:08:17 +0300 |
commit | d36c5514d3893578f1c8cce4d0a2256abfcdd1ed (patch) | |
tree | c591ac745d635c3320f7a858cdd7dd43065a894a | |
parent | 9963ae3553d059e4ac3b57c7a4cdc55d1a87d49a (diff) |
Fix ZipIO crash when reused (and possible leaks).
-rw-r--r-- | core/io/zip_io.cpp | 58 | ||||
-rw-r--r-- | core/io/zip_io.h | 6 | ||||
-rw-r--r-- | editor/editor_asset_installer.cpp | 6 | ||||
-rw-r--r-- | editor/editor_export.cpp | 3 | ||||
-rw-r--r-- | editor/export_template_manager.cpp | 6 | ||||
-rw-r--r-- | editor/project_manager.cpp | 6 | ||||
-rw-r--r-- | platform/android/export/export_plugin.cpp | 8 | ||||
-rw-r--r-- | platform/iphone/export/export_plugin.cpp | 3 | ||||
-rw-r--r-- | platform/javascript/api/javascript_tools_editor_plugin.cpp | 3 | ||||
-rw-r--r-- | platform/javascript/export/export_plugin.cpp | 3 | ||||
-rw-r--r-- | platform/osx/export/export_plugin.cpp | 6 | ||||
-rw-r--r-- | platform/uwp/export/export_plugin.cpp | 3 |
12 files changed, 70 insertions, 41 deletions
diff --git a/core/io/zip_io.cpp b/core/io/zip_io.cpp index 2cc844b628..e573e8de19 100644 --- a/core/io/zip_io.cpp +++ b/core/io/zip_io.cpp @@ -31,18 +31,19 @@ #include "zip_io.h" void *zipio_open(voidpf opaque, const char *p_fname, int mode) { - ZipIOData *zd = (ZipIOData *)opaque; + Ref<FileAccess> *fa = reinterpret_cast<Ref<FileAccess> *>(opaque); + ERR_FAIL_COND_V(fa == nullptr, nullptr); String fname; fname.parse_utf8(p_fname); if (mode & ZLIB_FILEFUNC_MODE_WRITE) { - zd->f = FileAccess::open(fname, FileAccess::WRITE); + (*fa) = FileAccess::open(fname, FileAccess::WRITE); } else { - zd->f = FileAccess::open(fname, FileAccess::READ); + (*fa) = FileAccess::open(fname, FileAccess::READ); } - if (zd->f.is_null()) { + if (fa->is_null()) { return nullptr; } @@ -50,49 +51,66 @@ void *zipio_open(voidpf opaque, const char *p_fname, int mode) { } uLong zipio_read(voidpf opaque, voidpf stream, void *buf, uLong size) { - ZipIOData *zd = (ZipIOData *)opaque; - return zd->f->get_buffer((uint8_t *)buf, size); + Ref<FileAccess> *fa = reinterpret_cast<Ref<FileAccess> *>(opaque); + ERR_FAIL_COND_V(fa == nullptr, 0); + ERR_FAIL_COND_V(fa->is_null(), 0); + + return (*fa)->get_buffer((uint8_t *)buf, size); } uLong zipio_write(voidpf opaque, voidpf stream, const void *buf, uLong size) { - ZipIOData *zd = (ZipIOData *)opaque; - zd->f->store_buffer((uint8_t *)buf, size); + Ref<FileAccess> *fa = reinterpret_cast<Ref<FileAccess> *>(opaque); + ERR_FAIL_COND_V(fa == nullptr, 0); + ERR_FAIL_COND_V(fa->is_null(), 0); + + (*fa)->store_buffer((uint8_t *)buf, size); return size; } long zipio_tell(voidpf opaque, voidpf stream) { - ZipIOData *zd = (ZipIOData *)opaque; - return zd->f->get_position(); + Ref<FileAccess> *fa = reinterpret_cast<Ref<FileAccess> *>(opaque); + ERR_FAIL_COND_V(fa == nullptr, 0); + ERR_FAIL_COND_V(fa->is_null(), 0); + + return (*fa)->get_position(); } long zipio_seek(voidpf opaque, voidpf stream, uLong offset, int origin) { - ZipIOData *zd = (ZipIOData *)opaque; + Ref<FileAccess> *fa = reinterpret_cast<Ref<FileAccess> *>(opaque); + ERR_FAIL_COND_V(fa == nullptr, 0); + ERR_FAIL_COND_V(fa->is_null(), 0); uint64_t pos = offset; switch (origin) { case ZLIB_FILEFUNC_SEEK_CUR: - pos = zd->f->get_position() + offset; + pos = (*fa)->get_position() + offset; break; case ZLIB_FILEFUNC_SEEK_END: - pos = zd->f->get_length() + offset; + pos = (*fa)->get_length() + offset; break; default: break; } - zd->f->seek(pos); + (*fa)->seek(pos); return 0; } int zipio_close(voidpf opaque, voidpf stream) { - ZipIOData *zd = (ZipIOData *)opaque; - memdelete(zd); + Ref<FileAccess> *fa = reinterpret_cast<Ref<FileAccess> *>(opaque); + ERR_FAIL_COND_V(fa == nullptr, 0); + ERR_FAIL_COND_V(fa->is_null(), 0); + + fa->unref(); return 0; } int zipio_testerror(voidpf opaque, voidpf stream) { - ZipIOData *zd = (ZipIOData *)opaque; - return (zd->f.is_valid() && zd->f->get_error() != OK) ? 1 : 0; + Ref<FileAccess> *fa = reinterpret_cast<Ref<FileAccess> *>(opaque); + ERR_FAIL_COND_V(fa == nullptr, 1); + ERR_FAIL_COND_V(fa->is_null(), 0); + + return (fa->is_valid() && (*fa)->get_error() != OK) ? 1 : 0; } voidpf zipio_alloc(voidpf opaque, uInt items, uInt size) { @@ -105,9 +123,9 @@ void zipio_free(voidpf opaque, voidpf address) { memfree(address); } -zlib_filefunc_def zipio_create_io() { +zlib_filefunc_def zipio_create_io(Ref<FileAccess> *p_data) { zlib_filefunc_def io; - io.opaque = (void *)memnew(ZipIOData); + io.opaque = (void *)p_data; io.zopen_file = zipio_open; io.zread_file = zipio_read; io.zwrite_file = zipio_write; diff --git a/core/io/zip_io.h b/core/io/zip_io.h index 3bcd1f830d..f137bd2bbf 100644 --- a/core/io/zip_io.h +++ b/core/io/zip_io.h @@ -39,10 +39,6 @@ #include "thirdparty/minizip/unzip.h" #include "thirdparty/minizip/zip.h" -struct ZipIOData { - Ref<FileAccess> f; -}; - void *zipio_open(voidpf opaque, const char *p_fname, int mode); uLong zipio_read(voidpf opaque, voidpf stream, void *buf, uLong size); uLong zipio_write(voidpf opaque, voidpf stream, const void *buf, uLong size); @@ -57,6 +53,6 @@ int zipio_testerror(voidpf opaque, voidpf stream); voidpf zipio_alloc(voidpf opaque, uInt items, uInt size); void zipio_free(voidpf opaque, voidpf address); -zlib_filefunc_def zipio_create_io(); +zlib_filefunc_def zipio_create_io(Ref<FileAccess> *p_data); #endif // ZIP_IO_H diff --git a/editor/editor_asset_installer.cpp b/editor/editor_asset_installer.cpp index 7dcb9a4088..f60dcade82 100644 --- a/editor/editor_asset_installer.cpp +++ b/editor/editor_asset_installer.cpp @@ -64,7 +64,8 @@ void EditorAssetInstaller::open(const String &p_path, int p_depth) { package_path = p_path; Set<String> files_sorted; - zlib_filefunc_def io = zipio_create_io(); + Ref<FileAccess> io_fa; + zlib_filefunc_def io = zipio_create_io(&io_fa); unzFile pkg = unzOpen2(p_path.utf8().get_data(), &io); if (!pkg) { @@ -237,7 +238,8 @@ void EditorAssetInstaller::open(const String &p_path, int p_depth) { } void EditorAssetInstaller::ok_pressed() { - zlib_filefunc_def io = zipio_create_io(); + Ref<FileAccess> io_fa; + zlib_filefunc_def io = zipio_create_io(&io_fa); unzFile pkg = unzOpen2(package_path.utf8().get_data(), &io); if (!pkg) { diff --git a/editor/editor_export.cpp b/editor/editor_export.cpp index a21ee46818..ef99425f68 100644 --- a/editor/editor_export.cpp +++ b/editor/editor_export.cpp @@ -1334,7 +1334,8 @@ Error EditorExportPlatform::save_pack(const Ref<EditorExportPreset> &p_preset, b Error EditorExportPlatform::save_zip(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path) { EditorProgress ep("savezip", TTR("Packing"), 102, true); - zlib_filefunc_def io = zipio_create_io(); + Ref<FileAccess> io_fa; + zlib_filefunc_def io = zipio_create_io(&io_fa); zipFile zip = zipOpen2(p_path.utf8().get_data(), APPEND_STATUS_CREATE, nullptr, &io); ZipData zd; diff --git a/editor/export_template_manager.cpp b/editor/export_template_manager.cpp index 3526b4ce4c..68796683d2 100644 --- a/editor/export_template_manager.cpp +++ b/editor/export_template_manager.cpp @@ -374,7 +374,8 @@ void ExportTemplateManager::_install_file() { } bool ExportTemplateManager::_install_file_selected(const String &p_file, bool p_skip_progress) { - zlib_filefunc_def io = zipio_create_io(); + Ref<FileAccess> io_fa; + zlib_filefunc_def io = zipio_create_io(&io_fa); unzFile pkg = unzOpen2(p_file.utf8().get_data(), &io); if (!pkg) { @@ -676,7 +677,8 @@ Error ExportTemplateManager::install_android_template_from_file(const String &p_ // Uncompress source template. - zlib_filefunc_def io = zipio_create_io(); + Ref<FileAccess> io_fa; + zlib_filefunc_def io = zipio_create_io(&io_fa); unzFile pkg = unzOpen2(p_file.utf8().get_data(), &io); ERR_FAIL_COND_V_MSG(!pkg, ERR_CANT_OPEN, "Android sources not in ZIP format."); diff --git a/editor/project_manager.cpp b/editor/project_manager.cpp index 565bf94708..b4cbb3b7f1 100644 --- a/editor/project_manager.cpp +++ b/editor/project_manager.cpp @@ -186,7 +186,8 @@ private: if (mode == MODE_IMPORT || mode == MODE_RENAME) { if (!valid_path.is_empty() && !d->file_exists("project.godot")) { if (valid_path.ends_with(".zip")) { - zlib_filefunc_def io = zipio_create_io(); + Ref<FileAccess> io_fa; + zlib_filefunc_def io = zipio_create_io(&io_fa); unzFile pkg = unzOpen2(valid_path.utf8().get_data(), &io); if (!pkg) { @@ -499,7 +500,8 @@ private: zip_path = project_path->get_text(); } - zlib_filefunc_def io = zipio_create_io(); + Ref<FileAccess> io_fa; + zlib_filefunc_def io = zipio_create_io(&io_fa); unzFile pkg = unzOpen2(zip_path.utf8().get_data(), &io); if (!pkg) { diff --git a/platform/android/export/export_plugin.cpp b/platform/android/export/export_plugin.cpp index d357cd586e..5aef64943b 100644 --- a/platform/android/export/export_plugin.cpp +++ b/platform/android/export/export_plugin.cpp @@ -2775,7 +2775,8 @@ Error EditorExportPlatformAndroid::export_project_helper(const Ref<EditorExportP return ERR_FILE_BAD_PATH; } - zlib_filefunc_def io = zipio_create_io(); + Ref<FileAccess> io_fa; + zlib_filefunc_def io = zipio_create_io(&io_fa); if (ep.step(TTR("Creating APK..."), 0)) { return ERR_SKIP; @@ -2789,7 +2790,8 @@ Error EditorExportPlatformAndroid::export_project_helper(const Ref<EditorExportP int ret = unzGoToFirstFile(pkg); - zlib_filefunc_def io2 = zipio_create_io(); + Ref<FileAccess> io2_fa; + zlib_filefunc_def io2 = zipio_create_io(&io2_fa); String tmp_unaligned_path = EditorPaths::get_singleton()->get_cache_dir().plus_file("tmpexport-unaligned." + uitos(OS::get_singleton()->get_unix_time()) + ".apk"); @@ -2985,7 +2987,7 @@ Error EditorExportPlatformAndroid::export_project_helper(const Ref<EditorExportP ret = unzGoToFirstFile(tmp_unaligned); - io2 = zipio_create_io(); + io2 = zipio_create_io(&io2_fa); zipFile final_apk = zipOpen2(p_path.utf8().get_data(), APPEND_STATUS_CREATE, nullptr, &io2); // Take files from the unaligned APK and write them out to the aligned one diff --git a/platform/iphone/export/export_plugin.cpp b/platform/iphone/export/export_plugin.cpp index 57bee59523..71f3b5f59f 100644 --- a/platform/iphone/export/export_plugin.cpp +++ b/platform/iphone/export/export_plugin.cpp @@ -1488,7 +1488,8 @@ Error EditorExportPlatformIOS::export_project(const Ref<EditorExportPreset> &p_p ERR_FAIL_COND_V(tmp_app_path.is_null(), ERR_CANT_CREATE); print_line("Unzipping..."); - zlib_filefunc_def io = zipio_create_io(); + Ref<FileAccess> io_fa; + zlib_filefunc_def io = zipio_create_io(&io_fa); unzFile src_pkg_zip = unzOpen2(src_pkg_name.utf8().get_data(), &io); if (!src_pkg_zip) { EditorNode::add_io_error("Could not open export template (not a zip file?):\n" + src_pkg_name); diff --git a/platform/javascript/api/javascript_tools_editor_plugin.cpp b/platform/javascript/api/javascript_tools_editor_plugin.cpp index 198af61eff..1507f32375 100644 --- a/platform/javascript/api/javascript_tools_editor_plugin.cpp +++ b/platform/javascript/api/javascript_tools_editor_plugin.cpp @@ -64,7 +64,8 @@ void JavaScriptToolsEditorPlugin::_download_zip(Variant p_v) { } String resource_path = ProjectSettings::get_singleton()->get_resource_path(); - zlib_filefunc_def io = zipio_create_io(); + Ref<FileAccess> io_fa; + zlib_filefunc_def io = zipio_create_io(&io_fa); // Name the downloaded ZIP file to contain the project name and download date for easier organization. // Replace characters not allowed (or risky) in Windows file names with safe characters. diff --git a/platform/javascript/export/export_plugin.cpp b/platform/javascript/export/export_plugin.cpp index 66d93d7c49..9576256d03 100644 --- a/platform/javascript/export/export_plugin.cpp +++ b/platform/javascript/export/export_plugin.cpp @@ -33,7 +33,8 @@ #include "core/config/project_settings.h" Error EditorExportPlatformJavaScript::_extract_template(const String &p_template, const String &p_dir, const String &p_name, bool pwa) { - zlib_filefunc_def io = zipio_create_io(); + Ref<FileAccess> io_fa; + zlib_filefunc_def io = zipio_create_io(&io_fa); unzFile pkg = unzOpen2(p_template.utf8().get_data(), &io); if (!pkg) { diff --git a/platform/osx/export/export_plugin.cpp b/platform/osx/export/export_plugin.cpp index 94ef875072..465925524c 100644 --- a/platform/osx/export/export_plugin.cpp +++ b/platform/osx/export/export_plugin.cpp @@ -722,7 +722,8 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p return ERR_FILE_BAD_PATH; } - zlib_filefunc_def io = zipio_create_io(); + Ref<FileAccess> io_fa; + zlib_filefunc_def io = zipio_create_io(&io_fa); if (ep.step(TTR("Creating app bundle"), 0)) { return ERR_SKIP; @@ -1327,7 +1328,8 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p OS::get_singleton()->move_to_trash(p_path); } - zlib_filefunc_def io_dst = zipio_create_io(); + Ref<FileAccess> io_fa_dst; + zlib_filefunc_def io_dst = zipio_create_io(&io_fa_dst); zipFile zip = zipOpen2(p_path.utf8().get_data(), APPEND_STATUS_CREATE, nullptr, &io_dst); _zip_folder_recursive(zip, tmp_base_path_name, "", pkg_name); diff --git a/platform/uwp/export/export_plugin.cpp b/platform/uwp/export/export_plugin.cpp index 7e06bf01e3..65a5ee7140 100644 --- a/platform/uwp/export/export_plugin.cpp +++ b/platform/uwp/export/export_plugin.cpp @@ -301,7 +301,8 @@ Error EditorExportPlatformUWP::export_project(const Ref<EditorExportPreset> &p_p AppxPackager packager; packager.init(fa_pack); - zlib_filefunc_def io = zipio_create_io(); + Ref<FileAccess> io_fa; + zlib_filefunc_def io = zipio_create_io(&io_fa); if (ep.step("Creating package...", 0)) { return ERR_SKIP; |