Skip to content
This repository
Browse code

Z-1647 Added handling of Tar formats for files over 8GB such as Posix…

… and Pax
  • Loading branch information...
commit a74a38553bdcc870d9f065472414c569cd037f41 1 parent 500dbba
David Pierson davidpierson authored

Showing 1 changed file with 36 additions and 9 deletions. Show diff stats Hide diff stats

  1. +36 9 src/Tar/TarHeader.cs
45 src/Tar/TarHeader.cs
@@ -33,6 +33,8 @@
33 33 // obligated to do so. If you do not wish to do so, delete this
34 34 // exception statement from your version.
35 35
  36 +// HISTORY
  37 +// 27-07-2012 Z-1647 Added handling of Tar formats for files over 8GB such as Posix and Pax
36 38
37 39 /* The tar format and its POSIX successor PAX have a long history which makes for compatability
38 40 issues when creating and reading files.
@@ -584,8 +586,8 @@ public void ParseBuffer(byte[] header)
584 586
585 587 GroupId = (int)TarHeader.ParseOctal(header, offset, TarHeader.GIDLEN);
586 588 offset += TarHeader.GIDLEN;
587   -
588   - Size = TarHeader.ParseOctal(header, offset, TarHeader.SIZELEN);
  589 +
  590 + Size = TarHeader.ParseBinaryOrOctal(header, offset, TarHeader.SIZELEN);
589 591 offset += TarHeader.SIZELEN;
590 592
591 593 ModTime = GetDateTimeFromCTime(TarHeader.ParseOctal(header, offset, TarHeader.MODTIMELEN));
@@ -638,10 +640,10 @@ public void WriteHeader(byte[] outBuffer)
638 640 offset = GetOctalBytes(mode, outBuffer, offset, MODELEN);
639 641 offset = GetOctalBytes(UserId, outBuffer, offset, UIDLEN);
640 642 offset = GetOctalBytes(GroupId, outBuffer, offset, GIDLEN);
641   -
642   - offset = GetLongOctalBytes(Size, outBuffer, offset, SIZELEN);
643   - offset = GetLongOctalBytes(GetCTime(ModTime), outBuffer, offset, MODTIMELEN);
644   -
  643 +
  644 + offset = GetBinaryOrOctalBytes(Size, outBuffer, offset, SIZELEN);
  645 + offset = GetOctalBytes(GetCTime(ModTime), outBuffer, offset, MODTIMELEN);
  646 +
645 647 int csOffset = offset;
646 648 for (int c = 0; c < CHKSUMLEN; ++c)
647 649 {
@@ -740,6 +742,21 @@ static internal void RestoreSetValues()
740 742 defaultGroupName = groupNameAsSet;
741 743 }
742 744
  745 + // Return value that may be stored in octal or binary. Length must exceed 8.
  746 + //
  747 + static private long ParseBinaryOrOctal(byte[] header, int offset, int length) {
  748 + if (header[offset] >= 128) {
  749 + // File sizes over 8GB are stored in 8 right-justified bytes of binary indicated by setting the high-order bit of the leftmost byte of a numeric field.
  750 + int pos = length - 8;
  751 + long result = 0;
  752 + while (pos < length) {
  753 + result = result << 8 | header[offset + pos++];
  754 + }
  755 + return result;
  756 + }
  757 + return ParseOctal(header, offset, length);
  758 + }
  759 +
743 760 /// <summary>
744 761 /// Parse an octal string from a header buffer.
745 762 /// </summary>
@@ -1017,15 +1034,25 @@ public static int GetOctalBytes(long value, byte[] buffer, int offset, int lengt
1017 1034 }
1018 1035
1019 1036 /// <summary>
1020   - /// Put an octal representation of a value into a buffer
  1037 + /// Put an octal or binary representation of a value into a buffer
1021 1038 /// </summary>
1022 1039 /// <param name = "value">Value to be convert to octal</param>
1023 1040 /// <param name = "buffer">The buffer to update</param>
1024 1041 /// <param name = "offset">The offset into the buffer to store the value</param>
1025   - /// <param name = "length">The length of the octal string</param>
  1042 + /// <param name = "length">The length of the octal string. Must be 12.</param>
1026 1043 /// <returns>Index of next byte</returns>
1027   - public static int GetLongOctalBytes(long value, byte[] buffer, int offset, int length)
  1044 + private static int GetBinaryOrOctalBytes(long value, byte[] buffer, int offset, int length)
1028 1045 {
  1046 + if (value > 0x1FFFFFFFF) { // Octal 77777777777 (11 digits)
  1047 + // Put value as binary, right-justified into the buffer. Set high order bit of left-most byte.
  1048 + int pos = length - 1;
  1049 + while (pos > 0) {
  1050 + buffer[offset + pos--] = (byte)value;
  1051 + value = value >> 8;
  1052 + }
  1053 + buffer[offset] = 128;
  1054 + return offset + length;
  1055 + }
1029 1056 return GetOctalBytes(value, buffer, offset, length);
1030 1057 }
1031 1058

0 comments on commit a74a385

Please sign in to comment.
Something went wrong with that request. Please try again.