Skip to content

Commit

Permalink
Check write bounds in columnchunk
Browse files Browse the repository at this point in the history
  • Loading branch information
benjaminwinger committed Nov 16, 2023
1 parent 7771bf8 commit feb92bb
Show file tree
Hide file tree
Showing 3 changed files with 16 additions and 6 deletions.
3 changes: 3 additions & 0 deletions src/include/storage/file_handle.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include <memory>
#include <shared_mutex>

#include "common/assert.h"
#include "common/constants.h"
#include "common/file_utils.h"
#include "common/types/types.h"
Expand Down Expand Up @@ -32,10 +33,12 @@ class FileHandle {
common::page_idx_t addNewPages(common::page_idx_t numPages);

inline void readPage(uint8_t* frame, common::page_idx_t pageIdx) const {
KU_ASSERT(pageIdx < numPages);
common::FileUtils::readFromFile(
fileInfo.get(), frame, getPageSize(), pageIdx * getPageSize());
}
inline void writePage(uint8_t* buffer, common::page_idx_t pageIdx) const {
KU_ASSERT(pageIdx < numPages);
common::FileUtils::writeToFile(
fileInfo.get(), buffer, getPageSize(), pageIdx * getPageSize());
}
Expand Down
8 changes: 6 additions & 2 deletions src/storage/store/column_chunk.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ namespace storage {

ColumnChunkMetadata fixedSizedFlushBuffer(const uint8_t* buffer, uint64_t bufferSize,
BMFileHandle* dataFH, page_idx_t startPageIdx, const ColumnChunkMetadata& metadata) {
KU_ASSERT(dataFH->getNumPages() >= startPageIdx + metadata.numPages);
FileUtils::writeToFile(dataFH->getFileInfo(), buffer, bufferSize,
startPageIdx * BufferPoolConstants::PAGE_4KB_SIZE);
return ColumnChunkMetadata(
Expand Down Expand Up @@ -49,7 +50,8 @@ class CompressedFlushBuffer {
auto numPages = 0;
auto numValuesPerPage =
metadata.compMeta.numValues(BufferPoolConstants::PAGE_4KB_SIZE, dataType);
do {
KU_ASSERT(numValuesPerPage * metadata.numPages >= metadata.numValues);
while (valuesRemaining > 0) {
auto compressedSize = alg->compressNextPage(bufferStart, valuesRemaining,
compressedBuffer.get(), BufferPoolConstants::PAGE_4KB_SIZE, metadata.compMeta);
// Avoid underflows (when data is compressed to nothing, numValuesPerPage may be
Expand All @@ -63,10 +65,12 @@ class CompressedFlushBuffer {
memset(compressedBuffer.get() + compressedSize, 0,
BufferPoolConstants::PAGE_4KB_SIZE - compressedSize);
}
KU_ASSERT(numPages < metadata.numPages);
KU_ASSERT(dataFH->getNumPages() > startPageIdx + numPages);
FileUtils::writeToFile(dataFH->getFileInfo(), compressedBuffer.get(), compressedSize,
(startPageIdx + numPages) * BufferPoolConstants::PAGE_4KB_SIZE);
numPages++;
} while (valuesRemaining > 0);
}
// Make sure that the file is the right length
if (numPages < metadata.numPages) {
memset(compressedBuffer.get(), 0, BufferPoolConstants::PAGE_4KB_SIZE);
Expand Down
11 changes: 7 additions & 4 deletions test/main/access_mode_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,17 @@ using namespace kuzu::main;

class AccessModeTest : public ApiTest {};

void assertQuery(QueryResult& result) {
ASSERT_TRUE(result.isSuccess()) << result.toString();
}

TEST_F(AccessModeTest, testAccessMode) {
systemConfig->readOnly = false;
auto db = std::make_unique<Database>(databasePath, *systemConfig);
auto con = std::make_unique<Connection>(db.get());
ASSERT_TRUE(con->query("CREATE NODE TABLE Person(name STRING, age INT64, PRIMARY KEY(name))")
->isSuccess());
ASSERT_TRUE(con->query("CREATE (:Person {name: 'Alice', age: 25})")->isSuccess());
ASSERT_TRUE(con->query("MATCH (:Person) RETURN COUNT(*)")->isSuccess());
assertQuery(*con->query("CREATE NODE TABLE Person(name STRING, age INT64, PRIMARY KEY(name))"));
assertQuery(*con->query("CREATE (:Person {name: 'Alice', age: 25})"));
assertQuery(*con->query("MATCH (:Person) RETURN COUNT(*)"));
db.reset();
systemConfig->readOnly = true;
std::unique_ptr<Database> db2;
Expand Down

0 comments on commit feb92bb

Please sign in to comment.