@@ -190,9 +190,9 @@ public MmapDefault(CodeContext/*!*/ context, int fileno, long length, string tag
190190 } else if ( RuntimeInformation . IsOSPlatform ( OSPlatform . OSX ) || RuntimeInformation . IsOSPlatform ( OSPlatform . Linux ) ) {
191191 // use file descriptor
192192#if NET8_0_OR_GREATER
193- CheckFileAccess ( _fileAccess , stream ) ;
193+ CheckFileAccessAndSize ( stream ) ;
194194 _handle = new SafeFileHandle ( ( IntPtr ) fileno , ownsHandle : false ) ;
195- _file = MemoryMappedFile . CreateFromFile ( _handle , _mapName , length , _fileAccess , HandleInheritability . None , leaveOpen : true ) ;
195+ _file = MemoryMappedFile . CreateFromFile ( _handle , _mapName , stream . Length , _fileAccess , HandleInheritability . None , leaveOpen : true ) ;
196196#else
197197 _handle = new SafeFileHandle ( ( IntPtr ) fileno , ownsHandle : false ) ;
198198 FileAccess fa = stream . CanWrite ? stream . CanRead ? FileAccess . ReadWrite : FileAccess . Write : FileAccess . Read ;
@@ -211,19 +211,12 @@ public MmapDefault(CodeContext/*!*/ context, int fileno, long length, string tag
211211 throw WindowsError ( PythonExceptions . _OSError . ERROR_INVALID_HANDLE ) ;
212212 }
213213
214- CheckFileAccess ( _fileAccess , _sourceStream ) ;
215-
216214 if ( length == 0 ) {
217- length = _sourceStream . Length ;
218- if ( length == 0 ) {
219- throw PythonOps . ValueError ( "cannot mmap an empty file" ) ;
220- }
221- if ( _offset >= length ) {
222- throw PythonOps . ValueError ( "mmap offset is greater than file size" ) ;
223- }
224- length -= _offset ;
215+ length = _sourceStream . Length - _offset ;
225216 }
226217
218+ CheckFileAccessAndSize ( _sourceStream ) ;
219+
227220 long capacity = checked ( _offset + length ) ;
228221
229222 // Enlarge the file as needed.
@@ -254,8 +247,8 @@ public MmapDefault(CodeContext/*!*/ context, int fileno, long length, string tag
254247 }
255248 _position = 0L ;
256249
257- void CheckFileAccess ( MemoryMappedFileAccess mmapAccess , Stream stream ) {
258- bool isValid = mmapAccess switch {
250+ void CheckFileAccessAndSize ( Stream stream ) {
251+ bool isValid = _fileAccess switch {
259252 MemoryMappedFileAccess . Read => stream . CanRead ,
260253 MemoryMappedFileAccess . ReadWrite => stream . CanRead && stream . CanWrite ,
261254 MemoryMappedFileAccess . CopyOnWrite => stream . CanRead ,
@@ -265,20 +258,27 @@ void CheckFileAccess(MemoryMappedFileAccess mmapAccess, Stream stream) {
265258 } ;
266259
267260 if ( ! isValid ) {
268- if ( _handle is not null && _sourceStream is not null ) {
269- _sourceStream . Dispose ( ) ;
270- }
271- throw PythonOps . OSError ( PythonExceptions . _OSError . ERROR_ACCESS_DENIED , "Invalid access mode" ) ;
261+ ThrowException ( PythonOps . OSError ( PythonExceptions . _OSError . ERROR_ACCESS_DENIED , "Invalid access mode" ) ) ;
272262 }
273263
274264 if ( ! RuntimeInformation . IsOSPlatform ( OSPlatform . Windows ) ) {
275265 // Unix map does not support increasing size on open
276- if ( _offset + length > stream . Length ) {
277- if ( _handle is not null && _sourceStream is not null ) {
278- _sourceStream . Dispose ( ) ;
279- }
280- throw PythonOps . ValueError ( "mmap length is greater than file size" ) ;
266+ if ( length != 0 && _offset + length > stream . Length ) {
267+ ThrowException ( PythonOps . ValueError ( "mmap length is greater than file size" ) ) ;
268+ }
269+ }
270+ if ( length == 0 && stream . Length == 0 ) {
271+ ThrowException ( PythonOps . ValueError ( "cannot mmap an empty file" ) ) ;
272+ }
273+ if ( _offset >= stream . Length ) {
274+ ThrowException ( PythonOps . ValueError ( "mmap offset is greater than file size" ) ) ;
275+ }
276+
277+ void ThrowException ( Exception ex ) {
278+ if ( _handle is not null && _sourceStream is not null ) { // .NET 6.0 on POSIX only
279+ _sourceStream . Dispose ( ) ;
281280 }
281+ throw ex ;
282282 }
283283 }
284284 } // end of constructor
0 commit comments