From 5cbf5f43c6b827a9454b2c326a61ea709e32947b Mon Sep 17 00:00:00 2001
From: Dmitry Timoshkov <dmitry@baikal.ru>
Date: Thu, 7 Jan 2016 19:12:47 +0800
Subject: widl: Properly align name table entries.

---
 tools/widl/write_sltg.c | 39 ++++++++++++++++++++++-----------------
 1 file changed, 22 insertions(+), 17 deletions(-)

diff --git a/tools/widl/write_sltg.c b/tools/widl/write_sltg.c
index 11b4d0c..1ba921d 100644
--- a/tools/widl/write_sltg.c
+++ b/tools/widl/write_sltg.c
@@ -192,39 +192,44 @@ static void init_index(struct sltg_data *index)
     add_index(index, compobj);
 }
 
-static int add_name(struct sltg_data *name_table, const char *name)
+static int add_name(struct sltg_typelib *sltg, const char *name)
 {
-    int name_offset = name_table->size;
-    int new_size = name_table->size + strlen(name) + 1 + 8;
+    int name_offset = sltg->name_table.size;
+    int new_size = sltg->name_table.size + strlen(name) + 1 + 8;
+    int aligned_size;
 
     chat("add_name: %s\n", name);
 
-    new_size = (new_size + 1) & ~1; /* align */
+    aligned_size = (new_size + 0x1f) & ~0x1f;
+    if (aligned_size - new_size < 4)
+        new_size = aligned_size;
+    else
+        new_size = (new_size + 1) & ~1;
 
-    if (new_size > name_table->allocated)
+    if (aligned_size > sltg->name_table.allocated)
     {
-        name_table->allocated = max(name_table->allocated * 2, new_size);
-        name_table->data = xrealloc(name_table->data, name_table->allocated);
+        sltg->name_table.allocated = max(sltg->name_table.allocated * 2, aligned_size);
+        sltg->name_table.data = xrealloc(sltg->name_table.data, sltg->name_table.allocated);
     }
 
-    memset(name_table->data + name_table->size, 0xff, 8);
-    strcpy(name_table->data + name_table->size + 8, name);
-    name_table->size = new_size;
-    name_table->data[name_table->size - 1] = 0; /* clear alignment */
+    memset(sltg->name_table.data + sltg->name_table.size, 0xff, 8);
+    strcpy(sltg->name_table.data + sltg->name_table.size + 8, name);
+    sltg->name_table.size = new_size;
+    sltg->name_table.data[sltg->name_table.size - 1] = 0; /* clear alignment */
 
     return name_offset;
 }
 
-static void init_name_table(struct sltg_data *name_table)
+static void init_name_table(struct sltg_typelib *sltg)
 {
-    init_sltg_data(name_table);
+    init_sltg_data(&sltg->name_table);
 }
 
 static void init_library(struct sltg_typelib *sltg)
 {
     const attr_t *attr;
 
-    sltg->library.name = add_name(&sltg->name_table, sltg->typelib->name);
+    sltg->library.name = add_name(sltg, sltg->typelib->name);
     sltg->library.helpstring = NULL;
     sltg->library.helpcontext = 0;
     sltg->library.syskind = SYS_WIN32;
@@ -443,7 +448,7 @@ static const char *add_typeinfo_block(struct sltg_typelib *typelib, const type_t
     strcpy((char *)p, other_name);
     p = (short *)((char *)p + strlen(other_name));
     *p++ = -1; /* res1a */
-    *p++ = add_name(&typelib->name_table, type->name); /* name offset */
+    *p++ = add_name(typelib, type->name); /* name offset */
     *p++ = 0; /* FIXME: helpstring */
     *p++ = -1; /* res20 */
     *(int *)p = helpcontext;
@@ -710,7 +715,7 @@ static void add_structure_typeinfo(struct sltg_typelib *typelib, const type_t *t
             next += sizeof(variable);
 
             variable.magic = 0x2a; /* always write flags to simplify calculations */
-            variable.name = add_name(&typelib->name_table, var->name);
+            variable.name = add_name(typelib, var->name);
             variable.byte_offs = 0;
             if (var_data[i].size > sizeof(short))
             {
@@ -1063,7 +1068,7 @@ int create_sltg_typelib(typelib_t *typelib)
     sltg.first_block = 1;
 
     init_index(&sltg.index);
-    init_name_table(&sltg.name_table);
+    init_name_table(&sltg);
     init_library(&sltg);
 
     add_library_block(&sltg);
-- 
2.6.4

