Skip to content

style: format code with ClangFormat and Prettier#99

Closed
deepsource-autofix[bot] wants to merge 3 commits into
masterfrom
deepsource-transform-4b2423d5
Closed

style: format code with ClangFormat and Prettier#99
deepsource-autofix[bot] wants to merge 3 commits into
masterfrom
deepsource-transform-4b2423d5

Conversation

@deepsource-autofix

Copy link
Copy Markdown
Contributor

This commit fixes the style issues introduced in 000fa7f according to the output
from ClangFormat and Prettier.

Details: None

This commit fixes the style issues introduced in 000fa7f according to the output
from ClangFormat and Prettier.

Details: None
@deepsource-io

deepsource-io Bot commented Jul 18, 2025

Copy link
Copy Markdown

Here's the code health analysis summary for commits 000fa7f..7e7d287. View details on DeepSource ↗.

Analysis Summary

AnalyzerStatusSummaryLink
DeepSource C & C++ LogoC & C++❌ Failure
❗ 20 occurences introduced
🎯 18 occurences resolved
View Check ↗
DeepSource Shell LogoShell✅ SuccessView Check ↗
DeepSource Secrets LogoSecrets✅ SuccessView Check ↗
DeepSource Test coverage LogoTest coverage⚠️ Artifact not reportedTimed out: Artifact was never reportedView Check ↗

💡 If you’re a repository administrator, you can configure the quality gates from the settings.

Comment on lines 13 to +17
void symlink(const std::filesystem::path &source, const std::filesystem::path &target);

void symlink_at(const std::filesystem::path &target,
const file_descriptor &dirfd,
const std::filesystem::path &link_path);
const file_descriptor &dirfd,
const std::filesystem::path &link_path);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Potential Naming Conflict with POSIX Functions

The function names symlink and symlink_at are identical to POSIX functions, which could lead to naming conflicts and confusion, especially in environments where POSIX functions are commonly used. This overlap might cause issues during compilation or runtime due to ambiguous references.

Recommendation: Consider renaming these functions to avoid conflicts and improve code clarity, perhaps to something like create_symlink and create_symlink_at.

Comment on lines 13 to +17
void symlink(const std::filesystem::path &source, const std::filesystem::path &target);

void symlink_at(const std::filesystem::path &target,
const file_descriptor &dirfd,
const std::filesystem::path &link_path);
const file_descriptor &dirfd,
const std::filesystem::path &link_path);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lack of Error Handling in Function Prototypes

The prototypes for symlink and symlink_at do not provide any mechanism for error handling. File system operations can fail for various reasons (e.g., permissions, non-existent directories), and it's essential to communicate these failures back to the caller to handle them appropriately.

Recommendation: Modify the function signatures to include error handling, such as returning a status code or throwing exceptions to indicate failure conditions.

