← Back to team overview

linuxdcpp-team team mailing list archive

[Branch ~dcplusplus-team/dcplusplus/trunk] Rev 3283: change dcext to ZIP with some restrictions

 

------------------------------------------------------------
revno: 3283
committer: poy <poy@xxxxxxxxxx>
branch nick: trunk
timestamp: Thu 2013-05-02 21:58:57 +0200
message:
  change dcext to ZIP with some restrictions
removed:
  test/data/gtest_h.tar.gz
added:
  test/data/gtest_h.zip
modified:
  Plugin format (dcext).txt
  SConstruct
  ThirdPartyLicenses.txt
  dcpp/Archive.cpp
  dcpp/Archive.h
  dcpp/SConscript
  test/SConscript
  test/testarchive.cpp
  utils/SConscript
  win32/SConscript


--
lp:dcplusplus
https://code.launchpad.net/~dcplusplus-team/dcplusplus/trunk

Your team Dcplusplus-team is subscribed to branch lp:dcplusplus.
To unsubscribe from this branch go to https://code.launchpad.net/~dcplusplus-team/dcplusplus/trunk/+edit-subscription
=== modified file 'Plugin format (dcext).txt'
--- Plugin format (dcext).txt	2013-04-23 15:34:45 +0000
+++ Plugin format (dcext).txt	2013-05-02 19:58:57 +0000
@@ -15,8 +15,13 @@
 Shared extensions are fine for testing but impractical to distribute and to have users install.
 Therefore, a DC plugin is preferably packaged as a .dcext file.
 
-A .dcext file is an archive. Currently, it is required to be a tar file, either uncompressed or
-compressed with bzip2 or gzip. This may be expanded in the future if needed.
+A .dcext file is a ZIP archive, as defined by PKWARE's APPNOTE, either uncompressed or compressed
+with DEFLATE, with the following restrictions:
+- No encryption.
+- No streaming / splitting / spanning.
+- No extension / extra fields.
+- No manifest file.
+- No character outside of the ASCII range in file names.
 
 That archive must contain an XML file named "info.xml" at its root, whose contents shall validate
 against the schemas/dcext.xsd schema.

=== modified file 'SConstruct'
--- SConstruct	2013-04-23 17:57:04 +0000
+++ SConstruct	2013-05-02 19:58:57 +0000
@@ -270,7 +270,6 @@
 	conf.env.Append(CPPDEFINES='HAVE_OLD_MINGW')
 env = conf.Finish()
 
-dev.archive = dev.build('archive/')
 dev.boost = dev.build('boost/')
 dev.dwarf = dev.build('dwarf/')
 dev.zlib = dev.build('zlib/')

=== modified file 'ThirdPartyLicenses.txt'
--- ThirdPartyLicenses.txt	2013-04-21 17:39:36 +0000
+++ ThirdPartyLicenses.txt	2013-05-02 19:58:57 +0000
@@ -1,36 +1,9 @@
 Licenses contained in this file:
-- libarchive license
 - GeoIP license
 - MiniUPnPc license
 - libnatpmp license
 - OpenSSL license
 
---- libarchive license ---
-
-Copyright (c) 2003-2009 <author(s)>
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-1. Redistributions of source code must retain the above copyright
-   notice, this list of conditions and the following disclaimer
-   in this position and unchanged.
-2. Redistributions in binary form must reproduce the above copyright
-   notice, this list of conditions and the following disclaimer in the
-   documentation and/or other materials provided with the distribution.
-
-THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
-IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
-IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
-INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
-NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
-THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
 --- GeoIP license ---
 
 There are two licenses, one for the C library software, and one for

=== modified file 'dcpp/Archive.cpp'
--- dcpp/Archive.cpp	2013-04-22 22:31:37 +0000
+++ dcpp/Archive.cpp	2013-05-02 19:58:57 +0000
@@ -23,39 +23,20 @@
 #include "File.h"
 #include "Util.h"
 
