|
1 | 1 | using System.IO; |
| 2 | +using System.Linq; |
2 | 3 | using System.Threading.Tasks; |
3 | 4 | using Confuser.Core; |
4 | 5 | using Confuser.Core.Project; |
5 | 6 | using Confuser.UnitTest; |
| 7 | +using dnlib.DotNet; |
6 | 8 | using Xunit; |
7 | 9 | using Xunit.Abstractions; |
8 | 10 |
|
@@ -64,5 +66,31 @@ public Task Library_Net10_RenameProtection() => |
64 | 66 | new SettingItem<Protection>("rename"), |
65 | 67 | outputDirSuffix: "-lib-net10", |
66 | 68 | checkOutput: false); |
| 69 | + |
| 70 | + // Regression guard: the subject has a 'allows ref struct' generic constraint |
| 71 | + // (GenericParamAttributes.AllowByRefLike). Renaming must not drop it — verify the flag |
| 72 | + // survives obfuscation on the output assembly. (dnlib 4.x names this flag; ConfuserEx |
| 73 | + // only renames generic parameters, so the attribute bits must be preserved.) |
| 74 | + [Fact] |
| 75 | + [Trait("Category", "CrossFramework")] |
| 76 | + [Trait("AppType", "Library")] |
| 77 | + [Trait("TFM", "net10.0")] |
| 78 | + public Task Library_Net10_PreservesAllowByRefLike() => |
| 79 | + Run("CrossFramework.Library.Net10.dll", |
| 80 | + null, |
| 81 | + new SettingItem<Protection>("rename"), |
| 82 | + outputDirSuffix: "-lib-net10-refstruct", |
| 83 | + checkOutput: false, |
| 84 | + postProcessAction: outputPath => { |
| 85 | + var modulePath = Path.Combine(outputPath, "CrossFramework.Library.Net10.dll"); |
| 86 | + using var module = ModuleDefMD.Load(modulePath); |
| 87 | + var genericParams = module.GetTypes() |
| 88 | + .SelectMany(type => type.Methods) |
| 89 | + .SelectMany(method => method.GenericParameters) |
| 90 | + .Concat(module.GetTypes().SelectMany(type => type.GenericParameters)); |
| 91 | + Assert.Contains(genericParams, |
| 92 | + gp => (gp.Flags & GenericParamAttributes.AllowByRefLike) != 0); |
| 93 | + return Task.CompletedTask; |
| 94 | + }); |
67 | 95 | } |
68 | 96 | } |
0 commit comments