From a5c0d57325c5f0814c39110a70ca19c070ae9486 Mon Sep 17 00:00:00 2001 From: Ikalco <73481042+ikalco@users.noreply.github.com> Date: Thu, 4 Jul 2024 10:59:59 -0500 Subject: [PATCH] core: only alloc as much as needed when reading in cursor images (#51) --- libhyprcursor/hyprcursor.cpp | 44 ++++++++++++++++++++++++------------ 1 file changed, 30 insertions(+), 14 deletions(-) diff --git a/libhyprcursor/hyprcursor.cpp b/libhyprcursor/hyprcursor.cpp index b6793ec..91d3a89 100644 --- a/libhyprcursor/hyprcursor.cpp +++ b/libhyprcursor/hyprcursor.cpp @@ -634,18 +634,22 @@ std::optional CHyprcursorImplementation::loadTheme() { int errp = 0; zip_t* zip = zip_open(cursor.path().string().c_str(), ZIP_RDONLY, &errp); - zip_file_t* meta_file = zip_fopen(zip, "meta.hl", ZIP_FL_UNCHANGED); - bool metaIsHL = true; - if (!meta_file) { - meta_file = zip_fopen(zip, "meta.toml", ZIP_FL_UNCHANGED); - metaIsHL = false; - if (!meta_file) - return "cursor" + cursor.path().string() + "failed to load meta"; + zip_int64_t index = zip_name_locate(zip, "meta.hl", ZIP_FL_ENC_GUESS); + bool metaIsHL = true; + + if (index == -1) { + index = zip_name_locate(zip, "meta.toml", ZIP_FL_ENC_GUESS); + metaIsHL = false; } - char* buffer = new char[1024 * 1024]; /* 1MB should be more than enough */ + if (index == -1) + return "cursor" + cursor.path().string() + "failed to load meta"; - int readBytes = zip_fread(meta_file, buffer, 1024 * 1024 - 1); + zip_file_t* meta_file = zip_fopen_index(zip, index, ZIP_FL_UNCHANGED); + + char* buffer = new char[1024 * 1024]; /* 1MB should be more than enough */ + + int readBytes = zip_fread(meta_file, buffer, 1024 * 1024 - 1); zip_fclose(meta_file); @@ -670,6 +674,9 @@ std::optional CHyprcursorImplementation::loadTheme() { SHAPE->overrides = meta.parsedData.overrides; + zip_stat_t sb; + zip_stat_init(&sb); + for (auto& i : SHAPE->images) { if (SHAPE->shapeType == SHAPE_INVALID) { if (i.filename.ends_with(".svg")) @@ -694,14 +701,23 @@ std::optional CHyprcursorImplementation::loadTheme() { IMAGE->delay = i.delay; IMAGE->isSVG = SHAPE->shapeType == SHAPE_SVG; - // read from zip - zip_file_t* image_file = zip_fopen(zip, i.filename.c_str(), ZIP_FL_UNCHANGED); - if (!image_file) + index = zip_name_locate(zip, i.filename.c_str(), ZIP_FL_ENC_GUESS); + if (index == -1) return "cursor" + cursor.path().string() + "failed to load image_file"; - IMAGE->data = new char[1024 * 1024]; /* 1MB should be more than enough, again. This probably should be in the spec. */ + // read from zip + zip_file_t* image_file = zip_fopen_index(zip, index, ZIP_FL_UNCHANGED); + zip_stat_index(zip, index, ZIP_FL_UNCHANGED, &sb); - IMAGE->dataLen = zip_fread(image_file, IMAGE->data, 1024 * 1024 - 1); + if (sb.valid & ZIP_STAT_SIZE) { + IMAGE->data = new char[sb.size + 1]; + IMAGE->dataLen = sb.size + 1; + } else { + IMAGE->data = new char[1024 * 1024]; /* 1MB should be more than enough, again. This probably should be in the spec. */ + IMAGE->dataLen = 1024 * 1024; + } + + IMAGE->dataLen = zip_fread(image_file, IMAGE->data, IMAGE->dataLen - 1); zip_fclose(image_file);