MattV
MattV

Reputation: 1383

ConvertFrom-Json converting lowercase e's into capital case (sometimes)

I'm processing JSON files in PowerShell, and it seems that ConvertFrom-Json changes case on its inputs only on some (rare) occasions.

For example, when I do:

$JsonStringSrc = '{"x":2.2737367544323206e-13,"y":1759,"z":33000,"width":664}' 
$JsonStringTarget = $JsonStringSrc | ConvertFrom-Json | ConvertTo-Json -Depth 100 -Compress
$JsonStringTarget 

It returns:

{"x":2.2737367544323206E-13,"y":1759,"z":33000,"width":664}

Lower case e became an uppercase E, messing up my hashes when validating proper i/o during processing.

Is this expected behavior (perhaps a regional setting)? Is there a setting for ConvertFrom-Json to leave my inputs alone for the output?

Upvotes: 2

Views: 497

Answers (1)

jessehouwing
jessehouwing

Reputation: 114641

The problem lies in the way PowerShell's JSON library output the CLR foating point numbers. By converting from JSON you turn the JSON string into a CLR/PowerShell object with associated types for numbers and strings and such. Converting back to JSON serializes that object back to JSON, but uses the .NET default formatter configuration to do so. There is no metadata from the original JSON document to aid the conversion. Rounding errors and truncation, different order for elements may happen here too.

The JSON spec for canonical form (the form you want to use when hashing) is as follows:

MUST represent all non-integer numbers in exponential notation

  • including a nonzero single-digit significant integer part, and
  • including a nonempty significant fractional part, and
  • including no trailing zeroes in the significant fractional part (other than as part of a “.0” required to satisfy the preceding point), and
  • including a capital “E”, and
  • including no plus sign in the exponent, and
  • including no insignificant leading zeroes in the exponent

Source: https://gibson042.github.io/canonicaljson-spec/

Though the specs for JSON supports both options (e and E).

exponent
   ""
   'E' sign digits
   'e' sign digits

Source: https://www.crockford.com/mckeeman.html

You may be able to convert the object to JSON using the Newtonsoft.Json classes directly and passing in a custom Convertor.

A better solution would probably be to use a specialized formatter component that directly manipulates the existing JSON document without converting it to CLR objects first.

Upvotes: 3

Related Questions