|
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 commit comments