[quickjs] Fix undefined flexible array member

Flexible array's in C are declared with no size, size 0 is
undefined and UBSan has recently learned to warn about
access to these.

Bug: 103545
Change-Id: Ic7cb83ad559aa87ff4df6871612ecb4dde9f4e68
diff --git a/quickjs.c b/quickjs.c
index 3ea7f46..722fd58 100644
--- a/quickjs.c
+++ b/quickjs.c
@@ -499,9 +499,10 @@
     struct list_head link; /* string list */
 #endif
     union {
-        uint8_t str8[0]; /* 8 bit strings will get an extra null terminator */
-        uint16_t str16[0];
+      uint8_t *str8; /* 8 bit strings will get an extra null terminator */
+      uint16_t *str16;
     } u;
+    uint8_t str_storage[];
 };
 
 typedef struct JSClosureVar {
@@ -1874,6 +1875,8 @@
     str->atom_type = 0;
     str->hash = 0;          /* optional but costless */
     str->hash_next = 0;     /* optional */
+    void **dest = is_wide_char ? (void **)&str->u.str16 : (void **)&str->u.str8;
+    *dest = &str->str_storage;
 #ifdef DUMP_LEAKS
     list_add_tail(&str->link, &rt->string_list);
 #endif
@@ -3590,6 +3593,8 @@
     new_size = min_int(new_size + (slack >> s->is_wide_char), JS_STRING_LEN_MAX);
     s->size = new_size;
     s->str = new_str;
+    void **dest = s->is_wide_char ? (void **)&new_str->u.str16 : (void **)&new_str->u.str8;
+    *dest = &new_str->str_storage;
     return 0;
 }
 
@@ -3819,6 +3824,8 @@
         if (str == NULL)
             str = s->str;
         s->str = str;
+        void **dest = s->is_wide_char ? (void **)&str->u.str16 : (void **)&str->u.str8;
+        *dest = &str->str_storage;
     }
     if (!s->is_wide_char)
         str->u.str8[s->len] = 0;
@@ -4044,7 +4051,7 @@
     if (!ptr)
         return;
     /* purposely removing constness */
-    p = (JSString *)(void *)(ptr - offsetof(JSString, u));
+    p = (JSString *)(void *)(ptr - offsetof(JSString, str_storage));
     JS_FreeValue(ctx, JS_MKPTR(JS_TAG_STRING, p));
 }