|
28 | 28 | using System.Buffers; |
29 | 29 | using System.Collections; |
30 | 30 | using System.Collections.Generic; |
| 31 | +using System.Diagnostics; |
31 | 32 | using System.IO; |
32 | 33 | using System.Runtime.InteropServices; |
33 | 34 | using System.Text; |
@@ -195,19 +196,26 @@ ErrorCode Open (string path, OpenFlags flags) |
195 | 196 | /// </summary> |
196 | 197 | /// <param name="stream">The stream to open</param> |
197 | 198 | /// <param name="options">Platform-specific options</param> |
198 | | - public static ZipArchive Open (Stream stream, IPlatformOptions options = null) |
| 199 | + /// <param name="strictConsistencyChecks"></param> |
| 200 | + public static ZipArchive Open (Stream stream, IPlatformOptions options = null, bool strictConsistencyChecks = false) |
199 | 201 | { |
200 | | - return ZipArchive.CreateInstanceFromStream (stream, OpenFlags.None, options); |
| 202 | + OpenFlags flags = OpenFlags.None; |
| 203 | + if (strictConsistencyChecks) |
| 204 | + flags |= OpenFlags.CheckCons; |
| 205 | + return ZipArchive.CreateInstanceFromStream (stream, flags, options); |
201 | 206 | } |
202 | 207 |
|
203 | 208 | /// <summary> |
204 | 209 | /// Create a new archive using the Stream provided. The steam should be an empty stream, any existing data will be overwritten. |
205 | 210 | /// </summary> |
206 | 211 | /// <param name="stream">The stream to create the arhive in</param> |
207 | 212 | /// <param name="options">Platform-specific options</param> |
208 | | - public static ZipArchive Create (Stream stream, IPlatformOptions options = null) |
| 213 | + public static ZipArchive Create (Stream stream, IPlatformOptions options = null, bool strictConsistencyChecks = false) |
209 | 214 | { |
210 | | - return ZipArchive.CreateInstanceFromStream (stream, OpenFlags.Create | OpenFlags.Truncate, options); |
| 215 | + OpenFlags flags = OpenFlags.Create | OpenFlags.Truncate; |
| 216 | + if (strictConsistencyChecks) |
| 217 | + flags |= OpenFlags.CheckCons; |
| 218 | + return ZipArchive.CreateInstanceFromStream (stream, flags, options); |
211 | 219 | } |
212 | 220 |
|
213 | 221 | /// <summary> |
@@ -788,6 +796,7 @@ internal ZipException GetErrorException () |
788 | 796 | internal static unsafe Int64 stream_callback (IntPtr state, IntPtr data, UInt64 len, SourceCommand cmd) |
789 | 797 | { |
790 | 798 | byte [] buffer = null; |
| 799 | + Native.zip_error_t error; |
791 | 800 | int length = (int)len; |
792 | 801 | var handle = GCHandle.FromIntPtr (state); |
793 | 802 | if (!handle.IsAllocated) |
@@ -833,30 +842,26 @@ internal static unsafe Int64 stream_callback (IntPtr state, IntPtr data, UInt64 |
833 | 842 | return -1; |
834 | 843 | } |
835 | 844 |
|
836 | | - long firstOffset, secondOffset; |
| 845 | + SeekOrigin seek = Native.ConvertWhence (args.whence); |
837 | 846 | if (args.offset > Int64.MaxValue) { |
838 | 847 | // Stream.Seek uses a signed 64-bit value for the offset, we need to split it up |
839 | | - firstOffset = Int64.MaxValue; |
840 | | - secondOffset = (long)(args.offset - Int64.MaxValue); |
| 848 | + if (!Seek (destination, seek, Int64.MaxValue) || !Seek (destination, seek, (long)(args.offset - Int64.MaxValue))) { |
| 849 | + return -1; |
| 850 | + } |
841 | 851 | } else { |
842 | | - firstOffset = (long)args.offset; |
843 | | - secondOffset = 0; |
844 | | - } |
845 | | - |
846 | | - SeekOrigin seek = Native.ConvertWhence (args.whence); |
847 | | - Native.zip_error_t error; |
848 | | - |
849 | | - if (!SeekIfNeeded (destination, seek, firstOffset) || !SeekIfNeeded (destination, seek, secondOffset)) { |
850 | | - return -1; |
| 852 | + if (!Seek (destination, seek, (long)args.offset)) { |
| 853 | + return -1; |
| 854 | + } |
851 | 855 | } |
| 856 | + |
852 | 857 | break; |
853 | 858 |
|
854 | 859 | case SourceCommand.Seek: |
855 | 860 | long offset = Native.zip_source_seek_compute_offset ((UInt64)stream.Position, (UInt64)stream.Length, data, len, out error); |
856 | 861 | if (offset < 0) { |
857 | 862 | return offset; |
858 | 863 | } |
859 | | - if (offset != stream.Seek (offset, SeekOrigin.Begin)) { |
| 864 | + if (!Seek (stream, SeekOrigin.Begin, offset)) { |
860 | 865 | return -1; |
861 | 866 | } |
862 | 867 | break; |
@@ -962,12 +967,8 @@ internal static unsafe Int64 stream_callback (IntPtr state, IntPtr data, UInt64 |
962 | 967 |
|
963 | 968 | return 0; |
964 | 969 |
|
965 | | - bool SeekIfNeeded (Stream s, SeekOrigin origin, long offset) |
| 970 | + bool Seek (Stream s, SeekOrigin origin, long offset) |
966 | 971 | { |
967 | | - if (offset == 0) { |
968 | | - return true; |
969 | | - } |
970 | | - |
971 | 972 | return s.Seek (offset, origin) == offset; |
972 | 973 | } |
973 | 974 | } |
|
0 commit comments