Skip to content
Open
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
22 changes: 6 additions & 16 deletions 09-fuzz/json-basalaev-ershov/fuzz_me.cc
Original file line number Diff line number Diff line change
Expand Up @@ -17,27 +17,17 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
return 0;
}

// generated fuzzed data write into file
const std::string inputFileName = "fuzzed_data.bin";
std::ofstream outFile(inputFileName, std::ios::out | std::ios::binary);
outFile.write((char*)data, size);
outFile.close();
std::vector<uint8_t> dataVector(data, data + size);

// calling covertBinaryToJson
TaskAux inputTask = getTaskType(inputFileName);
covertBinaryToJson(inputTask); // result will be writen into fuzzed_data.json
TaskAux inputTask = getTaskType(&dataVector, nullptr, TaskAux::Type::BinaryToJson);
std::string binToJson = covertBinaryToJson(inputTask); // result will be writen into fuzzed_data.json

// calling convertJsonToBinary
const std::string outputFileName = "fuzzed_data.json";
TaskAux outputTask = getTaskType(outputFileName);
convertJsonToBinary(outputTask);
TaskAux outputTask = getTaskType(nullptr, &binToJson, TaskAux::Type::JsonToBinary);
std::vector<uint8_t> jsonToBin = convertJsonToBinary(outputTask);

