Skip to content

Commit 5987204

Browse files
author
Don Johnson
committed
this should merge
1 parent 8f41beb commit 5987204

File tree

1 file changed

+36
-80
lines changed

1 file changed

+36
-80
lines changed

a.cpp

+36-80
Original file line numberDiff line numberDiff line change
@@ -1,92 +1,48 @@
11
#include <iostream>
2-
#include <string>
3-
#include <vector>
4-
#include <algorithm>
5-
#include <sstream>
2+
#include <string_view>
3+
#include <cstdlib>
4+
#include <stdexcept>
65

7-
/**
8-
* Example "allowlist" of shell commands permitted by this program.
9-
* In real-world usage, you'd carefully design or omit this approach
10-
* to avoid potential command injection altogether.
11-
*/
12-
static const std::vector<std::string> ALLOWED_COMMANDS = {
13-
"ls", // List directory
14-
"pwd", // Print working directory
15-
"whoami", // Show current user
16-
// Add others only if absolutely necessary
17-
};
18-
19-
/**
20-
* Splits a string into tokens, e.g. "ls -l /home" -> ["ls", "-l", "/home"].
21-
* Helps us separate the base command from its arguments.
22-
*/
23-
std::vector<std::string> tokenize(const std::string &input) {
24-
std::vector<std::string> tokens;
25-
std::istringstream iss(input);
26-
std::string token;
27-
while (iss >> token) {
28-
tokens.push_back(token);
29-
}
30-
return tokens;
31-
}
32-
33-
/**
34-
* Checks if a given command (the first token) is in the ALLOWED_COMMANDS.
35-
*/
36-
bool is_base_command_allowed(const std::string &cmd) {
37-
return std::find(ALLOWED_COMMANDS.begin(), ALLOWED_COMMANDS.end(), cmd)
38-
!= ALLOWED_COMMANDS.end();
39-
}
6+
namespace app {
407

41-
int main() {
42-
std::cout << "Enter a shell command to run (allowed: ls, pwd, whoami): ";
8+
class Greeter {
9+
public:
10+
// Use string_view for efficient string passing
11+
explicit Greeter(std::string_view message) noexcept
12+
: m_message(message) {}
4313

44-
// Safely read user input into a std::string
45-
std::string userInput;
46-
if (!std::getline(std::cin, userInput)) {
47-
std::cerr << "Error reading input or EOF reached.\n";
48-
return 1;
14+
// Mark member functions that don't modify state as const
15+
[[nodiscard]] auto getMessage() const noexcept -> std::string_view {
16+
return m_message;
4917
}
5018

51-
// Tokenize the input: first token is the base command; subsequent tokens are arguments
52-
std::vector<std::string> tokens = tokenize(userInput);
53-
if (tokens.empty()) {
54-
std::cerr << "No command entered.\n";
55-
return 1;
19+
// Use auto return type for better maintainability
20+
auto greet() const -> void {
21+
std::cout << getMessage() << '\n';
5622
}
5723

58-
// The first token (base command) must match our allowlist
59-
const std::string &baseCmd = tokens[0];
60-
if (!is_base_command_allowed(baseCmd)) {
61-
std::cerr << "[SECURITY] Denied: Command \"" << baseCmd << "\" is not in the allowed list.\n";
62-
return 1;
63-
}
64-
65-
// Optional: further checks on arguments if you want to allow only certain flags, etc.
66-
// For example:
67-
// for (size_t i = 1; i < tokens.size(); i++) {
68-
// // Validate each token carefully
69-
// }
24+
private:
25+
std::string_view m_message;
26+
};
7027

71-
// Construct a sanitized command string for system()
72-
// Minimal version: rejoin tokens with spaces
73-
std::ostringstream oss;
74-
for (size_t i = 0; i < tokens.size(); ++i) {
75-
if (i > 0) {
76-
oss << " "; // separate tokens by space
77-
}
78-
oss << tokens[i];
28+
// Use [[nodiscard]] to ensure return values are handled
29+
[[nodiscard]] auto createGreeter(std::string_view message) -> Greeter {
30+
if (message.empty()) {
31+
throw std::invalid_argument("Message cannot be empty");
7932
}
80-
std::string safeCommand = oss.str();
33+
return Greeter{message};
34+
}
8135

82-
// For demonstration purposes, using system() is still risky.
83-
// A truly secure design might replicate or wrap the needed functionality without calling the shell.
84-
int result = std::system(safeCommand.c_str());
85-
if (result == -1) {
86-
std::cerr << "[ERROR] Failed to execute command.\n";
87-
return 1;
36+
} // namespace app
37+
38+
auto main() -> int {
39+
try {
40+
constexpr std::string_view message = "Hello, World!";
41+
auto greeter = app::createGreeter(message);
42+
greeter.greet();
43+
return EXIT_SUCCESS;
44+
} catch (const std::exception& e) {
45+
std::cerr << "Error: " << e.what() << '\n';
46+
return EXIT_FAILURE;
8847
}
89-
90-
std::cout << "[INFO] Command completed with exit code: " << WEXITSTATUS(result) << "\n";
91-
return 0;
92-
}
48+
}

0 commit comments

Comments
 (0)