Skip to content

Commit 5c0f772

Browse files
committed
Properly serialize negative zero
1 parent f51248e commit 5c0f772

File tree

3 files changed

+92
-3
lines changed

3 files changed

+92
-3
lines changed
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
// <copyright file="DoubleConverter.cs" company="Selenium Committers">
2+
// Licensed to the Software Freedom Conservancy (SFC) under one
3+
// or more contributor license agreements. See the NOTICE file
4+
// distributed with this work for additional information
5+
// regarding copyright ownership. The SFC licenses this file
6+
// to you under the Apache License, Version 2.0 (the
7+
// "License"); you may not use this file except in compliance
8+
// with the License. You may obtain a copy of the License at
9+
//
10+
// http://www.apache.org/licenses/LICENSE-2.0
11+
//
12+
// Unless required by applicable law or agreed to in writing,
13+
// software distributed under the License is distributed on an
14+
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
// KIND, either express or implied. See the License for the
16+
// specific language governing permissions and limitations
17+
// under the License.
18+
// </copyright>
19+
20+
using System;
21+
using System.Text.Json;
22+
using System.Text.Json.Serialization;
23+
24+
namespace OpenQA.Selenium.BiDi.Communication.Json.Converters
25+
{
26+
internal class DoubleConverter : JsonConverter<double>
27+
{
28+
public override double Read(ref Utf8JsonReader reader, System.Type typeToConvert, JsonSerializerOptions options)
29+
{
30+
if (reader.TryGetDouble(out double d))
31+
{
32+
return d;
33+
}
34+
35+
var str = reader.GetString() ?? throw new JsonException();
36+
37+
if (str.Equals("-0", System.StringComparison.Ordinal))
38+
{
39+
return -0.0;
40+
}
41+
else if (str.Equals("NaN", System.StringComparison.Ordinal))
42+
{
43+
return double.NaN;
44+
}
45+
else if (str.Equals("Infinity", System.StringComparison.Ordinal))
46+
{
47+
return double.PositiveInfinity;
48+
}
49+
else if (str.Equals("-Infinity", System.StringComparison.Ordinal))
50+
{
51+
return double.NegativeInfinity;
52+
}
53+
54+
throw new JsonException();
55+
}
56+
57+
public override void Write(Utf8JsonWriter writer, double value, JsonSerializerOptions options)
58+
{
59+
if (double.IsNaN(value))
60+
{
61+
writer.WriteStringValue("NaN");
62+
}
63+
else if (double.IsPositiveInfinity(value))
64+
{
65+
writer.WriteStringValue("Infinity");
66+
}
67+
else if (double.IsNegativeInfinity(value))
68+
{
69+
writer.WriteStringValue("-Infinity");
70+
}
71+
else if (IsNegativeZero(value))
72+
{
73+
writer.WriteStringValue("-0");
74+
}
75+
else
76+
{
77+
writer.WriteNumberValue(value);
78+
}
79+
80+
static bool IsNegativeZero(double x)
81+
{
82+
const long NegativeZeroBits = -9223372036854775808;
83+
84+
return BitConverter.DoubleToInt64Bits(x) == NegativeZeroBits;
85+
}
86+
}
87+
}
88+
}

dotnet/src/webdriver/BiDi/Modules/Script/LocalValue.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
// under the License.
1818
// </copyright>
1919

20+
using OpenQA.Selenium.BiDi.Communication.Json.Converters;
2021
using System.Collections.Generic;
2122
using System.Text.Json.Serialization;
2223

@@ -75,7 +76,7 @@ public abstract record PrimitiveProtocolLocalValue : LocalValue
7576

7677
}
7778

78-
public record Number(double Value) : PrimitiveProtocolLocalValue
79+
public record Number([property: JsonConverter(typeof(DoubleConverter))] double Value) : PrimitiveProtocolLocalValue
7980
{
8081
public static explicit operator Number(double n) => new Number(n);
8182
}

dotnet/test/common/BiDi/Script/CallFunctionLocalValueTest.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -186,8 +186,8 @@ public void CanCallFunctionWithArgumentNumberNegative0()
186186
{
187187
await context.Script.CallFunctionAsync($$"""
188188
(arg) => {
189-
if (arg !== -0) {
190-
throw new Error("Assert failed: " + arg);
189+
if (arg !== 0 || arg.toLocaleString()[0] !== '-') {
190+
throw new Error("Assert failed: " + arg.toLocaleString());
191191
}
192192
}
193193
""", false, new() { Arguments = [arg] });

0 commit comments

Comments
 (0)