From a7c1d0c6a61467da7fed7647ffa1acd9feec5f38 Mon Sep 17 00:00:00 2001
From: "Christian W. Zuckschwerdt" <christian@zuckschwerdt.org>
Date: Sat, 18 Mar 2023 21:15:51 +0100
Subject: [PATCH] minor: Fix unaligned address, heap overflow in data array
 print

---
 include/data.h | 8 +++++---
 src/data.c     | 4 +++-
 2 files changed, 8 insertions(+), 4 deletions(-)

diff --git a/include/data.h b/include/data.h
index d2d10dad..b3de05c8 100644
--- a/include/data.h
+++ b/include/data.h
@@ -58,10 +58,12 @@ typedef struct data_array {
     void        *values;
 } data_array_t;
 
+// Note: Do not unwrap a packed array to data_value_t,
+// on 32-bit the union has different size/alignment than a pointer.
 typedef union data_value {
-    int         v_int;
-    double      v_dbl;
-    void        *v_ptr;
+    int         v_int;  /**< A data value of type int, 4 bytes size/alignment */
+    double      v_dbl;  /**< A data value of type double, 8 bytes size/alignment */
+    void        *v_ptr; /**< A data value pointer, 4/8 bytes size/alignment */
 } data_value_t;
 
 typedef struct data {
diff --git a/src/data.c b/src/data.c
index eb977d62..c1335435 100644
--- a/src/data.c
+++ b/src/data.c
@@ -409,7 +409,9 @@ R_API void print_array_value(data_output_t *output, data_array_t *array, char co
         memcpy(&value, (char *)array->values + element_size * idx, element_size);
         print_value(output, array->type, value, format);
     } else {
-        print_value(output, array->type, *(data_value_t*)((char *)array->values + element_size * idx), format);
+        // Note: on 32-bit data_value_t has different size/alignment than a pointer!
+        value.v_ptr = *(void **)((char *)array->values + element_size * idx);
+        print_value(output, array->type, value, format);
     }
 }