Skip to content

Commit 5559b8d

Browse files
committed
- Fixed a wrong protection flag in a test
- Added a routine to check the protection flag before writing - Added a unit test to check the error status for protection mode - Improved failure check for mmap()
1 parent d8939fa commit 5559b8d

File tree

2 files changed

+28
-12
lines changed

2 files changed

+28
-12
lines changed

cpp/src/arrow/ipc/ipc-memory-test.cc

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,6 @@
2626

2727
#include "arrow/ipc/memory.h"
2828
#include "arrow/ipc/test-common.h"
29-
#include "arrow/test-util.h"
30-
#include "arrow/util/buffer.h"
31-
#include "arrow/util/status.h"
3229

3330
namespace arrow {
3431
namespace ipc {
@@ -90,7 +87,7 @@ TEST_F(TestMemoryMappedSource, ReadOnly) {
9087
rwmmap->Close();
9188

9289
std::shared_ptr<MemoryMappedSource> rommap;
93-
ASSERT_OK(MemoryMappedSource::Open(path, MemorySource::READ_WRITE, &rommap));
90+
ASSERT_OK(MemoryMappedSource::Open(path, MemorySource::READ_ONLY, &rommap));
9491

9592
position = 0;
9693
std::shared_ptr<Buffer> out_buffer;
@@ -103,6 +100,21 @@ TEST_F(TestMemoryMappedSource, ReadOnly) {
103100
rommap->Close();
104101
}
105102

103+
TEST_F(TestMemoryMappedSource, InvalidMode) {
104+
const int64_t buffer_size = 1024;
105+
std::vector<uint8_t> buffer(buffer_size);
106+
107+
test::random_bytes(1024, 0, buffer.data());
108+
109+
std::string path = "ipc-invalid-mode-test";
110+
CreateFile(path, buffer_size);
111+
112+
std::shared_ptr<MemoryMappedSource> rommap;
113+
ASSERT_OK(MemoryMappedSource::Open(path, MemorySource::READ_ONLY, &rommap));
114+
115+
ASSERT_RAISES(IOError, rommap->Write(0, buffer.data(), buffer_size));
116+
}
117+
106118
TEST_F(TestMemoryMappedSource, InvalidFile) {
107119
std::string non_existent_path = "invalid-file-name-asfd";
108120

cpp/src/arrow/ipc/memory.cc

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -53,12 +53,11 @@ class MemoryMappedSource::Impl {
5353
Status Open(const std::string& path, MemorySource::AccessMode mode) {
5454
if (is_open_) { return Status::IOError("A file is already open"); }
5555

56-
path_ = path;
57-
int prot_flag = PROT_READ;
56+
prot_flags = PROT_READ;
5857

5958
if (mode == MemorySource::READ_WRITE) {
6059
file_ = fopen(path.c_str(), "r+b");
61-
prot_flag |= PROT_WRITE;
60+
prot_flags |= PROT_WRITE;
6261
} else {
6362
file_ = fopen(path.c_str(), "rb");
6463
}
@@ -75,13 +74,13 @@ class MemoryMappedSource::Impl {
7574
fseek(file_, 0L, SEEK_SET);
7675
is_open_ = true;
7776

78-
data_ = reinterpret_cast<uint8_t*>(
79-
mmap(nullptr, size_, prot_flag, MAP_SHARED, fileno(file_), 0));
80-
if (data_ == nullptr) {
81-
std::stringstream ss;
77+
void* result = mmap(nullptr, size_, prot_flags, MAP_SHARED, fileno(file_), 0);
78+
if (result == MAP_FAILED) {
79+
std::stringstream ss ;
8280
ss << "Memory mapping file failed, errno: " << errno;
8381
return Status::IOError(ss.str());
8482
}
83+
data_ = reinterpret_cast<uint8_t*>(result);
8584

8685
return Status::OK();
8786
}
@@ -90,11 +89,13 @@ class MemoryMappedSource::Impl {
9089

9190
uint8_t* data() { return data_; }
9291

92+
bool writable() { return (prot_flags & PROT_WRITE) == PROT_WRITE; }
93+
9394
private:
94-
std::string path_;
9595
FILE* file_;
9696
int64_t size_;
9797
bool is_open_;
98+
uint8_t prot_flags;
9899

99100
// The memory map
100101
uint8_t* data_;
@@ -135,6 +136,9 @@ Status MemoryMappedSource::ReadAt(
135136
}
136137

137138
Status MemoryMappedSource::Write(int64_t position, const uint8_t* data, int64_t nbytes) {
139+
if (!impl_->writable()) {
140+
return Status::IOError("Unable to write");
141+
}
138142
if (position < 0 || position >= impl_->size()) {
139143
return Status::Invalid("position is out of bounds");
140144
}

0 commit comments

Comments
 (0)