diff --git a/Lab_10/studentCourseEvaluation.cpp b/Lab_10/studentCourseEvaluation.cpp index 95843c5..ce74fcb 100644 --- a/Lab_10/studentCourseEvaluation.cpp +++ b/Lab_10/studentCourseEvaluation.cpp @@ -4,181 +4,186 @@ using namespace std; // creating a class named "Student" -class Student +void TakeData() { -private: - string student_id; - string student_name; - double OOP2_Score; - double math_Score; - double english_Score; - double total_Score; - double ctotal() - { - total_Score = OOP2_Score + math_Score + english_Score; - return total_Score; - } - -public: - void TakeData() - { - cout << "ID : "; - cin >> student_id; - cout << "Name: "; - cin >> student_name; - cout << "OOP2: "; - cin >> OOP2_Score; - cout << "Math: "; - cin >> math_Score; - cout << "English: "; - cin >> english_Score; - ctotal(); - } - void showData() - { - - cout << "ID: " << student_id << endl; - cout << "Name: " << student_name << endl; - cout << "OOP2: " << OOP2_Score << endl; - cout << "Math: " << math_Score << endl; - cout << "English: " << english_Score << endl; - cout << "Total score: " << total_Score << endl; - } -}; + // PRECOGS_FIX: perform robust input validation and allow spaces in name using getline + #include + + cout << "ID : "; + if (!(cin >> student_id)) { + cin.clear(); + string tmp; + getline(cin, tmp); + cout << "Invalid ID input. Aborting input." << endl; + return; + } + + // consume the trailing newline before using getline for full name + cin.ignore(std::numeric_limits::max(), '\n'); + cout << "Name: "; + if (!std::getline(cin, student_name) || student_name.empty()) { + cout << "Invalid name input. Aborting input." << endl; + return; + } + + auto readValidatedDouble = [&](const string &prompt, double &out, double minVal = 0.0, double maxVal = 1000.0) { + while (true) { + cout << prompt; + if (cin >> out) { + if (out >= minVal && out <= maxVal) { + break; + } + cout << "Value out of accepted range (" << minVal << " - " << maxVal << "). Try again." << endl; + } else { + // PRECOGS_FIX: clear stream and discard invalid token before retry + cin.clear(); + string discard; + getline(cin, discard); + cout << "Invalid numeric input. Try again." << endl; + } + } + }; + + readValidatedDouble("OOP2: ", OOP2_Score, 0.0, 100.0); + readValidatedDouble("Math: ", math_Score, 0.0, 100.0); + readValidatedDouble("English: ", english_Score, 0.0, 100.0); + + ctotal(); +} // creating a class named "Employee" -class Employee +double total_salary() { -private: - string Employee_ID; - string Employee_Name; - int Hours; - int Rate; - -public: - void setEmployee_ID(string x) - { - Employee_ID = x; - } - string getEmployee_ID() - { - return Employee_ID; - } - void setEmployee_Name(string y) - { - Employee_Name = y; - } - string getEmployee_Name() - { - return Employee_Name; - } - void setHours(int z) - { - Hours = z; - } - int getHours() - { - return Hours; - } - void setRate(int i) - { - Rate = i; - } - int getRate() - { - return Rate; - } - double total_salary() - { - int total; - total = Hours * Rate; - return total; - } -}; + // PRECOGS_FIX: validate inputs and perform multiplication in 64-bit to avoid 32-bit overflow + #include + + long long h = static_cast(Hours); + long long r = static_cast(Rate); + + // Basic validation: no negative hours/rate allowed for salary computation + if (h < 0 || r < 0) { + return 0.0; + } + + const long long maxAllowed = std::numeric_limits::max(); + if (r != 0 && h > maxAllowed / r) { + // Overflow would occur. Cap at max representable or handle as error. + return static_cast(maxAllowed); + } + + long long total = h * r; + return static_cast(total); +} int main() { - int choice; - cout << "1. Student" << endl; - cout << "2. Employee" << endl; - cout << "Your choice: "; - cin >> choice; - cout << endl; - - Student student; // creating an object of a class "Student" - Employee employee; // creating an object of a class "Employee" - switch (choice) - { - case 1: - { - student.TakeData(); - cout << endl; - student.showData(); - } - break; - case 2: - { - while (true) - { - system("cls"); - int choice_employee; - - cout << "1. Input Employee Details\n"; - cout << "2. Display Employee Details\n"; - cout << "3. Display Salary\n"; - cin >> choice_employee; - switch (choice_employee) - { - case 1: - { - string x, y; - int z, i; - system("cls"); - cout << "\t\t\tEmployee information\n"; - cout << "Employee_ID: "; - cin >> x; - cout << "Employee_Name: "; - cin >> y; - cout << "Number of worked Hours: "; - cin >> z; - cout << "Rate per Hour: "; - cin >> i; - cout << endl; - employee.setEmployee_ID(x); - employee.setEmployee_Name(y); - employee.setHours(z); - employee.setRate(i); - system("pause"); - } - break; - case 2: - { - system("cls"); - cout << "ID: " << employee.getEmployee_ID() << endl; - cout << "Name: " << employee.getEmployee_Name() << endl; - cout << "Hours: " << employee.getHours() << endl; - cout << "Rate: " << employee.getRate() << endl; - system("pause"); - } - break; - case 3: - { - system("cls"); - cout << "Total salary: " << employee.total_salary() << endl; - system("pause"); - } - break; - default: - cout << "Incorrect input! Try again!" << endl; - break; - } - } - } - break; - default: - cout << "Incorrect input! Try again!" << endl; - break; - } - system("pause"); - return 0; + // PRECOGS_FIX: remove unsafe system() use and replace with portable/controlled clear and pause behavior + #include + + auto clearScreen = []() { + // Best-effort portable clear: print several newlines instead of calling system("cls")/system("clear") + for (int i = 0; i < 50; ++i) std::cout << '\n'; + }; + + auto pausePrompt = []() { + std::cout << "Press Enter to continue..." << std::endl; + std::cin.ignore(std::numeric_limits::max(), '\n'); + std::cin.get(); + }; + + int choice; + std::cout << "1. Student" << std::endl; + std::cout << "2. Employee" << std::endl; + std::cout << "Your choice: "; + if (!(std::cin >> choice)) { + std::cerr << "Invalid input. Exiting." << std::endl; + return 1; + } + std::cout << std::endl; + + Student student; // creating an object of a class "Student" + Employee employee; // creating an object of a class "Employee" + switch (choice) + { + case 1: + { + student.TakeData(); + std::cout << std::endl; + student.showData(); + } + break; + case 2: + { + while (true) + { + clearScreen(); // PRECOGS_FIX: avoid system("cls") to reduce execution of shell commands + int choice_employee; + + std::cout << "1. Input Employee Details\n"; + std::cout << "2. Display Employee Details\n"; + std::cout << "3. Display Salary\n"; + if (!(std::cin >> choice_employee)) { + std::cin.clear(); + std::string discard; + std::getline(std::cin, discard); + std::cout << "Invalid selection. Try again." << std::endl; + pausePrompt(); // PRECOGS_FIX: replace system("pause") with controlled prompt + continue; + } + switch (choice_employee) + { + case 1: + { + std::string x, y; + int z, i; + clearScreen(); + std::cout << "\t\t\tEmployee information\n"; + std::cout << "Employee_ID: "; + if (!(std::cin >> x)) { std::cin.clear(); std::getline(std::cin, x); } + std::cin.ignore(std::numeric_limits::max(), '\n'); + std::cout << "Employee_Name: "; + std::getline(std::cin, y); + std::cout << "Number of worked Hours: "; + while (!(std::cin >> z)) { std::cin.clear(); std::string discard; std::getline(std::cin, discard); std::cout << "Invalid hours. Enter integer: "; } + std::cout << "Rate per Hour: "; + while (!(std::cin >> i)) { std::cin.clear(); std::string discard; std::getline(std::cin, discard); std::cout << "Invalid rate. Enter integer: "; } + std::cout << std::endl; + employee.setEmployee_ID(x); + employee.setEmployee_Name(y); + employee.setHours(z); + employee.setRate(i); + pausePrompt(); + } + break; + case 2: + { + clearScreen(); + std::cout << "ID: " << employee.getEmployee_ID() << std::endl; + std::cout << "Name: " << employee.getEmployee_Name() << std::endl; + std::cout << "Hours: " << employee.getHours() << std::endl; + std::cout << "Rate: " << employee.getRate() << std::endl; + pausePrompt(); + } + break; + case 3: + { + clearScreen(); + std::cout << "Total salary: " << employee.total_salary() << std::endl; + pausePrompt(); + } + break; + default: + std::cout << "Incorrect input! Try again!" << std::endl; + pausePrompt(); + break; + } + } + } + break; + default: + std::cout << "Incorrect input! Try again!" << std::endl; + break; + } + pausePrompt(); + return 0; } diff --git a/Lab_16/Source.cpp b/Lab_16/Source.cpp index 8f98917..d74eddd 100644 --- a/Lab_16/Source.cpp +++ b/Lab_16/Source.cpp @@ -57,35 +57,34 @@ class Staff } }; -class Teacher : public Staff +void getdata() { -protected: - string subject; - int publications; - -public: - Teacher() - { - subject = "Unknown"; - publications = 0; - } - void getdata() - { - Staff::getdata_code(); - Staff::getdata_name(); - cout << " Enter subject: "; - cin >> subject; - cout << " Enter number of publications: "; - cin >> publications; - } - void showdata() - { - Staff::showdata_code(); - Staff::showdata_name(); - cout << " Subject: " << subject << endl - << " Publications: " << publications << endl; - } -}; + Staff::getdata_code(); + Staff::getdata_name(); + + std::cout << " Enter subject: "; + std::string tmp_subj; + std::getline(std::cin >> std::ws, tmp_subj); + const size_t MAX_SUBJECT_LEN = 100; + if (tmp_subj.size() > MAX_SUBJECT_LEN) tmp_subj = tmp_subj.substr(0, MAX_SUBJECT_LEN); + subject = tmp_subj; + + // Validate integer input for publications + while (true) + { + std::cout << " Enter number of publications: "; + std::string line; + std::getline(std::cin, line); + std::stringstream ss(line); + int val; + if (ss >> val && ss.eof() && val >= 0) + { + publications = val; // PRECOGS_FIX: validated numeric parse, rejects non-numeric or negative inputs + break; + } + std::cout << " Invalid number, please enter a non-negative integer.\n"; + } +} class Officer : public Staff { @@ -253,81 +252,107 @@ class Admin : virtual public Person } }; -class Master : public Account, public Admin +void update() { -public: - void create() - { - getdetails(); - getpay(); - getexpr(); - } - - void display() - { - showdetails(); - showpay(); - showexpr(); - } - - void update() - { - for (int i = 0; i < 1000; i++) - { - system("cls"); - cout << "\t U P D A T E D E T A I L S\n"; - cout << "=========================================\n"; - cout << " Choose detail you want to update\n"; - cout << " 1. NAME\n"; - cout << " 2. CODE\n"; - cout << " 3. EXPERIENCE\n"; - cout << " 4. PAY\n"; - cout << " 0. Back\n"; - cout << " Your choice: "; - - switch (_getch()) - { - case 49: - cout << "\n\n Enter name: "; - cin >> name; - cout << " Successfully Updated!\n"; - Sleep(0700); - Sleep(0700); - break; - case 50: - cout << "\n\n Enter code: "; - cin >> code; - cout << " Successfully Updated!\n"; - Sleep(0700); - Sleep(0700); - break; - case 51: - cout << "\n\n Enter Expereince: "; - cin >> experience; - cout << " Successfully Updated!\n"; - Sleep(0700); - Sleep(0700); - break; - case 52: - cout << "\n\n Enter pay: "; - cin >> pay; - cout << " Successfully Updated!\n"; - Sleep(0700); - Sleep(0700); - break; - case 48: - i = 1000; - break; - default: - cout << endl - << endl; - cout << "\t\t Your choice is not abailable in Menu. \n\t\t Please try one more time.\n"; - Sleep(0700); - Sleep(0700); - } // switch - } - } // for loop -}; + for (int i = 0; i < 1000; i++) + { + // Replace system("cls") with platform-independent console-clearing simulation + for (int _i = 0; _i < 50; ++_i) std::cout << "\n"; // PRECOGS_FIX: avoid system() call by printing newlines to simulate clear + + std::cout << "\t U P D A T E D E T A I L S\n"; + std::cout << "=========================================\n"; + std::cout << " Choose detail you want to update\n"; + std::cout << " 1. NAME\n"; + std::cout << " 2. CODE\n"; + std::cout << " 3. EXPERIENCE\n"; + std::cout << " 4. PAY\n"; + std::cout << " 0. Back\n"; + std::cout << " Your choice: "; + + switch (_getch()) + { + case 49: + { + std::cout << "\n\n Enter name: "; + std::string tmp; + std::getline(std::cin >> std::ws, tmp); + const size_t MAX_NAME_LEN = 100; + if (tmp.size() > MAX_NAME_LEN) tmp = tmp.substr(0, MAX_NAME_LEN); + name = tmp; + std::cout << " Successfully Updated!\n"; + Sleep(0700); + Sleep(0700); + } + break; + case 50: + { + std::cout << "\n\n Enter code: "; + std::string tmp; + std::getline(std::cin >> std::ws, tmp); + const size_t MAX_CODE_LEN = 50; + if (tmp.size() > MAX_CODE_LEN) tmp = tmp.substr(0, MAX_CODE_LEN); + code = tmp; + std::cout << " Successfully Updated!\n"; + Sleep(0700); + Sleep(0700); + } + break; + case 51: + { + std::cout << "\n\n Enter Experience: "; + // validate integer + while (true) + { + std::string line; + std::getline(std::cin >> std::ws, line); + std::stringstream ss(line); + int val; + if (ss >> val && ss.eof() && val >= 0) + { + experience = val; // PRECOGS_FIX: validated numeric input for experience + break; + } + std::cout << " Invalid value. Enter a non-negative integer for experience: "; + } + std::cout << " Successfully Updated!\n"; + Sleep(0700); + Sleep(0700); + } + break; + case 52: + { + std::cout << "\n\n Enter pay: "; + // validate float + while (true) + { + std::string line; + std::getline(std::cin >> std::ws, line); + std::stringstream ss(line); + float val; + if (ss >> val && ss.eof() && val >= 0.0f) + { + pay = val; // PRECOGS_FIX: validated numeric input for pay + break; + } + std::cout << " Invalid value. Enter a non-negative numeric pay amount: "; + } + std::cout << " Successfully Updated!\n"; + Sleep(0700); + Sleep(0700); + } + break; + case 48: + i = 1000; + break; + default: + std::cout << std::endl + << std::endl; + std::cout << "\t\t Your choice is not abailable in Menu. \n\t\t Please try one more time.\n"; + Sleep(0700); + Sleep(0700); + } // switch + } +} int main() { @@ -386,9 +411,29 @@ void F_First_Program_Menu() Regular_Typist regular; Casual_Typist casual; + // Local helpers to avoid use of system() (use Win32 console APIs / direct input instead) + auto safeClear = []() { + HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE); + if (hConsole == INVALID_HANDLE_VALUE) return; + CONSOLE_SCREEN_BUFFER_INFO csbi; + DWORD count; + if (!GetConsoleScreenBufferInfo(hConsole, &csbi)) return; + DWORD cellCount = csbi.dwSize.X * csbi.dwSize.Y; + COORD homeCoords = {0, 0}; + FillConsoleOutputCharacterA(hConsole, ' ', cellCount, homeCoords, &count); + FillConsoleOutputAttribute(hConsole, csbi.wAttributes, cellCount, homeCoords, &count); + SetConsoleCursorPosition(hConsole, homeCoords); + }; + auto safePause = []() { + std::cout << "\nPress any key to continue..."; + // PRECOGS_FIX: replace system("pause") with direct keyboard read to avoid shell invocation + _getch(); + std::cout << "\n"; + }; + for (int k = 0; k < 1000; k++) { - system("cls"); + safeClear(); // PRECOGS_FIX: replace system("cls") with safeClear() to avoid shell invocation cout << "\tM A I N M E N U\n"; cout << " =====================\n"; cout << " 1. TEACHER\n"; @@ -400,7 +445,7 @@ void F_First_Program_Menu() { case '1': { - system("cls"); + safeClear(); cout << "\t T E A C H E R\n"; cout << "===================================\n"; teacher.getdata(); @@ -409,13 +454,13 @@ void F_First_Program_Menu() teacher.showdata(); cout << endl << endl; - system("pause"); + safePause(); } break; case '2': { - system("cls"); + safeClear(); cout << "\t O F F I C E R\n"; cout << "===================================\n"; officer.getdata(); @@ -424,7 +469,7 @@ void F_First_Program_Menu() officer.showdata(); cout << endl << endl; - system("pause"); + safePause(); } break; @@ -432,7 +477,7 @@ void F_First_Program_Menu() { for (int l = 0; l < 1000; l++) { - system("cls"); + safeClear(); cout << "\t T Y P I S T\n"; cout << "===================================\n"; cout << " 1. Regular typist\n"; @@ -443,7 +488,7 @@ void F_First_Program_Menu() { case '1': { - system("cls"); + safeClear(); cout << "\t R E G U L A R T Y P I S T\n"; cout << "===================================\n"; regular.getdata(); @@ -452,13 +497,13 @@ void F_First_Program_Menu() regular.showdata(); cout << endl << endl; - system("pause"); + safePause(); } break; case '2': { - system("cls"); + safeClear(); cout << "\t C A S U A L T Y P I S T\n"; cout << "===================================\n"; casual.getdata(); @@ -467,12 +512,12 @@ void F_First_Program_Menu() casual.showdata(); cout << endl << endl; - system("pause"); + safePause(); } break; case '0': { - system("cls"); + safeClear(); l = 1000; } break; @@ -481,17 +526,17 @@ void F_First_Program_Menu() cout << endl << endl; cout << "\t\t Your choice is not abailable in Menu. \n\t\t Please try one more time.\n"; - Sleep(0700); - Sleep(0700); + Sleep(700); + Sleep(700); } break; } // switch - } // for + } // for } break; case '0': { - system("cls"); + safeClear(); k = 1000; } break; @@ -500,12 +545,12 @@ void F_First_Program_Menu() cout << endl << endl; cout << "\t\t Your choice is not abailable in Menu. \n\t\t Please try one more time.\n"; - Sleep(0700); - Sleep(0700); + Sleep(700); + Sleep(700); } break; } // switch - } // for loop + } // for loop } void F_Second_Program_Menu() diff --git a/Lab_17/Education.cpp b/Lab_17/Education.cpp index 1f692b3..3f6922d 100644 --- a/Lab_17/Education.cpp +++ b/Lab_17/Education.cpp @@ -68,30 +68,39 @@ class Staff { } }; -class Teacher : public Staff, public Education { -protected: - string subject; - int publications; -public: +void Teacher::getdata() { + Staff::getdata_code(); + Staff::getdata_name(); + Education::getdata(); - Teacher() { - subject = "Unknown"; - publications = 0; - } - void getdata() { - Staff::getdata_code(); - Staff::getdata_name(); - Education::getdata(); - cout << "Enter subject: " ; cin >> subject; - cout << "Enter number of publications: " ; cin >> publications; - } - void showdata() { - Staff::showdata_code(); - Staff::showdata_name(); - Education::showdata(); - cout << "Subject: " << subject << endl << "Publications: " << publications << endl; - } -}; + // Read subject allowing spaces and validate length + std::string line; + while (true) { + std::cout << "Enter subject: "; + if (!std::getline(std::cin, line)) { std::cin.clear(); continue; } + if (!line.empty() && line.size() <= 256) { // PRECOGS_FIX: use getline to capture multi-word subject and bound length + subject = line; + break; + } + std::cout << "Invalid subject. Try again.\n"; + } + + // Read number of publications robustly + while (true) { + std::cout << "Enter number of publications: "; + if (!std::getline(std::cin, line)) { std::cin.clear(); continue; } + try { + long val = std::stol(line); + if (val >= 0 && val <= 1000000) { + publications = static_cast(val); // PRECOGS_FIX: validated numeric parse and range + break; + } + } catch (const std::exception &) { + // continue + } + std::cout << "Invalid number. Please enter a non-negative integer.\n"; + } +} class Officer : public Staff, public Education { protected: @@ -175,99 +184,111 @@ int main() { return 0; } void F_First_Program_Menu() { - // objects - Teacher teacher; - Officer officer; - Regular_Typist regular; - Casual_Typist casual; + // objects + Teacher teacher; + Officer officer; + Regular_Typist regular; + Casual_Typist casual; + + auto clear_screen = []() { + // PRECOGS_FIX: avoid system("cls"); simulate clear in a portable manner + std::cout << std::string(50, '\n'); + }; + + auto pause_console = []() { + // PRECOGS_FIX: avoid system("pause"); use a simple Enter-wait + std::cout << "Press Enter to continue..." << std::endl; + std::string _tmp; + std::getline(std::cin, _tmp); + }; - for (int k = 0; k < 1000; k++) { - system("cls"); - cout << "\tM A I N M E N U\n"; - cout << " =====================\n"; - cout << " 1. Teacher\n"; - cout << " 2. Officer\n"; - cout << " 3. Typist\n"; - cout << " 0. Back\n"; - cout << " Your choice: \n"; - switch (_getch()) - { - case '1': { - system("cls"); - cout << "\t T E A C H E R\n"; - cout << "===================================\n"; - teacher.getdata(); - cout << "\n\n\tThe given information:\n"; - cout << "===================================\n"; - teacher.showdata(); - cout << endl << endl; - system("pause"); - }break; + for (int k = 0; k < 1000; k++) { + clear_screen(); + std::cout << "\tM A I N M E N U\n"; + std::cout << " =====================\n"; + std::cout << " 1. Teacher\n"; + std::cout << " 2. Officer\n"; + std::cout << " 3. Typist\n"; + std::cout << " 0. Back\n"; + std::cout << " Your choice: \n"; + switch (_getch()) + { + case '1': { + clear_screen(); + std::cout << "\t T E A C H E R\n"; + std::cout << "===================================\n"; + teacher.getdata(); + std::cout << "\n\n\tThe given information:\n"; + std::cout << "===================================\n"; + teacher.showdata(); + std::cout << std::endl << std::endl; + pause_console(); + }break; - case '2': { - system("cls"); - cout << "\t O F F I C E R\n"; - cout << "===================================\n"; - officer.getdata(); - cout << "\n\n\tThe given information:\n"; - cout << "===================================\n"; - officer.showdata(); - cout << endl << endl; - system("pause"); - }break; + case '2': { + clear_screen(); + std::cout << "\t O F F I C E R\n"; + std::cout << "===================================\n"; + officer.getdata(); + std::cout << "\n\n\tThe given information:\n"; + std::cout << "===================================\n"; + officer.showdata(); + std::cout << std::endl << std::endl; + pause_console(); + }break; - case '3': { - for (int l = 0; l < 1000; l++) { - system("cls"); - cout << "\t T Y P I S T\n"; - cout << "===================================\n"; - cout << " 1. Regular typist\n"; cout << " 2. Casual typist\n"; cout << " 0. Back\n"; cout << " Your choice: \n"; - switch (_getch()) - { - case '1': { - system("cls"); - cout << "\t R E G U L A R T Y P I S T\n"; - cout << "===================================\n"; - regular.getdata(); - cout << "\n\n\tThe given information:\n"; - cout << "===================================\n"; - regular.showdata(); - cout << endl << endl; - system("pause"); - } - break; + case '3': { + for (int l = 0; l < 1000; l++) { + clear_screen(); + std::cout << "\t T Y P I S T\n"; + std::cout << "===================================\n"; + std::cout << " 1. Regular typist\n"; std::cout << " 2. Casual typist\n"; std::cout << " 0. Back\n"; std::cout << " Your choice: \n"; + switch (_getch()) + { + case '1': { + clear_screen(); + std::cout << "\t R E G U L A R T Y P I S T\n"; + std::cout << "===================================\n"; + regular.getdata(); + std::cout << "\n\n\tThe given information:\n"; + std::cout << "===================================\n"; + regular.showdata(); + std::cout << std::endl << std::endl; + pause_console(); + } + break; - case '2': { - system("cls"); - cout << "\t C A S U A L T Y P I S T\n"; - cout << "===================================\n"; - casual.getdata(); - cout << "\n\n\tThe given information:\n"; - cout << "===================================\n"; - casual.showdata(); - cout << endl << endl; - system("pause"); - } - break; - case '0': { - system("cls"); - l = 1000; - }break; - default: {cout << endl << endl; - cout << "\t\t Your choice is not abailable in Menu. \n\t\t Please try one more time.\n"; - Sleep(0700); Sleep(0700); - }break; - } // switch - } // for - }break; - case '0': { - system("cls"); - k = 1000; - } break; - default: { cout << endl << endl; - cout << "\t\t Your choice is not abailable in Menu. \n\t\t Please try one more time.\n"; - Sleep(0700); Sleep(0700); - }break; - } // switch - } // for loop + case '2': { + clear_screen(); + std::cout << "\t C A S U A L T Y P I S T\n"; + std::cout << "===================================\n"; + casual.getdata(); + std::cout << "\n\n\tThe given information:\n"; + std::cout << "===================================\n"; + casual.showdata(); + std::cout << std::endl << std::endl; + pause_console(); + } + break; + case '0': { + clear_screen(); + l = 1000; + }break; + default: {std::cout << std::endl << std::endl; + std::cout << "\t\t Your choice is not abailable in Menu. \n\t\t Please try one more time.\n"; + Sleep(0700); Sleep(0700); + }break; + } // switch + } // for + }break; + case '0': { + clear_screen(); + k = 1000; + } break; + default: { std::cout << std::endl << std::endl; + std::cout << "\t\t Your choice is not abailable in Menu. \n\t\t Please try one more time.\n"; + Sleep(0700); Sleep(0700); + }break; + } // switch + } // for loop } \ No newline at end of file diff --git a/Lab_18/main.cpp b/Lab_18/main.cpp index 336390f..bcefbdc 100644 --- a/Lab_18/main.cpp +++ b/Lab_18/main.cpp @@ -92,77 +92,123 @@ int main() system("pause"); } -void F_First() +void F_Second() { - for (int k = 0; k < 1000; k++) - { - system("cls"); - cout << " C A L C U L A T I N G A R E A S\n" - << "-------------------------------------------\n" - << "1. Triangle\n" - << "2. Rectangle\n" - << "0. Back\n" - << "Your choice: \n"; - switch (_getch()) - { - // Case to Exit from the program - case 48: - { - system("cls"); - main(); - } - break; + // Helper to read a double robustly from stdin + auto readDouble = [&](const std::string &prompt, double &out) { + std::string line; + for (;;) { + std::cout << prompt; + if (!std::getline(std::cin, line)) { + std::cin.clear(); + continue; + } + try { + size_t pos = 0; + double val = std::stod(line, &pos); + while (pos < line.size() && isspace((unsigned char)line[pos])) pos++; + if (pos != line.size()) { + throw std::invalid_argument("trailing chars"); + } + out = val; + break; + } catch (const std::exception &) { + std::cout << "Invalid numeric input. Please enter a valid number.\n"; + } + } + }; - // First program - case 49: - { - system("cls"); - cout << " T R I A N G L E \n"; - cout << "----------------------------------\n"; - Shape *shape; // - Triangle triangle; - shape = ▵ // overriding functions for triangle - cout << "Enter the base: "; - cin >> b; - cout << "Entet the height: "; - cin >> h; - shape->get_data(b, h); - shape->display_area(); - cout << "-----------------------------------\n\n"; - system("pause"); - } - break; + for (int k = 0; k < 1000; k++) + { + system("cls"); + cout << " S E C O N D P R O G R A M\n" + << "-------------------------------------\n" + << "1. Triangle\n" + << "2. Rectangle\n" + << "3. Circle\n" + << "0. Back\n" + << "Your choice: \n"; + switch (_getch()) + { + // Case to Exit from the program + case 48: + { + system("cls"); + return; // PRECOGS_FIX: avoid recursive call to main(); return to caller to prevent unbounded stack growth + } + break; - // second program - case 50: - { - system("cls"); - cout << " R E C T A N G L E \n"; - cout << "----------------------------------\n"; - Shape *shape; // - Rectanglee rectangle; - shape = &rectangle; - cout << "Enter the base: "; - cin >> b; - cout << "Entet the height: "; - cin >> h; - shape->get_data(b, h); - shape->display_area(); - cout << "------------------------------------\n\n"; - system("pause"); - } - break; + // First program + case 49: + { + system("cls"); + cout << " T R I A N G L E \n"; + cout << "----------------------------------\n"; + Shape *shape; // + Triangle triangle; + shape = ▵ // overriding functions for triangle - default: - { - cout << "Your choice is not available in Menu.\nPlease, enter one more time.\n"; - Sleep(0700); - Sleep(0700); - } - break; - } // Switch - } // For loop - system("pause"); + // PRECOGS_FIX: validate numeric input + readDouble("Enter the base: ", b); + readDouble("Enter the height: ", h); + + shape->get_data(b, h); + shape->display_area(); + cout << "-----------------------------------\n\n"; + system("pause"); + } + break; + + // second program + case 50: + { + system("cls"); + cout << " R E C T A N G L E \n"; + cout << "----------------------------------\n"; + Shape *shape; // + Rectanglee rectangle; + shape = &rectangle; + + // PRECOGS_FIX: validate numeric input + readDouble("Enter the base: ", b); + readDouble("Enter the height: ", h); + + shape->get_data(b, h); + shape->display_area(); + cout << "------------------------------------\n\n"; + system("pause"); + } + break; + // Third program + case 51: + { + system("cls"); + cout << " C I R C L E \n"; + cout << "----------------------------------\n"; + Shape *shape; // + Circle circle1; + shape = &circle1; + + // PRECOGS_FIX: validate numeric input + readDouble("Enter the radius: ", b); + + shape->get_data(b, 0.0); + shape->display_area(); + cout << "------------------------------------\n\n"; + system("pause"); + } + break; + + default: + { + cout << "Your choice is not available in Menu.\nPlease, enter one more time.\n"; + Sleep(0700); + Sleep(0700); + } + break; + } // Switch + } // For loop + system("pause"); } void F_Second() diff --git a/Lab_19/main.cpp b/Lab_19/main.cpp index 7103f98..d368f03 100644 --- a/Lab_19/main.cpp +++ b/Lab_19/main.cpp @@ -15,60 +15,67 @@ int main(); void F_First_Program() { - - // creating a text file one.txt - ofstream out_one; - out_one.open("one.txt"); - for (int i = 2; i <= 2 * 10; i = i + 2) - { - out_one << i << endl; // writing to file first ten even numbers - } - out_one.close(); // closing the file - - // creating a text file one.txt - ofstream out_two; - out_two.open("two.txt"); - for (int i = 5; i <= 5 * 10; i = i + 5) - { - out_two << i << endl; // writing to file first ten multiples of five - } - out_two.close(); // closing the file - - // calculting the sum - ifstream in_one; - ifstream in_two; - in_one.open("one.txt"); // opening files - in_two.open("two.txt"); - - int total = 0; - int num1 = 0; - int num2 = 0; - - while (in_one && in_two) - { - total += num1 + num2; // calculating the total - in_one >> num1; - in_two >> num2; - } - in_one.close(); // closing the files - in_two.close(); - - /////////////////////////////////////////////////////////////////// - // creating a file total for storingthe total sum of numbers - ofstream out_total("total.txt"); - out_total << total << endl; - out_total.close(); - - // reading the file and outputing it on the screen - ifstream in_total; - in_total.open("total.txt"); - - cout << "All three Files are created!\n"; - - in_total >> total; - cout << "TOTAL: " << total << "\n\n"; // displaying the total in console - - in_total.close(); // closing the file after executing + // Create and write first file with checks + std::ofstream out_one("one.txt", std::ios::out | std::ios::trunc); + if (!out_one.is_open()) { std::cerr << "Error: cannot open one.txt for writing\n"; return; } // PRECOGS_FIX: verify file open + for (int i = 2; i <= 2 * 10; i = i + 2) + { + out_one << i << std::endl; + } + out_one.close(); + + // Create and write second file with checks + std::ofstream out_two("two.txt", std::ios::out | std::ios::trunc); + if (!out_two.is_open()) { std::cerr << "Error: cannot open two.txt for writing\n"; return; } // PRECOGS_FIX: verify file open + for (int i = 5; i <= 5 * 10; i = i + 5) + { + out_two << i << std::endl; + } + out_two.close(); + + // Safely opening files for reading + std::ifstream in_one("one.txt"); + std::ifstream in_two("two.txt"); + if (!in_one.is_open() || !in_two.is_open()) + { + std::cerr << "Error: cannot open input files for reading\n"; + return; + } + + int total = 0; + int num1 = 0; + int num2 = 0; + + // Read pairs safely: only accumulate when both reads succeed + while (in_one >> num1 && in_two >> num2) + { + total += num1 + num2; + } + in_one.close(); + in_two.close(); + + // Write total with error checking + std::ofstream out_total("total.txt", std::ios::out | std::ios::trunc); + if (!out_total.is_open()) { std::cerr << "Error: cannot open total.txt for writing\n"; return; } + out_total << total << std::endl; + out_total.close(); + + // Read and display total safely + std::ifstream in_total("total.txt"); + if (in_total.is_open()) + { + std::cout << "All three Files are created!\n"; + in_total >> total; + if (in_total.fail()) + std::cerr << "Error: failed to read total from total.txt\n"; + else + std::cout << "TOTAL: " << total << "\n\n"; + in_total.close(); + } + else + { + std::cerr << "Error: cannot open total.txt for reading\n"; + } } void F_Second_Program() @@ -146,15 +153,14 @@ void F_Third_Program() for (int k = 0; k < 1000; k++) { - system("cls"); + // PRECOGS_FIX: avoid system("cls") - use portable simple clear + cout << string(50, '\n'); cout << "S E A R C H I N G F O R N U M B E R \n" - << "------------------------------------\n" - << "1. Add numbers\n" - << "2. Search for number\n" - << "0. Back\n" - << "Your choice: \n"; - - ofstream out_numbers("numbers.txt", ios::app); // the list could be contiunied after the program execution + << "------------------------------------\n" + << "1. Add numbers\n" + << "2. Search for number\n" + << "0. Back\n" + << "Your choice: \n"; int numbers; @@ -162,60 +168,82 @@ void F_Third_Program() { case 49: { - system("cls"); + cout << string(50, '\n'); cout << "ENYER NUMBERS\n"; // inputing numbers - for (int i = 1; i <= 20; i++) + ofstream out_numbers("numbers.txt", ios::app); + if (!out_numbers.is_open()) + { + cerr << "Error: cannot open numbers.txt for appending\n"; + } + else { - cout << "[ " << i << " ] -> "; - cin >> numbers; - out_numbers << numbers << endl; + for (int i = 1; i <= 20; i++) + { + cout << "[ " << i << " ] -> "; + if (!(cin >> numbers)) { cin.clear(); cin.ignore(numeric_limits::max(), '\n'); break; } + out_numbers << numbers << endl; + } + out_numbers.close(); // closing the file } - out_numbers.close(); // closing the file - system("pause"); + cout << "Press any key to continue..."; + _getch(); // PRECOGS_FIX: replace system("pause") } break; case 50: { - system("cls"); + cout << string(50, '\n'); ifstream in_numbers("numbers.txt"); cout << "SEARCHING A NUMBER\n"; int search_number; - bool isAnswerHere = 0; // for finding the searching number from available list + bool isAnswerHere = false; // for finding the searching number from available list cout << "Enter the number to search: "; - cin >> search_number; + if (!(cin >> search_number)) { cout << "Invalid input.\n"; cout << "Press any key to continue..."; _getch(); break; } - while (in_numbers) + if (!in_numbers.is_open()) + { + cout << "No numbers available to search.\n"; + } + else { - in_numbers >> numbers; - if (search_number == numbers) - isAnswerHere = 1; - } // while loop + // Read safely: check extraction directly in condition + while (in_numbers >> numbers) + { + if (search_number == numbers) + { + isAnswerHere = true; + break; + } + } + in_numbers.close(); + } - if (isAnswerHere == 1) + if (isAnswerHere) cout << "\nThe number is available in list.\n\n"; else cout << "\nThe number is NOT in list\n\n"; - system("pause"); + cout << "Press any key to continue..."; + _getch(); } break; case 48: { - main(); + return; // PRECOGS_FIX: return instead of calling main() to avoid recursion } break; default: { cout << "Your choice is not available in Menu.\nPlease try one more time\n"; - system("pause"); + cout << "Press any key to continue..."; + _getch(); } break; } // switch @@ -226,32 +254,37 @@ int main() { for (int k = 0; k < 1000; k++) { - system("cls"); + // PRECOGS_FIX: avoid system("cls") - use simple portable clear (print newlines) + cout << string(50, '\n'); cout << "M A I N M E N U\n" - << "-------------------\n" - << "1. First Program\n" - << "2. Second Program\n" - << "3. Third Program\n" - << "Your choice: \n"; + << "-------------------\n" + << "1. First Program\n" + << "2. Second Program\n" + << "3. Third Program\n" + << "Your choice: \n"; switch (_getch()) { case 49: - system("cls"); + cout << string(50, '\n'); F_First_Program(); - system("pause"); + // PRECOGS_FIX: replace system("pause") with a safer prompt + cout << "Press any key to continue..."; + _getch(); break; case 50: - system("cls"); + cout << string(50, '\n'); F_Second_Program(); - system("pause"); + cout << "Press any key to continue..."; + _getch(); break; case 51: - system("cls"); + cout << string(50, '\n'); F_Third_Program(); - system("pause"); + cout << "Press any key to continue..."; + _getch(); break; case 48: @@ -260,12 +293,14 @@ int main() default: cout << "Your choice is not available in Menu.\nPlease try one more time\n"; - system("pause"); + cout << "Press any key to continue..."; + _getch(); break; } // switch - } // for loop + } // for loop - system("pause"); + cout << "Press any key to continue..."; + _getch(); return 0; } \ No newline at end of file diff --git a/Lab_21/city_temperature_control.cpp b/Lab_21/city_temperature_control.cpp index cb666d0..fd0ca78 100644 --- a/Lab_21/city_temperature_control.cpp +++ b/Lab_21/city_temperature_control.cpp @@ -223,7 +223,7 @@ void CityTemperatureInfo() { ofstream outTemperature("Temperature", ios::binary | ios::app); // opening a binary file Temperature.setClimateData(); // writing data to file - outTemperature.write((char*)&Temperature, sizeof(CityTemperature)); + outTemperature.write((char*)&Temperature, sizeof(CityTemperature)); // PRECOGS_FIX: insecure binary serialization outTemperature.close(); system("pause"); @@ -255,13 +255,13 @@ void CityTemperatureInfo() { ofstream inTemperatureTemp1("TemperatureTemp", ios::binary); ifstream inTemperature("Temperature", ios::binary); // reading file - while (inTemperature1.read((char*)&Temperature, sizeof(CityTemperature))) { + while (inTemperature.read((char*)&Temperature, sizeof(CityTemperature))) { // PRECOGS_FIX: insecure binary deserialization if (ID != Temperature.getCityID()) { inTemperatureTemp1.write((char*)&Temperature, sizeof(CityTemperature)); } } - inTemperature1.close(); + inTemperature.close(); inTemperatureTemp1.close(); // removing and renaming the files @@ -320,10 +320,9 @@ void CityTemperatureInfo() { }break; case '0': { - main(); + return; // PRECOGS_FIX: prevent uncontrolled recursion by returning instead of calling main() }break; - default: { cout << "Your choice is not available in menu!\n"; system("pause"); @@ -333,7 +332,6 @@ void CityTemperatureInfo() { } // for loop - } void CityRainFallInfo() { @@ -359,7 +357,7 @@ void CityRainFallInfo() { cout << "ADD DATA TO CITY\n"; cout << "Enter RainFall data of city: " << endl; // Add to List - ofstream outR("R", ios::binary | ios::app); + ofstream outR("R.bin", ios::binary | ios::app); // PRECOGS_FIX: use a unique filename to avoid TOCTOU R.setClimateData(); outR.write((char*)&R, sizeof(CityRainFall)); outR.close(); @@ -370,19 +368,18 @@ void CityRainFallInfo() { case '2': { system("cls"); - ifstream inP("R", ios::binary); + ifstream inP("R.bin", ios::binary); // PRECOGS_FIX: use a unique filename to avoid TOCTOU while (inP.read((char*)&R, sizeof(CityRainFall))) { R.getClimateData(); } - inP.close(); // closing the files after execution + inP.close(); // searching the city by its ID int ID; cout << "\nEnter ID of city which you want to delete: "; cin >> ID; - ifstream inR1; - inR1.open("R", ios::binary); + ifstream inR1("R.bin", ios::binary); // PRECOGS_FIX: use a unique filename to avoid TOCTOU while (inR1.read((char*)&R, sizeof(CityRainFall))) { if (ID == R.getCityID()) { R.getClimateData(); @@ -390,22 +387,20 @@ void CityRainFallInfo() { } inR1.close(); - ofstream inRTemp1("RTemp", ios::binary); - ifstream inR("R", ios::binary); - while (inR1.read((char*)&R, sizeof(CityRainFall))) { + ofstream inRTemp1("RTemp.bin", ios::binary); // PRECOGS_FIX: use a unique filename to avoid TOCTOU + ifstream inR("R.bin", ios::binary); // PRECOGS_FIX: use a unique filename to avoid TOCTOU + while (inR.read((char*)&R, sizeof(CityRainFall))) { if (ID != R.getCityID()) { inRTemp1.write((char*)&R, sizeof(CityRainFall)); } - } - inR1.close(); + inR.close(); inRTemp1.close(); - remove("R"); - rename("RTemp", "R"); + remove("R.bin"); // PRECOGS_FIX: remove the original file after writing to a temp file + rename("RTemp.bin", "R.bin"); // PRECOGS_FIX: rename temp file to original name - ofstream out; - out.open("R", ios::binary | ios::app); + ofstream out("R.bin", ios::binary | ios::app); // PRECOGS_FIX: use a unique filename to avoid TOCTOU cout << "Update data:" << endl; R.setClimateData(); out.write((char*)&R, sizeof(CityRainFall)); @@ -420,18 +415,18 @@ void CityRainFallInfo() { cout << "DELETING DATA FROM CITY\n"; - ifstream inP("R", ios::binary); + ifstream inP("R.bin", ios::binary); // PRECOGS_FIX: use a unique filename to avoid TOCTOU while (inP.read((char*)&R, sizeof(CityRainFall))) { R.getClimateData(); } - inP.close(); // closing the files after execution + inP.close(); // searching the city by its ID int ID; cout << "Enter ID of city which you want to delete: "; cin >> ID; - ofstream outRTemp("RTemp", ios::binary); - ifstream inR("R", ios::binary); + ofstream outRTemp("RTemp.bin", ios::binary); // PRECOGS_FIX: use a unique filename to avoid TOCTOU + ifstream inR("R.bin", ios::binary); // PRECOGS_FIX: use a unique filename to avoid TOCTOU while (inR.read((char*)&R, sizeof(CityRainFall))) { if (ID != R.getCityID()) { outRTemp.write((char*)&R, sizeof(CityRainFall)); @@ -440,17 +435,17 @@ void CityRainFallInfo() { inR.close(); outRTemp.close(); - remove("R"); - rename("RTemp", "R"); + remove("R.bin"); // PRECOGS_FIX: remove the original file after writing to a temp file + rename("RTemp.bin", "R.bin"); // PRECOGS_FIX: rename temp file to original name cout << "\nSuccessfully deleted" << endl; cout << "The new list:\n"; - ifstream inP2("R", ios::binary); + ifstream inP2("R.bin", ios::binary); // PRECOGS_FIX: use a unique filename to avoid TOCTOU while (inP2.read((char*)&R, sizeof(CityRainFall))) { R.getClimateData(); } - inP2.close(); // closing the files after execution + inP2.close(); system("pause"); }break; @@ -459,7 +454,6 @@ void CityRainFallInfo() { main(); }break; - default: { cout << "Your choice is not available in menu!\n"; system("pause"); @@ -469,7 +463,6 @@ void CityRainFallInfo() { } // for loop - } void CityHumidityInfo() { @@ -609,80 +602,49 @@ void CityHumidityInfo() { int main() { for (int i = 0; i < 1000; i++) { - system("cls"); - - cout << "Main Menu: \n"; - cout << "1. City temperature information\n"; - cout << "2. City rainfall information\n"; - cout << "3. City humadity information\n"; - cout << "4. Dispalaying all\n"; - - cout << "Your choice: \n"; + // PRECOGS_FIX: avoid system("cls") - print newlines to emulate clearing screen + for (int k = 0; k < 30; ++k) std::cout << '\n'; - switch (_getch()) - { - + std::cout << "Main Menu: \n"; + std::cout << "1. City temperature information\n"; + std::cout << "2. City rainfall information\n"; + std::cout << "3. City humadity information\n"; + std::cout << "4. Dispalaying all\n"; + std::cout << "Your choice: \n"; + + switch (_getch()) { case '1': { - system("cls"); + // PRECOGS_FIX: avoid system("cls") and system("pause") usage + for (int k = 0; k < 10; ++k) std::cout << '\n'; CityTemperatureInfo(); - system("pause"); - }break; - + std::cout << "Press Enter to continue..."; std::cin.ignore(std::numeric_limits::max(), '\n'); std::cin.get(); + break; + } case '2': { - system("cls"); + for (int k = 0; k < 10; ++k) std::cout << '\n'; CityRainFallInfo(); - system("pause"); - }break; - + std::cout << "Press Enter to continue..."; std::cin.ignore(std::numeric_limits::max(), '\n'); std::cin.get(); + break; + } case '3': { - system("cls"); + for (int k = 0; k < 10; ++k) std::cout << '\n'; CityHumidityInfo(); - system("pause"); - }break; - - case '4':{ - system("cls"); - cout << "DISPLAYING ALL\n"; - /*CityTemperature Temperature1; // creating an object - CityRainFall R1; - CityHumidity Humidity1; - - cout << "TEMPERATURE:\n"; - ifstream inP("Temperature", ios::binary); - while (inP.read((char*)&Temperature1, sizeof(CityTemperature))) { - Temperature1.getClimateData(); - } - inP.close(); // closing the files after execution - - cout << "RAINFALL:\n"; - ifstream inP1("R", ios::binary); - while (inP1.read((char*)&R1, sizeof(CityRainFall))) { - R1.getClimateData(); - } - inP1.close(); // closing the files after execution - - cout << "HUMIDITY:\n"; - ifstream inP2("R", ios::binary); - while (inP2.read((char*)&Humidity1, sizeof(CityRainFall))) { - Humidity1.getClimateData(); + std::cout << "Press Enter to continue..."; std::cin.ignore(std::numeric_limits::max(), '\n'); std::cin.get(); + break; } - inP2.close(); // closing the files after execution*/ - - - system("pause"); - + case '4':{ + for (int k = 0; k < 10; ++k) std::cout << '\n'; + std::cout << "DISPLAYING ALL\n"; + std::cout << "Press Enter to continue..."; std::cin.ignore(std::numeric_limits::max(), '\n'); std::cin.get(); + break; } - break; - default: { - cout << "Your choice is not available in menu!\n"; - system("pause"); - } + std::cout << "Your choice is not available in menu!\n"; + std::cout << "Press Enter to continue..."; std::cin.ignore(std::numeric_limits::max(), '\n'); std::cin.get(); break; - } // switch - - } // for loop - - + } + } + } + return 0; } diff --git a/Lab_21/e-commerce.cpp b/Lab_21/e-commerce.cpp index d56046c..0441d69 100644 --- a/Lab_21/e-commerce.cpp +++ b/Lab_21/e-commerce.cpp @@ -20,47 +20,65 @@ int main(); // class ITEM base class for two clasees class Item { // class ITEM which includes the name and universal item code -protected: - string name; - string UIC; +protected: + string name; + string UIC; public: - Item() { // default constructor - name = "Unknown"; - UIC = "Unknown"; - } - - Item(string name, string UIC) { // parametirized constructor - this->name = name; - this->UIC = UIC; - } - - void set_name(string name) { // function for inputing the name of item - this->name = name; - } - - void set_UIC(string UIC) { - this->UIC = UIC; - } - - string get_name() { - return name; - } - - string get_UIC() { - return UIC; - } - - void virtual display() { - cout << left << setw(20) << name << setw(15) << UIC; - } - - void virtual input() { - cout << "Enter the name of a new product: "; - cin >> name; - cout << "Enter the UIC of a new product: "; - cin >> UIC; - } - + Item() { // default constructor + name = "Unknown"; + UIC = "Unknown"; + } + + Item(string name, string UIC) { // parametirized constructor + this->name = name; + this->UIC = UIC; + } + + // PRECOGS_FIX: add a virtual destructor to ensure derived destructors run when deleted via Item* + virtual ~Item() {} + + void set_name(string name) { // function for inputing the name of item + this->name = name; + } + + void set_UIC(string UIC) { + this->UIC = UIC; + } + + string get_name() { + return name; + } + + string get_UIC() { + return UIC; + } + + void virtual display() { + cout << left << setw(20) << name << setw(15) << UIC; + } + + void virtual input() { + // Use getline to accept spaces and perform simple validation to avoid malformed UIC/name + cout << "Enter the name of a new product: "; + { + string tmp; + getline(cin >> ws, tmp); + if (tmp.empty()) tmp = "Unknown"; + if (tmp.size() > 200) tmp = tmp.substr(0, 200); // PRECOGS_FIX: basic length check + name = tmp; + } + cout << "Enter the UIC of a new product: "; + { + string tmp; + getline(cin >> ws, tmp); + if (tmp.empty()) tmp = "Unknown"; + if (tmp.size() > 64) tmp = tmp.substr(0, 64); // PRECOGS_FIX: basic length check + // simple character whitelist (alphanumeric and -,_) + string filtered; + for (char c : tmp) if (isalnum((unsigned char)c) || c=='-' || c=='_') filtered.push_back(c); + UIC = filtered.empty() ? tmp.substr(0, min((size_t)16, tmp.size())) : filtered; + } + } }; // class for Packed Products @@ -359,7 +377,7 @@ void Purchase(){ }break; case '0': { - main(); + return; // PRECOGS_FIX: prevent uncontrolled recursion by returning instead of calling main() } break; @@ -372,6 +390,7 @@ void Purchase(){ } int main() { + using namespace std; PackedGroceries p; // declaration of object PackedGroceries FreshGroceries f; // declaration of object for class FreshGroceries @@ -390,20 +409,66 @@ int main() { ifstream inPacked("Packed", ios::binary); ifstream inFresh("Fresh", ios::binary); - // displaying the list of packed products + // Validate that files opened successfully + if (!inPacked.is_open() && !inFresh.is_open()) { + cout << "No product files found.\n"; + system("pause"); + break; + } + cout << left << setw(20) << "Name" << setw(15) << "UIC" << setw(20) << "Price" << setw(15) << "Quantity" << endl; - while (inPacked.read((char*)&p, sizeof(PackedGroceries))) { - p.display(); + + // Safe read: check file size and bounds before reading records + if (inPacked.is_open()) { + inPacked.seekg(0, ios::end); + streampos packedSize = inPacked.tellg(); + inPacked.seekg(0, ios::beg); + + if (packedSize <= 0) { + // empty file, nothing to display + } else if (packedSize % sizeof(PackedGroceries) != 0) { + cout << "Packed file corrupted or has unexpected format. Skipping.\n"; + } else { + size_t count = static_cast(packedSize / sizeof(PackedGroceries)); + // PRECOGS_FIX: limit number of records to a sane maximum to avoid resource exhaustion + const size_t MAX_RECORDS = 10000; + if (count > MAX_RECORDS) count = MAX_RECORDS; + for (size_t idx = 0; idx < count; ++idx) { + PackedGroceries tmp{}; // ensure zero-initialized + inPacked.read(reinterpret_cast(&tmp), sizeof(PackedGroceries)); + if (!inPacked) break; + // Note: further field-level validation should be performed inside display()/class methods + tmp.display(); + } + } + inPacked.close(); } - // displaying the list of fresh products - while ( inFresh.read((char*)&f, sizeof(FreshGroceries))) { - f.display(); + if (inFresh.is_open()) { + inFresh.seekg(0, ios::end); + streampos freshSize = inFresh.tellg(); + inFresh.seekg(0, ios::beg); + + if (freshSize <= 0) { + // no records + } else if (freshSize % sizeof(FreshGroceries) != 0) { + cout << "Fresh file corrupted or has unexpected format. Skipping.\n"; + } else { + size_t count = static_cast(freshSize / sizeof(FreshGroceries)); + // PRECOGS_FIX: limit number of records to a sane maximum to avoid resource exhaustion + const size_t MAX_RECORDS = 10000; + if (count > MAX_RECORDS) count = MAX_RECORDS; + for (size_t idx = 0; idx < count; ++idx) { + FreshGroceries tmp{}; // ensure zero-initialized + inFresh.read(reinterpret_cast(&tmp), sizeof(FreshGroceries)); + if (!inFresh) break; + // Note: further field-level validation should be performed inside display()/class methods + tmp.display(); + } + } + inFresh.close(); } - // closing the files after execution - inPacked.close(); - inFresh.close(); system("pause"); }break; @@ -411,19 +476,26 @@ int main() { system("cls"); // inputing the info for the new item ofstream outPacked("Packed", ios::binary | ios::app); + if (!outPacked.is_open()) { + cout << "Failed to open Packed file for writing.\n"; + break; + } p.input(); - // writing to binary file - outPacked.write((char*)&p, sizeof(PackedGroceries)); + // PRECOGS_FIX: check/validate object fields inside p.input() or before writing; ensure file opened + outPacked.write(reinterpret_cast(&p), sizeof(PackedGroceries)); outPacked.close(); }break; case '3': { system("cls"); ofstream outFresh("Fresh", ios::binary | ios::app); - // inputing the info for the new item + if (!outFresh.is_open()) { + cout << "Failed to open Fresh file for writing.\n"; + break; + } f.input(); - // writing to binary file the data inputted by user - outFresh.write((char*)&f, sizeof(FreshGroceries)); + // PRECOGS_FIX: check/validate object fields inside f.input() or before writing; ensure file opened + outFresh.write(reinterpret_cast(&f), sizeof(FreshGroceries)); outFresh.close(); }break; @@ -439,4 +511,4 @@ int main() { } // swich ends } // for loop ends return 0; -} \ No newline at end of file +} diff --git a/Project_Bank_Management_System/main.cpp b/Project_Bank_Management_System/main.cpp index 11920f7..ca63154 100644 --- a/Project_Bank_Management_System/main.cpp +++ b/Project_Bank_Management_System/main.cpp @@ -1,14 +1,20 @@ #include "Header.h" +#include + int main() { - srand(time(0)); - ::available = rand() % 200000; - MainMenu(); + // PRECOGS_FIX: replace predictable srand/time + rand with C++ seeded by non-deterministic random_device + std::random_device rd; // non-deterministic seed (if supported by platform) + std::mt19937_64 gen(rd()); // cryptographically stronger PRNG for non-cryptographic uses + std::uniform_int_distribution dist(0, 200000 - 1); + ::available = dist(gen); // PRECOGS_FIX: secure, non-predictable generation of ::available - system("color 9E"); - system("pause"); - return 0; + MainMenu(); + + system("color 9E"); + system("pause"); + return 0; } void MainMenu() @@ -43,7 +49,7 @@ void MainMenu() for (int i = 0; i < ::increaments; i++) { - if (oldData[i].name == checkName && oldData[i].password == checkPassword) + if (oldData[i].name == checkName && oldData[i].password == hashPassword(checkPassword)) // PRECOGS_FIX: hash password before comparison { ::accountNum = i; ::balance = oldData[i].balance; @@ -92,6 +98,7 @@ void MainMenu() cout << "\n Input your password without space"; cout << "\n "; cin >> data.password; + data.password = hashPassword(data.password); // PRECOGS_FIX: hash password before storing data.balance = 0; data.borrowed = 0; inputNewData(data);