mirror of
https://github.com/Xevion/easy7zip.git
synced 2025-12-07 13:15:04 -06:00
Fix handling of Tar PaxHeaders
- relax PaxHeader name check and add mtime pax property parsing - patch submitted by Vladimir Surguchev
This commit is contained in:
@@ -368,13 +368,13 @@ static HRESULT ReadDataToString(ISequentialInStream *stream, CItemEx &item, AStr
|
|||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool ParsePaxLongName(const AString &src, AString &dest)
|
static bool ParsePaxParams(const AString& src, AString& pax_path, Int64& pax_mtime)
|
||||||
{
|
{
|
||||||
dest.Empty();
|
pax_path.Empty();
|
||||||
for (unsigned pos = 0;;)
|
for (unsigned pos = 0;;)
|
||||||
{
|
{
|
||||||
if (pos >= src.Len())
|
if (pos >= src.Len())
|
||||||
return false;
|
return true; // false;
|
||||||
const char *start = src.Ptr(pos);
|
const char *start = src.Ptr(pos);
|
||||||
const char *end;
|
const char *end;
|
||||||
const UInt32 lineLen = ConvertStringToUInt32(start, &end);
|
const UInt32 lineLen = ConvertStringToUInt32(start, &end);
|
||||||
@@ -382,7 +382,9 @@ static bool ParsePaxLongName(const AString &src, AString &dest)
|
|||||||
return false;
|
return false;
|
||||||
if (*end != ' ')
|
if (*end != ' ')
|
||||||
return false;
|
return false;
|
||||||
if (lineLen > src.Len() - pos)
|
if (lineLen <= 0 || lineLen > src.Len() - pos)
|
||||||
|
return false;
|
||||||
|
if (start[lineLen - 1] != '\n')
|
||||||
return false;
|
return false;
|
||||||
unsigned offset = (unsigned)(end - start) + 1;
|
unsigned offset = (unsigned)(end - start) + 1;
|
||||||
if (lineLen < offset)
|
if (lineLen < offset)
|
||||||
@@ -390,13 +392,32 @@ static bool ParsePaxLongName(const AString &src, AString &dest)
|
|||||||
if (IsString1PrefixedByString2(src.Ptr(pos + offset), "path="))
|
if (IsString1PrefixedByString2(src.Ptr(pos + offset), "path="))
|
||||||
{
|
{
|
||||||
offset += 5; // "path="
|
offset += 5; // "path="
|
||||||
dest = src.Mid(pos + offset, lineLen - offset);
|
pax_path = src.Mid(pos + offset, lineLen - offset - 1);
|
||||||
if (dest.IsEmpty())
|
}
|
||||||
return false;
|
else if (IsString1PrefixedByString2(src.Ptr(pos + offset), "mtime="))
|
||||||
if (dest.Back() != '\n')
|
{
|
||||||
return false;
|
Int64 v = 0; int mult = 10 * 1000 * 1000;
|
||||||
dest.DeleteBack();
|
offset += 6; // "mtime=ssssssssss.ccccccc"
|
||||||
return true;
|
bool after_dot = false;
|
||||||
|
for (;;) {
|
||||||
|
const char c = start[offset++];
|
||||||
|
if (c >= '0' && c <= '9') {
|
||||||
|
v = 10 * v + (c - '0');
|
||||||
|
if (after_dot) {
|
||||||
|
mult /= 10;
|
||||||
|
if (mult == 1)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (c == '.')
|
||||||
|
after_dot = true;
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (v > 0)
|
||||||
|
pax_mtime = v * mult;
|
||||||
}
|
}
|
||||||
pos += lineLen;
|
pos += lineLen;
|
||||||
}
|
}
|
||||||
@@ -459,6 +480,9 @@ HRESULT ReadItem(ISequentialInStream *stream, bool &filled, CItemEx &item, EErro
|
|||||||
if (IsString1PrefixedByString2(s, "./"))
|
if (IsString1PrefixedByString2(s, "./"))
|
||||||
s += 2;
|
s += 2;
|
||||||
if ( IsString1PrefixedByString2(s, "PaxHeader/")
|
if ( IsString1PrefixedByString2(s, "PaxHeader/")
|
||||||
|
|| item.Name.Find("/PaxHeader/") >= 0
|
||||||
|
|| IsString1PrefixedByString2(s, "PaxHeaders/")
|
||||||
|
|| item.Name.Find("/PaxHeaders/") >= 0
|
||||||
|| IsString1PrefixedByString2(s, "PaxHeaders.X/")
|
|| IsString1PrefixedByString2(s, "PaxHeaders.X/")
|
||||||
|| IsString1PrefixedByString2(s, "PaxHeaders.4467/")
|
|| IsString1PrefixedByString2(s, "PaxHeaders.4467/")
|
||||||
|| StringsAreEqual_Ascii(s, "@PaxHeader")
|
|| StringsAreEqual_Ascii(s, "@PaxHeader")
|
||||||
@@ -503,8 +527,14 @@ HRESULT ReadItem(ISequentialInStream *stream, bool &filled, CItemEx &item, EErro
|
|||||||
if (!pax.IsEmpty())
|
if (!pax.IsEmpty())
|
||||||
{
|
{
|
||||||
AString name;
|
AString name;
|
||||||
if (ParsePaxLongName(pax, name))
|
Int64 mtime = 0;
|
||||||
item.Name = name;
|
if (ParsePaxParams(pax, name, mtime))
|
||||||
|
{
|
||||||
|
if (!name.IsEmpty())
|
||||||
|
item.Name = name;
|
||||||
|
if (mtime > 0)
|
||||||
|
item.MTime = mtime;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// no "path" property is allowed in pax4467
|
// no "path" property is allowed in pax4467
|
||||||
|
|||||||
Reference in New Issue
Block a user