@@ -176,5 +176,49 @@ int main() {
176176 printf ("/yolo/sharedoffset.txt content=%s %d\n" , buffer + offset , offset );
177177 fclose (fd );
178178 }
179+
180+ /**
181+ * MMAP to and expanded file
182+ *
183+ * When appending to a file, the buffer is expanded in chunks, and so the actual length
184+ * of the file could be less than the buffer length.
185+ *
186+ * When using mmap for an expanded file, we have to make sure that content from the buffer
187+ * is not written beyond the allocated memory area for the mmap operation.
188+ */
189+ {
190+ int fd = open ("/yolo/expandedfile.txt" , O_RDWR | O_CREAT , (mode_t )0600 );
191+ assert (fd != -1 );
192+
193+ const size_t textsize = 33 ;
194+
195+ // multiple calls to write so that the file is expanded
196+ for (int n = 0 ; n < textsize ; n ++ ) {
197+ assert (write (fd , "a" , 1 ) != -1 );
198+ }
199+
200+ EM_ASM_ ({
201+ const stream = FS .streams .find (stream = > stream .path .indexOf ('/yolo/expandedfile.txt' )>=0 );
202+ assert (stream .node .usedBytes == = $0 ,
203+ 'Used bytes on the expanded file (' + stream .node .usedBytes + ') ' +
204+ 'should be 33'
205+ );
206+ assert (stream .node .contents .length > stream .node .usedBytes ,
207+ 'Used bytes on the expanded file (' + stream .node .usedBytes + ') ' +
208+ 'should be less than the length of the content buffer (' + stream .node .contents .length + ')'
209+ );
210+ stream .node .contents [stream .node .usedBytes ] = 98 ; // 'b', we don't want to see this in the mmap area
211+ }, textsize );
212+
213+ char * map = (char * )mmap (NULL , textsize , PROT_READ , 0 , fd , 0 );
214+
215+ assert (map [textsize - 1 ] == 'a' );
216+
217+ // Assert that content from the expanded file buffer are not written beyond the maps allocated memory
218+ assert (map [textsize ] != 'b' );
219+
220+ close (fd );
221+ }
222+
179223 return 0 ;
180224}
0 commit comments