Skip to content

Commit

Permalink
config: return an error on an invalid hex value
Browse files Browse the repository at this point in the history
  • Loading branch information
MAKMED1337 committed Sep 1, 2024
1 parent 38d0680 commit e830700
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 23 deletions.
32 changes: 22 additions & 10 deletions src/config.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include "config.hpp"
#include <filesystem>
#include <fstream>
#include <stdexcept>
#include <string>
#include <format>
#include <algorithm>
Expand Down Expand Up @@ -160,14 +161,19 @@ void CConfig::commence() {
}

static std::expected<int64_t, std::string> configStringToInt(const std::string& VALUE) {
auto parseHex = [](const std::string& value) -> std::expected<int64_t, std::string> {
try {
size_t position;
auto result = stoll(value, &position, 16);
if (position == value.size())
return result;
} catch (std::out_of_range) { return std::unexpected("hex " + value + " is too big"); } catch (...) {
}
return std::unexpected("invalid hex " + value);
};
if (VALUE.starts_with("0x")) {
// Values with 0x are hex
size_t position;
auto result = stoll(VALUE, &position, 16);
if (position == VALUE.size())
return result;

return std::unexpected("invalid hex " + VALUE);
return parseHex(VALUE);
} else if (VALUE.starts_with("rgba(") && VALUE.ends_with(')')) {
const auto VALUEWITHOUTFUNC = trim(VALUE.substr(5, VALUE.length() - 6));

Expand All @@ -191,10 +197,13 @@ static std::expected<int64_t, std::string> configStringToInt(const std::string&

return a * (Hyprlang::INT)0x1000000 + r.value() * (Hyprlang::INT)0x10000 + g.value() * (Hyprlang::INT)0x100 + b.value();
} else if (VALUEWITHOUTFUNC.length() == 8) {
const auto RGBA = std::stoll(VALUEWITHOUTFUNC, nullptr, 16);
const auto RGBA = parseHex(VALUEWITHOUTFUNC);

if (!RGBA.has_value())
return RGBA;

// now we need to RGBA -> ARGB. The config holds ARGB only.
return (RGBA >> 8) + 0x1000000 * (RGBA & 0xFF);
return (RGBA.value() >> 8) + 0x1000000 * (RGBA.value() & 0xFF);
}

return std::unexpected("rgba() expects length of 8 characters (4 bytes) or 4 comma separated values");
Expand All @@ -217,9 +226,12 @@ static std::expected<int64_t, std::string> configStringToInt(const std::string&

return (Hyprlang::INT)0xFF000000 + r.value() * (Hyprlang::INT)0x10000 + g.value() * (Hyprlang::INT)0x100 + b.value();
} else if (VALUEWITHOUTFUNC.length() == 6) {
const auto RGB = std::stoll(VALUEWITHOUTFUNC, nullptr, 16);
const auto RGB = parseHex(VALUEWITHOUTFUNC);

if (!RGB.has_value())
return RGB;

return RGB + 0xFF000000;
return RGB.value() + 0xFF000000;
}

return std::unexpected("rgb() expects length of 6 characters (3 bytes) or 3 comma separated values");
Expand Down
5 changes: 0 additions & 5 deletions tests/config/error2.conf

This file was deleted.

15 changes: 15 additions & 0 deletions tests/config/invalid-numbers.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Every number/color in this file is invalid

invalidHex = 0x1Q
emptyHex = 0x
hugeHex = 0xFFFFFFFFFFFFFFFF

invalidInt = 1A
emptyInt =

invalidColor = rgb(ABCDEQ)
invalidFirstCharColor = rgb(QABCDE)

invalidColorAlpha = rgba(9ABCDEFQ)
invalidFirstCharColorAlpha = rgba(Q9ABCDEF)

23 changes: 15 additions & 8 deletions tests/parse/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -279,17 +279,24 @@ int main(int argc, char** argv, char** envp) {
const auto ERRORSTR = std::string{ERRORS.getError()};
EXPECT(std::count(ERRORSTR.begin(), ERRORSTR.end(), '\n'), 1);

std::cout << " → Testing error2.conf\n";
Hyprlang::CConfig errorConfig2("./config/error2.conf", {.throwAllErrors = true});
errorConfig2.addConfigValue("invalidHex", (Hyprlang::INT)0);
errorConfig2.addConfigValue("emptyHex", (Hyprlang::INT)0);

errorConfig2.commence();
const auto ERRORS2 = errorConfig2.parse();
std::cout << " → Testing invalid-numbers.conf\n";
Hyprlang::CConfig invalidNumbersConfig("./config/invalid-numbers.conf", {.throwAllErrors = true});
invalidNumbersConfig.addConfigValue("invalidHex", (Hyprlang::INT)0);
invalidNumbersConfig.addConfigValue("emptyHex", (Hyprlang::INT)0);
invalidNumbersConfig.addConfigValue("hugeHex", (Hyprlang::INT)0);
invalidNumbersConfig.addConfigValue("invalidInt", (Hyprlang::INT)0);
invalidNumbersConfig.addConfigValue("emptyInt", (Hyprlang::INT)0);
invalidNumbersConfig.addConfigValue("invalidColor", (Hyprlang::INT)0);
invalidNumbersConfig.addConfigValue("invalidFirstCharColor", (Hyprlang::INT)0);
invalidNumbersConfig.addConfigValue("invalidColorAlpha", (Hyprlang::INT)0);
invalidNumbersConfig.addConfigValue("invalidFirstCharColorAlpha", (Hyprlang::INT)0);

invalidNumbersConfig.commence();
const auto ERRORS2 = invalidNumbersConfig.parse();

EXPECT(ERRORS2.error, true);
const auto ERRORSTR2 = std::string{ERRORS2.getError()};
EXPECT(std::count(ERRORSTR2.begin(), ERRORSTR2.end(), '\n'), 1);
EXPECT(std::count(ERRORSTR2.begin(), ERRORSTR2.end(), '\n'), 9 - 1);
} catch (const char* e) {
std::cout << Colors::RED << "Error: " << Colors::RESET << e << "\n";
return 1;
Expand Down

0 comments on commit e830700

Please sign in to comment.