Skip to content

Commit

Permalink
rar5 read FHEXTRA_REDIR and expose via RarEntry
Browse files Browse the repository at this point in the history
  NOTE: api user should skip entries where RarEntry.IsRedir is true and not call OpenEntryStream()
  • Loading branch information
root committed Mar 14, 2024
1 parent ab5535e commit 226ce34
Show file tree
Hide file tree
Showing 5 changed files with 50 additions and 7 deletions.
26 changes: 19 additions & 7 deletions src/SharpCompress/Common/Rar/Headers/FileHeader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ private void ReadFromReaderV5(MarkingBinaryReader reader)
const ushort FHEXTRA_HASH = 0x02;
const ushort FHEXTRA_HTIME = 0x03;
// const ushort FHEXTRA_VERSION = 0x04;
// const ushort FHEXTRA_REDIR = 0x05;
const ushort FHEXTRA_REDIR = 0x05;
// const ushort FHEXTRA_UOWNER = 0x06;
// const ushort FHEXTRA_SUBDATA = 0x07;

Expand All @@ -120,7 +120,6 @@ private void ReadFromReaderV5(MarkingBinaryReader reader)
var type = reader.ReadRarVIntUInt16();
switch (type)
{
//TODO
case FHEXTRA_CRYPT: // file encryption

{
Expand Down Expand Up @@ -171,11 +170,17 @@ private void ReadFromReaderV5(MarkingBinaryReader reader)
//
// }
// break;
// case FHEXTRA_REDIR: // file system redirection
// {
//
// }
// break;
case FHEXTRA_REDIR: // file system redirection

{
RedirType = reader.ReadRarVIntByte();
RedirFlags = reader.ReadRarVIntByte();
var nn = reader.ReadRarVIntUInt16();
var bb = reader.ReadBytes(nn);
RedirTargetName = ConvertPathV5(Encoding.UTF8.GetString(bb, 0, bb.Length));
}
break;
//TODO
// case FHEXTRA_UOWNER: // unix owner
// {
//
Expand All @@ -189,6 +194,7 @@ private void ReadFromReaderV5(MarkingBinaryReader reader)

default:
// skip unknown record types to allow new record types to be added in the future
//Console.WriteLine($"unhandled rar header field type {type}");
break;
}
// drain any trailing bytes of extra record
Expand Down Expand Up @@ -437,6 +443,12 @@ internal byte[] FileCrc

public bool IsSolid { get; private set; }

public byte RedirType { get; private set; }
public bool IsRedir => RedirType != 0;
public byte RedirFlags { get; private set; }
public bool IsRedirDirectory => (RedirFlags & RedirFlagV5.DIRECTORY) != 0;
public string RedirTargetName { get; private set; }

// unused for UnpackV1 implementation (limitation)
internal size_t WindowSize { get; private set; }

Expand Down
14 changes: 14 additions & 0 deletions src/SharpCompress/Common/Rar/Headers/Flags.cs
Original file line number Diff line number Diff line change
Expand Up @@ -157,3 +157,17 @@ internal static class EndArchiveFlagsV5
{
public const ushort HAS_NEXT_VOLUME = 0x0001;
}

internal static class RedirTypeV5
{
public const byte UNIX_SYMLINK = 0x0001;
public const byte WIN_SYMLINK = 0x0002;
public const byte WIN_JUNCTION = 0x0003;
public const byte HARD_LINK = 0x0004;
public const byte FILE_COPY = 0x0005;
}

internal static class RedirFlagV5
{
public const byte DIRECTORY = 0x0001;
}
4 changes: 4 additions & 0 deletions src/SharpCompress/Common/Rar/RarEntry.cs
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,10 @@ public abstract class RarEntry : Entry

public override bool IsSplitAfter => FileHeader.IsSplitAfter;

public bool IsRedir => FileHeader.IsRedir;

public string RedirTargetName => FileHeader.RedirTargetName;

public override string ToString() =>
string.Format(
"Entry Path: {0} Compressed Size: {1} Uncompressed Size: {2} CRC: {3}",
Expand Down
7 changes: 7 additions & 0 deletions src/SharpCompress/Compressors/Rar/RarStream.cs
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,13 @@ public override int Read(byte[] buffer, int offset, int count)
fetch = false;
}
_position += outTotal;
if (count > 0 && outTotal == 0 && _position != Length)
{
// sanity check, eg if we try to decompress a redir entry
throw new InvalidOperationException(
$"unpacked file size does not match header: expected {Length} found {_position}"
);
}
return outTotal;
}

Expand Down
6 changes: 6 additions & 0 deletions src/SharpCompress/Readers/Rar/RarReader.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
Expand Down Expand Up @@ -64,6 +65,11 @@ protected override IEnumerable<RarReaderEntry> GetEntries(Stream stream)

protected override EntryStream GetEntryStream()
{
if (Entry.IsRedir)
{
throw new InvalidOperationException("no stream for redirect entry");
}

var stream = new MultiVolumeReadOnlyStream(
CreateFilePartEnumerableForCurrentEntry().Cast<RarFilePart>(),
this
Expand Down

0 comments on commit 226ce34

Please sign in to comment.