Commit 3f67d5d1 for libheif
commit 3f67d5d1166fb58fd7e68c4b2c87c3a68fec5c1f
Author: Dirk Farin <dirk.farin@gmail.com>
Date: Tue Sep 29 18:50:25 2026 +0200
tests: do not read the error message of a freed context in encode_plane_layout
The encode() helper freed its heif_context and returned the heif_error of
heif_context_encode_image(). The message of that error points into the
context, so printing it afterwards was a heap-use-after-free. The test
passed in a normal build and failed with AddressSanitizer.
Copy the message before the context is freed.
diff --git a/tests/encode_plane_layout.cc b/tests/encode_plane_layout.cc
index 29c124ad..97618f97 100644
--- a/tests/encode_plane_layout.cc
+++ b/tests/encode_plane_layout.cc
@@ -39,6 +39,7 @@
#include <cstdint>
#include <cstring>
+#include <string>
namespace {
@@ -78,7 +79,16 @@ void add_plane(heif_image* img, heif_channel channel, uint32_t w, uint32_t h)
}
}
-heif_error encode(heif_image* img, heif_compression_format format)
+// heif_error::message may point into the context that reported the error, so it has to be
+// copied before the context is freed.
+struct EncodeResult
+{
+ heif_error_code code;
+ heif_suberror_code subcode;
+ std::string message;
+};
+
+EncodeResult encode(heif_image* img, heif_compression_format format)
{
heif_context* ctx = heif_context_alloc();
heif_encoder* encoder = nullptr;
@@ -86,15 +96,16 @@ heif_error encode(heif_image* img, heif_compression_format format)
REQUIRE(err.code == heif_error_Ok);
err = heif_context_encode_image(ctx, img, encoder, nullptr, nullptr);
+ EncodeResult result{err.code, err.subcode, err.message ? err.message : ""};
heif_encoder_release(encoder);
heif_context_free(ctx);
- return err;
+ return result;
}
void expect_refused(heif_image* img, heif_compression_format format)
{
- heif_error err = encode(img, format);
+ EncodeResult err = encode(img, format);
INFO("encode error (" << err.code << "/" << err.subcode << "): " << err.message);
REQUIRE(err.code != heif_error_Ok);
CHECK(err.code == heif_error_Usage_error);
@@ -116,7 +127,7 @@ TEST_CASE("encoding refuses images with a non-canonical plane layout")
for (heif_channel ch : {heif_channel_R, heif_channel_G, heif_channel_B}) {
add_plane(img, ch, W, H);
}
- heif_error err = encode(img, format);
+ EncodeResult err = encode(img, format);
INFO("encode error (" << err.code << "/" << err.subcode << "): " << err.message);
CHECK(err.code == heif_error_Ok);
heif_image_release(img);
@@ -171,9 +182,9 @@ TEST_CASE("encoding refuses images with a non-canonical plane layout")
heif_component_datatype_unsigned_integer, 8, &id);
REQUIRE(err.code == heif_error_Ok);
- err = encode(img, format);
- INFO("encode error (" << err.code << "/" << err.subcode << "): " << err.message);
- CHECK(err.code == heif_error_Ok);
+ EncodeResult result = encode(img, format);
+ INFO("encode error (" << result.code << "/" << result.subcode << "): " << result.message);
+ CHECK(result.code == heif_error_Ok);
heif_image_release(img);
}
}