Skip to content

Added input sanitization for deprecatedMessage values from service models before they are emitted into generated C# code.#4359

Draft
GarrettBeatty wants to merge 1 commit intodevelopmentfrom
gcbeatty/deprecated
Draft

Added input sanitization for deprecatedMessage values from service models before they are emitted into generated C# code.#4359
GarrettBeatty wants to merge 1 commit intodevelopmentfrom
gcbeatty/deprecated

Conversation

@GarrettBeatty
Copy link
Copy Markdown
Contributor

@GarrettBeatty GarrettBeatty commented Mar 17, 2026

Description

Added input sanitization for deprecatedMessage values from service models before they are emitted into generated C# code. The deprecatedMessage field was being used raw in [Obsolete("...")] attributes, which could produce broken generated code if the message contained newlines (\r, \n), double quotes ("), or HTML tags (<p>, </p>, <code>, </code>).

A new SanitizeDeprecationMessage() extension method was added to the StringExtensions class in GeneratorHelpers.cs and is now called from the DeprecationMessage property getters in Member.cs, Operation.cs, and Shape.cs.

Motivation and Context

Other fields in the generator (e.g., documentation strings) are sanitized via Replace("\n", string.Empty) and similar transformations before being emitted into generated code. However, deprecatedMessage was not receiving any sanitization. Since deprecation messages are placed directly into [Obsolete("...")] string literals in generated C# code, unsanitized content such as newlines or quotes could break compilation of the generated SDK code.

Testing

  • Added 3 new unit tests in ServiceClientGeneratorTests/UnitTests.cs that verify sanitization of deprecation messages for operations, shapes, and members.
  • Created a test model (TestModelDeprecated.json) containing deprecated items with newlines, \r, HTML tags (<p>, </p>, <code>, </code>), and double quotes in their deprecatedMessage values.
  • All 3 new tests pass, and all existing tests continue to pass.

Dry-run

  • Dry-run ID: b87882a7-07cc-4fb6-9f71-88c01f4fdb2b
  • Status:
    • Pending
    • Completed successfully
    • Failed
  • Failed bypass reason:

Breaking Changes Assessment

No breaking changes. This is a strictly additive sanitization step applied to generated code output. The sanitization only removes/replaces characters that would have caused issues in generated code (\r, \n, ", HTML tags). Existing valid deprecation messages that don't contain these characters are unaffected.

Screenshots (if appropriate)

N/A

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)

Checklist

  • My code follows the code style of this project
  • My change requires a change to the documentation
  • I have updated the documentation accordingly
  • I have read the README document
  • I have added tests to cover my changes
  • All new and existing tests passed

License

  • I confirm that this pull request can be released under the Apache 2 license

@GarrettBeatty GarrettBeatty requested a review from Copilot March 17, 2026 19:15
@GarrettBeatty GarrettBeatty changed the title Update deprecationmessage to sanitize input Added input sanitization for deprecatedMessage values from service models before they are emitted into generated C# code. Mar 17, 2026
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR adds sanitization for deprecation messages (operation/shape/member) to prevent malformed generated code and adds unit tests plus a test service model to verify the sanitization behavior.

Changes:

  • Added SanitizeDeprecationMessage() and applied it to DeprecationMessage on Operation, Shape, and Member.
  • Added unit tests and a fixture model JSON to validate deprecation message sanitization.
  • Minor formatting change in SimpleModels.cs (blank line).

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
generator/ServiceClientGeneratorTests/UnitTests.cs Adds tests validating deprecation message sanitization for operations, shapes, and members.
generator/ServiceClientGeneratorTests/Content/TestModelDeprecated.json Adds a test service model containing deprecated traits/messages with newlines, quotes, and HTML tags.
generator/ServiceClientGeneratorLib/SimpleModels.cs Minor whitespace/formatting change.
generator/ServiceClientGeneratorLib/Shape.cs Sanitizes shape DeprecationMessage before returning.
generator/ServiceClientGeneratorLib/Operation.cs Sanitizes operation DeprecationMessage before returning.
generator/ServiceClientGeneratorLib/Member.cs Sanitizes member DeprecationMessage before returning.
generator/ServiceClientGeneratorLib/GeneratorHelpers.cs Introduces SanitizeDeprecationMessage() helper.

You can also share your feedback on Copilot code review. Take the survey.

Comment on lines +459 to +466
public static string SanitizeDeprecationMessage(this string s)
{
return s
.Replace("\r", string.Empty)
.Replace("\n", string.Empty)
.Replace("\"", "'")
.Replace("<p>", string.Empty)
.Replace("</p>", string.Empty)
return s
.Replace("\r", string.Empty)
.Replace("\n", string.Empty)
.Replace("\"", "'")
/// break generated code (e.g. newlines, HTML tags, quotes in [Obsolete("...")] attributes).
/// </summary>
public static string SanitizeDeprecationMessage(this string s)
{

#region Deprecation Message Sanitization Tests

private const string _deprecatedModelsPath = "../../Content/TestModelDeprecated.json";
{
"version": "1.0",
"metadata": {
"apiVersion": "2020-6-25",
@@ -0,0 +1,43 @@
{
"version": "1.0",
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I wonder if this approach using a json file can be simplified by just testing that the method works as intended by testing it with a string. Is there a reason a json file was chosen like this?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Right now the only way to verify the generator works is by running against the real models (these unit tests don't run anywhere in our build system, and I think they were broken for quite some time).

So for now I'd say let's just included the generator/ServiceClientGeneratorLib/ changes in the PR. Also, I assume we'd need to do the same for V3?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

i did run locally by manually updating one of the service json files, i just havent updated the PR description yet. and yeah i will also need to do same for v3

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants