Skip to content

Commit

Permalink
Add fuzz test for double parsing
Browse files Browse the repository at this point in the history
Also fix bug in parsing of decimal nums equal to ints
  • Loading branch information
molsonkiko committed Nov 9, 2024
1 parent a40137e commit a7fef1c
Show file tree
Hide file tree
Showing 5 changed files with 88 additions and 63 deletions.
6 changes: 4 additions & 2 deletions JsonToolsNppPlugin/JSONTools/JNode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -415,7 +415,8 @@ public static string DoubleToString(double d)
{
string dubstring = d.ToString(DOT_DECIMAL_SEP);
int indexOfE = dubstring.IndexOf('E');
if (d == Math.Round(d) && !(d > long.MaxValue || d < long.MinValue) && indexOfE < 0)
bool isValidLong = d == Math.Round(d) && !(d > long.MaxValue || d < long.MinValue);
if (isValidLong && indexOfE < 0)
{
// add ending ".0" to distinguish doubles equal to integers from actual integers
// unless they use exponential notation, in which case you mess things up
Expand All @@ -432,7 +433,8 @@ public static string DoubleToString(double d)
return dubstring; // default string representation has all necessary precision
}
catch { }
return d.ToString("G17", DOT_DECIMAL_SEP); // we need to use a string representation that retains as much precision as possible
string d17 = d.ToString("G17", DOT_DECIMAL_SEP); // we need to use a string representation that retains as much precision as possible
return (isValidLong && d17.IndexOf('E') < 0) ? d17 + ".0" : d17;
}

/// <summary>
Expand Down
4 changes: 2 additions & 2 deletions JsonToolsNppPlugin/Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,5 +28,5 @@
// Build Number
// Revision
//
[assembly: AssemblyVersion("8.1.0.15")]
[assembly: AssemblyFileVersion("8.1.0.15")]
[assembly: AssemblyVersion("8.1.0.16")]
[assembly: AssemblyFileVersion("8.1.0.16")]
31 changes: 27 additions & 4 deletions JsonToolsNppPlugin/Tests/Benchmarker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ private static bool BenchmarkParser(string jsonstr, int numTrials, JsonParser js
return true;
}

public static bool BenchmarkParseAndFormatDoubles(int numTrials, int arraySize)
public static bool BenchmarkAndFuzzParseAndFormatDoubles(int numTrials, int arraySize)
{
var parser = new JsonParser();
Stopwatch watch = new Stopwatch();
Expand All @@ -204,11 +204,11 @@ public static bool BenchmarkParseAndFormatDoubles(int numTrials, int arraySize)
return true;
}
numArrPreview = numArrayStr.Length <= 200 ? numArrayStr : numArrayStr.Substring(0, 200) + "...";
JNode numArrayNode = new JNode();
JArray numArray = new JArray();
try
{
watch.Start();
numArrayNode = parser.Parse(numArrayStr);
numArray = (JArray)parser.Parse(numArrayStr);
watch.Stop();
ticksToParse[ii] = watch.ElapsedTicks;
watch.Reset();
Expand All @@ -221,7 +221,7 @@ public static bool BenchmarkParseAndFormatDoubles(int numTrials, int arraySize)
try
{
watch.Start();
numArrayDumped = numArrayNode.ToString();
numArrayDumped = numArray.ToString();
watch.Stop();
ticksToDump[ii] = watch.ElapsedTicks;
watch.Reset();
Expand All @@ -231,6 +231,29 @@ public static bool BenchmarkParseAndFormatDoubles(int numTrials, int arraySize)
Npp.AddLine($"While compressing the JSON array made by parsing \"{numArrPreview}\", got exception {ex}");
return true;
}
try
{
// verify that all doubles in numArray round-trip to the same value when parsing numArrayDumped
JArray numArrayFromDumped = (JArray)parser.Parse(numArrayDumped);
var badValues = new List<double>();
for (int jj = 0; jj < numArray.Length; jj++)
{
double val = (double)numArray[jj].value;
double reloaded = (double)numArrayFromDumped[jj].value;
if (val != reloaded)
badValues.Add(val);
}
if (badValues.Count > 0)
{
Npp.AddLine($"The following doubles did not round-trip:\r\n" + string.Join(", ", badValues.Select(x => x.ToString(JNode.DOT_DECIMAL_SEP))));
return true;
}
}
catch (Exception ex)
{
Npp.AddLine($"While parsing the JSON array made by dumping numArray, and comparing the re-parsed array to numArray, got exception {ex}");
return true;
}
}
(double mean, double sd) = GetMeanAndSd(ticksToParse);
Npp.AddLine($"To parse arrays of {arraySize} non-integer numbers (representative length = {numArrayStr.Length}, representative example preview: \"{numArrPreview}\") " +
Expand Down
4 changes: 2 additions & 2 deletions JsonToolsNppPlugin/Tests/TestRunner.cs
Original file line number Diff line number Diff line change
Expand Up @@ -112,8 +112,8 @@ public static async Task RunAll()
"JsonParser performance",
true, false
),
(() => Benchmarker.BenchmarkParseAndFormatDoubles(32, 5000),
"performance of parsing and dumping arrays of non-integer numbers",
(() => Benchmarker.BenchmarkAndFuzzParseAndFormatDoubles(32, 5000),
"performance and correctness of parsing and dumping arrays of non-integer numbers",
false, false),
//(() => Benchmarker.BenchmarkParsingAndLintingJsonWithErrors(30), "JsonParser performance and performance of JsonLint.message"),
(() => Benchmarker.BenchmarkJNodeToString(64, bigRandomFname),
Expand Down
Loading

0 comments on commit a7fef1c

Please sign in to comment.