-#ifndef LIBARCHIVE_STATIC
-#define LIBARCHIVE_STATIC
-#endif
-#include <archive.h>
-#include <archive_entry.h>
+#include <unzip.h>
 
 namespace dcpp {
 
-Archive::Archive(const string& path) : a(nullptr), f(nullptr) {
-	a = archive_read_new();
-	if(!a) {
-		throw Exception(Util::translateError(ERROR_OUTOFMEMORY));
-	}
-
-	f = dcpp_fopen(path.c_str(), "rb");
-	if(!f) {
-		throw FileException(Util::translateError(ERROR_FILE_NOT_FOUND));
-	}
-
-	check(archive_read_support_format_tar(a));
-	check(archive_read_support_filter_bzip2(a));
-	check(archive_read_support_filter_gzip(a));
-
-	check(archive_read_open_FILE(a, f));
+Archive::Archive(const string& path) {
+	file = unzOpen64(Text::toT(path).c_str());
+	if(!file) {
+		throw Exception(_("Invalid archive"));
+	}
 }
 
 Archive::~Archive() {
-	if(a) {
-		archive_read_free(a);
-	}
-
-	if(f) {
-		fclose(f);
+	if(file) {
+		unzClose(file);
 	}
 }
 
@@ -64,10 +45,14 @@
 
 	dcassert(!path.empty() && isDir(path));
 
-	::archive_entry* entry;
-	while(check(archive_read_next_header(a, &entry)) != ARCHIVE_EOF) {
-
-		string path_out(archive_entry_pathname(entry));
+	if(check(unzGoToFirstFile(file)) != UNZ_OK) { return; }
+
+	do {
+		char pathBuf[MAX_PATH];
+		if(check(unzGetCurrentFileInfo(file, nullptr, pathBuf, MAX_PATH, nullptr, 0, nullptr, 0)) != UNZ_OK) { continue; }
+		if(check(unzOpenCurrentFile(file)) != UNZ_OK) { continue; }
+
+		string path_out(pathBuf);
 		if(path_out.empty() || isDir(path_out)) {
 			continue;
 		}
@@ -76,18 +61,28 @@
 		File::ensureDirectory(path_out);
 		File f_out(path_out, File::WRITE, File::CREATE | File::TRUNCATE);
 
-		const void* buf;
-		size_t size;
-		__LA_INT64_T offset;
-		while(check(archive_read_data_block(a, &buf, &size, &offset)) != ARCHIVE_EOF) {
-			f_out.write(buf, size);
+		const size_t BUF_SIZE = 64 * 1024;
+		ByteVector buf(BUF_SIZE);
+		while(true) {
+			auto read = unzReadCurrentFile(file, &buf[0], BUF_SIZE);
+			if(read > 0) {
+				f_out.write(&buf[0], read);
+			} else if(read == UNZ_EOF) {
+				break;
+			} else {
+				check(read);
+			}
 		}
-	}
+
+		// this does the CRC check.
+		check(unzCloseCurrentFile(file));
+
+	} while(check(unzGoToNextFile(file)) == UNZ_OK);
 }
 
 int Archive::check(int ret) {
-	if(ret != ARCHIVE_OK && ret != ARCHIVE_EOF) {
-		throw Exception(archive_error_string(a));
+	if(ret != UNZ_OK && ret != UNZ_END_OF_LIST_OF_FILE && ret != UNZ_EOF) {
+		throw Exception(_("Invalid archive"));
 	}
 	return ret;
 }

=== modified file 'dcpp/Archive.h'
--- dcpp/Archive.h	2013-04-22 22:31:37 +0000
+++ dcpp/Archive.h	2013-05-02 19:58:57 +0000
@@ -21,13 +21,13 @@
 
 #include <string>
 
-struct archive;
+typedef void* unzFile;
 
 namespace dcpp {
 
 using std::string;
 
-/** Wrappers around libarchive. */
+/** Extract a ZIP archive. */
 class Archive {
 public:
 	Archive(const string& path);
@@ -39,8 +39,7 @@
 private:
 	inline int check(int ret);
 
-	::archive* a;
-	::FILE* f;
+	::unzFile file;
 };
 
 } // namespace dcpp

=== modified file 'dcpp/SConscript'
--- dcpp/SConscript	2013-04-21 17:39:36 +0000
+++ dcpp/SConscript	2013-05-02 19:58:57 +0000
@@ -4,7 +4,7 @@
 
 env, target, sources = dev.prepare_build(source_path, 'dcpp', in_bin = False, precompiled_header = 'stdinc')
 
-env.Append(CPPPATH = ['#/openssl/include', '#/archive', '#/bzip2', '#/geoip', '#/zlib'])
+env.Append(CPPPATH = ['#/openssl/include', '#/bzip2', '#/geoip', '#/zlib'])
 
 env.Append(CPPDEFINES = ['BUILDING_DCPP=1'])
 

=== modified file 'test/SConscript'
--- test/SConscript	2013-04-21 17:39:36 +0000
+++ test/SConscript	2013-05-02 19:58:57 +0000
@@ -49,7 +49,7 @@
 if env['msvcproj']:
 	ret = dev.build_lib(env, target, sources, dev.cpp_lib)
 else:
-	ret = env.Program(target, [sources, dev.client, dev.archive, dev.dwarf, dev.zlib, dev.boost, dev.bzip2, dev.geoip, dev.miniupnpc, dev.natpmp, dev.intl])
+	ret = env.Program(target, [sources, dev.client, dev.dwarf, dev.zlib, dev.boost, dev.bzip2, dev.geoip, dev.miniupnpc, dev.natpmp, dev.intl])
 	ret = env.Command(dev.get_target(source_path, 'gtest.passed', in_bin=False), ret[0].abspath, runUnitTest)
 
 env.Help("\nYou can run the test suite by running 'scons test'\n")

=== removed file 'test/data/gtest_h.tar.gz'
Binary files test/data/gtest_h.tar.gz	2013-04-21 17:39:36 +0000 and test/data/gtest_h.tar.gz	1970-01-01 00:00:00 +0000 differ
=== added file 'test/data/gtest_h.zip'
Binary files test/data/gtest_h.zip	1970-01-01 00:00:00 +0000 and test/data/gtest_h.zip	2013-05-02 19:58:57 +0000 differ
=== modified file 'test/testarchive.cpp'
--- test/testarchive.cpp	2013-04-21 17:39:36 +0000
+++ test/testarchive.cpp	2013-05-02 19:58:57 +0000
@@ -8,17 +8,20 @@
 
 TEST(testarchive, test_archive)
 {
+	File::deleteFile("test/data/out/gtest.h");
+
 	try {
-		Archive("test/data/gtest_h.tar.gz").extract("test/data/out/");
-	}
-	catch(const Exception& e) {
+		Archive("test/data/gtest_h.zip").extract("test/data/out/");
+
+	} catch(const Exception& e) {
 		FAIL() << e.getError();
 	}
 
 	auto md5 = [](string path) {
 		File f(path, File::READ, File::OPEN);
 		MD5Hash h;
-		h.update(f.read().c_str(), f.getSize());
+		auto buf = f.read();
+		h.update(buf.c_str(), buf.size());
 		return MD5Value(h.finalize());
 	};
 

=== modified file 'utils/SConscript'
--- utils/SConscript	2013-04-25 18:18:43 +0000
+++ utils/SConscript	2013-05-02 19:58:57 +0000
@@ -44,7 +44,7 @@
 	ret = []
 	for f in Glob('*.cpp'):
 		sources = dev.get_sources(source_path, str(f))
-		ret.append(env.Program(dev.get_target(source_path, os.path.basename(str(f)).replace('.cpp', ''), in_bin = False), [sources, dev.client, dev.archive, dev.dwarf, dev.zlib, dev.boost, dev.bzip2, dev.geoip, dev.miniupnpc, dev.natpmp, dev.intl]))
+		ret.append(env.Program(dev.get_target(source_path, os.path.basename(str(f)).replace('.cpp', ''), in_bin = False), [sources, dev.client, dev.dwarf, dev.zlib, dev.boost, dev.bzip2, dev.geoip, dev.miniupnpc, dev.natpmp, dev.intl]))
 
 env.Help("\nYou can build additional utilities by running 'scons utils'\n")
 

=== modified file 'win32/SConscript'
--- win32/SConscript	2013-04-21 17:39:36 +0000
+++ win32/SConscript	2013-05-02 19:58:57 +0000
@@ -48,7 +48,7 @@
 if env['msvcproj']:
 	ret = dev.build_lib(env, target, sources, dev.cpp_lib)
 else:
-	ret = env.Program(target, [sources, res, dev.client, dev.archive, dev.dwarf, dev.zlib, dev.boost, dev.bzip2, dev.geoip, dev.miniupnpc, dev.natpmp, dev.dwt, dev.intl])
+	ret = env.Program(target, [sources, res, dev.client, dev.dwarf, dev.zlib, dev.boost, dev.bzip2, dev.geoip, dev.miniupnpc, dev.natpmp, dev.dwt, dev.intl])
 
 if 'gcc' in env['TOOLS']:
 	# strip debug info to a separate PDB file