Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package hyprcursor for openSUSE:Factory checked in at 2024-06-11 18:28:20 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/hyprcursor (Old) and /work/SRC/openSUSE:Factory/.hyprcursor.new.19518 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "hyprcursor" Tue Jun 11 18:28:20 2024 rev:3 rq:1179768 version:0.1.9 Changes: -------- --- /work/SRC/openSUSE:Factory/hyprcursor/hyprcursor.changes 2024-04-14 12:26:16.401192977 +0200 +++ /work/SRC/openSUSE:Factory/.hyprcursor.new.19518/hyprcursor.changes 2024-06-11 18:29:10.000591326 +0200 @@ -1,0 +2,21 @@ +Mon Jun 10 17:39:28 UTC 2024 - Florian "spirit" <sp1...@disroot.org> + +- Update to version 0.1.9: + + A small housekeeping update with a few minor patches. + + Fixes: + - fixed nearest size search for png cursor themes + - Fixed getconf command in build instructions + - add option to not use default fallbacks (env and first + available) + +- Changes from version 0.1.8: + + A minor update with some cleanups + + Fixes: + - util: fixed printing overrides + - Count cursor-less themes as invalid + + Other: + - Add validation for cursor file names and propagate the error + from parsing HL cursor + - Properly report error on zip_close + +------------------------------------------------------------------- Old: ---- hyprcursor-0.1.7.tar.xz New: ---- hyprcursor-0.1.9.tar.xz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ hyprcursor.spec ++++++ --- /var/tmp/diff_new_pack.ra3xay/_old 2024-06-11 18:29:10.888623734 +0200 +++ /var/tmp/diff_new_pack.ra3xay/_new 2024-06-11 18:29:10.888623734 +0200 @@ -20,7 +20,7 @@ %define sover 0 Name: hyprcursor -Version: 0.1.7 +Version: 0.1.9 Release: 0 Summary: Library and utilities for the hyprland cursor format License: BSD-3-Clause ++++++ hyprcursor-0.1.7.tar.xz -> hyprcursor-0.1.9.tar.xz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hyprcursor-0.1.7/CMakeLists.txt new/hyprcursor-0.1.9/CMakeLists.txt --- old/hyprcursor-0.1.7/CMakeLists.txt 2024-04-09 17:30:19.000000000 +0200 +++ new/hyprcursor-0.1.9/CMakeLists.txt 2024-05-24 20:46:51.000000000 +0200 @@ -1,6 +1,6 @@ cmake_minimum_required(VERSION 3.19) -set(HYPRCURSOR_VERSION "0.1.7") +set(HYPRCURSOR_VERSION "0.1.9") add_compile_definitions(HYPRCURSOR_VERSION="${HYPRCURSOR_VERSION}") project(hyprcursor diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hyprcursor-0.1.7/README.md new/hyprcursor-0.1.9/README.md --- old/hyprcursor-0.1.7/README.md 2024-04-09 17:30:19.000000000 +0200 +++ new/hyprcursor-0.1.9/README.md 2024-05-24 20:46:51.000000000 +0200 @@ -57,7 +57,7 @@ ### Build ```sh cmake --no-warn-unused-cli -DCMAKE_BUILD_TYPE:STRING=Release -DCMAKE_INSTALL_PREFIX:PATH=/usr -S . -B ./build -cmake --build ./build --config Release --target all -j`nproc 2>/dev/null || getconf NPROCESSORS_CONF` +cmake --build ./build --config Release --target all -j`nproc 2>/dev/null || getconf _NPROCESSORS_CONF` ``` Install with: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hyprcursor-0.1.7/flake.lock new/hyprcursor-0.1.9/flake.lock --- old/hyprcursor-0.1.7/flake.lock 2024-04-09 17:30:19.000000000 +0200 +++ new/hyprcursor-0.1.9/flake.lock 2024-05-24 20:46:51.000000000 +0200 @@ -5,14 +5,16 @@ "nixpkgs": [ "nixpkgs" ], - "systems": "systems" + "systems": [ + "systems" + ] }, "locked": { - "lastModified": 1709914708, - "narHash": "sha256-bR4o3mynoTa1Wi4ZTjbnsZ6iqVcPGriXp56bZh5UFTk=", + "lastModified": 1713121246, + "narHash": "sha256-502X0Q0fhN6tJK7iEUA8CghONKSatW/Mqj4Wappd++0=", "owner": "hyprwm", "repo": "hyprlang", - "rev": "a685493fdbeec01ca8ccdf1f3655c044a8ce2fe2", + "rev": "78fcaa27ae9e1d782faa3ff06c8ea55ddce63706", "type": "github" }, "original": { @@ -23,11 +25,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1708475490, - "narHash": "sha256-g1v0TsWBQPX97ziznfJdWhgMyMGtoBFs102xSYO4syU=", + "lastModified": 1712963716, + "narHash": "sha256-WKm9CvgCldeIVvRz87iOMi8CFVB1apJlkUT4GGvA0iM=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "0e74ca98a74bc7270d28838369593635a5db3260", + "rev": "cfd6b5fc90b15709b780a5a1619695a88505a176", "type": "github" }, "original": { @@ -41,28 +43,13 @@ "inputs": { "hyprlang": "hyprlang", "nixpkgs": "nixpkgs", - "systems": "systems_2" + "systems": "systems" } }, "systems": { "locked": { "lastModified": 1689347949, "narHash": "sha256-12tWmuL2zgBgZkdoB6qXZsgJEH9LR3oUgpaQq2RbI80=", - "owner": "nix-systems", - "repo": "default-linux", - "rev": "31732fcf5e8fea42e59c2488ad31a0e651500f68", - "type": "github" - }, - "original": { - "owner": "nix-systems", - "repo": "default-linux", - "type": "github" - } - }, - "systems_2": { - "locked": { - "lastModified": 1689347949, - "narHash": "sha256-12tWmuL2zgBgZkdoB6qXZsgJEH9LR3oUgpaQq2RbI80=", "owner": "nix-systems", "repo": "default-linux", "rev": "31732fcf5e8fea42e59c2488ad31a0e651500f68", diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hyprcursor-0.1.7/hyprcursor-util/src/main.cpp new/hyprcursor-0.1.9/hyprcursor-util/src/main.cpp --- old/hyprcursor-0.1.7/hyprcursor-util/src/main.cpp 2024-04-09 17:30:19.000000000 +0200 +++ new/hyprcursor-0.1.9/hyprcursor-util/src/main.cpp 2024-05-24 20:46:51.000000000 +0200 @@ -5,11 +5,16 @@ #include <array> #include <format> #include <algorithm> +#include <regex> #include <hyprlang.hpp> #include "internalSharedTypes.hpp" #include "manifest.hpp" #include "meta.hpp" +#ifndef ZIP_LENGTH_TO_END +#define ZIP_LENGTH_TO_END -1 +#endif + enum eOperation { OPERATION_CREATE = 0, OPERATION_EXTRACT = 1, @@ -87,7 +92,7 @@ const std::string THEMENAME = manifest.parsedData.name; - std::string out = (out_.empty() ? path.substr(0, path.find_last_of('/') + 1) : out_) + "/theme_" + THEMENAME + "/"; + std::string out = (out_.empty() ? path.substr(0, path.find_last_of('/')) : out_) + "/theme_" + THEMENAME; const std::string CURSORSSUBDIR = manifest.parsedData.cursorsDirectory; const std::string CURSORDIR = path + "/" + CURSORSSUBDIR; @@ -98,6 +103,9 @@ // iterate over the directory and record all cursors for (auto& dir : std::filesystem::directory_iterator(CURSORDIR)) { + if (!std::regex_match(dir.path().stem().string(), std::regex("^[A-Za-z0-9_\\-\\.]+$"))) + return "Invalid cursor directory name at " + dir.path().string() + " : characters must be within [A-Za-z0-9_\\-\\.]"; + const auto METAPATH = dir.path().string() + "/meta"; auto& SHAPE = currentTheme.shapes.emplace_back(std::make_unique<SCursorShape>()); @@ -113,6 +121,8 @@ SHAPE->images.push_back(SCursorImage{i.file, i.size, i.delayMs}); } + SHAPE->overrides = meta.parsedData.overrides; + // check if we have at least one image. for (auto& i : SHAPE->images) { @@ -178,7 +188,7 @@ // add meta.hl const auto METADIR = std::filesystem::exists(CURRENTCURSORSDIR + "/meta.hl") ? (CURRENTCURSORSDIR + "/meta.hl") : (CURRENTCURSORSDIR + "/meta.toml"); - zip_source_t* meta = zip_source_file(zip, METADIR.c_str(), 0, 0); + zip_source_t* meta = zip_source_file(zip, METADIR.c_str(), 0, ZIP_LENGTH_TO_END); if (!meta) return "(1) failed to add meta " + METADIR + " to hlc"; if (zip_file_add(zip, (std::string{"meta."} + (METADIR.ends_with(".hl") ? "hl" : "toml")).c_str(), meta, ZIP_FL_ENC_UTF_8) < 0) @@ -186,9 +196,9 @@ meta = nullptr; - // add each cursor png + // add each cursor image for (auto& i : shape->images) { - zip_source_t* image = zip_source_file(zip, (CURRENTCURSORSDIR + "/" + i.filename).c_str(), 0, 0); + zip_source_t* image = zip_source_file(zip, (CURRENTCURSORSDIR + "/" + i.filename).c_str(), 0, ZIP_LENGTH_TO_END); if (!image) return "(1) failed to add image " + (CURRENTCURSORSDIR + "/" + i.filename) + " to hlc"; if (zip_file_add(zip, (i.filename).c_str(), image, ZIP_FL_ENC_UTF_8) < 0) @@ -199,9 +209,8 @@ // close zip and write if (zip_close(zip) < 0) { - zip_error_t ziperror; - zip_error_init_with_code(&ziperror, errp); - return "Failed to write " + OUTPUTFILE + ": " + zip_error_strerror(&ziperror); + zip_error_t* ziperror = zip_get_error(zip); + return "Failed to write " + OUTPUTFILE + ": " + zip_error_strerror(ziperror); } std::cout << "Written " << OUTPUTFILE << "\n"; @@ -449,4 +458,4 @@ } return 0; -} \ No newline at end of file +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hyprcursor-0.1.7/include/hyprcursor/hyprcursor.hpp new/hyprcursor-0.1.9/include/hyprcursor/hyprcursor.hpp --- old/hyprcursor-0.1.7/include/hyprcursor/hyprcursor.hpp 2024-04-09 17:30:19.000000000 +0200 +++ new/hyprcursor-0.1.9/include/hyprcursor/hyprcursor.hpp 2024-05-24 20:46:51.000000000 +0200 @@ -48,6 +48,22 @@ }; /*! + struct for cursor manager options + */ + struct SManagerOptions { + explicit SManagerOptions(); + + /*! + The function used for logging by the cursor manager + */ + PHYPRCURSORLOGFUNC logFn; + /*! + Allow fallback to env and first theme found + */ + bool allowDefaultFallback; + }; + + /*! Basic Hyprcursor manager. Has to be created for either a specified theme, or @@ -58,6 +74,8 @@ If none found, bool valid() will be false. If loading fails, bool valid() will be false. + + If theme has no valid cursor shapes, bool valid() will be false. */ class CHyprcursorManager { public: @@ -66,6 +84,7 @@ \since 0.1.6 */ CHyprcursorManager(const char* themeName, PHYPRCURSORLOGFUNC fn); + CHyprcursorManager(const char* themeName, SManagerOptions options); ~CHyprcursorManager(); /*! @@ -170,9 +189,10 @@ private: void init(const char* themeName_); - CHyprcursorImplementation* impl = nullptr; - bool finalizedAndValid = false; - PHYPRCURSORLOGFUNC logFn = nullptr; + CHyprcursorImplementation* impl = nullptr; + bool finalizedAndValid = false; + bool allowDefaultFallback = true; + PHYPRCURSORLOGFUNC logFn = nullptr; friend class CHyprcursorImplementation; }; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hyprcursor-0.1.7/libhyprcursor/hyprcursor.cpp new/hyprcursor-0.1.9/libhyprcursor/hyprcursor.cpp --- old/hyprcursor-0.1.7/libhyprcursor/hyprcursor.cpp 2024-04-09 17:30:19.000000000 +0200 +++ new/hyprcursor-0.1.9/libhyprcursor/hyprcursor.cpp 2024-05-24 20:46:51.000000000 +0200 @@ -108,7 +108,7 @@ return ""; } -static std::string getFullPathForThemeName(const std::string& name, PHYPRCURSORLOGFUNC logfn) { +static std::string getFullPathForThemeName(const std::string& name, PHYPRCURSORLOGFUNC logfn, bool allowDefaultFallback) { const auto HOMEENV = getenv("HOME"); if (!HOMEENV) return ""; @@ -134,7 +134,7 @@ const auto MANIFESTPATH = themeDir.path().string() + "/manifest"; - if (name.empty()) { + if (allowDefaultFallback && name.empty()) { if (std::filesystem::exists(MANIFESTPATH + ".hl") || std::filesystem::exists(MANIFESTPATH + ".toml")) { Debug::log(HC_LOG_INFO, logfn, "getFullPathForThemeName: found {}", themeDir.path().string()); return std::filesystem::canonical(themeDir.path()).string(); @@ -193,14 +193,19 @@ } } - if (!name.empty()) { // try without name + if (allowDefaultFallback && !name.empty()) { // try without name Debug::log(HC_LOG_INFO, logfn, "getFullPathForThemeName: failed, trying without name of {}", name); - return getFullPathForThemeName("", logfn); + return getFullPathForThemeName("", logfn, allowDefaultFallback); } return ""; } +SManagerOptions::SManagerOptions() { + logFn = nullptr; + allowDefaultFallback = true; +} + CHyprcursorManager::CHyprcursorManager(const char* themeName_) { init(themeName_); } @@ -210,16 +215,22 @@ init(themeName_); } +CHyprcursorManager::CHyprcursorManager(const char* themeName_, SManagerOptions options) { + logFn = options.logFn; + allowDefaultFallback = options.allowDefaultFallback; + init(themeName_); +} + void CHyprcursorManager::init(const char* themeName_) { std::string themeName = themeName_ ? themeName_ : ""; - if (themeName.empty()) { + if (allowDefaultFallback && themeName.empty()) { // try reading from env Debug::log(HC_LOG_INFO, logFn, "CHyprcursorManager: attempting to find theme from env"); themeName = themeNameFromEnv(logFn); } - if (themeName.empty()) { + if (allowDefaultFallback && themeName.empty()) { // try finding first, in the hierarchy Debug::log(HC_LOG_INFO, logFn, "CHyprcursorManager: attempting to find any theme"); themeName = getFirstTheme(logFn); @@ -234,7 +245,7 @@ // initialize theme impl = new CHyprcursorImplementation(this, logFn); impl->themeName = themeName; - impl->themeFullDir = getFullPathForThemeName(themeName, logFn); + impl->themeFullDir = getFullPathForThemeName(themeName, logFn, allowDefaultFallback); if (impl->themeFullDir.empty()) return; @@ -248,6 +259,11 @@ return; } + if (impl->theme.shapes.empty()) { + Debug::log(HC_LOG_ERR, logFn, "Theme {} has no valid cursor shapes\n", impl->themeName); + return; + } + finalizedAndValid = true; } @@ -301,7 +317,7 @@ // find nearest int leader = 13371337; for (auto& image : impl->loadedShapes[shape.get()].images) { - if (std::abs((int)(image->side - info.size)) > leader) + if (std::abs((int)(image->side - info.size)) > std::abs((int)(leader - info.size))) continue; leader = image->side; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/hyprcursor-0.1.7/libhyprcursor/meta.cpp new/hyprcursor-0.1.9/libhyprcursor/meta.cpp --- old/hyprcursor-0.1.7/libhyprcursor/meta.cpp 2024-04-09 17:30:19.000000000 +0200 +++ new/hyprcursor-0.1.9/libhyprcursor/meta.cpp 2024-05-24 20:46:51.000000000 +0200 @@ -3,6 +3,7 @@ #include <hyprlang.hpp> #include <toml++/toml.hpp> #include <filesystem> +#include <regex> #include "VarList.hpp" @@ -95,6 +96,11 @@ RHS = LL; } + if (!std::regex_match(RHS, std::regex("^[A-Za-z0-9_\\-\\.]+$"))) { + result.setError("Invalid cursor file name, characters must be within [A-Za-z0-9_\\-\\.] (if this seems like a mistake, check for invisible characters)"); + return result; + } + size.file = RHS; if (!size.file.ends_with(".svg")) { @@ -132,7 +138,9 @@ meta->registerHandler(::parseDefineSize, "define_size", {.allowFlags = false}); meta->registerHandler(::parseOverride, "define_override", {.allowFlags = false}); meta->commence(); - meta->parse(); + const auto RESULT = meta->parse(); + if (RESULT.error) + return RESULT.getError(); } catch (const char* err) { return "failed parsing meta: " + std::string{err}; } parsedData.hotspotX = std::any_cast<Hyprlang::FLOAT>(meta->getConfigValue("hotspot_x"));