Alexandre Julliard : winebuild: Escape invalid characters in the dll name for static import libraries.
Alexandre Julliard
julliard at winehq.org
Tue Nov 16 16:32:27 CST 2021
Module: wine
Branch: master
Commit: 32cfdb549634dbd8ccf4b36a822905af4cc2c6bf
URL: https://source.winehq.org/git/wine.git/?a=commit;h=32cfdb549634dbd8ccf4b36a822905af4cc2c6bf
Author: Alexandre Julliard <julliard at winehq.org>
Date: Tue Nov 16 16:41:16 2021 +0100
winebuild: Escape invalid characters in the dll name for static import libraries.
This is necessary for things like vulkan-1.dll.
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
tools/winebuild/import.c | 94 +++++++++++++++++++++++++++++++++++++-----------
1 file changed, 73 insertions(+), 21 deletions(-)
diff --git a/tools/winebuild/import.c b/tools/winebuild/import.c
index 7972fc7b1d9..8e285b19872 100644
--- a/tools/winebuild/import.c
+++ b/tools/winebuild/import.c
@@ -212,6 +212,64 @@ static inline ORDDEF *find_export( const char *name, ORDDEF **table, int size )
return res ? *res : NULL;
}
+static const char valid_chars[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_.";
+
+/* encode a dll name into a linker-compatible name */
+static char *encode_dll_name( const char *name )
+{
+ char *p, *ret;
+ int len = strlen(name);
+
+ if (strendswith( name, ".dll" )) len -= 4;
+ if (strspn( name, valid_chars ) >= len) return strmake( "%.*s", len, name );
+
+ ret = p = xmalloc( len * 4 + 1 );
+ for ( ; len > 0; len--, name++)
+ {
+ if (!strchr( valid_chars, *name )) p += sprintf( p, "$x%02x", *name );
+ else *p++ = *name;
+ }
+ *p = 0;
+ return ret;
+}
+
+/* decode a linker-compatible dll name */
+static char *decode_dll_name( const char **name )
+{
+ const char *src = *name;
+ char *p, *ret;
+
+ ret = p = xmalloc( strlen( src ) + 5 );
+ for ( ; *src; src++, p++)
+ {
+ if (*src != '$')
+ {
+ *p = *src;
+ }
+ else if (src[1] == 'x') /* hex escape */
+ {
+ int val = 0;
+ src += 2;
+ if (*src >= '0' && *src <= '9') val += *src - '0';
+ else if (*src >= 'A' && *src <= 'F') val += *src - 'A' + 10;
+ else if (*src >= 'a' && *src <= 'f') val += *src - 'a' + 10;
+ else return NULL;
+ val *= 16;
+ src++;
+ if (*src >= '0' && *src <= '9') val += *src - '0';
+ else if (*src >= 'A' && *src <= 'F') val += *src - 'A' + 10;
+ else if (*src >= 'a' && *src <= 'f') val += *src - 'a' + 10;
+ else return NULL;
+ *p = val;
+ }
+ else break; /* end of dll name */
+ }
+ *p = 0;
+ if (!strchr( ret, '.' )) strcpy( p, ".dll" );
+ *name = src;
+ return ret;
+}
+
/* free an import structure */
static void free_imports( struct import *imp )
{
@@ -385,21 +443,20 @@ void add_extra_ld_symbol( const char *name )
}
/* retrieve an imported dll, adding one if necessary */
-struct import *add_static_import_dll( const char *name )
+static struct import *add_static_import_dll( const char *name )
{
struct import *import;
- char *dll_name = get_dll_name( name, NULL );
- if ((import = find_import_dll( dll_name ))) return import;
+ if ((import = find_import_dll( name ))) return import;
import = xmalloc( sizeof(*import) );
memset( import, 0, sizeof(*import) );
- import->dll_name = dll_name;
- import->full_name = xstrdup( dll_name );
- import->c_name = make_c_identifier( dll_name );
+ import->dll_name = xstrdup( name );
+ import->full_name = xstrdup( name );
+ import->c_name = make_c_identifier( name );
- if (is_delayed_import( dll_name ))
+ if (is_delayed_import( name ))
list_add_tail( &dll_delayed, &import->entry );
else
list_add_tail( &dll_imports, &import->entry );
@@ -426,21 +483,21 @@ static void add_import_func( struct import *imp, const char *name, const char *e
/* add an import for an undefined function of the form __wine$func$ */
static void add_undef_import( const char *name, int is_ordinal )
{
- char *p, *dll_name = xstrdup( name );
+ char *dll_name = decode_dll_name( &name );
int ordinal = 0;
struct import *import;
- if (!(p = strchr( dll_name, '$' ))) return;
- *p++ = 0;
- while (*p >= '0' && *p <= '9') ordinal = 10 * ordinal + *p++ - '0';
- if (*p != '$') return;
- p++;
+ if (!dll_name) return;
+ if (*name++ != '$') return;
+ while (*name >= '0' && *name <= '9') ordinal = 10 * ordinal + *name++ - '0';
+ if (*name++ != '$') return;
import = add_static_import_dll( dll_name );
if (is_ordinal)
- add_import_func( import, NULL, xstrdup( p ), ordinal, 0 );
+ add_import_func( import, NULL, xstrdup( name ), ordinal, 0 );
else
- add_import_func( import, xstrdup( p ), NULL, ordinal, 0 );
+ add_import_func( import, xstrdup( name ), NULL, ordinal, 0 );
+ free( dll_name );
}
/* check if the spec file exports any stubs */
@@ -1670,14 +1727,9 @@ static void build_windows_import_lib( const char *lib_name, DLLSPEC *spec )
/* create a Unix-style import library */
static void build_unix_import_lib( DLLSPEC *spec )
{
- static const char valid_chars[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789._@";
int i, total;
const char *name, *prefix;
- char *dll_name = xstrdup( spec->file_name );
-
- if (strendswith( dll_name, ".dll" )) dll_name[strlen(dll_name) - 4] = 0;
- if (strspn( dll_name, valid_chars ) < strlen( dll_name ))
- fatal_error( "%s contains invalid characters\n", spec->file_name );
+ char *dll_name = encode_dll_name( spec->file_name );
/* entry points */
More information about the wine-cvs
mailing list