Fix handling of mappings over file size.
authorVlad Brezae <brezaevlad@gmail.com>
Thu, 15 Jan 2015 21:59:45 +0000 (13:59 -0800)
committerVlad Brezae <brezaevlad@gmail.com>
Mon, 26 Jan 2015 23:08:14 +0000 (15:08 -0800)
Add tests.

mcs/class/System.Core/Test/System.IO.MemoryMappedFiles/MemoryMappedFileTest.cs
mono/metadata/file-mmap-posix.c

index 21aba946c55611c2524a3c177837105290339131..3905846c77174ef5cc21920a68855731a05d71cc 100644 (file)
@@ -316,6 +316,34 @@ namespace MonoTests.System.IO.MemoryMappedFiles {
                                tw.WriteLine ("Hello World!");
                        }
                }
+
+               [Test]
+               [ExpectedException(typeof(IOException))]
+               public void CreateViewStreamWithOffsetPastFileEnd ()
+               {
+                       string f = Path.Combine (tempDir, "8192-file");
+                       File.WriteAllBytes (f, new byte [8192]);
+
+                       MemoryMappedFile mappedFile = MemoryMappedFile.CreateFromFile (f, FileMode.Open, "myMap", 8192);
+
+                       /* Should throw exception when trying to map past end of file */
+                       MemoryMappedViewStream stream = mappedFile.CreateViewStream (8200, 10, MemoryMappedFileAccess.ReadWrite);
+               }
+
+               [Test]
+               [ExpectedException(typeof(NotSupportedException))]
+               public void CreateViewStreamWithOffsetPastFileEnd2 ()
+               {
+                       string f = Path.Combine (tempDir, "8192-file");
+                       File.WriteAllBytes (f, new byte [8192]);
+
+                       MemoryMappedFile mappedFile = MemoryMappedFile.CreateFromFile (f, FileMode.Open);
+
+                       MemoryMappedViewStream stream = mappedFile.CreateViewStream (8191, 8191, MemoryMappedFileAccess.ReadWrite);
+
+                       /* Should throw exception due to trying to overflow capacity */
+                       stream.Write (new byte [8191], 0, 8191);
+               }
        }
 }
 
index be9f740b8572df63433e40064e5a804896784f28..fcb6682fecee708c4946ba704b6b647f487259a1 100644 (file)
@@ -479,13 +479,15 @@ mono_mmap_map (void *handle, gint64 offset, gint64 *size, int access, void **mma
        struct stat buf = { 0 };
        fstat (fh->fd, &buf); //FIXME error handling
 
+       if (offset > buf.st_size)
+               goto error;
        /**
          * We use the file size if one of the following conditions is true:
          *  -input size is zero
          *  -input size is bigger than the file and the file is not a magical zero size file such as /dev/mem.
          */
-       if (eff_size == 0 || (eff_size > buf.st_size && !is_special_zero_size_file (&buf)))
-               eff_size = buf.st_size;
+       if (eff_size == 0 || ((eff_size + offset) > buf.st_size && !is_special_zero_size_file (&buf)))
+               eff_size = buf.st_size - offset;
        *size = eff_size;
 
        mmap_offset = align_down_to_page_size (offset);
@@ -500,6 +502,7 @@ mono_mmap_map (void *handle, gint64 offset, gint64 *size, int access, void **mma
                return 0;
        }
 
+error:
        *mmap_handle = NULL;
        *base_address = NULL;
        return COULD_NOT_MAP_MEMORY;