winebuild: Store length of Unicode strings explicitly.

Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Alexandre Julliard 2022-02-08 17:44:58 +01:00
parent 7d3938e811
commit 2c42d8b9a5
1 changed files with 41 additions and 41 deletions

View File

@ -35,6 +35,7 @@ typedef unsigned short WCHAR;
struct string_id
{
WCHAR *str; /* ptr to Unicode string */
unsigned int len; /* len in characters */
unsigned short id; /* integer id if str is NULL */
};
@ -92,19 +93,6 @@ static inline struct resource *add_resource( DLLSPEC *spec )
return &spec->resources[spec->nb_resources++];
}
static inline unsigned int strlenW( const WCHAR *str )
{
const WCHAR *s = str;
while (*s) s++;
return s - str;
}
static inline int strcmpW( const WCHAR *str1, const WCHAR *str2 )
{
while (*str1 && (*str1 == *str2)) { str1++; str2++; }
return *str1 - *str2;
}
static struct res_name *add_name( struct res_type *type, struct resource *res )
{
struct res_name *name;
@ -132,8 +120,11 @@ static struct res_type *add_type( struct res_tree *tree, struct resource *res )
/* get a string from the current resource file */
static void get_string( struct string_id *str )
{
unsigned int i = 0;
size_t start_pos = input_buffer_pos;
WCHAR wc = get_word();
str->len = 0;
if (wc == 0xffff)
{
str->str = NULL;
@ -141,10 +132,11 @@ static void get_string( struct string_id *str )
}
else
{
WCHAR *p = xmalloc( (strlenW( (const WCHAR *)(input_buffer + input_buffer_pos) - 1) + 1) * sizeof(WCHAR) );
str->str = p;
str->id = 0;
if ((*p++ = wc)) while ((*p++ = get_word()));
input_buffer_pos = start_pos;
while (get_word()) str->len++;
str->str = xmalloc( str->len * sizeof(WCHAR) );
input_buffer_pos = start_pos;
while ((wc = get_word())) str->str[i++] = wc;
}
}
@ -153,8 +145,8 @@ static void put_string( const struct string_id *str )
{
if (str->str)
{
const WCHAR *p = str->str;
while (*p) put_word( *p++ );
unsigned int i;
for (i = 0; i < str->len; i++) put_word( str->str[i] );
put_word( 0 );
}
else
@ -253,13 +245,18 @@ int load_res32_file( const char *name, DLLSPEC *spec )
/* compare two unicode strings/ids */
static int cmp_string( const struct string_id *str1, const struct string_id *str2 )
{
unsigned int i;
if (!str1->str)
{
if (!str2->str) return str1->id - str2->id;
return 1; /* an id compares larger than a string */
}
if (!str2->str) return -1;
return strcmpW( str1->str, str2->str );
for (i = 0; i < str1->len && i < str2->len; i++)
if (str1->str[i] != str2->str[i]) return str1->str[i] - str2->str[i];
return str1->len - str2->len;
}
/* compare two resources for sorting the resource directory */
@ -278,11 +275,13 @@ static int cmp_res( const void *ptr1, const void *ptr2 )
static char *format_res_string( const struct string_id *str )
{
int i, len = str->str ? strlenW(str->str) + 1 : 5;
char *ret = xmalloc( len );
unsigned int i;
char *ret;
if (!str->str) sprintf( ret, "%04x", str->id );
else for (i = 0; i < len; i++) ret[i] = str->str[i]; /* dumb W->A conversion */
if (!str->str) return strmake( "#%04x", str->id );
ret = xmalloc( str->len + 1 );
for (i = 0; i < str->len; i++) ret[i] = str->str[i]; /* dumb W->A conversion */
ret[i] = 0;
return ret;
}
@ -365,7 +364,7 @@ static struct res_tree *build_resource_tree( DLLSPEC *spec, unsigned int *dir_si
if (type->type->str)
{
type->name_offset = offset | 0x80000000;
offset += (strlenW(type->type->str)+1) * sizeof(WCHAR);
offset += (type->type->len + 1) * sizeof(WCHAR);
}
else type->name_offset = type->type->id;
@ -374,7 +373,7 @@ static struct res_tree *build_resource_tree( DLLSPEC *spec, unsigned int *dir_si
if (name->name->str)
{
name->name_offset = offset | 0x80000000;
offset += (strlenW(name->name->str)+1) * sizeof(WCHAR);
offset += (name->name->len + 1) * sizeof(WCHAR);
}
else name->name_offset = name->name->id;
for (k = 0, res = name->res; k < name->nb_languages; k++, res++)
@ -399,13 +398,13 @@ static void free_resource_tree( struct res_tree *tree )
}
/* output a Unicode string */
static void output_string( const WCHAR *name )
static void output_string( const struct string_id *str )
{
int i, len = strlenW(name);
output( "\t.short 0x%04x", len );
for (i = 0; i < len; i++) output( ",0x%04x", name[i] );
unsigned int i;
output( "\t.short 0x%04x", str->len );
for (i = 0; i < str->len; i++) output( ",0x%04x", str->str[i] );
output( " /* " );
for (i = 0; i < len; i++) output( "%c", isprint((char)name[i]) ? (char)name[i] : '?' );
for (i = 0; i < str->len; i++) output( "%c", isprint((char)str->str[i]) ? (char)str->str[i] : '?' );
output( " */\n" );
}
@ -480,9 +479,9 @@ void output_resources( DLLSPEC *spec )
for (i = 0, type = tree->types; i < tree->nb_types; i++, type++)
{
if (type->type->str) output_string( type->type->str );
if (type->type->str) output_string( type->type );
for (n = 0, name = type->names; n < type->nb_names; n++, name++)
if (name->name->str) output_string( name->name->str );
if (name->name->str) output_string( name->name );
}
/* resource data */
@ -503,11 +502,12 @@ void output_resources( DLLSPEC *spec )
}
/* output a Unicode string in binary format */
static void output_bin_string( const WCHAR *name )
static void output_bin_string( const struct string_id *str )
{
int i, len = strlenW(name);
put_word( len );
for (i = 0; i < len; i++) put_word( name[i] );
unsigned int i;
put_word( str->len );
for (i = 0; i < str->len; i++) put_word( str->str[i] );
}
/* output a resource directory in binary format */
@ -588,9 +588,9 @@ void output_bin_resources( DLLSPEC *spec, unsigned int start_rva )
for (i = 0, type = tree->types; i < tree->nb_types; i++, type++)
{
if (type->type->str) output_bin_string( type->type->str );
if (type->type->str) output_bin_string( type->type );
for (n = 0, name = type->names; n < type->nb_names; n++, name++)
if (name->name->str) output_bin_string( name->name->str );
if (name->name->str) output_bin_string( name->name );
}
/* resource data */
@ -610,10 +610,10 @@ static unsigned int get_resource_header_size( const struct resource *res )
unsigned int size = 5 * sizeof(unsigned int) + 2 * sizeof(unsigned short);
if (!res->type.str) size += 2 * sizeof(unsigned short);
else size += (strlenW(res->type.str) + 1) * sizeof(WCHAR);
else size += (res->type.len + 1) * sizeof(WCHAR);
if (!res->name.str) size += 2 * sizeof(unsigned short);
else size += (strlenW(res->name.str) + 1) * sizeof(WCHAR);
else size += (res->name.len + 1) * sizeof(WCHAR);
return size;
}