From 8376d142670a804647292709495fd9645bf05510 Mon Sep 17 00:00:00 2001 From: tamasmeszaros Date: Mon, 3 Jun 2019 15:27:46 +0200 Subject: [PATCH] Fix for opening issues with archive files. --- src/libslic3r/CMakeLists.txt | 2 ++ src/libslic3r/Format/3mf.cpp | 54 ++++++++-------------------- src/libslic3r/Format/AMF.cpp | 51 +++++++------------------- src/libslic3r/Format/PRUS.cpp | 13 +++---- src/libslic3r/Zipper.cpp | 18 ++-------- src/libslic3r/miniz_extension.cpp | 59 +++++++++++++++++++++++++++++++ src/libslic3r/miniz_extension.hpp | 16 +++++++++ 7 files changed, 113 insertions(+), 100 deletions(-) create mode 100644 src/libslic3r/miniz_extension.cpp create mode 100644 src/libslic3r/miniz_extension.hpp diff --git a/src/libslic3r/CMakeLists.txt b/src/libslic3r/CMakeLists.txt index 6a4fe3c28..833b1ae62 100644 --- a/src/libslic3r/CMakeLists.txt +++ b/src/libslic3r/CMakeLists.txt @@ -163,6 +163,8 @@ add_library(libslic3r STATIC MTUtils.hpp Zipper.hpp Zipper.cpp + miniz_extension.hpp + miniz_extension.cpp SLA/SLABoilerPlate.hpp SLA/SLABasePool.hpp SLA/SLABasePool.cpp diff --git a/src/libslic3r/Format/3mf.cpp b/src/libslic3r/Format/3mf.cpp index 710439113..38b34c462 100644 --- a/src/libslic3r/Format/3mf.cpp +++ b/src/libslic3r/Format/3mf.cpp @@ -17,7 +17,7 @@ #include #include -#include +#include "miniz_extension.hpp" // VERSION NUMBERS // 0 : .3mf, files saved by older slic3r or other applications. No version definition in them. @@ -188,24 +188,6 @@ bool is_valid_object_type(const std::string& type) namespace Slic3r { -namespace { -void close_archive_reader(mz_zip_archive *arch) { - if (arch) { - FILE *f = mz_zip_get_cfile(arch); - mz_zip_reader_end(arch); - if (f) fclose(f); - } -} - -void close_archive_writer(mz_zip_archive *arch) { - if (arch) { - FILE *f = mz_zip_get_cfile(arch); - mz_zip_writer_end(arch); - if (f) fclose(f); - } -} -} - // Base class with error messages management class _3MF_Base { @@ -522,10 +504,7 @@ void close_archive_writer(mz_zip_archive *arch) { mz_zip_archive archive; mz_zip_zero_struct(&archive); - FILE *f = boost::nowide::fopen(filename.c_str(), "rb"); - auto res = mz_bool(f != nullptr && mz_zip_reader_init_cfile(&archive, f, -1, 0)); - if (res == 0) - { + if (!open_zip_reader(&archive, filename)) { add_error("Unable to open the file"); return false; } @@ -549,7 +528,7 @@ void close_archive_writer(mz_zip_archive *arch) { // valid model name -> extract model if (!_extract_model_from_archive(archive, stat)) { - close_archive_reader(&archive); + close_zip_reader(&archive); add_error("Archive does not contain a valid model"); return false; } @@ -585,7 +564,7 @@ void close_archive_writer(mz_zip_archive *arch) { // extract slic3r model config file if (!_extract_model_config_from_archive(archive, stat, model)) { - close_archive_reader(&archive); + close_zip_reader(&archive); add_error("Archive does not contain a valid model config"); return false; } @@ -593,7 +572,7 @@ void close_archive_writer(mz_zip_archive *arch) { } } - close_archive_reader(&archive); + close_zip_reader(&archive); for (const IdToModelObjectMap::value_type& object : m_objects) { @@ -1659,10 +1638,7 @@ void close_archive_writer(mz_zip_archive *arch) { mz_zip_archive archive; mz_zip_zero_struct(&archive); - FILE *f = boost::nowide::fopen(filename.c_str(), "wb"); - auto res = mz_bool(f != nullptr && mz_zip_writer_init_cfile(&archive, f, 0)); - if (res == 0) - { + if (!open_zip_writer(&archive, filename)) { add_error("Unable to open the file"); return false; } @@ -1671,7 +1647,7 @@ void close_archive_writer(mz_zip_archive *arch) { // The content of this file is the same for each PrusaSlicer 3mf. if (!_add_content_types_file_to_archive(archive)) { - close_archive_writer(&archive); + close_zip_writer(&archive); boost::filesystem::remove(filename); return false; } @@ -1681,7 +1657,7 @@ void close_archive_writer(mz_zip_archive *arch) { // The relationshis file contains a reference to the geometry file "3D/3dmodel.model", the name was chosen to be compatible with CURA. if (!_add_relationships_file_to_archive(archive)) { - close_archive_writer(&archive); + close_zip_writer(&archive); boost::filesystem::remove(filename); return false; } @@ -1691,7 +1667,7 @@ void close_archive_writer(mz_zip_archive *arch) { IdToObjectDataMap objects_data; if (!_add_model_file_to_archive(archive, model, objects_data)) { - close_archive_writer(&archive); + close_zip_writer(&archive); boost::filesystem::remove(filename); return false; } @@ -1701,7 +1677,7 @@ void close_archive_writer(mz_zip_archive *arch) { // The index differes from the index of an object ID of an object instance of a 3MF file! if (!_add_layer_height_profile_file_to_archive(archive, model)) { - close_archive_writer(&archive); + close_zip_writer(&archive); boost::filesystem::remove(filename); return false; } @@ -1711,7 +1687,7 @@ void close_archive_writer(mz_zip_archive *arch) { // The index differes from the index of an object ID of an object instance of a 3MF file! if (!_add_sla_support_points_file_to_archive(archive, model)) { - close_archive_writer(&archive); + close_zip_writer(&archive); boost::filesystem::remove(filename); return false; } @@ -1722,7 +1698,7 @@ void close_archive_writer(mz_zip_archive *arch) { { if (!_add_print_config_file_to_archive(archive, *config)) { - close_archive_writer(&archive); + close_zip_writer(&archive); boost::filesystem::remove(filename); return false; } @@ -1734,20 +1710,20 @@ void close_archive_writer(mz_zip_archive *arch) { // is stored here as well. if (!_add_model_config_file_to_archive(archive, model, objects_data)) { - close_archive_writer(&archive); + close_zip_writer(&archive); boost::filesystem::remove(filename); return false; } if (!mz_zip_writer_finalize_archive(&archive)) { - close_archive_writer(&archive); + close_zip_writer(&archive); boost::filesystem::remove(filename); add_error("Unable to finalize the archive"); return false; } - close_archive_writer(&archive); + close_zip_writer(&archive); return true; } diff --git a/src/libslic3r/Format/AMF.cpp b/src/libslic3r/Format/AMF.cpp index c4b6901a8..d26b5f3ed 100644 --- a/src/libslic3r/Format/AMF.cpp +++ b/src/libslic3r/Format/AMF.cpp @@ -16,7 +16,7 @@ #include #include #include -#include +#include "miniz_extension.hpp" #if 0 // Enable debugging and assert in this file. @@ -712,37 +712,19 @@ bool load_amf_file(const char *path, DynamicPrintConfig *config, Model *model) return result; } -namespace { -void close_archive_reader(mz_zip_archive *arch) { - if (arch) { - FILE *f = mz_zip_get_cfile(arch); - mz_zip_reader_end(arch); - if (f) fclose(f); - } -} - -void close_archive_writer(mz_zip_archive *arch) { - if (arch) { - FILE *f = mz_zip_get_cfile(arch); - mz_zip_writer_end(arch); - if (f) fclose(f); - } -} -} - bool extract_model_from_archive(mz_zip_archive& archive, const mz_zip_archive_file_stat& stat, DynamicPrintConfig* config, Model* model, unsigned int& version) { if (stat.m_uncomp_size == 0) { printf("Found invalid size\n"); - close_archive_reader(&archive); + close_zip_reader(&archive); return false; } XML_Parser parser = XML_ParserCreate(nullptr); // encoding if (!parser) { printf("Couldn't allocate memory for parser\n"); - close_archive_reader(&archive); + close_zip_reader(&archive); return false; } @@ -755,7 +737,7 @@ bool extract_model_from_archive(mz_zip_archive& archive, const mz_zip_archive_fi if (parser_buffer == nullptr) { printf("Unable to create buffer\n"); - close_archive_reader(&archive); + close_zip_reader(&archive); return false; } @@ -763,14 +745,14 @@ bool extract_model_from_archive(mz_zip_archive& archive, const mz_zip_archive_fi if (res == 0) { printf("Error while reading model data to buffer\n"); - close_archive_reader(&archive); + close_zip_reader(&archive); return false; } if (!XML_ParseBuffer(parser, (int)stat.m_uncomp_size, 1)) { printf("Error (%s) while parsing xml file at line %d\n", XML_ErrorString(XML_GetErrorCode(parser)), XML_GetCurrentLineNumber(parser)); - close_archive_reader(&archive); + close_zip_reader(&archive); return false; } @@ -792,10 +774,7 @@ bool load_amf_archive(const char *path, DynamicPrintConfig *config, Model *model mz_zip_archive archive; mz_zip_zero_struct(&archive); - FILE * f = boost::nowide::fopen(path, "rb"); - auto res = mz_bool(f == nullptr ? MZ_FALSE : MZ_TRUE); - res = res && mz_zip_reader_init_cfile(&archive, f, -1, 0); - if (res == MZ_FALSE) + if (!open_zip_reader(&archive, path)) { printf("Unable to init zip reader\n"); return false; @@ -813,7 +792,7 @@ bool load_amf_archive(const char *path, DynamicPrintConfig *config, Model *model { if (!extract_model_from_archive(archive, stat, config, model, version)) { - close_archive_reader(&archive); + close_zip_reader(&archive); printf("Archive does not contain a valid model"); return false; } @@ -834,7 +813,7 @@ bool load_amf_archive(const char *path, DynamicPrintConfig *config, Model *model } #endif // forward compatibility - close_archive_reader(&archive); + close_zip_reader(&archive); return true; } @@ -874,10 +853,7 @@ bool store_amf(const char *path, Model *model, const DynamicPrintConfig *config) mz_zip_archive archive; mz_zip_zero_struct(&archive); - FILE *f = boost::nowide::fopen(export_path.c_str(), "wb"); - auto res = mz_bool(f != nullptr && mz_zip_writer_init_cfile(&archive, f, 0)); - if (res == 0) - return false; + if (!open_zip_writer(&archive, export_path)) return false; std::stringstream stream; // https://en.cppreference.com/w/cpp/types/numeric_limits/max_digits10 @@ -1039,20 +1015,19 @@ bool store_amf(const char *path, Model *model, const DynamicPrintConfig *config) if (!mz_zip_writer_add_mem(&archive, internal_amf_filename.c_str(), (const void*)out.data(), out.length(), MZ_DEFAULT_COMPRESSION)) { - close_archive_writer(&archive); - if (f) fclose(f); + close_zip_writer(&archive); boost::filesystem::remove(export_path); return false; } if (!mz_zip_writer_finalize_archive(&archive)) { - close_archive_writer(&archive); + close_zip_writer(&archive); boost::filesystem::remove(export_path); return false; } - close_archive_writer(&archive); + close_zip_writer(&archive); return true; } diff --git a/src/libslic3r/Format/PRUS.cpp b/src/libslic3r/Format/PRUS.cpp index 802a8304c..502cac6e9 100644 --- a/src/libslic3r/Format/PRUS.cpp +++ b/src/libslic3r/Format/PRUS.cpp @@ -5,7 +5,7 @@ #include #include -#include +#include "miniz_extension.hpp" #include @@ -300,11 +300,10 @@ bool load_prus(const char *path, Model *model) mz_zip_archive archive; mz_zip_zero_struct(&archive); - FILE *f = boost::nowide::fopen(path, "rb"); - auto res = mz_bool(f != nullptr && mz_zip_reader_init_cfile(&archive, f, -1, 0)); size_t n_models_initial = model->objects.size(); + mz_bool res = MZ_FALSE; try { - if (res == MZ_FALSE) + if (!open_zip_reader(&archive, path)) throw std::runtime_error(std::string("Unable to init zip reader for ") + path); std::vector scene_xml_data; // For grouping multiple STLs into a single ModelObject for multi-material prints. @@ -329,13 +328,11 @@ bool load_prus(const char *path, Model *model) } } } catch (std::exception &ex) { - mz_zip_reader_end(&archive); - if(f) fclose(f); + close_zip_reader(&archive); throw ex; } - mz_zip_reader_end(&archive); - if(f) fclose(f); + close_zip_reader(&archive); return model->objects.size() > n_models_initial; } diff --git a/src/libslic3r/Zipper.cpp b/src/libslic3r/Zipper.cpp index e821c2968..348be49cc 100644 --- a/src/libslic3r/Zipper.cpp +++ b/src/libslic3r/Zipper.cpp @@ -1,9 +1,8 @@ #include #include "Zipper.hpp" -#include +#include "miniz_extension.hpp" #include -#include #include "I18N.hpp" //! macro used to mark string used at localization, @@ -124,16 +123,9 @@ Zipper::Zipper(const std::string &zipfname, e_compression compression) memset(&m_impl->arch, 0, sizeof(m_impl->arch)); - FILE *f = boost::nowide::fopen(zipfname.c_str(), "wb"); - - if (f == nullptr) { - m_impl->arch.m_last_error = MZ_ZIP_FILE_OPEN_FAILED; + if (!open_zip_writer(&m_impl->arch, zipfname)) { m_impl->blow_up(); } - - // Initialize the archive data - if(!mz_zip_writer_init_cfile(&m_impl->arch, f, 0)) - m_impl->blow_up(); } Zipper::~Zipper() @@ -148,13 +140,9 @@ Zipper::~Zipper() BOOST_LOG_TRIVIAL(error) << m_impl->formatted_errorstr(); } - FILE *f = mz_zip_get_cfile(&m_impl->arch); - // The file should be closed no matter what... - if(!mz_zip_writer_end(&m_impl->arch)) + if(!close_zip_writer(&m_impl->arch)) BOOST_LOG_TRIVIAL(error) << m_impl->formatted_errorstr(); - - if(f != nullptr) fclose(f); } Zipper::Zipper(Zipper &&m): diff --git a/src/libslic3r/miniz_extension.cpp b/src/libslic3r/miniz_extension.cpp new file mode 100644 index 000000000..e87b1a552 --- /dev/null +++ b/src/libslic3r/miniz_extension.cpp @@ -0,0 +1,59 @@ +#include "miniz_extension.hpp" + +#if defined(_MSC_VER) || defined(__MINGW64__) +#include "boost/nowide/cstdio.hpp" +#endif + +namespace Slic3r { + +namespace { +bool open_zip(mz_zip_archive *zip, const char *fname, bool isread) +{ + if (!zip) return false; + const char *mode = isread ? "rb" : "wb"; + + FILE *f = nullptr; +#if defined(_MSC_VER) || defined(__MINGW64__) + f = boost::nowide::fopen(fname, mode); +#elif defined(__GNUC__) && defined(_LARGEFILE64_SOURCE) + f = fopen64(fname, mode); +#else + f = fopen(fname, mode); +#endif + + if (!f) { + zip->m_last_error = MZ_ZIP_FILE_OPEN_FAILED; + return false; + } + + return isread ? mz_zip_reader_init_cfile(zip, f, 0, 0) + : mz_zip_writer_init_cfile(zip, f, 0); +} + +bool close_zip(mz_zip_archive *zip, bool isread) +{ + bool ret = false; + if (zip) { + FILE *f = mz_zip_get_cfile(zip); + ret = bool(isread ? mz_zip_reader_end(zip) + : mz_zip_writer_end(zip)); + if (f) fclose(f); + } + return ret; +} +} + +bool open_zip_reader(mz_zip_archive *zip, const std::string &fname) +{ + return open_zip(zip, fname.c_str(), true); +} + +bool open_zip_writer(mz_zip_archive *zip, const std::string &fname) +{ + return open_zip(zip, fname.c_str(), false); +} + +bool close_zip_reader(mz_zip_archive *zip) { return close_zip(zip, true); } +bool close_zip_writer(mz_zip_archive *zip) { return close_zip(zip, false); } + +} diff --git a/src/libslic3r/miniz_extension.hpp b/src/libslic3r/miniz_extension.hpp new file mode 100644 index 000000000..8d0967cbc --- /dev/null +++ b/src/libslic3r/miniz_extension.hpp @@ -0,0 +1,16 @@ +#ifndef MINIZ_EXTENSION_HPP +#define MINIZ_EXTENSION_HPP + +#include +#include + +namespace Slic3r { + +bool open_zip_reader(mz_zip_archive *zip, const std::string &fname_utf8); +bool open_zip_writer(mz_zip_archive *zip, const std::string &fname_utf8); +bool close_zip_reader(mz_zip_archive *zip); +bool close_zip_writer(mz_zip_archive *zip); + +} + +#endif // MINIZ_EXTENSION_HPP