Skip to content

Commit

Permalink
Write to UTF8Encoding object memory instead of replacing method, whic…
Browse files Browse the repository at this point in the history
…h takes effect immediately and requires less code, but is a bit less easily portable.
  • Loading branch information
Aldaviva committed Nov 7, 2023
1 parent 822c309 commit 177b199
Show file tree
Hide file tree
Showing 14 changed files with 92 additions and 386 deletions.
30 changes: 21 additions & 9 deletions .github/workflows/dotnetpackage.yml
Expand Up @@ -28,24 +28,36 @@ jobs:
- name: Build
run: dotnet build --no-restore --configuration Release --verbosity normal

- name: Test
- name: Test x64
run: |
dotnet test --no-build --verbosity normal --configuration Release --collect:"XPlat Code Coverage" --settings Test/Test.runsettings --logger "trx;LogFileName=TestResults.xml"
Out-File -InputObject "TEST_EXIT_CODE=$LASTEXITCODE" -FilePath $env:GITHUB_ENV -Append -Encoding UTF8
Copy-Item Test/TestResults/*/coverage.info Test/TestResults -ErrorAction Continue
dotnet test --arch x64 --no-build --verbosity normal --configuration Release --collect:"XPlat Code Coverage" --settings Test/Test.runsettings --logger "trx;LogFileName=TestResults-x64.xml" --logger "console;verbosity=detailed"
Out-File -InputObject "TEST_EXIT_CODE_X64=$LASTEXITCODE" -FilePath $env:GITHUB_ENV -Append -Encoding UTF8
Move-Item Test/TestResults/*/coverage.info Test/TestResults/coverage-x64.info -ErrorAction Continue
exit 0
- name: Test x86
run: |
dotnet test --arch x86 --no-build --verbosity normal --configuration Release --collect:"XPlat Code Coverage" --settings Test/Test.runsettings --logger "trx;LogFileName=TestResults-x86.xml" --logger "console;verbosity=detailed"
Out-File -InputObject "TEST_EXIT_CODE_X86=$LASTEXITCODE" -FilePath $env:GITHUB_ENV -Append -Encoding UTF8
Move-Item Test/TestResults/*/coverage.info Test/TestResults/coverage-x86.info -ErrorAction Continue
exit 0
- name: Upload test report
run: testspace Test/TestResults/TestResults.xml
run: testspace Test/TestResults/TestResults*.xml

- name: Upload coverage
uses: coverallsapp/github-action@master
uses: coverallsapp/github-action@v2
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
path-to-lcov: Test/TestResults/coverage.info
files: Test/TestResults/coverage-x86.info Test/TestResults/coverage-x64.info
format: lcov
allow-empty: true

- name: Stop if x64 tests failed
run: exit $env:TEST_EXIT_CODE_X64

- name: Stop if tests failed
run: exit $env:TEST_EXIT_CODE
- name: Stop if x86 tests failed
run: exit $env:TEST_EXIT_CODE_X86

- name: Pack
run: dotnet pack ${{ env.ProjectName }} --no-build --configuration Release --verbosity normal
Expand Down
2 changes: 1 addition & 1 deletion Bom.Squad.sln.DotSettings
Expand Up @@ -19,4 +19,4 @@
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=StaticReadonly/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=TypeParameters/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="T" Suffix="" Style="AaBb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=TypesAndNamespaces/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /&gt;</s:String>
<s:Boolean x:Key="/Default/Environment/Filtering/ExcludeCoverageFilters/=_002A_003B_002A_003BBom_002ESquad_002EInternal_002EMethodRedirect_002E_002A_003B_002A/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>
</wpf:ResourceDictionary>
6 changes: 4 additions & 2 deletions Bom.Squad/Bom.Squad.csproj
@@ -1,15 +1,16 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFrameworks>net452;netstandard2.0</TargetFrameworks>
<TargetFrameworks>net452;netcoreapp2.0</TargetFrameworks>
<Nullable>enable</Nullable>
<LangVersion>latest</LangVersion>

<Version>0.0.0</Version>
<Version>0.1.0</Version>
<Authors>Ben Hutchison</Authors>
<Copyright>© 2023 $(Authors)</Copyright>
<Company>$(Authors)</Company>
<NoWarn>CS8524</NoWarn>
<CheckEolTargetFramework>false</CheckEolTargetFramework> <!-- It's just a library, I'm not actually using .NET Core 2 -->

<PackageProjectUrl>https://github.com/Aldaviva/Bom.Squad</PackageProjectUrl>
<RepositoryUrl>https://github.com/Aldaviva/Bom.Squad.git</RepositoryUrl>
Expand All @@ -30,6 +31,7 @@
<ItemGroup>
<None Include="icon.png" Pack="true" PackagePath="\" />
<None Include="..\Readme.md" Pack="true" PackagePath="\" />
<InternalsVisibleTo Include="Test" />
</ItemGroup>

<ItemGroup>
Expand Down
2 changes: 0 additions & 2 deletions Bom.Squad/Bom.Squad.csproj.DotSettings

This file was deleted.

44 changes: 21 additions & 23 deletions Bom.Squad/BomSquad.cs
@@ -1,11 +1,10 @@
using Bom.Squad.Internal.MethodRedirect;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Text;

namespace Bom.Squad;

/// <summary>
/// <para>Allows you to modify the base class library <see cref="Encoding.UTF8"/> to not output byte order markers when encoding, although it will parse them correctly.</para>
/// <para>Allows you to modify the base class library <see cref="Encoding.UTF8"/> to not output byte order markers when encoding, although it will still parse them correctly.</para>
/// <para>Other encodings, such as <see cref="Encoding.Unicode"/> and <c>new UTF8Encoding(true, true)</c>, will not be affected.</para>
///
/// <para>Usage:</para>
Expand All @@ -14,30 +13,29 @@ namespace Bom.Squad;
public static class BomSquad {

/// <summary>
/// A UTF-8 <see cref="Encoding"/> instance that does not output byte order markers when encoding, although it will parse them correctly.
/// It throws exceptions when invalid bytes are detected.
/// </summary>
public static readonly Encoding Utf8NoBom = new UTF8Encoding(false, true);

private static bool _armed = true;

/// <summary>
/// <para>Modify the base class library <see cref="Encoding.UTF8"/> to not output byte order markers when encoding, although it will parse them correctly.</para>
/// <para>After calling this method, subsequent calls to <see cref="Encoding.UTF8"/> will not write BOMs.</para>
/// <para>Modify the base class library <see cref="Encoding.UTF8"/> to not output byte order markers when encoding, although it will still parse them correctly.</para>
/// <para>After calling this method, the <see cref="Encoding.UTF8"/> instance will behave as if was constructed with the <c>encoderShouldEmitUTF8Identifier</c> constructor parameter set to false, so it will not write BOMs.</para>
/// <para>Other encodings, such as <see cref="Encoding.Unicode"/> and <c>new UTF8Encoding(true, true)</c>, will not be affected.</para>
/// </summary>
// ExceptionAdjustment: M:System.Type.GetProperty(System.String,System.Reflection.BindingFlags) -T:System.Reflection.AmbiguousMatchException
// ExceptionAdjustment: M:System.Type.GetMethod(System.String,System.Reflection.BindingFlags) -T:System.Reflection.AmbiguousMatchException
/// <exception cref="AccessViolationException">if dereferencing one of the pointers fails</exception>
public static void DefuseUtf8Bom() {
if (_armed) {
MethodInfo oldMethod = typeof(Encoding).GetProperty("UTF8", BindingFlags.Static | BindingFlags.Public | BindingFlags.GetProperty)!.GetMethod;
MethodInfo newMethod = typeof(BomSquad).GetMethod(nameof(Utf8), BindingFlags.Static | BindingFlags.NonPublic)!;

oldMethod.RedirectTo(newMethod, true);
_armed = false;
Encoding utf8 = Encoding.UTF8;
if (utf8.GetPreamble().LongLength > 0) {
GCHandle gcHandle = GCHandle.Alloc(utf8, GCHandleType.WeakTrackResurrection);
IntPtr pointer1 = GCHandle.ToIntPtr(gcHandle);
IntPtr pointer2 = Marshal.ReadIntPtr(pointer1);

int emitUtf8IdentifierFieldOffset = PlatformInfo.IsNetCore switch {
true when PlatformInfo.Is64Bit => 37,
true => 21,
false when PlatformInfo.Is64Bit => 38,
false => 22
};

Marshal.WriteByte(pointer2, emitUtf8IdentifierFieldOffset, 0); // set private readonly bool UTF8Encoding._emitUTF8Identifier to false

gcHandle.Free();
}
}

private static Encoding Utf8() => Utf8NoBom;

}
41 changes: 0 additions & 41 deletions Bom.Squad/Internal/MethodRedirect/.editorconfig

This file was deleted.

199 changes: 0 additions & 199 deletions Bom.Squad/Internal/MethodRedirect/Extensions.cs

This file was deleted.

0 comments on commit 177b199

Please sign in to comment.