Global: fixes a lot bugs found by AI

This commit is contained in:
Carter Li
2026-09-22 14:49:43 +08:00
committed by 李通洲
parent fe49a9624e
commit c26bace3c2
91 changed files with 563 additions and 282 deletions
+19 -1
View File
@@ -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
+4
View File
@@ -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;
}
+11
View File
@@ -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;
+26
View File
@@ -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;
}
+4 -4
View File
@@ -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;
}