aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLoic Blot <loic.blot@unix-experience.fr>2021-05-06 09:02:11 +0200
committerLoïc Blot <nerzhul@users.noreply.github.com>2021-05-06 16:01:52 +0200
commit225d4541ffb4d59001841747e0877a175da50c17 (patch)
treec6c7a0de449da5f9ab3390b16d0322e87a20ef82
parentba40b3950057c54609f8e4a56139563d30f8b84f (diff)
downloadminetest-225d4541ffb4d59001841747e0877a175da50c17.tar.gz
minetest-225d4541ffb4d59001841747e0877a175da50c17.tar.bz2
minetest-225d4541ffb4d59001841747e0877a175da50c17.zip
fix: extractZipFile is not part of Client but more generic.
This solve a crash from mainmenu while extracting the zip
-rw-r--r--src/client/client.cpp66
-rw-r--r--src/client/client.h2
-rw-r--r--src/filesys.cpp64
-rw-r--r--src/filesys.h6
-rw-r--r--src/script/lua_api/l_mainmenu.cpp3
5 files changed, 72 insertions, 69 deletions
diff --git a/src/client/client.cpp b/src/client/client.cpp
index c0da27e44..00ae8f6b8 100644
--- a/src/client/client.cpp
+++ b/src/client/client.cpp
@@ -725,72 +725,6 @@ bool Client::loadMedia(const std::string &data, const std::string &filename,
return false;
}
-bool Client::extractZipFile(const char *filename, const std::string &destination)
-{
- auto fs = m_rendering_engine->get_filesystem();
-
- if (!fs->addFileArchive(filename, false, false, io::EFAT_ZIP)) {
- return false;
- }
-
- sanity_check(fs->getFileArchiveCount() > 0);
-
- /**********************************************************************/
- /* WARNING this is not threadsafe!! */
- /**********************************************************************/
- io::IFileArchive* opened_zip = fs->getFileArchive(fs->getFileArchiveCount() - 1);
-
- const io::IFileList* files_in_zip = opened_zip->getFileList();
-
- unsigned int number_of_files = files_in_zip->getFileCount();
-
- for (unsigned int i=0; i < number_of_files; i++) {
- std::string fullpath = destination;
- fullpath += DIR_DELIM;
- fullpath += files_in_zip->getFullFileName(i).c_str();
- std::string fullpath_dir = fs::RemoveLastPathComponent(fullpath);
-
- if (!files_in_zip->isDirectory(i)) {
- if (!fs::PathExists(fullpath_dir) && !fs::CreateAllDirs(fullpath_dir)) {
- fs->removeFileArchive(fs->getFileArchiveCount()-1);
- return false;
- }
-
- io::IReadFile* toread = opened_zip->createAndOpenFile(i);
-
- FILE *targetfile = fopen(fullpath.c_str(),"wb");
-
- if (targetfile == NULL) {
- fs->removeFileArchive(fs->getFileArchiveCount()-1);
- return false;
- }
-
- char read_buffer[1024];
- long total_read = 0;
-
- while (total_read < toread->getSize()) {
-
- unsigned int bytes_read =
- toread->read(read_buffer,sizeof(read_buffer));
- if ((bytes_read == 0 ) ||
- (fwrite(read_buffer, 1, bytes_read, targetfile) != bytes_read))
- {
- fclose(targetfile);
- fs->removeFileArchive(fs->getFileArchiveCount() - 1);
- return false;
- }
- total_read += bytes_read;
- }
-
- fclose(targetfile);
- }
-
- }
-
- fs->removeFileArchive(fs->getFileArchiveCount() - 1);
- return true;
-}
-
// Virtual methods from con::PeerHandler
void Client::peerAdded(con::Peer *peer)
{
diff --git a/src/client/client.h b/src/client/client.h
index c9a72b1b3..85ca24049 100644
--- a/src/client/client.h
+++ b/src/client/client.h
@@ -384,8 +384,6 @@ public:
bool loadMedia(const std::string &data, const std::string &filename,
bool from_media_push = false);
- bool extractZipFile(const char *filename, const std::string &destination);
-
// Send a request for conventional media transfer
void request_media(const std::vector<std::string> &file_requests);
diff --git a/src/filesys.cpp b/src/filesys.cpp
index 5ffb4506e..99b030624 100644
--- a/src/filesys.cpp
+++ b/src/filesys.cpp
@@ -727,6 +727,70 @@ bool safeWriteToFile(const std::string &path, const std::string &content)
return true;
}
+bool extractZipFile(io::IFileSystem *fs, const char *filename, const std::string &destination)
+{
+ if (!fs->addFileArchive(filename, false, false, io::EFAT_ZIP)) {
+ return false;
+ }
+
+ sanity_check(fs->getFileArchiveCount() > 0);
+
+ /**********************************************************************/
+ /* WARNING this is not threadsafe!! */
+ /**********************************************************************/
+ io::IFileArchive* opened_zip = fs->getFileArchive(fs->getFileArchiveCount() - 1);
+
+ const io::IFileList* files_in_zip = opened_zip->getFileList();
+
+ unsigned int number_of_files = files_in_zip->getFileCount();
+
+ for (unsigned int i=0; i < number_of_files; i++) {
+ std::string fullpath = destination;
+ fullpath += DIR_DELIM;
+ fullpath += files_in_zip->getFullFileName(i).c_str();
+ std::string fullpath_dir = fs::RemoveLastPathComponent(fullpath);
+
+ if (!files_in_zip->isDirectory(i)) {
+ if (!fs::PathExists(fullpath_dir) && !fs::CreateAllDirs(fullpath_dir)) {
+ fs->removeFileArchive(fs->getFileArchiveCount()-1);
+ return false;
+ }
+
+ io::IReadFile* toread = opened_zip->createAndOpenFile(i);
+
+ FILE *targetfile = fopen(fullpath.c_str(),"wb");
+
+ if (targetfile == NULL) {
+ fs->removeFileArchive(fs->getFileArchiveCount()-1);
+ return false;
+ }
+
+ char read_buffer[1024];
+ long total_read = 0;
+
+ while (total_read < toread->getSize()) {
+
+ unsigned int bytes_read =
+ toread->read(read_buffer,sizeof(read_buffer));
+ if ((bytes_read == 0 ) ||
+ (fwrite(read_buffer, 1, bytes_read, targetfile) != bytes_read))
+ {
+ fclose(targetfile);
+ fs->removeFileArchive(fs->getFileArchiveCount() - 1);
+ return false;
+ }
+ total_read += bytes_read;
+ }
+
+ fclose(targetfile);
+ }
+
+ }
+
+ fs->removeFileArchive(fs->getFileArchiveCount() - 1);
+ return true;
+}
+
bool ReadFile(const std::string &path, std::string &out)
{
std::ifstream is(path, std::ios::binary | std::ios::ate);
diff --git a/src/filesys.h b/src/filesys.h
index cfbfa02bf..a9584b036 100644
--- a/src/filesys.h
+++ b/src/filesys.h
@@ -36,6 +36,10 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#define PATH_DELIM ":"
#endif
+namespace irr { namespace io {
+class IFileSystem;
+}}
+
namespace fs
{
@@ -125,6 +129,8 @@ const char *GetFilenameFromPath(const char *path);
bool safeWriteToFile(const std::string &path, const std::string &content);
+bool extractZipFile(irr::io::IFileSystem *fs, const char *filename, const std::string &destination);
+
bool ReadFile(const std::string &path, std::string &out);
bool Rename(const std::string &from, const std::string &to);
diff --git a/src/script/lua_api/l_mainmenu.cpp b/src/script/lua_api/l_mainmenu.cpp
index b13398539..ee3e72dea 100644
--- a/src/script/lua_api/l_mainmenu.cpp
+++ b/src/script/lua_api/l_mainmenu.cpp
@@ -628,8 +628,9 @@ int ModApiMainMenu::l_extract_zip(lua_State *L)
std::string absolute_destination = fs::RemoveRelativePathComponents(destination);
if (ModApiMainMenu::mayModifyPath(absolute_destination)) {
+ auto rendering_engine = getGuiEngine(L)->m_rendering_engine;
fs::CreateAllDirs(absolute_destination);
- lua_pushboolean(L, getClient(L)->extractZipFile(zipfile, destination));
+ lua_pushboolean(L, fs::extractZipFile(rendering_engine->get_filesystem(), zipfile, destination));
return 1;
}