mirror of
https://github.com/veracrypt/VeraCrypt.git
synced 2025-11-11 11:08:02 -06:00
Windows: Replace XZip/XUnzip library with zlib and libzip and include the sources of these library into VeraCrypt source tree.
This commit is contained in:
@@ -29,8 +29,7 @@
|
||||
#include "Registry.h"
|
||||
#include "Volumes.h"
|
||||
#include "Xml.h"
|
||||
#include "XZip.h"
|
||||
#include "XUnzip.h"
|
||||
#include "zip.h"
|
||||
|
||||
#ifdef VOLFORMAT
|
||||
#include "Format/FormatCom.h"
|
||||
@@ -40,6 +39,22 @@
|
||||
|
||||
#include <Strsafe.h>
|
||||
|
||||
bool ZipAdd (zip_t *z, const char* name, const unsigned char* pbData, DWORD cbData)
|
||||
{
|
||||
zip_error_t zerr;
|
||||
zip_source_t* zin = zip_source_buffer_create (pbData, cbData, 0, &zerr);
|
||||
if (!zin)
|
||||
return false;
|
||||
|
||||
if (-1 == zip_file_add (z, name, zin, 0))
|
||||
{
|
||||
zip_source_free (zin);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
namespace VeraCrypt
|
||||
{
|
||||
#if !defined (SETUP)
|
||||
@@ -2739,25 +2754,32 @@ namespace VeraCrypt
|
||||
if (!DcsRescueImg)
|
||||
throw ParameterIncorrect (SRC_POS);
|
||||
|
||||
unsigned int maxRescueZipSize = 4 * 1024 * 1024;
|
||||
ZRESULT res;
|
||||
HZIP hz = CreateZip (0, maxRescueZipSize, ZIP_MEMORY);
|
||||
if (!hz)
|
||||
char szTmpPath[MAX_PATH + 1], szTmpFilePath[MAX_PATH + 1];
|
||||
if (!GetTempPathA (MAX_PATH, szTmpPath))
|
||||
throw SystemException (SRC_POS);
|
||||
if (!GetTempFileNameA (szTmpPath, "_vrd", 0, szTmpFilePath))
|
||||
throw SystemException (SRC_POS);
|
||||
|
||||
finally_do_arg (char*, szTmpFilePath, { DeleteFileA (finally_arg);});
|
||||
|
||||
int ierr;
|
||||
zip_t* z = zip_open (szTmpFilePath, ZIP_CREATE | ZIP_TRUNCATE | ZIP_CHECKCONS, &ierr);
|
||||
if (!z)
|
||||
throw ParameterIncorrect (SRC_POS);
|
||||
|
||||
finally_do_arg (HZIP, hz, { CloseZip (finally_arg); });
|
||||
finally_do_arg (zip_t**, &z, { if (*finally_arg) zip_discard (*finally_arg);});
|
||||
|
||||
if (ZR_OK != ZipAdd (hz, L"EFI/Boot/bootx64.efi", DcsRescueImg, sizeDcsRescue, ZIP_MEMORY))
|
||||
if (!ZipAdd (z, "EFI/Boot/bootx64.efi", DcsRescueImg, sizeDcsRescue))
|
||||
throw ParameterIncorrect (SRC_POS);
|
||||
if (ZR_OK !=ZipAdd (hz, L"EFI/VeraCrypt/DcsBml.dcs", BootMenuLockerImg, sizeBootMenuLocker, ZIP_MEMORY))
|
||||
if (!ZipAdd (z, "EFI/VeraCrypt/DcsBml.dcs", BootMenuLockerImg, sizeBootMenuLocker))
|
||||
throw ParameterIncorrect (SRC_POS);
|
||||
if (ZR_OK != ZipAdd (hz, L"EFI/VeraCrypt/DcsBoot.efi", dcsBootImg, sizeDcsBoot, ZIP_MEMORY))
|
||||
if (!ZipAdd (z, "EFI/VeraCrypt/DcsBoot.efi", dcsBootImg, sizeDcsBoot))
|
||||
throw ParameterIncorrect (SRC_POS);
|
||||
if (ZR_OK != ZipAdd (hz, L"EFI/VeraCrypt/DcsCfg.dcs", dcsCfgImg, sizeDcsCfg, ZIP_MEMORY))
|
||||
if (!ZipAdd (z, "EFI/VeraCrypt/DcsCfg.dcs", dcsCfgImg, sizeDcsCfg))
|
||||
throw ParameterIncorrect (SRC_POS);
|
||||
if (ZR_OK != ZipAdd (hz, L"EFI/VeraCrypt/DcsInt.dcs", dcsIntImg, sizeDcsInt, ZIP_MEMORY))
|
||||
if (!ZipAdd (z, "EFI/VeraCrypt/DcsInt.dcs", dcsIntImg, sizeDcsInt))
|
||||
throw ParameterIncorrect (SRC_POS);
|
||||
if (ZR_OK != ZipAdd (hz, L"EFI/VeraCrypt/LegacySpeaker.dcs", LegacySpeakerImg, sizeLegacySpeaker, ZIP_MEMORY))
|
||||
if (!ZipAdd (z, "EFI/VeraCrypt/LegacySpeaker.dcs", LegacySpeakerImg, sizeLegacySpeaker))
|
||||
throw ParameterIncorrect (SRC_POS);
|
||||
|
||||
Buffer volHeader(TC_BOOT_ENCRYPTION_VOLUME_HEADER_SIZE);
|
||||
@@ -2778,20 +2800,21 @@ namespace VeraCrypt
|
||||
bootDevice.Read (volHeader.Ptr (), TC_BOOT_ENCRYPTION_VOLUME_HEADER_SIZE);
|
||||
}
|
||||
|
||||
if (ZR_OK != ZipAdd (hz, L"EFI/VeraCrypt/svh_bak", volHeader.Ptr (), TC_BOOT_ENCRYPTION_VOLUME_HEADER_SIZE, ZIP_MEMORY))
|
||||
if (!ZipAdd (z, "EFI/VeraCrypt/svh_bak", volHeader.Ptr (), TC_BOOT_ENCRYPTION_VOLUME_HEADER_SIZE))
|
||||
throw ParameterIncorrect (SRC_POS);
|
||||
|
||||
// Original system loader
|
||||
res = ZR_WRITE;
|
||||
Buffer fileBuf (0);
|
||||
bool bLoadAdded = false;
|
||||
try
|
||||
{
|
||||
DWORD fileSize = 0;
|
||||
File sysBakFile (GetSystemLoaderBackupPath(), true);
|
||||
sysBakFile.CheckOpened (SRC_POS);
|
||||
sysBakFile.GetFileSize(fileSize);
|
||||
Buffer fileBuf ((DWORD) fileSize);
|
||||
fileBuf.Resize ((DWORD) fileSize);
|
||||
DWORD sizeLoader = sysBakFile.Read (fileBuf.Ptr (), fileSize);
|
||||
res = ZipAdd (hz, L"EFI/Boot/original_bootx64.vc_backup", fileBuf.Ptr (), sizeLoader, ZIP_MEMORY);
|
||||
bLoadAdded = ZipAdd (z, "EFI/Boot/original_bootx64.vc_backup", fileBuf.Ptr (), sizeLoader);
|
||||
}
|
||||
catch (Exception &e)
|
||||
{
|
||||
@@ -2799,10 +2822,11 @@ namespace VeraCrypt
|
||||
Warning ("SYS_LOADER_UNAVAILABLE_FOR_RESCUE_DISK", ParentWindow);
|
||||
}
|
||||
|
||||
if (res != ZR_OK)
|
||||
if (!bLoadAdded)
|
||||
throw ParameterIncorrect (SRC_POS);
|
||||
|
||||
EfiBootConf conf;
|
||||
Buffer propBuf (0);
|
||||
wstring dcsPropFileName = GetTempPathString() + L"_dcsproprescue";
|
||||
finally_do_arg (wstring, dcsPropFileName, { DeleteFileW (finally_arg.c_str()); });
|
||||
if (conf.Save(dcsPropFileName.c_str(), ParentWindow))
|
||||
@@ -2811,24 +2835,40 @@ namespace VeraCrypt
|
||||
File propFile (dcsPropFileName, true, false);
|
||||
propFile.CheckOpened (SRC_POS);
|
||||
propFile.GetFileSize(fileSize);
|
||||
Buffer propBuf (fileSize);
|
||||
propBuf.Resize (fileSize);
|
||||
DWORD sizeDcsProp = propFile.Read (propBuf.Ptr (), fileSize);
|
||||
|
||||
if (ZR_OK != ZipAdd (hz, L"EFI/VeraCrypt/DcsProp", propBuf.Ptr (), sizeDcsProp, ZIP_MEMORY))
|
||||
if (!ZipAdd (z, "EFI/VeraCrypt/DcsProp", propBuf.Ptr (), sizeDcsProp))
|
||||
throw ParameterIncorrect (SRC_POS);
|
||||
}
|
||||
else
|
||||
throw ParameterIncorrect (SRC_POS);
|
||||
|
||||
void* pZipContent = NULL;
|
||||
unsigned long ulZipSize = 0;
|
||||
if (ZR_OK != ZipGetMemory (hz, &pZipContent, &ulZipSize))
|
||||
// flush the zip content to the temporary file
|
||||
if (zip_close (z) < 0)
|
||||
throw ParameterIncorrect (SRC_POS);
|
||||
|
||||
|
||||
z = NULL;
|
||||
|
||||
// read the zip data from the temporary file
|
||||
FILE* ftmpFile = fopen (szTmpFilePath, "rb");
|
||||
if (!ftmpFile)
|
||||
throw ParameterIncorrect (SRC_POS);
|
||||
|
||||
finally_do_arg (FILE*, ftmpFile, { fclose (finally_arg); });
|
||||
|
||||
unsigned long ulZipSize = (unsigned long) _filelength (_fileno (ftmpFile));
|
||||
RescueZipData = new byte[ulZipSize];
|
||||
if (!RescueZipData)
|
||||
throw bad_alloc();
|
||||
memcpy (RescueZipData, pZipContent, ulZipSize);
|
||||
|
||||
if (ulZipSize != fread (RescueZipData, 1, ulZipSize, ftmpFile))
|
||||
{
|
||||
delete [] RescueZipData;
|
||||
RescueZipData = NULL;
|
||||
throw ParameterIncorrect (SRC_POS);
|
||||
}
|
||||
|
||||
RescueZipSize = ulZipSize;
|
||||
|
||||
if (!isoImagePath.empty())
|
||||
@@ -3000,11 +3040,18 @@ namespace VeraCrypt
|
||||
L"EFI/Boot/original_bootx64.vc_backup"
|
||||
};
|
||||
|
||||
ZRESULT res;
|
||||
HZIP hz = OpenZip(RescueZipData, RescueZipSize, ZIP_MEMORY);
|
||||
if (!hz)
|
||||
zip_error_t zerr;
|
||||
zip_source_t* zsrc = zip_source_buffer_create (RescueZipData, RescueZipSize, 0, &zerr);
|
||||
if (!zsrc)
|
||||
throw ParameterIncorrect (SRC_POS);
|
||||
finally_do_arg (HZIP, hz, { CloseZip (finally_arg); });
|
||||
zip_t* z = zip_open_from_source (zsrc, ZIP_CHECKCONS | ZIP_RDONLY, &zerr);
|
||||
if (!z)
|
||||
{
|
||||
zip_source_free (zsrc);
|
||||
throw ParameterIncorrect (SRC_POS);
|
||||
}
|
||||
|
||||
finally_do_arg (zip_t*, z, { zip_close (finally_arg); });
|
||||
|
||||
for (WCHAR drive = L'Z'; drive >= L'C'; --drive)
|
||||
{
|
||||
@@ -3019,42 +3066,48 @@ namespace VeraCrypt
|
||||
if (GetVolumeInformationW (rootPath, NULL, 0, NULL, NULL, NULL, szNameBuffer, ARRAYSIZE(szNameBuffer))
|
||||
&& !wcsncmp (szNameBuffer, L"FAT", 3))
|
||||
{
|
||||
int index, i;
|
||||
ZIPENTRYW ze;
|
||||
int i;
|
||||
for (i = 0; i < ARRAYSIZE(efiFiles); i++)
|
||||
{
|
||||
bool bMatch = false;
|
||||
res = FindZipItemW (hz, efiFiles[i], true, &index, &ze);
|
||||
if ((res == ZR_OK) && (index >= 0))
|
||||
zip_int64_t index = zip_name_locate (z, WideToUtf8String (efiFiles[i]).c_str(), ZIP_FL_NOCASE);
|
||||
if (index >= 0)
|
||||
{
|
||||
// check that the file exists on the disk and that it has the same content
|
||||
StringCbCopyW (szNameBuffer, sizeof (szNameBuffer), rootPath);
|
||||
StringCbCatW (szNameBuffer, sizeof (szNameBuffer), efiFiles[i]);
|
||||
|
||||
try
|
||||
zip_stat_t stat;
|
||||
if ((0 == zip_stat_index (z, index, ZIP_FL_NOCASE, &stat)) && (stat.valid & ZIP_STAT_SIZE))
|
||||
{
|
||||
DWORD dwSize = 0;
|
||||
File diskFile (szNameBuffer, true);
|
||||
diskFile.CheckOpened (SRC_POS);
|
||||
diskFile.GetFileSize (dwSize);
|
||||
if (dwSize == (DWORD) ze.unc_size)
|
||||
// check that the file exists on the disk and that it has the same content
|
||||
StringCbCopyW (szNameBuffer, sizeof (szNameBuffer), rootPath);
|
||||
StringCbCatW (szNameBuffer, sizeof (szNameBuffer), efiFiles[i]);
|
||||
|
||||
try
|
||||
{
|
||||
Buffer fileBuf (dwSize);
|
||||
if (dwSize == diskFile.Read (fileBuf.Ptr (), dwSize))
|
||||
DWORD dwSize = 0;
|
||||
File diskFile (szNameBuffer, true);
|
||||
diskFile.CheckOpened (SRC_POS);
|
||||
diskFile.GetFileSize (dwSize);
|
||||
if (dwSize == (DWORD) stat.size)
|
||||
{
|
||||
Buffer efiBuf (dwSize);
|
||||
res = UnzipItem (hz, ze.index, efiBuf.Ptr (), dwSize, ZIP_MEMORY);
|
||||
if (res == ZR_OK)
|
||||
Buffer fileBuf (dwSize);
|
||||
if (dwSize == diskFile.Read (fileBuf.Ptr (), dwSize))
|
||||
{
|
||||
bMatch = (memcmp (efiBuf.Ptr(), fileBuf.Ptr(), dwSize) == 0);
|
||||
Buffer efiBuf (dwSize);
|
||||
zip_file_t* zf = zip_fopen_index (z, index, 0);
|
||||
if (zf)
|
||||
{
|
||||
if (0 < zip_fread (zf, efiBuf.Ptr (), stat.size))
|
||||
{
|
||||
bMatch = (memcmp (efiBuf.Ptr(), fileBuf.Ptr(), dwSize) == 0);
|
||||
}
|
||||
zip_fclose (zf);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
}
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -3129,70 +3182,99 @@ namespace VeraCrypt
|
||||
|
||||
if (dwSize == rescueFile.Read (rescueData.Ptr (), dwSize))
|
||||
{
|
||||
ZRESULT res;
|
||||
HZIP hzFile = OpenZip(rescueData.Ptr (), dwSize, ZIP_MEMORY);
|
||||
if (hzFile)
|
||||
zip_error_t zerr;
|
||||
zip_source_t* zsrc = zip_source_buffer_create (rescueData.Ptr (), dwSize, 0, &zerr);
|
||||
if (!zsrc)
|
||||
return false;
|
||||
zip_t* zFile = zip_open_from_source (zsrc, ZIP_CHECKCONS | ZIP_RDONLY, &zerr);
|
||||
if (!zFile)
|
||||
{
|
||||
finally_do_arg (HZIP, hzFile, { CloseZip (finally_arg); });
|
||||
HZIP hzMem = OpenZip(RescueZipData, RescueZipSize, ZIP_MEMORY);
|
||||
if (hzMem)
|
||||
{
|
||||
finally_do_arg (HZIP, hzMem, { CloseZip (finally_arg); });
|
||||
const wchar_t* efiFiles[] = {
|
||||
L"EFI/Boot/bootx64.efi",
|
||||
L"EFI/VeraCrypt/DcsBml.dcs",
|
||||
L"EFI/VeraCrypt/DcsBoot.efi",
|
||||
L"EFI/VeraCrypt/DcsCfg.dcs",
|
||||
L"EFI/VeraCrypt/DcsInt.dcs",
|
||||
L"EFI/VeraCrypt/LegacySpeaker.dcs",
|
||||
L"EFI/VeraCrypt/svh_bak",
|
||||
L"EFI/Boot/original_bootx64.vc_backup"
|
||||
};
|
||||
zip_source_free (zsrc);
|
||||
throw ParameterIncorrect (SRC_POS);
|
||||
}
|
||||
|
||||
int index, i;
|
||||
ZIPENTRYW zeFile, zeMem;
|
||||
for (i = 0; i < ARRAYSIZE(efiFiles); i++)
|
||||
finally_do_arg (zip_t*, zFile, { zip_close (finally_arg); });
|
||||
|
||||
zsrc = zip_source_buffer_create (RescueZipData, RescueZipSize, 0, &zerr);
|
||||
if (!zsrc)
|
||||
return false;
|
||||
zip_t* zMem = zip_open_from_source (zsrc, ZIP_CHECKCONS | ZIP_RDONLY, &zerr);
|
||||
if (!zMem)
|
||||
{
|
||||
zip_source_free (zsrc);
|
||||
throw ParameterIncorrect (SRC_POS);
|
||||
}
|
||||
|
||||
finally_do_arg (zip_t*, zMem, { zip_close (finally_arg); });
|
||||
|
||||
const wchar_t* efiFiles[] = {
|
||||
L"EFI/Boot/bootx64.efi",
|
||||
L"EFI/VeraCrypt/DcsBml.dcs",
|
||||
L"EFI/VeraCrypt/DcsBoot.efi",
|
||||
L"EFI/VeraCrypt/DcsCfg.dcs",
|
||||
L"EFI/VeraCrypt/DcsInt.dcs",
|
||||
L"EFI/VeraCrypt/LegacySpeaker.dcs",
|
||||
L"EFI/VeraCrypt/svh_bak",
|
||||
L"EFI/Boot/original_bootx64.vc_backup"
|
||||
};
|
||||
|
||||
int i;
|
||||
zip_stat_t statMem, statFile;
|
||||
zip_int64_t indexMem, indexFile;
|
||||
for (i = 0; i < ARRAYSIZE(efiFiles); i++)
|
||||
{
|
||||
bool bMatch = false;
|
||||
indexMem = zip_name_locate (zMem, WideToUtf8String (efiFiles[i]).c_str(), ZIP_FL_NOCASE);
|
||||
if (indexMem >= 0)
|
||||
{
|
||||
if ((0 == zip_stat_index (zMem, indexMem, ZIP_FL_NOCASE, &statMem)) && (statMem.valid & ZIP_STAT_SIZE))
|
||||
{
|
||||
bool bMatch = false;
|
||||
res = FindZipItemW (hzMem, efiFiles[i], true, &index, &zeMem);
|
||||
if ((res == ZR_OK) && (index >= 0))
|
||||
indexFile = zip_name_locate (zFile, WideToUtf8String (efiFiles[i]).c_str(), ZIP_FL_NOCASE);
|
||||
if (indexFile >= 0)
|
||||
{
|
||||
res = FindZipItemW (hzFile, efiFiles[i], true, &index, &zeFile);
|
||||
if ((res == ZR_OK) && (index >= 0) && (zeMem.unc_size == zeFile.unc_size))
|
||||
if ((0 == zip_stat_index (zFile, indexFile, ZIP_FL_NOCASE, &statFile)) && (statFile.valid & ZIP_STAT_SIZE))
|
||||
{
|
||||
Buffer fileBuf (zeFile.unc_size);
|
||||
Buffer memBuf (zeFile.unc_size);
|
||||
|
||||
res = UnzipItem (hzMem, zeMem.index, memBuf.Ptr (), zeMem.unc_size, ZIP_MEMORY);
|
||||
if (res == ZR_OK)
|
||||
if (statMem.size == statFile.size)
|
||||
{
|
||||
res = UnzipItem (hzFile, zeFile.index, fileBuf.Ptr (), zeFile.unc_size, ZIP_MEMORY);
|
||||
if (res == ZR_OK)
|
||||
Buffer fileBuf (statFile.size);
|
||||
Buffer memBuf (statMem.size);
|
||||
|
||||
zip_file_t* zfMem = zip_fopen_index (zMem, indexMem, 0);
|
||||
if (zfMem)
|
||||
{
|
||||
bMatch = (memcmp (memBuf.Ptr (), fileBuf.Ptr (), zeMem.unc_size) == 0);
|
||||
if (0 < zip_fread (zfMem, memBuf.Ptr (), statMem.size))
|
||||
{
|
||||
zip_file_t* zfFile = zip_fopen_index (zFile, indexFile, 0);
|
||||
if (zfFile)
|
||||
{
|
||||
if (0 < zip_fread (zfFile, fileBuf.Ptr (), statFile.size))
|
||||
{
|
||||
bMatch = (memcmp (memBuf.Ptr(), fileBuf.Ptr(), statFile.size) == 0);
|
||||
}
|
||||
zip_fclose (zfFile);
|
||||
}
|
||||
}
|
||||
zip_fclose (zfMem);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
// entry not found in our internal Rescue ZIP image. Skip it.
|
||||
bMatch = true;
|
||||
}
|
||||
|
||||
if (!bMatch)
|
||||
break;
|
||||
}
|
||||
|
||||
if (i == ARRAYSIZE(efiFiles))
|
||||
{
|
||||
// All entries processed
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
// entry not found in our internal Rescue ZIP image. Skip it.
|
||||
bMatch = true;
|
||||
}
|
||||
|
||||
if (!bMatch)
|
||||
break;
|
||||
}
|
||||
|
||||
if (i == ARRAYSIZE(efiFiles))
|
||||
{
|
||||
// All entries processed
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -82,6 +82,19 @@ namespace VeraCrypt
|
||||
~Buffer () { delete[] DataPtr; }
|
||||
byte *Ptr () const { return DataPtr; }
|
||||
size_t Size () const { return DataSize; }
|
||||
void Resize (size_t newSize)
|
||||
{
|
||||
if (newSize > DataSize)
|
||||
{
|
||||
byte *tmp = new byte[newSize];
|
||||
if (!tmp)
|
||||
throw bad_alloc();
|
||||
memcpy (tmp, DataPtr, DataSize);
|
||||
delete [] DataPtr;
|
||||
DataPtr = tmp;
|
||||
}
|
||||
DataSize = newSize;
|
||||
}
|
||||
|
||||
protected:
|
||||
byte *DataPtr;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,382 +0,0 @@
|
||||
// XUnzip.h Version 1.3
|
||||
//
|
||||
// Authors: Mark Adler et al. (see below)
|
||||
//
|
||||
// Modified by: Lucian Wischik
|
||||
// lu@wischik.com
|
||||
//
|
||||
// Version 1.0 - Turned C files into just a single CPP file
|
||||
// - Made them compile cleanly as C++ files
|
||||
// - Gave them simpler APIs
|
||||
// - Added the ability to zip/unzip directly in memory without
|
||||
// any intermediate files
|
||||
//
|
||||
// Modified by: Hans Dietrich
|
||||
// hdietrich@gmail.com
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Lucian Wischik's comments:
|
||||
// --------------------------
|
||||
// THIS FILE is almost entirely based upon code by info-zip.
|
||||
// It has been modified by Lucian Wischik.
|
||||
// The original code may be found at http://www.info-zip.org
|
||||
// The original copyright text follows.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Original authors' comments:
|
||||
// ---------------------------
|
||||
// This is version 2002-Feb-16 of the Info-ZIP copyright and license. The
|
||||
// definitive version of this document should be available at
|
||||
// ftp://ftp.info-zip.org/pub/infozip/license.html indefinitely.
|
||||
//
|
||||
// Copyright (c) 1990-2002 Info-ZIP. All rights reserved.
|
||||
//
|
||||
// For the purposes of this copyright and license, "Info-ZIP" is defined as
|
||||
// the following set of individuals:
|
||||
//
|
||||
// Mark Adler, John Bush, Karl Davis, Harald Denker, Jean-Michel Dubois,
|
||||
// Jean-loup Gailly, Hunter Goatley, Ian Gorman, Chris Herborth, Dirk Haase,
|
||||
// Greg Hartwig, Robert Heath, Jonathan Hudson, Paul Kienitz,
|
||||
// David Kirschbaum, Johnny Lee, Onno van der Linden, Igor Mandrichenko,
|
||||
// Steve P. Miller, Sergio Monesi, Keith Owens, George Petrov, Greg Roelofs,
|
||||
// Kai Uwe Rommel, Steve Salisbury, Dave Smith, Christian Spieler,
|
||||
// Antoine Verheijen, Paul von Behren, Rich Wales, Mike White
|
||||
//
|
||||
// This software is provided "as is", without warranty of any kind, express
|
||||
// or implied. In no event shall Info-ZIP or its contributors be held liable
|
||||
// for any direct, indirect, incidental, special or consequential damages
|
||||
// arising out of the use of or inability to use this software.
|
||||
//
|
||||
// Permission is granted to anyone to use this software for any purpose,
|
||||
// including commercial applications, and to alter it and redistribute it
|
||||
// freely, subject to the following restrictions:
|
||||
//
|
||||
// 1. Redistributions of source code must retain the above copyright notice,
|
||||
// definition, disclaimer, and this list of conditions.
|
||||
//
|
||||
// 2. Redistributions in binary form (compiled executables) must reproduce
|
||||
// the above copyright notice, definition, disclaimer, and this list of
|
||||
// conditions in documentation and/or other materials provided with the
|
||||
// distribution. The sole exception to this condition is redistribution
|
||||
// of a standard UnZipSFX binary as part of a self-extracting archive;
|
||||
// that is permitted without inclusion of this license, as long as the
|
||||
// normal UnZipSFX banner has not been removed from the binary or disabled.
|
||||
//
|
||||
// 3. Altered versions--including, but not limited to, ports to new
|
||||
// operating systems, existing ports with new graphical interfaces, and
|
||||
// dynamic, shared, or static library versions--must be plainly marked
|
||||
// as such and must not be misrepresented as being the original source.
|
||||
// Such altered versions also must not be misrepresented as being
|
||||
// Info-ZIP releases--including, but not limited to, labeling of the
|
||||
// altered versions with the names "Info-ZIP" (or any variation thereof,
|
||||
// including, but not limited to, different capitalizations),
|
||||
// "Pocket UnZip", "WiZ" or "MacZip" without the explicit permission of
|
||||
// Info-ZIP. Such altered versions are further prohibited from
|
||||
// misrepresentative use of the Zip-Bugs or Info-ZIP e-mail addresses or
|
||||
// of the Info-ZIP URL(s).
|
||||
//
|
||||
// 4. Info-ZIP retains the right to use the names "Info-ZIP", "Zip", "UnZip",
|
||||
// "UnZipSFX", "WiZ", "Pocket UnZip", "Pocket Zip", and "MacZip" for its
|
||||
// own source and binary releases.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef XUNZIP_H
|
||||
#define XUNZIP_H
|
||||
|
||||
|
||||
#ifndef XZIP_H
|
||||
DECLARE_HANDLE(HZIP); // An HZIP identifies a zip file that has been opened
|
||||
#endif
|
||||
|
||||
typedef DWORD ZRESULT;
|
||||
// return codes from any of the zip functions. Listed later.
|
||||
|
||||
#define ZIP_HANDLE 1
|
||||
#define ZIP_FILENAME 2
|
||||
#define ZIP_MEMORY 3
|
||||
|
||||
typedef struct
|
||||
{ int index; // index of this file within the zip
|
||||
char name[MAX_PATH]; // filename within the zip
|
||||
DWORD attr; // attributes, as in GetFileAttributes.
|
||||
FILETIME atime,ctime,mtime;// access, create, modify filetimes
|
||||
long comp_size; // sizes of item, compressed and uncompressed. These
|
||||
long unc_size; // may be -1 if not yet known (e.g. being streamed in)
|
||||
} ZIPENTRY;
|
||||
|
||||
typedef struct
|
||||
{ int index; // index of this file within the zip
|
||||
TCHAR name[MAX_PATH]; // filename within the zip
|
||||
DWORD attr; // attributes, as in GetFileAttributes.
|
||||
FILETIME atime,ctime,mtime;// access, create, modify filetimes
|
||||
long comp_size; // sizes of item, compressed and uncompressed. These
|
||||
long unc_size; // may be -1 if not yet known (e.g. being streamed in)
|
||||
} ZIPENTRYW;
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// OpenZip()
|
||||
//
|
||||
// Purpose: Open an existing zip archive file
|
||||
//
|
||||
// Parameters: z - archive file name if flags is ZIP_FILENAME; for other
|
||||
// uses see below
|
||||
// len - for memory (ZIP_MEMORY) should be the buffer size;
|
||||
// for other uses, should be 0
|
||||
// flags - indicates usage, see below; for files, this will be
|
||||
// ZIP_FILENAME
|
||||
//
|
||||
// Returns: HZIP - non-zero if zip archive opened ok, otherwise 0
|
||||
//
|
||||
HZIP OpenZip(void *z, unsigned int len, DWORD flags);
|
||||
// OpenZip - opens a zip file and returns a handle with which you can
|
||||
// subsequently examine its contents. You can open a zip file from:
|
||||
// from a pipe: OpenZip(hpipe_read,0, ZIP_HANDLE);
|
||||
// from a file (by handle): OpenZip(hfile,0, ZIP_HANDLE);
|
||||
// from a file (by name): OpenZip("c:\\test.zip",0, ZIP_FILENAME);
|
||||
// from a memory block: OpenZip(bufstart, buflen, ZIP_MEMORY);
|
||||
// If the file is opened through a pipe, then items may only be
|
||||
// accessed in increasing order, and an item may only be unzipped once,
|
||||
// although GetZipItem can be called immediately before and after unzipping
|
||||
// it. If it's opened i n any other way, then full random access is possible.
|
||||
// Note: pipe input is not yet implemented.
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// GetZipItem()
|
||||
//
|
||||
// Purpose: Get information about an item in an open zip archive
|
||||
//
|
||||
// Parameters: hz - handle of open zip archive
|
||||
// index - index number (0 based) of item in zip
|
||||
// ze - pointer to a ZIPENTRY (if ANSI) or ZIPENTRYW struct
|
||||
// (if Unicode)
|
||||
//
|
||||
// Returns: ZRESULT - ZR_OK if success, otherwise some other value
|
||||
//
|
||||
|
||||
#ifdef _UNICODE
|
||||
#define GetZipItem GetZipItemW
|
||||
#else
|
||||
#define GetZipItem GetZipItemA
|
||||
#endif
|
||||
|
||||
ZRESULT GetZipItemA(HZIP hz, int index, ZIPENTRY *ze);
|
||||
ZRESULT GetZipItemW(HZIP hz, int index, ZIPENTRYW *ze);
|
||||
// GetZipItem - call this to get information about an item in the zip.
|
||||
// If index is -1 and the file wasn't opened through a pipe,
|
||||
// then it returns information about the whole zipfile
|
||||
// (and in particular ze.index returns the number of index items).
|
||||
// Note: the item might be a directory (ze.attr & FILE_ATTRIBUTE_DIRECTORY)
|
||||
// See below for notes on what happens when you unzip such an item.
|
||||
// Note: if you are opening the zip through a pipe, then random access
|
||||
// is not possible and GetZipItem(-1) fails and you can't discover the number
|
||||
// of items except by calling GetZipItem on each one of them in turn,
|
||||
// starting at 0, until eventually the call fails. Also, in the event that
|
||||
// you are opening through a pipe and the zip was itself created into a pipe,
|
||||
// then then comp_size and sometimes unc_size as well may not be known until
|
||||
// after the item has been unzipped.
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// FindZipItem()
|
||||
//
|
||||
// Purpose: Find item by name and return information about it
|
||||
//
|
||||
// Parameters: hz - handle of open zip archive
|
||||
// name - name of file to look for inside zip archive
|
||||
// ic - TRUE = case insensitive
|
||||
// index - pointer to index number returned, or -1
|
||||
// ze - pointer to a ZIPENTRY (if ANSI) or ZIPENTRYW struct
|
||||
// (if Unicode)
|
||||
//
|
||||
// Returns: ZRESULT - ZR_OK if success, otherwise some other value
|
||||
//
|
||||
|
||||
#ifdef _UNICODE
|
||||
#define FindZipItem FindZipItemW
|
||||
#else
|
||||
#define FindZipItem FindZipItemA
|
||||
#endif
|
||||
|
||||
ZRESULT FindZipItemA(HZIP hz, const TCHAR *name, bool ic, int *index, ZIPENTRY *ze);
|
||||
ZRESULT FindZipItemW(HZIP hz, const TCHAR *name, bool ic, int *index, ZIPENTRYW *ze);
|
||||
// FindZipItem - finds an item by name. ic means 'insensitive to case'.
|
||||
// It returns the index of the item, and returns information about it.
|
||||
// If nothing was found, then index is set to -1 and the function returns
|
||||
// an error code.
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// UnzipItem()
|
||||
//
|
||||
// Purpose: Find item by index and unzip it
|
||||
//
|
||||
// Parameters: hz - handle of open zip archive
|
||||
// index - index number of file to unzip
|
||||
// dst - target file name of unzipped file
|
||||
// len - for memory (ZIP_MEMORY. length of buffer;
|
||||
// otherwise 0
|
||||
// flags - indicates usage, see below; for files, this will be
|
||||
// ZIP_FILENAME
|
||||
//
|
||||
// Returns: ZRESULT - ZR_OK if success, otherwise some other value
|
||||
//
|
||||
|
||||
ZRESULT UnzipItem(HZIP hz, int index, void *dst, unsigned int len, DWORD flags);
|
||||
// UnzipItem - given an index to an item, unzips it. You can unzip to:
|
||||
// to a pipe: UnzipItem(hz,i, hpipe_write,0,ZIP_HANDLE);
|
||||
// to a file (by handle): UnzipItem(hz,i, hfile,0,ZIP_HANDLE);
|
||||
// to a file (by name): UnzipItem(hz,i, ze.name,0,ZIP_FILENAME);
|
||||
// to a memory block: UnzipItem(hz,i, buf,buflen,ZIP_MEMORY);
|
||||
// In the final case, if the buffer isn't large enough to hold it all,
|
||||
// then the return code indicates that more is yet to come. If it was
|
||||
// large enough, and you want to know precisely how big, GetZipItem.
|
||||
// Note: zip files are normally stored with relative pathnames. If you
|
||||
// unzip with ZIP_FILENAME a relative pathname then the item gets created
|
||||
// relative to the current directory - it first ensures that all necessary
|
||||
// subdirectories have been created. Also, the item may itself be a directory.
|
||||
// If you unzip a directory with ZIP_FILENAME, then the directory gets created.
|
||||
// If you unzip it to a handle or a memory block, then nothing gets created
|
||||
// and it emits 0 bytes.
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// CloseZip()
|
||||
//
|
||||
// Purpose: Close an open zip archive
|
||||
//
|
||||
// Parameters: hz - handle to an open zip archive
|
||||
//
|
||||
// Returns: ZRESULT - ZR_OK if success, otherwise some other value
|
||||
//
|
||||
ZRESULT CloseZip(HZIP hz);
|
||||
// CloseZip - the zip handle must be closed with this function.
|
||||
|
||||
unsigned int FormatZipMessage(ZRESULT code, char *buf,unsigned int len);
|
||||
// FormatZipMessage - given an error code, formats it as a string.
|
||||
// It returns the length of the error message. If buf/len points
|
||||
// to a real buffer, then it also writes as much as possible into there.
|
||||
|
||||
|
||||
// These are the result codes:
|
||||
#define ZR_OK 0x00000000 // nb. the pseudo-code zr-recent is never returned,
|
||||
#define ZR_RECENT 0x00000001 // but can be passed to FormatZipMessage.
|
||||
// The following come from general system stuff (e.g. files not openable)
|
||||
#define ZR_GENMASK 0x0000FF00
|
||||
#define ZR_NODUPH 0x00000100 // couldn't duplicate the handle
|
||||
#define ZR_NOFILE 0x00000200 // couldn't create/open the file
|
||||
#define ZR_NOALLOC 0x00000300 // failed to allocate some resource
|
||||
#define ZR_WRITE 0x00000400 // a general error writing to the file
|
||||
#define ZR_NOTFOUND 0x00000500 // couldn't find that file in the zip
|
||||
#define ZR_MORE 0x00000600 // there's still more data to be unzipped
|
||||
#define ZR_CORRUPT 0x00000700 // the zipfile is corrupt or not a zipfile
|
||||
#define ZR_READ 0x00000800 // a general error reading the file
|
||||
// The following come from mistakes on the part of the caller
|
||||
#define ZR_CALLERMASK 0x00FF0000
|
||||
#define ZR_ARGS 0x00010000 // general mistake with the arguments
|
||||
#define ZR_NOTMMAP 0x00020000 // tried to ZipGetMemory, but that only works on mmap zipfiles, which yours wasn't
|
||||
#define ZR_MEMSIZE 0x00030000 // the memory size is too small
|
||||
#define ZR_FAILED 0x00040000 // the thing was already failed when you called this function
|
||||
#define ZR_ENDED 0x00050000 // the zip creation has already been closed
|
||||
#define ZR_MISSIZE 0x00060000 // the indicated input file size turned out mistaken
|
||||
#define ZR_PARTIALUNZ 0x00070000 // the file had already been partially unzipped
|
||||
#define ZR_ZMODE 0x00080000 // tried to mix creating/opening a zip
|
||||
// The following come from bugs within the zip library itself
|
||||
#define ZR_BUGMASK 0xFF000000
|
||||
#define ZR_NOTINITED 0x01000000 // initialisation didn't work
|
||||
#define ZR_SEEK 0x02000000 // trying to seek in an unseekable file
|
||||
#define ZR_NOCHANGE 0x04000000 // changed its mind on storage, but not allowed
|
||||
#define ZR_FLATE 0x05000000 // an internal error in the de/inflation code
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// e.g.
|
||||
//
|
||||
// SetCurrentDirectory("c:\\docs\\stuff");
|
||||
// HZIP hz = OpenZip("c:\\stuff.zip",0,ZIP_FILENAME);
|
||||
// ZIPENTRY ze; GetZipItem(hz,-1,&ze); int numitems=ze.index;
|
||||
// for (int i=0; i<numitems; i++)
|
||||
// { GetZipItem(hz,i,&ze);
|
||||
// UnzipItem(hz,i,ze.name,0,ZIP_FILENAME);
|
||||
// }
|
||||
// CloseZip(hz);
|
||||
//
|
||||
//
|
||||
// HRSRC hrsrc = FindResource(hInstance,MAKEINTRESOURCE(1),RT_RCDATA);
|
||||
// HANDLE hglob = LoadResource(hInstance,hrsrc);
|
||||
// void *zipbuf=LockResource(hglob);
|
||||
// unsigned int ziplen=SizeofResource(hInstance,hrsrc);
|
||||
// HZIP hz = OpenZip(zipbuf, ziplen, ZIP_MEMORY);
|
||||
// - unzip to a membuffer -
|
||||
// ZIPENTRY ze; int i; FindZipItem(hz,"file.dat",&i,&ze);
|
||||
// char *ibuf = new char[ze.unc_size];
|
||||
// UnzipItem(hz,i, ibuf, ze.unc_size,ZIP_MEMORY);
|
||||
// delete[] buf;
|
||||
// - unzip to a fixed membuff -
|
||||
// ZIPENTRY ze; int i; FindZipItem(hz,"file.dat",&i,&ze);
|
||||
// char ibuf[1024]; ZIPRESULT zr=ZR_MORE; unsigned long totsize=0;
|
||||
// while (zr==ZR_MORE)
|
||||
// { zr = UnzipItem(hz,i, ibuf,1024,ZIP_MEMORY);
|
||||
// unsigned long bufsize=1024; if (zr==ZR_OK) bufsize=ze.unc_size-totsize;
|
||||
// totsize+=bufsize;
|
||||
// }
|
||||
// - unzip to a pipe -
|
||||
// HANDLE hthread=CreateWavReaderThread(&hread,&hwrite);
|
||||
// FindZipItem(hz,"sound.wav",&i,&ze);
|
||||
// UnzipItem(hz,i, hwrite,0,ZIP_HANDLE);
|
||||
// CloseHandle(hwrite);
|
||||
// WaitForSingleObject(hthread,INFINITE);
|
||||
// CloseHandle(hread); CloseHandle(hthread);
|
||||
// - finished -
|
||||
// CloseZip(hz);
|
||||
// // note: no need to free resources obtained through Find/Load/LockResource
|
||||
//
|
||||
//
|
||||
// SetCurrentDirectory("c:\\docs\\pipedzipstuff");
|
||||
// HANDLE hread,hwrite; CreatePipe(&hread,&hwrite);
|
||||
// CreateZipWriterThread(hwrite);
|
||||
// HZIP hz = OpenZip(hread,0,ZIP_HANDLE);
|
||||
// for (int i=0; ; i++)
|
||||
// { ZIPENTRY ze; ZRESULT res = GetZipItem(hz,i,&ze);
|
||||
// if (res!=ZE_OK) break; // no more
|
||||
// UnzipItem(hz,i, ze.name,0,ZIP_FILENAME);
|
||||
// }
|
||||
// CloseZip(hz);
|
||||
//
|
||||
|
||||
|
||||
|
||||
|
||||
// Now we indulge in a little skullduggery so that the code works whether
|
||||
// the user has included just zip or both zip and unzip.
|
||||
// Idea: if header files for both zip and unzip are present, then presumably
|
||||
// the cpp files for zip and unzip are both present, so we will call
|
||||
// one or the other of them based on a dynamic choice. If the header file
|
||||
// for only one is present, then we will bind to that particular one.
|
||||
HZIP OpenZipU(void *z,unsigned int len,DWORD flags);
|
||||
ZRESULT CloseZipU(HZIP hz);
|
||||
unsigned int FormatZipMessageU(ZRESULT code, char *buf,unsigned int len);
|
||||
bool IsZipHandleU(HZIP hz);
|
||||
#define OpenZip OpenZipU
|
||||
|
||||
#ifdef XZIP_H
|
||||
#undef CloseZip
|
||||
#define CloseZip(hz) (IsZipHandleU(hz)?CloseZipU(hz):CloseZipZ(hz))
|
||||
#else
|
||||
#define CloseZip CloseZipU
|
||||
#define FormatZipMessage FormatZipMessageU
|
||||
#endif
|
||||
|
||||
|
||||
#endif //XUNZIP_H
|
||||
3215
src/Common/XZip.cpp
3215
src/Common/XZip.cpp
File diff suppressed because it is too large
Load Diff
@@ -1,323 +0,0 @@
|
||||
// XZip.h Version 1.3
|
||||
//
|
||||
// Authors: Mark Adler et al. (see below)
|
||||
//
|
||||
// Modified by: Lucian Wischik
|
||||
// lu@wischik.com
|
||||
//
|
||||
// Version 1.0 - Turned C files into just a single CPP file
|
||||
// - Made them compile cleanly as C++ files
|
||||
// - Gave them simpler APIs
|
||||
// - Added the ability to zip/unzip directly in memory without
|
||||
// any intermediate files
|
||||
//
|
||||
// Modified by: Hans Dietrich
|
||||
// hdietrich@gmail.com
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Lucian Wischik's comments:
|
||||
// --------------------------
|
||||
// THIS FILE is almost entirely based upon code by info-zip.
|
||||
// It has been modified by Lucian Wischik.
|
||||
// The original code may be found at http://www.info-zip.org
|
||||
// The original copyright text follows.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Original authors' comments:
|
||||
// ---------------------------
|
||||
// This is version 2002-Feb-16 of the Info-ZIP copyright and license. The
|
||||
// definitive version of this document should be available at
|
||||
// ftp://ftp.info-zip.org/pub/infozip/license.html indefinitely.
|
||||
//
|
||||
// Copyright (c) 1990-2002 Info-ZIP. All rights reserved.
|
||||
//
|
||||
// For the purposes of this copyright and license, "Info-ZIP" is defined as
|
||||
// the following set of individuals:
|
||||
//
|
||||
// Mark Adler, John Bush, Karl Davis, Harald Denker, Jean-Michel Dubois,
|
||||
// Jean-loup Gailly, Hunter Goatley, Ian Gorman, Chris Herborth, Dirk Haase,
|
||||
// Greg Hartwig, Robert Heath, Jonathan Hudson, Paul Kienitz,
|
||||
// David Kirschbaum, Johnny Lee, Onno van der Linden, Igor Mandrichenko,
|
||||
// Steve P. Miller, Sergio Monesi, Keith Owens, George Petrov, Greg Roelofs,
|
||||
// Kai Uwe Rommel, Steve Salisbury, Dave Smith, Christian Spieler,
|
||||
// Antoine Verheijen, Paul von Behren, Rich Wales, Mike White
|
||||
//
|
||||
// This software is provided "as is", without warranty of any kind, express
|
||||
// or implied. In no event shall Info-ZIP or its contributors be held liable
|
||||
// for any direct, indirect, incidental, special or consequential damages
|
||||
// arising out of the use of or inability to use this software.
|
||||
//
|
||||
// Permission is granted to anyone to use this software for any purpose,
|
||||
// including commercial applications, and to alter it and redistribute it
|
||||
// freely, subject to the following restrictions:
|
||||
//
|
||||
// 1. Redistributions of source code must retain the above copyright notice,
|
||||
// definition, disclaimer, and this list of conditions.
|
||||
//
|
||||
// 2. Redistributions in binary form (compiled executables) must reproduce
|
||||
// the above copyright notice, definition, disclaimer, and this list of
|
||||
// conditions in documentation and/or other materials provided with the
|
||||
// distribution. The sole exception to this condition is redistribution
|
||||
// of a standard UnZipSFX binary as part of a self-extracting archive;
|
||||
// that is permitted without inclusion of this license, as long as the
|
||||
// normal UnZipSFX banner has not been removed from the binary or disabled.
|
||||
//
|
||||
// 3. Altered versions--including, but not limited to, ports to new
|
||||
// operating systems, existing ports with new graphical interfaces, and
|
||||
// dynamic, shared, or static library versions--must be plainly marked
|
||||
// as such and must not be misrepresented as being the original source.
|
||||
// Such altered versions also must not be misrepresented as being
|
||||
// Info-ZIP releases--including, but not limited to, labeling of the
|
||||
// altered versions with the names "Info-ZIP" (or any variation thereof,
|
||||
// including, but not limited to, different capitalizations),
|
||||
// "Pocket UnZip", "WiZ" or "MacZip" without the explicit permission of
|
||||
// Info-ZIP. Such altered versions are further prohibited from
|
||||
// misrepresentative use of the Zip-Bugs or Info-ZIP e-mail addresses or
|
||||
// of the Info-ZIP URL(s).
|
||||
//
|
||||
// 4. Info-ZIP retains the right to use the names "Info-ZIP", "Zip", "UnZip",
|
||||
// "UnZipSFX", "WiZ", "Pocket UnZip", "Pocket Zip", and "MacZip" for its
|
||||
// own source and binary releases.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef XZIP_H
|
||||
#define XZIP_H
|
||||
|
||||
// ZIP functions -- for creating zip files
|
||||
// This file is a repackaged form of the Info-Zip source code available
|
||||
// at www.info-zip.org. The original copyright notice may be found in
|
||||
// zip.cpp. The repackaging was done by Lucian Wischik to simplify its
|
||||
// use in Windows/C++.
|
||||
|
||||
#ifndef XUNZIP_H
|
||||
DECLARE_HANDLE(HZIP); // An HZIP identifies a zip file that is being created
|
||||
#endif
|
||||
|
||||
typedef DWORD ZRESULT; // result codes from any of the zip functions. Listed later.
|
||||
|
||||
// flag values passed to some functions
|
||||
#define ZIP_HANDLE 1
|
||||
#define ZIP_FILENAME 2
|
||||
#define ZIP_MEMORY 3
|
||||
#define ZIP_FOLDER 4
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// CreateZip()
|
||||
//
|
||||
// Purpose: Create a zip archive file
|
||||
//
|
||||
// Parameters: z - archive file name if flags is ZIP_FILENAME; for other
|
||||
// uses see below
|
||||
// len - for memory (ZIP_MEMORY) should be the buffer size;
|
||||
// for other uses, should be 0
|
||||
// flags - indicates usage, see below; for files, this will be
|
||||
// ZIP_FILENAME
|
||||
//
|
||||
// Returns: HZIP - non-zero if zip archive created ok, otherwise 0
|
||||
//
|
||||
HZIP CreateZip(void *z, unsigned int len, DWORD flags);
|
||||
// CreateZip - call this to start the creation of a zip file.
|
||||
// As the zip is being created, it will be stored somewhere:
|
||||
// to a pipe: CreateZip(hpipe_write, 0,ZIP_HANDLE);
|
||||
// in a file (by handle): CreateZip(hfile, 0,ZIP_HANDLE);
|
||||
// in a file (by name): CreateZip("c:\\test.zip", 0,ZIP_FILENAME);
|
||||
// in memory: CreateZip(buf, len,ZIP_MEMORY);
|
||||
// or in pagefile memory: CreateZip(0, len,ZIP_MEMORY);
|
||||
// The final case stores it in memory backed by the system paging file,
|
||||
// where the zip may not exceed len bytes. This is a bit friendlier than
|
||||
// allocating memory with new[]: it won't lead to fragmentation, and the
|
||||
// memory won't be touched unless needed.
|
||||
// Note: because pipes don't allow random access, the structure of a zipfile
|
||||
// created into a pipe is slightly different from that created into a file
|
||||
// or memory. In particular, the compressed-size of the item cannot be
|
||||
// stored in the zipfile until after the item itself. (Also, for an item added
|
||||
// itself via a pipe, the uncompressed-size might not either be known until
|
||||
// after.) This is not normally a problem. But if you try to unzip via a pipe
|
||||
// as well, then the unzipper will not know these things about the item until
|
||||
// after it has been unzipped. Therefore: for unzippers which don't just write
|
||||
// each item to disk or to a pipe, but instead pre-allocate memory space into
|
||||
// which to unzip them, then either you have to create the zip not to a pipe,
|
||||
// or you have to add items not from a pipe, or at least when adding items
|
||||
// from a pipe you have to specify the length.
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// ZipAdd()
|
||||
//
|
||||
// Purpose: Add a file to a zip archive
|
||||
//
|
||||
// Parameters: hz - handle to an open zip archive
|
||||
// dstzn - name used inside the zip archive to identify the file
|
||||
// src - for a file (ZIP_FILENAME) this specifies the filename
|
||||
// to be added to the archive; for other uses, see below
|
||||
// len - for memory (ZIP_MEMORY) this specifies the buffer
|
||||
// length; for other uses, this should be 0
|
||||
// flags - indicates usage, see below; for files, this will be
|
||||
// ZIP_FILENAME
|
||||
//
|
||||
// Returns: ZRESULT - ZR_OK if success, otherwise some other value
|
||||
//
|
||||
ZRESULT ZipAdd(HZIP hz, const TCHAR *dstzn, void *src, unsigned int len, DWORD flags);
|
||||
// ZipAdd - call this for each file to be added to the zip.
|
||||
// dstzn is the name that the file will be stored as in the zip file.
|
||||
// The file to be added to the zip can come
|
||||
// from a pipe: ZipAdd(hz,"file.dat", hpipe_read,0,ZIP_HANDLE);
|
||||
// from a file: ZipAdd(hz,"file.dat", hfile,0,ZIP_HANDLE);
|
||||
// from a fname: ZipAdd(hz,"file.dat", "c:\\docs\\origfile.dat",0,ZIP_FILENAME);
|
||||
// from memory: ZipAdd(hz,"subdir\\file.dat", buf,len,ZIP_MEMORY);
|
||||
// (folder): ZipAdd(hz,"subdir", 0,0,ZIP_FOLDER);
|
||||
// Note: if adding an item from a pipe, and if also creating the zip file itself
|
||||
// to a pipe, then you might wish to pass a non-zero length to the ZipAdd
|
||||
// function. This will let the zipfile store the items size ahead of the
|
||||
// compressed item itself, which in turn makes it easier when unzipping the
|
||||
// zipfile into a pipe.
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// CloseZip()
|
||||
//
|
||||
// Purpose: Close an open zip archive
|
||||
//
|
||||
// Parameters: hz - handle to an open zip archive
|
||||
//
|
||||
// Returns: ZRESULT - ZR_OK if success, otherwise some other value
|
||||
//
|
||||
ZRESULT CloseZip(HZIP hz);
|
||||
// CloseZip - the zip handle must be closed with this function.
|
||||
|
||||
|
||||
ZRESULT ZipGetMemory(HZIP hz, void **buf, unsigned long *len);
|
||||
// ZipGetMemory - If the zip was created in memory, via ZipCreate(0,ZIP_MEMORY),
|
||||
// then this function will return information about that memory block.
|
||||
// buf will receive a pointer to its start, and len its length.
|
||||
// Note: you can't add any more after calling this.
|
||||
|
||||
|
||||
unsigned int FormatZipMessage(ZRESULT code, char *buf,unsigned int len);
|
||||
// FormatZipMessage - given an error code, formats it as a string.
|
||||
// It returns the length of the error message. If buf/len points
|
||||
// to a real buffer, then it also writes as much as possible into there.
|
||||
|
||||
|
||||
|
||||
// These are the result codes:
|
||||
#define ZR_OK 0x00000000 // nb. the pseudo-code zr-recent is never returned,
|
||||
#define ZR_RECENT 0x00000001 // but can be passed to FormatZipMessage.
|
||||
// The following come from general system stuff (e.g. files not openable)
|
||||
#define ZR_GENMASK 0x0000FF00
|
||||
#define ZR_NODUPH 0x00000100 // couldn't duplicate the handle
|
||||
#define ZR_NOFILE 0x00000200 // couldn't create/open the file
|
||||
#define ZR_NOALLOC 0x00000300 // failed to allocate some resource
|
||||
#define ZR_WRITE 0x00000400 // a general error writing to the file
|
||||
#define ZR_NOTFOUND 0x00000500 // couldn't find that file in the zip
|
||||
#define ZR_MORE 0x00000600 // there's still more data to be unzipped
|
||||
#define ZR_CORRUPT 0x00000700 // the zipfile is corrupt or not a zipfile
|
||||
#define ZR_READ 0x00000800 // a general error reading the file
|
||||
// The following come from mistakes on the part of the caller
|
||||
#define ZR_CALLERMASK 0x00FF0000
|
||||
#define ZR_ARGS 0x00010000 // general mistake with the arguments
|
||||
#define ZR_NOTMMAP 0x00020000 // tried to ZipGetMemory, but that only works on mmap zipfiles, which yours wasn't
|
||||
#define ZR_MEMSIZE 0x00030000 // the memory size is too small
|
||||
#define ZR_FAILED 0x00040000 // the thing was already failed when you called this function
|
||||
#define ZR_ENDED 0x00050000 // the zip creation has already been closed
|
||||
#define ZR_MISSIZE 0x00060000 // the indicated input file size turned out mistaken
|
||||
#define ZR_PARTIALUNZ 0x00070000 // the file had already been partially unzipped
|
||||
#define ZR_ZMODE 0x00080000 // tried to mix creating/opening a zip
|
||||
// The following come from bugs within the zip library itself
|
||||
#define ZR_BUGMASK 0xFF000000
|
||||
#define ZR_NOTINITED 0x01000000 // initialisation didn't work
|
||||
#define ZR_SEEK 0x02000000 // trying to seek in an unseekable file
|
||||
#define ZR_NOCHANGE 0x04000000 // changed its mind on storage, but not allowed
|
||||
#define ZR_FLATE 0x05000000 // an internal error in the de/inflation code
|
||||
|
||||
|
||||
|
||||
// e.g.
|
||||
//
|
||||
// (1) Traditional use, creating a zipfile from existing files
|
||||
// HZIP hz = CreateZip("c:\\temp.zip",0,ZIP_FILENAME);
|
||||
// ZipAdd(hz,"src1.txt", "c:\\src1.txt",0,ZIP_FILENAME);
|
||||
// ZipAdd(hz,"src2.bmp", "c:\\src2_origfn.bmp",0,ZIP_FILENAME);
|
||||
// CloseZip(hz);
|
||||
//
|
||||
// (2) Memory use, creating an auto-allocated mem-based zip file from various sources
|
||||
// HZIP hz = CreateZip(0,100000,ZIP_MEMORY);
|
||||
// // adding a conventional file...
|
||||
// ZipAdd(hz,"src1.txt", "c:\\src1.txt",0,ZIP_FILENAME);
|
||||
// // adding something from memory...
|
||||
// char buf[1000]; for (int i=0; i<1000; i++) buf[i]=(char)(i&0x7F);
|
||||
// ZipAdd(hz,"file.dat", buf,1000,ZIP_MEMORY);
|
||||
// // adding something from a pipe...
|
||||
// HANDLE hread,hwrite; CreatePipe(&hread,&write,NULL,0);
|
||||
// HANDLE hthread = CreateThread(ThreadFunc,(void*)hwrite);
|
||||
// ZipAdd(hz,"unz3.dat", hread,0,ZIP_HANDLE);
|
||||
// WaitForSingleObject(hthread,INFINITE);
|
||||
// CloseHandle(hthread); CloseHandle(hread);
|
||||
// ... meanwhile DWORD CALLBACK ThreadFunc(void *dat)
|
||||
// { HANDLE hwrite = (HANDLE)dat;
|
||||
// char buf[1000]={17};
|
||||
// DWORD writ; WriteFile(hwrite,buf,1000,&writ,NULL);
|
||||
// CloseHandle(hwrite);
|
||||
// return 0;
|
||||
// }
|
||||
// // and now that the zip is created, let's do something with it:
|
||||
// void *zbuf; unsigned long zlen; ZipGetMemory(hz,&zbuf,&zlen);
|
||||
// HANDLE hfz = CreateFile("test2.zip",GENERIC_WRITE,CREATE_ALWAYS);
|
||||
// DWORD writ; WriteFile(hfz,zbuf,zlen,&writ,NULL);
|
||||
// CloseHandle(hfz);
|
||||
// CloseZip(hz);
|
||||
//
|
||||
// (3) Handle use, for file handles and pipes
|
||||
// HANDLE hzread,hzwrite; CreatePipe(&hzread,&hzwrite);
|
||||
// HANDLE hthread = CreateThread(ZipReceiverThread,(void*)hread);
|
||||
// HZIP hz = ZipCreate(hzwrite,ZIP_HANDLE);
|
||||
// // ... add to it
|
||||
// CloseZip(hz);
|
||||
// CloseHandle(hzwrite);
|
||||
// WaitForSingleObject(hthread,INFINITE);
|
||||
// CloseHandle(hthread);
|
||||
// ... meanwhile DWORD CALLBACK ThreadFunc(void *dat)
|
||||
// { HANDLE hread = (HANDLE)dat;
|
||||
// char buf[1000];
|
||||
// while (true)
|
||||
// { DWORD red; ReadFile(hread,buf,1000,&red,NULL);
|
||||
// // ... and do something with this zip data we're receiving
|
||||
// if (red==0) break;
|
||||
// }
|
||||
// CloseHandle(hread);
|
||||
// return 0;
|
||||
// }
|
||||
//
|
||||
|
||||
|
||||
// Now we indulge in a little skullduggery so that the code works whether
|
||||
// the user has included just zip or both zip and unzip.
|
||||
// Idea: if header files for both zip and unzip are present, then presumably
|
||||
// the cpp files for zip and unzip are both present, so we will call
|
||||
// one or the other of them based on a dynamic choice. If the header file
|
||||
// for only one is present, then we will bind to that particular one.
|
||||
HZIP CreateZipZ(void *z,unsigned int len,DWORD flags);
|
||||
ZRESULT CloseZipZ(HZIP hz);
|
||||
unsigned int FormatZipMessageZ(ZRESULT code, char *buf,unsigned int len);
|
||||
bool IsZipHandleZ(HZIP hz);
|
||||
BOOL AddFolderContent(HZIP hZip, TCHAR* AbsolutePath, TCHAR* DirToAdd);
|
||||
|
||||
#define CreateZip CreateZipZ
|
||||
|
||||
#ifdef XUNZIP_H
|
||||
#undef CloseZip
|
||||
#define CloseZip(hz) (IsZipHandleZ(hz)?CloseZipZ(hz):CloseZipU(hz))
|
||||
#else
|
||||
#define CloseZip CloseZipZ
|
||||
#define FormatZipMessage FormatZipMessageZ
|
||||
#endif
|
||||
|
||||
|
||||
#endif //XZIP_H
|
||||
31
src/Common/libzip/LICENSE
Normal file
31
src/Common/libzip/LICENSE
Normal file
@@ -0,0 +1,31 @@
|
||||
Copyright (C) 1999-2016 Dieter Baron and Thomas Klausner
|
||||
|
||||
The authors can be contacted at <libzip@nih.at>
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
3. The names of the authors may not be used to endorse or promote
|
||||
products derived from this software without specific prior
|
||||
written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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.
|
||||
159
src/Common/libzip/NEWS.md
Normal file
159
src/Common/libzip/NEWS.md
Normal file
@@ -0,0 +1,159 @@
|
||||
1.1.3 [2016-05-28]
|
||||
==================
|
||||
|
||||
* Fix build on Windows when using autoconf.
|
||||
|
||||
1.1.2 [2016-02-19]
|
||||
==================
|
||||
|
||||
* Improve support for 3MF files
|
||||
|
||||
1.1.1 [2016-02-07]
|
||||
==================
|
||||
|
||||
* Build fixes for Linux
|
||||
* Fix some warnings reported by PVS-Studio
|
||||
|
||||
1.1 [2016-01-26]
|
||||
================
|
||||
|
||||
* ziptool(1): command line tool to modify zip archives
|
||||
* Speedups for archives with many entries
|
||||
* Coverity fixes
|
||||
* Better APK support
|
||||
* Support for running tests on Windows
|
||||
* More build fixes for Windows
|
||||
* Portability fixes
|
||||
* Documentation improvements
|
||||
|
||||
1.0.1 [2015-05-04]
|
||||
==================
|
||||
|
||||
* Build fixes for Windows.
|
||||
|
||||
1.0 [2015-05-03]
|
||||
================
|
||||
|
||||
* Implemented an I/O abstraction layer.
|
||||
* Added support for native Windows API for files.
|
||||
* Added support for setting the last modification time for a file.
|
||||
* Added a new type zip_error_t for errors.
|
||||
* Added more typedefs for structs.
|
||||
* Torrentzip support was removed.
|
||||
* CVE-2015-2331 was fixed.
|
||||
* Addressed all Coverity CIDs.
|
||||
|
||||
0.11.2 [2013-12-19]
|
||||
===================
|
||||
|
||||
* Support querying/setting operating system and external attributes.
|
||||
* For newly added files, set operating system to UNIX, permissions
|
||||
to 0666 (0777 for directories).
|
||||
* Fix bug when writing zip archives containing files bigger than 4GB.
|
||||
|
||||
0.11.1 [2013-04-27]
|
||||
===================
|
||||
|
||||
* Fix bugs in zip_set_file_compression().
|
||||
* Include Xcode build infrastructure.
|
||||
|
||||
0.11 [2013-03-23]
|
||||
=================
|
||||
|
||||
* Added Zip64 support (large file support)
|
||||
* Added UTF-8 support for file names, file comments, and archive comments
|
||||
* Changed API for name and comment related functions for UTF-8 support
|
||||
* Added zip_discard()
|
||||
* Added ZIP_TRUNCATE for zip_open()
|
||||
* Added zip_set_file_compression()
|
||||
* Added API for accessing and modifying extra fields
|
||||
* Improved API type consistency
|
||||
* Use gcc4's visibility __attribute__
|
||||
* More changes for Windows support
|
||||
* Additional test cases
|
||||
|
||||
0.10.1 [2012-03-20]
|
||||
===================
|
||||
|
||||
* Fixed CVE-2012-1162
|
||||
* Fixed CVE-2012-1163
|
||||
|
||||
0.10 [2010-03-18]
|
||||
=================
|
||||
|
||||
* Added zip_get_num_entries(), deprecated zip_get_num_files().
|
||||
* Better windows support.
|
||||
* Support for traditional PKWARE encryption added.
|
||||
* Fix opening archives with more than 65535 entries.
|
||||
* Fix some memory leaks.
|
||||
* Fix cmake build and installation
|
||||
* Fix memory leak in error case in zip_open()
|
||||
* Fixed CVE-2011-0421 (no security implications though)
|
||||
* More documentation.
|
||||
|
||||
0.9.3 [2010-02-01]
|
||||
==================
|
||||
|
||||
* Include m4/ directory in distribution; some packagers need it.
|
||||
|
||||
0.9.2 [2010-01-31]
|
||||
==================
|
||||
|
||||
* Avoid passing uninitialized data to deflate().
|
||||
* Fix memory leak when closing zip archives.
|
||||
|
||||
0.9.1 [2010-01-24]
|
||||
==================
|
||||
|
||||
* Fix infinite loop on reading some broken files.
|
||||
* Optimization in time conversion (don't call localtime()).
|
||||
* Clear data descriptor flag in central directory, fixing Open Office files.
|
||||
* Allow more than 64k entries.
|
||||
|
||||
0.9 [2008-07-25]
|
||||
==================
|
||||
|
||||
* on Windows, explictly set dllimport/dllexport
|
||||
* remove erroneous references to GPL
|
||||
* add support for torrentzip
|
||||
* new functions: zip_get_archive_flag, zip_set_archive_flag
|
||||
* zip_source_zip: add flag to force recompression
|
||||
* zip_sorce_file: only keep file open while reading from it
|
||||
|
||||
0.8 [2007-06-06]
|
||||
==================
|
||||
|
||||
* fix for zip archives larger than 2GiB
|
||||
* fix zip_error_strerror to include libzip error string
|
||||
* add support for reading streamed zip files
|
||||
* new functions: zip_add_dir, zip_error_clear, zip_file_error_clear
|
||||
* add basic support for building with CMake (incomplete)
|
||||
|
||||
0.7.1 [2006-05-18]
|
||||
==================
|
||||
|
||||
* bugfix for zip_close
|
||||
|
||||
0.7 [2006-05-06]
|
||||
================
|
||||
|
||||
* struct zip_stat increased for future encryption support
|
||||
* zip_add return value changed (now returns new index of added file)
|
||||
* shared library major bump because of previous two
|
||||
* added functions for reading and writing file and archive comments.
|
||||
New functions: zip_get_archive_comment, zip_get_file_comment,
|
||||
zip_set_archive_comment, zip_set_file_comment, zip_unchange_archive
|
||||
|
||||
0.6.1 [2005-07-14]
|
||||
==================
|
||||
|
||||
* various bug fixes
|
||||
|
||||
0.6 [2005-06-09]
|
||||
================
|
||||
|
||||
* first standalone release
|
||||
* changed license to three-clause BSD
|
||||
* overhauled API
|
||||
* added man pages
|
||||
* install zipcmp and zipmerge
|
||||
181
src/Common/libzip/compat.h
Normal file
181
src/Common/libzip/compat.h
Normal file
@@ -0,0 +1,181 @@
|
||||
#ifndef _HAD_LIBZIP_COMPAT_H
|
||||
#define _HAD_LIBZIP_COMPAT_H
|
||||
|
||||
/*
|
||||
compat.h -- compatibility defines.
|
||||
Copyright (C) 1999-2016 Dieter Baron and Thomas Klausner
|
||||
|
||||
This file is part of libzip, a library to manipulate ZIP archives.
|
||||
The authors can be contacted at <libzip@nih.at>
|
||||
|
||||
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.
|
||||
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.
|
||||
3. The names of the authors may not be used to endorse or promote
|
||||
products derived from this software without specific prior
|
||||
written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
/* to have *_MAX definitions for all types when compiling with g++ */
|
||||
#define __STDC_LIMIT_MACROS
|
||||
|
||||
#ifdef _WIN32
|
||||
#define ZIP_EXTERN __declspec(dllexport)
|
||||
/* for dup(), close(), etc. */
|
||||
#include <io.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_STDBOOL_H
|
||||
#include <stdbool.h>
|
||||
#else
|
||||
typedef char bool;
|
||||
#define true 1
|
||||
#define false 0
|
||||
#endif
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
/* at least MinGW does not provide EOPNOTSUPP, see
|
||||
* http://sourceforge.net/p/mingw/bugs/263/
|
||||
*/
|
||||
#ifndef EOPNOTSUPP
|
||||
#define EOPNOTSUPP EINVAL
|
||||
#endif
|
||||
|
||||
/* at least MinGW does not provide EOVERFLOW, see
|
||||
* http://sourceforge.net/p/mingw/bugs/242/
|
||||
*/
|
||||
#ifndef EOVERFLOW
|
||||
#define EOVERFLOW EFBIG
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
#if defined(HAVE__CLOSE)
|
||||
#define close _close
|
||||
#endif
|
||||
#if defined(HAVE__DUP)
|
||||
#define dup _dup
|
||||
#endif
|
||||
/* crashes reported when using fdopen instead of _fdopen on Windows/Visual Studio 10/Win64 */
|
||||
#if defined(HAVE__FDOPEN)
|
||||
#define fdopen _fdopen
|
||||
#endif
|
||||
#if !defined(HAVE_FILENO) && defined(HAVE__FILENO)
|
||||
#define fileno _fileno
|
||||
#endif
|
||||
/* Windows' open() doesn't understand Unix permissions */
|
||||
#if defined(HAVE__OPEN)
|
||||
#define open(a, b, c) _open((a), (b))
|
||||
#endif
|
||||
#if defined(HAVE__SNPRINTF)
|
||||
#define snprintf _snprintf
|
||||
#endif
|
||||
#if defined(HAVE__STRDUP)
|
||||
#if !defined(HAVE_STRDUP) || defined(_WIN32)
|
||||
#undef strdup
|
||||
#define strdup _strdup
|
||||
#endif
|
||||
#endif
|
||||
#if !defined(HAVE__SETMODE) && defined(HAVE_SETMODE)
|
||||
#define _setmode setmode
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_FSEEKO
|
||||
#define fseeko(s, o, w) (fseek((s), (long int)(o), (w)))
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_FTELLO
|
||||
#define ftello(s) ((long)ftell((s)))
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_MKSTEMP
|
||||
int _zip_mkstemp(char *);
|
||||
#define mkstemp _zip_mkstemp
|
||||
#endif
|
||||
|
||||
#if !defined(HAVE_STRCASECMP)
|
||||
#if defined(HAVE__STRICMP)
|
||||
#define strcasecmp _stricmp
|
||||
#elif defined(HAVE_STRICMP)
|
||||
#define strcasecmp stricmp
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if SIZEOF_OFF_T == 8
|
||||
#define ZIP_OFF_MAX ZIP_INT64_MAX
|
||||
#define ZIP_OFF_MIN ZIP_INT64_MIN
|
||||
#elif SIZEOF_OFF_T == 4
|
||||
#define ZIP_OFF_MAX ZIP_INT32_MAX
|
||||
#define ZIP_OFF_MIN ZIP_INT32_MIN
|
||||
#elif SIZEOF_OFF_T == 2
|
||||
#define ZIP_OFF_MAX ZIP_INT16_MAX
|
||||
#define ZIP_OFF_MIN ZIP_INT16_MIN
|
||||
#else
|
||||
#error unsupported size of off_t
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_FTELLO) && defined(HAVE_FSEEKO)
|
||||
#define ZIP_FSEEK_MAX ZIP_OFF_MAX
|
||||
#define ZIP_FSEEK_MIN ZIP_OFF_MIN
|
||||
#else
|
||||
#include <limits.h>
|
||||
#define ZIP_FSEEK_MAX LONG_MAX
|
||||
#define ZIP_FSEEK_MIN LONG_MIN
|
||||
#endif
|
||||
|
||||
#ifndef SIZE_MAX
|
||||
#if SIZEOF_SIZE_T == 8
|
||||
#define SIZE_MAX ZIP_INT64_MAX
|
||||
#elif SIZEOF_SIZE_T == 4
|
||||
#define SIZE_MAX ZIP_INT32_MAX
|
||||
#elif SIZEOF_SIZE_T == 2
|
||||
#define SIZE_MAX ZIP_INT16_MAX
|
||||
#else
|
||||
#error unsupported size of size_t
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef PRId64
|
||||
#ifdef _MSC_VER
|
||||
#define PRId64 "I64d"
|
||||
#else
|
||||
#define PRId64 "lld"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef PRIu64
|
||||
#ifdef _MSC_VER
|
||||
#define PRIu64 "I64u"
|
||||
#else
|
||||
#define PRIu64 "llu"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef S_ISDIR
|
||||
#define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR)
|
||||
#endif
|
||||
|
||||
#endif /* compat.h */
|
||||
72
src/Common/libzip/config.h
Normal file
72
src/Common/libzip/config.h
Normal file
@@ -0,0 +1,72 @@
|
||||
#ifndef HAD_CONFIG_H
|
||||
#define HAD_CONFIG_H
|
||||
#ifndef _HAD_ZIPCONF_H
|
||||
#include "zipconf.h"
|
||||
#endif
|
||||
/* BEGIN DEFINES */
|
||||
/* #undef HAVE___PROGNAME */
|
||||
#define HAVE__CLOSE
|
||||
#define HAVE__DUP
|
||||
#define HAVE__FDOPEN
|
||||
#define HAVE__FILENO
|
||||
#define HAVE__OPEN
|
||||
#define HAVE__SETMODE
|
||||
#define HAVE__SNPRINTF
|
||||
#define HAVE__STRDUP
|
||||
#define HAVE__STRICMP
|
||||
#define HAVE_FILENO
|
||||
/* #undef HAVE_FSEEKO */
|
||||
/* #undef HAVE_FTELLO */
|
||||
/* #undef HAVE_GETPROGNAME */
|
||||
#define HAVE_OPEN
|
||||
/* #undef HAVE_MKSTEMP */
|
||||
#define HAVE_SETMODE
|
||||
/* #undef HAVE_SNPRINTF */
|
||||
/* #undef HAVE_SSIZE_T_LIBZIP */
|
||||
/* #undef HAVE_STRCASECMP */
|
||||
#define HAVE_STRDUP
|
||||
#define HAVE_STRICMP
|
||||
/* #undef HAVE_STRUCT_TM_TM_ZONE */
|
||||
/* #undef HAVE_STDBOOL_H */
|
||||
/* #undef HAVE_STRINGS_H */
|
||||
/* #undef HAVE_UNISTD_H */
|
||||
#define __INT8_LIBZIP 1
|
||||
#define INT8_T_LIBZIP 1
|
||||
#define UINT8_T_LIBZIP 1
|
||||
#define __INT16_LIBZIP 2
|
||||
#define INT16_T_LIBZIP 2
|
||||
#define UINT16_T_LIBZIP 2
|
||||
#define __INT32_LIBZIP 4
|
||||
#define INT32_T_LIBZIP 4
|
||||
#define UINT32_T_LIBZIP 4
|
||||
#define __INT64_LIBZIP 8
|
||||
#define INT64_T_LIBZIP 8
|
||||
#define UINT64_T_LIBZIP 8
|
||||
#define SIZEOF_OFF_T 4
|
||||
#ifdef _WIN64
|
||||
#define SIZE_T_LIBZIP 8
|
||||
#else
|
||||
#define SIZE_T_LIBZIP 4
|
||||
#endif
|
||||
/* #undef SSIZE_T_LIBZIP */
|
||||
/* #undef HAVE_DIRENT_H */
|
||||
/* #undef HAVE_NDIR_H */
|
||||
/* #undef HAVE_SYS_DIR_H */
|
||||
/* #undef HAVE_SYS_NDIR_H */
|
||||
/* END DEFINES */
|
||||
#define PACKAGE "libzip"
|
||||
#define VERSION "1.1.3"
|
||||
|
||||
#ifndef HAVE_SSIZE_T_LIBZIP
|
||||
# if SIZE_T_LIBZIP == INT_LIBZIP
|
||||
typedef int ssize_t;
|
||||
# elif SIZE_T_LIBZIP == LONG_LIBZIP
|
||||
typedef long ssize_t;
|
||||
# elif SIZE_T_LIBZIP == LONG_LONG_LIBZIP
|
||||
typedef long long ssize_t;
|
||||
# else
|
||||
#error no suitable type for ssize_t found
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#endif /* HAD_CONFIG_H */
|
||||
150
src/Common/libzip/mkstemp.c
Normal file
150
src/Common/libzip/mkstemp.c
Normal file
@@ -0,0 +1,150 @@
|
||||
/* Adapted from NetBSB libc by Dieter Baron */
|
||||
|
||||
/* NetBSD: gettemp.c,v 1.13 2003/12/05 00:57:36 uebayasi Exp */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1987, 1993
|
||||
* The Regents of the University of California. 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.
|
||||
* 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.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#ifdef _WIN32
|
||||
#include <io.h>
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifndef O_BINARY
|
||||
#define O_BINARY 0
|
||||
#endif
|
||||
|
||||
|
||||
int
|
||||
_zip_mkstemp(char *path)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
int ret;
|
||||
ret = _creat(_mktemp(path), _S_IREAD|_S_IWRITE);
|
||||
if (ret == -1) {
|
||||
return 0;
|
||||
} else {
|
||||
return ret;
|
||||
}
|
||||
#else
|
||||
int fd;
|
||||
char *start, *trv;
|
||||
struct stat sbuf;
|
||||
pid_t pid;
|
||||
|
||||
/* To guarantee multiple calls generate unique names even if
|
||||
the file is not created. 676 different possibilities with 7
|
||||
or more X's, 26 with 6 or less. */
|
||||
static char xtra[2] = "aa";
|
||||
int xcnt = 0;
|
||||
|
||||
pid = getpid();
|
||||
|
||||
/* Move to end of path and count trailing X's. */
|
||||
for (trv = path; *trv; ++trv)
|
||||
if (*trv == 'X')
|
||||
xcnt++;
|
||||
else
|
||||
xcnt = 0;
|
||||
|
||||
/* Use at least one from xtra. Use 2 if more than 6 X's. */
|
||||
if (*(trv - 1) == 'X')
|
||||
*--trv = xtra[0];
|
||||
if (xcnt > 6 && *(trv - 1) == 'X')
|
||||
*--trv = xtra[1];
|
||||
|
||||
/* Set remaining X's to pid digits with 0's to the left. */
|
||||
while (*--trv == 'X') {
|
||||
*trv = (pid % 10) + '0';
|
||||
pid /= 10;
|
||||
}
|
||||
|
||||
/* update xtra for next call. */
|
||||
if (xtra[0] != 'z')
|
||||
xtra[0]++;
|
||||
else {
|
||||
xtra[0] = 'a';
|
||||
if (xtra[1] != 'z')
|
||||
xtra[1]++;
|
||||
else
|
||||
xtra[1] = 'a';
|
||||
}
|
||||
|
||||
/*
|
||||
* check the target directory; if you have six X's and it
|
||||
* doesn't exist this runs for a *very* long time.
|
||||
*/
|
||||
for (start = trv + 1;; --trv) {
|
||||
if (trv <= path)
|
||||
break;
|
||||
if (*trv == '/') {
|
||||
*trv = '\0';
|
||||
if (stat(path, &sbuf))
|
||||
return (0);
|
||||
if (!S_ISDIR(sbuf.st_mode)) {
|
||||
errno = ENOTDIR;
|
||||
return (0);
|
||||
}
|
||||
*trv = '/';
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
if ((fd=open(path, O_CREAT|O_EXCL|O_RDWR|O_BINARY, 0600)) >= 0)
|
||||
return (fd);
|
||||
if (errno != EEXIST)
|
||||
return (0);
|
||||
|
||||
/* tricky little algorithm for backward compatibility */
|
||||
for (trv = start;;) {
|
||||
if (!*trv)
|
||||
return (0);
|
||||
if (*trv == 'z')
|
||||
*trv++ = 'a';
|
||||
else {
|
||||
if (isdigit((unsigned char)*trv))
|
||||
*trv = 'a';
|
||||
else
|
||||
++*trv;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
/*NOTREACHED*/
|
||||
#endif
|
||||
}
|
||||
422
src/Common/libzip/zip.h
Normal file
422
src/Common/libzip/zip.h
Normal file
@@ -0,0 +1,422 @@
|
||||
#ifndef _HAD_ZIP_H
|
||||
#define _HAD_ZIP_H
|
||||
|
||||
/*
|
||||
zip.h -- exported declarations.
|
||||
Copyright (C) 1999-2015 Dieter Baron and Thomas Klausner
|
||||
|
||||
This file is part of libzip, a library to manipulate ZIP archives.
|
||||
The authors can be contacted at <libzip@nih.at>
|
||||
|
||||
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.
|
||||
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.
|
||||
3. The names of the authors may not be used to endorse or promote
|
||||
products derived from this software without specific prior
|
||||
written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef ZIP_EXTERN
|
||||
# ifndef ZIP_STATIC
|
||||
# ifdef _WIN32
|
||||
# define ZIP_EXTERN __declspec(dllimport)
|
||||
# elif defined(__GNUC__) && __GNUC__ >= 4
|
||||
# define ZIP_EXTERN __attribute__ ((visibility ("default")))
|
||||
# else
|
||||
# define ZIP_EXTERN
|
||||
# endif
|
||||
# else
|
||||
# define ZIP_EXTERN
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#if 0
|
||||
} /* fix autoindent */
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <zipconf.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
|
||||
/* flags for zip_open */
|
||||
|
||||
#define ZIP_CREATE 1
|
||||
#define ZIP_EXCL 2
|
||||
#define ZIP_CHECKCONS 4
|
||||
#define ZIP_TRUNCATE 8
|
||||
#define ZIP_RDONLY 16
|
||||
|
||||
|
||||
/* flags for zip_name_locate, zip_fopen, zip_stat, ... */
|
||||
|
||||
#define ZIP_FL_NOCASE 1u /* ignore case on name lookup */
|
||||
#define ZIP_FL_NODIR 2u /* ignore directory component */
|
||||
#define ZIP_FL_COMPRESSED 4u /* read compressed data */
|
||||
#define ZIP_FL_UNCHANGED 8u /* use original data, ignoring changes */
|
||||
#define ZIP_FL_RECOMPRESS 16u /* force recompression of data */
|
||||
#define ZIP_FL_ENCRYPTED 32u /* read encrypted data (implies ZIP_FL_COMPRESSED) */
|
||||
#define ZIP_FL_ENC_GUESS 0u /* guess string encoding (is default) */
|
||||
#define ZIP_FL_ENC_RAW 64u /* get unmodified string */
|
||||
#define ZIP_FL_ENC_STRICT 128u /* follow specification strictly */
|
||||
#define ZIP_FL_LOCAL 256u /* in local header */
|
||||
#define ZIP_FL_CENTRAL 512u /* in central directory */
|
||||
/* 1024u reserved for internal use */
|
||||
#define ZIP_FL_ENC_UTF_8 2048u /* string is UTF-8 encoded */
|
||||
#define ZIP_FL_ENC_CP437 4096u /* string is CP437 encoded */
|
||||
#define ZIP_FL_OVERWRITE 8192u /* zip_file_add: if file with name exists, overwrite (replace) it */
|
||||
|
||||
/* archive global flags flags */
|
||||
|
||||
#define ZIP_AFL_RDONLY 2u /* read only -- cannot be cleared */
|
||||
|
||||
|
||||
/* create a new extra field */
|
||||
|
||||
#define ZIP_EXTRA_FIELD_ALL ZIP_UINT16_MAX
|
||||
#define ZIP_EXTRA_FIELD_NEW ZIP_UINT16_MAX
|
||||
|
||||
|
||||
/* libzip error codes */
|
||||
|
||||
#define ZIP_ER_OK 0 /* N No error */
|
||||
#define ZIP_ER_MULTIDISK 1 /* N Multi-disk zip archives not supported */
|
||||
#define ZIP_ER_RENAME 2 /* S Renaming temporary file failed */
|
||||
#define ZIP_ER_CLOSE 3 /* S Closing zip archive failed */
|
||||
#define ZIP_ER_SEEK 4 /* S Seek error */
|
||||
#define ZIP_ER_READ 5 /* S Read error */
|
||||
#define ZIP_ER_WRITE 6 /* S Write error */
|
||||
#define ZIP_ER_CRC 7 /* N CRC error */
|
||||
#define ZIP_ER_ZIPCLOSED 8 /* N Containing zip archive was closed */
|
||||
#define ZIP_ER_NOENT 9 /* N No such file */
|
||||
#define ZIP_ER_EXISTS 10 /* N File already exists */
|
||||
#define ZIP_ER_OPEN 11 /* S Can't open file */
|
||||
#define ZIP_ER_TMPOPEN 12 /* S Failure to create temporary file */
|
||||
#define ZIP_ER_ZLIB 13 /* Z Zlib error */
|
||||
#define ZIP_ER_MEMORY 14 /* N Malloc failure */
|
||||
#define ZIP_ER_CHANGED 15 /* N Entry has been changed */
|
||||
#define ZIP_ER_COMPNOTSUPP 16 /* N Compression method not supported */
|
||||
#define ZIP_ER_EOF 17 /* N Premature end of file */
|
||||
#define ZIP_ER_INVAL 18 /* N Invalid argument */
|
||||
#define ZIP_ER_NOZIP 19 /* N Not a zip archive */
|
||||
#define ZIP_ER_INTERNAL 20 /* N Internal error */
|
||||
#define ZIP_ER_INCONS 21 /* N Zip archive inconsistent */
|
||||
#define ZIP_ER_REMOVE 22 /* S Can't remove file */
|
||||
#define ZIP_ER_DELETED 23 /* N Entry has been deleted */
|
||||
#define ZIP_ER_ENCRNOTSUPP 24 /* N Encryption method not supported */
|
||||
#define ZIP_ER_RDONLY 25 /* N Read-only archive */
|
||||
#define ZIP_ER_NOPASSWD 26 /* N No password provided */
|
||||
#define ZIP_ER_WRONGPASSWD 27 /* N Wrong password provided */
|
||||
#define ZIP_ER_OPNOTSUPP 28 /* N Operation not supported */
|
||||
#define ZIP_ER_INUSE 29 /* N Resource still in use */
|
||||
#define ZIP_ER_TELL 30 /* S Tell error */
|
||||
|
||||
/* type of system error value */
|
||||
|
||||
#define ZIP_ET_NONE 0 /* sys_err unused */
|
||||
#define ZIP_ET_SYS 1 /* sys_err is errno */
|
||||
#define ZIP_ET_ZLIB 2 /* sys_err is zlib error code */
|
||||
|
||||
/* compression methods */
|
||||
|
||||
#define ZIP_CM_DEFAULT -1 /* better of deflate or store */
|
||||
#define ZIP_CM_STORE 0 /* stored (uncompressed) */
|
||||
#define ZIP_CM_SHRINK 1 /* shrunk */
|
||||
#define ZIP_CM_REDUCE_1 2 /* reduced with factor 1 */
|
||||
#define ZIP_CM_REDUCE_2 3 /* reduced with factor 2 */
|
||||
#define ZIP_CM_REDUCE_3 4 /* reduced with factor 3 */
|
||||
#define ZIP_CM_REDUCE_4 5 /* reduced with factor 4 */
|
||||
#define ZIP_CM_IMPLODE 6 /* imploded */
|
||||
/* 7 - Reserved for Tokenizing compression algorithm */
|
||||
#define ZIP_CM_DEFLATE 8 /* deflated */
|
||||
#define ZIP_CM_DEFLATE64 9 /* deflate64 */
|
||||
#define ZIP_CM_PKWARE_IMPLODE 10 /* PKWARE imploding */
|
||||
/* 11 - Reserved by PKWARE */
|
||||
#define ZIP_CM_BZIP2 12 /* compressed using BZIP2 algorithm */
|
||||
/* 13 - Reserved by PKWARE */
|
||||
#define ZIP_CM_LZMA 14 /* LZMA (EFS) */
|
||||
/* 15-17 - Reserved by PKWARE */
|
||||
#define ZIP_CM_TERSE 18 /* compressed using IBM TERSE (new) */
|
||||
#define ZIP_CM_LZ77 19 /* IBM LZ77 z Architecture (PFS) */
|
||||
#define ZIP_CM_WAVPACK 97 /* WavPack compressed data */
|
||||
#define ZIP_CM_PPMD 98 /* PPMd version I, Rev 1 */
|
||||
|
||||
/* encryption methods */
|
||||
|
||||
#define ZIP_EM_NONE 0 /* not encrypted */
|
||||
#define ZIP_EM_TRAD_PKWARE 1 /* traditional PKWARE encryption */
|
||||
#if 0 /* Strong Encryption Header not parsed yet */
|
||||
#define ZIP_EM_DES 0x6601 /* strong encryption: DES */
|
||||
#define ZIP_EM_RC2_OLD 0x6602 /* strong encryption: RC2, version < 5.2 */
|
||||
#define ZIP_EM_3DES_168 0x6603
|
||||
#define ZIP_EM_3DES_112 0x6609
|
||||
#define ZIP_EM_AES_128 0x660e
|
||||
#define ZIP_EM_AES_192 0x660f
|
||||
#define ZIP_EM_AES_256 0x6610
|
||||
#define ZIP_EM_RC2 0x6702 /* strong encryption: RC2, version >= 5.2 */
|
||||
#define ZIP_EM_RC4 0x6801
|
||||
#endif
|
||||
#define ZIP_EM_UNKNOWN 0xffff /* unknown algorithm */
|
||||
|
||||
#define ZIP_OPSYS_DOS 0x00u
|
||||
#define ZIP_OPSYS_AMIGA 0x01u
|
||||
#define ZIP_OPSYS_OPENVMS 0x02u
|
||||
#define ZIP_OPSYS_UNIX 0x03u
|
||||
#define ZIP_OPSYS_VM_CMS 0x04u
|
||||
#define ZIP_OPSYS_ATARI_ST 0x05u
|
||||
#define ZIP_OPSYS_OS_2 0x06u
|
||||
#define ZIP_OPSYS_MACINTOSH 0x07u
|
||||
#define ZIP_OPSYS_Z_SYSTEM 0x08u
|
||||
#define ZIP_OPSYS_CPM 0x09u
|
||||
#define ZIP_OPSYS_WINDOWS_NTFS 0x0au
|
||||
#define ZIP_OPSYS_MVS 0x0bu
|
||||
#define ZIP_OPSYS_VSE 0x0cu
|
||||
#define ZIP_OPSYS_ACORN_RISC 0x0du
|
||||
#define ZIP_OPSYS_VFAT 0x0eu
|
||||
#define ZIP_OPSYS_ALTERNATE_MVS 0x0fu
|
||||
#define ZIP_OPSYS_BEOS 0x10u
|
||||
#define ZIP_OPSYS_TANDEM 0x11u
|
||||
#define ZIP_OPSYS_OS_400 0x12u
|
||||
#define ZIP_OPSYS_OS_X 0x13u
|
||||
|
||||
#define ZIP_OPSYS_DEFAULT ZIP_OPSYS_UNIX
|
||||
|
||||
|
||||
enum zip_source_cmd {
|
||||
ZIP_SOURCE_OPEN, /* prepare for reading */
|
||||
ZIP_SOURCE_READ, /* read data */
|
||||
ZIP_SOURCE_CLOSE, /* reading is done */
|
||||
ZIP_SOURCE_STAT, /* get meta information */
|
||||
ZIP_SOURCE_ERROR, /* get error information */
|
||||
ZIP_SOURCE_FREE, /* cleanup and free resources */
|
||||
ZIP_SOURCE_SEEK, /* set position for reading */
|
||||
ZIP_SOURCE_TELL, /* get read position */
|
||||
ZIP_SOURCE_BEGIN_WRITE, /* prepare for writing */
|
||||
ZIP_SOURCE_COMMIT_WRITE, /* writing is done */
|
||||
ZIP_SOURCE_ROLLBACK_WRITE, /* discard written changes */
|
||||
ZIP_SOURCE_WRITE, /* write data */
|
||||
ZIP_SOURCE_SEEK_WRITE, /* set position for writing */
|
||||
ZIP_SOURCE_TELL_WRITE, /* get write position */
|
||||
ZIP_SOURCE_SUPPORTS, /* check whether source supports command */
|
||||
ZIP_SOURCE_REMOVE /* remove file */
|
||||
};
|
||||
typedef enum zip_source_cmd zip_source_cmd_t;
|
||||
|
||||
#define ZIP_SOURCE_MAKE_COMMAND_BITMASK(cmd) (1<<(cmd))
|
||||
|
||||
#define ZIP_SOURCE_SUPPORTS_READABLE (ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_OPEN) \
|
||||
| ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_READ) \
|
||||
| ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_CLOSE) \
|
||||
| ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_STAT) \
|
||||
| ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_ERROR) \
|
||||
| ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_FREE))
|
||||
|
||||
#define ZIP_SOURCE_SUPPORTS_SEEKABLE (ZIP_SOURCE_SUPPORTS_READABLE \
|
||||
| ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_SEEK) \
|
||||
| ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_TELL) \
|
||||
| ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_SUPPORTS))
|
||||
|
||||
#define ZIP_SOURCE_SUPPORTS_WRITABLE (ZIP_SOURCE_SUPPORTS_SEEKABLE \
|
||||
| ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_BEGIN_WRITE) \
|
||||
| ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_COMMIT_WRITE) \
|
||||
| ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_ROLLBACK_WRITE) \
|
||||
| ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_WRITE) \
|
||||
| ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_SEEK_WRITE) \
|
||||
| ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_TELL_WRITE) \
|
||||
| ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_REMOVE))
|
||||
|
||||
/* for use by sources */
|
||||
struct zip_source_args_seek {
|
||||
zip_int64_t offset;
|
||||
int whence;
|
||||
};
|
||||
|
||||
typedef struct zip_source_args_seek zip_source_args_seek_t;
|
||||
#define ZIP_SOURCE_GET_ARGS(type, data, len, error) ((len) < sizeof(type) ? zip_error_set((error), ZIP_ER_INVAL, 0), (type *)NULL : (type *)(data))
|
||||
|
||||
|
||||
/* error information */
|
||||
/* use zip_error_*() to access */
|
||||
struct zip_error {
|
||||
int zip_err; /* libzip error code (ZIP_ER_*) */
|
||||
int sys_err; /* copy of errno (E*) or zlib error code */
|
||||
char *str; /* string representation or NULL */
|
||||
};
|
||||
|
||||
#define ZIP_STAT_NAME 0x0001u
|
||||
#define ZIP_STAT_INDEX 0x0002u
|
||||
#define ZIP_STAT_SIZE 0x0004u
|
||||
#define ZIP_STAT_COMP_SIZE 0x0008u
|
||||
#define ZIP_STAT_MTIME 0x0010u
|
||||
#define ZIP_STAT_CRC 0x0020u
|
||||
#define ZIP_STAT_COMP_METHOD 0x0040u
|
||||
#define ZIP_STAT_ENCRYPTION_METHOD 0x0080u
|
||||
#define ZIP_STAT_FLAGS 0x0100u
|
||||
|
||||
struct zip_stat {
|
||||
zip_uint64_t valid; /* which fields have valid values */
|
||||
const char *name; /* name of the file */
|
||||
zip_uint64_t index; /* index within archive */
|
||||
zip_uint64_t size; /* size of file (uncompressed) */
|
||||
zip_uint64_t comp_size; /* size of file (compressed) */
|
||||
time_t mtime; /* modification time */
|
||||
zip_uint32_t crc; /* crc of file data */
|
||||
zip_uint16_t comp_method; /* compression method used */
|
||||
zip_uint16_t encryption_method; /* encryption method used */
|
||||
zip_uint32_t flags; /* reserved for future use */
|
||||
};
|
||||
|
||||
struct zip;
|
||||
struct zip_file;
|
||||
struct zip_source;
|
||||
|
||||
typedef struct zip zip_t;
|
||||
typedef struct zip_error zip_error_t;
|
||||
typedef struct zip_file zip_file_t;
|
||||
typedef struct zip_source zip_source_t;
|
||||
typedef struct zip_stat zip_stat_t;
|
||||
|
||||
typedef zip_uint32_t zip_flags_t;
|
||||
|
||||
typedef zip_int64_t (*zip_source_callback)(void *, void *, zip_uint64_t, zip_source_cmd_t);
|
||||
|
||||
|
||||
#ifndef ZIP_DISABLE_DEPRECATED
|
||||
ZIP_EXTERN zip_int64_t zip_add(zip_t *, const char *, zip_source_t *); /* use zip_file_add */
|
||||
ZIP_EXTERN zip_int64_t zip_add_dir(zip_t *, const char *); /* use zip_dir_add */
|
||||
ZIP_EXTERN const char *zip_get_file_comment(zip_t *, zip_uint64_t, int *, int); /* use zip_file_get_comment */
|
||||
ZIP_EXTERN int zip_get_num_files(zip_t *); /* use zip_get_num_entries instead */
|
||||
ZIP_EXTERN int zip_rename(zip_t *, zip_uint64_t, const char *); /* use zip_file_rename */
|
||||
ZIP_EXTERN int zip_replace(zip_t *, zip_uint64_t, zip_source_t *); /* use zip_file_replace */
|
||||
ZIP_EXTERN int zip_set_file_comment(zip_t *, zip_uint64_t, const char *, int); /* use zip_file_set_comment */
|
||||
ZIP_EXTERN int zip_error_get_sys_type(int); /* use zip_error_system_type */
|
||||
ZIP_EXTERN void zip_error_get(zip_t *, int *, int *); /* use zip_get_error, zip_error_code_zip / zip_error_code_system */
|
||||
ZIP_EXTERN int zip_error_to_str(char *, zip_uint64_t, int, int);
|
||||
ZIP_EXTERN void zip_file_error_get(zip_file_t *, int *, int *); /* use zip_file_get_error, zip_error_code_zip / zip_error_code_system */
|
||||
#endif
|
||||
|
||||
ZIP_EXTERN int zip_archive_set_tempdir(zip_t *, const char *);
|
||||
ZIP_EXTERN int zip_close(zip_t *);
|
||||
ZIP_EXTERN int zip_delete(zip_t *, zip_uint64_t);
|
||||
ZIP_EXTERN zip_int64_t zip_dir_add(zip_t *, const char *, zip_flags_t);
|
||||
ZIP_EXTERN void zip_discard(zip_t *);
|
||||
|
||||
ZIP_EXTERN zip_error_t *zip_get_error(zip_t *);
|
||||
ZIP_EXTERN void zip_error_clear(zip_t *);
|
||||
ZIP_EXTERN int zip_error_code_zip(const zip_error_t *);
|
||||
ZIP_EXTERN int zip_error_code_system(const zip_error_t *);
|
||||
ZIP_EXTERN void zip_error_fini(zip_error_t *);
|
||||
ZIP_EXTERN void zip_error_init(zip_error_t *);
|
||||
ZIP_EXTERN void zip_error_init_with_code(zip_error_t *, int);
|
||||
ZIP_EXTERN void zip_error_set(zip_error_t *, int, int);
|
||||
ZIP_EXTERN const char *zip_error_strerror(zip_error_t *);
|
||||
ZIP_EXTERN int zip_error_system_type(const zip_error_t *);
|
||||
ZIP_EXTERN zip_int64_t zip_error_to_data(const zip_error_t *, void *, zip_uint64_t);
|
||||
|
||||
ZIP_EXTERN int zip_fclose(zip_file_t *);
|
||||
ZIP_EXTERN zip_t *zip_fdopen(int, int, int *);
|
||||
ZIP_EXTERN zip_int64_t zip_file_add(zip_t *, const char *, zip_source_t *, zip_flags_t);
|
||||
ZIP_EXTERN void zip_file_error_clear(zip_file_t *);
|
||||
ZIP_EXTERN int zip_file_extra_field_delete(zip_t *, zip_uint64_t, zip_uint16_t, zip_flags_t);
|
||||
ZIP_EXTERN int zip_file_extra_field_delete_by_id(zip_t *, zip_uint64_t, zip_uint16_t, zip_uint16_t, zip_flags_t);
|
||||
ZIP_EXTERN int zip_file_extra_field_set(zip_t *, zip_uint64_t, zip_uint16_t, zip_uint16_t, const zip_uint8_t *, zip_uint16_t, zip_flags_t);
|
||||
ZIP_EXTERN zip_int16_t zip_file_extra_fields_count(zip_t *, zip_uint64_t, zip_flags_t);
|
||||
ZIP_EXTERN zip_int16_t zip_file_extra_fields_count_by_id(zip_t *, zip_uint64_t, zip_uint16_t, zip_flags_t);
|
||||
ZIP_EXTERN const zip_uint8_t *zip_file_extra_field_get(zip_t *, zip_uint64_t, zip_uint16_t, zip_uint16_t *, zip_uint16_t *, zip_flags_t);
|
||||
ZIP_EXTERN const zip_uint8_t *zip_file_extra_field_get_by_id(zip_t *, zip_uint64_t, zip_uint16_t, zip_uint16_t, zip_uint16_t *, zip_flags_t);
|
||||
ZIP_EXTERN const char *zip_file_get_comment(zip_t *, zip_uint64_t, zip_uint32_t *, zip_flags_t);
|
||||
ZIP_EXTERN zip_error_t *zip_file_get_error(zip_file_t *);
|
||||
ZIP_EXTERN int zip_file_get_external_attributes(zip_t *, zip_uint64_t, zip_flags_t, zip_uint8_t *, zip_uint32_t *);
|
||||
ZIP_EXTERN int zip_file_rename(zip_t *, zip_uint64_t, const char *, zip_flags_t);
|
||||
ZIP_EXTERN int zip_file_replace(zip_t *, zip_uint64_t, zip_source_t *, zip_flags_t);
|
||||
ZIP_EXTERN int zip_file_set_comment(zip_t *, zip_uint64_t, const char *, zip_uint16_t, zip_flags_t);
|
||||
ZIP_EXTERN int zip_file_set_external_attributes(zip_t *, zip_uint64_t, zip_flags_t, zip_uint8_t, zip_uint32_t);
|
||||
ZIP_EXTERN int zip_file_set_mtime(zip_t *, zip_uint64_t, time_t, zip_flags_t);
|
||||
ZIP_EXTERN const char *zip_file_strerror(zip_file_t *);
|
||||
ZIP_EXTERN zip_file_t *zip_fopen(zip_t *, const char *, zip_flags_t);
|
||||
ZIP_EXTERN zip_file_t *zip_fopen_encrypted(zip_t *, const char *, zip_flags_t, const char *);
|
||||
ZIP_EXTERN zip_file_t *zip_fopen_index(zip_t *, zip_uint64_t, zip_flags_t);
|
||||
ZIP_EXTERN zip_file_t *zip_fopen_index_encrypted(zip_t *, zip_uint64_t, zip_flags_t, const char *);
|
||||
ZIP_EXTERN zip_int64_t zip_fread(zip_file_t *, void *, zip_uint64_t);
|
||||
ZIP_EXTERN const char *zip_get_archive_comment(zip_t *, int *, zip_flags_t);
|
||||
ZIP_EXTERN int zip_get_archive_flag(zip_t *, zip_flags_t, zip_flags_t);
|
||||
ZIP_EXTERN const char *zip_get_name(zip_t *, zip_uint64_t, zip_flags_t);
|
||||
ZIP_EXTERN zip_int64_t zip_get_num_entries(zip_t *, zip_flags_t);
|
||||
ZIP_EXTERN zip_int64_t zip_name_locate(zip_t *, const char *, zip_flags_t);
|
||||
ZIP_EXTERN zip_t *zip_open(const char *, int, int *);
|
||||
ZIP_EXTERN zip_t *zip_open_from_source(zip_source_t *, int, zip_error_t *);
|
||||
ZIP_EXTERN int zip_set_archive_comment(zip_t *, const char *, zip_uint16_t);
|
||||
ZIP_EXTERN int zip_set_archive_flag(zip_t *, zip_flags_t, int);
|
||||
ZIP_EXTERN int zip_set_default_password(zip_t *, const char *);
|
||||
ZIP_EXTERN int zip_set_file_compression(zip_t *, zip_uint64_t, zip_int32_t, zip_uint32_t);
|
||||
ZIP_EXTERN int zip_source_begin_write(zip_source_t *);
|
||||
ZIP_EXTERN zip_source_t *zip_source_buffer(zip_t *, const void *, zip_uint64_t, int);
|
||||
ZIP_EXTERN zip_source_t *zip_source_buffer_create(const void *, zip_uint64_t, int, zip_error_t *);
|
||||
ZIP_EXTERN int zip_source_close(zip_source_t *);
|
||||
ZIP_EXTERN int zip_source_commit_write(zip_source_t *);
|
||||
ZIP_EXTERN zip_error_t *zip_source_error(zip_source_t *src);
|
||||
ZIP_EXTERN zip_source_t *zip_source_file(zip_t *, const char *, zip_uint64_t, zip_int64_t);
|
||||
ZIP_EXTERN zip_source_t *zip_source_file_create(const char *, zip_uint64_t, zip_int64_t, zip_error_t *);
|
||||
ZIP_EXTERN zip_source_t *zip_source_filep(zip_t *, FILE *, zip_uint64_t, zip_int64_t);
|
||||
ZIP_EXTERN zip_source_t *zip_source_filep_create(FILE *, zip_uint64_t, zip_int64_t, zip_error_t *);
|
||||
ZIP_EXTERN void zip_source_free(zip_source_t *);
|
||||
ZIP_EXTERN zip_source_t *zip_source_function(zip_t *, zip_source_callback, void *);
|
||||
ZIP_EXTERN zip_source_t *zip_source_function_create(zip_source_callback, void *, zip_error_t *);
|
||||
ZIP_EXTERN int zip_source_is_deleted(zip_source_t *);
|
||||
ZIP_EXTERN void zip_source_keep(zip_source_t *);
|
||||
ZIP_EXTERN zip_int64_t zip_source_make_command_bitmap(zip_source_cmd_t, ...);
|
||||
ZIP_EXTERN int zip_source_open(zip_source_t *);
|
||||
ZIP_EXTERN zip_int64_t zip_source_read(zip_source_t *, void *, zip_uint64_t);
|
||||
ZIP_EXTERN void zip_source_rollback_write(zip_source_t *);
|
||||
ZIP_EXTERN int zip_source_seek(zip_source_t *, zip_int64_t, int);
|
||||
ZIP_EXTERN zip_int64_t zip_source_seek_compute_offset(zip_uint64_t, zip_uint64_t, void *, zip_uint64_t, zip_error_t *);
|
||||
ZIP_EXTERN int zip_source_seek_write(zip_source_t *, zip_int64_t, int);
|
||||
ZIP_EXTERN int zip_source_stat(zip_source_t *, zip_stat_t *);
|
||||
ZIP_EXTERN zip_int64_t zip_source_tell(zip_source_t *);
|
||||
ZIP_EXTERN zip_int64_t zip_source_tell_write(zip_source_t *);
|
||||
#ifdef _WIN32
|
||||
ZIP_EXTERN zip_source_t *zip_source_win32a(zip_t *, const char *, zip_uint64_t, zip_int64_t);
|
||||
ZIP_EXTERN zip_source_t *zip_source_win32a_create(const char *, zip_uint64_t, zip_int64_t, zip_error_t *);
|
||||
ZIP_EXTERN zip_source_t *zip_source_win32handle(zip_t *, void *, zip_uint64_t, zip_int64_t);
|
||||
ZIP_EXTERN zip_source_t *zip_source_win32handle_create(void *, zip_uint64_t, zip_int64_t, zip_error_t *);
|
||||
ZIP_EXTERN zip_source_t *zip_source_win32w(zip_t *, const wchar_t *, zip_uint64_t, zip_int64_t);
|
||||
ZIP_EXTERN zip_source_t *zip_source_win32w_create(const wchar_t *, zip_uint64_t, zip_int64_t, zip_error_t *);
|
||||
#endif
|
||||
ZIP_EXTERN zip_int64_t zip_source_write(zip_source_t *, const void *, zip_uint64_t);
|
||||
ZIP_EXTERN zip_source_t *zip_source_zip(zip_t *, zip_t *, zip_uint64_t, zip_flags_t, zip_uint64_t, zip_int64_t);
|
||||
ZIP_EXTERN int zip_stat(zip_t *, const char *, zip_flags_t, zip_stat_t *);
|
||||
ZIP_EXTERN int zip_stat_index(zip_t *, zip_uint64_t, zip_flags_t, zip_stat_t *);
|
||||
ZIP_EXTERN void zip_stat_init(zip_stat_t *);
|
||||
ZIP_EXTERN const char *zip_strerror(zip_t *);
|
||||
ZIP_EXTERN int zip_unchange(zip_t *, zip_uint64_t);
|
||||
ZIP_EXTERN int zip_unchange_all(zip_t *);
|
||||
ZIP_EXTERN int zip_unchange_archive(zip_t *);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _HAD_ZIP_H */
|
||||
50
src/Common/libzip/zip_add.c
Normal file
50
src/Common/libzip/zip_add.c
Normal file
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
zip_add.c -- add file via callback function
|
||||
Copyright (C) 1999-2014 Dieter Baron and Thomas Klausner
|
||||
|
||||
This file is part of libzip, a library to manipulate ZIP archives.
|
||||
The authors can be contacted at <libzip@nih.at>
|
||||
|
||||
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.
|
||||
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.
|
||||
3. The names of the authors may not be used to endorse or promote
|
||||
products derived from this software without specific prior
|
||||
written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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.
|
||||
*/
|
||||
|
||||
|
||||
#define _ZIP_COMPILING_DEPRECATED
|
||||
#include "zipint.h"
|
||||
|
||||
|
||||
/*
|
||||
NOTE: Return type is signed so we can return -1 on error.
|
||||
The index can not be larger than ZIP_INT64_MAX since the size
|
||||
of the central directory cannot be larger than
|
||||
ZIP_UINT64_MAX, and each entry is larger than 2 bytes.
|
||||
*/
|
||||
|
||||
ZIP_EXTERN zip_int64_t
|
||||
zip_add(zip_t *za, const char *name, zip_source_t *source)
|
||||
{
|
||||
return zip_file_add(za, name, source, 0);
|
||||
}
|
||||
45
src/Common/libzip/zip_add_dir.c
Normal file
45
src/Common/libzip/zip_add_dir.c
Normal file
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
zip_add_dir.c -- add directory
|
||||
Copyright (C) 1999-2014 Dieter Baron and Thomas Klausner
|
||||
|
||||
This file is part of libzip, a library to manipulate ZIP archives.
|
||||
The authors can be contacted at <libzip@nih.at>
|
||||
|
||||
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.
|
||||
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.
|
||||
3. The names of the authors may not be used to endorse or promote
|
||||
products derived from this software without specific prior
|
||||
written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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.
|
||||
*/
|
||||
|
||||
|
||||
#define _ZIP_COMPILING_DEPRECATED
|
||||
#include "zipint.h"
|
||||
|
||||
|
||||
/* NOTE: Signed due to -1 on error. See zip_add.c for more details. */
|
||||
|
||||
ZIP_EXTERN zip_int64_t
|
||||
zip_add_dir(zip_t *za, const char *name)
|
||||
{
|
||||
return zip_dir_add(za, name, 0);
|
||||
}
|
||||
81
src/Common/libzip/zip_add_entry.c
Normal file
81
src/Common/libzip/zip_add_entry.c
Normal file
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
zip_add_entry.c -- create and init struct zip_entry
|
||||
Copyright (C) 1999-2015 Dieter Baron and Thomas Klausner
|
||||
|
||||
This file is part of libzip, a library to manipulate ZIP archives.
|
||||
The authors can be contacted at <libzip@nih.at>
|
||||
|
||||
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.
|
||||
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.
|
||||
3. The names of the authors may not be used to endorse or promote
|
||||
products derived from this software without specific prior
|
||||
written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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.
|
||||
*/
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "zipint.h"
|
||||
|
||||
|
||||
/* NOTE: Signed due to -1 on error. See zip_add.c for more details. */
|
||||
|
||||
zip_int64_t
|
||||
_zip_add_entry(zip_t *za)
|
||||
{
|
||||
zip_uint64_t idx;
|
||||
|
||||
if (za->nentry+1 >= za->nentry_alloc) {
|
||||
zip_entry_t *rentries;
|
||||
zip_uint64_t nalloc = za->nentry_alloc;
|
||||
zip_uint64_t additional_entries = 2 * nalloc;
|
||||
zip_uint64_t realloc_size;
|
||||
|
||||
if (additional_entries < 16) {
|
||||
additional_entries = 16;
|
||||
}
|
||||
else if (additional_entries > 1024) {
|
||||
additional_entries = 1024;
|
||||
}
|
||||
/* neither + nor * overflows can happen: nentry_alloc * sizeof(struct zip_entry) < UINT64_MAX */
|
||||
nalloc += additional_entries;
|
||||
realloc_size = sizeof(struct zip_entry) * (size_t)nalloc;
|
||||
|
||||
if (sizeof(struct zip_entry) * (size_t)za->nentry_alloc > realloc_size) {
|
||||
zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
|
||||
return -1;
|
||||
}
|
||||
rentries = (zip_entry_t *)realloc(za->entry, sizeof(struct zip_entry) * (size_t)nalloc);
|
||||
if (!rentries) {
|
||||
zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
|
||||
return -1;
|
||||
}
|
||||
za->entry = rentries;
|
||||
za->nentry_alloc = nalloc;
|
||||
}
|
||||
|
||||
idx = za->nentry++;
|
||||
|
||||
_zip_entry_init(za->entry+idx);
|
||||
|
||||
return (zip_int64_t)idx;
|
||||
}
|
||||
321
src/Common/libzip/zip_buffer.c
Normal file
321
src/Common/libzip/zip_buffer.c
Normal file
@@ -0,0 +1,321 @@
|
||||
/*
|
||||
zip_buffer.c -- bounds checked access to memory buffer
|
||||
Copyright (C) 2014 Dieter Baron and Thomas Klausner
|
||||
|
||||
This file is part of libzip, a library to manipulate ZIP archives.
|
||||
The authors can be contacted at <libzip@nih.at>
|
||||
|
||||
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.
|
||||
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.
|
||||
3. The names of the authors may not be used to endorse or promote
|
||||
products derived from this software without specific prior
|
||||
written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "zipint.h"
|
||||
|
||||
zip_uint8_t *
|
||||
_zip_buffer_data(zip_buffer_t *buffer)
|
||||
{
|
||||
return buffer->data;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
_zip_buffer_free(zip_buffer_t *buffer)
|
||||
{
|
||||
if (buffer == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (buffer->free_data) {
|
||||
free(buffer->data);
|
||||
}
|
||||
|
||||
free(buffer);
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
_zip_buffer_eof(zip_buffer_t *buffer)
|
||||
{
|
||||
return buffer->ok && buffer->offset == buffer->size;
|
||||
}
|
||||
|
||||
|
||||
zip_uint8_t *
|
||||
_zip_buffer_get(zip_buffer_t *buffer, zip_uint64_t length)
|
||||
{
|
||||
zip_uint8_t *data;
|
||||
|
||||
if (!buffer->ok || buffer->offset + length < length || buffer->offset + length > buffer->size) {
|
||||
buffer->ok = false;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
data = buffer->data + buffer->offset;
|
||||
buffer->offset += length;
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
zip_uint16_t
|
||||
_zip_buffer_get_16(zip_buffer_t *buffer)
|
||||
{
|
||||
zip_uint8_t *data = _zip_buffer_get(buffer, 2);
|
||||
|
||||
if (data == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return (zip_uint16_t)(data[0] + (data[1] << 8));
|
||||
}
|
||||
|
||||
|
||||
zip_uint32_t
|
||||
_zip_buffer_get_32(zip_buffer_t *buffer)
|
||||
{
|
||||
zip_uint8_t *data = _zip_buffer_get(buffer, 4);
|
||||
|
||||
if (data == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return ((((((zip_uint32_t)data[3] << 8) + data[2]) << 8) + data[1]) << 8) + data[0];
|
||||
}
|
||||
|
||||
|
||||
zip_uint64_t
|
||||
_zip_buffer_get_64(zip_buffer_t *buffer)
|
||||
{
|
||||
zip_uint8_t *data = _zip_buffer_get(buffer, 8);
|
||||
|
||||
if (data == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return ((zip_uint64_t)data[7] << 56) + ((zip_uint64_t)data[6] << 48) + ((zip_uint64_t)data[5] << 40) + ((zip_uint64_t)data[4] << 32) + ((zip_uint64_t)data[3] << 24) + ((zip_uint64_t)data[2] << 16) + ((zip_uint64_t)data[1] << 8) + (zip_uint64_t)data[0];
|
||||
}
|
||||
|
||||
|
||||
|
||||
zip_uint8_t
|
||||
_zip_buffer_get_8(zip_buffer_t *buffer)
|
||||
{
|
||||
zip_uint8_t *data = _zip_buffer_get(buffer, 1);
|
||||
|
||||
if (data == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return data[0];
|
||||
}
|
||||
|
||||
|
||||
zip_uint64_t
|
||||
_zip_buffer_left(zip_buffer_t *buffer)
|
||||
{
|
||||
return buffer->ok ? buffer->size - buffer->offset : 0;
|
||||
}
|
||||
|
||||
|
||||
zip_buffer_t *
|
||||
_zip_buffer_new(zip_uint8_t *data, zip_uint64_t size)
|
||||
{
|
||||
bool free_data = (data == NULL);
|
||||
zip_buffer_t *buffer;
|
||||
|
||||
if (data == NULL) {
|
||||
if ((data = (zip_uint8_t *)malloc(size)) == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if ((buffer = (zip_buffer_t *)malloc(sizeof(*buffer))) == NULL) {
|
||||
if (free_data) {
|
||||
free(data);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
buffer->ok = true;
|
||||
buffer->data = data;
|
||||
buffer->size = size;
|
||||
buffer->offset = 0;
|
||||
buffer->free_data = free_data;
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
|
||||
zip_buffer_t *
|
||||
_zip_buffer_new_from_source(zip_source_t *src, zip_uint64_t size, zip_uint8_t *buf, zip_error_t *error)
|
||||
{
|
||||
zip_buffer_t *buffer;
|
||||
|
||||
if ((buffer = _zip_buffer_new(buf, size)) == NULL) {
|
||||
zip_error_set(error, ZIP_ER_MEMORY, 0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (_zip_read(src, buffer->data, size, error) < 0) {
|
||||
_zip_buffer_free(buffer);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
|
||||
zip_uint64_t
|
||||
_zip_buffer_offset(zip_buffer_t *buffer)
|
||||
{
|
||||
return buffer->ok ? buffer->offset : 0;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
_zip_buffer_ok(zip_buffer_t *buffer)
|
||||
{
|
||||
return buffer->ok;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
_zip_buffer_put(zip_buffer_t *buffer, const void *src, size_t length)
|
||||
{
|
||||
zip_uint8_t *dst = _zip_buffer_get(buffer, length);
|
||||
|
||||
if (dst == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
memcpy(dst, src, length);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
_zip_buffer_put_16(zip_buffer_t *buffer, zip_uint16_t i)
|
||||
{
|
||||
zip_uint8_t *data = _zip_buffer_get(buffer, 2);
|
||||
|
||||
if (data == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
data[0] = (zip_uint8_t)(i & 0xff);
|
||||
data[1] = (zip_uint8_t)((i >> 8) & 0xff);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
_zip_buffer_put_32(zip_buffer_t *buffer, zip_uint32_t i)
|
||||
{
|
||||
zip_uint8_t *data = _zip_buffer_get(buffer, 4);
|
||||
|
||||
if (data == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
data[0] = (zip_uint8_t)(i & 0xff);
|
||||
data[1] = (zip_uint8_t)((i >> 8) & 0xff);
|
||||
data[2] = (zip_uint8_t)((i >> 16) & 0xff);
|
||||
data[3] = (zip_uint8_t)((i >> 24) & 0xff);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
_zip_buffer_put_64(zip_buffer_t *buffer, zip_uint64_t i)
|
||||
{
|
||||
zip_uint8_t *data = _zip_buffer_get(buffer, 8);
|
||||
|
||||
if (data == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
data[0] = (zip_uint8_t)(i & 0xff);
|
||||
data[1] = (zip_uint8_t)((i >> 8) & 0xff);
|
||||
data[2] = (zip_uint8_t)((i >> 16) & 0xff);
|
||||
data[3] = (zip_uint8_t)((i >> 24) & 0xff);
|
||||
data[4] = (zip_uint8_t)((i >> 32) & 0xff);
|
||||
data[5] = (zip_uint8_t)((i >> 40) & 0xff);
|
||||
data[6] = (zip_uint8_t)((i >> 48) & 0xff);
|
||||
data[7] = (zip_uint8_t)((i >> 56) & 0xff);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
_zip_buffer_put_8(zip_buffer_t *buffer, zip_uint8_t i)
|
||||
{
|
||||
zip_uint8_t *data = _zip_buffer_get(buffer, 1);
|
||||
|
||||
if (data == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
data[0] = i;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
_zip_buffer_set_offset(zip_buffer_t *buffer, zip_uint64_t offset)
|
||||
{
|
||||
if (offset > buffer->size) {
|
||||
buffer->ok = false;
|
||||
return -1;
|
||||
}
|
||||
|
||||
buffer->ok = true;
|
||||
buffer->offset = offset;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
_zip_buffer_skip(zip_buffer_t *buffer, zip_uint64_t length) {
|
||||
zip_uint64_t offset = buffer->offset + length;
|
||||
|
||||
if (offset < buffer->offset) {
|
||||
buffer->ok = false;
|
||||
return -1;
|
||||
}
|
||||
return _zip_buffer_set_offset(buffer, offset);
|
||||
}
|
||||
|
||||
zip_uint64_t
|
||||
_zip_buffer_size(zip_buffer_t *buffer)
|
||||
{
|
||||
return buffer->size;
|
||||
}
|
||||
492
src/Common/libzip/zip_close.c
Normal file
492
src/Common/libzip/zip_close.c
Normal file
@@ -0,0 +1,492 @@
|
||||
/*
|
||||
zip_close.c -- close zip archive and update changes
|
||||
Copyright (C) 1999-2015 Dieter Baron and Thomas Klausner
|
||||
|
||||
This file is part of libzip, a library to manipulate ZIP archives.
|
||||
The authors can be contacted at <libzip@nih.at>
|
||||
|
||||
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.
|
||||
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.
|
||||
3. The names of the authors may not be used to endorse or promote
|
||||
products derived from this software without specific prior
|
||||
written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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.
|
||||
*/
|
||||
|
||||
|
||||
#include "zipint.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#ifdef HAVE_STRINGS_H
|
||||
#include <strings.h>
|
||||
#endif
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#ifdef _WIN32
|
||||
#include <io.h>
|
||||
#include <fcntl.h>
|
||||
#endif
|
||||
|
||||
|
||||
/* max deflate size increase: size + ceil(size/16k)*5+6 */
|
||||
#define MAX_DEFLATE_SIZE_32 4293656963u
|
||||
|
||||
static int add_data(zip_t *, zip_source_t *, zip_dirent_t *);
|
||||
static int copy_data(zip_t *, zip_uint64_t);
|
||||
static int copy_source(zip_t *, zip_source_t *);
|
||||
static int write_cdir(zip_t *, const zip_filelist_t *, zip_uint64_t);
|
||||
|
||||
|
||||
ZIP_EXTERN int
|
||||
zip_close(zip_t *za)
|
||||
{
|
||||
zip_uint64_t i, j, survivors;
|
||||
zip_int64_t off;
|
||||
int error;
|
||||
zip_filelist_t *filelist;
|
||||
int changed;
|
||||
|
||||
if (za == NULL)
|
||||
return -1;
|
||||
|
||||
changed = _zip_changed(za, &survivors);
|
||||
|
||||
/* don't create zip files with no entries */
|
||||
if (survivors == 0) {
|
||||
if ((za->open_flags & ZIP_TRUNCATE) || changed) {
|
||||
if (zip_source_remove(za->src) < 0) {
|
||||
_zip_error_set_from_source(&za->error, za->src);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
zip_discard(za);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!changed) {
|
||||
zip_discard(za);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (survivors > za->nentry) {
|
||||
zip_error_set(&za->error, ZIP_ER_INTERNAL, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((filelist=(zip_filelist_t *)malloc(sizeof(filelist[0])*(size_t)survivors)) == NULL)
|
||||
return -1;
|
||||
|
||||
/* create list of files with index into original archive */
|
||||
for (i=j=0; i<za->nentry; i++) {
|
||||
if (za->entry[i].deleted)
|
||||
continue;
|
||||
|
||||
if (j >= survivors) {
|
||||
free(filelist);
|
||||
zip_error_set(&za->error, ZIP_ER_INTERNAL, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
filelist[j].idx = i;
|
||||
j++;
|
||||
}
|
||||
if (j < survivors) {
|
||||
free(filelist);
|
||||
zip_error_set(&za->error, ZIP_ER_INTERNAL, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (zip_source_begin_write(za->src) < 0) {
|
||||
_zip_error_set_from_source(&za->error, za->src);
|
||||
free(filelist);
|
||||
return -1;
|
||||
}
|
||||
|
||||
error = 0;
|
||||
for (j=0; j<survivors; j++) {
|
||||
int new_data;
|
||||
zip_entry_t *entry;
|
||||
zip_dirent_t *de;
|
||||
|
||||
i = filelist[j].idx;
|
||||
entry = za->entry+i;
|
||||
|
||||
new_data = (ZIP_ENTRY_DATA_CHANGED(entry) || ZIP_ENTRY_CHANGED(entry, ZIP_DIRENT_COMP_METHOD));
|
||||
|
||||
/* create new local directory entry */
|
||||
if (entry->changes == NULL) {
|
||||
if ((entry->changes=_zip_dirent_clone(entry->orig)) == NULL) {
|
||||
zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
|
||||
error = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
de = entry->changes;
|
||||
|
||||
if (_zip_read_local_ef(za, i) < 0) {
|
||||
error = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
if ((off = zip_source_tell_write(za->src)) < 0) {
|
||||
error = 1;
|
||||
break;
|
||||
}
|
||||
de->offset = (zip_uint64_t)off;
|
||||
|
||||
if (new_data) {
|
||||
zip_source_t *zs;
|
||||
|
||||
zs = NULL;
|
||||
if (!ZIP_ENTRY_DATA_CHANGED(entry)) {
|
||||
if ((zs=_zip_source_zip_new(za, za, i, ZIP_FL_UNCHANGED, 0, 0, NULL)) == NULL) {
|
||||
error = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* add_data writes dirent */
|
||||
if (add_data(za, zs ? zs : entry->source, de) < 0) {
|
||||
error = 1;
|
||||
if (zs)
|
||||
zip_source_free(zs);
|
||||
break;
|
||||
}
|
||||
if (zs)
|
||||
zip_source_free(zs);
|
||||
}
|
||||
else {
|
||||
zip_uint64_t offset;
|
||||
|
||||
/* when copying data, all sizes are known -> no data descriptor needed */
|
||||
de->bitflags &= (zip_uint16_t)~ZIP_GPBF_DATA_DESCRIPTOR;
|
||||
if (_zip_dirent_write(za, de, ZIP_FL_LOCAL) < 0) {
|
||||
error = 1;
|
||||
break;
|
||||
}
|
||||
if ((offset=_zip_file_get_offset(za, i, &za->error)) == 0) {
|
||||
error = 1;
|
||||
break;
|
||||
}
|
||||
if (zip_source_seek(za->src, (zip_int64_t)offset, SEEK_SET) < 0) {
|
||||
_zip_error_set_from_source(&za->error, za->src);
|
||||
error = 1;
|
||||
break;
|
||||
}
|
||||
if (copy_data(za, de->comp_size) < 0) {
|
||||
error = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!error) {
|
||||
if (write_cdir(za, filelist, survivors) < 0)
|
||||
error = 1;
|
||||
}
|
||||
|
||||
free(filelist);
|
||||
|
||||
if (!error) {
|
||||
if (zip_source_commit_write(za->src) != 0) {
|
||||
_zip_error_set_from_source(&za->error, za->src);
|
||||
error = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (error) {
|
||||
zip_source_rollback_write(za->src);
|
||||
return -1;
|
||||
}
|
||||
|
||||
zip_discard(za);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
add_data(zip_t *za, zip_source_t *src, zip_dirent_t *de)
|
||||
{
|
||||
zip_int64_t offstart, offdata, offend;
|
||||
struct zip_stat st;
|
||||
zip_source_t *s2;
|
||||
int ret;
|
||||
int is_zip64;
|
||||
zip_flags_t flags;
|
||||
|
||||
if (zip_source_stat(src, &st) < 0) {
|
||||
_zip_error_set_from_source(&za->error, src);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((st.valid & ZIP_STAT_COMP_METHOD) == 0) {
|
||||
st.valid |= ZIP_STAT_COMP_METHOD;
|
||||
st.comp_method = ZIP_CM_STORE;
|
||||
}
|
||||
|
||||
if (ZIP_CM_IS_DEFAULT(de->comp_method) && st.comp_method != ZIP_CM_STORE)
|
||||
de->comp_method = st.comp_method;
|
||||
else if (de->comp_method == ZIP_CM_STORE && (st.valid & ZIP_STAT_SIZE)) {
|
||||
st.valid |= ZIP_STAT_COMP_SIZE;
|
||||
st.comp_size = st.size;
|
||||
}
|
||||
else {
|
||||
/* we'll recompress */
|
||||
st.valid &= ~ZIP_STAT_COMP_SIZE;
|
||||
}
|
||||
|
||||
|
||||
flags = ZIP_EF_LOCAL;
|
||||
|
||||
if ((st.valid & ZIP_STAT_SIZE) == 0)
|
||||
flags |= ZIP_FL_FORCE_ZIP64;
|
||||
else {
|
||||
de->uncomp_size = st.size;
|
||||
|
||||
if ((st.valid & ZIP_STAT_COMP_SIZE) == 0) {
|
||||
if (( ((de->comp_method == ZIP_CM_DEFLATE || ZIP_CM_IS_DEFAULT(de->comp_method)) && st.size > MAX_DEFLATE_SIZE_32)
|
||||
|| (de->comp_method != ZIP_CM_STORE && de->comp_method != ZIP_CM_DEFLATE && !ZIP_CM_IS_DEFAULT(de->comp_method))))
|
||||
flags |= ZIP_FL_FORCE_ZIP64;
|
||||
}
|
||||
else
|
||||
de->comp_size = st.comp_size;
|
||||
}
|
||||
|
||||
if ((offstart = zip_source_tell_write(za->src)) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* as long as we don't support non-seekable output, clear data descriptor bit */
|
||||
de->bitflags &= (zip_uint16_t)~ZIP_GPBF_DATA_DESCRIPTOR;
|
||||
if ((is_zip64=_zip_dirent_write(za, de, flags)) < 0)
|
||||
return -1;
|
||||
|
||||
|
||||
if (st.comp_method == ZIP_CM_STORE || (ZIP_CM_IS_DEFAULT(de->comp_method) && st.comp_method != de->comp_method)) {
|
||||
zip_source_t *s_store, *s_crc;
|
||||
zip_compression_implementation comp_impl;
|
||||
|
||||
if (st.comp_method != ZIP_CM_STORE) {
|
||||
if ((comp_impl=_zip_get_compression_implementation(st.comp_method)) == NULL) {
|
||||
zip_error_set(&za->error, ZIP_ER_COMPNOTSUPP, 0);
|
||||
return -1;
|
||||
}
|
||||
if ((s_store=comp_impl(za, src, st.comp_method, ZIP_CODEC_DECODE)) == NULL) {
|
||||
/* error set by comp_impl */
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* to have the same reference count to src as in the case where it's not stored */
|
||||
zip_source_keep(src);
|
||||
s_store = src;
|
||||
}
|
||||
|
||||
s_crc = zip_source_crc(za, s_store, 0);
|
||||
zip_source_free(s_store);
|
||||
if (s_crc == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (de->comp_method != ZIP_CM_STORE && ((st.valid & ZIP_STAT_SIZE) == 0 || st.size != 0)) {
|
||||
if ((comp_impl=_zip_get_compression_implementation(de->comp_method)) == NULL) {
|
||||
zip_error_set(&za->error, ZIP_ER_COMPNOTSUPP, 0);
|
||||
zip_source_free(s_crc);
|
||||
return -1;
|
||||
}
|
||||
s2 = comp_impl(za, s_crc, de->comp_method, ZIP_CODEC_ENCODE);
|
||||
zip_source_free(s_crc);
|
||||
if (s2 == NULL) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
s2 = s_crc;
|
||||
}
|
||||
}
|
||||
else {
|
||||
zip_source_keep(src);
|
||||
s2 = src;
|
||||
}
|
||||
|
||||
if ((offdata = zip_source_tell_write(za->src)) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = copy_source(za, s2);
|
||||
|
||||
if (zip_source_stat(s2, &st) < 0)
|
||||
ret = -1;
|
||||
|
||||
zip_source_free(s2);
|
||||
|
||||
if (ret < 0)
|
||||
return -1;
|
||||
|
||||
if ((offend = zip_source_tell_write(za->src)) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (zip_source_seek_write(za->src, offstart, SEEK_SET) < 0) {
|
||||
_zip_error_set_from_source(&za->error, za->src);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((st.valid & (ZIP_STAT_COMP_METHOD|ZIP_STAT_CRC|ZIP_STAT_SIZE)) != (ZIP_STAT_COMP_METHOD|ZIP_STAT_CRC|ZIP_STAT_SIZE)) {
|
||||
zip_error_set(&za->error, ZIP_ER_INTERNAL, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((de->changed & ZIP_DIRENT_LAST_MOD) == 0) {
|
||||
if (st.valid & ZIP_STAT_MTIME)
|
||||
de->last_mod = st.mtime;
|
||||
else
|
||||
time(&de->last_mod);
|
||||
}
|
||||
de->comp_method = st.comp_method;
|
||||
de->crc = st.crc;
|
||||
de->uncomp_size = st.size;
|
||||
de->comp_size = (zip_uint64_t)(offend - offdata);
|
||||
|
||||
if ((ret=_zip_dirent_write(za, de, flags)) < 0)
|
||||
return -1;
|
||||
|
||||
if (is_zip64 != ret) {
|
||||
/* Zip64 mismatch between preliminary file header written before data and final file header written afterwards */
|
||||
zip_error_set(&za->error, ZIP_ER_INTERNAL, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
if (zip_source_seek_write(za->src, offend, SEEK_SET) < 0) {
|
||||
_zip_error_set_from_source(&za->error, za->src);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
copy_data(zip_t *za, zip_uint64_t len)
|
||||
{
|
||||
zip_uint8_t buf[BUFSIZE];
|
||||
size_t n;
|
||||
|
||||
while (len > 0) {
|
||||
n = len > sizeof(buf) ? sizeof(buf) : len;
|
||||
if (_zip_read(za->src, buf, n, &za->error) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (_zip_write(za, buf, n) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
len -= n;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
copy_source(zip_t *za, zip_source_t *src)
|
||||
{
|
||||
zip_uint8_t buf[BUFSIZE];
|
||||
zip_int64_t n;
|
||||
int ret;
|
||||
|
||||
if (zip_source_open(src) < 0) {
|
||||
_zip_error_set_from_source(&za->error, src);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
while ((n=zip_source_read(src, buf, sizeof(buf))) > 0) {
|
||||
if (_zip_write(za, buf, (zip_uint64_t)n) < 0) {
|
||||
ret = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (n < 0) {
|
||||
_zip_error_set_from_source(&za->error, src);
|
||||
ret = -1;
|
||||
}
|
||||
|
||||
zip_source_close(src);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
write_cdir(zip_t *za, const zip_filelist_t *filelist, zip_uint64_t survivors)
|
||||
{
|
||||
zip_int64_t cd_start, end, size;
|
||||
|
||||
if ((cd_start = zip_source_tell_write(za->src)) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((size=_zip_cdir_write(za, filelist, survivors)) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((end = zip_source_tell_write(za->src)) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
_zip_changed(const zip_t *za, zip_uint64_t *survivorsp)
|
||||
{
|
||||
int changed;
|
||||
zip_uint64_t i, survivors;
|
||||
|
||||
changed = 0;
|
||||
survivors = 0;
|
||||
|
||||
if (za->comment_changed || za->ch_flags != za->flags)
|
||||
changed = 1;
|
||||
|
||||
for (i=0; i<za->nentry; i++) {
|
||||
if (za->entry[i].deleted || za->entry[i].source || (za->entry[i].changes && za->entry[i].changes->changed != 0))
|
||||
changed = 1;
|
||||
if (!za->entry[i].deleted)
|
||||
survivors++;
|
||||
}
|
||||
|
||||
if (survivorsp)
|
||||
*survivorsp = survivors;
|
||||
|
||||
return changed;
|
||||
}
|
||||
70
src/Common/libzip/zip_delete.c
Normal file
70
src/Common/libzip/zip_delete.c
Normal file
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
zip_delete.c -- delete file from zip archive
|
||||
Copyright (C) 1999-2015 Dieter Baron and Thomas Klausner
|
||||
|
||||
This file is part of libzip, a library to manipulate ZIP archives.
|
||||
The authors can be contacted at <libzip@nih.at>
|
||||
|
||||
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.
|
||||
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.
|
||||
3. The names of the authors may not be used to endorse or promote
|
||||
products derived from this software without specific prior
|
||||
written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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.
|
||||
*/
|
||||
|
||||
|
||||
#include "zipint.h"
|
||||
|
||||
|
||||
ZIP_EXTERN int
|
||||
zip_delete(zip_t *za, zip_uint64_t idx)
|
||||
{
|
||||
const char *name;
|
||||
|
||||
if (idx >= za->nentry) {
|
||||
zip_error_set(&za->error, ZIP_ER_INVAL, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ZIP_IS_RDONLY(za)) {
|
||||
zip_error_set(&za->error, ZIP_ER_RDONLY, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((name=_zip_get_name(za, idx, 0, &za->error)) == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!_zip_hash_delete(za->names, (const zip_uint8_t *)name, &za->error)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* allow duplicate file names, because the file will
|
||||
* be removed directly afterwards */
|
||||
if (_zip_unchange(za, idx, 1) != 0)
|
||||
return -1;
|
||||
|
||||
za->entry[idx].deleted = 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
93
src/Common/libzip/zip_dir_add.c
Normal file
93
src/Common/libzip/zip_dir_add.c
Normal file
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
zip_dir_add.c -- add directory
|
||||
Copyright (C) 1999-2014 Dieter Baron and Thomas Klausner
|
||||
|
||||
This file is part of libzip, a library to manipulate ZIP archives.
|
||||
The authors can be contacted at <libzip@nih.at>
|
||||
|
||||
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.
|
||||
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.
|
||||
3. The names of the authors may not be used to endorse or promote
|
||||
products derived from this software without specific prior
|
||||
written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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.
|
||||
*/
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "zipint.h"
|
||||
|
||||
|
||||
/* NOTE: Signed due to -1 on error. See zip_add.c for more details. */
|
||||
|
||||
ZIP_EXTERN zip_int64_t
|
||||
zip_dir_add(zip_t *za, const char *name, zip_flags_t flags)
|
||||
{
|
||||
size_t len;
|
||||
zip_int64_t idx;
|
||||
char *s;
|
||||
zip_source_t *source;
|
||||
|
||||
if (ZIP_IS_RDONLY(za)) {
|
||||
zip_error_set(&za->error, ZIP_ER_RDONLY, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (name == NULL) {
|
||||
zip_error_set(&za->error, ZIP_ER_INVAL, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
s = NULL;
|
||||
len = strlen(name);
|
||||
|
||||
if (name[len-1] != '/') {
|
||||
if ((s=(char *)malloc(len+2)) == NULL) {
|
||||
zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
|
||||
return -1;
|
||||
}
|
||||
strcpy(s, name);
|
||||
s[len] = '/';
|
||||
s[len+1] = '\0';
|
||||
}
|
||||
|
||||
if ((source=zip_source_buffer(za, NULL, 0, 0)) == NULL) {
|
||||
free(s);
|
||||
return -1;
|
||||
}
|
||||
|
||||
idx = _zip_file_replace(za, ZIP_UINT64_MAX, s ? s : name, source, flags);
|
||||
|
||||
free(s);
|
||||
|
||||
if (idx < 0)
|
||||
zip_source_free(source);
|
||||
else {
|
||||
if (zip_file_set_external_attributes(za, (zip_uint64_t)idx, 0, ZIP_OPSYS_DEFAULT, ZIP_EXT_ATTRIB_DEFAULT_DIR) < 0) {
|
||||
zip_delete(za, (zip_uint64_t)idx);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return idx;
|
||||
}
|
||||
913
src/Common/libzip/zip_dirent.c
Normal file
913
src/Common/libzip/zip_dirent.c
Normal file
@@ -0,0 +1,913 @@
|
||||
/*
|
||||
zip_dirent.c -- read directory entry (local or central), clean dirent
|
||||
Copyright (C) 1999-2016 Dieter Baron and Thomas Klausner
|
||||
|
||||
This file is part of libzip, a library to manipulate ZIP archives.
|
||||
The authors can be contacted at <libzip@nih.at>
|
||||
|
||||
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.
|
||||
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.
|
||||
3. The names of the authors may not be used to endorse or promote
|
||||
products derived from this software without specific prior
|
||||
written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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.
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "zipint.h"
|
||||
|
||||
static time_t _zip_d2u_time(zip_uint16_t, zip_uint16_t);
|
||||
static zip_string_t *_zip_dirent_process_ef_utf_8(const zip_dirent_t *de, zip_uint16_t id, zip_string_t *str);
|
||||
static zip_extra_field_t *_zip_ef_utf8(zip_uint16_t, zip_string_t *, zip_error_t *);
|
||||
|
||||
|
||||
void
|
||||
_zip_cdir_free(zip_cdir_t *cd)
|
||||
{
|
||||
zip_uint64_t i;
|
||||
|
||||
if (!cd)
|
||||
return;
|
||||
|
||||
for (i=0; i<cd->nentry; i++)
|
||||
_zip_entry_finalize(cd->entry+i);
|
||||
free(cd->entry);
|
||||
_zip_string_free(cd->comment);
|
||||
free(cd);
|
||||
}
|
||||
|
||||
|
||||
zip_cdir_t *
|
||||
_zip_cdir_new(zip_uint64_t nentry, zip_error_t *error)
|
||||
{
|
||||
zip_cdir_t *cd;
|
||||
zip_uint64_t i;
|
||||
|
||||
if ((cd=(zip_cdir_t *)malloc(sizeof(*cd))) == NULL) {
|
||||
zip_error_set(error, ZIP_ER_MEMORY, 0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (nentry == 0)
|
||||
cd->entry = NULL;
|
||||
else if ((nentry > SIZE_MAX/sizeof(*(cd->entry))) || (cd->entry=(zip_entry_t *)malloc(sizeof(*(cd->entry))*(size_t)nentry)) == NULL) {
|
||||
zip_error_set(error, ZIP_ER_MEMORY, 0);
|
||||
free(cd);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (i=0; i<nentry; i++)
|
||||
_zip_entry_init(cd->entry+i);
|
||||
|
||||
cd->nentry = cd->nentry_alloc = nentry;
|
||||
cd->size = cd->offset = 0;
|
||||
cd->comment = NULL;
|
||||
|
||||
return cd;
|
||||
}
|
||||
|
||||
|
||||
zip_int64_t
|
||||
_zip_cdir_write(zip_t *za, const zip_filelist_t *filelist, zip_uint64_t survivors)
|
||||
{
|
||||
zip_uint64_t offset, size;
|
||||
zip_string_t *comment;
|
||||
zip_uint8_t buf[EOCDLEN + EOCD64LEN + EOCD64LOCLEN];
|
||||
zip_buffer_t *buffer;
|
||||
zip_int64_t off;
|
||||
zip_uint64_t i;
|
||||
bool is_zip64;
|
||||
int ret;
|
||||
|
||||
if ((off = zip_source_tell_write(za->src)) < 0) {
|
||||
_zip_error_set_from_source(&za->error, za->src);
|
||||
return -1;
|
||||
}
|
||||
offset = (zip_uint64_t)off;
|
||||
|
||||
is_zip64 = false;
|
||||
|
||||
for (i=0; i<survivors; i++) {
|
||||
zip_entry_t *entry = za->entry+filelist[i].idx;
|
||||
|
||||
if ((ret=_zip_dirent_write(za, entry->changes ? entry->changes : entry->orig, ZIP_FL_CENTRAL)) < 0)
|
||||
return -1;
|
||||
if (ret)
|
||||
is_zip64 = true;
|
||||
}
|
||||
|
||||
if ((off = zip_source_tell_write(za->src)) < 0) {
|
||||
_zip_error_set_from_source(&za->error, za->src);
|
||||
return -1;
|
||||
}
|
||||
size = (zip_uint64_t)off - offset;
|
||||
|
||||
if (offset > ZIP_UINT32_MAX || survivors > ZIP_UINT16_MAX)
|
||||
is_zip64 = true;
|
||||
|
||||
|
||||
if ((buffer = _zip_buffer_new(buf, sizeof(buf))) == NULL) {
|
||||
zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (is_zip64) {
|
||||
_zip_buffer_put(buffer, EOCD64_MAGIC, 4);
|
||||
_zip_buffer_put_64(buffer, EOCD64LEN-12);
|
||||
_zip_buffer_put_16(buffer, 45);
|
||||
_zip_buffer_put_16(buffer, 45);
|
||||
_zip_buffer_put_32(buffer, 0);
|
||||
_zip_buffer_put_32(buffer, 0);
|
||||
_zip_buffer_put_64(buffer, survivors);
|
||||
_zip_buffer_put_64(buffer, survivors);
|
||||
_zip_buffer_put_64(buffer, size);
|
||||
_zip_buffer_put_64(buffer, offset);
|
||||
_zip_buffer_put(buffer, EOCD64LOC_MAGIC, 4);
|
||||
_zip_buffer_put_32(buffer, 0);
|
||||
_zip_buffer_put_64(buffer, offset+size);
|
||||
_zip_buffer_put_32(buffer, 1);
|
||||
}
|
||||
|
||||
_zip_buffer_put(buffer, EOCD_MAGIC, 4);
|
||||
_zip_buffer_put_32(buffer, 0);
|
||||
_zip_buffer_put_16(buffer, (zip_uint16_t)(survivors >= ZIP_UINT16_MAX ? ZIP_UINT16_MAX : survivors));
|
||||
_zip_buffer_put_16(buffer, (zip_uint16_t)(survivors >= ZIP_UINT16_MAX ? ZIP_UINT16_MAX : survivors));
|
||||
_zip_buffer_put_32(buffer, size >= ZIP_UINT32_MAX ? ZIP_UINT32_MAX : (zip_uint32_t)size);
|
||||
_zip_buffer_put_32(buffer, offset >= ZIP_UINT32_MAX ? ZIP_UINT32_MAX : (zip_uint32_t)offset);
|
||||
|
||||
comment = za->comment_changed ? za->comment_changes : za->comment_orig;
|
||||
|
||||
_zip_buffer_put_16(buffer, (zip_uint16_t)(comment ? comment->length : 0));
|
||||
|
||||
if (!_zip_buffer_ok(buffer)) {
|
||||
zip_error_set(&za->error, ZIP_ER_INTERNAL, 0);
|
||||
_zip_buffer_free(buffer);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (_zip_write(za, _zip_buffer_data(buffer), _zip_buffer_offset(buffer)) < 0) {
|
||||
_zip_buffer_free(buffer);
|
||||
return -1;
|
||||
}
|
||||
|
||||
_zip_buffer_free(buffer);
|
||||
|
||||
if (comment) {
|
||||
if (_zip_write(za, comment->raw, comment->length) < 0) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return (zip_int64_t)size;
|
||||
}
|
||||
|
||||
|
||||
zip_dirent_t *
|
||||
_zip_dirent_clone(const zip_dirent_t *sde)
|
||||
{
|
||||
zip_dirent_t *tde;
|
||||
|
||||
if ((tde=(zip_dirent_t *)malloc(sizeof(*tde))) == NULL)
|
||||
return NULL;
|
||||
|
||||
if (sde)
|
||||
memcpy(tde, sde, sizeof(*sde));
|
||||
else
|
||||
_zip_dirent_init(tde);
|
||||
|
||||
tde->changed = 0;
|
||||
tde->cloned = 1;
|
||||
|
||||
return tde;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
_zip_dirent_finalize(zip_dirent_t *zde)
|
||||
{
|
||||
if (!zde->cloned || zde->changed & ZIP_DIRENT_FILENAME) {
|
||||
_zip_string_free(zde->filename);
|
||||
zde->filename = NULL;
|
||||
}
|
||||
if (!zde->cloned || zde->changed & ZIP_DIRENT_EXTRA_FIELD) {
|
||||
_zip_ef_free(zde->extra_fields);
|
||||
zde->extra_fields = NULL;
|
||||
}
|
||||
if (!zde->cloned || zde->changed & ZIP_DIRENT_COMMENT) {
|
||||
_zip_string_free(zde->comment);
|
||||
zde->comment = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
_zip_dirent_free(zip_dirent_t *zde)
|
||||
{
|
||||
if (zde == NULL)
|
||||
return;
|
||||
|
||||
_zip_dirent_finalize(zde);
|
||||
free(zde);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
_zip_dirent_init(zip_dirent_t *de)
|
||||
{
|
||||
de->changed = 0;
|
||||
de->local_extra_fields_read = 0;
|
||||
de->cloned = 0;
|
||||
|
||||
de->version_madeby = 20 | (ZIP_OPSYS_DEFAULT << 8);
|
||||
de->version_needed = 20; /* 2.0 */
|
||||
de->bitflags = 0;
|
||||
de->comp_method = ZIP_CM_DEFAULT;
|
||||
de->last_mod = 0;
|
||||
de->crc = 0;
|
||||
de->comp_size = 0;
|
||||
de->uncomp_size = 0;
|
||||
de->filename = NULL;
|
||||
de->extra_fields = NULL;
|
||||
de->comment = NULL;
|
||||
de->disk_number = 0;
|
||||
de->int_attrib = 0;
|
||||
de->ext_attrib = ZIP_EXT_ATTRIB_DEFAULT;
|
||||
de->offset = 0;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
_zip_dirent_needs_zip64(const zip_dirent_t *de, zip_flags_t flags)
|
||||
{
|
||||
if (de->uncomp_size >= ZIP_UINT32_MAX || de->comp_size >= ZIP_UINT32_MAX
|
||||
|| ((flags & ZIP_FL_CENTRAL) && de->offset >= ZIP_UINT32_MAX))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
zip_dirent_t *
|
||||
_zip_dirent_new(void)
|
||||
{
|
||||
zip_dirent_t *de;
|
||||
|
||||
if ((de=(zip_dirent_t *)malloc(sizeof(*de))) == NULL)
|
||||
return NULL;
|
||||
|
||||
_zip_dirent_init(de);
|
||||
return de;
|
||||
}
|
||||
|
||||
|
||||
/* _zip_dirent_read(zde, fp, bufp, left, localp, error):
|
||||
Fills the zip directory entry zde.
|
||||
|
||||
If buffer is non-NULL, data is taken from there; otherwise data is read from fp as needed.
|
||||
|
||||
If local is true, it reads a local header instead of a central directory entry.
|
||||
|
||||
Returns size of dirent read if successful. On error, error is filled in and -1 is returned.
|
||||
*/
|
||||
|
||||
zip_int64_t
|
||||
_zip_dirent_read(zip_dirent_t *zde, zip_source_t *src, zip_buffer_t *buffer, bool local, zip_error_t *error)
|
||||
{
|
||||
zip_uint8_t buf[CDENTRYSIZE];
|
||||
zip_uint16_t dostime, dosdate;
|
||||
zip_uint32_t size, variable_size;
|
||||
zip_uint16_t filename_len, comment_len, ef_len;
|
||||
|
||||
bool from_buffer = (buffer != NULL);
|
||||
|
||||
size = local ? LENTRYSIZE : CDENTRYSIZE;
|
||||
|
||||
if (buffer) {
|
||||
if (_zip_buffer_left(buffer) < size) {
|
||||
zip_error_set(error, ZIP_ER_NOZIP, 0);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if ((buffer = _zip_buffer_new_from_source(src, size, buf, error)) == NULL) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (memcmp(_zip_buffer_get(buffer, 4), (local ? LOCAL_MAGIC : CENTRAL_MAGIC), 4) != 0) {
|
||||
zip_error_set(error, ZIP_ER_NOZIP, 0);
|
||||
if (!from_buffer) {
|
||||
_zip_buffer_free(buffer);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* convert buffercontents to zip_dirent */
|
||||
|
||||
_zip_dirent_init(zde);
|
||||
if (!local)
|
||||
zde->version_madeby = _zip_buffer_get_16(buffer);
|
||||
else
|
||||
zde->version_madeby = 0;
|
||||
zde->version_needed = _zip_buffer_get_16(buffer);
|
||||
zde->bitflags = _zip_buffer_get_16(buffer);
|
||||
zde->comp_method = _zip_buffer_get_16(buffer);
|
||||
|
||||
/* convert to time_t */
|
||||
dostime = _zip_buffer_get_16(buffer);
|
||||
dosdate = _zip_buffer_get_16(buffer);
|
||||
zde->last_mod = _zip_d2u_time(dostime, dosdate);
|
||||
|
||||
zde->crc = _zip_buffer_get_32(buffer);
|
||||
zde->comp_size = _zip_buffer_get_32(buffer);
|
||||
zde->uncomp_size = _zip_buffer_get_32(buffer);
|
||||
|
||||
filename_len = _zip_buffer_get_16(buffer);
|
||||
ef_len = _zip_buffer_get_16(buffer);
|
||||
|
||||
if (local) {
|
||||
comment_len = 0;
|
||||
zde->disk_number = 0;
|
||||
zde->int_attrib = 0;
|
||||
zde->ext_attrib = 0;
|
||||
zde->offset = 0;
|
||||
} else {
|
||||
comment_len = _zip_buffer_get_16(buffer);
|
||||
zde->disk_number = _zip_buffer_get_16(buffer);
|
||||
zde->int_attrib = _zip_buffer_get_16(buffer);
|
||||
zde->ext_attrib = _zip_buffer_get_32(buffer);
|
||||
zde->offset = _zip_buffer_get_32(buffer);
|
||||
}
|
||||
|
||||
if (!_zip_buffer_ok(buffer)) {
|
||||
zip_error_set(error, ZIP_ER_INTERNAL, 0);
|
||||
if (!from_buffer) {
|
||||
_zip_buffer_free(buffer);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
zde->filename = NULL;
|
||||
zde->extra_fields = NULL;
|
||||
zde->comment = NULL;
|
||||
|
||||
variable_size = (zip_uint32_t)filename_len+(zip_uint32_t)ef_len+(zip_uint32_t)comment_len;
|
||||
|
||||
if (from_buffer) {
|
||||
if (_zip_buffer_left(buffer) < variable_size) {
|
||||
zip_error_set(error, ZIP_ER_INCONS, 0);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
_zip_buffer_free(buffer);
|
||||
|
||||
if ((buffer = _zip_buffer_new_from_source(src, variable_size, NULL, error)) == NULL) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (filename_len) {
|
||||
zde->filename = _zip_read_string(buffer, src, filename_len, 1, error);
|
||||
if (!zde->filename) {
|
||||
if (zip_error_code_zip(error) == ZIP_ER_EOF) {
|
||||
zip_error_set(error, ZIP_ER_INCONS, 0);
|
||||
}
|
||||
if (!from_buffer) {
|
||||
_zip_buffer_free(buffer);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (zde->bitflags & ZIP_GPBF_ENCODING_UTF_8) {
|
||||
if (_zip_guess_encoding(zde->filename, ZIP_ENCODING_UTF8_KNOWN) == ZIP_ENCODING_ERROR) {
|
||||
zip_error_set(error, ZIP_ER_INCONS, 0);
|
||||
if (!from_buffer) {
|
||||
_zip_buffer_free(buffer);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ef_len) {
|
||||
zip_uint8_t *ef = _zip_read_data(buffer, src, ef_len, 0, error);
|
||||
|
||||
if (ef == NULL) {
|
||||
if (!from_buffer) {
|
||||
_zip_buffer_free(buffer);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
if (!_zip_ef_parse(ef, ef_len, local ? ZIP_EF_LOCAL : ZIP_EF_CENTRAL, &zde->extra_fields, error)) {
|
||||
free(ef);
|
||||
if (!from_buffer) {
|
||||
_zip_buffer_free(buffer);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
free(ef);
|
||||
if (local)
|
||||
zde->local_extra_fields_read = 1;
|
||||
}
|
||||
|
||||
if (comment_len) {
|
||||
zde->comment = _zip_read_string(buffer, src, comment_len, 0, error);
|
||||
if (!zde->comment) {
|
||||
if (!from_buffer) {
|
||||
_zip_buffer_free(buffer);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
if (zde->bitflags & ZIP_GPBF_ENCODING_UTF_8) {
|
||||
if (_zip_guess_encoding(zde->comment, ZIP_ENCODING_UTF8_KNOWN) == ZIP_ENCODING_ERROR) {
|
||||
zip_error_set(error, ZIP_ER_INCONS, 0);
|
||||
if (!from_buffer) {
|
||||
_zip_buffer_free(buffer);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
zde->filename = _zip_dirent_process_ef_utf_8(zde, ZIP_EF_UTF_8_NAME, zde->filename);
|
||||
zde->comment = _zip_dirent_process_ef_utf_8(zde, ZIP_EF_UTF_8_COMMENT, zde->comment);
|
||||
|
||||
/* Zip64 */
|
||||
|
||||
if (zde->uncomp_size == ZIP_UINT32_MAX || zde->comp_size == ZIP_UINT32_MAX || zde->offset == ZIP_UINT32_MAX) {
|
||||
zip_uint16_t got_len;
|
||||
zip_buffer_t *ef_buffer;
|
||||
const zip_uint8_t *ef = _zip_ef_get_by_id(zde->extra_fields, &got_len, ZIP_EF_ZIP64, 0, local ? ZIP_EF_LOCAL : ZIP_EF_CENTRAL, error);
|
||||
/* TODO: if got_len == 0 && !ZIP64_EOCD: no error, 0xffffffff is valid value */
|
||||
if (ef == NULL) {
|
||||
if (!from_buffer) {
|
||||
_zip_buffer_free(buffer);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((ef_buffer = _zip_buffer_new((zip_uint8_t *)ef, got_len)) == NULL) {
|
||||
zip_error_set(error, ZIP_ER_MEMORY, 0);
|
||||
if (!from_buffer) {
|
||||
_zip_buffer_free(buffer);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (zde->uncomp_size == ZIP_UINT32_MAX)
|
||||
zde->uncomp_size = _zip_buffer_get_64(ef_buffer);
|
||||
else if (local) {
|
||||
/* From appnote.txt: This entry in the Local header MUST
|
||||
include BOTH original and compressed file size fields. */
|
||||
(void)_zip_buffer_skip(ef_buffer, 8); /* error is caught by _zip_buffer_eof() call */
|
||||
}
|
||||
if (zde->comp_size == ZIP_UINT32_MAX)
|
||||
zde->comp_size = _zip_buffer_get_64(ef_buffer);
|
||||
if (!local) {
|
||||
if (zde->offset == ZIP_UINT32_MAX)
|
||||
zde->offset = _zip_buffer_get_64(ef_buffer);
|
||||
if (zde->disk_number == ZIP_UINT16_MAX)
|
||||
zde->disk_number = _zip_buffer_get_32(buffer);
|
||||
}
|
||||
|
||||
if (!_zip_buffer_eof(ef_buffer)) {
|
||||
zip_error_set(error, ZIP_ER_INCONS, 0);
|
||||
_zip_buffer_free(ef_buffer);
|
||||
if (!from_buffer) {
|
||||
_zip_buffer_free(buffer);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
_zip_buffer_free(ef_buffer);
|
||||
}
|
||||
|
||||
if (!_zip_buffer_ok(buffer)) {
|
||||
zip_error_set(error, ZIP_ER_INTERNAL, 0);
|
||||
if (!from_buffer) {
|
||||
_zip_buffer_free(buffer);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
if (!from_buffer) {
|
||||
_zip_buffer_free(buffer);
|
||||
}
|
||||
|
||||
/* zip_source_seek / zip_source_tell don't support values > ZIP_INT64_MAX */
|
||||
if (zde->offset > ZIP_INT64_MAX) {
|
||||
zip_error_set(error, ZIP_ER_SEEK, EFBIG);
|
||||
return -1;
|
||||
}
|
||||
|
||||
zde->extra_fields = _zip_ef_remove_internal(zde->extra_fields);
|
||||
|
||||
return (zip_int64_t)(size + variable_size);
|
||||
}
|
||||
|
||||
|
||||
static zip_string_t *
|
||||
_zip_dirent_process_ef_utf_8(const zip_dirent_t *de, zip_uint16_t id, zip_string_t *str)
|
||||
{
|
||||
zip_uint16_t ef_len;
|
||||
zip_uint32_t ef_crc;
|
||||
zip_buffer_t *buffer;
|
||||
|
||||
const zip_uint8_t *ef = _zip_ef_get_by_id(de->extra_fields, &ef_len, id, 0, ZIP_EF_BOTH, NULL);
|
||||
|
||||
if (ef == NULL || ef_len < 5 || ef[0] != 1) {
|
||||
return str;
|
||||
}
|
||||
|
||||
if ((buffer = _zip_buffer_new((zip_uint8_t *)ef, ef_len)) == NULL) {
|
||||
return str;
|
||||
}
|
||||
|
||||
_zip_buffer_get_8(buffer);
|
||||
ef_crc = _zip_buffer_get_32(buffer);
|
||||
|
||||
if (_zip_string_crc32(str) == ef_crc) {
|
||||
zip_uint16_t len = (zip_uint16_t)_zip_buffer_left(buffer);
|
||||
zip_string_t *ef_str = _zip_string_new(_zip_buffer_get(buffer, len), len, ZIP_FL_ENC_UTF_8, NULL);
|
||||
|
||||
if (ef_str != NULL) {
|
||||
_zip_string_free(str);
|
||||
str = ef_str;
|
||||
}
|
||||
}
|
||||
|
||||
_zip_buffer_free(buffer);
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
|
||||
zip_int32_t
|
||||
_zip_dirent_size(zip_source_t *src, zip_uint16_t flags, zip_error_t *error)
|
||||
{
|
||||
zip_int32_t size;
|
||||
bool local = (flags & ZIP_EF_LOCAL) != 0;
|
||||
int i;
|
||||
zip_uint8_t b[6];
|
||||
zip_buffer_t *buffer;
|
||||
|
||||
size = local ? LENTRYSIZE : CDENTRYSIZE;
|
||||
|
||||
if (zip_source_seek(src, local ? 26 : 28, SEEK_CUR) < 0) {
|
||||
_zip_error_set_from_source(error, src);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((buffer = _zip_buffer_new_from_source(src, local ? 4 : 6, b, error)) == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (i=0; i<(local ? 2 : 3); i++) {
|
||||
size += _zip_buffer_get_16(buffer);
|
||||
}
|
||||
|
||||
if (!_zip_buffer_eof(buffer)) {
|
||||
zip_error_set(error, ZIP_ER_INTERNAL, 0);
|
||||
_zip_buffer_free(buffer);
|
||||
return -1;
|
||||
}
|
||||
|
||||
_zip_buffer_free(buffer);
|
||||
return size;
|
||||
}
|
||||
|
||||
|
||||
/* _zip_dirent_write
|
||||
Writes zip directory entry.
|
||||
|
||||
If flags & ZIP_EF_LOCAL, it writes a local header instead of a central
|
||||
directory entry. If flags & ZIP_EF_FORCE_ZIP64, a ZIP64 extra field is written, even if not needed.
|
||||
|
||||
Returns 0 if successful, 1 if successful and wrote ZIP64 extra field. On error, error is filled in and -1 is
|
||||
returned.
|
||||
*/
|
||||
|
||||
int
|
||||
_zip_dirent_write(zip_t *za, zip_dirent_t *de, zip_flags_t flags)
|
||||
{
|
||||
zip_uint16_t dostime, dosdate;
|
||||
zip_encoding_type_t com_enc, name_enc;
|
||||
zip_extra_field_t *ef;
|
||||
zip_extra_field_t *ef64;
|
||||
zip_uint32_t ef_total_size;
|
||||
bool is_zip64;
|
||||
bool is_really_zip64;
|
||||
zip_uint8_t buf[CDENTRYSIZE];
|
||||
zip_buffer_t *buffer;
|
||||
|
||||
ef = NULL;
|
||||
|
||||
name_enc = _zip_guess_encoding(de->filename, ZIP_ENCODING_UNKNOWN);
|
||||
com_enc = _zip_guess_encoding(de->comment, ZIP_ENCODING_UNKNOWN);
|
||||
|
||||
if ((name_enc == ZIP_ENCODING_UTF8_KNOWN && com_enc == ZIP_ENCODING_ASCII) ||
|
||||
(name_enc == ZIP_ENCODING_ASCII && com_enc == ZIP_ENCODING_UTF8_KNOWN) ||
|
||||
(name_enc == ZIP_ENCODING_UTF8_KNOWN && com_enc == ZIP_ENCODING_UTF8_KNOWN))
|
||||
de->bitflags |= ZIP_GPBF_ENCODING_UTF_8;
|
||||
else {
|
||||
de->bitflags &= (zip_uint16_t)~ZIP_GPBF_ENCODING_UTF_8;
|
||||
if (name_enc == ZIP_ENCODING_UTF8_KNOWN) {
|
||||
ef = _zip_ef_utf8(ZIP_EF_UTF_8_NAME, de->filename, &za->error);
|
||||
if (ef == NULL)
|
||||
return -1;
|
||||
}
|
||||
if ((flags & ZIP_FL_LOCAL) == 0 && com_enc == ZIP_ENCODING_UTF8_KNOWN){
|
||||
zip_extra_field_t *ef2 = _zip_ef_utf8(ZIP_EF_UTF_8_COMMENT, de->comment, &za->error);
|
||||
if (ef2 == NULL) {
|
||||
_zip_ef_free(ef);
|
||||
return -1;
|
||||
}
|
||||
ef2->next = ef;
|
||||
ef = ef2;
|
||||
}
|
||||
}
|
||||
|
||||
is_really_zip64 = _zip_dirent_needs_zip64(de, flags);
|
||||
is_zip64 = (flags & (ZIP_FL_LOCAL|ZIP_FL_FORCE_ZIP64)) == (ZIP_FL_LOCAL|ZIP_FL_FORCE_ZIP64) || is_really_zip64;
|
||||
|
||||
if (is_zip64) {
|
||||
zip_uint8_t ef_zip64[EFZIP64SIZE];
|
||||
zip_buffer_t *ef_buffer = _zip_buffer_new(ef_zip64, sizeof(ef_zip64));
|
||||
if (ef_buffer == NULL) {
|
||||
zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
|
||||
_zip_ef_free(ef);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (flags & ZIP_FL_LOCAL) {
|
||||
if ((flags & ZIP_FL_FORCE_ZIP64) || de->comp_size > ZIP_UINT32_MAX || de->uncomp_size > ZIP_UINT32_MAX) {
|
||||
_zip_buffer_put_64(ef_buffer, de->uncomp_size);
|
||||
_zip_buffer_put_64(ef_buffer, de->comp_size);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if ((flags & ZIP_FL_FORCE_ZIP64) || de->comp_size > ZIP_UINT32_MAX || de->uncomp_size > ZIP_UINT32_MAX || de->offset > ZIP_UINT32_MAX) {
|
||||
if (de->uncomp_size >= ZIP_UINT32_MAX) {
|
||||
_zip_buffer_put_64(ef_buffer, de->uncomp_size);
|
||||
}
|
||||
if (de->comp_size >= ZIP_UINT32_MAX) {
|
||||
_zip_buffer_put_64(ef_buffer, de->comp_size);
|
||||
}
|
||||
if (de->offset >= ZIP_UINT32_MAX) {
|
||||
_zip_buffer_put_64(ef_buffer, de->offset);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!_zip_buffer_ok(ef_buffer)) {
|
||||
zip_error_set(&za->error, ZIP_ER_INTERNAL, 0);
|
||||
_zip_buffer_free(ef_buffer);
|
||||
_zip_ef_free(ef);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ef64 = _zip_ef_new(ZIP_EF_ZIP64, (zip_uint16_t)(_zip_buffer_offset(ef_buffer)), ef_zip64, ZIP_EF_BOTH);
|
||||
_zip_buffer_free(ef_buffer);
|
||||
ef64->next = ef;
|
||||
ef = ef64;
|
||||
}
|
||||
|
||||
if ((buffer = _zip_buffer_new(buf, sizeof(buf))) == NULL) {
|
||||
zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
|
||||
_zip_ef_free(ef);
|
||||
return -1;
|
||||
}
|
||||
|
||||
_zip_buffer_put(buffer, (flags & ZIP_FL_LOCAL) ? LOCAL_MAGIC : CENTRAL_MAGIC, 4);
|
||||
|
||||
if ((flags & ZIP_FL_LOCAL) == 0) {
|
||||
_zip_buffer_put_16(buffer, (zip_uint16_t)(is_really_zip64 ? 45 : de->version_madeby));
|
||||
}
|
||||
_zip_buffer_put_16(buffer, (zip_uint16_t)(is_really_zip64 ? 45 : de->version_needed));
|
||||
_zip_buffer_put_16(buffer, de->bitflags&0xfff9); /* clear compression method specific flags */
|
||||
_zip_buffer_put_16(buffer, (zip_uint16_t)de->comp_method);
|
||||
|
||||
_zip_u2d_time(de->last_mod, &dostime, &dosdate);
|
||||
_zip_buffer_put_16(buffer, dostime);
|
||||
_zip_buffer_put_16(buffer, dosdate);
|
||||
|
||||
_zip_buffer_put_32(buffer, de->crc);
|
||||
|
||||
if (((flags & ZIP_FL_LOCAL) == ZIP_FL_LOCAL) && ((de->comp_size >= ZIP_UINT32_MAX) || (de->uncomp_size >= ZIP_UINT32_MAX))) {
|
||||
/* In local headers, if a ZIP64 EF is written, it MUST contain
|
||||
* both compressed and uncompressed sizes (even if one of the
|
||||
* two is smaller than 0xFFFFFFFF); on the other hand, those
|
||||
* may only appear when the corresponding standard entry is
|
||||
* 0xFFFFFFFF. (appnote.txt 4.5.3) */
|
||||
_zip_buffer_put_32(buffer, ZIP_UINT32_MAX);
|
||||
_zip_buffer_put_32(buffer, ZIP_UINT32_MAX);
|
||||
}
|
||||
else {
|
||||
if (de->comp_size < ZIP_UINT32_MAX) {
|
||||
_zip_buffer_put_32(buffer, (zip_uint32_t)de->comp_size);
|
||||
}
|
||||
else {
|
||||
_zip_buffer_put_32(buffer, ZIP_UINT32_MAX);
|
||||
}
|
||||
if (de->uncomp_size < ZIP_UINT32_MAX) {
|
||||
_zip_buffer_put_32(buffer, (zip_uint32_t)de->uncomp_size);
|
||||
}
|
||||
else {
|
||||
_zip_buffer_put_32(buffer, ZIP_UINT32_MAX);
|
||||
}
|
||||
}
|
||||
|
||||
_zip_buffer_put_16(buffer, _zip_string_length(de->filename));
|
||||
/* TODO: check for overflow */
|
||||
ef_total_size = (zip_uint32_t)_zip_ef_size(de->extra_fields, flags) + (zip_uint32_t)_zip_ef_size(ef, ZIP_EF_BOTH);
|
||||
_zip_buffer_put_16(buffer, (zip_uint16_t)ef_total_size);
|
||||
|
||||
if ((flags & ZIP_FL_LOCAL) == 0) {
|
||||
_zip_buffer_put_16(buffer, _zip_string_length(de->comment));
|
||||
_zip_buffer_put_16(buffer, (zip_uint16_t)de->disk_number);
|
||||
_zip_buffer_put_16(buffer, de->int_attrib);
|
||||
_zip_buffer_put_32(buffer, de->ext_attrib);
|
||||
if (de->offset < ZIP_UINT32_MAX)
|
||||
_zip_buffer_put_32(buffer, (zip_uint32_t)de->offset);
|
||||
else
|
||||
_zip_buffer_put_32(buffer, ZIP_UINT32_MAX);
|
||||
}
|
||||
|
||||
if (!_zip_buffer_ok(buffer)) {
|
||||
zip_error_set(&za->error, ZIP_ER_INTERNAL, 0);
|
||||
_zip_buffer_free(buffer);
|
||||
_zip_ef_free(ef);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (_zip_write(za, buf, _zip_buffer_offset(buffer)) < 0) {
|
||||
_zip_buffer_free(buffer);
|
||||
_zip_ef_free(ef);
|
||||
return -1;
|
||||
}
|
||||
|
||||
_zip_buffer_free(buffer);
|
||||
|
||||
if (de->filename) {
|
||||
if (_zip_string_write(za, de->filename) < 0) {
|
||||
_zip_ef_free(ef);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (ef) {
|
||||
if (_zip_ef_write(za, ef, ZIP_EF_BOTH) < 0) {
|
||||
_zip_ef_free(ef);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
_zip_ef_free(ef);
|
||||
if (de->extra_fields) {
|
||||
if (_zip_ef_write(za, de->extra_fields, flags) < 0) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if ((flags & ZIP_FL_LOCAL) == 0) {
|
||||
if (de->comment) {
|
||||
if (_zip_string_write(za, de->comment) < 0) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return is_zip64;
|
||||
}
|
||||
|
||||
|
||||
static time_t
|
||||
_zip_d2u_time(zip_uint16_t dtime, zip_uint16_t ddate)
|
||||
{
|
||||
struct tm tm;
|
||||
|
||||
memset(&tm, 0, sizeof(tm));
|
||||
|
||||
/* let mktime decide if DST is in effect */
|
||||
tm.tm_isdst = -1;
|
||||
|
||||
tm.tm_year = ((ddate>>9)&127) + 1980 - 1900;
|
||||
tm.tm_mon = ((ddate>>5)&15) - 1;
|
||||
tm.tm_mday = ddate&31;
|
||||
|
||||
tm.tm_hour = (dtime>>11)&31;
|
||||
tm.tm_min = (dtime>>5)&63;
|
||||
tm.tm_sec = (dtime<<1)&62;
|
||||
|
||||
return mktime(&tm);
|
||||
}
|
||||
|
||||
|
||||
static zip_extra_field_t *
|
||||
_zip_ef_utf8(zip_uint16_t id, zip_string_t *str, zip_error_t *error)
|
||||
{
|
||||
const zip_uint8_t *raw;
|
||||
zip_uint32_t len;
|
||||
zip_buffer_t *buffer;
|
||||
zip_extra_field_t *ef;
|
||||
|
||||
if ((raw=_zip_string_get(str, &len, ZIP_FL_ENC_RAW, NULL)) == NULL) {
|
||||
/* error already set */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (len+5 > ZIP_UINT16_MAX) {
|
||||
zip_error_set(error, ZIP_ER_INVAL, 0); /* TODO: better error code? */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ((buffer = _zip_buffer_new(NULL, len+5)) == NULL) {
|
||||
zip_error_set(error, ZIP_ER_MEMORY, 0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
_zip_buffer_put_8(buffer, 1);
|
||||
_zip_buffer_put_32(buffer, _zip_string_crc32(str));
|
||||
_zip_buffer_put(buffer, raw, len);
|
||||
|
||||
if (!_zip_buffer_ok(buffer)) {
|
||||
zip_error_set(error, ZIP_ER_INTERNAL, 0);
|
||||
_zip_buffer_free(buffer);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ef = _zip_ef_new(id, (zip_uint16_t)(_zip_buffer_offset(buffer)), _zip_buffer_data(buffer), ZIP_EF_BOTH);
|
||||
_zip_buffer_free(buffer);
|
||||
|
||||
return ef;
|
||||
}
|
||||
|
||||
|
||||
zip_dirent_t *
|
||||
_zip_get_dirent(zip_t *za, zip_uint64_t idx, zip_flags_t flags, zip_error_t *error)
|
||||
{
|
||||
if (error == NULL)
|
||||
error = &za->error;
|
||||
|
||||
if (idx >= za->nentry) {
|
||||
zip_error_set(error, ZIP_ER_INVAL, 0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ((flags & ZIP_FL_UNCHANGED) || za->entry[idx].changes == NULL) {
|
||||
if (za->entry[idx].orig == NULL) {
|
||||
zip_error_set(error, ZIP_ER_INVAL, 0);
|
||||
return NULL;
|
||||
}
|
||||
if (za->entry[idx].deleted && (flags & ZIP_FL_UNCHANGED) == 0) {
|
||||
zip_error_set(error, ZIP_ER_DELETED, 0);
|
||||
return NULL;
|
||||
}
|
||||
return za->entry[idx].orig;
|
||||
}
|
||||
else
|
||||
return za->entry[idx].changes;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void
|
||||
_zip_u2d_time(time_t intime, zip_uint16_t *dtime, zip_uint16_t *ddate)
|
||||
{
|
||||
struct tm *tm;
|
||||
|
||||
tm = localtime(&intime);
|
||||
if (tm->tm_year < 80) {
|
||||
tm->tm_year = 80;
|
||||
}
|
||||
|
||||
*ddate = (zip_uint16_t)(((tm->tm_year+1900-1980)<<9) + ((tm->tm_mon+1)<<5) + tm->tm_mday);
|
||||
*dtime = (zip_uint16_t)(((tm->tm_hour)<<11) + ((tm->tm_min)<<5) + ((tm->tm_sec)>>1));
|
||||
|
||||
return;
|
||||
}
|
||||
79
src/Common/libzip/zip_discard.c
Normal file
79
src/Common/libzip/zip_discard.c
Normal file
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
zip_discard.c -- discard and free struct zip
|
||||
Copyright (C) 1999-2015 Dieter Baron and Thomas Klausner
|
||||
|
||||
This file is part of libzip, a library to manipulate ZIP archives.
|
||||
The authors can be contacted at <libzip@nih.at>
|
||||
|
||||
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.
|
||||
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.
|
||||
3. The names of the authors may not be used to endorse or promote
|
||||
products derived from this software without specific prior
|
||||
written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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.
|
||||
*/
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "zipint.h"
|
||||
|
||||
|
||||
/* zip_discard:
|
||||
frees the space allocated to a zipfile struct, and closes the
|
||||
corresponding file. */
|
||||
|
||||
void
|
||||
zip_discard(zip_t *za)
|
||||
{
|
||||
zip_uint64_t i;
|
||||
|
||||
if (za == NULL)
|
||||
return;
|
||||
|
||||
if (za->src) {
|
||||
zip_source_close(za->src);
|
||||
zip_source_free(za->src);
|
||||
}
|
||||
|
||||
free(za->default_password);
|
||||
_zip_string_free(za->comment_orig);
|
||||
_zip_string_free(za->comment_changes);
|
||||
|
||||
_zip_hash_free(za->names);
|
||||
|
||||
if (za->entry) {
|
||||
for (i=0; i<za->nentry; i++)
|
||||
_zip_entry_finalize(za->entry+i);
|
||||
free(za->entry);
|
||||
}
|
||||
|
||||
for (i=0; i<za->nopen_source; i++) {
|
||||
_zip_source_invalidate(za->open_source[i]);
|
||||
}
|
||||
free(za->open_source);
|
||||
|
||||
zip_error_fini(&za->error);
|
||||
|
||||
free(za);
|
||||
|
||||
return;
|
||||
}
|
||||
53
src/Common/libzip/zip_entry.c
Normal file
53
src/Common/libzip/zip_entry.c
Normal file
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
zip_entry.c -- struct zip_entry helper functions
|
||||
Copyright (C) 1999-2014 Dieter Baron and Thomas Klausner
|
||||
|
||||
This file is part of libzip, a library to manipulate ZIP archives.
|
||||
The authors can be contacted at <libzip@nih.at>
|
||||
|
||||
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.
|
||||
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.
|
||||
3. The names of the authors may not be used to endorse or promote
|
||||
products derived from this software without specific prior
|
||||
written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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.
|
||||
*/
|
||||
|
||||
|
||||
#include "zipint.h"
|
||||
|
||||
void
|
||||
_zip_entry_finalize(zip_entry_t *e)
|
||||
{
|
||||
_zip_unchange_data(e);
|
||||
_zip_dirent_free(e->orig);
|
||||
_zip_dirent_free(e->changes);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
_zip_entry_init(zip_entry_t *e)
|
||||
{
|
||||
e->orig = NULL;
|
||||
e->changes = NULL;
|
||||
e->source = NULL;
|
||||
e->deleted = 0;
|
||||
}
|
||||
80
src/Common/libzip/zip_err_str.c
Normal file
80
src/Common/libzip/zip_err_str.c
Normal file
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
This file was generated automatically by ./make_zip_err_str.sh
|
||||
from ./zip.h; make changes there.
|
||||
*/
|
||||
|
||||
#include "zipint.h"
|
||||
|
||||
const char * const _zip_err_str[] = {
|
||||
"No error",
|
||||
"Multi-disk zip archives not supported",
|
||||
"Renaming temporary file failed",
|
||||
"Closing zip archive failed",
|
||||
"Seek error",
|
||||
"Read error",
|
||||
"Write error",
|
||||
"CRC error",
|
||||
"Containing zip archive was closed",
|
||||
"No such file",
|
||||
"File already exists",
|
||||
"Can't open file",
|
||||
"Failure to create temporary file",
|
||||
"Zlib error",
|
||||
"Malloc failure",
|
||||
"Entry has been changed",
|
||||
"Compression method not supported",
|
||||
"Premature end of file",
|
||||
"Invalid argument",
|
||||
"Not a zip archive",
|
||||
"Internal error",
|
||||
"Zip archive inconsistent",
|
||||
"Can't remove file",
|
||||
"Entry has been deleted",
|
||||
"Encryption method not supported",
|
||||
"Read-only archive",
|
||||
"No password provided",
|
||||
"Wrong password provided",
|
||||
"Operation not supported",
|
||||
"Resource still in use",
|
||||
"Tell error",
|
||||
};
|
||||
|
||||
const int _zip_nerr_str = sizeof(_zip_err_str)/sizeof(_zip_err_str[0]);
|
||||
|
||||
#define N ZIP_ET_NONE
|
||||
#define S ZIP_ET_SYS
|
||||
#define Z ZIP_ET_ZLIB
|
||||
|
||||
const int _zip_err_type[] = {
|
||||
N,
|
||||
N,
|
||||
S,
|
||||
S,
|
||||
S,
|
||||
S,
|
||||
S,
|
||||
N,
|
||||
N,
|
||||
N,
|
||||
N,
|
||||
S,
|
||||
S,
|
||||
Z,
|
||||
N,
|
||||
N,
|
||||
N,
|
||||
N,
|
||||
N,
|
||||
N,
|
||||
N,
|
||||
N,
|
||||
S,
|
||||
N,
|
||||
N,
|
||||
N,
|
||||
N,
|
||||
N,
|
||||
N,
|
||||
N,
|
||||
S,
|
||||
};
|
||||
155
src/Common/libzip/zip_error.c
Normal file
155
src/Common/libzip/zip_error.c
Normal file
@@ -0,0 +1,155 @@
|
||||
/*
|
||||
zip_error.c -- zip_error_t helper functions
|
||||
Copyright (C) 1999-2015 Dieter Baron and Thomas Klausner
|
||||
|
||||
This file is part of libzip, a library to manipulate ZIP archives.
|
||||
The authors can be contacted at <libzip@nih.at>
|
||||
|
||||
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.
|
||||
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.
|
||||
3. The names of the authors may not be used to endorse or promote
|
||||
products derived from this software without specific prior
|
||||
written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "zipint.h"
|
||||
|
||||
|
||||
ZIP_EXTERN int
|
||||
zip_error_code_system(const zip_error_t *error) {
|
||||
return error->sys_err;
|
||||
}
|
||||
|
||||
|
||||
ZIP_EXTERN int
|
||||
zip_error_code_zip(const zip_error_t *error) {
|
||||
return error->zip_err;
|
||||
}
|
||||
|
||||
|
||||
ZIP_EXTERN void
|
||||
zip_error_fini(zip_error_t *err)
|
||||
{
|
||||
free(err->str);
|
||||
err->str = NULL;
|
||||
}
|
||||
|
||||
|
||||
ZIP_EXTERN void
|
||||
zip_error_init(zip_error_t *err)
|
||||
{
|
||||
err->zip_err = ZIP_ER_OK;
|
||||
err->sys_err = 0;
|
||||
err->str = NULL;
|
||||
}
|
||||
|
||||
ZIP_EXTERN void
|
||||
zip_error_init_with_code(zip_error_t *error, int ze)
|
||||
{
|
||||
zip_error_init(error);
|
||||
error->zip_err = ze;
|
||||
switch (zip_error_system_type(error)) {
|
||||
case ZIP_ET_SYS:
|
||||
error->sys_err = errno;
|
||||
break;
|
||||
|
||||
default:
|
||||
error->sys_err = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ZIP_EXTERN int
|
||||
zip_error_system_type(const zip_error_t *error) {
|
||||
if (error->zip_err < 0 || error->zip_err >= _zip_nerr_str)
|
||||
return ZIP_ET_NONE;
|
||||
|
||||
return _zip_err_type[error->zip_err];
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
_zip_error_clear(zip_error_t *err)
|
||||
{
|
||||
if (err == NULL)
|
||||
return;
|
||||
|
||||
err->zip_err = ZIP_ER_OK;
|
||||
err->sys_err = 0;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
_zip_error_copy(zip_error_t *dst, const zip_error_t *src)
|
||||
{
|
||||
dst->zip_err = src->zip_err;
|
||||
dst->sys_err = src->sys_err;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
_zip_error_get(const zip_error_t *err, int *zep, int *sep)
|
||||
{
|
||||
if (zep)
|
||||
*zep = err->zip_err;
|
||||
if (sep) {
|
||||
if (zip_error_system_type(err) != ZIP_ET_NONE)
|
||||
*sep = err->sys_err;
|
||||
else
|
||||
*sep = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
zip_error_set(zip_error_t *err, int ze, int se)
|
||||
{
|
||||
if (err) {
|
||||
err->zip_err = ze;
|
||||
err->sys_err = se;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
_zip_error_set_from_source(zip_error_t *err, zip_source_t *src)
|
||||
{
|
||||
_zip_error_copy(err, zip_source_error(src));
|
||||
}
|
||||
|
||||
|
||||
zip_int64_t
|
||||
zip_error_to_data(const zip_error_t *error, void *data, zip_uint64_t length)
|
||||
{
|
||||
int *e = (int *)data;
|
||||
|
||||
if (length < sizeof(int)*2) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
e[0] = zip_error_code_zip(error);
|
||||
e[1] = zip_error_code_system(error);
|
||||
return sizeof(int)*2;
|
||||
}
|
||||
45
src/Common/libzip/zip_error_clear.c
Normal file
45
src/Common/libzip/zip_error_clear.c
Normal file
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
zip_error_clear.c -- clear zip error
|
||||
Copyright (C) 1999-2014 Dieter Baron and Thomas Klausner
|
||||
|
||||
This file is part of libzip, a library to manipulate ZIP archives.
|
||||
The authors can be contacted at <libzip@nih.at>
|
||||
|
||||
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.
|
||||
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.
|
||||
3. The names of the authors may not be used to endorse or promote
|
||||
products derived from this software without specific prior
|
||||
written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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.
|
||||
*/
|
||||
|
||||
|
||||
#include "zipint.h"
|
||||
|
||||
|
||||
ZIP_EXTERN void
|
||||
zip_error_clear(zip_t *za)
|
||||
{
|
||||
if (za == NULL)
|
||||
return;
|
||||
|
||||
_zip_error_clear(&za->error);
|
||||
}
|
||||
57
src/Common/libzip/zip_error_get.c
Normal file
57
src/Common/libzip/zip_error_get.c
Normal file
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
zip_error_get.c -- get zip error
|
||||
Copyright (C) 1999-2014 Dieter Baron and Thomas Klausner
|
||||
|
||||
This file is part of libzip, a library to manipulate ZIP archives.
|
||||
The authors can be contacted at <libzip@nih.at>
|
||||
|
||||
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.
|
||||
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.
|
||||
3. The names of the authors may not be used to endorse or promote
|
||||
products derived from this software without specific prior
|
||||
written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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.
|
||||
*/
|
||||
|
||||
|
||||
#define _ZIP_COMPILING_DEPRECATED
|
||||
#include "zipint.h"
|
||||
|
||||
|
||||
ZIP_EXTERN void
|
||||
zip_error_get(zip_t *za, int *zep, int *sep)
|
||||
{
|
||||
_zip_error_get(&za->error, zep, sep);
|
||||
}
|
||||
|
||||
|
||||
ZIP_EXTERN zip_error_t *
|
||||
zip_get_error(zip_t *za)
|
||||
{
|
||||
return &za->error;
|
||||
}
|
||||
|
||||
|
||||
ZIP_EXTERN zip_error_t *
|
||||
zip_file_get_error(zip_file_t *f)
|
||||
{
|
||||
return &f->error;
|
||||
}
|
||||
45
src/Common/libzip/zip_error_get_sys_type.c
Normal file
45
src/Common/libzip/zip_error_get_sys_type.c
Normal file
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
zip_error_get_sys_type.c -- return type of system error code
|
||||
Copyright (C) 1999-2014 Dieter Baron and Thomas Klausner
|
||||
|
||||
This file is part of libzip, a library to manipulate ZIP archives.
|
||||
The authors can be contacted at <libzip@nih.at>
|
||||
|
||||
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.
|
||||
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.
|
||||
3. The names of the authors may not be used to endorse or promote
|
||||
products derived from this software without specific prior
|
||||
written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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.
|
||||
*/
|
||||
|
||||
#define _ZIP_COMPILING_DEPRECATED
|
||||
#include "zipint.h"
|
||||
|
||||
|
||||
ZIP_EXTERN int
|
||||
zip_error_get_sys_type(int ze)
|
||||
{
|
||||
if (ze < 0 || ze >= _zip_nerr_str)
|
||||
return 0;
|
||||
|
||||
return _zip_err_type[ze];
|
||||
}
|
||||
87
src/Common/libzip/zip_error_strerror.c
Normal file
87
src/Common/libzip/zip_error_strerror.c
Normal file
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
zip_error_sterror.c -- get string representation of struct zip_error
|
||||
Copyright (C) 1999-2015 Dieter Baron and Thomas Klausner
|
||||
|
||||
This file is part of libzip, a library to manipulate ZIP archives.
|
||||
The authors can be contacted at <libzip@nih.at>
|
||||
|
||||
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.
|
||||
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.
|
||||
3. The names of the authors may not be used to endorse or promote
|
||||
products derived from this software without specific prior
|
||||
written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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.
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "zipint.h"
|
||||
|
||||
|
||||
ZIP_EXTERN const char *
|
||||
zip_error_strerror(zip_error_t *err)
|
||||
{
|
||||
const char *zs, *ss;
|
||||
char buf[128], *s;
|
||||
|
||||
zip_error_fini(err);
|
||||
|
||||
if (err->zip_err < 0 || err->zip_err >= _zip_nerr_str) {
|
||||
sprintf(buf, "Unknown error %d", err->zip_err);
|
||||
zs = NULL;
|
||||
ss = buf;
|
||||
}
|
||||
else {
|
||||
zs = _zip_err_str[err->zip_err];
|
||||
|
||||
switch (_zip_err_type[err->zip_err]) {
|
||||
case ZIP_ET_SYS:
|
||||
ss = strerror(err->sys_err);
|
||||
break;
|
||||
|
||||
case ZIP_ET_ZLIB:
|
||||
ss = zError(err->sys_err);
|
||||
break;
|
||||
|
||||
default:
|
||||
ss = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (ss == NULL)
|
||||
return zs;
|
||||
else {
|
||||
if ((s=(char *)malloc(strlen(ss)
|
||||
+ (zs ? strlen(zs)+2 : 0) + 1)) == NULL)
|
||||
return _zip_err_str[ZIP_ER_MEMORY];
|
||||
|
||||
sprintf(s, "%s%s%s",
|
||||
(zs ? zs : ""),
|
||||
(zs ? ": " : ""),
|
||||
ss);
|
||||
err->str = s;
|
||||
|
||||
return s;
|
||||
}
|
||||
}
|
||||
68
src/Common/libzip/zip_error_to_str.c
Normal file
68
src/Common/libzip/zip_error_to_str.c
Normal file
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
zip_error_to_str.c -- get string representation of zip error code
|
||||
Copyright (C) 1999-2015 Dieter Baron and Thomas Klausner
|
||||
|
||||
This file is part of libzip, a library to manipulate ZIP archives.
|
||||
The authors can be contacted at <libzip@nih.at>
|
||||
|
||||
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.
|
||||
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.
|
||||
3. The names of the authors may not be used to endorse or promote
|
||||
products derived from this software without specific prior
|
||||
written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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.
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#define _ZIP_COMPILING_DEPRECATED
|
||||
#include "zipint.h"
|
||||
|
||||
|
||||
ZIP_EXTERN int
|
||||
zip_error_to_str(char *buf, zip_uint64_t len, int ze, int se)
|
||||
{
|
||||
const char *zs, *ss;
|
||||
|
||||
if (ze < 0 || ze >= _zip_nerr_str)
|
||||
return snprintf(buf, len, "Unknown error %d", ze);
|
||||
|
||||
zs = _zip_err_str[ze];
|
||||
|
||||
switch (_zip_err_type[ze]) {
|
||||
case ZIP_ET_SYS:
|
||||
ss = strerror(se);
|
||||
break;
|
||||
|
||||
case ZIP_ET_ZLIB:
|
||||
ss = zError(se);
|
||||
break;
|
||||
|
||||
default:
|
||||
ss = NULL;
|
||||
}
|
||||
|
||||
return snprintf(buf, len, "%s%s%s",
|
||||
zs, (ss ? ": " : ""), (ss ? ss : ""));
|
||||
}
|
||||
438
src/Common/libzip/zip_extra_field.c
Normal file
438
src/Common/libzip/zip_extra_field.c
Normal file
@@ -0,0 +1,438 @@
|
||||
/*
|
||||
zip_extra_field.c -- manipulate extra fields
|
||||
Copyright (C) 2012-2015 Dieter Baron and Thomas Klausner
|
||||
|
||||
This file is part of libzip, a library to manipulate ZIP archives.
|
||||
The authors can be contacted at <libzip@nih.at>
|
||||
|
||||
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.
|
||||
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.
|
||||
3. The names of the authors may not be used to endorse or promote
|
||||
products derived from this software without specific prior
|
||||
written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "zipint.h"
|
||||
|
||||
|
||||
zip_extra_field_t *
|
||||
_zip_ef_clone(const zip_extra_field_t *ef, zip_error_t *error)
|
||||
{
|
||||
zip_extra_field_t *head, *prev, *def;
|
||||
|
||||
head = prev = NULL;
|
||||
|
||||
while (ef) {
|
||||
if ((def=_zip_ef_new(ef->id, ef->size, ef->data, ef->flags)) == NULL) {
|
||||
zip_error_set(error, ZIP_ER_MEMORY, 0);
|
||||
_zip_ef_free(head);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (head == NULL)
|
||||
head = def;
|
||||
if (prev)
|
||||
prev->next = def;
|
||||
prev = def;
|
||||
|
||||
ef = ef->next;
|
||||
}
|
||||
|
||||
return head;
|
||||
}
|
||||
|
||||
|
||||
zip_extra_field_t *
|
||||
_zip_ef_delete_by_id(zip_extra_field_t *ef, zip_uint16_t id, zip_uint16_t id_idx, zip_flags_t flags)
|
||||
{
|
||||
zip_extra_field_t *head, *prev;
|
||||
int i;
|
||||
|
||||
i = 0;
|
||||
head = ef;
|
||||
prev = NULL;
|
||||
for (; ef; ef=(prev ? prev->next : head)) {
|
||||
if ((ef->flags & flags & ZIP_EF_BOTH) && ((ef->id == id) || (id == ZIP_EXTRA_FIELD_ALL))) {
|
||||
if (id_idx == ZIP_EXTRA_FIELD_ALL || i == id_idx) {
|
||||
ef->flags &= ~(flags & ZIP_EF_BOTH);
|
||||
if ((ef->flags & ZIP_EF_BOTH) == 0) {
|
||||
if (prev)
|
||||
prev->next = ef->next;
|
||||
else
|
||||
head = ef->next;
|
||||
ef->next = NULL;
|
||||
_zip_ef_free(ef);
|
||||
|
||||
if (id_idx == ZIP_EXTRA_FIELD_ALL)
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
i++;
|
||||
if (i > id_idx)
|
||||
break;
|
||||
}
|
||||
prev = ef;
|
||||
}
|
||||
|
||||
return head;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
_zip_ef_free(zip_extra_field_t *ef)
|
||||
{
|
||||
zip_extra_field_t *ef2;
|
||||
|
||||
while (ef) {
|
||||
ef2 = ef->next;
|
||||
free(ef->data);
|
||||
free(ef);
|
||||
ef = ef2;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const zip_uint8_t *
|
||||
_zip_ef_get_by_id(const zip_extra_field_t *ef, zip_uint16_t *lenp, zip_uint16_t id, zip_uint16_t id_idx, zip_flags_t flags, zip_error_t *error)
|
||||
{
|
||||
static const zip_uint8_t empty[1] = { '\0' };
|
||||
|
||||
int i;
|
||||
|
||||
i = 0;
|
||||
for (; ef; ef=ef->next) {
|
||||
if (ef->id == id && (ef->flags & flags & ZIP_EF_BOTH)) {
|
||||
if (i < id_idx) {
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (lenp)
|
||||
*lenp = ef->size;
|
||||
if (ef->size > 0)
|
||||
return ef->data;
|
||||
else
|
||||
return empty;
|
||||
}
|
||||
}
|
||||
|
||||
zip_error_set(error, ZIP_ER_NOENT, 0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
zip_extra_field_t *
|
||||
_zip_ef_merge(zip_extra_field_t *to, zip_extra_field_t *from)
|
||||
{
|
||||
zip_extra_field_t *ef2, *tt, *tail;
|
||||
int duplicate;
|
||||
|
||||
if (to == NULL)
|
||||
return from;
|
||||
|
||||
for (tail=to; tail->next; tail=tail->next)
|
||||
;
|
||||
|
||||
for (; from; from=ef2) {
|
||||
ef2 = from->next;
|
||||
|
||||
duplicate = 0;
|
||||
for (tt=to; tt; tt=tt->next) {
|
||||
if (tt->id == from->id && tt->size == from->size && memcmp(tt->data, from->data, tt->size) == 0) {
|
||||
tt->flags |= (from->flags & ZIP_EF_BOTH);
|
||||
duplicate = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
from->next = NULL;
|
||||
if (duplicate)
|
||||
_zip_ef_free(from);
|
||||
else
|
||||
tail = tail->next = from;
|
||||
}
|
||||
|
||||
return to;
|
||||
}
|
||||
|
||||
|
||||
zip_extra_field_t *
|
||||
_zip_ef_new(zip_uint16_t id, zip_uint16_t size, const zip_uint8_t *data, zip_flags_t flags)
|
||||
{
|
||||
zip_extra_field_t *ef;
|
||||
|
||||
if ((ef=(zip_extra_field_t *)malloc(sizeof(*ef))) == NULL)
|
||||
return NULL;
|
||||
|
||||
ef->next = NULL;
|
||||
ef->flags = flags;
|
||||
ef->id = id;
|
||||
ef->size = size;
|
||||
if (size > 0) {
|
||||
if ((ef->data=(zip_uint8_t *)_zip_memdup(data, size, NULL)) == NULL) {
|
||||
free(ef);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
ef->data = NULL;
|
||||
|
||||
return ef;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
_zip_ef_parse(const zip_uint8_t *data, zip_uint16_t len, zip_flags_t flags, zip_extra_field_t **ef_head_p, zip_error_t *error)
|
||||
{
|
||||
zip_buffer_t *buffer;
|
||||
zip_extra_field_t *ef, *ef2, *ef_head;
|
||||
|
||||
if ((buffer = _zip_buffer_new((zip_uint8_t *)data, len)) == NULL) {
|
||||
zip_error_set(error, ZIP_ER_MEMORY, 0);
|
||||
return false;
|
||||
}
|
||||
|
||||
ef_head = ef = NULL;
|
||||
|
||||
while (_zip_buffer_ok(buffer) && _zip_buffer_left(buffer) >= 4) {
|
||||
zip_uint16_t fid, flen;
|
||||
zip_uint8_t *ef_data;
|
||||
|
||||
fid = _zip_buffer_get_16(buffer);
|
||||
flen = _zip_buffer_get_16(buffer);
|
||||
ef_data = _zip_buffer_get(buffer, flen);
|
||||
|
||||
if (ef_data == NULL) {
|
||||
zip_error_set(error, ZIP_ER_INCONS, 0);
|
||||
_zip_buffer_free(buffer);
|
||||
_zip_ef_free(ef_head);
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((ef2=_zip_ef_new(fid, flen, ef_data, flags)) == NULL) {
|
||||
zip_error_set(error, ZIP_ER_MEMORY, 0);
|
||||
_zip_buffer_free(buffer);
|
||||
_zip_ef_free(ef_head);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ef_head) {
|
||||
ef->next = ef2;
|
||||
ef = ef2;
|
||||
}
|
||||
else
|
||||
ef_head = ef = ef2;
|
||||
}
|
||||
|
||||
if (!_zip_buffer_eof(buffer)) {
|
||||
/* Android APK files align stored file data with padding in extra fields; ignore. */
|
||||
/* see https://android.googlesource.com/platform/build/+/master/tools/zipalign/ZipAlign.cpp */
|
||||
size_t glen = _zip_buffer_left(buffer);
|
||||
zip_uint8_t *garbage;
|
||||
garbage = _zip_buffer_get(buffer, glen);
|
||||
if (glen >= 4 || garbage == NULL || memcmp(garbage, "\0\0\0", glen) != 0) {
|
||||
zip_error_set(error, ZIP_ER_INCONS, 0);
|
||||
_zip_buffer_free(buffer);
|
||||
_zip_ef_free(ef_head);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
_zip_buffer_free(buffer);
|
||||
|
||||
if (ef_head_p) {
|
||||
*ef_head_p = ef_head;
|
||||
}
|
||||
else {
|
||||
_zip_ef_free(ef_head);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
zip_extra_field_t *
|
||||
_zip_ef_remove_internal(zip_extra_field_t *ef)
|
||||
{
|
||||
zip_extra_field_t *ef_head;
|
||||
zip_extra_field_t *prev, *next;
|
||||
|
||||
ef_head = ef;
|
||||
prev = NULL;
|
||||
|
||||
while (ef) {
|
||||
if (ZIP_EF_IS_INTERNAL(ef->id)) {
|
||||
next = ef->next;
|
||||
if (ef_head == ef)
|
||||
ef_head = next;
|
||||
ef->next = NULL;
|
||||
_zip_ef_free(ef);
|
||||
if (prev)
|
||||
prev->next = next;
|
||||
ef = next;
|
||||
}
|
||||
else {
|
||||
prev = ef;
|
||||
ef = ef->next;
|
||||
}
|
||||
}
|
||||
|
||||
return ef_head;
|
||||
}
|
||||
|
||||
|
||||
zip_uint16_t
|
||||
_zip_ef_size(const zip_extra_field_t *ef, zip_flags_t flags)
|
||||
{
|
||||
zip_uint16_t size;
|
||||
|
||||
size = 0;
|
||||
for (; ef; ef=ef->next) {
|
||||
if (ef->flags & flags & ZIP_EF_BOTH)
|
||||
size = (zip_uint16_t)(size+4+ef->size);
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
_zip_ef_write(zip_t *za, const zip_extra_field_t *ef, zip_flags_t flags)
|
||||
{
|
||||
zip_uint8_t b[4];
|
||||
zip_buffer_t *buffer = _zip_buffer_new(b, sizeof(b));
|
||||
|
||||
if (buffer == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (; ef; ef=ef->next) {
|
||||
if (ef->flags & flags & ZIP_EF_BOTH) {
|
||||
_zip_buffer_set_offset(buffer, 0);
|
||||
_zip_buffer_put_16(buffer, ef->id);
|
||||
_zip_buffer_put_16(buffer, ef->size);
|
||||
if (!_zip_buffer_ok(buffer)) {
|
||||
zip_error_set(&za->error, ZIP_ER_INTERNAL, 0);
|
||||
_zip_buffer_free(buffer);
|
||||
return -1;
|
||||
}
|
||||
if (_zip_write(za, b, 4) < 0) {
|
||||
_zip_buffer_free(buffer);
|
||||
return -1;
|
||||
}
|
||||
if (ef->size > 0) {
|
||||
if (_zip_write(za, ef->data, ef->size) < 0) {
|
||||
_zip_buffer_free(buffer);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_zip_buffer_free(buffer);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
_zip_read_local_ef(zip_t *za, zip_uint64_t idx)
|
||||
{
|
||||
zip_entry_t *e;
|
||||
unsigned char b[4];
|
||||
zip_buffer_t *buffer;
|
||||
zip_uint16_t fname_len, ef_len;
|
||||
|
||||
if (idx >= za->nentry) {
|
||||
zip_error_set(&za->error, ZIP_ER_INVAL, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
e = za->entry+idx;
|
||||
|
||||
if (e->orig == NULL || e->orig->local_extra_fields_read)
|
||||
return 0;
|
||||
|
||||
if (e->orig->offset + 26 > ZIP_INT64_MAX) {
|
||||
zip_error_set(&za->error, ZIP_ER_SEEK, EFBIG);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (zip_source_seek(za->src, (zip_int64_t)(e->orig->offset + 26), SEEK_SET) < 0) {
|
||||
_zip_error_set_from_source(&za->error, za->src);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((buffer = _zip_buffer_new_from_source(za->src, sizeof(b), b, &za->error)) == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
fname_len = _zip_buffer_get_16(buffer);
|
||||
ef_len = _zip_buffer_get_16(buffer);
|
||||
|
||||
if (!_zip_buffer_eof(buffer)) {
|
||||
_zip_buffer_free(buffer);
|
||||
zip_error_set(&za->error, ZIP_ER_INTERNAL, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
_zip_buffer_free(buffer);
|
||||
|
||||
if (ef_len > 0) {
|
||||
zip_extra_field_t *ef;
|
||||
zip_uint8_t *ef_raw;
|
||||
|
||||
if (zip_source_seek(za->src, fname_len, SEEK_CUR) < 0) {
|
||||
zip_error_set(&za->error, ZIP_ER_SEEK, errno);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ef_raw = _zip_read_data(NULL, za->src, ef_len, 0, &za->error);
|
||||
|
||||
if (ef_raw == NULL)
|
||||
return -1;
|
||||
|
||||
if (!_zip_ef_parse(ef_raw, ef_len, ZIP_EF_LOCAL, &ef, &za->error)) {
|
||||
free(ef_raw);
|
||||
return -1;
|
||||
}
|
||||
free(ef_raw);
|
||||
|
||||
if (ef) {
|
||||
ef = _zip_ef_remove_internal(ef);
|
||||
e->orig->extra_fields = _zip_ef_merge(e->orig->extra_fields, ef);
|
||||
}
|
||||
}
|
||||
|
||||
e->orig->local_extra_fields_read = 1;
|
||||
|
||||
if (e->changes && e->changes->local_extra_fields_read == 0) {
|
||||
e->changes->extra_fields = e->orig->extra_fields;
|
||||
e->changes->local_extra_fields_read = 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
366
src/Common/libzip/zip_extra_field_api.c
Normal file
366
src/Common/libzip/zip_extra_field_api.c
Normal file
@@ -0,0 +1,366 @@
|
||||
/*
|
||||
zip_extra_field_api.c -- public extra fields API functions
|
||||
Copyright (C) 2012-2014 Dieter Baron and Thomas Klausner
|
||||
|
||||
This file is part of libzip, a library to manipulate ZIP archives.
|
||||
The authors can be contacted at <libzip@nih.at>
|
||||
|
||||
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.
|
||||
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.
|
||||
3. The names of the authors may not be used to endorse or promote
|
||||
products derived from this software without specific prior
|
||||
written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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.
|
||||
*/
|
||||
|
||||
|
||||
#include "zipint.h"
|
||||
|
||||
|
||||
ZIP_EXTERN int
|
||||
zip_file_extra_field_delete(zip_t *za, zip_uint64_t idx, zip_uint16_t ef_idx, zip_flags_t flags)
|
||||
{
|
||||
zip_dirent_t *de;
|
||||
|
||||
if ((flags & ZIP_EF_BOTH) == 0) {
|
||||
zip_error_set(&za->error, ZIP_ER_INVAL, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (((flags & ZIP_EF_BOTH) == ZIP_EF_BOTH) && (ef_idx != ZIP_EXTRA_FIELD_ALL)) {
|
||||
zip_error_set(&za->error, ZIP_ER_INVAL, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (_zip_get_dirent(za, idx, 0, NULL) == NULL)
|
||||
return -1;
|
||||
|
||||
if (ZIP_IS_RDONLY(za)) {
|
||||
zip_error_set(&za->error, ZIP_ER_RDONLY, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (_zip_file_extra_field_prepare_for_change(za, idx) < 0)
|
||||
return -1;
|
||||
|
||||
de = za->entry[idx].changes;
|
||||
|
||||
de->extra_fields = _zip_ef_delete_by_id(de->extra_fields, ZIP_EXTRA_FIELD_ALL, ef_idx, flags);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
ZIP_EXTERN int
|
||||
zip_file_extra_field_delete_by_id(zip_t *za, zip_uint64_t idx, zip_uint16_t ef_id, zip_uint16_t ef_idx, zip_flags_t flags)
|
||||
{
|
||||
zip_dirent_t *de;
|
||||
|
||||
if ((flags & ZIP_EF_BOTH) == 0) {
|
||||
zip_error_set(&za->error, ZIP_ER_INVAL, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (((flags & ZIP_EF_BOTH) == ZIP_EF_BOTH) && (ef_idx != ZIP_EXTRA_FIELD_ALL)) {
|
||||
zip_error_set(&za->error, ZIP_ER_INVAL, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (_zip_get_dirent(za, idx, 0, NULL) == NULL)
|
||||
return -1;
|
||||
|
||||
if (ZIP_IS_RDONLY(za)) {
|
||||
zip_error_set(&za->error, ZIP_ER_RDONLY, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (_zip_file_extra_field_prepare_for_change(za, idx) < 0)
|
||||
return -1;
|
||||
|
||||
de = za->entry[idx].changes;
|
||||
|
||||
de->extra_fields = _zip_ef_delete_by_id(de->extra_fields, ef_id, ef_idx, flags);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
ZIP_EXTERN const zip_uint8_t *
|
||||
zip_file_extra_field_get(zip_t *za, zip_uint64_t idx, zip_uint16_t ef_idx, zip_uint16_t *idp, zip_uint16_t *lenp, zip_flags_t flags)
|
||||
{
|
||||
static const zip_uint8_t empty[1] = { '\0' };
|
||||
|
||||
zip_dirent_t *de;
|
||||
zip_extra_field_t *ef;
|
||||
int i;
|
||||
|
||||
if ((flags & ZIP_EF_BOTH) == 0) {
|
||||
zip_error_set(&za->error, ZIP_ER_INVAL, 0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ((de=_zip_get_dirent(za, idx, flags, &za->error)) == NULL)
|
||||
return NULL;
|
||||
|
||||
if (flags & ZIP_FL_LOCAL)
|
||||
if (_zip_read_local_ef(za, idx) < 0)
|
||||
return NULL;
|
||||
|
||||
i = 0;
|
||||
for (ef=de->extra_fields; ef; ef=ef->next) {
|
||||
if (ef->flags & flags & ZIP_EF_BOTH) {
|
||||
if (i < ef_idx) {
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (idp)
|
||||
*idp = ef->id;
|
||||
if (lenp)
|
||||
*lenp = ef->size;
|
||||
if (ef->size > 0)
|
||||
return ef->data;
|
||||
else
|
||||
return empty;
|
||||
}
|
||||
}
|
||||
|
||||
zip_error_set(&za->error, ZIP_ER_NOENT, 0);
|
||||
return NULL;
|
||||
|
||||
}
|
||||
|
||||
|
||||
ZIP_EXTERN const zip_uint8_t *
|
||||
zip_file_extra_field_get_by_id(zip_t *za, zip_uint64_t idx, zip_uint16_t ef_id, zip_uint16_t ef_idx, zip_uint16_t *lenp, zip_flags_t flags)
|
||||
{
|
||||
zip_dirent_t *de;
|
||||
|
||||
if ((flags & ZIP_EF_BOTH) == 0) {
|
||||
zip_error_set(&za->error, ZIP_ER_INVAL, 0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ((de=_zip_get_dirent(za, idx, flags, &za->error)) == NULL)
|
||||
return NULL;
|
||||
|
||||
if (flags & ZIP_FL_LOCAL)
|
||||
if (_zip_read_local_ef(za, idx) < 0)
|
||||
return NULL;
|
||||
|
||||
return _zip_ef_get_by_id(de->extra_fields, lenp, ef_id, ef_idx, flags, &za->error);
|
||||
}
|
||||
|
||||
|
||||
ZIP_EXTERN zip_int16_t
|
||||
zip_file_extra_fields_count(zip_t *za, zip_uint64_t idx, zip_flags_t flags)
|
||||
{
|
||||
zip_dirent_t *de;
|
||||
zip_extra_field_t *ef;
|
||||
zip_uint16_t n;
|
||||
|
||||
if ((flags & ZIP_EF_BOTH) == 0) {
|
||||
zip_error_set(&za->error, ZIP_ER_INVAL, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((de=_zip_get_dirent(za, idx, flags, &za->error)) == NULL)
|
||||
return -1;
|
||||
|
||||
if (flags & ZIP_FL_LOCAL)
|
||||
if (_zip_read_local_ef(za, idx) < 0)
|
||||
return -1;
|
||||
|
||||
n = 0;
|
||||
for (ef=de->extra_fields; ef; ef=ef->next)
|
||||
if (ef->flags & flags & ZIP_EF_BOTH)
|
||||
n++;
|
||||
|
||||
return (zip_int16_t)n;
|
||||
}
|
||||
|
||||
|
||||
ZIP_EXTERN zip_int16_t
|
||||
zip_file_extra_fields_count_by_id(zip_t *za, zip_uint64_t idx, zip_uint16_t ef_id, zip_flags_t flags)
|
||||
{
|
||||
zip_dirent_t *de;
|
||||
zip_extra_field_t *ef;
|
||||
zip_uint16_t n;
|
||||
|
||||
if ((flags & ZIP_EF_BOTH) == 0) {
|
||||
zip_error_set(&za->error, ZIP_ER_INVAL, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((de=_zip_get_dirent(za, idx, flags, &za->error)) == NULL)
|
||||
return -1;
|
||||
|
||||
if (flags & ZIP_FL_LOCAL)
|
||||
if (_zip_read_local_ef(za, idx) < 0)
|
||||
return -1;
|
||||
|
||||
n = 0;
|
||||
for (ef=de->extra_fields; ef; ef=ef->next)
|
||||
if (ef->id == ef_id && (ef->flags & flags & ZIP_EF_BOTH))
|
||||
n++;
|
||||
|
||||
return (zip_int16_t)n;
|
||||
}
|
||||
|
||||
|
||||
ZIP_EXTERN int
|
||||
zip_file_extra_field_set(zip_t *za, zip_uint64_t idx, zip_uint16_t ef_id, zip_uint16_t ef_idx, const zip_uint8_t *data, zip_uint16_t len, zip_flags_t flags)
|
||||
{
|
||||
zip_dirent_t *de;
|
||||
zip_uint16_t ls, cs;
|
||||
zip_extra_field_t *ef, *ef_prev, *ef_new;
|
||||
int i, found, new_len;
|
||||
|
||||
if ((flags & ZIP_EF_BOTH) == 0) {
|
||||
zip_error_set(&za->error, ZIP_ER_INVAL, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (_zip_get_dirent(za, idx, 0, NULL) == NULL)
|
||||
return -1;
|
||||
|
||||
if (ZIP_IS_RDONLY(za)) {
|
||||
zip_error_set(&za->error, ZIP_ER_RDONLY, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ZIP_EF_IS_INTERNAL(ef_id)) {
|
||||
zip_error_set(&za->error, ZIP_ER_INVAL, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (_zip_file_extra_field_prepare_for_change(za, idx) < 0)
|
||||
return -1;
|
||||
|
||||
de = za->entry[idx].changes;
|
||||
|
||||
ef = de->extra_fields;
|
||||
ef_prev = NULL;
|
||||
i = 0;
|
||||
found = 0;
|
||||
|
||||
for (; ef; ef=ef->next) {
|
||||
if (ef->id == ef_id && (ef->flags & flags & ZIP_EF_BOTH)) {
|
||||
if (i == ef_idx) {
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
ef_prev = ef;
|
||||
}
|
||||
|
||||
if (i < ef_idx && ef_idx != ZIP_EXTRA_FIELD_NEW) {
|
||||
zip_error_set(&za->error, ZIP_ER_INVAL, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (flags & ZIP_EF_LOCAL)
|
||||
ls = _zip_ef_size(de->extra_fields, ZIP_EF_LOCAL);
|
||||
else
|
||||
ls = 0;
|
||||
if (flags & ZIP_EF_CENTRAL)
|
||||
cs = _zip_ef_size(de->extra_fields, ZIP_EF_CENTRAL);
|
||||
else
|
||||
cs = 0;
|
||||
|
||||
new_len = ls > cs ? ls : cs;
|
||||
if (found)
|
||||
new_len -= ef->size + 4;
|
||||
new_len += len + 4;
|
||||
|
||||
if (new_len > ZIP_UINT16_MAX) {
|
||||
zip_error_set(&za->error, ZIP_ER_INVAL, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((ef_new=_zip_ef_new(ef_id, len, data, flags)) == NULL) {
|
||||
zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (found) {
|
||||
if ((ef->flags & ZIP_EF_BOTH) == (flags & ZIP_EF_BOTH)) {
|
||||
ef_new->next = ef->next;
|
||||
ef->next = NULL;
|
||||
_zip_ef_free(ef);
|
||||
if (ef_prev)
|
||||
ef_prev->next = ef_new;
|
||||
else
|
||||
de->extra_fields = ef_new;
|
||||
}
|
||||
else {
|
||||
ef->flags &= ~(flags & ZIP_EF_BOTH);
|
||||
ef_new->next = ef->next;
|
||||
ef->next = ef_new;
|
||||
}
|
||||
}
|
||||
else if (ef_prev) {
|
||||
ef_new->next = ef_prev->next;
|
||||
ef_prev->next = ef_new;
|
||||
}
|
||||
else
|
||||
de->extra_fields = ef_new;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int
|
||||
_zip_file_extra_field_prepare_for_change(zip_t *za, zip_uint64_t idx)
|
||||
{
|
||||
zip_entry_t *e;
|
||||
|
||||
if (idx >= za->nentry) {
|
||||
zip_error_set(&za->error, ZIP_ER_INVAL, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
e = za->entry+idx;
|
||||
|
||||
if (e->changes && (e->changes->changed & ZIP_DIRENT_EXTRA_FIELD))
|
||||
return 0;
|
||||
|
||||
if (e->orig) {
|
||||
if (_zip_read_local_ef(za, idx) < 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (e->changes == NULL) {
|
||||
if ((e->changes=_zip_dirent_clone(e->orig)) == NULL) {
|
||||
zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (e->orig && e->orig->extra_fields) {
|
||||
if ((e->changes->extra_fields=_zip_ef_clone(e->orig->extra_fields, &za->error)) == NULL)
|
||||
return -1;
|
||||
}
|
||||
e->changes->changed |= ZIP_DIRENT_EXTRA_FIELD;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
55
src/Common/libzip/zip_fclose.c
Normal file
55
src/Common/libzip/zip_fclose.c
Normal file
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
zip_fclose.c -- close file in zip archive
|
||||
Copyright (C) 1999-2014 Dieter Baron and Thomas Klausner
|
||||
|
||||
This file is part of libzip, a library to manipulate ZIP archives.
|
||||
The authors can be contacted at <libzip@nih.at>
|
||||
|
||||
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.
|
||||
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.
|
||||
3. The names of the authors may not be used to endorse or promote
|
||||
products derived from this software without specific prior
|
||||
written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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.
|
||||
*/
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "zipint.h"
|
||||
|
||||
|
||||
ZIP_EXTERN int
|
||||
zip_fclose(zip_file_t *zf)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (zf->src)
|
||||
zip_source_free(zf->src);
|
||||
|
||||
ret = 0;
|
||||
if (zf->error.zip_err)
|
||||
ret = zf->error.zip_err;
|
||||
|
||||
zip_error_fini(&zf->error);
|
||||
free(zf);
|
||||
return ret;
|
||||
}
|
||||
85
src/Common/libzip/zip_fdopen.c
Normal file
85
src/Common/libzip/zip_fdopen.c
Normal file
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
zip_fdopen.c -- open read-only archive from file descriptor
|
||||
Copyright (C) 2009-2014 Dieter Baron and Thomas Klausner
|
||||
|
||||
This file is part of libzip, a library to manipulate ZIP archives.
|
||||
The authors can be contacted at <libzip@nih.at>
|
||||
|
||||
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.
|
||||
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.
|
||||
3. The names of the authors may not be used to endorse or promote
|
||||
products derived from this software without specific prior
|
||||
written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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.
|
||||
*/
|
||||
|
||||
|
||||
#include "zipint.h"
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
|
||||
ZIP_EXTERN zip_t *
|
||||
zip_fdopen(int fd_orig, int _flags, int *zep)
|
||||
{
|
||||
int fd;
|
||||
FILE *fp;
|
||||
zip_t *za;
|
||||
zip_source_t *src;
|
||||
struct zip_error error;
|
||||
|
||||
if (_flags < 0 || (_flags & ZIP_TRUNCATE)) {
|
||||
_zip_set_open_error(zep, NULL, ZIP_ER_INVAL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* We dup() here to avoid messing with the passed in fd.
|
||||
We could not restore it to the original state in case of error. */
|
||||
|
||||
if ((fd=dup(fd_orig)) < 0) {
|
||||
_zip_set_open_error(zep, NULL, ZIP_ER_OPEN);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ((fp=fdopen(fd, "rb")) == NULL) {
|
||||
close(fd);
|
||||
_zip_set_open_error(zep, NULL, ZIP_ER_OPEN);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
zip_error_init(&error);
|
||||
if ((src = zip_source_filep_create(fp, 0, -1, &error)) == NULL) {
|
||||
_zip_set_open_error(zep, &error, 0);
|
||||
zip_error_fini(&error);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ((za = zip_open_from_source(src, _flags, &error)) == NULL) {
|
||||
_zip_set_open_error(zep, &error, 0);
|
||||
zip_error_fini(&error);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
zip_error_fini(&error);
|
||||
close(fd_orig);
|
||||
return za;
|
||||
}
|
||||
53
src/Common/libzip/zip_file_add.c
Normal file
53
src/Common/libzip/zip_file_add.c
Normal file
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
zip_file_add.c -- add file via callback function
|
||||
Copyright (C) 1999-2014 Dieter Baron and Thomas Klausner
|
||||
|
||||
This file is part of libzip, a library to manipulate ZIP archives.
|
||||
The authors can be contacted at <libzip@nih.at>
|
||||
|
||||
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.
|
||||
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.
|
||||
3. The names of the authors may not be used to endorse or promote
|
||||
products derived from this software without specific prior
|
||||
written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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.
|
||||
*/
|
||||
|
||||
|
||||
#include "zipint.h"
|
||||
|
||||
/*
|
||||
NOTE: Return type is signed so we can return -1 on error.
|
||||
The index can not be larger than ZIP_INT64_MAX since the size
|
||||
of the central directory cannot be larger than
|
||||
ZIP_UINT64_MAX, and each entry is larger than 2 bytes.
|
||||
*/
|
||||
|
||||
ZIP_EXTERN zip_int64_t
|
||||
zip_file_add(zip_t *za, const char *name, zip_source_t *source, zip_flags_t flags)
|
||||
{
|
||||
if (name == NULL || source == NULL) {
|
||||
zip_error_set(&za->error, ZIP_ER_INVAL, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return _zip_file_replace(za, ZIP_UINT64_MAX, name, source, flags);
|
||||
}
|
||||
45
src/Common/libzip/zip_file_error_clear.c
Normal file
45
src/Common/libzip/zip_file_error_clear.c
Normal file
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
zip_file_error_clear.c -- clear zip file error
|
||||
Copyright (C) 1999-2014 Dieter Baron and Thomas Klausner
|
||||
|
||||
This file is part of libzip, a library to manipulate ZIP archives.
|
||||
The authors can be contacted at <libzip@nih.at>
|
||||
|
||||
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.
|
||||
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.
|
||||
3. The names of the authors may not be used to endorse or promote
|
||||
products derived from this software without specific prior
|
||||
written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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.
|
||||
*/
|
||||
|
||||
|
||||
#include "zipint.h"
|
||||
|
||||
|
||||
ZIP_EXTERN void
|
||||
zip_file_error_clear(zip_file_t *zf)
|
||||
{
|
||||
if (zf == NULL)
|
||||
return;
|
||||
|
||||
_zip_error_clear(&zf->error);
|
||||
}
|
||||
42
src/Common/libzip/zip_file_error_get.c
Normal file
42
src/Common/libzip/zip_file_error_get.c
Normal file
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
zip_file_error_get.c -- get zip file error
|
||||
Copyright (C) 1999-2014 Dieter Baron and Thomas Klausner
|
||||
|
||||
This file is part of libzip, a library to manipulate ZIP archives.
|
||||
The authors can be contacted at <libzip@nih.at>
|
||||
|
||||
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.
|
||||
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.
|
||||
3. The names of the authors may not be used to endorse or promote
|
||||
products derived from this software without specific prior
|
||||
written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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.
|
||||
*/
|
||||
|
||||
#define _ZIP_COMPILING_DEPRECATED
|
||||
#include "zipint.h"
|
||||
|
||||
|
||||
ZIP_EXTERN void
|
||||
zip_file_error_get(zip_file_t *zf, int *zep, int *sep)
|
||||
{
|
||||
_zip_error_get(&zf->error, zep, sep);
|
||||
}
|
||||
56
src/Common/libzip/zip_file_get_comment.c
Normal file
56
src/Common/libzip/zip_file_get_comment.c
Normal file
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
zip_file_get_comment.c -- get file comment
|
||||
Copyright (C) 2006-2014 Dieter Baron and Thomas Klausner
|
||||
|
||||
This file is part of libzip, a library to manipulate ZIP archives.
|
||||
The authors can be contacted at <libzip@nih.at>
|
||||
|
||||
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.
|
||||
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.
|
||||
3. The names of the authors may not be used to endorse or promote
|
||||
products derived from this software without specific prior
|
||||
written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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.
|
||||
*/
|
||||
|
||||
|
||||
#include "zipint.h"
|
||||
|
||||
/* lenp is 32 bit because converted comment can be longer than ZIP_UINT16_MAX */
|
||||
|
||||
ZIP_EXTERN const char *
|
||||
zip_file_get_comment(zip_t *za, zip_uint64_t idx, zip_uint32_t *lenp, zip_flags_t flags)
|
||||
{
|
||||
zip_dirent_t *de;
|
||||
zip_uint32_t len;
|
||||
const zip_uint8_t *str;
|
||||
|
||||
if ((de=_zip_get_dirent(za, idx, flags, NULL)) == NULL)
|
||||
return NULL;
|
||||
|
||||
if ((str=_zip_string_get(de->comment, &len, flags, &za->error)) == NULL)
|
||||
return NULL;
|
||||
|
||||
if (lenp)
|
||||
*lenp = len;
|
||||
|
||||
return (const char *)str;
|
||||
}
|
||||
51
src/Common/libzip/zip_file_get_external_attributes.c
Normal file
51
src/Common/libzip/zip_file_get_external_attributes.c
Normal file
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
zip_file_get_external_attributes.c -- get opsys/external attributes
|
||||
Copyright (C) 2013-2014 Dieter Baron and Thomas Klausner
|
||||
|
||||
This file is part of libzip, a library to manipulate ZIP archives.
|
||||
The authors can be contacted at <libzip@nih.at>
|
||||
|
||||
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.
|
||||
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.
|
||||
3. The names of the authors may not be used to endorse or promote
|
||||
products derived from this software without specific prior
|
||||
written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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.
|
||||
*/
|
||||
|
||||
#include "zipint.h"
|
||||
|
||||
int
|
||||
zip_file_get_external_attributes(zip_t *za, zip_uint64_t idx, zip_flags_t flags, zip_uint8_t *opsys, zip_uint32_t *attributes)
|
||||
{
|
||||
zip_dirent_t *de;
|
||||
|
||||
if ((de=_zip_get_dirent(za, idx, flags, NULL)) == NULL)
|
||||
return -1;
|
||||
|
||||
if (opsys)
|
||||
*opsys = (zip_uint8_t)((de->version_madeby >> 8) & 0xff);
|
||||
|
||||
if (attributes)
|
||||
*attributes = de->ext_attrib;
|
||||
|
||||
return 0;
|
||||
}
|
||||
73
src/Common/libzip/zip_file_get_offset.c
Normal file
73
src/Common/libzip/zip_file_get_offset.c
Normal file
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
zip_file_get_offset.c -- get offset of file data in archive.
|
||||
Copyright (C) 1999-2015 Dieter Baron and Thomas Klausner
|
||||
|
||||
This file is part of libzip, a library to manipulate ZIP archives.
|
||||
The authors can be contacted at <libzip@nih.at>
|
||||
|
||||
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.
|
||||
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.
|
||||
3. The names of the authors may not be used to endorse or promote
|
||||
products derived from this software without specific prior
|
||||
written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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.
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include "zipint.h"
|
||||
|
||||
|
||||
/* _zip_file_get_offset(za, ze):
|
||||
Returns the offset of the file data for entry ze.
|
||||
|
||||
On error, fills in za->error and returns 0.
|
||||
*/
|
||||
|
||||
zip_uint64_t
|
||||
_zip_file_get_offset(const zip_t *za, zip_uint64_t idx, zip_error_t *error)
|
||||
{
|
||||
zip_uint64_t offset;
|
||||
zip_int32_t size;
|
||||
|
||||
offset = za->entry[idx].orig->offset;
|
||||
|
||||
if (zip_source_seek(za->src, (zip_int64_t)offset, SEEK_SET) < 0) {
|
||||
_zip_error_set_from_source(error, za->src);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* TODO: cache? */
|
||||
if ((size=_zip_dirent_size(za->src, ZIP_EF_LOCAL, error)) < 0)
|
||||
return 0;
|
||||
|
||||
if (offset+(zip_uint32_t)size > ZIP_INT64_MAX) {
|
||||
zip_error_set(error, ZIP_ER_SEEK, EFBIG);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return offset + (zip_uint32_t)size;
|
||||
}
|
||||
68
src/Common/libzip/zip_file_rename.c
Normal file
68
src/Common/libzip/zip_file_rename.c
Normal file
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
zip_file_rename.c -- rename file in zip archive
|
||||
Copyright (C) 1999-2014 Dieter Baron and Thomas Klausner
|
||||
|
||||
This file is part of libzip, a library to manipulate ZIP archives.
|
||||
The authors can be contacted at <libzip@nih.at>
|
||||
|
||||
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.
|
||||
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.
|
||||
3. The names of the authors may not be used to endorse or promote
|
||||
products derived from this software without specific prior
|
||||
written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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.
|
||||
*/
|
||||
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "zipint.h"
|
||||
|
||||
|
||||
ZIP_EXTERN int
|
||||
zip_file_rename(zip_t *za, zip_uint64_t idx, const char *name, zip_flags_t flags)
|
||||
{
|
||||
const char *old_name;
|
||||
int old_is_dir, new_is_dir;
|
||||
|
||||
if (idx >= za->nentry || (name != NULL && strlen(name) > ZIP_UINT16_MAX)) {
|
||||
zip_error_set(&za->error, ZIP_ER_INVAL, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ZIP_IS_RDONLY(za)) {
|
||||
zip_error_set(&za->error, ZIP_ER_RDONLY, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((old_name=zip_get_name(za, idx, 0)) == NULL)
|
||||
return -1;
|
||||
|
||||
new_is_dir = (name != NULL && name[strlen(name)-1] == '/');
|
||||
old_is_dir = (old_name[strlen(old_name)-1] == '/');
|
||||
|
||||
if (new_is_dir != old_is_dir) {
|
||||
zip_error_set(&za->error, ZIP_ER_INVAL, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return _zip_set_name(za, idx, name, flags);
|
||||
}
|
||||
108
src/Common/libzip/zip_file_replace.c
Normal file
108
src/Common/libzip/zip_file_replace.c
Normal file
@@ -0,0 +1,108 @@
|
||||
/*
|
||||
zip_file_replace.c -- replace file via callback function
|
||||
Copyright (C) 1999-2014 Dieter Baron and Thomas Klausner
|
||||
|
||||
This file is part of libzip, a library to manipulate ZIP archives.
|
||||
The authors can be contacted at <libzip@nih.at>
|
||||
|
||||
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.
|
||||
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.
|
||||
3. The names of the authors may not be used to endorse or promote
|
||||
products derived from this software without specific prior
|
||||
written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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.
|
||||
*/
|
||||
|
||||
|
||||
#include "zipint.h"
|
||||
|
||||
|
||||
ZIP_EXTERN int
|
||||
zip_file_replace(zip_t *za, zip_uint64_t idx, zip_source_t *source, zip_flags_t flags)
|
||||
{
|
||||
if (idx >= za->nentry || source == NULL) {
|
||||
zip_error_set(&za->error, ZIP_ER_INVAL, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (_zip_file_replace(za, idx, NULL, source, flags) == -1)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* NOTE: Signed due to -1 on error. See zip_add.c for more details. */
|
||||
|
||||
zip_int64_t
|
||||
_zip_file_replace(zip_t *za, zip_uint64_t idx, const char *name, zip_source_t *source, zip_flags_t flags)
|
||||
{
|
||||
zip_uint64_t za_nentry_prev;
|
||||
|
||||
if (ZIP_IS_RDONLY(za)) {
|
||||
zip_error_set(&za->error, ZIP_ER_RDONLY, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
za_nentry_prev = za->nentry;
|
||||
if (idx == ZIP_UINT64_MAX) {
|
||||
zip_int64_t i = -1;
|
||||
|
||||
if (flags & ZIP_FL_OVERWRITE)
|
||||
i = _zip_name_locate(za, name, flags, NULL);
|
||||
|
||||
if (i == -1) {
|
||||
/* create and use new entry, used by zip_add */
|
||||
if ((i=_zip_add_entry(za)) < 0)
|
||||
return -1;
|
||||
}
|
||||
idx = (zip_uint64_t)i;
|
||||
}
|
||||
|
||||
if (name && _zip_set_name(za, idx, name, flags) != 0) {
|
||||
if (za->nentry != za_nentry_prev) {
|
||||
_zip_entry_finalize(za->entry+idx);
|
||||
za->nentry = za_nentry_prev;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* does not change any name related data, so we can do it here;
|
||||
* needed for a double add of the same file name */
|
||||
_zip_unchange_data(za->entry+idx);
|
||||
|
||||
if (za->entry[idx].orig != NULL && (za->entry[idx].changes == NULL || (za->entry[idx].changes->changed & ZIP_DIRENT_COMP_METHOD) == 0)) {
|
||||
if (za->entry[idx].changes == NULL) {
|
||||
if ((za->entry[idx].changes=_zip_dirent_clone(za->entry[idx].orig)) == NULL) {
|
||||
zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
za->entry[idx].changes->comp_method = ZIP_CM_REPLACED_DEFAULT;
|
||||
za->entry[idx].changes->changed |= ZIP_DIRENT_COMP_METHOD;
|
||||
}
|
||||
|
||||
za->entry[idx].source = source;
|
||||
|
||||
return (zip_int64_t)idx;
|
||||
}
|
||||
103
src/Common/libzip/zip_file_set_comment.c
Normal file
103
src/Common/libzip/zip_file_set_comment.c
Normal file
@@ -0,0 +1,103 @@
|
||||
/*
|
||||
zip_file_set_comment.c -- set comment for file in archive
|
||||
Copyright (C) 2006-2014 Dieter Baron and Thomas Klausner
|
||||
|
||||
This file is part of libzip, a library to manipulate ZIP archives.
|
||||
The authors can be contacted at <libzip@nih.at>
|
||||
|
||||
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.
|
||||
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.
|
||||
3. The names of the authors may not be used to endorse or promote
|
||||
products derived from this software without specific prior
|
||||
written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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.
|
||||
*/
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "zipint.h"
|
||||
|
||||
|
||||
ZIP_EXTERN int
|
||||
zip_file_set_comment(zip_t *za, zip_uint64_t idx,
|
||||
const char *comment, zip_uint16_t len, zip_flags_t flags)
|
||||
{
|
||||
zip_entry_t *e;
|
||||
zip_string_t *cstr;
|
||||
int changed;
|
||||
|
||||
if (_zip_get_dirent(za, idx, 0, NULL) == NULL)
|
||||
return -1;
|
||||
|
||||
if (ZIP_IS_RDONLY(za)) {
|
||||
zip_error_set(&za->error, ZIP_ER_RDONLY, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (len > 0 && comment == NULL) {
|
||||
zip_error_set(&za->error, ZIP_ER_INVAL, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (len > 0) {
|
||||
if ((cstr=_zip_string_new((const zip_uint8_t *)comment, len, flags, &za->error)) == NULL)
|
||||
return -1;
|
||||
if ((flags & ZIP_FL_ENCODING_ALL) == ZIP_FL_ENC_GUESS && _zip_guess_encoding(cstr, ZIP_ENCODING_UNKNOWN) == ZIP_ENCODING_UTF8_GUESSED)
|
||||
cstr->encoding = ZIP_ENCODING_UTF8_KNOWN;
|
||||
}
|
||||
else
|
||||
cstr = NULL;
|
||||
|
||||
e = za->entry+idx;
|
||||
|
||||
if (e->changes) {
|
||||
_zip_string_free(e->changes->comment);
|
||||
e->changes->comment = NULL;
|
||||
e->changes->changed &= ~ZIP_DIRENT_COMMENT;
|
||||
}
|
||||
|
||||
if (e->orig && e->orig->comment)
|
||||
changed = !_zip_string_equal(e->orig->comment, cstr);
|
||||
else
|
||||
changed = (cstr != NULL);
|
||||
|
||||
if (changed) {
|
||||
if (e->changes == NULL) {
|
||||
if ((e->changes=_zip_dirent_clone(e->orig)) == NULL) {
|
||||
zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
|
||||
_zip_string_free(cstr);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
e->changes->comment = cstr;
|
||||
e->changes->changed |= ZIP_DIRENT_COMMENT;
|
||||
}
|
||||
else {
|
||||
_zip_string_free(cstr);
|
||||
if (e->changes && e->changes->changed == 0) {
|
||||
_zip_dirent_free(e->changes);
|
||||
e->changes = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
83
src/Common/libzip/zip_file_set_external_attributes.c
Normal file
83
src/Common/libzip/zip_file_set_external_attributes.c
Normal file
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
zip_file_set_external_attributes.c -- set external attributes for entry
|
||||
Copyright (C) 2013-2014 Dieter Baron and Thomas Klausner
|
||||
|
||||
This file is part of libzip, a library to manipulate ZIP archives.
|
||||
The authors can be contacted at <libzip@nih.at>
|
||||
|
||||
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.
|
||||
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.
|
||||
3. The names of the authors may not be used to endorse or promote
|
||||
products derived from this software without specific prior
|
||||
written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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.
|
||||
*/
|
||||
|
||||
#include "zipint.h"
|
||||
|
||||
ZIP_EXTERN int
|
||||
zip_file_set_external_attributes(zip_t *za, zip_uint64_t idx, zip_flags_t flags, zip_uint8_t opsys, zip_uint32_t attributes)
|
||||
{
|
||||
zip_entry_t *e;
|
||||
int changed;
|
||||
zip_uint8_t unchanged_opsys;
|
||||
zip_uint32_t unchanged_attributes;
|
||||
|
||||
if (_zip_get_dirent(za, idx, 0, NULL) == NULL)
|
||||
return -1;
|
||||
|
||||
if (ZIP_IS_RDONLY(za)) {
|
||||
zip_error_set(&za->error, ZIP_ER_RDONLY, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
e = za->entry+idx;
|
||||
|
||||
unchanged_opsys = (e->orig ? (zip_uint8_t)(e->orig->version_madeby>>8) : (zip_uint8_t)ZIP_OPSYS_DEFAULT);
|
||||
unchanged_attributes = e->orig ? e->orig->ext_attrib : ZIP_EXT_ATTRIB_DEFAULT;
|
||||
|
||||
changed = (opsys != unchanged_opsys || attributes != unchanged_attributes);
|
||||
|
||||
if (changed) {
|
||||
if (e->changes == NULL) {
|
||||
if ((e->changes=_zip_dirent_clone(e->orig)) == NULL) {
|
||||
zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
e->changes->version_madeby = (zip_uint16_t)((opsys << 8) | (e->changes->version_madeby & 0xff));
|
||||
e->changes->ext_attrib = attributes;
|
||||
e->changes->changed |= ZIP_DIRENT_ATTRIBUTES;
|
||||
}
|
||||
else if (e->changes) {
|
||||
e->changes->changed &= ~ZIP_DIRENT_ATTRIBUTES;
|
||||
if (e->changes->changed == 0) {
|
||||
_zip_dirent_free(e->changes);
|
||||
e->changes = NULL;
|
||||
}
|
||||
else {
|
||||
e->changes->version_madeby = (zip_uint16_t)((unchanged_opsys << 8) | (e->changes->version_madeby & 0xff));
|
||||
e->changes->ext_attrib = unchanged_attributes;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
74
src/Common/libzip/zip_file_set_mtime.c
Normal file
74
src/Common/libzip/zip_file_set_mtime.c
Normal file
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
zip_file_set_mtime.c -- set modification time of entry.
|
||||
Copyright (C) 2014 Dieter Baron and Thomas Klausner
|
||||
|
||||
This file is part of libzip, a library to manipulate ZIP archives.
|
||||
The authors can be contacted at <libzip@nih.at>
|
||||
|
||||
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.
|
||||
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.
|
||||
3. The names of the authors may not be used to endorse or promote
|
||||
products derived from this software without specific prior
|
||||
written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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.
|
||||
*/
|
||||
|
||||
#include "zipint.h"
|
||||
|
||||
ZIP_EXTERN int zip_file_set_mtime(zip_t *za, zip_uint64_t idx, time_t mtime, zip_flags_t flags)
|
||||
{
|
||||
zip_entry_t *e;
|
||||
int changed;
|
||||
|
||||
if (_zip_get_dirent(za, idx, 0, NULL) == NULL)
|
||||
return -1;
|
||||
|
||||
if (ZIP_IS_RDONLY(za)) {
|
||||
zip_error_set(&za->error, ZIP_ER_RDONLY, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
e = za->entry+idx;
|
||||
|
||||
changed = e->orig == NULL || mtime != e->orig->last_mod;
|
||||
|
||||
if (changed) {
|
||||
if (e->changes == NULL) {
|
||||
if ((e->changes=_zip_dirent_clone(e->orig)) == NULL) {
|
||||
zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
e->changes->last_mod = mtime;
|
||||
e->changes->changed |= ZIP_DIRENT_LAST_MOD;
|
||||
}
|
||||
else {
|
||||
if (e->changes) {
|
||||
e->changes->changed &= ~ZIP_DIRENT_LAST_MOD;
|
||||
if (e->changes->changed == 0) {
|
||||
_zip_dirent_free(e->changes);
|
||||
e->changes = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
42
src/Common/libzip/zip_file_strerror.c
Normal file
42
src/Common/libzip/zip_file_strerror.c
Normal file
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
zip_file_sterror.c -- get string representation of zip file error
|
||||
Copyright (C) 1999-2014 Dieter Baron and Thomas Klausner
|
||||
|
||||
This file is part of libzip, a library to manipulate ZIP archives.
|
||||
The authors can be contacted at <libzip@nih.at>
|
||||
|
||||
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.
|
||||
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.
|
||||
3. The names of the authors may not be used to endorse or promote
|
||||
products derived from this software without specific prior
|
||||
written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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.
|
||||
*/
|
||||
|
||||
|
||||
#include "zipint.h"
|
||||
|
||||
|
||||
ZIP_EXTERN const char *
|
||||
zip_file_strerror(zip_file_t *zf)
|
||||
{
|
||||
return zip_error_strerror(&zf->error);
|
||||
}
|
||||
76
src/Common/libzip/zip_filerange_crc.c
Normal file
76
src/Common/libzip/zip_filerange_crc.c
Normal file
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
zip_filerange_crc.c -- compute CRC32 for a range of a file
|
||||
Copyright (C) 2008-2015 Dieter Baron and Thomas Klausner
|
||||
|
||||
This file is part of libzip, a library to manipulate ZIP archives.
|
||||
The authors can be contacted at <libzip@nih.at>
|
||||
|
||||
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.
|
||||
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.
|
||||
3. The names of the authors may not be used to endorse or promote
|
||||
products derived from this software without specific prior
|
||||
written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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.
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "zipint.h"
|
||||
|
||||
|
||||
|
||||
int
|
||||
_zip_filerange_crc(zip_source_t *src, zip_uint64_t start, zip_uint64_t len, uLong *crcp, zip_error_t *error)
|
||||
{
|
||||
Bytef buf[BUFSIZE];
|
||||
zip_int64_t n;
|
||||
|
||||
*crcp = crc32(0L, Z_NULL, 0);
|
||||
|
||||
if (start > ZIP_INT64_MAX) {
|
||||
zip_error_set(error, ZIP_ER_SEEK, EFBIG);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (zip_source_seek(src, (zip_int64_t)start, SEEK_SET) != 0) {
|
||||
_zip_error_set_from_source(error, src);
|
||||
return -1;
|
||||
}
|
||||
|
||||
while (len > 0) {
|
||||
n = (zip_int64_t)(len > BUFSIZE ? BUFSIZE : len);
|
||||
if ((n = zip_source_read(src, buf, (zip_uint64_t)n)) < 0) {
|
||||
_zip_error_set_from_source(error, src);
|
||||
return -1;
|
||||
}
|
||||
if (n == 0) {
|
||||
zip_error_set(error, ZIP_ER_EOF, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
*crcp = crc32(*crcp, buf, (uInt)n);
|
||||
|
||||
len -= (zip_uint64_t)n;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
47
src/Common/libzip/zip_fopen.c
Normal file
47
src/Common/libzip/zip_fopen.c
Normal file
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
zip_fopen.c -- open file in zip archive for reading
|
||||
Copyright (C) 1999-2014 Dieter Baron and Thomas Klausner
|
||||
|
||||
This file is part of libzip, a library to manipulate ZIP archives.
|
||||
The authors can be contacted at <libzip@nih.at>
|
||||
|
||||
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.
|
||||
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.
|
||||
3. The names of the authors may not be used to endorse or promote
|
||||
products derived from this software without specific prior
|
||||
written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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.
|
||||
*/
|
||||
|
||||
|
||||
#include "zipint.h"
|
||||
|
||||
|
||||
ZIP_EXTERN zip_file_t *
|
||||
zip_fopen(zip_t *za, const char *fname, zip_flags_t flags)
|
||||
{
|
||||
zip_int64_t idx;
|
||||
|
||||
if ((idx=zip_name_locate(za, fname, flags)) < 0)
|
||||
return NULL;
|
||||
|
||||
return zip_fopen_index_encrypted(za, (zip_uint64_t)idx, flags, za->default_password);
|
||||
}
|
||||
47
src/Common/libzip/zip_fopen_encrypted.c
Normal file
47
src/Common/libzip/zip_fopen_encrypted.c
Normal file
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
zip_fopen_encrypted.c -- open file for reading with password
|
||||
Copyright (C) 1999-2014 Dieter Baron and Thomas Klausner
|
||||
|
||||
This file is part of libzip, a library to manipulate ZIP archives.
|
||||
The authors can be contacted at <libzip@nih.at>
|
||||
|
||||
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.
|
||||
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.
|
||||
3. The names of the authors may not be used to endorse or promote
|
||||
products derived from this software without specific prior
|
||||
written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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.
|
||||
*/
|
||||
|
||||
|
||||
#include "zipint.h"
|
||||
|
||||
|
||||
ZIP_EXTERN zip_file_t *
|
||||
zip_fopen_encrypted(zip_t *za, const char *fname, zip_flags_t flags, const char *password)
|
||||
{
|
||||
zip_int64_t idx;
|
||||
|
||||
if ((idx=zip_name_locate(za, fname, flags)) < 0)
|
||||
return NULL;
|
||||
|
||||
return zip_fopen_index_encrypted(za, (zip_uint64_t)idx, flags, password);
|
||||
}
|
||||
45
src/Common/libzip/zip_fopen_index.c
Normal file
45
src/Common/libzip/zip_fopen_index.c
Normal file
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
zip_fopen_index.c -- open file in zip archive for reading by index
|
||||
Copyright (C) 1999-2015 Dieter Baron and Thomas Klausner
|
||||
|
||||
This file is part of libzip, a library to manipulate ZIP archives.
|
||||
The authors can be contacted at <libzip@nih.at>
|
||||
|
||||
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.
|
||||
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.
|
||||
3. The names of the authors may not be used to endorse or promote
|
||||
products derived from this software without specific prior
|
||||
written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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.
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "zipint.h"
|
||||
|
||||
|
||||
ZIP_EXTERN zip_file_t *
|
||||
zip_fopen_index(zip_t *za, zip_uint64_t index, zip_flags_t flags)
|
||||
{
|
||||
return zip_fopen_index_encrypted(za, index, flags, za->default_password);
|
||||
}
|
||||
86
src/Common/libzip/zip_fopen_index_encrypted.c
Normal file
86
src/Common/libzip/zip_fopen_index_encrypted.c
Normal file
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
zip_fopen_index_encrypted.c -- open file for reading by index w/ password
|
||||
Copyright (C) 1999-2015 Dieter Baron and Thomas Klausner
|
||||
|
||||
This file is part of libzip, a library to manipulate ZIP archives.
|
||||
The authors can be contacted at <libzip@nih.at>
|
||||
|
||||
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.
|
||||
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.
|
||||
3. The names of the authors may not be used to endorse or promote
|
||||
products derived from this software without specific prior
|
||||
written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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.
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "zipint.h"
|
||||
|
||||
static zip_file_t *_zip_file_new(zip_t *za);
|
||||
|
||||
|
||||
ZIP_EXTERN zip_file_t *
|
||||
zip_fopen_index_encrypted(zip_t *za, zip_uint64_t index, zip_flags_t flags,
|
||||
const char *password)
|
||||
{
|
||||
zip_file_t *zf;
|
||||
zip_source_t *src;
|
||||
|
||||
if ((src=_zip_source_zip_new(za, za, index, flags, 0, 0, password)) == NULL)
|
||||
return NULL;
|
||||
|
||||
if (zip_source_open(src) < 0) {
|
||||
_zip_error_set_from_source(&za->error, src);
|
||||
zip_source_free(src);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ((zf=_zip_file_new(za)) == NULL) {
|
||||
zip_source_free(src);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
zf->src = src;
|
||||
|
||||
return zf;
|
||||
}
|
||||
|
||||
|
||||
static zip_file_t *
|
||||
_zip_file_new(zip_t *za)
|
||||
{
|
||||
zip_file_t *zf;
|
||||
|
||||
if ((zf=(zip_file_t *)malloc(sizeof(struct zip_file))) == NULL) {
|
||||
zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
zf->za = za;
|
||||
zip_error_init(&zf->error);
|
||||
zf->eof = 0;
|
||||
zf->src = NULL;
|
||||
|
||||
return zf;
|
||||
}
|
||||
63
src/Common/libzip/zip_fread.c
Normal file
63
src/Common/libzip/zip_fread.c
Normal file
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
zip_fread.c -- read from file
|
||||
Copyright (C) 1999-2014 Dieter Baron and Thomas Klausner
|
||||
|
||||
This file is part of libzip, a library to manipulate ZIP archives.
|
||||
The authors can be contacted at <libzip@nih.at>
|
||||
|
||||
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.
|
||||
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.
|
||||
3. The names of the authors may not be used to endorse or promote
|
||||
products derived from this software without specific prior
|
||||
written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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.
|
||||
*/
|
||||
|
||||
|
||||
#include "zipint.h"
|
||||
|
||||
|
||||
ZIP_EXTERN zip_int64_t
|
||||
zip_fread(zip_file_t *zf, void *outbuf, zip_uint64_t toread)
|
||||
{
|
||||
zip_int64_t n;
|
||||
|
||||
if (!zf)
|
||||
return -1;
|
||||
|
||||
if (zf->error.zip_err != 0)
|
||||
return -1;
|
||||
|
||||
if (toread > ZIP_INT64_MAX) {
|
||||
zip_error_set(&zf->error, ZIP_ER_INVAL, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((zf->eof) || (toread == 0))
|
||||
return 0;
|
||||
|
||||
if ((n=zip_source_read(zf->src, outbuf, toread)) < 0) {
|
||||
_zip_error_set_from_source(&zf->error, zf->src);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
59
src/Common/libzip/zip_get_archive_comment.c
Normal file
59
src/Common/libzip/zip_get_archive_comment.c
Normal file
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
zip_get_archive_comment.c -- get archive comment
|
||||
Copyright (C) 2006-2014 Dieter Baron and Thomas Klausner
|
||||
|
||||
This file is part of libzip, a library to manipulate ZIP archives.
|
||||
The authors can be contacted at <libzip@nih.at>
|
||||
|
||||
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.
|
||||
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.
|
||||
3. The names of the authors may not be used to endorse or promote
|
||||
products derived from this software without specific prior
|
||||
written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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.
|
||||
*/
|
||||
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "zipint.h"
|
||||
|
||||
|
||||
ZIP_EXTERN const char *
|
||||
zip_get_archive_comment(zip_t *za, int *lenp, zip_flags_t flags)
|
||||
{
|
||||
zip_string_t *comment;
|
||||
zip_uint32_t len;
|
||||
const zip_uint8_t *str;
|
||||
|
||||
if ((flags & ZIP_FL_UNCHANGED) || (za->comment_changes == NULL))
|
||||
comment = za->comment_orig;
|
||||
else
|
||||
comment = za->comment_changes;
|
||||
|
||||
if ((str=_zip_string_get(comment, &len, flags, &za->error)) == NULL)
|
||||
return NULL;
|
||||
|
||||
if (lenp)
|
||||
*lenp = (int)len;
|
||||
|
||||
return (const char *)str;
|
||||
}
|
||||
46
src/Common/libzip/zip_get_archive_flag.c
Normal file
46
src/Common/libzip/zip_get_archive_flag.c
Normal file
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
zip_get_archive_flag.c -- get archive global flag
|
||||
Copyright (C) 2008-2014 Dieter Baron and Thomas Klausner
|
||||
|
||||
This file is part of libzip, a library to manipulate ZIP archives.
|
||||
The authors can be contacted at <libzip@nih.at>
|
||||
|
||||
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.
|
||||
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.
|
||||
3. The names of the authors may not be used to endorse or promote
|
||||
products derived from this software without specific prior
|
||||
written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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.
|
||||
*/
|
||||
|
||||
|
||||
#include "zipint.h"
|
||||
|
||||
|
||||
ZIP_EXTERN int
|
||||
zip_get_archive_flag(zip_t *za, zip_flags_t flag, zip_flags_t flags)
|
||||
{
|
||||
unsigned int fl;
|
||||
|
||||
fl = (flags & ZIP_FL_UNCHANGED) ? za->flags : za->ch_flags;
|
||||
|
||||
return (fl & flag) ? 1 : 0;
|
||||
}
|
||||
44
src/Common/libzip/zip_get_compression_implementation.c
Normal file
44
src/Common/libzip/zip_get_compression_implementation.c
Normal file
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
zip_get_compression_implementation.c -- get compression implementation
|
||||
Copyright (C) 2009-2014 Dieter Baron and Thomas Klausner
|
||||
|
||||
This file is part of libzip, a library to manipulate ZIP archives.
|
||||
The authors can be contacted at <libzip@nih.at>
|
||||
|
||||
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.
|
||||
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.
|
||||
3. The names of the authors may not be used to endorse or promote
|
||||
products derived from this software without specific prior
|
||||
written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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.
|
||||
*/
|
||||
|
||||
|
||||
#include "zipint.h"
|
||||
|
||||
|
||||
zip_compression_implementation
|
||||
_zip_get_compression_implementation(zip_int32_t cm)
|
||||
{
|
||||
if (cm == ZIP_CM_DEFLATE || ZIP_CM_IS_DEFAULT(cm))
|
||||
return zip_source_deflate;
|
||||
return NULL;
|
||||
}
|
||||
44
src/Common/libzip/zip_get_encryption_implementation.c
Normal file
44
src/Common/libzip/zip_get_encryption_implementation.c
Normal file
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
zip_get_encryption_implementation.c -- get encryption implementation
|
||||
Copyright (C) 2009-2014 Dieter Baron and Thomas Klausner
|
||||
|
||||
This file is part of libzip, a library to manipulate ZIP archives.
|
||||
The authors can be contacted at <libzip@nih.at>
|
||||
|
||||
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.
|
||||
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.
|
||||
3. The names of the authors may not be used to endorse or promote
|
||||
products derived from this software without specific prior
|
||||
written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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.
|
||||
*/
|
||||
|
||||
|
||||
#include "zipint.h"
|
||||
|
||||
|
||||
zip_encryption_implementation
|
||||
_zip_get_encryption_implementation(zip_uint16_t em)
|
||||
{
|
||||
if (em == ZIP_EM_TRAD_PKWARE)
|
||||
return zip_source_pkware;
|
||||
return NULL;
|
||||
}
|
||||
51
src/Common/libzip/zip_get_file_comment.c
Normal file
51
src/Common/libzip/zip_get_file_comment.c
Normal file
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
zip_get_file_comment.c -- get file comment
|
||||
Copyright (C) 2006-2014 Dieter Baron and Thomas Klausner
|
||||
|
||||
This file is part of libzip, a library to manipulate ZIP archives.
|
||||
The authors can be contacted at <libzip@nih.at>
|
||||
|
||||
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.
|
||||
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.
|
||||
3. The names of the authors may not be used to endorse or promote
|
||||
products derived from this software without specific prior
|
||||
written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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.
|
||||
*/
|
||||
|
||||
|
||||
#define _ZIP_COMPILING_DEPRECATED
|
||||
#include "zipint.h"
|
||||
|
||||
|
||||
ZIP_EXTERN const char *
|
||||
zip_get_file_comment(zip_t *za, zip_uint64_t idx, int *lenp, int flags)
|
||||
{
|
||||
zip_uint32_t len;
|
||||
const char *s;
|
||||
|
||||
if ((s=zip_file_get_comment(za, idx, &len, (zip_flags_t)flags)) != NULL) {
|
||||
if (lenp)
|
||||
*lenp = (int)len;
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
60
src/Common/libzip/zip_get_name.c
Normal file
60
src/Common/libzip/zip_get_name.c
Normal file
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
zip_get_name.c -- get filename for a file in zip file
|
||||
Copyright (C) 1999-2014 Dieter Baron and Thomas Klausner
|
||||
|
||||
This file is part of libzip, a library to manipulate ZIP archives.
|
||||
The authors can be contacted at <libzip@nih.at>
|
||||
|
||||
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.
|
||||
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.
|
||||
3. The names of the authors may not be used to endorse or promote
|
||||
products derived from this software without specific prior
|
||||
written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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.
|
||||
*/
|
||||
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "zipint.h"
|
||||
|
||||
|
||||
ZIP_EXTERN const char *
|
||||
zip_get_name(zip_t *za, zip_uint64_t idx, zip_flags_t flags)
|
||||
{
|
||||
return _zip_get_name(za, idx, flags, &za->error);
|
||||
}
|
||||
|
||||
|
||||
const char *
|
||||
_zip_get_name(zip_t *za, zip_uint64_t idx, zip_flags_t flags, zip_error_t *error)
|
||||
{
|
||||
zip_dirent_t *de;
|
||||
const zip_uint8_t *str;
|
||||
|
||||
if ((de=_zip_get_dirent(za, idx, flags, error)) == NULL)
|
||||
return NULL;
|
||||
|
||||
if ((str=_zip_string_get(de->filename, NULL, flags, error)) == NULL)
|
||||
return NULL;
|
||||
|
||||
return (const char *)str;
|
||||
}
|
||||
53
src/Common/libzip/zip_get_num_entries.c
Normal file
53
src/Common/libzip/zip_get_num_entries.c
Normal file
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
zip_get_num_entries.c -- get number of entries in archive
|
||||
Copyright (C) 1999-2014 Dieter Baron and Thomas Klausner
|
||||
|
||||
This file is part of libzip, a library to manipulate ZIP archives.
|
||||
The authors can be contacted at <libzip@nih.at>
|
||||
|
||||
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.
|
||||
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.
|
||||
3. The names of the authors may not be used to endorse or promote
|
||||
products derived from this software without specific prior
|
||||
written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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.
|
||||
*/
|
||||
|
||||
|
||||
#include "zipint.h"
|
||||
|
||||
|
||||
ZIP_EXTERN zip_int64_t
|
||||
zip_get_num_entries(zip_t *za, zip_flags_t flags)
|
||||
{
|
||||
zip_uint64_t n;
|
||||
|
||||
if (za == NULL)
|
||||
return -1;
|
||||
|
||||
if (flags & ZIP_FL_UNCHANGED) {
|
||||
n = za->nentry;
|
||||
while (n>0 && za->entry[n-1].orig == NULL)
|
||||
--n;
|
||||
return (zip_int64_t)n;
|
||||
}
|
||||
return (zip_int64_t)za->nentry;
|
||||
}
|
||||
52
src/Common/libzip/zip_get_num_files.c
Normal file
52
src/Common/libzip/zip_get_num_files.c
Normal file
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
zip_get_num_files.c -- get number of files in archive
|
||||
Copyright (C) 1999-2014 Dieter Baron and Thomas Klausner
|
||||
|
||||
This file is part of libzip, a library to manipulate ZIP archives.
|
||||
The authors can be contacted at <libzip@nih.at>
|
||||
|
||||
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.
|
||||
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.
|
||||
3. The names of the authors may not be used to endorse or promote
|
||||
products derived from this software without specific prior
|
||||
written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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.
|
||||
*/
|
||||
|
||||
|
||||
#define _ZIP_COMPILING_DEPRECATED
|
||||
#include "zipint.h"
|
||||
#include <limits.h>
|
||||
|
||||
|
||||
ZIP_EXTERN int
|
||||
zip_get_num_files(zip_t *za)
|
||||
{
|
||||
if (za == NULL)
|
||||
return -1;
|
||||
|
||||
if (za->nentry > INT_MAX) {
|
||||
zip_error_set(&za->error, ZIP_ER_OPNOTSUPP, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return (int)za->nentry;
|
||||
}
|
||||
267
src/Common/libzip/zip_hash.c
Normal file
267
src/Common/libzip/zip_hash.c
Normal file
@@ -0,0 +1,267 @@
|
||||
/*
|
||||
zip_hash.c -- hash table string -> uint64
|
||||
Copyright (C) 2015-2016 Dieter Baron and Thomas Klausner
|
||||
|
||||
This file is part of libzip, a library to manipulate ZIP archives.
|
||||
The authors can be contacted at <libzip@nih.at>
|
||||
|
||||
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.
|
||||
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.
|
||||
3. The names of the authors may not be used to endorse or promote
|
||||
products derived from this software without specific prior
|
||||
written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "zipint.h"
|
||||
|
||||
struct zip_hash_entry {
|
||||
const zip_uint8_t *name;
|
||||
zip_int64_t orig_index;
|
||||
zip_int64_t current_index;
|
||||
struct zip_hash_entry *next;
|
||||
};
|
||||
typedef struct zip_hash_entry zip_hash_entry_t;
|
||||
|
||||
struct zip_hash {
|
||||
zip_uint16_t table_size;
|
||||
zip_hash_entry_t **table;
|
||||
};
|
||||
|
||||
zip_hash_t *
|
||||
_zip_hash_new(zip_uint16_t table_size, zip_error_t *error)
|
||||
{
|
||||
zip_hash_t *hash;
|
||||
|
||||
if (table_size == 0) {
|
||||
zip_error_set(error, ZIP_ER_INTERNAL, 0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ((hash=(zip_hash_t *)malloc(sizeof(zip_hash_t))) == NULL) {
|
||||
zip_error_set(error, ZIP_ER_MEMORY, 0);
|
||||
return NULL;
|
||||
}
|
||||
hash->table_size = table_size;
|
||||
if ((hash->table=(zip_hash_entry_t**)calloc(table_size, sizeof(zip_hash_entry_t *))) == NULL) {
|
||||
free(hash);
|
||||
zip_error_set(error, ZIP_ER_MEMORY, 0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return hash;
|
||||
}
|
||||
|
||||
static void
|
||||
_free_list(zip_hash_entry_t *entry)
|
||||
{
|
||||
zip_hash_entry_t *next;
|
||||
do {
|
||||
next = entry->next;
|
||||
free(entry);
|
||||
entry = next;
|
||||
} while (entry != NULL);
|
||||
}
|
||||
|
||||
void
|
||||
_zip_hash_free(zip_hash_t *hash)
|
||||
{
|
||||
zip_uint16_t i;
|
||||
|
||||
if (hash == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (i=0; i<hash->table_size; i++) {
|
||||
if (hash->table[i] != NULL) {
|
||||
_free_list(hash->table[i]);
|
||||
}
|
||||
}
|
||||
free(hash->table);
|
||||
free(hash);
|
||||
}
|
||||
|
||||
static zip_uint16_t
|
||||
_hash_string(const zip_uint8_t *name, zip_uint16_t size)
|
||||
{
|
||||
#define HASH_MULTIPLIER 33
|
||||
zip_uint16_t value = 5381;
|
||||
|
||||
if (name == NULL)
|
||||
return 0;
|
||||
|
||||
while (*name != 0) {
|
||||
value = (zip_uint16_t)(((value * HASH_MULTIPLIER) + (zip_uint8_t)*name) % size);
|
||||
name++;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/* insert into hash, return error on existence or memory issues */
|
||||
bool
|
||||
_zip_hash_add(zip_hash_t *hash, const zip_uint8_t *name, zip_uint64_t index, zip_flags_t flags, zip_error_t *error)
|
||||
{
|
||||
zip_uint16_t hash_value;
|
||||
zip_hash_entry_t *entry;
|
||||
|
||||
if (hash == NULL || name == NULL || index > ZIP_INT64_MAX) {
|
||||
zip_error_set(error, ZIP_ER_INVAL, 0);
|
||||
return false;
|
||||
}
|
||||
|
||||
hash_value = _hash_string(name, hash->table_size);
|
||||
for (entry = hash->table[hash_value]; entry != NULL; entry = entry->next) {
|
||||
if (strcmp((const char *)name, (const char *)entry->name) == 0) {
|
||||
if (((flags & ZIP_FL_UNCHANGED) && entry->orig_index != -1) || entry->current_index != -1) {
|
||||
zip_error_set(error, ZIP_ER_EXISTS, 0);
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (entry == NULL) {
|
||||
if ((entry=(zip_hash_entry_t *)malloc(sizeof(zip_hash_entry_t))) == NULL) {
|
||||
zip_error_set(error, ZIP_ER_MEMORY, 0);
|
||||
return false;
|
||||
}
|
||||
entry->name = name;
|
||||
entry->next = hash->table[hash_value];
|
||||
hash->table[hash_value] = entry;
|
||||
entry->orig_index = -1;
|
||||
}
|
||||
|
||||
if (flags & ZIP_FL_UNCHANGED) {
|
||||
entry->orig_index = (zip_int64_t)index;
|
||||
}
|
||||
entry->current_index = (zip_int64_t)index;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* remove entry from hash, error if not found */
|
||||
bool
|
||||
_zip_hash_delete(zip_hash_t *hash, const zip_uint8_t *name, zip_error_t *error)
|
||||
{
|
||||
zip_uint16_t hash_value;
|
||||
zip_hash_entry_t *entry, *previous;
|
||||
|
||||
if (hash == NULL || name == NULL) {
|
||||
zip_error_set(error, ZIP_ER_INVAL, 0);
|
||||
return false;
|
||||
}
|
||||
|
||||
hash_value = _hash_string(name, hash->table_size);
|
||||
previous = NULL;
|
||||
entry = hash->table[hash_value];
|
||||
while (entry) {
|
||||
if (strcmp((const char *)name, (const char *)entry->name) == 0) {
|
||||
if (entry->orig_index == -1) {
|
||||
if (previous) {
|
||||
previous->next = entry->next;
|
||||
}
|
||||
else {
|
||||
hash->table[hash_value] = entry->next;
|
||||
}
|
||||
free(entry);
|
||||
}
|
||||
else {
|
||||
entry->current_index = -1;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
previous = entry;
|
||||
entry = entry->next;
|
||||
};
|
||||
|
||||
zip_error_set(error, ZIP_ER_NOENT, 0);
|
||||
return false;
|
||||
}
|
||||
|
||||
/* find value for entry in hash, -1 if not found */
|
||||
zip_int64_t
|
||||
_zip_hash_lookup(zip_hash_t *hash, const zip_uint8_t *name, zip_flags_t flags, zip_error_t *error)
|
||||
{
|
||||
zip_uint16_t hash_value;
|
||||
zip_hash_entry_t *entry;
|
||||
|
||||
if (hash == NULL || name == NULL) {
|
||||
zip_error_set(error, ZIP_ER_INVAL, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
hash_value = _hash_string(name, hash->table_size);
|
||||
for (entry = hash->table[hash_value]; entry != NULL; entry = entry->next) {
|
||||
if (strcmp((const char *)name, (const char *)entry->name) == 0) {
|
||||
if (flags & ZIP_FL_UNCHANGED) {
|
||||
if (entry->orig_index != -1) {
|
||||
return entry->orig_index;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (entry->current_index != -1) {
|
||||
return entry->current_index;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
zip_error_set(error, ZIP_ER_NOENT, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
void
|
||||
_zip_hash_revert(zip_hash_t *hash)
|
||||
{
|
||||
zip_uint16_t i;
|
||||
zip_hash_entry_t *entry, *previous;
|
||||
|
||||
for (i = 0; i < hash->table_size; i++) {
|
||||
previous = NULL;
|
||||
entry = hash->table[i];
|
||||
while (entry) {
|
||||
if (entry->orig_index == -1) {
|
||||
zip_hash_entry_t *p;
|
||||
if (previous) {
|
||||
previous->next = entry->next;
|
||||
}
|
||||
else {
|
||||
hash->table[i] = entry->next;
|
||||
}
|
||||
p = entry;
|
||||
entry = entry->next;
|
||||
/* previous does not change */
|
||||
free(p);
|
||||
}
|
||||
else {
|
||||
entry->current_index = entry->orig_index;
|
||||
previous = entry;
|
||||
entry = entry->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
138
src/Common/libzip/zip_io_util.c
Normal file
138
src/Common/libzip/zip_io_util.c
Normal file
@@ -0,0 +1,138 @@
|
||||
/*
|
||||
zip_io_util.c -- I/O helper functions
|
||||
Copyright (C) 1999-2015 Dieter Baron and Thomas Klausner
|
||||
|
||||
This file is part of libzip, a library to manipulate ZIP archives.
|
||||
The authors can be contacted at <libzip@nih.at>
|
||||
|
||||
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.
|
||||
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.
|
||||
3. The names of the authors may not be used to endorse or promote
|
||||
products derived from this software without specific prior
|
||||
written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "zipint.h"
|
||||
|
||||
int
|
||||
_zip_read(zip_source_t *src, zip_uint8_t *b, zip_uint64_t length, zip_error_t *error)
|
||||
{
|
||||
zip_int64_t n;
|
||||
|
||||
if (length > ZIP_INT64_MAX) {
|
||||
zip_error_set(error, ZIP_ER_INTERNAL, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((n = zip_source_read(src, b, length)) < 0) {
|
||||
_zip_error_set_from_source(error, src);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (n < (zip_int64_t)length) {
|
||||
zip_error_set(error, ZIP_ER_EOF, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
zip_uint8_t *
|
||||
_zip_read_data(zip_buffer_t *buffer, zip_source_t *src, size_t length, bool nulp, zip_error_t *error)
|
||||
{
|
||||
zip_uint8_t *r;
|
||||
|
||||
if (length == 0 && !nulp) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
r = (zip_uint8_t *)malloc(length + (nulp ? 1 : 0));
|
||||
if (!r) {
|
||||
zip_error_set(error, ZIP_ER_MEMORY, 0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (buffer) {
|
||||
zip_uint8_t *data = _zip_buffer_get(buffer, length);
|
||||
|
||||
if (data == NULL) {
|
||||
zip_error_set(error, ZIP_ER_MEMORY, 0);
|
||||
free(r);
|
||||
return NULL;
|
||||
}
|
||||
memcpy(r, data, length);
|
||||
}
|
||||
else {
|
||||
if (_zip_read(src, r, length, error) < 0) {
|
||||
free(r);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (nulp) {
|
||||
zip_uint8_t *o;
|
||||
/* replace any in-string NUL characters with spaces */
|
||||
r[length] = 0;
|
||||
for (o=r; o<r+length; o++)
|
||||
if (*o == '\0')
|
||||
*o = ' ';
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
zip_string_t *
|
||||
_zip_read_string(zip_buffer_t *buffer, zip_source_t *src, zip_uint16_t len, bool nulp, zip_error_t *error)
|
||||
{
|
||||
zip_uint8_t *raw;
|
||||
zip_string_t *s;
|
||||
|
||||
if ((raw=_zip_read_data(buffer, src, len, nulp, error)) == NULL)
|
||||
return NULL;
|
||||
|
||||
s = _zip_string_new(raw, len, ZIP_FL_ENC_GUESS, error);
|
||||
free(raw);
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
_zip_write(zip_t *za, const void *data, zip_uint64_t length)
|
||||
{
|
||||
zip_int64_t n;
|
||||
|
||||
if ((n = zip_source_write(za->src, data, length)) < 0) {
|
||||
_zip_error_set_from_source(&za->error, za->src);
|
||||
return -1;
|
||||
}
|
||||
if ((zip_uint64_t)n != length) {
|
||||
zip_error_set(&za->error, ZIP_ER_WRITE, EINTR);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
57
src/Common/libzip/zip_memdup.c
Normal file
57
src/Common/libzip/zip_memdup.c
Normal file
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
zip_memdup.c -- internal zip function, "strdup" with len
|
||||
Copyright (C) 1999-2014 Dieter Baron and Thomas Klausner
|
||||
|
||||
This file is part of libzip, a library to manipulate ZIP archives.
|
||||
The authors can be contacted at <libzip@nih.at>
|
||||
|
||||
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.
|
||||
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.
|
||||
3. The names of the authors may not be used to endorse or promote
|
||||
products derived from this software without specific prior
|
||||
written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "zipint.h"
|
||||
|
||||
|
||||
void *
|
||||
_zip_memdup(const void *mem, size_t len, zip_error_t *error)
|
||||
{
|
||||
void *ret;
|
||||
|
||||
if (len == 0)
|
||||
return NULL;
|
||||
|
||||
ret = malloc(len);
|
||||
if (!ret) {
|
||||
zip_error_set(error, ZIP_ER_MEMORY, 0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memcpy(ret, mem, len);
|
||||
|
||||
return ret;
|
||||
}
|
||||
94
src/Common/libzip/zip_name_locate.c
Normal file
94
src/Common/libzip/zip_name_locate.c
Normal file
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
zip_name_locate.c -- get index by name
|
||||
Copyright (C) 1999-2015 Dieter Baron and Thomas Klausner
|
||||
|
||||
This file is part of libzip, a library to manipulate ZIP archives.
|
||||
The authors can be contacted at <libzip@nih.at>
|
||||
|
||||
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.
|
||||
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.
|
||||
3. The names of the authors may not be used to endorse or promote
|
||||
products derived from this software without specific prior
|
||||
written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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.
|
||||
*/
|
||||
|
||||
|
||||
#include <string.h>
|
||||
#ifdef HAVE_STRINGS_H
|
||||
#include <strings.h>
|
||||
#endif
|
||||
|
||||
#include "zipint.h"
|
||||
|
||||
|
||||
ZIP_EXTERN zip_int64_t
|
||||
zip_name_locate(zip_t *za, const char *fname, zip_flags_t flags)
|
||||
{
|
||||
return _zip_name_locate(za, fname, flags, &za->error);
|
||||
}
|
||||
|
||||
|
||||
zip_int64_t
|
||||
_zip_name_locate(zip_t *za, const char *fname, zip_flags_t flags, zip_error_t *error)
|
||||
{
|
||||
int (*cmp)(const char *, const char *);
|
||||
const char *fn, *p;
|
||||
zip_uint64_t i;
|
||||
|
||||
if (za == NULL)
|
||||
return -1;
|
||||
|
||||
if (fname == NULL) {
|
||||
zip_error_set(error, ZIP_ER_INVAL, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (flags & (ZIP_FL_NOCASE|ZIP_FL_NODIR|ZIP_FL_ENC_CP437)) {
|
||||
/* can't use hash table */
|
||||
cmp = (flags & ZIP_FL_NOCASE) ? strcasecmp : strcmp;
|
||||
|
||||
for (i=0; i<za->nentry; i++) {
|
||||
fn = _zip_get_name(za, i, flags, error);
|
||||
|
||||
/* newly added (partially filled) entry or error */
|
||||
if (fn == NULL)
|
||||
continue;
|
||||
|
||||
if (flags & ZIP_FL_NODIR) {
|
||||
p = strrchr(fn, '/');
|
||||
if (p)
|
||||
fn = p+1;
|
||||
}
|
||||
|
||||
if (cmp(fname, fn) == 0) {
|
||||
_zip_error_clear(error);
|
||||
return (zip_int64_t)i;
|
||||
}
|
||||
}
|
||||
|
||||
zip_error_set(error, ZIP_ER_NOENT, 0);
|
||||
return -1;
|
||||
}
|
||||
else {
|
||||
return _zip_hash_lookup(za->names, (const zip_uint8_t *)fname, flags, error);
|
||||
}
|
||||
}
|
||||
74
src/Common/libzip/zip_new.c
Normal file
74
src/Common/libzip/zip_new.c
Normal file
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
zip_new.c -- create and init struct zip
|
||||
Copyright (C) 1999-2015 Dieter Baron and Thomas Klausner
|
||||
|
||||
This file is part of libzip, a library to manipulate ZIP archives.
|
||||
The authors can be contacted at <libzip@nih.at>
|
||||
|
||||
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.
|
||||
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.
|
||||
3. The names of the authors may not be used to endorse or promote
|
||||
products derived from this software without specific prior
|
||||
written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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.
|
||||
*/
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "zipint.h"
|
||||
|
||||
|
||||
/* _zip_new:
|
||||
creates a new zipfile struct, and sets the contents to zero; returns
|
||||
the new struct. */
|
||||
|
||||
zip_t *
|
||||
_zip_new(zip_error_t *error)
|
||||
{
|
||||
zip_t *za;
|
||||
|
||||
za = (zip_t *)malloc(sizeof(struct zip));
|
||||
if (!za) {
|
||||
zip_error_set(error, ZIP_ER_MEMORY, 0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ((za->names = _zip_hash_new(ZIP_HASH_TABLE_SIZE, error)) == NULL) {
|
||||
free(za);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
za->src = NULL;
|
||||
za->open_flags = 0;
|
||||
zip_error_init(&za->error);
|
||||
za->flags = za->ch_flags = 0;
|
||||
za->default_password = NULL;
|
||||
za->comment_orig = za->comment_changes = NULL;
|
||||
za->comment_changed = 0;
|
||||
za->nentry = za->nentry_alloc = 0;
|
||||
za->entry = NULL;
|
||||
za->nopen_source = za->nopen_source_alloc = 0;
|
||||
za->open_source = NULL;
|
||||
za->tempdir = NULL;
|
||||
|
||||
return za;
|
||||
}
|
||||
853
src/Common/libzip/zip_open.c
Normal file
853
src/Common/libzip/zip_open.c
Normal file
@@ -0,0 +1,853 @@
|
||||
/*
|
||||
zip_open.c -- open zip archive by name
|
||||
Copyright (C) 1999-2015 Dieter Baron and Thomas Klausner
|
||||
|
||||
This file is part of libzip, a library to manipulate ZIP archives.
|
||||
The authors can be contacted at <libzip@nih.at>
|
||||
|
||||
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.
|
||||
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.
|
||||
3. The names of the authors may not be used to endorse or promote
|
||||
products derived from this software without specific prior
|
||||
written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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.
|
||||
*/
|
||||
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "zipint.h"
|
||||
|
||||
typedef enum {
|
||||
EXISTS_ERROR = -1,
|
||||
EXISTS_NOT = 0,
|
||||
EXISTS_EMPTY,
|
||||
EXISTS_NONEMPTY,
|
||||
} exists_t;
|
||||
static zip_t *_zip_allocate_new(zip_source_t *src, unsigned int flags, zip_error_t *error);
|
||||
static zip_int64_t _zip_checkcons(zip_t *za, zip_cdir_t *cdir, zip_error_t *error);
|
||||
static zip_cdir_t *_zip_find_central_dir(zip_t *za, zip_uint64_t len);
|
||||
static exists_t _zip_file_exists(zip_source_t *src, zip_error_t *error);
|
||||
static int _zip_headercomp(const zip_dirent_t *, const zip_dirent_t *);
|
||||
static unsigned char *_zip_memmem(const unsigned char *, size_t, const unsigned char *, size_t);
|
||||
static zip_cdir_t *_zip_read_cdir(zip_t *za, zip_buffer_t *buffer, zip_uint64_t buf_offset, zip_error_t *error);
|
||||
static zip_cdir_t *_zip_read_eocd(zip_buffer_t *buffer, zip_uint64_t buf_offset, unsigned int flags, zip_error_t *error);
|
||||
static zip_cdir_t *_zip_read_eocd64(zip_source_t *src, zip_buffer_t *buffer, zip_uint64_t buf_offset, unsigned int flags, zip_error_t *error);
|
||||
|
||||
|
||||
ZIP_EXTERN zip_t *
|
||||
zip_open(const char *fn, int _flags, int *zep)
|
||||
{
|
||||
zip_t *za;
|
||||
zip_source_t *src;
|
||||
struct zip_error error;
|
||||
|
||||
zip_error_init(&error);
|
||||
if ((src = zip_source_file_create(fn, 0, -1, &error)) == NULL) {
|
||||
_zip_set_open_error(zep, &error, 0);
|
||||
zip_error_fini(&error);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ((za = zip_open_from_source(src, _flags, &error)) == NULL) {
|
||||
zip_source_free(src);
|
||||
_zip_set_open_error(zep, &error, 0);
|
||||
zip_error_fini(&error);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
zip_error_fini(&error);
|
||||
return za;
|
||||
}
|
||||
|
||||
|
||||
ZIP_EXTERN zip_t *
|
||||
zip_open_from_source(zip_source_t *src, int _flags, zip_error_t *error)
|
||||
{
|
||||
static zip_int64_t needed_support_read = -1;
|
||||
static zip_int64_t needed_support_write = -1;
|
||||
|
||||
unsigned int flags;
|
||||
zip_int64_t supported;
|
||||
exists_t exists;
|
||||
|
||||
if (_flags < 0 || src == NULL) {
|
||||
zip_error_set(error, ZIP_ER_INVAL, 0);
|
||||
return NULL;
|
||||
}
|
||||
flags = (unsigned int)_flags;
|
||||
|
||||
supported = zip_source_supports(src);
|
||||
if (needed_support_read == -1) {
|
||||
needed_support_read = zip_source_make_command_bitmap(ZIP_SOURCE_OPEN, ZIP_SOURCE_READ, ZIP_SOURCE_CLOSE, ZIP_SOURCE_SEEK, ZIP_SOURCE_TELL, ZIP_SOURCE_STAT, -1);
|
||||
needed_support_write = zip_source_make_command_bitmap(ZIP_SOURCE_BEGIN_WRITE, ZIP_SOURCE_COMMIT_WRITE, ZIP_SOURCE_ROLLBACK_WRITE, ZIP_SOURCE_SEEK_WRITE, ZIP_SOURCE_TELL_WRITE, ZIP_SOURCE_REMOVE, -1);
|
||||
}
|
||||
if ((supported & needed_support_read) != needed_support_read) {
|
||||
zip_error_set(error, ZIP_ER_OPNOTSUPP, 0);
|
||||
return NULL;
|
||||
}
|
||||
if ((supported & needed_support_write) != needed_support_write) {
|
||||
flags |= ZIP_RDONLY;
|
||||
}
|
||||
|
||||
if ((flags & (ZIP_RDONLY|ZIP_TRUNCATE)) == (ZIP_RDONLY|ZIP_TRUNCATE)) {
|
||||
zip_error_set(error, ZIP_ER_RDONLY, 0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
exists = _zip_file_exists(src, error);
|
||||
switch (exists) {
|
||||
case EXISTS_ERROR:
|
||||
return NULL;
|
||||
|
||||
case EXISTS_NOT:
|
||||
if ((flags & ZIP_CREATE) == 0) {
|
||||
zip_error_set(error, ZIP_ER_NOENT, 0);
|
||||
return NULL;
|
||||
}
|
||||
return _zip_allocate_new(src, flags, error);
|
||||
|
||||
default: {
|
||||
zip_t *za;
|
||||
if (flags & ZIP_EXCL) {
|
||||
zip_error_set(error, ZIP_ER_EXISTS, 0);
|
||||
return NULL;
|
||||
}
|
||||
if (zip_source_open(src) < 0) {
|
||||
_zip_error_set_from_source(error, src);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (flags & ZIP_TRUNCATE) {
|
||||
za = _zip_allocate_new(src, flags, error);
|
||||
}
|
||||
else {
|
||||
/* ZIP_CREATE gets ignored if file exists and not ZIP_EXCL, just like open() */
|
||||
za = _zip_open(src, flags, error);
|
||||
}
|
||||
|
||||
if (za == NULL) {
|
||||
zip_source_close(src);
|
||||
return NULL;
|
||||
}
|
||||
return za;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ZIP_EXTERN int
|
||||
zip_archive_set_tempdir(zip_t *za, const char *tempdir)
|
||||
{
|
||||
char *new_tempdir;
|
||||
|
||||
if (tempdir) {
|
||||
if ((new_tempdir = strdup(tempdir)) == NULL) {
|
||||
zip_error_set(&za->error, ZIP_ER_MEMORY, errno);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
new_tempdir = NULL;
|
||||
|
||||
free(za->tempdir);
|
||||
za->tempdir = new_tempdir;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
zip_t *
|
||||
_zip_open(zip_source_t *src, unsigned int flags, zip_error_t *error)
|
||||
{
|
||||
zip_t *za;
|
||||
zip_cdir_t *cdir;
|
||||
struct zip_stat st;
|
||||
zip_uint64_t len, idx;
|
||||
|
||||
zip_stat_init(&st);
|
||||
if (zip_source_stat(src, &st) < 0) {
|
||||
_zip_error_set_from_source(error, src);
|
||||
return NULL;
|
||||
}
|
||||
if ((st.valid & ZIP_STAT_SIZE) == 0) {
|
||||
zip_error_set(error, ZIP_ER_SEEK, EOPNOTSUPP);
|
||||
return NULL;
|
||||
}
|
||||
len = st.size;
|
||||
|
||||
/* treat empty files as empty archives */
|
||||
if (len == 0) {
|
||||
if ((za=_zip_allocate_new(src, flags, error)) == NULL) {
|
||||
zip_source_free(src);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return za;
|
||||
}
|
||||
|
||||
if ((za=_zip_allocate_new(src, flags, error)) == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ((cdir = _zip_find_central_dir(za, len)) == NULL) {
|
||||
_zip_error_copy(error, &za->error);
|
||||
/* keep src so discard does not get rid of it */
|
||||
zip_source_keep(src);
|
||||
zip_discard(za);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
za->entry = cdir->entry;
|
||||
za->nentry = cdir->nentry;
|
||||
za->nentry_alloc = cdir->nentry_alloc;
|
||||
za->comment_orig = cdir->comment;
|
||||
|
||||
free(cdir);
|
||||
|
||||
for (idx = 0; idx < za->nentry; idx++) {
|
||||
const zip_uint8_t *name = _zip_string_get(za->entry[idx].orig->filename, NULL, 0, error);
|
||||
if (name == NULL) {
|
||||
/* keep src so discard does not get rid of it */
|
||||
zip_source_keep(src);
|
||||
zip_discard(za);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (_zip_hash_add(za->names, name, idx, ZIP_FL_UNCHANGED, &za->error) == false) {
|
||||
if (za->error.zip_err != ZIP_ER_EXISTS || (flags & ZIP_CHECKCONS)) {
|
||||
_zip_error_copy(error, &za->error);
|
||||
/* keep src so discard does not get rid of it */
|
||||
zip_source_keep(src);
|
||||
zip_discard(za);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
za->ch_flags = za->flags;
|
||||
|
||||
return za;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
_zip_set_open_error(int *zep, const zip_error_t *err, int ze)
|
||||
{
|
||||
if (err) {
|
||||
ze = zip_error_code_zip(err);
|
||||
if (zip_error_system_type(err) == ZIP_ET_SYS) {
|
||||
errno = zip_error_code_system(err);
|
||||
}
|
||||
}
|
||||
|
||||
if (zep)
|
||||
*zep = ze;
|
||||
}
|
||||
|
||||
|
||||
/* _zip_readcdir:
|
||||
tries to find a valid end-of-central-directory at the beginning of
|
||||
buf, and then the corresponding central directory entries.
|
||||
Returns a struct zip_cdir which contains the central directory
|
||||
entries, or NULL if unsuccessful. */
|
||||
|
||||
static zip_cdir_t *
|
||||
_zip_read_cdir(zip_t *za, zip_buffer_t *buffer, zip_uint64_t buf_offset, zip_error_t *error)
|
||||
{
|
||||
zip_cdir_t *cd;
|
||||
zip_uint16_t comment_len;
|
||||
zip_uint64_t i, left;
|
||||
zip_uint64_t eocd_offset = _zip_buffer_offset(buffer);
|
||||
zip_buffer_t *cd_buffer;
|
||||
|
||||
if (_zip_buffer_left(buffer) < EOCDLEN) {
|
||||
/* not enough bytes left for comment */
|
||||
zip_error_set(error, ZIP_ER_NOZIP, 0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* check for end-of-central-dir magic */
|
||||
if (memcmp(_zip_buffer_get(buffer, 4), EOCD_MAGIC, 4) != 0) {
|
||||
zip_error_set(error, ZIP_ER_NOZIP, 0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (eocd_offset >= EOCD64LOCLEN && memcmp(_zip_buffer_data(buffer) + eocd_offset - EOCD64LOCLEN, EOCD64LOC_MAGIC, 4) == 0) {
|
||||
_zip_buffer_set_offset(buffer, eocd_offset - EOCD64LOCLEN);
|
||||
cd = _zip_read_eocd64(za->src, buffer, buf_offset, za->flags, error);
|
||||
}
|
||||
else {
|
||||
_zip_buffer_set_offset(buffer, eocd_offset);
|
||||
cd = _zip_read_eocd(buffer, buf_offset, za->flags, error);
|
||||
}
|
||||
|
||||
if (cd == NULL)
|
||||
return NULL;
|
||||
|
||||
_zip_buffer_set_offset(buffer, eocd_offset + 20);
|
||||
comment_len = _zip_buffer_get_16(buffer);
|
||||
|
||||
if (cd->offset + cd->size > buf_offset + eocd_offset) {
|
||||
/* cdir spans past EOCD record */
|
||||
zip_error_set(error, ZIP_ER_INCONS, 0);
|
||||
_zip_cdir_free(cd);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (comment_len || (za->open_flags & ZIP_CHECKCONS)) {
|
||||
zip_uint64_t tail_len;
|
||||
|
||||
_zip_buffer_set_offset(buffer, eocd_offset + EOCDLEN);
|
||||
tail_len = _zip_buffer_left(buffer);
|
||||
|
||||
if (tail_len < comment_len || ((za->open_flags & ZIP_CHECKCONS) && tail_len != comment_len)) {
|
||||
zip_error_set(error, ZIP_ER_INCONS, 0);
|
||||
_zip_cdir_free(cd);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (comment_len) {
|
||||
if ((cd->comment=_zip_string_new(_zip_buffer_get(buffer, comment_len), comment_len, ZIP_FL_ENC_GUESS, error)) == NULL) {
|
||||
_zip_cdir_free(cd);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (cd->offset >= buf_offset) {
|
||||
zip_uint8_t *data;
|
||||
/* if buffer already read in, use it */
|
||||
_zip_buffer_set_offset(buffer, cd->offset - buf_offset);
|
||||
|
||||
if ((data = _zip_buffer_get(buffer, cd->size)) == NULL) {
|
||||
zip_error_set(error, ZIP_ER_INCONS, 0);
|
||||
_zip_cdir_free(cd);
|
||||
return NULL;
|
||||
}
|
||||
if ((cd_buffer = _zip_buffer_new(data, cd->size)) == NULL) {
|
||||
zip_error_set(error, ZIP_ER_MEMORY, 0);
|
||||
_zip_cdir_free(cd);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
else {
|
||||
cd_buffer = NULL;
|
||||
|
||||
if (zip_source_seek(za->src, (zip_int64_t)cd->offset, SEEK_SET) < 0) {
|
||||
_zip_error_set_from_source(error, za->src);
|
||||
_zip_cdir_free(cd);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* possible consistency check: cd->offset = len-(cd->size+cd->comment_len+EOCDLEN) ? */
|
||||
if (zip_source_tell(za->src) != (zip_int64_t)cd->offset) {
|
||||
zip_error_set(error, ZIP_ER_NOZIP, 0);
|
||||
_zip_cdir_free(cd);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
left = (zip_uint64_t)cd->size;
|
||||
i=0;
|
||||
while (i<cd->nentry && left > 0) {
|
||||
zip_int64_t entry_size;
|
||||
if ((cd->entry[i].orig=_zip_dirent_new()) == NULL || (entry_size = _zip_dirent_read(cd->entry[i].orig, za->src, cd_buffer, false, error)) < 0) {
|
||||
_zip_cdir_free(cd);
|
||||
_zip_buffer_free(cd_buffer);
|
||||
return NULL;
|
||||
}
|
||||
i++;
|
||||
left -= (zip_uint64_t)entry_size;
|
||||
}
|
||||
|
||||
if (i != cd->nentry) {
|
||||
zip_error_set(error, ZIP_ER_INCONS, 0);
|
||||
_zip_buffer_free(cd_buffer);
|
||||
_zip_cdir_free(cd);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (za->open_flags & ZIP_CHECKCONS) {
|
||||
bool ok;
|
||||
|
||||
if (cd_buffer) {
|
||||
ok = _zip_buffer_eof(cd_buffer);
|
||||
}
|
||||
else {
|
||||
zip_int64_t offset = zip_source_tell(za->src);
|
||||
|
||||
if (offset < 0) {
|
||||
_zip_error_set_from_source(error, za->src);
|
||||
_zip_buffer_free(cd_buffer);
|
||||
_zip_cdir_free(cd);
|
||||
return NULL;
|
||||
}
|
||||
ok = ((zip_uint64_t)offset == cd->offset + cd->size);
|
||||
}
|
||||
|
||||
if (!ok) {
|
||||
zip_error_set(error, ZIP_ER_INCONS, 0);
|
||||
_zip_buffer_free(cd_buffer);
|
||||
_zip_cdir_free(cd);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
_zip_buffer_free(cd_buffer);
|
||||
return cd;
|
||||
}
|
||||
|
||||
|
||||
/* _zip_checkcons:
|
||||
Checks the consistency of the central directory by comparing central
|
||||
directory entries with local headers and checking for plausible
|
||||
file and header offsets. Returns -1 if not plausible, else the
|
||||
difference between the lowest and the highest fileposition reached */
|
||||
|
||||
static zip_int64_t
|
||||
_zip_checkcons(zip_t *za, zip_cdir_t *cd, zip_error_t *error)
|
||||
{
|
||||
zip_uint64_t i;
|
||||
zip_uint64_t min, max, j;
|
||||
struct zip_dirent temp;
|
||||
|
||||
_zip_dirent_init(&temp);
|
||||
if (cd->nentry) {
|
||||
max = cd->entry[0].orig->offset;
|
||||
min = cd->entry[0].orig->offset;
|
||||
}
|
||||
else
|
||||
min = max = 0;
|
||||
|
||||
for (i=0; i<cd->nentry; i++) {
|
||||
if (cd->entry[i].orig->offset < min)
|
||||
min = cd->entry[i].orig->offset;
|
||||
if (min > (zip_uint64_t)cd->offset) {
|
||||
zip_error_set(error, ZIP_ER_NOZIP, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
j = cd->entry[i].orig->offset + cd->entry[i].orig->comp_size
|
||||
+ _zip_string_length(cd->entry[i].orig->filename) + LENTRYSIZE;
|
||||
if (j > max)
|
||||
max = j;
|
||||
if (max > (zip_uint64_t)cd->offset) {
|
||||
zip_error_set(error, ZIP_ER_NOZIP, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (zip_source_seek(za->src, (zip_int64_t)cd->entry[i].orig->offset, SEEK_SET) < 0) {
|
||||
_zip_error_set_from_source(error, za->src);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (_zip_dirent_read(&temp, za->src, NULL, true, error) == -1) {
|
||||
_zip_dirent_finalize(&temp);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (_zip_headercomp(cd->entry[i].orig, &temp) != 0) {
|
||||
zip_error_set(error, ZIP_ER_INCONS, 0);
|
||||
_zip_dirent_finalize(&temp);
|
||||
return -1;
|
||||
}
|
||||
|
||||
cd->entry[i].orig->extra_fields = _zip_ef_merge(cd->entry[i].orig->extra_fields, temp.extra_fields);
|
||||
cd->entry[i].orig->local_extra_fields_read = 1;
|
||||
temp.extra_fields = NULL;
|
||||
|
||||
_zip_dirent_finalize(&temp);
|
||||
}
|
||||
|
||||
return (max-min) < ZIP_INT64_MAX ? (zip_int64_t)(max-min) : ZIP_INT64_MAX;
|
||||
}
|
||||
|
||||
|
||||
/* _zip_headercomp:
|
||||
compares a central directory entry and a local file header
|
||||
Return 0 if they are consistent, -1 if not. */
|
||||
|
||||
static int
|
||||
_zip_headercomp(const zip_dirent_t *central, const zip_dirent_t *local)
|
||||
{
|
||||
if ((central->version_needed != local->version_needed)
|
||||
#if 0
|
||||
/* some zip-files have different values in local
|
||||
and global headers for the bitflags */
|
||||
|| (central->bitflags != local->bitflags)
|
||||
#endif
|
||||
|| (central->comp_method != local->comp_method)
|
||||
|| (central->last_mod != local->last_mod)
|
||||
|| !_zip_string_equal(central->filename, local->filename))
|
||||
return -1;
|
||||
|
||||
if ((central->crc != local->crc) || (central->comp_size != local->comp_size)
|
||||
|| (central->uncomp_size != local->uncomp_size)) {
|
||||
/* InfoZip stores valid values in local header even when data descriptor is used.
|
||||
This is in violation of the appnote. */
|
||||
if (((local->bitflags & ZIP_GPBF_DATA_DESCRIPTOR) == 0
|
||||
|| local->crc != 0 || local->comp_size != 0 || local->uncomp_size != 0))
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static zip_t *
|
||||
_zip_allocate_new(zip_source_t *src, unsigned int flags, zip_error_t *error)
|
||||
{
|
||||
zip_t *za;
|
||||
|
||||
if ((za = _zip_new(error)) == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
za->src = src;
|
||||
za->open_flags = flags;
|
||||
if (flags & ZIP_RDONLY) {
|
||||
za->flags |= ZIP_AFL_RDONLY;
|
||||
za->ch_flags |= ZIP_AFL_RDONLY;
|
||||
}
|
||||
return za;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* tests for file existence
|
||||
*/
|
||||
static exists_t
|
||||
_zip_file_exists(zip_source_t *src, zip_error_t *error)
|
||||
{
|
||||
struct zip_stat st;
|
||||
|
||||
zip_stat_init(&st);
|
||||
if (zip_source_stat(src, &st) != 0) {
|
||||
zip_error_t *src_error = zip_source_error(src);
|
||||
if (zip_error_code_zip(src_error) == ZIP_ER_READ && zip_error_code_system(src_error) == ENOENT) {
|
||||
return EXISTS_NOT;
|
||||
}
|
||||
_zip_error_copy(error, src_error);
|
||||
return EXISTS_ERROR;
|
||||
}
|
||||
|
||||
return (st.valid & ZIP_STAT_SIZE) && st.size == 0 ? EXISTS_EMPTY : EXISTS_NONEMPTY;
|
||||
}
|
||||
|
||||
|
||||
static zip_cdir_t *
|
||||
_zip_find_central_dir(zip_t *za, zip_uint64_t len)
|
||||
{
|
||||
zip_cdir_t *cdir, *cdirnew;
|
||||
zip_uint8_t *match;
|
||||
zip_int64_t buf_offset;
|
||||
zip_uint64_t buflen;
|
||||
zip_int64_t a;
|
||||
zip_int64_t best;
|
||||
zip_error_t error;
|
||||
zip_buffer_t *buffer;
|
||||
|
||||
if (len < EOCDLEN) {
|
||||
zip_error_set(&za->error, ZIP_ER_NOZIP, 0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
buflen = (len < CDBUFSIZE ? len : CDBUFSIZE);
|
||||
if (zip_source_seek(za->src, -(zip_int64_t)buflen, SEEK_END) < 0) {
|
||||
zip_error_t *src_error = zip_source_error(za->src);
|
||||
if (zip_error_code_zip(src_error) != ZIP_ER_SEEK || zip_error_code_system(src_error) != EFBIG) {
|
||||
/* seek before start of file on my machine */
|
||||
_zip_error_copy(&za->error, src_error);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
if ((buf_offset = zip_source_tell(za->src)) < 0) {
|
||||
_zip_error_set_from_source(&za->error, za->src);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ((buffer = _zip_buffer_new_from_source(za->src, buflen, NULL, &za->error)) == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
best = -1;
|
||||
cdir = NULL;
|
||||
if (buflen >= CDBUFSIZE) {
|
||||
/* EOCD64 locator is before EOCD, so leave place for it */
|
||||
_zip_buffer_set_offset(buffer, EOCD64LOCLEN);
|
||||
}
|
||||
zip_error_set(&error, ZIP_ER_NOZIP, 0);
|
||||
|
||||
match = _zip_buffer_get(buffer, 0);
|
||||
while ((match=_zip_memmem(match, _zip_buffer_left(buffer)-(EOCDLEN-4), (const unsigned char *)EOCD_MAGIC, 4)) != NULL) {
|
||||
_zip_buffer_set_offset(buffer, (zip_uint64_t)(match - _zip_buffer_data(buffer)));
|
||||
if ((cdirnew = _zip_read_cdir(za, buffer, (zip_uint64_t)buf_offset, &error)) != NULL) {
|
||||
if (cdir) {
|
||||
if (best <= 0) {
|
||||
best = _zip_checkcons(za, cdir, &error);
|
||||
}
|
||||
|
||||
a = _zip_checkcons(za, cdirnew, &error);
|
||||
if (best < a) {
|
||||
_zip_cdir_free(cdir);
|
||||
cdir = cdirnew;
|
||||
best = a;
|
||||
}
|
||||
else {
|
||||
_zip_cdir_free(cdirnew);
|
||||
}
|
||||
}
|
||||
else {
|
||||
cdir = cdirnew;
|
||||
if (za->open_flags & ZIP_CHECKCONS)
|
||||
best = _zip_checkcons(za, cdir, &error);
|
||||
else {
|
||||
best = 0;
|
||||
}
|
||||
}
|
||||
cdirnew = NULL;
|
||||
}
|
||||
|
||||
match++;
|
||||
_zip_buffer_set_offset(buffer, (zip_uint64_t)(match - _zip_buffer_data(buffer)));
|
||||
}
|
||||
|
||||
_zip_buffer_free(buffer);
|
||||
|
||||
if (best < 0) {
|
||||
_zip_error_copy(&za->error, &error);
|
||||
_zip_cdir_free(cdir);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return cdir;
|
||||
}
|
||||
|
||||
|
||||
static unsigned char *
|
||||
_zip_memmem(const unsigned char *big, size_t biglen, const unsigned char *little, size_t littlelen)
|
||||
{
|
||||
const unsigned char *p;
|
||||
|
||||
if ((biglen < littlelen) || (littlelen == 0))
|
||||
return NULL;
|
||||
p = big-1;
|
||||
while ((p=(const unsigned char *)
|
||||
memchr(p+1, little[0], (size_t)(big-(p+1))+(size_t)(biglen-littlelen)+1)) != NULL) {
|
||||
if (memcmp(p+1, little+1, littlelen-1)==0)
|
||||
return (unsigned char *)p;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
static zip_cdir_t *
|
||||
_zip_read_eocd(zip_buffer_t *buffer, zip_uint64_t buf_offset, unsigned int flags, zip_error_t *error)
|
||||
{
|
||||
zip_cdir_t *cd;
|
||||
zip_uint64_t i, nentry, size, offset, eocd_offset;
|
||||
|
||||
if (_zip_buffer_left(buffer) < EOCDLEN) {
|
||||
zip_error_set(error, ZIP_ER_INCONS, 0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
eocd_offset = _zip_buffer_offset(buffer);
|
||||
|
||||
_zip_buffer_get(buffer, 4); /* magic already verified */
|
||||
|
||||
if (_zip_buffer_get_32(buffer) != 0) {
|
||||
zip_error_set(error, ZIP_ER_MULTIDISK, 0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* number of cdir-entries on this disk */
|
||||
i = _zip_buffer_get_16(buffer);
|
||||
/* number of cdir-entries */
|
||||
nentry = _zip_buffer_get_16(buffer);
|
||||
|
||||
if (nentry != i) {
|
||||
zip_error_set(error, ZIP_ER_NOZIP, 0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
size = _zip_buffer_get_32(buffer);
|
||||
offset = _zip_buffer_get_32(buffer);
|
||||
|
||||
if (offset+size < offset) {
|
||||
zip_error_set(error, ZIP_ER_SEEK, EFBIG);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (offset+size > buf_offset + eocd_offset) {
|
||||
/* cdir spans past EOCD record */
|
||||
zip_error_set(error, ZIP_ER_INCONS, 0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ((flags & ZIP_CHECKCONS) && offset+size != buf_offset + eocd_offset) {
|
||||
zip_error_set(error, ZIP_ER_INCONS, 0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ((cd=_zip_cdir_new(nentry, error)) == NULL)
|
||||
return NULL;
|
||||
|
||||
cd->size = size;
|
||||
cd->offset = offset;
|
||||
|
||||
return cd;
|
||||
}
|
||||
|
||||
|
||||
static zip_cdir_t *
|
||||
_zip_read_eocd64(zip_source_t *src, zip_buffer_t *buffer, zip_uint64_t buf_offset, unsigned int flags, zip_error_t *error)
|
||||
{
|
||||
zip_cdir_t *cd;
|
||||
zip_uint64_t offset;
|
||||
zip_uint8_t eocd[EOCD64LEN];
|
||||
zip_uint64_t eocd_offset;
|
||||
zip_uint64_t size, nentry, i, eocdloc_offset;
|
||||
bool free_buffer;
|
||||
zip_uint32_t num_disks, num_disks64, eocd_disk, eocd_disk64;
|
||||
|
||||
eocdloc_offset = _zip_buffer_offset(buffer);
|
||||
|
||||
_zip_buffer_get(buffer, 4); /* magic already verified */
|
||||
|
||||
num_disks = _zip_buffer_get_16(buffer);
|
||||
eocd_disk = _zip_buffer_get_16(buffer);
|
||||
eocd_offset = _zip_buffer_get_64(buffer);
|
||||
|
||||
if (eocd_offset > ZIP_INT64_MAX || eocd_offset + EOCD64LEN < eocd_offset) {
|
||||
zip_error_set(error, ZIP_ER_SEEK, EFBIG);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (eocd_offset + EOCD64LEN > eocdloc_offset + buf_offset) {
|
||||
zip_error_set(error, ZIP_ER_INCONS, 0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (eocd_offset >= buf_offset && eocd_offset + EOCD64LEN <= buf_offset + _zip_buffer_size(buffer)) {
|
||||
_zip_buffer_set_offset(buffer, eocd_offset - buf_offset);
|
||||
free_buffer = false;
|
||||
}
|
||||
else {
|
||||
if (zip_source_seek(src, (zip_int64_t)eocd_offset, SEEK_SET) < 0) {
|
||||
_zip_error_set_from_source(error, src);
|
||||
return NULL;
|
||||
}
|
||||
if ((buffer = _zip_buffer_new_from_source(src, EOCD64LEN, eocd, error)) == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
free_buffer = true;
|
||||
}
|
||||
|
||||
if (memcmp(_zip_buffer_get(buffer, 4), EOCD64_MAGIC, 4) != 0) {
|
||||
zip_error_set(error, ZIP_ER_INCONS, 0);
|
||||
if (free_buffer) {
|
||||
_zip_buffer_free(buffer);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
size = _zip_buffer_get_64(buffer);
|
||||
|
||||
if ((flags & ZIP_CHECKCONS) && size + eocd_offset + 12 != buf_offset + eocdloc_offset) {
|
||||
zip_error_set(error, ZIP_ER_INCONS, 0);
|
||||
if (free_buffer) {
|
||||
_zip_buffer_free(buffer);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
_zip_buffer_get(buffer, 4); /* skip version made by/needed */
|
||||
|
||||
num_disks64 = _zip_buffer_get_32(buffer);
|
||||
eocd_disk64 = _zip_buffer_get_32(buffer);
|
||||
|
||||
/* if eocd values are 0xffff, we have to use eocd64 values.
|
||||
otherwise, if the values are not the same, it's inconsistent;
|
||||
in any case, if the value is not 0, we don't support it */
|
||||
if (num_disks == 0xffff) {
|
||||
num_disks = num_disks64;
|
||||
}
|
||||
if (eocd_disk == 0xffff) {
|
||||
eocd_disk = eocd_disk64;
|
||||
}
|
||||
if ((flags & ZIP_CHECKCONS) && (eocd_disk != eocd_disk64 || num_disks != num_disks64)) {
|
||||
zip_error_set(error, ZIP_ER_INCONS, 0);
|
||||
return NULL;
|
||||
}
|
||||
if (num_disks != 0 || eocd_disk != 0) {
|
||||
zip_error_set(error, ZIP_ER_MULTIDISK, 0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
nentry = _zip_buffer_get_64(buffer);
|
||||
i = _zip_buffer_get_64(buffer);
|
||||
|
||||
if (nentry != i) {
|
||||
zip_error_set(error, ZIP_ER_MULTIDISK, 0);
|
||||
if (free_buffer) {
|
||||
_zip_buffer_free(buffer);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
size = _zip_buffer_get_64(buffer);
|
||||
offset = _zip_buffer_get_64(buffer);
|
||||
|
||||
if (!_zip_buffer_ok(buffer)) {
|
||||
zip_error_set(error, ZIP_ER_INTERNAL, 0);
|
||||
if (free_buffer) {
|
||||
_zip_buffer_free(buffer);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (free_buffer) {
|
||||
_zip_buffer_free(buffer);
|
||||
}
|
||||
|
||||
if (offset > ZIP_INT64_MAX || offset+size < offset) {
|
||||
zip_error_set(error, ZIP_ER_SEEK, EFBIG);
|
||||
return NULL;
|
||||
}
|
||||
if ((flags & ZIP_CHECKCONS) && offset+size != eocd_offset) {
|
||||
zip_error_set(error, ZIP_ER_INCONS, 0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ((cd=_zip_cdir_new(nentry, error)) == NULL)
|
||||
return NULL;
|
||||
|
||||
|
||||
cd->size = size;
|
||||
cd->offset = offset;
|
||||
|
||||
return cd;
|
||||
}
|
||||
45
src/Common/libzip/zip_rename.c
Normal file
45
src/Common/libzip/zip_rename.c
Normal file
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
zip_rename.c -- rename file in zip archive
|
||||
Copyright (C) 1999-2014 Dieter Baron and Thomas Klausner
|
||||
|
||||
This file is part of libzip, a library to manipulate ZIP archives.
|
||||
The authors can be contacted at <libzip@nih.at>
|
||||
|
||||
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.
|
||||
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.
|
||||
3. The names of the authors may not be used to endorse or promote
|
||||
products derived from this software without specific prior
|
||||
written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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.
|
||||
*/
|
||||
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#define _ZIP_COMPILING_DEPRECATED
|
||||
#include "zipint.h"
|
||||
|
||||
|
||||
ZIP_EXTERN int
|
||||
zip_rename(zip_t *za, zip_uint64_t idx, const char *name)
|
||||
{
|
||||
return zip_file_rename(za, idx, name, 0);
|
||||
}
|
||||
43
src/Common/libzip/zip_replace.c
Normal file
43
src/Common/libzip/zip_replace.c
Normal file
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
zip_replace.c -- replace file via callback function
|
||||
Copyright (C) 1999-2014 Dieter Baron and Thomas Klausner
|
||||
|
||||
This file is part of libzip, a library to manipulate ZIP archives.
|
||||
The authors can be contacted at <libzip@nih.at>
|
||||
|
||||
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.
|
||||
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.
|
||||
3. The names of the authors may not be used to endorse or promote
|
||||
products derived from this software without specific prior
|
||||
written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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.
|
||||
*/
|
||||
|
||||
|
||||
#define _ZIP_COMPILING_DEPRECATED
|
||||
#include "zipint.h"
|
||||
|
||||
|
||||
ZIP_EXTERN int
|
||||
zip_replace(zip_t *za, zip_uint64_t idx, zip_source_t *source)
|
||||
{
|
||||
return zip_file_replace(za, idx, source, 0);
|
||||
}
|
||||
82
src/Common/libzip/zip_set_archive_comment.c
Normal file
82
src/Common/libzip/zip_set_archive_comment.c
Normal file
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
zip_set_archive_comment.c -- set archive comment
|
||||
Copyright (C) 2006-2014 Dieter Baron and Thomas Klausner
|
||||
|
||||
This file is part of libzip, a library to manipulate ZIP archives.
|
||||
The authors can be contacted at <libzip@nih.at>
|
||||
|
||||
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.
|
||||
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.
|
||||
3. The names of the authors may not be used to endorse or promote
|
||||
products derived from this software without specific prior
|
||||
written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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.
|
||||
*/
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "zipint.h"
|
||||
|
||||
|
||||
ZIP_EXTERN int
|
||||
zip_set_archive_comment(zip_t *za, const char *comment, zip_uint16_t len)
|
||||
{
|
||||
zip_string_t *cstr;
|
||||
|
||||
if (ZIP_IS_RDONLY(za)) {
|
||||
zip_error_set(&za->error, ZIP_ER_RDONLY, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (len > 0 && comment == NULL) {
|
||||
zip_error_set(&za->error, ZIP_ER_INVAL, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (len > 0) {
|
||||
if ((cstr=_zip_string_new((const zip_uint8_t *)comment, len, ZIP_FL_ENC_GUESS, &za->error)) == NULL)
|
||||
return -1;
|
||||
|
||||
if (_zip_guess_encoding(cstr, ZIP_ENCODING_UNKNOWN) == ZIP_ENCODING_CP437) {
|
||||
_zip_string_free(cstr);
|
||||
zip_error_set(&za->error, ZIP_ER_INVAL, 0);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
cstr = NULL;
|
||||
|
||||
_zip_string_free(za->comment_changes);
|
||||
za->comment_changes = NULL;
|
||||
|
||||
if (((za->comment_orig && _zip_string_equal(za->comment_orig, cstr))
|
||||
|| (za->comment_orig == NULL && cstr == NULL))) {
|
||||
_zip_string_free(cstr);
|
||||
za->comment_changed = 0;
|
||||
}
|
||||
else {
|
||||
za->comment_changes = cstr;
|
||||
za->comment_changed = 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
67
src/Common/libzip/zip_set_archive_flag.c
Normal file
67
src/Common/libzip/zip_set_archive_flag.c
Normal file
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
zip_get_archive_flag.c -- set archive global flag
|
||||
Copyright (C) 2008-2014 Dieter Baron and Thomas Klausner
|
||||
|
||||
This file is part of libzip, a library to manipulate ZIP archives.
|
||||
The authors can be contacted at <libzip@nih.at>
|
||||
|
||||
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.
|
||||
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.
|
||||
3. The names of the authors may not be used to endorse or promote
|
||||
products derived from this software without specific prior
|
||||
written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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.
|
||||
*/
|
||||
|
||||
|
||||
#include "zipint.h"
|
||||
|
||||
|
||||
ZIP_EXTERN int
|
||||
zip_set_archive_flag(zip_t *za, zip_flags_t flag, int value)
|
||||
{
|
||||
unsigned int new_flags;
|
||||
|
||||
if (value)
|
||||
new_flags = za->ch_flags | flag;
|
||||
else
|
||||
new_flags = za->ch_flags & ~flag;
|
||||
|
||||
if (new_flags == za->ch_flags)
|
||||
return 0;
|
||||
|
||||
if (ZIP_IS_RDONLY(za)) {
|
||||
zip_error_set(&za->error, ZIP_ER_RDONLY, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((flag & ZIP_AFL_RDONLY) && value
|
||||
&& (za->ch_flags & ZIP_AFL_RDONLY) == 0) {
|
||||
if (_zip_changed(za, NULL)) {
|
||||
zip_error_set(&za->error, ZIP_ER_CHANGED, 0);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
za->ch_flags = new_flags;
|
||||
|
||||
return 0;
|
||||
}
|
||||
59
src/Common/libzip/zip_set_default_password.c
Normal file
59
src/Common/libzip/zip_set_default_password.c
Normal file
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
zip_set_default_password.c -- set default password for decryption
|
||||
Copyright (C) 2009-2014 Dieter Baron and Thomas Klausner
|
||||
|
||||
This file is part of libzip, a library to manipulate ZIP archives.
|
||||
The authors can be contacted at <libzip@nih.at>
|
||||
|
||||
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.
|
||||
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.
|
||||
3. The names of the authors may not be used to endorse or promote
|
||||
products derived from this software without specific prior
|
||||
written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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.
|
||||
*/
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "zipint.h"
|
||||
|
||||
|
||||
ZIP_EXTERN int
|
||||
zip_set_default_password(zip_t *za, const char *passwd)
|
||||
{
|
||||
if (za == NULL)
|
||||
return -1;
|
||||
|
||||
free(za->default_password);
|
||||
|
||||
if (passwd) {
|
||||
if ((za->default_password=strdup(passwd)) == NULL) {
|
||||
zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
za->default_password = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
49
src/Common/libzip/zip_set_file_comment.c
Normal file
49
src/Common/libzip/zip_set_file_comment.c
Normal file
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
zip_set_file_comment.c -- set comment for file in archive
|
||||
Copyright (C) 2006-2014 Dieter Baron and Thomas Klausner
|
||||
|
||||
This file is part of libzip, a library to manipulate ZIP archives.
|
||||
The authors can be contacted at <libzip@nih.at>
|
||||
|
||||
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.
|
||||
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.
|
||||
3. The names of the authors may not be used to endorse or promote
|
||||
products derived from this software without specific prior
|
||||
written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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.
|
||||
*/
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#define _ZIP_COMPILING_DEPRECATED
|
||||
#include "zipint.h"
|
||||
|
||||
|
||||
ZIP_EXTERN int
|
||||
zip_set_file_comment(zip_t *za, zip_uint64_t idx, const char *comment, int len)
|
||||
{
|
||||
if (len < 0 || len > ZIP_UINT16_MAX) {
|
||||
zip_error_set(&za->error, ZIP_ER_INVAL, 0);
|
||||
return -1;
|
||||
}
|
||||
return zip_file_set_comment(za, idx, comment, (zip_uint16_t)len, 0);
|
||||
}
|
||||
87
src/Common/libzip/zip_set_file_compression.c
Normal file
87
src/Common/libzip/zip_set_file_compression.c
Normal file
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
zip_set_file_compression.c -- set compression for file in archive
|
||||
Copyright (C) 2012-2014 Dieter Baron and Thomas Klausner
|
||||
|
||||
This file is part of libzip, a library to manipulate ZIP archives.
|
||||
The authors can be contacted at <libzip@nih.at>
|
||||
|
||||
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.
|
||||
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.
|
||||
3. The names of the authors may not be used to endorse or promote
|
||||
products derived from this software without specific prior
|
||||
written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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.
|
||||
*/
|
||||
|
||||
|
||||
#include "zipint.h"
|
||||
|
||||
|
||||
ZIP_EXTERN int
|
||||
zip_set_file_compression(zip_t *za, zip_uint64_t idx, zip_int32_t method, zip_uint32_t flags)
|
||||
{
|
||||
zip_entry_t *e;
|
||||
zip_int32_t old_method;
|
||||
|
||||
if (idx >= za->nentry) {
|
||||
zip_error_set(&za->error, ZIP_ER_INVAL, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ZIP_IS_RDONLY(za)) {
|
||||
zip_error_set(&za->error, ZIP_ER_RDONLY, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (method != ZIP_CM_DEFAULT && method != ZIP_CM_STORE && method != ZIP_CM_DEFLATE) {
|
||||
zip_error_set(&za->error, ZIP_ER_COMPNOTSUPP, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
e = za->entry+idx;
|
||||
|
||||
old_method = (e->orig == NULL ? ZIP_CM_DEFAULT : e->orig->comp_method);
|
||||
|
||||
/* TODO: revisit this when flags are supported, since they may require a recompression */
|
||||
|
||||
if (method == old_method) {
|
||||
if (e->changes) {
|
||||
e->changes->changed &= ~ZIP_DIRENT_COMP_METHOD;
|
||||
if (e->changes->changed == 0) {
|
||||
_zip_dirent_free(e->changes);
|
||||
e->changes = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (e->changes == NULL) {
|
||||
if ((e->changes=_zip_dirent_clone(e->orig)) == NULL) {
|
||||
zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
e->changes->comp_method = method;
|
||||
e->changes->changed |= ZIP_DIRENT_COMP_METHOD;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
158
src/Common/libzip/zip_set_name.c
Normal file
158
src/Common/libzip/zip_set_name.c
Normal file
@@ -0,0 +1,158 @@
|
||||
/*
|
||||
zip_set_name.c -- rename helper function
|
||||
Copyright (C) 1999-2015 Dieter Baron and Thomas Klausner
|
||||
|
||||
This file is part of libzip, a library to manipulate ZIP archives.
|
||||
The authors can be contacted at <libzip@nih.at>
|
||||
|
||||
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.
|
||||
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.
|
||||
3. The names of the authors may not be used to endorse or promote
|
||||
products derived from this software without specific prior
|
||||
written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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.
|
||||
*/
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "zipint.h"
|
||||
|
||||
|
||||
int
|
||||
_zip_set_name(zip_t *za, zip_uint64_t idx, const char *name, zip_flags_t flags)
|
||||
{
|
||||
zip_entry_t *e;
|
||||
zip_string_t *str;
|
||||
bool same_as_orig;
|
||||
zip_int64_t i;
|
||||
const zip_uint8_t *old_name, *new_name;
|
||||
zip_string_t *old_str;
|
||||
|
||||
if (idx >= za->nentry) {
|
||||
zip_error_set(&za->error, ZIP_ER_INVAL, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ZIP_IS_RDONLY(za)) {
|
||||
zip_error_set(&za->error, ZIP_ER_RDONLY, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (name && name[0] != '\0') {
|
||||
/* TODO: check for string too long */
|
||||
if ((str=_zip_string_new((const zip_uint8_t *)name, (zip_uint16_t)strlen(name), flags, &za->error)) == NULL)
|
||||
return -1;
|
||||
if ((flags & ZIP_FL_ENCODING_ALL) == ZIP_FL_ENC_GUESS && _zip_guess_encoding(str, ZIP_ENCODING_UNKNOWN) == ZIP_ENCODING_UTF8_GUESSED)
|
||||
str->encoding = ZIP_ENCODING_UTF8_KNOWN;
|
||||
}
|
||||
else
|
||||
str = NULL;
|
||||
|
||||
/* TODO: encoding flags needed for CP437? */
|
||||
if ((i=_zip_name_locate(za, name, 0, NULL)) >= 0 && (zip_uint64_t)i != idx) {
|
||||
_zip_string_free(str);
|
||||
zip_error_set(&za->error, ZIP_ER_EXISTS, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* no effective name change */
|
||||
if (i>=0 && (zip_uint64_t)i == idx) {
|
||||
_zip_string_free(str);
|
||||
return 0;
|
||||
}
|
||||
|
||||
e = za->entry+idx;
|
||||
|
||||
if (e->orig)
|
||||
same_as_orig = _zip_string_equal(e->orig->filename, str);
|
||||
else
|
||||
same_as_orig = false;
|
||||
|
||||
if (!same_as_orig && e->changes == NULL) {
|
||||
if ((e->changes=_zip_dirent_clone(e->orig)) == NULL) {
|
||||
zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
|
||||
_zip_string_free(str);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if ((new_name = _zip_string_get(same_as_orig ? e->orig->filename : str, NULL, 0, &za->error)) == NULL) {
|
||||
_zip_string_free(str);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (e->changes) {
|
||||
old_str = e->changes->filename;
|
||||
}
|
||||
else if (e->orig) {
|
||||
old_str = e->orig->filename;
|
||||
}
|
||||
else {
|
||||
old_str = NULL;
|
||||
}
|
||||
|
||||
if (old_str) {
|
||||
if ((old_name = _zip_string_get(old_str, NULL, 0, &za->error)) == NULL) {
|
||||
_zip_string_free(str);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
old_name = NULL;
|
||||
}
|
||||
|
||||
if (_zip_hash_add(za->names, new_name, idx, 0, &za->error) == false) {
|
||||
_zip_string_free(str);
|
||||
return -1;
|
||||
}
|
||||
if (old_name) {
|
||||
_zip_hash_delete(za->names, old_name, NULL);
|
||||
}
|
||||
|
||||
if (same_as_orig) {
|
||||
if (e->changes) {
|
||||
if (e->changes->changed & ZIP_DIRENT_FILENAME) {
|
||||
_zip_string_free(e->changes->filename);
|
||||
e->changes->changed &= ~ZIP_DIRENT_FILENAME;
|
||||
if (e->changes->changed == 0) {
|
||||
_zip_dirent_free(e->changes);
|
||||
e->changes = NULL;
|
||||
}
|
||||
else {
|
||||
/* TODO: what if not cloned? can that happen? */
|
||||
e->changes->filename = e->orig->filename;
|
||||
}
|
||||
}
|
||||
}
|
||||
_zip_string_free(str);
|
||||
}
|
||||
else {
|
||||
if (e->changes->changed & ZIP_DIRENT_FILENAME) {
|
||||
_zip_string_free(e->changes->filename);
|
||||
}
|
||||
e->changes->changed |= ZIP_DIRENT_FILENAME;
|
||||
e->changes->filename = str;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
53
src/Common/libzip/zip_source_begin_write.c
Normal file
53
src/Common/libzip/zip_source_begin_write.c
Normal file
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
zip_source_begin_write.c -- start a new file for writing
|
||||
Copyright (C) 2014 Dieter Baron and Thomas Klausner
|
||||
|
||||
This file is part of libzip, a library to manipulate ZIP archives.
|
||||
The authors can be contacted at <libzip@nih.at>
|
||||
|
||||
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.
|
||||
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.
|
||||
3. The names of the authors may not be used to endorse or promote
|
||||
products derived from this software without specific prior
|
||||
written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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.
|
||||
*/
|
||||
|
||||
|
||||
#include "zipint.h"
|
||||
|
||||
|
||||
ZIP_EXTERN int
|
||||
zip_source_begin_write(zip_source_t *src)
|
||||
{
|
||||
if (ZIP_SOURCE_IS_OPEN_WRITING(src)) {
|
||||
zip_error_set(&src->error, ZIP_ER_INVAL, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (_zip_source_call(src, NULL, 0, ZIP_SOURCE_BEGIN_WRITE) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
src->write_state = ZIP_SOURCE_WRITE_OPEN;
|
||||
|
||||
return 0;
|
||||
}
|
||||
435
src/Common/libzip/zip_source_buffer.c
Normal file
435
src/Common/libzip/zip_source_buffer.c
Normal file
@@ -0,0 +1,435 @@
|
||||
/*
|
||||
zip_source_buffer.c -- create zip data source from buffer
|
||||
Copyright (C) 1999-2016 Dieter Baron and Thomas Klausner
|
||||
|
||||
This file is part of libzip, a library to manipulate ZIP archives.
|
||||
The authors can be contacted at <libzip@nih.at>
|
||||
|
||||
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.
|
||||
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.
|
||||
3. The names of the authors may not be used to endorse or promote
|
||||
products derived from this software without specific prior
|
||||
written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "zipint.h"
|
||||
|
||||
#ifndef WRITE_FRAGMENT_SIZE
|
||||
#define WRITE_FRAGMENT_SIZE 64*1024
|
||||
#endif
|
||||
|
||||
struct buffer {
|
||||
zip_uint64_t fragment_size; /* size of each fragment */
|
||||
|
||||
zip_uint8_t **fragments; /* pointers to fragments */
|
||||
zip_uint64_t nfragments; /* number of allocated fragments */
|
||||
zip_uint64_t fragments_capacity; /* size of fragments (number of pointers) */
|
||||
zip_uint64_t size; /* size of data in bytes */
|
||||
zip_uint64_t offset; /* current offset */
|
||||
int free_data;
|
||||
};
|
||||
|
||||
typedef struct buffer buffer_t;
|
||||
|
||||
struct read_data {
|
||||
zip_error_t error;
|
||||
time_t mtime;
|
||||
buffer_t *in;
|
||||
buffer_t *out;
|
||||
};
|
||||
|
||||
static void buffer_free(buffer_t *buffer);
|
||||
static buffer_t *buffer_new(zip_uint64_t fragment_size);
|
||||
static buffer_t *buffer_new_read(const void *data, zip_uint64_t length, int free_data);
|
||||
static buffer_t *buffer_new_write(zip_uint64_t fragment_size);
|
||||
static zip_int64_t buffer_read(buffer_t *buffer, zip_uint8_t *data, zip_uint64_t length);
|
||||
static int buffer_seek(buffer_t *buffer, void *data, zip_uint64_t len, zip_error_t *error);
|
||||
static zip_int64_t buffer_write(buffer_t *buffer, const zip_uint8_t *data, zip_uint64_t length, zip_error_t *);
|
||||
|
||||
static zip_int64_t read_data(void *, void *, zip_uint64_t, zip_source_cmd_t);
|
||||
|
||||
|
||||
ZIP_EXTERN zip_source_t *
|
||||
zip_source_buffer(zip_t *za, const void *data, zip_uint64_t len, int freep)
|
||||
{
|
||||
if (za == NULL)
|
||||
return NULL;
|
||||
|
||||
return zip_source_buffer_create(data, len, freep, &za->error);
|
||||
}
|
||||
|
||||
|
||||
ZIP_EXTERN zip_source_t *
|
||||
zip_source_buffer_create(const void *data, zip_uint64_t len, int freep, zip_error_t *error)
|
||||
{
|
||||
struct read_data *ctx;
|
||||
zip_source_t *zs;
|
||||
|
||||
if (data == NULL && len > 0) {
|
||||
zip_error_set(error, ZIP_ER_INVAL, 0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ((ctx=(struct read_data *)malloc(sizeof(*ctx))) == NULL) {
|
||||
zip_error_set(error, ZIP_ER_MEMORY, 0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ((ctx->in = buffer_new_read(data, len, freep)) == NULL) {
|
||||
zip_error_set(error, ZIP_ER_MEMORY, 0);
|
||||
free(ctx);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ctx->out = NULL;
|
||||
ctx->mtime = time(NULL);
|
||||
zip_error_init(&ctx->error);
|
||||
|
||||
if ((zs=zip_source_function_create(read_data, ctx, error)) == NULL) {
|
||||
buffer_free(ctx->in);
|
||||
free(ctx);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return zs;
|
||||
}
|
||||
|
||||
|
||||
static zip_int64_t
|
||||
read_data(void *state, void *data, zip_uint64_t len, zip_source_cmd_t cmd)
|
||||
{
|
||||
struct read_data *ctx = (struct read_data *)state;
|
||||
|
||||
switch (cmd) {
|
||||
case ZIP_SOURCE_BEGIN_WRITE:
|
||||
if ((ctx->out = buffer_new_write(WRITE_FRAGMENT_SIZE)) == NULL) {
|
||||
zip_error_set(&ctx->error, ZIP_ER_MEMORY, 0);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
|
||||
case ZIP_SOURCE_CLOSE:
|
||||
return 0;
|
||||
|
||||
case ZIP_SOURCE_COMMIT_WRITE:
|
||||
buffer_free(ctx->in);
|
||||
ctx->in = ctx->out;
|
||||
ctx->out = NULL;
|
||||
return 0;
|
||||
|
||||
case ZIP_SOURCE_ERROR:
|
||||
return zip_error_to_data(&ctx->error, data, len);
|
||||
|
||||
case ZIP_SOURCE_FREE:
|
||||
buffer_free(ctx->in);
|
||||
buffer_free(ctx->out);
|
||||
free(ctx);
|
||||
return 0;
|
||||
|
||||
case ZIP_SOURCE_OPEN:
|
||||
ctx->in->offset = 0;
|
||||
return 0;
|
||||
|
||||
case ZIP_SOURCE_READ:
|
||||
if (len > ZIP_INT64_MAX) {
|
||||
zip_error_set(&ctx->error, ZIP_ER_INVAL, 0);
|
||||
return -1;
|
||||
}
|
||||
return buffer_read(ctx->in, data, len);
|
||||
|
||||
case ZIP_SOURCE_REMOVE:
|
||||
{
|
||||
buffer_t *empty = buffer_new_read(NULL, 0, 0);
|
||||
if (empty == 0) {
|
||||
zip_error_set(&ctx->error, ZIP_ER_MEMORY, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
buffer_free(ctx->in);
|
||||
ctx->in = empty;
|
||||
return 0;
|
||||
}
|
||||
|
||||
case ZIP_SOURCE_ROLLBACK_WRITE:
|
||||
buffer_free(ctx->out);
|
||||
ctx->out = NULL;
|
||||
return 0;
|
||||
|
||||
case ZIP_SOURCE_SEEK:
|
||||
return buffer_seek(ctx->in, data, len, &ctx->error);
|
||||
|
||||
case ZIP_SOURCE_SEEK_WRITE:
|
||||
return buffer_seek(ctx->out, data, len, &ctx->error);
|
||||
|
||||
case ZIP_SOURCE_STAT:
|
||||
{
|
||||
zip_stat_t *st;
|
||||
|
||||
if (len < sizeof(*st)) {
|
||||
zip_error_set(&ctx->error, ZIP_ER_INVAL, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
st = (zip_stat_t *)data;
|
||||
|
||||
zip_stat_init(st);
|
||||
st->mtime = ctx->mtime;
|
||||
st->size = ctx->in->size;
|
||||
st->comp_size = st->size;
|
||||
st->comp_method = ZIP_CM_STORE;
|
||||
st->encryption_method = ZIP_EM_NONE;
|
||||
st->valid = ZIP_STAT_MTIME|ZIP_STAT_SIZE|ZIP_STAT_COMP_SIZE|ZIP_STAT_COMP_METHOD|ZIP_STAT_ENCRYPTION_METHOD;
|
||||
|
||||
return sizeof(*st);
|
||||
}
|
||||
|
||||
case ZIP_SOURCE_SUPPORTS:
|
||||
return zip_source_make_command_bitmap(ZIP_SOURCE_OPEN, ZIP_SOURCE_READ, ZIP_SOURCE_CLOSE, ZIP_SOURCE_STAT, ZIP_SOURCE_ERROR, ZIP_SOURCE_FREE, ZIP_SOURCE_SEEK, ZIP_SOURCE_TELL, ZIP_SOURCE_BEGIN_WRITE, ZIP_SOURCE_COMMIT_WRITE, ZIP_SOURCE_REMOVE, ZIP_SOURCE_ROLLBACK_WRITE, ZIP_SOURCE_SEEK_WRITE, ZIP_SOURCE_TELL_WRITE, ZIP_SOURCE_WRITE, -1);
|
||||
|
||||
case ZIP_SOURCE_TELL:
|
||||
if (ctx->in->offset > ZIP_INT64_MAX) {
|
||||
zip_error_set(&ctx->error, ZIP_ER_TELL, EOVERFLOW);
|
||||
return -1;
|
||||
}
|
||||
return (zip_int64_t)ctx->in->offset;
|
||||
|
||||
|
||||
case ZIP_SOURCE_TELL_WRITE:
|
||||
if (ctx->out->offset > ZIP_INT64_MAX) {
|
||||
zip_error_set(&ctx->error, ZIP_ER_TELL, EOVERFLOW);
|
||||
return -1;
|
||||
}
|
||||
return (zip_int64_t)ctx->out->offset;
|
||||
|
||||
case ZIP_SOURCE_WRITE:
|
||||
if (len > ZIP_INT64_MAX) {
|
||||
zip_error_set(&ctx->error, ZIP_ER_INVAL, 0);
|
||||
return -1;
|
||||
}
|
||||
return buffer_write(ctx->out, data, len, &ctx->error);
|
||||
|
||||
default:
|
||||
zip_error_set(&ctx->error, ZIP_ER_OPNOTSUPP, 0);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
buffer_free(buffer_t *buffer)
|
||||
{
|
||||
if (buffer == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (buffer->free_data) {
|
||||
zip_uint64_t i;
|
||||
|
||||
for (i=0; i < buffer->nfragments; i++) {
|
||||
free(buffer->fragments[i]);
|
||||
}
|
||||
}
|
||||
free(buffer->fragments);
|
||||
free(buffer);
|
||||
}
|
||||
|
||||
|
||||
static buffer_t *
|
||||
buffer_new(zip_uint64_t fragment_size)
|
||||
{
|
||||
buffer_t *buffer;
|
||||
|
||||
if ((buffer = malloc(sizeof(*buffer))) == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
buffer->fragment_size = fragment_size;
|
||||
buffer->offset = 0;
|
||||
buffer->free_data = 0;
|
||||
buffer->nfragments = 0;
|
||||
buffer->fragments_capacity = 0;
|
||||
buffer->fragments = NULL;
|
||||
buffer->size = 0;
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
|
||||
static buffer_t *
|
||||
buffer_new_read(const void *data, zip_uint64_t length, int free_data)
|
||||
{
|
||||
buffer_t *buffer;
|
||||
|
||||
if ((buffer = buffer_new(length)) == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
buffer->size = length;
|
||||
|
||||
if (length > 0) {
|
||||
if ((buffer->fragments = malloc(sizeof(*(buffer->fragments)))) == NULL) {
|
||||
buffer_free(buffer);
|
||||
return NULL;
|
||||
}
|
||||
buffer->fragments_capacity = 1;
|
||||
|
||||
buffer->nfragments = 1;
|
||||
buffer->fragments[0] = (zip_uint8_t *)data;
|
||||
buffer->free_data = free_data;
|
||||
}
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
|
||||
static buffer_t *
|
||||
buffer_new_write(zip_uint64_t fragment_size)
|
||||
{
|
||||
buffer_t *buffer;
|
||||
|
||||
if ((buffer = buffer_new(fragment_size)) == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ((buffer->fragments = malloc(sizeof(*(buffer->fragments)))) == NULL) {
|
||||
buffer_free(buffer);
|
||||
return NULL;
|
||||
}
|
||||
buffer->fragments_capacity = 1;
|
||||
buffer->nfragments = 0;
|
||||
buffer->free_data = 1;
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
|
||||
static zip_int64_t
|
||||
buffer_read(buffer_t *buffer, zip_uint8_t *data, zip_uint64_t length)
|
||||
{
|
||||
zip_uint64_t n, i, fragment_offset;
|
||||
|
||||
length = ZIP_MIN(length, buffer->size - buffer->offset);
|
||||
|
||||
if (length == 0) {
|
||||
return 0;
|
||||
}
|
||||
if (length > ZIP_INT64_MAX) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
i = buffer->offset / buffer->fragment_size;
|
||||
fragment_offset = buffer->offset % buffer->fragment_size;
|
||||
n = 0;
|
||||
while (n < length) {
|
||||
zip_uint64_t left = ZIP_MIN(length - n, buffer->fragment_size - fragment_offset);
|
||||
|
||||
memcpy(data + n, buffer->fragments[i] + fragment_offset, left);
|
||||
|
||||
n += left;
|
||||
i++;
|
||||
fragment_offset = 0;
|
||||
}
|
||||
|
||||
buffer->offset += n;
|
||||
return (zip_int64_t)n;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
buffer_seek(buffer_t *buffer, void *data, zip_uint64_t len, zip_error_t *error)
|
||||
{
|
||||
zip_int64_t new_offset = zip_source_seek_compute_offset(buffer->offset, buffer->size, data, len, error);
|
||||
|
||||
if (new_offset < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
buffer->offset = (zip_uint64_t)new_offset;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static zip_int64_t
|
||||
buffer_write(buffer_t *buffer, const zip_uint8_t *data, zip_uint64_t length, zip_error_t *error)
|
||||
{
|
||||
zip_uint64_t n, i, fragment_offset;
|
||||
zip_uint8_t **fragments;
|
||||
|
||||
if (buffer->offset + length + buffer->fragment_size - 1 < length) {
|
||||
zip_error_set(error, ZIP_ER_INVAL, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* grow buffer if needed */
|
||||
if (buffer->offset + length > buffer->nfragments * buffer->fragment_size) {
|
||||
zip_uint64_t needed_fragments = (buffer->offset + length + buffer->fragment_size - 1) / buffer->fragment_size;
|
||||
|
||||
if (needed_fragments > buffer->fragments_capacity) {
|
||||
zip_uint64_t new_capacity = buffer->fragments_capacity;
|
||||
|
||||
while (new_capacity < needed_fragments) {
|
||||
new_capacity *= 2;
|
||||
}
|
||||
|
||||
fragments = realloc(buffer->fragments, new_capacity * sizeof(*fragments));
|
||||
|
||||
if (fragments == NULL) {
|
||||
zip_error_set(error, ZIP_ER_MEMORY, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
buffer->fragments = fragments;
|
||||
buffer->fragments_capacity = new_capacity;
|
||||
}
|
||||
|
||||
while (buffer->nfragments < needed_fragments) {
|
||||
if ((buffer->fragments[buffer->nfragments] = malloc(buffer->fragment_size)) == NULL) {
|
||||
zip_error_set(error, ZIP_ER_MEMORY, 0);
|
||||
return -1;
|
||||
}
|
||||
buffer->nfragments++;
|
||||
}
|
||||
}
|
||||
|
||||
i = buffer->offset / buffer->fragment_size;
|
||||
fragment_offset = buffer->offset % buffer->fragment_size;
|
||||
n = 0;
|
||||
while (n < length) {
|
||||
zip_uint64_t left = ZIP_MIN(length - n, buffer->fragment_size - fragment_offset);
|
||||
|
||||
memcpy(buffer->fragments[i] + fragment_offset, data + n, left);
|
||||
|
||||
n += left;
|
||||
i++;
|
||||
fragment_offset = 0;
|
||||
}
|
||||
|
||||
buffer->offset += n;
|
||||
if (buffer->offset > buffer->size) {
|
||||
buffer->size = buffer->offset;
|
||||
}
|
||||
|
||||
return (zip_int64_t)n;
|
||||
}
|
||||
69
src/Common/libzip/zip_source_call.c
Normal file
69
src/Common/libzip/zip_source_call.c
Normal file
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
zip_source_call.c -- invoke callback command on zip_source
|
||||
Copyright (C) 2009-2014 Dieter Baron and Thomas Klausner
|
||||
|
||||
This file is part of libzip, a library to manipulate ZIP archives.
|
||||
The authors can be contacted at <libzip@nih.at>
|
||||
|
||||
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.
|
||||
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.
|
||||
3. The names of the authors may not be used to endorse or promote
|
||||
products derived from this software without specific prior
|
||||
written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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.
|
||||
*/
|
||||
|
||||
|
||||
#include "zipint.h"
|
||||
|
||||
|
||||
zip_int64_t
|
||||
_zip_source_call(zip_source_t *src, void *data, zip_uint64_t length, zip_source_cmd_t command)
|
||||
{
|
||||
zip_int64_t ret;
|
||||
|
||||
if ((src->supports & ZIP_SOURCE_MAKE_COMMAND_BITMASK(command)) == 0) {
|
||||
zip_error_set(&src->error, ZIP_ER_OPNOTSUPP, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (src->src == NULL) {
|
||||
ret = src->cb.f(src->ud, data, length, command);
|
||||
}
|
||||
else {
|
||||
ret = src->cb.l(src->src, src->ud, data, length, command);
|
||||
}
|
||||
|
||||
if (ret < 0) {
|
||||
if (command != ZIP_SOURCE_ERROR && command != ZIP_SOURCE_SUPPORTS) {
|
||||
int e[2];
|
||||
|
||||
if (_zip_source_call(src, e, sizeof(e), ZIP_SOURCE_ERROR) < 0) {
|
||||
zip_error_set(&src->error, ZIP_ER_INTERNAL, 0);
|
||||
}
|
||||
else {
|
||||
zip_error_set(&src->error, e[0], e[1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
58
src/Common/libzip/zip_source_close.c
Normal file
58
src/Common/libzip/zip_source_close.c
Normal file
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
zip_source_close.c -- close zip_source (stop reading)
|
||||
Copyright (C) 2009-2014 Dieter Baron and Thomas Klausner
|
||||
|
||||
This file is part of libzip, a library to manipulate ZIP archives.
|
||||
The authors can be contacted at <libzip@nih.at>
|
||||
|
||||
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.
|
||||
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.
|
||||
3. The names of the authors may not be used to endorse or promote
|
||||
products derived from this software without specific prior
|
||||
written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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.
|
||||
*/
|
||||
|
||||
|
||||
#include "zipint.h"
|
||||
|
||||
|
||||
int
|
||||
zip_source_close(zip_source_t *src)
|
||||
{
|
||||
if (!ZIP_SOURCE_IS_OPEN_READING(src)) {
|
||||
zip_error_set(&src->error, ZIP_ER_INVAL, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
src->open_count--;
|
||||
if (src->open_count == 0) {
|
||||
_zip_source_call(src, NULL, 0, ZIP_SOURCE_CLOSE);
|
||||
|
||||
if (ZIP_SOURCE_IS_LAYERED(src)) {
|
||||
if (zip_source_close(src->src) < 0) {
|
||||
zip_error_set(&src->error, ZIP_ER_INTERNAL, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
64
src/Common/libzip/zip_source_commit_write.c
Normal file
64
src/Common/libzip/zip_source_commit_write.c
Normal file
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
zip_source_commit_write.c -- commit changes to file
|
||||
Copyright (C) 2014 Dieter Baron and Thomas Klausner
|
||||
|
||||
This file is part of libzip, a library to manipulate ZIP archives.
|
||||
The authors can be contacted at <libzip@nih.at>
|
||||
|
||||
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.
|
||||
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.
|
||||
3. The names of the authors may not be used to endorse or promote
|
||||
products derived from this software without specific prior
|
||||
written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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.
|
||||
*/
|
||||
|
||||
|
||||
#include "zipint.h"
|
||||
|
||||
|
||||
ZIP_EXTERN int
|
||||
zip_source_commit_write(zip_source_t *src)
|
||||
{
|
||||
if (!ZIP_SOURCE_IS_OPEN_WRITING(src)) {
|
||||
zip_error_set(&src->error, ZIP_ER_INVAL, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (src->open_count > 1) {
|
||||
zip_error_set(&src->error, ZIP_ER_INUSE, 0);
|
||||
return -1;
|
||||
}
|
||||
else if (ZIP_SOURCE_IS_OPEN_READING(src)) {
|
||||
if (zip_source_close(src) < 0) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (_zip_source_call(src, NULL, 0, ZIP_SOURCE_COMMIT_WRITE) < 0) {
|
||||
src->write_state = ZIP_SOURCE_WRITE_FAILED;
|
||||
return -1;
|
||||
}
|
||||
|
||||
src->write_state = ZIP_SOURCE_WRITE_CLOSED;
|
||||
|
||||
return 0;
|
||||
}
|
||||
202
src/Common/libzip/zip_source_crc.c
Normal file
202
src/Common/libzip/zip_source_crc.c
Normal file
@@ -0,0 +1,202 @@
|
||||
/*
|
||||
zip_source_crc.c -- pass-through source that calculates CRC32 and size
|
||||
Copyright (C) 2009-2016 Dieter Baron and Thomas Klausner
|
||||
|
||||
This file is part of libzip, a library to manipulate ZIP archives.
|
||||
The authors can be contacted at <libzip@nih.at>
|
||||
|
||||
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.
|
||||
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.
|
||||
3. The names of the authors may not be used to endorse or promote
|
||||
products derived from this software without specific prior
|
||||
written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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.
|
||||
*/
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include "zipint.h"
|
||||
|
||||
struct crc_context {
|
||||
int validate; /* whether to check CRC on EOF and return error on mismatch */
|
||||
int crc_complete; /* whether CRC was computed for complete file */
|
||||
zip_error_t error;
|
||||
zip_uint64_t size;
|
||||
zip_uint64_t position; /* current reading position */
|
||||
zip_uint64_t crc_position; /* how far we've computed the CRC */
|
||||
zip_uint32_t crc;
|
||||
};
|
||||
|
||||
static zip_int64_t crc_read(zip_source_t *, void *, void *, zip_uint64_t, zip_source_cmd_t);
|
||||
|
||||
|
||||
zip_source_t *
|
||||
zip_source_crc(zip_t *za, zip_source_t *src, int validate)
|
||||
{
|
||||
struct crc_context *ctx;
|
||||
|
||||
if (src == NULL) {
|
||||
zip_error_set(&za->error, ZIP_ER_INVAL, 0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ((ctx=(struct crc_context *)malloc(sizeof(*ctx))) == NULL) {
|
||||
zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
zip_error_init(&ctx->error);
|
||||
ctx->validate = validate;
|
||||
ctx->crc_complete = 0;
|
||||
ctx->crc_position = 0;
|
||||
ctx->crc = (zip_uint32_t)crc32(0, NULL, 0);
|
||||
ctx->size = 0;
|
||||
|
||||
return zip_source_layered(za, src, crc_read, ctx);
|
||||
}
|
||||
|
||||
|
||||
static zip_int64_t
|
||||
crc_read(zip_source_t *src, void *_ctx, void *data, zip_uint64_t len, zip_source_cmd_t cmd)
|
||||
{
|
||||
struct crc_context *ctx;
|
||||
zip_int64_t n;
|
||||
|
||||
ctx = (struct crc_context *)_ctx;
|
||||
|
||||
switch (cmd) {
|
||||
case ZIP_SOURCE_OPEN:
|
||||
ctx->position = 0;
|
||||
return 0;
|
||||
|
||||
case ZIP_SOURCE_READ:
|
||||
if ((n = zip_source_read(src, data, len)) < 0) {
|
||||
_zip_error_set_from_source(&ctx->error, src);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (n == 0) {
|
||||
if (ctx->crc_position == ctx->position) {
|
||||
ctx->crc_complete = 1;
|
||||
ctx->size = ctx->position;
|
||||
|
||||
if (ctx->validate) {
|
||||
struct zip_stat st;
|
||||
|
||||
if (zip_source_stat(src, &st) < 0) {
|
||||
_zip_error_set_from_source(&ctx->error, src);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((st.valid & ZIP_STAT_CRC) && st.crc != ctx->crc) {
|
||||
zip_error_set(&ctx->error, ZIP_ER_CRC, 0);
|
||||
return -1;
|
||||
}
|
||||
if ((st.valid & ZIP_STAT_SIZE) && st.size != ctx->size) {
|
||||
zip_error_set(&ctx->error, ZIP_ER_INCONS, 0);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (!ctx->crc_complete && ctx->position <= ctx->crc_position) {
|
||||
zip_uint64_t i, nn;
|
||||
|
||||
for (i = ctx->crc_position - ctx->position; i < (zip_uint64_t)n; i += nn) {
|
||||
nn = ZIP_MIN(UINT_MAX, (zip_uint64_t)n-i);
|
||||
|
||||
ctx->crc = (zip_uint32_t)crc32(ctx->crc, (const Bytef *)data+i, (uInt)nn);
|
||||
ctx->crc_position += nn;
|
||||
}
|
||||
}
|
||||
ctx->position += (zip_uint64_t)n;
|
||||
return n;
|
||||
|
||||
case ZIP_SOURCE_CLOSE:
|
||||
return 0;
|
||||
|
||||
case ZIP_SOURCE_STAT:
|
||||
{
|
||||
zip_stat_t *st;
|
||||
|
||||
st = (zip_stat_t *)data;
|
||||
|
||||
if (ctx->crc_complete) {
|
||||
/* TODO: Set comp_size, comp_method, encryption_method?
|
||||
After all, this only works for uncompressed data. */
|
||||
st->size = ctx->size;
|
||||
st->crc = ctx->crc;
|
||||
st->comp_size = ctx->size;
|
||||
st->comp_method = ZIP_CM_STORE;
|
||||
st->encryption_method = ZIP_EM_NONE;
|
||||
st->valid |= ZIP_STAT_SIZE|ZIP_STAT_CRC|ZIP_STAT_COMP_SIZE|ZIP_STAT_COMP_METHOD|ZIP_STAT_ENCRYPTION_METHOD;;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
case ZIP_SOURCE_ERROR:
|
||||
return zip_error_to_data(&ctx->error, data, len);
|
||||
|
||||
case ZIP_SOURCE_FREE:
|
||||
free(ctx);
|
||||
return 0;
|
||||
|
||||
case ZIP_SOURCE_SUPPORTS:
|
||||
{
|
||||
zip_int64_t mask = zip_source_supports(src);
|
||||
|
||||
if (mask < 0) {
|
||||
_zip_error_set_from_source(&ctx->error, src);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return mask & ~zip_source_make_command_bitmap(ZIP_SOURCE_BEGIN_WRITE, ZIP_SOURCE_COMMIT_WRITE, ZIP_SOURCE_ROLLBACK_WRITE, ZIP_SOURCE_SEEK_WRITE, ZIP_SOURCE_TELL_WRITE, ZIP_SOURCE_REMOVE, -1);
|
||||
}
|
||||
|
||||
case ZIP_SOURCE_SEEK:
|
||||
{
|
||||
zip_int64_t new_position;
|
||||
zip_source_args_seek_t *args = ZIP_SOURCE_GET_ARGS(zip_source_args_seek_t, data, len, &ctx->error);
|
||||
|
||||
if (args == NULL) {
|
||||
return -1;
|
||||
}
|
||||
if (zip_source_seek(src, args->offset, args->whence) < 0 || (new_position = zip_source_tell(src)) < 0) {
|
||||
_zip_error_set_from_source(&ctx->error, src);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ctx->position = (zip_uint64_t)new_position;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
case ZIP_SOURCE_TELL:
|
||||
return (zip_int64_t)ctx->position;
|
||||
|
||||
default:
|
||||
zip_error_set(&ctx->error, ZIP_ER_OPNOTSUPP, 0);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
415
src/Common/libzip/zip_source_deflate.c
Normal file
415
src/Common/libzip/zip_source_deflate.c
Normal file
@@ -0,0 +1,415 @@
|
||||
/*
|
||||
zip_source_deflate.c -- deflate (de)compressoin routines
|
||||
Copyright (C) 2009-2015 Dieter Baron and Thomas Klausner
|
||||
|
||||
This file is part of libzip, a library to manipulate ZIP archives.
|
||||
The authors can be contacted at <libzip@nih.at>
|
||||
|
||||
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.
|
||||
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.
|
||||
3. The names of the authors may not be used to endorse or promote
|
||||
products derived from this software without specific prior
|
||||
written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include "zipint.h"
|
||||
|
||||
struct deflate {
|
||||
zip_error_t error;
|
||||
|
||||
bool eof;
|
||||
bool can_store;
|
||||
bool is_stored;
|
||||
int mem_level;
|
||||
zip_uint64_t size;
|
||||
zip_uint8_t buffer[BUFSIZE];
|
||||
z_stream zstr;
|
||||
};
|
||||
|
||||
static zip_int64_t compress_read(zip_source_t *, struct deflate *, void *, zip_uint64_t);
|
||||
static zip_int64_t decompress_read(zip_source_t *, struct deflate *, void *, zip_uint64_t);
|
||||
static zip_int64_t deflate_compress(zip_source_t *, void *, void *, zip_uint64_t, zip_source_cmd_t);
|
||||
static zip_int64_t deflate_decompress(zip_source_t *, void *, void *, zip_uint64_t, zip_source_cmd_t);
|
||||
static void deflate_free(struct deflate *);
|
||||
|
||||
|
||||
zip_source_t *
|
||||
zip_source_deflate(zip_t *za, zip_source_t *src, zip_int32_t cm, int flags)
|
||||
{
|
||||
struct deflate *ctx;
|
||||
zip_source_t *s2;
|
||||
|
||||
if (src == NULL || (cm != ZIP_CM_DEFLATE && !ZIP_CM_IS_DEFAULT(cm))) {
|
||||
zip_error_set(&za->error, ZIP_ER_INVAL, 0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ((ctx=(struct deflate *)malloc(sizeof(*ctx))) == NULL) {
|
||||
zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
zip_error_init(&ctx->error);
|
||||
ctx->eof = false;
|
||||
ctx->is_stored = false;
|
||||
ctx->can_store = ZIP_CM_IS_DEFAULT(cm);
|
||||
if (flags & ZIP_CODEC_ENCODE) {
|
||||
ctx->mem_level = MAX_MEM_LEVEL;
|
||||
}
|
||||
|
||||
if ((s2=zip_source_layered(za, src,
|
||||
((flags & ZIP_CODEC_ENCODE)
|
||||
? deflate_compress : deflate_decompress),
|
||||
ctx)) == NULL) {
|
||||
deflate_free(ctx);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return s2;
|
||||
}
|
||||
|
||||
|
||||
static zip_int64_t
|
||||
compress_read(zip_source_t *src, struct deflate *ctx, void *data, zip_uint64_t len)
|
||||
{
|
||||
int end, ret;
|
||||
zip_int64_t n;
|
||||
zip_uint64_t out_offset;
|
||||
uInt out_len;
|
||||
|
||||
if (zip_error_code_zip(&ctx->error) != ZIP_ER_OK)
|
||||
return -1;
|
||||
|
||||
if (len == 0 || ctx->is_stored) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
out_offset = 0;
|
||||
out_len = (uInt)ZIP_MIN(UINT_MAX, len);
|
||||
ctx->zstr.next_out = (Bytef *)data;
|
||||
ctx->zstr.avail_out = out_len;
|
||||
|
||||
end = 0;
|
||||
while (!end) {
|
||||
ret = deflate(&ctx->zstr, ctx->eof ? Z_FINISH : 0);
|
||||
|
||||
switch (ret) {
|
||||
case Z_STREAM_END:
|
||||
if (ctx->can_store && ctx->zstr.total_in <= ctx->zstr.total_out) {
|
||||
ctx->is_stored = true;
|
||||
ctx->size = ctx->zstr.total_in;
|
||||
memcpy(data, ctx->buffer, ctx->size);
|
||||
return (zip_int64_t)ctx->size;
|
||||
}
|
||||
/* fallthrough */
|
||||
case Z_OK:
|
||||
/* all ok */
|
||||
|
||||
if (ctx->zstr.avail_out == 0) {
|
||||
out_offset += out_len;
|
||||
if (out_offset < len) {
|
||||
out_len = (uInt)ZIP_MIN(UINT_MAX, len-out_offset);
|
||||
ctx->zstr.next_out = (Bytef *)data+out_offset;
|
||||
ctx->zstr.avail_out = out_len;
|
||||
}
|
||||
else {
|
||||
ctx->can_store = false;
|
||||
end = 1;
|
||||
}
|
||||
}
|
||||
else if (ctx->eof && ctx->zstr.avail_in == 0)
|
||||
end = 1;
|
||||
break;
|
||||
|
||||
case Z_BUF_ERROR:
|
||||
if (ctx->zstr.avail_in == 0) {
|
||||
if (ctx->eof) {
|
||||
end = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
if ((n=zip_source_read(src, ctx->buffer, sizeof(ctx->buffer))) < 0) {
|
||||
_zip_error_set_from_source(&ctx->error, src);
|
||||
end = 1;
|
||||
break;
|
||||
}
|
||||
else if (n == 0) {
|
||||
ctx->eof = true;
|
||||
/* TODO: check against stat of src? */
|
||||
ctx->size = ctx->zstr.total_in;
|
||||
}
|
||||
else {
|
||||
if (ctx->zstr.total_in > 0) {
|
||||
/* we overwrote a previously filled ctx->buffer */
|
||||
ctx->can_store = false;
|
||||
}
|
||||
ctx->zstr.next_in = (Bytef *)ctx->buffer;
|
||||
ctx->zstr.avail_in = (uInt)n;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
/* fallthrough */
|
||||
case Z_NEED_DICT:
|
||||
case Z_DATA_ERROR:
|
||||
case Z_STREAM_ERROR:
|
||||
case Z_MEM_ERROR:
|
||||
zip_error_set(&ctx->error, ZIP_ER_ZLIB, ret);
|
||||
|
||||
end = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (ctx->zstr.avail_out < len) {
|
||||
ctx->can_store = false;
|
||||
return (zip_int64_t)(len - ctx->zstr.avail_out);
|
||||
}
|
||||
|
||||
return (zip_error_code_zip(&ctx->error) == ZIP_ER_OK) ? 0 : -1;
|
||||
}
|
||||
|
||||
|
||||
static zip_int64_t
|
||||
decompress_read(zip_source_t *src, struct deflate *ctx, void *data, zip_uint64_t len)
|
||||
{
|
||||
int end, ret;
|
||||
zip_int64_t n;
|
||||
zip_uint64_t out_offset;
|
||||
uInt out_len;
|
||||
|
||||
if (zip_error_code_zip(&ctx->error) != ZIP_ER_OK)
|
||||
return -1;
|
||||
|
||||
if (len == 0)
|
||||
return 0;
|
||||
|
||||
out_offset = 0;
|
||||
out_len = (uInt)ZIP_MIN(UINT_MAX, len);
|
||||
ctx->zstr.next_out = (Bytef *)data;
|
||||
ctx->zstr.avail_out = out_len;
|
||||
|
||||
end = 0;
|
||||
while (!end) {
|
||||
ret = inflate(&ctx->zstr, Z_SYNC_FLUSH);
|
||||
|
||||
switch (ret) {
|
||||
case Z_OK:
|
||||
if (ctx->zstr.avail_out == 0) {
|
||||
out_offset += out_len;
|
||||
if (out_offset < len) {
|
||||
out_len = (uInt)ZIP_MIN(UINT_MAX, len-out_offset);
|
||||
ctx->zstr.next_out = (Bytef *)data+out_offset;
|
||||
ctx->zstr.avail_out = out_len;
|
||||
}
|
||||
else {
|
||||
end = 1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case Z_STREAM_END:
|
||||
ctx->eof = 1;
|
||||
end = 1;
|
||||
break;
|
||||
|
||||
case Z_BUF_ERROR:
|
||||
if (ctx->zstr.avail_in == 0) {
|
||||
if (ctx->eof) {
|
||||
end = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
if ((n=zip_source_read(src, ctx->buffer, sizeof(ctx->buffer))) < 0) {
|
||||
_zip_error_set_from_source(&ctx->error, src);
|
||||
end = 1;
|
||||
break;
|
||||
}
|
||||
else if (n == 0) {
|
||||
ctx->eof = 1;
|
||||
}
|
||||
else {
|
||||
ctx->zstr.next_in = (Bytef *)ctx->buffer;
|
||||
ctx->zstr.avail_in = (uInt)n;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
/* fallthrough */
|
||||
case Z_NEED_DICT:
|
||||
case Z_DATA_ERROR:
|
||||
case Z_STREAM_ERROR:
|
||||
case Z_MEM_ERROR:
|
||||
zip_error_set(&ctx->error, ZIP_ER_ZLIB, ret);
|
||||
end = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (ctx->zstr.avail_out < len)
|
||||
return (zip_int64_t)(len - ctx->zstr.avail_out);
|
||||
|
||||
return (zip_error_code_zip(&ctx->error) == ZIP_ER_OK) ? 0 : -1;
|
||||
}
|
||||
|
||||
|
||||
static zip_int64_t
|
||||
deflate_compress(zip_source_t *src, void *ud, void *data, zip_uint64_t len, zip_source_cmd_t cmd)
|
||||
{
|
||||
struct deflate *ctx;
|
||||
int ret;
|
||||
|
||||
ctx = (struct deflate *)ud;
|
||||
|
||||
switch (cmd) {
|
||||
case ZIP_SOURCE_OPEN:
|
||||
ctx->zstr.zalloc = Z_NULL;
|
||||
ctx->zstr.zfree = Z_NULL;
|
||||
ctx->zstr.opaque = NULL;
|
||||
ctx->zstr.avail_in = 0;
|
||||
ctx->zstr.next_in = NULL;
|
||||
ctx->zstr.avail_out = 0;
|
||||
ctx->zstr.next_out = NULL;
|
||||
|
||||
/* negative value to tell zlib not to write a header */
|
||||
if ((ret=deflateInit2(&ctx->zstr, Z_BEST_COMPRESSION, Z_DEFLATED, -MAX_WBITS, ctx->mem_level, Z_DEFAULT_STRATEGY)) != Z_OK) {
|
||||
zip_error_set(&ctx->error, ZIP_ER_ZLIB, ret);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
case ZIP_SOURCE_READ:
|
||||
return compress_read(src, ctx, data, len);
|
||||
|
||||
case ZIP_SOURCE_CLOSE:
|
||||
deflateEnd(&ctx->zstr);
|
||||
return 0;
|
||||
|
||||
case ZIP_SOURCE_STAT:
|
||||
{
|
||||
zip_stat_t *st;
|
||||
|
||||
st = (zip_stat_t *)data;
|
||||
|
||||
st->comp_method = ctx->is_stored ? ZIP_CM_STORE : ZIP_CM_DEFLATE;
|
||||
st->valid |= ZIP_STAT_COMP_METHOD;
|
||||
if (ctx->eof) {
|
||||
st->comp_size = ctx->size;
|
||||
st->valid |= ZIP_STAT_COMP_SIZE;
|
||||
}
|
||||
else
|
||||
st->valid &= ~ZIP_STAT_COMP_SIZE;
|
||||
}
|
||||
return 0;
|
||||
|
||||
case ZIP_SOURCE_ERROR:
|
||||
return zip_error_to_data(&ctx->error, data, len);
|
||||
|
||||
case ZIP_SOURCE_FREE:
|
||||
deflate_free(ctx);
|
||||
return 0;
|
||||
|
||||
case ZIP_SOURCE_SUPPORTS:
|
||||
return ZIP_SOURCE_SUPPORTS_READABLE;
|
||||
|
||||
default:
|
||||
zip_error_set(&ctx->error, ZIP_ER_INTERNAL, 0);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static zip_int64_t
|
||||
deflate_decompress(zip_source_t *src, void *ud, void *data,
|
||||
zip_uint64_t len, zip_source_cmd_t cmd)
|
||||
{
|
||||
struct deflate *ctx;
|
||||
zip_int64_t n;
|
||||
int ret;
|
||||
|
||||
ctx = (struct deflate *)ud;
|
||||
|
||||
switch (cmd) {
|
||||
case ZIP_SOURCE_OPEN:
|
||||
if ((n=zip_source_read(src, ctx->buffer, sizeof(ctx->buffer))) < 0) {
|
||||
_zip_error_set_from_source(&ctx->error, src);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ctx->zstr.zalloc = Z_NULL;
|
||||
ctx->zstr.zfree = Z_NULL;
|
||||
ctx->zstr.opaque = NULL;
|
||||
ctx->zstr.next_in = (Bytef *)ctx->buffer;
|
||||
ctx->zstr.avail_in = (uInt)n;
|
||||
|
||||
/* negative value to tell zlib that there is no header */
|
||||
if ((ret=inflateInit2(&ctx->zstr, -MAX_WBITS)) != Z_OK) {
|
||||
zip_error_set(&ctx->error, ZIP_ER_ZLIB, ret);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
|
||||
case ZIP_SOURCE_READ:
|
||||
return decompress_read(src, ctx, data, len);
|
||||
|
||||
case ZIP_SOURCE_CLOSE:
|
||||
inflateEnd(&ctx->zstr);
|
||||
return 0;
|
||||
|
||||
case ZIP_SOURCE_STAT:
|
||||
{
|
||||
zip_stat_t *st;
|
||||
|
||||
st = (zip_stat_t *)data;
|
||||
|
||||
st->comp_method = ZIP_CM_STORE;
|
||||
if (st->comp_size > 0 && st->size > 0)
|
||||
st->comp_size = st->size;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
case ZIP_SOURCE_ERROR:
|
||||
return zip_error_to_data(&ctx->error, data, len);
|
||||
|
||||
case ZIP_SOURCE_FREE:
|
||||
free(ctx);
|
||||
return 0;
|
||||
|
||||
case ZIP_SOURCE_SUPPORTS:
|
||||
return zip_source_make_command_bitmap(ZIP_SOURCE_OPEN, ZIP_SOURCE_READ, ZIP_SOURCE_CLOSE, ZIP_SOURCE_STAT, ZIP_SOURCE_ERROR, ZIP_SOURCE_FREE, -1);
|
||||
|
||||
default:
|
||||
zip_error_set(&ctx->error, ZIP_ER_OPNOTSUPP, 0);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
deflate_free(struct deflate *ctx)
|
||||
{
|
||||
free(ctx);
|
||||
}
|
||||
42
src/Common/libzip/zip_source_error.c
Normal file
42
src/Common/libzip/zip_source_error.c
Normal file
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
zip_source_error.c -- get last error from zip_source
|
||||
Copyright (C) 2009-2014 Dieter Baron and Thomas Klausner
|
||||
|
||||
This file is part of libzip, a library to manipulate ZIP archives.
|
||||
The authors can be contacted at <libzip@nih.at>
|
||||
|
||||
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.
|
||||
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.
|
||||
3. The names of the authors may not be used to endorse or promote
|
||||
products derived from this software without specific prior
|
||||
written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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.
|
||||
*/
|
||||
|
||||
|
||||
#include "zipint.h"
|
||||
|
||||
|
||||
zip_error_t *
|
||||
zip_source_error(zip_source_t *src)
|
||||
{
|
||||
return &src->error;
|
||||
}
|
||||
63
src/Common/libzip/zip_source_file.c
Normal file
63
src/Common/libzip/zip_source_file.c
Normal file
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
zip_source_file.c -- create data source from file
|
||||
Copyright (C) 1999-2015 Dieter Baron and Thomas Klausner
|
||||
|
||||
This file is part of libzip, a library to manipulate ZIP archives.
|
||||
The authors can be contacted at <libzip@nih.at>
|
||||
|
||||
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.
|
||||
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.
|
||||
3. The names of the authors may not be used to endorse or promote
|
||||
products derived from this software without specific prior
|
||||
written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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.
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "zipint.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#error This file is incompatible with Windows, use zip_source_win32utf8.c instead.
|
||||
#error Something probably went wrong with configure/cmake.
|
||||
#endif
|
||||
|
||||
ZIP_EXTERN zip_source_t *
|
||||
zip_source_file(zip_t *za, const char *fname, zip_uint64_t start, zip_int64_t len)
|
||||
{
|
||||
if (za == NULL)
|
||||
return NULL;
|
||||
|
||||
return zip_source_file_create(fname, start, len, &za->error);
|
||||
}
|
||||
|
||||
|
||||
ZIP_EXTERN zip_source_t *
|
||||
zip_source_file_create(const char *fname, zip_uint64_t start, zip_int64_t length, zip_error_t *error)
|
||||
{
|
||||
if (fname == NULL || length < -1) {
|
||||
zip_error_set(error, ZIP_ER_INVAL, 0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return _zip_source_file_or_p(fname, NULL, start, length, NULL, error);
|
||||
}
|
||||
503
src/Common/libzip/zip_source_filep.c
Normal file
503
src/Common/libzip/zip_source_filep.c
Normal file
@@ -0,0 +1,503 @@
|
||||
/*
|
||||
zip_source_filep.c -- create data source from FILE *
|
||||
Copyright (C) 1999-2015 Dieter Baron and Thomas Klausner
|
||||
|
||||
This file is part of libzip, a library to manipulate ZIP archives.
|
||||
The authors can be contacted at <libzip@nih.at>
|
||||
|
||||
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.
|
||||
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.
|
||||
3. The names of the authors may not be used to endorse or promote
|
||||
products derived from this software without specific prior
|
||||
written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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.
|
||||
*/
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "zipint.h"
|
||||
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
/* WIN32 needs <fcntl.h> for _O_BINARY */
|
||||
#include <fcntl.h>
|
||||
#endif
|
||||
|
||||
/* Windows sys/types.h does not provide these */
|
||||
#ifndef S_ISREG
|
||||
#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
|
||||
#endif
|
||||
#if defined(S_IXUSR) && defined(S_IRWXG) && defined(S_IRWXO)
|
||||
#define _SAFE_MASK (S_IXUSR | S_IRWXG | S_IRWXO)
|
||||
#elif defined(_S_IWRITE)
|
||||
#define _SAFE_MASK (_S_IWRITE)
|
||||
#else
|
||||
#error do not know safe values for umask, please report this
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
/* MSVC doesn't have mode_t */
|
||||
typedef int mode_t;
|
||||
#endif
|
||||
|
||||
struct read_file {
|
||||
zip_error_t error; /* last error information */
|
||||
zip_int64_t supports;
|
||||
|
||||
/* reading */
|
||||
char *fname; /* name of file to read from */
|
||||
FILE *f; /* file to read from */
|
||||
struct zip_stat st; /* stat information passed in */
|
||||
zip_uint64_t start; /* start offset of data to read */
|
||||
zip_uint64_t end; /* end offset of data to read, 0 for up to EOF */
|
||||
zip_uint64_t current; /* current offset */
|
||||
|
||||
/* writing */
|
||||
char *tmpname;
|
||||
FILE *fout;
|
||||
};
|
||||
|
||||
static zip_int64_t read_file(void *state, void *data, zip_uint64_t len, zip_source_cmd_t cmd);
|
||||
static int create_temp_output(struct read_file *ctx);
|
||||
static int _zip_fseek_u(FILE *f, zip_uint64_t offset, int whence, zip_error_t *error);
|
||||
static int _zip_fseek(FILE *f, zip_int64_t offset, int whence, zip_error_t *error);
|
||||
|
||||
|
||||
ZIP_EXTERN zip_source_t *
|
||||
zip_source_filep(zip_t *za, FILE *file, zip_uint64_t start, zip_int64_t len)
|
||||
{
|
||||
if (za == NULL)
|
||||
return NULL;
|
||||
|
||||
return zip_source_filep_create(file, start, len, &za->error);
|
||||
}
|
||||
|
||||
|
||||
ZIP_EXTERN zip_source_t *
|
||||
zip_source_filep_create(FILE *file, zip_uint64_t start, zip_int64_t length, zip_error_t *error)
|
||||
{
|
||||
if (file == NULL || length < -1) {
|
||||
zip_error_set(error, ZIP_ER_INVAL, 0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return _zip_source_file_or_p(NULL, file, start, length, NULL, error);
|
||||
}
|
||||
|
||||
|
||||
zip_source_t *
|
||||
_zip_source_file_or_p(const char *fname, FILE *file, zip_uint64_t start, zip_int64_t len, const zip_stat_t *st, zip_error_t *error)
|
||||
{
|
||||
struct read_file *ctx;
|
||||
zip_source_t *zs;
|
||||
|
||||
if (file == NULL && fname == NULL) {
|
||||
zip_error_set(error, ZIP_ER_INVAL, 0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ((ctx=(struct read_file *)malloc(sizeof(struct read_file))) == NULL) {
|
||||
zip_error_set(error, ZIP_ER_MEMORY, 0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ctx->fname = NULL;
|
||||
if (fname) {
|
||||
if ((ctx->fname=strdup(fname)) == NULL) {
|
||||
zip_error_set(error, ZIP_ER_MEMORY, 0);
|
||||
free(ctx);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
ctx->f = file;
|
||||
ctx->start = start;
|
||||
ctx->end = (len < 0 ? 0 : start+(zip_uint64_t)len);
|
||||
if (st) {
|
||||
memcpy(&ctx->st, st, sizeof(ctx->st));
|
||||
ctx->st.name = NULL;
|
||||
ctx->st.valid &= ~ZIP_STAT_NAME;
|
||||
}
|
||||
else {
|
||||
zip_stat_init(&ctx->st);
|
||||
}
|
||||
|
||||
ctx->tmpname = NULL;
|
||||
ctx->fout = NULL;
|
||||
|
||||
zip_error_init(&ctx->error);
|
||||
|
||||
ctx->supports = ZIP_SOURCE_SUPPORTS_READABLE | zip_source_make_command_bitmap(ZIP_SOURCE_SUPPORTS, ZIP_SOURCE_TELL, -1);
|
||||
if (ctx->fname) {
|
||||
struct stat sb;
|
||||
|
||||
if (stat(ctx->fname, &sb) < 0 || S_ISREG(sb.st_mode)) {
|
||||
ctx->supports = ZIP_SOURCE_SUPPORTS_WRITABLE;
|
||||
}
|
||||
}
|
||||
else if (fseeko(ctx->f, 0, SEEK_CUR) == 0) {
|
||||
ctx->supports = ZIP_SOURCE_SUPPORTS_SEEKABLE;
|
||||
}
|
||||
|
||||
if ((zs=zip_source_function_create(read_file, ctx, error)) == NULL) {
|
||||
free(ctx->fname);
|
||||
free(ctx);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return zs;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
create_temp_output(struct read_file *ctx)
|
||||
{
|
||||
char *temp;
|
||||
int tfd;
|
||||
mode_t mask;
|
||||
FILE *tfp;
|
||||
|
||||
if ((temp=(char *)malloc(strlen(ctx->fname)+8)) == NULL) {
|
||||
zip_error_set(&ctx->error, ZIP_ER_MEMORY, 0);
|
||||
return -1;
|
||||
}
|
||||
sprintf(temp, "%s.XXXXXX", ctx->fname);
|
||||
|
||||
mask = umask(_SAFE_MASK);
|
||||
if ((tfd=mkstemp(temp)) == -1) {
|
||||
zip_error_set(&ctx->error, ZIP_ER_TMPOPEN, errno);
|
||||
umask(mask);
|
||||
free(temp);
|
||||
return -1;
|
||||
}
|
||||
umask(mask);
|
||||
|
||||
if ((tfp=fdopen(tfd, "r+b")) == NULL) {
|
||||
zip_error_set(&ctx->error, ZIP_ER_TMPOPEN, errno);
|
||||
close(tfd);
|
||||
(void)remove(temp);
|
||||
free(temp);
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
/*
|
||||
According to Pierre Joye, Windows in some environments per
|
||||
default creates text files, so force binary mode.
|
||||
*/
|
||||
_setmode(_fileno(tfp), _O_BINARY );
|
||||
#endif
|
||||
|
||||
ctx->fout = tfp;
|
||||
ctx->tmpname = temp;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static zip_int64_t
|
||||
read_file(void *state, void *data, zip_uint64_t len, zip_source_cmd_t cmd)
|
||||
{
|
||||
struct read_file *ctx;
|
||||
char *buf;
|
||||
zip_uint64_t n;
|
||||
size_t i;
|
||||
|
||||
ctx = (struct read_file *)state;
|
||||
buf = (char *)data;
|
||||
|
||||
switch (cmd) {
|
||||
case ZIP_SOURCE_BEGIN_WRITE:
|
||||
if (ctx->fname == NULL) {
|
||||
zip_error_set(&ctx->error, ZIP_ER_OPNOTSUPP, 0);
|
||||
return -1;
|
||||
}
|
||||
return create_temp_output(ctx);
|
||||
|
||||
case ZIP_SOURCE_COMMIT_WRITE: {
|
||||
mode_t mask;
|
||||
|
||||
if (fclose(ctx->fout) < 0) {
|
||||
ctx->fout = NULL;
|
||||
zip_error_set(&ctx->error, ZIP_ER_WRITE, errno);
|
||||
}
|
||||
ctx->fout = NULL;
|
||||
if (rename(ctx->tmpname, ctx->fname) < 0) {
|
||||
zip_error_set(&ctx->error, ZIP_ER_RENAME, errno);
|
||||
return -1;
|
||||
}
|
||||
mask = umask(022);
|
||||
umask(mask);
|
||||
/* not much we can do if chmod fails except make the whole commit fail */
|
||||
(void)chmod(ctx->fname, 0666&~mask);
|
||||
free(ctx->tmpname);
|
||||
ctx->tmpname = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
case ZIP_SOURCE_CLOSE:
|
||||
if (ctx->fname) {
|
||||
fclose(ctx->f);
|
||||
ctx->f = NULL;
|
||||
}
|
||||
return 0;
|
||||
|
||||
case ZIP_SOURCE_ERROR:
|
||||
return zip_error_to_data(&ctx->error, data, len);
|
||||
|
||||
case ZIP_SOURCE_FREE:
|
||||
free(ctx->fname);
|
||||
free(ctx->tmpname);
|
||||
if (ctx->f)
|
||||
fclose(ctx->f);
|
||||
free(ctx);
|
||||
return 0;
|
||||
|
||||
case ZIP_SOURCE_OPEN:
|
||||
if (ctx->fname) {
|
||||
if ((ctx->f=fopen(ctx->fname, "rb")) == NULL) {
|
||||
zip_error_set(&ctx->error, ZIP_ER_OPEN, errno);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (ctx->start > 0) {
|
||||
if (_zip_fseek_u(ctx->f, ctx->start, SEEK_SET, &ctx->error) < 0) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
ctx->current = ctx->start;
|
||||
return 0;
|
||||
|
||||
case ZIP_SOURCE_READ:
|
||||
if (ctx->end > 0) {
|
||||
n = ctx->end-ctx->current;
|
||||
if (n > len) {
|
||||
n = len;
|
||||
}
|
||||
}
|
||||
else {
|
||||
n = len;
|
||||
}
|
||||
|
||||
if (n > SIZE_MAX)
|
||||
n = SIZE_MAX;
|
||||
|
||||
if ((i=fread(buf, 1, (size_t)n, ctx->f)) == 0) {
|
||||
if (ferror(ctx->f)) {
|
||||
zip_error_set(&ctx->error, ZIP_ER_READ, errno);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
ctx->current += i;
|
||||
|
||||
return (zip_int64_t)i;
|
||||
|
||||
case ZIP_SOURCE_REMOVE:
|
||||
if (remove(ctx->fname) < 0) {
|
||||
zip_error_set(&ctx->error, ZIP_ER_REMOVE, errno);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
|
||||
case ZIP_SOURCE_ROLLBACK_WRITE:
|
||||
if (ctx->fout) {
|
||||
fclose(ctx->fout);
|
||||
ctx->fout = NULL;
|
||||
}
|
||||
(void)remove(ctx->tmpname);
|
||||
free(ctx->tmpname);
|
||||
ctx->tmpname = NULL;
|
||||
return 0;
|
||||
|
||||
case ZIP_SOURCE_SEEK: {
|
||||
zip_int64_t new_current;
|
||||
int need_seek;
|
||||
zip_source_args_seek_t *args = ZIP_SOURCE_GET_ARGS(zip_source_args_seek_t, data, len, &ctx->error);
|
||||
|
||||
if (args == NULL)
|
||||
return -1;
|
||||
|
||||
need_seek = 1;
|
||||
|
||||
switch (args->whence) {
|
||||
case SEEK_SET:
|
||||
new_current = args->offset;
|
||||
break;
|
||||
|
||||
case SEEK_END:
|
||||
if (ctx->end == 0) {
|
||||
if (_zip_fseek(ctx->f, args->offset, SEEK_END, &ctx->error) < 0) {
|
||||
return -1;
|
||||
}
|
||||
if ((new_current = ftello(ctx->f)) < 0) {
|
||||
zip_error_set(&ctx->error, ZIP_ER_SEEK, errno);
|
||||
return -1;
|
||||
}
|
||||
need_seek = 0;
|
||||
}
|
||||
else {
|
||||
new_current = (zip_int64_t)ctx->end + args->offset;
|
||||
}
|
||||
break;
|
||||
case SEEK_CUR:
|
||||
new_current = (zip_int64_t)ctx->current + args->offset;
|
||||
break;
|
||||
|
||||
default:
|
||||
zip_error_set(&ctx->error, ZIP_ER_INVAL, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (new_current < 0 || (zip_uint64_t)new_current < ctx->start || (ctx->end != 0 && (zip_uint64_t)new_current > ctx->end)) {
|
||||
zip_error_set(&ctx->error, ZIP_ER_INVAL, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ctx->current = (zip_uint64_t)new_current;
|
||||
|
||||
if (need_seek) {
|
||||
if (_zip_fseek_u(ctx->f, ctx->current, SEEK_SET, &ctx->error) < 0) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
case ZIP_SOURCE_SEEK_WRITE: {
|
||||
zip_source_args_seek_t *args;
|
||||
|
||||
args = ZIP_SOURCE_GET_ARGS(zip_source_args_seek_t, data, len, &ctx->error);
|
||||
if (args == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (_zip_fseek(ctx->fout, args->offset, args->whence, &ctx->error) < 0) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
case ZIP_SOURCE_STAT: {
|
||||
if (len < sizeof(ctx->st))
|
||||
return -1;
|
||||
|
||||
if (ctx->st.valid != 0)
|
||||
memcpy(data, &ctx->st, sizeof(ctx->st));
|
||||
else {
|
||||
zip_stat_t *st;
|
||||
struct stat fst;
|
||||
int err;
|
||||
|
||||
if (ctx->f)
|
||||
err = fstat(fileno(ctx->f), &fst);
|
||||
else
|
||||
err = stat(ctx->fname, &fst);
|
||||
|
||||
if (err != 0) {
|
||||
zip_error_set(&ctx->error, ZIP_ER_READ, errno);
|
||||
return -1;
|
||||
}
|
||||
|
||||
st = (zip_stat_t *)data;
|
||||
|
||||
zip_stat_init(st);
|
||||
st->mtime = fst.st_mtime;
|
||||
st->valid |= ZIP_STAT_MTIME;
|
||||
if (ctx->end != 0) {
|
||||
st->size = ctx->end - ctx->start;
|
||||
st->valid |= ZIP_STAT_SIZE;
|
||||
}
|
||||
else if ((fst.st_mode&S_IFMT) == S_IFREG) {
|
||||
st->size = (zip_uint64_t)fst.st_size;
|
||||
st->valid |= ZIP_STAT_SIZE;
|
||||
}
|
||||
}
|
||||
return sizeof(ctx->st);
|
||||
}
|
||||
|
||||
case ZIP_SOURCE_SUPPORTS:
|
||||
return ctx->supports;
|
||||
|
||||
case ZIP_SOURCE_TELL:
|
||||
return (zip_int64_t)ctx->current;
|
||||
|
||||
case ZIP_SOURCE_TELL_WRITE:
|
||||
{
|
||||
off_t ret = ftello(ctx->fout);
|
||||
|
||||
if (ret < 0) {
|
||||
zip_error_set(&ctx->error, ZIP_ER_TELL, errno);
|
||||
return -1;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
case ZIP_SOURCE_WRITE:
|
||||
{
|
||||
size_t ret;
|
||||
|
||||
clearerr(ctx->fout);
|
||||
ret = fwrite(data, 1, len, ctx->fout);
|
||||
if (ret != len || ferror(ctx->fout)) {
|
||||
zip_error_set(&ctx->error, ZIP_ER_WRITE, errno);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return (zip_int64_t)ret;
|
||||
}
|
||||
|
||||
default:
|
||||
zip_error_set(&ctx->error, ZIP_ER_OPNOTSUPP, 0);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
_zip_fseek_u(FILE *f, zip_uint64_t offset, int whence, zip_error_t *error)
|
||||
{
|
||||
if (offset > ZIP_INT64_MAX) {
|
||||
zip_error_set(error, ZIP_ER_SEEK, EOVERFLOW);
|
||||
return -1;
|
||||
}
|
||||
return _zip_fseek(f, (zip_int64_t)offset, whence, error);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
_zip_fseek(FILE *f, zip_int64_t offset, int whence, zip_error_t *error)
|
||||
{
|
||||
if (offset > ZIP_FSEEK_MAX || offset < ZIP_FSEEK_MIN) {
|
||||
zip_error_set(error, ZIP_ER_SEEK, EOVERFLOW);
|
||||
return -1;
|
||||
}
|
||||
if (fseeko(f, (off_t)offset, whence) < 0) {
|
||||
zip_error_set(error, ZIP_ER_SEEK, errno);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
72
src/Common/libzip/zip_source_free.c
Normal file
72
src/Common/libzip/zip_source_free.c
Normal file
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
zip_source_free.c -- free zip data source
|
||||
Copyright (C) 1999-2015 Dieter Baron and Thomas Klausner
|
||||
|
||||
This file is part of libzip, a library to manipulate ZIP archives.
|
||||
The authors can be contacted at <libzip@nih.at>
|
||||
|
||||
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.
|
||||
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.
|
||||
3. The names of the authors may not be used to endorse or promote
|
||||
products derived from this software without specific prior
|
||||
written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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.
|
||||
*/
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "zipint.h"
|
||||
|
||||
|
||||
ZIP_EXTERN void
|
||||
zip_source_free(zip_source_t *src)
|
||||
{
|
||||
if (src == NULL)
|
||||
return;
|
||||
|
||||
if (src->refcount > 0) {
|
||||
src->refcount--;
|
||||
}
|
||||
if (src->refcount > 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (ZIP_SOURCE_IS_OPEN_READING(src)) {
|
||||
src->open_count = 1; /* force close */
|
||||
zip_source_close(src);
|
||||
}
|
||||
if (ZIP_SOURCE_IS_OPEN_WRITING(src)) {
|
||||
zip_source_rollback_write(src);
|
||||
}
|
||||
|
||||
if (src->source_archive && !src->source_closed) {
|
||||
_zip_deregister_source(src->source_archive, src);
|
||||
}
|
||||
|
||||
(void)_zip_source_call(src, NULL, 0, ZIP_SOURCE_FREE);
|
||||
|
||||
if (src->src) {
|
||||
zip_source_free(src->src);
|
||||
}
|
||||
|
||||
free(src);
|
||||
}
|
||||
99
src/Common/libzip/zip_source_function.c
Normal file
99
src/Common/libzip/zip_source_function.c
Normal file
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
zip_source_function.c -- create zip data source from callback function
|
||||
Copyright (C) 1999-2014 Dieter Baron and Thomas Klausner
|
||||
|
||||
This file is part of libzip, a library to manipulate ZIP archives.
|
||||
The authors can be contacted at <libzip@nih.at>
|
||||
|
||||
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.
|
||||
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.
|
||||
3. The names of the authors may not be used to endorse or promote
|
||||
products derived from this software without specific prior
|
||||
written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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.
|
||||
*/
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "zipint.h"
|
||||
|
||||
|
||||
ZIP_EXTERN zip_source_t *
|
||||
zip_source_function(zip_t *za, zip_source_callback zcb, void *ud)
|
||||
{
|
||||
if (za == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return zip_source_function_create(zcb, ud, &za->error);
|
||||
}
|
||||
|
||||
|
||||
ZIP_EXTERN zip_source_t *
|
||||
zip_source_function_create(zip_source_callback zcb, void *ud, zip_error_t *error)
|
||||
{
|
||||
zip_source_t *zs;
|
||||
|
||||
if ((zs=_zip_source_new(error)) == NULL)
|
||||
return NULL;
|
||||
|
||||
zs->cb.f = zcb;
|
||||
zs->ud = ud;
|
||||
|
||||
zs->supports = zcb(ud, NULL, 0, ZIP_SOURCE_SUPPORTS);
|
||||
if (zs->supports < 0) {
|
||||
zs->supports = ZIP_SOURCE_SUPPORTS_READABLE;
|
||||
}
|
||||
|
||||
return zs;
|
||||
}
|
||||
|
||||
|
||||
ZIP_EXTERN void
|
||||
zip_source_keep(zip_source_t *src)
|
||||
{
|
||||
src->refcount++;
|
||||
}
|
||||
|
||||
|
||||
zip_source_t *
|
||||
_zip_source_new(zip_error_t *error)
|
||||
{
|
||||
zip_source_t *src;
|
||||
|
||||
if ((src=(zip_source_t *)malloc(sizeof(*src))) == NULL) {
|
||||
zip_error_set(error, ZIP_ER_MEMORY, 0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
src->src = NULL;
|
||||
src->cb.f = NULL;
|
||||
src->ud = NULL;
|
||||
src->open_count = 0;
|
||||
src->write_state = ZIP_SOURCE_WRITE_CLOSED;
|
||||
src->source_closed = false;
|
||||
src->source_archive = NULL;
|
||||
src->refcount = 1;
|
||||
zip_error_init(&src->error);
|
||||
|
||||
return src;
|
||||
}
|
||||
42
src/Common/libzip/zip_source_is_deleted.c
Normal file
42
src/Common/libzip/zip_source_is_deleted.c
Normal file
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
zip_source_is_deleted.c -- was archive was removed?
|
||||
Copyright (C) 2014 Dieter Baron and Thomas Klausner
|
||||
|
||||
This file is part of libzip, a library to manipulate ZIP archives.
|
||||
The authors can be contacted at <libzip@nih.at>
|
||||
|
||||
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.
|
||||
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.
|
||||
3. The names of the authors may not be used to endorse or promote
|
||||
products derived from this software without specific prior
|
||||
written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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.
|
||||
*/
|
||||
|
||||
|
||||
#include "zipint.h"
|
||||
|
||||
|
||||
ZIP_EXTERN int
|
||||
zip_source_is_deleted(zip_source_t *src)
|
||||
{
|
||||
return src->write_state == ZIP_SOURCE_WRITE_REMOVED;
|
||||
}
|
||||
69
src/Common/libzip/zip_source_layered.c
Normal file
69
src/Common/libzip/zip_source_layered.c
Normal file
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
zip_source_layered.c -- create layered source
|
||||
Copyright (C) 2009-2014 Dieter Baron and Thomas Klausner
|
||||
|
||||
This file is part of libzip, a library to manipulate ZIP archives.
|
||||
The authors can be contacted at <libzip@nih.at>
|
||||
|
||||
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.
|
||||
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.
|
||||
3. The names of the authors may not be used to endorse or promote
|
||||
products derived from this software without specific prior
|
||||
written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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.
|
||||
*/
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "zipint.h"
|
||||
|
||||
|
||||
zip_source_t *
|
||||
zip_source_layered(zip_t *za, zip_source_t *src, zip_source_layered_callback cb, void *ud)
|
||||
{
|
||||
if (za == NULL)
|
||||
return NULL;
|
||||
|
||||
return zip_source_layered_create(src, cb, ud, &za->error);
|
||||
}
|
||||
|
||||
|
||||
zip_source_t *
|
||||
zip_source_layered_create(zip_source_t *src, zip_source_layered_callback cb, void *ud, zip_error_t *error)
|
||||
{
|
||||
zip_source_t *zs;
|
||||
|
||||
if ((zs=_zip_source_new(error)) == NULL)
|
||||
return NULL;
|
||||
|
||||
zip_source_keep(src);
|
||||
zs->src = src;
|
||||
zs->cb.l = cb;
|
||||
zs->ud = ud;
|
||||
|
||||
zs->supports = cb(src, ud, NULL, 0, ZIP_SOURCE_SUPPORTS);
|
||||
if (zs->supports < 0) {
|
||||
zs->supports = ZIP_SOURCE_SUPPORTS_READABLE;
|
||||
}
|
||||
|
||||
return zs;
|
||||
}
|
||||
73
src/Common/libzip/zip_source_open.c
Normal file
73
src/Common/libzip/zip_source_open.c
Normal file
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
zip_source_open.c -- open zip_source (prepare for reading)
|
||||
Copyright (C) 2009-2014 Dieter Baron and Thomas Klausner
|
||||
|
||||
This file is part of libzip, a library to manipulate ZIP archives.
|
||||
The authors can be contacted at <libzip@nih.at>
|
||||
|
||||
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.
|
||||
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.
|
||||
3. The names of the authors may not be used to endorse or promote
|
||||
products derived from this software without specific prior
|
||||
written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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.
|
||||
*/
|
||||
|
||||
|
||||
#include "zipint.h"
|
||||
|
||||
ZIP_EXTERN int
|
||||
zip_source_open(zip_source_t *src)
|
||||
{
|
||||
if (src->source_closed) {
|
||||
return -1;
|
||||
}
|
||||
if (src->write_state == ZIP_SOURCE_WRITE_REMOVED) {
|
||||
zip_error_set(&src->error, ZIP_ER_DELETED, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ZIP_SOURCE_IS_OPEN_READING(src)) {
|
||||
if ((zip_source_supports(src) & ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_SEEK)) == 0) {
|
||||
zip_error_set(&src->error, ZIP_ER_INUSE, 0);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (ZIP_SOURCE_IS_LAYERED(src)) {
|
||||
if (zip_source_open(src->src) < 0) {
|
||||
_zip_error_set_from_source(&src->error, src->src);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (_zip_source_call(src, NULL, 0, ZIP_SOURCE_OPEN) < 0) {
|
||||
if (ZIP_SOURCE_IS_LAYERED(src)) {
|
||||
zip_source_close(src->src);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
src->open_count++;
|
||||
|
||||
return 0;
|
||||
}
|
||||
226
src/Common/libzip/zip_source_pkware.c
Normal file
226
src/Common/libzip/zip_source_pkware.c
Normal file
@@ -0,0 +1,226 @@
|
||||
/*
|
||||
zip_source_pkware.c -- Traditional PKWARE de/encryption routines
|
||||
Copyright (C) 2009-2015 Dieter Baron and Thomas Klausner
|
||||
|
||||
This file is part of libzip, a library to manipulate ZIP archives.
|
||||
The authors can be contacted at <libzip@nih.at>
|
||||
|
||||
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.
|
||||
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.
|
||||
3. The names of the authors may not be used to endorse or promote
|
||||
products derived from this software without specific prior
|
||||
written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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.
|
||||
*/
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "zipint.h"
|
||||
|
||||
struct trad_pkware {
|
||||
zip_error_t error;
|
||||
zip_uint32_t key[3];
|
||||
};
|
||||
|
||||
#define HEADERLEN 12
|
||||
#define KEY0 305419896
|
||||
#define KEY1 591751049
|
||||
#define KEY2 878082192
|
||||
|
||||
|
||||
static void decrypt(struct trad_pkware *, zip_uint8_t *,
|
||||
const zip_uint8_t *, zip_uint64_t, int);
|
||||
static int decrypt_header(zip_source_t *, struct trad_pkware *);
|
||||
static zip_int64_t pkware_decrypt(zip_source_t *, void *, void *,
|
||||
zip_uint64_t, zip_source_cmd_t);
|
||||
static void pkware_free(struct trad_pkware *);
|
||||
|
||||
|
||||
zip_source_t *
|
||||
zip_source_pkware(zip_t *za, zip_source_t *src,
|
||||
zip_uint16_t em, int flags, const char *password)
|
||||
{
|
||||
struct trad_pkware *ctx;
|
||||
zip_source_t *s2;
|
||||
|
||||
if (password == NULL || src == NULL || em != ZIP_EM_TRAD_PKWARE) {
|
||||
zip_error_set(&za->error, ZIP_ER_INVAL, 0);
|
||||
return NULL;
|
||||
}
|
||||
if (flags & ZIP_CODEC_ENCODE) {
|
||||
zip_error_set(&za->error, ZIP_ER_ENCRNOTSUPP, 0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ((ctx=(struct trad_pkware *)malloc(sizeof(*ctx))) == NULL) {
|
||||
zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
zip_error_init(&ctx->error);
|
||||
|
||||
ctx->key[0] = KEY0;
|
||||
ctx->key[1] = KEY1;
|
||||
ctx->key[2] = KEY2;
|
||||
decrypt(ctx, NULL, (const zip_uint8_t *)password, strlen(password), 1);
|
||||
|
||||
if ((s2=zip_source_layered(za, src, pkware_decrypt, ctx)) == NULL) {
|
||||
pkware_free(ctx);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return s2;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
decrypt(struct trad_pkware *ctx, zip_uint8_t *out, const zip_uint8_t *in,
|
||||
zip_uint64_t len, int update_only)
|
||||
{
|
||||
zip_uint16_t tmp;
|
||||
zip_uint64_t i;
|
||||
Bytef b;
|
||||
|
||||
for (i=0; i<len; i++) {
|
||||
b = in[i];
|
||||
|
||||
if (!update_only) {
|
||||
/* decrypt next byte */
|
||||
tmp = (zip_uint16_t)(ctx->key[2] | 2);
|
||||
tmp = (zip_uint16_t)(((zip_uint32_t)tmp * (tmp ^ 1)) >> 8);
|
||||
b ^= (Bytef)tmp;
|
||||
}
|
||||
|
||||
/* store cleartext */
|
||||
if (out)
|
||||
out[i] = b;
|
||||
|
||||
/* update keys */
|
||||
ctx->key[0] = (zip_uint32_t)crc32(ctx->key[0] ^ 0xffffffffUL, &b, 1) ^ 0xffffffffUL;
|
||||
ctx->key[1] = (ctx->key[1] + (ctx->key[0] & 0xff)) * 134775813 + 1;
|
||||
b = (Bytef)(ctx->key[1] >> 24);
|
||||
ctx->key[2] = (zip_uint32_t)crc32(ctx->key[2] ^ 0xffffffffUL, &b, 1) ^ 0xffffffffUL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
decrypt_header(zip_source_t *src, struct trad_pkware *ctx)
|
||||
{
|
||||
zip_uint8_t header[HEADERLEN];
|
||||
struct zip_stat st;
|
||||
zip_int64_t n;
|
||||
unsigned short dostime, dosdate;
|
||||
|
||||
if ((n=zip_source_read(src, header, HEADERLEN)) < 0) {
|
||||
_zip_error_set_from_source(&ctx->error, src);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (n != HEADERLEN) {
|
||||
zip_error_set(&ctx->error, ZIP_ER_EOF, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
decrypt(ctx, header, header, HEADERLEN, 0);
|
||||
|
||||
if (zip_source_stat(src, &st) < 0) {
|
||||
/* stat failed, skip password validation */
|
||||
return 0;
|
||||
}
|
||||
|
||||
_zip_u2d_time(st.mtime, &dostime, &dosdate);
|
||||
|
||||
if (header[HEADERLEN-1] != st.crc>>24 && header[HEADERLEN-1] != dostime>>8) {
|
||||
zip_error_set(&ctx->error, ZIP_ER_WRONGPASSWD, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static zip_int64_t
|
||||
pkware_decrypt(zip_source_t *src, void *ud, void *data,
|
||||
zip_uint64_t len, zip_source_cmd_t cmd)
|
||||
{
|
||||
struct trad_pkware *ctx;
|
||||
zip_int64_t n;
|
||||
|
||||
ctx = (struct trad_pkware *)ud;
|
||||
|
||||
switch (cmd) {
|
||||
case ZIP_SOURCE_OPEN:
|
||||
if (decrypt_header(src, ctx) < 0)
|
||||
return -1;
|
||||
return 0;
|
||||
|
||||
case ZIP_SOURCE_READ:
|
||||
if ((n=zip_source_read(src, data, len)) < 0) {
|
||||
_zip_error_set_from_source(&ctx->error, src);
|
||||
return -1;
|
||||
}
|
||||
|
||||
decrypt((struct trad_pkware *)ud, (zip_uint8_t *)data, (zip_uint8_t *)data, (zip_uint64_t)n, 0);
|
||||
return n;
|
||||
|
||||
case ZIP_SOURCE_CLOSE:
|
||||
return 0;
|
||||
|
||||
case ZIP_SOURCE_STAT:
|
||||
{
|
||||
zip_stat_t *st;
|
||||
|
||||
st = (zip_stat_t *)data;
|
||||
|
||||
st->encryption_method = ZIP_EM_NONE;
|
||||
st->valid |= ZIP_STAT_ENCRYPTION_METHOD;
|
||||
/* TODO: deduce HEADERLEN from size for uncompressed */
|
||||
if (st->valid & ZIP_STAT_COMP_SIZE)
|
||||
st->comp_size -= HEADERLEN;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
case ZIP_SOURCE_SUPPORTS:
|
||||
return zip_source_make_command_bitmap(ZIP_SOURCE_OPEN, ZIP_SOURCE_READ, ZIP_SOURCE_CLOSE, ZIP_SOURCE_STAT, ZIP_SOURCE_ERROR, ZIP_SOURCE_FREE, -1);
|
||||
|
||||
case ZIP_SOURCE_ERROR:
|
||||
return zip_error_to_data(&ctx->error, data, len);
|
||||
|
||||
case ZIP_SOURCE_FREE:
|
||||
pkware_free(ctx);
|
||||
return 0;
|
||||
|
||||
default:
|
||||
zip_error_set(&ctx->error, ZIP_ER_INVAL, 0);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
pkware_free(struct trad_pkware *ctx)
|
||||
{
|
||||
free(ctx);
|
||||
}
|
||||
50
src/Common/libzip/zip_source_read.c
Normal file
50
src/Common/libzip/zip_source_read.c
Normal file
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
zip_source_read.c -- read data from zip_source
|
||||
Copyright (C) 2009-2014 Dieter Baron and Thomas Klausner
|
||||
|
||||
This file is part of libzip, a library to manipulate ZIP archives.
|
||||
The authors can be contacted at <libzip@nih.at>
|
||||
|
||||
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.
|
||||
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.
|
||||
3. The names of the authors may not be used to endorse or promote
|
||||
products derived from this software without specific prior
|
||||
written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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.
|
||||
*/
|
||||
|
||||
|
||||
#include "zipint.h"
|
||||
|
||||
|
||||
zip_int64_t
|
||||
zip_source_read(zip_source_t *src, void *data, zip_uint64_t len)
|
||||
{
|
||||
if (src->source_closed) {
|
||||
return -1;
|
||||
}
|
||||
if (!ZIP_SOURCE_IS_OPEN_READING(src) || len > ZIP_INT64_MAX || (len > 0 && data == NULL)) {
|
||||
zip_error_set(&src->error, ZIP_ER_INVAL, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return _zip_source_call(src, data, len, ZIP_SOURCE_READ);
|
||||
}
|
||||
61
src/Common/libzip/zip_source_remove.c
Normal file
61
src/Common/libzip/zip_source_remove.c
Normal file
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
zip_source_remove.c -- remove empty archive
|
||||
Copyright (C) 2014 Dieter Baron and Thomas Klausner
|
||||
|
||||
This file is part of libzip, a library to manipulate ZIP archives.
|
||||
The authors can be contacted at <libzip@nih.at>
|
||||
|
||||
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.
|
||||
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.
|
||||
3. The names of the authors may not be used to endorse or promote
|
||||
products derived from this software without specific prior
|
||||
written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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.
|
||||
*/
|
||||
|
||||
|
||||
#include "zipint.h"
|
||||
|
||||
|
||||
int
|
||||
zip_source_remove(zip_source_t *src)
|
||||
{
|
||||
if (src->write_state == ZIP_SOURCE_WRITE_REMOVED) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ZIP_SOURCE_IS_OPEN_READING(src)) {
|
||||
if (zip_source_close(src) < 0) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
if (src->write_state != ZIP_SOURCE_WRITE_CLOSED) {
|
||||
zip_source_rollback_write(src);
|
||||
}
|
||||
|
||||
if (_zip_source_call(src, NULL, 0, ZIP_SOURCE_REMOVE) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
src->write_state = ZIP_SOURCE_WRITE_REMOVED;
|
||||
|
||||
return 0;
|
||||
}
|
||||
47
src/Common/libzip/zip_source_rollback_write.c
Normal file
47
src/Common/libzip/zip_source_rollback_write.c
Normal file
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
zip_source_rollback_write.c -- discard changes
|
||||
Copyright (C) 2014 Dieter Baron and Thomas Klausner
|
||||
|
||||
This file is part of libzip, a library to manipulate ZIP archives.
|
||||
The authors can be contacted at <libzip@nih.at>
|
||||
|
||||
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.
|
||||
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.
|
||||
3. The names of the authors may not be used to endorse or promote
|
||||
products derived from this software without specific prior
|
||||
written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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.
|
||||
*/
|
||||
|
||||
|
||||
#include "zipint.h"
|
||||
|
||||
|
||||
ZIP_EXTERN void
|
||||
zip_source_rollback_write(zip_source_t *src)
|
||||
{
|
||||
if (src->write_state != ZIP_SOURCE_WRITE_OPEN && src->write_state != ZIP_SOURCE_WRITE_FAILED) {
|
||||
return;
|
||||
}
|
||||
|
||||
_zip_source_call(src, NULL, 0, ZIP_SOURCE_ROLLBACK_WRITE);
|
||||
src->write_state = ZIP_SOURCE_WRITE_CLOSED;
|
||||
}
|
||||
92
src/Common/libzip/zip_source_seek.c
Normal file
92
src/Common/libzip/zip_source_seek.c
Normal file
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
zip_source_seek.c -- seek to offset
|
||||
Copyright (C) 2014 Dieter Baron and Thomas Klausner
|
||||
|
||||
This file is part of libzip, a library to manipulate ZIP archives.
|
||||
The authors can be contacted at <libzip@nih.at>
|
||||
|
||||
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.
|
||||
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.
|
||||
3. The names of the authors may not be used to endorse or promote
|
||||
products derived from this software without specific prior
|
||||
written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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.
|
||||
*/
|
||||
|
||||
|
||||
#include "zipint.h"
|
||||
|
||||
|
||||
ZIP_EXTERN int
|
||||
zip_source_seek(zip_source_t *src, zip_int64_t offset, int whence)
|
||||
{
|
||||
zip_source_args_seek_t args;
|
||||
|
||||
if (src->source_closed) {
|
||||
return -1;
|
||||
}
|
||||
if (!ZIP_SOURCE_IS_OPEN_READING(src) || (whence != SEEK_SET && whence != SEEK_CUR && whence != SEEK_END)) {
|
||||
zip_error_set(&src->error, ZIP_ER_INVAL, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
args.offset = offset;
|
||||
args.whence = whence;
|
||||
|
||||
return (_zip_source_call(src, &args, sizeof(args), ZIP_SOURCE_SEEK) < 0 ? -1 : 0);
|
||||
}
|
||||
|
||||
|
||||
zip_int64_t
|
||||
zip_source_seek_compute_offset(zip_uint64_t offset, zip_uint64_t length, void *data, zip_uint64_t data_length, zip_error_t *error)
|
||||
{
|
||||
zip_int64_t new_offset;
|
||||
zip_source_args_seek_t *args = ZIP_SOURCE_GET_ARGS(zip_source_args_seek_t, data, data_length, error);
|
||||
|
||||
if (args == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
switch (args->whence) {
|
||||
case SEEK_CUR:
|
||||
new_offset = (zip_int64_t)offset + args->offset;
|
||||
break;
|
||||
|
||||
case SEEK_END:
|
||||
new_offset = (zip_int64_t)length + args->offset;
|
||||
break;
|
||||
|
||||
case SEEK_SET:
|
||||
new_offset = args->offset;
|
||||
break;
|
||||
|
||||
default:
|
||||
zip_error_set(error, ZIP_ER_INVAL, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (new_offset < 0 || (zip_uint64_t)new_offset > length) {
|
||||
zip_error_set(error, ZIP_ER_INVAL, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return new_offset;
|
||||
}
|
||||
52
src/Common/libzip/zip_source_seek_write.c
Normal file
52
src/Common/libzip/zip_source_seek_write.c
Normal file
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
zip_source_seek_write.c -- seek to offset for writing
|
||||
Copyright (C) 2014 Dieter Baron and Thomas Klausner
|
||||
|
||||
This file is part of libzip, a library to manipulate ZIP archives.
|
||||
The authors can be contacted at <libzip@nih.at>
|
||||
|
||||
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.
|
||||
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.
|
||||
3. The names of the authors may not be used to endorse or promote
|
||||
products derived from this software without specific prior
|
||||
written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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.
|
||||
*/
|
||||
|
||||
|
||||
#include "zipint.h"
|
||||
|
||||
|
||||
ZIP_EXTERN int
|
||||
zip_source_seek_write(zip_source_t *src, zip_int64_t offset, int whence)
|
||||
{
|
||||
zip_source_args_seek_t args;
|
||||
|
||||
if (!ZIP_SOURCE_IS_OPEN_WRITING(src) || (whence != SEEK_SET && whence != SEEK_CUR && whence != SEEK_END)) {
|
||||
zip_error_set(&src->error, ZIP_ER_INVAL, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
args.offset = offset;
|
||||
args.whence = whence;
|
||||
|
||||
return (_zip_source_call(src, &args, sizeof(args), ZIP_SOURCE_SEEK_WRITE) < 0 ? -1 : 0);
|
||||
}
|
||||
63
src/Common/libzip/zip_source_stat.c
Normal file
63
src/Common/libzip/zip_source_stat.c
Normal file
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
zip_source_stat.c -- get meta information from zip_source
|
||||
Copyright (C) 2009-2015 Dieter Baron and Thomas Klausner
|
||||
|
||||
This file is part of libzip, a library to manipulate ZIP archives.
|
||||
The authors can be contacted at <libzip@nih.at>
|
||||
|
||||
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.
|
||||
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.
|
||||
3. The names of the authors may not be used to endorse or promote
|
||||
products derived from this software without specific prior
|
||||
written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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.
|
||||
*/
|
||||
|
||||
|
||||
#include "zipint.h"
|
||||
|
||||
|
||||
ZIP_EXTERN int
|
||||
zip_source_stat(zip_source_t *src, zip_stat_t *st)
|
||||
{
|
||||
if (src->source_closed) {
|
||||
return -1;
|
||||
}
|
||||
if (st == NULL) {
|
||||
zip_error_set(&src->error, ZIP_ER_INVAL, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
zip_stat_init(st);
|
||||
|
||||
if (ZIP_SOURCE_IS_LAYERED(src)) {
|
||||
if (zip_source_stat(src->src, st) < 0) {
|
||||
_zip_error_set_from_source(&src->error, src->src);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (_zip_source_call(src, st, sizeof(*st), ZIP_SOURCE_STAT) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
68
src/Common/libzip/zip_source_supports.c
Normal file
68
src/Common/libzip/zip_source_supports.c
Normal file
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
zip_source_supports.c -- check for supported functions
|
||||
Copyright (C) 2014-2015 Dieter Baron and Thomas Klausner
|
||||
|
||||
This file is part of libzip, a library to manipulate ZIP archives.
|
||||
The authors can be contacted at <libzip@nih.at>
|
||||
|
||||
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.
|
||||
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.
|
||||
3. The names of the authors may not be used to endorse or promote
|
||||
products derived from this software without specific prior
|
||||
written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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.
|
||||
*/
|
||||
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "zipint.h"
|
||||
|
||||
|
||||
zip_int64_t
|
||||
zip_source_supports(zip_source_t *src)
|
||||
{
|
||||
return src->supports;
|
||||
}
|
||||
|
||||
|
||||
ZIP_EXTERN zip_int64_t
|
||||
zip_source_make_command_bitmap(zip_source_cmd_t cmd0, ...)
|
||||
{
|
||||
zip_int64_t bitmap;
|
||||
va_list ap;
|
||||
|
||||
bitmap = ZIP_SOURCE_MAKE_COMMAND_BITMASK(cmd0);
|
||||
|
||||
|
||||
|
||||
va_start(ap, cmd0);
|
||||
for (;;) {
|
||||
int cmd = va_arg(ap, int);
|
||||
if (cmd < 0) {
|
||||
break;
|
||||
}
|
||||
bitmap |= ZIP_SOURCE_MAKE_COMMAND_BITMASK(cmd);
|
||||
}
|
||||
va_end(ap);
|
||||
|
||||
return bitmap;
|
||||
}
|
||||
50
src/Common/libzip/zip_source_tell.c
Normal file
50
src/Common/libzip/zip_source_tell.c
Normal file
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
zip_source_tell.c -- report current offset
|
||||
Copyright (C) 2014 Dieter Baron and Thomas Klausner
|
||||
|
||||
This file is part of libzip, a library to manipulate ZIP archives.
|
||||
The authors can be contacted at <libzip@nih.at>
|
||||
|
||||
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.
|
||||
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.
|
||||
3. The names of the authors may not be used to endorse or promote
|
||||
products derived from this software without specific prior
|
||||
written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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.
|
||||
*/
|
||||
|
||||
|
||||
#include "zipint.h"
|
||||
|
||||
|
||||
ZIP_EXTERN zip_int64_t
|
||||
zip_source_tell(zip_source_t *src)
|
||||
{
|
||||
if (src->source_closed) {
|
||||
return -1;
|
||||
}
|
||||
if (!ZIP_SOURCE_IS_OPEN_READING(src)) {
|
||||
zip_error_set(&src->error, ZIP_ER_INVAL, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return _zip_source_call(src, NULL, 0, ZIP_SOURCE_TELL);
|
||||
}
|
||||
47
src/Common/libzip/zip_source_tell_write.c
Normal file
47
src/Common/libzip/zip_source_tell_write.c
Normal file
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
zip_source_tell_write.c -- report current offset for writing
|
||||
Copyright (C) 2014 Dieter Baron and Thomas Klausner
|
||||
|
||||
This file is part of libzip, a library to manipulate ZIP archives.
|
||||
The authors can be contacted at <libzip@nih.at>
|
||||
|
||||
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.
|
||||
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.
|
||||
3. The names of the authors may not be used to endorse or promote
|
||||
products derived from this software without specific prior
|
||||
written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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.
|
||||
*/
|
||||
|
||||
|
||||
#include "zipint.h"
|
||||
|
||||
|
||||
ZIP_EXTERN zip_int64_t
|
||||
zip_source_tell_write(zip_source_t *src)
|
||||
{
|
||||
if (!ZIP_SOURCE_IS_OPEN_WRITING(src)) {
|
||||
zip_error_set(&src->error, ZIP_ER_INVAL, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return _zip_source_call(src, NULL, 0, ZIP_SOURCE_TELL_WRITE);
|
||||
}
|
||||
124
src/Common/libzip/zip_source_win32a.c
Normal file
124
src/Common/libzip/zip_source_win32a.c
Normal file
@@ -0,0 +1,124 @@
|
||||
/*
|
||||
zip_source_win32a.c -- create data source from Windows file (ANSI)
|
||||
Copyright (C) 1999-2016 Dieter Baron and Thomas Klausner
|
||||
|
||||
This file is part of libzip, a library to manipulate ZIP archives.
|
||||
The authors can be contacted at <libzip@nih.at>
|
||||
|
||||
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.
|
||||
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.
|
||||
3. The names of the authors may not be used to endorse or promote
|
||||
products derived from this software without specific prior
|
||||
written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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.
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "zipint.h"
|
||||
#include "zipwin32.h"
|
||||
|
||||
static void * _win32_strdup_a(const void *str);
|
||||
static HANDLE _win32_open_a(_zip_source_win32_read_file_t *ctx);
|
||||
static HANDLE _win32_create_temp_a(_zip_source_win32_read_file_t *ctx, void **temp, zip_uint32_t value, PSECURITY_ATTRIBUTES sa);
|
||||
static int _win32_rename_temp_a(_zip_source_win32_read_file_t *ctx);
|
||||
static int _win32_remove_a(const void *fname);
|
||||
|
||||
static _zip_source_win32_file_ops_t win32_ops_a = {
|
||||
_win32_strdup_a,
|
||||
_win32_open_a,
|
||||
_win32_create_temp_a,
|
||||
_win32_rename_temp_a,
|
||||
_win32_remove_a
|
||||
};
|
||||
|
||||
ZIP_EXTERN zip_source_t *
|
||||
zip_source_win32a(zip_t *za, const char *fname, zip_uint64_t start, zip_int64_t len)
|
||||
{
|
||||
if (za == NULL)
|
||||
return NULL;
|
||||
|
||||
return zip_source_win32a_create(fname, start, len, &za->error);
|
||||
}
|
||||
|
||||
|
||||
ZIP_EXTERN zip_source_t *
|
||||
zip_source_win32a_create(const char *fname, zip_uint64_t start, zip_int64_t length, zip_error_t *error)
|
||||
{
|
||||
if (fname == NULL || length < -1) {
|
||||
zip_error_set(error, ZIP_ER_INVAL, 0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return _zip_source_win32_handle_or_name(fname, INVALID_HANDLE_VALUE, start, length, 1, NULL, &win32_ops_a, error);
|
||||
}
|
||||
|
||||
|
||||
static void *
|
||||
_win32_strdup_a(const void *str)
|
||||
{
|
||||
return strdup((const char *)str);
|
||||
}
|
||||
|
||||
|
||||
static HANDLE
|
||||
_win32_open_a(_zip_source_win32_read_file_t *ctx)
|
||||
{
|
||||
return CreateFileA(ctx->fname, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
}
|
||||
|
||||
|
||||
static HANDLE
|
||||
_win32_create_temp_a(_zip_source_win32_read_file_t *ctx, void **temp, zip_uint32_t value, PSECURITY_ATTRIBUTES sa)
|
||||
{
|
||||
int len;
|
||||
|
||||
len = strlen((const char *)ctx->fname) + 10;
|
||||
if (*temp == NULL) {
|
||||
if ((*temp = malloc(sizeof(char) * len)) == NULL) {
|
||||
zip_error_set(&ctx->error, ZIP_ER_MEMORY, 0);
|
||||
return INVALID_HANDLE_VALUE;
|
||||
}
|
||||
}
|
||||
if (sprintf((char *)*temp, "%s.%08x", (const char *)ctx->fname, value) != len - 1) {
|
||||
return INVALID_HANDLE_VALUE;
|
||||
}
|
||||
|
||||
return CreateFileA((const char *)*temp, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, sa, CREATE_NEW, FILE_ATTRIBUTE_NORMAL | FILE_ATTRIBUTE_TEMPORARY, NULL);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
_win32_rename_temp_a(_zip_source_win32_read_file_t *ctx)
|
||||
{
|
||||
if (!MoveFileExA(ctx->tmpname, ctx->fname, MOVEFILE_REPLACE_EXISTING))
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
_win32_remove_a(const void *fname)
|
||||
{
|
||||
DeleteFileA((const char *)fname);
|
||||
return 0;
|
||||
}
|
||||
607
src/Common/libzip/zip_source_win32handle.c
Normal file
607
src/Common/libzip/zip_source_win32handle.c
Normal file
@@ -0,0 +1,607 @@
|
||||
/*
|
||||
zip_source_win32file.c -- create data source from HANDLE (Win32)
|
||||
Copyright (C) 1999-2016 Dieter Baron and Thomas Klausner
|
||||
|
||||
This file is part of libzip, a library to manipulate ZIP archives.
|
||||
The authors can be contacted at <libzip@nih.at>
|
||||
|
||||
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.
|
||||
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.
|
||||
3. The names of the authors may not be used to endorse or promote
|
||||
products derived from this software without specific prior
|
||||
written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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.
|
||||
*/
|
||||
|
||||
|
||||
#include <wchar.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "zipint.h"
|
||||
#include "zipwin32.h"
|
||||
|
||||
static zip_int64_t _win32_read_file(void *state, void *data, zip_uint64_t len, zip_source_cmd_t cmd);
|
||||
static int _win32_create_temp_file(_zip_source_win32_read_file_t *ctx);
|
||||
static int _zip_filetime_to_time_t(FILETIME ft, time_t *t);
|
||||
static int _zip_seek_win32_u(void *h, zip_uint64_t offset, int whence, zip_error_t *error);
|
||||
static int _zip_seek_win32(void *h, zip_int64_t offset, int whence, zip_error_t *error);
|
||||
static int _zip_win32_error_to_errno(unsigned long win32err);
|
||||
static int _zip_stat_win32(void *h, zip_stat_t *st, _zip_source_win32_read_file_t *ctx);
|
||||
|
||||
ZIP_EXTERN zip_source_t *
|
||||
zip_source_win32handle(zip_t *za, HANDLE h, zip_uint64_t start, zip_int64_t len)
|
||||
{
|
||||
if (za == NULL)
|
||||
return NULL;
|
||||
|
||||
return zip_source_win32handle_create(h, start, len, &za->error);
|
||||
}
|
||||
|
||||
|
||||
ZIP_EXTERN zip_source_t *
|
||||
zip_source_win32handle_create(HANDLE h, zip_uint64_t start, zip_int64_t length, zip_error_t *error)
|
||||
{
|
||||
if (h == INVALID_HANDLE_VALUE || length < -1) {
|
||||
zip_error_set(error, ZIP_ER_INVAL, 0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return _zip_source_win32_handle_or_name(NULL, h, start, length, 1, NULL, NULL, error);
|
||||
}
|
||||
|
||||
|
||||
zip_source_t *
|
||||
_zip_source_win32_handle_or_name(const void *fname, HANDLE h, zip_uint64_t start, zip_int64_t len, int closep, const zip_stat_t *st, _zip_source_win32_file_ops_t *ops, zip_error_t *error)
|
||||
{
|
||||
_zip_source_win32_read_file_t *ctx;
|
||||
zip_source_t *zs;
|
||||
|
||||
if (h == INVALID_HANDLE_VALUE && fname == NULL) {
|
||||
zip_error_set(error, ZIP_ER_INVAL, 0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ((ctx = (_zip_source_win32_read_file_t *)malloc(sizeof(_zip_source_win32_read_file_t))) == NULL) {
|
||||
zip_error_set(error, ZIP_ER_MEMORY, 0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ctx->fname = NULL;
|
||||
if (fname) {
|
||||
if ((ctx->fname = ops->op_strdup(fname)) == NULL) {
|
||||
zip_error_set(error, ZIP_ER_MEMORY, 0);
|
||||
free(ctx);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
ctx->ops = ops;
|
||||
ctx->h = h;
|
||||
ctx->start = start;
|
||||
ctx->end = (len < 0 ? 0 : start + (zip_uint64_t)len);
|
||||
ctx->closep = ctx->fname ? 1 : closep;
|
||||
if (st) {
|
||||
memcpy(&ctx->st, st, sizeof(ctx->st));
|
||||
ctx->st.name = NULL;
|
||||
ctx->st.valid &= ~ZIP_STAT_NAME;
|
||||
}
|
||||
else {
|
||||
zip_stat_init(&ctx->st);
|
||||
}
|
||||
|
||||
ctx->tmpname = NULL;
|
||||
ctx->hout = INVALID_HANDLE_VALUE;
|
||||
|
||||
zip_error_init(&ctx->error);
|
||||
|
||||
ctx->supports = ZIP_SOURCE_SUPPORTS_READABLE | zip_source_make_command_bitmap(ZIP_SOURCE_SUPPORTS, ZIP_SOURCE_TELL, -1);
|
||||
if (ctx->fname) {
|
||||
HANDLE th;
|
||||
|
||||
th = ops->op_open(ctx);
|
||||
if (th == INVALID_HANDLE_VALUE || GetFileType(th) == FILE_TYPE_DISK) {
|
||||
ctx->supports = ZIP_SOURCE_SUPPORTS_WRITABLE;
|
||||
}
|
||||
if (th != INVALID_HANDLE_VALUE) {
|
||||
CloseHandle(th);
|
||||
}
|
||||
}
|
||||
else if (GetFileType(ctx->h) == FILE_TYPE_DISK) {
|
||||
ctx->supports = ZIP_SOURCE_SUPPORTS_SEEKABLE;
|
||||
}
|
||||
|
||||
if ((zs = zip_source_function_create(_win32_read_file, ctx, error)) == NULL) {
|
||||
free(ctx->fname);
|
||||
free(ctx);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return zs;
|
||||
}
|
||||
|
||||
|
||||
static zip_int64_t
|
||||
_win32_read_file(void *state, void *data, zip_uint64_t len, zip_source_cmd_t cmd)
|
||||
{
|
||||
_zip_source_win32_read_file_t *ctx;
|
||||
char *buf;
|
||||
zip_uint64_t n;
|
||||
DWORD i;
|
||||
|
||||
ctx = (_zip_source_win32_read_file_t *)state;
|
||||
buf = (char *)data;
|
||||
|
||||
switch (cmd) {
|
||||
case ZIP_SOURCE_BEGIN_WRITE:
|
||||
if (ctx->fname == NULL) {
|
||||
zip_error_set(&ctx->error, ZIP_ER_OPNOTSUPP, 0);
|
||||
return -1;
|
||||
}
|
||||
return _win32_create_temp_file(ctx);
|
||||
|
||||
case ZIP_SOURCE_COMMIT_WRITE: {
|
||||
if (!CloseHandle(ctx->hout)) {
|
||||
ctx->hout = INVALID_HANDLE_VALUE;
|
||||
zip_error_set(&ctx->error, ZIP_ER_WRITE, _zip_win32_error_to_errno(GetLastError()));
|
||||
}
|
||||
ctx->hout = INVALID_HANDLE_VALUE;
|
||||
if (ctx->ops->op_rename_temp(ctx) < 0) {
|
||||
zip_error_set(&ctx->error, ZIP_ER_RENAME, _zip_win32_error_to_errno(GetLastError()));
|
||||
return -1;
|
||||
}
|
||||
free(ctx->tmpname);
|
||||
ctx->tmpname = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
case ZIP_SOURCE_CLOSE:
|
||||
if (ctx->fname) {
|
||||
CloseHandle(ctx->h);
|
||||
ctx->h = INVALID_HANDLE_VALUE;
|
||||
}
|
||||
return 0;
|
||||
|
||||
case ZIP_SOURCE_ERROR:
|
||||
return zip_error_to_data(&ctx->error, data, len);
|
||||
|
||||
case ZIP_SOURCE_FREE:
|
||||
free(ctx->fname);
|
||||
free(ctx->tmpname);
|
||||
if (ctx->closep && ctx->h != INVALID_HANDLE_VALUE)
|
||||
CloseHandle(ctx->h);
|
||||
free(ctx);
|
||||
return 0;
|
||||
|
||||
case ZIP_SOURCE_OPEN:
|
||||
if (ctx->fname) {
|
||||
if ((ctx->h = ctx->ops->op_open(ctx)) == INVALID_HANDLE_VALUE) {
|
||||
zip_error_set(&ctx->error, ZIP_ER_OPEN, _zip_win32_error_to_errno(GetLastError()));
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (ctx->closep && ctx->start > 0) {
|
||||
if (_zip_seek_win32_u(ctx->h, ctx->start, SEEK_SET, &ctx->error) < 0) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
ctx->current = ctx->start;
|
||||
return 0;
|
||||
|
||||
case ZIP_SOURCE_READ:
|
||||
if (ctx->end > 0) {
|
||||
n = ctx->end - ctx->current;
|
||||
if (n > len) {
|
||||
n = len;
|
||||
}
|
||||
}
|
||||
else {
|
||||
n = len;
|
||||
}
|
||||
|
||||
if (n > SIZE_MAX)
|
||||
n = SIZE_MAX;
|
||||
|
||||
if (!ctx->closep) {
|
||||
if (_zip_seek_win32_u(ctx->h, ctx->current, SEEK_SET, &ctx->error) < 0) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (!ReadFile(ctx->h, buf, (DWORD)n, &i, NULL)) {
|
||||
zip_error_set(&ctx->error, ZIP_ER_READ, _zip_win32_error_to_errno(GetLastError()));
|
||||
return -1;
|
||||
}
|
||||
ctx->current += i;
|
||||
|
||||
return (zip_int64_t)i;
|
||||
|
||||
case ZIP_SOURCE_REMOVE:
|
||||
if (ctx->ops->op_remove(ctx->fname) < 0) {
|
||||
zip_error_set(&ctx->error, ZIP_ER_REMOVE, _zip_win32_error_to_errno(GetLastError()));
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
|
||||
case ZIP_SOURCE_ROLLBACK_WRITE:
|
||||
if (ctx->hout) {
|
||||
CloseHandle(ctx->hout);
|
||||
ctx->hout = INVALID_HANDLE_VALUE;
|
||||
}
|
||||
ctx->ops->op_remove(ctx->tmpname);
|
||||
free(ctx->tmpname);
|
||||
ctx->tmpname = NULL;
|
||||
return 0;
|
||||
|
||||
case ZIP_SOURCE_SEEK: {
|
||||
zip_int64_t new_current;
|
||||
int need_seek;
|
||||
zip_source_args_seek_t *args = ZIP_SOURCE_GET_ARGS(zip_source_args_seek_t, data, len, &ctx->error);
|
||||
|
||||
if (args == NULL)
|
||||
return -1;
|
||||
|
||||
need_seek = ctx->closep;
|
||||
|
||||
switch (args->whence) {
|
||||
case SEEK_SET:
|
||||
new_current = args->offset;
|
||||
break;
|
||||
|
||||
case SEEK_END:
|
||||
if (ctx->end == 0) {
|
||||
LARGE_INTEGER zero;
|
||||
LARGE_INTEGER new_offset;
|
||||
|
||||
if (_zip_seek_win32(ctx->h, args->offset, SEEK_END, &ctx->error) < 0) {
|
||||
return -1;
|
||||
}
|
||||
zero.QuadPart = 0;
|
||||
if (!SetFilePointerEx(ctx->h, zero, &new_offset, FILE_CURRENT)) {
|
||||
zip_error_set(&ctx->error, ZIP_ER_SEEK, _zip_win32_error_to_errno(GetLastError()));
|
||||
return -1;
|
||||
}
|
||||
new_current = new_offset.QuadPart;
|
||||
need_seek = 0;
|
||||
}
|
||||
else {
|
||||
new_current = (zip_int64_t)ctx->end + args->offset;
|
||||
}
|
||||
break;
|
||||
case SEEK_CUR:
|
||||
new_current = (zip_int64_t)ctx->current + args->offset;
|
||||
break;
|
||||
|
||||
default:
|
||||
zip_error_set(&ctx->error, ZIP_ER_INVAL, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (new_current < 0 || (zip_uint64_t)new_current < ctx->start || (ctx->end != 0 && (zip_uint64_t)new_current > ctx->end)) {
|
||||
zip_error_set(&ctx->error, ZIP_ER_INVAL, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ctx->current = (zip_uint64_t)new_current;
|
||||
|
||||
if (need_seek) {
|
||||
if (_zip_seek_win32_u(ctx->h, ctx->current, SEEK_SET, &ctx->error) < 0) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
case ZIP_SOURCE_SEEK_WRITE: {
|
||||
zip_source_args_seek_t *args;
|
||||
|
||||
args = ZIP_SOURCE_GET_ARGS(zip_source_args_seek_t, data, len, &ctx->error);
|
||||
if (args == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (_zip_seek_win32(ctx->hout, args->offset, args->whence, &ctx->error) < 0) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
case ZIP_SOURCE_STAT: {
|
||||
if (len < sizeof(ctx->st))
|
||||
return -1;
|
||||
|
||||
if (ctx->st.valid != 0)
|
||||
memcpy(data, &ctx->st, sizeof(ctx->st));
|
||||
else {
|
||||
DWORD win32err;
|
||||
zip_stat_t *st;
|
||||
HANDLE h;
|
||||
int success;
|
||||
|
||||
st = (zip_stat_t *)data;
|
||||
|
||||
if (ctx->h != INVALID_HANDLE_VALUE) {
|
||||
h = ctx->h;
|
||||
}
|
||||
else {
|
||||
h = ctx->ops->op_open(ctx);
|
||||
if (h == INVALID_HANDLE_VALUE && GetLastError() == ERROR_FILE_NOT_FOUND) {
|
||||
zip_error_set(&ctx->error, ZIP_ER_READ, ENOENT);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
success = _zip_stat_win32(h, st, ctx);
|
||||
win32err = GetLastError();
|
||||
|
||||
/* We're done with the handle, so close it if we just opened it. */
|
||||
if (h != ctx->h) {
|
||||
CloseHandle(h);
|
||||
}
|
||||
|
||||
if (success < 0) {
|
||||
/* TODO: Is this the correct error to return in all cases? */
|
||||
zip_error_set(&ctx->error, ZIP_ER_READ, _zip_win32_error_to_errno(win32err));
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return sizeof(ctx->st);
|
||||
}
|
||||
|
||||
case ZIP_SOURCE_SUPPORTS:
|
||||
return ctx->supports;
|
||||
|
||||
case ZIP_SOURCE_TELL:
|
||||
return (zip_int64_t)ctx->current;
|
||||
|
||||
case ZIP_SOURCE_TELL_WRITE:
|
||||
{
|
||||
LARGE_INTEGER zero;
|
||||
LARGE_INTEGER offset;
|
||||
|
||||
zero.QuadPart = 0;
|
||||
if (!SetFilePointerEx(ctx->hout, zero, &offset, FILE_CURRENT)) {
|
||||
zip_error_set(&ctx->error, ZIP_ER_TELL, _zip_win32_error_to_errno(GetLastError()));
|
||||
return -1;
|
||||
}
|
||||
|
||||
return offset.QuadPart;
|
||||
}
|
||||
|
||||
case ZIP_SOURCE_WRITE:
|
||||
{
|
||||
DWORD ret;
|
||||
if (!WriteFile(ctx->hout, data, (DWORD)len, &ret, NULL) || ret != len) {
|
||||
zip_error_set(&ctx->error, ZIP_ER_WRITE, _zip_win32_error_to_errno(GetLastError()));
|
||||
return -1;
|
||||
}
|
||||
|
||||
return (zip_int64_t)ret;
|
||||
}
|
||||
|
||||
default:
|
||||
zip_error_set(&ctx->error, ZIP_ER_OPNOTSUPP, 0);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
_win32_create_temp_file(_zip_source_win32_read_file_t *ctx)
|
||||
{
|
||||
zip_uint32_t value;
|
||||
/*
|
||||
Windows has GetTempFileName(), but it closes the file after
|
||||
creation, leaving it open to a horrible race condition. So
|
||||
we reinvent the wheel.
|
||||
*/
|
||||
int i;
|
||||
HANDLE th = INVALID_HANDLE_VALUE;
|
||||
void *temp = NULL;
|
||||
SECURITY_INFORMATION si;
|
||||
SECURITY_ATTRIBUTES sa;
|
||||
PSECURITY_DESCRIPTOR psd = NULL;
|
||||
PSECURITY_ATTRIBUTES psa = NULL;
|
||||
DWORD len;
|
||||
BOOL success;
|
||||
|
||||
/*
|
||||
Read the DACL from the original file, so we can copy it to the temp file.
|
||||
If there is no original file, or if we can't read the DACL, we'll use the
|
||||
default security descriptor.
|
||||
*/
|
||||
if (ctx->h != INVALID_HANDLE_VALUE && GetFileType(ctx->h) == FILE_TYPE_DISK) {
|
||||
si = DACL_SECURITY_INFORMATION | UNPROTECTED_DACL_SECURITY_INFORMATION;
|
||||
len = 0;
|
||||
success = GetUserObjectSecurity(ctx->h, &si, NULL, len, &len);
|
||||
if (!success && GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
|
||||
if ((psd = (PSECURITY_DESCRIPTOR)malloc(len)) == NULL) {
|
||||
zip_error_set(&ctx->error, ZIP_ER_MEMORY, 0);
|
||||
return -1;
|
||||
}
|
||||
success = GetUserObjectSecurity(ctx->h, &si, psd, len, &len);
|
||||
}
|
||||
if (success) {
|
||||
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
|
||||
sa.bInheritHandle = FALSE;
|
||||
sa.lpSecurityDescriptor = psd;
|
||||
psa = &sa;
|
||||
}
|
||||
}
|
||||
|
||||
value = GetTickCount();
|
||||
for (i = 0; i < 1024 && th == INVALID_HANDLE_VALUE; i++) {
|
||||
th = ctx->ops->op_create_temp(ctx, &temp, value + i, psa);
|
||||
if (th == INVALID_HANDLE_VALUE && GetLastError() != ERROR_FILE_EXISTS)
|
||||
break;
|
||||
}
|
||||
|
||||
if (th == INVALID_HANDLE_VALUE) {
|
||||
free(temp);
|
||||
free(psd);
|
||||
zip_error_set(&ctx->error, ZIP_ER_TMPOPEN, _zip_win32_error_to_errno(GetLastError()));
|
||||
return -1;
|
||||
}
|
||||
|
||||
free(psd);
|
||||
ctx->hout = th;
|
||||
ctx->tmpname = temp;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
_zip_seek_win32_u(HANDLE h, zip_uint64_t offset, int whence, zip_error_t *error)
|
||||
{
|
||||
if (offset > ZIP_INT64_MAX) {
|
||||
zip_error_set(error, ZIP_ER_SEEK, EOVERFLOW);
|
||||
return -1;
|
||||
}
|
||||
return _zip_seek_win32(h, (zip_int64_t)offset, whence, error);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
_zip_seek_win32(HANDLE h, zip_int64_t offset, int whence, zip_error_t *error)
|
||||
{
|
||||
LARGE_INTEGER li;
|
||||
DWORD method;
|
||||
|
||||
switch (whence) {
|
||||
case SEEK_SET:
|
||||
method = FILE_BEGIN;
|
||||
break;
|
||||
case SEEK_END:
|
||||
method = FILE_END;
|
||||
break;
|
||||
case SEEK_CUR:
|
||||
method = FILE_CURRENT;
|
||||
break;
|
||||
default:
|
||||
zip_error_set(error, ZIP_ER_SEEK, EINVAL);
|
||||
return -1;
|
||||
}
|
||||
|
||||
li.QuadPart = (LONGLONG)offset;
|
||||
if (!SetFilePointerEx(h, li, NULL, method)) {
|
||||
zip_error_set(error, ZIP_ER_SEEK, _zip_win32_error_to_errno(GetLastError()));
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
_zip_win32_error_to_errno(DWORD win32err)
|
||||
{
|
||||
/*
|
||||
Note: This list isn't exhaustive, but should cover common cases.
|
||||
*/
|
||||
switch (win32err) {
|
||||
case ERROR_INVALID_PARAMETER:
|
||||
return EINVAL;
|
||||
case ERROR_FILE_NOT_FOUND:
|
||||
return ENOENT;
|
||||
case ERROR_INVALID_HANDLE:
|
||||
return EBADF;
|
||||
case ERROR_ACCESS_DENIED:
|
||||
return EACCES;
|
||||
case ERROR_FILE_EXISTS:
|
||||
return EEXIST;
|
||||
case ERROR_TOO_MANY_OPEN_FILES:
|
||||
return EMFILE;
|
||||
case ERROR_DISK_FULL:
|
||||
return ENOSPC;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
_zip_stat_win32(HANDLE h, zip_stat_t *st, _zip_source_win32_read_file_t *ctx)
|
||||
{
|
||||
FILETIME mtimeft;
|
||||
time_t mtime;
|
||||
LARGE_INTEGER size;
|
||||
int regularp;
|
||||
|
||||
if (!GetFileTime(h, NULL, NULL, &mtimeft)) {
|
||||
zip_error_set(&ctx->error, ZIP_ER_READ, _zip_win32_error_to_errno(GetLastError()));
|
||||
return -1;
|
||||
}
|
||||
if (_zip_filetime_to_time_t(mtimeft, &mtime) < 0) {
|
||||
zip_error_set(&ctx->error, ZIP_ER_READ, ERANGE);
|
||||
return -1;
|
||||
}
|
||||
|
||||
regularp = 0;
|
||||
if (GetFileType(h) == FILE_TYPE_DISK) {
|
||||
regularp = 1;
|
||||
}
|
||||
|
||||
if (!GetFileSizeEx(h, &size)) {
|
||||
zip_error_set(&ctx->error, ZIP_ER_READ, _zip_win32_error_to_errno(GetLastError()));
|
||||
return -1;
|
||||
}
|
||||
|
||||
zip_stat_init(st);
|
||||
st->mtime = mtime;
|
||||
st->valid |= ZIP_STAT_MTIME;
|
||||
if (ctx->end != 0) {
|
||||
st->size = ctx->end - ctx->start;
|
||||
st->valid |= ZIP_STAT_SIZE;
|
||||
}
|
||||
else if (regularp) {
|
||||
st->size = (zip_uint64_t)size.QuadPart;
|
||||
st->valid |= ZIP_STAT_SIZE;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
_zip_filetime_to_time_t(FILETIME ft, time_t *t)
|
||||
{
|
||||
/*
|
||||
Inspired by http://stackoverflow.com/questions/6161776/convert-windows-filetime-to-second-in-unix-linux
|
||||
*/
|
||||
const zip_int64_t WINDOWS_TICK = 10000000LL;
|
||||
const zip_int64_t SEC_TO_UNIX_EPOCH = 11644473600LL;
|
||||
ULARGE_INTEGER li;
|
||||
zip_int64_t secs;
|
||||
time_t temp;
|
||||
|
||||
li.LowPart = ft.dwLowDateTime;
|
||||
li.HighPart = ft.dwHighDateTime;
|
||||
secs = (li.QuadPart / WINDOWS_TICK - SEC_TO_UNIX_EPOCH);
|
||||
|
||||
temp = (time_t)secs;
|
||||
if (secs != (zip_int64_t)temp)
|
||||
return -1;
|
||||
|
||||
*t = temp;
|
||||
return 0;
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user