This commit is contained in:
Igor Pavlov
2022-01-22 18:43:09 +00:00
committed by Kornel
parent 52eeaf1ad6
commit c3529a41f5
88 changed files with 3474 additions and 435 deletions

View File

@@ -151,6 +151,7 @@ enum Enum
kCaseSensitive,
kArcNameMode,
kUseSlashMark,
kDisableWildcardParsing,
kElimDup,
kFullPathMode,
@@ -294,6 +295,7 @@ static const CSwitchForm kSwitchForms[] =
{ "ssc", SWFRM_MINUS },
{ "sa", NSwitchType::kChar, false, 1, k_ArcNameMode_PostCharSet },
{ "spm", SWFRM_STRING_SINGL(0) },
{ "spd", SWFRM_SIMPLE },
{ "spe", SWFRM_MINUS },
{ "spf", SWFRM_STRING_SINGL(0) },
@@ -407,12 +409,28 @@ static bool ParseArchiveCommand(const UString &commandString, CArcCommand &comma
// ------------------------------------------------------------------
// filenames functions
struct CNameOption
{
bool Include;
bool WildcardMatching;
Byte MarkMode;
NRecursedType::EEnum RecursedType;
CNameOption():
Include(true),
WildcardMatching(true),
MarkMode(NWildcard::kMark_FileOrDir),
RecursedType(NRecursedType::kNonRecursed)
{}
};
static void AddNameToCensor(NWildcard::CCensor &censor,
const UString &name, bool include, NRecursedType::EEnum type, bool wildcardMatching)
const CNameOption &nop, const UString &name)
{
bool recursed = false;
switch (type)
switch (nop.RecursedType)
{
case NRecursedType::kWildcardOnlyRecursed:
recursed = DoesNameContainWildcard(name);
@@ -423,7 +441,12 @@ static void AddNameToCensor(NWildcard::CCensor &censor,
default:
break;
}
censor.AddPreItem(include, name, recursed, wildcardMatching);
NWildcard::CCensorPathProps props;
props.Recursive = recursed;
props.WildcardMatching = nop.WildcardMatching;
props.MarkMode = nop.MarkMode;
censor.AddPreItem(nop.Include, name, props);
}
static void AddRenamePair(CObjectVector<CRenamePair> *renamePairs,
@@ -454,7 +477,7 @@ static void AddRenamePair(CObjectVector<CRenamePair> *renamePairs,
static void AddToCensorFromListFile(
CObjectVector<CRenamePair> *renamePairs,
NWildcard::CCensor &censor,
LPCWSTR fileName, bool include, NRecursedType::EEnum type, bool wildcardMatching, UInt32 codePage)
const CNameOption &nop, LPCWSTR fileName, UInt32 codePage)
{
UStringVector names;
/*
@@ -481,12 +504,12 @@ static void AddToCensorFromListFile(
for (unsigned i = 0; i < names.Size(); i += 2)
{
// change type !!!!
AddRenamePair(renamePairs, names[i], names[i + 1], type, wildcardMatching);
AddRenamePair(renamePairs, names[i], names[i + 1], nop.RecursedType, nop.WildcardMatching);
}
}
else
FOR_VECTOR (i, names)
AddNameToCensor(censor, names[i], include, type, wildcardMatching);
AddNameToCensor(censor, nop, names[i]);
}
static void AddToCensorFromNonSwitchesStrings(
@@ -495,14 +518,27 @@ static void AddToCensorFromNonSwitchesStrings(
NWildcard::CCensor &censor,
const UStringVector &nonSwitchStrings,
int stopSwitchIndex,
NRecursedType::EEnum type,
bool wildcardMatching,
const CNameOption &nop,
bool thereAreSwitchIncludes, UInt32 codePage)
{
// another default
if ((renamePairs || nonSwitchStrings.Size() == startIndex) && !thereAreSwitchIncludes)
AddNameToCensor(censor, UString(kUniversalWildcard), true, type,
true // wildcardMatching
);
{
/* for rename command: -i switch sets the mask for archive item reading.
if (thereAreSwitchIncludes), { we don't use UniversalWildcard. }
also for non-rename command: we set UniversalWildcard, only if there are no nonSwitches. */
// we use default fileds in (CNameOption) for UniversalWildcard.
CNameOption nop2;
// recursive mode is not important for UniversalWildcard (*)
// nop2.RecursedType = nop.RecursedType; // we don't need it
/*
nop2.RecursedType = NRecursedType::kNonRecursed;
nop2.Include = true;
nop2.WildcardMatching = true;
nop2.MarkMode = NWildcard::kMark_FileOrDir;
*/
AddNameToCensor(censor, nop2, UString(kUniversalWildcard));
}
int oldIndex = -1;
@@ -515,7 +551,7 @@ static void AddToCensorFromNonSwitchesStrings(
if (s.IsEmpty())
throw CArcCmdLineException(kEmptyFilePath);
if (i < (unsigned)stopSwitchIndex && s[0] == kFileListID)
AddToCensorFromListFile(renamePairs, censor, s.Ptr(1), true, type, wildcardMatching, codePage);
AddToCensorFromListFile(renamePairs, censor, nop, s.Ptr(1), codePage);
else if (renamePairs)
{
if (oldIndex == -1)
@@ -523,13 +559,13 @@ static void AddToCensorFromNonSwitchesStrings(
else
{
// NRecursedType::EEnum type is used for global wildcard (-i! switches)
AddRenamePair(renamePairs, nonSwitchStrings[(unsigned)oldIndex], s, NRecursedType::kNonRecursed, wildcardMatching);
AddRenamePair(renamePairs, nonSwitchStrings[(unsigned)oldIndex], s, NRecursedType::kNonRecursed, nop.WildcardMatching);
// AddRenamePair(renamePairs, nonSwitchStrings[oldIndex], s, type);
oldIndex = -1;
}
}
else
AddNameToCensor(censor, s, true, type, wildcardMatching);
AddNameToCensor(censor, nop, s);
}
if (oldIndex != -1)
@@ -557,9 +593,8 @@ static const char * const k_IncorrectMapCommand = "Incorrect Map command";
static const char *ParseMapWithPaths(
NWildcard::CCensor &censor,
const UString &s2, bool include,
NRecursedType::EEnum commonRecursedType,
bool wildcardMatching)
const UString &s2,
const CNameOption &nop)
{
UString s (s2);
int pos = s.Find(L':');
@@ -598,7 +633,7 @@ static const char *ParseMapWithPaths(
if (c == 0)
{
// MessageBoxW(0, name, L"7-Zip", 0);
AddNameToCensor(censor, name, include, commonRecursedType, wildcardMatching);
AddNameToCensor(censor, nop, name);
name.Empty();
}
else
@@ -614,9 +649,8 @@ static const char *ParseMapWithPaths(
static void AddSwitchWildcardsToCensor(
NWildcard::CCensor &censor,
const UStringVector &strings, bool include,
NRecursedType::EEnum commonRecursedType,
bool wildcardMatching,
const UStringVector &strings,
const CNameOption &nop,
UInt32 codePage)
{
const char *errorMessage = NULL;
@@ -624,7 +658,6 @@ static void AddSwitchWildcardsToCensor(
for (i = 0; i < strings.Size(); i++)
{
const UString &name = strings[i];
NRecursedType::EEnum recursedType;
unsigned pos = 0;
if (name.Len() < kSomeCludePostStringMinSize)
@@ -633,7 +666,7 @@ static void AddSwitchWildcardsToCensor(
break;
}
if (!include)
if (!nop.Include)
{
if (name.IsEqualTo_Ascii_NoCase("td"))
{
@@ -647,20 +680,85 @@ static void AddSwitchWildcardsToCensor(
}
}
if (::MyCharLower_Ascii(name[pos]) == kRecursedIDChar)
CNameOption nop2 = nop;
bool type_WasUsed = false;
bool recursed_WasUsed = false;
bool matching_WasUsed = false;
bool error = false;
for (;;)
{
pos++;
wchar_t c = name[pos];
int index = -1;
if (c <= 0x7F)
index = FindCharPosInString(kRecursedPostCharSet, (char)c);
recursedType = GetRecursedTypeFromIndex(index);
if (index >= 0)
wchar_t c = ::MyCharLower_Ascii(name[pos]);
if (c == kRecursedIDChar)
{
if (recursed_WasUsed)
{
error = true;
break;
}
recursed_WasUsed = true;
pos++;
c = name[pos];
int index = -1;
if (c <= 0x7F)
index = FindCharPosInString(kRecursedPostCharSet, (char)c);
nop2.RecursedType = GetRecursedTypeFromIndex(index);
if (index >= 0)
{
pos++;
continue;
}
}
if (c == 'w')
{
if (matching_WasUsed)
{
error = true;
break;
}
matching_WasUsed = true;
nop2.WildcardMatching = true;
pos++;
if (name[pos] == '-')
{
nop2.WildcardMatching = false;
pos++;
}
}
else if (c == 'm')
{
if (type_WasUsed)
{
error = true;
break;
}
type_WasUsed = true;
pos++;
nop2.MarkMode = NWildcard::kMark_StrictFile;
c = name[pos];
if (c == '-')
{
nop2.MarkMode = NWildcard::kMark_FileOrDir;
pos++;
}
else if (c == '2')
{
nop2.MarkMode = NWildcard::kMark_StrictFile_IfWildcard;
pos++;
}
}
else
break;
}
else
recursedType = commonRecursedType;
if (error)
{
errorMessage = "inorrect switch";
break;
}
if (name.Len() < pos + kSomeCludeAfterRecursedPostStringMinSize)
{
errorMessage = "Too short switch";
@@ -668,15 +766,17 @@ static void AddSwitchWildcardsToCensor(
}
const UString tail = name.Ptr(pos + 1);
if (name[pos] == kImmediateNameID)
AddNameToCensor(censor, tail, include, recursedType, wildcardMatching);
else if (name[pos] == kFileListID)
AddToCensorFromListFile(NULL, censor, tail, include, recursedType, wildcardMatching, codePage);
const wchar_t c = name[pos];
if (c == kImmediateNameID)
AddNameToCensor(censor, nop2, tail);
else if (c == kFileListID)
AddToCensorFromListFile(NULL, censor, nop2, tail, codePage);
#ifdef _WIN32
else if (name[pos] == kMapNameID)
else if (c == kMapNameID)
{
errorMessage = ParseMapWithPaths(censor, tail, include, recursedType, wildcardMatching);
errorMessage = ParseMapWithPaths(censor, tail, nop2);
if (errorMessage)
break;
}
@@ -687,6 +787,7 @@ static void AddSwitchWildcardsToCensor(
break;
}
}
if (i != strings.Size())
throw CArcCmdLineException(errorMessage, strings[i]);
}
@@ -1165,32 +1266,48 @@ void CArcCmdLineParser::Parse2(CArcCmdLineOptions &options)
if (parser[NKey::kNameTrailReplace].ThereIs)
g_PathTrailReplaceMode = !parser[NKey::kNameTrailReplace].WithMinus;
NRecursedType::EEnum recursedType;
if (parser[NKey::kRecursed].ThereIs)
recursedType = GetRecursedTypeFromIndex(parser[NKey::kRecursed].PostCharIndex);
else
recursedType = NRecursedType::kNonRecursed;
CNameOption nop;
if (parser[NKey::kRecursed].ThereIs)
nop.RecursedType = GetRecursedTypeFromIndex(parser[NKey::kRecursed].PostCharIndex);
bool wildcardMatching = true;
if (parser[NKey::kDisableWildcardParsing].ThereIs)
wildcardMatching = false;
nop.WildcardMatching = false;
if (parser[NKey::kUseSlashMark].ThereIs)
{
const UString &s = parser[NKey::kUseSlashMark].PostStrings[0];
if (s.IsEmpty())
nop.MarkMode = NWildcard::kMark_StrictFile;
else if (s.IsEqualTo_Ascii_NoCase("-"))
nop.MarkMode = NWildcard::kMark_FileOrDir;
else if (s.IsEqualTo_Ascii_NoCase("2"))
nop.MarkMode = NWildcard::kMark_StrictFile_IfWildcard;
else
throw CArcCmdLineException("Unsupported -spm:", s);
}
options.ConsoleCodePage = FindCharset(parser, NKey::kConsoleCharSet, true, -1);
UInt32 codePage = (UInt32)FindCharset(parser, NKey::kListfileCharSet, false, CP_UTF8);
bool thereAreSwitchIncludes = false;
if (parser[NKey::kInclude].ThereIs)
{
thereAreSwitchIncludes = true;
nop.Include = true;
AddSwitchWildcardsToCensor(options.Censor,
parser[NKey::kInclude].PostStrings, true, recursedType, wildcardMatching, codePage);
parser[NKey::kInclude].PostStrings, nop, codePage);
}
if (parser[NKey::kExclude].ThereIs)
{
nop.Include = false;
AddSwitchWildcardsToCensor(options.Censor,
parser[NKey::kExclude].PostStrings, false, recursedType, wildcardMatching, codePage);
parser[NKey::kExclude].PostStrings, nop, codePage);
}
unsigned curCommandIndex = kCommandIndex + 1;
bool thereIsArchiveName = !parser[NKey::kNoArName].ThereIs &&
@@ -1198,9 +1315,9 @@ void CArcCmdLineParser::Parse2(CArcCmdLineOptions &options)
options.Command.CommandType != NCommandType::kInfo &&
options.Command.CommandType != NCommandType::kHash;
bool isExtractGroupCommand = options.Command.IsFromExtractGroup();
bool isExtractOrList = isExtractGroupCommand || options.Command.CommandType == NCommandType::kList;
bool isRename = options.Command.CommandType == NCommandType::kRename;
const bool isExtractGroupCommand = options.Command.IsFromExtractGroup();
const bool isExtractOrList = isExtractGroupCommand || options.Command.CommandType == NCommandType::kList;
const bool isRename = options.Command.CommandType == NCommandType::kRename;
if ((isExtractOrList || isRename) && options.StdInMode)
thereIsArchiveName = false;
@@ -1220,10 +1337,11 @@ void CArcCmdLineParser::Parse2(CArcCmdLineOptions &options)
#endif
}
nop.Include = true;
AddToCensorFromNonSwitchesStrings(isRename ? &options.UpdateOptions.RenamePairs : NULL,
curCommandIndex, options.Censor,
nonSwitchStrings, parser.StopSwitchIndex,
recursedType, wildcardMatching,
nop,
thereAreSwitchIncludes, codePage);
options.YesToAll = parser[NKey::kYes].ThereIs;
@@ -1317,13 +1435,28 @@ void CArcCmdLineParser::Parse2(CArcCmdLineOptions &options)
NWildcard::CCensor &arcCensor = options.arcCensor;
CNameOption nopArc;
// nopArc.RecursedType = NRecursedType::kNonRecursed; // default: we don't want recursing for archives, if -r specified
// is it OK, external switches can disable WildcardMatching and MarcMode for arc.
nopArc.WildcardMatching = nop.WildcardMatching;
nopArc.MarkMode = nop.MarkMode;
if (parser[NKey::kArInclude].ThereIs)
AddSwitchWildcardsToCensor(arcCensor, parser[NKey::kArInclude].PostStrings, true, NRecursedType::kNonRecursed, wildcardMatching, codePage);
{
nopArc.Include = true;
AddSwitchWildcardsToCensor(arcCensor, parser[NKey::kArInclude].PostStrings, nopArc, codePage);
}
if (parser[NKey::kArExclude].ThereIs)
AddSwitchWildcardsToCensor(arcCensor, parser[NKey::kArExclude].PostStrings, false, NRecursedType::kNonRecursed, wildcardMatching, codePage);
{
nopArc.Include = false;
AddSwitchWildcardsToCensor(arcCensor, parser[NKey::kArExclude].PostStrings, nopArc, codePage);
}
if (thereIsArchiveName)
AddNameToCensor(arcCensor, options.ArchiveName, true, NRecursedType::kNonRecursed, wildcardMatching);
{
nopArc.Include = true;
AddNameToCensor(arcCensor, nopArc, options.ArchiveName);
}
arcCensor.AddPathsToCensor(NWildcard::k_RelatPath);
@@ -1515,7 +1648,7 @@ FString GetModuleDirPrefix()
{
FString s;
s = g_ModuleDirPrefix;
s = fas2fs(g_ModuleDirPrefix);
if (s.IsEmpty())
s = FTEXT(".") FSTRING_PATH_SEPARATOR;
return s;

View File

@@ -1000,8 +1000,8 @@ HRESULT CArchiveExtractCallback::CheckExistFile(FString &fullProcessedPath, bool
if (_overwriteMode == NExtract::NOverwriteMode::kAsk)
{
int slashPos = fullProcessedPath.ReverseFind_PathSepar();
FString realFullProcessedPath (fullProcessedPath.Left((unsigned)(slashPos + 1)) + fileInfo.Name);
const int slashPos = fullProcessedPath.ReverseFind_PathSepar();
const FString realFullProcessedPath = fullProcessedPath.Left((unsigned)(slashPos + 1)) + fileInfo.Name;
/* (fileInfo) can be symbolic link.
we can show final file properties here. */

View File

@@ -48,7 +48,7 @@ STDMETHODIMP COpenCallbackImp::GetProperty(PROPID propID, PROPVARIANT *value)
else
switch (propID)
{
case kpidName: prop = _fileInfo.Name; break;
case kpidName: prop = fs2us(_fileInfo.Name); break;
case kpidIsDir: prop = _fileInfo.IsDir(); break;
case kpidSize: prop = _fileInfo.Size; break;
case kpidAttrib: prop = (UInt32)_fileInfo.Attrib; break;
@@ -103,12 +103,20 @@ STDMETHODIMP COpenCallbackImp::GetStream(const wchar_t *name, IInStream **inStre
if (!IsSafePath(name2))
return S_FALSE;
// #ifdef _WIN32
// we don't want to support wildcards in names here here
if (name2.Find(L'?') >= 0 ||
name2.Find(L'*') >= 0)
#ifdef _WIN32
/* WIN32 allows wildcards in Find() function
and doesn't allow wildcard in File.Open()
so we can work without the following wildcard check here */
if (name2.Find(L'*') >= 0)
return S_FALSE;
// #endif
{
int startPos = 0;
if (name2.IsPrefixedBy_Ascii_NoCase("\\\\?\\"))
startPos = 3;
if (name2.Find(L'?', startPos) >= 0)
return S_FALSE;
}
#endif
#endif

View File

@@ -866,7 +866,7 @@ struct CAffinityMode
DWORD_PTR GetAffinityMask(UInt32 bundleIndex, CCpuSet *cpuSet) const;
bool NeedAffinity() const { return NumBundleThreads != 0; }
WRes CreateThread_WithAffinity(NWindows::CThread &thread, THREAD_FUNC_RET_TYPE (THREAD_FUNC_CALL_TYPE *startAddress)(void *), LPVOID parameter, UInt32 bundleIndex) const
WRes CreateThread_WithAffinity(NWindows::CThread &thread, THREAD_FUNC_TYPE startAddress, LPVOID parameter, UInt32 bundleIndex) const
{
if (NeedAffinity())
{

View File

@@ -33,12 +33,16 @@ using namespace NWindows;
#define k7zGui "7zG.exe"
// 21.07 : we can disable wildcard
// #define ISWITCH_NO_WILDCARD_POSTFIX "w-"
#define ISWITCH_NO_WILDCARD_POSTFIX
#define kShowDialogSwitch " -ad"
#define kEmailSwitch " -seml."
#define kIncludeSwitch " -i"
#define kArchiveTypeSwitch " -t"
#define kArcIncludeSwitches " -an -ai"
#define kHashIncludeSwitches " -i"
#define kIncludeSwitch " -i" ISWITCH_NO_WILDCARD_POSTFIX
#define kArcIncludeSwitches " -an -ai" ISWITCH_NO_WILDCARD_POSTFIX
#define kHashIncludeSwitches kIncludeSwitch
#define kStopSwitchParsing " --"
extern HWND g_HWND;

View File

@@ -124,7 +124,7 @@ HRESULT CompressFiles(
NWildcard::CCensor censor;
FOR_VECTOR (i, names)
{
censor.AddPreItem(names[i]);
censor.AddPreItem_NoWildcard(names[i]);
}
bool messageWasDisplayed = false;
@@ -178,7 +178,7 @@ static HRESULT ExtractGroupCommand(const UStringVector &arcPaths,
NWildcard::CCensor arcCensor;
FOR_VECTOR (i, arcPaths)
{
arcCensor.AddPreItem(arcPaths[i]);
arcCensor.AddPreItem_NoWildcard(arcPaths[i]);
}
arcCensor.AddPathsToCensor(NWildcard::k_RelatPath);
CDirItemsStat st;
@@ -268,7 +268,7 @@ void CalcChecksum(const UStringVector &paths,
NWildcard::CCensor censor;
FOR_VECTOR (i, paths)
{
censor.AddPreItem(paths[i]);
censor.AddPreItem_NoWildcard(paths[i]);
}
censor.AddPathsToCensor(NWildcard::k_RelatPath);

View File

@@ -767,6 +767,15 @@ static HRESULT EnumerateDirItems(
const UString &name = item.PathParts.Front();
FString fullPath = phyPrefix + us2fs(name);
/*
// not possible now
if (!item.ForDir && !item.ForFile)
{
RINOK(dirItems.AddError(fullPath, ERROR_INVALID_PARAMETER));
continue;
}
*/
#if defined(_WIN32) && !defined(UNDER_CE)
bool needAltStreams = true;
#endif
@@ -823,9 +832,20 @@ static HRESULT EnumerateDirItems(
continue;
}
/*
#ifdef _WIN32
#define MY_ERROR_IS_DIR ERROR_FILE_NOT_FOUND
#define MY_ERROR_NOT_DIR DI_DEFAULT_ERROR
#else
#define MY_ERROR_IS_DIR EISDIR
#define MY_ERROR_NOT_DIR ENOTDIR
#endif
*/
const bool isDir = fi.IsDir();
if ((isDir && !item.ForDir) || (!isDir && !item.ForFile))
if (isDir ? !item.ForDir : !item.ForFile)
{
// RINOK(dirItems.AddError(fullPath, isDir ? MY_ERROR_IS_DIR: MY_ERROR_NOT_DIR));
RINOK(dirItems.AddError(fullPath, DI_DEFAULT_ERROR));
continue;
}

View File

@@ -900,7 +900,7 @@ bool CHashPair::Parse(const char *s)
return false;
if (escape)
{
AString temp = Name;
const AString temp (Name);
return CSum_Name_EscapeToOriginal(temp, Name);
}
return true;

View File

@@ -974,6 +974,17 @@ static HRESULT Compress(
static bool Censor_AreAllAllowed(const NWildcard::CCensor &censor)
{
if (censor.Pairs.Size() != 1)
return false;
const NWildcard::CPair &pair = censor.Pairs[0];
/* Censor_CheckPath() ignores (CPair::Prefix).
So we also ignore (CPair::Prefix) here */
// if (!pair.Prefix.IsEmpty()) return false;
return pair.Head.AreAllAllowed();
}
bool CensorNode_CheckPath2(const NWildcard::CCensorNode &node, const CReadArcItem &item, bool &include);
static bool Censor_CheckPath(const NWildcard::CCensor &censor, const CReadArcItem &item)
@@ -981,9 +992,13 @@ static bool Censor_CheckPath(const NWildcard::CCensor &censor, const CReadArcIte
bool finded = false;
FOR_VECTOR (i, censor.Pairs)
{
/* (CPair::Prefix) in not used for matching items in archive.
So we ignore (CPair::Prefix) here */
bool include;
if (CensorNode_CheckPath2(censor.Pairs[i].Head, item, include))
{
// Check it and FIXME !!!!
// here we can exclude item via some Pair, that is still allowed by another Pair
if (!include)
return false;
finded = true;
@@ -1006,6 +1021,8 @@ static HRESULT EnumerateInArchiveItems(
CReadArcItem item;
const bool allFilesAreAllowed = Censor_AreAllAllowed(censor);
for (UInt32 i = 0; i < numItems; i++)
{
CArcItem ai;
@@ -1024,7 +1041,10 @@ static HRESULT EnumerateInArchiveItems(
if (!storeStreamsMode && ai.IsAltStream)
continue;
*/
ai.Censored = Censor_CheckPath(censor, item);
if (allFilesAreAllowed)
ai.Censored = true;
else
ai.Censored = Censor_CheckPath(censor, item);
RINOK(arc.GetItemMTime(i, ai.MTime, ai.MTimeDefined));
RINOK(arc.GetItemSize(i, ai.Size, ai.SizeDefined));
@@ -1418,7 +1438,7 @@ HRESULT UpdateArchive(
UString s;
s = "It is not allowed to include archive to itself";
s.Add_LF();
s += path;
s += fs2us(path);
throw s;
}
}