Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Obsolete Encoding.UTF7 property and UTF7Encoding ctors #37535

Merged
merged 14 commits into from
Jun 30, 2020

Conversation

GrabYourPitchforks
Copy link
Member

Resolves #32284.

Breaking changes

  • The property Encoding.UTF7 is now obsolete as warning (diagnostic id BCL0001).
  • The UTF7Encoding constructors are now obsolete as warning (diagnostic id BCL0001). The type itself is not obsolete in order to allow code like if (x is UTF7Encoding) to continue to work without warning.
  • The APIs Encoding.GetEncoding(65000 /* UTF-7 code page */) and Encoding.GetEncoding("utf-7") will now throw an "unknown code page" exception.

AppContext can be used to re-enable Encoding.GetEncoding recognizing the string "utf-7" or the code page 65000.

This resulted in some changes to unit tests. /cc @carlossanlop @jozkee @dotnet/ncl to review their areas of ownership and to make sure I didn't torpedo the tests. For the System.Net.Http.Json UTF-7 tests, I removed the test body entirely rather than suppressing, as the point of this change was to disallow HttpClient and friends from honoring Content-Type: ...; charset=utf-7 without explicit opt-in by the app developer.

/cc @terrajobst as well since this our first usage of the "better obsoletion" APIs that were added, so we should settle on URL and diagnostic id prefix.

@GrabYourPitchforks GrabYourPitchforks added area-System.Text.Encoding breaking-change Issue or PR that represents a breaking API or functional change over a prerelease. labels Jun 6, 2020
@ghost
Copy link

ghost commented Jun 6, 2020

Tagging subscribers to this area: @tarekgh, @krwq
Notify danmosemsft if you want to be subscribed.

@GrabYourPitchforks
Copy link
Member Author

/cc @jkotalik and @Tratcher since there's some aspnet code which touches the Encoding.UTF7 property

