-
Type: Bug
-
Resolution: Done
-
Priority: Major - P3
-
Affects Version/s: None
-
Component/s: GridFS
-
None
(ported from github)
When creating an empty file from a stream, GridFS crashes.
When create an empty file by calling mongoc_gridfs_create_file_from_stream() which will relocate the file pointer to the beginning of the created file after write all bytes(no byte written for empty file) into mongodb. Please notice my comments in the following code snippet:
int mongoc_gridfs_file_seek (mongoc_gridfs_file_t * file, /** Arthur Xie: the new created empty file */ uint64_t delta, /** Arthur Xie: 0 */ int whence) /** Arthur Xie: SEEK_SET */ { uint64_t offset; BSON_ASSERT(file); switch (whence) { case SEEK_SET: offset = delta; break; case SEEK_CUR: offset = file->pos + delta; break; case SEEK_END: offset = (file->length - 1) + delta; break; default: errno = EINVAL; return -1; break; } /** Arthur Xie: abort in debug mode because file->length = 0 and offset = 0*/ BSON_ASSERT (file->length > (int64_t)offset); /** Arthur Xie: offset = 0, file->pos = 0, file->page = NULL */ if (offset % file->chunk_size != file->pos % file->chunk_size) { /** no longer on the same page */ if (file->page) { if (_mongoc_gridfs_file_page_is_dirty (file->page)) { _mongoc_gridfs_file_flush_page (file); } else { _mongoc_gridfs_file_page_destroy (file->page); } } /** we'll pick up the seek when we fetch a page on the next action. We lazily load */ } else { /** Arthur Xie: file->page = NULL */ _mongoc_gridfs_file_page_seek (file->page, offset % file->chunk_size); } file->pos = offset; return 0; } bool _mongoc_gridfs_file_page_seek (mongoc_gridfs_file_page_t *page, uint32_t offset) { ENTRY; BSON_ASSERT (page); /** Arthur Xie: assert(page) or nothing happened if not define BSON_DISABLE_ASSERT */ BSON_ASSERT (offset <= page->len); /** Arthur Xie: crash or nothing happened */ page->offset = offset; /** Arthur Xie: crash */ RETURN (1); }
How to fix it:
int mongoc_gridfs_file_seek (mongoc_gridfs_file_t *file, uint64_t delta, int whence) { uint64_t offset; BSON_ASSERT(file); switch (whence) { case SEEK_SET: offset = delta; break; case SEEK_CUR: offset = file->pos + delta; break; case SEEK_END: offset = (file->length - 1) + delta; break; default: errno = EINVAL; return -1; break; } BSON_ASSERT (file->length >= (int64_t)offset); if (file->pos == offset) return 0; ... }
- depends on
-
CDRIVER-839 Bad interpretation of GridFS "SEEK_END" mode
- Closed
-
CDRIVER-849 Allow GridFS seek past end-of-file
- Closed