diff --git a/src/zimlib/include/zim/error.h b/src/zimlib/include/zim/error.h index c8e05a0..fb59e0d 100644 --- a/src/zimlib/include/zim/error.h +++ b/src/zimlib/include/zim/error.h @@ -24,10 +24,10 @@ namespace zim { - class ZenoFileFormatError : public std::runtime_error + class ZimFileFormatError : public std::runtime_error { public: - ZenoFileFormatError(const std::string& msg) + explicit ZimFileFormatError(const std::string& msg) : std::runtime_error(msg) { } }; diff --git a/src/zimlib/src/config.h.in b/src/zimlib/src/config.h.in index 29c5503..6c511fc 100644 --- a/src/zimlib/src/config.h.in +++ b/src/zimlib/src/config.h.in @@ -1,5 +1,11 @@ /* src/zimlib/src/config.h.in. Generated from configure.ac by autoheader. */ +/* set zim cluster cache size to number of cached chunks */ +#undef CLUSTER_CACHE_SIZE + +/* set zim dirent cache size to number of cached chunks */ +#undef DIRENT_CACHE_SIZE + /* Define to 1 if you have the header file. */ #undef HAVE_DLFCN_H @@ -42,10 +48,6 @@ /* Define to 1 if you have the header file. */ #undef HAVE_UNISTD_H -/* Define to the sub-directory in which libtool stores uninstalled libraries. - */ -#undef LT_OBJDIR - /* Name of package */ #undef PACKAGE @@ -61,9 +63,6 @@ /* Define to the one symbol short name of this package. */ #undef PACKAGE_TARNAME -/* Define to the home page for this package. */ -#undef PACKAGE_URL - /* Define to the version of this package. */ #undef PACKAGE_VERSION diff --git a/src/zimlib/src/fileimpl.cpp b/src/zimlib/src/fileimpl.cpp index cd63fa1..97d9870 100644 --- a/src/zimlib/src/fileimpl.cpp +++ b/src/zimlib/src/fileimpl.cpp @@ -24,30 +24,44 @@ #include #include #include +#include +#include #include #include "config.h" #include "log.h" #ifdef WITH_CXXTOOLS # include -#else -# include #endif log_define("zim.file.impl") namespace zim { + namespace + { + unsigned envValue(const char* env, unsigned def) + { + const char* v = ::getenv(env); + if (v) + { + std::istringstream s(v); + s >> def; + } + return def; + } + } + ////////////////////////////////////////////////////////////////////// // FileImpl // FileImpl::FileImpl(const char* fname) : zimFile(fname, std::ios::in | std::ios::binary), - direntCache(512), - clusterCache(16) + direntCache(envValue("ZIM_DIRENTCACHE", DIRENT_CACHE_SIZE)), + clusterCache(envValue("ZIM_CLUSTERCACHE", CLUSTER_CACHE_SIZE)) { if (!zimFile) - throw ZenoFileFormatError(std::string("can't open zim-file \"") + fname + '"'); + throw ZimFileFormatError(std::string("can't open zim-file \"") + fname + '"'); #ifdef HAVE_STAT64 struct stat64 st; @@ -73,7 +87,7 @@ namespace zim // read header zimFile >> header; if (zimFile.fail()) - throw ZenoFileFormatError("error reading zim-file header"); + throw ZimFileFormatError("error reading zim-file header"); // read index offsets { @@ -105,6 +119,18 @@ namespace zim *it = fromLittleEndian(&*it); } + if (clusterOffsets.empty()) + log_warn("no clusters found"); + else + { + offset_type lastOffset = clusterOffsets.back(); + log_debug("last offset=" << lastOffset << " file size=" << st.st_size); + if (lastOffset > st.st_size) + { + log_fatal("last offset (" << lastOffset << ") larger than file size (" << st.st_size << ')'); + throw ZimFileFormatError("last cluster offset larger than file size; file corrupt"); + } + } } Dirent FileImpl::getDirent(size_type idx) @@ -112,12 +138,12 @@ namespace zim log_trace("FileImpl::getDirent(" << idx << ')'); if (idx >= indexOffsets.size()) - throw ZenoFileFormatError("article index out of range"); + throw ZimFileFormatError("article index out of range"); if (!zimFile) { log_warn("file in error state"); - throw ZenoFileFormatError("file in error state"); + throw ZimFileFormatError("file in error state"); } std::pair v = direntCache.getx(idx); @@ -133,7 +159,7 @@ namespace zim if (!zimFile) { log_warn("failed to seek to directory entry"); - throw ZenoFileFormatError("failed to seek to directory entry"); + throw ZimFileFormatError("failed to seek to directory entry"); } Dirent dirent; @@ -142,7 +168,7 @@ namespace zim if (!zimFile) { log_warn("failed to read to directory entry"); - throw ZenoFileFormatError("failed to read directory entry"); + throw ZimFileFormatError("failed to read directory entry"); } log_debug("dirent read from " << indexOffsets[idx]); @@ -156,7 +182,7 @@ namespace zim log_trace("getCluster(" << idx << ')'); if (idx >= clusterOffsets.size()) - throw ZenoFileFormatError("article index out of range"); + throw ZimFileFormatError("article index out of range"); Cluster cluster = clusterCache.get(idx); if (cluster) @@ -170,7 +196,7 @@ namespace zim zimFile >> cluster; if (zimFile.fail()) - throw ZenoFileFormatError("error reading cluster data"); + throw ZimFileFormatError("error reading cluster data"); if (cluster.isCompressed()) {