From eb5be96aa0e401458dca3f6bc9fd3b94553efc01 Mon Sep 17 00:00:00 2001 From: EvilLary Date: Fri, 28 Nov 2025 19:52:41 +0300 Subject: [PATCH] core: fix crash with same name special category and keyword (#87) --------- Co-authored-by: Vaxry --- src/config.cpp | 6 +++++- tests/config/config.conf | 11 +++++++++++ tests/parse/main.cpp | 23 ++++++++++++++++++++++- 3 files changed, 38 insertions(+), 2 deletions(-) diff --git a/src/config.cpp b/src/config.cpp index 3e71742..c727bec 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -352,9 +352,13 @@ std::pair CConfig::configSetValueSafe(const std::string& com found = true; } + // probably a handler + if (!valueName.contains(":")) + return {false, result}; + if (!found) { for (auto& sc : impl->specialCategories) { - if (!valueName.starts_with(sc->name)) + if (!valueName.starts_with(sc->name + ":")) continue; if (!sc->isStatic && std::string{std::any_cast(sc->values[sc->key].getValue())} != impl->currentSpecialKey) diff --git a/tests/config/config.conf b/tests/config/config.conf index 3ff1146..096bf09 100644 --- a/tests/config/config.conf +++ b/tests/config/config.conf @@ -172,3 +172,14 @@ doABarrelRoll = woohoo, some, params # Funny! flagsabc = test #doSomethingFunny = 1, 2, 3, 4 # Funnier! #testSpaces = abc , def # many spaces, should be trimmed + +sameKeywordSpecialCat = pablo + +sameKeywordSpecialCat:two:hola = rose + +sameKeywordSpecialCat { + one { + some_size = 44 + some_radius = 7.6 + } +} diff --git a/tests/parse/main.cpp b/tests/parse/main.cpp index 07265a1..309040d 100644 --- a/tests/parse/main.cpp +++ b/tests/parse/main.cpp @@ -29,6 +29,7 @@ Hyprlang::CConfig* pConfig = nullptr; std::string currentPath = ""; std::string ignoreKeyword = ""; std::string useKeyword = ""; +std::string sameKeywordSpecialCat = ""; bool testHandlerDontOverrideValue = false; static std::vector categoryKeywordActualValues; @@ -75,6 +76,12 @@ static Hyprlang::CParseResult handleSource(const char* COMMAND, const char* VALU return pConfig->parseFile(PATH.c_str()); } +static Hyprlang::CParseResult handleSameKeywordSpecialCat(const char* COMMAND, const char* VALUE) { + sameKeywordSpecialCat = VALUE; + + return Hyprlang::CParseResult(); +} + static Hyprlang::CParseResult handleTestHandlerDontOverride(const char* COMMAND, const char* VALUE) { testHandlerDontOverrideValue = true; @@ -82,7 +89,6 @@ static Hyprlang::CParseResult handleTestHandlerDontOverride(const char* COMMAND, return result; } - static Hyprlang::CParseResult handleCustomValueSet(const char* VALUE, void** data) { if (!*data) *data = calloc(1, sizeof(int64_t)); @@ -176,8 +182,17 @@ int main(int argc, char** argv, char** envp) { config.addConfigValue("multiline", ""); + config.registerHandler(&handleSameKeywordSpecialCat, "sameKeywordSpecialCat", {.allowFlags = false}); + config.addSpecialCategory("sameKeywordSpecialCat", {.key = nullptr, .ignoreMissing = true, .anonymousKeyBased = false}); + config.commence(); + config.addSpecialCategory("sameKeywordSpecialCat:one", {.key = nullptr, .ignoreMissing = true}); + config.addSpecialConfigValue("sameKeywordSpecialCat:one", "some_size", (Hyprlang::INT)10); + config.addSpecialConfigValue("sameKeywordSpecialCat:one", "some_radius", (Hyprlang::FLOAT)0.0); + config.addSpecialCategory("sameKeywordSpecialCat:two", {.key = nullptr, .ignoreMissing = true}); + config.addSpecialConfigValue("sameKeywordSpecialCat:two", "hola", ""); + config.addSpecialCategory("specialGeneric:one", {.key = nullptr, .ignoreMissing = true}); config.addSpecialConfigValue("specialGeneric:one", "value", (Hyprlang::INT)0); config.addSpecialCategory("specialGeneric:two", {.key = nullptr, .ignoreMissing = true}); @@ -216,6 +231,12 @@ int main(int argc, char** argv, char** envp) { EXPECT(ignoreKeyword, "aaa"); EXPECT(useKeyword, "yes"); + // test special category with same name as a keyword + EXPECT(sameKeywordSpecialCat, std::string_view{"pablo"}); + EXPECT(std::any_cast(config.getSpecialConfigValue("sameKeywordSpecialCat:one", "some_size")), (Hyprlang::INT)44); + EXPECT(std::any_cast(config.getSpecialConfigValue("sameKeywordSpecialCat:one", "some_radius")), (Hyprlang::FLOAT)7.6); + EXPECT(std::any_cast(config.getSpecialConfigValue("sameKeywordSpecialCat:two", "hola")), std::string_view{"rose"}); + // Test templated wrapper auto T1 = Hyprlang::CSimpleConfigValue(&config, "testInt"); auto T2 = Hyprlang::CSimpleConfigValue(&config, "testFloat");