ffGetFileContent now uses FFstrbuf for preventing buffer overflows

This commit is contained in:
Linus Dierheimer
2021-03-21 16:52:17 +01:00
parent 0d3500c66f
commit 101d19a015
24 changed files with 144 additions and 123 deletions
+19 -18
View File
@@ -232,26 +232,23 @@ void ffTrimTrailingWhitespace(char* buffer)
buffer[end + 1] = '\0';
}
void ffGetFileContent(const char* fileName, char* buffer, uint32_t bufferSize)
void ffGetFileContent(const char* fileName, FFstrbuf* buffer)
{
buffer[0] = '\0';
int fd = open(fileName, O_RDONLY);
if(fd == -1)
return;
ssize_t readed = read(fd, buffer, bufferSize - 1);
if(readed < 1)
return;
ssize_t readed;
while((readed = read(fd, buffer->chars, buffer->allocated)) == buffer->allocated && readed > 0)
ffStrbufEnsureCapacity(buffer, buffer->allocated * 2);
if(readed >= 0)
buffer->length = readed;
ffStrbufTrimRight(buffer, '\n');
ffStrbufTrimRight(buffer, ' ');
close(fd);
if(buffer[readed - 1] == '\n')
buffer[readed - 1] = '\0';
else
buffer[readed] = '\0';
ffTrimTrailingWhitespace(buffer);
}
static const char* getCacheDir(FFinstance* instance)
@@ -289,17 +286,21 @@ bool ffPrintCachedValue(FFinstance* instance, const char* key)
FFstrbuf filename;
ffStrbufInitF(&filename, "%s%s", getCacheDir(instance), key);
char value[1024];
ffGetFileContent(filename.chars, value, sizeof(value));
FF_STRBUF_CREATE(value);
ffGetFileContent(filename.chars, &value);
ffStrbufDestroy(&filename);
if(value[0] == '\0')
if(ffStrbufIsEmpty(&value))
{
ffStrbufDestroy(&value);
return false;
}
ffPrintLogoAndKey(instance, key);
puts(value);
ffStrbufWriteTo(&value, stdout);
putchar('\n');
ffStrbufDestroy(&value);
return true;
}
+1 -1
View File
@@ -116,7 +116,7 @@ void ffInitState(FFstate* state);
void ffDefaultConfig(FFconfig* config);
void ffPrintKey(FFconfig* config, const char* key);
void ffPrintLogoAndKey(FFinstance* instance, const char* key);
void ffGetFileContent(const char* fileName, char* buffer, uint32_t bufferSize);
void ffGetFileContent(const char* fileName, FFstrbuf* buffer);
void ffParsePropFile(const char* file, const char* regex, char* buffer);
void ffParsePropFileHome(FFinstance* instance, const char* relativeFile, const char* regex, char* buffer);
void ffParseFont(char* font, char* buffer);
+42 -31
View File
@@ -4,36 +4,42 @@
static void printBattery(FFinstance* instance, uint8_t index)
{
char manufactor[128];
FF_STRBUF_CREATE(manufactor);
char manufactorPath[42];
sprintf(manufactorPath, "/sys/class/power_supply/BAT%i/manufacturer", index);
ffGetFileContent(manufactorPath, manufactor, sizeof(manufactor));
ffGetFileContent(manufactorPath, &manufactor);
char model[128];
FF_STRBUF_CREATE(model);
char modelPath[40];
sprintf(modelPath, "/sys/class/power_supply/BAT%i/model_name", index);
ffGetFileContent(modelPath, model, sizeof(model));
ffGetFileContent(modelPath, &model);
char technology[32];
FF_STRBUF_CREATE(technology);
char technologyPath[40];
sprintf(technologyPath, "/sys/class/power_supply/BAT%i/technology", index);
ffGetFileContent(technologyPath, technology, sizeof(technology));
ffGetFileContent(technologyPath, &technology);
char capacity[32];
FF_STRBUF_CREATE(capacity);
char capacityPath[38];
sprintf(capacityPath, "/sys/class/power_supply/BAT%i/capacity", index);
ffGetFileContent(capacityPath, capacity, sizeof(capacity));
ffGetFileContent(capacityPath, &capacity);
char status[32];
FF_STRBUF_CREATE(status);
char statusPath[36];
sprintf(statusPath, "/sys/class/power_supply/BAT%i/status", index);
ffGetFileContent(statusPath, status, sizeof(status));
ffGetFileContent(statusPath, &status);
char key[10];
sprintf(key, "Battery %i", index);
if(manufactor[0] == '\0' && model[0] == '\0' && technology[0] == '\0' && capacity[0] == '\0' && status[0] == '\0' && ffStrbufIsEmpty(&instance->config.batteryFormat))
{
if(
ffStrbufIsEmpty(&manufactor) &&
ffStrbufIsEmpty(&model) &&
ffStrbufIsEmpty(&technology) &&
ffStrbufIsEmpty(&capacity) &&
ffStrbufIsEmpty(&status) &&
ffStrbufIsEmpty(&instance->config.batteryFormat)
) {
ffPrintError(instance, key, "No file in /sys/class/power_supply/BAT0/ could be read or all battery options are disabled");
return;
}
@@ -42,49 +48,54 @@ static void printBattery(FFinstance* instance, uint8_t index)
if(ffStrbufIsEmpty(&instance->config.batteryFormat))
{
if(manufactor[0] != '\0')
printf("%s ", manufactor);
if(!ffStrbufIsEmpty(&manufactor))
printf("%s ", manufactor.chars);
if(model[0] != '\0')
printf("%s ", model);
if(!ffStrbufIsEmpty(&model))
printf("%s ", manufactor.chars);
if(technology[0] != '\0')
printf("(%s) ", technology);
if(!ffStrbufIsEmpty(&technology))
printf("(%s) ", technology.chars);
if(capacity[0] != '\0')
if(!ffStrbufIsEmpty(&capacity))
{
printf("[%s%%", capacity);
printf("[%s%%", capacity.chars);
if(status[0] == '\0')
if(ffStrbufIsEmpty(&status))
puts("]");
else
printf("; %s]\n", status);
printf("; %s]\n", status.chars);
}
else
{
if(status[0] != '\0')
printf("%s", status);
if(!ffStrbufIsEmpty(&status))
printf("[%s]", status.chars);
else
putchar('\n');
}
}
else
{
FFstrbuf battery;
ffStrbufInit(&battery);
FF_STRBUF_CREATE(battery);
ffParseFormatString(&battery, &instance->config.batteryFormat, 5,
(FFformatarg){FF_FORMAT_ARG_TYPE_STRING, manufactor},
(FFformatarg){FF_FORMAT_ARG_TYPE_STRING, model},
(FFformatarg){FF_FORMAT_ARG_TYPE_STRING, technology},
(FFformatarg){FF_FORMAT_ARG_TYPE_STRING, capacity},
(FFformatarg){FF_FORMAT_ARG_TYPE_STRING, status}
(FFformatarg){FF_FORMAT_ARG_TYPE_STRBUF, &manufactor},
(FFformatarg){FF_FORMAT_ARG_TYPE_STRBUF, &model},
(FFformatarg){FF_FORMAT_ARG_TYPE_STRBUF, &technology},
(FFformatarg){FF_FORMAT_ARG_TYPE_STRBUF, &capacity},
(FFformatarg){FF_FORMAT_ARG_TYPE_STRBUF, &status}
);
ffStrbufWriteTo(&battery, stdout);
putchar('\n');
ffStrbufDestroy(&battery);
}
ffStrbufDestroy(&manufactor);
ffStrbufDestroy(&model);
ffStrbufDestroy(&technology);
ffStrbufDestroy(&capacity);
ffStrbufDestroy(&status);
}
void ffPrintBattery(FFinstance* instance)
+1 -2
View File
@@ -35,8 +35,7 @@ void ffPrintCPU(FFinstance* instance)
ffPrintLogoAndKey(instance, "CPU");
FFstrbuf cpu;
ffStrbufInit(&cpu);
FF_STRBUF_CREATE(cpu);
if(ffStrbufIsEmpty(&instance->config.cpuFormat))
{
+3 -7
View File
@@ -17,11 +17,8 @@ void ffPrintDesktopEnvironment(FFinstance* instance)
if(ffStrbufIsEmpty(&sessionDesktop))
ffStrbufSetS(&sessionDesktop, getenv("XDG_SESSION_DESKTOP"));
FFstrbuf sessionVersion;
ffStrbufInit(&sessionVersion);
FFstrbuf sessionType;
ffStrbufInit(&sessionType);
FF_STRBUF_CREATE(sessionVersion);
FF_STRBUF_CREATE(sessionType);
if(ffStrbufIgnCaseCompS(&sessionDesktop, "KDE") == 0)
getKDE(&sessionDesktop, &sessionVersion, &sessionType);
@@ -72,8 +69,7 @@ void ffPrintDesktopEnvironment(FFinstance* instance)
{
ffPrintLogoAndKey(instance, "DE");
FFstrbuf de;
ffStrbufInit(&de);
FF_STRBUF_CREATE(de);
ffParseFormatString(&de, &instance->config.deFormat, 3,
(FFformatarg){FF_FORMAT_ARG_TYPE_STRBUF, &sessionDesktop},
+1 -2
View File
@@ -27,8 +27,7 @@ void ffPrintDisk(FFinstance* instance)
}
else
{
FFstrbuf disk;
ffStrbufInit(&disk);
FF_STRBUF_CREATE(disk);
ffParseFormatString(&disk, &instance->config.diskFormat, 3,
(FFformatarg){FF_FORMAT_ARG_TYPE_UINT, &used},
+2 -4
View File
@@ -38,8 +38,7 @@ void ffPrintFont(FFinstance* instance)
else
ffParseFont(gtk4, gtk4Pretty);
FFstrbuf gtkPretty;
ffStrbufInit(&gtkPretty);
FF_STRBUF_CREATE(gtkPretty);
ffFormatGtkPretty(&gtkPretty, gtk2Pretty, gtk3Pretty, gtk4Pretty);
ffPrintLogoAndKey(instance, "Font");
@@ -51,8 +50,7 @@ void ffPrintFont(FFinstance* instance)
}
else
{
FFstrbuf font;
ffStrbufInit(&font);
FF_STRBUF_CREATE(font);
ffParseFormatString(&font, &instance->config.fontFormat, 5,
(FFformatarg){FF_FORMAT_ARG_TYPE_STRING, plasmaPretty},
+1 -2
View File
@@ -11,8 +11,7 @@ static void handleGPU(FFinstance* instance, struct pci_access* pacc, struct pci_
if(ffPrintCachedValue(instance, key))
return;
FFstrbuf gpu;
ffStrbufInit(&gpu);
FF_STRBUF_CREATE(gpu);
char vendor[512];
ffpci_lookup_name(pacc, vendor, sizeof(vendor), PCI_LOOKUP_VENDOR, dev->vendor_id, dev->device_id);
+20 -17
View File
@@ -5,16 +5,16 @@ void ffPrintHost(FFinstance* instance)
if(ffPrintCachedValue(instance, "Host"))
return;
char family[256];
ffGetFileContent("/sys/devices/virtual/dmi/id/product_family", family, sizeof(family));
FF_STRBUF_CREATE(family);
ffGetFileContent("/sys/devices/virtual/dmi/id/product_family", &family);
char name[256];
ffGetFileContent("/sys/devices/virtual/dmi/id/product_name", name, sizeof(name));
FF_STRBUF_CREATE(name);
ffGetFileContent("/sys/devices/virtual/dmi/id/product_name", &name);
char version[256];
ffGetFileContent("/sys/devices/virtual/dmi/id/product_version", version, sizeof(version));
FF_STRBUF_CREATE(version);
ffGetFileContent("/sys/devices/virtual/dmi/id/product_version", &version);
if(family[0] == '\0' && name[0] == '\0')
if(ffStrbufIsEmpty(&family) && ffStrbufIsEmpty(&name) && ffStrbufIsEmpty(&instance->config.hostFormat))
{
ffPrintError(instance, "Host", "neither family nor name could be determined");
return;
@@ -22,30 +22,33 @@ void ffPrintHost(FFinstance* instance)
ffPrintLogoAndKey(instance, "Host");
FFstrbuf host;
ffStrbufInit(&host);
FF_STRBUF_CREATE(host);
if(!ffStrbufIsEmpty(&instance->config.hostFormat))
{
ffParseFormatString(&host, &instance->config.hostFormat, 3,
(FFformatarg){FF_FORMAT_ARG_TYPE_STRING, family},
(FFformatarg){FF_FORMAT_ARG_TYPE_STRING, name},
(FFformatarg){FF_FORMAT_ARG_TYPE_STRING, version}
(FFformatarg){FF_FORMAT_ARG_TYPE_STRBUF, &family},
(FFformatarg){FF_FORMAT_ARG_TYPE_STRBUF, &name},
(FFformatarg){FF_FORMAT_ARG_TYPE_STRBUF, &version}
);
}
else if(family[0] != '\0' && name[0] != '\0')
else if(!ffStrbufIsEmpty(&family) && !ffStrbufIsEmpty(&name))
{
ffStrbufSetF(&host, "%s %s %s", family, name, version);
ffStrbufSetF(&host, "%s %s %s", family.chars, name.chars, version.chars);
}
else if(family[0] != '\0')
else if(!ffStrbufIsEmpty(&family))
{
ffStrbufSetF(&host, "%s %s", family, version);
ffStrbufSetF(&host, "%s %s", family.chars, version.chars);
}
else
{
ffStrbufSetF(&host, "%s %s", name, version);
ffStrbufSetF(&host, "%s %s", name.chars, version.chars);
}
ffPrintAndSaveCachedValue(instance, "Host", host.chars);
ffStrbufDestroy(&host);
ffStrbufDestroy(&family);
ffStrbufDestroy(&name);
ffStrbufDestroy(&version);
}
+3 -5
View File
@@ -20,8 +20,7 @@ void ffPrintIcons(FFinstance* instance)
if(gtk4[0] == '\0')
strcpy(gtk4, "Adwaita");
FFstrbuf gtkPretty;
ffStrbufInit(&gtkPretty);
FF_STRBUF_CREATE(gtkPretty);
ffFormatGtkPretty(&gtkPretty, gtk2, gtk3, gtk4);
ffPrintLogoAndKey(instance, "Icons");
@@ -37,9 +36,8 @@ void ffPrintIcons(FFinstance* instance)
}
else
{
FFstrbuf icons;
ffStrbufInit(&icons);
FF_STRBUF_CREATE(icons);
ffParseFormatString(&icons, &instance->config.iconsFormat, 5,
(FFformatarg){FF_FORMAT_ARG_TYPE_STRING, plasma},
(FFformatarg){FF_FORMAT_ARG_TYPE_STRING, gtk2},
+1 -2
View File
@@ -9,8 +9,7 @@ void ffPrintKernel(FFinstance* instance)
return;
}
FFstrbuf kernel;
ffStrbufInit(&kernel);
FF_STRBUF_CREATE(kernel);
ffParseFormatString(&kernel, &instance->config.kernelFormat, 3,
(FFformatarg){FF_FORMAT_ARG_TYPE_STRING, instance->state.utsname.sysname},
+1 -2
View File
@@ -41,8 +41,7 @@ void ffPrintLocale(FFinstance* instance)
ffPrintLogoAndKey(instance, "Locale");
FFstrbuf locale;
ffStrbufInit(&locale);
FF_STRBUF_CREATE(locale);
if(ffStrbufIsEmpty(&instance->config.localeFormat))
{
+1 -2
View File
@@ -38,8 +38,7 @@ void ffPrintMemory(FFinstance* instance)
}
else
{
FFstrbuf memory;
ffStrbufInit(&memory);
FF_STRBUF_CREATE(memory);
ffParseFormatString(&memory, &instance->config.memoryFormat, 3,
(FFformatarg){FF_FORMAT_ARG_TYPE_UINT, &used_mem},
+1 -2
View File
@@ -15,8 +15,7 @@ void ffPrintOS(FFinstance* instance)
ffPrintLogoAndKey(instance, "OS");
FFstrbuf os;
ffStrbufInit(&os);
FF_STRBUF_CREATE(os);
if(!ffStrbufIsEmpty(&instance->config.osFormat))
{
+1 -2
View File
@@ -57,8 +57,7 @@ void ffPrintPackages(FFinstance* instance)
return;
}
FFstrbuf packages;
ffStrbufInit(&packages);
FF_STRBUF_CREATE(packages);
ffParseFormatString(&packages, &instance->config.packagesFormat, 3,
(FFformatarg){FF_FORMAT_ARG_TYPE_UINT, &all},
+1 -2
View File
@@ -76,8 +76,7 @@ void ffPrintResolution(FFinstance* instance)
ffPrintLogoAndKey(instance, "Resolution");
FFstrbuf resolution;
ffStrbufInit(&resolution);
FF_STRBUF_CREATE(resolution);
if(!ffStrbufIsEmpty(&instance->config.resolutionFormat))
{
+1 -2
View File
@@ -29,8 +29,7 @@ void ffPrintShell(FFinstance* instance)
ffPrintLogoAndKey(instance, "Shell");
FFstrbuf shell;
ffStrbufInit(&shell);
FF_STRBUF_CREATE(shell);
if(!ffStrbufIsEmpty(&instance->config.shellFormat))
{
+1 -2
View File
@@ -94,8 +94,7 @@ void ffPrintTerminal(FFinstance* instance)
}
else
{
FFstrbuf terminal;
ffStrbufInit(&terminal);
FF_STRBUF_CREATE(terminal);
ffParseFormatString(&terminal, &instance->config.terminalFormat, 1,
(FFformatarg){FF_FORMAT_ARG_TYPE_STRBUF, &instance->state.terminal.value}
+1 -2
View File
@@ -10,8 +10,7 @@ static void printTerminalFont(FFinstance* instance, char* font)
}
else
{
FFstrbuf termfont;
ffStrbufInit(&termfont);
FF_STRBUF_CREATE(termfont);
ffParseFormatString(&termfont, &instance->config.termFontFormat, 1,
(FFformatarg){FF_FORMAT_ARG_TYPE_STRING, font}
+4 -5
View File
@@ -20,9 +20,7 @@ void ffPrintTheme(FFinstance* instance)
if(gtk4[0] == '\0')
strcpy(gtk4, "Adwaita");
FFstrbuf gtkPretty;
ffStrbufInit(&gtkPretty);
FF_STRBUF_CREATE(gtkPretty);
ffFormatGtkPretty(&gtkPretty, gtk2, gtk3, gtk4);
ffPrintLogoAndKey(instance, "Theme");
@@ -36,8 +34,7 @@ void ffPrintTheme(FFinstance* instance)
}
else
{
FFstrbuf theme;
ffStrbufInit(&theme);
FF_STRBUF_CREATE(theme);
ffParseFormatString(&theme, &instance->config.themeFormat, 5,
(FFformatarg){FF_FORMAT_ARG_TYPE_STRING, plasma},
@@ -48,6 +45,8 @@ void ffPrintTheme(FFinstance* instance)
);
ffStrbufWriteTo(&theme, stdout);
ffStrbufDestroy(&theme);
}
putchar('\n');
+1 -3
View File
@@ -29,9 +29,7 @@ void ffPrintUptime(FFinstance* instance)
}
else
{
FFstrbuf uptime;
ffStrbufInit(&uptime);
FF_STRBUF_CREATE(uptime);
ffParseFormatString(&uptime, &instance->config.uptimeFormat, 4,
(FFformatarg){FF_FORMAT_ARG_TYPE_UINT, &days},
+4 -8
View File
@@ -23,8 +23,7 @@ void ffPrintWM(FFinstance* instance)
struct dirent* dirent;
FFstrbuf name;
ffStrbufInit(&name);
FF_STRBUF_CREATE(name);
bool found = false;
@@ -36,10 +35,7 @@ void ffPrintWM(FFinstance* instance)
char path[20];
sprintf(path, "/proc/%.8s/comm", dirent->d_name);
char comm[17]; //MAX_COMM_LENGTH is 17 + null terminator
ffGetFileContent(path, comm, sizeof(comm));
ffStrbufSetS(&name, comm);
ffGetFileContent(path, &name);
if((found = parseProcessName(&name)))
break;
@@ -60,8 +56,7 @@ void ffPrintWM(FFinstance* instance)
}
else
{
FFstrbuf wm;
ffStrbufInit(&wm);
FF_STRBUF_CREATE(wm);
ffParseFormatString(&wm, &instance->config.wmFormat, 1,
(FFformatarg){FF_FORMAT_ARG_TYPE_STRBUF, &name}
@@ -74,4 +69,5 @@ void ffPrintWM(FFinstance* instance)
}
putchar('\n');
ffStrbufDestroy(&name);
}
+27
View File
@@ -262,6 +262,33 @@ int ffStrbufIgnCaseCompNS(FFstrbuf* strbuf, uint32_t length, const char* comp)
return strncasecmp(strbuf->chars, comp, length);
}
void ffStrbufTrimLeft(FFstrbuf* strbuf, char c)
{
uint32_t index = 0;
while(strbuf->chars[index] == c && index < strbuf->length)
++index;
if(index == 0)
return;
memcpy(strbuf->chars, strbuf->chars + index, index);
strbuf->length -= index;
}
void ffStrbufTrimRight(FFstrbuf* strbuf, char c)
{
while(strbuf->length > 0 && strbuf->chars[strbuf->length - 1] == c)
--strbuf->length;
strbuf->chars[strbuf->length] = '\0';
}
void ffStrbufTrim(FFstrbuf* strbuf, char c)
{
ffStrbufTrimRight(strbuf, c);
ffStrbufTrimLeft(strbuf, c);
}
void ffStrbufDestroy(FFstrbuf* strbuf)
{
free(strbuf->chars);
+6
View File
@@ -17,6 +17,8 @@ typedef struct FFstrbuf
char* chars;
} FFstrbuf;
#define FF_STRBUF_CREATE(name) FFstrbuf name; ffStrbufInit(&name);
void ffStrbufInit(FFstrbuf* strbuf);
void ffStrbufInitS(FFstrbuf* strbuf, const char* value);
void ffStrbufInitNS(FFstrbuf* strbuf, uint32_t length, const char* value);
@@ -59,6 +61,10 @@ int ffStrbufIgnCaseComp(FFstrbuf* strbuf, FFstrbuf* comp);
int ffStrbufIgnCaseCompS(FFstrbuf* strbuf, const char* comp);
int ffStrbufIgnCaseCompNS(FFstrbuf* strbuf, uint32_t length, const char* comp);
void ffStrbufTrimLeft(FFstrbuf* strbuf, char c);
void ffStrbufTrimRight(FFstrbuf* strbuf, char c);
void ffStrbufTrim(FFstrbuf* strbuf, char c);
void ffStrbufDestroy(FFstrbuf* strbuf);
#endif