@@ -111,7 +111,9 @@ public void Encoding_ISCIIAssemese()
public void Encoding_UTF7()
{
Debug.WriteLine("Verifying UTF7Encoding Encoding");
#pragma warning disable BCL0001 // Encoding.UTF7 property is obsolete
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do obsoletion IDs need to be numerical? If not, have we considered using more descriptive names that would avoid the need for a comment? May not be a great idea to break from convention even if it's possible.

case CodePageUTF7: // 65000
{
// Support for UTF-7 is disabled by default. It can be re-enabled by registering a custom
// provider (which early-exits this method before the 'switch' statement) or by using
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What custom provider?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you call Encoding.RegisterProvider, you can override the return value of Encoding.GetEncoding("utf-7"), Encoding.GetEncoding("utf-8"), and any other encoding instance. If you register a custom provider for UTF-7, we never query the AppContext switch because this switch statement never get hit.

Registering a custom provider doesn't change the return value of the built-in accelerators (like Encoding.UTF7 or Encoding.UTF8) since they're hardcoded to always use the built-in implementation.

Copy link
Member

@stephentoub stephentoub Jun 8, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right. It's the "re-enabled" lingo that confuses me. There's no way for someone to get at our built-in Encoding to "re-enable" it via Encoding.RegisterProvider, is there? They've have to implement one from scratch, no?

@Tratcher
Copy link
Member

Tratcher commented Jun 8, 2020

/cc @jkotalik and @Tratcher since there's some aspnet code which touches the Encoding.UTF7 property

All AspNetCore usages I see are either checks to prevent it from being used, or tests for explicit usage. We may have to tweak the code a bit, but there shouldn't be any functional changes.

@jkotas
Copy link
Member

jkotas commented Jun 25, 2020

@eerhardt Anything we want to adjust here to make it easy for the linker to strip the UTF7Encoding?

@eerhardt
Copy link
Member

Anything we want to adjust here to make it easy for the linker to strip the UTF7Encoding?

Yes, as it exists today the linker won't be able to strip UTF7Encoding since it is being rooted by System.Text.Encoding::GetEncoding(System.Int32).

To enable stripping, we can make the new switch a full blown feature switch. You can see an example of this in #38129.

Basically the thing we will want to add is an entry into this file

<assembly fullname="System.Private.CoreLib">
<type fullname="System.Globalization.GlobalizationMode">
<method signature="System.Boolean get_Invariant()" body="stub" value="true" feature="System.Globalization.Invariant" featurevalue="true" />
</type>
</assembly>

that tells the linker when LocalAppContextSwitches.EnableUnsafeUTF7Encoding property can be stubbed out as return false;. This will allow any code that branches based on the property to get the branch removed during linking time.

Something like:

    <type fullname="System.LocalAppContextSwitches">
      <method signature="System.Boolean get_EnableUnsafeUTF7Encoding()" body="stub" value="false" feature="Switch.System.Text.Encoding.EnableUnsafeUTF7Encoding" featurevalue="false" />
    </type>

@GrabYourPitchforks
Copy link
Member Author

Thanks @eerhardt for the tip! I'll plumb it through in the next iteration.

Drop switch prefix
Disallow Encoding.GetEncoding from seeing an EncodingProvider-returned UTF-7 encoding
@@ -3,5 +3,8 @@
<type fullname="System.Globalization.GlobalizationMode">
<method signature="System.Boolean get_Invariant()" body="stub" value="true" feature="System.Globalization.Invariant" featurevalue="true" />
</type>
<type fullname="System.LocalAppContextSwitches">
<method signature="System.Boolean get_EnableUnsafeUTF7Encoding()" body="stub" value="true" feature="System.Text.Encoding.EnableUnsafeUTF7Encoding" featurevalue="true" />
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks reversed to me. I believe that this would allow UTF7Encoding to be unconditionally enabled; but not trimmed.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you're right. Even though the default value is false, we still want trimming to take place if somebody has set false.

@GrabYourPitchforks
Copy link
Member Author

@jkotas any idea why the wasm tests might be failing?
https://helix.dot.net/api/2019-06-17/jobs/b400b19c-d5d5-41c2-a0a5-10064c66ac86/workitems/System.Text.Encoding.Tests/console

[23:20:06] dbug: test[0]
      [FAIL] System.Text.Encodings.Tests.EncodingMiscTests.NormalizationTest(codepage: 65000, normalized: False, normalizedC: False, normalizedD: False, normalizedKC: False, normalizedKD: False)
      
[23:20:06] dbug: test[0]
      System.NotSupportedException : Support for UTF-7 is disabled. See https://aka.ms/dotnet-warnings/MSLIB0001 for more information.

There is a runtimeconfig.template.json file present in that test directory which re-enables the UTF-7 code paths, so the test project succeeds on all other platforms. See https://github.com/dotnet/runtime/blob/9d6811c5753d0d627d608a4d5d932aee014f43e5/src/libraries/System.Text.Encoding/tests/runtimeconfig.template.json.

@jkotas
Copy link
Member

jkotas commented Jun 26, 2020

@jkotas any idea why the wasm tests might be failing?

I do not think wasm supports .runtimeconfig.json files. @safern ?

@akoeplinger
Copy link
Member

@jkotas any idea why the wasm tests might be failing?

I do not think wasm supports .runtimeconfig.json files. @safern ?

It's not supported right now, but I think we should make it work.

I've opened #38433 to track that, you can add an [ActiveIssue(..., TestPlatforms.Browser)] on the affected tests.

@GrabYourPitchforks
Copy link
Member Author

Awesome - thanks both for the pointer! :)

@GrabYourPitchforks
Copy link
Member Author

Test failure is #38605. I'm just waiting for a review signoff before merging.

@tarekgh I think I addressed all your feedback?

Copy link
Member

@tarekgh tarekgh left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @GrabYourPitchforks. LGTM.

@tarekgh
Copy link
Member

tarekgh commented Jun 30, 2020

@GrabYourPitchforks just checking, did you log and fill a breaking change template for this one? sorry if I missed it.

@GrabYourPitchforks
Copy link
Member Author

@tarekgh Not yet, thanks for the reminder. :)
I'll add it to the docs repo and make sure the aka.ms link forwards to it.

@GrabYourPitchforks GrabYourPitchforks merged commit 74cfc0f into dotnet:master Jun 30, 2020
@GrabYourPitchforks GrabYourPitchforks deleted the obs_utf7 branch June 30, 2020 20:10
@GrabYourPitchforks
Copy link
Member Author

Breaking change notification: dotnet/docs#19274

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-System.Text.Encoding breaking-change Issue or PR that represents a breaking API or functional change over a prerelease.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Proposal: Obsolete UTF-7 encoding in the framework
8 participants