mirror of
https://github.com/fastfetch-cli/fastfetch.git
synced 2026-11-01 02:22:52 +01:00
Global: fixes a lot bugs found by AI
This commit is contained in:
@@ -85,11 +85,29 @@ void ffPrepareCommandOption(FFdata* data) {
|
||||
#define FF_IF_MODULE_MATCH(moduleNameConstant) if (ffStrEqualsIgnCase(moduleType, moduleNameConstant) && !ffStrbufSeparatedContainIgnCaseS(&data->structureDisabled, moduleNameConstant, ':'))
|
||||
|
||||
switch (moduleType[0]) {
|
||||
#if !FF_MODULE_DISABLE_CPUUSAGE
|
||||
#if !FF_MODULE_DISABLE_CPUUSAGE || !FF_MODULE_DISABLE_COMMAND
|
||||
case 'C':
|
||||
case 'c':
|
||||
#endif
|
||||
#if !FF_MODULE_DISABLE_CPUUSAGE
|
||||
FF_IF_MODULE_MATCH(ffCPUUsageModuleInfo.name)
|
||||
ffPrepareCPUUsage(); // The rate is derived from the CPU's own counters; no options are involved
|
||||
#endif
|
||||
|
||||
#if !FF_MODULE_DISABLE_COMMAND
|
||||
FF_IF_MODULE_MATCH(ffCommandModuleInfo.name) {
|
||||
// `command` runs its shell commands in parallel: `ffPrepareCommand` spawns them here,
|
||||
// in the prepare pass, and `ffDetectCommand` collects them in the print pass. The
|
||||
// command line itself can only be read from the JSON config, and this code path does
|
||||
// not consult it, so nothing would ever be queued and the module would report an
|
||||
// internal error marker. Refuse it up front instead of letting it get that far.
|
||||
fputs("Error: module `command` is not supported with `--structure`\n", stderr);
|
||||
fputs(" Its options can only be read from the JSON config, which `--structure` bypasses.\n", stderr);
|
||||
fputs(" Add it to the config instead, e.g. `{ \"modules\": [ { \"type\": \"command\", \"text\": \"uname -r\" } ] }`\n", stderr);
|
||||
exit(481);
|
||||
}
|
||||
#endif
|
||||
#if !FF_MODULE_DISABLE_CPUUSAGE || !FF_MODULE_DISABLE_COMMAND
|
||||
break;
|
||||
#endif
|
||||
|
||||
|
||||
@@ -329,6 +329,10 @@ FFNativeFD ffGetNullFD(void) {
|
||||
return hNullFile;
|
||||
}
|
||||
|
||||
bool ffIsTerminal(int fd) {
|
||||
return isatty(fd) != 0;
|
||||
}
|
||||
|
||||
bool ffRemoveFile(const char* fileName) {
|
||||
return unlink(fileName) == 0;
|
||||
}
|
||||
|
||||
@@ -500,6 +500,17 @@ FFNativeFD ffGetNullFD(void) {
|
||||
return hNullFile;
|
||||
}
|
||||
|
||||
bool ffIsTerminal(int fd) {
|
||||
intptr_t handle = _get_osfhandle(fd);
|
||||
if (handle == -1 || handle == -2) {
|
||||
// -1: an invalid fd; -2: a valid fd with no file behind it (`_get_osfhandle`'s way of
|
||||
// saying FF_INVALID_FD). Neither is a terminal.
|
||||
return false;
|
||||
}
|
||||
DWORD mode;
|
||||
return GetConsoleMode((HANDLE) handle, &mode) != 0;
|
||||
}
|
||||
|
||||
bool ffRemoveFile(const char* fileName) {
|
||||
wchar_t fileNameW[MAX_PATH];
|
||||
ULONG len;
|
||||
|
||||
@@ -60,6 +60,22 @@ void ffJsonConfigGenerateModuleArgsConfig(yyjson_mut_doc* doc, yyjson_mut_val* m
|
||||
}
|
||||
}
|
||||
|
||||
bool ffJsonConfigParseUInt32(yyjson_val* val, uint32_t* result, uint32_t max) {
|
||||
if (!yyjson_is_int(val)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// `yyjson_get_sint()` is exact for every value that fits into `int64_t`, and is negative for the
|
||||
// `uint64_t` values above `INT64_MAX`, which no caller accepts anyway.
|
||||
int64_t num = unsafe_yyjson_get_sint(val);
|
||||
if (num < 0 || (uint64_t) num > max) {
|
||||
return false;
|
||||
}
|
||||
|
||||
*result = (uint32_t) num;
|
||||
return true;
|
||||
}
|
||||
|
||||
const char* ffJsonConfigParseEnum(yyjson_val* val, int* result, FFKeyValuePair pairs[]) {
|
||||
if (yyjson_is_int(val)) {
|
||||
int intVal = yyjson_get_int(val);
|
||||
@@ -311,6 +327,16 @@ static const char* printJsonConfig(FFdata* data, bool prepare) {
|
||||
if (!unsafe_yyjson_is_bool(previousSucceeded)) {
|
||||
return "Property 'succeeded' in 'condition' must be a boolean";
|
||||
}
|
||||
if (prepare) {
|
||||
// Whether this module is printed at all depends on the result of the previous
|
||||
// one, which is only known in the print pass. Preparing it here would leave a
|
||||
// result behind that no print pass ever consumes, and since the modules are
|
||||
// paired by position (see `ffPrepareCommand` / `ffDetectCommand`), that
|
||||
// would silently shift every later module onto the wrong result.
|
||||
// Skip it, and let the module report the missing preparation if it turns out
|
||||
// to be printed after all.
|
||||
continue;
|
||||
}
|
||||
if (succeeded != unsafe_yyjson_get_bool(previousSucceeded)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
#include "common/textModifier.h"
|
||||
#include "logo/logo.h"
|
||||
|
||||
void ffPrintLogoAndKey(const char* moduleName, uint8_t moduleIndex, const FFModuleArgs* moduleArgs, FFPrintType printType) {
|
||||
void ffPrintLogoAndKey(const char* moduleName, uint32_t moduleIndex, const FFModuleArgs* moduleArgs, FFPrintType printType) {
|
||||
ffLogoPrintLine();
|
||||
|
||||
// This is used by --set-keyless, in this case we want neither the module name nor the separator
|
||||
@@ -40,7 +40,7 @@ void ffPrintLogoAndKey(const char* moduleName, uint8_t moduleIndex, const FFModu
|
||||
fputs(moduleName, stdout);
|
||||
|
||||
if (moduleIndex > 0) {
|
||||
printf(" %hhu", moduleIndex);
|
||||
printf(" %u", moduleIndex);
|
||||
}
|
||||
} else {
|
||||
FF_STRBUF_AUTO_DESTROY key = ffStrbufCreate();
|
||||
@@ -82,7 +82,7 @@ void ffPrintLogoAndKey(const char* moduleName, uint8_t moduleIndex, const FFModu
|
||||
}
|
||||
}
|
||||
|
||||
bool ffPrintFormat(const char* moduleName, uint8_t moduleIndex, const FFModuleArgs* moduleArgs, FFPrintType printType, uint32_t numArgs, const FFformatarg* arguments) {
|
||||
bool ffPrintFormat(const char* moduleName, uint32_t moduleIndex, const FFModuleArgs* moduleArgs, FFPrintType printType, uint32_t numArgs, const FFformatarg* arguments) {
|
||||
FF_STRBUF_AUTO_DESTROY buffer = ffStrbufCreate();
|
||||
bool success;
|
||||
if (__builtin_expect(moduleArgs != nullptr, 1)) {
|
||||
@@ -102,7 +102,7 @@ bool ffPrintFormat(const char* moduleName, uint8_t moduleIndex, const FFModuleAr
|
||||
return success;
|
||||
}
|
||||
|
||||
void ffPrintError(const char* moduleName, uint8_t moduleIndex, const FFModuleArgs* moduleArgs, FFPrintType printType, const char* message, ...) {
|
||||
void ffPrintError(const char* moduleName, uint32_t moduleIndex, const FFModuleArgs* moduleArgs, FFPrintType printType, const char* message, ...) {
|
||||
if (!instance.config.display.showErrors) {
|
||||
return;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user