Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion src/mathicgb/SparseMatrix.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -498,6 +498,13 @@ SparseMatrix::Scalar SparseMatrix::read(FILE* file) {
const auto rowCount = readOne<uint32>(file);
[[maybe_unused]] const auto colCount = readOne<uint32>(file);
const auto modulus = readOne<uint32>(file);
if (modulus > std::numeric_limits<Scalar>::max()) {
std::ostringstream err;
err << "The matrix file has modulus " << modulus
<< ", which does not fit in the " << 8 * sizeof(Scalar)
<< " bits that this file format stores coefficients in.";
mathic::reportError(err.str());
}
const auto entryCount64 = readOne<uint64>(file);
if (entryCount64 > std::numeric_limits<size_t>::max())
throw std::bad_alloc();
Expand Down Expand Up @@ -545,7 +552,7 @@ SparseMatrix::Scalar SparseMatrix::read(FILE* file) {
}

MATHICGB_ASSERT(mBlock.mPreviousBlock == 0); // still only one block
return modulus;
return static_cast<Scalar>(modulus);
}

void SparseMatrix::writePBM(FILE* file) {
Expand Down
29 changes: 29 additions & 0 deletions src/test/SparseMatrix.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@
#include "mathicgb/PolyRing.hpp"
#include "mathicgb/io-util.hpp"
#include "mathicgb/MathicIO.hpp"
#include "mathicgb/CFile.hpp"
#include <gtest/gtest.h>
#include <cstdio>
#include <memory>
#include <string>

Expand Down Expand Up @@ -88,3 +90,30 @@ TEST(SparseMatrix, toRow) {
mat.rowToPolynomial(2, monomials, p);
ASSERT_EQ(*parsePoly(*ring, "20a3+40a1"), p);
}

TEST(SparseMatrix, ReadRejectsAnOversizedModulus) {
const char* const fileName = "SparseMatrix-modulus-test.tmp";
SparseMatrix mat;
mat.appendEntry(0, 5);
mat.rowDone();

// write() takes a Scalar, so the only way to get an out-of-range modulus
// into a file is to patch the field, which sits after two uint32s.
{
CFile file(fileName, "wb");
mat.write(101, file.handle());
}
{
CFile file(fileName, "r+b");
const uint32 modulus = 65637; // 65536 + 101, so it truncates to 101
ASSERT_EQ(0, std::fseek(file.handle(), 2 * sizeof(uint32), SEEK_SET));
ASSERT_EQ(1, std::fwrite(&modulus, sizeof(modulus), 1, file.handle()));
}

SparseMatrix read;
{
CFile file(fileName, "rb");
ASSERT_THROW(read.read(file.handle()), mathic::MathicException);
}
ASSERT_EQ(0, std::remove(fileName));
}
Loading