You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@arrow.apache.org by we...@apache.org on 2018/07/08 17:16:41 UTC
[arrow] branch master updated: ARROW-2784: [C++]
MemoryMappedFile::WriteAt allow writing past the end
This is an automated email from the ASF dual-hosted git repository.
wesm pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/arrow.git
The following commit(s) were added to refs/heads/master by this push:
new 735e38b ARROW-2784: [C++] MemoryMappedFile::WriteAt allow writing past the end
735e38b is described below
commit 735e38b2b906dfde32d4d294a9a606dab0566f88
Author: Dimitri Vorona <vo...@in.tum.de>
AuthorDate: Sun Jul 8 13:16:35 2018 -0400
ARROW-2784: [C++] MemoryMappedFile::WriteAt allow writing past the end
Author: Dimitri Vorona <vo...@in.tum.de>
Closes #2206 from alendit/fix_write_past_the_end and squashes the following commits:
a8987bb2 <Dimitri Vorona> Remove WriteAt position tests
9fad80ce <Dimitri Vorona> Revert "Make WriteAt not move files position"
35b40be0 <Dimitri Vorona> Make WriteAt not move files position
c905183d <Dimitri Vorona> Check position before seeking and add more tests for ReadAt
f0ed44d1 <Dimitri Vorona> Fix write beyond the end in MemoryMappedFile::ReatAt
---
cpp/src/arrow/io/file.cc | 4 +++
cpp/src/arrow/io/io-file-test.cc | 55 ++++++++++++++++++++++++++++++++++++++++
2 files changed, 59 insertions(+)
diff --git a/cpp/src/arrow/io/file.cc b/cpp/src/arrow/io/file.cc
index 8113482..19f4a35 100644
--- a/cpp/src/arrow/io/file.cc
+++ b/cpp/src/arrow/io/file.cc
@@ -515,6 +515,9 @@ Status MemoryMappedFile::WriteAt(int64_t position, const void* data, int64_t nby
if (!memory_map_->opened() || !memory_map_->writable()) {
return Status::IOError("Unable to write");
}
+ if (position + nbytes > memory_map_->size()) {
+ return Status::Invalid("Cannot write past end of memory map");
+ }
RETURN_NOT_OK(memory_map_->Seek(position));
return WriteInternal(data, nbytes);
@@ -529,6 +532,7 @@ Status MemoryMappedFile::Write(const void* data, int64_t nbytes) {
if (nbytes + memory_map_->position() > memory_map_->size()) {
return Status::Invalid("Cannot write past end of memory map");
}
+
return WriteInternal(data, nbytes);
}
diff --git a/cpp/src/arrow/io/io-file-test.cc b/cpp/src/arrow/io/io-file-test.cc
index 4d9120f..a06edca 100644
--- a/cpp/src/arrow/io/io-file-test.cc
+++ b/cpp/src/arrow/io/io-file-test.cc
@@ -614,6 +614,61 @@ TEST_F(TestMemoryMappedFile, WriteRead) {
}
}
+TEST_F(TestMemoryMappedFile, WriteAt) {
+ const int64_t buffer_size = 1024;
+ std::vector<uint8_t> buffer(buffer_size);
+ test::random_bytes(buffer_size, 0, buffer.data());
+
+ std::string path = "io-memory-map-write-read-test";
+ std::shared_ptr<MemoryMappedFile> result;
+ ASSERT_OK(InitMemoryMap(buffer_size, path, &result));
+
+ ASSERT_OK(result->WriteAt(0, buffer.data(), buffer_size / 2));
+
+ ASSERT_OK(
+ result->WriteAt(buffer_size / 2, buffer.data() + buffer_size / 2, buffer_size / 2));
+
+ std::shared_ptr<Buffer> out_buffer;
+ ASSERT_OK(result->ReadAt(0, buffer_size, &out_buffer));
+
+ ASSERT_EQ(memcmp(out_buffer->data(), buffer.data(), buffer_size), 0);
+}
+
+TEST_F(TestMemoryMappedFile, WriteBeyondEnd) {
+ const int64_t buffer_size = 1024;
+ std::vector<uint8_t> buffer(buffer_size);
+ test::random_bytes(buffer_size, 0, buffer.data());
+
+ std::string path = "io-memory-map-write-read-test";
+ std::shared_ptr<MemoryMappedFile> result;
+ ASSERT_OK(InitMemoryMap(buffer_size, path, &result));
+
+ ASSERT_OK(result->Seek(1));
+ ASSERT_RAISES(Invalid, result->Write(buffer.data(), buffer_size));
+
+ // The position should remain unchanged afterwards
+ int64_t position;
+ ASSERT_OK(result->Tell(&position));
+ ASSERT_EQ(position, 1);
+}
+
+TEST_F(TestMemoryMappedFile, WriteAtBeyondEnd) {
+ const int64_t buffer_size = 1024;
+ std::vector<uint8_t> buffer(buffer_size);
+ test::random_bytes(buffer_size, 0, buffer.data());
+
+ std::string path = "io-memory-map-write-read-test";
+ std::shared_ptr<MemoryMappedFile> result;
+ ASSERT_OK(InitMemoryMap(buffer_size, path, &result));
+
+ ASSERT_RAISES(Invalid, result->WriteAt(1, buffer.data(), buffer_size));
+
+ // The position should remain unchanged afterwards
+ int64_t position;
+ ASSERT_OK(result->Tell(&position));
+ ASSERT_EQ(position, 0);
+}
+
TEST_F(TestMemoryMappedFile, GetSize) {
std::string path = "io-memory-map-get-size";
std::shared_ptr<MemoryMappedFile> result;