// Compare the buffer with original data
std::ifstream inFile(inputFileName, std::ios::in | std::ios::binary);
std::vector<uint8_t> buffer(std::istreambuf_iterator<char>(inFile), {});
bool isSame = (memcmp(data, buffer.data(), size) == 0);
if(isSame) {
inFile.close();
if (dataVector == jsonToBin) {
return 0;
} else {
assert(false);
Expand Down
136 changes: 47 additions & 89 deletions 09-fuzz/json-basalaev-ershov/json-basalaev.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,137 +31,95 @@ struct TaskAux {
Unknown = 3,
};

const std::string inputFilename;
const std::string outputFilename;
std::vector<uint8_t> inputData;
std::vector<uint8_t> outputData;
Type type;
};

std::vector<Student> readBinaryStudents(const TaskAux& taskAux) {
auto in = fopen(taskAux.inputFilename.c_str(), "r");
//std::cout << "Reading binary students data from "
// << taskAux.inputFilename << std::endl;

Student student;
std::vector<Student> result;

while(fread(&student, sizeof(Student), 1, in)) {
result.emplace_back(student);
}

//std::cout << result.size() << " students read..." << std::endl;

fclose(in); // fix

return result;
std::vector<Student> readBinaryStudents(const std::vector<uint8_t>& data) {
size_t numStudents = data.size() / sizeof(Student);
const Student* studentsPtr = reinterpret_cast<const Student*>(data.data());
return std::vector<Student>(studentsPtr, studentsPtr + numStudents);
}

void writeStudentsIntoJson(const std::vector<Student>& students, const TaskAux& taskAux) {
std::ofstream out(taskAux.outputFilename);

auto wrapStr = [](const std::string& field, const std::string& str, std::ofstream& out) {
out << "\"" << field << "\": " << "\"" << str << "\",\n";
};

std::string writeStudentsIntoJson(const std::vector<Student>& students) {
json result;
for (auto i = 0; i < students.size(); ++i) {
for (const auto& student : students) {
json currentStudent;
currentStudent["name"] = student.name;
currentStudent["login"] = student.login;
currentStudent["group"] = student.group;

currentStudent["name"] = students[i].name;
currentStudent["login"] = students[i].login;
currentStudent["group"] = students[i].group;

for (auto j = 0; j < students[i].practiceSize; j++) {
currentStudent["practice"].push_back(std::to_string(students[i].practice[j]));
for (auto j = 0; j < student.practiceSize; j++) {
currentStudent["practice"].push_back(std::to_string(student.practice[j]));
}

currentStudent["project"] = {{"repo", students[i].project.repo}, {"mark", static_cast<uint32_t>(students[i].project.mark)}};
currentStudent["mark"] = students[i].mark;
currentStudent["project"] = {{"repo", student.project.repo}, {"mark", static_cast<uint32_t>(student.project.mark)}};
currentStudent["mark"] = student.mark;

result.push_back(currentStudent);
}

out << result;

//std::cout << "Written to " << taskAux.outputFilename;
}

void covertBinaryToJson(const TaskAux& taskAux) {
auto students = readBinaryStudents(taskAux);
writeStudentsIntoJson(students, taskAux);
return result.dump();
}

void parseString(const std::string& str, char out[]) {
memcpy(out, str.c_str(), str.size());
std::string covertBinaryToJson(const TaskAux& taskAux) {
auto students = readBinaryStudents(taskAux.inputData);
return writeStudentsIntoJson(students);
}

std::vector<Student> readJsonStudents(const TaskAux& taskAux) {
//std::cout << "Reading json students data from "
// << taskAux.inputFilename << std::endl;

std::ifstream in(taskAux.inputFilename);
json j = json::parse(in);

std::vector<Student> readJsonStudents(const std::string& jsonString) {
std::vector<Student> result;
Student student{};

auto j = json::parse(jsonString);
for (const auto& jsonStudent : j) {
parseString(jsonStudent["name"].get<std::string>(), student.name);
parseString(jsonStudent["login"].get<std::string>(), student.login);
parseString(jsonStudent["group"].get<std::string>(), student.group);
parseString(jsonStudent["project"]["repo"].get<std::string>(), student.project.repo);
Student student;
strncpy(student.name, jsonStudent["name"].get<std::string>().c_str(), sizeof(student.name));
strncpy(student.login, jsonStudent["login"].get<std::string>().c_str(), sizeof(student.login));
strncpy(student.group, jsonStudent["group"].get<std::string>().c_str(), sizeof(student.group));
for (int i = 0; i < student.practiceSize; ++i) {
student.practice[i] = std::stoi(jsonStudent["practice"][i].get<std::string>());
}
strncpy(student.project.repo, jsonStudent["project"]["repo"].get<std::string>().c_str(), sizeof(student.project.repo));
student.project.mark = jsonStudent["project"]["mark"].get<uint8_t>();
student.mark = jsonStudent["mark"].get<float>();
for (auto i = 0; i < jsonStudent["practice"].size(); ++i) {
if (jsonStudent["practice"][i].get<std::string>() == "0")
student.practice[i] = 0;
else
student.practice[i] = 1;
}
result.push_back(student);
student = Student{};
}

//std::cout << result.size() << " students read..." << std::endl;
return result;
}

void writeStudentsIntoBin(const std::vector<Student>& students, const TaskAux& taskAux) {
auto out = fopen(taskAux.outputFilename.c_str(), "w");
std::vector<uint8_t> writeStudentsIntoBin(const std::vector<Student>& students) {
std::vector<uint8_t> result;
for (const auto& student : students) {
fwrite(&student, sizeof(Student), 1, out);
const uint8_t* ptr = reinterpret_cast<const uint8_t*>(&student);
result.insert(result.end(), ptr, ptr + sizeof(Student));
}
fclose(out); // fix

//std::cout << "Written to " << taskAux.outputFilename;
return result;
}

void convertJsonToBinary(const TaskAux& taskAux) {
auto students = readJsonStudents(taskAux);
writeStudentsIntoBin(students, taskAux);
std::vector<uint8_t> convertJsonToBinary(const TaskAux& taskAux) {
std::string jsonString(taskAux.inputData.begin(), taskAux.inputData.end());
auto students = readJsonStudents(jsonString);
return writeStudentsIntoBin(students);
}

TaskAux getTaskType(const std::string& filename) {
auto idx = filename.find_last_of(".");
auto name = filename.substr(0, idx);
auto type = filename.substr(idx + 1);

if (type == "bin") {
TaskAux getTaskType(std::vector<uint8_t>* binData, std::string* jsonData, TaskAux::Type type) {
if (type == TaskAux::Type::BinaryToJson) {
return TaskAux{
.inputFilename = filename,
.outputFilename = name + ".json",
.inputData = *binData,
.outputData = {},
.type = TaskAux::Type::BinaryToJson
};
} else if (type == "json") {
std::vector<uint8_t> vec(jsonData->begin(), jsonData->end());
return TaskAux{
.inputFilename = filename,
.outputFilename = name + ".bin",
.inputData = vec,
.outputData = {},
.type = TaskAux::Type::JsonToBinary
};
}

return TaskAux{
.inputFilename = {},
.outputFilename = {},
.inputData = {},
.outputData = {},
.type = TaskAux::Type::Unknown
};
}
20 changes: 11 additions & 9 deletions 09-fuzz/json-basalaev-ershov/precheck.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,12 @@ class MyException: public std::exception {
}
};

class NullBuffer : public std::streambuf
{
public:
int overflow(int c) { return c; }
};

struct StudentCheck {
char name[32];
char login[16];
Expand All @@ -53,19 +59,15 @@ void fail(const char* where) {
throw MyException(std::string(where));
}

void isConvertibleToJson(const char* str, size_t size, const char* where) {
void isConvertibleToJson(const char* str, const char* where) {
try {
char tmpBuffer[64];
tmpnam(tmpBuffer);
std::string tmpFileName(tmpBuffer);
std::ofstream out(tmpFileName);
NullBuffer null_buffer;
std::ostream null_stream(&null_buffer);

json tmp;
tmp["tmp"] = str;

out << tmp;

std::remove(tmpFileName.c_str());
null_stream << tmp;
} catch (...) {
fail(where);
}
Expand All @@ -89,7 +91,7 @@ void check_str(const char* str, int len, const char* name) {
fail(name);
if (str[i] != 0)
fail(name);
isConvertibleToJson(str, len, name);
isConvertibleToJson(str, name);
}

bool checkStudent(StudentCheck& student) {
Expand Down