diff --git a/09-fuzz/json-basalaev-ershov/fuzz_me.cc b/09-fuzz/json-basalaev-ershov/fuzz_me.cc index 26cecf31..92b5a4c2 100644 --- a/09-fuzz/json-basalaev-ershov/fuzz_me.cc +++ b/09-fuzz/json-basalaev-ershov/fuzz_me.cc @@ -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 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 jsonToBin = convertJsonToBinary(outputTask); - // Compare the buffer with original data - std::ifstream inFile(inputFileName, std::ios::in | std::ios::binary); - std::vector buffer(std::istreambuf_iterator(inFile), {}); - bool isSame = (memcmp(data, buffer.data(), size) == 0); - if(isSame) { - inFile.close(); + if (dataVector == jsonToBin) { return 0; } else { assert(false); diff --git a/09-fuzz/json-basalaev-ershov/json-basalaev.h b/09-fuzz/json-basalaev-ershov/json-basalaev.h index 7e600968..401b33c3 100644 --- a/09-fuzz/json-basalaev-ershov/json-basalaev.h +++ b/09-fuzz/json-basalaev-ershov/json-basalaev.h @@ -31,137 +31,95 @@ struct TaskAux { Unknown = 3, }; - const std::string inputFilename; - const std::string outputFilename; + std::vector inputData; + std::vector outputData; Type type; }; -std::vector 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 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 readBinaryStudents(const std::vector& data) { + size_t numStudents = data.size() / sizeof(Student); + const Student* studentsPtr = reinterpret_cast(data.data()); + return std::vector(studentsPtr, studentsPtr + numStudents); } -void writeStudentsIntoJson(const std::vector& 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& 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(students[i].project.mark)}}; - currentStudent["mark"] = students[i].mark; + currentStudent["project"] = {{"repo", student.project.repo}, {"mark", static_cast(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 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 readJsonStudents(const std::string& jsonString) { std::vector result; - Student student{}; - + auto j = json::parse(jsonString); for (const auto& jsonStudent : j) { - parseString(jsonStudent["name"].get(), student.name); - parseString(jsonStudent["login"].get(), student.login); - parseString(jsonStudent["group"].get(), student.group); - parseString(jsonStudent["project"]["repo"].get(), student.project.repo); + Student student; + strncpy(student.name, jsonStudent["name"].get().c_str(), sizeof(student.name)); + strncpy(student.login, jsonStudent["login"].get().c_str(), sizeof(student.login)); + strncpy(student.group, jsonStudent["group"].get().c_str(), sizeof(student.group)); + for (int i = 0; i < student.practiceSize; ++i) { + student.practice[i] = std::stoi(jsonStudent["practice"][i].get()); + } + strncpy(student.project.repo, jsonStudent["project"]["repo"].get().c_str(), sizeof(student.project.repo)); student.project.mark = jsonStudent["project"]["mark"].get(); student.mark = jsonStudent["mark"].get(); - for (auto i = 0; i < jsonStudent["practice"].size(); ++i) { - if (jsonStudent["practice"][i].get() == "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& students, const TaskAux& taskAux) { - auto out = fopen(taskAux.outputFilename.c_str(), "w"); +std::vector writeStudentsIntoBin(const std::vector& students) { + std::vector result; for (const auto& student : students) { - fwrite(&student, sizeof(Student), 1, out); + const uint8_t* ptr = reinterpret_cast(&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 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* 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 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 }; } diff --git a/09-fuzz/json-basalaev-ershov/precheck.h b/09-fuzz/json-basalaev-ershov/precheck.h index 0e9bbab7..e1cf9da5 100644 --- a/09-fuzz/json-basalaev-ershov/precheck.h +++ b/09-fuzz/json-basalaev-ershov/precheck.h @@ -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]; @@ -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); } @@ -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) {