mirror of
https://github.com/minetest/minetest.git
synced 2024-12-24 15:12:23 +01:00
fix: extractZipFile is not part of Client but more generic.
This solve a crash from mainmenu while extracting the zip
This commit is contained in:
parent
ba40b39500
commit
225d4541ff
@ -725,72 +725,6 @@ bool Client::loadMedia(const std::string &data, const std::string &filename,
|
|||||||
return false;
|
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
|
// Virtual methods from con::PeerHandler
|
||||||
void Client::peerAdded(con::Peer *peer)
|
void Client::peerAdded(con::Peer *peer)
|
||||||
{
|
{
|
||||||
|
@ -384,8 +384,6 @@ public:
|
|||||||
bool loadMedia(const std::string &data, const std::string &filename,
|
bool loadMedia(const std::string &data, const std::string &filename,
|
||||||
bool from_media_push = false);
|
bool from_media_push = false);
|
||||||
|
|
||||||
bool extractZipFile(const char *filename, const std::string &destination);
|
|
||||||
|
|
||||||
// Send a request for conventional media transfer
|
// Send a request for conventional media transfer
|
||||||
void request_media(const std::vector<std::string> &file_requests);
|
void request_media(const std::vector<std::string> &file_requests);
|
||||||
|
|
||||||
|
@ -727,6 +727,70 @@ bool safeWriteToFile(const std::string &path, const std::string &content)
|
|||||||
return true;
|
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)
|
bool ReadFile(const std::string &path, std::string &out)
|
||||||
{
|
{
|
||||||
std::ifstream is(path, std::ios::binary | std::ios::ate);
|
std::ifstream is(path, std::ios::binary | std::ios::ate);
|
||||||
|
@ -36,6 +36,10 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
#define PATH_DELIM ":"
|
#define PATH_DELIM ":"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
namespace irr { namespace io {
|
||||||
|
class IFileSystem;
|
||||||
|
}}
|
||||||
|
|
||||||
namespace fs
|
namespace fs
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -125,6 +129,8 @@ const char *GetFilenameFromPath(const char *path);
|
|||||||
|
|
||||||
bool safeWriteToFile(const std::string &path, const std::string &content);
|
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 ReadFile(const std::string &path, std::string &out);
|
||||||
|
|
||||||
bool Rename(const std::string &from, const std::string &to);
|
bool Rename(const std::string &from, const std::string &to);
|
||||||
|
@ -628,8 +628,9 @@ int ModApiMainMenu::l_extract_zip(lua_State *L)
|
|||||||
std::string absolute_destination = fs::RemoveRelativePathComponents(destination);
|
std::string absolute_destination = fs::RemoveRelativePathComponents(destination);
|
||||||
|
|
||||||
if (ModApiMainMenu::mayModifyPath(absolute_destination)) {
|
if (ModApiMainMenu::mayModifyPath(absolute_destination)) {
|
||||||
|
auto rendering_engine = getGuiEngine(L)->m_rendering_engine;
|
||||||
fs::CreateAllDirs(absolute_destination);
|
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;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user