[msitools: 1/2] msi/string: fix msi_load_string_table
- From: Marc-André Lureau <malureau src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [msitools: 1/2] msi/string: fix msi_load_string_table
- Date: Fri, 28 Sep 2018 08:21:15 +0000 (UTC)
commit 31bd06e12db26147434735e5a60c385f0d25332f
Author: Marc-André Lureau <marcandre lureau redhat com>
Date: Mon Sep 24 11:58:24 2018 +0400
msi/string: fix msi_load_string_table
Rewrite the function to follow more closely the original wine code.
Fixes:
https://bugzilla.redhat.com/show_bug.cgi?id=1629516
Signed-off-by: Marc-André Lureau <marcandre lureau redhat com>
libmsi/string.c | 39 ++++++++++++++++++++++-----------------
1 file changed, 22 insertions(+), 17 deletions(-)
---
diff --git a/libmsi/string.c b/libmsi/string.c
index 0dfa003..8d88953 100644
--- a/libmsi/string.c
+++ b/libmsi/string.c
@@ -484,7 +484,7 @@ string_table *msi_load_string_table( GsfInfile *stg, unsigned *bytes_per_strref
{
string_table *st = NULL;
char *data = NULL;
- uint8_t *pool = NULL;
+ uint16_t *pool = NULL;
unsigned r, datasize = 0, poolsize = 0, codepage;
unsigned i, count, offset, len, n, refs;
@@ -495,47 +495,51 @@ string_table *msi_load_string_table( GsfInfile *stg, unsigned *bytes_per_strref
if( r != LIBMSI_RESULT_SUCCESS)
goto end;
- if ( (poolsize > 4) && (pool[3] & 0x80) )
+ if ( (poolsize > 4) && (pool[1] & 0x8000) )
*bytes_per_strref = LONG_STR_BYTES;
else
*bytes_per_strref = sizeof(uint16_t);
- /* All data is little-endian. */
+ count = poolsize/4;
if( poolsize > 4 )
- codepage = pool[0] | (pool[1] << 8) | (pool[2] << 16) | ((pool[3] & ~0x80) << 24);
+ codepage = pool[0] | ( (pool[1] & ~0x8000) << 16 );
else
codepage = CP_ACP;
- count = poolsize/4;
st = init_stringtable( count, codepage );
if (!st)
goto end;
offset = 0;
+ n = 1;
i = 1;
- for (n = 1; i<count ; n++)
+ while ( i<count )
{
/* the string reference count is always the second word */
- len = pool[i*4] | (pool[i*4+1] << 8);
- refs = pool[i*4+2] | (pool[i*4+3] << 8);
- i++;
+ refs = pool[i*2+1];
/* empty entries have two zeros, still have a string id */
- if (len == 0 && refs == 0)
+ if (pool[i*2] == 0 && refs == 0)
+ {
+ i++;
+ n++;
continue;
+ }
/*
* If a string is over 64k, the previous string entry is made null
* and the high word of the length is inserted in the null string's
- * reference count field (i.e. mixed endian).
- *
- * TODO: add testcase
+ * reference count field.
*/
- if (len == 0)
+ if (pool[i*2] == 0)
{
- len = (refs << 16) | pool[i*4] | (pool[i*4+1] << 8);
- refs = pool[i*4+2] | (pool[i*4+3] << 8);
- i++;
+ len = (pool[i*2+3] << 16) + pool[i*2+2];
+ i += 2;
+ }
+ else
+ {
+ len = pool[i*2];
+ i += 1;
}
if ( (offset + len) > datasize )
@@ -547,6 +551,7 @@ string_table *msi_load_string_table( GsfInfile *stg, unsigned *bytes_per_strref
r = msi_addstring( st, n, data+offset, len, refs, StringPersistent );
if( r != n )
g_critical("Failed to add string %d\n", n );
+ n++;
offset += len;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]