Comment on lines +25 to 28
TEST(LINYAPS_BOX, Placeholder1)
{
EXPECT_EQ(1, 1);
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The test case LINYAPS_BOX, Placeholder1 contains a test that always passes (EXPECT_EQ(1, 1);). This is likely a placeholder and does not test any actual functionality. Recommendation: Implement a meaningful test that verifies specific functionality of the LINYAPS_BOX or remove this placeholder if it serves no purpose.

This PR refactors the mounting and device-configuration code to improve maintainability and comply with coding and security guidelines. We break up a large monolithic class into smaller functions, consolidate duplicated branching logic, enforce const correctness on globals, and make all implicit conversions explicit.

- Function with cyclomatic complexity higher than threshold: We extracted the core mounting logic from the original `mounter` class into six focused helper functions (`processCgroupMount`, `setupMountDestination`, `needsRemount`, `computeRemountFlags`, `finalizeRemount`, and `do_mount`). Each helper now handles a single responsibility, drastically reducing the cyclomatic complexity of any individual function and making the control flow easier to follow.
- Audit required: found a non-const global variable: All previously mutable globals were either declared inside anonymous namespaces or marked `static const`. For example, the return value of `getenv` is now `static const char* const`, and flag lookup tables (`mount_flags`, `flagInfos`) are defined as `static constexpr` arrays to prevent unintended modifications at runtime.
- Empty exception handler block: Several catch blocks that previously had empty bodies are now explicitly rethrowing exceptions with `throw;`. This ensures that errors are not silently swallowed, improving observability and error reporting.
- Found redundant cloned branches: We replaced dozens of nearly identical `if` statements that tested and appended flag names with data-driven loops over `mount_flags` and `flagInfos`. This removes redundant code clones and centralizes flag metadata.
- Avoid array-to-pointer decay: Instead of manual pointer arithmetic and array decay, we use range-based for loops over `static constexpr` arrays. This preserves compile-time size information, avoids pointer decay, and makes iterations safer and clearer.
- Found an implicit conversion across boolean and other primitive type: Conditions such as `if (*c)` have been changed to `if (*c != '\0')`, stream checks use explicit methods (`!ofs.is_open()`) or `static_cast<bool>`, and boolean contexts are now unambiguous, preventing hidden type conversions.
- Implicit deletion of copy and move assignment constructors due to non-static const data member: The original `mounter` class contained non-static const members which disabled default assignment operators. By removing the class and using free functions instead, we avoid the implicit deletion issue and simplify object semantics.

> This Autofix was generated by AI. Please review the change before merging.
This commit fixes the style issues introduced in 80e425b according to the output
from ClangFormat and Prettier.

Details: #99
Comment thread src/linyaps_box/app.cpp
Comment on lines 38 to 44
std::stringstream result;
for (int i = 0; i < argc; ++i) {
result << " \"";
for (char *c = argv[i]; *c; ++c) {
for (char *c = argv[i]; *c != '\0'; ++c) {
if (*c == '\\') {
result << "\\\\";
} else if (*c == '"') {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The use of std::stringstream inside a loop that processes each character of command line arguments can lead to performance inefficiencies due to potential frequent memory reallocations. Consider using a more efficient string concatenation strategy, such as reserving an estimated amount of space in the std::stringstream object before the loop starts.

Suggested Change:

std::stringstream result;
result.reserve(estimated_size); // estimate based on typical argv content size

This pre-allocation can help in reducing the number of memory allocations during string construction.

Comment thread src/linyaps_box/app.cpp
Comment on lines 38 to 44
std::stringstream result;
for (int i = 0; i < argc; ++i) {
result << " \"";
for (char *c = argv[i]; *c; ++c) {
for (char *c = argv[i]; *c != '\0'; ++c) {
if (*c == '\\') {
result << "\\\\";
} else if (*c == '"') {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The nested loop structure for escaping special characters in command line arguments makes the code hard to read and maintain. Consider abstracting this functionality into a separate utility function that handles the escaping of strings. This would not only improve readability but also enhance reusability of the escaping logic across different parts of your application.

Suggested Change:

std::string escape_string(const char* input) {
    std::string result;
    for (; *input != '\0'; ++input) {
        switch (*input) {
            case '\\': result += "\\\\"; break;
            case '"': result += "\\\""; break;
            default: result += *input;
        }
    }
    return result;
}

Then replace the inner loop with a call to escape_string(argv[i]).

private:
std::string id;
const status_directory &status_dir_;
const status_directory *status_dir_;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The use of a raw pointer status_dir_ for referencing status_directory instances can lead to potential memory management issues, such as dangling pointers if the status_directory object is deleted elsewhere. Consider using smart pointers like std::shared_ptr or std::unique_ptr to automatically manage the lifetime of the object and prevent such issues.

Recommended Change:

std::shared_ptr<const status_directory> status_dir_;

@@ -26,7 +26,7 @@ class container_ref

private:
std::string id;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The id member variable is mutable, which might not be desirable if the identifier should remain constant after the object's construction. To enforce immutability and prevent accidental modification, consider declaring id as const std::string.

Recommended Change:

const std::string id;

Comment on lines 24 to 30

std::stringstream ss;
std::string key;
while (fdinfo >> key) {
while (static_cast<bool>(fdinfo >> key)) {
ss << " " << key << " ";
if (key != "flags:") {
std::string value;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The function inspect_fdinfo lacks proper error handling for file operations. Using assert to check if the file is open is not sufficient for production code as it only works in debug mode and does not provide a way to handle the error gracefully in release builds.

Recommendation:
Replace assert(fdinfo.is_open()); with proper error checking and handling. If the file cannot be opened, log an error and return an appropriate error message or code. This will make the function more robust and prevent potential crashes or undefined behavior in scenarios where the file cannot be accessed.

Comment on lines 56 to 92

std::string inspect_fcntl_or_open_flags(size_t flags)
{
std::stringstream ss;
struct FlagInfo { size_t mask; const char* name; };
static constexpr FlagInfo flagInfos[] = {
{ O_RDONLY, "O_RDONLY" },
{ O_WRONLY, "O_WRONLY" },
{ O_RDWR, "O_RDWR" },
{ O_CREAT, "O_CREAT" },
{ O_EXCL, "O_EXCL" },
{ O_NOCTTY, "O_NOCTTY" },
{ O_TRUNC, "O_TRUNC" },
{ O_APPEND, "O_APPEND" },
{ O_NONBLOCK, "O_NONBLOCK" },
{ O_NDELAY, "O_NDELAY" },
{ O_SYNC, "O_SYNC" },
{ O_ASYNC, "O_ASYNC" },
{ O_LARGEFILE, "O_LARGEFILE" },
{ O_DIRECTORY, "O_DIRECTORY" },
{ O_NOFOLLOW, "O_NOFOLLOW" },
{ O_CLOEXEC, "O_CLOEXEC" },
{ O_DIRECT, "O_DIRECT" },
{ O_NOATIME, "O_NOATIME" },
{ O_PATH, "O_PATH" },
{ O_DSYNC, "O_DSYNC" },
{ O_TMPFILE, "O_TMPFILE" }
};

std::stringstream ss;
ss << "[";
if ((flags & O_RDONLY) != 0) {
ss << " O_RDONLY";
}
if ((flags & O_WRONLY) != 0) {
ss << " O_WRONLY";
}
if ((flags & O_RDWR) != 0) {
ss << " O_RDWR";
}
if ((flags & O_CREAT) != 0) {
ss << " O_CREAT";
}
if ((flags & O_EXCL) != 0) {
ss << " O_EXCL";
}
if ((flags & O_NOCTTY) != 0) {
ss << " O_NOCTTY";
}
if ((flags & O_TRUNC) != 0) {
ss << " O_TRUNC";
}
if ((flags & O_APPEND) != 0) {
ss << " O_APPEND";
}
if ((flags & O_NONBLOCK) != 0) {
ss << " O_NONBLOCK";
}
if ((flags & O_NDELAY) != 0) {
ss << " O_NDELAY";
}
if ((flags & O_SYNC) != 0) {
ss << " O_SYNC";
}
if ((flags & O_ASYNC) != 0) {
ss << " O_ASYNC";
}
if ((flags & O_LARGEFILE) != 0) {
ss << " O_LARGEFILE";
}
if ((flags & O_DIRECTORY) != 0) {
ss << " O_DIRECTORY";
}
if ((flags & O_NOFOLLOW) != 0) {
ss << " O_NOFOLLOW";
}
if ((flags & O_CLOEXEC) != 0) {
ss << " O_CLOEXEC";
}
if ((flags & O_DIRECT) != 0) {
ss << " O_DIRECT";
}
if ((flags & O_NOATIME) != 0) {
ss << " O_NOATIME";
}
if ((flags & O_PATH) != 0) {
ss << " O_PATH";
}
if ((flags & O_DSYNC) != 0) {
ss << " O_DSYNC";
}
if ((flags & O_TMPFILE) == O_TMPFILE) {
ss << " O_TMPFILE";
for (const auto& info : flagInfos) {
if ((flags & info.mask) == info.mask) {
ss << " " << info.name;
}
}
ss << " ]";
return ss.str();

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The function inspect_fcntl_or_open_flags iterates over all possible flags even after all flags have been matched. This results in unnecessary processing and can affect performance, especially with a large number of flags.

Recommendation:
Implement a mechanism to break out of the loop once all flags have been matched. This could involve keeping a count of matched flags and comparing it against the number of flags set in the input. This optimization will reduce the number of iterations and improve the function's performance.

Comment on lines +74 to 75
static const char *const result = getenv("LINYAPS_BOX_LOG_FORCE_STDERR");
return result != nullptr;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The use of getenv in a potentially multi-threaded environment can lead to race conditions, as getenv is not thread-safe. This could result in undefined behavior if environment variables are modified concurrently.

Recommendation:
Consider using a thread-safe alternative or ensure that environment variables are not modified after the program starts. Additionally, caching the result of getenv after the first call can prevent repeated environment lookups, improving performance.

Comment on lines +268 to +303
static linyaps_box::config::process_t parse_process(const nlohmann::json &j,
const nlohmann::json::json_pointer &ptr)
{
linyaps_box::config::process_t proc;
if (j.contains(ptr / "process" / "terminal")) {
proc.terminal = j[ptr / "process" / "terminal"].get<bool>();
}
if (proc.terminal && j.contains(ptr / "process" / "consoleSize")) {
proc.console.height = j[ptr / "process" / "consoleSize" / "height"].get<uint>();
proc.console.width = j[ptr / "process" / "consoleSize" / "width"].get<uint>();
}
proc.cwd = j[ptr / "process" / "cwd"].get<std::string>();
if (j.contains(ptr / "process" / "env")) {
auto env = j[ptr / "process" / "env"].get<std::vector<std::string>>();
for (const auto &e : env) {
auto pos = e.find('=');
if (pos == std::string::npos) {
throw std::runtime_error("invalid env entry: " + e);
}
}
proc.env = std::move(env);
}
proc.args = j[ptr / "process" / "args"].get<std::vector<std::string>>();
if (auto rlimits = ptr / "process" / "rlimits"; j.contains(rlimits)) {
proc.rlimits = parse_rlimits(j, rlimits);
}
#ifdef LINYAPS_BOX_ENABLE_CAP
if (auto cap = ptr / "process" / "capabilities"; j.contains(cap)) {
proc.capabilities = parse_capability(j, cap);
}
#endif
if (j.contains(ptr / "process" / "noNewPrivileges")) {
proc.no_new_privileges = j[ptr / "process" / "noNewPrivileges"].get<bool>();
}
return proc;
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Error Handling and Security Concern

The function parse_process lacks robust error handling for malformed environment variables. If an environment variable string does not contain an '=' character, it throws a runtime error (line 285), which could be exploited to cause a denial of service if the input is not controlled.

Recommendation:

  • Implement more comprehensive validation of the input JSON structure before processing. Consider using a schema validation library to ensure all inputs meet expected formats and contain necessary characters like '=' in environment variables. This would prevent the application from throwing runtime errors unexpectedly and improve the overall security and stability of the configuration parsing.

@@ -265,6 +265,43 @@ linyaps_box::config::linux_t parse_linux(const nlohmann::json &obj,
return linux;
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maintainability and Modularity Issue

The parse_linux function handles multiple aspects of the Linux configuration parsing, making it lengthy and complex. This decreases maintainability and readability.

Recommendation:

  • Refactor parse_linux into smaller, more focused functions. Each function should handle a specific part of the Linux configuration, such as parsing user IDs, group IDs, or namespaces. This modular approach would make the code easier to manage, test, and debug.

@ComixHe ComixHe closed this Jul 23, 2025
@ComixHe
ComixHe deleted the deepsource-transform-4b2423d5 branch July 7, 2026 06:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant