Skip to content

Commit a4a5f0a

Browse files
authored
Merge pull request #950 from Unity-Technologies/unity-master-ignore-assembly-version-no-strong-name
Ignore assembly version when loading non-strong named reference assemblies (case 996473)
2 parents 5b484a7 + 178c05e commit a4a5f0a

File tree

3 files changed

+48
-23
lines changed

3 files changed

+48
-23
lines changed

mono/metadata/appdomain.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2072,12 +2072,18 @@ mono_domain_assembly_search (MonoAssemblyName *aname,
20722072
GSList *tmp;
20732073
MonoAssembly *ass;
20742074
gboolean refonly = GPOINTER_TO_UINT (user_data);
2075+
const gboolean strong_name = aname->public_key_token[0] != 0;
2076+
/* If it's not a strong name, any version that has the right simple
2077+
* name is good enough to satisfy the request. .NET Framework also
2078+
* ignores case differences in this case. */
2079+
const MonoAssemblyNameEqFlags eq_flags = strong_name ? MONO_ANAME_EQ_IGNORE_CASE :
2080+
(MONO_ANAME_EQ_IGNORE_PUBKEY | MONO_ANAME_EQ_IGNORE_VERSION | MONO_ANAME_EQ_IGNORE_CASE);
20752081

20762082
mono_domain_assemblies_lock (domain);
20772083
for (tmp = domain->domain_assemblies; tmp; tmp = tmp->next) {
20782084
ass = (MonoAssembly *)tmp->data;
20792085
/* Dynamic assemblies can't match here in MS.NET */
2080-
if (assembly_is_dynamic (ass) || refonly != ass->ref_only || !mono_assembly_names_equal (aname, &ass->aname))
2086+
if (assembly_is_dynamic (ass) || refonly != ass->ref_only || !mono_assembly_names_equal_flags (aname, &ass->aname, eq_flags))
20812087
continue;
20822088

20832089
mono_domain_assemblies_unlock (domain);

mono/metadata/assembly-internals.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,24 @@
99
#include <glib.h>
1010

1111
#include <mono/metadata/assembly.h>
12+
#include <mono/metadata/metadata-internals.h>
13+
14+
/* Flag bits for mono_assembly_names_equal_flags (). */
15+
typedef enum {
16+
/* Default comparison: all fields must match */
17+
MONO_ANAME_EQ_NONE = 0x0,
18+
/* Don't compare public key token */
19+
MONO_ANAME_EQ_IGNORE_PUBKEY = 0x1,
20+
/* Don't compare the versions */
21+
MONO_ANAME_EQ_IGNORE_VERSION = 0x2,
22+
/* When comparing simple names, ignore case differences */
23+
MONO_ANAME_EQ_IGNORE_CASE = 0x4,
24+
25+
MONO_ANAME_EQ_MASK = 0x7
26+
} MonoAssemblyNameEqFlags;
27+
28+
gboolean
29+
mono_assembly_names_equal_flags (MonoAssemblyName *l, MonoAssemblyName *r, MonoAssemblyNameEqFlags flags);
1230

1331
MONO_API MonoImage* mono_assembly_load_module_checked (MonoAssembly *assembly, uint32_t idx, MonoError *error);
1432

mono/metadata/assembly.c

Lines changed: 23 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -63,18 +63,6 @@ typedef struct {
6363
gboolean framework_facade_assembly;
6464
} AssemblyVersionMap;
6565

66-
/* Flag bits for assembly_names_equal_flags (). */
67-
typedef enum {
68-
/* Default comparison: all fields must match */
69-
ANAME_EQ_NONE = 0x0,
70-
/* Don't compare public key token */
71-
ANAME_EQ_IGNORE_PUBKEY = 0x1,
72-
/* Don't compare the versions */
73-
ANAME_EQ_IGNORE_VERSION = 0x2,
74-
75-
ANAME_EQ_MASK = 0x3
76-
} AssemblyNameEqFlags;
77-
7866
/* the default search path is empty, the first slot is replaced with the computed value */
7967
static const char*
8068
default_path [] = {
@@ -359,9 +347,6 @@ mono_assembly_is_in_gac (const gchar *filanem);
359347
static MonoAssembly*
360348
prevent_reference_assembly_from_running (MonoAssembly* candidate, gboolean refonly);
361349

362-
static gboolean
363-
assembly_names_equal_flags (MonoAssemblyName *l, MonoAssemblyName *r, AssemblyNameEqFlags flags);
364-
365350
/* Assembly name matching */
366351
static gboolean
367352
exact_sn_match (MonoAssemblyName *wanted_name, MonoAssemblyName *candidate_name);
@@ -685,28 +670,44 @@ check_policy_versions (MonoAssemblyBindingInfo *info, MonoAssemblyName *name)
685670
gboolean
686671
mono_assembly_names_equal (MonoAssemblyName *l, MonoAssemblyName *r)
687672
{
688-
return assembly_names_equal_flags (l, r, ANAME_EQ_NONE);
673+
return mono_assembly_names_equal_flags (l, r, MONO_ANAME_EQ_NONE);
689674
}
690675

676+
/**
677+
* mono_assembly_names_equal_flags:
678+
* \param l first assembly name
679+
* \param r second assembly name
680+
* \param flags flags that affect what is compared.
681+
*
682+
* Compares two \c MonoAssemblyName instances and returns whether they are equal.
683+
*
684+
* This compares the simple names and cultures and optionally the versions and
685+
* public key tokens, depending on the \c flags.
686+
*
687+
* \returns TRUE if both assembly names are equal.
688+
*/
691689
gboolean
692-
assembly_names_equal_flags (MonoAssemblyName *l, MonoAssemblyName *r, AssemblyNameEqFlags flags)
690+
mono_assembly_names_equal_flags (MonoAssemblyName *l, MonoAssemblyName *r, MonoAssemblyNameEqFlags flags)
693691
{
694692
if (!l->name || !r->name)
695693
return FALSE;
696694

697-
if (strcmp (l->name, r->name))
695+
if ((flags & MONO_ANAME_EQ_IGNORE_CASE) != 0 && g_strcasecmp (l->name, r->name))
696+
return FALSE;
697+
698+
if ((flags & MONO_ANAME_EQ_IGNORE_CASE) == 0 && strcmp (l->name, r->name))
698699
return FALSE;
699700

700701
if (l->culture && r->culture && strcmp (l->culture, r->culture))
701702
return FALSE;
702703

703704
if ((l->major != r->major || l->minor != r->minor ||
704705
l->build != r->build || l->revision != r->revision) &&
705-
(flags & ANAME_EQ_IGNORE_VERSION) == 0)
706+
(flags & MONO_ANAME_EQ_IGNORE_VERSION) == 0)
706707
if (! ((l->major == 0 && l->minor == 0 && l->build == 0 && l->revision == 0) || (r->major == 0 && r->minor == 0 && r->build == 0 && r->revision == 0)))
707708
return FALSE;
708709

709-
if (!l->public_key_token [0] || !r->public_key_token [0] || (flags & ANAME_EQ_IGNORE_PUBKEY) != 0)
710+
if (!l->public_key_token [0] || !r->public_key_token [0] || (flags & MONO_ANAME_EQ_IGNORE_PUBKEY) != 0)
710711
return TRUE;
711712

712713
if (!mono_public_tokens_are_equal (l->public_key_token, r->public_key_token))
@@ -3626,13 +3627,13 @@ framework_assembly_sn_match (MonoAssemblyName *wanted_name, MonoAssemblyName *ca
36263627
if (vmap) {
36273628
if (!vmap->framework_facade_assembly) {
36283629
/* If the wanted name is a framework assembly, it's enough for the name/version/culture to match. If the assembly was remapped, the public key token is likely unrelated. */
3629-
gboolean result = assembly_names_equal_flags (wanted_name, candidate_name, ANAME_EQ_IGNORE_PUBKEY);
3630+
gboolean result = mono_assembly_names_equal_flags (wanted_name, candidate_name, MONO_ANAME_EQ_IGNORE_PUBKEY);
36303631
mono_trace (G_LOG_LEVEL_INFO, MONO_TRACE_ASSEMBLY, "Predicate: candidate and wanted names %s (ignoring the public key token)", result ? "match, returning TRUE" : "don't match, returning FALSE");
36313632
return result;
36323633
} else {
36333634
/* For facades, the name and public key token should
36343635
* match, but the version doesn't matter. */
3635-
gboolean result = assembly_names_equal_flags (wanted_name, candidate_name, ANAME_EQ_IGNORE_VERSION);
3636+
gboolean result = mono_assembly_names_equal_flags (wanted_name, candidate_name, MONO_ANAME_EQ_IGNORE_VERSION);
36363637
mono_trace (G_LOG_LEVEL_INFO, MONO_TRACE_ASSEMBLY, "Predicate: candidate and wanted names %s (ignoring version)", result ? "match, returning TRUE" : "don't match, returning FALSE");
36373638
return result;
36383639
}

0 commit comments

Comments
 (0)