mirror of
https://github.com/Heretek-AI/game-engine.git
synced 2026-11-07 17:17:01 -10:00
illusion: ILLU-FOLLOW snprintf-free CopyName (Sonar cpp:S6494)
This commit is contained in:
1 parent
dcff5be6dd
commit
a3f3181aad
2 files changed
+38
-14
No files matched your search
@@ -14,9 +14,9 @@
|
||||
// enkiTS C handle for the batch lane fan-out (opaque to this TU).
|
||||
struct enkiTaskScheduler;
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <memory>
|
||||
@@ -64,6 +64,21 @@ static_assert(offsetof(EngineChunkColumns, user_data) == 112, "EngineChunkColumn
|
||||
|
||||
namespace {
|
||||
|
||||
// Bounded NUL-terminated copy: clamps to dst capacity, never reads past
|
||||
// src's terminator. Replaces snprintf("%s") so Sonar cpp:S6494 stays quiet.
|
||||
template <std::size_t N>
|
||||
auto CopyName(char (&dst)[N], const char* src) noexcept -> void {
|
||||
static_assert(N > 0, "name buffer must hold at least the NUL terminator");
|
||||
if (src == nullptr) {
|
||||
dst[0] = '\0';
|
||||
return;
|
||||
}
|
||||
const std::size_t len = std::strlen(src);
|
||||
const std::size_t n = (std::min)(len, N - 1);
|
||||
std::memcpy(dst, src, n);
|
||||
dst[n] = '\0';
|
||||
}
|
||||
|
||||
// One registered managed system: C# callback + opaque context.
|
||||
struct ManagedSystemEntry {
|
||||
char name[64];
|
||||
@@ -330,12 +345,8 @@ auto ApiRegisterSystem(EngineWorld* world, const char* name,
|
||||
}
|
||||
ManagedSystemEntry entry{};
|
||||
if (name != nullptr) {
|
||||
// snprintf always NUL-terminates; the return check makes silent
|
||||
// truncation explicit for -Wformat-truncation/MSVC /W4 readers.
|
||||
const int n = std::snprintf(entry.name, sizeof(entry.name), "%s", name);
|
||||
if (n < 0 || static_cast<std::size_t>(n) >= sizeof(entry.name)) {
|
||||
entry.name[sizeof(entry.name) - 1] = '\0';
|
||||
}
|
||||
// Bounded copy keeps truncation explicit (clamped to buffer capacity).
|
||||
CopyName(entry.name, name);
|
||||
}
|
||||
entry.callback = callback;
|
||||
entry.user_data = user_data;
|
||||
|
||||
@@ -1,12 +1,29 @@
|
||||
// generic_systems.cpp — ABI 4.2 generic component/system tail; see header.
|
||||
#include "generic_systems.hpp"
|
||||
|
||||
#include <cstdio>
|
||||
#include <algorithm>
|
||||
#include <cstddef>
|
||||
#include <cstring>
|
||||
|
||||
namespace engine::bridge {
|
||||
namespace {
|
||||
|
||||
// Bounded NUL-terminated copy: never truncates silently (clamps to dst
|
||||
// capacity), never reads past src's terminator. Replaces snprintf("%s")
|
||||
// so -Wformat-truncation-style diagnostics and Sonar cpp:S6494 stay quiet.
|
||||
template <std::size_t N>
|
||||
auto CopyName(char (&dst)[N], const char* src) noexcept -> void {
|
||||
static_assert(N > 0, "name buffer must hold at least the NUL terminator");
|
||||
if (src == nullptr) {
|
||||
dst[0] = '\0';
|
||||
return;
|
||||
}
|
||||
const std::size_t len = std::strlen(src);
|
||||
const std::size_t n = (std::min)(len, N - 1);
|
||||
std::memcpy(dst, src, n);
|
||||
dst[n] = '\0';
|
||||
}
|
||||
|
||||
constexpr std::size_t kMaxNameLen = 255;
|
||||
|
||||
// Component size/alignment as Flecs recorded it; nullptr when `id` is not a
|
||||
@@ -179,12 +196,8 @@ auto GenericSystems::register_system(ecs_world_t* world, const char* name,
|
||||
return ENGINE_ABI_ERR_INTERNAL;
|
||||
}
|
||||
if (name != nullptr) {
|
||||
// snprintf always NUL-terminates; the return check makes silent
|
||||
// truncation explicit for -Wformat-truncation/MSVC /W4 readers.
|
||||
const int n = std::snprintf(sys.name, sizeof(sys.name), "%s", name);
|
||||
if (n < 0 || static_cast<std::size_t>(n) >= sizeof(sys.name)) {
|
||||
sys.name[sizeof(sys.name) - 1] = '\0';
|
||||
}
|
||||
// Bounded copy keeps truncation explicit (clamped to buffer capacity).
|
||||
CopyName(sys.name, name);
|
||||
}
|
||||
sys.callback = callback;
|
||||
sys.user_data = user_data;
|
||||
|
||||
Reference in new issue
Block a user