From b6db1d5d9c04aa960bce2b6651f6d8fbadb5726c Mon Sep 17 00:00:00 2001 From: Ryan Lucia Date: Fri, 28 Jun 2019 11:54:27 -0400 Subject: [PATCH] [netcore] Fix Assembly.GetForwardedTypes() (mono/mono#15452) * [netcore] Make GetForwardedTypes return nested types * [netcore] Throw proper error in GetTopLevelForwardedTypes * Remove unnecessary function * Formatting * Re-enable relevant tests * Switch to REFERENCE_MISSING * Use local error Commit migrated from https://github.com/mono/mono/commit/c879bc4691b4a76f1866af08024b0df5e27b6b8e --- src/mono/mono/metadata/icall-def-netcore.h | 2 +- src/mono/mono/metadata/icall.c | 56 ++++++++++++++++------ src/mono/netcore/CoreFX.issues.rsp | 8 ---- .../src/System.Reflection/RuntimeAssembly.cs | 38 ++++++++++++++- 4 files changed, 80 insertions(+), 24 deletions(-) diff --git a/src/mono/mono/metadata/icall-def-netcore.h b/src/mono/mono/metadata/icall-def-netcore.h index 1ee4922..680a46f 100644 --- a/src/mono/mono/metadata/icall-def-netcore.h +++ b/src/mono/mono/metadata/icall-def-netcore.h @@ -244,12 +244,12 @@ HANDLES(MMETHI_3, "get_retval_marshal", ves_icall_System_MonoMethodInfo_get_retv ICALL_TYPE(RASSEM, "System.Reflection.RuntimeAssembly", RASSEM_1) HANDLES(RASSEM_1, "GetExportedTypes", ves_icall_System_Reflection_RuntimeAssembly_GetExportedTypes, MonoArray, 1, (MonoReflectionAssembly)) HANDLES(RASSEM_1a, "GetFilesInternal", ves_icall_System_Reflection_RuntimeAssembly_GetFilesInternal, MonoObject, 3, (MonoReflectionAssembly, MonoString, MonoBoolean)) -HANDLES(RASSEM_1b, "GetForwardedTypes", ves_icall_System_Reflection_RuntimeAssembly_GetForwardedTypes, MonoArray, 1, (MonoReflectionAssembly)) HANDLES(RASSEM_2, "GetManifestModuleInternal", ves_icall_System_Reflection_Assembly_GetManifestModuleInternal, MonoReflectionModule, 1, (MonoReflectionAssembly)) HANDLES(RASSEM_3, "GetManifestResourceInfoInternal", ves_icall_System_Reflection_RuntimeAssembly_GetManifestResourceInfoInternal, MonoBoolean, 3, (MonoReflectionAssembly, MonoString, MonoManifestResourceInfo)) HANDLES(RASSEM_4, "GetManifestResourceInternal", ves_icall_System_Reflection_RuntimeAssembly_GetManifestResourceInternal, gpointer, 4, (MonoReflectionAssembly, MonoString, gint32_ref, MonoReflectionModuleOut)) HANDLES(RASSEM_5, "GetManifestResourceNames", ves_icall_System_Reflection_RuntimeAssembly_GetManifestResourceNames, MonoArray, 1, (MonoReflectionAssembly)) HANDLES(RASSEM_6, "GetModulesInternal", ves_icall_System_Reflection_RuntimeAssembly_GetModulesInternal, MonoArray, 1, (MonoReflectionAssembly)) +HANDLES(RASSEM_6b, "GetTopLevelForwardedTypes", ves_icall_System_Reflection_RuntimeAssembly_GetTopLevelForwardedTypes, MonoArray, 1, (MonoReflectionAssembly)) HANDLES(RASSEM_7, "InternalGetReferencedAssemblies", ves_icall_System_Reflection_Assembly_InternalGetReferencedAssemblies, GPtrArray_ptr, 1, (MonoReflectionAssembly)) HANDLES(RASSEM_8, "InternalImageRuntimeVersion", ves_icall_System_Reflection_RuntimeAssembly_InternalImageRuntimeVersion, MonoString, 1, (MonoReflectionAssembly)) HANDLES(RASSEM_9, "get_EntryPoint", ves_icall_System_Reflection_RuntimeAssembly_get_EntryPoint, MonoReflectionMethod, 1, (MonoReflectionAssembly)) diff --git a/src/mono/mono/metadata/icall.c b/src/mono/mono/metadata/icall.c index cf65719..d9c3505 100644 --- a/src/mono/mono/metadata/icall.c +++ b/src/mono/mono/metadata/icall.c @@ -6023,7 +6023,7 @@ ves_icall_System_Reflection_RuntimeAssembly_GetExportedTypes (MonoReflectionAsse } MonoArrayHandle -ves_icall_System_Reflection_RuntimeAssembly_GetForwardedTypes (MonoReflectionAssemblyHandle assembly_h, MonoError *error) +ves_icall_System_Reflection_RuntimeAssembly_GetTopLevelForwardedTypes (MonoReflectionAssemblyHandle assembly_h, MonoError *error) { MonoAssembly *assembly = MONO_HANDLE_GETVAL (assembly_h, assembly); MonoImage *image = assembly->image; @@ -6039,10 +6039,16 @@ ves_icall_System_Reflection_RuntimeAssembly_GetForwardedTypes (MonoReflectionAss if (mono_metadata_decode_row_col (table, i, MONO_EXP_TYPE_FLAGS) & TYPE_ATTRIBUTE_FORWARDER) count ++; } - MonoArrayHandle res = mono_array_new_handle (mono_domain_get (), mono_defaults.runtimetype_class, count, error); + + MonoArrayHandle types = mono_array_new_handle (mono_domain_get (), mono_defaults.runtimetype_class, count, error); + return_val_if_nok (error, NULL_HANDLE_ARRAY); + MonoArrayHandle exceptions = mono_array_new_handle (mono_domain_get (), mono_defaults.exception_class, count, error); return_val_if_nok (error, NULL_HANDLE_ARRAY); + int aindex = 0; + int exception_count = 0; for (int i = 0; i < table->rows; ++i) { + ERROR_DECL (local_error); mono_metadata_decode_row (table, i, cols, MONO_EXP_TYPE_SIZE); if (!(cols [MONO_EXP_TYPE_FLAGS] & TYPE_ATTRIBUTE_FORWARDER)) continue; @@ -6056,23 +6062,45 @@ ves_icall_System_Reflection_RuntimeAssembly_GetForwardedTypes (MonoReflectionAss mono_assembly_load_reference (image, assembly_idx - 1); g_assert (image->references [assembly_idx - 1]); - if (image->references [assembly_idx - 1] == (gpointer)-1) + if (image->references [assembly_idx - 1] == REFERENCE_MISSING) { + MonoExceptionHandle ex = MONO_HANDLE_NEW (MonoException, mono_get_exception_bad_image_format ("Invalid image")); + MONO_HANDLE_ARRAY_SETREF (types, aindex, NULL_HANDLE); + MONO_HANDLE_ARRAY_SETREF (exceptions, aindex, ex); + exception_count++; aindex++; continue; - MonoClass *klass = mono_class_from_name_checked (image->references [assembly_idx - 1]->image, nspace, name, error); - if (!is_ok (error)) + } + MonoClass *klass = mono_class_from_name_checked (image->references [assembly_idx - 1]->image, nspace, name, local_error); + if (!is_ok (local_error)) { + MonoExceptionHandle ex = mono_error_convert_to_exception_handle (local_error); + MONO_HANDLE_ARRAY_SETREF (types, aindex, NULL_HANDLE); + MONO_HANDLE_ARRAY_SETREF (exceptions, aindex, ex); + mono_error_cleanup (local_error); + exception_count++; aindex++; continue; - MonoReflectionTypeHandle rt = mono_type_get_object_handle (mono_domain_get (), m_class_get_byval_arg (klass), error); - if (!is_ok (error)) + } + MonoReflectionTypeHandle rt = mono_type_get_object_handle (mono_domain_get (), m_class_get_byval_arg (klass), local_error); + if (!is_ok (local_error)) { + MonoExceptionHandle ex = mono_error_convert_to_exception_handle (local_error); + MONO_HANDLE_ARRAY_SETREF (types, aindex, NULL_HANDLE); + MONO_HANDLE_ARRAY_SETREF (exceptions, aindex, ex); + mono_error_cleanup (local_error); + exception_count++; aindex++; continue; - MONO_HANDLE_ARRAY_SETREF (res, aindex, rt); - aindex ++; + } + MONO_HANDLE_ARRAY_SETREF (types, aindex, rt); + MONO_HANDLE_ARRAY_SETREF (exceptions, aindex, NULL_HANDLE); + aindex++; } - if (aindex < count) { - // FIXME: - mono_error_set_type_load_name (error, g_strdup (""), g_strdup (""), ""); - return MONO_HANDLE_NEW (MonoArray, NULL); + + if (exception_count > 0) { + MonoExceptionHandle exc = MONO_HANDLE_NEW (MonoException, NULL); + MONO_HANDLE_ASSIGN (exc, mono_get_exception_reflection_type_load_checked (types, exceptions, error)); + return_val_if_nok (error, NULL_HANDLE_ARRAY); + mono_error_set_exception_handle (error, exc); + return NULL_HANDLE_ARRAY; } - return res; + + return types; } #endif diff --git a/src/mono/netcore/CoreFX.issues.rsp b/src/mono/netcore/CoreFX.issues.rsp index e18acb0..b8e91b3 100644 --- a/src/mono/netcore/CoreFX.issues.rsp +++ b/src/mono/netcore/CoreFX.issues.rsp @@ -531,14 +531,6 @@ # https://github.com/mono/mono/issues/15077 -nomethod System.Reflection.Tests.GetTypeTests.GetType -# Expects ReflectionTypeLoadException but TypeLoadException is thrown -# https://github.com/mono/mono/issues/15078 --nomethod System.Reflection.Tests.AssemblyNetCoreAppTests.AssemblyGetForwardedTypesLoadFailure - -# Extra types in the type array are expected. -# https://github.com/mono/mono/issues/15079 --nomethod System.Reflection.Tests.AssemblyNetCoreAppTests.AssemblyGetForwardedTypes - # Assertion expects false, but we return true # https://github.com/mono/mono/issues/15080 -nomethod System.Reflection.Tests.TypeInfoTests.IsAssignableFrom diff --git a/src/mono/netcore/System.Private.CoreLib/src/System.Reflection/RuntimeAssembly.cs b/src/mono/netcore/System.Private.CoreLib/src/System.Reflection/RuntimeAssembly.cs index 17b0741..2ebea8c 100644 --- a/src/mono/netcore/System.Private.CoreLib/src/System.Reflection/RuntimeAssembly.cs +++ b/src/mono/netcore/System.Private.CoreLib/src/System.Reflection/RuntimeAssembly.cs @@ -137,7 +137,43 @@ namespace System.Reflection public override extern Type[] GetExportedTypes (); [MethodImplAttribute (MethodImplOptions.InternalCall)] - public override extern Type[] GetForwardedTypes (); + internal extern Type[] GetTopLevelForwardedTypes (); + + public override Type[] GetForwardedTypes () { + Type[] topLevelTypes = GetTopLevelForwardedTypes (); + List forwardedTypes = new List (topLevelTypes); + List exceptions = new List (); + + foreach (Type t in topLevelTypes) + AddPublicNestedTypes (t, forwardedTypes, exceptions); + + if (exceptions.Count > 0) { + forwardedTypes.AddRange (new Type [exceptions.Count]); // add one null Type for each exception + exceptions.InsertRange (0, new Exception [forwardedTypes.Count]); // align the Exceptions with the null Types + throw new ReflectionTypeLoadException (forwardedTypes.ToArray (), exceptions.ToArray ()); + } + + return forwardedTypes.ToArray (); + } + + private static void AddPublicNestedTypes (Type type, List types, List exceptions) + { + Type[] nestedTypes; + + try { + nestedTypes = type.GetNestedTypes (BindingFlags.Public); + } + catch (FileLoadException e) { exceptions.Add (e); return; } + catch (FileNotFoundException e) { exceptions.Add (e); return; } + catch (TypeLoadException e) { exceptions.Add (e); return; } + catch (IOException e) { exceptions.Add (e); return; } + catch (UnauthorizedAccessException e) { exceptions.Add (e); return; } + + foreach (Type nestedType in nestedTypes) { + types.Add(nestedType); + AddPublicNestedTypes(nestedType, types, exceptions); + } + } public override ManifestResourceInfo GetManifestResourceInfo (string resourceName) { -- 2.7.4