Skip to content

STJ source generator produces noncompilable code on some locales #121277

@luryus

Description

@luryus

Description

If JsonPropertyOrder is used with a negative value, and STJ source generation is used, the order number is written to the generated code file using the current culture. Depending on the active locale, this can make the code uncompilable.

For example, on locale fi_FI.UTF-8, negative numbers use the U+2212 minus sign instead of the normal hyphen character. This is not valid C# syntax and therefore the code won't compile.

I ran into this when trying to build ASP.NET Core on my own machine. The ProblemDetails class uses negative JsonPropertyOrder values there.

Similar issue from regex code generation: #113077

Reproduction Steps

  1. Set up this Program.cs file:
using System.Text.Json;
using System.Text.Json.Serialization;

public static class Program
{
    public static void Main()
    {
        var foo = new Foo { Bar = 123 };
        var ser = JsonSerializer.Serialize(foo, FooJsonContext.Default.Foo);
        Console.WriteLine(ser);
    }
}

public class Foo
{
    [JsonPropertyOrder(-1)]
    public int Bar { get; set; }
}

[JsonSerializable(typeof(Foo))]
public partial class FooJsonContext : JsonSerializerContext;
  1. Verify that build works on locale en_US.UTF-8
export LANG="en_US.UTF-8"
dotnet build-server shutdown
dotnet build
  1. Try to build on locale fi_FI.UTF-8, and see the build fail:
export LANG="fi_FI.UTF-8"
dotnet build-server shutdown
dotnet build

Expected behavior

The generated code is valid C# code and compiles on all locales.

Actual behavior

The generated code contains a minus sign (U+2212) character that's not a valid token in C#. This makes the generated code not compile.

FooJsonContext.Foo.g.cs(68,31): error CS1525: Invalid expression term ''
FooJsonContext.Foo.g.cs(68,31): error CS1002: ; expected
FooJsonContext.Foo.g.cs(68,31): error CS1056: Unexpected character '−'
FooJsonContext.Foo.g.cs(68,32): error CS0201: Only assignment, call, increment, decrement, await, and new object expressions can be used as a statement

Regression?

No response

Known Workarounds

No response

Configuration

  • .NET 9.0.9, SDK 9.0.110
  • Arch Linux, kernel 6.17.5-arch1-1, x64

Other information

STJ code generator should probably use CultureInfo.InvariantCulture here:

writer.WriteLine($"properties[{i}].Order = {property.Order};");

Metadata

Metadata

Assignees

Labels

area-System.Text.Jsonbugin-prThere is an active PR which will close this issue when it is merged

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions